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个字符" }
|
{ max: 50, message: "最大50个字符" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
editForm: { component: { disabled: true } },
|
editForm: { component: { disabled: false } },
|
||||||
column: {
|
column: {
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 200
|
width: 200
|
||||||
|
@ -107,11 +107,35 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
||||||
sorter: true
|
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: {
|
avatar: {
|
||||||
title: "头像",
|
title: "头像",
|
||||||
type: "cropper-uploader",
|
type: "cropper-uploader",
|
||||||
column: {
|
column: {
|
||||||
width: 100,
|
width: 70,
|
||||||
component: {
|
component: {
|
||||||
//设置高度,修复操作列错位的问题
|
//设置高度,修复操作列错位的问题
|
||||||
style: {
|
style: {
|
||||||
|
|
|
@ -1,75 +1,54 @@
|
||||||
import { request } from "/src/api/service";
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
const apiPrefix = "/sys/suite/userSuite";
|
export function createApi() {
|
||||||
|
const apiPrefix = "/sys/suite/userSuites";
|
||||||
export async function GetList(query: any) {
|
return {
|
||||||
|
async GetList(query: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/page",
|
url: apiPrefix + "/page",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: query
|
data: query
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function AddObj(obj: any) {
|
async AddObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/add",
|
url: apiPrefix + "/add",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: obj
|
data: obj
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function UpdateObj(obj: any) {
|
async UpdateObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/update",
|
url: apiPrefix + "/update",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: obj
|
data: obj
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function DelObj(id: any) {
|
async DelObj(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/delete",
|
url: apiPrefix + "/delete",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id }
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetObj(id: any) {
|
async GetObj(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/info",
|
url: apiPrefix + "/info",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id }
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
async ListAll() {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/all",
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function GetDetail(id: any) {
|
export const pipelineGroupApi = createApi();
|
||||||
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 }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,249 +1,321 @@
|
||||||
import * as api from "./api";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { useI18n } from "vue-i18n";
|
import { pipelineGroupApi } from "./api";
|
||||||
import { computed, Ref, ref } from "vue";
|
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
|
import SuiteValueEdit from "/@/views/sys/suite/product/suite-value-edit.vue";
|
||||||
import { useUserStore } from "/@/store/modules/user";
|
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
||||||
import { useSettingStore } from "/@/store/modules/settings";
|
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
||||||
import { Modal } from "ant-design-vue";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const router = useRouter();
|
const api = pipelineGroupApi;
|
||||||
const { t } = useI18n();
|
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await api.GetList(query);
|
||||||
};
|
};
|
||||||
const editRequest = async ({ form, row }: EditReq) => {
|
const editRequest = async (req: EditReq) => {
|
||||||
|
const { form, row } = req;
|
||||||
form.id = row.id;
|
form.id = row.id;
|
||||||
const res = await api.UpdateObj(form);
|
const res = await api.UpdateObj(form);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
const delRequest = async ({ row }: DelReq) => {
|
const delRequest = async (req: DelReq) => {
|
||||||
|
const { row } = req;
|
||||||
return await api.DelObj(row.id);
|
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);
|
const res = await api.AddObj(form);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const router = useRouter();
|
||||||
const settingStore = useSettingStore();
|
|
||||||
const selectedRowKeys: Ref<any[]> = ref([]);
|
|
||||||
context.selectedRowKeys = selectedRowKeys;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
settings: {
|
|
||||||
plugins: {
|
|
||||||
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
|
||||||
rowSelection: {
|
|
||||||
enabled: true,
|
|
||||||
order: -2,
|
|
||||||
before: true,
|
|
||||||
// handle: (pluginProps,useCrudProps)=>CrudOptions,
|
|
||||||
props: {
|
|
||||||
multiple: true,
|
|
||||||
crossPage: true,
|
|
||||||
selectedRowKeys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
request: {
|
request: {
|
||||||
pageRequest,
|
pageRequest,
|
||||||
addRequest,
|
addRequest,
|
||||||
editRequest,
|
editRequest,
|
||||||
delRequest
|
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: {
|
rowHandle: {
|
||||||
minWidth: 200,
|
width: 200,
|
||||||
fixed: "right"
|
fixed: "right",
|
||||||
|
buttons: {
|
||||||
|
view: { show: false },
|
||||||
|
copy: { show: false },
|
||||||
|
edit: { show: false },
|
||||||
|
remove: { show: false }
|
||||||
|
// continue:{
|
||||||
|
// text:"续期",
|
||||||
|
// type:"link",
|
||||||
|
// click(){
|
||||||
|
// console.log("续期");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
id: {
|
id: {
|
||||||
title: "ID",
|
title: "ID",
|
||||||
key: "id",
|
key: "id",
|
||||||
type: "number",
|
type: "number",
|
||||||
|
search: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 100
|
width: 100,
|
||||||
|
editable: {
|
||||||
|
disabled: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
show: false
|
show: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
domain: {
|
title: {
|
||||||
title: "CNAME域名",
|
title: "套餐名称",
|
||||||
type: "text",
|
type: "text",
|
||||||
editForm: {
|
|
||||||
component: {
|
|
||||||
disabled: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
search: {
|
search: {
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
component: {
|
|
||||||
placeholder: "cname.handsfree.work"
|
|
||||||
},
|
|
||||||
helper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
|
||||||
rules: [{ required: true, message: "此项必填" }]
|
rules: [{ required: true, message: "此项必填" }]
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 200
|
width: 200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dnsProviderType: {
|
productType: {
|
||||||
title: "DNS提供商",
|
title: "类型",
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
search: {
|
editForm: {
|
||||||
show: true
|
component: {
|
||||||
|
disabled: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
dict: dict({
|
dict: dict({
|
||||||
url: "pi/dnsProvider/list",
|
data: [
|
||||||
value: "key",
|
{ label: "套餐", value: "suite", color: "green" },
|
||||||
label: "title"
|
{ label: "加量包", value: "addon", color: "blue" }
|
||||||
|
]
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
rules: [{ required: true, message: "此项必填" }]
|
rules: [{ required: true, message: "此项必填" }]
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 150,
|
width: 80,
|
||||||
component: {
|
align: "center"
|
||||||
color: "auto"
|
},
|
||||||
|
valueBuilder: ({ row }) => {
|
||||||
|
if (row.content) {
|
||||||
|
row.content = JSON.parse(row.content);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
valueResolve: ({ form }) => {
|
||||||
|
if (form.content) {
|
||||||
|
form.content = JSON.stringify(form.content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
accessId: {
|
"content.maxDomainCount": {
|
||||||
title: "DNS提供商授权",
|
title: "域名数量",
|
||||||
type: "dict-select",
|
type: "text",
|
||||||
dict: dict({
|
|
||||||
url: "/pi/access/list",
|
|
||||||
value: "id",
|
|
||||||
label: "name"
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
|
key: ["content", "maxDomainCount"],
|
||||||
component: {
|
component: {
|
||||||
name: "access-selector",
|
name: SuiteValueEdit,
|
||||||
vModel: "modelValue",
|
vModel: "modelValue",
|
||||||
type: compute(({ form }) => {
|
unit: "个"
|
||||||
return form.dnsProviderType;
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: "此项必填" }]
|
rules: [{ required: true, message: "此项必填" }]
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 150,
|
width: 100,
|
||||||
component: {
|
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: {
|
activeTime: {
|
||||||
title: "是否默认",
|
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",
|
type: "dict-switch",
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: "是", value: true, color: "success" },
|
{ label: "是", value: true, color: "success" },
|
||||||
{ label: "否", value: false, color: "default" }
|
{ label: "否", value: false, color: "blue" }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
value: false,
|
value: true
|
||||||
rules: [{ required: true, message: "请选择是否默认" }]
|
|
||||||
},
|
|
||||||
column: {
|
|
||||||
align: "center",
|
|
||||||
width: 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setDefault: {
|
|
||||||
title: "设置默认",
|
|
||||||
type: "text",
|
|
||||||
form: {
|
|
||||||
show: false
|
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 100,
|
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"
|
align: "center"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
updateTime: {
|
|
||||||
title: "更新时间",
|
|
||||||
type: "datetime",
|
|
||||||
form: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
column: {
|
|
||||||
show: true,
|
|
||||||
width: 160
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<fs-page class="page-cert">
|
<fs-page>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
CNAME服务配置
|
用户套餐
|
||||||
<span class="sub">
|
<span class="sub">管理用户的套餐</span>
|
||||||
此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。
|
|
||||||
<a href="https://certd.docmirror.cn/guide/feature/cname/" target="_blank">CNAME功能原理及使用说明</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<fs-crud ref="crudRef" v-bind="crudBinding">
|
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||||
<template #pagination-left>
|
|
||||||
<a-tooltip title="批量删除">
|
|
||||||
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
|
|
||||||
</a-tooltip>
|
|
||||||
</template>
|
|
||||||
</fs-crud>
|
|
||||||
</fs-page>
|
</fs-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted } from "vue";
|
import { defineComponent, onActivated, onMounted } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { message, Modal } from "ant-design-vue";
|
import { createApi } from "./api";
|
||||||
import { DeleteBatch } from "./api";
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "CnameProvider"
|
name: "UserSuites"
|
||||||
});
|
});
|
||||||
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||||
|
|
||||||
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("请先勾选记录");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
crudExpose.doRefresh();
|
crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
|
onActivated(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less"></style>
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { MoreThan, Repository } from 'typeorm';
|
import { MoreThan, Not, Repository } from 'typeorm';
|
||||||
import { UserEntity } from '../entity/user.js';
|
import { UserEntity } from '../entity/user.js';
|
||||||
import * as _ from 'lodash-es';
|
import * as _ from 'lodash-es';
|
||||||
import { BaseService, CommonException, Constants, FileService, SysInstallInfo, SysSettingsService } from '@certd/lib-server';
|
import { BaseService, CommonException, Constants, FileService, SysInstallInfo, SysSettingsService } from '@certd/lib-server';
|
||||||
|
@ -100,7 +100,18 @@ export class UserService extends BaseService<UserEntity> {
|
||||||
throw new CommonException('用户不存在');
|
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)) {
|
if (!_.isEmpty(param.password)) {
|
||||||
param.passwordVersion = 2;
|
param.passwordVersion = 2;
|
||||||
param.password = await this.genPassword(param.password, param.passwordVersion);
|
param.password = await this.genPassword(param.password, param.passwordVersion);
|
||||||
|
|
Loading…
Reference in New Issue