mirror of https://github.com/certd/certd
perf: 站点证书监控增加导出和分组功能
parent
e578c52fdf
commit
2ed12c429e
|
|
@ -227,6 +227,7 @@ export default {
|
||||||
},
|
},
|
||||||
notificationDefault: "Use Default Notification",
|
notificationDefault: "Use Default Notification",
|
||||||
monitor: {
|
monitor: {
|
||||||
|
remark: "Remark",
|
||||||
title: "Site Certificate Monitoring",
|
title: "Site Certificate Monitoring",
|
||||||
description: "Check website certificates' expiration at 0:00 daily; reminders sent 10 days before expiration (using default notification channel);",
|
description: "Check website certificates' expiration at 0:00 daily; reminders sent 10 days before expiration (using default notification channel);",
|
||||||
settingLink: "Site Monitoring Settings",
|
settingLink: "Site Monitoring Settings",
|
||||||
|
|
@ -248,6 +249,7 @@ export default {
|
||||||
certDomains: "Certificate Domains",
|
certDomains: "Certificate Domains",
|
||||||
certProvider: "Issuer",
|
certProvider: "Issuer",
|
||||||
certStatus: "Certificate Status",
|
certStatus: "Certificate Status",
|
||||||
|
error: "Error",
|
||||||
status: {
|
status: {
|
||||||
ok: "Valid",
|
ok: "Valid",
|
||||||
expired: "Expired",
|
expired: "Expired",
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,7 @@ export default {
|
||||||
},
|
},
|
||||||
notificationDefault: "使用默认通知",
|
notificationDefault: "使用默认通知",
|
||||||
monitor: {
|
monitor: {
|
||||||
|
remark: "备注",
|
||||||
title: "站点证书监控",
|
title: "站点证书监控",
|
||||||
description: "每天0点,检查网站证书的过期时间,到期前10天时将发出提醒(使用默认通知渠道);",
|
description: "每天0点,检查网站证书的过期时间,到期前10天时将发出提醒(使用默认通知渠道);",
|
||||||
settingLink: "站点监控设置",
|
settingLink: "站点监控设置",
|
||||||
|
|
@ -253,6 +254,7 @@ export default {
|
||||||
certDomains: "证书域名",
|
certDomains: "证书域名",
|
||||||
certProvider: "颁发机构",
|
certProvider: "颁发机构",
|
||||||
certStatus: "证书状态",
|
certStatus: "证书状态",
|
||||||
|
error: "错误信息",
|
||||||
status: {
|
status: {
|
||||||
ok: "正常",
|
ok: "正常",
|
||||||
expired: "过期",
|
expired: "过期",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
import { dict } from "@fast-crud/fast-crud";
|
||||||
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
|
export function createApi() {
|
||||||
|
const apiPrefix = "/basic/group";
|
||||||
|
return {
|
||||||
|
async 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(type: string) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/all",
|
||||||
|
method: "post",
|
||||||
|
params: { type },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const pipelineGroupApi = createApi();
|
||||||
|
|
||||||
|
export function createGroupDictRef(type: string) {
|
||||||
|
return dict({
|
||||||
|
url: "/basic/group/all?type=" + type,
|
||||||
|
value: "id",
|
||||||
|
label: "name",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
import { pipelineGroupApi } from "./api";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const api = pipelineGroupApi;
|
||||||
|
const typeRef = ref(context.type);
|
||||||
|
|
||||||
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
|
return await api.GetList(query);
|
||||||
|
};
|
||||||
|
const editRequest = async (req: EditReq) => {
|
||||||
|
const { form, row } = req;
|
||||||
|
form.id = row.id;
|
||||||
|
const res = await api.UpdateObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
const delRequest = async (req: DelReq) => {
|
||||||
|
const { row } = req;
|
||||||
|
return await api.DelObj(row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addRequest = async (req: AddReq) => {
|
||||||
|
const { form } = req;
|
||||||
|
form.type = typeRef.value;
|
||||||
|
const res = await api.AddObj(form);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudOptions: {
|
||||||
|
settings: {
|
||||||
|
plugins: {
|
||||||
|
mobile: {
|
||||||
|
props: {
|
||||||
|
rowHandle: {
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
pageRequest,
|
||||||
|
addRequest,
|
||||||
|
editRequest,
|
||||||
|
delRequest,
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
initialForm: {
|
||||||
|
type: typeRef.value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
labelCol: {
|
||||||
|
//固定label宽度
|
||||||
|
span: null,
|
||||||
|
style: {
|
||||||
|
width: "100px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
col: {
|
||||||
|
span: 22,
|
||||||
|
},
|
||||||
|
wrapper: {
|
||||||
|
width: 600,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rowHandle: {
|
||||||
|
width: 200,
|
||||||
|
group: {
|
||||||
|
editable: {
|
||||||
|
edit: {
|
||||||
|
text: t("certd.edit"),
|
||||||
|
order: -1,
|
||||||
|
type: "primary",
|
||||||
|
click({ row, index }) {
|
||||||
|
crudExpose.openEdit({
|
||||||
|
index,
|
||||||
|
row,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
editable: {
|
||||||
|
enabled: true,
|
||||||
|
mode: "cell",
|
||||||
|
exclusive: true,
|
||||||
|
//排他式激活效果,将其他行的编辑状态触发保存
|
||||||
|
exclusiveEffect: "save", //自动保存其他行编辑状态,cancel = 自动关闭其他行编辑状态
|
||||||
|
async updateCell(opts) {
|
||||||
|
const { row, key, value } = opts;
|
||||||
|
//如果是添加,需要返回{[rowKey]:xxx},比如:{id:2}
|
||||||
|
return await api.UpdateObj({ id: row.id, [key]: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
id: {
|
||||||
|
title: "ID",
|
||||||
|
key: "id",
|
||||||
|
type: "number",
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 100,
|
||||||
|
editable: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
title: t("certd.groupName"),
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("certd.enterGroupName"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 400,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
<template>
|
||||||
|
<div class="pi-group-selector flex full-w">
|
||||||
|
<div class="flex-1">
|
||||||
|
<fs-dict-select :value="modelValue" :dict="groupDictRef" :allow-clear="true" @update:value="doUpdate"></fs-dict-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<fs-table-select
|
||||||
|
class="flex-0"
|
||||||
|
:create-crud-options="createCrudOptions"
|
||||||
|
:crud-options-override="{
|
||||||
|
search: { show: false, initialForm: { type: props.type } },
|
||||||
|
table: {
|
||||||
|
scroll: {
|
||||||
|
x: 540,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
:model-value="modelValue"
|
||||||
|
:dict="groupDictRef"
|
||||||
|
:show-current="false"
|
||||||
|
:show-select="false"
|
||||||
|
:dialog="{ width: 960 }"
|
||||||
|
:destroy-on-close="false"
|
||||||
|
height="400px"
|
||||||
|
@update:model-value="doUpdate"
|
||||||
|
@dialog-closed="doRefresh"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<fs-button class="ml-5" type="primary" icon="ant-design:edit-outlined" @click="scope.open({ context: { type: props.type } })"></fs-button>
|
||||||
|
</template>
|
||||||
|
</fs-table-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { createGroupDictRef } from "./api";
|
||||||
|
import createCrudOptions from "./crud";
|
||||||
|
import { dict, FsDictSelect } from "@fast-crud/fast-crud";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue?: number;
|
||||||
|
type: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "GroupSelector",
|
||||||
|
});
|
||||||
|
const groupDictRef = createGroupDictRef(props.type);
|
||||||
|
const emit = defineEmits(["refresh", "update:modelValue", "change"]);
|
||||||
|
function doRefresh() {
|
||||||
|
emit("refresh");
|
||||||
|
groupDictRef.reloadDict();
|
||||||
|
}
|
||||||
|
|
||||||
|
function doUpdate(value: any) {
|
||||||
|
emit("update:modelValue", value);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<template>
|
||||||
|
<fs-page>
|
||||||
|
<template #header>
|
||||||
|
<div class="title">
|
||||||
|
分组管理
|
||||||
|
<span class="sub">流水线分组</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, onActivated, onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "./crud";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "BasicGroupManager",
|
||||||
|
setup() {
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
onActivated(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudBinding,
|
||||||
|
crudRef,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
import { AddReq, ColumnCompositionProps, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, ColumnCompositionProps, ColumnProps, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DataFormatterContext, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { siteInfoApi } from "./api";
|
import { siteInfoApi } from "./api";
|
||||||
import * as settingApi from "./setting/api";
|
import * as settingApi from "./setting/api";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
@ -11,7 +11,8 @@ import { mitter } from "/@/utils/util.mitt";
|
||||||
import { useSiteIpMonitor } from "./ip/use";
|
import { useSiteIpMonitor } from "./ip/use";
|
||||||
import { useSiteImport } from "/@/views/certd/monitor/site/use";
|
import { useSiteImport } from "/@/views/certd/monitor/site/use";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import GroupSelector from "../../basic/group/group-selector.vue";
|
||||||
|
import { createGroupDictRef } from "../../basic/group/api";
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const api = siteInfoApi;
|
const api = siteInfoApi;
|
||||||
|
|
@ -91,6 +92,16 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GroupTypeSite = "site";
|
||||||
|
const groupDictRef = createGroupDictRef(GroupTypeSite);
|
||||||
|
|
||||||
|
function getDefaultGroupId() {
|
||||||
|
const searchFrom = crudExpose.getSearchValidatedFormData();
|
||||||
|
if (searchFrom.groupId) {
|
||||||
|
return searchFrom.groupId;
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
id: "siteMonitorCrud",
|
id: "siteMonitorCrud",
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
|
|
@ -100,6 +111,53 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
editRequest,
|
editRequest,
|
||||||
delRequest,
|
delRequest,
|
||||||
},
|
},
|
||||||
|
tabs: {
|
||||||
|
name: "groupId",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
buttons: {
|
||||||
|
export: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
export: {
|
||||||
|
dataFrom: "search",
|
||||||
|
columnFilter: (col: ColumnProps) => {
|
||||||
|
//列过滤器,返回true则导出该列
|
||||||
|
//例如: 只导出show=true的列
|
||||||
|
return col.show === true;
|
||||||
|
},
|
||||||
|
dataFormatter: (opts: DataFormatterContext) => {
|
||||||
|
//例如 格式化日期
|
||||||
|
const { row, originalRow, col, exportCol } = opts;
|
||||||
|
const key = col.key;
|
||||||
|
const element = originalRow[key];
|
||||||
|
if (key.includes("Time") && element) {
|
||||||
|
row[key] = dayjs(element).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col.width) {
|
||||||
|
exportCol.width = col.width / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col.key === "certInfo" && originalRow?.certProvider) {
|
||||||
|
row[key] = originalRow?.certProvider + " " + originalRow?.certDomains;
|
||||||
|
}
|
||||||
|
|
||||||
|
//参数说明
|
||||||
|
// DataFormatterContext = {row: any,originalRow: any, key: string, col: ColumnProps, exportCol:ExportColumn}
|
||||||
|
// row = 当前行数据
|
||||||
|
// originalRow = 当前行原始数据
|
||||||
|
// key = 当前列的key
|
||||||
|
// col = 当前列的配置
|
||||||
|
// exportCol = 当前列的导出配置
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagination: {
|
||||||
|
pageSizeOptions: ["10", "20", "50", "100", "200"],
|
||||||
|
},
|
||||||
settings: {
|
settings: {
|
||||||
plugins: {
|
plugins: {
|
||||||
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
//这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并
|
||||||
|
|
@ -158,7 +216,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await crudExpose.openAdd({});
|
const defaultGroupId = getDefaultGroupId();
|
||||||
|
await crudExpose.openAdd({
|
||||||
|
row: { groupId: defaultGroupId },
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
//导入按钮
|
//导入按钮
|
||||||
|
|
@ -167,7 +228,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
text: t("certd.monitor.bulkImport"),
|
text: t("certd.monitor.bulkImport"),
|
||||||
type: "primary",
|
type: "primary",
|
||||||
async click() {
|
async click() {
|
||||||
|
const defaultGroupId = getDefaultGroupId();
|
||||||
openSiteImportDialog({
|
openSiteImportDialog({
|
||||||
|
defaultGroupId,
|
||||||
afterSubmit() {
|
afterSubmit() {
|
||||||
crudExpose.doRefresh();
|
crudExpose.doRefresh();
|
||||||
},
|
},
|
||||||
|
|
@ -219,10 +282,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tabs: {
|
// tabs: {
|
||||||
name: "disabled",
|
// name: "disabled",
|
||||||
show: true,
|
// show: true,
|
||||||
},
|
// },
|
||||||
columns: {
|
columns: {
|
||||||
id: {
|
id: {
|
||||||
title: "ID",
|
title: "ID",
|
||||||
|
|
@ -403,6 +466,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
column: {
|
column: {
|
||||||
sorter: true,
|
sorter: true,
|
||||||
width: 155,
|
width: 155,
|
||||||
|
show: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certExpiresTime: {
|
certExpiresTime: {
|
||||||
|
|
@ -451,6 +515,46 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
groupId: {
|
||||||
|
title: t("certd.fields.group"),
|
||||||
|
type: "dict-select",
|
||||||
|
search: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
dict: groupDictRef,
|
||||||
|
form: {
|
||||||
|
component: {
|
||||||
|
name: GroupSelector,
|
||||||
|
vModel: "modelValue",
|
||||||
|
type: GroupTypeSite,
|
||||||
|
onRefresh() {
|
||||||
|
groupDictRef.reloadDict();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
column: {
|
||||||
|
width: 130,
|
||||||
|
align: "center",
|
||||||
|
component: {
|
||||||
|
color: "auto",
|
||||||
|
},
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
remark: {
|
||||||
|
title: t("certd.monitor.remark"),
|
||||||
|
search: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
type: "text",
|
||||||
|
column: {
|
||||||
|
width: 200,
|
||||||
|
sorter: true,
|
||||||
|
cellRender({ value }) {
|
||||||
|
return <a-tooltip title={value}>{value}</a-tooltip>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
lastCheckTime: {
|
lastCheckTime: {
|
||||||
title: t("certd.monitor.lastCheckTime"),
|
title: t("certd.monitor.lastCheckTime"),
|
||||||
search: {
|
search: {
|
||||||
|
|
@ -618,6 +722,21 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
error: {
|
||||||
|
title: t("certd.monitor.error"),
|
||||||
|
search: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
type: "text",
|
||||||
|
form: { show: false },
|
||||||
|
column: {
|
||||||
|
width: 200,
|
||||||
|
sorter: true,
|
||||||
|
cellRender({ value }) {
|
||||||
|
return <a-tooltip title={value}>{value}</a-tooltip>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||||
import { siteInfoApi } from "./api";
|
import { siteInfoApi } from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
|
import GroupSelector from "../../basic/group/group-selector.vue";
|
||||||
export function useSiteImport() {
|
export function useSiteImport() {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openCrudFormDialog } = useFormWrapper();
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
|
|
||||||
async function openSiteImportDialog(opts: { afterSubmit: any }) {
|
async function openSiteImportDialog(opts: { afterSubmit: any; defaultGroupId?: number }) {
|
||||||
const { afterSubmit } = opts;
|
const { afterSubmit, defaultGroupId } = opts;
|
||||||
await openCrudFormDialog<any>({
|
await openCrudFormDialog<any>({
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
columns: {
|
columns: {
|
||||||
|
|
@ -26,6 +26,21 @@ export function useSiteImport() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
groupId: {
|
||||||
|
type: "select",
|
||||||
|
title: t("certd.fields.group"),
|
||||||
|
form: {
|
||||||
|
value: defaultGroupId,
|
||||||
|
component: {
|
||||||
|
name: GroupSelector,
|
||||||
|
vModel: "modelValue",
|
||||||
|
type: "site",
|
||||||
|
},
|
||||||
|
col: {
|
||||||
|
span: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
form: {
|
form: {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
ALTER TABLE cd_site_info ADD COLUMN "remark" varchar(512);
|
||||||
|
|
||||||
|
CREATE TABLE "cd_group"
|
||||||
|
(
|
||||||
|
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
|
"user_id" integer NOT NULL,
|
||||||
|
"name" varchar(100) NOT NULL,
|
||||||
|
"icon" varchar(100),
|
||||||
|
"favorite" boolean NOT NULL DEFAULT (false),
|
||||||
|
"type" varchar(512),
|
||||||
|
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||||
|
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||||
|
);
|
||||||
|
|
||||||
|
--分组字段
|
||||||
|
ALTER TABLE cd_site_info ADD COLUMN "group_id" integer;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||||
|
import { Constants, CrudController } from '@certd/lib-server';
|
||||||
|
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||||
|
import { GroupService } from '../../../modules/basic/service/group-service.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通知
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
@Controller('/api/basic/group')
|
||||||
|
export class GroupController extends CrudController<GroupService> {
|
||||||
|
@Inject()
|
||||||
|
service: GroupService;
|
||||||
|
@Inject()
|
||||||
|
authService: AuthService;
|
||||||
|
|
||||||
|
getService(): GroupService {
|
||||||
|
return this.service;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/page', { summary: Constants.per.authOnly })
|
||||||
|
async page(@Body(ALL) body: any) {
|
||||||
|
body.query = body.query ?? {};
|
||||||
|
delete body.query.userId;
|
||||||
|
const buildQuery = qb => {
|
||||||
|
qb.andWhere('user_id = :userId', { userId: this.getUserId() });
|
||||||
|
};
|
||||||
|
const res = await this.service.page({
|
||||||
|
query: body.query,
|
||||||
|
page: body.page,
|
||||||
|
sort: body.sort,
|
||||||
|
buildQuery,
|
||||||
|
});
|
||||||
|
return this.ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/list', { summary: Constants.per.authOnly })
|
||||||
|
async list(@Body(ALL) body: any) {
|
||||||
|
body.query = body.query ?? {};
|
||||||
|
body.query.userId = this.getUserId();
|
||||||
|
return await super.list(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/add', { summary: Constants.per.authOnly })
|
||||||
|
async add(@Body(ALL) bean: any) {
|
||||||
|
bean.userId = this.getUserId();
|
||||||
|
return await super.add(bean);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/update', { summary: Constants.per.authOnly })
|
||||||
|
async update(@Body(ALL) bean) {
|
||||||
|
await this.service.checkUserId(bean.id, this.getUserId());
|
||||||
|
delete bean.userId;
|
||||||
|
return await super.update(bean);
|
||||||
|
}
|
||||||
|
@Post('/info', { summary: Constants.per.authOnly })
|
||||||
|
async info(@Query('id') id: number) {
|
||||||
|
await this.service.checkUserId(id, this.getUserId());
|
||||||
|
return await super.info(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/delete', { summary: Constants.per.authOnly })
|
||||||
|
async delete(@Query('id') id: number) {
|
||||||
|
await this.service.checkUserId(id, this.getUserId());
|
||||||
|
return await super.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/all', { summary: Constants.per.authOnly })
|
||||||
|
async all(@Query('type') type: string) {
|
||||||
|
const list: any = await this.service.find({
|
||||||
|
where: {
|
||||||
|
userId: this.getUserId(),
|
||||||
|
type,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return this.ok(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
|
export const GROUP_TYPE_SITE = 'site';
|
||||||
|
|
||||||
|
@Entity('cd_group')
|
||||||
|
export class GroupEntity {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({ name: 'user_id', comment: '用户id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'name', comment: '分组名称' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'icon', comment: '图标' })
|
||||||
|
icon: string;
|
||||||
|
|
||||||
|
@Column({ name: 'favorite', comment: '收藏' })
|
||||||
|
favorite: boolean;
|
||||||
|
|
||||||
|
@Column({ name: 'type', comment: '类型', length: 512 })
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'create_time',
|
||||||
|
comment: '创建时间',
|
||||||
|
default: () => 'CURRENT_TIMESTAMP',
|
||||||
|
})
|
||||||
|
createTime: Date;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'update_time',
|
||||||
|
comment: '修改时间',
|
||||||
|
default: () => 'CURRENT_TIMESTAMP',
|
||||||
|
})
|
||||||
|
updateTime: Date;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||||
|
import { BaseService } from '@certd/lib-server';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { merge } from 'lodash-es';
|
||||||
|
import { GroupEntity } from '../entity/group.js';
|
||||||
|
|
||||||
|
@Provide()
|
||||||
|
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||||
|
export class GroupService extends BaseService<GroupEntity> {
|
||||||
|
@InjectEntityModel(GroupEntity)
|
||||||
|
repository: Repository<GroupEntity>;
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
getRepository() {
|
||||||
|
return this.repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(bean: any) {
|
||||||
|
if (!bean.type) {
|
||||||
|
throw new Error('type is required');
|
||||||
|
}
|
||||||
|
bean = merge(
|
||||||
|
{
|
||||||
|
favorite: false,
|
||||||
|
},
|
||||||
|
bean
|
||||||
|
);
|
||||||
|
return await this.repository.save(bean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,6 +56,12 @@ export class SiteInfoEntity {
|
||||||
@Column({ name: 'disabled', comment: '禁用启用' })
|
@Column({ name: 'disabled', comment: '禁用启用' })
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
|
||||||
|
@Column({ name: 'remark', comment: '备注', length: 512 })
|
||||||
|
remark: string;
|
||||||
|
|
||||||
|
@Column({ name: 'group_id', comment: '分组id' })
|
||||||
|
groupId: number;
|
||||||
|
|
||||||
@Column({ name: 'create_time', comment: '创建时间', default: () => 'CURRENT_TIMESTAMP' })
|
@Column({ name: 'create_time', comment: '创建时间', default: () => 'CURRENT_TIMESTAMP' })
|
||||||
createTime: Date;
|
createTime: Date;
|
||||||
@Column({ name: 'update_time', comment: '修改时间', default: () => 'CURRENT_TIMESTAMP' })
|
@Column({ name: 'update_time', comment: '修改时间', default: () => 'CURRENT_TIMESTAMP' })
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue