4a419fac by lihua

提交元数据导入修改;新增引用完整性规则

1 parent 6181cbd2
...@@ -3,7 +3,7 @@ VITE_APP_TITLE = 数据资产管理系统 ...@@ -3,7 +3,7 @@ VITE_APP_TITLE = 数据资产管理系统
3 # 接口域名 3 # 接口域名
4 # VITE_API_BASEURL = https://www.zgsjzc.com/api 4 # VITE_API_BASEURL = https://www.zgsjzc.com/api
5 # VITE_API_BASEURL = https://swzl-test.csbr.cn/api 5 # VITE_API_BASEURL = https://swzl-test.csbr.cn/api
6 VITE_API_BASEURL = http://10.4.82.30:8052/ 6 VITE_API_BASEURL = http://10.4.82.1:28052/
7 # 平台用户 接口请地址 7 # 平台用户 接口请地址
8 VITE_APP_USER_API_BASEURL = gateway-server/user 8 VITE_APP_USER_API_BASEURL = gateway-server/user
9 # 系统管理 接口地址 9 # 系统管理 接口地址
......
...@@ -150,6 +150,13 @@ export const getSmallCategoryList = () => request({ ...@@ -150,6 +150,13 @@ export const getSmallCategoryList = () => request({
150 data: { paramCode: "SMALL-CATEGORY" } 150 data: { paramCode: "SMALL-CATEGORY" }
151 }) 151 })
152 152
153 // 获取规范性检验规则。
154 export const getCheckRulesList = () => request({
155 url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
156 method: 'post',
157 data: { paramCode: "REGULAR_RULE" }
158 })
159
153 // 根据规则guid获取规则的详情信息。 160 // 根据规则guid获取规则的详情信息。
154 export const getRuleConfDetail = (param) => request({ 161 export const getRuleConfDetail = (param) => request({
155 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/detail?ruleConfGuid=${param}`, 162 url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/detail?ruleConfGuid=${param}`,
......
...@@ -47,7 +47,7 @@ export const getImageUrl = (params) => request({ ...@@ -47,7 +47,7 @@ export const getImageUrl = (params) => request({
47 47
48 /** 查看图片 */ 48 /** 查看图片 */
49 export const getImageContent = (params) => request({ 49 export const getImageContent = (params) => request({
50 url: `${import.meta.env.VITE_APP_API_BASEURL}/obs/view-pic?filePath=${params}`, 50 url: `${import.meta.env.VITE_APP_API_BASEURL}/obs`,
51 method: 'get', 51 method: 'get',
52 responseType: 'blob' 52 responseType: 'blob'
53 }); 53 });
......
...@@ -146,11 +146,26 @@ defineExpose({ ...@@ -146,11 +146,26 @@ defineExpose({
146 :max-collapse-tags="item.cascaderInfo.maxTags ?? 1" :filterable="item.cascaderInfo.filterable ?? false" 146 :max-collapse-tags="item.cascaderInfo.maxTags ?? 1" :filterable="item.cascaderInfo.filterable ?? false"
147 @change="cascaderChange" /> 147 @change="cascaderChange" />
148 </div> 148 </div>
149 <div class="form_item" v-if="item.type == 'input'"> 149 <div class="form_item" v-else-if="item.type == 'input'">
150 <span class="item_label" :class="{ required_mark: item.selectInfo.required }">{{ item.selectInfo.label 150 <span class="item_label" :class="{ required_mark: item.selectInfo.required }">{{ item.selectInfo.label
151 }}:</span> 151 }}:</span>
152 <el-input v-model="extraParams[item.selectInfo.field]" :placeholder="item.selectInfo.placeholder" 152 <el-input v-model="extraParams[item.selectInfo.field]" :placeholder="item.selectInfo.placeholder"
153 :disabled="item.selectInfo.disabled" :clearable="item.selectInfo.disabled"> </el-input> 153 :disabled="item.selectInfo.disabled" :clearable="item.selectInfo.clearable"> </el-input>
154 </div>
155 <div class="group-con" v-else-if="item.type == 'group'">
156 <template v-for="formItem in (item.formItems || [])">
157 <div class="form_item" v-if="formItem.type == 'input'" style="margin-right: 15px;">
158 <span class="item_label" style="display: block;margin-bottom: 2px" :class="{ required_mark: formItem.required }">{{ formItem.label }}:</span>
159 <el-input v-model="extraParams[formItem.field]" :placeholder="formItem.placeholder"
160 :disabled="formItem.disabled" :clearable="formItem.clearable"> </el-input>
161 </div>
162 <div class="form_item" v-else-if="formItem.type == 'switch'">
163 <span class="item_label" style="display: block;margin-bottom: 2px" :class="{ required_mark: formItem.required }">{{ formItem.label }}:</span>
164 <el-switch inline-prompt v-model="extraParams[formItem.field]" :active-value="formItem.activeValue"
165 :inactive-value="formItem.inactiveValue" :active-text="formItem.activeText"
166 :inactive-text="formItem.inactiveText" :disabled="formItem.disabled" />
167 </div>
168 </template>
154 </div> 169 </div>
155 <div class="item_btn" v-else-if="item.type == 'btn_down'"> 170 <div class="item_btn" v-else-if="item.type == 'btn_down'">
156 <el-button plain @click="toolBtnClick({ value: 'exoprt_model' })" v-preReClick> 171 <el-button plain @click="toolBtnClick({ value: 'exoprt_model' })" v-preReClick>
...@@ -363,5 +378,11 @@ defineExpose({ ...@@ -363,5 +378,11 @@ defineExpose({
363 } 378 }
364 } 379 }
365 } 380 }
381
382 .group-con {
383 display: flex;
384 flex-wrap: wrap;
385 margin-bottom: -12px;
386 }
366 } 387 }
367 </style> 388 </style>
......
...@@ -44,16 +44,13 @@ const routes: RouteRecordRaw[] = [ ...@@ -44,16 +44,13 @@ const routes: RouteRecordRaw[] = [
44 name: 'importFileMeta', 44 name: 'importFileMeta',
45 component: () => import('@/views/importFile.vue'), 45 component: () => import('@/views/importFile.vue'),
46 meta: { 46 meta: {
47 title: '导入数据', 47 title: '导入数据-采集任务',
48 sidebar: false, 48 sidebar: false,
49 breadcrumb: false, 49 breadcrumb: false,
50 cache: true, 50 cache: true,
51 reuse: true 51 reuse: true
52 }, 52 },
53 beforeEnter: (to, from) => { 53 beforeEnter: (to, from) => {
54 if (to.query.bizGuid) {
55 to.meta.title = `导入数据-采集任务`;
56 }
57 } 54 }
58 } 55 }
59 ], 56 ],
......
...@@ -598,7 +598,7 @@ onBeforeMount(() => { ...@@ -598,7 +598,7 @@ onBeforeMount(() => {
598 <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" :init="false" /> 598 <TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" :init="false" />
599 <div class="tools_btns"> 599 <div class="tools_btns">
600 <el-button type="primary" @click="loadDrawer">新建</el-button> 600 <el-button type="primary" @click="loadDrawer">新建</el-button>
601 <el-button type="primary" @click="importMeta">导入</el-button> 601 <el-button @click="importMeta">导入</el-button>
602 </div> 602 </div>
603 </div> 603 </div>
604 <div class="table_panel_wrap"> 604 <div class="table_panel_wrap">
......
...@@ -5,7 +5,8 @@ import { ...@@ -5,7 +5,8 @@ import {
5 validateCustomSql, 5 validateCustomSql,
6 getSubjectFields, 6 getSubjectFields,
7 getSubjectTableTree, 7 getSubjectTableTree,
8 getSubjectTableByDomain 8 getSubjectTableByDomain,
9 getCheckRulesList
9 } from '@/api/modules/dataQuality'; 10 } from '@/api/modules/dataQuality';
10 import Table from "@/components/Table/index.vue"; 11 import Table from "@/components/Table/index.vue";
11 import Form from "@/components/Form/index.vue"; 12 import Form from "@/components/Form/index.vue";
...@@ -125,6 +126,9 @@ watch(() => props.largeCategoryList, (val) => { ...@@ -125,6 +126,9 @@ watch(() => props.largeCategoryList, (val) => {
125 } 126 }
126 }) 127 })
127 128
129 /** 规范性检验规则 */
130 const checkRulesList: any = ref([]);
131
128 onBeforeMount(() => { 132 onBeforeMount(() => {
129 if (props.ruleTypeList?.length) { 133 if (props.ruleTypeList?.length) {
130 if (props.ruleTypeValue) { 134 if (props.ruleTypeValue) {
...@@ -159,6 +163,13 @@ onBeforeMount(() => { ...@@ -159,6 +163,13 @@ onBeforeMount(() => {
159 if (Object.keys(props.value).length > 0) { 163 if (Object.keys(props.value).length > 0) {
160 setPanelListValue(props.value, false, true); 164 setPanelListValue(props.value, false, true);
161 } 165 }
166 getCheckRulesList().then((res: any) => {
167 if (res.code == proxy.$passCode) {
168 checkRulesList.value = res.data || [];
169 } else {
170 ElMessage.error(res.msg);
171 }
172 })
162 }); 173 });
163 174
164 const getDefaultLargeCategory = (ruleCode) => { 175 const getDefaultLargeCategory = (ruleCode) => {
...@@ -166,7 +177,7 @@ const getDefaultLargeCategory = (ruleCode) => { ...@@ -166,7 +177,7 @@ const getDefaultLargeCategory = (ruleCode) => {
166 return '3'; //准确性 177 return '3'; //准确性
167 } else if (ruleCode == 'volatility_check' || ruleCode == 'rows_check') { 178 } else if (ruleCode == 'volatility_check' || ruleCode == 'rows_check') {
168 return '5'; 179 return '5';
169 } else if (ruleCode == 'null_value_check') { 180 } else if (ruleCode == 'null_value_check' || ruleCode == 'ref_integrality') {
170 return '2'; 181 return '2';
171 } else { 182 } else {
172 return '1'; 183 return '1';
...@@ -180,7 +191,7 @@ const getDefaultSmallCategory = (ruleCode) => { ...@@ -180,7 +191,7 @@ const getDefaultSmallCategory = (ruleCode) => {
180 return '9'; 191 return '9';
181 } else if (ruleCode == 'volatility_check' || ruleCode == 'rows_check') { 192 } else if (ruleCode == 'volatility_check' || ruleCode == 'rows_check') {
182 return '17'; 193 return '17';
183 } else if (ruleCode == 'null_value_check') { 194 } else if (ruleCode == 'null_value_check' || ruleCode == 'ref_integrality') {
184 return '7'; 195 return '7';
185 } else { 196 } else {
186 return '1'; 197 return '1';
...@@ -383,6 +394,28 @@ const panelList: any = ref([ ...@@ -383,6 +394,28 @@ const panelList: any = ref([
383 block: true, 394 block: true,
384 visible: false 395 visible: false
385 }, { 396 }, {
397 label: '规则设置',
398 type: 'input-dom',
399 placeholder: '请设置,可多选',
400 field: 'ruleSettings-ref-integrality', //13
401 default: '',//描述型的字段
402 defaultValue: [], //实际的表格数据值数组
403 readonly: true,
404 required: true,
405 block: true,
406 visible: false
407 }, {
408 label: '规则设置',
409 type: 'input-dom',
410 placeholder: '请设置,可多选',
411 field: 'ruleSettings-norm-check', //14
412 default: '',//描述型的字段
413 defaultValue: {},
414 readonly: true,
415 required: true,
416 block: true,
417 visible: false
418 }, {
386 label: '描述', 419 label: '描述',
387 type: 'textarea', 420 type: 'textarea',
388 placeholder: '请输入', 421 placeholder: '请输入',
...@@ -468,6 +501,12 @@ const formRules = ref({ ...@@ -468,6 +501,12 @@ const formRules = ref({
468 'ruleSettings-value-range': [ 501 'ruleSettings-value-range': [
469 { required: true, trigger: 'change', message: "请设置规则" } 502 { required: true, trigger: 'change', message: "请设置规则" }
470 ], 503 ],
504 'ruleSettings-ref-integrality': [
505 { required: true, trigger: 'change', message: "请设置规则" }
506 ],
507 'ruleSettings-norm-check': [
508 { required: true, trigger: 'change', message: "请设置规则" }
509 ],
471 orangeThreshold: [ 510 orangeThreshold: [
472 { 511 {
473 trigger: 'blur', validator: (rule: any, value: any, callback: any) => { 512 trigger: 'blur', validator: (rule: any, value: any, callback: any) => {
...@@ -703,6 +742,54 @@ const formBtnClick = (btn) => { ...@@ -703,6 +742,54 @@ const formBtnClick = (btn) => {
703 } 742 }
704 }) 743 })
705 } 744 }
745 } else if (ruleType.value == 'ref_integrality') {
746 if (!contrastSubjects.value?.length) {
747 getSubjectTableTreeData().then(res => {
748 return res;
749 })
750 }
751 tableRefIntegralityDialogVisible.value = true;
752 tableRefIntegralityRulesData.value = cloneDeep(panelList.value[13].defaultValue || []);
753 if (!tableRefIntegralityRulesData.value.length) {
754 tableRefIntegralityRulesData.value = [{}];
755 } else {
756 tableRefIntegralityRulesData.value.forEach((rule) => {
757 if (!mainTableFields.value[rule.mainTable]?.length) {
758 tableInteMainSelectChange(rule.mainTable)
759 }
760 if (!compareTableFields.value[rule.compareTableGuid]?.length) {
761 tableInteCompareSelectChange(rule.compareTableGuid);
762 }
763 })
764 }
765 } else if (ruleType.value == 'norm_check') {
766 normCheckDialogVisible.value = true;
767 tableListInfo.value.data = props.toSubjectTables;
768 dialogSelectSubjectTable.value = props.toSubjectTables[0];
769 let defaultValue = panelList.value[12].defaultValue;
770 normCheckTableListData.value[dialogSelectSubjectTable.value.enName] = [];
771 if (props.toSubjectTables[0]?.guid) {
772 normCheckTableListLoading.value[dialogSelectSubjectTable.value.enName] = true;
773 getSubjectFields(props.toSubjectTables[0]?.guid).then((res: any) => {
774 normCheckTableListLoading.value[dialogSelectSubjectTable.value.enName] = false;
775 if (res.code == proxy.$passCode) {
776 let data = res.data || [];
777 normCheckTableListData.value[dialogSelectSubjectTable.value.enName] = data;
778 let valueFields = defaultValue.ruleFields?.[dialogSelectSubjectTable.value.enName] || [];
779 if (valueFields.length) {
780 valueFields.forEach(field => {
781 let fIndex = data.findIndex(d => d.enName == field.enName);
782 if (fIndex > -1) {
783 let f = normCheckTableListData.value[dialogSelectSubjectTable.value.enName][fIndex];
784 Object.assign(f, field);
785 }
786 });
787 }
788 } else {
789 ElMessage.error(res.msg);
790 }
791 })
792 }
706 } 793 }
707 } 794 }
708 795
...@@ -814,12 +901,33 @@ const setPanelListValue = (item, isSelectChange = false, init = false, radioGrou ...@@ -814,12 +901,33 @@ const setPanelListValue = (item, isSelectChange = false, init = false, radioGrou
814 } else { 901 } else {
815 p.defaultValue = []; 902 p.defaultValue = [];
816 } 903 }
904 } else if (ruleCode == 'ref_integrality' && p.field == 'ruleSettings-ref-integrality') {
905 if (!init) {
906 p.default = val[field];
907 return;
908 }
909 if (val.ruleField?.length) {
910 p.default = val.ruleField?.map(f => f.enName)?.join(';');
911 p.defaultValue = val.ruleField.map(field => {
912 return {
913 mainTable: val.subjectGuid,
914 mainTableName: val.subjectName,
915 mainTableZhName: val.subjectZhName,
916 mainTableField: field.enName,
917 compareTableGuid: field.compareTableGuid,
918 compareEnName: field.compareEnName,
919 }
920 })
921 } else {
922 p.default = '';
923 p.defaultValue = [];
924 }
817 } else if (ruleCode == 'value_of_range' && p.field == 'ruleSettings-value-range') { 925 } else if (ruleCode == 'value_of_range' && p.field == 'ruleSettings-value-range') {
818 if (!init) { 926 if (!init) {
819 p.default = val[field]; 927 p.default = val[field];
820 return; 928 return;
821 } 929 }
822 if (val.ruleField) { 930 if (val.ruleField?.length) {
823 p.default = val.ruleField?.map(f => f.enName)?.join(';'); 931 p.default = val.ruleField?.map(f => f.enName)?.join(';');
824 let ruleFields = {}; 932 let ruleFields = {};
825 ruleFields[val.subjectName] = val.ruleField || []; 933 ruleFields[val.subjectName] = val.ruleField || [];
...@@ -873,54 +981,54 @@ const radioGroupChange = (val, inlineValue, init) => { ...@@ -873,54 +981,54 @@ const radioGroupChange = (val, inlineValue, init) => {
873 list.forEach((item, index) => { 981 list.forEach((item, index) => {
874 if (val == 'volatility_check') {//表行数波动率 982 if (val == 'volatility_check') {//表行数波动率
875 item.visible = true 983 item.visible = true
876 if (index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index == 12 || index === 14) {// 7是规则设置,9是联合不为空 : 9+4 984 if (index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index == 12 || index == 13 || index === 14 || index === 16) {// 7是规则设置,9是联合不为空 : 9+4
877 item.visible = false 985 item.visible = false
878 } 986 }
879 } else if (val === 'null_value_check') {//空值检查 987 } else if (val === 'null_value_check') {//空值检查
880 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 11 || index == 12) { 988 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 11 || index == 12 || index == 13 || index === 14) {
881 item.visible = false 989 item.visible = false
882 } else { //index为10的显示 990 } else { //index为10的显示
883 item.visible = true; 991 item.visible = true;
884 } 992 }
885 } else if (val === 'repeate_data_check') { //重复数据检查 993 } else if (val === 'repeate_data_check') { //重复数据检查
886 item.visible = false 994 item.visible = false
887 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 8 || index == 9 || index == 10 || index == 11 || index == 12 || index === 14) { 995 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 8 || index == 9 || index == 10 || index == 11 || index == 12 || index == 13 || index === 14 || index === 16) {
888 } else { 996 } else {
889 item.visible = true; 997 item.visible = true;
890 } 998 }
891 } else if (val === 'logic_check') { //逻辑检查 999 } else if (val === 'logic_check') { //逻辑检查
892 item.visible = false 1000 item.visible = false
893 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 9 || index == 10 || index == 11 || index == 12 || index === 14) { 1001 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 9 || index == 10 || index == 11 || index == 12 || index == 13 || index === 14 || index === 16) {
894 } else { 1002 } else {
895 item.visible = true; 1003 item.visible = true;
896 } 1004 }
897 } else if (val === 'value_of_range') { // 值域范围 1005 } else if (val === 'value_of_range') { // 值域范围
898 item.visible = false 1006 item.visible = false
899 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index === 14) { 1007 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index == 13 || index === 14 || index === 16) {
900 } else { 1008 } else {
901 item.visible = true; 1009 item.visible = true;
902 } 1010 }
903 } else if (val === 'ref_integrality') { // 引用完整性 1011 } else if (val === 'ref_integrality') { // 引用完整性
904 item.visible = false 1012 item.visible = false
905 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index === 14) { 1013 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index == 12 || index === 14 || index === 16) {
906 } else { 1014 } else {
907 item.visible = true; 1015 item.visible = true;
908 } 1016 }
909 } else if (val === 'norm_check') { // 规范校验 1017 } else if (val === 'norm_check') { // 规范校验
910 item.visible = false 1018 item.visible = false
911 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index === 13) { 1019 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 11 || index == 12 || index == 13 || index === 16) {
912 } else { 1020 } else {
913 item.visible = true; 1021 item.visible = true;
914 } 1022 }
915 } else if (val === 'custom_sql') {//自定义sql 1023 } else if (val === 'custom_sql') {//自定义sql
916 item.visible = false 1024 item.visible = false
917 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 10 || index == 11 || index == 12 || index === 14) { 1025 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 10 || index == 11 || index == 12 || index == 13 || index === 14 || index === 16) {
918 } else { 1026 } else {
919 item.visible = true; 1027 item.visible = true;
920 } 1028 }
921 } else if (val === 'rows_check') { //表行数 1029 } else if (val === 'rows_check') { //表行数
922 item.visible = false 1030 item.visible = false
923 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 12 || index === 14) { 1031 if (index === 3 || index === 4 || index === 5 || index === 6 || index == 7 || index == 8 || index == 9 || index == 10 || index == 12 || index == 13 || index === 14 || index === 16) {
924 } else { 1032 } else {
925 item.visible = true; 1033 item.visible = true;
926 } 1034 }
...@@ -1184,6 +1292,7 @@ const handleFilterChange = () => { ...@@ -1184,6 +1292,7 @@ const handleFilterChange = () => {
1184 tableFilterValidates.value[dialogSelectSubjectTable.value.enName] = false; 1292 tableFilterValidates.value[dialogSelectSubjectTable.value.enName] = false;
1185 } 1293 }
1186 1294
1295 /** ----------------- 表行数检查 --------------------------------- */
1187 const tableRowDialogVisible = ref(false); 1296 const tableRowDialogVisible = ref(false);
1188 const tableRowRulesDataLoading = ref(false); 1297 const tableRowRulesDataLoading = ref(false);
1189 const tableRowRulesData: any = ref([{ 1298 const tableRowRulesData: any = ref([{
...@@ -1585,6 +1694,112 @@ const submitValueRange = () => { ...@@ -1585,6 +1694,112 @@ const submitValueRange = () => {
1585 valueRangeDialogVisible.value = false; 1694 valueRangeDialogVisible.value = false;
1586 } 1695 }
1587 1696
1697 /** ---------------------- 引用完整性 ------------------------------------ */
1698 const tableRefIntegralityDialogVisible = ref(false);
1699 const tableRefIntegralityRulesDataLoading = ref(false);
1700 const tableRefIntegralityRulesData: any = ref([{}]);
1701 const mainTableFields = ref({}); // 选择主表对应的字段列表
1702 const compareTableFields = ref({}); //选择对比表对应的字段列表
1703
1704 /** 主表下拉选择变化 */
1705 const tableInteMainSelectChange = (val) => {
1706 mainTableFields.value[val] = [];
1707 getSubjectFields(val).then((res: any) => {
1708 if (res.code == proxy.$passCode) {
1709 mainTableFields.value[val] = res.data?.map(d => {
1710 return Object.assign({}, d, {
1711 label: `${d.enName}(${d.chName})`
1712 });
1713 }) || [];
1714 } else {
1715 ElMessage.error(res.msg);
1716 }
1717 })
1718 }
1719
1720 /** 对比表下拉选择变化 */
1721 const tableInteCompareSelectChange = (val) => {
1722 compareTableFields.value[val] = [];
1723 getSubjectFields(val).then((res: any) => {
1724 if (res.code == proxy.$passCode) {
1725 compareTableFields.value[val] = res.data?.map(d => {
1726 return Object.assign({}, d, {
1727 label: `${d.enName}(${d.chName})`
1728 });
1729 }) || [];
1730 } else {
1731 ElMessage.error(res.msg);
1732 }
1733 })
1734 }
1735
1736 const addIntegralityRules = () => {
1737 tableRefIntegralityRulesData.value.push({
1738 });
1739 }
1740
1741 const deleteIntegralityRules = (scope) => {
1742 tableRefIntegralityRulesData.value.splice(scope.$index, 1);
1743 }
1744
1745 const cancelTableRefIntegralityDialog = () => {
1746 tableRefIntegralityDialogVisible.value = false;
1747 }
1748
1749 const submitTableRefIntegrality = () => {
1750 let v: any = [];
1751 if (!tableRefIntegralityRulesData.value.length) {
1752 ElMessage.error('表行数检查规则不能为空');
1753 return;
1754 }
1755 for (const rule of tableRefIntegralityRulesData.value) {
1756 if (!rule.mainTable) {
1757 ElMessage.error('主表不能为空');
1758 return;
1759 }
1760 if (!rule.mainTableField) {
1761 ElMessage.error('主表字段不能为空');
1762 return;
1763 }
1764 if (!rule.compareTableGuid) {
1765 ElMessage.error('对比表不能为空');
1766 return;
1767 }
1768 if (!rule.compareEnName) {
1769 ElMessage.error('对比表字段不能为空');
1770 return;
1771 }
1772 v.push(rule.mainTableField);
1773 }
1774 let formInline = oldOriginValue.value = Object.assign({
1775 qualityModelGuids: props.toSubjectTables.map(s => s.guid),
1776 parity: 1,
1777 compareWay: 1,
1778 jointly: 'N',
1779 bizState: 'Y'
1780 }, oldOriginValue.value, ruleFormRef.value.formInline);
1781 panelList.value[13].defaultValue = tableRefIntegralityRulesData.value;
1782 formInline[`${panelList.value[13].field}`] = v.join(';');
1783 setPanelListValue(formInline);
1784 tableRefIntegralityDialogVisible.value = false;
1785 }
1786
1787 /** ---------------------- 规范校验 ----------------------------------- */
1788
1789 const normCheckDialogVisible = ref(false);
1790
1791 const normCheckTableListLoading = ref({});
1792
1793 const normCheckTableListData = ref({});
1794
1795 const cancelNormCheckDialog = () => {
1796 normCheckDialogVisible.value = false;
1797 }
1798
1799 const submitNormCheck = () => {
1800
1801 }
1802
1588 const getFormInfo = () => { 1803 const getFormInfo = () => {
1589 let formInline = ruleFormRef.value.formInline; 1804 let formInline = ruleFormRef.value.formInline;
1590 let ruleName = props.ruleTypeList.find(option => option.ruleCode == formInline.ruleCode).ruleName; 1805 let ruleName = props.ruleTypeList.find(option => option.ruleCode == formInline.ruleCode).ruleName;
...@@ -1621,7 +1836,14 @@ const getFormInfo = () => { ...@@ -1621,7 +1836,14 @@ const getFormInfo = () => {
1621 } else if (formInline.ruleCode == 'value_of_range') { 1836 } else if (formInline.ruleCode == 'value_of_range') {
1622 let v = panelList.value[12].defaultValue; 1837 let v = panelList.value[12].defaultValue;
1623 return Object.assign({}, formInline, v, { 1838 return Object.assign({}, formInline, v, {
1624 ruleName: ruleName 1839 ruleName: ruleName,
1840 ruleFields: v
1841 });
1842 } else if (formInline.ruleCode == 'ref_integrality') {
1843 let v = panelList.value[13].defaultValue;
1844 return Object.assign({}, formInline, {
1845 ruleName: ruleName,
1846 ruleFields: v
1625 }); 1847 });
1626 } 1848 }
1627 } 1849 }
...@@ -1812,6 +2034,141 @@ defineExpose({ ...@@ -1812,6 +2034,141 @@ defineExpose({
1812 </template> 2034 </template>
1813 </el-dialog> 2035 </el-dialog>
1814 2036
2037 <!-- 引用完整性 -->
2038 <el-dialog v-model="tableRefIntegralityDialogVisible" title="规则设置" width="750" :modal="true" :close-on-click-modal="false"
2039 destroy-on-close align-center>
2040 <div class="row-dialog-content">
2041 <el-table ref="rowTableRef" :data="tableRefIntegralityRulesData" height="100%" :highlight-current-row="true" stripe
2042 v-loading="tableRefIntegralityRulesDataLoading" tooltip-effect="light" border
2043 :style="{ height: 'calc(100% - 28px)', width: 'auto', 'max-width': '100%', display: 'inline-block' }">
2044 <el-table-column prop="mainTable" label="选择主表" width="180px" align="left" show-overflow-tooltip>
2045 <template #default="scope">
2046 <el-select v-if="!props.readonly" v-model="scope.row['mainTable']" placeholder="请选择" @change="tableInteMainSelectChange">
2047 <el-option v-for="opt in toSubjectTables" :key="opt['guid']" :label="opt['label']" :value="opt['guid']" />
2048 </el-select>
2049 <span v-else>{{ scope.row['mainTableName'] + `(${scope.row['mainTableZhName']})` }}</span>
2050 </template>
2051 </el-table-column>
2052 <el-table-column prop="mainTableField" label="选择主表字段" width="180px" align="left" show-overflow-tooltip>
2053 <template #default="scope">
2054 <el-select v-if="!props.readonly" v-model="scope.row['mainTableField']" placeholder="请选择" filterable clearable>
2055 <el-option v-for="opt in (scope.row.mainTable ? mainTableFields[scope.row.mainTable] : [])" :key="opt['enName']" :label="opt['label']" :value="opt['enName']" />
2056 </el-select>
2057 <span v-else>{{ scope.row['mainTableField'] + `(${scope.row['mainTableFieldZhName']})` }}</span>
2058 </template>
2059 </el-table-column>
2060 <el-table-column prop="compareTableGuid" label="选择对比表" width="180px" align="left" show-overflow-tooltip>
2061 <template #default="scope">
2062 <el-tree-select v-if="!props.readonly" ref="compareTreeSelectRef" filterable clearable @change="tableInteCompareSelectChange"
2063 v-model="scope.row['compareTableGuid']" node-key="guid" :data="contrastSubjects" placeholder="请选择" lazy
2064 :load="(node, resolve) => treeSelectLoad(node, resolve)" :default-expanded-keys="contrastSubjects?.length ? [contrastSubjects.find(c => c.children?.some(cc => cc.guid == scope.row['compareSubjectDomainGuid'])).guid, scope.row.compareSubjectDomainGuid] : []"
2065 :auto-expand-parent="true" :default-checked-keys="[scope.row['compareTableGuid']]"
2066 :filter-node-method="contrastSubjectInputFilterMethod" :props="{
2067 value: 'guid',
2068 label: 'name',
2069 children: 'children',
2070 isLeaf: 'isLeaf'
2071 }">
2072 </el-tree-select>
2073 <span v-else>{{ scope.row['compareTableName'] + `(${scope.row['compareTableZhName']})` }}</span>
2074 </template>
2075 </el-table-column>
2076 <el-table-column prop="compareEnName" label="选择对比字段" width="180px" align="left" show-overflow-tooltip>
2077 <template #default="scope">
2078 <el-select v-if="!props.readonly" v-model="scope.row['compareEnName']" placeholder="请选择" filterable clearable>
2079 <el-option v-for="opt in (scope.row.compareTableGuid ? compareTableFields[scope.row.compareTableGuid] : [])" :key="opt['enName']" :label="opt['label']" :value="opt['enName']" />
2080 </el-select>
2081 <span v-else>{{ scope.row['compareEnName'] + `(${scope.row['compareZhName']})` }}</span>
2082 </template>
2083 </el-table-column>
2084 <el-table-column label="操作" width="100px" align="left" fixed="right" v-if="!props.readonly">
2085 <template #default="scope">
2086 <span class="text_btn" @click="deleteIntegralityRules(scope)" v-preReClick>删除</span>
2087 </template>
2088 </el-table-column>
2089 </el-table>
2090 <div class="row-add-btn" v-if="!props.readonly">
2091 <el-button link @click="addIntegralityRules"
2092 :icon="CirclePlus" v-preReClick>添加规则</el-button>
2093 </div>
2094 </div>
2095
2096 <template #footer v-if="!props.readonly">
2097 <div class="dialog-footer">
2098 <el-button @click="cancelTableRefIntegralityDialog" v-preReClick>取消</el-button>
2099 <el-button @click="submitTableRefIntegrality" type="primary" v-preReClick>确定</el-button>
2100 </div>
2101 </template>
2102 </el-dialog>
2103
2104 <!-- 规范校验 -->
2105 <el-dialog v-model="normCheckDialogVisible" title="规则设置" width="850" :modal="true" :close-on-click-modal="false"
2106 destroy-on-close align-center>
2107 <div class="filter-dialog-content" :style="{ height: '500px' }">
2108 <div class="filter-table-list">
2109 <div class="left-title">质检表</div>
2110 <ListPanel class="list_unit" ref="normCheckFormListRef" :listInfo="tableListInfo" @itemClick="listItemClick" />
2111 </div>
2112 <div class="table-field-right">
2113 <div class="left-title">字段列表详情</div>
2114 <el-table ref="rowTableRef" :data="normCheckTableListData[dialogSelectSubjectTable.enName]" height="100%" :highlight-current-row="true" stripe
2115 v-loading="normCheckTableListLoading[dialogSelectSubjectTable.enName]" tooltip-effect="light" border
2116 :style="{ height: 'calc(100% - 32px)', width: '100%', display: 'inline-block' }">
2117 <el-table-column prop="enName" label="字段名" width="140px" align="left" show-overflow-tooltip>
2118 </el-table-column>
2119 <el-table-column prop="chName" label="注释" width="120px" align="left" show-overflow-tooltip>
2120 </el-table-column>
2121 <el-table-column prop="dataTypeChName" label="数据类型" width="100px" show-overflow-tooltip>
2122 <template #default="scope">
2123 <span>{{ scope.row["dataTypeChName"] || '--' }}</span>
2124 </template>
2125 </el-table-column>
2126 <el-table-column prop="checkRule" label="选择检验规则" width="150px" align="left" show-overflow-tooltip>
2127 <template #default="scope">
2128 <el-select v-if="!props.readonly" v-model="scope.row['checkRule']" placeholder="请选择" filterable clearable>
2129 <el-option v-for="opt in checkRulesList" :key="opt['paramValue']" :label="opt['paramName']" :value="opt['paramValue']" />
2130 </el-select>
2131 <span v-else>{{ scope.row.checkRuleName ?? '--' }}</span>
2132 </template>
2133 </el-table-column>
2134 <el-table-column label="填写配置项" width="200px" align="left">
2135 <template #default="scope">
2136 <span v-if="!scope.row.checkRule">--</span>
2137 <template v-else>
2138 <el-input v-show="scope.row.dataType == 'varchar' || scope.row.dataType == 'char' || scope.row.dataType == 'bit'" v-model.trim="scope.row.dataRange" clearable placeholder="多值按照分号;分隔"> </el-input>
2139 <div class="range-sum" v-show="scope.row.dataType == 'datetime' || scope.row.dataType == 'date'">
2140 <el-date-picker
2141 v-model="scope.row.dateValueRange"
2142 type="daterange"
2143 range-separator="至"
2144 start-placeholder="开始日期"
2145 end-placeholder="结束日期"
2146 format="YYYY-MM-DD"
2147 value-format="YYYY-MM-DD"
2148 :unlink-panels="false"
2149 :disabled="props.readonly"
2150 />
2151 </div>
2152 <div class="range-sum" v-show="scope.row.dataType == 'int' || scope.row.dataType == 'decimal' || scope.row.dataType == 'tinyint' || scope.row.dataType == 'timestamp' || scope.row.dataType == 'time'">
2153 <el-input :disabled="props.readonly" v-model.trim="scope.row.startValue" placeholder="请输入" clearable> </el-input>
2154 <span class="text"> </span>
2155 <el-input :disabled="props.readonly" v-model.trim="scope.row.endValue" placeholder="请输入" clearable> </el-input>
2156 </div>
2157 </template>
2158 </template>
2159 </el-table-column>
2160 </el-table>
2161 </div>
2162 </div>
2163
2164 <template #footer v-if="!props.readonly">
2165 <div class="dialog-footer">
2166 <el-button @click="cancelNormCheckDialog" v-preReClick>取消</el-button>
2167 <el-button @click="submitNormCheck" type="primary" v-preReClick>确定</el-button>
2168 </div>
2169 </template>
2170 </el-dialog>
2171
1815 <!-- 表行数检查 --> 2172 <!-- 表行数检查 -->
1816 <el-dialog v-model="tableRowDialogVisible" title="规则设置" width="750" :modal="true" :close-on-click-modal="false" 2173 <el-dialog v-model="tableRowDialogVisible" title="规则设置" width="750" :modal="true" :close-on-click-modal="false"
1817 destroy-on-close align-center> 2174 destroy-on-close align-center>
......
...@@ -332,6 +332,35 @@ const transformRulesInfo = (info: any) => { ...@@ -332,6 +332,35 @@ const transformRulesInfo = (info: any) => {
332 })] 332 })]
333 })); 333 }));
334 } 334 }
335 } else if (info.ruleCode == 'ref_integrality') {
336 let subjectTables = toSubjectTables.value;
337 info.ruleFields.forEach(row => {
338 let tableInfo = subjectTables.find(t => t.guid === row.mainTable);
339 let modelRule = modelRules.find(m => m.subjectName == tableInfo.enName);
340 if (modelRule) {
341 modelRule.modelRuleConfList.ruleField.push({
342 enName: row.mainTableField,
343 compareTableGuid: row.compareTableGuid,
344 compareTableName: row.compareTableName,
345 compareEnName: row.compareEnName
346 });
347 } else {
348 modelRules.push(Object.assign({}, {
349 modelGroupGuid: modelGroupGuid.value,
350 name: tableInfo.chName,
351 subjectName: tableInfo.enName,
352 subjectGuid: tableInfo.guid,
353 dataSourceGuid: tableInfo.dataSourceGuid,
354 databaseName: tableInfo.dataServerName,
355 modelRuleConfList: [Object.assign({}, info, {
356 enName: row.mainTableField,
357 compareTableGuid: row.compareTableGuid,
358 compareTableName: row.compareTableName,
359 compareEnName: row.compareEnName
360 })]
361 }));
362 }
363 })
335 } 364 }
336 return modelRules; 365 return modelRules;
337 } 366 }
...@@ -382,7 +411,8 @@ const save = () => { ...@@ -382,7 +411,8 @@ const save = () => {
382 :transferOpenNode="true" width="70%" :defaultProps="{ 411 :transferOpenNode="true" width="70%" :defaultProps="{
383 label: 'name', 412 label: 'name',
384 value: 'guid' 413 value: 'guid'
385 }" :lazyFn="handleSubjectTableLazyFn" @left-check-change="handleSubjectCheckedChange" height="calc(100% - 64px)"> 414 }" :lazyFn="handleSubjectTableLazyFn" @left-check-change="handleSubjectCheckedChange"
415 height="calc(100% - 64px)">
386 </TreeTransfer> 416 </TreeTransfer>
387 </div> 417 </div>
388 </div> 418 </div>
......
...@@ -140,6 +140,21 @@ const transformRulesInfo = (info: any) => { ...@@ -140,6 +140,21 @@ const transformRulesInfo = (info: any) => {
140 }), 140 }),
141 ruleFields: '' 141 ruleFields: ''
142 }); 142 });
143 } else if (info.ruleCode == 'ref_integrality') {
144 return Object.assign({}, info, {
145 guid: ruleGuid,
146 qualityModelGuid: detailInfo.value.qualityModelGuid,
147 ruleCode: detailInfo.value.ruleCode,
148 ruleField: info.ruleFields.map(row => {
149 return {
150 enName: row.mainTableField,
151 compareTableGuid: row.compareTableGuid,
152 compareTableName: row.compareTableName,
153 compareEnName: row.compareEnName
154 }
155 }),
156 ruleFields: ''
157 });
143 } 158 }
144 } 159 }
145 160
......
...@@ -135,6 +135,22 @@ const transformRulesInfo = (info) => { ...@@ -135,6 +135,22 @@ const transformRulesInfo = (info) => {
135 }), 135 }),
136 ruleFields: '' 136 ruleFields: ''
137 }); 137 });
138 } else if (info.ruleCode == 'ref_integrality') {
139 return Object.assign({}, info, {
140 qualityModelGuid: modelGuid,
141 ruleCode: info.ruleCode,
142 ruleField: info.ruleFields.map(row => {
143 return {
144 // guid: row.mainTable,
145 enName: row.mainTableField,
146 //chName: row.chName,
147 compareTableGuid: row.compareTableGuid,
148 compareTableName: row.compareTableName,
149 compareEnName: row.compareEnName
150 }
151 }),
152 ruleFields: ''
153 });
138 } 154 }
139 } 155 }
140 156
......
...@@ -271,7 +271,7 @@ const batching = (type) => { ...@@ -271,7 +271,7 @@ const batching = (type) => {
271 if (isfileImport == '2' || isfileImport == '4') { 271 if (isfileImport == '2' || isfileImport == '4') {
272 dialogInfo.value.header.title = '导入数据' 272 dialogInfo.value.header.title = '导入数据'
273 dialogInfo.value.type = 'upload' 273 dialogInfo.value.type = 'upload'
274 dialogInfo.value.size = 500 274 dialogInfo.value.size = isfileImport == '4' ? 600 : 500;
275 uploadFiles.value = [] 275 uploadFiles.value = []
276 uploadInfo.value.uploadInfo.steps = uploadSteps.value 276 uploadInfo.value.uploadInfo.steps = uploadSteps.value
277 const content: any = [uploadInfo.value] 277 const content: any = [uploadInfo.value]
...@@ -374,17 +374,24 @@ const importData = (info) => { ...@@ -374,17 +374,24 @@ const importData = (info) => {
374 }); 374 });
375 paramUrl = `${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/excel-by-subject-guid?staffGuid=${userData.staffGuid}&subjectGuid=${route.query.bizGuid}` 375 paramUrl = `${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/excel-by-subject-guid?staffGuid=${userData.staffGuid}&subjectGuid=${route.query.bizGuid}`
376 } else if (isfileImport == '4') { 376 } else if (isfileImport == '4') {
377 if (!info.collectTaskName) { 377 if (!info.databaseNameZh) {
378 ElMessage({ 378 ElMessage({
379 type: 'error', 379 type: 'error',
380 message: '请填写采集任务名称' 380 message: '请填写数据源名称'
381 })
382 return;
383 }
384 if (!info.databaseNameEn) {
385 ElMessage({
386 type: 'error',
387 message: '请填写数据库英文名'
381 }) 388 })
382 return; 389 return;
383 } 390 }
384 uploadFiles.value.forEach((item: any, index: number) => { 391 uploadFiles.value.forEach((item: any, index: number) => {
385 params.append("uploadFile", item.raw); 392 params.append("uploadFile", item.raw);
386 }); 393 });
387 paramUrl = `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/meta-collect-import?staffGuid=${userData.staffGuid}&collectTaskName=${info.collectTaskName}` 394 paramUrl = `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/meta-collect-import?staffGuid=${userData.staffGuid}&databaseNameZh=${info.databaseNameZh}&databaseNameEn=${info.databaseNameEn}&isCover=${info.isCover}`
388 } else { 395 } else {
389 uploadFiles.value.forEach((item: any, index: number) => { 396 uploadFiles.value.forEach((item: any, index: number) => {
390 params.append("file", item.raw); 397 params.append("file", item.raw);
...@@ -562,17 +569,36 @@ const setUploadInfo = () => { ...@@ -562,17 +569,36 @@ const setUploadInfo = () => {
562 uploadSteps.value = [ 569 uploadSteps.value = [
563 { 570 {
564 title: '1、导入前请先录入以下内容', 571 title: '1、导入前请先录入以下内容',
572 type: 'group',
573 formItems: [{
565 type: 'input', 574 type: 'input',
566 selectInfo: { 575 label: '数据源名称',
567 label: '采集任务名称',
568 placeholder: '请输入', 576 placeholder: '请输入',
569 field: 'collectTaskName', 577 field: 'databaseNameZh',
570 default: '', 578 default: '',
571 clearable: true, 579 clearable: true,
572 maxlength: 50, 580 maxlength: 50,
573 filterable: true, 581 filterable: true,
574 required: true 582 required: true
575 } 583 }, {
584 type: 'input',
585 label: '数据库英文名',
586 placeholder: '请输入',
587 field: 'databaseNameEn',
588 default: '',
589 clearable: true,
590 maxlength: 50,
591 filterable: true,
592 required: true
593 }, {
594 label: '是否覆盖原有数据',
595 type: 'switch',
596 field: 'isCover',
597 activeValue: 'Y',
598 block: true,
599 required: true,
600 inactiveValue: 'N'
601 }]
576 }, 602 },
577 { 603 {
578 title: '2、请下载最新的模板,并按照模板格式准备需要导入的数据', 604 title: '2、请下载最新的模板,并按照模板格式准备需要导入的数据',
...@@ -591,7 +617,7 @@ const setUploadInfo = () => { ...@@ -591,7 +617,7 @@ const setUploadInfo = () => {
591 } 617 }
592 } 618 }
593 ] 619 ]
594 uploadInfo.value.uploadInfo.extraParams = {} 620 uploadInfo.value.uploadInfo.extraParams = { isCover: 'Y' }
595 } else { 621 } else {
596 uploadSteps.value = [ 622 uploadSteps.value = [
597 { 623 {
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!