新增前端vue
This commit is contained in:
298
web-vue/packages/test/views/test/testData/form.vue
Normal file
298
web-vue/packages/test/views/test/testData/form.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'test:testData:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="70%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #remarks="{ model, field }">
|
||||
<WangEditor
|
||||
v-model:value="model[field]"
|
||||
:bizKey="record.id"
|
||||
:bizType="'testDataChild_' + field"
|
||||
:height="300"
|
||||
/>
|
||||
</template>
|
||||
<template #testDataChildList>
|
||||
<FormDataChildList ref="formDataChildListRef" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestDataForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { TestData, testDataSave, testDataForm } from '@jeesite/test/api/test/testData';
|
||||
import { officeTreeData } from '@jeesite/core/api/sys/office';
|
||||
import { areaTreeData } from '@jeesite/core/api/sys/area';
|
||||
import { WangEditor } from '@jeesite/core/components/WangEditor';
|
||||
// import { dateUtil, formatToDateTime } from '@jeesite/core/utils/dateUtil';
|
||||
import FormDataChildList from './formDataChildList.vue';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('test.testData');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<TestData>({} as TestData);
|
||||
const formDataChildListRef = ref<InstanceType<typeof FormDataChildList>>();
|
||||
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增数据') : t('编辑数据'),
|
||||
}));
|
||||
|
||||
const inputFormSchemas: FormSchema<TestData>[] = [
|
||||
{
|
||||
label: t('单行文本'),
|
||||
field: 'testInput',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
// addonBefore: t('前'),
|
||||
// addonAfter: t('后'),
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('列表选择'),
|
||||
field: 'testInput2',
|
||||
fieldLabel: 'testTextarea',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
configFile: import('./select'),
|
||||
checkbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('多行文本'),
|
||||
field: 'testTextarea',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('下拉框'),
|
||||
field: 'testSelect',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('下拉多选'),
|
||||
field: 'testSelectMultiple',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
mode: 'multiple',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('单选框'),
|
||||
field: 'testRadio',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('复选框'),
|
||||
field: 'testCheckbox',
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期选择'),
|
||||
field: 'testDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
// defaultValue: dateUtil(new Date()),
|
||||
// defaultValue: formatToDateTime(new Date()),
|
||||
// defaultValue: '2024-05-31',
|
||||
},
|
||||
{
|
||||
label: t('日期时间'),
|
||||
field: 'testDatetime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期范围'),
|
||||
field: 'dateRange',
|
||||
component: 'RangePicker',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('用户选择'),
|
||||
field: 'testUser.userCode',
|
||||
fieldLabel: 'testUser.userName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
treeCheckable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户列表选择'),
|
||||
field: 'testUser.userCode',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'empUserSelect',
|
||||
checkbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('机构选择'),
|
||||
field: 'testOffice.officeCode',
|
||||
fieldLabel: 'testOffice.officeName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('区域选择'),
|
||||
field: 'testAreaCode',
|
||||
fieldLabel: 'testAreaName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
slot: 'remarks',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('图片上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_image',
|
||||
uploadType: 'image',
|
||||
// imageMaxWidth: 1024,
|
||||
// imageMaxHeight: 768,
|
||||
// imageThumbName: '150x150.jpg',
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
// 文件上传的必填验证实例
|
||||
// rules: [
|
||||
// { required: true },
|
||||
// {
|
||||
// validator(_rule, value) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const len = !value || value['testData_image__len'] || 0;
|
||||
// if (len == 0) reject(t('请上传图片'));
|
||||
// else resolve();
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
{
|
||||
label: t('文件上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_file',
|
||||
uploadType: 'all',
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('子表数据'),
|
||||
field: 'testDataChildList',
|
||||
component: 'Input',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
slot: 'testDataChildList',
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm<TestData>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
fieldMapToTime: [['dateRange', ['testDate', 'testDatetime']]],
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await testDataForm(data);
|
||||
record.value = (res.testData || {}) as TestData;
|
||||
record.value.__t = new Date().getTime();
|
||||
setFieldsValue(record.value);
|
||||
formDataChildListRef.value?.setTableData(record.value);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
id: record.value.id,
|
||||
};
|
||||
await formDataChildListRef.value?.getTableData(data);
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await testDataSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
309
web-vue/packages/test/views/test/testData/formDataChildList.vue
Normal file
309
web-vue/packages/test/views/test/testData/formDataChildList.vue
Normal file
@@ -0,0 +1,309 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" @row-click="handleRowClick" @edit-change="onEditChange" />
|
||||
<a-button class="mt-2" @click="handleRowAdd" v-auth="'test:testData:edit'">
|
||||
<Icon icon="i-ant-design:plus-circle-outlined" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { officeTreeData } from '@jeesite/core/api/sys/office';
|
||||
import { areaTreeData } from '@jeesite/core/api/sys/area';
|
||||
import { TestData } from '@jeesite/test/api/test/testData';
|
||||
import { TestDataChild } from '@jeesite/test/api/test/testDataChild';
|
||||
|
||||
const { t } = useI18n('test.testDataChild');
|
||||
const record = ref<TestData>({} as TestData);
|
||||
|
||||
const tableColumns: BasicColumn<TestDataChild>[] = [
|
||||
{
|
||||
title: t('单行文本'),
|
||||
dataIndex: 'testInput',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editComponentProps: {
|
||||
// addonBefore: t('前'),
|
||||
// addonAfter: t('后'),
|
||||
},
|
||||
editRule: true,
|
||||
},
|
||||
{
|
||||
title: t('多行文本'),
|
||||
dataIndex: 'testTextarea',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'InputTextArea',
|
||||
// 子表自定义验证实例
|
||||
editRule: (value, _record) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!value || value === '') return resolve();
|
||||
if (value.length < 3) return reject('至少3个字符');
|
||||
return resolve(); // 验证成功
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('下拉框'),
|
||||
dataIndex: 'testSelect',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉多选'),
|
||||
dataIndex: 'testSelectMultiple',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
mode: 'multiple',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期选择'),
|
||||
dataIndex: 'testDate',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期时间'),
|
||||
dataIndex: 'testDatetime',
|
||||
width: 215,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('用户选择'),
|
||||
dataIndex: 'testUser.userCode',
|
||||
dataLabel: 'testUser.userName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
// editComponent: 'TreeSelect',
|
||||
editComponent: 'ListSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
// configFile: import('./select'),
|
||||
// checkbox: false,
|
||||
},
|
||||
// 编辑表格联动例子(选择框查询条件,实时读取第一列的数据)
|
||||
// editComponentProps: ({ record: childRecord }) => {
|
||||
// return {
|
||||
// configFile: import('./select'),
|
||||
// queryParams: {
|
||||
// testInput: childRecord.editValueRefs.testInput,
|
||||
// },
|
||||
// };
|
||||
// },
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('机构选择'),
|
||||
dataIndex: 'testOffice.officeCode',
|
||||
dataLabel: 'testOffice.officeName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('区域选择'),
|
||||
dataIndex: 'testAreaCode',
|
||||
dataLabel: 'testAreaName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: areaTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('图片上传'),
|
||||
dataIndex: 'dataMap',
|
||||
width: 160,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Upload',
|
||||
editComponentProps: ({ record: childRecord }) => {
|
||||
return {
|
||||
loadTime: record.value.__t,
|
||||
bizKey: childRecord.id,
|
||||
bizType: 'testDataChild_image',
|
||||
uploadType: 'image',
|
||||
// imageMaxWidth: 1024,
|
||||
// imageMaxHeight: 768,
|
||||
// imageThumbName: '150x150.jpg',
|
||||
size: 'small',
|
||||
};
|
||||
},
|
||||
// 图片上传的必填验证实例
|
||||
// editRule: (value: any, record: Recordable) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const len = !value || value['testDataChild_image__len'] || 0;
|
||||
// if (len == 0) reject(t('请上传图片'));
|
||||
// else resolve();
|
||||
// });
|
||||
// },
|
||||
},
|
||||
{
|
||||
title: t('文件上传'),
|
||||
dataIndex: 'dataMap',
|
||||
width: 160,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Upload',
|
||||
editComponentProps: ({ record: childRecord }) => {
|
||||
return {
|
||||
loadTime: record.value.__t,
|
||||
bizKey: childRecord.id,
|
||||
bizType: 'testDataChild_file',
|
||||
uploadType: 'all',
|
||||
size: 'small',
|
||||
};
|
||||
},
|
||||
// 文件上传的必填验证实例
|
||||
// editRule: (value: any, record: Recordable) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const len = !value || value['testDataChild_file__len'] || 0;
|
||||
// if (len == 0) reject(t('请上传文件'));
|
||||
// else resolve();
|
||||
// });
|
||||
// },
|
||||
},
|
||||
];
|
||||
|
||||
const [registerTable, tableAction] = useTable<TestDataChild>({
|
||||
columns: tableColumns,
|
||||
actionColumn: {
|
||||
width: 60,
|
||||
actions: (record: TestDataChild) => [
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: t('是否确认删除'),
|
||||
confirm: handleRowDelete.bind(this, record),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
],
|
||||
},
|
||||
rowKey: 'id',
|
||||
pagination: false,
|
||||
bordered: true,
|
||||
size: 'small',
|
||||
inset: true,
|
||||
});
|
||||
|
||||
function onEditChange({ column, record }) {
|
||||
// 当修改 testInput 的时候,更改 testTextarea 的值,例子(联动)
|
||||
if (column.dataIndex == 'testInput' && record.editValueRefs) {
|
||||
// record.testTextarea = record.editValueRefs.testInput;
|
||||
}
|
||||
}
|
||||
|
||||
function handleRowClick(data: Recordable) {
|
||||
data.onEdit?.(true, false);
|
||||
}
|
||||
|
||||
function handleRowAdd() {
|
||||
tableAction.insertTableDataRecord({
|
||||
id: 'rid_' + new Date().getTime(),
|
||||
isNewRecord: true,
|
||||
editable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function handleRowDelete(data: Recordable) {
|
||||
tableAction.deleteTableDataRecord(data);
|
||||
}
|
||||
|
||||
async function getTableData(data: Recordable): Promise<Recordable> {
|
||||
let valid = true;
|
||||
let tableList: Recordable[] = [];
|
||||
for (const record of tableAction.getDataSource()) {
|
||||
if (!(await record.onEdit?.(false, true))) {
|
||||
valid = false;
|
||||
}
|
||||
tableList.push({
|
||||
...record,
|
||||
id: !!record.isNewRecord ? '' : record.id,
|
||||
});
|
||||
}
|
||||
for (const record of tableAction.getDelDataSource()) {
|
||||
if (!!record.isNewRecord) continue;
|
||||
tableList.push({
|
||||
...record,
|
||||
status: '1',
|
||||
});
|
||||
}
|
||||
if (!valid) {
|
||||
throw {
|
||||
errorFields: [{ name: ['testDataChildList'] }],
|
||||
message: t('测试数据子表填写有误,请根据提示修正'),
|
||||
};
|
||||
}
|
||||
data.testDataChildList = tableList;
|
||||
return tableList;
|
||||
}
|
||||
|
||||
async function setTableData(data: Recordable) {
|
||||
record.value = data as TestData;
|
||||
tableAction.setTableData(data.testDataChildList || []);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getTableData,
|
||||
setTableData,
|
||||
});
|
||||
</script>
|
||||
493
web-vue/packages/test/views/test/testData/formModal.vue
Normal file
493
web-vue/packages/test/views/test/testData/formModal.vue
Normal file
@@ -0,0 +1,493 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'test:testData:edit'"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
width="70%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #remarks="{ model, field }">
|
||||
<WangEditor
|
||||
v-model:value="model[field]"
|
||||
:bizKey="record.id"
|
||||
:bizType="'testDataChild_' + field"
|
||||
:height="300"
|
||||
/>
|
||||
</template>
|
||||
<template #testDataChildList>
|
||||
<BasicTable @register="registerTestDataChildTable" @row-click="handleTestDataChildRowClick">
|
||||
<template #testDataChildUpload="{ record: childRecord }">
|
||||
<BasicUpload
|
||||
v-model:value="childRecord.dataMap"
|
||||
:bizKey="childRecord.id"
|
||||
:bizType="'testDataChild_file'"
|
||||
:uploadType="'all'"
|
||||
:loadTime="record.__t"
|
||||
:size="'small'"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<a-button class="mt-2" @click="handleTestDataChildAdd" v-auth="'test:testData:edit'">
|
||||
<Icon icon="i-ant-design:plus-circle-outlined" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestDataForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicTable, useTable } from '@jeesite/core/components/Table';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { TestData, testDataSave, testDataForm } from '@jeesite/test/api/test/testData';
|
||||
import { TestDataChild } from '@jeesite/test/api/test/testDataChild';
|
||||
import { officeTreeData } from '@jeesite/core/api/sys/office';
|
||||
import { areaTreeData } from '@jeesite/core/api/sys/area';
|
||||
import { BasicUpload } from '@jeesite/core/components/Upload';
|
||||
import { WangEditor } from '@jeesite/core/components/WangEditor';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('test.testData');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<TestData>({} as TestData);
|
||||
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增数据') : t('编辑数据'),
|
||||
}));
|
||||
|
||||
const inputFormSchemas: FormSchema<TestData>[] = [
|
||||
{
|
||||
label: t('单行文本'),
|
||||
field: 'testInput',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('列表选择'),
|
||||
field: 'testInput2',
|
||||
fieldLabel: 'testTextarea',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
configFile: import('./select'),
|
||||
checkbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('多行文本'),
|
||||
field: 'testTextarea',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('下拉框'),
|
||||
field: 'testSelect',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('下拉多选'),
|
||||
field: 'testSelectMultiple',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
mode: 'multiple',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('单选框'),
|
||||
field: 'testRadio',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('复选框'),
|
||||
field: 'testCheckbox',
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期选择'),
|
||||
field: 'testDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期时间'),
|
||||
field: 'testDatetime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户选择'),
|
||||
field: 'testUser.userCode',
|
||||
fieldLabel: 'testUser.userName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户列表选择'),
|
||||
field: 'testUser.userCode',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'empUserSelect',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('机构选择'),
|
||||
field: 'testOffice.officeCode',
|
||||
fieldLabel: 'testOffice.officeName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('区域选择'),
|
||||
field: 'testAreaCode',
|
||||
fieldLabel: 'testAreaName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
slot: 'remarks',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('图片上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_image',
|
||||
uploadType: 'image',
|
||||
// imageMaxWidth: 1024,
|
||||
// imageMaxHeight: 768,
|
||||
// imageThumbName: '150x150.jpg',
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
// 文件上传的必填验证实例
|
||||
// rules: [
|
||||
// { required: true },
|
||||
// {
|
||||
// validator(_rule, value) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const len = !value || value['testData_image__len'] || 0;
|
||||
// if (len == 0) reject(t('请上传图片'));
|
||||
// else resolve();
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
{
|
||||
label: t('文件上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_file',
|
||||
uploadType: 'all',
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('子表数据'),
|
||||
field: 'testDataChildList',
|
||||
component: 'Input',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
slot: 'testDataChildList',
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm<TestData>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerTestDataChildTable, testDataChildTable] = useTable<TestDataChild>({
|
||||
actionColumn: {
|
||||
width: 60,
|
||||
actions: (record: TestDataChild) => [
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: t('是否确认删除'),
|
||||
confirm: handleTestDataChildDelete.bind(this, record),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
],
|
||||
},
|
||||
rowKey: 'id',
|
||||
pagination: false,
|
||||
bordered: true,
|
||||
size: 'small',
|
||||
inset: true,
|
||||
});
|
||||
|
||||
async function setTestDataChildTableData(_res: Recordable) {
|
||||
testDataChildTable.setColumns([
|
||||
{
|
||||
title: t('单行文本'),
|
||||
dataIndex: 'testInput',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editRule: true,
|
||||
},
|
||||
{
|
||||
title: t('多行文本'),
|
||||
dataIndex: 'testTextarea',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉框'),
|
||||
dataIndex: 'testSelect',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉多选'),
|
||||
dataIndex: 'testSelectMultiple',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
mode: 'multiple',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期选择'),
|
||||
dataIndex: 'testDate',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期时间'),
|
||||
dataIndex: 'testDatetime',
|
||||
width: 215,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('用户选择'),
|
||||
dataIndex: 'testUser.userCode',
|
||||
dataLabel: 'testUser.userName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('机构选择'),
|
||||
dataIndex: 'testOffice.officeCode',
|
||||
dataLabel: 'testOffice.officeName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('区域选择'),
|
||||
dataIndex: 'testAreaCode',
|
||||
dataLabel: 'testAreaName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: areaTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('文件上传'),
|
||||
dataIndex: 'upload',
|
||||
width: 160,
|
||||
align: 'left',
|
||||
slot: 'testDataChildUpload',
|
||||
},
|
||||
]);
|
||||
testDataChildTable.setTableData(record.value.testDataChildList || []);
|
||||
}
|
||||
|
||||
function handleTestDataChildRowClick(record: Recordable) {
|
||||
record.onEdit?.(true, false);
|
||||
}
|
||||
|
||||
function handleTestDataChildAdd() {
|
||||
testDataChildTable.insertTableDataRecord({
|
||||
id: new Date().getTime(),
|
||||
isNewRecord: true,
|
||||
editable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function handleTestDataChildDelete(record: Recordable) {
|
||||
testDataChildTable.deleteTableDataRecord(record);
|
||||
}
|
||||
|
||||
async function getTestDataChildList() {
|
||||
let testDataChildListValid = true;
|
||||
let testDataChildList: Recordable[] = [];
|
||||
for (const record of testDataChildTable.getDataSource()) {
|
||||
if (!(await record.onEdit?.(false, true))) {
|
||||
testDataChildListValid = false;
|
||||
}
|
||||
testDataChildList.push({
|
||||
...record,
|
||||
id: !!record.isNewRecord ? '' : record.id,
|
||||
});
|
||||
}
|
||||
for (const record of testDataChildTable.getDelDataSource()) {
|
||||
if (!!record.isNewRecord) continue;
|
||||
testDataChildList.push({
|
||||
...record,
|
||||
status: '1',
|
||||
});
|
||||
}
|
||||
if (!testDataChildListValid) {
|
||||
throw { errorFields: [{ name: ['testDataChildList'] }] };
|
||||
}
|
||||
return testDataChildList;
|
||||
}
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
setModalProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await testDataForm(data);
|
||||
record.value = (res.testData || {}) as TestData;
|
||||
record.value.__t = new Date().getTime();
|
||||
setFieldsValue(record.value);
|
||||
setTestDataChildTableData(res);
|
||||
setModalProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setModalProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
id: record.value.id,
|
||||
};
|
||||
data.testDataChildList = await getTestDataChildList();
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await testDataSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeModal);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
582
web-vue/packages/test/views/test/testData/formRoute.vue
Normal file
582
web-vue/packages/test/views/test/testData/formRoute.vue
Normal file
@@ -0,0 +1,582 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<CollapseForm
|
||||
:config="formConfig"
|
||||
:loading="loadingRef"
|
||||
:okLoading="okLoadingRef"
|
||||
:okAuth="'test:testData:edit'"
|
||||
@close="handleClose"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<template #form1>
|
||||
<BasicForm @register="registerForm1">
|
||||
<template #remarks="{ model, field }">
|
||||
<WangEditor
|
||||
v-model:value="model[field]"
|
||||
:bizKey="record.id"
|
||||
:bizType="'testDataChild_' + field"
|
||||
:height="300"
|
||||
/>
|
||||
</template>
|
||||
<template #testCheckbox="{ model, field }">
|
||||
<Form.Item class="inline-block" :name="field">
|
||||
<CheckboxGroup
|
||||
:value="model[field]"
|
||||
@change="
|
||||
model[field] = $event || ''; // 给表单赋值(写到这里是为了方便演示,可写到一个函数里)
|
||||
$event && (model[field + 'Other'] = ''); // 不选“无”的时候,清空后面的复选框和输入框
|
||||
"
|
||||
:options="[{ label: '无', value: '0' }]"
|
||||
/>
|
||||
<div class="ml-3 inline-block"></div>
|
||||
</Form.Item>
|
||||
<Form.Item class="inline-block" :name="field">
|
||||
<CheckboxGroup
|
||||
:value="model[field]"
|
||||
@change="model[field] = $event || ''"
|
||||
:dictType="'sys_menu_type'"
|
||||
:disabled="model[field] == '0' /* 选择“无”的时候禁用 */"
|
||||
/>
|
||||
</Form.Item>
|
||||
<div class="ml-2 inline-block"></div>
|
||||
<Form.Item
|
||||
class="inline-block"
|
||||
:name="field + 'Other'"
|
||||
:rules="[
|
||||
// 如果选择了最后一个复选框,则出现输入框,并启用表单验证
|
||||
//{ required: (',' + model[field] + ',').indexOf(',2,') != -1, message: '请填写' },
|
||||
]"
|
||||
v-show="(',' + model[field] + ',').indexOf(',2,') != -1 /* 是否显示输入框 */"
|
||||
>
|
||||
<Input
|
||||
:value="model[field + 'Other']"
|
||||
@change="model[field + 'Other'] = $event.target.value"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form.Item>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</template>
|
||||
<template #form2>
|
||||
<BasicForm @register="registerForm2">
|
||||
<template #testDataChildList>
|
||||
<BasicTable @register="registerTestDataChildTable" @row-click="handleTestDataChildRowClick">
|
||||
<template #testDataChildUpload="{ record: childRecord }">
|
||||
<BasicUpload
|
||||
v-model:value="childRecord.dataMap"
|
||||
:bizKey="childRecord.id"
|
||||
:bizType="'testDataChild_file'"
|
||||
:uploadType="'all'"
|
||||
:loadTime="record.__t"
|
||||
:size="'small'"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<a-button class="mt-2" @click="handleTestDataChildAdd" v-auth="'test:testData:edit'">
|
||||
<Icon icon="i-ant-design:plus-circle-outlined" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</template>
|
||||
</CollapseForm>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestDataFormRoute">
|
||||
import { ref, unref, computed, onMounted } from 'vue';
|
||||
import { useEmitter } from '@jeesite/core/store/modules/user';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { CollapseForm } from '@jeesite/core/components/CollapseForm';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicTable, useTable } from '@jeesite/core/components/Table';
|
||||
import { TestData, testDataSave, testDataForm } from '@jeesite/test/api/test/testData';
|
||||
import { TestDataChild } from '@jeesite/test/api/test/testDataChild';
|
||||
import { officeTreeData } from '@jeesite/core/api/sys/office';
|
||||
import { areaTreeData } from '@jeesite/core/api/sys/area';
|
||||
import { BasicUpload } from '@jeesite/core/components/Upload';
|
||||
import { WangEditor } from '@jeesite/core/components/WangEditor';
|
||||
import { useQuery } from '@jeesite/core/hooks/web/usePage';
|
||||
import { useTabs } from '@jeesite/core/hooks/web/useTabs';
|
||||
import { CheckboxGroup } from '@jeesite/core/components/Form';
|
||||
import { Input, Form } from 'ant-design-vue';
|
||||
|
||||
const formConfig = ref<any[]>([
|
||||
{
|
||||
label: '基础表单',
|
||||
value: 'form1',
|
||||
open: true,
|
||||
},
|
||||
{
|
||||
label: '子表列表',
|
||||
value: 'form2',
|
||||
open: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const emitter = useEmitter();
|
||||
|
||||
const { t } = useI18n('test.testData');
|
||||
const { showMessage } = useMessage();
|
||||
const { setTitle, close } = useTabs(router);
|
||||
const record = ref<TestData>({} as TestData);
|
||||
const loadingRef = ref<boolean>(false);
|
||||
const okLoadingRef = ref<boolean>(false);
|
||||
const query = useQuery();
|
||||
|
||||
const updateTabTitle = () => {
|
||||
setTitle(record.value.isNewRecord ? t('新增数据') : t('编辑数据'));
|
||||
};
|
||||
|
||||
const inputFormSchemas1: FormSchema<TestData>[] = [
|
||||
{
|
||||
label: t('单行文本'),
|
||||
field: 'testInput',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('列表选择'),
|
||||
field: 'testInput2',
|
||||
fieldLabel: 'testTextarea',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
configFile: import('./select'),
|
||||
checkbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('多行文本'),
|
||||
field: 'testTextarea',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('下拉框'),
|
||||
field: 'testSelect',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('下拉多选'),
|
||||
field: 'testSelectMultiple',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
mode: 'multiple',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('单选框'),
|
||||
field: 'testRadio',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('复选框'),
|
||||
field: 'testCheckbox',
|
||||
// component: 'CheckboxGroup',
|
||||
// componentProps: {
|
||||
// dictType: 'sys_menu_type',
|
||||
// },
|
||||
component: 'Input',
|
||||
slot: 'testCheckbox',
|
||||
},
|
||||
{
|
||||
label: t('日期选择'),
|
||||
field: 'testDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期时间'),
|
||||
field: 'testDatetime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户选择'),
|
||||
field: 'testUser.userCode',
|
||||
fieldLabel: 'testUser.userName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户列表选择'),
|
||||
field: 'testUser.userCode',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'empUserSelect',
|
||||
checkbox: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('机构选择'),
|
||||
field: 'testOffice.officeCode',
|
||||
fieldLabel: 'testOffice.officeName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('区域选择'),
|
||||
field: 'testAreaCode',
|
||||
fieldLabel: 'testAreaName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
slot: 'remarks',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('图片上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_image',
|
||||
uploadType: 'image',
|
||||
// imageMaxWidth: 1024,
|
||||
// imageMaxHeight: 768,
|
||||
// imageThumbName: '150x150.jpg',
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
// 文件上传的必填验证实例
|
||||
// rules: [
|
||||
// { required: true },
|
||||
// {
|
||||
// validator(_rule, value) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// const len = !value || value['testData_image__len'] || 0;
|
||||
// if (len == 0) reject(t('请上传图片'));
|
||||
// else resolve();
|
||||
// });
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
},
|
||||
{
|
||||
label: t('文件上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_file',
|
||||
uploadType: 'all',
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm1, formAction1] = useForm<TestData>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas1,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const inputFormSchemas2: FormSchema<TestData>[] = [
|
||||
{
|
||||
field: 'testDataChildList',
|
||||
component: 'Input',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
slot: 'testDataChildList',
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm2, formAction2] = useForm<TestData>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas2,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerTestDataChildTable, testDataChildTable] = useTable<TestDataChild>({
|
||||
actionColumn: {
|
||||
width: 60,
|
||||
actions: (record: TestDataChild) => [
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: t('是否确认删除'),
|
||||
confirm: handleTestDataChildDelete.bind(this, record),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
],
|
||||
},
|
||||
rowKey: 'id',
|
||||
pagination: false,
|
||||
bordered: true,
|
||||
size: 'small',
|
||||
inset: true,
|
||||
});
|
||||
|
||||
async function setTestDataChildTableData(_res: Recordable) {
|
||||
testDataChildTable.setColumns([
|
||||
{
|
||||
title: t('单行文本'),
|
||||
dataIndex: 'testInput',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editRule: true,
|
||||
},
|
||||
{
|
||||
title: t('多行文本'),
|
||||
dataIndex: 'testTextarea',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉框'),
|
||||
dataIndex: 'testSelect',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉多选'),
|
||||
dataIndex: 'testSelectMultiple',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
mode: 'multiple',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期选择'),
|
||||
dataIndex: 'testDate',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期时间'),
|
||||
dataIndex: 'testDatetime',
|
||||
width: 215,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('用户选择'),
|
||||
dataIndex: 'testUser.userCode',
|
||||
dataLabel: 'testUser.userName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('机构选择'),
|
||||
dataIndex: 'testOffice.officeCode',
|
||||
dataLabel: 'testOffice.officeName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('区域选择'),
|
||||
dataIndex: 'testAreaCode',
|
||||
dataLabel: 'testAreaName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: areaTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('文件上传'),
|
||||
dataIndex: 'upload',
|
||||
width: 160,
|
||||
align: 'left',
|
||||
slot: 'testDataChildUpload',
|
||||
},
|
||||
]);
|
||||
testDataChildTable.setTableData(record.value.testDataChildList || []);
|
||||
}
|
||||
|
||||
function handleTestDataChildRowClick(record: Recordable) {
|
||||
record.onEdit?.(true, false);
|
||||
}
|
||||
|
||||
function handleTestDataChildAdd() {
|
||||
testDataChildTable.insertTableDataRecord({
|
||||
id: new Date().getTime(),
|
||||
isNewRecord: true,
|
||||
editable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function handleTestDataChildDelete(record: Recordable) {
|
||||
testDataChildTable.deleteTableDataRecord(record);
|
||||
}
|
||||
|
||||
async function getTestDataChildList() {
|
||||
let testDataChildListValid = true;
|
||||
let testDataChildList: Recordable[] = [];
|
||||
for (const record of testDataChildTable.getDataSource()) {
|
||||
if (!(await record.onEdit?.(false, true))) {
|
||||
testDataChildListValid = false;
|
||||
}
|
||||
testDataChildList.push({
|
||||
...record,
|
||||
id: !!record.isNewRecord ? '' : record.id,
|
||||
});
|
||||
}
|
||||
for (const record of testDataChildTable.getDelDataSource()) {
|
||||
if (!!record.isNewRecord) continue;
|
||||
testDataChildList.push({
|
||||
...record,
|
||||
status: '1',
|
||||
});
|
||||
}
|
||||
if (!testDataChildListValid) {
|
||||
throw { errorFields: [{ name: ['testDataChildList'] }] };
|
||||
}
|
||||
return testDataChildList;
|
||||
}
|
||||
|
||||
async function resetFields() {
|
||||
await formAction1.resetFields();
|
||||
await formAction2.resetFields();
|
||||
}
|
||||
|
||||
async function setFieldsValue(values: Recordable) {
|
||||
await formAction1.setFieldsValue(values);
|
||||
await formAction2.setFieldsValue(values);
|
||||
}
|
||||
|
||||
async function validate(): Promise<Recordable> {
|
||||
return Object.assign(await formAction1.validate(), await formAction2.validate());
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadingRef.value = true;
|
||||
await resetFields();
|
||||
const res = await testDataForm(unref(query));
|
||||
record.value = (res.testData || {}) as TestData;
|
||||
record.value.__t = new Date().getTime();
|
||||
setFieldsValue(record.value);
|
||||
setTestDataChildTableData(res);
|
||||
updateTabTitle();
|
||||
loadingRef.value = false;
|
||||
});
|
||||
|
||||
function handleClose() {
|
||||
setTimeout(close);
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
okLoadingRef.value = true;
|
||||
const data = await validate();
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
id: record.value.id,
|
||||
};
|
||||
data.testDataChildList = await getTestDataChildList();
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await testDataSave(params, data);
|
||||
showMessage(res.message);
|
||||
emitter.emit('test-testData-reload');
|
||||
handleClose();
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
okLoadingRef.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
516
web-vue/packages/test/views/test/testData/formTabs.vue
Normal file
516
web-vue/packages/test/views/test/testData/formTabs.vue
Normal file
@@ -0,0 +1,516 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'test:testData:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="70%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<Tabs v-model:activeKey="activeKey" tabPosition="left">
|
||||
<Tabs.TabPane key="1" :forceRender="true" tab="基本信息">
|
||||
<BasicForm @register="registerForm1">
|
||||
<template #remarks="{ model, field }">
|
||||
<WangEditor
|
||||
v-model:value="model[field]"
|
||||
:bizKey="record.id"
|
||||
:bizType="'testDataChild_' + field"
|
||||
:height="300"
|
||||
/>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane key="2" :forceRender="true" tab="详细信息">
|
||||
<BasicForm @register="registerForm2">
|
||||
<template #testDataChildList>
|
||||
<BasicTable @register="registerTestDataChildTable" @row-click="handleTestDataChildRowClick">
|
||||
<template #testDataChildUpload="{ record: childRecord }">
|
||||
<BasicUpload
|
||||
v-model:value="childRecord.dataMap"
|
||||
:bizKey="childRecord.id"
|
||||
:bizType="'testDataChild_file'"
|
||||
:uploadType="'all'"
|
||||
:loadTime="record.__t"
|
||||
:size="'small'"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<a-button class="mt-2" @click="handleTestDataChildAdd" v-auth="'test:testData:edit'">
|
||||
<Icon icon="i-ant-design:plus-circle-outlined" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestDataForm">
|
||||
import { ref, unref, computed, h } from 'vue';
|
||||
import { Tabs } from 'ant-design-vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicTable, useTable } from '@jeesite/core/components/Table';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { TestData, testDataSave, testDataForm } from '@jeesite/test/api/test/testData';
|
||||
import { TestDataChild } from '@jeesite/test/api/test/testDataChild';
|
||||
import { officeTreeData } from '@jeesite/core/api/sys/office';
|
||||
import { areaTreeData } from '@jeesite/core/api/sys/area';
|
||||
import { BasicUpload } from '@jeesite/core/components/Upload';
|
||||
import { WangEditor } from '@jeesite/core/components/WangEditor';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('test.testData');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<TestData>({} as TestData);
|
||||
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增数据') : t('编辑数据'),
|
||||
}));
|
||||
|
||||
const activeKey = ref<string>('1');
|
||||
|
||||
const inputFormSchemas1: FormSchema<TestData>[] = [
|
||||
{
|
||||
label: t('单行文本'),
|
||||
field: 'testInput',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: 'testInputHelpMessage',
|
||||
component: 'Text',
|
||||
render: () => h('div', { class: 'ml-4 text-gray-500' }, '这是栅格帮助信息,优点是可以对齐。'),
|
||||
},
|
||||
{
|
||||
label: t('多行文本'),
|
||||
field: 'testTextarea',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
suffix: h('div', { class: 'ml-4 text-gray-500' }, 'Suffix帮助信息,优点是自由嵌入组件后。'),
|
||||
rules: [{ required: true }],
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('下拉框'),
|
||||
field: 'testSelect',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('下拉多选'),
|
||||
field: 'testSelectMultiple',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
mode: 'multiple',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('单选框'),
|
||||
field: 'testRadio',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('复选框'),
|
||||
field: 'testCheckbox',
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期选择'),
|
||||
field: 'testDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期时间'),
|
||||
field: 'testDatetime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户选择'),
|
||||
field: 'testUser.userCode',
|
||||
fieldLabel: 'testUser.userName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户列表选择'),
|
||||
field: 'testUser.userCode',
|
||||
component: 'ListSelect',
|
||||
componentProps: {
|
||||
selectType: 'empUserSelect',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('机构选择'),
|
||||
field: 'testOffice.officeCode',
|
||||
fieldLabel: 'testOffice.officeName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('区域选择'),
|
||||
field: 'testAreaCode',
|
||||
fieldLabel: 'testAreaName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
slot: 'remarks',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
];
|
||||
const inputFormSchemas2: FormSchema<TestData>[] = [
|
||||
{
|
||||
label: t('图片上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_image',
|
||||
uploadType: 'image',
|
||||
},
|
||||
suffix: [
|
||||
h('div', { class: 'ml-4 text-gray-500' }, '请上传图片格式,文件小于 5 M。'),
|
||||
h('a', { href: 'https://jeesite.com', target: '_blank', class: 'mr-8' }, '查看模板'),
|
||||
],
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('文件上传'),
|
||||
field: 'dataMap',
|
||||
component: 'Upload',
|
||||
componentProps: {
|
||||
loadTime: computed(() => record.value.__t),
|
||||
bizKey: computed(() => record.value.id),
|
||||
bizType: 'testData_file',
|
||||
uploadType: 'all',
|
||||
},
|
||||
suffix: [
|
||||
h('div', { class: 'ml-4 text-gray-500' }, '请上传文档格式,文件小于 5 M。'),
|
||||
h('a', { href: 'https://jeesite.com', target: '_blank', class: 'mr-8' }, '查看模板'),
|
||||
],
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
{
|
||||
label: t('子表数据'),
|
||||
field: 'testDataChildList',
|
||||
component: 'Input',
|
||||
colProps: { md: 24, lg: 24 },
|
||||
slot: 'testDataChildList',
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm1, formAction1] = useForm<TestData>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas1,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerForm2, formAction2] = useForm<TestData>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas2,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
async function resetFields() {
|
||||
activeKey.value = '1';
|
||||
await formAction1.resetFields();
|
||||
await formAction2.resetFields();
|
||||
}
|
||||
|
||||
async function setFieldsValue(values: Recordable) {
|
||||
await formAction1.setFieldsValue(values);
|
||||
await formAction2.setFieldsValue(values);
|
||||
}
|
||||
|
||||
async function validate(): Promise<Recordable> {
|
||||
return Object.assign(await formAction1.validate(), await formAction2.validate());
|
||||
}
|
||||
|
||||
const [registerTestDataChildTable, testDataChildTable] = useTable<TestDataChild>({
|
||||
actionColumn: {
|
||||
width: 60,
|
||||
actions: (record: Recordable) => [
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: t('是否确认删除'),
|
||||
confirm: handleTestDataChildDelete.bind(this, record),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
],
|
||||
},
|
||||
rowKey: 'id',
|
||||
pagination: false,
|
||||
bordered: true,
|
||||
size: 'small',
|
||||
inset: true,
|
||||
scroll: { x: 1000 },
|
||||
});
|
||||
|
||||
async function setTestDataChildTableData(_res: Recordable) {
|
||||
testDataChildTable.setColumns([
|
||||
{
|
||||
title: t('单行文本'),
|
||||
dataIndex: 'testInput',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editRule: true,
|
||||
},
|
||||
{
|
||||
title: t('多行文本'),
|
||||
dataIndex: 'testTextarea',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'Input',
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉框'),
|
||||
dataIndex: 'testSelect',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('下拉多选'),
|
||||
dataIndex: 'testSelectMultiple',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
dictType: 'sys_menu_type',
|
||||
editRow: true,
|
||||
editComponent: 'Select',
|
||||
editComponentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
mode: 'multiple',
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期选择'),
|
||||
dataIndex: 'testDate',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('日期时间'),
|
||||
dataIndex: 'testDatetime',
|
||||
width: 215,
|
||||
align: 'center',
|
||||
editRow: true,
|
||||
editComponent: 'DatePicker',
|
||||
editComponentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('用户选择'),
|
||||
dataIndex: 'testUser.userCode',
|
||||
dataLabel: 'testUser.userName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('机构选择'),
|
||||
dataIndex: 'testOffice.officeCode',
|
||||
dataLabel: 'testOffice.officeName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: officeTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('区域选择'),
|
||||
dataIndex: 'testAreaCode',
|
||||
dataLabel: 'testAreaName',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
editRow: true,
|
||||
editComponent: 'TreeSelect',
|
||||
editComponentProps: {
|
||||
api: areaTreeData,
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
editRule: false,
|
||||
},
|
||||
{
|
||||
title: t('文件上传'),
|
||||
dataIndex: 'upload',
|
||||
width: 160,
|
||||
align: 'left',
|
||||
slot: 'testDataChildUpload',
|
||||
},
|
||||
]);
|
||||
testDataChildTable.setTableData(record.value.testDataChildList || []);
|
||||
}
|
||||
|
||||
function handleTestDataChildRowClick(record: Recordable) {
|
||||
record.onEdit?.(true, false);
|
||||
}
|
||||
|
||||
function handleTestDataChildAdd() {
|
||||
testDataChildTable.insertTableDataRecord({
|
||||
id: new Date().getTime(),
|
||||
isNewRecord: true,
|
||||
editable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function handleTestDataChildDelete(record: Recordable) {
|
||||
testDataChildTable.deleteTableDataRecord(record);
|
||||
}
|
||||
|
||||
async function getTestDataChildList() {
|
||||
let testDataChildListValid = true;
|
||||
let testDataChildList: Recordable[] = [];
|
||||
for (const record of testDataChildTable.getDataSource()) {
|
||||
if (!(await record.onEdit?.(false, true))) {
|
||||
testDataChildListValid = false;
|
||||
}
|
||||
testDataChildList.push({
|
||||
...record,
|
||||
id: !!record.isNewRecord ? '' : record.id,
|
||||
});
|
||||
}
|
||||
for (const record of testDataChildTable.getDelDataSource()) {
|
||||
if (!!record.isNewRecord) continue;
|
||||
testDataChildList.push({
|
||||
...record,
|
||||
status: '1',
|
||||
});
|
||||
}
|
||||
if (!testDataChildListValid) {
|
||||
throw { errorFields: [{ name: ['testDataChildList'] }] };
|
||||
}
|
||||
return testDataChildList;
|
||||
}
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await testDataForm(data);
|
||||
record.value = (res.testData || {}) as TestData;
|
||||
record.value.__t = new Date().getTime();
|
||||
setFieldsValue(record.value);
|
||||
setTestDataChildTableData(res);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
id: record.value.id,
|
||||
};
|
||||
data.testDataChildList = await getTestDataChildList();
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await testDataSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
505
web-vue/packages/test/views/test/testData/list.vue
Normal file
505
web-vue/packages/test/views/test/testData/list.vue
Normal file
@@ -0,0 +1,505 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'test:testData:edit'">
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #firstColumn="{ record }">
|
||||
<a @click="handleForm({ id: record.id })">
|
||||
{{ record.testInput }}
|
||||
</a>
|
||||
</template>
|
||||
<template #expandedRowRender="{ record }">
|
||||
<div>编号: {{ record.id }}(这里生成内容自定义,也可以加载子表)</div>
|
||||
</template>
|
||||
<template #customFilterIcon="filter">
|
||||
<Icon icon="i-ant-design:search-outlined" :style="{ color: filter.filtered ? '#108ee9' : undefined }" />
|
||||
</template>
|
||||
<template #customFilterDropdown="filter">
|
||||
<div class="p-2" v-if="filter.column.dataIndex == 'testInput'">
|
||||
<a-input
|
||||
ref="searchInput"
|
||||
:placeholder="t('搜索单行文本')"
|
||||
:value="filter.selectedKeys[0]"
|
||||
class="!w-168px !mb-8px !block"
|
||||
@change="(e: any) => filter.setSelectedKeys(e.target.value ? [e.target.value] : [])"
|
||||
/>
|
||||
<a-button type="primary" size="small" class="mr-2 w-20" @click="filter.confirm()">
|
||||
{{ t('确定') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
size="small"
|
||||
class="w-20"
|
||||
@click="
|
||||
filter.clearFilters();
|
||||
filter.confirm();
|
||||
"
|
||||
>
|
||||
{{ t('重置') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
<InputFormTabs @register="registerDrawerTabs" @success="handleSuccess" />
|
||||
<InputFormModal @register="registerModal" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestDataList">
|
||||
import { unref, h } from 'vue';
|
||||
import { useEmitter } from '@jeesite/core/store/modules/user';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { useGo } from '@jeesite/core/hooks/web/usePage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { TestData, testDataDelete, testDataListData } from '@jeesite/test/api/test/testData';
|
||||
import { testDataDisable, testDataEnable } from '@jeesite/test/api/test/testData';
|
||||
import { officeTreeData } from '@jeesite/core/api/sys/office';
|
||||
import { areaTreeData } from '@jeesite/core/api/sys/area';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { useModal } from '@jeesite/core/components/Modal';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import InputForm from './form.vue';
|
||||
import InputFormTabs from './formTabs.vue';
|
||||
import InputFormModal from './formModal.vue';
|
||||
// import { dateUtil, formatToDateTime } from '@jeesite/core/utils/dateUtil';
|
||||
|
||||
const emitter = useEmitter();
|
||||
|
||||
const { t } = useI18n('test.testData');
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const { showMessage } = useMessage();
|
||||
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: meta.title || t('数据管理'),
|
||||
};
|
||||
const go = useGo();
|
||||
|
||||
const searchForm: FormProps<TestData> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('单行文本'),
|
||||
field: 'testInput',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('多行文本'),
|
||||
field: 'testTextarea',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('下拉框'),
|
||||
field: 'testSelect',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('下拉多选'),
|
||||
field: 'testSelectMultiple',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
allowClear: true,
|
||||
mode: 'multiple',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('单选框'),
|
||||
field: 'testRadio',
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('复选框'),
|
||||
field: 'testCheckbox',
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期选择起'),
|
||||
field: 'testDate_gte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
// defaultValue: dateUtil(new Date()),
|
||||
// defaultValue: formatToDateTime(new Date()),
|
||||
// defaultValue: '2024-05-31',
|
||||
},
|
||||
{
|
||||
label: t('日期选择止'),
|
||||
field: 'testDate_lte',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
showTime: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户选择'),
|
||||
field: 'testUser.userCode',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('机构选择'),
|
||||
field: 'testOffice.officeCode',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('区域选择'),
|
||||
field: 'testAreaCode',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('状态'),
|
||||
field: 'status',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_search_status',
|
||||
allowClear: true,
|
||||
onChange: handleSuccess,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('日期时间'),
|
||||
field: 'dateRange',
|
||||
component: 'RangePicker',
|
||||
},
|
||||
],
|
||||
fieldMapToTime: [['dateRange', ['testDatetime_gte', 'testDatetime_lte']]],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<TestData>[] = [
|
||||
{
|
||||
// title: t('单行文本'),
|
||||
// title: h('font', { color: '#f00' }, '单行文本'),
|
||||
title: [h('font', { color: '#cf0202' }, '单行'), h('font', { color: '#25b110' }, '文本')],
|
||||
dataIndex: 'testInput',
|
||||
key: 'a.test_input',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
slot: 'firstColumn',
|
||||
// 方式一:简单配置过滤窗口
|
||||
// filters: [
|
||||
// { text: 'Male', value: '1' },
|
||||
// { text: 'Female', value: '2' },
|
||||
// ],
|
||||
// filterMultiple: true,
|
||||
// onFilter: (value: any, record: TestData) => {
|
||||
// console.log('onFilter', value, record);
|
||||
// return record.userName === value;
|
||||
// },
|
||||
// 方式一:简单配置过滤窗口
|
||||
customFilterDropdown: true,
|
||||
},
|
||||
{
|
||||
title: t('多行文本'),
|
||||
dataIndex: 'testTextarea',
|
||||
key: 'a.test_textarea',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
// 根据数据状态改变单元格的颜色(例子)
|
||||
customCell: (record: Recordable) => {
|
||||
const color = record.status === '2' ? '#f8d8d8' : '';
|
||||
return {
|
||||
// innerHTML: record.testTextarea, // 原样输出,不进行html编码(例子)
|
||||
style: `background-color: ${color} !important`,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('下拉框'),
|
||||
dataIndex: 'testSelect',
|
||||
key: 'a.test_select',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
{
|
||||
title: t('下拉多选'),
|
||||
dataIndex: 'testSelectMultiple',
|
||||
key: 'a.test_select_multiple',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
{
|
||||
title: t('单选框'),
|
||||
dataIndex: 'testRadio',
|
||||
key: 'a.test_radio',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
{
|
||||
title: t('复选框'),
|
||||
dataIndex: 'testCheckbox',
|
||||
key: 'a.test_checkbox',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_menu_type',
|
||||
},
|
||||
{
|
||||
title: t('日期选择'),
|
||||
dataIndex: 'testDate',
|
||||
key: 'a.test_date',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('日期时间'),
|
||||
dataIndex: 'testDatetime',
|
||||
key: 'a.test_datetime',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('用户选择'),
|
||||
dataIndex: 'testUser.userName',
|
||||
key: 'a.test_user_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('机构选择'),
|
||||
dataIndex: 'testOffice.officeName',
|
||||
key: 'a.test_office_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('区域选择'),
|
||||
dataIndex: 'testAreaName',
|
||||
key: 'a.test_area_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('状态'),
|
||||
dataIndex: 'status',
|
||||
key: 'a.status',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_status',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateDate',
|
||||
key: 'a.update_date',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('备注信息'),
|
||||
dataIndex: 'remarks',
|
||||
key: 'a.remarks',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<TestData> = {
|
||||
width: 250,
|
||||
actions: (record: TestData) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
title: t('抽屉模式编辑'),
|
||||
onClick: handleForm.bind(this, { id: record.id }),
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-clarity:timeline-line',
|
||||
title: t('表单页签编辑'),
|
||||
onClick: handleFormTabs.bind(this, { id: record.id }),
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:file-markdown-outlined',
|
||||
title: t('弹窗模式编辑'),
|
||||
onClick: handleFormModal.bind(this, { id: record.id }),
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:layout-outlined',
|
||||
title: t('路由模式编辑'),
|
||||
onClick: handleFormRoute.bind(this, { id: record.id }),
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:stop-outlined',
|
||||
color: 'error',
|
||||
title: t('停用数据'),
|
||||
popConfirm: {
|
||||
title: t('是否确认停用数据'),
|
||||
confirm: handleDisable.bind(this, { id: record.id }),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
ifShow: () => record.status === '0',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:check-circle-outlined',
|
||||
color: 'success',
|
||||
title: t('启用数据'),
|
||||
popConfirm: {
|
||||
title: t('是否确认启用数据'),
|
||||
confirm: handleEnable.bind(this, { id: record.id }),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
ifShow: () => record.status === '2',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除数据'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除数据'),
|
||||
confirm: handleDelete.bind(this, { id: record.id }),
|
||||
},
|
||||
auth: 'test:testData:edit',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const [registerDrawerTabs, { openDrawer: openDrawerTabs }] = useDrawer();
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const [registerTable, { reload /*, getForm*/ }] = useTable<TestData>({
|
||||
api: testDataListData,
|
||||
beforeFetch: (params) => {
|
||||
// 查询前增加默认条件(例子)
|
||||
// params.testDate_gte = '2022-05-31';
|
||||
// getForm().setFieldsValue(params);
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
canResize: true,
|
||||
// 设置为true可以通过点击行来展开 expandedRowRender 插槽(例子)
|
||||
expandRowByClick: false,
|
||||
// 给单行文本列标题上添加一个过滤按钮,提交到后台过滤(例子)
|
||||
filterFn: (data: Partial<Recordable<string[]>>) => {
|
||||
const testInput = 'a.test_input';
|
||||
if (data[testInput]) {
|
||||
data['testInput'] = data[testInput]?.join(',') as any;
|
||||
delete data[testInput];
|
||||
}
|
||||
console.log(data);
|
||||
return data;
|
||||
},
|
||||
// 根据数据状态改变行的颜色(例子)
|
||||
rowClassName: (record: Recordable) => {
|
||||
return record.status === '2' ? 'table-tr-red' : '';
|
||||
},
|
||||
});
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
function handleFormTabs(record: Recordable) {
|
||||
openDrawerTabs(true, record);
|
||||
}
|
||||
|
||||
function handleFormModal(record: Recordable) {
|
||||
openModal(true, record);
|
||||
}
|
||||
|
||||
function handleFormRoute(record: Recordable) {
|
||||
go({
|
||||
path: '/test/testData/formRoute',
|
||||
query: record,
|
||||
});
|
||||
}
|
||||
|
||||
async function handleDisable(record: Recordable) {
|
||||
const res = await testDataDisable(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
async function handleEnable(record: Recordable) {
|
||||
const res = await testDataEnable(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const res = await testDataDelete(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
emitter.on('test-testData-reload', reload, true);
|
||||
</script>
|
||||
<style lang="less">
|
||||
.table-tr-red {
|
||||
td {
|
||||
background-color: #fde7e7 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
242
web-vue/packages/test/views/test/testData/select.ts
Normal file
242
web-vue/packages/test/views/test/testData/select.ts
Normal file
@@ -0,0 +1,242 @@
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { BasicColumn, BasicTableProps, FormProps } from '@jeesite/core/components/Table';
|
||||
import { TestData, testDataListData } from '@jeesite/test/api/test/testData';
|
||||
|
||||
const { t } = useI18n('sys.testData');
|
||||
|
||||
const modalProps = {
|
||||
title: t('测试数据选择'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps<TestData> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('单行文本'),
|
||||
field: 'testInput',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('多行文本'),
|
||||
field: 'testTextarea',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('下拉框'),
|
||||
field: 'testSelect',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('下拉多选'),
|
||||
field: 'testSelectMultiple',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('单选框'),
|
||||
field: 'testRadio',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('复选框'),
|
||||
field: 'testCheckbox',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('日期选择'),
|
||||
field: 'testDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('日期时间'),
|
||||
field: 'testDatetime',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD HH:mm',
|
||||
showTime: { format: 'HH:mm' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('用户选择'),
|
||||
field: 'testUserCode',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('机构选择'),
|
||||
field: 'testOfficeCode',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('区域选择'),
|
||||
field: 'testAreaCode',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('区域名称'),
|
||||
field: 'testAreaName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('状态'),
|
||||
field: 'status',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_search_status',
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'Input',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<TestData>[] = [
|
||||
{
|
||||
title: t('单行文本'),
|
||||
dataIndex: 'testInput',
|
||||
key: 'a.test_input',
|
||||
sorter: true,
|
||||
width: 230,
|
||||
align: 'left',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
// {
|
||||
// title: t('多行文本'),
|
||||
// dataIndex: 'testTextarea',
|
||||
// key: 'a.test_textarea',
|
||||
// sorter: true,
|
||||
// width: 130,
|
||||
// align: 'left',
|
||||
// },
|
||||
{
|
||||
title: t('下拉框'),
|
||||
dataIndex: 'testSelect',
|
||||
key: 'a.test_select',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('下拉多选'),
|
||||
dataIndex: 'testSelectMultiple',
|
||||
key: 'a.test_select_multiple',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('单选框'),
|
||||
dataIndex: 'testRadio',
|
||||
key: 'a.test_radio',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('复选框'),
|
||||
dataIndex: 'testCheckbox',
|
||||
key: 'a.test_checkbox',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('日期选择'),
|
||||
dataIndex: 'testDate',
|
||||
key: 'a.test_date',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('日期时间'),
|
||||
dataIndex: 'testDatetime',
|
||||
key: 'a.test_datetime',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('用户选择'),
|
||||
dataIndex: 'testUserCode',
|
||||
key: 'a.test_user_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('机构选择'),
|
||||
dataIndex: 'testOfficeCode',
|
||||
key: 'a.test_office_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('区域选择'),
|
||||
dataIndex: 'testAreaCode',
|
||||
key: 'a.test_area_code',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('区域名称'),
|
||||
dataIndex: 'testAreaName',
|
||||
key: 'a.test_area_name',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: t('状态'),
|
||||
dataIndex: 'status',
|
||||
key: 'a.status',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_search_status',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateDate',
|
||||
key: 'a.update_date',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('备注信息'),
|
||||
dataIndex: 'remarks',
|
||||
key: 'a.remarks',
|
||||
sorter: true,
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
];
|
||||
|
||||
const tableProps: BasicTableProps<TestData> = {
|
||||
api: testDataListData,
|
||||
beforeFetch: (params) => {
|
||||
params['isAll'] = true;
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
formConfig: searchForm,
|
||||
rowKey: 'id',
|
||||
};
|
||||
|
||||
export default {
|
||||
modalProps,
|
||||
tableProps,
|
||||
itemCode: 'id',
|
||||
itemName: 'testInput',
|
||||
isShowCode: false,
|
||||
};
|
||||
153
web-vue/packages/test/views/test/testTree/form.vue
Normal file
153
web-vue/packages/test/views/test/testTree/form.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'test:testTree:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="70%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestTreeForm">
|
||||
import { ref, unref, computed } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '@jeesite/core/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '@jeesite/core/components/Drawer';
|
||||
import { TestTree, testTreeSave, testTreeForm, testTreeTreeData } from '@jeesite/test/api/test/testTree';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('test.testTree');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const record = ref<TestTree>({} as TestTree);
|
||||
const getTitle = computed(() => ({
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增数据') : t('编辑数据'),
|
||||
}));
|
||||
|
||||
const inputFormSchemas: FormSchema<TestTree>[] = [
|
||||
{
|
||||
label: t('上级数据'),
|
||||
field: 'parentCode',
|
||||
fieldLabel: 'parentName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('节点编码'),
|
||||
field: 'treeCode',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 64,
|
||||
},
|
||||
rules: [{ required: true }, { pattern: /^[a-zA-Z0-9_]*$/, message: t('请输入字母数字下划线') }],
|
||||
},
|
||||
{
|
||||
label: t('节点名称'),
|
||||
field: 'treeName',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
maxlength: 200,
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('排序号'),
|
||||
field: 'treeSort',
|
||||
helpMessage: '升序',
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
maxlength: 10,
|
||||
},
|
||||
defaultValue: '30',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
maxlength: 500,
|
||||
},
|
||||
colProps: { md: 24, lg: 24 },
|
||||
},
|
||||
];
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm<TestTree>({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
baseColProps: { md: 24, lg: 12 },
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
setDrawerProps({ loading: true });
|
||||
await resetFields();
|
||||
const res = await testTreeForm(data);
|
||||
record.value = (res.testTree || {}) as TestTree;
|
||||
if (data.parentCode && data.parentName) {
|
||||
record.value.parentCode = data.parentCode;
|
||||
record.value.parentName = data.parentName;
|
||||
}
|
||||
setFieldsValue(record.value);
|
||||
updateSchema([
|
||||
{
|
||||
field: 'parentCode',
|
||||
componentProps: {
|
||||
api: testTreeTreeData,
|
||||
params: {
|
||||
excludeCode: record.value.id,
|
||||
isShowRawName: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'treeCode',
|
||||
componentProps: {
|
||||
disabled: !record.value.isNewRecord,
|
||||
},
|
||||
},
|
||||
]);
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
treeCode: record.value.treeCode,
|
||||
};
|
||||
data.oldParentCode = record.value.parentCode;
|
||||
// console.log('submit', params, data, record);
|
||||
const res = await testTreeSave(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
if (error && error.errorFields) {
|
||||
showMessage(error.message || t('common.validateError'));
|
||||
}
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
32
web-vue/packages/test/views/test/testTree/index.vue
Normal file
32
web-vue/packages/test/views/test/testTree/index.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<PageWrapper :sidebarWidth="230">
|
||||
<template #sidebar>
|
||||
<BasicTree
|
||||
:title="t('数据')"
|
||||
:search="true"
|
||||
:toolbar="true"
|
||||
:showIcon="true"
|
||||
:api="testTreeTreeData"
|
||||
:defaultExpandLevel="2"
|
||||
v-model:selectedKeys="treeCodes"
|
||||
/>
|
||||
</template>
|
||||
<ListView v-model:treeCodes="treeCodes" />
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestTreeIndex">
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { PageWrapper } from '@jeesite/core/components/Page';
|
||||
import { BasicTree } from '@jeesite/core/components/Tree';
|
||||
import { testTreeTreeData } from '@jeesite/test/api/test/testTree';
|
||||
import ListView from './list.vue';
|
||||
|
||||
const { t } = useI18n('sys.testTree');
|
||||
const treeCodes = ref<string[]>([]);
|
||||
</script>
|
||||
240
web-vue/packages/test/views/test/testTree/list.vue
Normal file
240
web-vue/packages/test/views/test/testTree/list.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable" @fetch-success="fetchSuccess">
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button @click="expandAll" :title="t('展开一级')">
|
||||
<Icon icon="i-bi:chevron-double-down" /> {{ t('展开') }}
|
||||
</a-button>
|
||||
<a-button @click="collapseAll" :title="t('折叠全部')">
|
||||
<Icon icon="i-bi:chevron-double-up" /> {{ t('折叠') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'test:testTree:edit'">
|
||||
<Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #firstColumn="{ record }">
|
||||
<span class="cursor-pointer" @click="expandCollapse(record)"> ( {{ record.treeCode }} ) </span>
|
||||
<a @click="handleForm({ treeCode: record.treeCode })">
|
||||
{{ record.treeName }}
|
||||
</a>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="ViewsTestTestTreeList">
|
||||
import { watch, nextTick, unref } from 'vue';
|
||||
import { useI18n } from '@jeesite/core/hooks/web/useI18n';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { router } from '@jeesite/core/router';
|
||||
import { Icon } from '@jeesite/core/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '@jeesite/core/components/Table';
|
||||
import { TestTree, testTreeDelete, testTreeListData } from '@jeesite/test/api/test/testTree';
|
||||
import { testTreeDisable, testTreeEnable } from '@jeesite/test/api/test/testTree';
|
||||
import { useDrawer } from '@jeesite/core/components/Drawer';
|
||||
import { FormProps } from '@jeesite/core/components/Form';
|
||||
import { isEmpty } from '@jeesite/core/utils/is';
|
||||
import InputForm from './form.vue';
|
||||
|
||||
const props = defineProps({
|
||||
treeCodes: Array as PropType<String[]>,
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:treeCodes']);
|
||||
|
||||
const { t } = useI18n('test.testTree');
|
||||
const { showMessage } = useMessage();
|
||||
const { meta } = unref(router.currentRoute);
|
||||
const getTitle = {
|
||||
icon: meta.icon || 'ant-design:book-outlined',
|
||||
value: meta.title || t('数据管理'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps<TestTree> = {
|
||||
baseColProps: { md: 8, lg: 6 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
{
|
||||
label: t('节点名称'),
|
||||
field: 'treeName',
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
label: t('状态'),
|
||||
field: 'status',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: 'sys_search_status',
|
||||
allowClear: true,
|
||||
onChange: handleSuccess,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('备注信息'),
|
||||
field: 'remarks',
|
||||
component: 'Input',
|
||||
},
|
||||
],
|
||||
resetFunc: async () => {
|
||||
emit('update:treeCodes', []);
|
||||
},
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn<TestTree>[] = [
|
||||
{
|
||||
title: t('节点名称'),
|
||||
dataIndex: 'treeName',
|
||||
width: 230,
|
||||
align: 'left',
|
||||
slot: 'firstColumn',
|
||||
},
|
||||
{
|
||||
title: t('排序号'),
|
||||
dataIndex: 'treeSort',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('状态'),
|
||||
dataIndex: 'status',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
dictType: 'sys_status',
|
||||
},
|
||||
{
|
||||
title: t('更新时间'),
|
||||
dataIndex: 'updateDate',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: t('备注信息'),
|
||||
dataIndex: 'remarks',
|
||||
width: 130,
|
||||
align: 'left',
|
||||
},
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn<TestTree> = {
|
||||
width: 160,
|
||||
actions: (record: TestTree) => [
|
||||
{
|
||||
icon: 'i-clarity:note-edit-line',
|
||||
title: t('编辑数据'),
|
||||
onClick: handleForm.bind(this, { treeCode: record.treeCode }),
|
||||
auth: 'test:testTree:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:stop-outlined',
|
||||
color: 'error',
|
||||
title: t('停用数据'),
|
||||
popConfirm: {
|
||||
title: t('是否确认停用数据'),
|
||||
confirm: handleDisable.bind(this, record),
|
||||
},
|
||||
auth: 'test:testTree:edit',
|
||||
ifShow: () => record.status === '0',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:check-circle-outlined',
|
||||
color: 'success',
|
||||
title: t('启用数据'),
|
||||
popConfirm: {
|
||||
title: t('是否确认启用数据'),
|
||||
confirm: handleEnable.bind(this, record),
|
||||
},
|
||||
auth: 'test:testTree:edit',
|
||||
ifShow: () => record.status === '2',
|
||||
},
|
||||
{
|
||||
icon: 'i-ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除数据'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除数据'),
|
||||
confirm: handleDelete.bind(this, record),
|
||||
},
|
||||
auth: 'test:testTree:edit',
|
||||
},
|
||||
{
|
||||
icon: 'i-fluent:add-circle-24-regular',
|
||||
title: t('新增下级数据'),
|
||||
onClick: handleForm.bind(this, {
|
||||
parentCode: record.treeCode,
|
||||
parentName: record.treeName,
|
||||
}),
|
||||
auth: 'test:testTree:edit',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const [registerTable, { reload, expandAll, collapseAll, expandCollapse }] = useTable<TestTree>({
|
||||
api: testTreeListData,
|
||||
beforeFetch: (params) => {
|
||||
params.id = !isEmpty(props.treeCodes) ? props.treeCodes[0] : '';
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
isTreeTable: true,
|
||||
pagination: false,
|
||||
canResize: true,
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.treeCodes,
|
||||
() => {
|
||||
if (!isEmpty(props.treeCodes)) {
|
||||
reload();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function fetchSuccess() {
|
||||
if (!isEmpty(props.treeCodes)) {
|
||||
nextTick(expandAll);
|
||||
}
|
||||
}
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
|
||||
async function handleDisable(record: Recordable) {
|
||||
const params = { treeCode: record.treeCode };
|
||||
const res = await testTreeDisable(params);
|
||||
showMessage(res.message);
|
||||
handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleEnable(record: Recordable) {
|
||||
const params = { treeCode: record.treeCode };
|
||||
const res = await testTreeEnable(params);
|
||||
showMessage(res.message);
|
||||
handleSuccess(record);
|
||||
}
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const params = { treeCode: record.treeCode };
|
||||
const res = await testTreeDelete(params);
|
||||
showMessage(res.message);
|
||||
handleSuccess(record);
|
||||
}
|
||||
|
||||
function handleSuccess(record: Recordable) {
|
||||
reload({ record });
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user