Pre Merge pull request !156 from xingyu/dev
commit
42df728de0
|
@ -2,6 +2,8 @@ import type { VbenFormSchema } from '#/adapter/form';
|
|||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { SystemAreaApi } from '#/api/system/area';
|
||||
|
||||
import { z } from '#/adapter/form';
|
||||
|
||||
/** 查询 IP 的表单 */
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
|
@ -12,7 +14,7 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||
componentProps: {
|
||||
placeholder: '请输入 IP 地址',
|
||||
},
|
||||
rules: 'required',
|
||||
rules: z.string().ip({ message: '请输入正确的 IP 地址' }),
|
||||
},
|
||||
{
|
||||
fieldName: 'result',
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { DescriptionItemSchema } from '#/components/description';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE, getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
|
@ -84,3 +90,50 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 详情页的字段 */
|
||||
export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
label: '日志编号',
|
||||
},
|
||||
{
|
||||
field: 'logType',
|
||||
label: '操作类型',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_LOGIN_TYPE,
|
||||
value: data?.logType,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'username',
|
||||
label: '用户名称',
|
||||
},
|
||||
{
|
||||
field: 'userIp',
|
||||
label: '登录地址',
|
||||
},
|
||||
{
|
||||
field: 'userAgent',
|
||||
label: '浏览器',
|
||||
},
|
||||
{
|
||||
field: 'result',
|
||||
label: '登录结果',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_LOGIN_RESULT,
|
||||
value: data?.result,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
label: '登录日期',
|
||||
content: (data) => formatDateTime(data?.createTime || '') as string,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,15 +4,22 @@ import type { SystemLoginLogApi } from '#/api/system/login-log';
|
|||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { useDescription } from '#/components/description';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE } from '#/utils';
|
||||
import { useDetailSchema } from '../data';
|
||||
|
||||
const formData = ref<SystemLoginLogApi.LoginLog>();
|
||||
|
||||
const [Descriptions] = useDescription({
|
||||
componentProps: {
|
||||
bordered: true,
|
||||
column: 1,
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
|
@ -41,40 +48,6 @@ const [Modal, modalApi] = useVbenModal({
|
|||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
>
|
||||
<Descriptions
|
||||
bordered
|
||||
:column="1"
|
||||
size="middle"
|
||||
class="mx-4"
|
||||
:label-style="{ width: '110px' }"
|
||||
>
|
||||
<Descriptions.Item label="日志编号">
|
||||
{{ formData?.id }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作类型">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_LOGIN_TYPE"
|
||||
:value="formData?.logType"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="用户名称">
|
||||
{{ formData?.username }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="登录地址">
|
||||
{{ formData?.userIp }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="浏览器">
|
||||
{{ formData?.userAgent }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="登录结果">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_LOGIN_RESULT"
|
||||
:value="formData?.result"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="登录日期">
|
||||
{{ formatDateTime(formData?.createTime || '') }}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Descriptions :data="formData" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -31,7 +31,7 @@ const [Form, formApi] = useVbenForm({
|
|||
class: 'w-full',
|
||||
},
|
||||
formItemClass: 'col-span-2',
|
||||
labelWidth: 80,
|
||||
labelWidth: 140,
|
||||
},
|
||||
layout: 'horizontal',
|
||||
schema: useFormSchema(),
|
||||
|
@ -83,7 +83,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="getTitle">
|
||||
<Modal :title="getTitle" class="w-1/3">
|
||||
<Form class="mx-4" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { DescriptionItemSchema } from '#/components/description';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { getSimpleMailAccountList } from '#/api/system/mail/account';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
|
@ -117,3 +123,79 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 详情页的字段 */
|
||||
export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
label: '编号',
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
label: '创建时间',
|
||||
content: (data) => formatDateTime(data?.createTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'toMail',
|
||||
label: '收件邮箱',
|
||||
},
|
||||
{
|
||||
field: 'fromMail',
|
||||
label: '发送邮箱',
|
||||
},
|
||||
{
|
||||
field: 'userId',
|
||||
label: '用户编号',
|
||||
},
|
||||
{
|
||||
field: 'userType',
|
||||
label: '用户类型',
|
||||
},
|
||||
{
|
||||
field: 'templateId',
|
||||
label: '模板编号',
|
||||
},
|
||||
{
|
||||
field: 'templateCode',
|
||||
label: '模板编码',
|
||||
},
|
||||
{
|
||||
field: 'templateTitle',
|
||||
label: '邮件标题',
|
||||
},
|
||||
{
|
||||
field: 'templateContent',
|
||||
label: '邮件内容',
|
||||
content: (data) => {
|
||||
// 渲染HTML内容
|
||||
return h('div', {
|
||||
innerHTML: data?.templateContent || '',
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'sendStatus',
|
||||
label: '发送状态',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_MAIL_SEND_STATUS,
|
||||
value: data?.sendStatus,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'sendTime',
|
||||
label: '发送时间',
|
||||
content: (data) => formatDateTime(data?.sendTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'sendMessageId',
|
||||
label: '发送消息编号',
|
||||
},
|
||||
{
|
||||
field: 'sendException',
|
||||
label: '发送异常',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,15 +4,22 @@ import type { SystemMailLogApi } from '#/api/system/mail/log';
|
|||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { useDescription } from '#/components/description';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE } from '#/utils';
|
||||
import { useDetailSchema } from '../data';
|
||||
|
||||
const formData = ref<SystemMailLogApi.MailLog>();
|
||||
|
||||
const [Descriptions] = useDescription({
|
||||
componentProps: {
|
||||
bordered: true,
|
||||
column: 2,
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
|
@ -41,53 +48,6 @@ const [Modal, modalApi] = useVbenModal({
|
|||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
>
|
||||
<div class="p-4">
|
||||
<Descriptions :column="2" bordered :label-style="{ width: '140px' }">
|
||||
<Descriptions.Item label="编号">{{ formData?.id }}</Descriptions.Item>
|
||||
<Descriptions.Item label="创建时间">
|
||||
{{ formatDateTime(formData?.createTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="收件邮箱">
|
||||
{{ formData?.toMail }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送邮箱">
|
||||
{{ formData?.fromMail }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="用户编号">
|
||||
{{ formData?.userId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="用户类型">
|
||||
{{ formData?.userType }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模板编号">
|
||||
{{ formData?.templateId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模板编码">
|
||||
{{ formData?.templateCode }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="邮件标题" :span="2">
|
||||
{{ formData?.templateTitle }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="邮件内容" :span="2">
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-html="formData?.templateContent"></div>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送状态">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_MAIL_SEND_STATUS"
|
||||
:value="formData?.sendStatus"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送时间">
|
||||
{{ formatDateTime(formData?.sendTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送消息编号">
|
||||
{{ formData?.sendMessageId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送异常">
|
||||
{{ formData?.sendException }}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
<Descriptions :data="formData" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -83,7 +83,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="getTitle">
|
||||
<Modal :title="getTitle" class="w-1/3">
|
||||
<Form class="mx-4" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -87,7 +87,7 @@ async function handleDeleteBatch() {
|
|||
/** 推送公告 */
|
||||
async function handlePush(row: SystemNoticeApi.Notice) {
|
||||
const hideLoading = message.loading({
|
||||
content: $t('ui.actionMessage.processing', ['推送']),
|
||||
content: '正在推送中',
|
||||
key: 'action_process_msg',
|
||||
});
|
||||
try {
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { DescriptionItemSchema } from '#/components/description';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
|
@ -135,3 +141,84 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 详情页的字段 */
|
||||
export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
label: '编号',
|
||||
},
|
||||
{
|
||||
field: 'userType',
|
||||
label: '用户类型',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.USER_TYPE,
|
||||
value: data?.userType,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'userId',
|
||||
label: '用户编号',
|
||||
},
|
||||
{
|
||||
field: 'templateId',
|
||||
label: '模版编号',
|
||||
},
|
||||
{
|
||||
field: 'templateCode',
|
||||
label: '模板编码',
|
||||
},
|
||||
{
|
||||
field: 'templateNickname',
|
||||
label: '发送人名称',
|
||||
},
|
||||
{
|
||||
field: 'templateContent',
|
||||
label: '模版内容',
|
||||
},
|
||||
{
|
||||
field: 'templateParams',
|
||||
label: '模版参数',
|
||||
content: (data) => {
|
||||
try {
|
||||
return JSON.stringify(data?.templateParams);
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'templateType',
|
||||
label: '模版类型',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE,
|
||||
value: data?.templateType,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'readStatus',
|
||||
label: '是否已读',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.INFRA_BOOLEAN_STRING,
|
||||
value: data?.readStatus,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'readTime',
|
||||
label: '阅读时间',
|
||||
content: (data) => formatDateTime(data?.readTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
label: '创建时间',
|
||||
content: (data) => formatDateTime(data?.createTime || '') as string,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,15 +4,22 @@ import type { SystemNotifyMessageApi } from '#/api/system/notify/message';
|
|||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { useDescription } from '#/components/description';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE } from '#/utils';
|
||||
import { useDetailSchema } from '../data';
|
||||
|
||||
const formData = ref<SystemNotifyMessageApi.NotifyMessage>();
|
||||
|
||||
const [Descriptions] = useDescription({
|
||||
componentProps: {
|
||||
bordered: true,
|
||||
column: 1,
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
|
@ -37,51 +44,10 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<template>
|
||||
<Modal
|
||||
title="站内信详情"
|
||||
class="w-1/2"
|
||||
class="w-1/3"
|
||||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
>
|
||||
<Descriptions bordered :column="1" size="middle" class="mx-4">
|
||||
<Descriptions.Item label="编号">{{ formData?.id }}</Descriptions.Item>
|
||||
<Descriptions.Item label="用户类型">
|
||||
<DictTag :type="DICT_TYPE.USER_TYPE" :value="formData?.userType" />
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="用户编号">
|
||||
{{ formData?.userId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模版编号">
|
||||
{{ formData?.templateId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模板编码">
|
||||
{{ formData?.templateCode }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送人名称">
|
||||
{{ formData?.templateNickname }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模版内容">
|
||||
{{ formData?.templateContent }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模版参数">
|
||||
{{ formData?.templateParams }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模版类型">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE"
|
||||
:value="formData?.templateType"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="是否已读">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.INFRA_BOOLEAN_STRING"
|
||||
:value="formData?.readStatus"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="阅读时间">
|
||||
{{ formatDateTime(formData?.readTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="创建时间">
|
||||
{{ formatDateTime(formData?.createTime || '') }}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Descriptions :data="formData" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -11,7 +11,6 @@ const [Description, descApi] = useDescription({
|
|||
componentProps: {
|
||||
bordered: true,
|
||||
column: 1,
|
||||
size: 'middle',
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
|
@ -40,6 +39,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
<template>
|
||||
<Modal
|
||||
title="消息详情"
|
||||
class="w-1/3"
|
||||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
>
|
||||
|
|
|
@ -116,7 +116,17 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||
componentProps: {
|
||||
placeholder: '请输入自动授权范围',
|
||||
mode: 'multiple',
|
||||
// TODO @芋艿:根据权限,自动授权范围
|
||||
},
|
||||
dependencies: {
|
||||
triggerFields: ['scopes'],
|
||||
componentProps: (values) => ({
|
||||
options: values.scopes
|
||||
? values.scopes.map((scope: string) => ({
|
||||
label: scope,
|
||||
value: scope,
|
||||
}))
|
||||
: [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -30,9 +30,10 @@ const [Form, formApi] = useVbenForm({
|
|||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
formItemClass: 'col-span-2',
|
||||
labelWidth: 140,
|
||||
},
|
||||
// 一共2列
|
||||
wrapperClass: 'grid-cols-2',
|
||||
layout: 'horizontal',
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
|
@ -83,7 +84,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-2/5" :title="getTitle">
|
||||
<Modal class="w-1/2" :title="getTitle">
|
||||
<Form class="mx-4" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -88,7 +88,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
icon: ACTION_ICON.DELETE,
|
||||
auth: ['system:oauth2-token:delete'],
|
||||
popConfirm: {
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.name]),
|
||||
title: `确定要强退令牌吗?`,
|
||||
confirm: handleDelete.bind(null, row),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { DescriptionItemSchema } from '#/components/description';
|
||||
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { getSimpleUserList } from '#/api/system/user';
|
||||
import { getRangePickerDefaultProps } from '#/utils';
|
||||
|
@ -113,3 +116,68 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 详情页的字段 */
|
||||
export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
label: '日志编号',
|
||||
},
|
||||
{
|
||||
field: 'traceId',
|
||||
label: '链路追踪',
|
||||
content: (data) => data?.traceId || '',
|
||||
},
|
||||
{
|
||||
field: 'userId',
|
||||
label: '操作人编号',
|
||||
},
|
||||
{
|
||||
field: 'userName',
|
||||
label: '操作人名字',
|
||||
},
|
||||
{
|
||||
field: 'userIp',
|
||||
label: '操作人IP',
|
||||
},
|
||||
{
|
||||
field: 'userAgent',
|
||||
label: '操作人UA',
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
label: '操作模块',
|
||||
},
|
||||
{
|
||||
field: 'subType',
|
||||
label: '操作名',
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作内容',
|
||||
},
|
||||
{
|
||||
field: 'extra',
|
||||
label: '操作拓展参数',
|
||||
},
|
||||
{
|
||||
field: 'requestUrl',
|
||||
label: '请求URL',
|
||||
content: (data) => {
|
||||
const method = data?.requestMethod || '';
|
||||
const url = data?.requestUrl || '';
|
||||
return `${method} ${url}`.trim();
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
label: '操作时间',
|
||||
content: (data) => formatDateTime(data?.createTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'bizId',
|
||||
label: '业务编号',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,12 +4,22 @@ import type { SystemOperateLogApi } from '#/api/system/operate-log';
|
|||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { useDescription } from '#/components/description';
|
||||
|
||||
import { useDetailSchema } from '../data';
|
||||
|
||||
const formData = ref<SystemOperateLogApi.OperateLog>();
|
||||
|
||||
const [Descriptions] = useDescription({
|
||||
componentProps: {
|
||||
bordered: true,
|
||||
column: 1,
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
|
@ -38,52 +48,6 @@ const [Modal, modalApi] = useVbenModal({
|
|||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
>
|
||||
<Descriptions
|
||||
bordered
|
||||
:column="1"
|
||||
size="middle"
|
||||
class="mx-4"
|
||||
:label-style="{ width: '110px' }"
|
||||
>
|
||||
<Descriptions.Item label="日志编号">
|
||||
{{ formData?.id }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="链路追踪" v-if="formData?.traceId">
|
||||
{{ formData?.traceId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作人编号">
|
||||
{{ formData?.userId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作人名字">
|
||||
{{ formData?.userName }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作人IP">
|
||||
{{ formData?.userIp }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作人UA">
|
||||
{{ formData?.userAgent }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作模块">
|
||||
{{ formData?.type }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作名">
|
||||
{{ formData?.subType }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作内容">
|
||||
{{ formData?.action }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item v-if="formData?.extra" label="操作拓展参数">
|
||||
{{ formData?.extra }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="请求URL">
|
||||
{{ formData?.requestMethod }} {{ formData?.requestUrl }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="操作时间">
|
||||
{{ formatDateTime(formData?.createTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="业务编号">
|
||||
{{ formData?.bizId }}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Descriptions :data="formData" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { DescriptionItemSchema } from '#/components/description';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { getSimpleSmsChannelList } from '#/api/system/sms/channel';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
|
@ -153,3 +159,94 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 详情页的字段 */
|
||||
export function useDetailSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'createTime',
|
||||
label: '创建时间',
|
||||
content: (data) => formatDateTime(data?.createTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
label: '手机号',
|
||||
},
|
||||
{
|
||||
field: 'channelCode',
|
||||
label: '短信渠道',
|
||||
},
|
||||
{
|
||||
field: 'templateId',
|
||||
label: '模板编号',
|
||||
},
|
||||
{
|
||||
field: 'templateType',
|
||||
label: '模板类型',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE,
|
||||
value: data?.templateType,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'templateContent',
|
||||
label: '短信内容',
|
||||
},
|
||||
{
|
||||
field: 'sendStatus',
|
||||
label: '发送状态',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_SMS_SEND_STATUS,
|
||||
value: data?.sendStatus,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'sendTime',
|
||||
label: '发送时间',
|
||||
content: (data) => formatDateTime(data?.sendTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'apiSendCode',
|
||||
label: 'API 发送编码',
|
||||
},
|
||||
{
|
||||
field: 'apiSendMsg',
|
||||
label: 'API 发送消息',
|
||||
},
|
||||
{
|
||||
field: 'receiveStatus',
|
||||
label: '接收状态',
|
||||
content: (data) => {
|
||||
return h(DictTag, {
|
||||
type: DICT_TYPE.SYSTEM_SMS_RECEIVE_STATUS,
|
||||
value: data?.receiveStatus,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'receiveTime',
|
||||
label: '接收时间',
|
||||
content: (data) => formatDateTime(data?.receiveTime || '') as string,
|
||||
},
|
||||
{
|
||||
field: 'apiReceiveCode',
|
||||
label: 'API 接收编码',
|
||||
},
|
||||
{
|
||||
field: 'apiReceiveMsg',
|
||||
label: 'API 接收消息',
|
||||
},
|
||||
{
|
||||
field: 'apiRequestId',
|
||||
label: 'API 请求 ID',
|
||||
},
|
||||
{
|
||||
field: 'apiSerialNo',
|
||||
label: 'API 序列号',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,15 +4,22 @@ import type { SystemSmsLogApi } from '#/api/system/sms/log';
|
|||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { formatDateTime } from '@vben/utils';
|
||||
|
||||
import { Descriptions } from 'ant-design-vue';
|
||||
import { useDescription } from '#/components/description';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE } from '#/utils';
|
||||
import { useDetailSchema } from '../data';
|
||||
|
||||
const formData = ref<SystemSmsLogApi.SmsLog>();
|
||||
|
||||
const [Descriptions] = useDescription({
|
||||
componentProps: {
|
||||
bordered: true,
|
||||
column: 2,
|
||||
class: 'mx-4',
|
||||
},
|
||||
schema: useDetailSchema(),
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
|
@ -41,70 +48,6 @@ const [Modal, modalApi] = useVbenModal({
|
|||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
>
|
||||
<Descriptions
|
||||
bordered
|
||||
:column="2"
|
||||
size="middle"
|
||||
class="mx-4"
|
||||
:label-style="{ width: '140px' }"
|
||||
>
|
||||
<Descriptions.Item label="创建时间">
|
||||
{{ formatDateTime(formData?.createTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">
|
||||
{{ formData?.mobile }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="短信渠道">
|
||||
{{ formData?.channelCode }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模板编号">
|
||||
{{ formData?.templateId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="模板类型">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_SMS_TEMPLATE_TYPE"
|
||||
:value="formData?.templateType"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="短信内容">
|
||||
{{ formData?.templateContent }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送状态">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_SMS_SEND_STATUS"
|
||||
:value="formData?.sendStatus"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="发送时间">
|
||||
{{ formatDateTime(formData?.sendTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="API 发送编码">
|
||||
{{ formData?.apiSendCode }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="API 发送消息">
|
||||
{{ formData?.apiSendMsg }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="接收状态">
|
||||
<DictTag
|
||||
:type="DICT_TYPE.SYSTEM_SMS_RECEIVE_STATUS"
|
||||
:value="formData?.receiveStatus"
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="接收时间">
|
||||
{{ formatDateTime(formData?.receiveTime || '') }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="API 接收编码">
|
||||
{{ formData?.apiReceiveCode }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="API 接收消息" :span="2">
|
||||
{{ formData?.apiReceiveMsg }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="API 请求 ID">
|
||||
{{ formData?.apiRequestId }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="API 序列号">
|
||||
{{ formData?.apiSerialNo }}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Descriptions :data="formData" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -108,6 +108,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
},
|
||||
gridOptions: {
|
||||
columns: useGridColumns(getPackageName),
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
|
|
|
@ -26,9 +26,9 @@ const [Form, formApi] = useVbenForm({
|
|||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
formItemClass: 'col-span-2',
|
||||
labelWidth: 80,
|
||||
},
|
||||
// 一共2列
|
||||
wrapperClass: 'grid-cols-2',
|
||||
layout: 'horizontal',
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
|
@ -75,7 +75,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="getTitle">
|
||||
<Modal :title="getTitle" class="w-1/3">
|
||||
<Form class="mx-4" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -8,7 +8,7 @@ import { ref } from 'vue';
|
|||
import { confirm, DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||
import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { Card, message } from 'ant-design-vue';
|
||||
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
|
@ -215,9 +215,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
|
||||
<div class="flex h-full w-full">
|
||||
<!-- 左侧部门树 -->
|
||||
<div class="h-full w-1/6 pr-4">
|
||||
<Card class="mr-4 h-full w-1/6">
|
||||
<DeptTree @select="handleDeptSelect" />
|
||||
</div>
|
||||
</Card>
|
||||
<!-- 右侧用户列表 -->
|
||||
<div class="w-5/6">
|
||||
<Grid table-title="用户列表">
|
||||
|
|
|
@ -26,9 +26,9 @@ const [Form, formApi] = useVbenForm({
|
|||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
formItemClass: 'col-span-2',
|
||||
labelWidth: 80,
|
||||
},
|
||||
// 一共2列
|
||||
wrapperClass: 'grid-cols-2',
|
||||
layout: 'horizontal',
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
|
@ -76,7 +76,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="getTitle">
|
||||
<Modal :title="getTitle" class="w-1/3">
|
||||
<Form class="mx-4" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<script lang="ts" setup>
|
||||
import type { DocAlertProps } from './types';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { isDocAlertEnable } from '@vben/hooks';
|
||||
|
||||
import { VbenIcon } from '@vben-core/shadcn-ui';
|
||||
import { cn, openWindow } from '@vben-core/shared/utils';
|
||||
import { openWindow } from '@vben-core/shared/utils';
|
||||
|
||||
defineOptions({
|
||||
name: 'DocAlert',
|
||||
|
@ -12,28 +14,42 @@ defineOptions({
|
|||
|
||||
const props = defineProps<DocAlertProps>();
|
||||
|
||||
/** 控制组件显示状态 */
|
||||
const isVisible = ref(true);
|
||||
|
||||
function goToUrl() {
|
||||
openWindow(props.url);
|
||||
}
|
||||
|
||||
function close() {
|
||||
isVisible.value = false;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<!-- Alert Component -->
|
||||
<!-- TODO @xingyu:是不是左右边距 + 下,和搜索的对齐,会好看一丢丢的 -->
|
||||
<div
|
||||
role="alert"
|
||||
v-if="isDocAlertEnable()"
|
||||
:class="
|
||||
cn(
|
||||
'border-primary bg-primary/10 relative m-1 flex w-full items-center gap-5 rounded-md border p-1',
|
||||
)
|
||||
"
|
||||
v-if="isDocAlertEnable() && isVisible"
|
||||
class="border-primary bg-primary/10 relative my-2 flex h-8 w-full items-center gap-2 rounded-md border p-2"
|
||||
>
|
||||
<span class="grid shrink-0 place-items-center">
|
||||
<VbenIcon icon="mdi:information-outline" class="text-primary size-5" />
|
||||
</span>
|
||||
<div class="text-primary w-full font-sans text-sm leading-none">
|
||||
【{{ title }}】文档地址:
|
||||
<a class="hover:text-primary" @click="goToUrl">{{ url }}</a>
|
||||
<div class="text-primary min-w-0 flex-1 font-sans text-sm leading-none">
|
||||
<span class="inline-block">【{{ title }}】</span>
|
||||
<a
|
||||
class="hover:text-success cursor-pointer break-all"
|
||||
@click="goToUrl"
|
||||
:title="url"
|
||||
>
|
||||
文档地址:{{ url }}
|
||||
</a>
|
||||
</div>
|
||||
<span class="grid shrink-0 cursor-pointer place-items-center">
|
||||
<VbenIcon
|
||||
icon="mdi:close"
|
||||
class="text-primary size-5 hover:text-red-500"
|
||||
@click="close"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -63,7 +63,7 @@ onMounted(() => {
|
|||
ref="docRef"
|
||||
:class="
|
||||
cn(
|
||||
'bg-card border-border relative flex items-start rounded-md border-b p-1',
|
||||
'bg-card border-border relative mx-4 flex items-start rounded-md border-b',
|
||||
)
|
||||
"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue