mirror of https://github.com/certd/certd
perf: 用户名支持修改
parent
b150b2f034
commit
89c7f07034
|
@ -75,7 +75,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||
{ max: 50, message: "最大50个字符" }
|
||||
]
|
||||
},
|
||||
editForm: { component: { disabled: true } },
|
||||
editForm: { component: { disabled: false } },
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 200
|
||||
|
@ -107,11 +107,35 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
|||
sorter: true
|
||||
}
|
||||
},
|
||||
email: {
|
||||
title: "邮箱",
|
||||
type: "text",
|
||||
search: { show: true }, // 开启查询
|
||||
form: {
|
||||
rules: [{ max: 50, message: "最大50个字符" }]
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 160
|
||||
}
|
||||
},
|
||||
mobile: {
|
||||
title: "手机号",
|
||||
type: "text",
|
||||
search: { show: true }, // 开启查询
|
||||
form: {
|
||||
rules: [{ max: 50, message: "最大50个字符" }]
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 130
|
||||
}
|
||||
},
|
||||
avatar: {
|
||||
title: "头像",
|
||||
type: "cropper-uploader",
|
||||
column: {
|
||||
width: 100,
|
||||
width: 70,
|
||||
component: {
|
||||
//设置高度,修复操作列错位的问题
|
||||
style: {
|
||||
|
|
|
@ -1,75 +1,54 @@
|
|||
import { request } from "/src/api/service";
|
||||
|
||||
const apiPrefix = "/sys/suite/userSuite";
|
||||
export function createApi() {
|
||||
const apiPrefix = "/sys/suite/userSuites";
|
||||
return {
|
||||
async GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query
|
||||
});
|
||||
},
|
||||
|
||||
export async function GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query
|
||||
});
|
||||
async AddObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/add",
|
||||
method: "post",
|
||||
data: obj
|
||||
});
|
||||
},
|
||||
|
||||
async UpdateObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/update",
|
||||
method: "post",
|
||||
data: obj
|
||||
});
|
||||
},
|
||||
|
||||
async DelObj(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
},
|
||||
|
||||
async GetObj(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/info",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
},
|
||||
async ListAll() {
|
||||
return await request({
|
||||
url: apiPrefix + "/all",
|
||||
method: "post"
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function AddObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/add",
|
||||
method: "post",
|
||||
data: obj
|
||||
});
|
||||
}
|
||||
|
||||
export async function UpdateObj(obj: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/update",
|
||||
method: "post",
|
||||
data: obj
|
||||
});
|
||||
}
|
||||
|
||||
export async function DelObj(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetObj(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/info",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetDetail(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/detail",
|
||||
method: "post",
|
||||
params: { id }
|
||||
});
|
||||
}
|
||||
|
||||
export async function DeleteBatch(ids: any[]) {
|
||||
return await request({
|
||||
url: apiPrefix + "/deleteByIds",
|
||||
method: "post",
|
||||
data: { ids }
|
||||
});
|
||||
}
|
||||
|
||||
export async function SetDefault(id: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/setDefault",
|
||||
method: "post",
|
||||
data: { id }
|
||||
});
|
||||
}
|
||||
|
||||
export async function SetDisabled(id: any, disabled: boolean) {
|
||||
return await request({
|
||||
url: apiPrefix + "/setDisabled",
|
||||
method: "post",
|
||||
data: { id, disabled }
|
||||
});
|
||||
}
|
||||
export const pipelineGroupApi = createApi();
|
||||
|
|
|
@ -1,249 +1,321 @@
|
|||
import * as api from "./api";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { computed, Ref, ref } from "vue";
|
||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||
import { pipelineGroupApi } from "./api";
|
||||
import { useRouter } from "vue-router";
|
||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
|
||||
import { useUserStore } from "/@/store/modules/user";
|
||||
import { useSettingStore } from "/@/store/modules/settings";
|
||||
import { Modal } from "ant-design-vue";
|
||||
import SuiteValueEdit from "/@/views/sys/suite/product/suite-value-edit.vue";
|
||||
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
||||
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const api = pipelineGroupApi;
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const editRequest = async ({ form, row }: EditReq) => {
|
||||
const editRequest = async (req: EditReq) => {
|
||||
const { form, row } = req;
|
||||
form.id = row.id;
|
||||
const res = await api.UpdateObj(form);
|
||||
return res;
|
||||
};
|
||||
const delRequest = async ({ row }: DelReq) => {
|
||||
const delRequest = async (req: DelReq) => {
|
||||
const { row } = req;
|
||||
return await api.DelObj(row.id);
|
||||
};
|
||||
|
||||
const addRequest = async ({ form }: AddReq) => {
|
||||
const addRequest = async (req: AddReq) => {
|
||||
const { form } = req;
|
||||
const res = await api.AddObj(form);
|
||||
return res;
|
||||
};
|
||||
|
||||
const userStore = useUserStore();
|
||||
const settingStore = useSettingStore();
|
||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
||||
context.selectedRowKeys = selectedRowKeys;
|
||||
const router = useRouter();
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
settings: {
|
||||
plugins: {
|
||||
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
||||
rowSelection: {
|
||||
enabled: true,
|
||||
order: -2,
|
||||
before: true,
|
||||
// handle: (pluginProps,useCrudProps)=>CrudOptions,
|
||||
props: {
|
||||
multiple: true,
|
||||
crossPage: true,
|
||||
selectedRowKeys
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest
|
||||
},
|
||||
form: {
|
||||
labelCol: {
|
||||
//固定label宽度
|
||||
span: null,
|
||||
style: {
|
||||
width: "100px"
|
||||
}
|
||||
},
|
||||
col: {
|
||||
span: 22
|
||||
},
|
||||
wrapper: {
|
||||
width: 600
|
||||
}
|
||||
},
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: { show: false },
|
||||
buy: {
|
||||
text: "购买",
|
||||
type: "primary",
|
||||
click() {
|
||||
router.push({
|
||||
path: "/certd/suite/buy"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
rowHandle: {
|
||||
minWidth: 200,
|
||||
fixed: "right"
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: false },
|
||||
copy: { show: false },
|
||||
edit: { show: false },
|
||||
remove: { show: false }
|
||||
// continue:{
|
||||
// text:"续期",
|
||||
// type:"link",
|
||||
// click(){
|
||||
// console.log("续期");
|
||||
// }
|
||||
// }
|
||||
}
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
title: "ID",
|
||||
key: "id",
|
||||
type: "number",
|
||||
search: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 100
|
||||
width: 100,
|
||||
editable: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
form: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
domain: {
|
||||
title: "CNAME域名",
|
||||
title: {
|
||||
title: "套餐名称",
|
||||
type: "text",
|
||||
editForm: {
|
||||
component: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
form: {
|
||||
component: {
|
||||
placeholder: "cname.handsfree.work"
|
||||
},
|
||||
helper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
width: 200
|
||||
}
|
||||
},
|
||||
dnsProviderType: {
|
||||
title: "DNS提供商",
|
||||
productType: {
|
||||
title: "类型",
|
||||
type: "dict-select",
|
||||
search: {
|
||||
show: true
|
||||
editForm: {
|
||||
component: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
dict: dict({
|
||||
url: "pi/dnsProvider/list",
|
||||
value: "key",
|
||||
label: "title"
|
||||
data: [
|
||||
{ label: "套餐", value: "suite", color: "green" },
|
||||
{ label: "加量包", value: "addon", color: "blue" }
|
||||
]
|
||||
}),
|
||||
form: {
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
width: 150,
|
||||
component: {
|
||||
color: "auto"
|
||||
width: 80,
|
||||
align: "center"
|
||||
},
|
||||
valueBuilder: ({ row }) => {
|
||||
if (row.content) {
|
||||
row.content = JSON.parse(row.content);
|
||||
}
|
||||
},
|
||||
valueResolve: ({ form }) => {
|
||||
if (form.content) {
|
||||
form.content = JSON.stringify(form.content);
|
||||
}
|
||||
}
|
||||
},
|
||||
accessId: {
|
||||
title: "DNS提供商授权",
|
||||
type: "dict-select",
|
||||
dict: dict({
|
||||
url: "/pi/access/list",
|
||||
value: "id",
|
||||
label: "name"
|
||||
}),
|
||||
"content.maxDomainCount": {
|
||||
title: "域名数量",
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxDomainCount"],
|
||||
component: {
|
||||
name: "access-selector",
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
type: compute(({ form }) => {
|
||||
return form.dnsProviderType;
|
||||
})
|
||||
unit: "个"
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
width: 150,
|
||||
width: 100,
|
||||
component: {
|
||||
color: "auto"
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: "个"
|
||||
},
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
"content.maxPipelineCount": {
|
||||
title: "流水线数量",
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxPipelineCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
unit: "条"
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
component: {
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: "条"
|
||||
},
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
"content.maxDeployCount": {
|
||||
title: "部署次数",
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxDeployCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
unit: "次"
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
component: {
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: "次"
|
||||
},
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
"content.maxMonitorCount": {
|
||||
title: "证书监控数量",
|
||||
type: "text",
|
||||
form: {
|
||||
key: ["content", "maxMonitorCount"],
|
||||
component: {
|
||||
name: SuiteValueEdit,
|
||||
vModel: "modelValue",
|
||||
unit: "个"
|
||||
},
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
width: 120,
|
||||
component: {
|
||||
name: SuiteValue,
|
||||
vModel: "modelValue",
|
||||
unit: "个"
|
||||
},
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
duration: {
|
||||
title: "时长",
|
||||
type: "text",
|
||||
form: {},
|
||||
column: {
|
||||
component: {
|
||||
name: DurationValue,
|
||||
vModel: "modelValue"
|
||||
},
|
||||
width: 100,
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
status: {
|
||||
title: "状态",
|
||||
type: "text",
|
||||
form: { show: false },
|
||||
column: {
|
||||
width: 100,
|
||||
align: "center",
|
||||
conditionalRender: {
|
||||
match() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
cellRender({ row }) {
|
||||
if (row.activeTime == null) {
|
||||
return <a-tag color="blue">未使用</a-tag>;
|
||||
}
|
||||
const now = dayjs().valueOf();
|
||||
//已过期
|
||||
const isExpired = row.expiresTime != -1 && now > row.expiresTime;
|
||||
if (isExpired) {
|
||||
return <a-tag color="error">已过期</a-tag>;
|
||||
}
|
||||
//如果在激活时间之前
|
||||
if (now < row.activeTime) {
|
||||
return <a-tag color="blue">待生效</a-tag>;
|
||||
}
|
||||
// 是否在激活时间和过期时间之间
|
||||
if (now > row.activeTime && (row.expiresTime == -1 || now < row.expiresTime)) {
|
||||
return <a-tag color="success">生效中</a-tag>;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
isDefault: {
|
||||
title: "是否默认",
|
||||
activeTime: {
|
||||
title: "激活时间",
|
||||
type: "date",
|
||||
column: {
|
||||
width: 150
|
||||
}
|
||||
},
|
||||
expiresTime: {
|
||||
title: "过期时间",
|
||||
type: "date",
|
||||
column: {
|
||||
width: 150,
|
||||
component: {
|
||||
name: "expires-time-text",
|
||||
vModel: "value",
|
||||
mode: "tag"
|
||||
}
|
||||
}
|
||||
},
|
||||
isPresent: {
|
||||
title: "是否赠送",
|
||||
type: "dict-switch",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "是", value: true, color: "success" },
|
||||
{ label: "否", value: false, color: "default" }
|
||||
{ label: "否", value: false, color: "blue" }
|
||||
]
|
||||
}),
|
||||
form: {
|
||||
value: false,
|
||||
rules: [{ required: true, message: "请选择是否默认" }]
|
||||
},
|
||||
column: {
|
||||
align: "center",
|
||||
width: 100
|
||||
}
|
||||
},
|
||||
setDefault: {
|
||||
title: "设置默认",
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
value: true
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
align: "center",
|
||||
conditionalRenderDisabled: true,
|
||||
cellRender: ({ row }) => {
|
||||
if (row.isDefault) {
|
||||
return;
|
||||
}
|
||||
const onClick = async () => {
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: `确定要设置为默认吗?`,
|
||||
onOk: async () => {
|
||||
await api.SetDefault(row.id);
|
||||
await crudExpose.doRefresh();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<a-button type={"link"} size={"small"} onClick={onClick}>
|
||||
设为默认
|
||||
</a-button>
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
title: "禁用/启用",
|
||||
type: "dict-switch",
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: "启用", value: false, color: "success" },
|
||||
{ label: "禁用", value: true, color: "error" }
|
||||
]
|
||||
}),
|
||||
form: {
|
||||
value: false
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
component: {
|
||||
title: "点击可禁用/启用",
|
||||
on: {
|
||||
async click({ value, row }) {
|
||||
Modal.confirm({
|
||||
title: "提示",
|
||||
content: `确定要${!value ? "禁用" : "启用"}吗?`,
|
||||
onOk: async () => {
|
||||
await api.SetDisabled(row.id, !value);
|
||||
await crudExpose.doRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
createTime: {
|
||||
title: "创建时间",
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 160,
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
updateTime: {
|
||||
title: "更新时间",
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
show: true,
|
||||
width: 160
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,57 +1,30 @@
|
|||
<template>
|
||||
<fs-page class="page-cert">
|
||||
<fs-page>
|
||||
<template #header>
|
||||
<div class="title">
|
||||
CNAME服务配置
|
||||
<span class="sub">
|
||||
此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。
|
||||
<a href="https://certd.docmirror.cn/guide/feature/cname/" target="_blank">CNAME功能原理及使用说明</a>
|
||||
</span>
|
||||
用户套餐
|
||||
<span class="sub">管理用户的套餐</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||
<template #pagination-left>
|
||||
<a-tooltip title="批量删除">
|
||||
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</fs-crud>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from "vue";
|
||||
import { defineComponent, onActivated, onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import { DeleteBatch } from "./api";
|
||||
|
||||
import { createApi } from "./api";
|
||||
defineOptions({
|
||||
name: "CnameProvider"
|
||||
name: "UserSuites"
|
||||
});
|
||||
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
||||
|
||||
const selectedRowKeys = context.selectedRowKeys;
|
||||
const handleBatchDelete = () => {
|
||||
if (selectedRowKeys.value?.length > 0) {
|
||||
Modal.confirm({
|
||||
title: "确认",
|
||||
content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
|
||||
async onOk() {
|
||||
await DeleteBatch(selectedRowKeys.value);
|
||||
message.info("删除成功");
|
||||
crudExpose.doRefresh();
|
||||
selectedRowKeys.value = [];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
message.error("请先勾选记录");
|
||||
}
|
||||
};
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
onActivated(() => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
<style lang="less"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { MoreThan, Repository } from 'typeorm';
|
||||
import { MoreThan, Not, Repository } from 'typeorm';
|
||||
import { UserEntity } from '../entity/user.js';
|
||||
import * as _ from 'lodash-es';
|
||||
import { BaseService, CommonException, Constants, FileService, SysInstallInfo, SysSettingsService } from '@certd/lib-server';
|
||||
|
@ -100,7 +100,18 @@ export class UserService extends BaseService<UserEntity> {
|
|||
throw new CommonException('用户不存在');
|
||||
}
|
||||
|
||||
delete param.username;
|
||||
if (param.username) {
|
||||
const username = param.username;
|
||||
const id = param.id;
|
||||
const old = await this.findOne([
|
||||
{ username: username, id: Not(id) },
|
||||
{ mobile: username, id: Not(id) },
|
||||
{ email: username, id: Not(id) },
|
||||
]);
|
||||
if (old != null) {
|
||||
throw new CommonException('用户名已被占用');
|
||||
}
|
||||
}
|
||||
if (!_.isEmpty(param.password)) {
|
||||
param.passwordVersion = 2;
|
||||
param.password = await this.genPassword(param.password, param.passwordVersion);
|
||||
|
|
Loading…
Reference in New Issue