24ba6db6 by lihua

去掉不用的图片等

1 parent 8a799ac8
Showing 154 changed files with 579 additions and 9711 deletions
......@@ -570,3 +570,10 @@ export const getTransactionDetail = (params) => request({
export const getDictAllList = () => request({
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-all`
})
// 数据字典树形数据
export const getDictionaryTree = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/tree-list`,
method: 'post',
params
})
\ No newline at end of file
......
/** --------------------- 质量评估模型 ------------------------------- */
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 getRegiaterDetail = (params) => request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/detail`,
method: 'get',
params
})
/** 获取产品登记详情 */
export const getRegisterCatalogDetail = (damGuid) => request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/detail-by-dam-guid?damGuid=${damGuid}`,
method: 'get'
})
/** 提交登记信息。 */
export const registerSave = (params) => request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/save`,
method: 'post',
data: params
});
/** 更新登记信息 */
export const registerUpdate = (params) => request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/update`,
method: 'post',
data: params
});
/** 删除登记信息 */
export const registerDelete = (params) => request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/public-data-products-main/delete`,
method: 'delete',
data: params
});
/** 获取可使用的资产目录列表 */
export const getRegisterCatalogList = () => request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/dam-catalog-table/public-data/dam-list?isRegister=${'Y'}&foundMode=4`,
method: 'get'
})
import request from "@/utils/request";
//获取需求表树形列表
export const getDemandTreeList = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/page-list`,
method: "post",
data: params,
});
};
//获取所有需求表列表
export const getDemandAll = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/get-list-data`,
method: "get",
params
});
};
//新增需求列表
export const saveDemandTree = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/save`,
method: "post",
data: params,
});
};
//修改需求列表
export const updateDemandTree = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/update`,
method: "post",
data: params,
});
};
// 删除需求列表
export const deleteDemandTree = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-menu/delete`,
method: "delete",
data: params,
});
};
//获取需求表
export const getDemandList = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/page-list`,
method: "post",
data: params,
});
};
//获取需求表详情
export const getDemandDetail = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/detail`,
method: "get",
params,
});
};
//新增需求表
export const saveDemand = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/save`,
method: "post",
data: params,
});
};
//修改需求表
export const updateDemand = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/update`,
method: "post",
data: params,
});
};
// 删除需求表
export const deleteDemand = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-demand-table/delete`,
method: "delete",
data: params,
});
};
// 获取疾病列表
export const getDiseaseList = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/page-list`,
method: "post",
data: params,
});
};
//获取所有疾病列表
export const getDiseaseAll = () => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/get-list-data`,
method: "post"
});
};
// 获取疾病详情
export const getDiseaseDetail = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/detail`,
method: "get",
params,
});
};
// 新增疾病
export const saveDisease = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/save`,
method: "post",
data: params,
});
};
// 修改疾病
export const updateDisease = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/update`,
method: "post",
data: params,
});
};
// 删除疾病
export const deleteDisease = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/disease-manage/delete`,
method: "delete",
data: params,
});
};
// 获取定价配置
export const getConfigureList = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/page-list`,
method: "post",
data: params,
});
};
// 获取配置详情
export const getConfigureDetail = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/detail`,
method: "get",
params,
});
};
// 新增配置
export const saveConfigure = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/save`,
method: "post",
data: params,
});
};
// 修改配置
export const updateConfigure = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/update`,
method: "post",
data: params,
});
};
// 删除配置
export const deleteConfigure = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/delete`,
method: "delete",
data: params,
});
};
// 复制配置
export const addCopyConfigure = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-configure/copy`,
method: "post",
data: params,
});
};
// 获取数据定价
export const getPriceList = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/page-list`,
method: "post",
data: params,
});
};
// 获取数据定价详情
export const getPriceDetail = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/detail`,
method: "get",
params,
});
};
// 新增数据定价
export const savePrice = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/save`,
method: "post",
data: params,
});
};
// 修改数据定价
export const updatePrice = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/update`,
method: "post",
data: params,
});
};
// 获取数据定价结果
export const getPriceResult = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/pricing-price`,
method: "post",
data: params,
});
};
// 计算数据定价
export const calculatPrice = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/calculate-price`,
method: "post",
data: params,
});
};
// 删除数据定价
export const deletePrice = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/delete`,
method: "delete",
data: params,
});
};
// 获取数据资源目录
export const getDamCatalogList = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/dam-catalog-table/get-table-select-new`,
method: "get",
params,
});
};
// 获取模型相关需求表
export const getModelDemand = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/pricing-model`,
method: "get",
params,
});
};
// 获取质量模型评分
export const getModelScore = (params) => {
return request({
url: `${import.meta.env.VITE_APP_QUALITY_BASEURL}/quality-analysis-report/get-quality-score-by-dam-guid-v2`,
method: "get",
params,
});
};
export const exportModelScore = (params) => {
return request({
url: `${import.meta.env.VITE_API_NEW_PORTAL}/pricing-data/download-template`,
method: "post",
data: params,
responseType: 'blob'
});
};
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h341.333333v341.333333H0zM0 682.666667h341.333333v341.333333H0zM682.666667 0h341.333333v341.333333H682.666667zM682.666667 682.666667h341.333333v341.333333H682.666667z" fill="#ffffff" p-id="882"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h341.333333v341.333333H0zM0 682.666667h341.333333v341.333333H0zM682.666667 0h341.333333v341.333333H682.666667zM682.666667 682.666667h341.333333v341.333333H682.666667z" fill="#b2b2b2" p-id="882"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h1024v146.261H0z m0 438.87h1024v146.26H0z m0 438.869h1024V1024H0z" p-id="896" fill="#ffffff"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M0 0h1024v146.261H0z m0 438.87h1024v146.26H0z m0 438.869h1024V1024H0z" p-id="896" fill="#b2b2b2"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path fill="#DCA54F" d="m136.533 273.067 669.048 422.058c10.65 6.725 15.838 20.48 12.697 33.588-3.106 13.073-13.824 22.186-26.077 22.22H238.42c-27.306 0-50.346-22.425-53.726-52.326l-48.162-425.54z"/><path fill="#DCA54F" d="M834.219 698.607c-3.345 29.9-26.385 52.326-53.692 52.326H245.794c-12.288 0-41.984-9.113-45.124-22.186-3.175-13.073 2.048-26.863 12.697-33.588l668.98-422.092-48.128 425.506z"/><path fill="#E7B15C" d="m512 170.667 298.428 490.598a61.44 61.44 0 0 1 2.184 59.324c-9.489 18.705-27.818 30.344-47.718 30.344H512V170.667z"/><path fill="#F2D59C" d="M512 170.667 196.062 666.01a61.44 61.44 0 0 0-2.185 59.323c9.49 18.705 27.341 25.6 47.24 25.6H512V170.667z"/><path fill="#E7B15C" d="M459.776 153.327c0 18.193 9.967 34.987 26.112 44.1a53.35 53.35 0 0 0 52.224 0c16.145-9.113 26.112-25.941 26.112-44.1 0-28.126-23.381-50.927-52.224-50.927s-52.224 22.801-52.224 50.927zM851.319 255.18c-.41 18.432 9.455 35.67 25.771 45.022 16.316 9.318 36.523 9.318 52.873 0 16.315-9.353 26.18-26.59 25.77-45.056-.614-27.648-23.825-49.8-52.224-49.8-28.364 0-51.541 22.152-52.19 49.834zm-783.018 0c-.444 18.432 9.42 35.67 25.736 45.022 16.316 9.318 36.523 9.318 52.873 0 16.316-9.353 26.18-26.59 25.77-45.056-.614-27.648-23.825-49.8-52.223-49.8-28.365 0-51.542 22.152-52.19 49.834z"/><path fill="#DCA54F" d="M238.933 819.2h546.134q34.133 0 34.133 34.133 0 34.134-34.133 34.134H238.933q-34.133 0-34.133-34.134 0-34.133 34.133-34.133z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M512 85.333c235.648 0 426.667 191.019 426.667 426.667S747.648 938.667 512 938.667 85.333 747.648 85.333 512 276.352 85.333 512 85.333zm0 85.334a341.333 341.333 0 1 0 0 682.666 341.333 341.333 0 0 0 0-682.666zm0 298.666c85.333 0 156.459 14.208 213.333 42.667a213.333 213.333 0 0 1-426.666 0c56.874-28.459 128-42.667 213.333-42.667zM362.667 298.667A106.667 106.667 0 0 1 467.2 384H258.133a106.667 106.667 0 0 1 104.534-85.333zm298.666 0A106.667 106.667 0 0 1 765.867 384H556.8a106.667 106.667 0 0 1 104.533-85.333z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M512 938.667C276.352 938.667 85.333 747.648 85.333 512S276.352 85.333 512 85.333 938.667 276.352 938.667 512 747.648 938.667 512 938.667zm0-85.334a341.333 341.333 0 1 0 0-682.666 341.333 341.333 0 0 0 0 682.666zM341.333 554.667h341.334a170.667 170.667 0 1 1-341.334 0zm0-85.334a64 64 0 1 1 0-128 64 64 0 0 1 0 128zm341.334 0a64 64 0 1 1 0-128 64 64 0 0 1 0 128z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M512 938.667C276.352 938.667 85.333 747.648 85.333 512S276.352 85.333 512 85.333 938.667 276.352 938.667 512 747.648 938.667 512 938.667zm0-85.334a341.333 341.333 0 1 0 0-682.666 341.333 341.333 0 0 0 0 682.666zm-213.333-128a213.333 213.333 0 0 1 426.666 0H640a128 128 0 0 0-256 0h-85.333zm42.666-256a64 64 0 1 1 0-128 64 64 0 0 1 0 128zm341.334 0a64 64 0 1 1 0-128 64 64 0 0 1 0 128z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M704 328a72 72 0 1 0 144 0 72 72 0 1 0-144 0z"/><path d="M999.904 116.608a32 32 0 0 0-21.952-10.912L521.76 73.792a31.552 31.552 0 0 0-27.2 11.904l-92.192 114.848a32 32 0 0 0 .672 40.896l146.144 169.952-147.456 194.656 36.48-173.376a32 32 0 0 0-11.136-31.424L235.616 245.504l79.616-125.696a32 32 0 0 0-29.28-49.024L45.76 87.552a32 32 0 0 0-29.696 34.176l55.808 798.016a32.064 32.064 0 0 0 34.304 29.696l176.512-13.184c17.632-1.312 30.848-16.672 29.504-34.272s-16.576-31.04-34.304-29.536L133.44 883.232l-6.432-92.512 125.312-12.576a32 32 0 0 0 28.672-35.04 32.16 32.16 0 0 0-35.04-28.672L122.56 726.848 82.144 149.184l145.152-10.144-60.96 96.224a32 32 0 0 0 6.848 41.952l198.4 161.344-58.752 279.296a30.912 30.912 0 0 0 .736 14.752 31.68 31.68 0 0 0 1.408 11.04l51.52 154.56a31.968 31.968 0 0 0 27.456 21.76l523.104 47.552a32.064 32.064 0 0 0 34.848-29.632l55.776-798.048a32.064 32.064 0 0 0-7.776-23.232zm-98.912 630.848-412.576-39.648a31.52 31.52 0 0 0-34.912 28.768 32 32 0 0 0 28.8 34.912l414.24 39.808-6.272 89.536-469.728-42.72-39.584-118.72 234.816-310.016a31.936 31.936 0 0 0-1.248-40.192L468.896 219.84l65.088-81.056 407.584 28.48-40.576 580.192z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M165.415 827.077c-11.815 0-19.692-7.877-19.692-19.692V214.646c0-11.815 7.877-19.692 19.692-19.692h159.508c7.877 0 17.723 3.938 23.63 9.846l228.432 287.508c7.877 9.846 7.877 25.6 0 37.415l-230.4 287.508c-5.908 7.877-15.754 11.815-25.6 11.815l-155.57-1.97zm706.954-334.77L641.97 206.77c-9.846-11.815-27.569-15.754-41.354-3.938l-45.292 37.415c-13.785 9.846-15.754 29.539-3.938 41.354L738.462 512 551.385 744.37c-9.847 11.815-7.877 31.507 3.938 41.353l45.292 37.415c13.785 9.847 29.539 7.877 41.354-3.938l230.4-287.508c7.877-15.754 7.877-29.538 0-39.384z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M914.5 653.5c-5.5 0-11 1.1-16 3.3l-.2.1h-.2L510.2 822.2 122.2 657h-.2l-.2-.1c-5-2.1-10.3-3.3-16-3.3-23.1 0-41.8 19.3-41.8 43.1 0 18 10.7 33.3 25.8 39.8l403.9 172.1.4.1c10.2 4.4 21.8 4.4 32 0l.2-.1c.1 0 .1-.1.2-.1l403.9-172.1c15.1-6.5 25.8-21.8 25.8-39.8.1-23.8-18.6-43.1-41.7-43.1zm0-186.5c-7.9-.2-16 3.2-16 3.2L510.2 635.6 121.8 470.2s-10.3-3.2-16-3.2C82.7 467 64 486.2 64 510c0 17.9 10.7 33.3 25.8 39.7l403.9 172c.1 0 .1.1.2.1l.1.1c5 2.1 10.3 3.3 16 3.3 5.7 0 11.1-1.2 16-3.3l.2-.1c.1 0 .1 0 .2-.1l403.9-172c15.1-6.4 25.8-21.8 25.9-39.7.1-23.8-18.6-43-41.7-43zM89.8 363.2l403.9 172.1c.1 0 .1 0 .2.1l.1.1c5 2.1 10.3 3.2 16 3.2 5.5 0 10.9-1.1 16-3.2l.2-.1.2-.1 403.9-172c15.1-6.5 25.8-21.8 25.9-39.7 0-18-10.7-33.3-25.8-39.8L526.5 111.6c-.1 0-.1 0-.2-.1l-.2-.1c-10.2-4.4-21.8-4.4-32 0l-.1.1L89.8 283.7C74.7 290.1 64 305.5 64 323.5c0 17.9 10.7 33.2 25.8 39.7z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="232.422" height="200" class="icon" viewBox="0 0 1190 1024"><path d="M610.533 122.802A890.76 890.76 0 0 1 668.74 51.22a140.855 140.855 0 0 1 212.38 0q132.528 132.014 263.63 265.454a143.25 143.25 0 0 1 1.083 209.243q-223.76 227.667-449.972 452.88a140.484 140.484 0 0 1-205.592-.57Q266.309 755.61 45.374 530.11a142.595 142.595 0 0 1 1.14-209.272q135.18-139.087 273.297-275.18a142.595 142.595 0 0 1 210.698 2.453c22.473 22.416 41.523 48.311 62.114 72.61zm-66.906 55.812c-28.975-24.669-53.415-45.117-77.428-66.05a57.038 57.038 0 0 0-85.3 1.283q-133.897 133.07-266.053 267.85c-30.715 31.37-29.717 57.038.427 90.148 13.09 14.26 27.265 27.72 40.954 41.552L540.86 900.542c30.972 31.114 59.89 36.19 87.61 15.999 15.6-11.408 30.715-23.414 46.058-35.164l1.227-17.111c-25.154-21.333-51.334-41.467-75.12-64.31-28.147-27.15-29.63-49.48-8.555-71.298s44.832-20.619 71.297 6.417c23.072 23.642 43.492 49.88 70.214 80.908l51.733-57.58c-28.946-26.58-57.038-49.822-82.106-76.088s-19.963-61.972 12.663-72.181a69.615 69.615 0 0 1 54.015 13.033 770.98 770.98 0 0 1 72.666 69.928l95.167-93.742-234.796-236.421c-8.556 7.985-20.762 19.706-33.196 31.37a179.27 179.27 0 0 1-221.079 18.196c-55.982-37.503-60.488-79.197-13.118-126.995 32.768-33.054 66.22-65.594 108.172-106.86zM511.43 342.94a93.029 93.029 0 0 0 101.498-21.104c16.541-17.368 33.624-34.223 50.793-51.049 34.907-34.223 54.186-34.223 89.406 1.112q115.131 115.302 229.777 231.003c8.556 8.699 17.739 16.912 34.68 33.025 19.364-23.014 36.19-44.575 54.699-64.538 35.62-38.472 36.019-62-1.512-99.987Q948.938 248.2 826.592 125.569c-39.67-39.756-64.082-39.756-104.151.285q-94.626 94.54-188.538 189.85c-6.788 6.73-12.406 14.859-22.473 27.122z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M487 71.425a75 75 0 0 1 72.575 0l335.7 185.5a75 75 0 0 1 38.75 65.65V690.85a75 75 0 0 1-38.75 65.625l-335.7 185.55a75 75 0 0 1-72.55 0l-335.7-185.5a75 75 0 0 1-38.75-65.675V322.6a75 75 0 0 1 38.75-65.6L487 71.4v.025zM859 322.6 523.275 137.1l-335.7 185.5v368.25l335.7 185.5 335.75-185.5V322.6zm-601.75 37.1A37.5 37.5 0 0 1 308.2 345l215.1 118.875L738.45 345a37.5 37.5 0 0 1 36.25 65.625l-213.9 118.25V764.55a37.5 37.5 0 0 1-75 0v-235.7l-213.9-118.2a37.5 37.5 0 0 1-14.65-51v.05z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200.195" height="200" class="icon" viewBox="0 0 1025 1024"><path d="M960.13 661.73c45.18-217.23-72.82-435.39-279.35-516.48C668.79 62.35 597.7.84 513.93.9 430.17.85 359.09 62.35 347.11 145.25 172.89 213.66 58.28 381.73 58.23 568.91c0 23.86 3.21 54.82 9.53 92.77-39.81 30.79-65.38 78.96-65.38 133.1.02 44.67 17.8 87.5 49.4 119.07a168.43 168.43 0 0 0 119.13 49.27c29.77 0 57.76-7.68 81.95-21.16a454.28 454.28 0 0 0 261.08 82.03c93.38.16 184.54-28.51 261.03-82.08 24.28 13.49 52.23 21.25 81.99 21.25 44.67.03 87.52-17.7 119.13-49.27a168.394 168.394 0 0 0 49.4-119.08 167.91 167.91 0 0 0-65.36-133.08zM512.67 74c51.95 0 94.06 42.1 94.06 93.93.03 51.92-42.03 94.03-93.94 94.07-51.92.03-94.03-42.03-94.06-93.94-.04-51.92 42.02-94.04 93.94-94.06zM171.59 884.57c-51.92.03-94.03-42.03-94.06-93.94-.04-51.92 42.02-94.03 93.94-94.06 51.95 0 94.06 42.1 94.06 93.93.03 51.93-42.03 94.04-93.94 94.07zm536.95-9.94c-57.43 36.55-124.44 56.51-194.61 56.51a360.66 360.66 0 0 1-194.58-56.56 167.297 167.297 0 0 0 20.09-79.75c0-92.97-77.1-175.32-183.55-167.6 0 0-5.72-35.81-4.65-58.32.04-141.03 81.92-269.23 209.87-328.56 27.74 59.34 87.32 97.24 152.82 97.2 66.03 0 123.14-36.47 152.76-97.29 127.98 59.35 209.89 187.58 209.92 328.65 0 19.71-4.74 58.32-4.74 58.32-104.78-9.35-183.46 74.59-183.46 167.6a167.3 167.3 0 0 0 20.13 79.8zm144.05 9.94c-51.92.03-94.03-42.03-94.06-93.94-.04-51.92 42.02-94.03 93.94-94.06 51.95 0 94.06 42.1 94.06 93.93.03 51.93-42.03 94.04-93.94 94.07z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M804.571 530.286v182.857q0 68-48.285 116.286T640 877.714H164.571q-68 0-116.285-48.285T0 713.143V237.714q0-68 48.286-116.285T164.57 73.143h402.286q8 0 13.143 5.143t5.143 13.143V128q0 8-5.143 13.143t-13.143 5.143H164.571q-37.714 0-64.571 26.857t-26.857 64.571v475.429q0 37.714 26.857 64.571t64.571 26.857H640q37.714 0 64.571-26.857t26.858-64.571V530.286q0-8 5.142-13.143T749.714 512h36.572q8 0 13.143 5.143t5.142 13.143zM1024 36.57v292.572q0 14.857-10.857 25.714t-25.714 10.857-25.715-10.857l-100.571-100.57L488.57 626.857q-5.714 5.714-13.142 5.714t-13.143-5.714l-65.143-65.143q-5.714-5.714-5.714-13.143t5.714-13.142l372.571-372.572-100.57-100.571q-10.857-10.857-10.857-25.715t10.857-25.714T694.857 0H987.43q14.857 0 25.714 10.857T1024 36.571z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="m878.6 246.4-328-196.6c-3-1.6-6-3.2-9-4.4-3.2-1.2-6.4-2.4-9.6-3.2-3.2-.8-6.6-1.6-10-2-3.4-.4-6.8-.6-10-.6-3.4 0-6.8.2-10 .6-3.4.4-6.6 1-10 2-3.2.8-6.4 2-9.6 3.2-3.2 1.2-6.2 2.8-9 4.4l-328 196.6c-3 1.8-5.8 3.8-8.4 6s-5.2 4.4-7.6 7c-2.4 2.4-4.6 5.2-6.6 7.8-2 2.8-4 5.6-5.6 8.6-1.6 3-3.2 6.2-4.4 9.4-1.2 3.2-2.4 6.4-3.2 9.8-.8 3.4-1.4 6.8-2 10.2-.4 3.4-.6 6.8-.6 10.4v392.8c0 3.4.2 6.8.6 10.4.4 3.4 1 6.8 2 10.2.8 3.4 2 6.6 3.2 9.8 1.2 3.2 2.8 6.4 4.4 9.4 1.6 3 3.6 6 5.6 8.6 2 2.8 4.2 5.4 6.6 8 2.4 2.4 5 4.8 7.6 7 2.6 2.2 5.6 4.2 8.4 6l86 51.4.4.2c43.4 22.2 60 22.2 79.2 22.2 67.8 0 110-43.8 110-114.6V355.8c0-1.2 0-2.4-.4-3.4s-.6-2.2-1-3.4c-.4-1-1-2.2-1.6-3.2-.6-1-1.4-1.8-2.2-2.8-.8-.8-1.8-1.6-2.6-2.2s-2-1.2-3-1.6c-1-.4-2.2-.8-3.4-1-1.2-.2-2.4-.4-3.4-.4h-47.2c-1.2 0-2.4.2-3.4.4-1.2.2-2.2.6-3.4 1-1 .4-2.2 1-3 1.6-1 .6-1.8 1.4-2.6 2.2-.8.8-1.6 1.8-2.2 2.8-.6 1-1.2 2-1.6 3.2-.4 1-.8 2.2-1 3.4s-.4 2.4-.4 3.4v380.8c0 2.8-.2 5.4-.8 8-.6 2.6-1.6 5.2-2.8 7.6-1.2 2.4-2.8 4.6-4.6 6.6-1.8 2-4 3.8-6.2 5.2-12.4 7.6-30.6 6-51-4.6L190.6 710c-.6-.4-1-1.2-1-2V321c0-1 .4-1.8 1.2-2.2L511 122.6c.6-.2 1-.2 1.6 0L833 318.8c.8.6 1.2 1.4 1.2 2.4v387c0 .8-.2 1.6-1 2.2L512.4 901.6c-.6.2-1.2.2-1.6 0l-82-48.6c-1.2-.8-2.6-1.4-3.8-1.8-1.4-.4-2.8-.8-4.2-.8-1.4 0-2.8 0-4.4.4-1.4.4-2.8.8-4 1.4l-.8.4C389 866 383 869.4 362 877.2c-3.4 1.2-11.4 4.2-12.2 12.2s7 13.6 13.8 17.6L473 974.2c5.8 3.4 12 6.2 18.6 8 6.6 1.8 13.2 2.8 20 2.8h1.2c6.6-.2 13.2-1 19.6-2.8 6.4-1.8 12.4-4.4 18.2-7.8L878.4 778c3-1.8 5.8-3.8 8.4-6 2.6-2.2 5.2-4.6 7.6-7 2.4-2.4 4.6-5.2 6.6-8s4-5.6 5.6-8.8 3.2-6.2 4.4-9.4c1.2-3.2 2.4-6.4 3.2-9.8.8-3.4 1.6-6.8 2-10.2.4-3.4.6-6.8.6-10.4v-393c0-3.4-.2-6.8-.6-10.4-.4-3.4-1-6.8-2-10.2-.8-3.4-2-6.6-3.2-9.8s-2.8-6.4-4.4-9.4c-1.6-3-3.6-6-5.6-8.6-2-2.8-4.2-5.4-6.6-7.8-2.4-2.4-5-4.8-7.6-7-2.6-2-5.4-4-8.2-5.8z"/><path d="M621.4 642.8c-78.6 0-95.4-22-100.4-57.4l-.6-3-1.2-3c-.4-1-1-1.8-1.8-2.6-.6-.8-1.4-1.6-2.2-2.4-.8-.8-1.6-1.4-2.6-1.8-1-.6-1.8-1-2.8-1.4-1-.4-2-.6-3-.8-1-.2-2-.4-3.2-.4H462c-1.2 0-2.4.2-3.4.4-1.2.2-2.2.6-3.4 1-1 .4-2 1-3 1.8-1 .6-1.8 1.4-2.6 2.2-.8.8-1.6 1.8-2.2 2.8-.6 1-1.2 2-1.6 3-.4 1-.8 2.2-1 3.4-.2 1.2-.4 2.4-.2 3.4 0 30.8 10.8 131.2 177 131.2 51.4 0 94.2-12 123.6-34.8 29.4-22.8 45.2-55.8 45.2-95.4 0-79.2-51.6-100.8-153.4-115-103.4-14.4-103.4-21.8-103.4-37.8 0-11.6 0-38.6 74.8-38.6 53.2 0 81.8 6.8 90.8 42.2.2 1 .4 2 .8 2.8.4 1 .8 1.8 1.4 2.6.6.8 1 1.6 1.8 2.4.6.8 1.4 1.4 2.2 2 .8.6 1.6 1.2 2.4 1.6.8.4 1.8 1 2.6 1.2 1 .4 1.8.6 2.8.8s2 .2 3 .2h42c2.4 0 4.8-.6 7.2-1.6 2.2-1 4.2-2.6 5.8-4.4 1.6-1.8 2.8-4 3.6-6.4.8-2.4 1-4.8.8-7.2-5.4-75-60.2-113-167.2-113-97.2 0-155.2 43.8-155.2 117 0 80.4 60 103 150.4 112.4C709 561.2 709 577 709 591c.2 22.6-9 51.8-87.6 51.8z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M440.064 761.856A319.36 319.36 0 0 1 320 512a319.36 319.36 0 0 1 120.064-249.856 256 256 0 1 0 0 499.712zM512 218.624a320 320 0 1 1 0 586.752 320 320 0 1 1 0-586.752zm63.168 376.96L469.76 497.6l-43.52 46.848 150.592 139.968 277.76-277.76-45.248-45.312-234.176 234.24z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M600.874667 128H85.333333v760.021333h472.704v-58.453333H144.426667V186.453333h384.256v207.36h206.890666V426.666667l-0.128 168.490666h59.136L794.666667 426.666667V347.434667L600.874667 128z m-13.098667 73.984l117.76 133.376h-117.76V201.984z" fill="#727272" p-id="1060"></path><path d="M338.688 432h304v50.688H338.602667v-50.688z m0 253.354667h304v50.645333H338.602667v-50.688z m0-126.72h304v50.688H338.602667v-50.645334z" fill="#B2B2B2" p-id="1061"></path><path d="M784.512 938.666667h-55.722667v-111.488H617.386667v-55.722667h111.445333V660.053333h55.722667v111.445334H896v55.722666h-111.488z" fill="#44ABB4" p-id="1062"></path><path d="M186.666667 229.333333h228.010666v75.989334H186.666667V229.333333z m0 173.525334h75.989333v333.141333H186.666667V402.858667z" fill="#0098E6" p-id="1063" /></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M582.485333 128H85.333333v760.021333h455.808v-58.453333H142.336V186.453333h370.517333v207.36h199.466667V426.666667l-0.085333 168.490666h57.002666L769.322667 426.666667V347.434667L582.442667 128z m-12.672 73.984l113.578667 133.376h-113.578667V201.984z" fill="#727272" p-id="920"></path><path d="M212.010667 305.322667h177.322666v50.688H212.010667z" fill="#0098E6" p-id="921"></path><path d="M262.656 457.344h380.032v56.746667H262.613333v-56.746667z m0 171.221333h379.904v56.746667H262.656v-56.746667z" fill="#B2B2B2" p-id="922"></path><path d="M784.512 771.456V660.053333h-55.722667v111.445334H617.386667v55.722666h111.445333V938.666667h55.722667v-111.488H896v-55.722667z" fill="#44ABB4" p-id="923" /></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" class="icon" viewBox="0 0 1024 1024"><path d="M256 213.333333h426.666667v85.333334H256z" fill="#5280C1" p-id="971"></path><path d="M256 426.666667h426.666667v42.666666H256v-42.666666z m0 128h298.666667v42.666666H256v-42.666666z m0 128h256v42.666666H256v-42.666666z" fill="#B2B2B2" p-id="972"></path><path d="M938.666667 636.970667L813.056 512 682.666667 636.970667v93.696l90.666666-62.250667V938.666667h79.445334v-270.250667L938.666667 730.709333z" fill="#5280C1" p-id="973"></path><path d="M629.205333 875.050667H128V85.333333h725.333333v373.802667h-60.416V146.346667H188.416V814.08h440.746667z" fill="#727272" p-id="974" /></svg>
\ No newline at end of file
......@@ -353,521 +353,5 @@ const routes: RouteRecordRaw[] = [
}
],
},
// {
// path: '/data-asset/register-managemant',
// component: Layout,
// meta: {
// title: '数据登记管理',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'registerManagemant',
// component: () => import('@/views/data_asset/registerManagemant.vue'),
// meta: {
// title: '数据登记管理',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'register-start',
// name: 'registerStart',
// component: () => import('@/views/data_asset/registerStart.vue'),
// meta: {
// title: '新建资产登记',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// editPage: true,
// reuse: true
// },
// beforeEnter: (to, from) => {
// if (to.query.type) {
// to.meta.title = `详情-`;
// return;
// }
// if (to.query.guid) {
// to.meta.title = `编辑-`;
// to.meta.editPage = true;
// }
// }
// },
// {
// path: 'register-detail',
// name: 'registerInfoDetail',
// component: () => import('@/views/data_asset/registerDetail.vue'),
// meta: {
// title: '详情-',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// }
// }
// ],
// },
// {
// path: '/data-asset/quality-evaluate',
// component: Layout,
// meta: {
// title: '资产质量评价管理',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'qualityEvaluate',
// component: () => import('@/views/data_asset/qualityEvaluate.vue'),
// meta: {
// title: '资产质量评价管理',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'register-detail',
// name: 'registerDetail',
// component: () => import('@/views/data_asset/registerDetail.vue'),
// meta: {
// title: '详情-',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// }
// }
// ],
// },
// {
// path: '/data-asset/quality-assess',
// component: Layout,
// meta: {
// title: '质量评估模型',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'damQualityAssess',
// component: () => import('@/views/data_asset/damQualityAssess.vue'),
// meta: {
// title: '质量评估模型',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'dam-quality-plan',
// name: 'damQualityPlan',
// component: () => import('@/views/data_asset/damQualityPlan.vue'),
// meta: {
// title: '新建质量评估',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// editPage: true,
// reuse: true
// },
// beforeEnter: (to, from) => {
// if (to.query.guid) {
// to.meta.title = `编辑-${to.query.damName}`;
// to.meta.editPage = true;
// }
// }
// },
// {
// path: 'dam-assess-log',
// name: 'damQualityAssessLog',
// component: () => import('@/views/data_asset/damQualityAssessLog.vue'),
// meta: {
// title: '执行日志',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// },
// beforeEnter: (to, from) => {
// if (to.query.guid) {
// to.meta.title = `日志-${to.query.name}`;
// }
// }
// },
// {
// path: 'dam-assess-detail',
// name: 'damAssessDetail',
// component: () => import('@/views/data_asset/damAssessDetail.vue'),
// meta: {
// title: '查看结果',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// },
// beforeEnter: (to, from) => {
// if (to.query.name) {
// to.meta.title = `查看结果-${to.query.name}`;
// }
// }
// },
// {
// path: 'dam-analysis-report',
// name: 'damAnalysisReport',
// component: () => import('@/views/data_asset/damAnalysisReport.vue'),
// meta: {
// title: '分析报告',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// },
// beforeEnter: (to, from) => {
// if (to.query.name) {
// to.meta.title = `分析报告-${to.query.name}`;
// }
// }
// },
// ],
// },
// {
// path: '/data-asset/value-evaluate',
// component: Layout,
// meta: {
// title: '资产价值评估管理',
// icon: 'ep:grid',
// },
// children: [
// {
// path: '',
// name: 'valueEvaluate',
// component: () => import('@/views/data_asset/valueEvaluate.vue'),
// meta: {
// title: '资产价值评估管理',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'register-detail',
// name: 'registerValueDetail',
// component: () => import('@/views/data_asset/registerDetail.vue'),
// meta: {
// title: '详情-',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// }
// }
// ],
// },
// {
// path: '/data-asset/certificate-management',
// component: Layout,
// meta: {
// title: '资产证件管理',
// icon: 'ep:grid',
// },
// children: [
// {
// path: '',
// name: 'certificateManagement',
// component: () => import('@/views/data_asset/certificateManagement.vue'),
// meta: {
// title: '资产证件管理',
// sidebar: false,
// cache: true,
// breadcrumb: false,
// },
// },
// {
// path: 'register-detail',
// name: 'certificateDetail',
// component: () => import('@/views/data_asset/registerDetail.vue'),
// meta: {
// title: '详情-',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true
// }
// }
// ],
// },
// {
// path: '/data-asset/objection-handle',
// component: Layout,
// meta: {
// title: '公示异议处理',
// icon: 'ep:grid',
// },
// children: [
// {
// path: '',
// name: 'damObjectionHandle',
// component: () => import('@/views/data_asset/damObjectionHandle.vue'),
// meta: {
// title: '公示异议处理',
// sidebar: false,
// cache: true,
// breadcrumb: false,
// },
// },
// ]
// },
// {
// path: '/data-entry/entry-consult',
// component: Layout,
// meta: {
// title: '入表咨询',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'entryConsult',
// component: () => import('@/views/data_entry/index.vue'),
// meta: {
// title: '入表咨询',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// ],
// },
// {
// path: '/data-entry/entry-management',
// component: Layout,
// meta: {
// title: '入表管理',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'entryManagement',
// component: () => import('@/views/data_transaction/entryManagement.vue'),
// meta: {
// title: '入表管理',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// ],
// },
// {
// path: '/data-product/product-listing',
// component: Layout,
// meta: {
// title: '数据产品上架',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'productListing',
// component: () => import('@/views/data_product/productListing.vue'),
// meta: {
// title: '数据产品上架',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'listing-detail',
// name: 'productListingDetail',
// component: () => import('@/views/data_product/productListingDetail.vue'),
// meta: {
// title: '新建数据产品',
// sidebar: false,
// reuse: true,
// breadcrumb: false,
// cache: true
// },
// beforeEnter: (to, from) => {
// if(to.query.type){
// if (to.query.type == 'detail') {
// to.meta.title = `详情-${to.query.name}`;
// } else {
// to.meta.editPage = true;
// to.meta.title = to.query.type=='add'? '新建数据产品': to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
// }
// }
// }
// },
// ],
// },
// {
// path: '/data-product/listing-check',
// component: Layout,
// meta: {
// title: '数据产品审核',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'productListingCheck',
// component: () => import('@/views/data_product/productListingCheck.vue'),
// meta: {
// title: '数据产品审核',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// },
// },
// {
// path: 'listing-detail',
// name: 'productListingCheckDetail',
// component: () => import('@/views/data_product/productListingDetail.vue'),
// meta: {
// title: '产品审核详情',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true,
// },
// beforeEnter: (to, from) => {
// if (to.query.type == 'check') {
// to.meta.editPage = true;
// to.meta.title = `详情-${to.query.name}`;
// return;
// }
// }
// },
// ],
// },
// {
// path: '/data-product/demands-publish',
// component: Layout,
// meta: {
// title: '数据需求发布',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'productDemandsPublish',
// component: () => import('@/views/data_product/productDemandsPublish.vue'),
// meta: {
// title: '数据需求发布',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'demands-detail',
// name: 'productDemandsDetail',
// component: () => import('@/views/data_product/productDemandsDetail.vue'),
// meta: {
// title: '新建数据需求',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true,
// },
// beforeEnter: (to, from) => {
// if(to.query.type){
// if (to.query.type == 'detail') {
// to.meta.title = `详情-${to.query.name}`;
// } else {
// to.meta.editPage = true;
// to.meta.title = to.query.type=='add'? `新建数据需求${to.query.interfaceType == '2' ? '(算法竞赛)' : (to.query.interfaceType == '3' ? '(要素市场)' : '')}`: to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
// }
// }
// }
// },
// ],
// },
// {
// path: '/data-product/demands-check',
// component: Layout,
// meta: {
// title: '数据需求审核',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'productDemandsCheck',
// component: () => import('@/views/data_product/productDemandsCheck.vue'),
// meta: {
// title: '数据需求审核',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// {
// path: 'demands-detail',
// name: 'productDemandsCheckDetail',
// component: () => import('@/views/data_product/productDemandsDetail.vue'),
// meta: {
// title: '需求审核详情',
// sidebar: false,
// breadcrumb: false,
// cache: true,
// reuse: true,
// },
// beforeEnter: (to, from) => {
// if (to.query.type == 'check') {
// to.meta.editPage = true;
// to.meta.title = `详情-${to.query.name}`;
// }
// }
// },
// ],
// },
// {
// path: '/data-guide/transaction-finance',
// component: Layout,
// meta: {
// title: '交易融资指南',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'transactionFinanceGuid',
// component: () => import('@/views/data_transaction/transactionFinanceGuide.vue'),
// meta: {
// title: '交易融资指南',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// ],
// },
{
path: '/data-product/transaction-management',
component: Layout,
meta: {
title: '资产交易管理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'transactionManagement',
component: () => import('@/views/data_transaction/transactionManagement.vue'),
meta: {
title: '资产交易管理',
sidebar: false,
breadcrumb: false,
cache: true
},
},
],
},
]
export default routes
......
......@@ -254,27 +254,6 @@ const routes: RouteRecordRaw[] = [
],
},
{
path: '/data-asset-register/objection-handle',
component: Layout,
meta: {
title: '公示异议处理',
icon: 'ep:grid',
},
children: [
{
path: '',
name: 'damObjectionHandle',
component: () => import('@/views/data_asset/damObjectionHandle.vue'),
meta: {
title: '公示异议处理',
sidebar: false,
cache: true,
breadcrumb: false,
},
},
]
},
{
path: '/data-asset-register/register-progress',
component: Layout,
meta: {
......
import type { RouteRecordRaw } from 'vue-router'
function Layout() {
return import('@/layouts/index.vue')
}
const routes: RouteRecordRaw[] = [
{
path: '/data-product/product-listing',
component: Layout,
meta: {
title: '数据产品上架',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'productListing',
component: () => import('@/views/data_product/productListing.vue'),
meta: {
title: '数据产品上架',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'listing-detail',
name: 'productListingDetail',
component: () => import('@/views/data_product/productListingDetail.vue'),
meta: {
title: '新建数据产品',
sidebar: false,
reuse: true,
breadcrumb: false,
cache: true
},
beforeEnter: (to, from) => {
if(to.query.type){
if (to.query.type == 'detail') {
to.meta.title = `详情-${to.query.name}`;
} else {
to.meta.editPage = true;
to.meta.title = to.query.type=='add'? '新建数据产品': to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
}
}
}
},
{
path: 'product-JQZQ-detail',
name: 'productInfoJSZQDetail',
component: () => import('@/views/data_asset/registerJSZQDetail.vue'),
meta: {
title: '详情-',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true
},
beforeEnter: (to, from) => {
if(to.query.type){
if (to.query.type == 'detail') {
to.meta.title = `详情-${to.query.name}`;
} else {
to.meta.editPage = true;
to.meta.title = to.query.type=='add'? '新建数据产品': to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
}
}
}
}
],
},
{
path: '/data-product/listing-check',
component: Layout,
meta: {
title: '数据产品审核',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'productListingCheck',
component: () => import('@/views/data_product/productListingCheck.vue'),
meta: {
title: '数据产品审核',
sidebar: false,
breadcrumb: false,
cache: true,
},
},
{
path: 'listing-detail',
name: 'productListingCheckDetail',
component: () => import('@/views/data_product/productListingDetail.vue'),
meta: {
title: '产品审核详情',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
},
beforeEnter: (to, from) => {
if (to.query.type == 'check') {
to.meta.editPage = true;
to.meta.title = `详情-${to.query.name}`;
return;
}
}
},
],
},
{
path: '/data-product/demands-publish',
component: Layout,
meta: {
title: '数据需求发布',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'productDemandsPublish',
component: () => import('@/views/data_product/productDemandsPublish.vue'),
meta: {
title: '数据需求发布',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'demands-detail',
name: 'productDemandsDetail',
component: () => import('@/views/data_product/productDemandsDetail.vue'),
meta: {
title: '新建数据需求',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
},
beforeEnter: (to, from) => {
if(to.query.type){
if (to.query.type == 'detail') {
to.meta.title = `详情-${to.query.name}`;
} else {
to.meta.editPage = true;
to.meta.title = to.query.type=='add'? `新建数据需求${to.query.interfaceType == '2' ? '(算法竞赛)' : (to.query.interfaceType == '3' ? '(要素市场)' : '')}`: to.query.type=='edit'? `编辑-${to.query.name}`: `详情-${to.query.name}`;
}
}
}
},
],
},
{
path: '/data-product/demands-check',
component: Layout,
meta: {
title: '数据需求审核',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'productDemandsCheck',
component: () => import('@/views/data_product/productDemandsCheck.vue'),
meta: {
title: '数据需求审核',
sidebar: false,
breadcrumb: false,
cache: true
},
},
{
path: 'demands-detail',
name: 'productDemandsCheckDetail',
component: () => import('@/views/data_product/productDemandsDetail.vue'),
meta: {
title: '需求审核详情',
sidebar: false,
breadcrumb: false,
cache: true,
reuse: true,
},
beforeEnter: (to, from) => {
if (to.query.type == 'check') {
to.meta.editPage = true;
to.meta.title = `详情-${to.query.name}`;
}
}
},
],
},
// {
// path: '/data-guide/transaction-finance',
// component: Layout,
// meta: {
// title: '交易融资指南',
// icon: 'sidebar-videos',
// },
// children: [
// {
// path: '',
// name: 'transactionFinanceGuid',
// component: () => import('@/views/data_transaction/transactionFinanceGuide.vue'),
// meta: {
// title: '交易融资指南',
// sidebar: false,
// breadcrumb: false,
// cache: true
// },
// },
// ],
// },
{
path: '/data-product/transaction-management',
component: Layout,
meta: {
title: '资产交易管理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'transactionManagement',
component: () => import('@/views/data_transaction/transactionManagement.vue'),
meta: {
title: '资产交易管理',
sidebar: false,
breadcrumb: false,
cache: true
},
},
],
},
]
export default routes
......@@ -29,19 +29,11 @@ const constantRoutes: RouteRecordRaw[] = [
// },
// },
{
path: '/register',
name: 'register',
component: () => import('@/views/register.vue'),
meta: {
title: '注册',
},
},
{
path: '/:all(.*)*',
name: 'notFound',
component: () => import('@/views/[...all].vue'),
meta: {
title: '数据资产管理',
title: '可信数据空间',
},
},
]
......@@ -97,17 +89,8 @@ const systemRoutes: RouteRecordRaw[] = [
// 动态路由(异步路由、导航栏路由)
const asyncRoutes: RouteRecordRaw[] = [
...AssetIndex,
...DataAssess,
...DataAssetRegistry,
...DataEntry,
...SecurityMenu,
...DataMeta,
...DataQuality,
...DataInventory,
...DataAnonymization,
...DataTrustedSpace,
...DataPricing
]
const constantRoutesByFilesystem = generatedRoutes.filter((item) => {
......
<template>
<div class="guide">
<div class="title">{{ data.title }}</div>
<div class="content">
<div class="guid-item " :class="{
qualityAssessment: data.qualityAssessment || false,
assetRegistration: data.assetRegistration || false,
registration: data.registration || false,
}" v-for="item in data.children" :key="item.title">
<div class="guid-item-title">{{ item.title }}</div>
<div style="padding-right: 30px;">
<div class="text" v-for="text in item.children" :key="text" v-html="text"></div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
data: {
type: Object,
default: {} as any
}
})
const data: any = computed(() => props.data)
</script>
<style lang="scss" scoped>
.guide {
padding-top: 16px;
width: 100%;
height: auto;
padding-left: 16px;
padding-right: 11px;
background: #fff;
margin-bottom: 16px;
.title {
font-size: 18px;
color: #212121;
letter-spacing: 0;
line-height: 27px;
font-weight: 600;
padding-top: 10px;
}
.content {
display: flex;
justify-content: space-around;
padding-bottom: 16px;
.qualityAssessment {
background: url("../../../../assets/images/qualityAssessment.png");
background-size: auto 100%;
background-position: center right;
background-repeat: no-repeat;
}
.assetRegistration {
background: url("../../../../assets/images/assetRegistration.png");
background-size: auto 100%;
background-position: center right;
background-repeat: no-repeat;
}
.registration {
background: url("../../../../assets/images/registration.png");
background-size: auto 100%;
background-position: center right;
background-repeat: no-repeat;
}
.guid-item {
width: 100%;
height: 171px;
border-right: 1px solid rgba(217, 217, 217, 1);
// background: url("../../../../assets/images/qualityAssessment.png");
// width: 100%;
// height:171px;
// background-size: auto 100%;
// background-position: center right;
// background-repeat: no-repeat;
&>div {
margin-left: 24px
}
.guid-item-title {
font-size: 20px;
color: #2D60B9;
letter-spacing: 0;
line-height: 30px;
font-weight: 500;
margin-top: 24px;
margin-bottom: 16px;
}
.text {
list-style: none;
color: #666666;
letter-spacing: 0;
line-height: 21px;
font-weight: 400;
margin-bottom: 8px;
width: 100%;
}
}
}
}
</style>
\ No newline at end of file
<route lang="yaml">
name: damAnalysisReport
</route>
<script lang="ts" setup name="damAnalysisReport">
import { ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import {
getReportDetail,
getLargeCategoryScore,
getPlanReportDetail,
getTableRuleDetail,
htmlToWord
} from '@/api/modules/dataAssetQuality';
import * as echarts from 'echarts';
import { QuestionFilled } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { changeNum, tagMethod, tagType } from '@/utils/common';
//报告导出word
import html2canvas from 'html2canvas';
const route = useRoute();
const reportExecGuid = route.query.reportExecGuid;
const planGuid = route.query.planGuid;
const wordName = ref(route.query.name);
const { proxy } = getCurrentInstance() as any;
const detailInfo: any = ref({});
const fullscreenLoading = ref(false);
const loadingText = ref('报告图表生成中,请勿关闭浏览器...');
const getReportDetailInfo = () => {
let ps: any = [];
fullscreenLoading.value = true;
loadingText.value = '报告图表生成中,请勿关闭浏览器...';
ps.push(getReportDetail({ reportExecGuid: reportExecGuid, planGuid: planGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data || {};
detailInfo.value = data;
barChartData.value = data.qualityScoreLine?.slice(0, 12) || [];
planDetailTableInfo.value.data = [{
guid: '1',
planName: data.planName,
planType: data.analysisReportType == 1 ? '表' : (data.analysisReportType == 2 ? '数据库' : (data.analysisReportType == 4 ? '数据同步' : '分组')),
execDuration: data.planExecDuration != null ? changeNum(data.planExecDuration ?? 0) : '--',
execTime: data.execTime,
qualityTableNum: data.qualityTableNum != null ? changeNum(data.qualityTableNum ?? 0) : '--',
ruleCount: data.ruleCount != null ? changeNum(data.ruleCount ?? 0) : '--',
totalNum: data.totalNum != null ? changeNum(data.totalNum ?? 0) : '--',
qualifiedNum: data.qualifiedNum != null ? changeNum(data.qualifiedNum ?? 0) : '--',
unqualifiedNum: data.unqualifiedNum != null ? changeNum(data.unqualifiedNum ?? 0) : '--',
qualityScore: data.qualityScore ?? '--',
qualifiedRate: data.qualifiedRate != null ? (changeNum((data.qualifiedRate ?? 0) * 100, 2, true) + '%') : '--'
}]
} else {
ElMessage.error(res.msg);
}
}))
ps.push(getLargeCategoryScore(reportExecGuid).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data || {};
qualityRuleDetailTableInfo.value.data = data.largeCategoryScoreList || [];
if (!qualityRuleDetailTableInfo.value.data.length) {
qualityRuleDetailTableInfo.value.footerHtml = '';
} else {
qualityRuleDetailTableInfo.value.footerHtml = `<span>质量得分</span><span>∑规则得分*权重</span>`;
}
radarChartData.value = data.largeCategoryScore || {};
} else {
ElMessage.error(res.msg);
}
}))
/** 表明细,单表时没有。 */
ps.push(getPlanReportDetail({ reportExecGuid: reportExecGuid, planGuid: planGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data || [];
modelDetailTableInfo.value.data = data;
} else {
ElMessage.error(res.msg);
}
}))
ps.push(getTableRuleDetail(reportExecGuid).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data || [];
modelRuleDetailTableInfo.value.data = data;
} else {
ElMessage.error(res.msg);
}
}))
Promise.all(ps).then(() => {
fullscreenLoading.value = false;
});
}
/** 方案明细表。 */
const planDetailTableInfo: any = ref({
id: "plan-detail-table",
loading: false,
height: 'auto',
minPanelHeight: '60px',
minHeight: '60px',
fields: [
{ label: "评估时间", field: "execTime", width: 180, },
{ label: "耗时(秒)", field: "execDuration", width: 100, align: 'right' },
{ label: "评估表数", field: "qualityTableNum", width: 100, align: 'right' },
{ label: "规则数", field: "ruleCount", width: 100, align: 'right' },
{ label: "评估总数", field: "totalNum", width: 100, align: 'right' },
{ label: "合格条数", field: "qualifiedNum", width: 100, align: 'right' },
{ label: "不合格条数", field: "unqualifiedNum", width: 100, align: 'right' },
{ label: "合格率", field: "qualifiedRate", width: 100, align: 'right' },
{ label: "质量评分", field: "qualityScore", width: 100, align: "right" }
],
data: [],
showPage: false,
actionInfo: {
show: false
}
});
/** 数据质量一级指标得分明细 */
const qualityRuleDetailTableInfo = ref({
id: "quality-rule-detail-table",
loading: false,
minHeight: '60px',
footerClass: 'last-row',
footerHtml: `<span>质量得分</span><span></span>`,
fields: [
{ label: "规则大类", field: "largeCategoryName", width: 100 },
{
label: "规则数", field: "ruleCount", width: 100, align: 'right', getName: (scope) => {
return scope.row.ruleCount != null ? changeNum(scope.row.ruleCount ?? 0) : '--';
}
},
{
label: "规则得分", field: "largeCategoryScore", width: 100, align: "right", getName: (scope) => {
return scope.row.largeCategoryScore != null ? changeNum(scope.row.largeCategoryScore ?? 0, 2, true) : '--';
}
},
{
label: "权重", field: "ruleLargeWeight", width: 100, align: "right", getName: (scope) => {
return scope.row.ruleLargeWeight != null ? scope.row.ruleLargeWeight.toFixed(2) : '--';
}
},
{
label: "质量评分", field: "qualityScore", width: 100, align: "right", getName: (scope) => {
return scope.row.qualityScore != null ? changeNum(scope.row.qualityScore ?? 0, 2, true) : '--';
}
}
],
data: [],
showPage: false,
actionInfo: {
show: false
}
});
/** 表明细。 */
const modelDetailTableInfo = ref({
id: "model-detail-table",
loading: false,
height: 'auto',
minPanelHeight: '60px',
minHeight: '60px',
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "表名", field: "qualityModelName", width: 140 },
{ label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
{ label: "评估时间", field: "execTime", width: 180, },
{
label: "耗时(秒)", field: "execDuration", width: 100, align: "right", getName: (scope) => {
return scope.row.execDuration != null ? changeNum(scope.row.execDuration ?? 0) : '--';
}
},
{
label: "规则数", field: "ruleNum", width: 100, align: "right", getName: (scope) => {
return scope.row.ruleNum != null ? changeNum(scope.row.ruleNum ?? 0) : '--';
}
},
{
label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
}
},
{
label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
}
},
{
label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
}
},
{
label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
}
},
{ label: "评估范围", field: "dataRange", width: 180 },
],
data: [{
guid: '1',
executeState: 'N'
}],
showPage: false,
actionInfo: {
show: false
}
});
/** 规则明细。 */
const modelRuleDetailTableInfo = ref({
id: "model-rule-detail-table",
loading: false,
height: 'auto',
minPanelHeight: '60px',
minHeight: '60px',
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "表名", field: "qualityModelName", width: 140 },
{ label: "规则类型", field: "ruleName", width: 140 },
{ label: "规则名称", field: "ruleConfName", width: 140 },
{ label: "规则大类", field: "largeCategory", width: 100 },
{ label: "规则小类", field: "smallCategory", width: 140 },
{ label: "规则字段", field: "ruleField", width: 140 },
{ label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
{
label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
}
},
{
label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
}
},
{
label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
}
},
{
label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
}
}
],
data: [],
showPage: false,
actionInfo: {
show: false
}
});
/** 柱形图数据数组 */
const barChartData: any = ref([]);
/** 雷达图数据数组 */
const radarChartData: any = ref([]);
let barChart: any = null;
let radarChart: any = null;
let barChartWord: any = null;
let radarChartWord: any = null;
/** 设置柱形图option,默认只 展示12次的 */
const setBarChartOption = (barChart, isWord = false) => {
return new Promise((resolve, reject) => {
if (!barChartData.value.length) {
let option1 = {
title: [
{
text: "",
left: "30px",
top: "30px",
},
{
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
fontStyle: "normal",
fontWeight: "400",
fontSize: 18,
},
},
],
};
barChart.setOption(option1, true);
window.addEventListener("resize", () => {
barChart.resize();
});
return;
}
let itemXAxisData: any = [];
let itemYAxisData1: any = [];
let itemYAxisData2: any = [];
barChartData.value.forEach(d => {
itemXAxisData.push(d['execTime']);
itemYAxisData1.push(d['qualityScore']);
itemYAxisData2.push((d['qualifiedRate'] ?? 0) * 100);
})
let option = {
textStyle: {
fontFamily: 'SimSun'
},
color: ['#5B8FF9', '#FF4E00', '#867EEC', '#FDBC3E', '#F48A64', '#276FF5', '#46D0B5'],
title: {
show: false,
text: '评分趋势',
left: '30px',
top: '30px',
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
},
textStyle: {
align: 'left'
},
},
legend: {
right: 0,
textStyle: {
fontSize: 14
},
data: ['评分', '合格率']
},
grid: {
left: 30,
right: 60,
bottom: 5,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
nameTextStyle: {
color: '#000000'
},
axisLabel: {
interval: isWord ? 'auto' : 0,
textStyle: {
color: '#000000'
},
formatter: function (value) {
if (!value) {
return value;
}
let v = value.split(' ');
return v.join('\n');
}
},
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: '#d9d9d9'
}
},
data: itemXAxisData
},
yAxis: {
type: 'value',
name: '',
min: 0,
max: 100,
nameTextStyle: {
color: '#000000'
},
axisLabel: {
textStyle: {
color: '#000000'
}
},
axisLine: {
//y轴
show: false
}
},
series: [{
name: '评分',
type: 'line',
data: itemYAxisData1,
label: {
show: false,
},
yAxisIndex: 0
}, {
name: '合格率',
type: 'line',
data: itemYAxisData2,
label: {
show: false,
},
tooltip: {
valueFormatter: function (value) {
return changeNum(value, 2, true) + '%';
}
},
yAxisIndex: 0
}]
};
option && barChart.setOption(option, true);
barChart.on('finished', () => {
resolve(true);
});
window.addEventListener('resize', () => {
barChart.resize();
});
});
}
/** 设置雷达图option. */
const setRadarChartOption = (radarChart) => {
return new Promise((resolve, reject) => {
let indicator = [{ name: '规范性', max: 100, min: 0, color: '#000' },
{ name: '完整性', max: 100, min: 0, color: '#000' },
{ name: '一致性', max: 100, min: 0, color: '#000' },
{ name: '准确性', max: 100, min: 0, color: '#000' },
{ name: '时效性', max: 100, min: 0, color: '#000' },
{ name: '可访问性', max: 100, min: 0, color: '#000' }]
let data: any = [];
for (const key in radarChartData.value) {
let index = indicator.findIndex(i => i.name == key);
index > -1 && (data[index] = changeNum(radarChartData.value[key] ?? 0, 2));
}
let option = {
textStyle: {
fontFamily: 'SimSun'
},
color: ['#5B8FF9', '#6DD18E', '#867EEC', '#FDBC3E', '#F48A64', '#276FF5', '#46D0B5'],
title: {
show: false,
text: '数据质量一级指标得分',
left: '30px',
top: '30px',
},
tooltip: {
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
},
textStyle: {
align: 'left'
},
},
legend: {
show: false
},
grid: {
left: 0,
bottom: 0,
containLabel: true
},
radar: {
indicator: indicator,
axisLabel: {
show: false
},
axisLine: {
lineStyle: {
color: '#d9d9d9'
}
},
axisTick: {
lineStyle: {
color: '#d9d9d9'
}
},
splitLine: {
lineStyle: {
color: '#d9d9d9'
}
}
},
series: [
{
type: 'radar',
data: [{
name: '数据质量一级指标得分',
value: data
}],
label: {
show: true,
position: 'bottom',
distance: 1,
color: '#000'
},
areaStyle: {
color: '#e8eefc'
}
}
]
};
option && radarChart.setOption(option, true);
radarChart.on('finished', () => {
resolve(true);
});
window.addEventListener('resize', () => {
radarChart.resize();
});
});
}
watch(() => barChartData.value, (val) => {
setBarChartOption(barChart);
barChartWord && setBarChartOption(barChartWord, true);
})
watch(() => radarChartData.value, (val) => {
setRadarChartOption(radarChart);
radarChartWord && setRadarChartOption(radarChartWord);
})
onBeforeMount(() => {
getReportDetailInfo();
})
onMounted(() => {
barChart = echarts.init(document.getElementById('bar'));
radarChart = echarts.init(document.getElementById('radar'));
setBarChartOption(barChart);
setRadarChartOption(radarChart);
})
const domClone: any = ref(null);
const convertChartsToBase64 = (contentDocument) => {
// 找到所有的图表 (echart)
let canvases = contentDocument.querySelectorAll('#bar-word');
// 遍历图表,转换为 base64 静态图片
canvases.forEach((canvas, i) => {
let url = barChartWord.getDataURL();
let img = document.createElement('img');
if (url) {
// img.src = url.split(',')[1];
img.src = url;
img.width = 620;
img.height = 400;
img.crossOrigin = 'Anonymous';
}
canvas.parentNode.replaceChild(img, canvas);
});
let canvases1 = contentDocument.querySelectorAll('#radar-word');
canvases1.forEach((canvas, i) => {
let url = radarChartWord.getDataURL();
let img = document.createElement('img');
if (url) {
// img.src = url.split(',')[1];
img.src = url;
img.width = 620;
img.height = 400;
img.crossOrigin = 'Anonymous';
}
canvas.parentNode.replaceChild(img, canvas);
});
}
const convertHtml2Img = (dom, domClone) => {
const element = <HTMLElement>dom.querySelector('.kpi-content')
if (!element) {
return Promise.resolve();
}
return html2canvas(element, {
allowTaint: true,
useCORS: true,
scale: 1,
}).then((canvas: any) => {
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
element.parentNode && ((<HTMLElement>element.parentNode).scrollTop = 0);
let url = canvas.toDataURL('image/jpeg');
let img = document.createElement('img');
if (url) {
// img.src = url.split(',')[1];
img.src = url;
img.width = 620;
img.height = 80;
img.crossOrigin = 'Anonymous';
}
const copyElement = <HTMLElement>domClone.querySelector('.kpi-content')
copyElement.parentNode?.replaceChild(img, copyElement);
})
}
const report = ref();
const isWordStyle = ref(false);
const isTransfered = ref(false);
const downloadBtnDisable = ref(false);
const transfer = () => {
isWordStyle.value = true;
nextTick(() => {
if (!isTransfered.value) {
barChartWord = echarts.init(document.getElementById('bar-word'));
downloadBtnDisable.value = true;
let ps1 = setBarChartOption(barChartWord, true);
radarChartWord = echarts.init(document.getElementById('radar-word'));
let ps2 = setRadarChartOption(radarChartWord);
Promise.all([ps1, ps2]).then(res => {
downloadBtnDisable.value = false;
isTransfered.value = true;
})
}
});
};
const getHTML = (reportResultContent) => {
let html = reportResultContent;
html = html.replace(/"/g, "'");
return html;
};
const download = () => {
let dom = domClone.value || (domClone.value = document.createElement('div'));
dom.innerHTML = report.value.innerHTML;
convertChartsToBase64(dom);
fullscreenLoading.value = true;
loadingText.value = '报告正在下载中,请勿关闭浏览器...';
convertHtml2Img(report.value, dom).then(() => {
htmlToWord({ html: getHTML(dom.innerHTML) }).then((res: any) => {
fullscreenLoading.value = false;
// let blob = new Blob([res.data], { type: 'application/msword' });
let objectUrl = URL.createObjectURL(res);
const link = document.createElement('a')
link.download = wordName.value + '质量评估报告.docx';
link.href = objectUrl
link.click()
})
// // 下载word 需要接口。
// const converted = htmlDocx.asBlob(`
// <html xmlns:o=\'urn:schemas-microsoft-com:office:office\' xmlns:w=\'urn:schemas-microsoft-com:office:word\' xmlns=\'http://www.w3.org/TR/REC-html40\'><head><style>
// ${document.head.outerHTML}
// </head>
// <body>
// ${dom.outerHTML}
// </body>
// </html>`)
// converted.then((res: any) => {
// // 导出无样式。
// console.log(res);
// let objectUrl = URL.createObjectURL(res);
// const link = document.createElement('a')
// link.download = detailInfo.value.analysisReportName + '.docx';
// link.href = objectUrl
// link.click()
// })
})
}
</script>
<template>
<div class="container_wrap" v-loading="fullscreenLoading" :element-loading-text="loadingText">
<div v-show="!isWordStyle" class="header-title">
<div>
<span>{{ `【${detailInfo.damName ?? '--'}】` + '资产质量评估报告' }}</span>
<span class="time-detail">{{ '生成时间:' + (detailInfo.execTime ?? '--') }}</span>
</div>
<el-button type="primary" @click="transfer">生成Word报告</el-button>
<!-- <el-button @click="download">下载 Word</el-button> -->
</div>
<div v-show="!isWordStyle" class="content-main">
<div class="title">数据汇总</div>
<div class="kpi-content">
<div class="border-content">
<span class="number score-color">{{ detailInfo.qualityScore ?? '--' }}</span>
<div class="text">质量评分<el-tooltip placement="top" effect="light" popper-class="table_tooltip">
<template #content>
<div style="max-width: 236px;">
质量一级指标得分*权重
</div>
</template>
<el-icon style="margin-left: 2px;">
<QuestionFilled />
</el-icon>
</el-tooltip></div>
</div>
<div v-if="detailInfo.analysisReportType != 1" class="border-content ml16">
<span class="number">{{ detailInfo.qualityTableNum != null ? changeNum(detailInfo.qualityTableNum ?? 0) :
'--'
}}</span>
<span class="text">评估表数</span>
</div>
<div class="border-content ml16">
<span class="number num-color">{{ detailInfo.ruleCount != null ? changeNum(detailInfo.ruleCount ?? 0) : '--'
}}</span>
<span class="text">质量规则数</span>
</div>
<div class="border-content ml16">
<span class="number num-color">{{ detailInfo.totalNum != null ? changeNum(detailInfo.totalNum ?? 0) : '--'
}}</span>
<span class="text">评估总数</span>
</div>
<div class="border-content ml16">
<span class="number pass-color">{{ detailInfo.qualifiedNum != null ? changeNum(detailInfo.qualifiedNum ?? 0)
:
'--' }}</span>
<span class="text">合格条数</span>
</div>
<div class="border-content ml16">
<span class="number no-pass-color">{{ detailInfo.unqualifiedNum != null ?
changeNum(detailInfo.unqualifiedNum ??
0) : '--' }}</span>
<span class="text">不合格条数</span>
</div>
<div class="border-content ml16">
<span class="number rate-color">{{ detailInfo.qualifiedRate != null ? (changeNum((detailInfo.qualifiedRate
?? 0) *
100, 2, true) + '%') : '--' }}</span>
<span class="text">合格率</span>
</div>
</div>
<div class="title">评分趋势</div>
<div class="content-chart-bar" id="bar">
</div>
<div class="content-radar-table">
<div class="content-two">
<div class="title">数据质量一级指标得分</div>
<div class="content-chart-radar" id="radar">
</div>
</div>
<div class="content-two">
<div class="title">数据质量一级指标得分明细</div>
<Table :tableInfo="qualityRuleDetailTableInfo" />
</div>
</div>
<div class="title">评估方案明细</div>
<Table :tableInfo="planDetailTableInfo" />
<template v-if="detailInfo.analysisReportType != 1">
<div class="title">表明细</div>
<Table :tableInfo="modelDetailTableInfo" />
</template>
<div class="title">规则明细</div>
<Table :tableInfo="modelRuleDetailTableInfo" />
</div>
<div v-show="isWordStyle" class="word-report">
<div class="word-btn">
<span>{{ `【${detailInfo.damName ?? '--'}】` + '资产质量评估报告' }}</span>
<div>
<el-button @click="isWordStyle = false">返回</el-button>
<el-button type="primary" :disabled="downloadBtnDisable" @click="download">下载 Word</el-button>
</div>
</div>
<div class="word-report-main" ref="report">
<div style="width: 625px;">
<div style="text-align: center;padding: 8px 0px;">
<div
style="height: 40px;display: block;line-height: 32px;font-size: 18px;color: #212121;font-weight: 600;text-align: center;">
{{ `【${detailInfo.damName ?? '--'}】` + '资产质量评估报告' }}</div>
<div style="font-size: 14px;color: #666666;font-weight: 400;">{{ '生成时间:' + detailInfo.execTime }}</div>
</div>
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
数据汇总</div>
<div class="kpi-content">
<div class="border-content" style="padding-left: 8px;min-width: 70px;height: 72px">
<span class="number score-color">{{ detailInfo.qualityScore ?? '--' }}</span>
<div class="text">质量评分</div>
</div>
<div v-if="detailInfo.analysisReportType != 1" class="border-content"
style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
<span class="number">{{ detailInfo.qualityTableNum != null ? changeNum(detailInfo.qualityTableNum ?? 0)
:
'--'
}}</span>
<span class="text">评估表数</span>
</div>
<div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 84px;height: 72px">
<span class="number num-color">{{ detailInfo.ruleCount != null ? changeNum(detailInfo.ruleCount ?? 0) :
'--'
}}</span>
<span class="text">质量规则数</span>
</div>
<div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
<span class="number num-color">{{ detailInfo.totalNum != null ? changeNum(detailInfo.totalNum ?? 0) :
'--'
}}</span>
<span class="text">评估总数</span>
</div>
<div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
<span class="number pass-color">{{ detailInfo.qualifiedNum != null ? changeNum(detailInfo.qualifiedNum
?? 0)
:
'--' }}</span>
<span class="text">合格条数</span>
</div>
<div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 84px;height: 72px">
<span class="number no-pass-color">{{ detailInfo.unqualifiedNum != null ?
changeNum(detailInfo.unqualifiedNum ??
0) : '--' }}</span>
<span class="text">不合格条数</span>
</div>
<div class="border-content" style="padding-left: 8px;margin-left: 8px;min-width: 70px;height: 72px">
<span class="number rate-color">{{ detailInfo.qualifiedRate != null ?
(changeNum((detailInfo.qualifiedRate
?? 0) *
100, 2, true) + '%') : '--' }}</span>
<span class="text">合格率</span>
</div>
</div>
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
评分趋势</div>
<div class="content-chart-bar" style="border:none;padding: 8px 0px;" id="bar-word">
</div>
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
数据质量一级指标得分</div>
<div class="content-chart-bar" style="border:none;height: 380px;padding: 8px 0px;" id="radar-word"></div>
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
数据质量一级指标得分明细</div>
<table border="1" cellspacing="0"
style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
<thead>
<tr>
<th v-for="(item, index) in qualityRuleDetailTableInfo.fields.map(f => f.label)" :key="index">
<span>{{ item }}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(recordItem, j) in qualityRuleDetailTableInfo.data" :key="j">
<td v-for="(columnItem, i) in qualityRuleDetailTableInfo.fields" :key="i"
:style="{ 'text-align': <any>(columnItem.align ?? 'left') }">
<span :style="{ 'word-break': 'break-all' }">
{{ columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
recordItem[columnItem.field]) ?? '--') }}
</span>
</td>
</tr>
</tbody>
</table>
<div style="
background: #FFF1D4;
/* border-bottom: 1px solid #000;
border-right: 1px solid #000;
border-left: 1px solid #000; */
"><span>质量得分:</span><span>∑规则得分*权重</span></div>
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
评估方案明细</div>
<table border="1" cellspacing="0"
style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
<thead>
<tr>
<th v-for="(item, index) in planDetailTableInfo.fields.map(f => f.label)" :key="index">
<span>{{ item }}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(recordItem, j) in planDetailTableInfo.data" :key="j">
<td v-for="(columnItem, i) in planDetailTableInfo.fields" :key="i"
:style="{ 'text-align': <any>(columnItem.align ?? 'left'), width: columnItem.field == 'qualifiedRate' ? '53px' : '' }">
<span :style="{ 'word-break': 'break-all' }">
{{ columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
recordItem[columnItem.field]) ?? '--') }}
</span>
</td>
</tr>
</tbody>
</table>
<template v-if="detailInfo.analysisReportType != 1">
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
表明细</div>
<table border="1" cellspacing="0"
style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
<thead>
<tr>
<th v-for="(item, index) in modelDetailTableInfo.fields.slice(1).map(f => f.label)" :key="index">
<span>{{ item }}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(recordItem, j) in modelDetailTableInfo.data" :key="j">
<td v-for="(columnItem, i) in modelDetailTableInfo.fields.slice(1)" :key="i"
:style="{ 'text-align': <any>(columnItem.align ?? 'left'), width: columnItem.field == 'qualifiedRate' ? '53px' : '' }">
<span v-if="columnItem.type != 'tag'">
{{ (columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
recordItem[columnItem.field]) ?? '--')) }}
</span>
<span v-else :style="{
'white-space': 'nowrap', 'font-size': '12px', color: tagType(recordItem, columnItem.field) == 'success' ? '#1BA854' : (tagType(recordItem, columnItem.field) == 'warning' ? '#e6a23c' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FB2323' : '#999999')),
background: tagType(recordItem, columnItem.field) == 'success' ? '#F2FFF5' : (tagType(recordItem, columnItem.field) == 'warning' ? '#fdf6ec' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FFF2F4' : '#F5F5F5'))
}">
{{ (columnItem.field && recordItem[columnItem.field]) ? tagMethod(recordItem, columnItem.field) :
'--' }}
</span>
</td>
</tr>
</tbody>
</table>
</template>
<div
style="line-height: 24px;font-size: 16px;color: #212121;font-weight: 600;margin-top: 12px;margin-bottom: 8px;">
规则明细</div>
<table border="1" cellspacing="0"
style="width: 100%;table-layout: fixed;word-break: break-all;margin: 0 auto;text-align: center;border-collapse: collapse;">
<thead>
<tr>
<th v-for="(item, index) in modelRuleDetailTableInfo.fields.slice(1).map(f => f.label)" :key="index">
<span>{{ item }}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(recordItem, j) in modelRuleDetailTableInfo.data" :key="j">
<td v-for="(columnItem, i) in modelRuleDetailTableInfo.fields.slice(1)" :key="i"
:style="{ 'text-align': <any>(columnItem.align ?? 'left'), width: columnItem.field == 'qualifiedRate' ? '53px' : '' }">
<span v-if="columnItem.type != 'tag'">
{{ (columnItem.getName ? columnItem.getName({ row: recordItem }) : ((columnItem?.field &&
recordItem[columnItem.field]) ?? '--')) }}
</span>
<span v-else :style="{
'white-space': 'nowrap', 'font-size': '12px', color: tagType(recordItem, columnItem.field) == 'success' ? '#1BA854' : (tagType(recordItem, columnItem.field) == 'warning' ? '#e6a23c' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FB2323' : '#999999')),
background: tagType(recordItem, columnItem.field) == 'success' ? '#F2FFF5' : (tagType(recordItem, columnItem.field) == 'warning' ? '#fdf6ec' : (tagType(recordItem, columnItem.field) == 'danger' ? '#FFF2F4' : '#F5F5F5'))
}">
{{ (columnItem.field && recordItem[columnItem.field]) ? tagMethod(recordItem, columnItem.field) :
'--'
}}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0;
}
.content-main {
height: calc(100% - 64px);
border-top: 1px solid #d9d9d9;
overflow-y: auto;
overflow-x: hidden;
padding: 0px 16px 16px;
}
.header-title {
margin: 16px 16px 8px;
height: 40px;
line-height: 32px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 18px;
color: #212121;
font-weight: 600;
}
.time-detail {
font-size: 14px;
color: #666666;
font-weight: 400;
margin-left: 16px;
}
.kpi-content {
display: flex;
flex-direction: row;
}
.border-content {
height: 76px;
display: flex;
flex-direction: column;
align-items: left;
padding-left: 16px;
justify-content: center;
border: 1px solid #d9d9d9;
width: 160px;
min-width: 100px;
border-radius: 2px;
.number {
line-height: 30px;
font-weight: 700;
font-size: 20px;
}
.num-color {
color: #212121;
}
.score-color {
color: #FF5F1F;
}
.pass-color {
color: #1BA854;
}
.no-pass-color {
color: #FB2323;
}
.rate-color {
color: #5B8FF9;
}
.text {
font-size: 14px;
color: #666666;
display: flex;
.el-icon {
color: #b2b2b2;
}
}
}
.ml16 {
margin-left: 16px;
}
.ml32 {
margin-left: 32px;
}
.title {
line-height: 24px;
font-size: 16px;
color: #212121;
font-weight: 600;
margin-top: 12px;
margin-bottom: 8px;
}
.content-radar-table {
display: flex;
flex-direction: row;
height: 380px;
justify-content: space-between;
.content-two {
width: calc(50% - 16px);
.table_panel {
min-height: 200px !important;
height: calc(100% - 44px) !important;
}
}
.content-chart-radar {
height: calc(100% - 44px);
width: 100%;
border: 1px solid #d9d9d9;
padding: 8px;
}
}
.content-chart-bar {
height: 300px;
border: 1px solid #d9d9d9;
padding: 8px;
}
.word-report {
height: 100%;
widows: 100%;
background-color: #f1f1f1;
.word-btn {
background-color: #fff;
margin: 8px 0px;
padding: 0px 8px 8px;
height: 48px;
line-height: 32px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 18px;
color: #212121;
font-weight: 600;
}
}
.word-report-main {
height: calc(100% - 56px);
overflow-y: auto;
overflow-x: hidden;
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
padding-bottom: 12px;
}
</style>
<route lang="yaml">
name: damAssessDetail
</route>
<script lang="ts" setup name="damAssessDetail">
import { ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import {
getRecordRuleConfDetail,
getExecPlanDetailTableData,
getAssessTableRulesData,
downloadDirtyData
} from '@/api/modules/dataAssetQuality';
import { ElMessage } from "element-plus";
import { changeNum, download } from '@/utils/common';
import tableRuleForm from "./tableRuleForm.vue";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const planExecGuid = route.query.planExecGuid;
const tableInfo = ref({
id: "quality-table",
loading: false,
fields: [
{ label: "表名", field: "qualityModelName", width: 140 },
{ label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
{ label: "评估时间", field: "execTime", width: 180, },
{
label: "耗时(秒)", field: "execDuration", width: 100, align: "right", getName: (scope) => {
return scope.row.execDuration != null ? changeNum(scope.row.execDuration ?? 0) : '--';
}
},
{
label: "规则数", field: "ruleNum", width: 100, align: "right", getName: (scope) => {
return scope.row.ruleNum != null ? changeNum(scope.row.ruleNum ?? 0) : '--';
}
},
{
label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
}
},
{
label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
}
},
{
label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
}
},
{
label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
}
},
{ label: "评估范围", field: "dataRange", width: 180 },
],
data: [],
showPage: false,
actionInfo: {
label: "操作",
type: "btn",
width: 200,
fixed: 'right',
btns: (scope) => {
let unqualifiedNum = scope.row.unqualifiedNum ?? 0;
return [
{ label: "查看规则", value: "rule" },
{ label: "脏数据下载", value: "download", disabled: unqualifiedNum == 0 || scope.row.isTable == 'Y' },
]
},
}
});
/** 获取方案详情列表数据。 */
const getAssessDetail = () => {
tableInfo.value.loading = true;
getExecPlanDetailTableData({ planExecGuid: planExecGuid }).then((res: any) => {
tableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
tableInfo.value.data = res.data || []
} else {
ElMessage.error(res.msg);
}
});
}
/** 获取每个表的规则详情。 */
const getModelRulesDetail = (qualityModelGuid: string) => {
rulesDetailTableInfo.value.loading = true;
getAssessTableRulesData({ planExecGuid: planExecGuid, qualityModelGuid: qualityModelGuid }).then((res: any) => {
rulesDetailTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
rulesDetailTableInfo.value.data = res.data || [];
} else {
ElMessage.error(res.msg);
}
});
}
/** 下载脏数据。 */
const exportDirtyData = (row) => {
downloadDirtyData({
planExecGuid: row.planExecGuid,
qualityModelGuid: row.qualityModelGuid
}).then((res: any) => {
if (res && !res.msg) {
download(res, `脏数据-${row.qualityModelName}.xlsx`, 'excel');
} else {
res?.msg && ElMessage.error(res?.msg);
}
})
}
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
if (type == 'rule') {
rulesDetailDialogVisible.value = true;
getModelRulesDetail(row.qualityModelGuid);
} else if (type == 'download') {
exportDirtyData(row);
}
};
onBeforeMount(() => {
getAssessDetail();
});
/** 单个规则详情对话框 */
const oneRulesDetailDialogVisible = ref(false);
const toSubjectTables: any = ref([]);
const ruleType = ref('');
const detailInfo: any = ref({});
const detailLoading = ref(false);
const ruleTypeList: any = ref([]);
const smallCategoryList: any = ref([]);
const largeCategoryList: any = ref([]);
const detailJson: any = ref({});
/** 查看表规则详情的对话框显示隐藏。 */
const rulesDetailDialogVisible = ref(false);
const rulesDetailTableInfo: any = ref({
id: "rules-detail-table",
loading: false,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "表名", field: "qualityModelName", width: 140 },
{ label: "规则类型", field: "ruleName", width: 140 },
{ label: "规则名称", field: "ruleConfName", width: 140 },
{ label: "规则大类", field: "largeCategory", width: 100 },
{ label: "规则小类", field: "smallCategory", width: 140 },
{ label: "规则字段", field: "ruleField", width: 140 },
{ label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
// { label: "规则权重", field: "weight", width: 100, align: 'right' },
{
label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
}
},
{
label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
}
},
{
label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
}
},
{
label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
}
},
{ label: "失败原因", field: "errorLog", width: 140 },
],
data: [],
showPage: false,
actionInfo: {
label: "操作",
type: "btn",
width: 90,
fixed: 'right',
btns: [
{
label: "规则详情 ", value: "ruleDetail", click: (scope) => {
let row = scope.row;
detailLoading.value = true;
if (detailJson.value[row.ruleConfGuid]) {
ruleType.value = detailInfo.value.ruleCode;
toSubjectTables.value = [{
guid: detailInfo.value.subjectGuid,
enName: detailInfo.value.subjectName,
chName: detailInfo.value.subjectZhName,
label: `${detailInfo.value.subjectName}(${detailInfo.value.subjectZhName})`
}]
ruleTypeList.value = [{
value: detailInfo.value.ruleCode,
label: row.ruleName
}];
smallCategoryList.value = [{
paramValue: detailInfo.value.smallCategory,
paramName: row.smallCategory
}];
largeCategoryList.value = [{
paramValue: detailInfo.value.largeCategory,
paramName: row.largeCategory
}];
oneRulesDetailDialogVisible.value = true;
} else {
detailJson.value[row.ruleConfGuid] = { isRequest: true };
getRecordRuleConfDetail({ ruleConfGuid: row.ruleConfGuid, planExecGuid: planExecGuid }).then((res: any) => {
detailLoading.value = false;
oneRulesDetailDialogVisible.value = true;
if (res.code == proxy.$passCode) {
let data = res.data || {};
detailInfo.value = data;
detailJson.value[row.ruleConfGuid] = detailInfo.value;
detailJson.value[row.ruleConfGuid].isRequest = false;
ruleType.value = detailInfo.value.ruleCode;
toSubjectTables.value = [{
guid: detailInfo.value.subjectGuid,
tableName: detailInfo.value.subjectName,
tableChName: detailInfo.value.subjectZhName,
label: `${detailInfo.value.subjectName}(${detailInfo.value.subjectZhName})`
}]
ruleTypeList.value = [{
value: detailInfo.value.ruleCode,
label: row.ruleName
}];
smallCategoryList.value = [{
paramValue: detailInfo.value.smallCategory,
paramName: row.smallCategory
}];
largeCategoryList.value = [{
paramValue: detailInfo.value.largeCategory,
paramName: row.largeCategory
}];
} else {
ElMessage.error(res.msg);
delete detailJson.value[row.ruleConfGuid];
}
})
}
}
},
],
}
});
</script>
<template>
<div class="container_wrap">
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" />
</div>
<el-dialog v-model="rulesDetailDialogVisible" title="查看规则" width="800" :modal="true" :close-on-click-modal="false"
destroy-on-close align-center>
<div class="rules-detail-dialog-content">
<Table class="long-tooltip-table" :tableInfo="rulesDetailTableInfo" />
</div>
</el-dialog>
<el-dialog v-model="oneRulesDetailDialogVisible" title="规则详情" width="800" :modal="true"
:close-on-click-modal="false" destroy-on-close align-center>
<tableRuleForm ref="ruleFormRef" :readonly="true" :toSubjectTables="toSubjectTables" :ruleTypeValue="ruleType"
:value="detailInfo" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
:smallCategoryList="smallCategoryList">
</tableRuleForm>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 16px;
}
.table_panel_wrap {
height: 100%;
}
.rules-detail-dialog-content {
height: 450px;
}
.long-tooltip-table {
:deep(.el-table) {
.table_cell_tooltip {
max-width: 500px;
// max-height: 100px;
// overflow: auto;
}
}
}
</style>
<route lang="yaml">
name: damObjectionHandle
</route>
<script lang="ts" setup name="damObjectionHandle">
import { ref } from 'vue';
import TableTools from "@/components/Tools/table_tools.vue";
import {
getDissentList,
updateDissentState
} from "@/api/modules/dataAsset";
import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
import { useValidator } from '@/hooks/useValidator';
const router = useRouter();
const { proxy } = getCurrentInstance() as any;
const { required } = useValidator();
const searchItemList = ref([
{
type: "input",
label: "",
field: "damName",
default: "",
maxlength: 50,
placeholder: "资产名称",
clearable: true,
},
{
type: "input",
label: "",
field: "applyCompany",
default: "",
maxlength: 50,
placeholder: "申请单位",
clearable: true,
},
]);
const toSearch = (val: any, clear: boolean = false) => {
page.value.curr = 1;
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.damName = '';
page.value.applyCompany = "";
} else {
page.value.damName = val.damName;
page.value.applyCompany = val.applyCompany;
}
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true;
getDissentList({
pageSize: page.value.limit,
pageIndex: page.value.curr,
damName: page.value.damName,
applyCompany: page.value.applyCompany
}).then((res: any) => {
tableInfo.value.loading = false
if (res.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || [];
tableInfo.value.page.curr = data.pageIndex;
tableInfo.value.page.rows = data.totalRows || 0;
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
const page = ref({
...commonPageConfig,
damName: '',
applyCompany: ''
});
const tableInfo = ref({
id: 'dissent-data-table',
rowKey: 'guid',
loading: false,
fields: [{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "数据资产名称", field: "damName", width: 160, align: "left" },
{ label: "公司名称", field: "companyName", width: 240 },
{ label: "申请时间", field: "applyTime", width: TableColumnWidth.DATETIME, align: "left" },
{ label: "申请单位", field: "applyCompany", width: 240 },
{ label: "申请人", field: "applicant", width: TableColumnWidth.USERNAME },
{ label: "联系方式", field: "contactTel", width: 120 },
{ label: "申请事由", field: "applyRemark", width: TableColumnWidth.DESCRIPTION },
{ label: "状态", field: "state", type: "tag", width: 96, align: 'center' },
{ label: "操作人", field: "lastApprover", width: TableColumnWidth.USERNAME, align: "left" },
{ label: "操作时间", field: "lastApprovalTime", width: TableColumnWidth.DATETIME, align: "left" },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 100,
btns: (scope) => {
let row = scope.row;
return getTableBtns(row);
}
}
});
const getTableBtns = (row) => {
let btnsArr: any[] = [];
if (row.state != 'Y' && row.state != 'R') {//审批中
btnsArr.push({
label: "通过", value: "pass", click: (scope) => {
currTableData.value = scope.row;
passDialogInfo.value.visible = true;
passFormItems.value[0].readonly = false;
passDialogInfo.value.contents[0].formInfo.items = passFormItems.value;
passDialogInfo.value.contents[0].formInfo.items[0].default = ''
passDialogInfo.value.footer.visible = true;
}
});
btnsArr.push({
label: "驳回", value: "backup", click: (scope) => {
currTableData.value = scope.row;
rejectDialogInfo.value.visible = true;
rejectDialogInfo.value.contents[0].formInfo.items[0].readonly = false;
rejectDialogInfo.value.contents[0].formInfo.items[0].default = '';
rejectDialogInfo.value.footer.visible = true;
}
});
} else {
btnsArr.push({
label: "查看", value: "detail", click: (scope) => {
if (row.state == 'Y') {
passDialogInfo.value.visible = true;
passFormItems.value[0].readonly = true;
passDialogInfo.value.contents[0].formInfo.items = passFormItems.value;
passDialogInfo.value.contents[0].formInfo.items[0].default = row.description;
passDialogInfo.value.footer.visible = false;
} else {
rejectDialogInfo.value.visible = true;
rejectDialogInfo.value.contents[0].formInfo.items[0].readonly = true;
rejectDialogInfo.value.contents[0].formInfo.items[0].default = row.description;
rejectDialogInfo.value.footer.visible = false;
}
}
});
}
return btnsArr;
}
const currTableData: any = ref({});
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData();
};
const passFormItems = ref([
{
label: '',
type: "textarea",
placeholder: "请填写通过描述,至少五个字符",
field: "description",
clearable: true,
block: true,
readonly: false,
rows: 5,
maxlength: 200,
default: '',
col: 'margin_b_0',
}
]);
const passFormRules = ref({
description: [required('请填写通过描述'), {
validator: (rule: any, value: any, callback: any) => {
if (value?.length < 5) {
callback(new Error('请填写至少五个字符的通过描述'))
} else {
callback();
}
},
trigger: 'blur'
}]
});
const passDialogInfo = ref({
visible: false,
size: 460,
direction: "column",
header: {
title: "通过描述",
},
type: '',
contents: [
{
type: 'form',
title: '',
formInfo: {
id: 'dissent-pass-dialog',
items: passFormItems.value,
rules: passFormRules.value
}
}
],
footer: {
visible: true,
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", loading: false, value: "submit" },
],
},
});
const passDialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
passDialogInfo.value.footer.btns[1].loading = true;
updateDissentState({
guid: currTableData.value.guid,
damName: currTableData.value.damName,
description: info.description,
contactTel: currTableData.value.contactTel,
damGuid: currTableData.value.damGuid,
tenantGuid: currTableData.value.tenantGuid,
state: 'Y'
}).then((res: any) => {
passDialogInfo.value.footer.btns[1].loading = false;
if (res?.code == proxy.$passCode) {
if (res.data) {
proxy.$ElMessage.success('该资产异议受理通过成功');
passDialogInfo.value.visible = false;
getTableData();
} else {
proxy.$ElMessage.error('该资产异议受理通过失败');
}
} else {
proxy.$ElMessage.error(res.msg);
}
}).catch(() => {
passDialogInfo.value.footer.btns[1].loading = false;
})
} else if (btn.value == 'cancel') {
passDialogInfo.value.visible = false;
}
};
const rejectDialogInfo = ref({
visible: false,
size: 460,
direction: "column",
header: {
title: "驳回描述",
},
type: '',
contents: [
{
type: 'form',
title: '',
formInfo: {
id: 'batch-reject-form',
items: [
{
label: '',
type: "textarea",
placeholder: "请填写驳回描述,至少五个字符",
field: "description",
clearable: true,
block: true,
rows: 5,
maxlength: 200,
default: '',
readonly: false,
col: 'margin_b_0',
}
],
rules: {
description: [required('请填写驳回描述'), {
validator: (rule: any, value: any, callback: any) => {
if (value?.length < 5) {
callback(new Error('请填写至少五个字符的驳回描述'))
} else {
callback();
}
},
trigger: 'blur'
}]
}
}
}
],
footer: {
visible: true,
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", loading: false, value: "submit" },
],
},
});
const rejectDialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
rejectDialogInfo.value.footer.btns[1].loading = true;
updateDissentState({
guid: currTableData.value.guid,
damName: currTableData.value.damName,
description: info.description,
contactTel: currTableData.value.contactTel,
damGuid: currTableData.value.damGuid,
tenantGuid: currTableData.value.tenantGuid,
state: 'R'
}).then((res: any) => {
rejectDialogInfo.value.footer.btns[1].loading = false;
if (res?.code == proxy.$passCode) {
if (res.data) {
proxy.$ElMessage.success('该资产异议受理驳回成功');
getTableData();
rejectDialogInfo.value.visible = false;
} else {
proxy.$ElMessage.error('该资产异议受理驳回失败');
}
} else {
proxy.$ElMessage.error(res.msg);
}
}).catch(() => {
rejectDialogInfo.value.footer.btns[1].loading = false;
});
} else if (btn.value == 'cancel') {
rejectDialogInfo.value.visible = false;
}
};
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'register-data-search'" @search="toSearch" :init="true" />
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
<Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
<Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
</div>
</template>
<style scoped lang="scss">
.container_wrap {
padding: 0 16px;
}
.table_panel_wrap {
height: calc(100% - 48px);
}
:deep(.el-dialog) {
.dialog_panel {
padding: 14px 24px;
}
}
</style>
\ No newline at end of file
<route lang="yaml">
name: damQualityAssess
</route>
<script lang="ts" setup name="damQualityAssess">
import { ref } from 'vue';
import { TableColumnWidth, commonPageConfig } from '@/utils/enum';
import {
getQualityList,
getQualityDamList,
deleteQualityPlan,
executePlan,
downPlanSql
} from "@/api/modules/dataAssetQuality";
import useDataAssetStore from "@/store/modules/dataAsset";
import { download } from '@/utils/common';
import useUserStore from "@/store/modules/user";
const userStore = useUserStore()
const userData = JSON.parse(userStore.userData)
const assetStore = useDataAssetStore();
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const damListData = ref([]);
const serachFormRef = ref();
const searchItemList = ref([
{
type: 'select',
label: '',
field: 'damGuid',
default: '',
placeholder: '数据资产名称',
options: damListData.value,
props: {
value: 'guid',
label: 'damName'
},
filterable: true,
clearable: true,
required: true,
visible: true
}
])
/** 分页及搜索传参信息配置。 */
const page = ref({
...commonPageConfig,
damGuid: ''
});
/** 方案表格配置信息。 */
const tableInfo = ref({
id: 'quality-table',
// multiple: true,
loading: false,
nodeKey: 'guid',
fields: [
{ label: "序号", type: "index", width: TableColumnWidth.INDEX, fixed: "left", align: "center" },
{
label: "数据资产名称", field: "damName", width: 160, fixed: "left", type: "text_btn", value: "damDetail", columClass: 'text_btn', click: (scope) => {
router.push({
name: "registerCatalogDetail",
query: { guid: scope.row.damGuid },
});
}
},
{ label: "所属企业", field: "tenantName", width: 240 },
{ label: "质量评分", field: "qualityScore", width: 120, align: 'right' },
{ label: "执行状态", field: "execState", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
{ label: "执行时间", field: "lastExecTime", width: TableColumnWidth.DATETIME, },
{ label: "创建人", field: "createUserName", width: TableColumnWidth.USERNAME },
{ label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME, },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
isMore: true,
width: 271,
btns: (scope) => {
const row = scope.row
let btnsArr: any = [{
label: "查看报告", value: "reportView", disabled: row.execState == 1 || row.isExecute || row.execState == 0, click: (scope) => {
router.push({
name: 'damAnalysisReport',
query: {
planGuid: row.guid,
name: row.damName,
reportExecGuid: row.reportExecGuid
}
});
}
}, {
label: "查看结果", value: "resultView", disabled: row.execState == 1 || row.isExecute || row.execState == 0, click: (scope) => {
router.push({
name: 'damAssessDetail',
query: {
name: row.damName,
planExecGuid: row.planExecGuid
}
});
}
}, {
label: "编辑", value: "edit", disabled: row.execState == 1 || row.isExecute, click: (scope) => {
router.push({
name: 'damQualityPlan',
query: {
guid: row.guid,
damName: row.damName
}
});
}
}];
if (row.isExecute) {
btnsArr.push({ label: "执行中", value: "execute", disabled: true });
} else {
btnsArr.push({
label: "执行", value: "execute", disabled: row.execState == 1 || row.state == 0, click: (scope) => {
row.isExecute = true
executePlan({ planGuid: row.guid, reportGuid: row.reportGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
getTableData();
proxy.$ElMessage.success('执行完成');
} else {
proxy.$ElMessage.error(res.msg);
}
row.isExecute = false
}).catch(() => {
row.isExecute = false
})
}
});
}
btnsArr.push({
label: "日志", value: "path_log", disabled: row.execState == 0, click: (scope) => {
router.push({
name: 'damQualityAssessLog',
query: {
guid: row.damGuid,
name: row.damName,
reportGuid: row.reportGuid
}
});
}
});
btnsArr.push({
label: "删除", value: "delete", disabled: row.execState == 1 || row.isExecute, click: (scope) => {
if (scope.row.createUserId && userData.userGuid !== scope.row.createUserId) {
proxy.$ElMessage.error('只有创建人才可以删除该资产质量评估');
return;
}
proxy.$openMessageBox("确定要删除该资产质量评估吗?", () => {
deleteQualityPlan([scope.row.guid]).then((res: any) => {
if (res.code == proxy.$passCode) {
page.value.curr = 1;
/** 将当前查询到的删除了,清除。 */
if (page.value.damGuid == row.damGuid) {
page.value.damGuid = '';
serachFormRef.value?.toolSearch?.formRef?.resetFields?.();
getTableData();
} else {
getTableData();
}
proxy.$ElMessage.success('删除该资产质量评估成功');
} else {
proxy.$ElMessage.error(res.msg);
}
});
}, () => {
proxy.$ElMessage.info("已取消删除");
})
}
});
btnsArr.push({
label: 'SQL下载', value: 'sqldown', disabled: row.execState == 1 || row.isExecute || row.execState == 0, click: (scope) => {
downPlanSql(scope.row.guid).then((res: any) => {
if (res && !res.msg) {
download(res, `SQL-${scope.row.damName}.zip`, 'zip');
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
});
}
});
return btnsArr
}
}
});
const toSearch = (val: any, clear: boolean = false) => {
page.value.curr = 1;
if (clear) {
searchItemList.value.map(item => item.default = '')
page.value.damGuid = '';
getTableData(false);
return;
}
page.value.damGuid = val.damGuid;
getTableData(false);
};
/**
* 调用接口刷新获取方案表格数据
* @param refreshData 如果是刷新数据,需要更新查询列表。
*/
const getTableData = (refreshData = true) => {
tableInfo.value.loading = true;
getQualityList({
pageIndex: page.value.curr, pageSize: page.value.limit,
damGuid: page.value.damGuid
}).then((res: any) => {
tableInfo.value.loading = false;
if (res === undefined) {
return;
}
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 {
proxy.$ElMessage.error(res.msg);
}
})
if (refreshData) {
getSearchQualityDamList();
}
};
/** 监听处理分页事件。 */
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData(false);
};
const handleCreate = () => {
router.push({
name: 'damQualityPlan'
});
}
const getSearchQualityDamList = () => {
getQualityDamList().then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
searchItemList.value[0].options = data;
} else {
proxy.$ElMessage.error(res.msg);
}
});
}
onBeforeMount(() => {
if (!assetStore.qualityAssessRefresh) {
getSearchQualityDamList();
}
});
onActivated(() => {
if (assetStore.qualityAssessRefresh) {
page.value.curr = 1;
getTableData();
assetStore.setQualityAssessRefresh(false);
}
})
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap has_search">
<Table_tools ref="serachFormRef" :searchItems="searchItemList" searchId="quality-search" @search="toSearch" />
<div class="tools_btns">
<el-button type="primary" @click="handleCreate">新建</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
</div>
</template>
<style lang="scss" scoped>
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
:deep(.table-tools) {
.el-select {
width: 230px;
}
}
.tools_btns {
padding: 8px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 8px 8px 0;
}
</style>
\ No newline at end of file
<route lang="yaml">
name: damQualityAssessLog
</route>
<script lang="ts" setup name="damQualityAssessLog">
import { ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import {
getAssessDetailTableData,
} from '@/api/modules/dataAssetQuality';
import { ElMessage } from "element-plus";
import { changeNum } from '@/utils/common';
import { TableColumnWidth } from "@/utils/enum"
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
/** 方案guid */
const planGuid = route.query.guid;
const reportGuid = route.query.reportGuid;
const planName = route.query.name;
const execType = route.query.type;
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 tableInfo = ref({
id: "user-authority-table",
fields: [
{ type: "index", width: TableColumnWidth.INDEX, align: "center", label: "序号" },
{ label: "数据资产名称", field: "damName", width: 160 },
{ label: "所属企业", field: "tenantName", width: 240 },
{ label: "质量评分", field: "qualityScore", width: 120, align: 'right' },
{ label: "执行状态", field: "execResult", width: TableColumnWidth.STATE, align: 'center', type: "tag" },
{ label: "执行时间", field: "lastExecTime", width: TableColumnWidth.DATETIME, },
{ label: "执行人", field: "updateUserName", width: TableColumnWidth.USERNAME },
],
loading: false,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 160,
fixed: 'right',
btns: (scope) => {
return [
{ label: "查看报告", disabled: scope.row.execResult != 'Y', value: "reportView", click: (scope) => {
let row = scope.row;
router.push({
name: 'damAnalysisReport',
query: {
planGuid: row.planGuid,
name: row.damName,
reportExecGuid: row.reportExecGuid
}
});
} },
{
label: "查看结果", value: "resultView", click: (scope) => {
let row = scope.row;
router.push({
name: 'damAssessDetail',
query: {
name: row.damName,
planExecGuid: row.planExecGuid
}
});
}
},
]
}
}
});
const formTable = ref({
type: "table",
title: "",
col: 'no-margin',
tableInfo: {
id: "log-detail-table",
loading: false,
fields: [
{ label: "执行时间", field: "changeTime", width: 140, },
{ label: "日志类型", field: "metaCurrValue", width: 120 },
{ label: "日志级别", field: "collectTaskName", width: 110 },
{ label: "执行步骤", field: "updateType", width: 240 },
],
data: [],
showPage: false,
actionInfo: {
show: false
},
},
})
const drawerInfo: any = ref({
visible: false,
direction: "rtl",
modalClass: "wrap_width_auto",
size: 650,
header: {
title: "日志详情",
},
type: '',
container: {
contents: [
formTable.value,
],
},
footer: {
visible: false,
},
})
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true;
getAssessDetailTableData({ pageSize: page.value.limit, pageIndex: page.value.curr, damGuid: planGuid, reportGuid: reportGuid }).then((res: any) => {
tableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize ?? 50;
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows ?? 0;
} else {
ElMessage.error(res.msg);
}
});
};
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
if (type == 'resultView') {
if (!!execType) {
router.push({
name: 'syncAssessDetail',
query: {
name: planName,
planGuid: row.planGuid,
planExecGuid: row.planExecGuid
}
});
} else {
router.push({
name: 'assessDetail',
query: {
name: planName,
planGuid: row.planGuid,
planExecGuid: row.planExecGuid
}
});
}
} else if (type == 'log') {
const params = {
logGuid: row.guid
}
drawerInfo.value.visible = true
// formTable.value.tableInfo.loading = true;
// getLogDetail(params).then((res: any) => {
// formTable.value.tableInfo.loading = false;
// if (res.code == proxy.$passCode && res.data) {
// const data = res.data
// formTable.value.tableInfo.data = data
// drawerInfo.value.container.contents[0].listInfo.data = data
// drawerInfo.value.visible = true
// } else {
// ElMessage({
// type: "info",
// message: res.msg,
// });
// }
// })
}
};
const drawerBtnClick = (btn) => {
drawerInfo.value.visible = false;
};
onBeforeMount(() => {
getTableData();
});
</script>
<template>
<div class="container_wrap">
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" />
</div>
<Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" />
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0;
.table_panel_wrap {
height: 100%;
padding: 16px 16px 0;
}
}
:deep(.el-drawer) {
.drawer_panel {
height: 100%;
.table_panel_wrap {
height: 100%;
}
}
}
</style>
\ No newline at end of file
<route lang="yaml">
name: damQualityPlan
</route>
<script lang="ts" setup name="damQualityPlan">
import { onBeforeMount, ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import useUserStore from "@/store/modules/user";
import { useValidator } from '@/hooks/useValidator';
import { CirclePlus } from '@element-plus/icons-vue';
import {
getDamList,
getDamTableRulesList,
saveDamTableRules,
getDamTableList,
getRuleTypeList,
getSmallCategoryList,
getLargeCategoryList,
getRuleConfDetail,
updateDamTableRule,
deleteDamTableRule,
getModelRuleCount,
saveQualityPlan,
updateQualityPlan,
getPlanDetail,
getPlanFilterDetail
} from "@/api/modules/dataAssetQuality";
import tableRules from './tableRules.vue';
import tableRuleForm from './tableRuleForm.vue';
import { TableColumnWidth } from '@/utils/enum';
import { changeNum } from '@/utils/common';
import filtersSettingBatch from "./filtersSettingBatch.vue";
import useDataAssetStore from "@/store/modules/dataAsset";
const userStore = useUserStore();
const assetStore = useDataAssetStore();
const { proxy } = getCurrentInstance() as any;
const { required } = useValidator();
const router = useRouter();
const route = useRoute();
const fullPath = route.fullPath;
/** 编辑时会有guid */
const planGuid = route.query.guid;
const fullscreenLoading = ref(false);
/** 记录编辑时,规则是否被新增,编辑,删除过。 */
const editedTableRule = ref(false);
const step = ref(0);
const stepsInfo = ref({
step: step.value,
list: [
{ title: '配置数据质量规则', value: 1 },
{ title: '设置质量规则权重', value: 2 },
{ title: '执行配置的质量规则', value: 3 }
]
})
const damListData: any = ref([]);
const damGuid: any = ref('');
/** 规则中显示的表 */
const toSubjectTables: any = ref([]);
/** 资产目录表的原始值 */
const damSubjectTables: any = ref([]);
const ruleType: any = ref('');
const detailRuleInfo: any = ref({});
const tableRuleFormRef = ref();
const drawerInfoLoading = ref(false);
const damInfoFormRef = ref();
const damFormItems = ref([{
label: '资产名称',
type: 'select',
placeholder: '请选择',
field: 'damGuid',
default: damGuid.value,
options: damListData.value,
props: {
value: 'guid',
label: 'damName'
},
filterable: true,
clearable: true,
required: true,
visible: true,
disabled: false
}]);
const damFormRules = ref({
damGuid: [required('请选择资产名称')]
});
const modelRuleDetailTableInfo = ref({
id: "model-rule-table",
loading: false,
height: '300px',
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "表名称", field: "name", width: 140 },
{ label: "规则名称", field: "ruleConfName", width: 140 },
{ label: "规则大类", field: "largeCategoryName", width: 100 },
{ label: "规则小类", field: "smallCategoryName", width: 140 },
{ label: "规则类型", field: "ruleName", width: 140 },
{ label: "规则字段", field: "ruleField", width: 140 }
],
data: [],
showPage: false,
actionInfo: {
label: "操作",
type: "btn",
width: 110,
btns: [{
label: "编辑", value: "edit", click: (scope) => {
drawerInfo.value.type = 'edit';
drawerInfo.value.header.title = '编辑规则';
drawerInfo.value.visible = true;
drawerInfoLoading.value = true;
getRuleConfDetail(scope.row.guid).then((res: any) => {
drawerInfoLoading.value = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
detailRuleInfo.value = data;
ruleType.value = detailRuleInfo.value.ruleCode;
toSubjectTables.value = [{
guid: detailRuleInfo.value.subjectGuid, //编辑的时候显示的是主题表
tableName: detailRuleInfo.value.subjectName,
tableChName: detailRuleInfo.value.subjectZhName,
label: `${detailRuleInfo.value.subjectName}(${detailRuleInfo.value.subjectZhName})`
}]
detailRuleInfo.value.qualityModelGuids = [detailRuleInfo.value.subjectGuid];
} else {
proxy.$ElMessage.error(res.msg);
}
});
}
}, {
label: "删除", value: "delete", click: (scope) => {
proxy.$openMessageBox("确定要删除该资产表规则吗?", () => {
deleteDamTableRule(scope.row.guid, planGuid).then((res: any) => {
if (res.code == proxy.$passCode) {
planGuid && (editedTableRule.value = true);
getDamTableRulesData(damGuid.value);
proxy.$ElMessage.success('删除该资产表规则成功');
} else {
proxy.$ElMessage.error(res.msg);
}
});
}, () => {
proxy.$ElMessage.info("已取消删除");
})
}
}]
}
});
const drawerInfo = ref({
visible: false,
direction: 'rtl',
size: 600,
header: {
title: '新增规则',
},
type: '',
footer: {
btns: [
{ type: 'default', label: '取消', value: 'cancel' },
{ type: 'primary', label: '确定', value: 'save' },
]
}
})
const ruleTypeList = ref([]);
const smallCategoryList = ref([]);
const largeCategoryList = ref([]);
onBeforeMount(() => {
if (!planGuid) {
getDamList().then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
damListData.value = data;
damFormItems.value[0].options = damListData.value;
} else {
proxy.$ElMessage.error(res.msg);
}
});
} else {
fullscreenLoading.value = true;
getPlanDetail(planGuid).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
const data = res.data || {};
damGuid.value = data.damGuid;
damFormItems.value[0].default = data.damGuid;
damFormItems.value[0].disabled = true;
damFormItems.value[0].options = damFormItemsReadOnly.value[0].options = configFormItems.value[0].options = [{
guid: damGuid.value,
damName: data.damName
}]
getDamTableRulesData(damGuid.value);
getDamTableList(damGuid.value).then((res1: any) => {
if (res1.code == proxy.$passCode) {
toSubjectTables.value = res1.data || [];
damSubjectTables.value = res1.data || [];
getPlanFilterDetail(planGuid).then((res1: any) => {
fullscreenLoading.value = false;
if (res1.code == proxy.$passCode) {
let data1 = res1.data || [];
data1.forEach(d => {
let tables: any = [];
for (const id in d.qualityModelInfo) {
let table = damSubjectTables.value?.find(m => m.guid == id)
tables.push({
guid: id,
subjectGuid: table?.guid,
tableChName: table?.tableChName
});
}
batchFiltersValue.value[d.dataFilterGroup] = {
filter: d.dataRange,
tables: tables,
checked: true
}
});
} else {
proxy.$ElMessage.error(res1.msg);
}
});
} else {
proxy.$ElMessage.error(res1.msg);
}
});
ruleWeightData.value = data.modelRuleWeights?.map(r => {
r.ruleLargeWeight = r.ruleLargeWeight.toFixed(2);
return r;
}) || [];
configFormItems.value.forEach(item => {
item.default = data[item.field];
});
} else {
proxy.$ElMessage.error(res.msg);
}
});
}
getRuleTypeList().then((res: any) => {
if (res.code == proxy.$passCode) {
ruleTypeList.value = res.data?.map((d: any) => {
d.label = d.ruleName;
d.value = d.ruleCode;
return d;
})?.filter(t => t.value != 'rows_check' && t.value != 'volatility_check') || [];
} else {
proxy.$ElMessage.error(res.msg);
}
})
getSmallCategoryList().then((res: any) => {
if (res.code == proxy.$passCode) {
smallCategoryList.value = res.data || [];
} else {
proxy.$ElMessage.error(res.msg);
}
})
getLargeCategoryList().then((res: any) => {
if (res.code == proxy.$passCode) {
largeCategoryList.value = res.data || [];
} else {
proxy.$ElMessage.error(res.msg);
}
})
});
const handleDamInfoSelectChange = (val) => {
damGuid.value = val;
if (!val) {
modelRuleDetailTableInfo.value.data = [];
damGuid.value = '';
toSubjectTables.value = [];
damSubjectTables.value = [];
} else {
getDamTableRulesData(val);
getDamTableList(val).then((res: any) => {
if (res.code == proxy.$passCode) {
toSubjectTables.value = res.data || [];
damSubjectTables.value = res.data || [];
} else {
proxy.$ElMessage.error(res.msg);
}
});
}
}
/** 根据资产获取规则列表 */
const getDamTableRulesData = (damGuid) => {
modelRuleDetailTableInfo.value.loading = true;
getDamTableRulesList({
damGuid: damGuid,
}).then((res: any) => {
modelRuleDetailTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
modelRuleDetailTableInfo.value.data = res.data || [];
} else {
proxy.$ElMessage.error(res.msg);
}
});
}
/** 添加资产表规则 */
const addTableRules = () => {
drawerInfo.value.type = 'add';
tableRulesRef.value && tableRulesRef.value.initValue();
drawerInfo.value.visible = true;
drawerInfo.value.header.title = '新增规则';
toSubjectTables.value = damSubjectTables.value;
}
const tableRulesRef = ref();
const submitRulesLoading = ref(false);
/** 提交编辑修改的资产表规则 */
const addSubmitRules = () => {
if (drawerInfo.value.type == 'add') {
tableRulesRef.value && tableRulesRef.value.saveRules().then((info: any) => {
submitRulesLoading.value = true;
if (planGuid) {
info.forEach(rule => rule.planGuid = planGuid);
}
saveDamTableRules(info).then((res: any) => {
submitRulesLoading.value = false;
if (res.code == proxy.$passCode) {
planGuid && (editedTableRule.value = true);
proxy.$ElMessage.success('新增规则成功');
drawerInfo.value.visible = false;
tableRulesRef.value && tableRulesRef.value.clearValue();
getDamTableRulesData(damGuid.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
})
} else {
let ruleGuid = detailRuleInfo.value.guid;
/** 将新建规则之后转化为对应质检表的规则。 */
const transformRulesInfo = (info: any) => {
if (info.ruleCode == 'null_value_check' || info.ruleCode == 'repeate_data_check') {
return Object.assign({}, info, {
guid: ruleGuid,
qualityModelGuid: detailRuleInfo.value.qualityModelGuid,
ruleCode: detailRuleInfo.value.ruleCode,
ruleField: info.modelFields[detailRuleInfo.value.subjectZhName] || []
});
} else if (info.ruleCode === 'logic_check') {
let subjectName = detailRuleInfo.value.subjectName;
let fields = info.ruleFields[subjectName];
return Object.assign({}, info, {
guid: ruleGuid,
qualityModelGuid: detailRuleInfo.value.qualityModelGuid,
ruleCode: detailRuleInfo.value.ruleCode,
ruleField: [{
guid: fields.guid,
enName: fields.enName,
chName: fields.chName
}],
conditionSql: info.conditionSqls?.[subjectName],
conditionSqls: '',
ruleFields: ''
});
} else if (info.ruleCode === 'custom_sql') {
return Object.assign({}, info, {
guid: ruleGuid,
qualityModelGuid: detailRuleInfo.value.qualityModelGuid,
ruleCode: detailRuleInfo.value.ruleCode,
customSql: info.customSqls?.[detailRuleInfo.value.subjectName],
ruleField: info.ruleFields?.[detailRuleInfo.value.subjectName]?.map(f => {
return {
enName: f
}
}) || [],
fieldSelects: info.sqlFieldsList?.[detailRuleInfo.value.subjectName] || [],
customSqls: '',
ruleFields: ''
});
}
}
tableRuleFormRef.value?.ruleFormRef?.ruleFormRef?.validate((valid) => {
if (valid) {
let v = tableRuleFormRef.value?.getFormInfo();
let params = transformRulesInfo(v);
submitRulesLoading.value = true;
planGuid && (params.planGuid = planGuid);
updateDamTableRule(params).then((res: any) => {
submitRulesLoading.value = false;
if (res.code == proxy.$passCode) {
planGuid && (editedTableRule.value = true);
proxy.$ElMessage.success(`【${params.ruleConfName}】` + '规则编辑成功');
drawerInfo.value.visible = false;
tableRulesRef.value && tableRulesRef.value.clearValue();
getDamTableRulesData(damGuid.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
});
}
}
/** 取消修改资产表的规则 */
const cancelEditRules = () => {
proxy.$openMessageBox("当前修改内容尚未保存,确定取消吗?", () => {
drawerInfo.value.visible = false
tableRulesRef.value && tableRulesRef.value.clearValue();
}, () => {
proxy.$ElMessage.info("已取消");
});
}
const previousStep = (val) => {
step.value = val - 1;
stepsInfo.value.step = val - 1;
}
const nextStep = (val) => {
if (val == 1) {
damInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
if (valid) {
if (!modelRuleDetailTableInfo.value.data.length) {
proxy.$ElMessage.error('请配置当前资产的质量规则');
return;
}
ruleModelTableInfo.value.data = modelRuleDetailTableInfo.value.data || [];
if (!planGuid) {
getModelRuleCountListData();
} else { //编辑页面,直接读取后端的值即可。
if (editedTableRule.value) {
getModelRuleCountListData(true);
}
}
damFormItemsReadOnly.value[0].default = damGuid.value;
damFormItemsReadOnly.value[0].options = damListData.value;
step.value = val;
stepsInfo.value.step = val;
} else {
var obj = Object.keys(errorItem);
damInfoFormRef.value.ruleFormRef.scrollToField(obj[0])
}
});
} else if (val == 2) {
let sum = 0;
ruleWeightData.value.forEach(item => {
if (item.ruleLargeWeight != null) {
sum += parseFloat(item.ruleLargeWeight);
}
});
sum = changeNum(sum, 2);
if (!(sum <= 100.02 && sum >= 99.98)) {// 允许浮动0.01误差
proxy.$ElMessage.error('规则权重总分应为100分');
return;
}
configFormItems.value[0].default = damGuid.value;
configFormItems.value[0].options = damListData.value;
step.value = val;
stepsInfo.value.step = val;
}
}
/** -------------------- 第二步,权重规则设置 ----------------------------- */
const damFormItemsReadOnly = ref([{
label: '资产名称',
type: 'select',
placeholder: '请选择',
field: 'damGuid',
default: damGuid.value,
options: damListData.value,
props: {
value: 'guid',
label: 'damName'
},
disabled: true,
filterable: true,
clearable: true,
required: true,
visible: true
}]);
const ruleModelTableInfo = ref({
id: 'rule-model-table',
loading: false,
height: '200px',
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "表名称", field: "name", width: 140 },
{ label: "规则名称", field: "ruleConfName", width: 140 },
{ label: "规则大类", field: "largeCategoryName", width: 100 },
{ label: "规则小类", field: "smallCategoryName", width: 140 },
{ label: "规则类型", field: "ruleName", width: 140 },
{ label: "规则字段", field: "ruleField", width: 140 }
],
data: [],
showPage: false,
actionInfo: {
show: false
}
})
/** 选择的所有质检表对应的规则大类数量及权重占比。 */
const ruleWeightData: any = ref([]);
const ruleWeightDataLoading = ref(false);
const inputWeightChange = (val, row) => {
let strArr = val.split(".");
if (strArr.length > 1) {
let right = strArr[1];
if (right === "" || right.length < 2) {
row.ruleLargeWeight = val = parseFloat(val || 0).toFixed(2);
}
} else {
row.ruleLargeWeight = val = parseFloat(val || 0).toFixed(2);
}
};
/** 输入框输入触发事件 */
const inputEventWeightChange = (val, row) => {
row.ruleLargeWeight = row.ruleLargeWeight.toString().replace(/[^\d.]/g, "")
row.ruleLargeWeight = row.ruleLargeWeight.toString().replace(/\.{2,}/g, ".")
row.ruleLargeWeight = row.ruleLargeWeight.toString().replace(/^\D*(\d{0,3}(?:\.\d{0,2})?).*$/g, "$1")
if (row.ruleLargeWeight > 100) {
row.ruleLargeWeight = changeNum(100, 2, true);
}
}
/** 记录分组json的过滤条件。最后提交时需要转化到table里。 */
const batchFiltersValue: any = ref({});
const batchFiltersValueChange = (value) => {
batchFiltersValue.value = value;
}
const batchFilterDialogRef = ref();
/** 批量配置过滤条件 */
const handleFiltersAdd = () => {
batchFilterDialogRef.value?.openDialog(batchFiltersValue.value);
}
/** 根据所选择的模型表,获取对应的权重信息。 */
const getModelRuleCountListData = (isEdit = false) => {
ruleWeightDataLoading.value = true;
return getModelRuleCount({ damGuid: damGuid.value }).then((res: any) => {
ruleWeightDataLoading.value = false;
if (res.code == proxy.$passCode) {
if (isEdit) {
ruleWeightData.value = res.data?.map(r => {
r.ruleLargeWeight = r.ruleLargeWeight.toFixed(2);
return r;
}) || [];
editedTableRule.value = false;
return;
}
//新建时,可能是上一步,再下一步返回的。
let largeCategoryList: string[] = [];
if (ruleWeightData.value.length) {
largeCategoryList = ruleWeightData.value.map(d => d.largeCategory);
}
let data = res.data || [];
if (largeCategoryList.length != data.length) {
ruleWeightData.value = data;
if (ruleWeightData.value.length) {
let v = changeNum(100 / ruleWeightData.value.length, 2, true);
ruleWeightData.value.forEach(d => d.ruleLargeWeight = v);
}
} else {
if (data.some(d => !largeCategoryList.includes(d.largeCategory))) {
ruleWeightData.value = data;
if (ruleWeightData.value.length) {
let v = changeNum(100 / ruleWeightData.value.length, 2, true);
ruleWeightData.value.forEach(d => d.ruleLargeWeight = v);
}
} else {
// 不处理。使用原始值。
}
}
} else {
proxy.$ElMessage.error(res.msg);
}
});
}
/** ----------------------- 第三步 -------------------------------- */
const configInfoFormRef = ref();
const configFormItems = ref([
{
label: '资产名称',
type: 'select',
placeholder: '请选择',
field: 'damGuid',
default: damGuid.value,
options: damListData.value,
props: {
value: 'guid',
label: 'damName'
},
disabled: true,
filterable: true,
clearable: true,
required: true,
visible: true
},
{
label: '报告保留期数(期)',
type: 'input',
inputType: 'integerNumber',
placeholder: '请输入正整数,不超过20',
field: 'reportReserveCycle',
default: 7,
max: 20,
min: 1,
clearable: true,
required: false,
visible: true
},
{
label: "立即执行",
type: "radio-group",
placeholder: "",
field: "isExec",
default: 'Y',
options: [
{
label: "是",
value: "Y",
},
{
label: "否",
value: 'N',
},
],
required: true,
},
]);
const configFormRules = ref({
reportReserveCycle: [required('请填写报告保留期数')]
});
const save = () => {
configInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => {
if (valid) {
let params = { ...configInfoFormRef.value.formInline, isCreateReport: 'Y', ruleWeights: ruleWeightData.value };
let models: any = [];
let transferFilters: any = [];
for (const key in batchFiltersValue.value) {
let info = batchFiltersValue.value[key];
if (info.tables.length) {
info.tables.forEach(t => {
transferFilters.push(Object.assign({}, t, {
filter: info.filter,
dataFilterGroup: key
}));
});
}
}
damSubjectTables.value.forEach(t => {
let filterInfo = transferFilters.find(b => b.guid == t.guid);
let rule: any = ruleModelTableInfo.value.data.find((d: any) => d.subjectGuid == t.guid)
models.push({
qualityModelGuid: rule?.qualityModelGuid,
subjectGuid: t.guid,
dataRange: filterInfo?.filter,
dataFilterGroup: filterInfo?.dataFilterGroup,
});
});
params.models = models;
if (planGuid) {
params.guid = planGuid;
fullscreenLoading.value = true;
updateQualityPlan(params).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
proxy.$ElMessage.success('资产质量评估编辑成功');
router.push({
name: 'damQualityAssess'
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.setQualityAssessRefresh(true);
} else {
proxy.$ElMessage.error(res.msg);
}
})
} else {
fullscreenLoading.value = true;
// params.damName =
saveQualityPlan(params).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
proxy.$ElMessage.success('新建资产质量评估保存成功');
router.push({
name: 'damQualityAssess'
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.setQualityAssessRefresh(true);
} else {
proxy.$ElMessage.error(res.msg);
}
})
}
}
})
}
const cancelPlan = () => {
proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
path: '/data-asset/quality-assess'
});
}, () => {
proxy.$ElMessage.info("已取消");
});
}
</script>
<template>
<div class="container_wrap full" v-loading="fullscreenLoading">
<div class="content_main">
<div class="top_tool_wrap">
<StepBar :steps-info="stepsInfo" />
</div>
<div class="operator_panel_wrap" v-show="step == 0">
<ContentWrap id="id-baseInfo" title="配置数据资产质量规则" description="">
<Form ref="damInfoFormRef" :itemList="damFormItems" formId="dam-base-form" :rules="damFormRules"
@select-change="handleDamInfoSelectChange" col="col3" />
<Table class="mt4" :tableInfo="modelRuleDetailTableInfo" />
<div class="row-add-btn">
<el-button :disabled="!damGuid" link @click="addTableRules" :icon="CirclePlus" v-preReClick>新增</el-button>
</div>
</ContentWrap>
</div>
<div class="operator_panel_wrap" v-show="step == 1">
<ContentWrap id="id-filterInfo" title="批量配置过滤条件" description="" class="mb16">
<Form ref="damInfoFormRef" :itemList="damFormItemsReadOnly" formId="dam-base-form2" col="col3" />
<div class="tools_btns">
<el-button type="primary" @click="handleFiltersAdd">批量配置过滤条件</el-button>
<span class="tips_text">批量给表添加质检数据范围,不需要写where关键字,支持函数。未填写默认质检全部数据。</span>
</div>
<Table :tableInfo="ruleModelTableInfo" />
</ContentWrap>
<ContentWrap id="id-ruleWeight" title="规则权重" description="">
<el-table class="rule-weight-table" ref="ruleWeightTableRef" v-loading="ruleWeightDataLoading"
:data="ruleWeightData" height="100%" :highlight-current-row="true" stripe tooltip-effect="light" border
:style="{ height: '100%', width: 'auto', 'max-width': '100%', display: 'inline-block' }">
<el-table-column prop="largeCategoryName" label="规则大类" width="150px" align="left" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="ruleCount" label="规则数量" width="150px" header-align="right" align="right"
show-overflow-tooltip>
</el-table-column>
<el-table-column prop="ruleLargeWeight" label="规则权重(总分100)" width="200px" align="left"
show-overflow-tooltip>
<template #default="scope">
<el-input v-model.trim="scope.row['ruleLargeWeight']" placeholder="请输入"
@change="(val) => inputWeightChange(val, scope.row)"
@input="(val) => inputEventWeightChange(val, scope.row)"></el-input>
</template>
</el-table-column>
</el-table>
</ContentWrap>
</div>
<div class="operator_panel_wrap" v-show="step == 2">
<ContentWrap id="id-baseInfo" title="执行配置的质量规则" description="">
<Form ref="configInfoFormRef" :itemList="configFormItems" formId="config-base-form" :rules="configFormRules"
col="col3" />
</ContentWrap>
</div>
</div>
<div class="bottom_tool_wrap">
<template v-if="step == 0">
<el-button @click="cancelPlan">取消</el-button>
<el-button type="primary" @click="nextStep(1)">下一步</el-button>
</template>
<template v-else-if="step == 1">
<el-button @click="cancelPlan">取消</el-button>
<el-button type="primary" @click="previousStep(1)">上一步</el-button>
<el-button type="primary" @click="nextStep(2)">下一步</el-button>
</template>
<template v-else>
<el-button @click="cancelPlan">取消</el-button>
<el-button type="primary" @click="previousStep(2)">上一步</el-button>
<el-button type="primary" v-preReClick @click="save">提交</el-button>
</template>
</div>
<filtersSettingBatch ref="batchFilterDialogRef" :subject-tables="damSubjectTables"
@filtersValueChange="batchFiltersValueChange"></filtersSettingBatch>
<el-drawer v-model="drawerInfo.visible" :size="drawerInfo.size" :close-on-click-modal="false"
:close-on-press-escape="false" :before-close="cancelEditRules">
<template #header>
<span class="title">{{ drawerInfo.header.title }}</span>
</template>
<template #default>
<tableRules v-if="drawerInfo.type == 'add'" ref="tableRulesRef" :damGuid="damGuid"
:toSubjectTables="toSubjectTables" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
:smallCategoryList="smallCategoryList"></tableRules>
<div class="drawer-form-content" v-else v-loading="drawerInfoLoading">
<tableRuleForm ref="tableRuleFormRef" :toSubjectTables="toSubjectTables" :ruleTypeValue="ruleType"
:value="detailRuleInfo" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
:smallCategoryList="smallCategoryList"></tableRuleForm>
</div>
</template>
<template #footer>
<div style="flex:auto">
<el-button v-preReClick @click="cancelEditRules">取消</el-button>
<el-button type="primary" :loading="submitRulesLoading" v-preReClick @click="addSubmitRules">确定</el-button>
</div>
</template>
</el-drawer>
</div>
</template>
<style scoped lang="scss">
.top_tool_wrap {
width: 100%;
height: 72px;
margin: 8px 0 0px;
display: flex;
justify-content: center;
align-items: center;
:deep(.el-steps) {
width: 50%;
justify-content: center;
}
}
.content_main {
height: calc(100% - 40px);
padding: 0 16px;
overflow: hidden auto;
.operator_panel_wrap {
height: auto;
.tools_btns {
margin-bottom: 8px;
.tips_text {
margin-left: 8px;
font-size: 12px;
color: #b2b2b2;
}
}
}
}
.row-add-btn {
.el-button:focus-visible {
outline: none;
}
.el-button--default {
padding: 8px 0px;
}
:deep(.el-icon) {
width: 16px;
height: 16px;
svg {
width: 16px;
height: 16px;
}
}
}
.bottom_tool_wrap {
height: 40px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
display: flex;
justify-content: flex-end;
align-items: center;
}
:deep(.el-drawer) {
.el-drawer__body {
padding: 0px;
.drawer-form-content {
height: 100%;
width: 100%;
&>.el-form {
padding: 16px;
}
}
}
}
.mt4 {
margin-top: 4px;
}
:deep(.rule-weight-table.el-table) {
& td.el-table__cell {
padding: 2px 0;
height: 36px;
}
}
</style>
\ No newline at end of file
......@@ -8,9 +8,8 @@ import {
getParamsList,
chTransformEn
} from "@/api/modules/dataAsset";
import { pinyin } from 'pinyin-pro';
import useUserStore from "@/store/modules/user";
import { getDictionaryTree } from '@/api/modules/dataInventory';
import { getDictionaryTree } from '@/api/modules/dataAsset';
const emits = defineEmits([
"cancelImport",
......
<route lang="yaml">
name: assetIndex
</route>
<script lang="ts" setup name="assetIndex">
import { ref } from "vue";
import * as echarts from "echarts";
import {
getHomeServiceInfo,
getStatisticsInfo,
getRegisterInfo,
getDaTradeInfo,
getQualityInfo,
getFinanceInfo,
getRegisterUrl,
} from "@/api/modules/dataAssetIndex";
import { getImageContent } from "@/api/modules/queryService";
import { ElMessage } from "element-plus";
import { calcColumnWidth } from "@/utils/index";
import { changeNum } from "@/utils/common";
import useUserStore from "@/store/modules/user";
import platformIndex from "./platformIndex.vue";
import { useRouter, useRoute } from "vue-router";
import Moment from "moment";
const router = useRouter();
const userStore = useUserStore();
const userData = JSON.parse(userStore.userData);
const { proxy } = getCurrentInstance() as any;
const noData = ref(false);
/** 资产登记数 */
const registerNum = ref(0);
const registerNumUrl = new URL(
"@/assets/images/registerNum.png",
import.meta.url
).href;
/** 价值评估数 */
const costAssessNum = ref(0);
const costAssessNumUrl = new URL(
"@/assets/images/costAssess.png",
import.meta.url
).href;
/** 证书url */
const docUrl: any = ref([]);
const docUrlList: any = ref([
[
{
url: new URL("@/assets/images/icon1.png", import.meta.url).href,
},
{
url: new URL("@/assets/images/icon2.png", import.meta.url).href,
},
{
url: new URL("@/assets/images/icon3.png", import.meta.url).href,
},
],
[
{
url: new URL("@/assets/images/icon4.png", import.meta.url).href,
},
{
url: new URL("@/assets/images/icon5.png", import.meta.url).href,
},
],
]);
const cardList = ref([
{
name: "dataScale",
value: 0,
label: "数据规模",
unit: " GB",
},
{
name: "tableNum",
value: 0,
label: "表数量",
unit: "",
},
{
name: "fieldNum",
value: 0,
label: "字段数量",
unit: "",
},
{
name: "assessmentMoney",
value: 0,
label: "资产估值",
unit: " 万元",
},
{
name: "intableNum",
value: 0,
label: "入表资产数",
unit: "",
},
{
name: "noIntableNum",
value: 0,
label: "未入表资产数",
unit: "",
},
{
name: "lastIntableTime",
value: "--",
label: "最近入表时间",
unit: "",
},
{
name: "dataCategoryNum",
value: 0,
label: "数据分类",
unit: "",
},
{
name: "dataGradeNum",
value: 0,
label: "数据分级",
unit: "",
},
]);
const checkImage = () => {
let a: any = document.querySelector(".el-image-viewer__actions__inner");
let lenBtn = a.getElementsByClassName("el-icon");
if (lenBtn.length == 6) {
return;
}
let ff = document.createElement("i");
ff.classList.add("el-icon");
ff.addEventListener("click", () => {
let imgsrc = (<HTMLImageElement>(
document.querySelector(".el-image-viewer__img")
))?.src;
let image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context: any = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
let a = document.createElement("a"); // 生成一个a元素
let event = new MouseEvent("click"); // 创建一个单击事件
a.download = "资产登记证书"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
image.src = imgsrc;
});
ff.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" data-v-ea893728=""><path fill="currentColor" d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64m384-253.696 236.288-236.352 45.248 45.248L508.8 704 192 387.2l45.248-45.248L480 584.704V128h64z"></path></svg>`;
a.appendChild(ff);
};
const assetPage = 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 },
],
rows: 0,
});
const assetTableInfo = ref({
id: "asset-table",
multiple: false,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{
label: "资产名称",
field: "daName",
width: 140,
type: "text_btn",
columClass: 'text_btn',
value: "detail",
},
{
label: "登记日期",
field: "registerTime",
width: 120,
getName: (scope) => {
if (!scope.row.registerTime) {
return "--";
}
return Moment(scope.row.registerTime).format("YYYY-MM-DD");
},
},
{ label: "交易所", field: "exchangeName", width: 250 },
{
label: "资产登记",
field: "register",
width: 100,
getSvg: (scope) => {
return scope.row.register == "已登记" ? "icon-success" : "icon-audit";
},
},
{
label: "质量评价",
field: "quality",
width: 100,
getSvg: (scope) => {
return scope.row.quality == "已评价" ? "icon-success" : "icon-audit";
},
},
{
label: "价值评估",
field: "cost",
width: 100,
getSvg: (scope) => {
return scope.row.cost == "已评估" ? "icon-success" : "icon-audit";
},
},
{
label: "入表",
field: "intable",
width: 100,
getSvg: (scope) => {
return scope.row.intable == "已入表" ? "icon-success" : "icon-audit";
},
},
{
label: "交易",
field: "trade",
width: 100,
getSvg: (scope) => {
return scope.row.trade == "已交易" ? "icon-success" : "icon-audit";
},
},
{
label: "融资",
field: "financing",
width: 100,
getSvg: (scope) => {
return scope.row.financing == "已融资" ? "icon-success" : "icon-audit";
},
},
],
data: [],
page: {
type: "concise",
showCount: true,
...assetPage.value,
},
actionInfo: {
show: false,
},
loading: false,
});
const getAssetTableData = () => {
assetTableInfo.value.loading = true;
getRegisterInfo({
pageSize: assetPage.value.limit,
pageIndex: assetPage.value.curr,
}).then((res: any) => {
assetTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
assetTableInfo.value.data = data.records || [];
assetPage.value.rows = data.totalRows ?? 0;
assetTableInfo.value.page.rows = data.totalRows ?? 0;
} else {
ElMessage.error(res.msg);
}
});
};
const assetTablePageChange = (info) => {
assetPage.value.curr = Number(info.curr);
assetPage.value.limit = Number(info.limit);
getAssetTableData();
};
const tableBtnClick = (scope, btn) => {
const type = btn.value;
let row = scope.row;
if (type == "detail") {
router.push({
name: "registerInfoDetail",
query: {
guid: row.registerGuid,
type: "asset",
daTenantGuid: userData.tenantGuid,
},
});
}
};
let qualityPieChart: any = null;
const qualityPieData: any = ref([]);
/** 设置柱形图option,默认只 展示12次的 */
const setPieChartOption = () => {
if (!qualityPieData.value.length) {
let option1 = {
title: [
{
text: "",
left: "30px",
top: "30px",
},
{
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
fontStyle: "normal",
fontWeight: "400",
fontSize: 18,
},
},
],
};
qualityPieChart.setOption(option1, true);
window.addEventListener("resize", () => {
qualityPieChart.resize();
});
return;
}
let sum = qualityPieData.value
.map((d) => d.value)
.reduce(function (prev, curr, idx, arr) {
return prev + curr;
});
let option = {
textStyle: {
fontFamily: "SimSun",
},
color: ["#4DC5BE", "#40A9FF", "#FF8601"],
legend: {
// left: "right",
orient: "vertical",
top: "middle",
// right: 50,
x: "60%",
y: "cenetr",
itemGap: 20,
icon: "circle",
itemHeight: 10,
align: "left",
textStyle: {
color: "#666666",
fontSize: 14,
},
},
series: [
{
name: "quality",
type: "pie",
center: ["30%", "50%"],
radius: ["60%", "80%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
label: {
show: true,
position: "center",
fontSize: 24,
formatter: ["{a|已评估资产}", `{b|${changeNum(sum)}}{c| 个}`].join("\n"),
rich: {
a: {
fontSize: 16,
color: "#212121",
fontWeight: 600,
lineHeight: 27,
},
b: {
fontSize: 24,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
c: {
fontSize: 18,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
},
},
emphasis: {
focus: "self",
label: {
show: true,
formatter: (params) => {
return [
`{a|${params.data.originName}}`,
`{b|${params.percent}%}`,
].join("\n");
},
fontSize: 24,
fontWeight: "bold",
rich: {
a: {
fontSize: 16,
color: "#212121",
fontWeight: 600,
lineHeight: 27,
},
b: {
fontSize: 24,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
},
},
},
labelLine: {
show: false,
},
data: qualityPieData.value.map((d) => {
return {
value: d.value,
name: `${d.name} ${(d.value / sum) * 100}% ${changeNum(
d.value
)}个`,
originName: d.name,
};
}),
},
],
};
option && qualityPieChart.setOption(option, true);
window.addEventListener("resize", () => {
qualityPieChart.resize();
});
};
const tradePage = 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 tradeTableInfo = ref({
id: "trade-table",
multiple: false,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{
label: "资产名称",
field: "daName",
width: 140,
type: "text_btn",
columClass: 'text_btn',
value: "detail",
},
{ label: "交易日期", field: "tradeTime", width: 120 },
{ label: "交易对象", field: "tradeObject", width: 250 },
],
data: [],
page: {
type: "concise",
showCount: true,
rows: 0,
...tradePage.value,
},
actionInfo: {
show: false,
},
loading: false,
});
const getTradeTableData = () => {
tradeTableInfo.value.loading = true;
getDaTradeInfo({
pageSize: tradePage.value.limit,
pageIndex: tradePage.value.curr,
}).then((res: any) => {
tradeTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
tradeTableInfo.value.data = data.records || [];
tradeTableInfo.value.page.rows = data.totalRows ?? 0;
} else {
ElMessage.error(res.msg);
}
});
};
const tradeTablePageChange = (info) => {
tradePage.value.curr = Number(info.curr);
tradePage.value.limit = Number(info.limit);
getTradeTableData();
};
const tradeTableBtnClick = (scope, btn) => {
const type = btn.value;
let row = scope.row;
if (type == "detail") {
router.push({
name: "registerInfoDetail",
query: {
guid: row.registerGuid,
type: "asset",
daTenantGuid: userData.tenantGuid,
},
});
}
};
const financingPage = 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 financingTableInfo = ref({
id: "financing-table",
multiple: false,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{
label: "资产名称",
field: "daName",
width: 140,
type: "text_btn",
columClass: 'text_btn',
value: "detail",
},
{ label: "授信日期", field: "creditGrantingTime", width: 120 },
{ label: "授信主体", field: "creditGrantingGenerality", width: 250 },
{
label: "授信金额(万元)",
field: "creditGrantingMoney",
width: 140,
align: "right",
getName: (scope) => {
return changeNum(scope.row.creditGrantingMoney ?? 0, 2, true);
},
},
{
label: "授信期限(月)",
field: "creditGrantingTerm",
width: 140,
align: "right",
getName: (scope) => {
return changeNum(scope.row.creditGrantingTerm ?? 0);
},
},
],
data: [],
page: {
type: "concise",
showCount: true,
rows: 0,
...financingPage.value,
},
actionInfo: {
show: false,
},
loading: false,
});
const getFinancingTableData = () => {
financingTableInfo.value.loading = true;
getFinanceInfo({
pageSize: financingPage.value.limit,
pageIndex: financingPage.value.curr,
}).then((res: any) => {
financingTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
financingTableInfo.value.data = data.records || [];
financingTableInfo.value.page.rows = data.totalRows ?? 0;
} else {
ElMessage.error(res.msg);
}
});
};
const financingTablePageChange = (info) => {
financingPage.value.curr = Number(info.curr);
financingPage.value.limit = Number(info.limit);
getFinancingTableData();
};
const financingTableBtnClick = (scope, btn) => {
const type = btn.value;
let row = scope.row;
if (type == "detail") {
router.push({
name: "registerInfoDetail",
query: {
guid: row.registerGuid,
type: "asset",
daTenantGuid: userData.tenantGuid,
},
});
}
};
const serviceDataTitle: any = ref([
{
url: new URL("@/assets/images/service.png", import.meta.url).href,
title: "数据服务经济商",
},
{
url: new URL("@/assets/images/register.png", import.meta.url).href,
title: "登记机构",
},
{
url: new URL("@/assets/images/cost.png", import.meta.url).href,
title: "价值评估机构",
},
{
url: new URL("@/assets/images/credit.png", import.meta.url).href,
title: "授信机构",
},
{
url: new URL("@/assets/images/trade.png", import.meta.url).href,
title: "交易机构",
},
]);
const serviceData: any = ref([{}, {}, {}, {}, {}]);
const calcTableColumnWidth = (data: any[], prop) => {
let d: any[] = [];
data.forEach((dt) => d.push(dt[prop]));
return calcColumnWidth(
d,
"",
{
fontSize: 14,
fontFamily: "SimSun",
},
{
fontSize: 14,
fontFamily: "SimSun",
}
);
};
/** 记录列宽 */
const originTableFieldColumn = ref({});
/** 记录最大列值 */
const maxLen = ref(0);
/** 所有列宽和 */
const columnSumWidth = computed(() => {
let sum = 0;
for (const key in originTableFieldColumn.value) {
sum += originTableFieldColumn.value[key];
}
return sum;
});
/** 统计数量加载状态。 */
const statisticsInfoLoading = ref(false);
/** 服务机构信息加载状态 */
const serviceLoading = ref(false);
/** 饼图数据质量加载状态。 */
const qualityPieLoading = ref(false);
/** 证书图片加载 */
const docUrlLoading = ref(false);
onBeforeMount(() => {
if (userData.tenantType == 1) {
getAssetTableData();
statisticsInfoLoading.value = true;
getStatisticsInfo().then((res: any) => {
statisticsInfoLoading.value = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
registerNum.value = data.registerNum ?? 0;
costAssessNum.value = data.costAssessNum ?? 0;
cardList.value.forEach((card) => {
if (card.name == "lastIntableTime") {
card.value = data[card.name] ?? "--";
} else if (
card.name == "assessmentMoney" ||
card.name == "dataScale"
) {
card.value = changeNum(data[card.name] ?? 0, 2, true);
} else {
card.value = changeNum(data[card.name] ?? 0);
}
});
} else {
ElMessage.error(res.msg);
}
});
qualityPieLoading.value = true;
getQualityInfo().then((res: any) => {
qualityPieLoading.value = false;
qualityPieChart = echarts.init(document.getElementById("pie-quality"));
if (res.code == proxy.$passCode) {
qualityPieData.value = res.data || [];
setPieChartOption();
} else {
ElMessage.error(res.msg);
}
});
getTradeTableData();
getFinancingTableData();
docUrlLoading.value = true;
getRegisterUrl().then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data || [];
if (data.length) {
let ps: any = [];
for (const d of data) {
ps.push(
getImageContent(d).then((res: any) => {
if (res) {
return URL.createObjectURL(res);
}
})
);
}
Promise.all(ps).then((res: any[]) => {
console.log(res);
docUrl.value = res;
docUrlList.value = res.flatMap((value, index, array) => {
if (index % 2 === 0) {
return [
array.slice(index, index + 2).map((a) => {
return { url: a };
}),
];
}
return [];
});
docUrlLoading.value = false;
});
} else {
docUrl.value = [];
docUrlList.value = [];
docUrlLoading.value = false;
}
} else {
docUrlLoading.value = false;
ElMessage.error(res.msg);
}
});
serviceLoading.value = true;
getHomeServiceInfo().then((res: any) => {
serviceLoading.value = false;
if (res.code == proxy.$passCode) {
const data = res.data || {
serviceName: ["会员A"],
registerOrgName: [
"北京国际大数据交易所有限责任公司",
"贵阳大数据交易所",
],
costOrgName: ["会员A"],
creditGrantingOrgName: ["3213"],
tradeOrgName: ["hhhmmmm111"],
};
let serviceName = data.serviceName || [];
let registerOrgName = data.registerOrgName || [];
let costOrgName = data.costOrgName || [];
let creditGrantingOrgName = data.creditGrantingOrgName || [];
let tradeOrgName = data.tradeOrgName || [];
let maxLength = (maxLen.value = Math.max(
serviceName.length,
registerOrgName.length,
costOrgName.length,
creditGrantingOrgName.length,
tradeOrgName.length
));
for (let i = 0; i < maxLength; i++) {
serviceData.value.forEach((s, j) => {
s[i + 1 + ""] =
j == 0
? serviceName[i]
: j == 1
? registerOrgName[i]
: j == 2
? costOrgName[i]
: j == 3
? creditGrantingOrgName[i]
: tradeOrgName[i];
});
originTableFieldColumn.value[i + 1 + ""] =
calcTableColumnWidth(serviceData.value, i + 1 + "") - 20;
}
console.log(serviceData.value);
} else {
ElMessage.error(res.msg);
}
});
}
});
</script>
<template>
<div v-if="userData.tenantType == 1" class="main-scroll">
<div class="main-content">
<div class="one-row">
<div class="left" :style="{ width: 'calc(40% - 4px)' }">
<div class="header">
<span class="header-title">证书登记情况</span>
</div>
<div class="content">
<div class="icon-sum">
<template v-if="!statisticsInfoLoading">
<div class="img_tags_card" :style="{ background: '#ECF2FF' }">
<img :src="registerNumUrl" alt="" />
<div class="tags_item">
<p class="tag_text">资产登记数</p>
<p class="tag_num">
<span>{{ changeNum(registerNum) }}</span><span class="unit"></span>
</p>
</div>
</div>
<div class="img_tags_card" :style="{ background: '#FFF0E1' }">
<img :src="costAssessNumUrl" alt="" />
<div class="tags_item">
<p class="tag_text">价值评估数</p>
<p class="tag_num">
<span>{{ changeNum(costAssessNum) }}</span><span class="unit"></span>
</p>
</div>
</div>
</template>
<el-skeleton v-else :rows="1" animated :style="{ height: '80px' }" />
</div>
<el-carousel v-if="!docUrlLoading" :interval="2000">
<el-carousel-item class="img-card" v-for="(imgData, i) in docUrlList" :key="i" @click="checkImage">
<template v-for="(img, index) in imgData" :key="index">
<el-image class="top-img" :src="img.url" :zoom-rate="1.2" :max-scale="10" :min-scale="0.2"
:preview-src-list="docUrl" :initial-index="i * 3 + index" :preview-teleported="true" fit="cover" />
</template>
</el-carousel-item>
</el-carousel>
<el-skeleton class="el-ske-crousel" v-else>
<template #template>
<el-skeleton-item class="el-ske-img" variant="image" />
</template>
</el-skeleton>
</div>
</div>
<div class="right" :style="{ width: 'calc(60% - 4px)' }">
<div class="header">
<span class="header-title">数据资产情况</span>
</div>
<div class="num-content">
<div class="icon-sum num-sum" v-if="!statisticsInfoLoading" v-for="item in cardList">
<div class="tags_item">
<p class="tag_text">{{ item.label }}</p>
<p class="tag_num">
<span>{{ item.value }}</span>
<span class="unit">{{ item.unit }}</span>
</p>
</div>
</div>
<el-skeleton v-else :rows="5" animated />
</div>
</div>
</div>
<div class="second-row">
<div class="header">
<span class="header-title">资产情况</span>
</div>
<div class="content">
<Table v-if="!assetTableInfo.loading" :tableInfo="assetTableInfo" @tablePageChange="assetTablePageChange"
@tableBtnClick="tableBtnClick" />
<el-skeleton v-else :rows="6" animated />
</div>
</div>
<div class="three-row">
<div class="left" :style="{ width: 'calc(40% - 4px)' }">
<div class="header">
<span class="header-title">数据资产质量情况</span>
</div>
<div class="content-chart-pie">
<el-skeleton class="content-chart-pie-ske" v-if="qualityPieLoading" :rows="7" animated />
<div id="pie-quality" class="pie"></div>
</div>
</div>
<div class="right" :style="{ width: 'calc(60% - 4px)' }">
<div class="header">
<span class="header-title">服务机构情况</span>
</div>
<template v-if="!serviceLoading">
<div class="content row-layout-left">
<template v-for="item in serviceDataTitle">
<el-row :gutter="10">
<el-col :span="6">
<img :src="item.url" :style="{ width: '32px', height: '32px' }" alt="" />
</el-col>
<el-col :span="14">
<div class="title">{{ item.title }}</div>
</el-col>
</el-row>
</template>
</div>
<div class="content row-layout-right">
<div class="scroll-container" :style="{
width: `${columnSumWidth * 2}px`,
}">
<div class="scroll-content" :style="{
width: `${columnSumWidth}px`,
}">
<template v-for="item in 5">
<el-row :gutter="10" :style="{ animationDuration: columnSumWidth / 50 + 's' }">
<template v-for="sd in maxLen">
<el-col :span="originTableFieldColumn[sd + '']">
<div class="title" :style="{
width: `${originTableFieldColumn[sd + '']}px`,
}">
{{ serviceData[item - 1][sd + ""] }}
</div>
</el-col>
</template>
</el-row>
</template>
</div>
<div class="virtual" :style="{
width: `${columnSumWidth + 40}px`,
}">
<template v-for="item in 5">
<el-row :gutter="10">
<template v-for="sd in maxLen">
<el-col :span="originTableFieldColumn[sd + '']">
<div class="title" :style="{
width: `${originTableFieldColumn[sd + '']}px`,
}">
{{ serviceData[item - 1][sd + ""] }}
</div>
</el-col>
</template>
</el-row>
</template>
</div>
</div>
</div>
</template>
<el-skeleton v-else :rows="7" animated :style="{ margin: '12px', width: 'calc(100% - 24px)' }" />
</div>
</div>
<div class="four-row">
<div class="left" :style="{ width: 'calc(40% - 4px)' }">
<div class="header">
<span class="header-title">资产交易情况</span>
</div>
<div class="content trade-con">
<Table v-if="!tradeTableInfo.loading" :tableInfo="tradeTableInfo" @tablePageChange="tradeTablePageChange"
@tableBtnClick="tradeTableBtnClick" />
<el-skeleton v-else :rows="5" animated />
</div>
</div>
<div class="right" :style="{ width: 'calc(60% - 4px)' }">
<div class="header">
<span class="header-title">资产授信情况</span>
</div>
<div class="content trade-con">
<Table v-if="!financingTableInfo.loading" :tableInfo="financingTableInfo"
@tablePageChange="financingTablePageChange" @tableBtnClick="financingTableBtnClick" />
<el-skeleton v-else :rows="5" animated />
</div>
</div>
</div>
<div class="foot-sty" style="white-space: pre-wrap;">北京传世博润科技有限公司 Copyright @ 2023-2024 <a
href="https://beian.miit.gov.cn" target="_blank">京ICP备2024044205号</a>
</div>
</div>
</div>
<platformIndex v-else-if="userData.tenantType != 1" />
<div v-else class="main-placeholder">
<img style="width: 480px; height: 110px;" src="../../../public/swzl_logo.gif" />
</div>
</template>
<style lang="scss" scoped>
.main-placeholder {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.main-scroll {
height: 100%;
overflow-y: auto;
}
.main-content {
background-color: #e2e7ef;
padding: 8px 8px 0px 8px;
}
.one-row {
height: 290px;
display: inline-flex;
width: 100%;
justify-content: space-between;
.icon-sum {
display: inline-flex;
width: 100%;
justify-content: space-between;
&.num-sum {
width: calc(33% - 4px);
}
.img_tags_card {
height: 80px;
width: calc(50% - 4px);
display: flex;
align-items: center;
border-radius: 4px;
padding-left: 12px;
img {
width: 48px;
height: 48px;
margin-right: 12px;
display: flex;
align-items: center;
}
}
.tags_item {
height: 50px;
display: flex;
flex-direction: column;
justify-content: space-between;
p {
font-size: 14px;
color: var(--el-text-color-regular);
margin: 0;
line-height: 21px;
&.tag_num {
color: var(--el-color-regular);
font-size: 24px;
font-weight: 700;
.unit {
font-size: 18px;
}
}
}
}
}
}
.right,
.left {
background-color: #fff;
height: 100%;
}
.header {
height: 40px;
border-bottom: 1px solid #e5e5e5;
display: flex;
align-items: center;
.header-title {
font-size: 14px;
color: #212121;
line-height: 21px;
font-weight: 600;
padding-left: 12px;
}
}
.content {
padding: 12px;
}
.num-content {
padding: 12px;
height: calc(100% - 40px);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.second-row {
height: 322px;
background-color: #fff;
margin-top: 8px;
.content {
height: calc(100% - 40px);
padding-bottom: 0px;
}
}
.three-row {
height: 366px;
display: inline-flex;
width: 100%;
justify-content: space-between;
margin-top: 8px;
.row-layout-left {
width: 200px;
height: calc(100% - 40px);
padding: 12px 0px 0px 12px;
display: inline-block;
&>.el-row:nth-child(odd) {
background-color: #fafafa;
}
.title {
font-size: 14px;
color: #0e5fd8;
line-height: 21px;
}
.el-row {
height: 60px;
margin-left: 0px !important;
margin-right: 0px !important;
.el-col:first-child {
padding-left: 18px !important;
}
.el-col:nth-child(2) {
margin-left: 13px !important;
}
.el-col {
display: flex;
align-items: center;
}
}
}
.row-layout-right {
width: calc(100% - 200px);
height: calc(100% - 40px);
padding: 12px 12px 0px 0px;
display: inline-block;
vertical-align: bottom;
overflow: hidden;
.title {
font-size: 14px;
color: #212121;
line-height: 21px;
}
.el-row {
height: 60px;
margin-left: 0px !important;
margin-right: 0px !important;
flex-wrap: nowrap;
.el-col {
display: flex;
align-items: center;
}
}
.scroll-container {
display: flex;
min-width: 200%;
animation: roll 10s infinite linear;
.scroll-content {
flex-shrink: 0;
min-width: 50%;
&>.el-row:nth-child(odd) {
background-color: #fafafa;
}
}
.virtual {
flex-shrink: 0;
// padding-left: 40px;
min-width: 50%;
.el-row {
padding-left: 10px !important;
}
&>.el-row:nth-child(odd) {
background-color: #fafafa;
}
}
}
}
}
@keyframes roll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
.four-row {
height: 312px;
display: inline-flex;
width: 100%;
justify-content: space-between;
margin-top: 8px;
.trade-con {
height: calc(100% - 40px);
padding-bottom: 0px;
}
}
:deep(.el-carousel) {
height: 140px;
margin-top: 8px;
.el-carousel__arrow--left {
left: 0px;
}
.el-carousel__arrow--right {
right: 0px;
}
.el-carousel__arrow {
width: 20px;
height: 48px;
opacity: 0.5;
background: #000000;
border-radius: 4px 0px 0px 4px;
}
.el-carousel__container {
height: 100%;
.img-card {
width: 100%;
display: flex;
padding: 5px 0px;
justify-content: center;
.top-img {
width: 33%;
margin-right: 15px;
cursor: pointer;
&:last-child {
margin-right: 0px;
}
}
}
}
}
.content-chart-pie {
width: 100%;
height: calc(100% - 40px);
padding: 12px;
position: relative;
.pie {
height: 100%;
width: 100%;
}
}
.content-chart-pie-ske {
position: absolute;
width: calc(100% - 24px);
}
.el-ske-crousel {
display: flex;
justify-content: center;
.el-ske-img {
width: 240px;
height: 140px;
margin-top: 8px;
}
}
</style>
<route lang="yaml">
name: platformIndex
</route>
<script lang="ts" setup name="platformIndex">
import { ref } from "vue";
import * as echarts from "echarts";
import {
getFinanceInfo,
getIndustryInfo,
getCreditMoneyInfo,
getPlatformStatisticsInfo,
getPlatformMonth,
getPlatformService,
} from "@/api/modules/dataAssetIndex";
import { ElMessage } from "element-plus";
import { changeNum } from "@/utils/common";
import { useRouter, useRoute } from "vue-router";
import useUserStore from "@/store/modules/user";
const router = useRouter();
const userStore = useUserStore();
const userData = JSON.parse(userStore.userData);
const { proxy } = getCurrentInstance() as any;
const cardList = ref([
{
name: "dataScale",
value: 0,
label: "数据规模",
unit: " GB",
},
{
name: "tableNum",
value: 0,
label: "表数量",
unit: "",
},
{
name: "fieldNum",
value: 0,
label: "字段数量",
unit: "",
},
{
name: "assessmentMoney",
value: 0,
label: "资产估值",
unit: " 万元",
},
{
name: "tradeNum",
value: 0,
label: "交易资产数",
unit: " 个",
},
{
name: "financingNum",
value: 0,
label: "融资资产数",
unit: " 个",
},
{
name: "daNum",
value: "0",
label: "数据资产数",
unit: " 个",
},
{
name: "registerNum",
value: 0,
label: "资产登记数",
unit: " 张",
},
{
name: "cooperationOrNum",
value: 0,
label: "合作机构数",
unit: " 个",
},
]);
const financingPage = 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 financingTableInfo = ref({
id: "financing-table",
multiple: false,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{
label: "企业名称",
field: "companyName",
width: 200,
},
{
label: "资产名称",
field: "daName",
width: 140,
type: "text_btn",
columClass: 'text_btn',
value: "detail",
},
{ label: "授信日期", field: "creditGrantingTime", width: 120 },
{ label: "授信主体", field: "creditGrantingGenerality", width: 250 },
{
label: "授信金额(万元)",
field: "creditGrantingMoney",
width: 140,
align: "right",
getName: (scope) => {
return changeNum(scope.row.creditGrantingMoney ?? 0, 2, true);
},
},
{
label: "授信期限(月)",
field: "creditGrantingTerm",
width: 140,
align: "right",
getName: (scope) => {
return changeNum(scope.row.creditGrantingTerm ?? 0);
},
},
],
data: [],
page: {
type: "concise",
showCount: true,
rows: 0,
...financingPage.value,
},
actionInfo: {
show: false,
},
loading: false,
});
const getFinancingTableData = () => {
financingTableInfo.value.loading = true;
getFinanceInfo({
pageSize: financingPage.value.limit,
pageIndex: financingPage.value.curr,
}).then((res: any) => {
financingTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
financingTableInfo.value.data = data.records || [];
financingTableInfo.value.page.rows = data.totalRows ?? 0;
} else {
ElMessage.error(res.msg);
}
});
};
const financingTablePageChange = (info) => {
financingPage.value.curr = Number(info.curr);
financingPage.value.limit = Number(info.limit);
getFinancingTableData();
};
const financingTableBtnClick = (scope, btn) => {
const type = btn.value;
let row = scope.row;
if (type == "detail") {
router.push({
name: "registerInfoDetail",
query: {
guid: row.registerGuid,
type: "asset",
daTenantGuid: row.companyGuid,
},
});
}
};
const statisticsInfoLoading = ref(false);
onBeforeMount(() => {
getFinancingTableData();
statisticsInfoLoading.value = true;
getPlatformStatisticsInfo().then((res: any) => {
statisticsInfoLoading.value = false;
if (res.code == proxy.$passCode) {
let data = res.data || {};
cardList.value.forEach((card) => {
if (card.name == "assessmentMoney" || card.name == "dataScale") {
card.value = changeNum(data[card.name] ?? 0, 2);
} else {
card.value = changeNum(data[card.name] ?? 0);
}
});
} else {
ElMessage.error(res.msg);
}
});
});
/** 行业类型分布的饼图。 */
const industryPieLoading = ref(false);
let industryPieChart: any = null;
const industryPieData: any = ref([]);
const industryPieDataTotal: any = ref(0);/** 服务总家数 */
/** 授信主体金额加载 */
const creditMoneyPieLoading = ref(false);
let creditMoneyPieChart: any = null;
const creditMoneyPieData: any = ref([]);
/** 设置行业类型饼图分布 */
const setPieChartOption = () => {
if (!industryPieData.value.length) {
let option1 = {
title: [
{
text: "",
left: "30px",
top: "30px",
},
{
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
fontStyle: "normal",
fontWeight: "400",
fontSize: 18,
},
},
],
};
industryPieChart.setOption(option1, true);
window.addEventListener("resize", () => {
industryPieChart.resize();
});
return;
}
let sum = industryPieData.value
.map((d) => d.value)
.reduce(function (prev, curr, idx, arr) {
return prev + curr;
});
let option = {
textStyle: {
fontFamily: "SimSun",
},
color: ["#4DC5BE", "#40A9FF", "#FF8601", "#656BE9", "#EA6671", "#60D78D"],
legend: {
// left: "right",
orient: "vertical",
top: "middle",
//right: 50,
x: "60%",
y: "cenetr",
itemGap: 20,
icon: "circle",
itemHeight: 10,
align: "left",
textStyle: {
color: "#666666",
fontSize: 14,
},
},
series: [
{
name: "industry",
type: "pie",
center: ["30%", "50%"],
radius: ["60%", "80%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
label: {
show: true,
position: "center",
fontSize: 24,
formatter: ["{a|服务家数}", `{b|${changeNum(industryPieDataTotal.value)}}{c| 家}`].join("\n"),
rich: {
a: {
fontSize: 16,
color: "#212121",
fontWeight: 600,
lineHeight: 27,
},
b: {
fontSize: 24,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
c: {
fontSize: 18,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
},
},
emphasis: {
focus: "self",
label: {
show: true,
formatter: (params) => {
return [
`{a|${params.data.originName}}`,
`{b|${params.percent}%}`,
].join("\n");
},
fontSize: 24,
fontWeight: "bold",
rich: {
a: {
fontSize: 16,
color: "#212121",
fontWeight: 600,
lineHeight: 27,
},
b: {
fontSize: 24,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
},
},
},
labelLine: {
show: false,
},
data: industryPieData.value.map((d) => {
return {
value: d.value,
name: `${d.name} ${((d.value / sum) * 100).toFixed(
2
)}% ${changeNum(d.value)}家`,
originName: d.name,
};
}),
},
],
};
option && industryPieChart.setOption(option, true);
window.addEventListener("resize", () => {
industryPieChart.resize();
});
};
/** 设置授信主体金额饼图分布 */
const setCreditPieChartOption = () => {
if (!creditMoneyPieData.value.length) {
let option1 = {
title: [
{
text: "",
left: "30px",
top: "30px",
},
{
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
fontStyle: "normal",
fontWeight: "400",
fontSize: 18,
},
},
],
};
creditMoneyPieChart.setOption(option1, true);
window.addEventListener("resize", () => {
creditMoneyPieChart.resize();
});
return;
}
let sum = creditMoneyPieData.value
.map((d) => d.value)
.reduce(function (prev, curr, idx, arr) {
return prev + curr;
});
let option = {
textStyle: {
fontFamily: "SimSun",
},
color: ["#4DC5BE", "#40A9FF", "#FF8601", "#656BE9", "#EA6671", "#60D78D"],
legend: {
// left: "right",
orient: "vertical",
top: "middle",
//right: 50,
x: "55%",
y: "cenetr",
itemGap: 20,
icon: "circle",
itemHeight: 10,
align: "left",
textStyle: {
color: "#666666",
fontSize: 14,
overflow: 'break'
},
},
series: [
{
name: "creditMoney",
type: "pie",
center: ["30%", "50%"],
radius: ["60%", "80%"],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
label: {
show: true,
position: "center",
fontSize: 24,
formatter: ["{a|总授信额}", `{b|${changeNum(sum, 2, true)}}{c| 万元}`].join("\n"),
rich: {
a: {
fontSize: 16,
color: "#212121",
fontWeight: 600,
lineHeight: 27,
},
b: {
fontSize: 24,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
c: {
fontSize: 18,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
}
},
},
emphasis: {
focus: "self",
label: {
show: true,
formatter: (params) => {
return [
`{a|${params.data.originName}}`,
`{b|${params.percent}%}`,
].join("\n");
},
fontSize: 24,
fontWeight: "bold",
rich: {
a: {
fontSize: 16,
color: "#212121",
fontWeight: 600,
lineHeight: 27,
},
b: {
fontSize: 24,
color: "#212121",
lineHeight: 42,
fontWeight: 600,
},
},
},
},
labelLine: {
show: false,
},
data: creditMoneyPieData.value.map((d) => {
return {
value: d.value,
name: `${d.name} ${((d.value / sum) * 100).toFixed(
2
)}% ${changeNum(d.value, 2, true)}万元`,
originName: d.name,
};
}),
},
],
};
creditMoneyPieChart.setOption(option, true);
window.addEventListener("resize", () => {
creditMoneyPieChart.resize();
});
};
/** 行业类型地区分布的柱形图。 */
const serviceAreaBarLoading = ref(false);
let serviceAreaBarChart: any = null;
const serviceAreaBarData: any = ref([]);
/** 资产登记月趋势分布的柱形图。 */
const platformMonthBarLoading = ref(false);
let platformMonthBarChart: any = null;
const platformMonthBarData: any = ref([]);
/** 设置服务企业地区类型分布-柱形图 */
const setBarChartOption = (data, barChart, unit) => {
if (!data.length) {
let option1 = {
title: [
{
text: "",
left: "30px",
top: "30px",
},
{
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
fontStyle: "normal",
fontWeight: "400",
fontSize: 18,
},
},
],
};
barChart.setOption(option1, true);
window.addEventListener("resize", () => {
barChart.resize();
});
return;
}
let xAxisData = data.map((s) => s.name);
let xAxisDataLen = xAxisData.length;
let option = {
textStyle: {
fontFamily: "SimSun",
},
color: [
"#5797FF",
"#6DD18E",
"#867EEC",
"#FDBC3E",
"#F48A64",
"#276FF5",
"#46D0B5",
],
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
crossStyle: {
color: "#999",
},
},
textStyle: {
align: "left",
},
position: function (point, params, dom, rect, size) {
dom.style.transform = "translateZ(0)";
},
formatter: function (params) {
return (
params[0].name +
":" +
changeNum(params[0].data?.value) +
unit +
"<br>"
);
},
},
legend: {
show: false,
},
grid: {
left: "5%",
top: "5%",
right: "5%",
bottom: xAxisData.length <= 10 ? "8%" : "18%",
},
xAxis: {
type: "category",
nameTextStyle: {
color: "#323233",
},
axisLabel: {
textStyle: {
color: "#323233",
},
},
axisTick: {
show: false,
},
data: xAxisData || [],
},
yAxis: {
type: "value",
nameTextStyle: {
color: "#323233",
},
axisLabel: {
textStyle: {
color: "#323233",
},
},
axisLine: {
//y轴
show: false,
},
},
dataZoom: [
{
type: "inside",
filterMode: "filter", // 设定为 'filter' 从而 X 的窗口变化会影响 Y 的范围。
zoomLock: xAxisDataLen <= 12 ? true : false,
start: xAxisDataLen <= 12 ? 0 : 80,
end: 100,
},
{
type: "slider",
show: xAxisDataLen <= 12 ? false : true,
height: 25,
bottom: 0,
start: xAxisDataLen <= 12 ? 0 : 80,
end: 100,
},
],
series: {
type: "bar",
data: data,
},
};
barChart.setOption(option, true);
window.addEventListener("resize", () => {
barChart.resize();
});
};
onMounted(() => {
industryPieChart = echarts.init(document.getElementById("pie-industry"));
industryPieLoading.value = true;
getIndustryInfo().then((res: any) => {
industryPieLoading.value = false;
if (res.code == proxy.$passCode) {
industryPieData.value = res.data?.homeGraphStatistics || [];
industryPieDataTotal.value = res.data?.totalCompanyNum ?? 0;
setPieChartOption();
} else {
ElMessage.error(res.msg);
}
});
creditMoneyPieLoading.value = true;
creditMoneyPieChart = echarts.init(
document.getElementById("pie-creditMoney")
);
getCreditMoneyInfo().then((res: any) => {
creditMoneyPieLoading.value = false;
if (res.code == proxy.$passCode) {
creditMoneyPieData.value = res.data || [];
setCreditPieChartOption();
} else {
ElMessage.error(res.msg);
}
});
serviceAreaBarLoading.value = true;
serviceAreaBarChart = echarts.init(document.getElementById("bar-area"));
getPlatformService().then((res: any) => {
serviceAreaBarLoading.value = false;
if (res.code == proxy.$passCode) {
console.log(res.data);
serviceAreaBarData.value = res.data || [];
setBarChartOption(serviceAreaBarData.value, serviceAreaBarChart, '家');
} else {
ElMessage.error(res.msg);
}
});
platformMonthBarLoading.value = true;
platformMonthBarChart = echarts.init(document.getElementById("bar-month"));
getPlatformMonth().then((res: any) => {
platformMonthBarLoading.value = false;
if (res.code == proxy.$passCode) {
console.log(res.data);
platformMonthBarData.value = res.data || [];
setBarChartOption(platformMonthBarData.value, platformMonthBarChart, '张');
} else {
ElMessage.error(res.msg);
}
});
});
</script>
<template>
<div class="main-scroll">
<div class="main-content">
<div class="one-row" :style="{ height: '312px', 'margin-top': '8px' }">
<div class="left" :style="{ width: 'calc(50% - 4px)' }">
<div class="header">
<span class="header-title">服务企业地区分布</span>
</div>
<div class="content-chart-pie">
<el-skeleton
class="content-chart-pie-ske"
v-if="serviceAreaBarLoading"
:rows="6"
animated
/>
<div id="bar-area" class="pie"></div>
</div>
</div>
<div class="right" :style="{ width: 'calc(50% - 4px)' }">
<div class="header">
<span class="header-title">行业类型分布</span>
</div>
<div class="content-chart-pie">
<el-skeleton
class="content-chart-pie-ske"
v-if="industryPieLoading"
:rows="6"
animated
/>
<div id="pie-industry" class="pie"></div>
</div>
</div>
</div>
<div class="one-row" :style="{ height: '320px', 'margin-top': '8px' }">
<div class="left" :style="{ width: 'calc(50% - 4px)' }">
<div class="header">
<span class="header-title">数据服务资产情况</span>
</div>
<div class="num-content">
<div
v-if="!statisticsInfoLoading"
class="icon-sum num-sum"
v-for="item in cardList"
>
<div class="tags_item">
<p class="tag_text">{{ item.label }}</p>
<p class="tag_num">
<span>{{ item.value }}</span
><span class="unit">{{ item.unit }}</span>
</p>
</div>
</div>
<el-skeleton v-else :rows="6" animated />
</div>
</div>
<div class="right" :style="{ width: 'calc(50% - 4px)' }">
<div class="header">
<span class="header-title">数据资产登记趋势</span>
</div>
<div class="content-chart-pie">
<el-skeleton
class="content-chart-pie-ske"
v-if="platformMonthBarLoading"
:rows="6"
animated
/>
<div id="bar-month" class="pie"></div>
</div>
</div>
</div>
<div class="one-row" :style="{ height: '312px', 'margin-top': '8px' }">
<div class="left" :style="{ width: 'calc(50% - 4px)' }">
<div class="header">
<span class="header-title">资产授信情况</span>
</div>
<div class="content trade-con">
<Table
v-if="!financingTableInfo.loading"
:tableInfo="financingTableInfo"
@tableBtnClick="financingTableBtnClick"
@tablePageChange="financingTablePageChange"
/>
<el-skeleton v-else :rows="6" animated />
</div>
</div>
<div class="right" :style="{ width: 'calc(50% - 4px)' }">
<div class="header">
<span class="header-title">授信主体金额分布</span>
</div>
<div class="content-chart-pie">
<el-skeleton
class="content-chart-pie-ske"
v-if="creditMoneyPieLoading"
:rows="6"
animated
/>
<div id="pie-creditMoney" class="pie"></div>
</div>
</div>
</div>
<div class="foot-sty" style="white-space: pre-wrap;">北京传世博润科技有限公司 Copyright @ 2023-2024 <a href="https://beian.miit.gov.cn" target="_blank">京ICP备2024044205号</a>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.main-scroll {
height: 100%;
overflow-y: auto;
}
.main-content {
background-color: #e2e7ef;
padding: 8px 8px 0px 8px;
}
.one-row {
height: 290px;
display: inline-flex;
width: 100%;
justify-content: space-between;
.trade-con {
height: calc(100% - 40px);
padding-bottom: 0px;
}
}
.num-content {
padding: 12px;
height: calc(100% - 40px);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.icon-sum {
display: inline-flex;
width: 100%;
justify-content: space-between;
&.num-sum {
width: calc(33% - 4px);
}
.tags_item {
height: 50px;
display: flex;
flex-direction: column;
justify-content: space-between;
p {
font-size: 14px;
color: var(--el-text-color-regular);
margin: 0;
line-height: 21px;
&.tag_num {
color: var(--el-color-regular);
font-size: 24px;
font-weight: 700;
.unit {
font-size: 18px;
}
}
}
}
}
}
.right,
.left {
background-color: #fff;
height: 100%;
}
.header {
height: 40px;
border-bottom: 1px solid #e5e5e5;
display: flex;
align-items: center;
.header-title {
font-size: 14px;
color: #212121;
line-height: 21px;
font-weight: 600;
padding-left: 12px;
}
}
.content {
padding: 12px;
}
.content-chart-pie {
width: 100%;
height: calc(100% - 40px);
padding: 12px;
position: relative;
.pie {
height: 100%;
width: 100%;
}
}
.content-chart-pie-ske {
position: absolute;
width: calc(100% - 24px);
}
</style>
<template>
<div class="registerGuide">
<div class="box">
<template v-for="item in data" :key="item.title">
<GuideItem :data="item" />
</template>
</div>
</div>
</template>
<script setup name="registerGuide">
import GuideItem from "./components/GuideItem/index.vue"
const data = [
{
title: "资产登记指南",
children: [
{
title: "1、登记准备",
children: ["·数据资产登记合规承诺函盖章", "·数据资产登记信息收集函填写"]
},
{
title: "2、登记录入",
children: ["·录入数据资产基本信息", "·上传登记合规承诺函和信息收集函", "·录入数据资产权利主体信息"]
},
{
title: "3、检查提交",
children: ["·录入完成后,将填写的相关信息与附件的信息进行核对,避免信息不一致导致重复修改审核"]
},
{
title: "4、审核发证",
children: ["·提交后,<span style='color:#1161BF;'>初审1~2个工作日</span>;最终审核发证为<span style='color:#1161BF;'>3~5个工作日</span>"]
}
]
},
{
title: "质量评估指南",
children: [
{
title: "1、质量评估准备",
children: ["·数据资产质量评估承诺函盖章", "·数据资产质量评估库表结构信息收集表填写"]
},
{
title: "2、质量申请",
children: ["·选择已登记的数据资产", "·上传质量评估所需的承诺函和信息收集表",]
},
{
title: "3、质量评估",
children: ["·质量申请发起后,<span style='color:#1161BF;'>10</span>张表左右的数据资产质量评估工作日在<span style='color:#1161BF;'>10~15个工作日</span>出具评估结果及报告"]
},
{
title: "4、结果查看",
children: ["·查看质量评分及质量评估报告"]
}
]
},
{
title: "价值评估指南",
children: [
{
title: "1、价值评估准备",
children: ["·填写调查问卷", "·填写收入分成明细表", "·填写数据资产成本明细"]
},
{
title: "2、评估申请",
children: ["·选择已登记的数据资产", "·上传价值评估的调查问题、收入分成明细及成本明细",]
},
{
title: "3、价值评估",
children: ["·价值评估申请发起后,<span style='color:#1161BF;'>10~15个工作日</span>出具评估结果及报告"]
},
{
title: "4、结果查看",
children: ["·查看评估值及价值评估报告"]
}
]
}
]
</script>
<style lang="scss" scoped>
.entryTableguide {
min-width: 1000px;
height: 100%;
background: rgb(242, 243, 248);
overflow: auto;
}
</style>
<route lang="yaml">
name: productDemandsCheck
</route>
<script lang="ts" setup name="productDemandsCheck">
import { ref, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import useUserStore from "@/store/modules/user";
import useDataAssetStore from "@/store/modules/dataAsset";
import { ElMessage, ElMessageBox } from "element-plus";
import { getDemandList, getParamsDataList, filterVal } from "@/api/modules/dataProduct";
import { registerApproveAllow, registerApproveBackup, } from "@/api/modules/dataAsset";
import { TableColumnWidth } from '@/utils/enum';
import TableTools from "@/components/Tools/table_tools.vue";
import Table from "@/components/Table/index.vue";
import Dialog from "@/components/Dialog/index.vue";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const userStore = useUserStore();
const assetStore = useDataAssetStore();
const userData = JSON.parse(userStore.userData);
const interfaceTypes: any = ref([]);
const searchItemList: any = ref([
{
type: "input",
label: "",
field: "dataName",
default: "",
placeholder: "需求名称",
clearable: true
},
{
type: "select",
label: "",
field: "interfaceType",
default: "",
props: {
value: 'paramValue',
label: 'paramName'
},
placeholder: "界面类型",
options: interfaceTypes.value,
clearable: true,
},
]);
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 searchItemValue: any = ref({});
const tableInfo = ref({
id: "mapping-table",
fields: [
{ label: "序号", type: "index", width: 56, align: "center", fixed: "left" },
{ label: "数据需求名称", field: "dataName", width: 140 },
{
label: "界面类型", field: "interfaceTypeName", width: 100
},
{ label: "发布主体", field: "tenantName", width: 240,
// getName: (scope) => {
// return userData.tenantName;
// }
},
{ label: "参考价", field: "productPrice", width: 120, },
{
label: "审核状态", field: "approveState", width: TableColumnWidth.STATE, align: 'center', type: "tag", getName: (scope) => {
return filterVal(scope.row.approveState, 'approveState');
}
},
{ label: "申请时间", field: "applicationTime", width: TableColumnWidth.DATETIME },
{ label: "操作时间", field: "updateTime", width: TableColumnWidth.DATETIME },
],
loading: false,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 140,
btns: (scope) => {
let row = scope.row, btnsArr = [];
if (row.approveState == 'A') {
if (row.approveTenantGuids?.includes(userData.tenantGuid)) {
btnsArr.splice(0, 0, { label: "通过", value: "pass", type: 'primary' }, { label: "驳回", value: "reject", type: 'danger', plain: true });
}
btnsArr.splice(0, 0, { label: "详情", value: "check" });
} else {
btnsArr.splice(0, 0, { label: "详情", value: "check" });
}
return btnsArr;
},
},
});
const contents = ref({
pass: [
{
type: 'form',
title: '',
formInfo: {
id: 'batch-pass-form',
items: [
{
label: '',
type: "textarea",
placeholder: "请填写通过备注(选填)",
field: "approveSuggest",
clearable: true,
maxlength: 400,
block: true,
col: 'margin_b_0',
}
]
}
}
],
reject: [
{
type: 'form',
title: '',
formInfo: {
id: 'batch-reject-form',
items: [
{
label: '',
type: "textarea",
placeholder: "请填写驳回理由(必填)",
field: "approveSuggest",
clearable: true,
maxlength: 400,
block: true,
col: 'margin_b_0',
}
]
}
}
],
});
const listingDialogRef = ref();
const dialogInfo = ref({
visible: false,
size: 460,
direction: "column",
header: {
title: "",
},
type: '',
contents: [],
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", value: "submit" },
],
},
});
const getTableData = () => {
tableInfo.value.loading = true;
getDemandList(
Object.assign({}, searchItemValue.value, {
isGrounding: 1,
pageIndex: page.value.curr,
pageSize: page.value.limit,
})
)
.then((res: any) => {
tableInfo.value.loading = false;
tableInfo.value.data = res.data.records || [];
tableInfo.value.page.curr = res.data.pageIndex;
tableInfo.value.page.limit = res.data.pageSize;
tableInfo.value.page.rows = res.data.totalRows;
})
.catch((res) => {
tableInfo.value.loading = false;
});
};
/** 搜索同步任务列表 */
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
searchItemValue.value = {};
} else {
searchItemValue.value = Object.keys(val).length ? { ...val } : {};
}
page.value.curr = 1;
tableInfo.value.page.curr = 1;
getTableData();
};
const currTableData: any = ref({});
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
currTableData.value = row;
if (type == "check") {
toPatn(type);
} else {
dialogInfo.value.type = type
dialogInfo.value.header.title = type == 'pass' ? '通过' : '驳回'
dialogInfo.value.contents = contents.value[type]
dialogInfo.value.visible = true
}
};
const toPatn = (type) => {
router.push({
name: "productDemandsCheckDetail",
query: {
guid: currTableData.value.guid,
name: currTableData.value.dataName,
type
},
});
}
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.limit = page.value.limit;
tableInfo.value.page.curr = page.value.curr;
getTableData();
};
const getFirstPageData = () => {
page.value.curr = 1
tableInfo.value.page.curr = 1;
getTableData();
}
const dialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
let params = { ...info }
params.bizGuid = currTableData.value.guid
params.funcCode = currTableData.value.funcCode
if (dialogInfo.value.type == 'pass') {
dialogInfo.value.visible = false;
registerApproveAllow(params).then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: 'success',
message: '审批成功'
})
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
}).catch(() => {
})
} else if (dialogInfo.value.type == 'reject') {
if (info.approveSuggest == '') {
ElMessage.error('请填写驳回原因')
return
}
dialogInfo.value.visible = false;
registerApproveBackup(params).then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: 'success',
message: '驳回成功'
})
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
}).catch(() => {
})
}
} else if (btn.value == 'cancel') {
nextTick(() => {
dialogInfo.value.visible = false;
})
}
};
onActivated(() => {
if (assetStore.isRefresh) {//如果是首次加载,则不需要调用
getFirstPageData();
assetStore.set(false);
}
})
onBeforeMount(() => {
getParamsDataList({ paramCode: 'INTERFACE_TYPE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
interfaceTypes.value = res.data || [];
let item = searchItemList.value.find(item => item.field == 'interfaceType');
item && (item.options = interfaceTypes.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
})
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" />
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" />
</div>
<!-- 上架对话框 -->
<Dialog ref="listingDialogRef" :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" />
</div>
</template>
<style scoped lang="scss">
.table_tool_wrap {
width: 100%;
height: auto;
padding: 0 8px;
min-height: 44px;
.tools_btns {
padding: 0px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 44px);
padding: 0px 8px 0;
}
</style>
<route lang="yaml">
name: productDemandsDetail
</route>
<script lang="ts" setup name="productDemandsDetail">
import { ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { CaretRight, CircleCloseFilled } from '@element-plus/icons-vue'
import { useRoute } from "vue-router";
import Form from "@/components/Form/index.vue";
import Dialog from "@/components/Dialog/index.vue";
import useUserStore from "@/store/modules/user";
import useDataAssetStore from "@/store/modules/dataAsset";
import { onUploadFilePreview, onUploadFileDownload } from '@/api/modules/common';
import { getApproveList, getTenantApprove, registerApproveAllow, registerApproveBackup, getParamsList } from "@/api/modules/dataAsset";
import { getDemandDetail, demandSave, competitionSave, marketSave, demandUpdate, competitionUpdate, marketUpdate, checkDemandName, getParamsDataList, getProductTypeList } from "@/api/modules/dataProduct";
import { getMatchDetail } from "@/api/modules/dataFinance";
import { useValidator } from '@/hooks/useValidator';
import { changeNum } from "@/utils/common";
const { required, checkExistName } = useValidator();
const route = useRoute();
const userStore = useUserStore();
const userData = JSON.parse(userStore.userData);
const assetStore = useDataAssetStore();
const fullPath = route.fullPath;
const guid = route.query.guid as string;
const dGuid = route.query.dGuid as string;
const damName = route.query.name as string || '';
const detailType = <string>route.query.type || '';
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
/** 需求类型 */
const demandTypes = ref([]);
const damTypes = ref([]);
/** 界面类型 */
const interfaceTypes: any = ref([]);
/** 数据服务数据字典 */
const dataServiceDetails: any = ref([]);
/** 项目的数据字典 */
const projectDetails: any = ref([]);
const subjectDomainListData: any = ref([]);
/** 竞赛类型 */
const competitionTypes: any = ref([]);
/** 产品类别树形字典 */
const productTypes: any = ref([]);
/** 交付方式 */
const deliveryWayList: any = ref([]);
const collapseIcon = ref(false);
const collapseIcon1 = ref(false);
const collapseIcon2 = ref(false);
const flowDetail: any = ref({});
const flowDetailLoading = ref(false);
const applyDetail: any = ref({});
const approveTableInfo: any = ref({
id: 'approve-table',
rowKey: 'guid',
loading: false,
height: null,
minHeight: '60px',
maxHeight: '300',
fields: [
{ label: "节点", field: "tenantType", width: 140, align: "left", getName: (scope) => {
if(detailType == 'add'){
return scope.row.tenantType;
} else {
let v = scope.row.tenantType;
return v == 1 ? '企业' : (v == 2 ? '服务商' : '交易所');
}
}
},
{ label: '处理对象', field: 'approvedTenantName', width: 200, align: "left" },
{ label: "操作时间", field: "approveTime", width: 180 },
{ label: "审批状态", field: "approveState", type: "tag", width: 96, align: 'center' },
{ label: "审批原因", field: "approveSuggest", width: 240 }
],
data: [],
showPage: false,
actionInfo: {
show: false
}
});
/** 界面类型为数据需求时的表单 */
const demandFormItems = ref([
{
label: "界面类型",
type: "select",
placeholder: "请选择",
field: "interfaceType",
default: '1',
props: {
value: 'paramValue',
label: 'paramName'
},
options: interfaceTypes.value,
required: true,
disabled: true
},
{
label: "数据需求名称",
type: "input",
placeholder: "请输入",
field: "dataName",
default: '',
maxlength: 20,
clearable: true,
required: true,
}, {
label: "需求类型",
type: "select",
placeholder: "请选择",
field: "demandType",
default: 'DAM-TYPE',//默认值,数据资源
props: {
value: 'paramValue',
label: 'paramName'
},
options: demandTypes.value,
required: true,
},
{
label: "数据类型",
type: "select",
placeholder: "请选择",
field: "demandTypeDetail-type",
default: '',
props: {
value: 'paramValue',
label: 'paramName'
},
options: damTypes.value,
required: true,
},
{
label: "数据服务",
type: "select",
placeholder: "请选择",
field: "demandTypeDetail-service",
default: '',
props: {
value: 'paramValue',
label: 'paramName'
},
options: dataServiceDetails.value,
visible: false,
required: true,
},
{
label: "项目",
type: "select",
placeholder: "请选择",
field: "demandTypeDetail-project",
default: '',
props: {
value: 'paramValue',
label: 'paramName'
},
options: projectDetails.value,
visible: false,
required: true,
},
{ //只有需求类型为数据资源时才有
label: '所属主题',
type: 'tree-select',
placeholder: '请选择',
field: 'subjectDomain',
options: subjectDomainListData.value,
showAllLevels: false,
checkStrictly: false,//只能选择叶子节点。
lazy: false,
props: {
label: "paramName",
value: "paramValue",
},
filterable: true,
clearable: true,
disabled: false,
default: '',
required: true
},
{
label: '产品预算',
type: 'checkbox-input-item',
placeholder: '面议',
field: 'isDiscussPersonally',
default: 'Y',
trueValue: 'Y',
falseValue: 'N',
children: [
{
label: '',
type: 'input',
placeholder: '请输入预算金额',
field: 'productPrice',
default: '',
maxlength: 10,
disabled: false,
clearable: true,
visible: false,
style: {width: '100%', margin: 0}
}
],
required: true,
col: 'checkbox-input'
}, {
label: '审核后自动上架',
type: 'switch',
field: 'isApproveGrounding',
default: 'Y',
activeValue: 'Y',
inactiveValue: 'N',
required: true,
}, {
label: '需求描述',
placeholder: '该数据资产主要包含的信息,数据更新方式等。',
field: 'content',
type: 'textarea-rich',
id: 'demandDesc',
default: '',
block: true,
clearable: true,
required: true,
}, {
label: '需求图片',
tip: '支持扩展名:.jpg .png .jpeg',
accept: '.jpg, .png, .jpeg',
type: 'upload-file',
placeholder: '请选择',
field: 'productImg',
default: [],
limit: 1,
block: true,
required: false,
},
]);
/** 记录已校验过的信息。 */
const checkedInfo: any = ref({});
/** 检验规则 */
const demandRules = ref({
dataName: [
required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
],
demandType: [required('请选择需求类型')],
'demandTypeDetail-type': [required('请选择数据类型')],
'demandTypeDetail-service': [required('请选择数据服务')],
productPrice: [
{ required: true, message: "请填写产品预算", trigger: "blur", },
],
content: [
{ required: true, message: "请填写需求描述", trigger: "blur", },
],
// productImg: [
// {
// validator: (rule: any, value: any, callback: any) => {
// if (!value?.length) {
// callback(new Error('请上传需求图片'))
// } else {
// callback();
// }
// }, trigger: 'change'
// },
// ],
});
/** 算法竞赛的formItems */
const algorithmFormItem = ref([
{
label: "界面类型",
type: "select",
placeholder: "请选择",
field: "interfaceType",
default: '2',
props: {
value: 'paramValue',
label: 'paramName'
},
options: interfaceTypes.value,
required: true,
disabled: true
},
{
label: "数据需求名称",
type: "input",
placeholder: "请输入",
field: "dataName",
default: '',
maxlength: 200,
clearable: true,
required: true,
},
{
label: "竞赛类型",
type: "select",
placeholder: "请选择",
field: "competitionType",
default: '',
props: {
value: 'paramValue',
label: 'paramName'
},
options: competitionTypes.value,
required: true
}, {
label: '奖金(元)',
type: 'input',
placeholder: '请输入',
inputType: 'moneyNumber',
field: 'bonus',
default: '',
maxlength: 10,
disabled: false,
clearable: true,
visible: true
},
{
label: "报名截止日",
type: "datetime",
field: "signupEndDate",
default: null,
placeholder: "请选择",
clearable: true,
required: true,
},
{
label: '举办方',
type: 'input',
placeholder: '请输入',
field: 'organizer',
default: '',
maxlength: 200,
clearable: true,
required: true,
},
{
label: '审核后自动上架',
type: 'switch',
field: 'isApproveGrounding',
default: 'Y',
activeValue: 'Y',
inactiveValue: 'N',
required: true,
}, {
label: '赛事描述',
placeholder: '该数据资产主要包含的信息,数据更新方式等。',
field: 'content',
type: 'textarea-rich',
id: 'demandDesc',
default: '',
block: true,
clearable: true,
required: true,
},
// {
// label: '赛事图片',
// tip: '支持扩展名:.jpg .png .jpeg',
// accept: '.jpg, .png, .jpeg',
// type: 'upload-file',
// placeholder: '请选择',
// field: 'productImg',
// default: [],
// limit: 1,
// block: true,
// required: true,
// },
]);
const algorithmFormRules = ref({
dataName: [
required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
],
competitionType: [required('请选择竞赛类型')],
bonus: [{
validator: (rule: any, value: any, callback: any) => {
if (value === 0) {
callback();
return;
}
if (!value) {
callback(new Error('请填写奖金'));
return;
}
callback();
},
trigger: "blur",
}],
signupEndDate: [required('请选择报名截止日')],
organizer: [required('请填写举办方')],
content: [
{ required: true, message: "请填写赛事描述", trigger: "blur", },
],
// productImg: [
// {
// validator: (rule: any, value: any, callback: any) => {
// if (!value?.length) {
// callback(new Error('请上赛事图片'))
// } else {
// callback();
// }
// }, trigger: 'change'
// },
// ]
});
/** 要素市场的formItem */
const elementFormItems = ref([
{
label: "界面类型",
type: "select",
placeholder: "请选择",
field: "interfaceType",
default: '3',
props: {
value: 'paramValue',
label: 'paramName'
},
options: interfaceTypes.value,
required: true,
disabled: true
},
{
label: "数据需求名称",
type: "input",
placeholder: "请输入",
field: "dataName",
default: '',
maxlength: 200,
clearable: true,
required: true,
},
{
label: '产品类别',
type: 'tree-select',
placeholder: '请选择',
field: 'productType',
options: productTypes.value,
showAllLevels: false,
checkStrictly: false,//只能选择叶子节点。
lazy: false,
props: {
label: "paramName",
value: "paramValue",
},
filterable: true,
clearable: true,
disabled: false,
default: '',
required: true
},{
label: "交付方式",
type: "select",
placeholder: "请选择",
field: "deliveryWay",
default: '',
options: deliveryWayList.value,
props: {
value: 'paramValue',
label: 'paramName'
},
filterable: true,
clearable: true,
disabled: false,
required: true,
},
{
label: '产品预算',
type: 'checkbox-input-item',
placeholder: '面议',
field: 'isDiscussPersonally',
default: 'Y',
trueValue: 'Y',
falseValue: 'N',
children: [
{
label: '',
type: 'input',
placeholder: '请输入预算金额',
field: 'productPrice',
default: '',
maxlength: 10,
disabled: false,
clearable: true,
visible: false,
style: {width: '100%', margin: 0}
}
],
required: true,
col: 'checkbox-input'
}, {
label: '审核后自动上架',
type: 'switch',
field: 'isApproveGrounding',
default: 'Y',
activeValue: 'Y',
inactiveValue: 'N',
required: true,
}, {
label: '产品描述',
placeholder: '该数据资产主要包含的信息,数据更新方式等。',
field: 'content',
type: 'textarea-rich',
id: 'demandDesc',
default: '',
block: true,
clearable: true,
required: true,
}, {
label: '产品图片',
tip: '支持扩展名:.jpg .png .jpeg',
accept: '.jpg, .png, .jpeg',
type: 'upload-file',
placeholder: '请选择',
field: 'productImg',
default: [],
limit: 1,
block: true,
required: true,
},
]);
const elementFormRules = ref({
dataName: [
required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
],
productType: [required('请选择产品类别')],
deliveryWay: [
required('请选择交付方式')
],
content: [
{ required: true, message: "请填写产品描述", trigger: "blur", },
],
productImg: [
{
validator: (rule: any, value: any, callback: any) => {
if (!value?.length) {
callback(new Error('请上传产品图片'))
} else {
callback();
}
}, trigger: 'change'
},
],
});
const listingFormRef = ref();
const subForm: any = ref({});
const formInfo: any = ref({
id: 'check-form',
col: 'col3',
items: demandFormItems.value,
rules: demandRules.value
})
const contents = ref({
pass: [
{
type: 'form',
title: '',
formInfo: {
id: 'batch-pass-form',
items: [
{
label: '',
type: "textarea",
placeholder: "请填写通过备注(选填)",
field: "approveSuggest",
clearable: true,
maxlength: 400,
block: true,
col: 'margin_b_0',
}
]
}
}
],
reject: [
{
type: 'form',
title: '',
formInfo: {
id: 'batch-reject-form',
items: [
{
label: '',
type: "textarea",
placeholder: "请填写驳回理由(必填)",
field: "approveSuggest",
clearable: true,
maxlength: 400,
block: true,
col: 'margin_b_0',
}
]
}
}
],
});
const listingDialogRef = ref();
const dialogInfo = ref({
visible: false,
size: 460,
direction: "column",
header: {
title: "",
},
type: '',
contents: [],
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", value: "submit" },
],
},
});
const getProductDetail = () => {
flowDetailLoading.value = true;
getDemandDetail({ guid }).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
flowDetail.value = res.data || {};
let interfaceType = flowDetail.value.interfaceType;
if (interfaceType) {
initMethodByInterfaceType.value[interfaceType]();
if (interfaceType == '1') {
processDemanTypeChange(flowDetail.value.demandType);
if (flowDetail.value.demandType == 'DAM-TYPE') {
flowDetail.value['demandTypeDetail-type'] = flowDetail.value.demandTypeDetail;
} else if (flowDetail.value.demandType == 'DATA_SERVICE_DETAIL') {
flowDetail.value['demandTypeDetail-service'] = flowDetail.value.demandTypeDetail;
} else if (flowDetail.value.demandType == 'PROJECT_DETAIL') {
flowDetail.value['demandTypeDetail-project'] = flowDetail.value.demandTypeDetail;
}
demandRules.value.dataName = [
required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
];
if (flowDetail.value.subjectDomainTree?.length) {
let item: any = demandFormItems.value.find(item => item.field == 'subjectDomain');
let tree = flowDetail.value.subjectDomainTree?.[0];
if (item && tree) {
if (!tree.children[0]?.children?.[0]?.children) {
item.expandKeys = tree.children[0]?.children?.[0].parentGuids;
} else if (!tree.children[0]?.children?.[0]?.children?.[0]?.children) {
item.expandKeys = tree.children[0]?.children?.[0]?.children?.[0]?.parentGuids;
}
}
}
} else if (interfaceType == '2') {
if (flowDetail.value.bonus != null) {
flowDetail.value.bonus = parseFloat(flowDetail.value.bonus).toFixed(2);
}
algorithmFormRules.value.dataName = [
required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
];
} else {
elementFormRules.value.dataName = [
required('请填写需求名称'), checkExistName(checkedInfo.value, checkDemandName, flowDetail.value, 'dataName')
];
}
}
setFormItems(flowDetail.value);
} else {
ElMessage.error(res.msg);
}
})
}
// 获取审批信息
const getApproveData = () => {
if(detailType == 'add'){
approveTableInfo.value.loading = true;
getTenantApprove({funcCode: 'Demand-base-9'}).then((res: any) => {
approveTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
approveTableInfo.value.data = res.data?.map(d => {
return {
tenantType: d.substring(4)
}
}) || [];
} else {
ElMessage.error(res.msg);
}
});
} else {
approveTableInfo.value.loading = true;
getApproveList(guid).then((res: any) => {
approveTableInfo.value.loading = false;
if (res.code == proxy.$passCode) {
console.log(res.data);
approveTableInfo.value.data = res.data || [];
} else {
ElMessage.error(res.msg);
}
});
}
}
// 获取申请信息
const getApplyDeatil = () => {
getMatchDetail({ guid: dGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
applyDetail.value = data;
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
}).catch((res) => {
ElMessage({
type: "error",
message: '获取申请信息失败',
});
});
}
const submitForm = (btn, formEl, tosub = false) => {
if (!formEl) return;
formEl.validate((valid, fields) => {
if (valid) {
let params: any = { ...subForm.value }
delete params.productImg;
delete params.productImgList;
params.demandPic = subForm.value.productImg?.length ? { name: subForm.value.productImg[0].name, url: subForm.value.productImg[0].url } : {};
flowDetailLoading.value = true;
if (detailType == 'add') {
if (route.query.interfaceType == '1') {
params.interfaceType = '1';
if (params.demandType == 'DAM-TYPE') {
params.demandTypeDetail = params['demandTypeDetail-type'];
} else if (params.demandType == 'DATA_SERVICE_DETAIL') {
params.demandTypeDetail = params['demandTypeDetail-service']
} else if (params.demandType == 'PROJECT_DETAIL') {
params.demandTypeDetail = params['demandTypeDetail-project']
}
demandSave(params).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '提交成功',
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
} else {
ElMessage.error(res.msg);
}
})
} else if (route.query.interfaceType == '2') {
params.interfaceType = '2';
competitionSave(params).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '提交成功',
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
} else {
ElMessage.error(res.msg);
}
})
} else if (route.query.interfaceType == '3') {
params.interfaceType = '3';
marketSave(params).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '提交成功',
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
} else {
ElMessage.error(res.msg);
}
})
}
} else {
params.guid = guid;
if (flowDetail.value.interfaceType == '1') {
params.interfaceType = '1';
if (params.demandType == 'DAM-TYPE') {
params.demandTypeDetail = params['demandTypeDetail-type'];
} else if (params.demandType == 'DATA_SERVICE_DETAIL') {
params.demandTypeDetail = params['demandTypeDetail-service']
} else if (params.demandType == 'PROJECT_DETAIL') {
params.demandTypeDetail = params['demandTypeDetail-project']
}
demandUpdate(params).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '提交成功',
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
} else {
ElMessage.error(res.msg);
}
})
} else if (flowDetail.value.interfaceType == '2') {
params.interfaceType = '2';
competitionUpdate(params).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '提交成功',
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
} else {
ElMessage.error(res.msg);
}
})
} else if (flowDetail.value.interfaceType == '3') {
params.interfaceType = '3';
marketUpdate(params).then((res: any) => {
flowDetailLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '提交成功',
});
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
} else {
ElMessage.error(res.msg);
}
})
}
}
} else {
nextTick(() => {
const isError = document.getElementsByClassName('is-error');
if (isError[0]) {
isError[0].scrollIntoView({
behavior: 'smooth',
block: 'center',
});
}
})
}
});
};
const btnClick = (btn) => {
if (btn.value == 'submit') {
const checkForm = listingFormRef.value;
const formEl = checkForm.ruleFormRef;
const form = checkForm.formInline;
subForm.value = { ...form };
submitForm(btn, formEl, true);
} else if(btn.value == 'pass' || btn.value == 'reject'){
dialogInfo.value.type = btn.value
dialogInfo.value.header.title = btn.value == 'pass' ? '通过' : '驳回'
dialogInfo.value.contents = contents.value[btn.value]
dialogInfo.value.visible = true
} else {
if(detailType == 'add' || detailType == 'edit'){
ElMessageBox.confirm(
"当前页面尚未保存,确定放弃修改吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
).then(() => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsPublish",
query: {},
});
}).catch(() => {
ElMessage({
type: "info",
message: "已取消",
});
});
} else {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: "productDemandsCheck",
query: {},
});
}
}
}
const setFormItems = (row: any = null) => {
formInfo.value.items.map(item => {
if (item.field == 'productImg') {
item.default = row ? (row.demandPic?[row.demandPic] : row[item.field] || []) : []
} else if (item.field == 'isDiscussPersonally') {
item.default = row ? row[item.field] : 'Y'
item.children.map(child => {
child.default = row ? row[child.field] : child.default;
child.visible = item.default == 'N'
})
} else if(item.field == 'isApproveGrounding') {
item.default = row ? row[item.field] : 'Y'
} else {
item.default = row ? row[item.field] : (item.default || '')
}
})
}
const checkboxChange = async (val, info, row) => {
if(row.field == 'isDiscussPersonally'){
let formItem = formInfo.value.items.find(i => i.field == 'isDiscussPersonally');
if (formItem) {
formItem.default = info.isDiscussPersonally;
formItem.children[0].visible = info.isDiscussPersonally != 'Y';
await setFormItems(info);
}
}
}
const switchChange = async (val, info, row) => {
if(row.field == 'isApproveGrounding') {
let formItem = formInfo.value.items.find(i => i.field == 'autoGrounding');
if (formItem) {
formItem.children[0].default = val;
setFormItems(info);
}
}
}
/** 用于保留下拉框切换之后的值 */
let oldOriginValue = ref({});
const processDemanTypeChange = (val) => {
if (val == 'DAM-TYPE') {
demandFormItems.value[3].visible = true;
demandFormItems.value[4].visible = false;
demandFormItems.value[5].visible = false;
demandFormItems.value[6].visible = true;
} else if (val == 'DATA_SERVICE_DETAIL') {
demandFormItems.value[3].visible = false;
demandFormItems.value[4].visible = true;
demandFormItems.value[5].visible = false;
demandFormItems.value[6].visible = false;
} else if (val == 'PROJECT_DETAIL') {
demandFormItems.value[3].visible = false;
demandFormItems.value[4].visible = false;
demandFormItems.value[5].visible = true;
demandFormItems.value[6].visible = false;
}
formInfo.value.items = demandFormItems.value;
}
const handleSelectChange = (val, info, row) => {
if (info.field == 'demandType') {
processDemanTypeChange(val);
let newInfo = Object.assign({}, oldOriginValue.value, row);
oldOriginValue.value = { ...newInfo };
setFormItems(newInfo);
}
}
const dialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
let params = { ...info }
params.bizGuid = guid
params.funcCode = flowDetail.value.funcCode;
if (dialogInfo.value.type == 'pass') {
dialogInfo.value.visible = false;
registerApproveAllow(params).then((res: any) => {
if (res.code == proxy.$passCode) {
ElMessage({
type: 'success',
message: '审批成功'
})
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsCheck",
query: {},
});
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
}).catch(() => {
})
} else if (dialogInfo.value.type == 'reject') {
if (info.approveSuggest == '') {
ElMessage.error('请填写驳回原因')
return
}
dialogInfo.value.visible = false;
registerApproveBackup(params).then((res: any) => {
if (res.code == proxy.$passCode) {
ElMessage({
type: 'success',
message: '驳回成功'
})
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
assetStore.set(true);
router.push({
name: "productDemandsCheck",
query: {},
});
} else {
ElMessage({
type: 'error',
message: res.msg,
})
}
}).catch(() => {
})
}
} else if (btn.value == 'cancel') {
nextTick(() => {
dialogInfo.value.visible = false;
})
}
};
onActivated(() => {
let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === router.currentRoute.value.fullPath);
if (tab) {
switch(detailType){
case 'add':
tab.meta.title = `新建数据需求${route.query.interfaceType == '2' ? '(算法竞赛)' : (route.query.interfaceType == '3' ? '(要素市场)' : '')}`;
break;
case 'edit':
tab.meta.title = `编辑-${damName}`;
break;
case 'check':
tab.meta.title = `详情-${damName}`;
break;
case 'detail':
tab.meta.title = `详情-${damName}`;
break;
}
}
})
const initMethodByInterfaceType = ref({
'1': () => {
getParamsDataList({ paramCode: 'DEMAND_TYPE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
demandTypes.value = res.data || [];
let item = demandFormItems.value.find(item => item.field == 'demandType');
item && (item.options = demandTypes.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
getParamsDataList({ paramCode: 'DAM-TYPE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
damTypes.value = res.data || [];
let item = demandFormItems.value.find(item => item.field == 'demandTypeDetail-type');
item && (item.options = damTypes.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
getParamsDataList({ paramCode: 'DATA_SERVICE_DETAIL' }).then((res: any) => {
if (res.code == proxy.$passCode) {
dataServiceDetails.value = res.data || [];
let item = demandFormItems.value.find(item => item.field == 'demandTypeDetail-service');
item && (item.options = dataServiceDetails.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
getParamsDataList({ paramCode: 'PROJECT_DETAIL' }).then((res: any) => {
if (res.code == proxy.$passCode) {
projectDetails.value = res.data || [];
let item = demandFormItems.value.find(item => item.field == 'demandTypeDetail-project');
item && (item.options = projectDetails.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
getParamsList({dictType: 'SUBJECT-DOMAIN'}).then((res: any) => {
if (res.code == proxy.$passCode) {
subjectDomainListData.value = res.data || [];
let item = demandFormItems.value.find(item => item.field == 'subjectDomain');
item && (item.options = subjectDomainListData.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
demandFormItems.value[0].default = '1';
formInfo.value.items = demandFormItems.value;
formInfo.value.rules = demandRules.value
},
'2': () => {
getParamsDataList({ paramCode: 'COMPETITION_TYPE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
projectDetails.value = res.data || [];
let item = algorithmFormItem.value.find(item => item.field == 'competitionType');
item && (item.options = projectDetails.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
formInfo.value.items = algorithmFormItem.value;
formInfo.value.rules = algorithmFormRules.value
},
'3': () => {
getProductTypeList().then((res: any) => {
if (res.code == proxy.$passCode) {
productTypes.value = res.data || [];
let item = elementFormItems.value.find(item => item.field == 'productType');
item && (item.options = productTypes.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
getParamsDataList({ paramCode: 'DELIVERY-WAY' }).then((res: any) => {
if (res.code == proxy.$passCode) {
deliveryWayList.value = res.data || [];
let item = elementFormItems.value.find(item => item.field == 'deliveryWay');
item && (item.options = deliveryWayList.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
formInfo.value.items = elementFormItems.value;
formInfo.value.rules = elementFormRules.value
}
});
onBeforeMount(() => {
if(detailType && detailType != 'add'){
getProductDetail();
if (detailType == 'detail' && dGuid !== undefined) {
getApplyDeatil();
}
}
getApproveData();
getParamsDataList({ paramCode: 'INTERFACE_TYPE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
interfaceTypes.value = res.data || [];
let item = demandFormItems.value[0];
item && (item.options = interfaceTypes.value);
algorithmFormItem.value[0].options = interfaceTypes.value;
elementFormItems.value[0].options = interfaceTypes.value;
} else {
proxy.$ElMessage.error(res.msg);
}
})
if (detailType == 'add' || detailType == 'edit') {
let interfaceType = route.query.interfaceType;
if (interfaceType == '1') {
initMethodByInterfaceType.value['1']();
} else if (interfaceType == '2') {
initMethodByInterfaceType.value['2']();
} else {
initMethodByInterfaceType.value['3']();
}
}
})
</script>
<template>
<div class="container_wrap" v-loading="flowDetailLoading">
<div class="content_main">
<div v-if="detailType == 'check'"
:class="['panel_wrap', 'results_panel', flowDetail.approveState == 'Y' ? 'success' : (flowDetail.approveState == 'R' ? 'reject' : (flowDetail.approveState == 'C' ? 'revoke' : 'audit'))]">
<div class="panel_header">
<div class="header_title" v-if="flowDetail.approveState == 'Y'">
<el-icon class="title-icon">
<svg-icon name="icon-success" />
</el-icon>
<span class="title_text">审批通过</span>
</div>
<div class="header_title" v-else-if="flowDetail.approveState == 'R'">
<el-icon class="title-icon">
<CircleCloseFilled />
</el-icon>
<span class="title_text">审批被驳回</span>
</div>
<div class="header_title" v-else-if="flowDetail.approveState == 'A'">
<el-icon class="title-icon">
<svg-icon name="icon-audit" />
</el-icon>
<span class="title_text">待审批</span>
</div>
<div class="header_title" v-else-if="flowDetail.approveState == 'C'">
<el-icon class="title-icon">
<svg-icon name="icon-revoke" />
</el-icon>
<span class="title_text">已撤销</span>
</div>
</div>
<div class="panel_body" v-if="flowDetail.approveState != 'A' && flowDetail.approveState != 'C'">
<div class="results_list">
<div class="list_item">
<span class="item_label">审批人:</span>
<span class="item_value">{{ approveTableInfo.data.at(-1)?.approvedTenantName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">审批时间:</span>
<span class="item_value">{{ approveTableInfo.data.at(-1)?.approveTime || '--' }}</span>
</div>
<div class="list_item" v-if="flowDetail.approveState == 'R'">
<span class="item_label">审批意见:</span>
<span class="item_value">{{ approveTableInfo.data.at(-1)?.approveSuggest || '--' }}</span>
</div>
</div>
</div>
</div>
<div class="panel_wrap">
<div class="panel_header">
<div class="header_title">
<span class="title_text">
<span>数据需求信息</span>
</span>
</div>
</div>
<div class="panel_body" :class="{collapse: collapseIcon}">
<div class="list_panel" v-if="detailType == 'add' || detailType == 'edit'">
<Form ref="listingFormRef" :itemList="formInfo.items" :formId="formInfo.id" :rules="formInfo.rules"
:col="formInfo.col" @checkboxChange="checkboxChange" @switchChange="switchChange" @selectChange="handleSelectChange" />
</div>
<div class="list_panel" v-else>
<div class="list_item">
<span class="item_label">界面类型:</span>
<span class="item_value">{{ flowDetail.interfaceTypeName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">数据需求名称:</span>
<span class="item_value"><ellipsis-tooltip :content="flowDetail.dataName || '--'"
class-name="w100f" :refName="'tooltipOver' + 'dataName'"></ellipsis-tooltip></span>
</div>
<template v-if="flowDetail.interfaceType == '1'">
<div class="list_item" >
<span class="item_label">需求类型:</span>
<span class="item_value">{{ flowDetail.demandTypeName || '--' }}</span>
</div>
<template v-if="flowDetail.demandType == 'DAM-TYPE'">
<div class="list_item">
<span class="item_label">数据类型:</span>
<span class="item_value">{{ flowDetail.demandTypeDetailName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">所属主题:</span>
<span class="item_value">{{ flowDetail.subjectDomainName || '--' }}</span>
</div>
</template>
<div v-else class="list_item">
<span class="item_label">{{ flowDetail.demandType == 'DATA_SERVICE_DETAIL' ? '数据服务:' : '项目:' }} </span>
<span class="item_value">{{ flowDetail.demandTypeDetailName || '--' }}</span>
</div>
</template>
<template v-if="flowDetail.interfaceType == '2'">
<div class="list_item">
<span class="item_label">竞赛类型:</span>
<span class="item_value">{{ flowDetail.competitionTypeName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">奖金(元):</span>
<span class="item_value">{{ changeNum(flowDetail.bonus, 2) || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">报名截止日:</span>
<span class="item_value">{{ flowDetail.signupEndDate || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">举办方:</span>
<span class="item_value">{{ flowDetail.organizer || '--' }}</span>
</div>
</template>
<template v-if="flowDetail.interfaceType == '3'">
<div class="list_item">
<span class="item_label">产品类别:</span>
<span class="item_value">{{ flowDetail.productTypeName || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">交付方式:</span>
<span class="item_value">{{ flowDetail.deliveryWayName || '--' }}</span>
</div>
</template>
<div class="list_item" v-if="flowDetail.interfaceType != '2'">
<span class="item_label">产品预算:</span>
<span class="item_value">{{ flowDetail.isDiscussPersonally == 'Y'?'面议':(flowDetail.productPrice || '--') }}</span>
</div>
<div class="list_item">
<span class="item_label">审核后上架:</span>
<span class="item_value">{{ flowDetail.isApproveGrounding == 'Y'?`自动上架` : '手动上架' }}</span>
</div>
<div class="list_item is_block">
<div class="file_item" v-if="flowDetail.demandPic && flowDetail.demandPic.name">
<span class="item_label">{{ flowDetail.interfaceType == '3' ? '产品图片:' : (flowDetail.interfaceType == '2' ? '赛事图片' : '需求图片') }}</span>
<span class="item_value">
<div class="file-operate">
<template
v-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'xls' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'xlsx' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'csv'">
<img class="file-img" src="../../assets/images/excel.png" />
</template>
<template
v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'doc' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'docx'">
<img class="file-img" src="../../assets/images/word.png" />
</template>
<template
v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'zip'">
<img class="file-img" src="../../assets/images/zip.png" />
</template>
<template
v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'rar'">
<img class="file-img" src="../../assets/images/RAR.png" />
</template>
<template
v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf'">
<img class="file-img" src="../../assets/images/PDF.png" />
</template>
<template
v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'png'">
<img class="file-img" src="../../assets/images/png.png" />
</template>
<template
v-else-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'">
<img class="file-img" src="../../assets/images/jpg.png" />
</template>
<div class="file-name">{{ flowDetail.demandPic.name }}</div>
<div :style="{ right: '36px' }"
v-if="flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'png' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || flowDetail.demandPic.name.substring(flowDetail.demandPic.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'"
class="file-preview" @click="onUploadFilePreview(flowDetail.demandPic)">查看</div>
<div :style="{ right: '0px' }" class="file-preview"
@click="onUploadFileDownload(flowDetail.demandPic)">下载</div>
</div>
</span>
</div>
</div>
</div>
</div>
</div>
<div class="panel_wrap" v-if="(detailType == 'detail' || detailType == 'check') && (flowDetail.content || flowDetail.demandDesc)">
<div class="panel_header">
<div class="header_title">
<span class="title_text">
<span>{{ flowDetail.interfaceType == '2' ? '赛事描述' : (flowDetail.interfaceType == '3' ? '产品描述' : '需求描述')}}</span>
</span>
</div>
</div>
<div class="panel_body" >
<div class="list_panel">
<div class="list_item is_block">
<span class="item_value" style="padding: 0px" v-html="flowDetail.content || flowDetail.demandDesc || '--'"></span>
</div>
</div>
</div>
</div>
<div class="panel_wrap" v-if="!dGuid">
<div class="panel_header">
<div class="header_title">
<span class="title_text">
<span>审批信息</span>
</span>
</div>
</div>
<div class="panel_body" :class="{collapse: collapseIcon1}">
<div class="list_panel">
<div class="table_panel_wrap">
<Table :tableInfo="approveTableInfo" />
</div>
</div>
</div>
</div>
<div class="panel_wrap" v-if="detailType == 'detail' && dGuid !== undefined">
<div class="panel_header">
<div class="header_title">
<span class="title_text">
<span>申请信息</span>
</span>
</div>
</div>
<div class="panel_body" :class="{ collapse: collapseIcon2 }">
<div class="list_panel">
<div class="list_item">
<span class="item_label">申请人姓名:</span>
<span class="item_value">{{ applyDetail.buyerContact || '--' }}</span>
</div>
<div class="list_item">
<span class="item_label">所在企业:</span>
<span class="item_value"><ellipsis-tooltip :content="applyDetail.buyer ?? '--'" class-name="w100f"
:refName="'tooltipOver' + 'releaseAgency'"></ellipsis-tooltip></span>
</div>
<div class="list_item">
<span class="item_label">联系方式:</span>
<span class="item_value">{{ applyDetail.buyerContactTel || '--' }}</span>
</div>
<div class="list_item is_block">
<span class="item_label">申请事由:</span>
<span class="item_value">{{ applyDetail.buyerRemark || '--' }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="tool_btns" v-if="detailType == 'add' || detailType == 'edit'">
<div class="btns">
<el-button @click="btnClick({ value: 'cancel' })">取消</el-button>
<el-button type="primary" @click="btnClick({ value: 'submit' })">提交</el-button>
</div>
</div>
<div class="tool_btns" v-else-if="detailType == 'check'">
<div class="btns">
<el-button plain @click="btnClick({ value: 'cancel' })">关闭</el-button>
<el-button type="primary" @click="btnClick({ value: 'pass' })" v-if="flowDetail.approveState == 'A' && flowDetail.approveTenantGuids?.includes(userData.tenantGuid)">通过</el-button>
<el-button plain type="danger" @click="btnClick({ value: 'reject' })" v-if="flowDetail.approveState == 'A' && flowDetail.approveTenantGuids?.includes(userData.tenantGuid)">驳回</el-button>
</div>
</div>
<!-- 审核对话框 -->
<Dialog ref="listingDialogRef" :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" />
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0;
height: 100%;
overflow: hidden;
&>.content_main {
padding: 16px;
height: calc(100% - 44px);
overflow: hidden auto;
&.full {
height: 100%;
}
}
}
.panel_wrap {
.panel_header {
.header_title {
height: 40px;
padding: 0 16px;
background-color: #fafafa;
box-shadow: 0 0 0 1px #e5e5e5;
display: flex;
align-items: center;
}
.title_text {
line-height: 22px;
font-size: 14px;
color: var(--el-color-regular);
font-weight: 600;
display: flex;
align-items: center;
.title_icon {
width: 26px;
height: 21px;
margin-right: 4px;
cursor: pointer;
&.active {
transform: rotate(90deg);
}
}
}
}
.panel_body {
padding: 8px 16px;
box-shadow: 0 0 0 1px rgba(229, 229, 229, 1);
border-top: none;
margin-top: 1px;
.list_panel {
display: flex;
flex-wrap: wrap;
.list_item {
width: 33.33%;
line-height: 32px;
font-size: 14px;
color: #666666;
display: flex;
justify-content: space-between;
.item_label {
width: 100px;
text-align: right;
}
.file_item {
width: 50%;
display: flex;
justify-content: space-between;
}
.item_value {
color: var(--el-color-regular);
padding: 0 16px;
flex: 1;
text-align: justify;
min-width: 0;
.file-operate {
display: flex;
align-items: center;
position: relative;
.file-img {
width: 24px;
height: 24px;
}
&:hover {
background-color: #f5f5f5;
}
.file-name {
color: var(--el-color-regular);
margin-left: 4px;
}
.file-preview {
position: absolute;
cursor: pointer;
color: var(--el-color-primary);
margin-right: 8px;
}
}
.area_text +.area_text{
&::before {
content: '、',
}
}
}
&.is_block {
width: 100%;
.item_value {
white-space: pre-wrap;
}
}
}
:deep(.el-form) {
width: 100%;
}
:deep(.panel_body) {
box-shadow: none;
}
&.label_auto {
.list_item {
.item_label {
width: auto;
}
.item_value {
padding-left: 0;
}
}
}
}
.table_panel_wrap {
.table_panel {
padding: 0;
min-height: unset;
}
}
.process_panel {
height: 500px;
.iframe-sty {
width: 100%;
height: 100%;
border: none;
}
:deep(.property-panel) {
height: calc(100% - 50px) !important;
}
}
&.collapse {
height: 0;
padding: 0;
overflow: hidden;
}
}
+.panel_wrap {
margin-top: 16px;
}
&.results_panel {
box-shadow: 0 0 0 1px #d9d9d9;
.panel_header {
.header_title {
background-color: transparent;
box-shadow: none;
.el-icon {
margin-right: 8px;
width: 20px;
height: 20px;
svg {
width: 100%;
height: 100%;
}
}
}
}
.panel_body {
padding-top: 0;
margin-top: 0;
box-shadow: none;
.results_list {
display: flex;
.list_item {
display: flex;
margin-bottom: 8px;
margin-right: 60px;
color: #666;
.item_value {
padding: 0 8px;
color: var(--el-color-regular);
}
}
}
}
&.success {
background-color: #F4FEF6;
box-shadow: 0 0 0 1px #4FA55D;
.panel_header {
.header_title {
.el-icon {
color: #4FA55D;
}
}
}
}
&.reject {
background-color: #FDF2F4;
box-shadow: 0 0 0 1px #E63E33;
.panel_header {
.header_title {
.el-icon {
color: #E63E33;
}
}
}
}
&.audit {
background-color: #FEFBF3;
box-shadow: 0 0 0 1px #F19E40;
.panel_header {
.header_title {
.el-icon {
color: #F19E40;
}
}
}
}
&.revoke {
background-color: #F5F5F5;
box-shadow: 0 0 0 1px #CCCCCC;
.panel_header {
.header_title {
.el-icon {
color: #666666;
}
}
}
}
}
}
.tool_btns {
display: flex;
justify-content: center;
align-items: center;
height: 44px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
}
:deep(.list_panel) {
.list_item .item_value {
p {
margin: 0px;
}
img {
max-width: 100%;
}
}
}
</style>
<route lang="yaml">
name: productDemandsPublish
</route>
<script lang="ts" setup name="productDemandsPublish">
import { ref, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import useUserStore from "@/store/modules/user";
import { ElMessage, ElMessageBox } from "element-plus";
import useDataAssetStore from "@/store/modules/dataAsset";
import { changeNum } from "@/utils/common";
import { getDemandList, demandDelete, demandUpdateStatus, filterVal, getParamsDataList } from "@/api/modules/dataProduct";
import { TableColumnWidth } from '@/utils/enum';
import TableTools from "@/components/Tools/table_tools.vue";
import Table from "@/components/Table/index.vue";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const assetStore = useDataAssetStore();
const interfaceTypes = ref([]);
const searchItemList: any = ref([
{
type: "input",
label: "",
field: "dataName",
default: "",
placeholder: "需求名称",
clearable: true
},
{
type: "select",
label: "",
field: "interfaceType",
default: "",
props: {
value: 'paramValue',
label: 'paramName'
},
placeholder: "界面类型",
options: interfaceTypes.value,
clearable: true,
}
]);
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 searchItemValue: any = ref({});
const currTableData: any = ref({});
const tableInfo = ref({
id: "mapping-table",
fields: [
{ label: "序号", type: "index", width: 56, align: "center", fixed: "left" },
{ label: "数据需求名称", field: "dataName", width: 200 },
{
label: "界面类型", field: "interfaceTypeName", width: 140
},
{ label: "产品预算", field: "productPrice", width: 120, },
{
label: "审核状态", field: "approveState", width: TableColumnWidth.STATE, align: 'center', type: "tag", getName: (scope) => {
return filterVal(scope.row.approveState, 'approveState');
}
},
{
label: '上架状态', field: 'listingStatus', type: 'switch', activeValue: 'Y', inactiveValue: 'N', switchWidth: 28, width: 96, align: 'center', isDisabled: (scope) => {
return scope.row.approveState != 'Y';
}
},
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
],
loading: false,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 140,
btns: (scope) => {
let row = scope.row, btnArr: any = [];
if(row.approveState == 'Y'){
if(row.listingStatus == 'Y'){
btnArr.splice(0, 0, { label: "详情", value: "detail" });
} else {
btnArr.splice(0, 0, { label: "编辑", value: "edit" }, { label: "详情", value: "detail" }, { label: "删除", value: "delete" });
}
} else {
if(row.approveState == 'A'){
btnArr.splice(0, 0, { label: "详情", value: "detail" });
} else {
btnArr.splice(0, 0, { label: "编辑", value: "edit" }, { label: "详情", value: "detail" }, { label: "删除", value: "delete" });
}
}
return btnArr;
},
},
});
const getTableData = () => {
tableInfo.value.loading = true;
getDemandList(
Object.assign({}, searchItemValue.value, {
pageIndex: page.value.curr,
pageSize: page.value.limit,
})
)
.then((res: any) => {
tableInfo.value.loading = false;
tableInfo.value.data = res.data.records || [];
tableInfo.value.page.curr = res.data.pageIndex;
tableInfo.value.page.limit = res.data.pageSize;
tableInfo.value.page.rows = res.data.totalRows;
})
.catch((res) => {
tableInfo.value.loading = false;
});
};
/** 搜索同步任务列表 */
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
searchItemValue.value = {};
} else {
searchItemValue.value = Object.keys(val).length ? { ...val } : {};
}
page.value.curr = 1;
tableInfo.value.page.curr = 1;
getTableData();
};
const tableSwitchBeforeChange = (scope, field, callback) => {
const msg = `确定${scope.row[field] == 'Y'?'下架':'上架'}该需求吗?`
ElMessageBox.confirm(
msg,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
const state = scope.row[field] == 'Y'?'N':'Y';
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,
listingStatus: val
}
demandUpdateStatus(params).then((res: any) => {
if (res.code == proxy.$passCode && res.data) {
getFirstPageData();
ElMessage({
type: "success",
message: `该产品${val == 'Y' ? '上架' : '下架'}成功`,
});
resolve(true)
} else {
ElMessage({
type: "error",
message: res.msg,
});
getTableData();
reject(false)
}
}).catch(() => {
getTableData();
reject(false)
})
})
}
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
currTableData.value = row;
if (type == "detail" || type === "edit") {
router.push({
name: "productDemandsDetail",
query: {
guid: currTableData.value.guid,
name: currTableData.value.dataName,
type
},
});
} else if (type === "delete") {
open("此操作将永久删除,是否继续?", "warning");
}
};
const handleCreateCommand = (command) => {
router.push({
name: "productDemandsDetail",
query: {
type: 'add',
interfaceType: command
},
});
}
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.limit = page.value.limit;
tableInfo.value.page.curr = page.value.curr;
getTableData();
};
const open = (msg, type, isBatch = false) => {
ElMessageBox.confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: type,
}).then(() => {
const guids = [currTableData.value.guid];
demandDelete(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: "success",
message: "删除成功",
});
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
}).catch((res) => {
tableInfo.value.loading = false;
});
});
};
const getFirstPageData = () => {
page.value.curr = 1
tableInfo.value.page.curr = 1;
getTableData();
}
onActivated(() => {
if (assetStore.isRefresh) {//如果是首次加载,则不需要调用
getFirstPageData();
assetStore.set(false);
}
})
onBeforeMount(() => {
getParamsDataList({ paramCode: 'INTERFACE_TYPE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
interfaceTypes.value = res.data || [];
let item = searchItemList.value.find(item => item.field == 'interfaceType');
item && (item.options = interfaceTypes.value);
} else {
proxy.$ElMessage.error(res.msg);
}
})
})
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" />
<div class="tools_btns">
<el-dropdown popper-class="table-create-menu-noicon" @command="handleCreateCommand" placement="bottom-start"
trigger="click">
<span class="el-dropdown-link">
<el-button type="primary" >新建</el-button>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="1">
<div class="item-content">
<span class="item-content-title">数据需求</span>
</div>
</el-dropdown-item>
</el-dropdown-menu>
<el-dropdown-menu>
<el-dropdown-item command="2">
<div class="item-content">
<span class="item-content-title">算法竞赛</span>
</div>
</el-dropdown-item>
</el-dropdown-menu>
<el-dropdown-menu>
<el-dropdown-item command="3">
<div class="item-content">
<span class="item-content-title">要素市场</span>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange" @tableSwitchBeforeChange="tableSwitchBeforeChange" />
</div>
</div>
</template>
<style scoped lang="scss">
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
.tools_btns {
padding: 0px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 0px 8px 0;
}
</style>
......@@ -19,7 +19,6 @@ import {
getProductList, getFileByDamGuid, productRejectFlowData,
getListingDetail, listingSave, listingUpdate, listingSavePortal, getParamsDataList, listingUpdateGateway, getDataExchangeProductList, getTemplateFile, getListingList
} from "@/api/modules/dataProduct";
import { getMatchDetail } from "@/api/modules/dataFinance";
import { useValidator } from '@/hooks/useValidator';
import { getCamundaDeploymentId, rejectFlowData, passFlowData, isMyFirstNode, revokeFlowData } from "@/api/modules/workFlowService";
......@@ -769,26 +768,6 @@ const getApproveData = () => {
}
// 获取申请信息
const getApplyDeatil = () => {
getMatchDetail({ guid: dGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
applyDetail.value = data;
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
}).catch((res) => {
ElMessage({
type: "error",
message: '获取申请信息失败',
});
});
}
const submitForm = (btn, formEl, tosub = false) => {
if (!formEl) return;
formEl.validate((valid, fields) => {
......
......@@ -27,7 +27,7 @@ import {
} from '@/api/modules/obsService';
import {
getDictionaryTree
} from '@/api/modules/dataInventory';
} from '@/api/modules/dataAsset';
import { commonPageConfig } from '@/utils/enum';
import { getDemandTreeList, getDiseaseAll } from '@/api/modules/dataPricing';
......
<route lang="yaml">
meta:
title: 登录
constant: true
layout: false
</route>
<script lang="ts" setup name="login">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import useUserStore from '@/store/modules/user'
import { autoSalt } from '@/utils/common'
import Form from "@/components/Form/index.vue";
import { checkCompanyName, getImgCodeSrc, getRegisterCode, checkImgCode, checkRegisterCode, registerInfoSave } from "@/api/modules/dataPartners";
import { getParamsList } from "@/api/modules/queryHomeService";
const banner = new URL('../assets/images/login-left.png', import.meta.url).href
const { proxy } = getCurrentInstance() as any;
const tenantNatureList: any = ref([]);
const loading = ref(false)
const registerFormRef = ref()
const subInfo = ref({});
const registerForm = ref({
items: [
{
label: '注册类型',
type: 'radio-group-panel',
children: [
{
label: "",
type: "radio-group",
placeholder: "",
field: 'registerType',
default: 2,
options: [
{
label: "服务端",
value: 2,
tips: '为申请数据资产服务的企业提供专业的合规登记入表等服务'
},
{
label: "企业端",
value: 1,
tips: '企业发起数据资产登记入表服务的操作'
}
],
},
],
required: true,
block: true
}, {
label: '申请人姓名',
type: 'input',
placeholder: '请输入',
field: 'contacts',
default: '',
maxlength: 20,
clearable: true,
required: true,
},
{
label: '职务',
type: 'input',
placeholder: '请输入',
field: 'contactDuties',
default: '',
maxlength: 10,
clearable: true,
required: false,
},
{
label: '所在企业',
type: 'input',
placeholder: '请输入',
field: 'companyName',
default: '',
maxlength: 200,
clearable: true,
required: true,
block: true
},
{
label: '企业类型',
type: 'select',
placeholder: '请选择',
field: 'tenantNature',
default: '',
options: tenantNatureList.value,
props: {
value: 'paramValue',
label: 'paramName'
},
clearable: true,
required: true,
block: true
},
{
label: '联系方式',
type: 'input',
placeholder: '请输入',
field: 'contactTel',
maxlength: 11,
default: '',
clearable: true,
required: true,
},
{
label: '短信验证码',
type: 'input-append-code-verify',
col: 'input_append',
placeholder: '请输入',
field: 'smsCode',
default: '',
maxlength: 6,
appendTxt: '获取短信验证码',
appendDisabled: false,
clearable: true,
required: true,
},
{
label: '注册事由',
type: 'textarea',
placeholder: '请输入',
field: 'remark',
default: '',
maxlength: 200,
clearable: true,
required: true,
block: true
},
],
rules: {
registerType: [
{ required: true, trigger: 'change', message: '请选择注册类型' },
],
contacts: [
{ required: true, trigger: 'blur', message: '请填写申请人姓名' },
{
min: 1,
max: 20,
message: '请填写申请人姓名',
trigger: 'change',
},
],
companyName: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请填写企业名称'))
} else {
if(value.length > 200){
return callback(new Error('企业名称长度不能超过200个字符'))
}
let params: any = {
companyName: value,
};
checkCompanyName(params).then((res: any) => {
if (res.code == proxy.$passCode) {
if (res.data) {
callback(new Error("该企业名称已存在,请填写其他企业名称"));
} else {
callback();
}
} else {
callback(new Error(res.msg));
}
}).catch((xhr) => {
callback(new Error(xhr.msg));
});
}
},
trigger: 'blur'
},
{
min: 1,
max: 200,
message: '请填写企业名称',
trigger: 'change',
},
],
tenantNature: [
{ required: true, trigger: 'change', message: '请选择企业类型' },
],
contactTel: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请填写手机号'))
} else {
const regs = /^(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(16[0-9]{1})|(17[0-9]{1})|(19[0-9]{1})|(18[0-9]{1}))+\d{8})$/
if (regs.test(value)) {
callback();
} else {
callback(new Error('请填写正确的手机号'))
}
}
},
trigger: 'blur'
},
{
min: 1,
max: 11,
message: '请填写手机号',
trigger: 'change',
},
],
smsCode: [
{ required: true, trigger: 'blur', message: '请填写短信验证码' },
{
min: 1,
max: 6,
message: '请填写短信验证码',
trigger: 'change',
},
],
remark: [
{ required: true, trigger: 'blur', message: '请填写注册事由' },
{
min: 1,
max: 200,
message: '请填写注册事由',
trigger: 'change',
},
]
}
})
const centerDialogVisible = ref(false);
const imgCodePath = ref('')
const imgCodeGuid = ref('');
const ruleFormRef = ref();
const ruleForm = ref({
captcha: ''
})
const rules = ref({
captcha: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请填写图形验证码'))
} else {
let params: any = {
captcha: value,
captchaGuid: imgCodeGuid.value
};
checkImgCode(params).then((res: any) => {
if (res.code == proxy.$passCode) {
if (!res.data) {
callback(new Error("验证码错误,请重新填写"));
} else {
callback();
}
} else {
callback(new Error(res.msg));
}
}).catch((xhr) => {
callback(new Error(xhr.msg));
});
}
}, trigger: 'blur'
},
{
min: 1,
message: '请填写图形验证码',
trigger: 'change',
},
]
})
const getImgCode = () => {
getImgCodeSrc({width: 180, height: 40}).then((res) => {
imgCodeGuid.value = res.data?.guid || '';
imgCodePath.value = res.data?.imageBase64 || '';
if(!centerDialogVisible.value) {
ruleForm.value.captcha = '';
centerDialogVisible.value = true;
nextTick(() => {
ruleFormRef.value.clearValidate();
})
}
})
}
const getSmsCode = (info) => {
if(registerForm.value.items.at(-2).col.indexOf('is_disabled') > -1) return
const formObj = registerFormRef.value;
const formEl = formObj.ruleFormRef;
formEl.validateField('contactTel', (valid) => {
if (valid) {
subInfo.value = info;
getImgCode();
}
});
}
const sendCode = () => {
const formEl = ruleFormRef.value;
if (!formEl) return;
formEl.validate((valid, fields) => {
if (valid) {
centerDialogVisible.value = false;
toRegister();
}
})
}
const toRegister = () => {
registerForm.value.items.at(-2).col = 'input_append is_disabled';
let count = 59;
const intervalId = setInterval(() => {
// 如果倒计时大于0,则减少1秒
if (count > 0) {
registerForm.value.items.at(-2).appendTxt = `再次发送(${count})s`;
count--;
} else {
// 如果倒计时到0,清除间隔调用并可以做其他操作
clearInterval(intervalId);
registerForm.value.items.at(-2).appendTxt = '获取短信验证码';
registerForm.value.items.at(-2).col = 'input_append';
}
}, 1000);
let params: any = {
mobileNo: subInfo.value.contactTel,
captcha: ruleForm.value.captcha,
captchaGuid: imgCodeGuid.value,
type: 1
};
getRegisterCode(params).then((res: any) => {
if (res.code == proxy.$passCode) {
ElMessage({
message: '验证码发送成功',
type: 'success',
})
} else {
ElMessage({
message: '验证码发送失败',
type: 'error',
})
}
}).catch((xhr) => {
ElMessage({
message: '验证码发送失败',
type: 'error',
})
});
}
const submitForm = (formEl, info) => {
if (!formEl) return;
formEl.validate((valid, fields) => {
if (valid) {
let param: any = {
mobileNo: info.contactTel,
code: info.smsCode
};
checkRegisterCode(param).then((res: any) => {
if (res.code == proxy.$passCode) {
if (res.data) {
let params = { ...info };
delete params.smsCode;
registerInfoSave(params).then((res: any) => {
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
message: '注册成功',
});
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
loading.value = false;
}).catch((res) => {
ElMessage({
type: "error",
message: '注册失败',
});
loading.value = false;
});
} else {
ElMessage({
message: '验证码不正确',
type: 'error',
})
loading.value = false;
}
} else {
ElMessage({
message: res.msg,
type: 'error',
})
loading.value = false;
}
}).catch((xhr) => {
ElMessage({
message: '验证码校验失败',
type: 'error',
})
loading.value = false;
});
} else {
console.log("error submit!", fields);
loading.value = false;
}
});
};
function handleRegister() {
loading.value = true;
const formObj = registerFormRef.value;
const formEl = formObj.ruleFormRef;
const form = formObj.formInline;
submitForm(formEl, { ...form });
}
onBeforeMount(() => {
getParamsList({ paramCode: 'TENANT-NATURE' }).then((res: any) => {
if (res.code == proxy.$passCode) {
tenantNatureList.value = res.data || [];
let item = registerForm.value.items?.find(c => c.field == 'tenantNature');
if (item) {
item.options = tenantNatureList.value;
// registerForm.value
}
} else {
proxy.$ElMessage.error(res.msg);
}
});
})
</script>
<template>
<div>
<div class="bg-banner" />
<div id="login-box">
<div class="login-banner">
<div>
<img :src="banner" class="banner">
<div class="banner_desc">
<h4>数据资产管理系统</h4>
<span>激活数据流通体系,释放数据要素新质生产力</span>
</div>
</div>
</div>
<div class="login_form_panel">
<div class="login_form">
<Form ref="registerFormRef" :itemList="registerForm.items" formId="partnerRegisterForm"
:rules="registerForm.rules" @inputAppendClick="getSmsCode"/>
<el-button type="primary" @click="handleRegister" :loading="loading" size="large" style="width: 100%; margin-top: 12px;">注册</el-button>
</div>
</div>
</div>
<div class="footer">
北京传世博润科技有限公司 Copyright @ 2023-2024 <a href="https://beian.miit.gov.cn" target="_blank">京ICP备2024044205号</a>
</div>
<el-dialog
v-model="centerDialogVisible"
width="360"
title="图形验证码"
align-center
>
<template #default>
<div class="img-code">
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
class="demo-ruleForm"
@submit.native.prevent
>
<el-form-item>
<div class="img_code">
<img :src="imgCodePath"/>
<span>看不清?<span class="text_btn" @click="getImgCode">换一张</span></span>
</div>
</el-form-item>
<el-form-item prop="captcha">
<el-input v-model="ruleForm.captcha" placeholder="请输入图形验证码" clearable @keyup.enter="sendCode" />
</el-form-item>
</el-form>
</div>
</template>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" size="large" @click="sendCode">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.footer {
position: absolute;
bottom: 20px;
left: 0;
width: 100%;
text-align: center;
font-size: 12px;
color: #606060;
font-weight: 200;
}
[data-mode="mobile"] {
#login-box {
position: relative;
width: 100%;
height: 100%;
top: inherit;
left: inherit;
transform: translateX(0) translateY(0);
flex-direction: column;
justify-content: start;
border-radius: 0;
box-shadow: none;
.login-banner {
width: 100%;
padding: 20px 0;
.banner {
position: relative;
right: inherit;
width: 100%;
max-width: 375px;
margin: 0 auto;
display: inherit;
top: inherit;
transform: translateY(0);
}
}
.login-form {
width: 100%;
min-height: auto;
padding: 30px;
}
}
.copyright {
position: relative;
bottom: 0;
padding-bottom: 10px;
}
}
:deep(input[type="password"]::-ms-reveal) {
display: none;
}
:deep(.el-form) {
.el-form-item {
display: flex;
flex-direction: column;
align-items: flex-start;
.el-form-item__content {
width: 100%;
}
.el-select {
width: 100%;
}
}
}
.bg-banner {
position: fixed;
z-index: 0;
width: 100%;
height: 100%;
background: url('@/assets/images/login-bg.png') center/100% 100% no-repeat;
}
#login-box {
width: 100%;
height: 100%;
display: flex;
justify-content: space-around;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
overflow: hidden;
max-width: 1280px;
min-width: 900px;
padding-bottom: 20px;
.login-banner {
height: 100%;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
>div {
display: flex;
flex-direction: column;
align-items: center;
}
.banner {
width: 495px;
}
.banner_desc {
width: 496px;
text-align: justify;
font-size: 24px;
color: #414141;
font-weight: 200;
margin-top: -32px;
h4 {
text-align: center;
margin: 0 0 8px;
font-size: 28px;
color: #414141;
font-weight: 600;
}
}
}
.login_form_panel {
display: flex;
align-items: center;
justify-content: center;
position: relative;
.login_form {
width: 600px;
height: 635px;
padding: 32px;
background: #FFFFFF;
box-shadow: 0px 4px 10px 0px rgba(0,0,0,0.2);
.title_img {
margin-top: 54px;
margin-bottom: 47px;
}
.form-content {
margin: 0px 30px;
}
}
.title-container {
text-align: center;
>img {
width: 263px;
}
.form_title {
height: 42px;
font-size: 28px;
color: #8D8D8E;
letter-spacing: 0;
text-align: center;
line-height: 42px;
font-weight: 400;
margin: 32px 0;
}
}
}
.login-form {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
.title-container {
position: relative;
.title {
font-size: 1.3em;
color: var(--el-text-color-primary);
margin: 0 auto 30px;
font-weight: bold;
}
}
}
.el-form-item {
margin-bottom: 24px;
:deep(.el-input) {
height: 44px;
line-height: inherit;
width: 100%;
input {
height: 44px;
font-size: 14px;
&:-webkit-autofill::first-line {
font-size: 14px;
}
}
.el-input__icon {
width: 20px;
height: 15px;
svg {
width: 100%;
height: 100%;
}
}
.el-input__prefix,
.el-input__suffix {
display: flex;
align-items: center;
}
.el-input__prefix {
left: 10px;
}
.el-input__suffix {
right: 10px;
}
.el-input__wrapper {
// border-radius: 0;
// box-shadow: none;
// border-bottom: 1px solid #e5e5e5;
&:hover {
// box-shadow: none;
}
}
}
}
.flex-bar {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.sub-link {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20px;
font-size: 14px;
color: var(--el-text-color-secondary);
.text {
margin-right: 10px;
}
}
}
.login-btn {
margin: 24px 30px 0 30px;
height: 44px;
width: auto;
font-size: 20px;
}
:deep(.el-dialog){
padding: 0;
.el-dialog__header {
height: 40px;
.el-dialog__headerbtn {
height: 40px;
line-height: 40px;
}
}
.el-dialog__footer {
border-top: 0;
height: 68px;
padding: 0 24px;
.dialog-footer {
display: block;
>.el-button {
width: 100%;
>span {
letter-spacing: 2px;
}
}
}
}
.img_code {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin: 8px 0;
>span {
display: block;
width: 100%;
text-align: center;
margin-top: 16px;
}
}
}
</style>
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!