调整结果总览模型区筛选与列表列
This commit is contained in:
@@ -38,6 +38,36 @@
|
||||
</div>
|
||||
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item filter-item--keyword">
|
||||
<span class="filter-label">员工姓名或工号</span>
|
||||
<el-input
|
||||
v-model.trim="keyword"
|
||||
size="mini"
|
||||
clearable
|
||||
placeholder="请输入员工姓名或工号"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="filter-item filter-item--dept">
|
||||
<span class="filter-label">部门</span>
|
||||
<el-select
|
||||
v-model="deptId"
|
||||
size="mini"
|
||||
clearable
|
||||
filterable
|
||||
:loading="deptLoading"
|
||||
placeholder="请选择部门"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in deptOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="filter-item filter-item--mode">
|
||||
<span class="filter-label">触发方式</span>
|
||||
<el-radio-group
|
||||
@@ -62,12 +92,35 @@
|
||||
</div>
|
||||
|
||||
<el-table v-loading="tableLoading" :data="peopleList" class="model-table">
|
||||
<template slot="empty">
|
||||
<el-empty :image-size="80" description="当前筛选条件下暂无命中人员" />
|
||||
</template>
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="staffCode" label="工号" min-width="120" />
|
||||
<el-table-column prop="idNo" label="身份证号" min-width="180" />
|
||||
<el-table-column prop="department" label="所属部门" min-width="140" />
|
||||
<el-table-column prop="warningType" label="预警类型" min-width="120" />
|
||||
<el-table-column prop="modelName" label="筛查模型" min-width="180" />
|
||||
<el-table-column label="命中模型" min-width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ formatModelNames(scope.row.modelNames) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="异常标签" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<div v-if="scope.row.hitTagList && scope.row.hitTagList.length" class="hit-tag-list">
|
||||
<el-tag
|
||||
v-for="(tag, index) in scope.row.hitTagList"
|
||||
:key="`${scope.row.staffCode || scope.row.idNo || index}-tag-${index}`"
|
||||
size="mini"
|
||||
effect="plain"
|
||||
:type="mapRiskLevelToTagType(tag.riskLevel)"
|
||||
>
|
||||
{{ tag.ruleName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini">{{
|
||||
@@ -94,6 +147,7 @@
|
||||
|
||||
<script>
|
||||
import { getOverviewRiskModelPeople } from "@/api/ccdi/projectOverview";
|
||||
import { deptTreeSelect } from "@/api/system/user";
|
||||
|
||||
function normalizePeopleRows(rows) {
|
||||
if (!Array.isArray(rows)) {
|
||||
@@ -102,11 +156,29 @@ function normalizePeopleRows(rows) {
|
||||
return rows.map((item) => ({
|
||||
...item,
|
||||
name: item.staffName || item.name || "",
|
||||
modelName: Array.isArray(item.modelNames) ? item.modelNames.join("、") : item.modelName || "",
|
||||
warningType: item.warningType || "-",
|
||||
staffCode: item.staffCode || "",
|
||||
modelNames: Array.isArray(item.modelNames) ? item.modelNames : [],
|
||||
hitTagList: Array.isArray(item.hitTagList) ? item.hitTagList : [],
|
||||
}));
|
||||
}
|
||||
|
||||
function flattenDeptOptions(nodes, result = []) {
|
||||
if (!Array.isArray(nodes)) {
|
||||
return result;
|
||||
}
|
||||
nodes.forEach((item) => {
|
||||
const value = item.id || item.deptId;
|
||||
const label = item.label || item.deptName;
|
||||
if (value !== undefined && label) {
|
||||
result.push({ value, label });
|
||||
}
|
||||
if (Array.isArray(item.children) && item.children.length) {
|
||||
flattenDeptOptions(item.children, result);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "RiskModelSection",
|
||||
props: {
|
||||
@@ -125,6 +197,8 @@ export default {
|
||||
pageSize: 5,
|
||||
cardLoading: false,
|
||||
tableLoading: false,
|
||||
deptLoading: false,
|
||||
deptOptions: [],
|
||||
peopleList: [],
|
||||
total: 0,
|
||||
};
|
||||
@@ -163,6 +237,9 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadDeptOptions();
|
||||
},
|
||||
methods: {
|
||||
isModelSelected(modelCode) {
|
||||
return this.selectedModelCodes.includes(modelCode);
|
||||
@@ -207,6 +284,34 @@ export default {
|
||||
pageSize: this.pageSize,
|
||||
};
|
||||
},
|
||||
formatModelNames(modelNames) {
|
||||
if (!Array.isArray(modelNames) || !modelNames.length) {
|
||||
return "-";
|
||||
}
|
||||
return modelNames.join("、");
|
||||
},
|
||||
mapRiskLevelToTagType(riskLevel) {
|
||||
const level = String(riskLevel || "").toUpperCase();
|
||||
if (level === "HIGH") {
|
||||
return "danger";
|
||||
}
|
||||
if (level === "MEDIUM") {
|
||||
return "warning";
|
||||
}
|
||||
return "info";
|
||||
},
|
||||
async loadDeptOptions() {
|
||||
this.deptLoading = true;
|
||||
try {
|
||||
const response = await deptTreeSelect();
|
||||
this.deptOptions = flattenDeptOptions(response && response.data);
|
||||
} catch (error) {
|
||||
this.deptOptions = [];
|
||||
console.error("加载部门选项失败", error);
|
||||
} finally {
|
||||
this.deptLoading = false;
|
||||
}
|
||||
},
|
||||
async fetchPeopleList() {
|
||||
if (!this.projectId) {
|
||||
this.peopleList = [];
|
||||
@@ -337,6 +442,16 @@ export default {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.filter-item--keyword,
|
||||
.filter-item--dept {
|
||||
min-width: 240px;
|
||||
}
|
||||
|
||||
.filter-item--keyword :deep(.el-input),
|
||||
.filter-item--dept :deep(.el-select) {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.filter-label,
|
||||
.summary-label {
|
||||
font-size: 12px;
|
||||
@@ -376,6 +491,16 @@ export default {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.hit-tag-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.pagination-bar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
23
ruoyi-ui/tests/unit/preliminary-check-model-filters.test.js
Normal file
23
ruoyi-ui/tests/unit/preliminary-check-model-filters.test.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const source = fs.readFileSync(
|
||||
path.resolve(
|
||||
__dirname,
|
||||
"../../src/views/ccdiProject/components/detail/RiskModelSection.vue"
|
||||
),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
[
|
||||
"员工姓名或工号",
|
||||
"部门",
|
||||
"任意触发",
|
||||
"同时触发",
|
||||
].forEach((token) => assert(source.includes(token), token));
|
||||
|
||||
[
|
||||
"筛查模型",
|
||||
"预警类型",
|
||||
].forEach((token) => assert(!source.includes(token), token));
|
||||
@@ -0,0 +1,24 @@
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const source = fs.readFileSync(
|
||||
path.resolve(
|
||||
__dirname,
|
||||
"../../src/views/ccdiProject/components/detail/RiskModelSection.vue"
|
||||
),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
[
|
||||
'label="工号"',
|
||||
'prop="staffCode"',
|
||||
"异常标签",
|
||||
"hitTagList",
|
||||
"ruleName",
|
||||
].forEach((token) => assert(source.includes(token), token));
|
||||
|
||||
[
|
||||
'prop="warningType"',
|
||||
'label="预警类型"',
|
||||
].forEach((token) => assert(!source.includes(token), token));
|
||||
Reference in New Issue
Block a user