Commit b51d407d authored by liwei's avatar liwei

Merge remote-tracking branch 'origin/master'

parents 01e4d1a7 13b6cb6a
...@@ -34,7 +34,7 @@ export const columns: BasicColumn[] = [ ...@@ -34,7 +34,7 @@ export const columns: BasicColumn[] = [
dataIndex: 'originalPrincipal', dataIndex: 'originalPrincipal',
slots: { customRender: 'originalPrincipal' }, slots: { customRender: 'originalPrincipal' },
width: 150, width: 150,
} },
]; ];
export const searchFormSchema: FormSchema[] = [ export const searchFormSchema: FormSchema[] = [
{ {
...@@ -104,6 +104,104 @@ export const MoveFormSchema: any[] = [ ...@@ -104,6 +104,104 @@ export const MoveFormSchema: any[] = [
}, },
]; ];
/**存储管理*/
export const StorageSchema: FormSchema[] = [
{
field: 'isStorage',
label: '存储主体问题数据明细',
component: 'Checkbox',
colProps: { lg: 12, md: 24 },
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
formActionType.updateSchema([{ field: 'isStorageInHDFS', ifShow: formModel.isStorage }]);
formActionType.updateSchema([{ field: 'handle', ifShow: formModel.isStorage }]);
formActionType.updateSchema([{ field: 'isAutoClear', ifShow: formModel.isStorage }]);
formActionType.updateSchema([{ field: 'clear', ifShow: formModel.isStorage }]);
formActionType.updateSchema([{ field: 'divider', ifShow: formModel.isStorage }]);
},
}),
},
{
field: 'isStorageInHDFS',
label: '存储到HDFS',
labelWidth: 85,
component: 'Checkbox',
colProps: { lg: 12, md: 24 },
ifShow: false,
},
{
field: 'handle',
label: '手动清理',
component: 'BasicTitle',
ifShow: false,
colProps: { lg: 24, md: 24 },
},
{
field: 'clear',
label: '清理',
component: 'Input',
labelWidth: 30,
colProps: { lg: 24, md: 24 },
ifShow: false,
slot: 'clear',
},
{
field: 'divider',
component: 'Divider',
ifShow: false,
colProps: { lg: 24, md: 24 },
},
{
field: 'isAutoClear',
label: '自动清理',
labelWidth: 70,
component: 'Checkbox',
colProps: { lg: 12, md: 24 },
ifShow: false,
componentProps: ({ formModel, formActionType }) => ({
onChange: () => {
formActionType.updateSchema([{ field: 'maxRetentionTime', ifShow: formModel.isAutoClear }]);
formActionType.updateSchema([{ field: 'inspectionCycle', ifShow: formModel.isAutoClear }]);
formActionType.updateSchema([{ field: 'inspectionTime', ifShow: formModel.isAutoClear }]);
},
}),
},
{
field: 'maxRetentionTime',
label: '最长保留时间',
component: 'Input',
colProps: { lg: 24, md: 24 },
componentProps: {
addonAfter: '天',
},
ifShow: false,
},
{
field: 'inspectionCycle',
label: '检查周期',
component: 'Select',
colProps: { lg: 24, md: 24 },
componentProps: {
options: [
{ label: '每天', value: '每天' },
{ label: '每周', value: '每周' },
{ label: '每月', value: '每月' },
{ label: '每年', value: '每年' },
],
},
ifShow: false,
},
{
field: 'inspectionTime',
label: '检查时间',
component: 'Input',
colProps: { lg: 24, md: 24 },
ifShow: false,
slot: 'isStorageInHDFS',
},
];
export const resetNameFormSchema: FormSchema[] = [ export const resetNameFormSchema: FormSchema[] = [
{ {
field: 'fileName', field: 'fileName',
...@@ -197,4 +295,3 @@ export const createTaskFormSchema: FormSchema[] = [ ...@@ -197,4 +295,3 @@ export const createTaskFormSchema: FormSchema[] = [
colProps: { lg: 24, md: 24 }, colProps: { lg: 24, md: 24 },
}, },
]; ];
...@@ -123,6 +123,10 @@ export const TreeData: any[] = [ ...@@ -123,6 +123,10 @@ export const TreeData: any[] = [
dimensionCodeColumn: 'code', dimensionCodeColumn: 'code',
questionTablePrefix: 'quailty_', questionTablePrefix: 'quailty_',
dimensionMeaningColumn: 'code', dimensionMeaningColumn: 'code',
sql:
'SELECT COUNT(*)\n' +
'FROM $(table a}\n' +
'WHERE ${column a}IS NOT NULL AND ${column a}NOT IN (${range a})',
isIndependent: true, isIndependent: true,
}, },
{ {
...@@ -157,6 +161,10 @@ export const TreeData: any[] = [ ...@@ -157,6 +161,10 @@ export const TreeData: any[] = [
holder: 'admin', holder: 'admin',
createDate: '2024-10-23 12:04:04', createDate: '2024-10-23 12:04:04',
updateDate: '2024-10-23 12:04:04', updateDate: '2024-10-23 12:04:04',
originalPrincipal: '贫困毕业生',
dimensionCodeColumn: 'code',
questionTablePrefix: 'quailty_',
dimensionMeaningColumn: 'code',
icon: 'ant-design:partition-outlined', icon: 'ant-design:partition-outlined',
}, },
{ {
...@@ -174,181 +182,13 @@ export const TreeData: any[] = [ ...@@ -174,181 +182,13 @@ export const TreeData: any[] = [
holder: 'admin', holder: 'admin',
createDate: '2024-10-23 12:04:04', createDate: '2024-10-23 12:04:04',
updateDate: '2024-10-23 12:04:04', updateDate: '2024-10-23 12:04:04',
originalPrincipal: '贫困毕业生',
dimensionCodeColumn: 'code',
questionTablePrefix: 'quailty_',
dimensionMeaningColumn: 'code',
icon: 'ant-design:partition-outlined', icon: 'ant-design:partition-outlined',
}, },
]; ];
export const DetailTreeData: any[] = [
{
delFlag: '0',
flag: '1',
businessId: 100,
fileName: '任务',
parentId: 0,
'code:': '001',
ancestors: '0',
orderNum: 0,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 101,
fileName: '代码文件',
parentId: 100,
'code:': '002',
ancestors: '0,100',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 102,
fileName: '数据处理',
parentId: 100,
'code:': '003',
ancestors: '0,100',
orderNum: 2,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 103,
fileName: '任务流',
parentId: 100,
'code:': '003',
ancestors: '0,100',
orderNum: 2,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 401,
fileName: '脚本',
parentId: 101,
'code:': '002',
ancestors: '0,100,101',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 402,
fileName: 'SQL',
parentId: 101,
'code:': '002',
ancestors: '0,100,101',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 403,
fileName: '数据加载',
parentId: 102,
'code:': '002',
ancestors: '0,100,102',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 404,
fileName: '数据同步',
parentId: 102,
'code:': '002',
ancestors: '0,100,102',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 405,
fileName: '数据质量',
parentId: 102,
'code:': '002',
ancestors: '0,100,102',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
{
delFlag: '0',
flag: '1',
businessId: 406,
fileName: '嵌套任务流',
parentId: 103,
'code:': '002',
ancestors: '0,100,103',
orderNum: 1,
// "children" : [ ],
selectType: null,
fileSize: '1024KB',
location: '位置1',
holder: 'admin',
createDate: '2024-10-24 10:04:04',
updateDate: '2024-10-24 10:04:04',
},
];
export const fileData: any[] = [ export const fileData: any[] = [
{ {
delFlag: '0', delFlag: '0',
...@@ -412,68 +252,6 @@ export const fileData: any[] = [ ...@@ -412,68 +252,6 @@ export const fileData: any[] = [
}, },
]; ];
export const addUserData: any[] = [
{
delFlag: '0',
flag: '1',
businessId: 400,
username: 'tianjia1',
nickName: '添加用户1',
userType: '1',
name: '添加用户1',
roleName: '工作区访客',
createDate: '2024-10-24 10:04:04',
institutionId: null,
institutionName: '',
code: '123f',
identity: '1',
roleIds: null,
roleNames: '三级用户',
roleList: null,
menuList: [],
},
{
delFlag: '0',
flag: '1',
businessId: 402,
username: 'tianjia2',
nickName: '添加用户2',
userType: '1',
name: '添加用户2',
roleName: '工作区访客',
createDate: '2024-10-25 10:05:05',
sex: '0',
institutionId: null,
institutionName: '',
code: '123a',
identity: '1',
roleIds: null,
roleNames: null,
roleList: null,
menuList: [],
},
{
delFlag: '0',
flag: '1',
businessId: 403,
username: 'tianjia3',
nickName: '添加用户3',
userType: '1',
name: '添加用户3',
roleName: '工作区访客',
createDate: '2024-10-26 10:06:06',
sex: '1',
institutionId: null,
institutionName: '',
code: '123c',
identity: '1',
roleIds: null,
roleNames: '超级管理员',
roleList: null,
menuList: [],
},
];
export const infoData: any[] = [ export const infoData: any[] = [
{ {
tableName: 'st', tableName: 'st',
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
<CreateFile @register="registerCreateFileModal" @success="handleAddSuccess" /> <CreateFile @register="registerCreateFileModal" @success="handleAddSuccess" />
<CreateMainBodyModal @register="registerCreateCreateMainBodyModal" @success="handleSuccess" /> <CreateMainBodyModal @register="registerCreateCreateMainBodyModal" @success="handleSuccess" />
<MainBodyEdit @register="registerMainBodyEditModal" /> <MainBodyEdit @register="registerMainBodyEditModal" />
<StorageManageModal @register="registerStorageManageModal" />
</PageWrapper> </PageWrapper>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
...@@ -78,6 +79,7 @@ ...@@ -78,6 +79,7 @@
import { router } from '@/router'; import { router } from '@/router';
import CreateMainBodyModal from '@/views/dataQuality/agentClass/mainBody/createMainBodyModal.vue'; import CreateMainBodyModal from '@/views/dataQuality/agentClass/mainBody/createMainBodyModal.vue';
import MainBodyEdit from '@/views/dataQuality/agentClass/mainBody/mainBodyEdit.vue'; import MainBodyEdit from '@/views/dataQuality/agentClass/mainBody/mainBodyEdit.vue';
import StorageManageModal from '@/views/dataQuality/agentClass/mainBody/storageManageModal.vue';
defineOptions({ name: 'AccountManagement' }); defineOptions({ name: 'AccountManagement' });
const { createMessage, createConfirm } = useMessage(); const { createMessage, createConfirm } = useMessage();
...@@ -90,6 +92,7 @@ ...@@ -90,6 +92,7 @@
useModal(); // 新建质量主体弹窗 useModal(); // 新建质量主体弹窗
const [registerCreateFileModal, { openModal: openCreateFileModal }] = useModal(); // 新建文件夹弹窗 const [registerCreateFileModal, { openModal: openCreateFileModal }] = useModal(); // 新建文件夹弹窗
const [registerMainBodyEditModal, { openModal: openMainBodyEditModal }] = useModal(); // 质量主体编辑 const [registerMainBodyEditModal, { openModal: openMainBodyEditModal }] = useModal(); // 质量主体编辑
const [registerStorageManageModal, { openModal: openStorageManageModal }] = useModal(); // 存储管理弹窗
const searchInfo = reactive<Recordable>({}); const searchInfo = reactive<Recordable>({});
const tableData = ref([]); const tableData = ref([]);
const [ const [
...@@ -243,6 +246,12 @@ ...@@ -243,6 +246,12 @@
}); });
} }
function handleSaveManage(record: Recordable) {
openStorageManageModal(true, {
record,
});
}
/** 删除按钮*/ /** 删除按钮*/
function handleDelete(record: Recordable) { function handleDelete(record: Recordable) {
tableData.value.splice( tableData.value.splice(
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
@register="registerModal" @register="registerModal"
:title="title" :title="title"
:showOkBtn="false" :showOkBtn="false"
v-model:visible="showModal"
@cancel="handleCancel" @cancel="handleCancel"
> >
<div class="mianBodyEditContainer"> <div class="mianBodyEditContainer">
...@@ -39,8 +38,14 @@ ...@@ -39,8 +38,14 @@
<div class="editor"> <div class="editor">
<textarea v-model="sql" placeholder="请输入内容..."></textarea> <textarea v-model="sql" placeholder="请输入内容..."></textarea>
</div> </div>
<a-button @click="handleRun">测试运行</a-button> <a-button type="primary" @click="handleRun">测试运行</a-button>
<div v-if="isRun"> <BasicTable @register="registerColumnInformationTable" /></div> <div v-if="isRun">
<strong>检测结果</strong>
<p>️✅包含主键</p>
<p>✅包含维度</p>
<p>✅运行结果</p>
<BasicTable @register="registerReviewTable" />
</div>
</div> </div>
</div> </div>
</a-tab-pane> </a-tab-pane>
...@@ -67,6 +72,7 @@ ...@@ -67,6 +72,7 @@
</Tabs> </Tabs>
</div> </div>
</BasicModal> </BasicModal>
<StorageManageModal @register="registerStorageManageModal" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { BasicColumn, BasicTable, useTable } from '@/components/Table'; import { BasicColumn, BasicTable, useTable } from '@/components/Table';
...@@ -78,6 +84,7 @@ ...@@ -78,6 +84,7 @@
import { useMessage } from '@/hooks/web/useMessage'; import { useMessage } from '@/hooks/web/useMessage';
import { informationData, tbData } from '@/views/metadata/metadataData'; import { informationData, tbData } from '@/views/metadata/metadataData';
import { informationColumns, tbSearchFormSchema } from '@/views/metadata/data'; import { informationColumns, tbSearchFormSchema } from '@/views/metadata/data';
import StorageManageModal from '@/views/dataQuality/agentClass/mainBody/storageManageModal.vue';
import { import {
infoData, infoData,
reviewData, reviewData,
...@@ -240,7 +247,7 @@ ...@@ -240,7 +247,7 @@
}, },
}, },
{ {
field: 'questionTablePrefix ', field: 'questionTablePrefix',
label: '问题数据表名前缀', label: '问题数据表名前缀',
required: true, required: true,
colProps: { lg: 12, md: 12 }, colProps: { lg: 12, md: 12 },
...@@ -288,18 +295,17 @@ ...@@ -288,18 +295,17 @@
span: 23, span: 23,
}, },
}); });
const [registerModal, { closeModal }] = useModalInner(async (data) => { const [registerModal, { closeModal }] = useModalInner((data) => {
resetFields();
title.value = data.record.fileName; title.value = data.record.fileName;
isIndependent.value = data.record.isIndependent; isIndependent.value = data.record.isIndependent;
// console.log('isIndependent.value', isIndependent.value); sql.value = data.record.sql;
let record = data.record; setFieldsValue({
await resetFields(); ...data.record,
await setFieldsValue({
...record,
}); });
changeAble.value = true; changeAble.value = true;
const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined); const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined);
await updateSchema([ updateSchema([
{ {
field: 'originalPrincipal', field: 'originalPrincipal',
componentProps: { componentProps: {
...@@ -315,7 +321,6 @@ ...@@ -315,7 +321,6 @@
} }
function handleRun() { function handleRun() {
changeAble.value = false;
isRun.value = true; isRun.value = true;
} }
...@@ -354,6 +359,13 @@ ...@@ -354,6 +359,13 @@
}); });
return treeData !== '' ? treeData : data; return treeData !== '' ? treeData : data;
} }
const [registerStorageManageModal, { openModal: openStorageManageModal }] = useModal(); // 存储管理弹窗
function handleStorage(record: Recordable) {
openStorageManageModal(true, {
record,
});
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.editor { .editor {
......
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
title="存储管理"
@ok="handleSubmit"
minHeight="50"
>
<BasicForm @register="registerForm">
<template #clear="{ model, field }">
<DatePicker style="width: 55%" />之前所有的执行记录
<a-button v-model="model.clear" @click="handleClear" style="margin-left: 5px" type="error"
>清理</a-button
>
</template>
<template #isStorageInHDFS="{ model, field }">
<a-input style="width: 60px; margin-right: 5px" /><a-input
style="width: 60px; margin-right: 5px"
/>
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref, reactive } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { StorageSchema } from './account.data';
import { useMessage } from '@/hooks/web/useMessage';
import { DatePicker } from 'ant-design-vue';
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
labelWidth: 160,
labelAlign: 'left',
baseColProps: { span: 24 },
schemas: StorageSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
});
/**确定按钮*/
function handleSubmit() {
createMessage.success('保存成功!');
closeModal();
}
/**确定按钮*/
function handleClear() {
createMessage.success('清理成功!');
closeModal();
}
</script>
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
title="质量主体"
ref="treeRef"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="false"
:defaultExpandAll="true"
:treeData="treeData"
:fieldNames="{ key: 'businessId', title: 'fileName' }"
@select="handleSelect"
:actionList="actionList"
/>
</div>
</template>
<script lang="ts" setup>
import { h, nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { Nullable } from '@vben/types';
import { TreeData } from '@/views/dataQuality/agentClass/mainBody/dataQualityMainBodyData';
import { useMessage } from '@/hooks/web/useMessage';
import { ReloadOutlined } from '@ant-design/icons-vue';
defineOptions({ name: 'DeptTree' });
const { createMessage } = useMessage();
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const treeRef = ref<Nullable<TreeActionType>>(null);
function getTree() {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
}
async function fetch() {
const data = TreeData;
treeData.value = handleTree(data, 'businessId', undefined, undefined, undefined);
await nextTick(() => {
getTree().expandAll(true);
});
}
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id';
parentId = parentId || 'parentId';
children = children || 'children';
rootId =
rootId ||
Math.min.apply(
Math,
data.map((item) => {
return item[parentId];
}),
) ||
0;
// 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项
const treeData = cloneData.filter((father) => {
const branchArr = cloneData.filter((child) => {
// 返回每一项的子级数组
return father[id] === child[parentId];
});
branchArr.length > 0 ? (father.children = branchArr) : '';
// 返回第一层
return father[parentId] === rootId;
});
return treeData !== '' ? treeData : data;
}
function handleSelect(keys) {
emit('select', keys[0]);
}
onMounted(() => {
fetch();
});
// 树的操作列表
const actionList = [
{
render: () => {
return h(ReloadOutlined, {
class: 'ml-2',
onClick: () => {
refresh();
},
});
},
},
];
function refresh() {
createMessage.success('刷新成功');
}
</script>
<template>
<BasicModal
width="30%"
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { useMessage } from '@/hooks/web/useMessage';
import { createFileFormSchema } from './data';
import { TreeData } from './dataQualityWhiteData';
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const isUpdate = ref(true);
const isMove = ref(false);
const rowId = ref('');
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
labelWidth: 100,
baseColProps: { lg: 12, md: 24 },
schemas: createFileFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
const formData = {
taskId: '100',
};
// 塞值
setFieldsValue({
...formData,
});
const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined);
updateSchema([
{
field: 'taskId',
componentProps: {
treeData: treeList,
},
},
]);
});
const getTitle = computed(() => '新建文件夹');
/**确定按钮*/
async function handleSubmit() {
closeModal();
}
/**数组对象转成树*/
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id';
parentId = parentId || 'parentId';
children = children || 'children';
rootId =
rootId ||
Math.min.apply(
Math,
data.map((item) => {
return item[parentId];
}),
) ||
0;
// 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项
const treeData = cloneData.filter((father) => {
const branchArr = cloneData.filter((child) => {
// 返回每一项的子级数组
return father[id] === child[parentId];
});
branchArr.length > 0 ? (father.children = branchArr) : '';
// 返回第一层
return father[parentId] === rootId;
});
return treeData !== '' ? treeData : data;
}
</script>
<template>
<BasicModal
width="40%"
v-bind="$attrs"
@register="registerModal"
:title="title"
@ok="handleSubmit"
>
<BasicForm @register="registerForm" />
<div class="modalRow">
<div>可见范围</div>
<div class="right">
<div class="clearAll"> 清空 </div>
<div>
<a-button type="primary">添加工作组</a-button>
</div>
</div>
</div>
<div class="addDialogBG">
<div style="float: right">
<Icon icon="ant-design:delete-outlined" :size="25" :color="'#ED6F6F'" />
</div>
<TreeTwo class="w-1/4 xl:w-1/5" />
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { formSchemaMain } from './data';
import TreeTwo from './treeTwo.vue';
import { useMessage } from '@/hooks/web/useMessage';
import Icon from '@/components/Icon/Icon.vue';
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const isUpdate = ref(true);
const title = ref('');
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { resetFields }] = useForm({
labelWidth: 100,
baseColProps: { lg: 24, md: 24 },
schemas: formSchemaMain,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal] = useModalInner(async (data) => {
await resetFields();
title.value = data.title;
});
async function handleSubmit() {
createMessage.success('提交成功');
}
</script>
<style lang="scss" scoped>
.modalRow {
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
.clearAll {
padding-right: 10px;
font-size: 16px;
}
.right {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.addDialogBG {
margin: 10px;
border-radius: 10px;
padding: 20px;
background-color: #e8ecf7;
width: 98%;
height: 400px;
}
</style>
import { BasicColumn, FormSchema } from '@/components/Table';
export const columns: BasicColumn[] = [
{
title: '文件名称',
dataIndex: 'fileName',
width: 150,
slots: { customRender: 'fileName' },
},
{
title: '创建时间',
dataIndex: 'createDate',
width: 150,
},
{
title: '更新时间',
dataIndex: 'updateDate',
width: 150,
},
{
title: '拥有者',
dataIndex: 'holder',
width: 150,
},
{
title: '权属工作组',
dataIndex: 'workGroupName',
width: 150,
},
];
export const searchFormSchema: FormSchema[] = [
{
field: 'name',
label: '名称',
component: 'Input',
componentProps: {
placeholder: '请输入名称',
},
colProps: { span: 7 },
},
];
export const accountFormSchema: any[] = [
{
field: 'fileName',
label: '文件名称',
component: 'Input',
colProps: { lg: 24, md: 24 },
componentProps: {
disabled: true,
},
},
{
field: 'location',
label: '保存位置',
component: 'Input',
colProps: { lg: 24, md: 24 },
componentProps: {
disabled: true,
},
},
{
field: 'createDate',
label: '创建时间',
component: 'Input',
colProps: { lg: 24, md: 24 },
componentProps: {
disabled: true,
},
},
{
field: 'updateDate',
label: '最近修改',
component: 'Input',
colProps: { lg: 24, md: 24 },
componentProps: {
disabled: true,
},
},
];
/**移动*/
export const MoveFormSchema: any[] = [
{
field: 'taskId',
label: '路径',
component: 'TreeSelect',
colProps: { lg: 24, md: 24 },
componentProps: {
fieldNames: {
label: 'fileName',
value: 'businessId',
},
getPopupContainer: () => document.body,
},
required: true,
},
];
export const resetNameFormSchema: FormSchema[] = [
{
field: 'fileName',
label: '文件名称',
component: 'Input',
rules: [
{
required: true,
message: '请输入文件名称',
},
],
componentProps: {
placeholder: '请输入文件名称',
},
colProps: { span: 8 },
},
];
export const createFileFormSchema: FormSchema[] = [
{
field: 'taskId',
label: '路径',
component: 'TreeSelect',
colProps: { lg: 24, md: 24 },
componentProps: {
fieldNames: {
label: 'fileName',
value: 'businessId',
},
getPopupContainer: () => document.body,
},
required: true,
},
{
field: 'fileName',
label: '文件名称',
component: 'Input',
colProps: { lg: 24, md: 24 },
rules: [
{
required: true,
message: '请输入文件名称',
},
],
componentProps: {
placeholder: '请输入文件名称',
},
},
];
export const createTaskFormSchema: FormSchema[] = [
{
field: 'taskId',
label: '路径',
component: 'TreeSelect',
colProps: { lg: 24, md: 24 },
componentProps: {
fieldNames: {
label: 'fileName',
value: 'businessId',
},
getPopupContainer: () => document.body,
},
required: true,
},
{
field: 'name',
label: '质量主体名称',
component: 'Input',
rules: [
{
required: true,
message: '请输入质量主体名称',
},
],
componentProps: {
placeholder: '请输入质量主体名称',
},
colProps: { lg: 24, md: 24 },
},
{
field: 'fileType',
label: '文件类型',
component: 'Input',
defaultValue: '质量主体',
componentProps: {
readonly: true,
style: {
border: 'none',
backgroundColor: 'transparent',
},
},
colProps: { lg: 24, md: 24 },
},
];
export const formSchemaMain: any = [
{
field: 'path',
label: '路径',
component: 'TreeSelect',
rules: [
{
required: true,
message: '请选择上级菜单',
},
],
componentProps: {
fieldNames: {
label: 'label',
value: 'businessId',
},
getPopupContainer: () => document.body,
},
},
{
field: 'name',
label: '主体名称',
component: 'Input',
colProps: { span: 8 },
componentProps: {
placeholder: '输入主体名称',
},
},
{
field: 'des',
label: '描述',
component: 'Input',
colProps: { span: 8 },
componentProps: {
placeholder: '输入描述',
},
},
{
field: 'fileType',
label: '文件类型',
component: 'Input',
defaultValue: '质量白名单',
colProps: { span: 8 },
componentProps: {
readOnly: true,
disabled: true,
placeholder: '输入描述',
},
},
{
field: 'menuModal',
label: '目录权属模式',
component: 'Input',
defaultValue: '资源自定义',
colProps: { span: 8 },
componentProps: {
readOnly: true,
disabled: true,
placeholder: '输入描述',
},
},
{
field: 'group',
label: '权属工作组',
component: 'Select',
defaultValue: '默认工作组',
colProps: { span: 8 },
componentProps: {
placeholder: '输入描述',
options: [{ label: '默认工作组', value: '默认工作组' }],
},
},
];
<template> <template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" />
<BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">
<template #toolbar>
<a-button type="primary" @click="handleMove">移动</a-button>
<a-button type="primary" @click="deleteButton">删除</a-button>
<a-button type="primary" @click="createFileButton">新建文件夹</a-button>
<a-button type="primary" @click="createWhite">新建白名单</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
color: 'error',
label: '删除',
popConfirm: {
title: '是否确认删除',
placement: 'left',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<MoveFile @register="registerMoveFile" />
<CreateFile @register="registerCreateFileModal" />
<CreateWhite @register="registerCreateWhiteFile" />
</PageWrapper>
</template> </template>
<script lang="ts" setup>
import { reactive, onMounted, ref } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { PageWrapper } from '@/components/Page';
import DeptTree from './FileTree.vue';
import { useMessage } from '@/hooks/web/useMessage';
import { columns, searchFormSchema } from './data';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import { useFilterStore } from '@/store/modules/filterData';
import { TreeData } from './dataQualityWhiteData';
import { useModal } from '@/components/Modal';
import MoveFile from './moveFile.vue';
import CreateFile from './createFile.vue';
import CreateWhite from './createWhiteModal.vue';
<script> defineOptions({ name: 'AccountManagement' });
export default { const { createMessage, createConfirm } = useMessage();
name: "index" const filterStore = useFilterStore();
} const route = useRoute();
</script> const searchInfo = reactive<Recordable>({});
const tableData = ref([]);
const [registerMoveFile, { openModal: openMoveFileModal }] = useModal();
const [registerCreateWhiteFile, { openModal: openCreateWhiteModal }] = useModal();
const [registerCreateFileModal, { openModal: openCreateFileModal }] = useModal(); // 新建文件夹弹窗
const [registerTable, { reload, getSearchInfo, getForm }] = useTable({
api: async (params) => {
//过滤掉tableData.value中,businessId等于100的
var data = [];
if (params.taskId == undefined || params.taskId == '') {
data = tableData.value.filter((item) => item.businessId >= 200);
} else if (params.taskId >= 200) {
data = tableData.value.filter((item) => item.businessId == params.taskId);
} else {
data = tableData.value.filter((item) => item.parentId == params.taskId);
}
const response = {
pageNu: '1',
pageSize: '10',
pages: '1',
total: data.length,
code: '',
message: '',
data: [],
};
//过滤data中的数据,取出等于params.deptId的数据
return { ...response, data: data };
},
rowKey: 'businessId',
columns,
rowSelection: true,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
resetFunc: () => {
searchInfo.taskId = '';
},
},
useSearchForm: true,
showTableSetting: false,
showIndexColumn: false,
bordered: true,
handleSearchInfoFn(info) {
return info;
},
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
},
});
/**删除按钮*/
function deleteButton() {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '确认批量删除选中数据吗?',
onOk() {
createMessage.success('删除成功!');
reload();
},
});
}
/**新建文件夹*/
function createFileButton() {
openCreateFileModal(true, {
isAdd: true,
});
}
/**新建白名单*/
function createWhite() {
openCreateWhiteModal(true, {
title: '新建文件',
});
}
<style scoped> /** 部门树的select*/
function handleSelect(taskId = '') {
searchInfo.taskId = taskId;
reload();
}
</style> /** 编辑按钮*/
function handleEdit(record: Recordable) {}
/** 删除按钮*/
function handleDelete(record: Recordable) {
tableData.value.splice(
tableData.value.findIndex((item) => item.businessId === record.businessId),
1,
);
createMessage.success('删除成功!');
reload();
}
/** 移动按钮*/
function handleMove(record: Recordable) {
openMoveFileModal(true, {
record,
isMove: true,
});
}
onMounted(() => {
tableData.value = TreeData;
const path = route.path;
if (filterStore.getSearchParams[path]) {
if (JSON.parse(filterStore.getSearchParams[path] !== {})) {
const params = JSON.parse(filterStore.getSearchParams[path]);
getForm().setFieldsValue({
page: params.page,
pageSize: params.pageSize,
username: params.username,
flag: params.flag,
});
searchInfo.institutionId = params.institutionId;
}
}
});
onBeforeRouteLeave((to, from, next) => {
const params = Object.assign({}, getSearchInfo(), getForm().getFieldsValue());
filterStore.setSearchParams({
path: from.path,
param: {
...params,
},
});
next(); // 允许导航
});
</script>
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
width="30%"
>
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { MoveFormSchema } from './data';
import { useMessage } from '@/hooks/web/useMessage';
import { TreeData } from './dataQualityWhiteData';
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage();
const isUpdate = ref(true);
const rowId = ref('');
const rowData = ref([]);
//获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: MoveFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
//初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//每次点击弹窗 需要清空存储的数据
rowData.value = [];
//重置表单数据
resetFields();
setModalProps({ confirmLoading: false });
if (data.idList != null && data.idList != undefined && data.idList.length > 0) {
} else {
rowData.value.push(data.record);
//单个移动
rowId.value = data.record.businessId;
data.record.taskId = data.record.businessId;
setFieldsValue({
...data.record,
});
}
const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined);
updateSchema([
{
field: 'taskId',
componentProps: {
treeData: treeList,
},
},
]);
console.log('treeList:', treeList);
});
const getTitle = computed(() => '移动');
/**确定按钮*/
async function handleSubmit() {
createMessage.success('移动成功!');
closeModal();
}
/**数组对象转成树*/
function handleTree(data, id, parentId, children, rootId) {
id = id || 'id';
parentId = parentId || 'parentId';
children = children || 'children';
rootId =
rootId ||
Math.min.apply(
Math,
data.map((item) => {
return item[parentId];
}),
) ||
0;
// 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项
const treeData = cloneData.filter((father) => {
const branchArr = cloneData.filter((child) => {
// 返回每一项的子级数组
return father[id] === child[parentId];
});
branchArr.length > 0 ? (father.children = branchArr) : '';
// 返回第一层
return father[parentId] === rootId;
});
return treeData !== '' ? treeData : data;
}
</script>
<template>
<div class="m-4 mr-0 overflow-hidden bg-white">
<BasicTree
title="工作组"
ref="treeRef"
toolbar
search
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
:clickRowToExpand="true"
:checkable="true"
:defaultExpandAll="true"
:treeData="treeData"
:fieldNames="{ key: 'businessId', title: 'label' }"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, unref } from 'vue';
import { BasicTree, TreeActionType, TreeItem } from '@/components/Tree';
import { Nullable } from '@vben/types';
import { treeDataListTwo } from './dataQualityWhiteData';
defineOptions({ name: 'DeptTree' });
const emit = defineEmits(['select']);
const treeData = ref<TreeItem[]>([]);
const treeRef = ref<Nullable<TreeActionType>>(null);
async function fetch() {
treeData.value = treeDataListTwo;
await nextTick(() => {
getTree().expandAll(true);
});
}
function getTree() {
const tree = unref(treeRef);
if (!tree) {
throw new Error('tree is null!');
}
return tree;
}
function handleSelect(keys) {
emit('select', keys[0]);
}
onMounted(() => {
fetch();
});
</script>
<style lang="scss" scoped>
.bg-white {
width: 97%;
}
::v-deep(.vben-tree) {
background-color: #e8ecf7 !important;
}
</style>
...@@ -36,9 +36,9 @@ export const new3Data = [ ...@@ -36,9 +36,9 @@ export const new3Data = [
{ date: '06-20', value: 11 }, { date: '06-20', value: 11 },
]; ];
export const fieldChangeData = [ export const fieldChangeData = [
{ name: '失败', value: 24 }, { name: '失败', value: 24, color: '#ea8d8d' },
{ name: '成功', value: 77 }, { name: '成功', value: 77, color: '#8ce788' },
{ name: '进行中', value: 12 }, { name: '进行中', value: 12, color: '#81c9f5' },
]; ];
export const partitionData: any[] = [ export const partitionData: any[] = [
{ {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
margin-left: 20px; margin-left: 20px;
" "
>标准概览 >标准概览
<div style="margin-left: 30px;width: 200px"> <div style="margin-left: 30px; width: 200px">
<BasicForm @register="registerForm" /> <BasicForm @register="registerForm" />
</div> </div>
</div> </div>
...@@ -190,9 +190,9 @@ ...@@ -190,9 +190,9 @@
orient: 'vertical', orient: 'vertical',
left: 'right', left: 'right',
}, },
color: fieldChangeData.map((item) => item.color),
series: [ series: [
{ {
name: '字段变更',
type: 'pie', type: 'pie',
radius: '55%', // 饼图的半径,默认情况下,内圆半径为0,外圆半径为55% radius: '55%', // 饼图的半径,默认情况下,内圆半径为0,外圆半径为55%
center: ['50%', '50%'], // 饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标 center: ['50%', '50%'], // 饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标
......
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
import { editData, historyData } from '@/views/kinship/kinshipEdit/kinshipEditData'; import { editData, historyData } from '@/views/kinship/kinshipEdit/kinshipEditData';
import { cardData } from '@/views/kinship/kinshipParse/kinshipParseData'; import { cardData } from '@/views/kinship/kinshipParse/kinshipParseData';
import Icon from '@/components/Icon/Icon.vue'; import Icon from '@/components/Icon/Icon.vue';
import {router} from "@/router"; import { router } from '@/router';
defineOptions({ name: 'AccountDetail' }); defineOptions({ name: 'AccountDetail' });
......
...@@ -48,13 +48,13 @@ export const cardData: any[] = [ ...@@ -48,13 +48,13 @@ export const cardData: any[] = [
version: 'kettle-1.0', version: 'kettle-1.0',
remark: 'kettle', remark: 'kettle',
color: 'blue', color: 'blue',
icon: 'ant-design:file-text-outlined', icon: 'material-symbols:border-color-outline-rounded',
}, },
{ {
title: 'ORACLE_SQL脚本解析', title: 'ORACLE_SQL脚本解析',
version: 'oracle_sql_1.0', version: 'oracle_sql_1.0',
remark: 'oracle_sql', remark: 'oracle_sql',
color: 'blue', color: 'blue',
icon: 'ant-design:file-text-outlined', icon: 'material-symbols:border-color-outline-rounded',
}, },
]; ];
...@@ -24,10 +24,20 @@ ...@@ -24,10 +24,20 @@
<a-button style="margin-right: 5px" type="primary" v-show="cancelType" @click="handleCancel" <a-button style="margin-right: 5px" type="primary" v-show="cancelType" @click="handleCancel"
>退出</a-button >退出</a-button
> >
<a-button style="margin-right: 5px" type="primary" @click="handleComparison" <a-button
style="margin-right: 70px"
type="primary"
v-show="!cancelType"
@click="handleComparison"
>开始对比</a-button >开始对比</a-button
> >
<a-button style="margin-right: 70px" type="primary" @click="handleImport">导出</a-button> <a-button
style="margin-right: 70px"
type="primary"
v-show="cancelType"
@click="handleImport"
>导出</a-button
>
</div> </div>
</div> </div>
<div style="display: flex"> <div style="display: flex">
...@@ -171,6 +181,7 @@ ...@@ -171,6 +181,7 @@
labelWidth: 100, labelWidth: 100,
schemas: lastSchema, schemas: lastSchema,
showActionButtonGroup: false, showActionButtonGroup: false,
disabled: cancelType,
}); });
const [registerMainTable, { reload: reloadMain }] = useTable({ const [registerMainTable, { reload: reloadMain }] = useTable({
api: async () => { api: async () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment