Commit 61392af5 authored by chenjiahao's avatar chenjiahao

数据质量-主体类-质量主体

parent 621ba672
...@@ -120,6 +120,10 @@ export const TreeData: any[] = [ ...@@ -120,6 +120,10 @@ export const TreeData: any[] = [
updateDate: '2024-10-22 8:04:04', updateDate: '2024-10-22 8:04:04',
icon: 'ant-design:partition-outlined', icon: 'ant-design:partition-outlined',
originalPrincipal: '贫困毕业生', originalPrincipal: '贫困毕业生',
dimensionCodeColumn: 'code',
questionTablePrefix: 'quailty_',
dimensionMeaningColumn: 'code',
isIndependent: true,
}, },
{ {
delFlag: '0', delFlag: '0',
...@@ -470,4 +474,165 @@ export const addUserData: any[] = [ ...@@ -470,4 +474,165 @@ export const addUserData: any[] = [
}, },
]; ];
export const infoData: any[] = [
{
tableName: 'st',
columnsName: 'user_id',
CNname: '用户ID',
type: 'INT',
length: 11,
precision: null,
isNull: 'NO',
remark: '用户的唯一标识符',
primaryKey: 'YES',
foreignKey: 'NO',
dataType: '整数型',
safeLevel: '高',
sensitiveStatus: '敏感',
isFixation: 'true',
},
{
tableName: 'st',
columnsName: 'username',
CNname: '用户名',
type: 'VARCHAR',
length: 50,
precision: null,
isNull: 'NO',
remark: '用户的登录名称',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '字符串型',
safeLevel: '中',
sensitiveStatus: '非敏感',
isFixation: 'true',
},
{
tableName: 'st',
columnsName: 'password',
CNname: '密码',
type: 'VARCHAR',
length: 100,
precision: null,
isNull: 'NO',
remark: '用户登录密码(加密存储)',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '字符串型',
safeLevel: '极高',
sensitiveStatus: '非常敏感',
isFixation: 'true',
},
{
tableName: 'st',
columnsName: 'email',
CNname: '邮箱地址',
type: 'VARCHAR',
length: 100,
precision: null,
isNull: 'YES',
remark: '用户注册邮箱地址',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '字符串型',
safeLevel: '中',
sensitiveStatus: '敏感',
isFixation: 'true',
},
{
tableName: 'st',
columnsName: 'created_at',
CNname: '创建时间',
type: 'DATETIME',
length: null,
precision: null,
isNull: 'NO',
remark: '账户创建的时间戳',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '日期时间型',
safeLevel: '低',
sensitiveStatus: '非敏感',
isFixation: 'false',
},
{
tableName: 'st',
columnsName: 'updated_at',
CNname: '最后更新时间',
type: 'DATETIME',
length: null,
precision: null,
isNull: 'YES',
remark: '账户信息最后更新的时间戳',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '日期时间型',
safeLevel: '低',
sensitiveStatus: '非敏感',
isFixation: 'true',
},
{
tableName: 'st',
columnsName: 'is_active',
CNname: '账户状态',
type: 'TINYINT',
length: 1,
precision: null,
isNull: 'NO',
remark: '账户是否处于激活状态(0-未激活,1-已激活)',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '布尔型',
safeLevel: '中',
sensitiveStatus: '非敏感',
isFixation: 'true',
},
{
tableName: 'st',
columnsName: 'is_deleted',
CNname: '删除标记',
type: 'TINYINT',
length: 1,
precision: null,
isNull: 'NO',
remark: '账户是否被标记为删除(0-未删除,1-已删除)',
primaryKey: 'NO',
foreignKey: 'NO',
dataType: '布尔型',
safeLevel: '中',
sensitiveStatus: '非敏感',
isFixation: 'true',
},
];
export const reviewData: any[] = [
{
age: 23,
id: 4,
name: '戴瑞灰',
score: 92,
sex: '男',
},
{
age: 30,
id: 8,
name: '康再溪',
score: 60,
sex: '女',
},
{
age: 23,
id: 1,
name: '田欣慧',
score: 100,
sex: '女',
},
{
age: 18,
id: 5,
name: '宋艳',
score: 99,
sex: '女',
},
];
export const accountFormSchema: any[] = []; export const accountFormSchema: any[] = [];
...@@ -197,7 +197,7 @@ ...@@ -197,7 +197,7 @@
function handleMainBodyEdit(record) { function handleMainBodyEdit(record) {
openMainBodyEditModal(true, { openMainBodyEditModal(true, {
...record, record,
}); });
} }
......
<template> <template>
<BasicModal <BasicModal
v-bind="$attrs" v-bind="$attrs"
width="80%" width="60%"
@register="registerModal" @register="registerModal"
:title="title" :title="title"
:showOkBtn="false" :showOkBtn="false"
v-model:visible="showModal"
@cancel="handleCancel"
> >
<div> <div class="mianBodyEditContainer">
<div style="display: flex; justify-content: flex-end"> <div style="display: flex; justify-content: flex-end">
<a-button style="margin-right: 5px" type="primary" @click="handleStorage" <a-button style="margin-right: 5px" type="primary" @click="handleStorage"
>存储管理</a-button >存储管理</a-button
...@@ -31,14 +33,33 @@ ...@@ -31,14 +33,33 @@
description="请一定确保主键唯一性、维度列完整性、否则检查结果可能不准确;建议为质量主体创建单独的质量任务,检查主键唯一、维度列非空" description="请一定确保主键唯一性、维度列完整性、否则检查结果可能不准确;建议为质量主体创建单独的质量任务,检查主键唯一、维度列非空"
/> />
<BasicForm @register="registerInfoForm" /> <BasicForm @register="registerInfoForm" />
<!-- <div class="editor" v-show="isIndependent === true">-->
<!-- <textarea v-model="sql" placeholder="请输入内容..."></textarea>-->
<!-- </div>-->
<div class="editor">
<textarea v-model="sql" placeholder="请输入内容..."></textarea>
</div>
<a-button @click="handleRun">测试运行</a-button>
<div v-if="isRun"> <BasicTable @register="registerColumnInformationTable" /></div>
</div> </div>
</div> </div>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="列信息"> <a-tab-pane key="2" tab="列信息">
<div v-if="page === '2'"> <BasicTable @register="registerColumnInformationTable" /></div> <div v-if="page === '2'">
<BasicTable @register="registerColumnInformationTable">
<template #fileName="{ text }">
<div>
{{ text }}
<Switch :checked="'1' === '1'" />
</div>
</template>
</BasicTable>
</div>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="数据预览"> <a-tab-pane key="3" tab="数据预览">
<div v-if="page === '3'"> </div> <div v-if="page === '3'">
<BasicTable @register="registerReviewTable" />
</div>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="4" tab="关联规则"> <a-tab-pane key="4" tab="关联规则">
<div v-if="page === '4'"> </div> <div v-if="page === '4'"> </div>
...@@ -48,24 +69,143 @@ ...@@ -48,24 +69,143 @@
</BasicModal> </BasicModal>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { BasicTable, useTable } from '@/components/Table'; import { BasicColumn, BasicTable, useTable } from '@/components/Table';
import BasicModal from '@/components/Modal/src/BasicModal.vue'; import BasicModal from '@/components/Modal/src/BasicModal.vue';
import { BasicForm, FormSchema, useForm } from '@/components/Form'; import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { ref } from 'vue'; import { ref } from 'vue';
import { Tabs, Alert } from 'ant-design-vue'; import { Tabs, Alert, Switch } from 'ant-design-vue';
import { useModal, useModalInner } from '@/components/Modal'; import { useModal, useModalInner } from '@/components/Modal';
import { useMessage } from '@/hooks/web/useMessage'; import { useMessage } from '@/hooks/web/useMessage';
import { informationData } from '@/views/metadata/metadataData'; import { informationData, tbData } from '@/views/metadata/metadataData';
import { informationColumns } from '@/views/metadata/data'; import { informationColumns, tbSearchFormSchema } from '@/views/metadata/data';
import {
infoData,
reviewData,
TreeData,
} from '@/views/dataQuality/agentClass/mainBody/dataQualityMainBodyData';
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const page = ref('1'); const page = ref('1');
const tableData = ref([]); const tableData = ref(infoData);
const title = ref(''); const title = ref('');
const tableTitle = ref(''); const sql = ref('');
let changeAble = ref(false);
let isIndependent = ref(false);
let isRun = ref(false);
const infoColumns: { dataIndex: string; width: number; title: string }[] = [
{
title: '表名',
dataIndex: 'tableName',
width: 120,
},
{
title: '列名',
dataIndex: 'columnsName',
width: 120,
},
{
title: '中文名',
dataIndex: 'CNname',
width: 120,
// edit: true,
},
{
title: '字段描述',
dataIndex: 'remark',
width: 120,
},
{
title: '字段类型',
dataIndex: 'type',
width: 120,
},
{
title: '可空',
dataIndex: 'isNull',
width: 120,
},
{
title: '问题数据固定列',
dataIndex: 'isFixation',
width: 120,
},
];
const SearchFormSchema: FormSchema[] = [
{
field: 'columnsName',
label: '',
componentProps: {
placeholder: '搜索字段',
},
component: 'Input',
colProps: { span: 5 },
},
];
const [registerColumnInformationTable] = useTable({ const [registerColumnInformationTable] = useTable({
dataSource: informationData, api: async () => {
columns: informationColumns, const response = {
pageNum: '1',
pageSize: '10',
pages: '1',
total: tableData.value.length,
code: '',
message: '',
data: [],
};
//过滤data中的数据,取出等于params.deptId的数据
var data = [];
data = tableData.value.filter((item) => item.parentId !== 0);
return { ...response, data: data };
},
// dataSource: infoData,
columns: infoColumns,
useSearchForm: true,
pagination: false,
formConfig: {
labelWidth: 120,
schemas: SearchFormSchema,
autoSubmitOnEnter: true,
},
showIndexColumn: false,
scroll: { y: 400 },
handleSearchInfoFn(info) {
tableData.value = infoData.filter((item) => item.columnsName.includes(info.columnsName));
// console.log('info', info);
// console.log('tableData', tableData.value);
return info;
},
});
const reviewColumns: { dataIndex: string; width: number; title: string }[] = [
{
title: '年龄',
dataIndex: 'age',
width: 120,
},
{
title: '序列',
dataIndex: 'id',
width: 120,
},
{
title: '姓名',
dataIndex: 'name',
width: 120,
},
{
title: '成绩',
dataIndex: 'score',
width: 120,
},
{
title: '性别',
dataIndex: 'sex',
width: 120,
},
];
const [registerReviewTable] = useTable({
dataSource: reviewData,
columns: reviewColumns,
pagination: false, pagination: false,
showIndexColumn: false, showIndexColumn: false,
scroll: { y: 400 }, scroll: { y: 400 },
...@@ -73,12 +213,18 @@ ...@@ -73,12 +213,18 @@
const infoSchema: FormSchema[] = [ const infoSchema: FormSchema[] = [
{ {
field: 'name', field: 'originalPrincipal',
label: '原始主体', label: '原始主体',
required: true, required: true,
component: 'Cascader', component: 'TreeSelect',
colProps: { lg: 12, md: 12 }, colProps: { lg: 12, md: 12 },
componentProps: {}, componentProps: {
fieldNames: {
label: 'fileName',
value: 'businessId',
},
getPopupContainer: () => document.body,
},
}, },
{ {
field: 'dimensionCodeColumn', field: 'dimensionCodeColumn',
...@@ -88,13 +234,13 @@ ...@@ -88,13 +234,13 @@
componentProps: { componentProps: {
placeholder: '请选择维度代码列', placeholder: '请选择维度代码列',
options: [ options: [
{ label: '规范性', value: '规范性' }, { label: 'code', value: 'code' },
// 其他选项... // 其他选项...
], ],
}, },
}, },
{ {
field: 'description', field: 'questionTablePrefix ',
label: '问题数据表名前缀', label: '问题数据表名前缀',
required: true, required: true,
colProps: { lg: 12, md: 12 }, colProps: { lg: 12, md: 12 },
...@@ -104,25 +250,34 @@ ...@@ -104,25 +250,34 @@
}, },
}, },
{ {
field: 'category', field: 'dimensionMeaningColumn',
label: '维度含义列', label: '维度含义列',
component: 'Select', component: 'Select',
colProps: { lg: 11, md: 11, offset: 1 }, colProps: { lg: 11, md: 11, offset: 1 },
componentProps: { componentProps: {
placeholder: '请选择维度含义列', placeholder: '请选择维度含义列',
options: [ options: [
{ label: '规范性', value: '规范性' }, { label: 'code', value: 'code' },
// 其他选项... // 其他选项...
], ],
}, },
}, },
{ {
field: 'category', field: 'isIndependent',
label: '维度含义列', label: '问题数据存储独立SQL',
colProps: { lg: 12, md: 12 }, colProps: { lg: 12, md: 12 },
component: 'Switch', component: 'Switch',
defaultValue: false,
componentProps: {
onChange() {
if (changeAble.value === true) {
isIndependent.value = !isIndependent.value;
}
},
},
}, },
]; ];
const [registerInfoForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({ const [registerInfoForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
labelWidth: 145, labelWidth: 145,
labelAlign: 'left', labelAlign: 'left',
...@@ -134,7 +289,87 @@ ...@@ -134,7 +289,87 @@
}, },
}); });
const [registerModal, { closeModal }] = useModalInner(async (data) => { const [registerModal, { closeModal }] = useModalInner(async (data) => {
tableTitle.value = data.fileName; title.value = data.record.fileName;
isIndependent.value = data.record.isIndependent;
// console.log('isIndependent.value', isIndependent.value);
let record = data.record;
await resetFields();
await setFieldsValue({
...record,
});
changeAble.value = true;
const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined);
await updateSchema([
{
field: 'originalPrincipal',
componentProps: {
treeData: treeList,
},
},
]);
});
function handleCancel() {
changeAble.value = false;
isRun.value = false;
}
function handleRun() {
changeAble.value = false;
isRun.value = true;
}
function handleSave() {
changeAble.value = false;
isRun.value = false;
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> </script>
<style scoped lang="less"></style> <style scoped lang="scss">
.editor {
background-color: white;
height: 560px;
border: 1px solid #d9d9d9;
padding: 16px;
margin-bottom: 8px;
}
.editor textarea {
width: 100%;
height: 100%;
border: none;
outline: none;
font-size: 16px;
resize: none;
}
</style>
<template> <template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit" minHeight="50"> <BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
minHeight="50"
>
<BasicForm @register="registerForm" /> <BasicForm @register="registerForm" />
</BasicModal> </BasicModal>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {ref, computed, unref, reactive} from 'vue'; import { ref, computed, unref, reactive } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal'; import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form'; import { BasicForm, useForm } from '@/components/Form';
import {accountFormSchema, MoveFormSchema } from './account.data'; import { accountFormSchema, MoveFormSchema } from './account.data';
import { getDeptList } from '@/api/system/dept/dept'; import { getDeptList } from '@/api/system/dept/dept';
import {resetUserPwd} from '@/api/system/user/user' import { resetUserPwd } from '@/api/system/user/user';
import { useMessage } from '@/hooks/web/useMessage'; import { useMessage } from '@/hooks/web/useMessage';
import { TreeData } from "./dataQualityMainBodyData"; import { TreeData } from './dataQualityMainBodyData';
defineOptions({ name: 'AccountModal' }); defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']); const emit = defineEmits(['success', 'register']);
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const isUpdate = ref(true); const isUpdate = ref(true);
const rowId = ref(''); const rowId = ref('');
const idList = ref([]) const idList = ref([]);
const rowData = ref([]) const rowData = ref([]);
//获取接口数据并放在下拉框里(这里是打开了一个弹框) //获取接口数据并放在下拉框里(这里是打开了一个弹框)
//初始化表单 //初始化表单
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({ const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
labelWidth: 100, labelWidth: 100,
baseColProps: { span: 24 }, baseColProps: { span: 24 },
schemas: MoveFormSchema, schemas: MoveFormSchema,
...@@ -30,64 +36,70 @@ const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = ...@@ -30,64 +36,70 @@ const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] =
actionColOptions: { actionColOptions: {
span: 23, span: 23,
}, },
}); });
//初始化弹框 //初始化弹框
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//每次点击弹窗 需要清空存储的数据 //每次点击弹窗 需要清空存储的数据
rowData.value = [] rowData.value = [];
//重置表单数据 //重置表单数据
resetFields(); resetFields();
setModalProps({ confirmLoading: false }); setModalProps({ confirmLoading: false });
if (data.idList != null && data.idList != undefined && data.idList.length > 0){ if (data.idList != null && data.idList != undefined && data.idList.length > 0) {
} else { } else {
rowData.value.push(data.record) rowData.value.push(data.record);
//单个移动 //单个移动
rowId.value = data.record.businessId; rowId.value = data.record.businessId;
data.record.taskId = data.record.businessId data.record.taskId = data.record.businessId;
setFieldsValue({ setFieldsValue({
...data.record, ...data.record,
}); });
} }
const treeList = handleTree(TreeData, 'businessId',undefined,undefined,undefined) const treeList = handleTree(TreeData, 'businessId', undefined, undefined, undefined);
updateSchema([ updateSchema([
{ {
field: 'taskId', field: 'taskId',
componentProps: { componentProps: {
treeData: treeList treeData: treeList,
}, },
}, },
]); ]);
console.log('treeList:',treeList) console.log('treeList:', treeList);
}); });
const getTitle = computed(() => ('移动')); const getTitle = computed(() => '移动');
/**确定按钮*/ /**确定按钮*/
async function handleSubmit() { async function handleSubmit() {
createMessage.success('移动成功!') createMessage.success('移动成功!');
closeModal() closeModal();
} }
/**数组对象转成树*/ /**数组对象转成树*/
function handleTree(data, id, parentId, children, rootId) { function handleTree(data, id, parentId, children, rootId) {
id = id || 'id' id = id || 'id';
parentId = parentId || 'parentId' parentId = parentId || 'parentId';
children = children || 'children' children = children || 'children';
rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0 rootId =
rootId ||
Math.min.apply(
Math,
data.map((item) => {
return item[parentId];
}),
) ||
0;
// 对源数据深度克隆 // 对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data)) const cloneData = JSON.parse(JSON.stringify(data));
// 循环所有项 // 循环所有项
const treeData = cloneData.filter(father => { const treeData = cloneData.filter((father) => {
const branchArr = cloneData.filter(child => { const branchArr = cloneData.filter((child) => {
// 返回每一项的子级数组 // 返回每一项的子级数组
return father[id] === child[parentId] return father[id] === child[parentId];
}) });
branchArr.length > 0 ? father.children = branchArr : '' branchArr.length > 0 ? (father.children = branchArr) : '';
// 返回第一层 // 返回第一层
return father[parentId] === rootId return father[parentId] === rootId;
}) });
return treeData !== '' ? treeData : data return treeData !== '' ? treeData : data;
} }
</script> </script>
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