Merge remote-tracking branch 'origin/main'
This commit is contained in:
213
src/views/manage/log/index.vue
Normal file
213
src/views/manage/log/index.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<script setup lang="tsx">
|
||||
import { Button, Popconfirm, Tag } from 'ant-design-vue';
|
||||
import type { Key } from 'ant-design-vue/es/_util/type';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { SimpleScrollbar } from '~/packages/materials/src';
|
||||
import logSearch from './modules/log-search.vue';
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
const wrapperEl = shallowRef<HTMLElement | null>(null);
|
||||
const { height: wrapperElHeight } = useElementSize(wrapperEl);
|
||||
|
||||
const scrollConfig = computed(() => {
|
||||
return {
|
||||
y: wrapperElHeight.value - 72,
|
||||
x: 1000
|
||||
};
|
||||
});
|
||||
|
||||
const { columns, columnChecks, data, loading, getData, mobilePagination, searchParams, resetSearchParams } = useTable({
|
||||
apiFn: doGetlogList,
|
||||
apiParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
status: undefined,
|
||||
},
|
||||
rowKey: 'operId',
|
||||
columns: () => [
|
||||
{
|
||||
key: 'operId',
|
||||
dataIndex: 'operId',
|
||||
title: t('page.manage.log.logId'),
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
dataIndex: 'title',
|
||||
title: t('page.manage.log.module'),
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'operatorType',
|
||||
dataIndex: 'operatorType',
|
||||
title: t('page.manage.log.operType'),
|
||||
align: 'center',
|
||||
customRender: ({ record }: any) => {
|
||||
if (record.operatorType === null) {
|
||||
return null;
|
||||
}
|
||||
const tagMap: any = {
|
||||
0: t('page.manage.log.other'),
|
||||
1: t('page.manage.log.backUser'),
|
||||
2: t('page.manage.log.phoneUser'),
|
||||
};
|
||||
const tagColor: any = {
|
||||
'0': 'pink',
|
||||
'1': 'warning',
|
||||
'2': 'blue',
|
||||
};
|
||||
return <Tag color={tagColor[record.operatorType]}> {tagMap[record.operatorType]} </Tag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'operName',
|
||||
dataIndex: 'operName',
|
||||
title: t('page.manage.log.operName'),
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'operIp',
|
||||
dataIndex: 'operIp',
|
||||
title: t('page.manage.log.operIp'),
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
align: 'center',
|
||||
customRender: ({ record }: any) => {
|
||||
if (record.status === null) {
|
||||
return null;
|
||||
}
|
||||
const tagMap: any = {
|
||||
0: t('common.normal'),
|
||||
1: t('common.abnormal'),
|
||||
};
|
||||
const tagColor: any = {
|
||||
'0': 'success',
|
||||
'1': 'error'
|
||||
};
|
||||
return <Tag color={tagColor[record.status]}> {tagMap[record.status]} </Tag>;
|
||||
},
|
||||
title: t('page.manage.log.operStatus'),
|
||||
},
|
||||
{
|
||||
key: 'operTime',
|
||||
dataIndex: 'operTime',
|
||||
align: 'center',
|
||||
title: t('page.manage.log.operTime'),
|
||||
},
|
||||
{
|
||||
key: 'costTime',
|
||||
dataIndex: 'costTime',
|
||||
align: 'center',
|
||||
title: t('page.manage.log.useTime'),
|
||||
customRender: ({ record }: any) => {
|
||||
if (!record.costTime) {
|
||||
return '0ms';
|
||||
}
|
||||
|
||||
return `${record.costTime} ${t('common.ms')}`;
|
||||
},
|
||||
|
||||
},
|
||||
// {
|
||||
// key: 'operate',
|
||||
// title: t('common.operate'),
|
||||
// align: 'center',
|
||||
// width: 200,
|
||||
// customRender: ({ record }: any) =>
|
||||
// !record.admin && (
|
||||
// <div class="flex justify-around gap-8px">
|
||||
// {isShowBtn('system:user:remove') && (
|
||||
// <Popconfirm onConfirm={() => handleDelete(record.operId)} title={t('common.confirmDelete')} >
|
||||
// <Button danger size="small" >
|
||||
// {t('common.delete')}
|
||||
// </Button>
|
||||
// </Popconfirm>
|
||||
// )}
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
]
|
||||
});
|
||||
|
||||
const {
|
||||
handleAdd,
|
||||
checkedRowKeys,
|
||||
onBatchDeleted,
|
||||
onDeleted
|
||||
// closeDrawer
|
||||
} = useTableOperate(data, { getData, idKey: 'operId' });
|
||||
const deptTreeData = ref<Api.Common.CommonTree>([]);
|
||||
|
||||
onMounted(() => {
|
||||
getUserDeptTree();
|
||||
});
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const { error } = await doDeleteLog(checkedRowKeys.value);
|
||||
if (!error) {
|
||||
onBatchDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(id: number) {
|
||||
const { error } = await doDeleteLog([id]);
|
||||
if (!error) {
|
||||
onDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleUserSelectChange(selectedRowKeys: Key[], selectedRows: any[]) {
|
||||
checkedRowKeys.value = selectedRowKeys as number[];
|
||||
}
|
||||
|
||||
function fnTest() {
|
||||
searchParams.value = {
|
||||
|
||||
};
|
||||
|
||||
resetSearchParams();
|
||||
// 使用 nextTick 确保视图更新后检查
|
||||
nextTick(() => {
|
||||
console.log('视图更新后:', { ...searchParams.value });
|
||||
console.log(searchParams.value);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async function getUserDeptTree() {
|
||||
const { error, data: tree } = await doGetUserDeptTree();
|
||||
if (!error) {
|
||||
deptTreeData.value = tree;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SimpleScrollbar>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<logSearch v-model:model="searchParams" :dept-tree-data="deptTreeData" @reset="fnTest" @search="getData" />
|
||||
<ACard :title="t('page.manage.user.title')" :bordered="false" :body-style="{ flex: 1, overflow: 'hidden' }"
|
||||
class="flex-col-stretch sm:flex-1-hidden card-wrapper">
|
||||
<template #extra>
|
||||
<TableHeaderOperation v-model:columns="columnChecks" :disabled-delete="checkedRowKeys.length === 0"
|
||||
:loading="loading" :show-delete="true" @add="handleAdd" @delete="handleBatchDelete" @refresh="getData"
|
||||
:not-show-add="true" />
|
||||
</template>
|
||||
<ATable ref="wrapperEl" row-key="operId" :columns="columns" :data-source="data" :loading="loading"
|
||||
:row-selection="{
|
||||
selectedRowKeys: checkedRowKeys,
|
||||
onChange: handleUserSelectChange,
|
||||
}" size="small" :pagination="mobilePagination" :scroll="scrollConfig" class="h-full" />
|
||||
|
||||
</ACard>
|
||||
</div>
|
||||
</SimpleScrollbar>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
127
src/views/manage/log/modules/log-search.vue
Normal file
127
src/views/manage/log/modules/log-search.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from '@/locales';
|
||||
import { enableStatusOptions } from '@/constants/business';
|
||||
import { SyncOutlined, SearchOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'logSearch'
|
||||
});
|
||||
|
||||
|
||||
|
||||
interface Emits {
|
||||
(e: 'reset'): void;
|
||||
(e: 'search'): void;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
deptTreeData: Api.Common.CommonTree;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const model = defineModel<any>('model', { required: true });
|
||||
|
||||
/**记录开始结束时间 */
|
||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||
|
||||
function reset() {
|
||||
// 重置表单
|
||||
//formRef.value?.resetFields();
|
||||
|
||||
// 重置日期选择器
|
||||
queryRangePicker.value = ['', ''];
|
||||
|
||||
// 确保 model 也被重置
|
||||
model.value = {};
|
||||
|
||||
// 使用 nextTick 确保视图更新后检查
|
||||
nextTick(() => {
|
||||
console.log('视图更新后:', { ...model.value });
|
||||
console.log(model);
|
||||
});
|
||||
emit('reset');
|
||||
}
|
||||
|
||||
function search() {
|
||||
if (!queryRangePicker.value) {
|
||||
queryRangePicker.value = ['', ''];
|
||||
}
|
||||
model.value.beginTime = queryRangePicker.value[0];
|
||||
model.value.endTime = queryRangePicker.value[1];
|
||||
emit('search');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ACard :title="$t('common.search')" :bordered="false" class="card-wrapper">
|
||||
<AForm :model="model" :label-width="80">
|
||||
<ARow :gutter="[16, 16]" wrap>
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem :label="$t('page.manage.log.operIp')" name="operIp" class="m-0">
|
||||
<AInput v-model:value="model.operIp" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem :label="$t('page.manage.log.module')" name="title" class="m-0">
|
||||
<AInput v-model:value="model.title" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem :label="$t('page.manage.user.status')" name="status" class="m-0">
|
||||
<ASelect v-model:value="model.status" :placeholder="$t('page.manage.user.form.status')" allow-clear>
|
||||
<ASelectOption v-for="option in enableStatusOptions" :key="option.value" :value="option.value">
|
||||
{{ $t(option.label) }}
|
||||
</ASelectOption>
|
||||
</ASelect>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem :label="$t('page.manage.log.operName')" name="operName" class="m-0">
|
||||
<AInput v-model:value="model.operName" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
|
||||
|
||||
|
||||
<a-col :lg="8" :md="12" :xs="24">
|
||||
<a-form-item :label="$t('page.manage.log.useTime')" name="queryRangePicker">
|
||||
<a-range-picker v-model:value="queryRangePicker" allow-clear bordered show-time
|
||||
value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></a-range-picker>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<ACol :lg="16" :md="12" :xs="24">
|
||||
<AFormItem class="m-0">
|
||||
<div class="w-full flex-y-center justify-end gap-8px">
|
||||
|
||||
<a-space :size="8">
|
||||
<a-button @click="reset">
|
||||
<template #icon>
|
||||
<SyncOutlined />
|
||||
</template>
|
||||
{{ $t('common.reset') }}
|
||||
</a-button>
|
||||
<AButton type="primary" ghost @click="search">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
{{ $t('common.search') }}
|
||||
</AButton>
|
||||
</a-space>
|
||||
|
||||
</div>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
</ARow>
|
||||
</AForm>
|
||||
</ACard>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -6,6 +6,8 @@ import { $t } from '@/locales';
|
||||
import { enableStatusRecord } from '@/constants/business';
|
||||
import RoleOperateDrawer from './modules/role-operate-drawer.vue';
|
||||
import RoleSearch from './modules/role-search.vue';
|
||||
import {useI18n} from "vue-i18n";
|
||||
const { t } = useI18n();
|
||||
|
||||
const wrapperEl = shallowRef<HTMLElement | null>(null);
|
||||
const { height: wrapperElHeight } = useElementSize(wrapperEl);
|
||||
@@ -45,17 +47,17 @@ const { columns, columnChecks, data, loading, getData, mobilePagination, searchP
|
||||
dataIndex: 'status',
|
||||
title: $t('page.manage.role.roleStatus'),
|
||||
align: 'center',
|
||||
customRender: ({ record }) => {
|
||||
customRender: ({ record }:any) => {
|
||||
if (record.status === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tagMap: Record<Api.Common.EnableStatus, string> = {
|
||||
const tagMap: any = {
|
||||
'0': 'success',
|
||||
'1': 'warning'
|
||||
};
|
||||
|
||||
const label = $t(enableStatusRecord[record.status]);
|
||||
const label = t(enableStatusRecord[record.status]);
|
||||
|
||||
return <Tag color={tagMap[record.status]}>{label}</Tag>;
|
||||
}
|
||||
@@ -76,7 +78,7 @@ const { columns, columnChecks, data, loading, getData, mobilePagination, searchP
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 200,
|
||||
customRender: ({ record }) =>
|
||||
customRender: ({ record }:any) =>
|
||||
!record.admin && (
|
||||
<div class="flex justify-around gap-8px">
|
||||
{isShowBtn('system:role:edit') && (
|
||||
|
||||
@@ -14,7 +14,7 @@ interface Props {
|
||||
/** the type of operation */
|
||||
operateType: AntDesign.TableOperateType;
|
||||
/** the edit row data */
|
||||
rowData?: Api.SystemManage.Role | null;
|
||||
rowData?: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
630
src/views/manage/task/index.vue
Normal file
630
src/views/manage/task/index.vue
Normal file
@@ -0,0 +1,630 @@
|
||||
<script setup lang="tsx">
|
||||
import { message, Tag } from 'ant-design-vue';
|
||||
import type { Key } from 'ant-design-vue/es/_util/type';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { SimpleScrollbar } from '~/packages/materials/src';
|
||||
import taskOperateDrawer from './modules/task-operate-drawer.vue';
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { SyncOutlined, SearchOutlined, ProfileOutlined, FormOutlined, DeleteOutlined, RocketOutlined, ContainerOutlined } from '@ant-design/icons-vue';
|
||||
import { enableStatusOptions } from '@/constants/business';
|
||||
|
||||
import { useAntdForm, useFormRules } from '@/hooks/common/form';
|
||||
const { defaultRequiredRule, formRules } = useFormRules();
|
||||
|
||||
const rules = {
|
||||
jonName: defaultRequiredRule,
|
||||
invokeTarget: defaultRequiredRule,
|
||||
cronExpression: defaultRequiredRule,
|
||||
};
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
const wrapperEl = shallowRef<HTMLElement | null>(null);
|
||||
const { height: wrapperElHeight } = useElementSize(wrapperEl);
|
||||
|
||||
|
||||
/**对话框对象信息状态 */
|
||||
let modalState: any = reactive({
|
||||
openByView: false,
|
||||
openByEdit: false,
|
||||
title: '任务',
|
||||
from: {
|
||||
jobId: undefined,
|
||||
jobName: '',
|
||||
invokeTarget: '',
|
||||
cronExpression: '',
|
||||
misfirePolicy: '3',
|
||||
concurrent: '0',
|
||||
jobGroup: 'DEFAULT',
|
||||
status: '0',
|
||||
saveLog: '0',
|
||||
targetParams: '',
|
||||
remark: '',
|
||||
},
|
||||
confirmLoading: false,
|
||||
openByCron: false,
|
||||
});
|
||||
|
||||
const scrollConfig = computed(() => {
|
||||
return {
|
||||
y: wrapperElHeight.value - 72,
|
||||
x: 1000
|
||||
};
|
||||
});
|
||||
|
||||
const { columns, columnChecks, data, loading, getData, mobilePagination, searchParams, resetSearchParams } = useTable({
|
||||
apiFn: doGetjobList,
|
||||
apiParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
rowKey: 'jobId',
|
||||
columns: () => [
|
||||
{
|
||||
key: 'jobId',
|
||||
dataIndex: 'jobId',
|
||||
title: t('page.manage.task.taskId'),
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'jobName',
|
||||
dataIndex: 'jobName',
|
||||
title: t('page.manage.task.taskName'),
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'jobGroup',
|
||||
dataIndex: 'jobGroup',
|
||||
title: t('page.manage.task.group'),
|
||||
align: 'center',
|
||||
// customRender: ({ record }: any) => {
|
||||
// if (record.operatorType === null) {
|
||||
// return null;
|
||||
// }
|
||||
// const tagMap: any = {
|
||||
// 0: t('page.manage.log.other'),
|
||||
// 1: t('page.manage.log.backUser'),
|
||||
// 2: t('page.manage.log.phoneUser'),
|
||||
// };
|
||||
// const tagColor: any = {
|
||||
// '0': 'pink',
|
||||
// '1': 'warning',
|
||||
// '2': 'blue',
|
||||
// };
|
||||
// return <Tag color={tagColor[record.operatorType]}>{tagMap[record.operatorType]}</Tag>;
|
||||
// }
|
||||
},
|
||||
{
|
||||
key: 'invokeTarget',
|
||||
dataIndex: 'invokeTarget',
|
||||
title: t('page.manage.task.invoke'),
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'cronExpression',
|
||||
dataIndex: 'cronExpression',
|
||||
title: t('page.manage.task.cron'),
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
align: 'center',
|
||||
customRender: ({ record }: any) => {
|
||||
if (record.status === null) {
|
||||
return null;
|
||||
}
|
||||
const tagMap: any = {
|
||||
'0': t('common.normal'),
|
||||
'1': t('common.abnormal'),
|
||||
};
|
||||
const tagColor: any = {
|
||||
'0': 'success',
|
||||
'1': 'error'
|
||||
};
|
||||
return <Tag color={tagColor[record.status]}>{tagMap[record.status]}</Tag>;
|
||||
},
|
||||
title: t('page.manage.log.operStatus'),
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: t('common.operate'),
|
||||
align: 'center',
|
||||
width: 200,
|
||||
// customRender: ({ record }: any) =>
|
||||
// !record.admin && (
|
||||
// <div class="flex justify-around gap-8px">
|
||||
// <Popconfirm onConfirm={() => handleDelete(record.operId)} title={t('common.confirmDelete')}>
|
||||
// <a-button danger size="small">
|
||||
// <template #icon>
|
||||
// <SyncOutlined />
|
||||
// </template>
|
||||
// </a-button>
|
||||
// </Popconfirm>
|
||||
// </div>
|
||||
// )
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const {
|
||||
drawerVisible,
|
||||
operateType,
|
||||
editingData,
|
||||
handleAdd,
|
||||
checkedRowKeys,
|
||||
onBatchDeleted,
|
||||
onDeleted
|
||||
// closeDrawer
|
||||
} = useTableOperate(data, { getData, idKey: 'jobId' });
|
||||
const deptTreeData = ref<Api.Common.CommonTree>([]);
|
||||
|
||||
onMounted(() => {
|
||||
});
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const { error } = await doDeleteLog(checkedRowKeys.value);
|
||||
if (!error) {
|
||||
onBatchDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(id: number) {
|
||||
const { error } = await doDeleteLog([id]);
|
||||
if (!error) {
|
||||
onDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleUserSelectChange(selectedRowKeys: Key[], selectedRows: any[]) {
|
||||
checkedRowKeys.value = selectedRowKeys as number[];
|
||||
}
|
||||
|
||||
function fnTest() {
|
||||
searchParams.value = {
|
||||
|
||||
};
|
||||
|
||||
resetSearchParams();
|
||||
// 使用 nextTick 确保视图更新后检查
|
||||
nextTick(() => {
|
||||
console.log(operateType)
|
||||
});
|
||||
}
|
||||
|
||||
async function fnRecordView(jobId: number) {
|
||||
// const { error, data } = await doGetjobInfo(jobId);
|
||||
// // if (!error) {
|
||||
// // onDeleted();
|
||||
// // }
|
||||
// console.log(data);
|
||||
operateType.value = 'view';
|
||||
|
||||
if (modalState.confirmLoading) return;
|
||||
const hide = message.loading('Waiting...', 0);
|
||||
modalState.confirmLoading = true;
|
||||
doGetjobInfo(jobId).then(res => {
|
||||
modalState.confirmLoading = false;
|
||||
hide();
|
||||
console.log(res);
|
||||
if (!res.error) {
|
||||
modalState.from = Object.assign(modalState.from, res.data);
|
||||
modalState.openByView = true;
|
||||
modalState.title = t('page.manage.task.viewJob');
|
||||
console.log(modalState.openByView);
|
||||
}
|
||||
// if (res.code === RESULT_CODE_SUCCESS && res.data) {
|
||||
// modalState.from = Object.assign(modalState.from, res.data);
|
||||
// modalState.title = t('views.manage.job.viewJob');
|
||||
// modalState.openByView = true;
|
||||
// } else {
|
||||
// message.error(t('views.manage.job.viewInfoErr'), 2);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对话框弹出关闭执行函数
|
||||
* 进行表达规则校验
|
||||
*/
|
||||
function fnModalCancel() {
|
||||
modalState.openByEdit = false;
|
||||
modalState.openByView = false;
|
||||
// modalStateFrom.resetFields();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对话框弹出显示为 新增或者修改
|
||||
* @param jobId 任务id, 不传为新增
|
||||
*/
|
||||
function fnModalVisibleByEdit(jobId?: string | number) {
|
||||
if (!jobId) {
|
||||
//modalStateFrom.resetFields();
|
||||
modalState.title = t('page.manage.task.addJob');
|
||||
modalState.openByEdit = true;
|
||||
} else {
|
||||
if (modalState.confirmLoading) return;
|
||||
const hide = message.loading(t('common.loading'), 0);
|
||||
modalState.confirmLoading = true;
|
||||
doGetjobInfo(jobId).then(res => {
|
||||
modalState.confirmLoading = false;
|
||||
hide();
|
||||
if (!res.error) {
|
||||
modalState.from = Object.assign(modalState.from, res.data);
|
||||
modalState.title = t('page.manage.task.editJob');
|
||||
modalState.openByEdit = true;
|
||||
} else {
|
||||
message.error(t('page.manage.task.getInfoError'), 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SimpleScrollbar>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<!-- 搜索框 -->
|
||||
<ACard :title="$t('common.search')" :bordered="false" class="card-wrapper">
|
||||
<AForm :model="searchParams" :label-width="80">
|
||||
<ARow :gutter="[16, 16]" wrap>
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem label="Name" name="operIp" class="m-0">
|
||||
<AInput v-model:value="searchParams.operIp" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem label="Group" name="title" class="m-0">
|
||||
<AInput v-model:value="searchParams.title" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem :label="$t('page.manage.user.status')" name="status" class="m-0">
|
||||
<ASelect v-model:value="searchParams.status" :placeholder="$t('page.manage.user.form.status')"
|
||||
allow-clear>
|
||||
<ASelectOption v-for="option in enableStatusOptions" :key="option.value" :value="option.value">
|
||||
{{ $t(option.label) }}
|
||||
</ASelectOption>
|
||||
</ASelect>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem class="m-0">
|
||||
<div class="w-full flex-y-center justify-end gap-8px">
|
||||
<a-space :size="8">
|
||||
<a-button @click="fnTest">
|
||||
<template #icon>
|
||||
<SyncOutlined />
|
||||
</template>
|
||||
{{ $t('common.reset') }}
|
||||
</a-button>
|
||||
<AButton type="primary" ghost @click="getData">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
{{ $t('common.search') }}
|
||||
</AButton>
|
||||
</a-space>
|
||||
|
||||
</div>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
</ARow>
|
||||
</AForm>
|
||||
</ACard>
|
||||
|
||||
<ACard title="Task Management" :bordered="false" :body-style="{ flex: 1, overflow: 'hidden' }"
|
||||
class="flex-col-stretch sm:flex-1-hidden card-wrapper">
|
||||
<template #extra>
|
||||
<!-- <TableHeaderOperation v-model:columns="columnChecks" :disabled-delete="checkedRowKeys.length === 0"
|
||||
:loading="loading" :show-delete="true" @add="handleAdd" @delete="handleBatchDelete" @refresh="getData"
|
||||
:showExport="true" :not-show-add="false" /> -->
|
||||
|
||||
<div class="flex flex-wrap justify-end gap-x-12px gap-y-8px lt-sm:(w-200px py-12px)">
|
||||
<slot name="prefix"></slot>
|
||||
<slot name="default">
|
||||
<AButton size="small" ghost type="primary" @click="fnModalVisibleByEdit()">
|
||||
<div class="flex-y-center gap-8px">
|
||||
<icon-ic-round-plus class="text-icon" />
|
||||
<span>{{ $t('common.add') }}</span>
|
||||
</div>
|
||||
</AButton>
|
||||
<APopconfirm :title="$t('common.confirmDelete')" :disabled="checkedRowKeys.length === 0"
|
||||
@confirm="handleBatchDelete">
|
||||
<AButton size="small" danger :disabled="checkedRowKeys.length <= 0">
|
||||
<div class="flex-y-center gap-8px">
|
||||
<icon-ic-round-delete class="text-icon" />
|
||||
<span>{{ $t('common.batchDelete') }}</span>
|
||||
</div>
|
||||
</AButton>
|
||||
</APopconfirm>
|
||||
</slot>
|
||||
<AButton size="small" @click="getData">
|
||||
<div class="flex-y-center gap-8px">
|
||||
<icon-mdi-refresh class="text-icon" :class="{ 'animate-spin': loading }" />
|
||||
<span>{{ $t('common.refresh') }}</span>
|
||||
</div>
|
||||
</AButton>
|
||||
<!-- <AButton size="small" type="primary" @click="handleExport" v-show="showExport">
|
||||
<div class="flex-y-center gap-8px">
|
||||
<icon-mdi-refresh class="text-icon" :class="{ 'animate-spin': loading }" />
|
||||
<span>{{ $t('common.export') }}</span>
|
||||
</div>
|
||||
</AButton> -->
|
||||
<TableColumnSetting v-model:columns="columns" />
|
||||
<slot name="suffix"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<ATable ref="wrapperEl" row-key="jobId" :columns="columns" :data-source="data" :loading="loading"
|
||||
:row-selection="{
|
||||
selectedRowKeys: checkedRowKeys,
|
||||
onChange: handleUserSelectChange,
|
||||
}" size="small" :pagination="mobilePagination" :scroll="scrollConfig" class="h-full">
|
||||
<template #bodyCell="{ column, record }">
|
||||
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-switch v-model:checked="record.status" checked-value="0" un-checked-value="1" size="small" />
|
||||
<!-- <DictTag :options="{
|
||||
'0': t('common.normal'),
|
||||
'1': t('common.abnormal'),
|
||||
}" :value="record.status" /> -->
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'operate'">
|
||||
<a-space :size="8" align="center">
|
||||
<a-tooltip>
|
||||
<template #title>{{ 'View' }}</template>
|
||||
<a-button type="link" @click.prevent="fnRecordView(record.jobId)">
|
||||
<template #icon>
|
||||
<ProfileOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip>
|
||||
<template #title>{{ 'Edit' }}</template>
|
||||
<a-button type="link" @click.prevent="fnModalVisibleByEdit(record.jobId)">
|
||||
<template #icon>
|
||||
<FormOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip>
|
||||
<template #title>{{ 'Delete' }}</template>
|
||||
<a-button type="link">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip>
|
||||
<template #title>{{ 'run' }}</template>
|
||||
<a-button type="link">
|
||||
<template #icon>
|
||||
<RocketOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip>
|
||||
<template #title>{{ 'Job Log' }}</template>
|
||||
<a-button type="link">
|
||||
<template #icon>
|
||||
<ContainerOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</ATable>
|
||||
|
||||
|
||||
|
||||
<!-- <taskOperateDrawer v-model:visible="drawerVisible" :dept-tree-data="deptTreeData" :operate-type="operateType"
|
||||
:row-data="editingData" @submitted="getData" /> -->
|
||||
|
||||
|
||||
<!-- 详情框 -->
|
||||
<a-modal :width="800" v-model:open="modalState.openByView" :title="modalState.title" @cancel="fnModalCancel">
|
||||
<a-form layout=" horizontal" :label-col="{ span: 6 }" :label-wrap="true">
|
||||
<a-row>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="$t('page.manage.task.taskName')" name="jobName">
|
||||
{{ modalState.from.jobName }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.status')" name="status">
|
||||
{{
|
||||
[{
|
||||
label: t('common.normal'),
|
||||
value: '0',
|
||||
}, {
|
||||
label: t('common.abnormal'),
|
||||
value: '1',
|
||||
}].find(s => s.value === modalState.from.status)
|
||||
?.label
|
||||
}}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.invoke')" name="invokeTarget">
|
||||
{{ modalState.from.invokeTarget }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.group')" name="jobGroup">
|
||||
<!-- <DictTag
|
||||
:options="dict.sysJobGroup"
|
||||
:value="modalState.from.jobGroup"
|
||||
/> -->
|
||||
{{ modalState.from.jobGroup }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.cron')" name="cronExpression">
|
||||
<a-tag color="default">
|
||||
{{ modalState.from.cronExpression }}
|
||||
</a-tag>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- <a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.log')" name="saveLog">
|
||||
<DictTag
|
||||
:options="dict.sysJobSaveLog"
|
||||
:value="modalState.from.saveLog"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col> -->
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.createTime')" name="createTime" :label-wrap="true">
|
||||
{{ modalState.from.createTime }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
|
||||
|
||||
<a-form-item :label="t('page.manage.task.targetParams')" name="targetParams" :label-col="{ span: 3 }"
|
||||
:label-wrap="true">
|
||||
<a-textarea v-model:value="modalState.from.targetParams" :auto-size="{ minRows: 2, maxRows: 6 }"
|
||||
:disabled="true" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label="t('page.manage.task.remark')" name="remark" :label-col="{ span: 3 }"
|
||||
:label-wrap="true">
|
||||
<a-textarea v-model:value="modalState.from.remark" :auto-size="{ minRows: 2, maxRows: 6 }"
|
||||
:disabled="true" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button key="cancel" @click="fnModalCancel">
|
||||
{{ t('common.close') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-modal>
|
||||
|
||||
|
||||
|
||||
<!-- 新增框或修改框 -->
|
||||
<!-- <a-modal :drag="true" :width="800" :destroyOnClose="true" :keyboard="false" :mask-closable="false"
|
||||
:open="modalState.openByEdit" :title="modalState.title" :confirm-loading="modalState.confirmLoading"
|
||||
@ok="fnModalOk" @cancel="fnModalCancel">
|
||||
<a-form name="modalStateFrom" layout="horizontal" :label-col="{ span: 6 }" :label-wrap="true" :rules="rules">
|
||||
<a-row>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.taskName')" name="jobName">
|
||||
<a-input v-model:value="modalState.from.jobName" allow-clear
|
||||
:placeholder="t('page.manage.task.jobNamePlease')"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.status')" name="status">
|
||||
<a-select v-model:value="modalState.from.status" default-value="0"
|
||||
:placeholder="t('common.selectPlease')" :options="dict.sysJobStatus">
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.jobGroup')" name="jobGroup">
|
||||
<a-select v-model:value="modalState.from.jobGroup" default-value="DEFAULT"
|
||||
:placeholder="t('common.selectPlease')" :options="dict.sysJobGroup">
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="12" :md="12" :xs="24">
|
||||
<a-form-item :label="t('page.manage.task.saveLog')" name="saveLog">
|
||||
<a-select v-model:value="modalState.from.saveLog" default-value="0"
|
||||
:placeholder="t('common.selectPlease')" :options="dict.sysJobSaveLog">
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item :label="t('page.manage.task.invokeTarget')" name="invokeTarget" :label-col="{ span: 3 }"
|
||||
:label-wrap="true">
|
||||
<a-input v-model:value="modalState.from.invokeTarget" allow-clear
|
||||
:placeholder="t('page.manage.task.invokeTargetPlease')">
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div>{{ t('page.manage.task.invokeTargetTip') }}</div>
|
||||
</template>
|
||||
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label="t('page.manage.task.cronExpression')" name="cronExpression" :label-col="{ span: 3 }"
|
||||
:label-wrap="true">
|
||||
<a-input v-model:value="modalState.from.cronExpression" allow-clear
|
||||
:placeholder="t('page.manage.task.cronExpressionPlease')">
|
||||
<template #prefix>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div>
|
||||
{{ t('page.manage.task.cronExpressionTip') }}<br />
|
||||
{{ t('page.manage.task.cronExpressionTip1') }}
|
||||
</div>
|
||||
</template>
|
||||
<InfoCircleOutlined style="opacity: 0.45; color: inherit" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #addonAfter>
|
||||
<a-button type="text" size="small" @click.prevent="fnModalCron(true)">
|
||||
<template #icon>
|
||||
<FieldTimeOutlined />
|
||||
</template>
|
||||
{{ t('page.manage.task.cronExpressionNew') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label="t('page.manage.task.targetParams')" name="targetParams" :label-col="{ span: 3 }"
|
||||
:label-wrap="true">
|
||||
<a-textarea v-model:value="modalState.from.targetParams" :auto-size="{ minRows: 2, maxRows: 6 }"
|
||||
:maxlength="400" :placeholder="t('page.manage.task.targetParamsPlease')" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :label="t('page.manage.task.remark')" name="remark" :label-col="{ span: 3 }"
|
||||
:label-wrap="true">
|
||||
<a-textarea v-model:value="modalState.from.remark" :auto-size="{ minRows: 2, maxRows: 6 }"
|
||||
:maxlength="400" :show-count="true" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal> -->
|
||||
|
||||
</ACard>
|
||||
|
||||
|
||||
</div>
|
||||
</SimpleScrollbar>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
222
src/views/manage/task/modules/task-operate-drawer.vue
Normal file
222
src/views/manage/task/modules/task-operate-drawer.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<script setup lang="ts">
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import { useAntdForm, useFormRules } from '@/hooks/common/form';
|
||||
import { $t } from '@/locales';
|
||||
import { enableStatusOptions } from '@/constants/business';
|
||||
|
||||
defineOptions({
|
||||
name: 'logOperateDrawer'
|
||||
});
|
||||
|
||||
interface Props {
|
||||
/** the type of operation */
|
||||
operateType: any;
|
||||
/** the edit row data */
|
||||
rowData?:any;
|
||||
deptTreeData:any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
interface Emits {
|
||||
(e: 'submitted'): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const visible = defineModel<boolean>('visible', {
|
||||
default: false
|
||||
});
|
||||
|
||||
const { formRef, validate, resetFields } = useAntdForm();
|
||||
const { defaultRequiredRule, formRules } = useFormRules();
|
||||
const [spinning, spin] = useToggle();
|
||||
|
||||
const title = computed(() => {
|
||||
const titles: any = {
|
||||
add: $t('page.manage.user.addUser'),
|
||||
edit: $t('page.manage.user.editUser')
|
||||
};
|
||||
return titles[props.operateType];
|
||||
});
|
||||
|
||||
type Model = Partial<
|
||||
Pick<Api.Auth.User, 'userName' | 'nickName' | 'email' | 'phonenumber' | 'status' | 'deptId' | 'remark'> & {
|
||||
postIds: number[];
|
||||
roleIds: number[];
|
||||
password?: string;
|
||||
}
|
||||
>;
|
||||
|
||||
const model = ref<Model>(createDefaultModel());
|
||||
|
||||
const userPosts = ref<Api.SystemManage.Post[]>([]);
|
||||
const userRoles = ref<Api.SystemManage.Role[]>([]);
|
||||
|
||||
function createDefaultModel(): Model {
|
||||
return {
|
||||
userName: '',
|
||||
nickName: '',
|
||||
email: '',
|
||||
phonenumber: '',
|
||||
status: '0',
|
||||
deptId: undefined,
|
||||
remark: '',
|
||||
postIds: [],
|
||||
roleIds: [],
|
||||
password: ''
|
||||
};
|
||||
}
|
||||
|
||||
//制定规则
|
||||
const rules = {
|
||||
userName: defaultRequiredRule,
|
||||
nickName: defaultRequiredRule,
|
||||
status: defaultRequiredRule,
|
||||
deptId: defaultRequiredRule,
|
||||
email: formRules.email,
|
||||
phonenumber: formRules.phone,
|
||||
password: formRules.pwd,
|
||||
postIds: defaultRequiredRule,
|
||||
roleIds: defaultRequiredRule
|
||||
};
|
||||
|
||||
// 修改时触发
|
||||
async function init(userId: number | undefined = undefined) {
|
||||
spin(true);
|
||||
try {
|
||||
await Promise.all([getUserPostAndRole(userId)]);
|
||||
spin(false);
|
||||
} catch (error) {
|
||||
spin(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserPostAndRole(userId: number | undefined) {
|
||||
const { error, data } = await doGetUserPostsAndRoles(userId);
|
||||
//渲染用户岗位和角色option
|
||||
if (!error) {
|
||||
const { postIds, posts, roleIds, roles } = data;
|
||||
userPosts.value = posts;
|
||||
userRoles.value = roles;
|
||||
model.value.postIds = postIds;
|
||||
model.value.roleIds = roleIds;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleUpdateModelWhenEdit() {
|
||||
if (props.operateType === 'add') {
|
||||
model.value = createDefaultModel(); //新增时赋值
|
||||
}
|
||||
|
||||
if (props.operateType === 'edit' && props.rowData) {
|
||||
await init(props.rowData.userId);
|
||||
model.value = Object.assign(model.value, omit(props.rowData, ['postIds', 'roleIds']));
|
||||
} else {
|
||||
await init();
|
||||
model.value = createDefaultModel();
|
||||
}
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
await validate();
|
||||
|
||||
const { error } = await (props.operateType === 'edit' ? doPutUser : doPostUser)(model.value as Api.Auth.User);
|
||||
|
||||
if (!error) {
|
||||
$message?.success($t(props.operateType === 'add' ? 'common.addSuccess' : 'common.updateSuccess'));
|
||||
closeDrawer();
|
||||
emit('submitted');
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => visible.value,
|
||||
val => {
|
||||
if (val) {
|
||||
handleUpdateModelWhenEdit();
|
||||
resetFields();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// console.log(props.operateType)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ADrawer
|
||||
v-model:open="visible"
|
||||
:body-style="{ paddingRight: '0px', paddingTop: '0', paddingBottom: '0' }"
|
||||
:title="title"
|
||||
:width="460"
|
||||
>
|
||||
<SimpleScrollbar>
|
||||
<ASpin :spinning="spinning" size="small">
|
||||
<AForm ref="formRef" py-20px pr-20px layout="vertical" :model="model" :rules="rules">
|
||||
<AFormItem :label="$t('page.manage.user.userName')" name="userName">
|
||||
<AInput v-model:value="model.userName" :placeholder="$t('page.manage.user.form.userName')" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.nickName')" name="nickName">
|
||||
<AInput v-model:value="model.nickName" :placeholder="$t('page.manage.user.form.nickName')" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.email')" name="email">
|
||||
<AInput v-model:value="model.email" :placeholder="$t('page.manage.user.form.email')" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.phonenumber')" name="phonenumber">
|
||||
<AInput v-model:value="model.phonenumber" :placeholder="$t('page.manage.user.form.phonenumber')" />
|
||||
</AFormItem>
|
||||
<AFormItem v-if="props.operateType === 'add'" :label="$t('page.manage.user.password')" name="password">
|
||||
<AInput
|
||||
v-model:value="model.password"
|
||||
type="password"
|
||||
:placeholder="$t('page.manage.user.form.password')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.post')" name="postIds">
|
||||
<ASelect
|
||||
v-model:value="model.postIds"
|
||||
:field-names="{ label: 'postName', value: 'postId' }"
|
||||
mode="multiple"
|
||||
:options="userPosts"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.role')" name="roleIds">
|
||||
<ASelect
|
||||
v-model:value="model.roleIds"
|
||||
:field-names="{ label: 'roleName', value: 'roleId' }"
|
||||
mode="multiple"
|
||||
:options="userRoles"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.status')" name="status">
|
||||
<ARadioGroup v-model:value="model.status">
|
||||
<ARadio v-for="item in enableStatusOptions" :key="item.value" :value="item.value">
|
||||
{{ $t(item.label) }}
|
||||
</ARadio>
|
||||
</ARadioGroup>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.dept')" name="deptId">
|
||||
<ATreeSelect v-model:value="model.deptId" :field-names="{ value: 'id' }" :tree-data="deptTreeData" />
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.user.remark')" name="remark">
|
||||
<ATextarea v-model:value="model.remark" :placeholder="$t('page.manage.user.form.remark')" />
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</ASpin>
|
||||
</SimpleScrollbar>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex-y-center justify-end gap-12px">
|
||||
<AButton @click="closeDrawer">{{ $t('common.cancel') }}</AButton>
|
||||
<AButton type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</AButton>
|
||||
</div>
|
||||
</template>
|
||||
</ADrawer>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
109
src/views/manage/task/modules/task-search.vue
Normal file
109
src/views/manage/task/modules/task-search.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from '@/locales';
|
||||
import { enableStatusOptions } from '@/constants/business';
|
||||
import { SyncOutlined, SearchOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'logSearch'
|
||||
});
|
||||
|
||||
|
||||
|
||||
interface Emits {
|
||||
(e: 'reset'): void;
|
||||
(e: 'search'): void;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const model = defineModel<any>('model', { required: true });
|
||||
|
||||
/**记录开始结束时间 */
|
||||
let queryRangePicker = ref<[string, string]>(['', '']);
|
||||
|
||||
function reset() {
|
||||
// 重置表单
|
||||
//formRef.value?.resetFields();
|
||||
|
||||
// 重置日期选择器
|
||||
queryRangePicker.value = ['', ''];
|
||||
|
||||
// 确保 model 也被重置
|
||||
model.value = {};
|
||||
|
||||
// 使用 nextTick 确保视图更新后检查
|
||||
nextTick(() => {
|
||||
console.log('视图更新后:', { ...model.value });
|
||||
console.log(model);
|
||||
});
|
||||
emit('reset');
|
||||
}
|
||||
|
||||
function search() {
|
||||
if (!queryRangePicker.value) {
|
||||
queryRangePicker.value = ['', ''];
|
||||
}
|
||||
model.value.beginTime = queryRangePicker.value[0];
|
||||
model.value.endTime = queryRangePicker.value[1];
|
||||
emit('search');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ACard :title="$t('common.search')" :bordered="false" class="card-wrapper">
|
||||
<AForm :model="model" :label-width="80">
|
||||
<ARow :gutter="[16, 16]" wrap>
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem label="Name" name="operIp" class="m-0">
|
||||
<AInput v-model:value="model.operIp" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem label="Group" name="title" class="m-0">
|
||||
<AInput v-model:value="model.title" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem :label="$t('page.manage.user.status')" name="status" class="m-0">
|
||||
<ASelect v-model:value="model.status" :placeholder="$t('page.manage.user.form.status')" allow-clear>
|
||||
<ASelectOption v-for="option in enableStatusOptions" :key="option.value" :value="option.value">
|
||||
{{ $t(option.label) }}
|
||||
</ASelectOption>
|
||||
</ASelect>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
|
||||
|
||||
<ACol :lg="6" :md="12" :xs="24">
|
||||
<AFormItem class="m-0">
|
||||
<div class="w-full flex-y-center justify-end gap-8px">
|
||||
|
||||
<a-space :size="8">
|
||||
<a-button @click="reset">
|
||||
<template #icon>
|
||||
<SyncOutlined />
|
||||
</template>
|
||||
{{ $t('common.reset') }}
|
||||
</a-button>
|
||||
<AButton type="primary" ghost @click="search">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
{{ $t('common.search') }}
|
||||
</AButton>
|
||||
</a-space>
|
||||
|
||||
</div>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
</ARow>
|
||||
</AForm>
|
||||
</ACard>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user