495dd53e by lxs

合并

2 parents abc5146e 98d58c5e
......@@ -13,6 +13,7 @@ VITE_APP_AUTH_URL = 'ms-daop-auth-service'
# 系统管理 接口地址
VITE_APP_API_BASEURL = ms-daop-zcgl-system-manager-service
# 文件上传请求地址
VITE_APP_ADD_FILE = ms-daop-import-data-service
# 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空
......@@ -32,6 +33,10 @@ VITE_APP_QUALITY_BASEURL = ms-daop-data-quality-service
# VITE_APP_CHECK_BASEURL = /mock
VITE_APP_CHECK_BASEURL = ms-daop-zcgl-data-inventory
# 数据字典接口地址
VITE_APP_CONFIG_URL = 'ms-daop-configure-service'
#门户接口
VITE_API_PORTALURL = https://swzl-test.zgsjzc.com/portal
......
# 页面标题
VITE_APP_TITLE = 数据资产管理系统
# 接口域名
VITE_API_BASEURL = https://www.zgsjzc.com/api
VITE_API_BASEURL = http://192.168.6.20:28052/
# VITE_API_BASEURL = http://49.4.26.201:31709/
# # 平台用户 接口请地址
# VITE_APP_USER_API_BASEURL = gateway-server
# # 系统管理 接口地址
# VITE_APP_API_BASEURL = ms-daop-zcgl-system-manager-service
# # 文件上传请求地址
# VITE_APP_ADD_FILE = ms-daop-import-data-service
# # 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空
# VITE_APP_DEBUG_TOOL =
# # 是否开启代理
# VITE_OPEN_PROXY = true
# # vite serve base
# VITE_SERVE_BASE = /
# # 流程设计访问地址
# VITE_BPMN_URL = https://workflow.zgsjzc.com
# # 数据标准、元数据、数据目录 接口地址
# VITE_APP_PLAN_BASEURL = ms-daop-jgjf-data-plan-service
# #数据质量接口地址
# VITE_APP_QUALITY_BASEURL = ms-daop-data-quality-service
# #门户接口
# VITE_API_PORTALURL = https://www.zgsjzc.com/portal
# #数据资产接口地址
# VITE_API_ASSET_BASEURL = ms-swzl-data-dam-service
# #数据同步接口地址
# VITE_API_DATA_SYNC = ms-swzl-data-sync-service
# #消息接口
# VITE_API_MESSAGE = ms-swzl-message-notification-service
# 平台用户 接口请地址
VITE_APP_USER_API_BASEURL = gateway-server
#AUTH服务
VITE_APP_AUTH_URL = 'ms-daop-auth-service'
# 系统管理 接口地址
VITE_APP_API_BASEURL = ms-daop-zcgl-system-manager-service
# 文件上传请求地址
VITE_APP_ADD_FILE = ms-daop-import-data-service
# 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空
......@@ -16,14 +49,22 @@ VITE_OPEN_PROXY = true
# vite serve base
VITE_SERVE_BASE = /
# 流程设计访问地址
VITE_BPMN_URL = https://workflow.zgsjzc.com
VITE_BPMN_URL = https://workflow-swzl-test.csbr.cn
# 数据标准、元数据、数据目录 接口地址
VITE_APP_PLAN_BASEURL = ms-daop-jgjf-data-plan-service
#数据质量接口地址
VITE_APP_QUALITY_BASEURL = ms-daop-data-quality-service
#数据盘点接口地址ms-daop-zcgl-data-inventory
# VITE_APP_CHECK_BASEURL = /mock
VITE_APP_CHECK_BASEURL = ms-daop-zcgl-data-inventory
# 数据字典接口地址
VITE_APP_CONFIG_URL = 'ms-daop-configure-service'
#门户接口
VITE_API_PORTALURL = https://www.zgsjzc.com/portal
VITE_API_PORTALURL = https://swzl-test.zgsjzc.com/portal
#数据资产接口地址
VITE_API_ASSET_BASEURL = ms-swzl-data-dam-service
......
FROM 192.168.5.4:82/csbr/nginx:stable-alpine
FROM 192.168.6.22:8081/csbr/nginx:stable-alpine
VOLUME /tmp
#将当前文件夹的dist文件复制到容器的/usr/share/nginx/html目录
COPY ./dist/* /usr/share/nginx/html/
COPY ./dist/assets /usr/share/nginx/html/assets
#COPY ./dist/importTemplate /usr/share/nginx/html/importTemplate
COPY default.conf /etc/nginx/conf.d/
#声明运行时容器暴露的端口(容器提供的服务端口)
EXPOSE 8911
RUN chown -R nginx:nginx /usr/share/nginx/html
EXPOSE 29900
#CMD:指定容器启动时要运行的命令
CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
CMD ["nginx", "-g", "daemon off;"]
......
......@@ -3,21 +3,22 @@ pipeline {
//环境定义
environment{
//服务名称
SVN_FOLD = "fe-swzl-asset-temp"
SVN_FOLD = "fe-data-asset-management"
//部署远程服务器
//192.168.4.4服务器
//SSH_PATH = "csbr4.4"
//192.168.5.4
SSH_PATH = "csbr5.2"
SSH_PATH = "csbr20"
SVN_TYPE = "dev"
//139.9.190.186
//SSH_PATH = "csbr190.186"
//SVN_TYPE = "master"
//镜像版本号
image_tag = "1.0.0"
//docker私服ip
ip = "192.168.5.4:82"
ip = "192.168.6.22:8081"
//前端端口号
port = "8911"
port = "29900"
//映射端口号
vport = "80"
......@@ -49,8 +50,10 @@ pipeline {
steps {
nodejs('node 16.20.2'){}
//配置私有npm仓库
sh 'npm config set registry http://192.168.5.4:8001/repository/csbr-npm/'
sh 'yarn config set registry http://192.168.5.4:8001/repository/csbr-npm/'
// sh 'npm config set registry http://192.168.5.4:8001/repository/csbr-npm/'
// sh 'yarn config set registry http://192.168.5.4:8001/repository/csbr-npm/'
sh 'npm config set registry http://49.4.23.228:8001/repository/csbr-npm/'
sh 'yarn config set registry http://49.4.23.228:8001/repository/csbr-npm/'
// 配置后可通过下面方式来验证是否成功
sh 'npm config get registry'
sh 'npm install -g pnpm'
......@@ -63,9 +66,9 @@ pipeline {
steps {
//分分支构建
script{
if(env.BRANCH_NAME=='master-asset'){
if(env.BRANCH_NAME=='develop'){
//master-asset分支环境
echo 'start to deploy ${SVN_FOLD} on master-asset ...'
echo 'start to deploy ${SVN_FOLD} on develop ...'
sh '''
#docker rmi -f $(docker images | grep "none" | awk '{print $3}')
CID=$(docker ps -a | grep "${SVN_FOLD}" | awk '{print $1}')
......@@ -77,15 +80,15 @@ pipeline {
##构建镜像到远程仓库
docker login "${ip}" -u admin -p E6w611g864wQ2
#docker tag "${SVN_FOLD}":"${image_tag}" "${ip}"/csbr/"${SVN_FOLD}":"${image_tag}"
docker build -t "${ip}"/csbr/"${SVN_FOLD}":"${image_tag}" .
docker push "${ip}"/csbr/"${SVN_FOLD}":"${image_tag}"
docker build -t "${ip}"/csbr/"${SVN_FOLD}""-${SVN_TYPE}":"${image_tag}" .
docker push "${ip}"/csbr/"${SVN_FOLD}""-${SVN_TYPE}":"${image_tag}"
else
echo "不存在'${SVN_FOLD}'镜像,开始构建镜像"
##构建镜像到远程仓库
docker login "${ip}" -u admin -p E6w611g864wQ2
#docker tag "${SVN_FOLD}":"${image_tag}" "${ip}"/csbr/"${SVN_FOLD}":"${image_tag}"
docker build -t "${ip}"/csbr/"${SVN_FOLD}":"${image_tag}" .
docker push "${ip}"/csbr/"${SVN_FOLD}":"${image_tag}"
docker build -t "${ip}"/csbr/"${SVN_FOLD}""-${SVN_TYPE}":"${image_tag}" .
docker push "${ip}"/csbr/"${SVN_FOLD}""-${SVN_TYPE}":"${image_tag}"
fi
'''
echo 'Depoly ${SVN_FOLD} success ...'
......@@ -107,14 +110,14 @@ pipeline {
echo 'Deploying'
//分分支部署
script{
if(env.BRANCH_NAME=='master-asset'){
if(env.BRANCH_NAME=='develop'){
//master-asset分支环境
echo 'start to deploy ${SVN_FOLD} on master-asset ...'
echo 'start to deploy ${SVN_FOLD} on develop ...'
//调用Publish Over SSH插件,上传docker-compose.yaml文件并且执行deploy脚本
sshPublisher(publishers: [sshPublisherDesc(configName: "csbr5.3", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: """
sshPublisher(publishers: [sshPublisherDesc(configName: "csbr20", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: """
#使用k8s构建
kubectl delete -f /mnt/k8s/production/fe-swzl-asset.yaml
kubectl apply -f /mnt/k8s/production/fe-swzl-asset.yaml
kubectl delete -f /mnt/k8s/develop/daop-jgjf/fe-data-asset-management.yaml
kubectl apply -f /mnt/k8s/develop/daop-jgjf/fe-data-asset-management.yaml
""", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/mnt/csbr/data', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'output/*.*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo 'Depoly ${SVN_FOLD} success ...'
......
......@@ -2,48 +2,53 @@ server {
listen 80;
listen [::]:80;
server_name localhost;
# server_name http://192.168.6.20:8052;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
# 设置允许跨域的域名,可以使用通配符 '*' 允许所有域访问
add_header 'Access-Control-Allow-Origin' * always;
# 设置允许的 HTTP 方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
# 设置允许的请求头
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Origin, X-Requested-With';
# 如果需要支持 cookie,可以设置以下 header
add_header 'Access-Control-Allow-Credentials' 'true';
# 缓存设置
add_header Cache-Control no-cache;
add_header Cache-Control private;
# # 预检请求处理
# if ($request_method = OPTIONS) {
# return 204;
# }
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1s;
}
location /api {
# 设置允许跨域的域名,可以使用通配符 '*' 允许所有域访问
add_header 'Access-Control-Allow-Origin' * always;
# 设置允许的 HTTP 方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
# 设置允许的请求头
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Origin, X-Requested-With';
# 如果需要支持 cookie,可以设置以下 header
add_header 'Access-Control-Allow-Credentials' 'true';
# 缓存设置
add_header Cache-Control no-cache;
add_header Cache-Control private;
expires -1s;
# 使用 rewrite 将 /api 替换为 /new-api
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://192.168.6.20:28052;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
......
/** --------------------- 质量评估模型 ------------------------------- */
import request from "@/utils/request";
/** 获取质量评估方案资产名称列表 */
export const getQualityDamList = () => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/dam-name-list`,
method: 'get'
})
/** 获取质量评估列表 */
export const getQualityList = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/dam-list`,
method: 'post',
data: params
})
/** 获取可选择的资产目录列表 */
export const getDamList = () => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/dam-name-list`,
method: 'post',
data: {}
})
/** 获取资产目录的表列表 */
export const getDamTableList = (damGuid) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/get-table-list?damGuid=${damGuid}`,
method: 'get'
})
/** 获取资产目录表的详情 */
export const getTableFields = (subjectGuid) => request({
url:`${import.meta.env.VITE_API_ASSET_BASEURL}/dam-catalog-table/get-table-detail?subjectGuid=${subjectGuid}`,
method: 'get'
});
/** 获取资产表的规则列表 */
export const getDamTableRulesList = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/list/rule-by-dam-guid`,
method: 'post',
data: params
})
/** 批量新增资产表的规则 */
export const saveDamTableRules = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/add`,
method: 'post',
data: params
})
/** 获取资产表的单个规则 */
export const getRuleConfDetail = (param) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/detail?ruleConfGuid=${param}`,
method: 'get'
})
/** 获取对应执行方案的规则详情 */
export const getRecordRuleConfDetail = (param) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model-record/conf/detail?ruleConfGuid=${param.ruleConfGuid}&planExecGuid=${param.planExecGuid}`,
method: 'get'
});
/** 编辑资产表的单个规则 */
export const updateDamTableRule = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/update`,
method: 'post',
data: params
})
/** 删除资产表的单个规则 */
export const deleteDamTableRule = (ruleConfGuid, planGuid: any = null) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/del?ruleConfGuid=${ruleConfGuid}&planGuid=${planGuid}`,
method: 'delete'
})
// 获取规则类型的接口
export const getRuleTypeList = () => request({
url:`${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-rule/list`,
method: 'post',
data: {}
})
// 获取规则大类的接口
export const getLargeCategoryList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "LARGE-CATEGORY" }
})
// 获取规则小类的接口
export const getSmallCategoryList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "SMALL-CATEGORY" }
})
/** 表的逻辑条件和sql检验。 */
export const validateSubjectTableRule = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/sql-operate/check-sql`,
method: 'post',
data: params
})
/** 自定义sql检验 */
export const validateCustomSql = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/conf/check-custom-sql`,
method: 'post',
data: params
})
/** 批量验证过滤条件 */
export const batchValidateSubjectTableRule = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/sql-operate/batch-check-sql`,
method: 'post',
data: params
})
/** ---------- 第二步,规则权重设置接口 ------ - */
/** 获取规则大类统计 */
export const getModelRuleCount = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-model/list/model-rule-category-count`,
method: 'post',
data: params
})
/** 保存质量评估方案 */
export const saveQualityPlan = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/add`,
method: 'post',
data: params
})
/** 更新质量方案 */
export const updateQualityPlan = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/update`,
method: 'put',
data: params
})
/** 删除质量方案 */
export const deleteQualityPlan = (guids) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/del`,
method: 'delete',
data: guids
})
/** 获取方案详情,用于编辑 */
export const getPlanDetail = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/detail/${params}`,
method: 'get'
})
/** 获取方案详情中的过滤条件,用于编辑 */
export const getPlanFilterDetail = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/query-plan-filter?planGuid=${params}`,
method: 'get'
})
/** 手动执行方案 */
export const executePlan = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/dam-exec-plan?planGuid=${params.planGuid}&reportGuid=${params.reportGuid}`,
method: 'post'
})
/** 获取方案查看详情列表数据。 */
export const getAssessDetailTableData = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/page-exec-log-list`,
method: 'post',
data: params
})
/** 根据执行guid,获取方案执行详情。 */
export const getExecPlanDetailTableData = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/query-exec-detail?&planExecGuid=${params.planExecGuid}`,
method: 'get'
})
/** 获取方案详情中每个表的规则详细执行列表数据。 */
export const getAssessTableRulesData = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/query-exec-table-detail?planExecGuid=${params.planExecGuid}&qualityModelGuid=${params.qualityModelGuid}`,
method: 'get'
})
/** 下载脏数据 */
export const downloadDirtyData = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/down-dirty-data`,
method: 'post',
data: params,
responseType: 'blob'
})
/** html转word接口 */
export const htmlToWord = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/download/html-to-word`,
method: 'postJsonD',
data: params,
responseType: 'blob'
});
/** 获取方案执行表规则查看 */
export const getTableRuleDetail= (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/query-exec-table-rule-detail?reportExecGuid=${params}`,
method: 'get'
});
/** 获取数据质量一级指标得分统计 */
export const getLargeCategoryScore = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-largeCategory-score?reportExecGuid=${params}`,
method: 'get'
});
/** 获取质量分析报告的详细内容,根绝报告guid。 */
export const getReportDetail = (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-report-data`,
method: 'post',
data: params
});
/** 获取方案执行明细 */
export const getPlanReportDetail= (params) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/query-exec-table-detail?reportExecGuid=${params.reportExecGuid}&planGuid=${params.planGuid}`,
method: 'get'
});
/** 下载sql语句执行 */
export const downPlanSql = (planGuid) => request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-plan/down-plan-sql?planGuid=${planGuid}`,
method: 'post',
responseType: 'blob'
})
import request from "@/utils/request";
/**
* 流通撮合
**/
/** 获取已添加的数据产品列表 */
export const getMatchList = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/circulation-matching/page-list`,
method: 'post',
data: params
})
/** 获取撮合详情 */
export const getMatchDetail = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/circulation-matching/detail`,
method: 'get',
params
})
/** 新增撮合信息 */
export const matchSave = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/circulation-matching/save`,
method: 'post',
data: params
});
/** 更新撮合信息 */
export const matchUpdate = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/circulation-matching/update`,
method: 'post',
data: params
});
/** 删除撮合信息 */
export const matchDelete = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/circulation-matching/delete`,
method: 'delete',
data: params
});
/** 获取撮合日志 */
export const getMatchLog = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/circulation-matching/state-change-log-list`,
method: 'get',
params
});
/**
* 金融产品
**/
/** 获取金融产品列表。 */
export const getFinancialList = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/page-list`,
method: 'post',
data: params
})
/** 获取金融产品详情 */
export const getFinancialDetail = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/detail`,
method: 'get',
params
})
/** 新增金融产品信息 */
export const financialSave = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/save`,
method: 'post',
data: params
});
/** 更新金融产品信息 */
export const financialUpdate = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/update`,
method: 'post',
data: params
});
/** 删除金融产品信息 */
export const financialDelete = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/delete`,
method: 'delete',
data: params
});
/** 更新金融产品上架状态 */
export const financialUpdateStatus = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/update-listing-Status`,
method: 'post',
data: params
});
/** 验证金融产品名称唯一性 */
export const checkFinancialName = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/financial-products/verify-data-name`,
method: 'get',
params
})
// 数据要素乘
export const orderStates = [{
value: 'N',
label: '待沟通'
}, {
value: 'I',
label: '沟通中'
}, {
value: 'R',
label: '达成意向'
}, {
value: 'C',
label: '合同拟定'
}, {
value: 'S',
label: '合同签署'
}, {
value: 'P',
label: '合同执行中'
}, {
value: 'Y',
label: '合同执行完'
}, {
value: 'D',
label: '撮合关闭'
}]
export const filterVal = (val, type) => {
if(type == 'orderState'){
const row = orderStates.filter(d => d.value == val);
return row.length?row[0].label:'--';
} else if(type == 'tenantNature'){
let approval = '--';
switch (val) {
case 1:
approval = '数据字典数据治理';
break;
case 2:
approval = '律师事务所';
break;
case 3:
approval = '会计师事务所';
break;
case 4:
approval = '金融机构';
break;
case 5:
approval = '资产评估机构';
break;
case 6:
approval = '申请数据资产化企业';
break;
case 7:
approval = '其他';
break;
default:
approval = '--';
break;
}
return approval;
}
}
export const filterStatus = (row, type) => {
let state = 'info'
if (type == 'orderState') {
switch (row[type]) {
case "N":
state = 'warning'
break;
case "I":
state = 'warning'
break;
case "R":
state = "warning"
break
case "C":
state = "warning"
break
case "S":
state = "primary"
break
case "P":
state = "primary"
break
case "Y":
state = 'success';
break;
case "D":
state = "info"
break
default:
state = "info"
break
}
}
return state;
}
......@@ -2,16 +2,174 @@ import request from "@/utils/request";
/**
* 数据字典
**/
// 编码规则流水号
export const getCoderuleList = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/code-rule/list`,
method: 'post',
data: params
})
// 获取数据类型的接口
export const getDataTypeList = (params) => request({
url: `${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: params,
})
// 获取数据库列表
export const getDataBaseList = (params) => request({
url: `${import.meta.env.VITE_APP_API_BASEURL}/data-source/get-source-list`,
method: 'post',
data: params,
})
// 新增
export const addDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/add`,
method: 'post',
data: params
})
// 删除
export const deleteDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/del`,
method: 'delete',
data: params
})
// 删除数据字典前的校验
export const checkDeleteDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/check-del`,
method: 'delete',
data: params
})
// 编辑校验数据结构删除的条件
export const checkDeleteDictionaryScheme = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/check-del/dictionary-scheme`,
method: 'post',
data: params
})
// 分页查询
// export const getDictionary = (params) => request({
// url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/page-list`,
// method: 'post',
// data: params
// })
// 查询数据字典启用状态的数据
export const getDictionaryAll = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/list-all`,
method: 'post',
params
})
// 修改
export const updateDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/update`,
method: 'put',
data: params
})
// 详情
export const getDictionaryDetail = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/detail/${params}`,
method: 'get'
})
// 查看数据字典数据
export const getDictionaryFileds = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/dictionary-data/${params}`,
method: 'get'
})
// 数据字典启用停用
export const updateDictionaryState = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/change-state`,
method: 'get',
params
})
// 检验是否存在
export const checkDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/check-exist`,
method: 'get',
params
})
// 数据字典新增数据时生成编码规则
export const getDictionaryRuleData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/generate/code-rule/byGuid`,
method: 'get',
params
})
// 数据字典树形数据
export const getDictionaryTree = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/tree-list`,
method: 'post',
params
})
// 保存动态数据字典数据
export const saveDictionaryData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/save/dictionary-data`,
method: 'post',
data: params
})
// 更新数据字典数据
export const updateDictionaryData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/update/dictionary-data`,
method: 'post',
data: params
})
// 删除数据字典数据
export const deleteDictionaryData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/del/dictionary-data`,
method: 'delete',
data: params
})
// 导入数据字典
export const importDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/import/data-dictionary`,
method: 'post',
data: params
})
// 显示导入的数据字典数据
export const showDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/import/show/data-dictionary`,
method: 'post',
data: params,
headers: {
'Content-Type': 'multipart/form-data'
}
})
// 导出数据字典模板
export const exportDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/export/data-dictionary/schema`,
method: 'post',
data: params,
responseType: 'blob'
})
// 导出数据字典数据
export const exportDictionaryFileds = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/export/data-dictionary/data`,
method: 'post',
data: params,
responseType: 'blob'
})
// 验证数据是否符合标准
export const checkDictionaryData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/check/dictionary-data`,
method: 'post',
data: params
})
/**
* 获取数据级别
* @param {Object}
* { paramCode: "DATA-CLASSIFY" }
* DATA-CLASSIFY 数据类别
* DATA-GRADE 数据级别
*/
export const getLargeCategoryList = (data) => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data
// export const getLargeCategoryList = (data) => request({
// url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
// method: 'post',
// data
// })
export const getLargeCategoryList = (params) => request({
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${params.dictType}`,
method: 'get',
})
......@@ -213,6 +371,18 @@ export const getCgTemplateClassifyTreeList = (data) => request({
/**-------------------------分类分级目录--------------------------------- */
/**
* 查询执行guid和目录名称
* @param {no params}
* @path /cg-dir/get-exec-guid-and-name
*/
export const getExecGuidAndName = () => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/cg-dir/get-exec-guid-and-name`,
method: 'post',
})
/**
* 分类分级目录树形列表
......@@ -390,3 +560,152 @@ export const filterVal = (val, type) => {
}
return status;
}
/** 获取字典列表
* VITE_APP_PLAN_BASEURL 为环境变量 现在只是mock数据
*/
export const getDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/data-dictionary-general/list-all?state=1`,
method: 'post'
})
/** 业务规则配置-新增
* @param {Object}
* @path /biz-rule-config/save
*/
export const saveBizRuleConfig = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/save`,
method: 'post',
data
})
/**树形目录
* @param {Object}
* @path /db-dir/tree-list
*/
export const getDbDirTreeList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/tree-list`,
method: 'post',
data
})
/**
* 数据库目录-表数据列表查询
* @param {Object}
* @path /db-dir/table/page-list
*/
export const getDbDirTablePageList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/page-list`,
method: 'post',
data
})
/**
* 数据库目录-已有数据库列表
* @param {no params}
* @path /db-dir/data-source/list
*/
export const getDbDirDataSourceList = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/data-source/list?execGuid=${params.execGuid}`,
method: 'post',
})
/**
* 获取列表
* @param {Object}
* @path /db-dir/field/page-list
* @returns
*/
export const getDbDirFieldPageList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/page-list`,
method: 'post',
data
})
/** 获取已有字段信息 */
export const getDsTableStructure= (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/list-by-table-guid`,
method: 'post',
data
});
/** 根据选择的连接池获取表列表 */
export const getDsTableByDs = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/list-by-datasource-guid`,
method: 'post',
data: params
})
/** 根据数据表获取表结构 */
export const getDsData= (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/table-column-list`,
method: 'post',
data: params
});
/**
* 数据库新建目录表
* @param {Object}
* @path /db-dir/table/save
*/
export const saveDbDirTable = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/save`,
method: 'post',
data
})
/**
* 数据库目录修改表
* @param {Object}
* @path /db-dir/table/update
*/
export const updateDbDirTable = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/update`,
method: 'post',
data
})
/**
* 生成建表sql语句
* @param {Object}
* @path /db-dir/table/create-table-sql
*/
export const createTableSql = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/create-table-sql`,
method: 'post',
data
})
/*********************业务规则配置 ************数据库目录************************* */
/**
* 业务规则配置-详情
* @param {Object}
* @path /biz-rule-config/detail
* @returns
*/
export const getBizRuleConfigDetail = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/detail?tableGuid=${params.tableGuid}&execGuid=${params.execGuid}`,
method: 'get',
})
/**
* 业务规则配置-修改
* @param {Object}
* @path /biz-rule-config/update
* @returns
*/
export const updateBizRuleConfig = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/update`,
method: 'post',
data
})
......
......@@ -17,10 +17,11 @@ export const deleteMetaDataTask = (params) => request({
})
// 分页查询
export const getMetaDataTask = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/page-list`,
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/meta-collect-task/page-list`,
method: 'post',
data: params
})
// 修改
export const updateMetaDataTask = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-collect-task/update`,
......@@ -92,7 +93,7 @@ export const getMetaDataSheet = (params) => request({
})
// 表字段查询
export const getMetaSheetField = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/meta-table/meta-table-field-list`,
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/meta-table/meta-table-field-list`,
method: 'post',
params
})
......
import request from "@/utils/request";
/** 校验公司名称是否重复 */
export const checkCompanyName = (params) => request({
url: `${import.meta.env.VITE_API_PORTALURL}/portal/cooperate-register/verify-company-name`,
method: 'get',
params
})
/** 获取短信验证码 */
export const getRegisterCode = (params) => request({
url: `${import.meta.env.VITE_API_PORTALURL}/portal/sms/get-verify-code`,
method: 'post',
params
})
/** 校验短信验证码 */
export const checkRegisterCode = (params) => request({
url: `${import.meta.env.VITE_API_PORTALURL}/portal/sms/get-verify-code-validation`,
method: 'post',
params
})
/** 注册信息申请 */
export const registerInfoSave = (params) => request({
url: `${import.meta.env.VITE_API_PORTALURL}/portal/cooperate/save`,
method: 'post',
data: params
});
/** 获取注册信息列表。 */
export const getRegisterInfoList = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/cooperate-register/page-list`,
method: 'post',
data: params
})
/** 获取注册信息详情 */
export const getRegiaterInfoDetail = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/cooperate-register/detail`,
method: 'get',
params
})
/** 更新注册信息 */
export const registerInfoUpdate = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/cooperate-register/update`,
method: 'post',
data: params
});
/** 删除注册信息 */
export const registerInfoDelete = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/cooperate-register/delete`,
method: 'delete',
data: params
});
/** 验证管理员账号是否重复 */
export const checkAccount = (params) => request({
url: `${import.meta.env.VITE_API_ASSET_BASEURL}/cooperate-register/verify-admin-account`,
method: 'get',
params
})
/** 获取登录日志 */
export const getAccountLog = (params) => request({
url: `${import.meta.env.VITE_APP_API_BASEURL}/user/user-login-record`,
method: 'post',
data: params
})
/** 获取图形验证码 **/
export const getImgCodeSrc = (params={}) => request({
url: `${import.meta.env.VITE_API_PORTALURL}/portal/get-captcha`,
method: 'get',
params
})
/** 校验图形验证码 **/
export const checkImgCode = (params={}) => request({
url: `${import.meta.env.VITE_API_PORTALURL}/portal/check`,
method: 'post',
params
})
......@@ -2,18 +2,622 @@ import type { MockMethod } from 'vite-plugin-mock'
import Mock from 'mockjs'
export const confirmDelivery = {
url: '/mock/youthBoost/admin/shipment',
/**
* {
"children": [
{
"parentGuids": [
"string"
]
}
],
"parentGuids": [
"string"
],
"guid": "string",
"tenantGuid": "string",
"cgDirName": "string",
"classifyName": "string",
"orderNum": 0,
"level": 0,
"levelCode": "string",
"parentGuid": "string"
}
*/
export const getCgDirTreeList = {
url: '/mock/cg-dir/tree-list',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data|10-30': [{
guid: '@guid',
tenantGuid: '@guid',
cgDirName: '@cword(3, 10)',
classifyName: '@cword(3, 5)',
orderNum: '@integer(1, 100)',
level: '@integer(1, 3)',
levelCode: '@string("number", 6)',
parentGuid: '@guid',
'parentGuids|1-2': ['@guid'],
'children|0-3': [{
guid: '@guid',
tenantGuid: '@guid',
cgDirName: '@cword(3, 5)',
classifyName: '@cword(3, 5)',
orderNum: '@integer(1, 100)',
level: '@integer(1, 3)',
levelCode: '@string("number", 6)',
parentGuid: '@guid',
'parentGuids|1-2': ['@guid']
}]
}]
}
}
}
/**
* "data": {
"totalRows": 0,
"totalPages": 0,
"pageSize": 0,
"pageIndex": 0,
"records": [
{
"guid": "string",
"tenantGuid": "string",
"cgDirName": "string",
"dirGuid": "string",
"classifyName": "string",
"gradeDetailName": "string",
"label": "string",
"fieldName": "string",
"fieldChName": "string",
"tableName": "string",
"tableChName": "string",
"database": "string",
"databaseChName": "string"
}
],
export const getCgDirFieldPageList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/cg-dir/field/page-list`,
method: 'post',
data
})
*/
export const getCgDirFieldPageList = {
url: '/mock/cg-dir/field/page-list',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data': {
totalRows: '@integer(50, 100)',
totalPages: '@integer(1, 10)',
pageSize: 10,
pageIndex: 1,
'records|20-30': [{
guid: '@guid',
tenantGuid: '@guid',
cgDirName: '@cword(3, 5)',
dirGuid: '@guid',
classifyName: '@cword(3, 5)',
gradeDetailName: '@cword(3, 5)',
label: '@cword(3, 5)',
fieldName: '@cword(3, 5)',
fieldChName: '@cword(3, 5)',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)'
}]
}
}
}
}
/**
*
* export const getDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/list-all?state=1`,
method: 'post'
})
*/
export const getDictionary = {
url: '/mock/data-dictionary-general/list-all',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data|10-30': [{
guid: '@guid',
tenantGuid: '@guid',
chName: '@cword(3, 5)',
classifyName: '@cword(3, 5)',
orderNum: '@integer(1, 100)',
level: '@integer(1, 3)',
levelCode: '@string("number", 6)',
parentGuid: '@guid',
'parentGuids|1-2': ['@guid'],
'children|0-3': [{
guid: '@guid',
tenantGuid: '@guid',
chName: '@cword(3, 5)',
classifyName: '@cword(3, 5)',
orderNum: '@integer(1, 100)',
level: '@integer(1, 3)',
levelCode: '@string("number", 6)',
parentGuid: '@guid',
'parentGuids|1-2': ['@guid']
}]
}]
}
}
}
export const saveBizRuleConfig = {
url: '/mock/biz-rule-config/save',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功'
}
}
}
/**
* "data": [
{
"cgDirName": "string",
"childList": [
{
"databaseGuid": "string",
"database": "string",
"databaseChName": "string",
"childList": [
{
"tableGuid": "string",
"tableName": "string",
"tableChName": "string"
}
]
}
]
}
],
export const getDbDirTreeList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/tree-list`,
method: 'post',
data
})
*/
export const getDbDirTreeList = {
url: '/mock/db-dir/tree-list',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data|10-30': [{
cgDirName: '@cword(3, 5)',
'children|1-3': [{
databaseGuid: '@guid',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)',
'children|1-3': [{
tableGuid: '@guid',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)'
}]
}]
}]
}
}
}
/**
* /**
* 数据库目录-表数据列表查询
* @param {Object}
* @path /db-dir/table/page-list
* export const getDbDirTablePageList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/page-list`,
method: 'post',
data
})
"data": {
"totalRows": 0,
"totalPages": 0,
"pageSize": 0,
"pageIndex": 0,
"records": [
{
"guid": "string",
"tenantGuid": "string",
"cgDirName": "string",
"dirGuid": "string",
"tableGuid": "string",
"tableName": "string",
"tableChName": "string",
"databaseGuid": "string",
"database": "string",
"databaseChName": "string",
"foundMode": 0,
"state": 0,
"isDataAsset": "string"
}
],
}
*/
export const getDbDirTablePageList = {
url: '/mock/db-dir/table/page-list',
method: 'post',
response: ({body}:{body:any}) => {
const {pageIndex, pageSize} = body
return {
code: '00000',
message: '成功',
'data': {
totalRows: '@integer(50, 100)',
totalPages: '@integer(1, 10)',
pageSize,
pageIndex,
'records|20-30': [{
guid: '@guid',
tenantGuid: '@guid',
cgDirName: '@cword(3, 5)',
dirGuid: '@guid',
tableGuid: '@guid',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)',
databaseGuid: '@guid',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)',
foundMode: '@integer(1, 3)',
state: '@integer(0,2)',
isDataAsset: 'Y',
description: '@cword(10, 15)',
}]
}
}
}
}
/**
* export const getDbDirDataSourceList = () => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/data-source/list`,
method: 'post',
})
"data": [
{
"tableGuid": "string",
"tableName": "string",
"tableChName": "string",
"databaseGuid": "string",
"database": "string",
"databaseChName": "string"
}
],
*/
export const getDbDirDataSourceList = {
url: '/mock/db-dir/data-source/list',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data|10-30': [{
tableGuid: '@guid',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)',
databaseGuid: '@guid',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)'
}]
}
}
}
/**
* export const getDsData = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/list-by-datasource-guid`,
method: 'post',
data: params
});
"data": {
"totalRows": 0,
"totalPages": 0,
"pageSize": 0,
"pageIndex": 0,
"records": [
{
"tableGuid": "string",
"tableName": "string",
"tableChName": "string",
"databaseGuid": "string",
"database": "string",
"databaseChName": "string"
}
],
*/
export const getDsTableByDs = {
url: '/mock/db-dir/table/list-by-datasource-guid',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data': {
totalRows: '@integer(50, 100)',
totalPages: '@integer(1, 10)',
pageSize: 10,
pageIndex: 1,
'records|50-100': [{
tableGuid: '@guid',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)',
databaseGuid: '@guid',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)'
}]
}
}
}
}
export const getDsTableStructure = {
url: '/mock/db-dir/field/list-by-table-guid',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data|2-5': [{
guid: '@guid',
tableGuid: '@guid',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)',
databaseGuid: '@guid',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)',
fieldGuid: '@guid',
fieldName: '@cword(3, 5)',
fieldChName: '@cword(3, 5)',
fieldType: '@cword(3, 5)',
fieldLength: '@integer(1, 100)',
fieldPrecision: '@integer(1, 100)',
dimGuid: '@guid',
dictionaryGuid: '@guid',
sortValue: '@integer(1, 100)',
isPrimary: 'Y',
isFk: 'Y',
isNotNull: 'Y'
}]
}
}
}
/**
* export const getDbDirFieldPageList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/page-list`,
method: 'post',
data
})
{
"code": "string",
"msg": "string",
"data": {
"totalRows": 0,
"totalPages": 0,
"pageSize": 0,
"pageIndex": 0,
"records": [
{
"guid": "string",
"tenantGuid": "string",
"cgDirName": "string",
"dirGuid": "string",
"classifyName": "string",
"gradeDetailName": "string",
"label": "string",
"fieldName": "string",
"fieldChName": "string",
"tableName": "string",
"tableChName": "string",
"database": "string",
"databaseChName": "string"
}
],
*/
export const getDbDirFieldPageList = {
url: '/mock/db-dir/field/page-list',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data': {
totalRows: '@integer(50, 100)',
totalPages: '@integer(1, 10)',
pageSize: 10,
pageIndex: 1,
'records|20-30': [{
guid: '@guid',
tenantGuid: '@guid',
cgDirName: '@cword(3, 5)',
dirGuid: '@guid',
classifyName: '@cword(3, 5)',
gradeDetailName: '@cword(3, 5)',
label: '@cword(3, 5)',
fieldName: '@cword(3, 5)',
fieldChName: '@cword(3, 5)',
tableName: '@cword(3, 5)',
tableChName: '@cword(3, 5)',
database: '@cword(3, 5)',
databaseChName: '@cword(3, 5)'
}]
}
}
}
}
/**
* export const getBizRuleConfigDetail = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/detail?tableGuid=${params.tableGuid}&execGuid=${params.execGuid}`,
method: 'get',
})
"data": [
{
"guid": "string",
"tenantGuid": "string",
"classifyName": "string",
"gradeDetailName": "string",
"fieldName": "string",
"fieldChName": "string",
"fieldGuid": "string",
"fieldType": "string",
"fieldLengthCondition": "string",
"fieldPrecision": 0,
"dictionaryGuid": "string",
"isUnique": "string",
"isNotNull": "string",
"fieldValueRange": "string"
}
],
*/
export const getBizRuleConfigDetail = {
url: '/mock/biz-rule-config/detail',
method: 'get',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
'data|1-3': [{
guid: '@guid',
tenantGuid: '@guid',
classifyName: '@cword(3, 5)',
gradeDetailName: '@cword(3, 5)',
fieldName: '@cword(3, 5)',
fieldChName: '@cword(3, 5)',
fieldGuid: '@guid',
fieldType: '@cword(3, 5)',
fieldLengthCondition: '>#10',
fieldPrecision: '@integer(1, 100)',
dictionaryGuid: '@guid',
isUnique: 'Y',
isNotNull: 'Y',
fieldValueRange: '0-100'
}]
}
}
}
/**
* export const updateBizRuleConfig = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/update`,
method: 'post',
data
}){
"code": "string",
"msg": "string",
"data": true,
"at": "string",
"serviceCode": "string"
}
*/
export const updateBizRuleConfig = {
url: '/mock/biz-rule-config/update',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: 200,
code: '00000',
message: '成功',
data: []
data: true,
at: 'string',
serviceCode: 'string'
}
}
}
/**
* /**
* 数据库新建目录表
* @param {Object}
* @path /db-dir/table/save
* export const saveDbDirTable = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/save`,
method: 'post',
data
})
*/
export const saveDbDirTable = {
url: '/mock/db-dir/table/save',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功'
}
}
}
/**
* /**
* 数据库目录修改表
* @param {Object}
* @path /db-dir/table/update
* export const updateDbDirTable = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/update`,
method: 'post',
data
})
*/
export const updateDbDirTable = {
url: '/mock/db-dir/table/update',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功'
}
}
}
/***
* /**
* 生成建表sql语句
* @param {Object}
* @path /db-dir/table/create-table-sql
* export const createTableSql = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/create-table-sql`,
method: 'post',
data
})
*/
export const createTableSql = {
url: '/mock/db-dir/table/create-table-sql',
method: 'post',
response: ({body}:{body:any}) => {
return {
code: '00000',
message: '成功',
data: 'create table test_table (id int, name varchar(255))'
}
}
}
export default [confirmDelivery] as MockMethod[]
export default [getCgDirTreeList,getCgDirFieldPageList,
getDictionary,saveBizRuleConfig, getDbDirTreeList,
getDbDirTablePageList,getDbDirDataSourceList,getDsTableByDs,
getDsTableStructure,getDbDirFieldPageList,getBizRuleConfigDetail,
updateBizRuleConfig,saveDbDirTable,createTableSql,updateDbDirTable] as MockMethod[]
......
......@@ -209,8 +209,76 @@ const routes: RouteRecordRaw[] = [
cache: true
},
},
{
path: 'configure-rules',
name: 'configureRules',
component: () => import('@/views/data_inventory/configureRules.vue'),
meta: {
title: '配置业务规则',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
editPage: true,
activeMenu: '/data-inventory/classify-grade-catalogue',
},
},
{
path: 'table-create-existing',
name: 'tableCreateExisting',
component: () => import('@/views/data_inventory/tableCreateExisting.vue'),
meta: {
title: '已有表新建',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
},
beforeEnter: (to, from) => {
if (to.query.domainName) {
to.meta.title = `已有表新建(${to.query.domainName})`;
to.meta.editPage = true;
}
}
},
{
path: 'table-create-file',
name: 'tableCreateFile',
component: () => import('@/views/data_inventory/tableCreateFile.vue'),
meta: {
title: '根据文件新建',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
},
beforeEnter: (to, from) => {
}
},
],
},
{
path: '/data-inventory/data-dictionary',
component: Layout,
meta: {
title: '数据字典',
icon: 'sidebar-cooperation',
},
children: [
{
path: '',
name: 'dictionary',
component: () => import('@/views/data_inventory/dictionary.vue'),
meta: {
title: '数据字典',
sidebar: false,
breadcrumb: false,
cache: true
},
},
],
}
},
]
export default routes
......
......@@ -101,6 +101,13 @@ const systemRoutes: RouteRecordRaw[] = [
// 动态路由(异步路由、导航栏路由)
const asyncRoutes: Route.recordMainRaw[] = [
{
meta:{
title: '首页',
},
children: [
],
},
{
meta: {
title: '数据资产管理',
},
......
......@@ -218,7 +218,7 @@ const rulesDetailTableInfo: any = ref({
oneRulesDetailDialogVisible.value = true;
} else {
detailJson.value[row.ruleConfGuid] = { isRequest: true };
getRecordRuleConfDetail({ruleConfGuid: row.ruleConfGuid, planExecGuid: planExecGuid }).then((res: any) => {
getRecordRuleConfDetail({ ruleConfGuid: row.ruleConfGuid, planExecGuid: planExecGuid }).then((res: any) => {
detailLoading.value = false;
oneRulesDetailDialogVisible.value = true;
if (res.code == proxy.$passCode) {
......@@ -302,4 +302,4 @@ const rulesDetailTableInfo: any = ref({
}
}
}
</style>
\ No newline at end of file
</style>
......
......@@ -72,9 +72,12 @@ const tableInfo = ref({
return status == 'Y' ? '有效' : '停用';
}
},
{ label: "定义说明", width: 360, field: "description", },
{ label: "定义说明", width: 140, field: "description", },
{
label: "最低安全级别参考", field: "name", width: 140,
label: "最低安全级别参考", field: "name", width: 140, getName: (scope) => {
let dataGrade = scope.row.dataGrade;
return dataGrade + '级';
}
},
{ label: "修改人", field: "updateUserName", width: 140 },
{ label: "更新时间", field: "updateTime", width: 180 },
......@@ -386,6 +389,7 @@ const getGradeListData = async () => {
const newCreateClass = () => {
drawerInfo.value.visible = true;
classEditFormItems.value[2].options = treeListData.value;
drawerInfo.value.header.title = '添加分类';
classEditFormItems.value.forEach(item => {
if (item.field == 'status') {
......@@ -702,7 +706,7 @@ onMounted(() => {
style="margin-top:16px; height: calc(100% - 161px)">
<div class="tools_btns">
<el-button v-show="dataShowMethod == 'table'" type="primary" @click="newCreateClass">添加分类</el-button>
<el-button v-show="dataShowMethod == 'table'" @click="importClass">导入分类</el-button>
<!-- <el-button v-show="dataShowMethod == 'table'" @click="importClass">导入分类</el-button> -->
<el-button class="show-change-btn" @click="changeShowMethod">{{ '图形展示' }}</el-button>
</div>
<Table v-show="dataShowMethod == 'table'" :tableInfo="tableInfo" />
......
......@@ -31,14 +31,14 @@ const getGradeListData = async () => {
// 获取数据类别
const getDataGrade = async () => {
const params = {
paramCode: "DATA-CLASSIFY"
dictType: "数据类别"
}
const res: any = await getLargeCategoryList(params);
if (res.code == proxy.$passCode) {
// 提出value和label 作为select的options
const options = res.data.map((item: any) => ({
label: item.paramName,
value: item.paramValue
label: item.label,
value: item.value
}));
newCreateGradeFormItems.value[1].options = options;
classDataRef.value = options;
......@@ -50,14 +50,14 @@ const getDataGrade = async () => {
// 获取数据级别
const getDataClassify = async () => {
const params = {
paramCode: "DATA-GRADE"
dictType: "数据级别"
}
const res: any = await getLargeCategoryList(params);
if (res.code == proxy.$passCode) {
// 提出value和label 作为select的options
const options = res.data.map((item: any) => ({
label: item.paramName,
value: item.paramValue
label: item.label,
value: item.value
}));
newCreateGradeFormItems.value[0].options = options;
// 这里需要过滤已经在表格中数据级别
......
......@@ -3,54 +3,33 @@
</route>
<script lang="ts" setup name="classifyGradeCatalogue">
import { CirclePlus, Delete, Warning } from "@element-plus/icons-vue";
import { Warning } from "@element-plus/icons-vue";
import TableTools from '@/components/Tools/table_tools.vue';
import { getCgDirTreeList, getCgDirFieldPageList } from '@/api/modules/dataInventory';
const currentPath = ref<string[]>(['全部', '个人信息', '个人自然信息', '个人基本概况信息']);
const tempData = [
{
guid: '1',
standardName: '个人信息',
status: 'published',
children: [
{
guid: '1-1',
standardName: '个人自然信息',
status: 'published',
children: [
{
guid: '1-1-1',
standardName: '个人基本概况信息',
status: 'published',
},
{
guid: '1-1-2',
standardName: '个人财产信息',
status: 'published',
},
{
guid: '1-1-3',
standardName: '个人健康信息',
status: 'published',
},
]
},
]
},
];
import {
getCgDirTreeList, getCgDirFieldPageList, getDictionary, saveBizRuleConfig,
getDbDirTreeList, getDbDirTablePageList, getDbDirFieldPageList, getExecGuidAndName
} from '@/api/modules/dataInventory';
import { TableColumnWidth } from "@/utils/enum";
import router from "@/router";
const currentPath = ref<string[]>([]);
const { proxy } = getCurrentInstance() as any;
// 分级分类树形列表
const CgDirTreeList = ref();
const getCgDirTreeData = async () => {
treeInfo.value.loading = true;
const params = {
classifyName: '',
}
const res: any = await getCgDirTreeList(params);
if (res.code == proxy.$passCode) {
CgDirTreeList.value = res.data;
treeInfo.value.data = res.data;
currentPath.value = [res.data[0].classifyName];
treeInfo.value.expandedKey = [res.data[0].guid];
treeInfo.value.currentNodeKey = res.data[0].guid;
treeInfo.value.loading = false;
} else {
proxy.$ElMessage.error(res.msg);
}
......@@ -58,6 +37,7 @@ const getCgDirTreeData = async () => {
// 分页列表
const CgDirFieldPageList = ref();
const getCgDirFieldPage = async (params = {}) => {
tableInfo.value.loading = true;
// 在这里你可以根据需要扩展或修改 params
const defaultParams = {
pageIndex: 1,
......@@ -74,165 +54,74 @@ const getCgDirFieldPage = async (params = {}) => {
const finalParams = { ...defaultParams, ...params };
const res: any = await getCgDirFieldPageList(finalParams);
if (res.code == proxy.$passCode) {
CgDirFieldPageList.value = res.data;
CgDirFieldPageList.value = res.data.records;
tableInfo.value.page.rows = res.data.totalRows;
tableInfo.value.page.limit = res.data.pageSize
tableInfo.value.page.curr = res.data.pageIndex
tableInfo.value.data = res.data.records;
tableInfo.value.loading = false;
} else {
proxy.$ElMessage.error(res.msg);
}
};
const dictionaryList = ref([]);
const getDictionaryList = () => {
getDictionary({}).then((res: any) => {
dictionaryList.value = [];
if (res.code == proxy.$passCode) {
dictionaryList.value = res.data || [];
classEditFormItems.value[4].options = res.data || [];
} else {
proxy.$ElMessage.error(res.msg);
}
})
};
// 获取执行guid
const execGuidInfo = ref<any>({});
const getExecGuid = async () => {
const res: any = await getExecGuidAndName();
if (res.code == proxy.$passCode) {
execGuidInfo.value = res.data;
} else {
proxy.$ElMessage.error(res.msg);
}
}
onMounted(() => {
getCgDirTreeData();
getCgDirFieldPage();
getDictionaryList();
getExecGuid();
})
// 左侧tree-list
const treeInfo = ref({
id: "data-pickup-tree",
filter: true,
editTreeItem: true,
editTreeItem: false,
queryValue: "",
className: 'tree-list',
queryPlaceholder: "输入标准集名称搜索",
props: {
label: "standardName",
label: "classifyName",
value: "guid",
},
nodeKey: 'guid',
expandedKey: ['0'],
currentNodeKey: '',
expandOnNodeClick: false,
data: tempData,
data: [],
loading: false
});
// 弹窗配置
const formItems: any = ref([
{
label: '标准集名称',
type: 'input',
maxlength: 50,
placeholder: '请输入',
field: 'standardName',
clearable: true,
required: true
}, {
label: '标准集编号',
type: 'input',
placeholder: '',
field: 'standardCode',
required: true,
disabled: true
}, {
label: "上级标准集",
type: 'tree-select',
placeholder: '请选择',
field: 'parentGuid',
default: '',
checkStrictly: true,
lazy: false,
clearable: true,
options: [],
props: {
label: 'standardName',
value: 'guid',
children: 'children',
isLeaf: 'isLeaf'
},
expandKeys: [],
filterable: true,
required: false
}, {
label: '排序',
type: 'input',
placeholder: '请输入',
field: 'orderNum',
maxlength: 6,
required: true,
clearable: true,
}, {
label: '描述',
type: 'textarea',
placeholder: '请输入',
field: 'description',
clearable: true,
required: false,
block: true
},
])
const formRules: any = ref({
standardName: [
{
required: true,
message: '请输入标准集名称',
trigger: 'blur'
},
{
max: 50,
message: '长度在 50 个字符以内',
trigger: 'blur'
},
],
orderNum: [{
validator: (rule: any, value: any, callback: any) => {
if (value === 0) {
callback();
return;
}
if (!value) {
callback(new Error('请填写排序'));
return;
}
const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头)
if (value && !r.test(value)) {
callback(new Error('请填写大于或等于零整数'));
return;
}
callback();
},
trigger: "blur",
}],
})
const formInfo = ref({
type: "form",
title: "",
formInfo: {
id: "add-set-standard-form",
items: formItems.value,
rules: formRules.value
},
})
const standardSetDialogInfo: any = ref({
visible: false,
size: 700,
direction: "column",
header: {
title: "新建",
},
type: '',
contents: [formInfo.value],
footer: {
visible: true,
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", value: "submit" },
],
},
})
const addStandardSet = () => {
standardSetDialogInfo.value.visible = true;
console.log('addStandardSet');
}
const standardSetDialogBtnClick = (btn: any, info: any) => {
console.log('standardSetDialogBtnClick', btn, info);
if (btn.value === 'submit') {
standardSetDialogInfo.value.visible = false;
}
if (btn.value === 'cancel') {
standardSetDialogInfo.value.visible = false;
}
}
// 右侧上方搜索tab配置
const searchItemList = ref([
......@@ -250,20 +139,20 @@ const searchItemList = ref([
},
clearable: true,
},
{
label: '字段名',
type: 'select',
maxlength: 19,
placeholder: '选择字段名',
field: 'fieldName',
default: '',
options: [],
props: {
label: 'name',
value: 'guid',
},
clearable: true,
},
// {
// label: '字段名',
// type: 'select',
// maxlength: 19,
// placeholder: '选择字段名',
// field: 'fieldName',
// default: '',
// options: [],
// props: {
// label: 'name',
// value: 'guid',
// },
// clearable: true,
// },
{
label: '分类',
type: 'select',
......@@ -290,34 +179,7 @@ const searchItemList = ref([
value: 'guid',
},
clearable: true,
}, {
label: '数据库名',
type: 'select',
maxlength: 19,
placeholder: '选择数据库名',
field: 'databaseName',
default: '',
options: [],
props: {
label: 'name',
value: 'guid',
},
clearable: true,
},
{
label: '表名',
type: 'select',
maxlength: 19,
placeholder: '选择表名',
field: 'tableName',
default: '',
options: [],
props: {
label: 'name',
value: 'guid',
},
clearable: true,
}
])
const searchParams = ref({})
const toSearch = (val: any, clear: boolean = false) => {
......@@ -336,14 +198,11 @@ const toSearch = (val: any, clear: boolean = false) => {
// params.standardSetLevelCode = standardSetLevelCode.value;
// return getTableData(params);
};
const treeSelectNodeChange = (node: any) => {
console.log('treeSelectNodeChange', node);
const { guid, standardName } = node
treeInfo.value.currentNodeKey = guid;
console.log('nodeClick', guid, standardName);
const nodeClick = (data: any) => {
const { guid, classifyName } = data
// 递归tempData找到所有祖先元素的standardName,存入currentPath中
const path = findPath(tempData, guid);
const path = findPath(CgDirTreeList.value, guid);
if (path) {
currentPath.value = path;
console.log('找到路径:', path);
......@@ -351,31 +210,43 @@ const treeSelectNodeChange = (node: any) => {
console.error('未找到路径');
}
}
const findPath = (data: any[], targetGuid: string, path: string[] = []) => {
for (const item of data) {
path.push(item.classifyName); // 添加当前节点名称
if (item.guid === targetGuid) {
return path; // 找到目标节点,返回路径
}
if (item.children && item.children.length > 0) {
const result = findPath(item.children, targetGuid, path);
if (result) return result; // 子节点找到目标节点,返回路径
}
path.pop(); // 回溯,移除当前节点
}
return null; // 未找到目标节点
};
// btns-area
const checked1 = ref(false);
const checked = ref(false);
const changeCheck = (val) => {
checked.value = val;
getDataBaseTableData();
}
//下方表格配置
const tableDataList = ref([{
fieldStandardCode: '个人基本概况信息',
chName: '个人自然信息',
enName: '个人信息',
dataTypeValue: '规则',
approveState: 'Y',
}, {
fieldStandardCode: '个人财产信息',
chName: '个人自然信息',
enName: '个人信息',
dataTypeValue: '规则',
approveState: 'Y',
}, {
fieldStandardCode: '个人健康信息',
chName: '个人自然信息',
enName: '个人信息',
dataTypeValue: '规则',
approveState: 'Y',
}]);
const tableDataList = ref();
const page = ref({
limit: 10,
curr: 1,
sizes: [
{ label: "10", value: 10 },
{ label: "20", value: 20 },
{ label: "100", value: 100 },
{ label: "150", value: 150 },
{ label: "200", value: 200 },
],
});
const tableInfo = ref({
id: "role-manage-table",
multiple: true,
......@@ -384,20 +255,142 @@ const tableInfo = ref({
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "字段名", field: "fieldName", width: 140 },
{ label: "分类", field: "classifyName", width: 180 },
{ label: "分级", field: "enName", width: 120 },
{ label: "标签", field: "labelName", width: 140 },
{ label: "分级", field: "gradeDetailName", width: 120 },
{ label: "标签", field: "label", width: 140 },
{ label: "规则", field: "rulesName", width: 180 },
{ label: "表名", field: "tableName", width: 120, align: 'center' },
{ label: "表中文名", field: "tableCHName", width: 120, align: 'center' },
{ label: "数据库名", field: "databaseName", width: 120, align: 'center' },
{ label: "数据类型", field: "databaseCHName", width: 120, align: 'center' },
{ label: "表中文名", field: "tableChName", width: 120, align: 'center' },
{ label: "数据库名", field: "database", width: 120, align: 'center' },
{ label: "数据类型", field: "databaseChName", width: 120, align: 'center' },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
show: false,
},
loading: false
});
const tablePageChange = (info) => {
console.log('tablePageChange', info);
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getCgDirFieldPage({
pageIndex: info.curr,
pageSize: info.limit
});
}
// 选中配置的业务规则
const selectedRulesData = ref();
const tableCheckboxSelectChange = (select, row) => {
// 遍历选中的数据,存入selectedRulesData
let rulesName: any = [];
let rulesGuid: any = [];
select.forEach((item: any) => {
rulesName.push(item.classifyName);
rulesGuid.push(item.guid);
});
selectedRulesData.value = {
rulesName: rulesName.join('、'),
guids: rulesGuid
};
}
const tableCheckboxAllSelectChange = (select) => {
// 遍历选中的数据,存入selectedRulesData
let rulesName: any = [];
let rulesGuid: any = [];
select.forEach((item: any) => {
rulesName.push(item.classifyName);
rulesGuid.push(item.guid);
});
selectedRulesData.value = {
rulesName: rulesName.join('、'),
guids: rulesGuid
};
}
// 批量配置业务规则
const batchControlRules = () => {
// 判断是否选中数据
if (!selectedRulesData.value || !selectedRulesData.value.guids || selectedRulesData.value.guids.length == 0) {
proxy.$ElMessage.warning('请选择数据');
return;
}
drawerInfo.value.visible = true;
classEditFormItems.value[0].default = selectedRulesData.value.rulesName;
}
// 数据库目录
// 左侧tree-list
const dataBaseTreeInfo = ref<any>({
id: "data-pickup-tree",
filter: true,
editTreeItem: false,
queryValue: "",
className: 'tree-list',
queryPlaceholder: "输入标准集名称搜索",
props: {
label: "name",
value: "guid",
},
nodeKey: 'guid',
expandedKey: ['0'],
currentNodeKey: '',
expandOnNodeClick: false,
data: [],
loading: false
});
const dataBasePage = ref({
limit: 10,
curr: 1,
sizes: [
{ label: "10", value: 10 },
{ label: "20", value: 20 },
{ label: "100", value: 100 },
{ label: "150", value: 150 },
{ label: "200", value: 200 },
],
data: tableDataList.value,
});
const dataBaseTableInfo = ref({
id: "data-base-table",
multiple: true,
fixedSelection: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "数据源", field: "cgDirName", width: 140 },
{ label: "表名称", field: "tableName", width: 180 },
{ label: "数据库表", field: "tableChName", width: 120 },
{
label: "新建方式", field: "foundMode", width: 140, getName: (scope) => {
let dataGrade = scope.row.foundMode;
return dataGrade == 1 ? '根据文件新建' : '已有表新建';
}
},
{
label: "状态", field: "state", type: 'tag', width: 180, getName: (scope) => {
let status = scope.row.state;
// 0 草稿中 1 已建表 2 已有默认表
return status == 0 ? '草稿中' : status == 1 ? '已建表' : '已有默认表';
}
},
{ label: "任务修改人", field: "damName", width: 120 },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
{ label: "描述", field: "description", width: 120, align: 'center' },
{ label: "规划数据资产", field: "isDataAsset", type: 'switch', activeText: '是', inactiveText: '否', activeValue: 'Y', inactiveValue: 'N', switchWidth: 56, width: 120, align: 'center' },
],
data: [],
page: {
type: "normal",
rows: 0,
// ...page.value,
...dataBasePage.value,
},
actionInfo: {
label: "操作",
......@@ -406,22 +399,27 @@ const tableInfo = ref({
fixed: 'right',
btns: [
{
label: "编辑", value: "edit", click: (scope) => {
label: "配置业务规则", value: "edit", click: (scope) => {
console.log('编辑', scope);
drawerInfo.value.visible = true
// 路由跳转configure-rules
router.push({
name: 'configureRules',
query: {
cgDirName: scope.row.cgDirName,
tableName: scope.row.tableName,
tableChName: scope.row.tableChName,
guid: scope.row.guid,
description: scope.row.description,
}
});
}
},
{
label: "复制", value: "copy", click: (scope) => {
label: "编辑表结构", value: "copy", click: (scope) => {
console.log('复制', scope);
}
},
{
label: "删除 ", value: "delete", click: (scope) => {
console.log('删除', scope);
}
},
}
]
},
......@@ -429,36 +427,17 @@ const tableInfo = ref({
});
const nodeClick = (data: any) => {
const { guid, standardName } = data
console.log('nodeClick', guid, standardName);
searchItemList.value[0].default = standardName;
// 递归tempData找到所有祖先元素的standardName,存入currentPath中
const path = findPath(tempData, guid);
if (path) {
currentPath.value = path;
console.log('找到路径:', path);
} else {
console.error('未找到路径');
}
}
const findPath = (data: any[], targetGuid: string, path: string[] = []) => {
for (const item of data) {
path.push(item.standardName); // 添加当前节点名称
if (item.guid === targetGuid) {
return path; // 找到目标节点,返回路径
}
if (item.children && item.children.length > 0) {
const result = findPath(item.children, targetGuid, path);
if (result) return result; // 子节点找到目标节点,返回路径
}
path.pop(); // 回溯,移除当前节点
}
return null; // 未找到目标节点
};
// 映射 大于,小于,等于 三种关系
const selectLength = ref([
{ label: '大于', value: '>', },
{ label: '小于', value: '<', },
{ label: '等于', value: '=', },
]
)
const classEditFormItems = ref([{
label: '已选字段',
type: 'input',
......@@ -468,14 +447,14 @@ const classEditFormItems = ref([{
default: '',
clearable: true,
required: true,
block: true
block: true,
disabled: true,
}, {
label: '长度',
type: 'input',
type: 'select',
placeholder: '请选择',
field: 'orderNum',
maxlength: 6,
regexp: /\D/g,
field: 'orderNumLength',
options: selectLength.value,
required: true,
clearable: true,
},
......@@ -494,31 +473,21 @@ const classEditFormItems = ref([{
label: '精度',
type: 'input',
placeholder: '请选择',
field: 'orderNum',
maxlength: 6,
regexp: /\D/g,
required: true,
clearable: true,
},
{
label: '',
type: 'input',
placeholder: '请输入',
field: 'orderNum',
field: 'fieldPrecision',
maxlength: 6,
regexp: /\D/g,
required: true,
clearable: true,
col: 'numberClass',
block: true,
}, {
label: '关联字典',
field: 'parentGuid',
field: 'dictionaryGuid',
type: 'select',
placeholder: '请选择',
default: '',
options: [],
props: {
label: "classifyName",
label: "chName",
value: "guid",
},
filterable: true,
......@@ -529,7 +498,7 @@ const classEditFormItems = ref([{
label: '字段取值范围',
type: 'input-group',
placeholder: '请输入',
field: 'numberAround',
field: 'fieldValueRange',
default: '',
children: [
{
......@@ -555,26 +524,31 @@ const classEditFormItems = ref([{
{
label: '数据是否唯一',
type: "radio-group",
field: "radioField",
field: "isUnique",
disabled: false,
default: 'N',
options: [
{ label: "选项一", value: "option1", disabled: false },
{ label: "选项二", value: "option2", disabled: false },
{ label: "是", value: "Y", disabled: false },
{ label: "否", value: "N", disabled: false },
],
},
{
label: '是否必填',
type: "radio-group",
field: "radioField",
field: "isNotNull",
disabled: false,
default: 'N',
options: [
{ label: "选项一", value: "option1", disabled: false },
{ label: "选项二", value: "option2", disabled: false },
{ label: "是", value: "Y", disabled: false },
{ label: "否", value: "N", disabled: false },
],
}
]);
const classEditFormRules = ref({
classifyName: [{ required: true, message: '请填写分类名称', trigger: 'blur' }],
orderNumLength: [{ required: true, message: '请选择长度', trigger: 'blur' }],
orderNum: [{ required: true, message: '请填写长度', trigger: 'blur' }],
fieldPrecision: [{ required: true, message: '请填写精度', trigger: 'blur' }],
});
/** 新增分类的form */
const classEditFormInfo = ref({
......@@ -611,73 +585,258 @@ const drawerBtnClick = async (btn, info) => {
if (btn.value == 'cancel') {
drawerInfo.value.visible = false;
} else {
// if (drawerInfo.value.header.title == '添加分类') {
// const params = {
// ...info,
// classifyGradeGuid: router.currentRoute.value.query.guid,
// }
// const res: any = await saveClassify(params);
// if (res.code == proxy.$passCode) {
// proxy.$ElMessage.success('添加成功!');
// drawerInfo.value.visible = false;
// getTreeListData();
// } else {
// proxy.$ElMessage.error(res.msg);
// }
// } else {
// // 编辑分类
// const params = {
// ...info,
// classifyGradeGuid: router.currentRoute.value.query.guid,
// guid: currTableInfo.value.guid
// }
// const res: any = await updateClassify(params);
// if (res.code == proxy.$passCode) {
// proxy.$ElMessage.success('修改成功!');
// drawerInfo.value.visible = false;
// getTreeListData();
// } else {
// proxy.$ElMessage.error(res.msg);
// }
// }
console.log('aaa')
btn.loading = true;
const { orderNumLength, orderNum, numberStart, numberEnd, fieldPrecision, dictionaryGuid, isUnique, isNotNull } = info;
let fieldLengthCondition = orderNumLength + '#' + orderNum;
let fieldValueRange: any = [];
if (numberStart && numberEnd) {
if (numberEnd < numberStart) {
proxy.$ElMessage.error('字段取值范围结束值不能小于开始值');
return;
}
fieldValueRange = [numberStart, numberEnd];
}
const params = {
fieldPrecision,
dictionaryGuid,
isUnique,
isNotNull,
fieldLengthCondition,
fieldValueRange,
fieldGuid: selectedRulesData.value.guids
}
const res: any = await saveBizRuleConfig(params);
if (res.code == proxy.$passCode) {
btn.loading = false;
proxy.$ElMessage.success('配置成功!');
drawerInfo.value.visible = false;
getCgDirFieldPage();
} else {
proxy.$ElMessage.error(res.msg);
}
}
}
const handleTreeItemMenuClick = (data: any, type) => {
console.log('handleTreeItemMenuClick', data, type);
}
const getItemStyle = (status: string) => {
const styles: { [key: string]: any } = {
published: {
color: '#1BA854',
background: '#F2FFF5',
border: '1px solid rgba(109, 209, 142, 1)',
},
running: {
color: '#FF991C',
background: '#FFFBF2',
border: '1px solid rgba(255, 203, 120, 1)',
},
pending: {
border: '1px solid rgba(217, 217, 217, 1)',
color: '#404040',
background: '#F5F5F5',
},
};
return styles[status] || {}; // 如果状态没有对应的样式,则返回空对象
}
// tab切换
const activeName = ref('first');
const handleClick = (tab: any) => {
console.log(tab.props.name);
activeName.value = tab.props.name;
if (tab.props.name === 'second') {
getDataBaseTreeData();
getDataBaseTableData();
getDataBaseFieldData();
}
}
// 获取数据库树形列表 getDbDirTreeList
const dataBaseTreeData = ref<any>();
const getDataBaseTreeData = async () => {
dataBaseTreeInfo.value.loading = true;
try {
const res: any = await getDbDirTreeList({});
if (res.code == proxy.$passCode) {
const dataArray = [res.data];
// 遍历并添加 GUIDs
dataArray.forEach(addGuids);
// 更新到绑定的响应式数据
dataBaseTreeData.value = dataArray;
dataBaseTreeInfo.value.data = dataArray;
} else {
proxy.$ElMessage.error(res.msg);
}
} catch (error) {
proxy.$ElMessage.error('请求失败');
} finally {
dataBaseTreeInfo.value.loading = false;
}
};
// 处理数据,给每个节点添加 GUID
const addGuids = (node) => {
if (node.databaseGuid) {
node.guid = node.databaseGuid;
node.name = node.databaseChName;
} else if (node.tableGuid) {
node.guid = node.tableGuid;
node.name = node.tableChName;
} else {
node.guid = crypto.randomUUID();
node.name = node.cgDirName;
}
if (node.children && Array.isArray(node.children)) {
node.children.forEach(addGuids);
}
};
// 获取数据列表
const dataBaseTableDataList = ref<any>();
const getDataBaseTableData = async (params = {}) => {
dataBaseTableInfo.value.loading = true;
const dataBaseParams = {
pageIndex: 1,
pageSize: 10,
databaseGuid: "",
isDataAsset: checked.value ? 'Y' : 'N',
execGuid: execGuidInfo.value.execGuid,
};
const finalParams = { ...dataBaseParams, ...params };
const res: any = await getDbDirTablePageList(finalParams);
if (res.code == proxy.$passCode) {
dataBaseTableDataList.value = res.data.records;
dataBaseTableInfo.value.page.rows = res.data.totalRows;
dataBaseTableInfo.value.data = res.data.records;
dataBasePage.value.limit = res.data.pageSize
dataBasePage.value.curr = res.data.pageIndex
} else {
proxy.$ElMessage.error(res.msg);
}
dataBaseTableInfo.value.loading = false;
};
const dataBaseTablePageChange = (info) => {
console.log('dataBaseTablePageChange', info);
dataBasePage.value.curr = Number(info.curr);
dataBasePage.value.limit = Number(info.limit);
getDataBaseTableData({
pageIndex: info.curr,
pageSize: info.limit
});
}
// 获取字段信息getDbDirFieldPageList
const tableFieldsLoading = ref(false);
const tableFieldsData = ref([]);
const getDataBaseFieldData = async (params = {}) => {
tableFieldsLoading.value = true;
const dataBaseParams = {
pageIndex: 1,
pageSize: 10,
tableGuid: "",
execGuid: execGuidInfo.value.execGuid,
databaseGuid: "",
isDataAsset: checked.value ? 'Y' : 'N',
};
const finalParams = { ...dataBaseParams, ...params };
const res: any = await getDbDirFieldPageList(finalParams);
if (res.code == proxy.$passCode) {
tableFieldsData.value = res.data.records;
tableFieldsDataInfo.value.data = res.data.records;
} else {
proxy.$ElMessage.error(res.msg);
}
tableFieldsLoading.value = false;
};
const tableFieldsDataInfo = ref({
id: "data-field-table",
multiple: false,
fixedSelection: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "字段名", field: "fieldName", width: 140 },
{ label: "字段中文名", field: "fieldChName", width: 180 },
{ label: "表名", field: "tableName", width: 120 },
{ label: "表中文名", field: "tableChName", width: 140, },
{ label: "数据库名称", field: "database", width: 120 },
{ label: "数据库中文名", field: "databaseChName", width: TableColumnWidth.DATETIME },
{ label: "分类", field: "description", width: 120, align: 'center' },
{ label: "分级", field: "isDataAsset", width: 120, align: 'center' },
{ label: "标签", field: "label", width: 120, align: 'center' },
],
data: [],
showPage: false,
page: {
// type: "normal",
// rows: 0,
// ...dataBasePage.value,
},
actionInfo: {
show: false,
},
loading: false
});
const showTableOrDatabase = ref(true);
// 定义tableGuid
const tableGuid = ref('');
const dataBaseGuid = ref('');
const dataBasenodeClick = (data: any) => {
console.log('dataBasenodeClick', data);
if (data.cgDirName) {
tableGuid.value = '';
dataBaseGuid.value = '';
getDataBaseFieldData();
getDataBaseTableData();
}
if (data.databaseGuid) {
dataBaseGuid.value = data.databaseGuid;
tableGuid.value = '';
getDataBaseFieldData({
databaseGuid: data.databaseGuid
});
getDataBaseTableData({
databaseGuid: data.databaseGuid
});
}
if (data.tableGuid) {
tableGuid.value = data.tableGuid;
dataBaseGuid.value = '';
getDataBaseFieldData({
tableGuid: data.tableGuid
});
getDataBaseTableData({
tableGuid: data.tableGuid
});
}
if (data.databaseGuid || data.cgDirName) {
showTableOrDatabase.value = true;
return;
}
if (data.tableGuid) {
showTableOrDatabase.value = false;
return;
}
}
const nodeSelectChange = (data: any) => {
console.log('nodeSelectChange', data);
}
const handleSubjectTableCommand = (command: string) => {
console.log('handleSubjectTableCommand', command);
if (command === 'manualCreate') {
router.push({
name: 'tableCreateFile',
query: {
type: 'tableCreateFile'
}
});
} else if (command === 'existingCreate') {
// 已有表新建
router.push({
name: 'tableCreateExisting',
query: {
execGuid: execGuidInfo.value.execGuid
}
});
}
}
// 文字提示区域
......@@ -691,13 +850,112 @@ const addIsShowDatabaseTip = () => {
isShowDatabaseTip.value = false;
}
// 表信息和字段信息切换
const activeTab = ref('table');
const setActiveTab = (tab) => {
console.log('setActiveTab', tab);
activeTab.value = tab;
};
// 模拟后端接口
const fetchOptionsA = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ label: "选项 A1", value: "a1" },
{ label: "选项 A2", value: "a2" },
]);
}, 500);
});
};
const fetchOptionsB = (aValue) => {
return new Promise((resolve) => {
setTimeout(() => {
const data = {
a1: [
{ label: "B1-1", value: "b1" },
{ label: "B1-2", value: "b2" },
],
a2: [
{ label: "B2-1", value: "b3" },
{ label: "B2-2", value: "b4" },
],
};
resolve(data[aValue] || []);
}, 500);
});
};
const fetchOptionsC = (bValue) => {
return new Promise((resolve) => {
setTimeout(() => {
const data = {
b1: [
{ label: "C1-1", value: "c1" },
{ label: "C1-2", value: "c2" },
],
b3: [
{ label: "C2-1", value: "c3" },
{ label: "C2-2", value: "c4" },
],
};
resolve(data[bValue] || []);
}, 500);
});
};
const selectedA = ref<any>(null);
const selectedB = ref<any>(null);
const selectedC = ref<any>(null);
const optionsA = ref<any>([]);
const optionsB = ref<any>([]);
const optionsC = ref<any>([]);
// 初始化加载第一个下拉框的选项
const loadOptionsA = async () => {
optionsA.value = await fetchOptionsA();
};
// 第一个下拉框值改变时
const onAChange = async () => {
selectedB.value = null;
selectedC.value = null;
optionsB.value = [];
optionsC.value = [];
optionsB.value = await fetchOptionsB(selectedA.value); // 根据 A 动态加载 B 的选项
};
// 第二个下拉框值改变时
const onBChange = async () => {
selectedC.value = null;
optionsC.value = [];
optionsC.value = await fetchOptionsC(selectedB.value); // 根据 B 动态加载 C 的选项
};
// 页面加载时初始化 A 的数据
loadOptionsA();
</script>
<template>
<div class="classification-template-content">
<div class="v-table-tools">
<TableTools :searchItems="searchItemList" :init="false" :searchId="'files-standard-search'" @search="toSearch"
@treeSelectNodeChange="treeSelectNodeChange" />
<el-select v-model="selectedA" placeholder="选择数据库名" @change="onAChange" style="width: 140px; margin-right: 8px"
clearable>
<el-option v-for="item in optionsA" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="selectedB" placeholder="选择表名" :disabled="!selectedA" @change="onBChange"
style="width: 140px; margin-right: 8px" clearable>
<el-option v-for="item in optionsB" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="selectedC" placeholder="选择字段名" :disabled="!selectedB" style="width: 140px;margin-right: 8px"
clearable>
<el-option v-for="item in optionsC" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<TableTools :searchItems="searchItemList" :init="false" :searchId="'files-standard-search'" @search="toSearch" />
</div>
<div class="container_wrap full flex">
<div class="aside_wrap">
......@@ -705,7 +963,9 @@ const addIsShowDatabaseTip = () => {
<el-tab-pane label="分类分级目录" name="first">
<Tree :treeInfo="treeInfo" @nodeClick="nodeClick" @itemMenuClick="handleTreeItemMenuClick" />
</el-tab-pane>
<el-tab-pane label="数据库目录" name="second">Config</el-tab-pane>
<el-tab-pane label="数据库目录" name="second">
<Tree :treeInfo="dataBaseTreeInfo" @nodeClick="dataBasenodeClick" @nodeSelectChange='nodeSelectChange' />
</el-tab-pane>
</el-tabs>
</div>
<div class="main_wrap" v-if="activeName === 'first'">
......@@ -732,11 +992,13 @@ const addIsShowDatabaseTip = () => {
<div class="left-btns">
<el-button type="primary" @click="addStandardSet">查看已生产报告</el-button>
<el-button>导出</el-button>
<el-button>批量配置业务规则</el-button>
<el-button @click="batchControlRules">批量配置业务规则</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" />
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange"
@tableCheckboxSelectChange="tableCheckboxSelectChange"
@tableCheckboxAllSelectChange="tableCheckboxAllSelectChange" />
</div>
</div>
......@@ -755,7 +1017,20 @@ const addIsShowDatabaseTip = () => {
</el-button>
</div>
<div>全部</div>
<div class="btns-area">
<div class="tab-btn">
内容信息:
<div v-if="showTableOrDatabase" class="table" :class="{ active: activeTab === 'table' }"
@click="setActiveTab('table')">
表信息
</div>
<div class="word" :class="{ active: activeTab === 'word' || !showTableOrDatabase }"
@click="setActiveTab('word')">
字段信息
</div>
</div>
<div class="btns-area" v-if="!tableGuid && activeTab === 'table'">
<div class="left-btns">
<div class="dropdown_btn">
<el-dropdown popper-class="table-create-menu" @command="handleSubjectTableCommand"
......@@ -792,15 +1067,16 @@ const addIsShowDatabaseTip = () => {
<el-button>查看质量规则</el-button>
</div>
<div class="right-btns">
<el-checkbox v-model="checked1" label="仅看规划数据资产表" size="large" />
<el-checkbox v-model="checked" label="仅看规划数据资产表" size="large" @change="changeCheck" />
</div>
</div>
<div class="table_panel_wrap_database">
<Table :tableInfo="tableInfo" />
<div class="table_panel_wrap_database" v-if="!tableGuid && activeTab === 'table'">
<Table :tableInfo="dataBaseTableInfo" @tablePageChange="dataBaseTablePageChange" />
</div>
<div class="table_field" v-if="tableGuid || activeTab === 'word'">
<Table :tableInfo="tableFieldsDataInfo" :loading="tableFieldsLoading" />
</div>
</div>
<Dialog :dialogInfo="standardSetDialogInfo" @btnClick="standardSetDialogBtnClick" />
<Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" class="v-drawer" />
</div>
......@@ -817,6 +1093,8 @@ const addIsShowDatabaseTip = () => {
flex-direction: column;
.v-table-tools {
display: flex;
align-items: center;
padding: 8px 12px;
}
......@@ -830,23 +1108,39 @@ const addIsShowDatabaseTip = () => {
border-right: 1px solid #d9d9d9;
box-shadow: none;
:deep(.v-tabs) {
.el-tabs__item {
padding: 0 10px;
}
:deep(.el-tabs__item) {
padding: 0 8px;
}
.tree_panel {
.v-tabs {
height: 100%;
padding-top: 0;
:deep(.el-tree) {
margin: 0;
height: calc(100% - 68px);
overflow: hidden auto;
.el-tabs__content {
height: 100%;
.el-tab-pane {
height: 100%;
}
}
}
// :deep(.v-tabs) {
// .el-tabs__item {
// padding: 0 12px;
// }
// }
.tree_panel {
height: 100%;
padding-top: 0;
:deep(.el-tree) {
margin: 0;
height: calc(100% - 115px);
overflow: hidden auto;
}
}
}
}
.main_wrap {
......@@ -915,17 +1209,66 @@ const addIsShowDatabaseTip = () => {
.table_panel_wrap {
width: 100%;
height: calc(100% - 113px);
height: calc(100% - 175px);
min-height: 210px;
overflow: visible;
}
.table_panel_wrap_database {
width: 100%;
height: calc(100% - 113px);
height: calc(100% - 215px);
min-height: 210px;
overflow: visible;
}
.table_field {
width: 100%;
height: calc(100% - 180px);
min-height: 210px;
overflow: visible;
}
/* 外层容器 */
.tab-btn {
display: flex;
align-items: center;
font-size: 14px;
margin-top: 6px;
margin-bottom: 6px;
}
/* Tab 按钮样式 */
.tab-btn div {
padding: 4px 12px;
cursor: pointer;
border: 1px solid #ccc;
background-color: #f7f7f7;
transition: background-color 0.3s ease, color 0.3s ease;
}
.tab-btn .table {
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
.tab-btn .word {
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
/* 默认未选中样式 */
.tab-btn div:not(.active):hover {
background-color: #e0e0e0;
}
/* 选中样式 */
.tab-btn .active {
background-color: #4FA1A4;
color: white;
border-color: #4FA1A4;
}
}
}
......@@ -954,7 +1297,7 @@ const addIsShowDatabaseTip = () => {
:deep(.v-drawer) {
.numberClass {
margin-top: 12px;
margin-top: 10px;
}
}
}
......
<template>
<el-select v-if="!readonly && isEdit && isSelectType(dbType, scope)" v-model="scope.row['defaultValue']" placeholder="请选择" collapse-tags-tooltip
filterable allow-create default-first-option :reserve-keyword="false">
<el-option v-for="opt in optionsConfig[dataType]" :key="opt['value']" :label="opt['label']" :value="opt['value']" />
</el-select>
<el-date-picker v-else-if="!readonly && isEdit && dataType === 'date'" v-model="scope.row['defaultValue']" type="date"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="请选择" />
<el-date-picker v-else-if="!readonly && isEdit && dbType === 'mysql' && dataType === 'datetime'"
v-model="scope.row['defaultValue']" placeholder="请选择" type="datetime" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss" />
<el-input v-else-if="!readonly && isEdit" v-model.trim="scope.row['defaultValue']" placeholder="请填写"
@input="(val) => inputChange(val, scope.row.dataType, scope)" />
<span v-else>{{ scope.row["defaultValue"] == null ? '--' : (isSelectType(dbType, scope) ?
(optionsConfig[dataType].find(s => s.value == scope.row["defaultValue"])?.label ??
scope.row["defaultValue"]) : scope.row["defaultValue"]) }}</span>
</template>
<script lang="ts" setup name="tableDefaultValue">
import { ref } from "vue";
import { useDefault } from "@/hooks/useDefault";
const { optionsConfig, inputChange, isSelectType } = useDefault()
const props = defineProps({
dbType: {
type: String,
default: ''
},
scope: {
type: Object,
default: {}
},
readonly: {
type: Boolean,
default: false
}
})
const isEdit = computed(() => {
return props.scope.row['isEdit'];
});
const dataType = computed(() => {
return props.scope.row['dataType'];
});
</script>
\ No newline at end of file
<script lang="ts" setup name="uploadExcelFile">
import { ref } from "vue";
import { ElMessage, ElMessageBox, ElTable } from "element-plus";
import { TableColumnWidth } from '@/utils/enum';
import Moment from 'moment';
import { calcColumnWidth } from "@/utils/index";
import * as XLSX from 'xlsx';
import {
getImageContent
} from '@/api/modules/queryService';
const props = defineProps({
noUpload: {
type: Boolean,
default: false
}
})
const emits = defineEmits([
"fileDataChange"
]);
const noUpload = computed(() => props.noUpload)
const sheetList: any = ref([]);
const fileFormRef = ref();
/** 文件上传表单配置。 */
const fileFormItems: any = ref([
{
label: '选择文件上传',
tip: '支持扩展名:xlsx、xls,文件大小不超过20MB',
type: 'upload-file',
accept: '.xlsx, .xls',
limit: 1,
limitSize: 20,
isExcel: true,
required: true,
default: [],
field: 'file',
},
{
label: '选择sheet页',
type: 'select',
placeholder: '请选择',
field: 'sheet',
default: '',
options: sheetList,
required: true,
visible: true
},
]);
const fileFormRules = ref({
file: [{
validator: (rule: any, value: any, callback: any) => {
if (!value?.length) {
callback(new Error('请上传文件'))
} else {
callback();
}
}, trigger: 'change'
}],
sheet: [
{ required: true, trigger: 'change', message: "请选择sheet页" }
],
});
const uploadFileChange = (file) => {
fileTableFields.value = [];
fileTableData.value = [];
sheetList.value = [];
if (!file.length) {
fileTableFields.value = [];
fileTableData.value = [];
sheetList.value = [];
fileFormItems.value[1].options = sheetList.value;
fileFormItems.value[1].default = '';
fileFormItems.value[0].default = file;
fileWb.value = {};
emits("fileDataChange", fileTableFields.value, file, '', fileTableData.value);
return;
}
let fileRaw = file[0].file;
fileFieldLoading.value = true;
fileRaw.arrayBuffer().then((f) => {
const wb = XLSX.read(f, {
raw: false, cellDates: true
});
fileWb.value = wb;
console.log(wb);
sheetList.value = wb.SheetNames?.map(s => {
return {
value: s,
label: s
}
}) || [];
fileFormItems.value[1].options = sheetList.value;
fileFormItems.value[1].default = wb.SheetNames[0];
fileFormItems.value[0].default = file;
const sheet = wb.Sheets[wb.SheetNames[0]];
const json: any[] = XLSX.utils.sheet_to_json(sheet, { header: 1 });
if (json.length == 0) {
fileTableFields.value = [];
fileTableData.value = [];
} else {
fileTableFields.value = json[0]?.map((j, index) => {
return {
index: index,
enName: j + '',
chName: j + '',
dataType: 'varchar'
}
}) || [];
if (json.length > 1) {
fileTableData.value = json.slice(1, 51).map((info, row) => {
let object = {};
json[0].forEach((name, col) => {
if (info[col] === "" || info[col] == null) {
object[name] = info[col];
} else {
var cellRef = XLSX.utils.encode_cell({ r: row + 1, c: col });
var cell = sheet[cellRef];
object[name] = cell.w || info[col];
let isNum = cell.t == 'n';
if (isNum && fileTableFields.value[col].dataType != 'int') {
fileTableFields.value[col].dataType = 'int';
}
}
});
return object;
});
} else {
fileTableData.value = [];
}
}
fileFieldLoading.value = false;
emits("fileDataChange", fileTableFields.value, file, wb.SheetNames[0], fileTableData.value);
});
}
/** 切换sheet页 */
const handleSelectChange = (val, row, info) => {
if (!val) {
return;
}
let wb = fileWb.value;
const sheet = wb.Sheets[val];
const json: any[] = XLSX.utils.sheet_to_json(sheet, { header: 1 });
if (json.length == 0) {
fileTableFields.value = [];
fileTableData.value = [];
} else {
fileTableFields.value = json[0]?.map((j, index) => {
return {
index: index,
enName: j + '',
chName: j + '',
dataType: 'varchar'
}
}) || [];
if (json.length > 1) {
fileTableData.value = json.slice(1, 51).map((info, row) => {
let object = {};
json[0].forEach((name, col) => {
if (info[col] === "" || info[col] == null) {
object[name] = info[col];
} else {
var cellRef = XLSX.utils.encode_cell({ r: row + 1, c: col });
var cell = sheet[cellRef];
object[name] = cell.w || info[col];
let isNum = cell.t == 'n';
if (isNum && fileTableFields.value[col].dataType != 'int') {
fileTableFields.value[col].dataType = 'int';
}
}
});
return object;
});
} else {
fileTableData.value = [];
}
}
emits("fileDataChange", fileTableFields.value, info.file, val, fileTableData.value);
}
/** 上传文件之后解析出字段和数据 */
const fileFieldLoading = ref(false);
const fileTableFields: any = ref([]);
const fileTableData: any = ref([]);
/** 解析后的excel文件流信息,切换sheet页选择时使用。 */
const fileWb: any = ref({});
const getTextAlign = (field) => {
if (field.dataType === 'decimal' || field.dataType === 'int') {
return 'right';
}
return 'left'
}
/** otherWidth表示使用标题宽度时添加标题排序图标等宽度 */
const calcTableColumnWidth = (data: any[], prop, title, otherWidth = 0) => {
let d: any[] = [];
data.forEach((dt) => d.push(dt[prop]));
return calcColumnWidth(
d,
title,
{
fontSize: 14,
fontFamily: "SimSun",
},
{
fontSize: 14,
fontFamily: "SimSun",
},
otherWidth
);
};
/** 每列字段对应的列宽计算结果。 */
const originTableFieldColumn = ref({});
watch(
fileTableData,
(val: any[], oldVal) => {
if (!fileTableFields.value?.length) {
originTableFieldColumn.value = {};
return;
}
originTableFieldColumn.value = {};
fileTableFields.value.forEach((field, index) => {
originTableFieldColumn.value[field.enName] = calcTableColumnWidth(
val?.slice(0, 20) || [],
field.enName,
field.chName,
24
);
});
},
{
deep: true,
}
);
const formatterPreviewDate = (row, info) => {
let enName = info.enName;
let v = row[enName];
if (v === 0) {
return v;
}
if (!v) {
return v || '--';
}
if (info.dataType === 'datetime') {
return Moment(v).format('YYYY-MM-DD HH:mm:ss');
}
if (info.dataType === 'date') {
if (isNaN(<any>(new Date(v)))) {
return Moment(parseInt(v)).format('YYYY-MM-DD');
} else {
return Moment(v).format('YYYY-MM-DD');
}
}
return v;
};
const setFormValue = (v) => {
fileFormItems.value[1].default = v.sheetName || "";
let url = v.file?.[0]?.url;
if (fileFormItems.value[0].default?.[0]?.url !== url) {
fileFormItems.value[0].default = v.file || [];
//获取文件流去解析出数据和字段。
fileFieldLoading.value = true;
fileTableFields.value = [];
fileTableData.value = [];
getImageContent(url).then((res: any) => {
if (res && !res.msg) {
let urlNames = url.split('/');
let name = urlNames.at(-1);
let reader = new FileReader();
reader.onload = function (e) {
if (!e?.target) {
fileFieldLoading.value = false;
return;
}
let data = new Uint8Array(<any>e.target.result);
const wb = XLSX.read(data, { type: 'array', raw: false, cellDates: true });
fileWb.value = wb;
console.log(wb);
sheetList.value = wb.SheetNames?.map(s => {
return {
value: s,
label: s
}
}) || [];
fileFormItems.value[1].options = sheetList.value;
fileFormItems.value[1].default = v.sheetName || "";
const sheet = wb.Sheets[v.sheetName];
const json: any[] = XLSX.utils.sheet_to_json(sheet, { header: 1 });
if (json.length == 0) {
fileTableFields.value = [];
fileTableData.value = [];
} else {
fileTableFields.value = json[0]?.map((j, index) => {
return {
index: index,
enName: j + '',
chName: j + '',
dataType: 'varchar'
}
}) || [];
if (json.length > 1) {
fileTableData.value = json.slice(1, 51).map((info, row) => {
let object = {};
json[0].forEach((name, col) => {
if (info[col] === "" || info[col] == null) {
object[name] = info[col];
} else {
var cellRef = XLSX.utils.encode_cell({ r: row + 1, c: col });
var cell = sheet[cellRef];
object[name] = cell.w || info[col];
let isNum = cell.t == 'n';
if (isNum && fileTableFields.value[col].dataType != 'int') {
fileTableFields.value[col].dataType = 'int';
}
}
});
return object;
});
} else {
fileTableData.value = [];
}
}
fileFieldLoading.value = false;
};
reader.readAsArrayBuffer(res);
} else {
res?.msg && ElMessage.error(res?.msg);
}
})
}
}
defineExpose({
fileFormRef,
setFormValue
});
</script>
<template>
<div class="upload-main">
<div class="header-bg-title">选择文件上传</div>
<div class="form-main">
<Form ref="fileFormRef" :itemList="fileFormItems" :noUpload="noUpload" formId="file-form" :rules="fileFormRules"
@uploadFileChange="uploadFileChange" @select-change="handleSelectChange" />
</div>
<div class="header-bg-title">预览文件
<div class="preview-data-totals">
<span>该页面仅显示</span>
<span class="fontC-4fa1a4"> 50 </span>
<span>条数据</span>
</div>
</div>
<div class="table-main">
<el-table ref="tableRef" v-loading="fileFieldLoading" v-show="fileTableFields.length" :data="fileTableData"
:highlight-current-row="true" stripe border tooltip-effect="light" height="100%" row-key="guid"
:style="{ width: '100%', height: '100%' }">
<template v-for="(item, index) in (fileTableFields || [])">
<el-table-column :label="item.chName" :width="item.dataType === 'datetime'
? TableColumnWidth.DATETIME
: item.dataType === 'date'
? TableColumnWidth.DATE
: originTableFieldColumn[item.enName]
" :align="getTextAlign(item)" :header-align="getTextAlign(item)"
:formatter="(row) => formatterPreviewDate(row, item)" :show-overflow-tooltip="true">
</el-table-column>
</template>
</el-table>
<div v-show="!fileTableFields.length" class="empty-content">
<img src="../../../assets/images/empty-data.png" :style="{ width: '168px', height: '96px' }" />
<div class="empty-text">暂无数据</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.upload-main {
height: calc(100% - 96px);
}
.header-bg-title {
margin: 16px 16px 0px;
background: #F5F5F5;
padding-left: 16px;
height: 48px;
font-size: 14px;
color: #212121;
letter-spacing: 0;
line-height: 21px;
font-weight: 600;
display: flex;
align-items: center;
position: relative;
.preview-data-totals {
position: absolute;
right: 16px;
line-height: 32px;
font-size: 14px;
color: #666666;
font-weight: 400;
}
.fontC-4fa1a4 {
color: var(--el-color-primary);
}
}
.form-main {
border: 1px solid #d9d9d9;
margin: 0px 16px;
padding: 16px 16px 0px 16px;
height: 125px;
.dialog-form-inline {
align-items: flex-start;
}
:deep(.el-form) {
.item-label {
width: 100%;
}
.el-select {
max-width: 300px;
}
}
}
.table-main {
height: calc(100% - 253px);
border: 1px solid #d9d9d9;
margin: 0px 16px 16px 16px;
padding: 16px;
}
.empty-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
flex-direction: column;
.empty-text {
font-size: 14px;
color: #b2b2b2;
}
}
:deep(.upload-file .el-upload-list) {
.el-upload-list__item {
&:first-child {
display: flex;
}
display: none
}
}
</style>
\ No newline at end of file
<route lang="yaml">
name: configureRules //标签管理
</route>
<script lang="ts" setup name="configureRules">
import { ref } from "vue";
import router from "@/router";
import { getBizRuleConfigDetail, updateBizRuleConfig } from '@/api/modules/dataInventory'
const { proxy } = getCurrentInstance() as any;
const bizRuleConfigData = ref<any>()
const getBizRuleConfigDetailData = async () => {
const params = {
tableGuid: router.currentRoute.value.query.guid,
execGuid: router.currentRoute.value.query.execGuid
}
const res: any = await getBizRuleConfigDetail(params)
if (res.code === proxy.$passCode) {
bizRuleConfigData.value = res.data
// 每条数据添加一个isEdit: false 属性,用于判断是否进入编辑模式
bizRuleConfigData.value.forEach((item: any) => {
item.isEdit = false
})
tableData.value = bizRuleConfigData.value
} else {
proxy.$message.error(res.msg)
}
}
onMounted(() => {
getBizRuleConfigDetailData()
})
const tableData1 = ref([
{
cgDirName: router.currentRoute.value.query.cgDirName,
tableName: router.currentRoute.value.query.tableName,
tableChName: router.currentRoute.value.query.tableChName,
description: router.currentRoute.value.query.description,
},
])
// 表格数据
const tableData = ref()
// 配置哪些字段可编辑
const editableFields = {
fieldName: true, // 字段中文名可编辑
length: true, // 长度可编辑
isUnique: true, // 数据是否唯一可编辑
fieldPrecision: true, // 精度可编辑
dictionaryGuid: true, // 关联字典可编辑
}
const tableFieldsLoading = ref(false)
const selectedRows = ref([]);
// 监听选中行
const selectionFieldsChange = (selection) => {
console.log('selection', selection)
selectedRows.value = selection;
};
// 上移功能
const moveUp = () => {
// 1. 找到选中行在 tableData 中的索引
const selectedIds = selectedRows.value.map((row: any) => row.id);
// 2. 遍历选中行,按顺序上移
for (let i = 0; i < tableData.value.length; i++) {
const currentRow = tableData.value[i];
// 如果当前行被选中,且不是第一行,则交换位置
if (selectedIds.includes(currentRow.id) && i > 0) {
const previousRow = tableData.value[i - 1];
// 如果上一行没有被选中,交换位置
if (!selectedIds.includes(previousRow.id)) {
[tableData.value[i], tableData.value[i - 1]] = [tableData.value[i - 1], tableData.value[i]];
}
}
}
};
// 下移功能
const moveDown = () => {
// 1. 找到选中行在 tableData 中的索引
const selectedIds = selectedRows.value.map((row: any) => row.id);
// 2. 遍历选中行,倒序下移
for (let i = tableData.value.length - 1; i >= 0; i--) {
const currentRow = tableData.value[i];
// 如果当前行被选中,且不是最后一行,则交换位置
if (selectedIds.includes(currentRow.id) && i < tableData.value.length - 1) {
const nextRow = tableData.value[i + 1];
// 如果下一行没有被选中,交换位置
if (!selectedIds.includes(nextRow.id)) {
[tableData.value[i], tableData.value[i + 1]] = [tableData.value[i + 1], tableData.value[i]];
}
}
}
};
// 编辑行
const editRow = (row) => {
if (!row.isEdit) {
const [symbol, value] = row.fieldLengthCondition.split('#');
row.lengthSymbol = symbol; // 初始化符号部分
row.lengthValue = value; // 初始化数值部分
row.isEdit = true; // 进入编辑模式
}
};
// 保存数据
const saveRow = (row) => {
row.fieldLengthCondition = `${row.lengthSymbol}#${row.lengthValue}`;
row.isEdit = false
}
// 删除行
const deleteRow = (index) => {
tableData.value.splice(index, 1)
}
// 批量删除功能
const batchDelete = () => {
selectedRows.value.forEach((row: any) => {
const index = tableData.value.findIndex((item) => item.id === row.id);
if (index !== -1) tableData.value.splice(index, 1);
});
selectedRows.value = [];
};
const data = [
{
value: '1',
label: 'Level one 1',
children: [
{
value: '1-1',
label: 'Level two 1-1',
children: [
{
value: '1-1-1',
label: 'Level three 1-1-1',
},
],
},
],
},
{
value: '2',
label: 'Level one 2',
children: [
{
value: '2-1',
label: 'Level two 2-1',
children: [
{
value: '2-1-1',
label: 'Level three 2-1-1',
},
],
},
{
value: '2-2',
label: 'Level two 2-2',
children: [
{
value: '2-2-1',
label: 'Level three 2-2-1',
},
],
},
],
},
{
value: '3',
label: 'Level one 3',
children: [
{
value: '3-1',
label: 'Level two 3-1',
children: [
{
value: '3-1-1',
label: 'Level three 3-1-1',
},
],
},
{
value: '3-2',
label: 'Level two 3-2',
children: [
{
value: '3-2-1',
label: 'Level three 3-2-1',
},
],
},
],
},
]
const saveData = async () => {
/**入参
* "guid": "string",
"fieldGuid": "string",
"fieldLengthCondition": "string",
"fieldPrecision": 0,
"dictionaryGuid": "string",
"isUnique": "string",
"isNotNull": "string",
"fieldValueRange": "string"
*/
const params = tableData.value.map((item: any) => {
return {
guid: item.guid,
fieldGuid: item.fieldGuid,
fieldLengthCondition: item.fieldLengthCondition,
fieldPrecision: item.fieldPrecision,
dictionaryGuid: item.dictionaryGuid,
isUnique: item.isUnique,
isNotNull: item.isNotNull,
fieldValueRange: item.fieldValueRange
}
})
const res: any = await updateBizRuleConfig(params)
if (res.code === proxy.$passCode) {
proxy.$message.success('修改配置规则成功!')
router.back()
} else {
proxy.$message.error(res.msg)
}
}
const cancel = () => {
router.back()
}
</script>
<template>
<div class="configure-rules">
<div class="table_panel_wrap">
<el-table :data="tableData1" :highlight-current-row="true" stripe border height="100%" row-key="guid"
tooltip-effect="light" :style="{
width: '100%',
'max-height': 'calc(100% - 16px)',
display: 'inline-block',
}">
<el-table-column prop="cgDirName" label="数据源" width="180" />
<el-table-column prop="tableName" label="表名称" width="180" />
<el-table-column prop="tableChName" label="数据库表" width="280" />
<el-table-column prop="description" label="描述" width="180" show-overflow-tooltip />
</el-table>
</div>
<div class="btn-area">
<el-button @click="moveUp">上移</el-button>
<el-button @click="moveDown">下移</el-button>
<el-button @click="batchDelete">批量删除</el-button>
</div>
<div class="bottom_table">
<el-table :data="tableData" v-loading="tableFieldsLoading" :highlight-current-row="true" stripe border
height="100%" row-key="guid" @selection-change="selectionFieldsChange" tooltip-effect="light" :style="{
width: '100%',
'max-height': 'calc(100% - 16px)',
display: 'inline-block',
}">
<el-table-column type="selection" :width="32" align="center" />
<!-- 排序列(不可编辑) -->
<el-table-column prop="index" label="排序" width="80" align="center" />
<!-- 字段中文名(不可编辑)fieldChName -->
<el-table-column prop="fieldName" label="字段中文名" width="120">
<template #default="scope">
{{ scope.row.fieldName ? scope.row.fieldName : '--' }}
</template>
</el-table-column>
<!-- 字段英文名(不可编辑) -->
<el-table-column prop="fieldEnglish" label="字段英文名" width="120">
<template #default="scope">
{{ scope.row.fieldEnglish ? scope.row.fieldEnglish : '--' }}
</template>
</el-table-column>
<!-- 分类(不可编辑)classifyName -->
<el-table-column prop="fieldEnglish" label="分类" width="120">
<template #default="scope">
{{ scope.row.fieldEnglish ? scope.row.fieldEnglish : '--' }}
</template>
</el-table-column>
<!-- 分级(不可编辑) -->
<el-table-column prop="gradeDetailName" label="分级" width="120" align="center">
<template #default="scope">
{{ scope.row.gradeDetailName ? scope.row.gradeDetailName : '--' }}
</template>
</el-table-column>
<!-- 字段类型fieldType (不可编辑) -->
<el-table-column prop="fieldType" label="字段类型" width="150" align="center">
<template #default="scope">
{{ scope.row.fieldType ? scope.row.fieldType : '--' }}
</template>
</el-table-column>
<!-- 长度列 fieldLengthCondition: '>#10',-->
<el-table-column prop="fieldLengthCondition" label="长度" width="240" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.fieldLengthCondition || '--' }}</span>
<div v-else>
<el-select v-model="scope.row.lengthSymbol" placeholder="请选择" style="width: 50%;margin-right: 8px;">
<el-option label="大于" value=">"></el-option>
<el-option label="等于" value="="></el-option>
<el-option label="小于" value="<"></el-option>
</el-select>
<el-input v-model="scope.row.lengthValue" placeholder="请输入" style="width: 45%;" />
</div>
</template>
</el-table-column>
<!-- 精度列 -->
<!-- <el-table-column prop="fieldPrecision" label="精度" width="240" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.fieldPrecision || '--' }}</span>
<div v-else>
<el-select v-model="scope.row.fieldPrecision" placeholder="请选择" style="width: 50%;margin-right: 8px;">
<el-option label="<=500" value="<=500"></el-option>
<el-option label=">500" value=">500"></el-option>
</el-select>
<el-input v-model="scope.row.precisionValue" placeholder="请输入" style="width: 45%;" />
</div>
</template>
</el-table-column> -->
<!-- 精度(可编辑)fieldPrecision -->
<el-table-column prop="fieldPrecision" label="精度" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.fieldPrecision">{{
scope.row.fieldPrecision ? scope.row.fieldPrecision : '--' }}</span>
<el-input v-else v-model="scope.row.fieldPrecision" placeholder="请输入精度" />
</template>
</el-table-column>
<!-- 关联字典(可编辑)el-tree-select 形式下拉形式 -->
<el-table-column prop="dictionaryGuid" label="关联字典" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.dictionaryGuid">{{ scope.row.isDict ? scope.row.isDict :
'--' }}</span>
<el-tree-select v-else v-model="scope.row.isDict" :data="data" placeholder="请选择" />
</template>
</el-table-column>
<!-- 数据是否唯一(可编辑) -->
<el-table-column prop="isUnique" label="数据是否唯一" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.isUnique">{{ scope.row.isUnique ? scope.row.isUnique : '--'
}}</span>
<el-select v-else v-model="scope.row.isUnique" placeholder="请选择">
<el-option label="是" value="Y" />
<el-option label="否" value="N" />
</el-select>
</template>
</el-table-column>
<!-- 是否必填(可编辑) -->
<el-table-column prop="isRequired" label="是否必填" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.isRequired ? scope.row.isRequired : '--' }}</span>
<el-select v-else v-model="scope.row.isRequired" placeholder="请选择">
<el-option label="是" value="Y" />
<el-option label="否" value="N" />
</el-select>
</template>
</el-table-column>
<!-- 字段取值范围 fieldValueRange(可编辑)-->
<el-table-column prop="fieldValueRange" label="字段取值范围" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.fieldValueRange ? scope.row.fieldValueRange : '--' }}</span>
<el-input v-else v-model="scope.row.fieldValueRange" placeholder="请输入字段取值范围" />
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<span class="text_btn" v-if="!scope.row.isEdit" @click="editRow(scope.row)">编辑</span>
<span class="text_btn" v-else @click="saveRow(scope.row)">保存</span>
<el-divider direction="vertical" />
<span class="text_btn" @click="deleteRow(scope.$index)">删除</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="botton_btn">
<el-button type="primary" @click="saveData">保存</el-button>
<el-button @click="cancel">取消</el-button>
</div>
</div>
</template>
<style lang="scss" scoped>
.configure-rules {
padding: 16px;
height: 100%;
.table_panel_wrap {
width: 100%;
height: auto;
overflow: visible;
}
.btn-area {
margin-top: 12px;
}
:deep(.bottom_table) {
margin-top: 12px;
height: calc(100% - 150px);
overflow-y: auto;
.el-table td.el-table__cell {
padding: 2px 0;
height: 36px;
}
}
}
</style>
......@@ -7,7 +7,7 @@ import TableTools from '@/components/Tools/table_tools.vue';
import { getGradeList } from "@/api/modules/dataInventory";
import { getLabelList, getClassifyGradeTreeList, saveLabel, getLabelPageList, deleteLabel, updateLabel } from "@/api/modules/dataLabel";
import { CirclePlus, Delete } from "@element-plus/icons-vue";
import { el, tr } from 'element-plus/es/locale';
const { proxy } = getCurrentInstance() as any;
const dialogLabelFormRef = ref();
......@@ -123,7 +123,7 @@ const treeInfo = ref<any>({
filter: true,
queryValue: "",
className: 'tree-list',
queryPlaceholder: "输入标准集名称搜索",
queryPlaceholder: "输入目录名称搜索",
props: {
label: "classifyName",
value: "guid",
......@@ -560,7 +560,6 @@ const searchClass = async (val: any, clear: boolean = false) => {
return;
}
if (val?.labelName?.length !== 0) {
console.log('调用了吗');
tableInfo.value.loading = true;
const params = {
pageIndex: page.value.curr,
......
<route lang="yaml">
name: dictFileds
</route>
<script lang="ts" setup name="dictFileds">
import { ref } from 'vue'
import router from '@/router'
import { ElMessage, ElMessageBox } from "element-plus";
import Table from '@/components/Table/index.vue'
// import Dialog from '@/components/Dialog/index.vue'
import useCatchStore from "@/store/modules/catch";
import { chunk } from '@/utils/common'
import {
saveDictionaryData,
getDictionaryFileds,
deleteDictionaryData,
checkDictionaryData,
showDictionary,
getDictionaryRuleData
} from '@/api/modules/dataInventory';
const emits = defineEmits(["exportData"])
const { proxy } = getCurrentInstance() as any;
const cacheStore = useCatchStore()
const dictionaryGuid = ref("")
const tableSearchInput = ref('')
const tableFields: any = ref([])
const orginData: any = ref([])
const currTableData: any = ref<Object>({});
const selectRowData = ref([])
const page = ref({
limit: 50,
curr: 1,
// sizes: [
// { label: "100", value: 100 },
// { label: "200", value: 200 },
// { label: "300", value: 300 },
// { label: "400", value: 400 },
// { label: "500", value: 500 },
// ],
});
const tableChunkData: any = ref([])
const tableData: any = ref([])
const tableInfo: any = ref({
id: 'data-fileds-table',
multiple: true,
fields: [],
data: [],
page: {
type: "count",
rows: 0,
...page.value,
},
// showPage: false,
actionInfo: {
label: "操作",
type: "btn",
width: 92,
btns: (scope) => {
return [
{ label: "编辑", value: "edit", visible: scope.row['STATE'] !== 'Running' },
{ label: "删除", value: "remove", visible: scope.row['STATE'] !== 'Running' },
{ label: "保存", value: "save", visible: scope.row['STATE'] === 'Running' },
{ label: "取消", value: "cancel", visible: scope.row['STATE'] === 'Running' },
]
},
},
editInfo: {},
loading: false
})
const uploadFiles = ref([])
const uploadInfo = ref({
type: 'upload',
title: '',
col: '',
uploadInfo: {
id: 'upload-file-form',
type: 'panel',
action: '',
auto: false,
cover: true,
fileList: [],
accept: '.xlsx, .xls',
triggerBtn: {
label: '导入',
value: 'import_file',
icon: 'Upload',
},
tips: '当前支持xls、xlsx文件,默认使用第一个sheet'
},
})
const dialogInfo = ref({
visible: false,
size: 640,
direction: "column",
header: {
title: "新建",
},
type: '',
contents: [
uploadInfo.value
],
footer: {
visible: true,
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "开始导入", value: "submit" },
],
},
})
const getFirstPageData = () => {
toSearch({})
}
const toSearch = (val: any, clear: boolean = false) => {
let params = dictionaryGuid.value
getTableData(params);
};
const getTableData = (params) => {
tableInfo.value.loading = true
getDictionaryFileds(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? {}
setUploadDataInfo(data, true)
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
tableInfo.value.loading = false
}).catch(xhr => {
tableInfo.value.loading = false
})
};
const tableSelectionChange = (val, tId) => {
selectRowData.value = val;
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
if (page.value.limit != Number(info.limit)) {
page.value.limit = Number(info.limit);
chunkData()
} else {
tableData.value = tableChunkData.value[page.value.curr - 1]
tableInfo.value.data = tableData.value
tableInfo.value.page.limit = page.value.limit
tableInfo.value.page.curr = page.value.curr
}
};
const toolBtnClick = (btn) => {
const type = btn.value
if (type == 'export') {
exportData()
} else if (type == 'import') {
const info = {
type: 'dictionary',
dictionaryGuid: dictionaryGuid.value
}
cacheStore.setCatch('uploadSetting', info)
nextTick(() => {
router.push({
path: '/data-standards/import-file',
});
})
} else if (type == 'submit') {
saveData()
} else if (type == 'add_row') {
const params = {
guid: dictionaryGuid.value
}
getDictionaryRuleData(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? {}
let rowInfo: any = {}
tableFields.value.map(item => {
rowInfo[item.field] = data[item.field] ?? ''
})
rowInfo.guid = undefined;
rowInfo.STATE = 'Running'
rowInfo.STATUS = 'edit'
rowInfo.ROWID = `upload_${tableData.value.length}`
tableData.value.unshift(rowInfo)
orginData.value.unshift(rowInfo)
tableInfo.value.page.rows = tableData.value.length
// orginData.value.unshift(rowInfo)
// page.value.curr = 1
// chunkData()
} else {
ElMessage({
type: 'error',
message: res.msg
})
}
})
}
}
const tableBtnClick = (scope, btn) => {
const type = btn.value;
let row = scope.row;
currTableData.value = row;
if (type == "edit") {
row.STATE = 'Running'
row.STATUS = 'edit'
tableData.value[scope.$index] = row
} else if (type == 'save') {
saveData(scope)
} else if (type == 'cancel') {
if (row.guid != undefined) {
// row = orginData.value[(page.value.curr - 1) * page.value.limit + scope.$index]
row = JSON.parse(JSON.stringify(orginData.value[scope.$index]))
row.STATE = ''
row.STATUS = ''
tableData.value[scope.$index] = row
} else {
tableData.value.splice(scope.$index, 1)
orginData.value.splice(scope.$index, 1)
// orginData.value.splice((page.value.curr - 1) * page.value.limit + scope.$index, 1)
// if (scope.$index == 0) {
// page.value.curr = (page.value.curr - 1 > 1) ? page.value.curr - 1 : 1
// }
// chunkData()
}
tableInfo.value.page.rows = tableData.value.length
} else if (type == 'remove') {
open("是否确定删除所选数据?", "warning");
}
};
const onUpload = (file, fileList) => {
uploadFiles.value = fileList
}
const uploadBtnClick = (btn) => {
exportData('model')
}
const exportData = (type: any = null) => {
emits('exportData', type)
}
const importData = (file: any = null) => {
let params = new FormData()
if (file) {
params.append("file", file.raw);
} else {
if (uploadFiles.value.length) {
uploadFiles.value.forEach((item: any, index: number) => {
params.append("file", item.raw);
});
}
}
params.append("dictionaryGuid", dictionaryGuid.value);
showDictionary(params).then((res: any) => {
if (res.code == proxy.$passCode) {
dialogInfo.value.visible = false
let data = res.data ?? []
// data.map((item: any, i) => {
// item.index = tableData.value.length + i
// })
const tData = { jsonArray: data }
setUploadDataInfo(tData)
// saveData(null, tData)
} else {
ElMessage({
type: "error",
message: res.msg,
});
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
}).catch(() => {
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
});
}
const checkSave = () => {
const toSaveData = tableData.value.filter(item => item.STATE === 'Running')
return toSaveData.length == 0 ? true : false
}
const checkParamsData = (scope: any = null) => {
let addJsonArray: any = [], upJsonArray: any = [], jsonArray: any = [], pass = true
let passArr = scope ? [scope.row] : tableData.value
passArr.map((item, index) => {
const obj = JSON.parse(JSON.stringify(item))
delete obj.STATUS
delete obj.NOTES
delete obj.STATE
delete obj.ROWID
// if (item.STATE === 'Running') {
for (var i in obj) {
if (obj[i] == '') {
pass = false
}
}
// }
if (obj.guid !== undefined) {
upJsonArray.push(obj)
} else {
addJsonArray.push(obj)
}
if (scope) {
obj.index = scope.$index
jsonArray.push(obj)
} else {
obj.index = index
jsonArray.push(obj)
}
})
return { pass, addJsonArray, upJsonArray, jsonArray }
}
const saveData = async (scope: any = null, checkParamData: any = null) => {
let passInfo: any = {}
if (checkParamData) {
passInfo = checkParamData
} else {
passInfo = await checkParamsData(scope)
if (!passInfo.pass) {
// ElMessage({
// type: 'error',
// message: '请填写所有数据项'
// })
// return
}
}
const checkParams = {
dictionaryGuid: dictionaryGuid.value,
addJsonArray: passInfo.jsonArray
}
checkDictionaryData(checkParams).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data
if (Object.keys(data).length) {
addColumn(data)
} else {
addColumn()
const params = {
dictionaryGuid: dictionaryGuid.value,
addJsonArray: passInfo.addJsonArray,
upJsonArray: passInfo.upJsonArray
}
saveDictionaryData(params).then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: 'success',
message: '保存成功'
})
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
})
}
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
})
}
const addColumn = (info: any = null) => {
const fields = tableFields.value
const existIndex = fields.findIndex(item => item.field == 'NOTES')
if (info) {
if (existIndex == -1) {
fields.push({
label: '备注',
field: 'NOTES',
width: 200
})
}
for (var d in info) {
tableData.value[d].NOTES = info[d].join(',')
}
} else {
if (existIndex > -1) {
fields.splice(existIndex, 1)
}
}
}
// 生成表头
const setUploadDataFields = (data) => {
let fields: any = [], editInfo: any = {}
data.map(item => {
let fieldItem: any = {
label: item.description, field: item.fieldName, width: 140
}
fieldItem.type = 'edit'
fieldItem.columClass = 'edit-colum'
editInfo[item.fieldName] = {
label: '',
type: 'input',
placeholder: '',
maxlength: 50,
field: item.fieldName,
default: '',
disabled: item.codeRuleGuid ? true : false,
clearable: true,
}
fields.push(fieldItem)
})
tableFields.value = fields
tableInfo.value.fields = tableFields.value
tableInfo.value.editInfo = editInfo
}
// 生成表数据
const setUploadDataInfo = async (info, setField = false) => {
if (setField) {
const fields = info.schemaDataVOS ?? []
await setUploadDataFields(fields)
}
let data = info.jsonArray ?? []
// 设置表数据
data.map((item, i) => {
item.ROWID = `upload_${tableData.value.length + i}`
})
if (setField) {
tableData.value = data
} else {
tableData.value = [...tableData.value, ...data]
}
orginData.value = JSON.parse(JSON.stringify(tableData.value))
tableInfo.value.data = tableData.value
tableInfo.value.page.rows = tableData.value.length
// if (setField) {
// orginData.value = data
// } else {
// orginData.value = [...orginData.value, ...data]
// }
// chunkData()
}
const chunkData = () => {
const data = orginData.value
tableChunkData.value = chunk(data, page.value.limit)
tableData.value = tableChunkData.value[page.value.curr - 1]
tableInfo.value.data = tableData.value
tableInfo.value.page.limit = page.value.limit
tableInfo.value.page.curr = page.value.curr
tableInfo.value.page.rows = orginData.value.length
}
const batching = (type) => {
if (type == 'delete') {
if (selectRowData.value.length == 0) {
ElMessage({
type: 'error',
message: '请选择需要删除的数据',
})
return
}
open("是否确定删除所选数据?", "warning", true);
}
};
const open = (msg, type, isBatch = false) => {
ElMessageBox.confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: type,
}).then(() => {
let guids: any = []
if (isBatch) {
const list = selectRowData.value.filter((item: any) => item.guid !== undefined)
if (list.length) {
guids = list.map((l: any) => l.guid)
}
const newRows = selectRowData.value.filter((item: any) => item.guid == undefined)
newRows.map((n: any, r) => {
const existIndex = tableData.value.findIndex(t => t.ROWID == n.ROWID)
if (existIndex > -1) {
tableData.value.splice(existIndex, 1)
orginData.value.splice(existIndex, 1)
}
// const existIndex = orginData.value.findIndex(t => t.id == n.id)
// existIndex > -1 && orginData.value.splice(existIndex, 1)
// if (r == newRows.length - 1) {
// page.value.curr = 1
// chunkData()
// }
})
tableInfo.value.page.rows = tableData.value.length
} else {
guids = [currTableData.value.guid]
}
if (guids.length) {
const params = {
guid: dictionaryGuid.value,
delGuids: guids
}
deleteDictionaryData(params).then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: "success",
message: "删除成功",
});
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
});
}
});
};
const dialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
// dialogInfo.value.footer.btns.map((item: any) => item.disabled = true)
importData()
} else if (btn.value == 'cancel') {
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
nextTick(() => {
dialogInfo.value.visible = false;
})
}
};
defineExpose({
dictionaryGuid,
getFirstPageData,
checkSave
});
</script>
<template>
<div class="container_wrap full flex">
<div class="main_wrap">
<div class="table_tool_wrap">
<div class="tools_btns">
<el-button type="primary" @click="toolBtnClick({ value: 'add_row' })" v-preReClick>新增行</el-button>
<el-button type="primary" plain @click="toolBtnClick({ value: 'submit' })" v-preReClick>保存数据</el-button>
<el-button @click="batching('delete')" v-preReClick>批量删除</el-button>
<el-button @click="toolBtnClick({ value: 'import' })" v-preReClick>导入数据</el-button>
<el-button @click="toolBtnClick({ value: 'export' })" v-preReClick>导出数据</el-button>
</div>
<!-- <el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="输入名称搜索" :suffix-icon="Search" clearable
@change="val => toSearch({})" /> -->
</div>
<div class="table_panel_wrap full">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange"
@tablePageChange="tablePageChange" />
</div>
</div>
<!-- <Dialog :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @onUpload="onUpload" @uploadBtnClick="uploadBtnClick" /> -->
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
width: calc(100% - 200px);
.main_wrap {
width: 100%;
.table_panel_wrap {
height: calc(100% - 44px);
}
}
}
</style>
<route lang="yaml">
name: dictionary
</route>
<script lang="ts" setup name="dictionary">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from "element-plus";
import { Search } from '@element-plus/icons-vue'
import Tree from '@/components/Tree/index.vue'
import Table from '@/components/Table/index.vue'
import Drawer from '@/components/Drawer/index.vue'
import DictFileds from './dictFileds.vue'
import useCatchStore from "@/store/modules/catch";
import { download } from '@/utils/common'
import {
addDictionary,
deleteDictionary,
getDictionary,
updateDictionary,
getDictionaryTree,
getDictionaryDetail,
exportDictionary,
showDictionary,
getDataBaseList,
getDataTypeList,
getCoderuleList,
saveDictionaryData,
getDictionaryFileds,
updateDictionaryState,
getDictionaryRuleData,
exportDictionaryFileds,
checkDeleteDictionary,
checkDeleteDictionaryScheme,
checkDictionaryData
} from '@/api/modules/dataInventory';
const { proxy } = getCurrentInstance() as any;
const cacheStore = useCatchStore()
// 禁用字段
const forbidFields = [
'guid',
'sharding_flag',
'create_user_id',
'create_user_name',
'update_user_id',
'update_user_name',
'create_time',
'update_time',
'is_deleted'
]
const showFiledsPage = ref(false)
const dictFiledsRef = ref()
const dataTypeList = ref([])
const dataBaseList = ref([])
const codeRuleList = ref([])
const dictTreeRef = ref()
const dictType = ref(-1)
const dictGuid = ref('')
const expandedKey: any = ref([])
const currentNodeKey = ref('')
const showLoading = ref(true)
const treeData = ref([])
const treeInfo = ref({
id: "data-pickup-tree",
filter: true,
queryValue: "",
queryPlaceholder: "输入字典名称搜索",
props: {
label: "name",
value: "guid",
},
nodeKey: 'guid',
expandedKey: [],
currentNodeKey: '',
data: [],
expandOnNodeClick: false,
loading: false
});
const tableSearchInput = ref('')
const currTableData: any = ref<Object>({});
const page = ref({
limit: 50,
curr: 1,
sizes: [
{ label: "10", value: 10 },
{ label: "50", value: 50 },
{ label: "100", value: 100 },
{ label: "150", value: 150 },
{ label: "200", value: 200 },
],
});
const selectRowData = ref([])
const tableInfo: any = ref({
id: 'data-source-table',
multiple: true,
fixedSelection: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "字典中文名", field: "chName", type: 'text_btn', class: 'drawer-detail-cell', width: 120, value: 'detail', columClass: 'text_btn' },
{ label: "字典英文名", field: "enName", width: 120 },
{ label: "字典类型", field: "dictionaryType", type: 'filter', width: 120 },
{ label: "排序", field: "orderNum", type: 'filter', width: 56, align: 'center' },
{ label: '状态', field: 'state', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 1, inactiveValue: 0, switchWidth: 56, width: 100, align: 'center' },
{ label: "编码规则", field: "codeRuleName", width: 120 },
{ label: "修改人", field: "updateUserName", width: 140 },
{ label: "修改时间", field: "updateTime", width: 180, },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 92, //不要刚好90.缩小浏览器会因为小数点的差距而换行,
fixed: 'right',
btns: [
{ label: "编辑", value: "edit" },
{ label: "删除", value: "delete" },
],
},
loading: false
})
const dictionaryType = ref(1)
const orginOptions = [
{ label: 'code', value: 'code' },
{ label: 'name', value: 'name' },
]
const orginItems = [
// {
// label: '数据库名称',
// type: 'select',
// placeholder: '请选择',
// field: 'databaseNameZh',
// options: [],
// clearable: true,
// required: true,
// visible: true,
// },
{
label: '字典中文名',
type: 'input',
maxlength: 50,
placeholder: '请输入',
field: 'chName',
clearable: true,
required: true,
disabled: false
}, {
label: '字典英文名',
type: 'input',
maxlength: 50,
placeholder: '请输入',
field: 'enName',
clearable: true,
required: true,
disabled: false
}, {
label: '排序',
type: 'input',
placeholder: '请输入',
field: 'orderNum',
maxlength: 6,
clearable: true,
required: true,
visible: true,
}, {
label: '字典类型',
type: 'radio-panel',
placeholder: '',
field: 'dictionaryType',
default: 1,
options: [
{ label: '列表结构', value: 1 },
{ label: '层级结构', value: 2 },
{ label: '螺旋结构', value: 3 },
{ label: '通用结构', value: 4 },
],
children: [
{
label: '编码字段',
type: 'select',
placeholder: '请输入',
field: 'codeColumn',
default: '',
options: [],
clearable: true,
required: true
}, {
label: '编码名称',
type: 'select',
placeholder: '请输入',
field: 'codeName',
default: '',
options: [],
clearable: true,
required: true
}, {
label: '顶级节点值',
type: 'input',
placeholder: '请输入',
field: 'topNodeValue',
clearable: true,
required: true,
visible: false
}, {
label: '路径',
type: 'input',
placeholder: '请输入',
field: 'path',
clearable: true,
required: true,
block: true,
visible: false
}
],
clearable: true,
required: false,
block: true,
visible: true,
},
]
const formItems: any = ref([])
const formRules: any = ref({
chName: [
{
required: true,
message: "请填写中文名",
trigger: "blur",
},
],
enName: [
{
required: true,
message: "请填写英文名",
trigger: "blur",
},
],
orderNum: [{
validator: (rule: any, value: any, callback: any) => {
if (value === 0) {
callback();
return;
}
if (!value) {
callback(new Error('请填写排序'));
return;
}
const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头)
if (value && !r.test(value)) {
callback(new Error('请填写大于或等于零整数'));
return;
}
callback();
},
trigger: "blur",
}],
codeColumn: [
{
required: true,
message: "请填写编码字段",
trigger: "blur",
},
],
codeName: [
{
required: true,
message: "请填写编码名称",
trigger: "blur",
},
],
})
const formInfo = ref({
type: 'form',
title: '',
col: 'span',
formInfo: {
id: 'add-dict-form',
col: 'col3',
readonly: false,
items: formItems.value,
rules: formRules.value
}
})
const orginData = [
{
ROWID: 'field_0',
fieldName: 'code',
description: '编码字段',
fieldType: 'varchar',
fieldLength: '10',
fieldPrecision: '',
// orderNum: '1',
codeRuleGuid: '',
STATUS: 'edit',
STATE: 'Running'
}, {
ROWID: 'field_1',
fieldName: 'name',
description: '编码名称',
fieldType: 'varchar',
fieldLength: '20',
fieldPrecision: '',
// orderNum: '2',
codeRuleGuid: '',
STATUS: 'edit',
STATE: 'Running'
}
]
const orginFields = [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "字段英文名", field: "fieldName", width: 140, },
{ label: "字段中文名", field: "description", width: 140, },
{ label: "字段类型", field: "fieldType", width: 100, },
{ label: "长度", field: "fieldLength", width: 80, },
{ label: "精度", field: "fieldPrecision", width: 80, },
// { label: "排序", field: "orderNum", width: 56, },
{ label: "编码规则", field: "codeRuleGuid", width: 140, },
]
const formTableData: any = ref([])
const formTableSelectRowData: any = ref([])
const editTableInfo = ref({
fieldName: {
label: '字段英文名',
type: 'input',
maxlength: 50,
placeholder: '',
field: 'fieldName',
default: '',
clearable: true,
required: true,
},
description: {
label: '字段中文名',
type: 'input',
maxlength: 50,
placeholder: '',
field: 'description',
default: '',
clearable: true,
required: true,
},
fieldType: {
label: '字段类型',
type: 'select',
placeholder: '',
field: 'fieldType',
default: '',
options: [],
clearable: true,
required: true
},
fieldLength: {
label: '长度',
type: 'input',
placeholder: '',
field: 'fieldLength',
default: '',
clearable: true,
required: true,
},
fieldPrecision: {
label: '精度',
type: 'input',
placeholder: '',
field: 'fieldPrecision',
default: '',
clearable: true,
required: true,
},
// orderNum: {
// label: '排序',
// type: 'input',
// placeholder: '',
// field: 'orderNum',
// default: '',
// maxlength: 6,
// clearable: true,
// required: true,
// },
codeRuleGuid: {
label: '编码规则',
type: 'select',
placeholder: '',
field: 'codeRuleGuid',
default: '',
options: [],
clearable: true,
required: true
}
})
const formTable = ref({
type: "table",
title: "定义表结构",
col: 'no-margin',
style: {
height: 'calc(100% - 234px)'
},
tableInfo: {
id: "role-authority-table",
multiple: true,
minHeight: 'unset',
maxHeight: '100%',
fields: [],
data: [],
showPage: false,
actionInfo: {
show: true,
label: "操作",
type: "btn",
width: 60,
fixed: 'right',
btns: [
{ label: "删除", value: "remove" },
]
},
editInfo: {},
readonly: false,
col: 'auto-height',
style: {
height: 'calc(100% - 40px)'
},
loading: false
},
tableTool: {
col: 'float-right',
visible: true,
btns: [
{ label: "新增行", value: "add-row", type: 'primary', plain: true },
{ label: "批量删除", value: "remove_batch" },
]
},
})
const fieldSheetInfo: any = ref({})
const uploadTableData: any = ref([])
const uploadSelectRowData: any = ref([])
const uploadTableFields: any = ref([])
const uploadTableInfo = ref({
id: "role-authority-table",
multiple: true,
// minHeight: 'unset',
// maxHeight: '100%',
fields: [],
data: [],
showPage: false,
actionInfo: {
label: "操作",
type: "btn",
width: 60,
btns: [
{ label: "删除", value: "remove" },
],
},
editInfo: {},
readonly: false,
loading: false
})
const uploadFiles: any = ref([])
const uploadInfo = ref({
type: 'upload',
title: '添加表数据',
col: 'row-reverse',
uploadInfo: {
id: 'upload-file-form',
action: '',
auto: false,
fileList: [],
accept: '.xlsx, .xls',
cover: true,
triggerBtn: {
label: '导入文件',
value: 'import_file',
icon: 'Upload',
plain: true,
},
toolBar: [
{ label: '下载模板', value: 'export_model', plain: true, icon: 'Download' },
]
// showList: false,
},
tableInfo: {},
tools: {
col: 'right',
visible: true,
btns: [
{ label: '树形显示', value: 'show_tree', type: 'primary', plain: true, visible: false },
{ label: '新增行', value: 'add_row', type: 'primary', plain: true },
{ label: '批量删除', value: 'remove_batch', plain: true },
]
}
})
const fieldTableInfo = ref({
type: 'field-table',
title: '表数据',
tableInfo: {
id: 'dict-field-table',
minHeight: 'unset',
maxHeight: '100%',
fields: [],
data: [],
loading: false,
showPage: false,
actionInfo: {
show: false
},
col: 'auto-height'
}
})
const contents = ref({
add: [
formInfo.value,
formTable.value,
],
upload: [
formInfo.value,
uploadInfo.value,
],
sheet: [
formInfo.value,
formTable.value,
],
field: [
formInfo.value,
fieldTableInfo.value,
]
})
const drawerRef = ref()
const drawerInfo: any = ref({
visible: false,
direction: "rtl",
modalClass: "",
modalClose: false,
modal: true,
size: 700,
header: {
title: "新增",
},
type: '',
container: {
contents: [],
},
footer: {
btns: [
{ type: 'default', label: '取消', value: 'cancel' },
{ type: 'primary', label: '保存', value: 'submit' },
{ type: 'primary', label: '查看数据', value: 'fileds', visible: false },
{ type: 'primary', label: '查看表结构', value: 'sheet', visible: false },
{ type: 'primary', label: '保存并添加数据', value: 'saveAndAdd', visible: true },
]
},
})
const setFormItems = (row: any = null) => {
formItems.value = JSON.parse(JSON.stringify(orginItems))
formItems.value.map(item => {
if (item.field == 'databaseNameZh') {
item.options = dataBaseList.value
item.default = row ? row[item.field] : ''
} else if (item.field == 'dictionaryType') {
item.default = dictionaryType.value
// item.disabled = drawerInfo.value.type == 'add' ? false : true
item.disabled = true
item.children.map(child => {
child.options = orginOptions
if (child.field == 'codeColumn') {
child.default = row ? row[child.field] : 'code'
} else if (child.field == 'codeName') {
child.default = row ? row[child.field] : 'name'
} else {
child.default = row ? row[child.field] : ''
}
child.disabled = drawerInfo.value.type == 'detail' ? true : false
child.clearable = drawerInfo.value.type == 'detail' ? false : true
})
} else if (item.field == 'enName') {
item.default = row ? row[item.field] : ''
item.disabled = drawerInfo.value.type == 'add' ? false : true
item.clearable = drawerInfo.value.type == 'add' ? true : false
} else {
item.default = row ? row[item.field] : ''
item.disabled = drawerInfo.value.type == 'detail' ? true : false
item.clearable = drawerInfo.value.type == 'detail' ? false : true
}
})
formInfo.value.formInfo.readonly = drawerInfo.value.type == 'detail'
formInfo.value.formInfo.items = formItems.value
// for(var e in editTableInfo.value){
// const editItem = editTableInfo.value[e]
// if(editItem.field != 'description' && editItem.field != 'codeRuleGuid'){
// editItem.disabled = drawerInfo.value.type != 'add'
// }
// }
}
// 获取数据类型列表
const getDataType = (type) => {
let params = {
paramCode: type
}
getDataTypeList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data
if (type == 'DATA_TYPE') {
data.map(item => {
item.label = item.paramName
item.value = item.paramValue
})
dataTypeList.value = data
editTableInfo.value['fieldType'].options = data
}
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
})
}
// 获取数据库列表
const getDataBase = () => {
const params = {
pageIndex: 1,
connectStatus: '1'
}
getDataBaseList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? []
data.map(item => {
item.label = item.databaseNameZh
item.value = item.guid
})
dataBaseList.value = data
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
})
}
// 获取编码规则列表
const getCodeRuleData = () => {
let params = {}
getCoderuleList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data
data.map(item => {
item.label = item.ruleName
item.value = item.guid
})
codeRuleList.value = data
editTableInfo.value['codeRuleGuid'].options = data
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
})
}
const treePromise = ref();
// 获取数据字典树形数据
const getTreeData = (needClick = false, currData = {}) => {
const params = {
paramCode: 'data_structure_code'
}
treeInfo.value.loading = true
treePromise.value = getDictionaryTree(params).then((res: any) => {
treePromise.value = null;
if (res.code == proxy.$passCode) {
const data = res.data ?? []
const treeList = data.filter(item => item.children && item.children.length)
treeData.value = treeList
treeInfo.value.data = treeList
if (treeList.length) {
dictType.value = dictType.value == -1 ? Number(treeList[0].dictionaryType) : dictType.value;
expandedKey.value = expandedKey.value.length == 0 ? [treeList[0].guid] : expandedKey.value;
if (!needClick && !cacheStore.getCatch('dictionaryGuid')) {
currentNodeKey.value = currentNodeKey.value == '' ? treeList[0].guid : currentNodeKey.value
nextTick(() => {
treeInfo.value.currentNodeKey = currentNodeKey.value
treeInfo.value.expandedKey = expandedKey.value
})
} else {
nextTick(() => {
treeInfo.value.expandedKey = expandedKey.value;
});
}
getFirstPageData()
}
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
treeInfo.value.loading = false;
if (needClick) {
nextTick(() => {
nodeClick(currData);
});
}
}).catch(() => {
treeInfo.value.loading = false
})
}
const getFirstPageData = () => {
page.value.curr = 1;
toSearch({})
}
const toSearch = (val: any, clear: boolean = false) => {
let params: any = Object.keys(val).length ? { ...val } : {}
params.pageIndex = page.value.curr;
params.pageSize = page.value.limit;
params.dictionaryType = dictType.value
params.name = tableSearchInput.value
getTableData(params);
};
const getTableData = (params) => {
tableInfo.value.loading = true
getDictionary(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
tableInfo.value.loading = false
}).catch(xhr => {
tableInfo.value.loading = false
})
};
const tableSelectionChange = (val, tId) => {
if (drawerInfo.value.visible) {
if (formItems.value.length == 2) {
uploadSelectRowData.value = val
} else {
formTableSelectRowData.value = val
}
} else {
selectRowData.value = val.map((item) => item.guid);
}
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
toSearch({});
};
const tableInputChange = (val, scope) => {
if (forbidFields.indexOf(val) > -1) {
ElMessage({
type: "error",
message: '该名称已存在,请填写其他名称',
});
return
}
setCodeOptions()
}
const setCodeOptions = () => {
let opts: any = []
formTableData.value.map(item => {
if (item.fieldName) {
const row = JSON.parse(JSON.stringify(item))
row.label = item.fieldName
row.value = item.fieldName
opts.push(row)
}
})
formItems.value.at(-1).children.map(child => {
if (child.type == 'select') {
child.options = opts
}
})
}
const toolBtnClick = (btn, data) => {
const type = btn.value
if (data) {
if (type.indexOf('add') > -1) {
if (formItems.value.length == 2) {
const params = {
guid: fieldSheetInfo.value.guid
}
uploadTableInfo.value.loading = true
getDictionaryRuleData(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? {}
let rowInfo: any = {}
uploadTableFields.value.map(item => {
rowInfo[item.field] = data[item.field] ?? ''
})
rowInfo.STATUS = 'edit'
rowInfo.STATE = 'Running'
rowInfo.ROWID = `upload_${uploadTableData.value.length}`
uploadTableData.value.push(rowInfo)
uploadTableInfo.value.data = uploadTableData.value
scrollTable(rowInfo)
} else {
ElMessage({
type: 'error',
message: res.msg
})
}
uploadTableInfo.value.loading = false
}).catch(() => {
uploadTableInfo.value.loading = false
})
} else {
const rowInfo = {
ROWID: `formData_${formTableData.value.length}`,
fieldName: '',
description: '',
fieldType: '',
fieldLength: '',
fieldPrecision: '',
orderNum: '',
codeRuleGuid: '',
STATUS: 'edit',
STATE: 'Running'
}
let list: any = formTableData.value
list.push(rowInfo)
formTable.value.tableInfo.data = list
scrollTable(rowInfo)
}
} else if (type.indexOf('remove') > -1) {
if (formItems.value.length == 2) {
if (uploadSelectRowData.value.length == 0) {
ElMessage({
type: "error",
message: '请选择需要删除的数据',
});
return
}
uploadSelectRowData.value.map(item => {
const existIndex = uploadTableData.value.findIndex(s => s.ROWID == item.ROWID)
existIndex > -1 && uploadTableData.value.splice(existIndex, 1)
})
} else {
if (formTableSelectRowData.value.length == 0) {
ElMessage({
type: "error",
message: '请选择需要删除的数据',
});
return
}
const removeRows = () => {
formTableSelectRowData.value.map(item => {
const existIndex = formTableData.value.findIndex(s => s.ROWID == item.ROWID)
existIndex > -1 && formTableData.value.splice(existIndex, 1)
})
}
if (drawerInfo.value.type == 'edit') {
const editRows = formTableSelectRowData.value.filter(item => item.guid !== undefined)
if (editRows.length) {
formTable.value.tableInfo.loading = true
checkDelete().then((res: any) => {
if (res) {
ElMessageBox.confirm("数据字典有数据, 确定是否继续删除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: 'warning',
}).then(() => {
removeRows()
})
} else {
removeRows()
}
formTable.value.tableInfo.loading = false
}).catch(xhr => {
ElMessage({
type: 'error',
message: xhr
})
formTable.value.tableInfo.loading = false
})
} else {
removeRows()
}
} else {
removeRows()
}
}
}
} else {
if (type == 'export_model') {
exportData('model')
} else if (type == 'import_file') {
importData()
}
}
}
const tableSwitchBeforeChange = (scope, field, callback) => {
const msg = '确定修改状态?'
ElMessageBox.confirm(
msg,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
const state = scope.row[field] == 1 ? 0 : 1
const result = tableSwitchChange(state, scope, field)
callback(result)
}).catch(() => {
callback(false)
})
}
const tableSwitchChange = (val, scope, field) => {
return new Promise((resolve, reject) => {
let params = {
guid: scope.row.guid,
dictionaryState: val
}
updateDictionaryState(params).then((res: any) => {
if (res.code == proxy.$passCode && res.data) {
getFirstPageData()
ElMessage({
type: "success",
message: '状态修改成功',
});
resolve(true)
} else {
ElMessage({
type: "error",
message: res.msg,
});
reject(false)
}
}).catch(() => {
reject(false)
})
})
}
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
if (type == "edit" || type == 'detail') {
fieldTableInfo.value.tableInfo.fields = []
fieldTableInfo.value.tableInfo.data = []
drawerInfo.value.header.title = type == 'edit' ? "编辑数据字典" : "数据字典详情";
drawerInfo.value.modalClass = type == 'edit' ? '' : 'wrap_width_auto'
drawerInfo.value.type = type
drawerInfo.value.visible = true;
if (drawerInfo.value.type == 'detail') {
formTable.value.tableInfo.multiple = false
formTable.value.tableTool.visible = false
formTable.value.tableInfo.actionInfo.show = false
drawerInfo.value.footer.btns.at(1).visible = false
drawerInfo.value.footer.btns.at(-1).visible = false
drawerInfo.value.footer.btns.at(-2).visible = false
drawerInfo.value.footer.btns.at(-3).visible = true
} else {
formTable.value.tableInfo.multiple = true
formTable.value.tableInfo.actionInfo.show = true
formTable.value.tableTool.visible = true
drawerInfo.value.footer.btns.at(1).visible = true
drawerInfo.value.footer.btns.at(-1).visible = true
drawerInfo.value.footer.btns.at(-2).visible = false
drawerInfo.value.footer.btns.at(-3).visible = false
}
drawerInfo.value.loading = true;
formTable.value.tableInfo.loading = true
getDictionaryDetail(row.guid).then((res: any) => {
if (res.code == proxy.$passCode && res.data) {
let data = res.data
currTableData.value = data;
setDetailInfo()
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
formTable.value.tableInfo.loading = false
drawerInfo.value.loading = false;
}).catch(() => {
formTable.value.tableInfo.loading = false
drawerInfo.value.loading = false;
})
} else if (type == 'remove') {
const rowIndex = scope.$index
if (formItems.value.length == 2) {
uploadTableData.value.splice(rowIndex, 1)
} else {
if (row.guid !== undefined) {
formTable.value.tableInfo.loading = true
checkDelete().then((res: any) => {
if (res) {
ElMessageBox.confirm("数据字典有数据, 确定是否继续删除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: 'warning',
}).then(() => {
formTableData.value.splice(rowIndex, 1)
})
} else {
formTableData.value.splice(rowIndex, 1)
}
formTable.value.tableInfo.loading = false
}).catch(xhr => {
ElMessage({
type: 'error',
message: xhr
})
formTable.value.tableInfo.loading = false
})
} else {
formTableData.value.splice(rowIndex, 1)
}
}
} else if (type == "delete") {
currTableData.value = row;
tableInfo.value.loading = true
checkDelete().then((res: any) => {
if (res.used) {
ElMessage({
type: 'error',
message: '数据字典被引用,请解除引用关系后再删除'
})
} else {
const unused = res.data.filter(item => item.have.length > 0)
if (unused.length) {
open("数据字典有数据, 确定是否继续删除?", "warning");
} else {
open("此操作将永久删除, 是否继续?", "warning");
}
}
tableInfo.value.loading = false
}).catch(xhr => {
ElMessage({
type: 'error',
message: xhr
})
tableInfo.value.loading = false
})
}
};
const checkDelete = (isBatch: any = false) => {
if (drawerInfo.value.visible) {
return new Promise((resolve, reject) => {
let params: any = {
guid: currTableData.value.guid
}
checkDeleteDictionaryScheme(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data
resolve(data)
} else {
reject(res.msg)
}
}).catch((xhr: any) => {
reject(xhr.msg)
})
})
} else {
return new Promise((resolve, reject) => {
let guids = [currTableData.value.guid]
if (isBatch) {
guids = selectRowData.value
}
checkDeleteDictionary(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? {}
if (data.used) {
resolve({
used: true,
data: data.used
})
} else {
resolve({
used: false,
data: data.unuse
})
}
} else {
reject(res.msg)
}
}).catch((xhr: any) => {
reject(xhr.msg)
})
})
}
}
const open = (msg, type, isBatch = false) => {
ElMessageBox.confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: type,
}).then(() => {
let guids = [currTableData.value.guid]
if (isBatch) {
guids = selectRowData.value
}
tableInfo.value.loading = true
deleteDictionary(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
getTreeData();
ElMessage({
type: "success",
message: "删除成功",
});
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
tableInfo.value.loading = false
}).catch(() => {
tableInfo.value.loading = false
});
});
};
const onUpload = (file, fileList) => {
uploadFiles.value = fileList
}
const uploadFile = (file) => {
importData(file)
}
const exportData = (type: any = null) => {
if (type == 'model') {
let params = {
guid: dictGuid.value
}
if (drawerInfo.value.type == 'add') {
params.guid = fieldSheetInfo.value.guid
}
exportDictionary(params).then((res: any) => {
download(res, '数据字典模板.xlsx', 'excel')
});
} else {
let params = {
guid: dictGuid.value
}
exportDictionaryFileds(params).then((res: any) => {
download(res, '字典数据.xlsx', 'excel')
});
}
}
const importData = (file: any = null) => {
let params = new FormData()
if (file) {
params.append("file", file.raw);
} else {
if (uploadFiles.value.length) {
uploadFiles.value.forEach((item: any, index: number) => {
params.append("file", item.raw);
});
}
}
params.append("dictionaryGuid", fieldSheetInfo.value.guid);
showDictionary(params).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data ?? []
setUploadDataInfo(data)
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
})
}
// 生成表头
const setUploadDataFields = (data) => {
let fields: any = [], editInfo: any = {}
data.map(item => {
let fieldItem: any = {
label: item.description, field: item.fieldName, width: 140
}
if (drawerInfo.value.type != 'detail') {
fieldItem.type = 'edit'
fieldItem.columClass = 'edit-colum'
editInfo[item.fieldName] = {
label: '',
type: 'input',
placeholder: '',
field: item.fieldName,
default: '',
disabled: item.codeRuleGuid ? true : false,
clearable: true,
}
}
fields.push(fieldItem)
})
uploadTableFields.value = fields
if (drawerInfo.value.type == 'detail') {
fieldTableInfo.value.tableInfo.fields = uploadTableFields.value
} else {
uploadTableInfo.value.fields = uploadTableFields.value
uploadTableInfo.value.editInfo = editInfo
}
}
// 生成表数据
const setUploadDataInfo = async (info) => {
let data = info
if (drawerInfo.value.type == 'detail') {
data = info.jsonArray ?? []
const fields = info.schemaDataVOS ?? []
setUploadDataFields(fields)
}
if (drawerInfo.value.type == 'detail') {
fieldTableInfo.value.tableInfo.data = data
drawerInfo.value.container.contents = contents.value['field']
} else {
// 设置表数据
data.map((item, i) => {
item.STATUS = 'edit'
item.STATE = 'Running'
item.ROWID = `upload_${i}`
})
uploadTableData.value = data
uploadTableInfo.value.data = uploadTableData.value
}
}
const loadDrawer = async () => {
drawerInfo.value.header.title = '新增数据字典'
drawerInfo.value.type = 'add'
drawerInfo.value.modalClass = '';
await setFormItems()
let fields = JSON.parse(JSON.stringify(orginFields))
fields.map((item: any) => {
if (!item.type || item.type != 'index') {
item.type = 'edit'
item.columClass = 'edit-colum'
}
})
formTable.value.tableInfo.fields = fields
formInfo.value.formInfo.items = formItems.value
formTableData.value = JSON.parse(JSON.stringify(orginData))
formTable.value.tableInfo.data = formTableData.value
formTable.value.tableInfo.editInfo = JSON.parse(JSON.stringify(editTableInfo.value))
formTable.value.tableInfo.readonly = false
formTable.value.tableInfo.multiple = true
formTable.value.tableInfo.actionInfo.show = true
formTable.value.tableTool.visible = true
drawerInfo.value.container.contents = contents.value['add']
drawerInfo.value.footer.btns.at(1).visible = true
drawerInfo.value.footer.btns.at(-1).visible = true
drawerInfo.value.footer.btns.at(-2).visible = false
drawerInfo.value.footer.btns.at(-3).visible = false
drawerInfo.value.visible = true
};
const batching = (type) => {
if (type == 'delete') {
if (selectRowData.value.length == 0) {
ElMessage({
type: 'error',
message: '请选择需要删除的数据',
})
return
}
tableInfo.value.loading = true
checkDelete().then((res: any) => {
if (res.used) {
ElMessage({
type: 'error',
message: '数据字典被引用,请解除引用关系后再删除'
})
} else {
const unused = res.data.filter(item => !item.have || item.have.length == 0)
if (unused.length) {
open("数据字典有数据, 确定是否继续删除?", "warning", true);
} else {
open("此操作将永久删除, 是否继续?", "warning", true);
}
}
tableInfo.value.loading = false
}).catch(xhr => {
ElMessage({
type: 'error',
message: xhr
})
tableInfo.value.loading = false
})
}
};
const nodeClick = (data) => {
drawerInfo.value.visible = false
const changeCont = () => {
dictGuid.value = data.guid
const info = {
type: 'dictionary',
dictionaryGuid: dictGuid.value
}
cacheStore.setCatch('uploadSetting', info)
if (data.type == 1) {
showFiledsPage.value = false
dictType.value = Number(data.dictionaryType)
} else {
showFiledsPage.value = true
nextTick(() => {
dictFiledsRef.value.dictionaryGuid = dictGuid.value
dictFiledsRef.value.getFirstPageData()
})
}
nextTick(() => {
treeInfo.value.currentNodeKey = dictGuid.value
})
}
if (showFiledsPage.value) {
const toChange = dictFiledsRef.value.checkSave()
if (!toChange) {
ElMessageBox.confirm(
'存在未保存的数据,切换后会丢失,是否确定切换',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
changeCont()
}).catch(() => {
treeInfo.value.currentNodeKey = dictGuid.value
})
} else {
changeCont()
}
} else {
changeCont()
}
}
// 设置详情信息
const setDetailInfo = () => {
const row = JSON.parse(JSON.stringify(currTableData.value))
dictionaryType.value = row.dictionaryType
setFormItems(row)
let fields = JSON.parse(JSON.stringify(orginFields))
let schemaVOS = row.schemaVOS ?? []
setGroup()
let list: any = []
schemaVOS.map((schema, s) => {
list.push({
label: schema.fieldName,
value: schema.fieldName
})
schema.STATUS = 'edit'
schema.STATE = 'Running'
schema.ROWID = `formData_${s}`
})
formItems.value.at(-1).children.map(child => {
if (child.type == 'select') {
child.options = list
child.default = row[child.field]
child.clearable = drawerInfo.value.type == 'detail' ? false : true
}
})
fields.map((item: any) => {
if (!item.type || item.type != 'index') {
item.type = 'edit'
item.columClass = 'edit-colum'
}
})
for (var key in editTableInfo.value) {
editTableInfo.value[key].clearable = drawerInfo.value.type == 'detail' ? false : true
}
let editInfo = JSON.parse(JSON.stringify(editTableInfo.value))
if (drawerInfo.value.type == 'edit') {
for (var e in editInfo) {
if (e == 'description' || e == 'fieldType' || e == 'fieldLength' || e == 'fieldPrecision') {
editInfo[e].disabled = true
}
}
}
formInfo.value.formInfo.items = formItems.value
formTableData.value = schemaVOS
formTable.value.tableInfo.fields = fields
formTable.value.tableInfo.data = formTableData.value
formTable.value.tableInfo.readonly = drawerInfo.value.type == 'detail'
formTable.value.tableInfo.editInfo = editInfo
drawerInfo.value.container.contents = contents.value['add']
drawerInfo.value.visible = true
}
const checkParamsData = () => {
let addJsonArray: any = [], upJsonArray: any = [], jsonArray: any = [], pass = true
let passArr = uploadTableData.value
passArr.map((item, index) => {
const obj = JSON.parse(JSON.stringify(item))
delete obj.STATE
delete obj.STATUS
delete obj.NOTES
delete obj.ROWID
for (var i in obj) {
if (obj[i] == '') {
pass = false
}
}
if (obj.guid !== undefined) {
upJsonArray.push(obj)
} else {
addJsonArray.push(obj)
}
obj.index = index
jsonArray.push(obj)
})
return { pass, addJsonArray, upJsonArray, jsonArray }
}
const saveData = async () => {
const passInfo = await checkParamsData()
const checkParams = {
dictionaryGuid: fieldSheetInfo.value.guid,
addJsonArray: passInfo.jsonArray
}
checkDictionaryData(checkParams).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data
if (Object.keys(data).length) {
addColumn(data)
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
} else {
addColumn()
const params = {
dictionaryGuid: fieldSheetInfo.value.guid,
addJsonArray: passInfo.addJsonArray,
upJsonArray: passInfo.upJsonArray
}
saveDictionaryData(params).then((res: any) => {
if (res.code == proxy.$passCode) {
showLoading.value = true
getTreeData();
ElMessage({
type: 'success',
message: '保存数据字典成功'
})
drawerInfo.value.visible = false;
} else {
ElMessage({
type: 'error',
message: res.msg,
})
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
}).catch(() => {
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
})
}
} else {
ElMessage({
type: 'error',
message: res.msg,
})
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
}).catch(() => {
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
})
}
const addColumn = (info: any = null) => {
const fields = uploadTableFields.value
const existIndex = fields.findIndex(item => item.field == 'NOTES')
if (info) {
if (existIndex == -1) {
fields.push({
label: '备注',
field: 'NOTES',
width: 276
})
}
for (var d in info) {
uploadTableData.value[d].NOTES = info[d].join(',')
}
} else {
if (existIndex > -1) {
fields.splice(existIndex, 1)
}
}
}
const scrollTable = (rowInfo) => {
nextTick(() => {
const drawerBody = document.getElementsByClassName('el-drawer__body')[0];
const tableListRef = drawerRef.value.getDrawerConRef("drawerTableRef");
if (!tableListRef) return;
//设置选中表格当前新增行。
tableListRef.setCurrentRow(rowInfo);
drawerBody.scrollTop = drawerBody.scrollHeight;
let table = tableListRef.layout.table.refs;
// 获取表格滚动元素
let tableScrollEle =
table.bodyWrapper.firstElementChild.firstElementChild;
// 设置表格滚动的位置
tableScrollEle.scrollTop = tableScrollEle.scrollHeight;
});
};
const drawerBtnClick = (btn, info) => {
if (btn.value == 'submit' || btn.value == 'saveAndAdd') {
drawerInfo.value.footer.btns.map((item: any) => item.disabled = true)
if (formItems.value.length == 2) {
if (drawerInfo.value.type == 'add') {
saveData()
}
} else {
if (drawerInfo.value.type == 'edit' && btn.value == 'saveAndAdd') {
nodeClick(currTableData.value)
drawerInfo.value.visible = false
return
}
let params = { ...info }
let dtos: any = []
if (formTableData.value.length == 0) {
ElMessage({
type: 'error',
message: '表结构至少需要一条数据',
})
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
return
}
formTableData.value.map((item, i) => {
const dto = { ...item }
delete dto.STATE
delete dto.STATUS
delete dto.ROWID
delete dto.NOTES
dto.orderNum = i
dtos.push(dto)
})
params.dataDictionarySchemaAddDTOS = dtos
if (drawerInfo.value.type == 'add') {
formTable.value.tableInfo.loading = true
addDictionary(params).then((res: any) => {
if (res.code == proxy.$passCode) {
ElMessage({
type: 'success',
message: '添加数据字典成功'
})
drawerInfo.value.visible = false;
getTreeData(btn.value == 'saveAndAdd', res.data || {});
} else {
ElMessage({
type: 'error',
message: res.msg,
})
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
formTable.value.tableInfo.loading = false
}).catch(() => {
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
formTable.value.tableInfo.loading = false
})
} else {
params.guid = currTableData.value.guid
updateDictionary(params).then((res: any) => {
if (res.code == proxy.$passCode) {
if (btn.value == 'saveAndAdd') {
showLoading.value = false
drawerInfo.value.container.id = 'upload-table-form'
drawerInfo.value.footer.btns.at(-1).visible = false
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
getDictionaryDataDetail(currTableData.value.guid)
} else {
getTreeData();
ElMessage({
type: 'success',
message: '修改数据字典成功'
})
drawerInfo.value.visible = false;
}
} else {
ElMessage({
type: 'error',
message: res.msg,
})
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
}).catch(() => {
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
})
}
}
} else if (btn.value == 'fileds') {
drawerInfo.value.footer.btns.at(-2).visible = true
drawerInfo.value.footer.btns.at(-3).visible = false
formItems.value.map(item => {
if (item.field != 'chName' && item.field != 'enName') {
item.visible = false
}
})
if (currTableData.value.detailInfo == null) {
getTableFiled()
} else {
drawerInfo.value.container.contents = contents.value['field']
}
} else if (btn.value == 'sheet') {
formItems.value.map(item => {
item.visible = true
})
drawerInfo.value.container.contents = contents.value['add']
drawerInfo.value.footer.btns.at(-2).visible = false
drawerInfo.value.footer.btns.at(-3).visible = true
} else {
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled)
nextTick(() => {
drawerInfo.value.visible = false
})
}
}
const getTableFiled = () => {
const guid = currTableData.value.guid;
fieldTableInfo.value.tableInfo.loading = true;
drawerInfo.value.container.contents = contents.value['field']
getDictionaryFileds(guid).then((res: any) => {
fieldTableInfo.value.tableInfo.loading = false;
if (res.code == proxy.$passCode) {
const data = res.data ?? {}
currTableData.value.detailInfo = data
setUploadDataInfo(data)
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
}).catch(() => {
fieldTableInfo.value.tableInfo.loading = false;
})
}
const getDictionaryDataDetail = (params) => {
uploadTableInfo.value.loading = true
getDictionaryFileds(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data ?? {}
setContents(data)
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
uploadTableInfo.value.loading = false
}).catch(xhr => {
uploadTableInfo.value.loading = false
})
}
// 设置添加数据面板信息
const setContents = async (info) => {
formItems.value.splice(2)
formItems.value.map(item => {
item.default = fieldSheetInfo.value[item.field]
item.disabled = true
})
const fields = info.schemaDataVOS ?? []
await setUploadDataFields(fields)
uploadTableData.value = []
uploadTableInfo.value.data = []
uploadInfo.value.tableInfo = uploadTableInfo.value
drawerInfo.value.container.contents = contents.value['upload']
}
const radioGroupChange = async (val, info) => {
dictionaryType.value = Number(val)
await setFormItems(info)
setGroup()
}
// 切换结构类型 设置选项显隐
const setGroup = () => {
let dictionaryOpts = formItems.value.at(-1).children
if (dictionaryType.value == 1) {
dictionaryOpts[2].visible = false
dictionaryOpts[3].visible = false
} else if (dictionaryType.value == 2) {
dictionaryOpts[2].visible = false
dictionaryOpts[3].block = false
dictionaryOpts[3].visible = true
} else if (dictionaryType.value == 3) {
dictionaryOpts[2].visible = true
dictionaryOpts[3].block = true
dictionaryOpts[3].visible = true
} else if (dictionaryType.value == 4) {
dictionaryOpts[2].visible = false
dictionaryOpts[3].block = true
dictionaryOpts[3].visible = true
}
formInfo.value.formInfo.items = formItems.value
}
onActivated(() => {
getCodeRuleData();
let guid = cacheStore.getCatch('dictionaryGuid');
if (guid) {
nextTick(() => {
if (treePromise.value) {
treePromise.value.then(() => {
nodeClick({ guid: guid, dictionaryType: '1', type: 2 });
cacheStore.setCatch('dictionaryGuid', null);
});
} else {
nodeClick({ guid: guid, type: 1 });
cacheStore.setCatch('dictionaryGuid', null);
}
});
}
})
onBeforeMount(() => {
getDataType('DATA_TYPE')
getTreeData()
})
onMounted(() => {
let dom = document.getElementById('main-app');
if (dom) {
dom.addEventListener('click', (event: any) => {
// 新建时不要处理。
if (drawerInfo.value.header.title == '数据字典详情' && !event.target?.classList?.contains('drawer-detail-cell')) {
if (drawerInfo.value.visible) {
drawerInfo.value.visible = false;
}
}
});
}
});
</script>
<template>
<div class="container_wrap full flex">
<div class="aside_wrap">
<div class="aside_title">数据字典列表</div>
<Tree ref="dictTreeRef" :treeInfo="treeInfo" @nodeClick="nodeClick" />
</div>
<DictFileds ref="dictFiledsRef" v-if="showFiledsPage" @exportData="exportData" />
<div class="main_wrap" v-else>
<div class="table_tool_wrap">
<div class="tools_btns">
<el-button type="primary" @click="loadDrawer" v-preReClick>新建</el-button>
<el-button @click="batching('delete')" v-preReClick>批量删除</el-button>
</div>
<el-input class="table_search_input" v-model.trim="tableSearchInput" placeholder="请输入字典中/英文名搜索"
:suffix-icon="Search" clearable @change="val => getFirstPageData()" />
</div>
<div class="table_panel_wrap full">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tableSelectionChange="tableSelectionChange"
@tablePageChange="tablePageChange" @tableSwitchBeforeChange="tableSwitchBeforeChange" />
</div>
</div>
<Drawer ref="drawerRef" :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick"
@radioGroupChange="radioGroupChange" @drawerTableBtnClick="tableBtnClick"
@drawerTableSelectionChange="tableSelectionChange" @drawerTableToolBtnClick="toolBtnClick"
@drawerTableInputChange="tableInputChange" @drawerToolBtnClick="toolBtnClick" @onUpload="onUpload"
@uploadFile="uploadFile" @uploadBtnClick="toolBtnClick" />
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
.aside_wrap {
width: 200px;
}
}
.tree_panel {
height: 100%;
padding-top: 0;
:deep(.el-tree) {
margin: 0;
height: calc(100% - 68px);
overflow: hidden auto;
}
}
</style>
<script lang="ts" setup name="existingTableSelect">
import { ref } from "vue";
import { Search, Close } from "@element-plus/icons-vue";
import { ElMessage, ElTable } from "element-plus";
import PageNav from "@/components/PageNav/index.vue";
import Moment from 'moment';
import {
getDsTableByDs,
getDsData,
getDsTableStructure,
} from "@/api/modules/dataInventory";
/** 需要从父组件接收已选中的数据表 和 数据库列表(由父组件获取,只需获取一次,因为父组件也需要使用)。 */
const props = defineProps({
databaseList: {
type: Array<any>,
default: [],
},
dataSourceGuid: {
type: String,
default: ''
},
dsList: {
type: Array<any>,
default: [],
},
isLook: {
type: Boolean,
default: false,
},
tableCreateType: {
type: Number,
default: 2,
},
subjectDomainGuid: {
type: String,
default: ''
},
execGuid: {
type: String,
default: ''
}
});
watch(() => { }, () => {
// datasourceSelectedRows.value = props.dsList?.slice(0) || [];
let selectTableName = currDatasourceSelect.value?.tableName;
if (selectTableName) {
let ds = datasourceSelectedRows.value?.find(d => d.tableName === selectTableName);
if (!ds) {
currDatasourceSelect.value = {};
}
}
})
const datasourceSelectedRows: any = ref([]);
const emits = defineEmits(["datasourceSelectedChange"]);
const { proxy } = getCurrentInstance() as any;
/** 当前选中的数据源连接池guid,和相关信息。 */
const databaseInfo: any = computed(() => {
if (!databaseGuid.value) {
return {};
}
return props.databaseList.find(d => d.guid == databaseGuid.value);
});
const databaseGuid: any = ref('');
watch(() => props.databaseList, (val) => {
if (!val?.length) {
return;
}
if (props.dataSourceGuid != "") {
databaseGuid.value = props.dataSourceGuid;
} else if (!databaseInfo.value.guid) {
databaseGuid.value = val[0]?.guid;
}
})
const searchKey = ref("");
const dsTableList: Ref<any> = ref();
const dsTableListLoading = ref(false);
const datasourceTableRef = ref<InstanceType<typeof ElTable>>();
const dsPageInfo = ref({
limit: 50,
curr: 1,
rows: 0,
type: "concise",
});
const currDatasourceSelect: Ref<any> = ref({});
const currDsPreviewActiveName = ref("resultData");
const currDsPreviewData = ref([]);
const currDsFields: Ref<any> = ref([]);
/** 每列字段对应的列宽计算结果。 */
const originTableFieldColumn = ref({});
const currDsPreviewDataLoading = ref(false);
const currDsTableStructure = ref([]);
const currDsTableStructureLoading = ref(false);
// const calcTableColumnWidth = (data: any[], prop, title) => {
// let d: any[] = [];
// data.forEach((dt) => d.push(dt[prop]));
// return calcColumnWidth(
// d,
// title,
// {
// fontSize: 14,
// fontFamily: "SimSun",
// },
// {
// fontSize: 14,
// fontFamily: "SimSun",
// }
// );
// };
const formatterPreviewDate = (row, info) => {
let enName = info.enName;
let v = row[enName];
if (v === 0) {
return v;
}
if (!v) {
return v || '--';
}
if (info.dataType === 'datetime') {
return Moment(v).format('YYYY-MM-DD HH:mm:ss');
}
if (info.dataType === 'date') {
if (isNaN(<any>(new Date(v)))) {
return Moment(parseInt(v)).format('YYYY-MM-DD');
} else {
return Moment(v).format('YYYY-MM-DD');
}
}
return v;
};
const getTableListPromise = ref();
const getDsTableList = (params) => {
dsTableList.value = [];
dsTableListLoading.value = true;
let promise: any = null;
promise = getTableListPromise.value = getDsTableByDs(params).then((res: any) => {
if (promise !== getTableListPromise.value) {
return;
}
dsTableListLoading.value = false;
if (res.code == proxy.$passCode) {
dsPageInfo.value.rows = res.data?.totalRows || 0;
dsTableList.value = res.data?.records || [];
//需要根据新的datasourceList 和选中行,设置表格的选中。
nextTick(() => {
datasourceSelectedRows.value.forEach((d) => {
let row = dsTableList.value.find((v: any) => v.tableName == d.tableName);
if (row) {
datasourceTableRef.value?.toggleRowSelection(row, true);
}
});
});
} else {
ElMessage.error(res.msg);
}
})
};
const getPreviewData = () => {
currDsPreviewData.value = [];
currDsPreviewDataLoading.value = true;
getDsData({
pageSize: 50,
pageIndex: 1,
dataSourceGuid: databaseInfo.value.guid,
database: currDatasourceSelect.value.database,
tableName: currDatasourceSelect.value.tableName,
}).then((res: any) => {
currDsPreviewDataLoading.value = false;
if (res.code == proxy.$passCode) {
currDsPreviewData.value = res.data.datas || [];
currDsFields.value = res.data.fields || [];
} else {
ElMessage.error(res.msg);
}
});
};
const getTableStructure = () => {
let tableName = currDatasourceSelect.value.tableName;
currDsTableStructureLoading.value = true;
currDsTableStructure.value = [];
getDsTableStructure({
tableName: tableName,
dataSourceGuid: databaseInfo.value.guid,
database: databaseInfo.value.databaseNameEn,
databaseType: databaseInfo.value.databaseType
}).then((res: any) => {
currDsTableStructureLoading.value = false;
if (res.code == proxy.$passCode) {
currDsTableStructure.value = res.data || [];
} else {
ElMessage.error(res.msg);
}
});
};
watch(() => databaseInfo.value, (val) => {
if (!val) {
return;
}
dsPageInfo.value.curr = 1;
searchKey.value = "";
getDsTableList({
pageSize: dsPageInfo.value.limit,
pageIndex: dsPageInfo.value.curr,
dataSourceGuid: val.guid,
execGuid: props.execGuid
});
})
const handleSearchInputChange = () => {
dsPageInfo.value.curr = 1;
getDsTableList({
pageSize: dsPageInfo.value.limit,
pageIndex: dsPageInfo.value.curr,
dataSourceGuid: databaseInfo.value.guid,
execGuid: props.execGuid
});
};
const dsPageChange = (page) => {
console.log(page);
dsPageInfo.value.curr = page.curr;
dsPageInfo.value.limit = page.limit;
getDsTableList({
pageSize: dsPageInfo.value.limit,
pageIndex: dsPageInfo.value.curr,
dataSourceGuid: databaseInfo.value.guid,
execGuid: props.execGuid
});
};
const datasource_row_class_name = ({ row, rowIndex }) => {
return datasourceSelectedRows.value.find((v: any) => v.tableName == row.tableName)
? "selected"
: "";
};
const datasource_selection_all_change = (selection) => {
let isChecked = selection.length > 0;
dsTableList.value.forEach((d) => {
let index = datasourceSelectedRows.value.findIndex(
(v: any) => v.tableName == d.tableName
);
if (index === -1 && isChecked) {
datasourceSelectedRows.value.push(Object.assign({}, d, databaseInfo.value));
} else if (index !== -1 && !isChecked) {
datasourceSelectedRows.value.splice(index, 1);
if (currDatasourceSelect.value?.tableName === d.tableName) {
currDatasourceSelect.value = {};
}
}
});
};
const datasource_selection_change = (selection, row) => {
console.log(selection, row);
let index = selection.findIndex((s) => s.tableName == row.tableName);
if (index === -1) {
datasourceSelectedRows.value.splice(
datasourceSelectedRows.value.findIndex((v: any) => v.tableName == row.tableName),
1
);
if (currDatasourceSelect.value?.tableName === row.tableName) {
currDatasourceSelect.value = {};
}
} else {
datasourceSelectedRows.value.push(Object.assign({}, row));
}
};
/** 点击行选中或再次点击取消。不知是否有此种需求,一般都是点击勾选框选中。@row-click="datasource_row_click" */
// const datasource_row_click = (row, column, event) => {
// let index = datasourceSelectedRows.value.findIndex(
// (v: any) => v.tableName == row.tableName
// );
// datasourceTableRef.value?.toggleRowSelection(row, index === -1);
// if (index === -1) {
// datasourceSelectedRows.value.push(Object.assign({}, row, databaseInfo.value));
// } else {
// datasourceSelectedRows.value.splice(index, 1);
// }
// };
const handleDsSelect = (item) => {
currDatasourceSelect.value = item;
};
const delSelectDs = (item, i) => {
datasourceSelectedRows.value.splice(i, 1);
if (currDatasourceSelect.value?.tableName === item.tableName) {
currDatasourceSelect.value = {};
}
let table = dsTableList.value.find(t => t.tableName === item.tableName);
table && datasourceTableRef.value?.toggleRowSelection(table, false);
};
watch(
datasourceSelectedRows,
(val, oldVal) => {
if (val?.length && !currDatasourceSelect.value?.tableName) {
currDatasourceSelect.value = val[0];
}
emits("datasourceSelectedChange", val);
},
{
deep: true,
}
);
watch(currDatasourceSelect, (val) => {
if (val?.tableName) {
getPreviewData();
getTableStructure();
}
});
const getTextAlign = (field) => {
if (field.dataType === 'decimal' || field.dataType === 'int' || field.dataType == 'bit' || field.dataType == 'tinyint') {
return 'right';
}
return 'left'
}
</script>
<template>
<div class="first-step-content">
<div class="content-left">
<div class="title-left">待选库表</div>
<div class="content-selecte-left">
<span class="select-ds-title">数据存储连接池</span>
<el-select v-model="databaseGuid" placeholder="请选择" filterable value-key="guid">
<el-option v-for="opt in databaseList" :key="opt['guid']" :label="opt['databaseChName']"
:value="opt['guid']" />
</el-select>
<el-input class="table_search_input" v-model.trim="searchKey" placeholder="关键字搜索" :prefix-icon="Search"
@change="handleSearchInputChange" clearable />
<el-table class="datasource-small-table" ref="datasourceTableRef" :data="dsTableList"
v-loading="dsTableListLoading" :border="false" row-key="tableName" :row-class-name="datasource_row_class_name"
@select="datasource_selection_change" @select-all="datasource_selection_all_change" tooltip-effect="light">
<el-table-column type="selection" :width="22" align="center" />
<el-table-column prop="tableName" label="名称" width="100px" align="left" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="tableComment" label="表注释" width="60px" align="left" show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row['tableComment'] ?? '--' }}</span>
</template>
</el-table-column>
</el-table>
<PageNav :class="[dsPageInfo.type]" :pageInfo="dsPageInfo" @pageChange="dsPageChange" />
</div>
</div>
<div class="content-right">
<div class="title-right">已选库表</div>
<div class="ds-select-container">
<template v-if="datasourceSelectedRows.length">
<div v-for="(item, i) in datasourceSelectedRows" :key="item.tableName" :class="currDatasourceSelect?.tableName === item.tableName
? 'ds-select-item selected'
: 'ds-select-item'
" @click="handleDsSelect(item)" v-preReClick>
<span class="item-title">{{ item.tableName }}</span>
<el-icon v-if="!isLook" @click.stop="delSelectDs(item, i)" v-preReClick>
<Close />
</el-icon>
</div>
</template>
<div v-if="!datasourceSelectedRows.length" class="ds-select-placeholder">
请从左侧待选库表选择
</div>
</div>
<div class="ds-data-preview">
<div class="preview-data-totals t-left" v-show="currDsPreviewActiveName == 'resultData'">
<span>该页面仅显示</span>
<span style="color: var(--el-color-primary)"> 50 </span>
<span>条数据</span>
</div>
<el-tabs class="preview-tabs" v-model="currDsPreviewActiveName">
<el-tab-pane label="查询结果" name="resultData" class="t-left">
<div v-if="!currDatasourceSelect?.tableName" class="no-select-table">
<img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" />
<span>请从已选库表中选择</span>
</div>
<el-table key="previewTableData" v-loading="currDsPreviewDataLoading" :data="currDsPreviewData" border
tooltip-effect="light" style="
width: 100%;
min-width: 200px;
max-width: calc(100% - 17px);
height: calc(100% - 8px);
display: inline-block;
margin: 0 8px;
" stripe ref="previewTable">
<el-table-column v-for="(field, index) in currDsFields" :key="field.enName" :prop="field.enName"
:label="field.chName" :width="field.dataType === 'datetime'
? 180
: field.dataType === 'date'
? 140
: originTableFieldColumn[field.enName]
" :align="getTextAlign(field)" :header-align="getTextAlign(field)" :show-overflow-tooltip="true"
:formatter="(row) => formatterPreviewDate(row, field)">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="库表结构" name="tableStructure" class="t-left">
<div v-if="!currDatasourceSelect?.tableName" class="no-select-table">
<img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" />
<span>请从已选库表中选择</span>
</div>
<el-table key="previewTableStructure" v-loading="currDsTableStructureLoading" tooltip-effect="light"
:data="currDsTableStructure" border style="
width: 100%;
max-width: calc(100% - 17px);
height: calc(100% - 8px);
display: inline-block;
margin: 0 8px;
" stripe ref="previewTableStructure">
<el-table-column type="index" label="序号" :width="56" align="center" />
<el-table-column prop="fieldName" label="字段英文名" width="150px" align="left" header-align="left"
show-overflow-tooltip>
</el-table-column>
<el-table-column prop="fieldChName" label="字段名" width="150px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row['fieldChName'] ?? '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldType" label="字段类型" width="100px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row['fieldType'] ?? '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldLength" label="长度" width="100px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">
<!--- 直接用??会导致空字符串时无法显示'--',此处需要区分0和“” -->
<span>{{ (scope.row['fieldLength'] !== 0 && !scope.row['fieldLength']) ? "--" :
scope.row['fieldLength'] }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldPrecision" label="精度" width="100px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">
<!--- 直接用??会导致空字符串时无法显示'--',此处需要区分0和“” -->
<span>{{ (scope.row['fieldPrecision'] !== 0 && !scope.row['fieldPrecision']) ? "--" :
scope.row['fieldPrecision'] }}</span>
</template>
</el-table-column>
<el-table-column prop="isPrimary" label="是否主键" width="100px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row['isPrimary'] ?? '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="isNotNull" label="是否必填" width="100px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">{{ scope.row['isNotNull'] === 'Y' ? 'N' : 'Y' }}</template>
</el-table-column>
<el-table-column prop="isFk" label="是否外键" width="100px" align="left" header-align="left"
show-overflow-tooltip>
<template #default="scope">
<span>{{ scope.row['isFk'] ?? '--' }}</span>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.first-step-content {
display: flex;
flex-direction: row;
height: calc(100% - 80px);
.content-left {
width: 200px;
border-right: 1px solid #d9d9d9;
.title-left {
height: 44px;
line-height: 44px;
border-bottom: 1px solid #d9d9d9;
padding-left: 8px;
font-size: 14px;
color: #212121;
}
.content-selecte-left {
height: calc(100% - 44px);
padding: 6px 8px 0px 8px;
.select-ds-title {
display: block;
font-size: 14px;
color: #999999;
line-height: 21px;
margin-bottom: 2px;
}
.table_search_input {
margin-top: 16px;
}
.page_nav_wrap.concise {
justify-content: center;
}
}
}
.content-right {
width: calc(100% - 200px);
.title-right {
height: 44px;
line-height: 44px;
border-bottom: 1px solid #d9d9d9;
padding-left: 8px;
font-size: 14px;
color: #212121;
}
.ds-select-container {
background: #f2f2f2;
height: 100px;
display: flex;
padding: 0px 0 12px 12px;
flex-direction: row;
flex-wrap: wrap;
overflow-y: auto;
.ds-select-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #999999;
}
.ds-select-item {
height: 32px;
border: 2px solid #d9d9d9;
display: flex;
align-items: center;
padding: 0 8px;
background: #fff;
cursor: pointer;
margin-right: 12px;
margin-top: 12px;
.item-title {
font-size: 14px;
color: #212121;
margin-right: 16px;
}
}
.ds-select-item:hover {
border: 2px solid var(--el-color-primary);
}
.ds-select-item.selected {
border: 2px solid var(--el-color-primary);
background-color: var(--el-menu-hover-bg-color);
}
}
.ds-data-preview {
height: calc(100% - 144px);
position: relative;
.preview-data-totals {
position: absolute;
right: 0;
top: 10px;
right: 16px;
}
}
}
}
:deep(.datasource-small-table) {
height: calc(100% - 143px);
margin-top: 4px;
border: 1px solid #d9d9d9;
td.el-table__cell::after,
.el-table__inner-wrapper::before {
height: 0px;
}
.cell {
padding: 0 2px;
}
th.el-table__cell {
line-height: 18px;
font-size: 12px;
color: #999999;
background-color: #fff;
}
td.el-table__cell .cell {
line-height: 18px;
font-size: 12px;
color: #212121;
}
tr.selected {
background-color: var(--el-menu-hover-bg-color);
td {
background-color: var(--el-menu-hover-bg-color);
}
}
.el-table__body tr.selected:hover>td.el-table__cell {
background-color: var(--el-menu-hover-bg-color);
}
}
:deep(.preview-tabs) {
height: 100%;
.el-tabs__header {
margin: 0 0 8px;
}
.el-tabs__nav-wrap::after {
height: 1px;
}
.el-tabs__item {
width: 88px;
padding: 0;
}
.el-tabs__nav {
padding-left: 8px;
}
.el-tabs__content {
height: calc(100% - 48px);
.el-tab-pane {
height: 100%;
:deep(.el-table) {
.cell {
white-space: nowrap;
}
}
.no-select-table {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: #999999;
background-color: #fafafa;
}
}
}
}
:deep(.el-table) {
.el-scrollbar__view {
height: 100%;
}
}
</style>
<route lang="yaml">
name: tableCreateExisting
</route>
<script lang="ts" setup name="tableCreateExisting">
import { ref } from "vue";
import { ElMessage } from "element-plus";
import StepBar from "@/components/StepBar/index.vue";
import {
getDbDirDataSourceList,
getDsData,
getDsTableStructure,
saveDbDirTable,
updateDbDirTable,
createTableSql,
} from "@/api/modules/dataInventory";
import existingTableSelect from "./existingTableSelect.vue";
/** 草稿中未建表时就可以编辑表相关信息。如果建表之后就只能编辑字段。 不能修改字段英文名称,数据库修改英文名就相当于删除再添加。都可以直接跳转到*/
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const isDimTable = route.query.isDim;
const execGuid: any = ref(route.query.execGuid);
// 获取数据库列表
const databaseList: any = ref([]);
const getDbDirDataSourceListData = async () => {
const params = {
execGuid: execGuid.value,
};
const res: any = await getDbDirDataSourceList(params);
if (res.code === proxy.$passCode) {
databaseList.value = processData(res.data);
} else {
proxy.$ElMessage.error(res.msg);
}
};
// 数据处理函数
const processData = (data) => {
return data.map(item => ({
...item,
guid: item.databaseGuid, // 添加新键 "guid"
databaseGuid: undefined, // 删除旧键 "databaseGuid"
})).map(({ databaseGuid, ...rest }) => rest); // 过滤掉 undefined 键
};
onMounted(async () => {
await getDbDirDataSourceListData();
});
const stepsInfo = ref({
step: 0,
list: [
{ title: "选择数据库表", value: 1 },
{ title: "设置属性字段", value: 2 },
],
});
const datasourceSelectedRows: Ref<any> = ref([]);
//记录下一步时选中的库表信息。
const selectedDatabaseTable: Ref<any> = ref([]);
const handlDsSelectedChange = (v) => {
datasourceSelectedRows.value = v || [];
const params: any = [];
v.forEach((item) => {
params.push({
tableName: item.tableName,
database: item.database,
});
});
selectedDatabaseTable.value = params;
console.log('params', params)
// if (isPrevious.value) {
// tableCreateInfo.value.tableFields = [];
// tableCreateInfo.value.inputNameValue = '';
// tableCreateInfo.value.tableData[0].chName = '';
// }
};
const fullscreenLoading = ref(false);
/** 下一步 */
const nextStep = () => {
if (!datasourceSelectedRows.value.length) {
ElMessage({
type: "error",
message: "已选库表不能为空!",
});
return;
}
getNextTableInfo();
stepsInfo.value.step = 1;
};
//下一步获取表字段信息getNextTableInfo。getDsData 入参selectedDatabaseTable.value
const getNextTableInfo = async () => {
const res: any = await getDsTableStructure(selectedDatabaseTable.value);
if (res.code === proxy.$passCode) {
tableDataDetailInfo.value = res.data;
} else {
proxy.$ElMessage.error(res.msg);
}
};
const isPrevious = ref(false);
/** 上一步 */
const previousStep = () => {
stepsInfo.value.step = 0;
isPrevious.value = true;
};
//记录当前正在编辑的表创建信息。
const tableCreateInfo: Ref<any> = ref({
guid: "",
isCreate: false,
inputNameValue: '',
tableData: [],
partitionAttribute: {},
tableFields: [], // 字段标准数组。
});
const tableDataInfo = ref([
{
tableName: '',
tableChName: '',
description: '',
},
])
// 表格数据
const tableDataDetailInfo = ref([
{ id: 1, fieldName: '系统唯一标识', fieldEnglish: 'ID', length: '<200', isUnique: '是', isEdit: false },
{ id: 2, fieldName: '姓名', fieldEnglish: 'NAME', length: '<=200', isUnique: '否', isEdit: false },
{ id: 3, fieldName: '年纪', fieldEnglish: 'AGE', length: '=200', isUnique: '否', isEdit: false },
{ id: 4, fieldName: '系统唯一标识', fieldEnglish: 'ID', length: '<200', isUnique: '是', isEdit: false },
{ id: 5, fieldName: '姓名', fieldEnglish: 'NAME', length: '<=200', isUnique: '否', isEdit: false },
{ id: 6, fieldName: '年纪', fieldEnglish: 'AGE', length: '=200', isUnique: '否', isEdit: false },
])
// 配置哪些字段可编辑
const editableFields = {
fieldName: true, // 字段中文名可编辑
length: true, // 长度可编辑
isUnique: true, // 数据是否唯一可编辑
fieldPrecision: true, // 精度可编辑
dictionaryGuid: true, // 关联字典可编辑
}
const tableFieldsLoading = ref(false)
const selectedRows = ref([]);
// 监听选中行
const selectionFieldsChange = (selection) => {
console.log('selection', selection)
selectedRows.value = selection;
};
// 上移功能
const moveUp = () => {
// 1. 找到选中行在 tableData 中的索引
const selectedIds = selectedRows.value.map((row: any) => row.id);
// 2. 遍历选中行,按顺序上移
for (let i = 0; i < tableDataDetailInfo.value.length; i++) {
const currentRow = tableDataDetailInfo.value[i];
// 如果当前行被选中,且不是第一行,则交换位置
if (selectedIds.includes(currentRow.id) && i > 0) {
const previousRow = tableDataDetailInfo.value[i - 1];
// 如果上一行没有被选中,交换位置
if (!selectedIds.includes(previousRow.id)) {
[tableDataDetailInfo.value[i], tableDataDetailInfo.value[i - 1]] = [tableDataDetailInfo.value[i - 1], tableDataDetailInfo.value[i]];
}
}
}
};
// 下移功能
const moveDown = () => {
// 1. 找到选中行在 tableData 中的索引
const selectedIds = selectedRows.value.map((row: any) => row.id);
// 2. 遍历选中行,倒序下移
for (let i = tableDataDetailInfo.value.length - 1; i >= 0; i--) {
const currentRow = tableDataDetailInfo.value[i];
// 如果当前行被选中,且不是最后一行,则交换位置
if (selectedIds.includes(currentRow.id) && i < tableDataDetailInfo.value.length - 1) {
const nextRow = tableDataDetailInfo.value[i + 1];
// 如果下一行没有被选中,交换位置
if (!selectedIds.includes(nextRow.id)) {
[tableDataDetailInfo.value[i], tableDataDetailInfo.value[i + 1]] = [tableDataDetailInfo.value[i + 1], tableDataDetailInfo.value[i]];
}
}
}
};
// 进入编辑模式
const editRow = (row) => {
row.isEdit = true
}
// 保存数据
const saveRow = (row) => {
row.isEdit = false
}
// 删除行
const deleteRow = (index) => {
// confirm 弹窗
proxy.$confirm('是否删除该行数据?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
tableDataDetailInfo.value.splice(index, 1)
}).catch(() => {
proxy.$message({
type: 'info',
message: '已取消删除'
});
});
}
// 批量删除功能
const batchDelete = () => {
selectedRows.value.forEach((row: any) => {
const index = tableDataDetailInfo.value.findIndex((item) => item.id === row.id);
if (index !== -1) tableDataDetailInfo.value.splice(index, 1);
});
selectedRows.value = [];
};
// 新增一行
const addRow = () => {
tableDataDetailInfo.value.push({
id: tableDataDetailInfo.value.length + 1,
fieldName: '',
fieldEnglish: '', // 英文名不可编辑
length: '',
isUnique: '',
isEdit: true, // 新增时默认进入编辑模式
})
}
const data = [
{
value: '1',
label: 'Level one 1',
children: [
{
value: '1-1',
label: 'Level two 1-1',
children: [
{
value: '1-1-1',
label: 'Level three 1-1-1',
},
],
},
],
},
{
value: '2',
label: 'Level one 2',
children: [
{
value: '2-1',
label: 'Level two 2-1',
children: [
{
value: '2-1-1',
label: 'Level three 2-1-1',
},
],
},
{
value: '2-2',
label: 'Level two 2-2',
children: [
{
value: '2-2-1',
label: 'Level three 2-2-1',
},
],
},
],
},
{
value: '3',
label: 'Level one 3',
children: [
{
value: '3-1',
label: 'Level two 3-1',
children: [
{
value: '3-1-1',
label: 'Level three 3-1-1',
},
],
},
{
value: '3-2',
label: 'Level two 3-2',
children: [
{
value: '3-2-1',
label: 'Level three 3-2-1',
},
],
},
],
},
]
const submitAsDraft = () => {
// 保存为草稿,无论有没有guid 都传入guid
saveOrUpdate({ isDraft: 'Y' }, 0)
}
/**
* 需求写一个校验函数,校验表格数据是否填写完整
* 1、表名称、数据库表、为空
* 2、tableDataDetailInfo.value 每一项中的字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典、不能为空
*/
const checkTableData = (tableDataInfo, tableDataDetailInfo) => {
const tableDataInfoKeys = ['tableName', 'tableChName']
const tableDataDetailInfoKeys = ['fieldName', 'fieldEnglish', 'fieldType', 'length', 'fieldPrecision', 'isUnique', 'isRequired', 'fieldValueRange', 'dictionaryGuid']
let flag = true
tableDataInfo.forEach(item => {
tableDataInfoKeys.forEach(key => {
if (!item[key]) {
flag = false
proxy.$ElMessage.error('表名称、数据库表不能为空')
}
})
})
tableDataDetailInfo.forEach(item => {
tableDataDetailInfoKeys.forEach(key => {
if (!item[key]) {
flag = false
proxy.$ElMessage.error('字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典不能为空')
}
})
})
return flag
}
const guid = ref('')
const submit = async () => {
console.log('提交', tableDataDetailInfo.value, tableDataInfo.value)
// 校验表格数据是否填写完整
if (!checkTableData(tableDataDetailInfo.value, tableDataInfo.value)) {
return
}
/**
"guid": "string",
"cgDirName": "string",
"dirGuid": "string",
"tableGuid": "string",
"tableName": "string",
"tableChName": "string",
"databaseGuid": "string",
"database": "string",
"dbType": "string",
"databaseChName": "string",
"foundMode": 0,
"state": 0,
"isDraft": "string",
"fieldRQVOList": [
{
"guid": "string",
"cgDirName": "string",
"dirGuid": "string",
"classifyName": "string",
"gradeDetailName": "string",
"tableGuid": "string",
"tableName": "string",
"tableChName": "string",
"databaseGuid": "string",
"database": "string",
"databaseChName": "string",
"fieldGuid": "string",
"fieldName": "string",
"fieldChName": "string",
"fieldType": "string",
"fieldLength": 0,
"fieldPrecision": 0,
"dimGuid": "string",
"dictionaryGuid": "string",
"sortValue": 0,
"isPrimary": "string",
"isFk": "string",
"isNotNull": "string",
"defaultValue": "string"
}
], 这是入参
*/
// 如果提交时没有 guid 则为新增type 0,否则为修改 type 1, 也要传参
if (!guid.value) {
saveOrUpdate({}, 0)
} else {
saveOrUpdate({}, 1)
}
}
// 单独将保存和修改函数提取出来 type 0 保存 1 修改 2 生成建表语句
const saveOrUpdate = async (params: any = {}, type) => {
const InParams = {
guid: '',
cgDirName: '',
dirGuid: '',
tableGuid: '',
tableName: '',
tableChName: '',
databaseGuid: '',
database: '',
dbType: '',
databaseChName: '',
foundMode: 0,
state: 0,
isDraft: '',
fieldRQVOList: tableDataDetailInfo.value
}
const finalParams = { ...InParams, ...params }
// 使用switch case 语句
switch (type) {
case 0:
// 保存/保存为草稿
const res: any = await saveDbDirTable(finalParams);
if (res.code === proxy.$passCode) {
if (params.isDraft === 'Y') {
proxy.$ElMessage.success('保存为草稿成功!');
}
proxy.$ElMessage.success('保存成功!');
router.push({ name: 'classifyGradeCatalogue' });
} else {
proxy.$ElMessage.error(res.msg);
}
break;
case 1:
// 修改
const res1: any = await updateDbDirTable(finalParams);
if (res1.code === proxy.$passCode) {
proxy.$ElMessage.success('修改成功!');
router.push({ name: 'classifyGradeCatalogue' });
} else {
proxy.$ElMessage.error(res1.msg);
}
break;
case 2:
// 生成建表语句
const res2: any = await createTableSql(finalParams);
if (res2.code === proxy.$passCode) {
proxy.$ElMessage.success('建表生成成功!');
} else {
proxy.$ElMessage.error(res2.msg);
}
break;
default:
break;
}
}
// 生成建表弹窗区域
const options = [
{ value: 'mysql', label: 'mysql' },
{ value: 'doris', label: 'doris' },
];
const newCreateSqlFormItems = ref([{
label: '选择数据库',
type: 'select',
maxlength: 50,
placeholder: '请输入',
field: 'name',
default: 'mysql',
options: options,
block: true,
clearable: true,
required: true
}]);
const newCreateSqlFormRules = ref({
name: [
{ required: true, message: '请选择数据库名称', trigger: 'blur' },
]
});
const newCreateSqlDialogInfo = ref({
visible: false,
size: 460,
title: "生成建表语句",
type: "",
formInfo: {
id: "grade-form",
items: newCreateSqlFormItems.value,
rules: newCreateSqlFormRules.value,
},
submitBtnLoading: false,
btns: {
cancel: () => {
newCreateSqlDialogInfo.value.visible = false;
},
submit: async (btn, info) => {
newCreateSqlDialogInfo.value.submitBtnLoading = true;
const params = {
...info,
};
await saveOrUpdate(params, 2);
newCreateSqlDialogInfo.value.submitBtnLoading = false;
newCreateSqlDialogInfo.value.visible = false;
}
}
})
// 生成建表语句
const createNewSql = () => {
newCreateSqlDialogInfo.value.visible = true;
}
</script>
<template>
<div class="container_wrap full" v-loading.fullscreen.lock="fullscreenLoading">
<div class="content_main">
<div class="top_tool_wrap">
<StepBar :steps-info="stepsInfo" />
</div>
<existingTableSelect v-show="stepsInfo.step === 0" :databaseList="databaseList" :table-create-type="2"
:execGuid="execGuid" @datasource-selected-change="handlDsSelectedChange"></existingTableSelect>
<div class="second-step-content" v-show="stepsInfo.step === 1">
<div class="table_panel_wrap">
<el-table :data="tableDataInfo" :highlight-current-row="true" stripe border height="100%" row-key="guid"
tooltip-effect="light" :style="{
width: '100%',
'max-height': 'calc(100% - 16px)',
display: 'inline-block',
}">
<!-- 表名称列 -->
<el-table-column prop="tableName" label="表名称" width="180">
<template #header>
<span>表名称</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<el-input v-model="scope.row.tableName" placeholder="请输入表名称" />
</template>
</el-table-column>
<!-- 数据库表列 -->
<el-table-column prop="tableChName" label="数据库表" width="280">
<template #header>
<span>数据库表</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<el-input v-model="scope.row.tableChName" placeholder="请输入数据库表" />
</template>
</el-table-column>
<!-- 描述列 -->
<el-table-column prop="description" label="描述" width="180">
<template #default="scope">
<el-input v-model="scope.row.description" placeholder="请输入描述" />
</template>
</el-table-column>
</el-table>
</div>
<div class="btn-area">
<el-button type="primary" @click="addRow">新增</el-button>
<el-button @click="moveUp">上移</el-button>
<el-button @click="moveDown">下移</el-button>
<el-button @click="batchDelete">批量删除</el-button>
<el-button @click="createNewSql">生成建表语句</el-button>
</div>
<div class="bottom_table">
<el-table :data="tableDataDetailInfo" v-loading="tableFieldsLoading" :highlight-current-row="true" stripe
border height="100%" row-key="guid" @selection-change="selectionFieldsChange" tooltip-effect="light" :style="{
width: '100%',
'max-height': 'calc(100% - 16px)',
display: 'inline-block',
}">
<el-table-column type="selection" :width="32" align="center" />
<!-- 排序列(不可编辑) -->
<el-table-column prop="id" label="排序" width="80" align="center" />
<!-- 字段中文名(不可编辑)fieldChName -->
<el-table-column prop="fieldName" label="字段中文名" width="150">
<template #default="scope">
{{ scope.row.fieldName ? scope.row.fieldName : '--' }}
</template>
</el-table-column>
<!-- 字段英文名(不可编辑) -->
<el-table-column prop="fieldEnglish" label="字段英文名" width="150">
<template #default="scope">
{{ scope.row.fieldEnglish ? scope.row.fieldEnglish : '--' }}
</template>
</el-table-column>
<!-- 分类(不可编辑)classifyName -->
<el-table-column prop="classifyName" label="分类" width="150">
<template #default="scope">
{{ scope.row.classifyName ? scope.row.classifyName : '--' }}
</template>
</el-table-column>
<!-- 分级(不可编辑) -->
<el-table-column prop="gradeDetailName" label="分级" width="120" align="center">
<template #default="scope">
{{ scope.row.gradeDetailName ? scope.row.gradeDetailName : '--' }}
</template>
</el-table-column>
<!-- 字段类型fieldType (不可编辑) -->
<el-table-column prop="fieldType" label="字段类型" width="150" align="center">
<template #default="scope">
{{ scope.row.fieldType ? scope.row.fieldType : '--' }}
</template>
</el-table-column>
<!-- 长度(可编辑) -->
<el-table-column prop="length" label="长度" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.length">{{ scope.row.length ? scope.row.length
: '--' }}</span>
<el-input v-else v-model="scope.row.length" placeholder="请输入长度" />
</template>
</el-table-column>
<!-- 精度(可编辑)fieldPrecision -->
<el-table-column prop="fieldPrecision" label="精度" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.fieldPrecision">{{ scope.row.fieldPrecision ?
scope.row.fieldPrecision : '--' }}</span>
<el-input v-else v-model="scope.row.fieldPrecision" placeholder="请输入精度" />
</template>
</el-table-column>
<!-- 关联字典(可编辑)el-tree-select 形式下拉形式 -->
<el-table-column prop="dictionaryGuid" label="关联字典" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.dictionaryGuid">{{ scope.row.isDict ? scope.row.isDict
: '--' }}</span>
<el-tree-select v-else v-model="scope.row.isDict" :data="data" placeholder="请选择" />
</template>
</el-table-column>
<!-- 数据是否唯一(可编辑) -->
<el-table-column prop="isUnique" label="数据是否唯一" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.isUnique">{{ scope.row.isUnique ? scope.row.isUnique :
'--' }}</span>
<el-select v-else v-model="scope.row.isUnique" placeholder="请选择">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</template>
</el-table-column>
<!-- 是否必填(可编辑) -->
<el-table-column prop="isRequired" label="是否必填" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.isRequired ? scope.row.isRequired : '--' }}</span>
<el-select v-else v-model="scope.row.isRequired" placeholder="请选择">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</template>
</el-table-column>
<!-- 字段取值范围 fieldValueRange(可编辑)-->
<el-table-column prop="fieldValueRange" label="字段取值范围" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.fieldValueRange ? scope.row.fieldValueRange : '--' }}</span>
<el-input v-else v-model="scope.row.fieldValueRange" placeholder="请输入字段取值范围" />
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<!-- <el-button v-if="!scope.row.isEdit" type="primary" size="small" @click="editRow(scope.row)">
编辑
</el-button> -->
<!-- <el-button v-else type="success" size="small" @click="saveRow(scope.row)">
保存
</el-button>
<el-button type="danger" size="small" @click="deleteRow(scope.$index)">
删除
</el-button> -->
<span class="text_btn" v-if="!scope.row.isEdit" @click="editRow(scope.row)">编辑</span>
<span class="text_btn" v-else @click="saveRow(scope.row)">保存</span>
<el-divider direction="vertical" />
<span class="text_btn" @click="deleteRow(scope.$index)">删除</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<div class="bottom_tool_wrap">
<template v-if="stepsInfo.step == 0">
<el-button type="primary" @click="nextStep">下一步</el-button>
</template>
<template v-else>
<el-button @click="previousStep">上一步</el-button>
<el-button type="primary" @click="submitAsDraft">保存为草稿</el-button>
<el-button type="primary" @click="submit">提交</el-button>
</template>
</div>
<Dialog_form :dialogConfigInfo="newCreateSqlDialogInfo" />
</div>
</template>
<style lang="scss" scoped>
.top_tool_wrap {
width: 100%;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #d9d9d9;
:deep(.el-steps) {
width: 30%;
}
}
.content_main {
height: calc(100% - 40px);
.second-step-content {
height: calc(100% - 80px);
width: 100%;
padding: 16px;
.table_panel_wrap {
width: 100%;
height: auto;
overflow: visible;
}
.btn-area {
margin-top: 12px;
}
:deep(.bottom_table) {
margin-top: 12px;
height: calc(100% - 150px);
overflow-y: auto;
.el-table td.el-table__cell {
padding: 2px 0;
height: 36px;
}
}
}
}
:deep(.el-dialog) {
.dialog-form-inline {
.checkbox_input {
display: flex;
flex-direction: column;
.input_panel {
margin: 0;
}
}
.select_group {
.el-form-item__content>.el-input {
margin-top: 21px;
}
}
.radio_panel {
.panel_content {
display: none;
}
}
}
}
:deep(.batchDialog) {
.el-tree-node__content {
padding-left: 8px !important;
.el-icon {
display: none;
}
}
}
.bottom_tool_wrap {
height: 40px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
display: flex;
justify-content: flex-end;
align-items: center;
}
</style>
<route lang="yaml">
name: tableCreateFile
</route>
<script lang="ts" setup name="tableCreateFile">
import { ref } from "vue";
import { ElMessage, ElMessageBox, ElTable } from "element-plus";
import useUserStore from "@/store/modules/user";
import useDataCatalogStore from "@/store/modules/dataCatalog";
import expandPropertyDialog from "./expandPropertyDialog.vue";
import tableDefaultValue from "./components/tableDefaultValue.vue";
// import {
// getDatabase,
// getFileStandards,
// getDictionary,
// getSubjectFieldByFile,
// tableCategoryList,
// syncPolicys,
// getDataTypeList,
// tableModels,
// aggMethodList,
// getCharacterList,
// saveSubjectTable,
// updateSubjectTable,
// getTableStandardDetail,
// getSubjectDomainDetail,
// saveSubjectTableDraft,
// updateSubjectTableDraft,
// getFieldStandardTree,
// dimTypeList,
// getDimList,
// getSubjectTableDetail,
// checkSubjectTableData
// } from "@/api/modules/dataCatalogService";
import { useDefault } from "@/hooks/useDefault";
import uploadExcelFile from "./components/uploadExcelFile.vue";
const userStore = useUserStore();
const dataCatalogStore = useDataCatalogStore();
const { checkDefault } = useDefault();
const userData = JSON.parse(userStore.userData);
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const isDimTable = route.query.isDim;
const subjectDomainGuid: any = ref(route.query.domainGuid);
const fullPath = route.fullPath;
const standardSetGuids = ref([]);
//记录已入库的表创建信息。
const originTableCreateInfo = ref({});
//记录当前正在编辑的表创建信息。
const tableCreateInfo: Ref<any> = ref({
guid: "",
isCreate: false,
inputNameValue: '',
isSync: 'Y', //是否默认同步数据。
sheetName: '', //所选择的sheet页。
tableData: [
{
//数据库表信息。
dataSourceGuid: '',
dataServerName: "",
dataServerChName: "",
enName: "",
chName: "",
subjectDomain: route.query.domainName,
subjectDomainGuid: subjectDomainGuid.value,
tableCategory: route.query.layereAttribute == '3' ? 6 : 1,
dimType: isDimTable ? 1 : null,
codeColumn: '',
codeName: '',
syncPolicy: 3,
characterSet: 'utf8mb3',
tableModel: 1, //若是聚合模型,下方出现一列聚合方式选择。处了主键列,其余列都需要选择。每个表里都要有主键。
description: "",
},
],
partitionAttribute: {},
tableFields: [], // 字段标准数组。
});
const stepsInfo = ref({
step: 0,
list: [
{ title: "上传文件", value: 1 },
{ title: "设置属性字段", value: 2 },
],
});
/** 上传的文件字段信息。 */
const fileTableFields: any = ref([]);
/** 上传的文件数据信息 */
const fileTableData: any = ref([]);
/** 上传的文件信息。 */
const uploadDataFileInfo: any = ref([]);
const handleFileDataChange = (fileFields, files, sheetName, data) => {
if (fileTableFields.value != fileFields) {//文件字段改变,下一步时需要清空。
fileTableFields.value = fileFields.slice(0);
tableCreateInfo.value.tableFields = [];
}
fileTableData.value = data;
uploadDataFileInfo.value = files;
tableCreateInfo.value.sheetName = sheetName;
console.log(files);
}
const uploadFileRef = ref();
// const getSubjectField = () => {
// tableFieldsLoading.value = true;
// getSubjectFieldByFile(fileTableFields.value.map(f => f.chName), tableCreateInfo.value.tableData[0].subjectDomainGuid).then((res: any) => {
// tableFieldsLoading.value = false;
// if (res.code == proxy.$passCode) {
// tableCreateInfo.value.tableFields = res.data?.map((field, i) => {
// field.dimOrdictionaryGuid = field.dictionaryGuid;
// field.fileFieldName = fileTableFields.value[i].chName;
// field.isEdit = true;
// !field.notNull && (field.notNull = 'N');
// return field;
// }) || [];
// } else {
// ElMessage.error(res.msg);
// }
// });
// }
const nextStep = () => {
uploadFileRef.value.fileFormRef.ruleFormRef.validate((valid) => {
if (valid) {
if (!fileTableFields.value.length) {
ElMessage({
type: "error",
message: "上传文件字段不能为空!",
});
return;
}
if (!fileTableData.value.length) {
tableCreateInfo.value.isSync = 'N';
} else {
tableCreateInfo.value.isSync = 'Y';
}
stepsInfo.value.step = 1;
// getDictionaryList();
// getDimListData();
// if (!fieldTypes.value.length) {
// getFieldTypeList();
// getCharacterListData();
// }
// if (!databaseList.value.length) {
// getDatabaseList();
// }
// getDomainDetail(subjectDomainGuid.value);
// if (!tableCreateInfo.value.tableFields.length) {
// getSubjectField();
// }
}
});
};
const isPrevious = ref(false);
/** 上一步 */
const previousStep = () => {
stepsInfo.value.step = 0;
isPrevious.value = true;
};
/** 记录是否开启字段标准,根据主题域相关信息获取 */
const isOpenStandard = ref(true);
const selectTableFieldRows = ref([]);
const tableStandardGuid = ref('');
const tableStandardDetail: any = ref({});
const fieldStandardSetGuids = ref([]);
// 实际显示的字段标准列表
const standardListOptions: any = ref([]);
const databaseList: any = ref([]);
//字段类型
const fieldTypes: any = ref([]);
//字符集
const characterList: any = ref([]);
//是否列表
const isNotList = ref([
{
label: "Y",
value: "Y",
},
{
label: "N",
value: "N",
},
]);
const batchAddFieldStandardPage = ref({
pageSize: 50,
pageIndex: 1,
standardSetGuids: [],
approveState: 'Y',
name: '',
standardSetLevelCode: ""
});
const init = ref(true);
const fullscreenLoading = ref(false);
/** 表里有数据时不能修改字段类型,长度,精度 */
const hasSubjectData = ref(false);
/** 保存表 */
const saveTable = () => {
}
</script>
<template>
<div class="container_wrap full" v-loading.fullscreen.lock="fullscreenLoading">
<div class="content_main">
<div class="top_tool_wrap">
<StepBar :steps-info="stepsInfo" />
</div>
<uploadExcelFile ref="uploadFileRef" v-show="stepsInfo.step === 0" @fileDataChange="handleFileDataChange">
</uploadExcelFile>
<div class="second-step-content" v-show="stepsInfo.step === 1">
aaa
</div>
</div>
<div class="bottom_tool_wrap">
<template v-if="stepsInfo.step == 0">
<el-button type="primary" @click="nextStep">下一步</el-button>
</template>
<template v-else>
<el-checkbox v-model="tableCreateInfo.isSync" true-label="Y" :disabled="!fileTableData?.length"
false-label="N">同步数据(说明:勾选代表建表同时写入表格数据。)</el-checkbox>
<el-button @click="previousStep">上一步</el-button>
<el-button type="primary">保存为草稿</el-button>
<el-button type="primary" @click="saveTable">提交</el-button>
</template>
</div>
</div>
</template>
<style lang="scss" scoped>
.top_tool_wrap {
width: 100%;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #d9d9d9;
:deep(.el-steps) {
width: 30%;
}
}
.content_main {
height: calc(100% - 40px);
.header-bg-title {
margin: 16px 16px 0px;
background: #F5F5F5;
padding-left: 16px;
height: 48px;
font-size: 14px;
color: #212121;
letter-spacing: 0;
line-height: 21px;
font-weight: 600;
display: flex;
align-items: center;
position: relative;
.preview-data-totals {
position: absolute;
right: 16px;
line-height: 32px;
font-size: 14px;
color: #666666;
font-weight: 400;
}
.fontC-4fa1a4 {
color: var(--el-color-primary);
}
}
.form-main {
border: 1px solid #d9d9d9;
margin: 0px 16px;
padding: 16px 16px 0px 16px;
height: 125px;
.dialog-form-inline {
align-items: flex-start;
}
:deep(.el-form) {
.item-label {
width: 100%;
}
.el-select {
max-width: 300px;
}
}
}
.table-main {
height: calc(100% - 350px);
border: 1px solid #d9d9d9;
margin: 0px 16px 16px 16px;
padding: 16px;
}
.empty-content {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
flex-direction: column;
.empty-text {
font-size: 14px;
color: #b2b2b2;
}
}
.second-step-content {
height: calc(100% - 80px);
width: 100%;
padding: 16px;
.tools_btns {
padding: 8px 0;
}
:deep(.el-table) {
.cell {
.prefix-or-suffix-cell {
display: inline-flex;
align-items: center;
}
}
}
.table_panel {
height: calc(100% - 114px);
}
:deep(.el-table) {
& td.el-table__cell {
padding: 3px 0;
height: 36px;
}
}
}
}
:deep(.el-dialog) {
.dialog-form-inline {
.checkbox_input {
display: flex;
flex-direction: column;
.input_panel {
margin: 0;
}
}
.select_group {
.el-form-item__content>.el-input {
margin-top: 21px;
}
}
.radio_panel {
.panel_content {
display: none;
}
}
}
}
:deep(.batchDialog) {
.el-tree-node__content {
padding-left: 8px !important;
.el-icon {
display: none;
}
}
}
.bottom_tool_wrap {
height: 40px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
display: flex;
justify-content: flex-end;
align-items: center;
.el-checkbox {
margin-right: 20px;
}
:deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
color: var(--el-color-regular);
}
}
</style>
......@@ -137,6 +137,9 @@ const handleClassDataEdit = (params) => {
if (item.field === 'classStandardName') {
item.default = params.name
}
if (item.field === 'description') {
item.default = params.description
}
})
}
......@@ -209,6 +212,15 @@ const classStandardFormItems = ref([{
default: '',
required: true,
block: true,
}, {
label: '分类描述',
type: 'textarea',
placeholder: '请输入',
field: 'description',
default: '',
clearable: true,
required: false,
block: true
}]);
const classStandardFormRules = ref({
......@@ -235,6 +247,7 @@ const newCreateClassStandardDialogInfo = ref({
if (newCreateClassStandardDialogInfo.value.title === '新增分类') {
newCreateClassStandardDialogInfo.value.submitBtnLoading = true;
const params = {
description: info.description,
name: info.classStandardName,
refGradeGuid: info.refGradeGuid,
type: 'C'
......
<route lang="yaml">
name: home
meta:
title: 数据资产管理
</route>
<script lang="ts" setup name="home">
import homeDamRegister from './homeDamRegister.vue';
import homeDamDataCircule from './homeDamDataCircule.vue';
import homeDamDemand from './homeDamDemand.vue';
import homeDamAlgorithm from './homeDamAlgorithm.vue';
import homeDamFinance from './homeDamFinance.vue';
import homeDamMarket from './homeDamMarket.vue';
const activeName = ref('register');
const enterCompany = () => {
window.open('https://www.csbr.cn/');
}
const logon = () => {
window.open('/login');
}
const register = () => {
window.open('/register');
}
const companyDesc = ref('国家级数据交易所经纪服务商,为客户提供数据资产登记服务、数据要素及数据产品交易服务、数据要素金融服务等一揽子经纪服务。\n北京传世博润科技有限公司以软硬件一体化的人工智能物流网为基础,结合大数据技术提供数字化综合解决方案,帮助客户在数字经济时代转型为数字化企业的飞跃。');
const tabsInfo = ref({
activeName: "index",
tabs: [
{ label: "首页", name: 'index' },
{ label: "资产登记服务", name: "dam", description: '' },
{ label: "数据供给", name: "dataCircule" },
{ label: "供需信息", name: "demand" },
{ label: "算法竞赛", name: "algorithm" },
{ label: "服务工具", name: "market" },
{ label: "融资服务", name: "service" },
]
});
const homeDamFinanceRef = ref();
const homeDamDataCirculeRef = ref();
const homeDamDemandRef = ref();
const homeDamAlgorithmRef = ref();
const homeDamMarketRef = ref();
const tabClick = (val) => {
if (val?.props.name == 'dataCircule') {
homeDamDataCirculeRef.value.initPage();
} else if (val?.props.name == 'demand') {
homeDamDemandRef.value.initPage();
} else if (val?.props.name == 'algorithm') {
homeDamAlgorithmRef.value.initPage();
} else if (val?.props.name == 'market') {
homeDamMarketRef.value.initPage();
} else if (val?.props.name == 'service') {
homeDamFinanceRef.value.initPage();
}
}
</script>
<template>
<div class="home-full-wrap">
<div class="home-container">
<div class="logo-header">
<img style="width: 120px;height: 36px;margin-left: 27px;" src="../assets/images/logo-white.png" alt="" />
<el-tabs v-model="tabsInfo.activeName" class="header-tabs" @tab-click="tabClick">
<el-tab-pane v-for="tab in tabsInfo.tabs" :label="tab.label" :name="tab.name">
</el-tab-pane>
</el-tabs>
<div class="logon-btns">
<el-button class="logon-btn" @click="register">注册</el-button>
<el-button class="logon-btn main-btn" @click="logon">登录</el-button>
</div>
</div>
<div v-show="tabsInfo.activeName == 'index'">
<div class="banner">
<img style="width: 100%;height: 100%;" src="../assets/images/home-banner.png" alt="" />
<div class="header">
<div class="header-content">
<!-- <div class="header-top">
<img src="../assets/images/logo.png" class="logo" />
</div> -->
<div class="header-bottom">
<div class="title">数据资产管理系统</div>
<div class="header-right">激活数据流通体系,释放数据要素新质生产力</div>
</div>
</div>
</div>
</div>
<div class="second-container">
<div class="content">
<div class="chunk">
<img class="effect-img" src="../assets/images/financial-optimization.png" alt="" />
</div>
<div class="chunk">
<img class="effect-img" src="../assets/images/enhance.png" alt="" />
</div>
<div class="chunk">
<img class="effect-img" src="../assets/images/promote-circulation.png" alt="" />
</div>
<div class="chunk">
<img class="effect-img" src="../assets/images/data-element.png" alt="" />
</div>
</div>
</div>
<el-tabs class="three-tabs" v-model="activeName">
<el-tab-pane label="数据资产登记服务" name="register" class="register">
<div class="title-a">确权凭证可交易</div>
<div class="step-main">
<div class="step-one">
<div class="left">1</div>
<div class="right">加入数据资产生产体系</div>
</div>
<div class="step-one">
<div class="left">2</div>
<div class="right">资源盘点资产规划</div>
</div>
<div class="step-one">
<div class="left">3</div>
<div class="right">合规核验权利梳理</div>
</div>
<div class="step-one">
<div class="left">4</div>
<div class="right">资产登记确权凭证</div>
</div>
<div class="step-one">
<div class="left">5</div>
<div class="right">确定目标资产质量评价</div>
</div>
<div class="step-one">
<div class="left">6</div>
<div class="right">确定目标资产价值评估</div>
</div>
</div>
<div class="title-a" style="margin-top: 0px">确权凭证不可交易</div>
<div class="step-main">
<div class="step-one">
<div class="left">1</div>
<div class="right">加入数据资产生产体系</div>
</div>
<div class="step-one">
<div class="left">2</div>
<div class="right">资源盘点资产规划</div>
</div>
<div class="step-one">
<div class="left">3</div>
<div class="right">合规核验权利梳理</div>
</div>
<div class="step-one">
<div class="left">4</div>
<div class="right">资产登记确权凭证</div>
</div>
<div class="step-one" style="background: transparent"></div>
<div class="step-one" style="background: transparent"></div>
</div>
</el-tab-pane>
<el-tab-pane label="数据资产入表服务" name="entry" class="entry">
<div style="width: 100%; position: relative;">
<img style="width: 100%;height: 208px;" src="../assets/images/entry-bg.png" alt="" />
<div class="content">
<div class="title">提供入表咨询服务</div>
<div class="desc">提供权威会计师律师事务所辅导资产入表工作 上市公司 拟上市公司 国有企业 事业单位</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="数据场内交易服务" name="transactio" class="transactio">
<div class="title-a">获取加工及产品经营授权,将数据资源形成数据产品,在可信空间进行买卖双方的交易</div>
<div class="step-main">
<div class="step-one" style="width: calc(25% - 25px)">
<div class="left">1</div>
<div class="right">数据产品设计</div>
</div>
<div class="step-one" style="width: calc(25% - 25px)">
<div class="left">2</div>
<div class="right">数据产品发布</div>
</div>
<div class="step-one" style="width: calc(25% - 25px)">
<div class="left">3</div>
<div class="right">寻找数据需求方</div>
</div>
<div class="step-one" style="width: calc(25% - 25px)">
<div class="left">4</div>
<div class="right">撮合成交</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="数据金融化服务" name="finace" class="finace">
<div class="title-a">提供辅导完成数据资产金融化业务,获取以数据资产或数据产品的融资</div>
<div class="step-main">
<div class="step-one" style="width: calc(33% - 35px)">
<div class="left">1</div>
<div class="right">提出金融需求</div>
</div>
<div class="step-one" style="width: calc(33% - 35px)">
<div class="left">2</div>
<div class="right">寻找资金方</div>
</div>
<div class="step-one" style="width: calc(33% - 35px)">
<div class="left">3</div>
<div class="right">撮合成交</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="治理及挖掘服务" name="governance" class="governance">
<div style="width: 100%; position: relative;">
<img style="width: 100%;height: 208px;" src="../assets/images/governance-bg.png" alt="" />
<div class="content">
<div class="title">治理及挖掘服务</div>
<div class="desc">提供专业的数据治理服务商为其提供数据治理服务及建议咨询</div>
<div class="desc">提供专业的数据挖掘应用服务</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
<div class="four-container">
<div style="height: 100%; width: 100%;">
<div class="title">重点领域数据要素乘数效应</div>
<div class="desc">12重点领域</div>
<img style="width: 100%;margin-bottom: 61px;" src="../assets/images/primary-area.png" alt="" />
</div>
</div>
<div class="company">
<div style="height: 100%; width: 100%;">
<div class="title">北京传世博润科技有限公司</div>
<div class="desc">{{ companyDesc }}</div>
<div class="btn-dom">
<el-button class="btn" @click="enterCompany">了解我们</el-button>
</div>
<img style="width: 100%;height: 543px;" src="../assets/images/company-bg.png" alt="" />
</div>
</div>
<div class="exchange">
<div class="title">合作交易所</div>
<div class="img-main">
<img class="img-exchange" src="../assets/images/exchange-beijing.png" alt="" />
<img class="img-exchange" src="../assets/images/exchange-guiyang.png" alt="" />
<img class="img-exchange" src="../assets/images/exchange-xibu.png" alt="" />
<img class="img-exchange" src="../assets/images/exchange-wenzhou.png" alt="" />
</div>
</div>
</div>
<homeDamRegister v-show="tabsInfo.activeName == 'dam'"></homeDamRegister>
<!-- 数据供给页面 -->
<homeDamDataCircule ref="homeDamDataCirculeRef" v-show="tabsInfo.activeName == 'dataCircule'"></homeDamDataCircule>
<!-- 供需信息页面 -->
<homeDamDemand ref="homeDamDemandRef" v-show="tabsInfo.activeName == 'demand'"></homeDamDemand>
<!-- 算法竞赛页面 -->
<homeDamAlgorithm ref="homeDamAlgorithmRef" v-show="tabsInfo.activeName == 'algorithm'"></homeDamAlgorithm>
<!-- 服务工具 -->
<homeDamMarket ref="homeDamMarketRef" v-show="tabsInfo.activeName == 'market'"></homeDamMarket>
<homeDamFinance ref="homeDamFinanceRef" v-show="tabsInfo.activeName == 'service'"></homeDamFinance>
<div class="footer-link">
<div class="link-title">友情链接</div>
<div class="link-main">
<div class="column">
<!-- 目前没找到官网,暂时先不跳转,跟统计局不是同一个。 -->
<span class="link-detail" href="https://data.stats.gov.cn" target="_blank">国家数据局</span>
<a class="link-detail" href="https://www.miit.gov.cn" target="_blank">中华人民共和国工业和信息化部</a>
<a class="link-detail" href="http://www.caict.ac.cn" target="_blank">中国信息通信研究院</a>
<a class="link-detail" href="https://www.trimps.ac.cn" target="_blank">公安部第三研究所</a>
</div>
<div class="column">
<a class="link-detail" href="https://www.cufe.edu.cn" target="_blank">中央财经大学</a>
<a class="link-detail" href="https://www.henu.edu.cn" target="_blank">河南大学</a>
<a class="link-detail" href="https://www.wzu.edu.cn" target="_blank">温州大学</a>
</div>
<div class="column">
<a class="link-detail" href="https://www.landinglawyer.com" target="_blank">上海兰迪律师事务所</a>
<a class="link-detail" href="https://www.cairui.com.cn" target="_blank">上海财瑞会计事务所</a>
<a class="link-detail" href="https://www.cairui.com.cn" target="_blank">上海财瑞资产评估有限公司</a>
</div>
<div class="column">
<a class="link-detail" href="https://ebanking1.ccb.com.cn" target="_blank">中国建设银行</a>
<a class="link-detail" href="https://bankofbeijing.com.cn" target="_blank">北京银行股份有限公司</a>
<a class="link-detail" href="https://www.cebbank.com" target="_blank">中国光大银行股份有限公司</a>
<a class="link-detail" href="https://www.zybank.com.cn" target="_blank">中原银行股份有限公司</a>
<a class="link-detail" href="https://www.shxibank.com" target="_blank">山西银行股份有限公司</a>
</div>
</div>
</div>
<div class="footer">
<div class="desc">北京传世博润科技有限公司 Copyright @ 2023-2024 <a style="color: #fff" href="https://beian.miit.gov.cn"
target="_blank">京ICP备2024044205号 </a>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.home-full-wrap {
height: 100%;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
}
.home-container {
display: flex;
flex-direction: column;
min-height: 100%;
}
.logo-header {
height: 48px;
display: flex;
align-items: center;
justify-content: space-between;
:deep(.header-tabs.el-tabs) {
margin-top: 14px;
.el-tabs__nav-scroll {
display: flex;
justify-content: center;
}
.el-tabs__nav-wrap::after {
height: 0px;
}
.el-tabs__nav {
margin: 0px 20px;
}
.el-tabs__item:focus-visible {
box-shadow: none;
}
}
}
.banner {
height: 500px;
position: relative;
.header {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
position: absolute;
left: 0;
top: 0;
.header-content {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.header-top {
height: 80px;
display: flex;
align-items: center;
.logo {
margin-left: 40px;
height: 40px;
}
}
.header-bottom {
height: calc(100% - 120px);
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 40px;
.title {
font-size: 56px;
color: #FFFFFF;
font-weight: 400;
margin-bottom: 18px;
display: block;
margin-left: 213px;
}
.header-right {
font-size: 30px;
font-weight: 200;
padding-top: 25px;
margin-left: 331px;
}
}
}
}
}
.logon-btns {
display: flex;
margin-right: 55px;
}
.logon-btn {
font-size: 14px;
color: #666666;
text-align: center;
height: 32px;
width: 64px;
display: block;
border-radius: 4px;
&.main-btn {
background: #0098E6;
color: #fff;
}
}
.second-container {
height: auto;
background-color: #fff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 32px 20px;
.content {
width: 100%;
display: flex;
height: 100%;
justify-content: space-between;
.chunk {
min-width: 250px;
width: 23.5%;
.effect-img {
height: 100%;
width: 100%;
}
.text {
font-size: 24px;
color: #1B1B1B;
font-weight: 200;
padding-left: 20px;
padding-right: 40px;
padding-top: 12px;
height: 118px;
}
}
}
}
:deep(.three-tabs.el-tabs) {
background-color: #EAEDF4;
.el-tabs__content {
padding: 0px 20px;
}
.el-tabs__nav-next,
.el-tabs__nav-prev {
top: 35px;
}
.el-tabs__nav-scroll {
display: flex;
flex-direction: row;
justify-content: center;
padding: 0px 20px;
.el-tabs__nav {
width: 100%;
}
}
.el-tabs__active-bar {
background-color: #E1822F;
}
.el-tabs__item {
height: 110px;
width: 256px;
font-size: 24px;
color: #414141;
font-weight: 200;
padding-right: 30px;
flex: 1;
&.is-active {
color: #E1822F;
font-weight: 500;
}
}
.el-tab-pane {
display: flex;
flex-direction: column;
align-items: center;
}
.title-a {
margin-top: 37px;
margin-bottom: 16px;
font-size: 24px;
color: #2B2B2B;
font-weight: 200;
width: 100%;
}
.governance,
.entry {
margin-bottom: 50px;
margin-top: 36px;
position: relative;
.content {
position: absolute;
left: 60px;
top: 0;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.title {
font-size: 32px;
color: #FFFFFF;
font-weight: 200;
}
.desc {
margin-top: 12px;
font-size: 20px;
color: #FFFFFF;
font-weight: 200;
}
}
}
.step-main {
margin-bottom: 81px;
display: flex;
width: 100%;
justify-content: space-between;
.step-one {
height: 127px;
background-image: linear-gradient(90deg, #D96D03 2%, #F1A981 100%);
display: flex;
min-width: 205px;
width: calc(16.7% - 20px);
.left {
display: flex;
align-items: center;
margin-left: 12px;
font-size: 80px;
color: #FFFFFF;
font-weight: 500;
}
.right {
display: flex;
align-items: center;
margin-left: 8px;
margin-right: 24px;
font-size: 24px;
color: #FFFFFF;
font-weight: 200;
}
}
}
}
.four-container {
height: auto;
display: flex;
flex-direction: column;
align-items: center;
padding: 0px 20px;
.title {
width: 100%;
margin-top: 80px;
font-size: 40px;
color: #242424;
line-height: 56px;
font-weight: 200;
}
.desc {
width: 100%;
font-size: 24px;
color: #242424;
line-height: 33px;
font-weight: 200;
margin-bottom: 32px;
}
}
.company {
background: #EAEDF4;
display: flex;
flex-direction: column;
align-items: center;
padding: 0px 20px;
.title {
width: 100%;
margin-top: 80px;
font-size: 40px;
color: #2B2B2B;
font-weight: 200;
height: 56px;
}
.desc {
width: 100%;
margin-top: 14px;
font-size: 20px;
color: #2B2B2B;
font-weight: 200;
white-space: pre-line;
line-height: 28px;
}
.btn-dom {
width: 100%;
}
.btn {
font-size: 18px;
margin-top: 21px;
margin-bottom: 23px;
background: #0759B7;
border-radius: 0px;
color: #fff;
font-weight: 500;
padding: 8px 33px;
height: 40px;
width: 120px;
}
}
.exchange {
height: 394px;
display: flex;
flex-direction: column;
align-items: center;
padding: 0px 20px;
.title {
width: 100%;
margin-top: 40px;
margin-bottom: 30px;
font-size: 40px;
color: #2B2B2B;
font-weight: 200;
}
.img-main {
width: 100%;
height: 228px;
display: flex;
justify-content: space-between;
.img-exchange {
width: 23%;
min-width: 230px;
}
}
}
.footer {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
background: #2A2B2C;
.desc {
font-size: 14px;
color: #FFFFFF;
font-weight: 200;
}
}
.footer-link {
height: 262px;
display: flex;
flex-direction: column;
align-items: flex-start;
background: #2A2B2C;
padding: 0px 90px;
.link-title {
margin: 28px 0px;
font-size: 16px;
color: #FFFFFF;
font-weight: 600;
}
.link-main {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
.column {
display: flex;
flex-direction: column;
}
.link-detail {
font-size: 16px;
color: #C9C9C9;
line-height: 18px;
font-weight: 400;
line-height: 24px;
margin-bottom: 8px;
text-decoration: none;
cursor: pointer;
}
}
}
:deep(.el-overlay) {
background-color: transparent;
}
</style>
......@@ -4,14 +4,14 @@
<script lang="ts" setup name="importFile">
import { ref } from "vue";
import { useRoute,useRouter } from "vue-router"
import { useRoute, useRouter } from "vue-router"
import useUserStore from "@/store/modules/user";
import { ElMessage, ElMessageBox } from "element-plus";
import Tabs from '@/components/Tabs/index.vue'
import Table from '@/components/Table/index.vue'
import Dialog from '@/components/Dialog/index.vue'
import useCatchStore from "@/store/modules/catch";
import { download, downFile,getDownloadUrl } from '@/utils/common'
import { download, downFile, getDownloadUrl } from '@/utils/common'
import {
addImportData,
deleteImportData,
......@@ -25,7 +25,7 @@ import { commonPageConfig } from '@/utils/enum';
const { proxy } = getCurrentInstance() as any;
const userStore = useUserStore()
const route = useRoute()
const route = useRoute()
const router = useRouter()
/** 2表示资产目录的。3是主数据; 4是元数据导入 */
const isfileImport = route.query.isfileImport
......@@ -39,21 +39,21 @@ const tabsActiveName = ref('')
const uploadSetting: any = ref({})
const importType = ref('')
const defaulttabs = [
{ label: '标准集导入', name: 'standard' },
{ label: '字段标准导入', name: 'field' },
{ label: '命名标准导入', name: 'naming' },
{ label: '数据字典导入', name: 'dictionary' },
// { label: '质量模型导入', name: 'qualityModelGroup' },
// { label: '质量规则导入', name: 'qualityRule' },
]
{ label: '标准集导入', name: 'standard' },
{ label: '字段标准导入', name: 'field' },
{ label: '命名标准导入', name: 'naming' },
{ label: '数据字典导入', name: 'dictionary' },
// { label: '质量模型导入', name: 'qualityModelGroup' },
// { label: '质量规则导入', name: 'qualityRule' },
]
const importTabs = [
{ label: '导入文件数据', name: 'importFile' },
// { label: '质量模型导入', name: 'qualityModelGroup' },
// { label: '质量规则导入', name: 'qualityRule' },
]
{ label: '导入文件数据', name: 'importFile' },
// { label: '质量模型导入', name: 'qualityModelGroup' },
// { label: '质量规则导入', name: 'qualityRule' },
]
const tabsInfo = ref({
activeName: '',
tabs: isfileImport?importTabs:defaulttabs
tabs: isfileImport ? importTabs : defaulttabs
})
const currTableData: any = ref<Object>({});
......@@ -217,27 +217,27 @@ const tableBtnClick = async (scope, btn) => {
currTableData.value = row;
if (type == "export_file") {
getImageContent(row.filePath).then((res: any) => {
if (res && !res.msg) {
let name = row.filePath;
var fileSuffix = name ? name.substring(name.lastIndexOf('.') + 1) : '';
download(res, row.fileName, fileSuffix);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
if (res && !res.msg) {
let name = row.filePath;
var fileSuffix = name ? name.substring(name.lastIndexOf('.') + 1) : '';
download(res, row.fileName, fileSuffix);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
//downFile(row.filePath, row.fileName)
} else if (type == 'export_abnormal_data') {
//downFile(row.errorFilePath, '')
getImageContent(row.errorFilePath).then((res: any) => {
if (res && !res.msg) {
let name = row.errorFilePath;
var fileSuffix = name ? name.substring(name.lastIndexOf('.') + 1) : '';
let fileName = name ? name.substring(name.lastIndexOf('/') + 1) :''
download(res, fileName, fileSuffix);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
if (res && !res.msg) {
let name = row.errorFilePath;
var fileSuffix = name ? name.substring(name.lastIndexOf('.') + 1) : '';
let fileName = name ? name.substring(name.lastIndexOf('/') + 1) : ''
download(res, fileName, fileSuffix);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
} else if (type == "delete") {
open("此操作将永久删除, 是否继续?", "warning");
}
......@@ -267,7 +267,7 @@ const batching = (type) => {
return
}
open("此操作将永久删除, 是否继续?", "warning", true);
} else if(type === 'importFile') {
} else if (type === 'importFile') {
if (isfileImport == '2' || isfileImport == '4') {
dialogInfo.value.header.title = '导入数据'
dialogInfo.value.type = 'upload'
......@@ -279,8 +279,8 @@ const batching = (type) => {
dialogInfo.value.visible = true
} else {
router.push({
name:"importData",
query:route.query
name: "importData",
query: route.query
})
}
}
......@@ -379,19 +379,19 @@ const importData = (info) => {
type: 'error',
message: '请填写数据源名称'
})
return;
return;
}
if (!info.databaseNameEn) {
ElMessage({
type: 'error',
message: '请填写数据库英文名'
})
return;
return;
}
uploadFiles.value.forEach((item: any, index: number) => {
params.append("uploadFile", item.raw);
});
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}`
paramUrl = `${import.meta.env.VITE_APP_CHECK_BASEURL}/meta-collect-task/meta-collect-import?staffGuid=${userData.staffGuid}&databaseNameZh=${info.databaseNameZh}&databaseNameEn=${info.databaseNameEn}&isCover=${info.isCover}`
} else {
uploadFiles.value.forEach((item: any, index: number) => {
params.append("file", item.raw);
......@@ -455,7 +455,7 @@ const setUploadInfo = () => {
importType.value = '0034';
} else if (isfileImport == '4') {
importType.value = '0042';
} else {
} else {
importType.value = '0033';
}
}
......@@ -567,7 +567,7 @@ const setUploadInfo = () => {
uploadInfo.value.uploadInfo.extraParams = {}
} else if (tabsActiveName.value == 'importFile' && isfileImport == '4') { //元数据导入
uploadSteps.value = [
{
{
title: '1、导入前请先录入以下内容',
type: 'group',
formItems: [{
......@@ -643,12 +643,12 @@ const setUploadInfo = () => {
onActivated(() => {
uploadSetting.value = cacheStore.getCatch('uploadSetting') ?? {}
if(isfileImport) {
if (isfileImport) {
tabsActiveName.value = 'importFile'
} else {
} else {
tabsActiveName.value = uploadSetting.value?.type || 'standard'
}
//getDictList()
setUploadInfo()
})
......@@ -660,8 +660,10 @@ onActivated(() => {
<Tabs v-if="!isfileImport" :tabs-info="tabsInfo" @tabChange="tabsChange" />
<div class="table_tool_wrap">
<div class="tools_btns">
<el-button type="primary" @click="batching('import')" v-if="tabsActiveName !== 'importFile'" v-preReClick>批量导入</el-button>
<el-button type="primary" @click="batching('importFile')" v-if="tabsActiveName == 'importFile'" v-preReClick>文件导入</el-button>
<el-button type="primary" @click="batching('import')" v-if="tabsActiveName !== 'importFile'"
v-preReClick>批量导入</el-button>
<el-button type="primary" @click="batching('importFile')" v-if="tabsActiveName == 'importFile'"
v-preReClick>文件导入</el-button>
<el-button @click="batching('delete')" v-preReClick>批量删除</el-button>
<el-button @click="getFirstPageData" v-preReClick>刷新结果</el-button>
</div>
......@@ -736,4 +738,4 @@ onActivated(() => {
height: calc(100% - 71px);
}
}
</style>
\ No newline at end of file
</style>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!