数字督察一体化平台-前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

221 lines
5.6 KiB

<template>
<!-- 重复件抽屉 -->
<el-drawer
v-model="visible"
direction="rtl"
size="40%"
class="duplicate-drawer"
>
<template #header>
<div class="drawer-header danger">
<el-icon size="22">
<WarningFilled />
</el-icon>
<div class="title-group">
<div class="title">信息重复件风险提醒</div>
</div>
</div>
</template>
<div class="drawer-body">
<el-alert type="warning" show-icon :closable="false" class="drawer-alert">
<template #title>系统检测到信息可能存在重复登记记录</template>
</el-alert>
<div class="id-highlight">
当前信息:
<span>
身份证:{{ query.responderIdCode || "-" }}
&nbsp;&nbsp;&nbsp;
姓名:{{ query.responderName || "-" }}
&nbsp;&nbsp;&nbsp;
电话:{{ query.responderPhone || "-" }}
</span>
</div>
<el-empty v-if="list.length === 0" description="暂无重复数据" />
<el-table
v-else
:data="list"
stripe
style="width: 100%"
:row-class-name="rowClassName"
@row-click="handleRowClick"
>
<el-table-column prop="originId" label="编号" width="140" />
<el-table-column prop="sourceTable" label="来源" width="120" />
<!-- <el-table-column prop="sourceTable" label="来源" width="120">-->
<!-- <template #default="{ row }">-->
<!-- <span :class="{ 'source-highlight': String(row?.sourceTable || '').includes('(投)') }">-->
<!-- {{ row.sourceTable || '-' }}-->
<!-- </span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column prop="responderName" label="姓名" width="90" />
<el-table-column prop="responderIdCode" label="身份证号" width="100" show-overflow-tooltip />
<el-table-column prop="thingDesc" label="投诉内容" width="150" show-overflow-tooltip />
<el-table-column prop="discoveryTime" label="登记/受理时间" width="180">
<template #default="{ row }">
{{ row.discoveryTime ? dayjs(row.discoveryTime).format("YYYY-MM-DD HH:mm:ss") : "-" }}
</template>
</el-table-column>
</el-table>
</div>
</el-drawer>
</template>
<script setup>
import { computed, ref, watch } from "vue";
import dayjs from "dayjs";
import { WarningFilled } from "@element-plus/icons-vue";
/**
* 目标:组件内部封装:
* 1) 抽屉展示重复件列表
* 2) 点击行 -> 查看详情
*
* props:
* - modelValue: 抽屉开关
* - query: 查重条件(身份证/姓名/电话)
* - dict: 详情组件需要的 dict
* - requestFn: 请求查重函数(如 maileRepeatt)
* - autoFetchOnOpen: 打开抽屉是否自动查一次
*
* emits:
* - update:modelValue
* - loaded: 查重结果(给父组件可选做缓存/提示)
* - opened-detail: 打开了哪条详情(可选)
*/
const props = defineProps({
modelValue: { type: Boolean, default: false },
query: {
type: Object,
default: () => ({ responderIdCode: "", responderName: "", responderPhone: "" }),
},
dict: { type: Object, default: () => ({}) },
requestFn: { type: Function, required: true },
autoFetchOnOpen: { type: Boolean, default: true },
// 允许父组件指定用哪个字段当详情id(默认 complaintId)
detailIdKey: { type: String, default: "complaintId" },
excludeId: { type: [String, Number], default: "" },
});
const emit = defineEmits(["update:modelValue", "loaded", "opened-detail"]);
const visible = computed({
get: () => props.modelValue,
set: (v) => emit("update:modelValue", v),
});
const list = ref([]);
const detailShow = ref(false);
const activeId = ref("");
const fetchList = async () => {
const body = {
responderIdCode: props.query?.responderIdCode,
responderName: props.query?.responderName,
responderPhone: props.query?.responderPhone,
};
const res = await props.requestFn(body);
const rows = res?.complaintCollectionRepeatDTOS || [];
const exclude = String(props.excludeId || "");
list.value = exclude
? rows.filter(r => String(r?.complaintId || "") !== exclude)
: rows;
emit("loaded", rows);
return rows;
};
watch(
() => visible.value,
async (v) => {
if (!v) return;
list.value = [];
if (props.autoFetchOnOpen) {
try {
await fetchList();
} catch (e) {
list.value = [];
}
}
}
);
const handleRowClick = (row) => {
const id = row?.[props.detailIdKey];
if (!id) return; // 可选:这里也可以 ElMessage.warning("缺少详情ID")
activeId.value = id;
detailShow.value = true;
emit("opened-detail", row);
};
const rowClassName = ({ row }) => {
return String(row?.sourceTable || "").includes("投") ? "row-highlight" : "";
};
</script>
<style>
/* 抽屉整体 */
.duplicate-drawer {
--el-drawer-padding-primary: 20px;
}
.drawer-header {
display: flex;
align-items: center;
gap: 12px;
padding: 4px 0;
}
.drawer-header.danger {
color: #0d73ee;
}
.drawer-header .title {
font-size: 20px;
font-weight: 600;
line-height: 1.2;
}
.drawer-body {
padding-top: 8px;
}
.drawer-alert {
margin-bottom: 16px;
}
.id-highlight {
margin-bottom: 20px;
padding: 12px 16px;
background: #fafafa;
border-left: 4px solid #faad14;
font-size: 14px;
line-height: 22px;
}
.id-highlight span {
margin-left: 8px;
font-weight: 600;
color: #d4380d;
}
.clickable-row:hover > td {
background: #f5f7fa;
}
.row-highlight > td {
background: #fff4e6 !important;
}
</style>