Browse Source

入住详情,审核逻辑

master
ZhaoYang 3 weeks ago
parent
commit
d688b6bbc8
  1. 2
      chenhai-ui/src/api/system/user.js
  2. 11
      chenhai-ui/src/api/vet/qualification.js
  3. 373
      chenhai-ui/src/views/syd.vue
  4. 287
      chenhai-ui/src/views/system/vet/aduit/index.vue
  5. 2
      chenhai-ui/src/views/vet/info/index.vue
  6. 815
      chenhai-ui/src/views/vet/qualification/index.vue

2
chenhai-ui/src/api/system/user.js

@ -167,7 +167,7 @@ export function areaTreeSelect(query) {
// 获取用户信息
export function getUserInfo() {
return request({
url: '/muhu/user/getUserInfo',
url: '/vet/unified/info',
method: 'get'
})
}

11
chenhai-ui/src/api/vet/qualification.js

@ -17,6 +17,17 @@ export function getQualificationStatus() {
})
}
// 新增资质
export function addqualification(data) {
return request({
url: '/vet/qualification',
method: 'post',
data: data
})
}
// 重新提交
export function resubmitQualification(data) {
return request({

373
chenhai-ui/src/views/syd.vue

@ -278,10 +278,10 @@
style="width: 100%;"
>
<el-option
v-for="option in qualificationTypeOptions"
:key="option.value"
:label="option.label"
:value="option.value"
v-for="dict in dict.type.qualification_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
@ -293,10 +293,10 @@
style="width: 100%;"
>
<el-option
v-for="scope in scopeOptions"
:key="scope.value"
:label="scope.label"
:value="scope.value"
v-for="dict in dict.type.scope_names"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<div class="scope-choice">
@ -539,21 +539,21 @@
</template>
<script>
import { submitAuditQualification, getQualificationTypeOptions, getScopeOptions, getQualificationStatus } from "../api/vet/qualification";
import { submitAuditQualification, getQualificationStatus } from "../api/vet/qualification";
import { getStatsCard } from "../api/vet/notification";
import * as echarts from 'echarts';
export default {
name: "Syd",
dicts: ['qualification_type','scope_names'],
data() {
return {
tjzs: {}, //
tjzs: {},
title: "兽医资质审核",
flag: false, //
flag: false,
loading: false,
activeStep: 0,
qualificationForm: {
qualificationId: "",
realName: '',
idCard: '',
qualificationType: '',
@ -569,8 +569,6 @@ export default {
}
],
},
scopeOptions: [],
qualificationTypeOptions: [],
rules: {
realName: [
{required: true, message: "请输入真实姓名", trigger: "blur"},
@ -579,7 +577,6 @@ export default {
idCard: [
{required: true, message: "请输入身份证号", trigger: "blur"},
{ pattern: /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}(\d|X|x)$/, message: "身份证号码不合法", trigger: "blur" },
{ min: 1, max: 18, message: "长度在18个字符", trigger: "blur" },
],
qualificationType: [
{required: true, message: "请选择资质类型", trigger: "change"}
@ -588,14 +585,11 @@ export default {
{required: true, type: 'array', message: "请选择至少一个经营范围", trigger: "change"}
],
},
//
trendTimeRange: "7",
dashboardTimeRange: "7",
notificationChart: null,
trendChart: null,
qualificationChart: null,
//
platformUserValue: 12589.68,
herdsmanCount: "456/2",
vetCount: 89.50,
@ -603,7 +597,6 @@ export default {
}
},
created() {
this.initOptions();
this.getcountSummary();
this.getQualStatusAndHandle();
},
@ -613,62 +606,33 @@ export default {
});
},
beforeDestroy() {
//
if (this.notificationChart) {
this.notificationChart.dispose();
}
if (this.trendChart) {
this.trendChart.dispose();
}
if (this.qualificationChart) {
this.qualificationChart.dispose();
}
if (this.notificationChart) this.notificationChart.dispose();
if (this.trendChart) this.trendChart.dispose();
if (this.qualificationChart) this.qualificationChart.dispose();
window.removeEventListener('resize', this.handleResize);
},
methods: {
/** 获取通知数据 */
getcountSummary() {
getStatsCard().then(res => {
this.tjzs = res.data;
//
this.updateNotificationChart();
})
},
/** 初始化选项 */
initOptions() {
const fetchData = async () => {
const qtypeRes = await getQualificationTypeOptions();
this.qualificationTypeOptions = qtypeRes.data;
//
this.updateQualificationChart();
const scopeRes = await getScopeOptions();
this.scopeOptions = scopeRes.data;
}
fetchData();
},
/** 获取资质类型标签 */
getQualificationTypeLabel(value) {
const option = this.qualificationTypeOptions.find(item => item.value === value);
return option ? option.label : value;
const dictItem = this.dict.type.qualification_type.find(item => item.value === value);
return dictItem ? dictItem.label : value;
},
/** 获取经营范围标签 */
getScopeLabel(scopeId) {
const scope = this.scopeOptions.find(item => item.value === scopeId);
return scope ? scope.label : scopeId;
const dictItem = this.dict.type.scope_names.find(item => item.value === scopeId);
return dictItem ? dictItem.label : scopeId;
},
/** 上一步 */
prevStep() {
if (this.activeStep > 0) {
this.activeStep--
}
if (this.activeStep > 0) this.activeStep--;
},
/** 下一步 */
nextStep() {
if (this.activeStep === 0) {
this.$refs.qualificationForm.validate(valid => {
@ -687,13 +651,10 @@ export default {
this.$message.warning(`${index + 1}个证书:到期日期不能早于发证日期`);
}
});
if (isValid) {
this.activeStep++;
}
if (isValid) this.activeStep++;
}
},
/** 获取资质状态 */
getQualStatusAndHandle() {
getQualificationStatus()
.then(res => {
@ -704,28 +665,26 @@ export default {
})
},
/** 提交审核 */
submitQualification() {
this.loading = true;
const certificates = this.qualificationForm.certificateslist.map(item => ({
certName: item.certName || '',
issueOrg: item.issueOrg || '',
certificateNo: item.certificateNo || '',
certName: item.certName,
issueOrg: item.issueOrg,
certificateNo: item.certificateNo,
issueDate: item.issueDate,
expireDate: item.expireDate,
certificateFiles: item.certificateFiles || ''
certificateFiles: item.certificateFiles
}));
const requestData = {
realName: this.qualificationForm.realName,
idCard: this.qualificationForm.idCard,
qualificationType: this.qualificationForm.qualificationType,
scopeIds: this.qualificationForm.scopeIds || [],
scopeIds: this.qualificationForm.scopeIds,
certificates: certificates,
};
submitAuditQualification(requestData).then(response => {
submitAuditQualification(requestData).then(() => {
this.$message.success('提交成功,请等待审核');
this.flag = false;
setTimeout(() => {
@ -744,7 +703,6 @@ export default {
});
},
//
removeCertificate(index) {
if (this.qualificationForm.certificateslist.length > 1) {
this.qualificationForm.certificateslist.splice(index, 1);
@ -753,7 +711,6 @@ export default {
}
},
//
addCertificate() {
this.qualificationForm.certificateslist.push({
certName: '',
@ -765,23 +722,13 @@ export default {
});
},
/** 初始化图表 */
initCharts() {
//
this.notificationChart = echarts.init(document.getElementById('notificationChart'));
//
this.trendChart = echarts.init(document.getElementById('trendChart'));
//
this.qualificationChart = echarts.init(document.getElementById('qualificationChart'));
//
this.updateNotificationChart();
this.updateTrendChart();
this.updateQualificationChart();
//
window.addEventListener('resize', this.handleResize);
},
@ -791,76 +738,29 @@ export default {
if (this.qualificationChart) this.qualificationChart.resize();
},
/** 更新通知状态环形图 */
updateNotificationChart() {
if (!this.notificationChart) return;
const unreadCount = this.tjzs.unreadCount || 0;
const readCount = this.tjzs.readCount || 0;
const totalCount = this.tjzs.totalCount || (unreadCount + readCount);
const option = {
tooltip: {
trigger: 'item',
formatter: '{b}: {c} ({d}%)'
},
legend: {
show: false
},
series: [
{
name: '通知状态',
type: 'pie',
radius: ['55%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
position: 'outside',
formatter: '{b}\n{d}%',
color: '#606266',
fontSize: 12
},
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
}
},
data: [
{
value: unreadCount,
name: '未读通知',
itemStyle: { color: '#ff6b6b' }
},
{
value: readCount,
name: '已读通知',
itemStyle: { color: '#51cf66' }
}
]
}
]
};
this.notificationChart.setOption(option);
this.notificationChart.setOption({
tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
series: [{
type: 'pie',
radius: ['55%', '70%'],
data: [
{ value: unreadCount, name: '未读通知', itemStyle: { color: '#ff6b6b' } },
{ value: readCount, name: '已读通知', itemStyle: { color: '#51cf66' } }
]
}]
});
},
/** 更新趋势图 */
updateTrendChart() {
if (!this.trendChart) return;
//
const days = parseInt(this.trendTimeRange);
const dates = [];
const applicationData = [];
const approvalData = [];
for (let i = days - 1; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
@ -868,184 +768,45 @@ export default {
applicationData.push(Math.floor(Math.random() * 20) + 10);
approvalData.push(Math.floor(Math.random() * 15) + 5);
}
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['资质申请', '审核通过'],
orient: 'horizontal',
right: 10,
top: 0,
itemWidth: 10,
itemHeight: 10,
borderRadius: 4
},
grid: {
left: '3%',
right: '4%',
bottom: '10%',
top: '15%',
containLabel: true
},
xAxis: {
type: 'category',
data: dates,
axisLine: {
lineStyle: {
color: '#dcdfe6'
}
},
axisLabel: {
fontSize: 11
}
},
yAxis: {
type: 'value',
name: '数量',
nameTextStyle: {
fontSize: 12,
color: '#909399'
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#e9e9e9'
}
}
},
this.trendChart.setOption({
tooltip: { trigger: 'axis' },
legend: { data: ['资质申请', '审核通过'] },
xAxis: { type: 'category', data: dates },
yAxis: { type: 'value', name: '数量' },
series: [
{
name: '资质申请',
type: 'bar',
barWidth: '30%',
itemStyle: {
borderRadius: [4, 4, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#5470c6' },
{ offset: 1, color: '#91a7ff' }
])
},
data: applicationData
},
{
name: '审核通过',
type: 'bar',
barWidth: '30%',
itemStyle: {
borderRadius: [4, 4, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#91cc75' },
{ offset: 1, color: '#bae7a4' }
])
},
data: approvalData
}
{ name: '资质申请', type: 'bar', data: applicationData },
{ name: '审核通过', type: 'bar', data: approvalData }
]
};
this.trendChart.setOption(option);
});
},
/** 更新资质类型分布图 */
updateQualificationChart() {
if (!this.qualificationChart) return;
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '5%',
top: '8%',
containLabel: true
},
xAxis: {
type: 'value',
axisLabel: {
fontSize: 11
},
splitLine: {
show: false
}
},
this.qualificationChart.setOption({
tooltip: { trigger: 'axis' },
grid: { containLabel: true },
xAxis: { type: 'value' },
yAxis: {
type: 'category',
data: ['执业兽医', '乡村兽医', '官方兽医', '高级兽医师', '中级兽医师'],
axisLabel: {
fontSize: 12,
fontWeight: 500,
color: '#606266'
},
axisLine: {
show: false
},
axisTick: {
show: false
}
data: this.dict.type.qualification_type.map(item => item.label)
},
series: [
{
name: '人数',
type: 'bar',
barWidth: 12,
data: [120, 85, 45, 32, 68],
label: {
show: true,
position: 'right',
color: '#409EFF',
fontWeight: 'bold',
fontSize: 12
},
itemStyle: {
borderRadius: [0, 6, 6, 0],
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: '#409EFF' },
{ offset: 0.5, color: '#6ab7ff' },
{ offset: 1, color: '#91ccff' }
])
}
}
]
};
this.qualificationChart.setOption(option);
series: [{
name: '人数',
type: 'bar',
data: this.dict.type.qualification_type.map(() => Math.floor(Math.random() * 100) + 20)
}]
});
},
/** 刷新图表数据 */
refreshCharts() {
this.$message({
message: '正在刷新数据...',
type: 'info',
duration: 1000
});
//
this.$message({ message: '正在刷新数据...', type: 'info', duration: 1000 });
this.getcountSummary();
//
this.updateTrendChart();
//
setTimeout(() => {
this.platformUserValue += Math.floor(Math.random() * 100);
this.vetCount += Math.floor(Math.random() * 10);
this.shopCount += Math.floor(Math.random() * 5);
this.$message({
message: '数据刷新完成',
type: 'success',
duration: 1500
});
this.$message({ message: '数据刷新完成', type: 'success', duration: 1500 });
}, 800);
}
},
@ -1118,7 +879,6 @@ export default {
gap: 20px;
}
/* 主通知卡片 - 动态变色 */
.notification-card-main {
grid-column: span 1;
display: flex;
@ -1258,7 +1018,6 @@ export default {
}
}
/* 统计卡片 */
.stat-card {
background: #fff;
border-radius: 16px;
@ -1359,7 +1118,6 @@ export default {
}
}
/* 仪表板区域 */
.dashboard-section {
background: #fff;
border-radius: 20px;
@ -1398,7 +1156,6 @@ export default {
}
}
/* 图表网格 */
.chart-grid {
display: grid;
gap: 24px;
@ -1413,7 +1170,6 @@ export default {
}
}
/* 图表卡片 */
.chart-card {
background: #fff;
border-radius: 20px;
@ -1509,7 +1265,6 @@ export default {
}
}
/* KPI卡片特殊样式 */
.kpi-card {
background: linear-gradient(145deg, #fff, #fafcff);
}
@ -1586,7 +1341,6 @@ export default {
}
}
/* 资质弹窗样式 (保持原样) */
.scope-choice {
color: #b6bbc6;
font-size: 12px;
@ -1616,10 +1370,6 @@ export default {
font-weight: bold;
}
.summary-value {
color: #303133;
}
.scope-tags {
display: flex;
flex-wrap: wrap;
@ -1711,7 +1461,6 @@ export default {
}
}
/* 动画效果 */
@keyframes softPulse {
0% {
box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.4);
@ -1724,7 +1473,6 @@ export default {
}
}
/* 响应式设计 */
@media (max-width: 1200px) {
.notification-grid {
grid-template-columns: repeat(2, 1fr);
@ -1778,7 +1526,6 @@ export default {
}
}
/* 滚动条样式 */
.certificate-upload-container::-webkit-scrollbar {
width: 6px;
}
@ -1796,4 +1543,4 @@ export default {
.certificate-upload-container::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
</style>
</style>

287
chenhai-ui/src/views/system/vet/aduit/index.vue

@ -3,44 +3,20 @@
<!-- 搜索部分 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
<el-form-item label="真实姓名" prop="realName">
<el-input
v-model="queryParams.realName"
placeholder="请输入真实姓名"
clearable
@keyup.enter.native="handleQuery"
/>
<el-input v-model="queryParams.realName" placeholder="请输入真实姓名" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-input
v-model="queryParams.gender"
placeholder="请输入性别"
clearable
@keyup.enter.native="handleQuery"
/>
<el-input v-model="queryParams.gender" placeholder="请输入性别" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input
v-model="queryParams.idCard"
placeholder="请输入身份证号"
clearable
@keyup.enter.native="handleQuery"
/>
<el-input v-model="queryParams.idCard" placeholder="请输入身份证号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="工作经验" prop="workExperience">
<el-input
v-model="queryParams.workExperience"
placeholder="请输入工作经验"
clearable
@keyup.enter.native="handleQuery"
/>
<el-input v-model="queryParams.workExperience" placeholder="请输入工作经验" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="所属医院" prop="hospital">
<el-input
v-model="queryParams.hospital"
placeholder="请输入所属医院"
clearable
@keyup.enter.native="handleQuery"
/>
<el-input v-model="queryParams.hospital" placeholder="请输入所属医院" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@ -50,26 +26,12 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vet:info:remove']"
>删除</el-button>
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
v-hasPermi="['vet:info:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-check"
size="mini"
:disabled="single"
@click="handleAudit"
v-hasPermi="['sys:vetAudit:audit']"
>审核</el-button>
<el-button type="warning" plain icon="el-icon-check" size="mini" :disabled="single" @click="handleAudit"
v-hasPermi="['sys:vetAudit:audit']">审核</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@ -79,59 +41,34 @@
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="用户昵称" align="center" prop="nickName" />
<el-table-column label="真实姓名" align="center" prop="realName" />
<el-table-column label="擅长领域" align="center" prop="specialty" :show-overflow-tooltip="true"/>
<el-table-column label="职称" align="center" prop="title"/>
<el-table-column label="擅长领域" align="center" prop="specialty" :show-overflow-tooltip="true" />
<el-table-column label="职称" align="center" prop="title" />
<el-table-column label="专家类型" align="center" prop="expertType" />
<el-table-column label="所属医院" align="center" prop="hospital" :show-overflow-tooltip="true"/>
<el-table-column label="所属医院" align="center" prop="hospital" :show-overflow-tooltip="true" />
<el-table-column label="个人简介" align="center" prop="introduction" :show-overflow-tooltip="true" />
<el-table-column label="审核状态" align="center" prop="auditStatus" width="100" class-name="audit-status-column">
<template slot-scope="scope">
<dict-tag :options="dict.type.audit_status" :value="scope.row.auditStatus" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" >
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
class="info-btn view-btn"
@click="handleView(scope.row)"
v-hasPermi="['sys:vetAudit:view']"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-check"
style="color: #072eed"
class="info-btn audit-btn"
@click="handleAudit(scope.row)"
v-hasPermi="['sys:vetAudit:auditVetPersonalInfo']"
>审核</el-button>
<el-button size="mini" type="text" icon="el-icon-view" class="info-btn view-btn" @click="handleView(scope.row)"
v-hasPermi="['sys:vetAudit:view']">详情</el-button>
<el-button v-if="scope.row.auditStatus!=1" size="mini" type="text" icon="el-icon-check" style="color: #072eed" class="info-btn audit-btn"
@click="handleAudit(scope.row)" v-hasPermi="['sys:vetAudit:auditVetPersonalInfo']">审核</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagestyle">
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
</div>
<!-- 审核对话框 -->
<el-dialog
:title="auditTitle"
:visible.sync="auditVisible"
width="80%"
append-to-body
:close-on-click-modal="false"
class="audit-dialog"
@close="closeAuditDialog"
>
<el-dialog :title="auditTitle" :visible.sync="auditVisible" width="80%" append-to-body :close-on-click-modal="false"
class="audit-dialog" @close="closeAuditDialog">
<el-tabs v-model="activeAuditTab" type="border-card">
<!-- 基本信息审核标签页 -->
<el-tab-pane label="基本信息审核" name="basic">
@ -146,13 +83,14 @@
<el-descriptions :column="2" border>
<el-descriptions-item label="真实姓名">{{ basicInfo.realName || '-' }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ basicInfo.gender || '-' }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ parseTime(basicInfo.birthday, '{y}-{m}-{d}') || '-' }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ parseTime(basicInfo.birthday, '{y}-{m}-{d}') || '-'
}}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ basicInfo.idCard || '-' }}</el-descriptions-item>
<el-descriptions-item label="职称">{{ basicInfo.title || '-' }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ basicInfo.phone || '-' }}</el-descriptions-item>
<el-descriptions-item label="电子邮箱">{{ basicInfo.email || '-' }}</el-descriptions-item>
<el-descriptions-item label="专家类型">
<dict-tag :options="dict.type.expert_type" :value="basicInfo.expertType"/>
<dict-tag :options="dict.type.expert_type" :value="basicInfo.expertType" />
</el-descriptions-item>
<el-descriptions-item label="所属医院">{{ basicInfo.hospital || '-' }}</el-descriptions-item>
<el-descriptions-item label="联系地址" :span="2">{{ basicInfo.address || '-' }}</el-descriptions-item>
@ -179,14 +117,8 @@
</span>
</el-form-item>
<el-form-item label="审核意见" prop="auditDesc" v-if="basicAuditForm.auditStatus === '2'">
<el-input
v-model="basicAuditForm.auditDesc"
type="textarea"
:rows="4"
placeholder="请输入审核意见"
:maxlength="500"
show-word-limit
/>
<el-input v-model="basicAuditForm.auditDesc" type="textarea" :rows="4" placeholder="请输入审核意见"
:maxlength="500" show-word-limit />
</el-form-item>
</el-form>
</div>
@ -202,59 +134,42 @@
<div v-else>
<div v-if="!certificateList || certificateList.length === 0" class="no-data">
<el-alert
title="该兽医暂无资质证书"
type="info"
:closable="false"
show-icon
/>
<el-alert title="该兽医暂无资质证书" type="info" :closable="false" show-icon />
</div>
<div v-else>
<div class="cert-summary" v-if="certificateList.length > 0">
<el-alert
:title="getCertSummaryText()"
type="info"
:closable="false"
show-icon
/>
<el-alert :title="getCertSummaryText()" type="info" :closable="false" show-icon />
</div>
<el-tabs v-model="activeCertTab" type="card" class="cert-tabs">
<el-tab-pane
v-for="(cert, index) in certificateList"
:key="cert.qualificationId"
<el-tab-pane v-for="(cert, index) in certificateList" :key="cert.qualificationId"
:label="cert.certName || cert.qualificationType || `证书${index + 1}`"
:name="'cert' + cert.qualificationId"
>
<div class="certificate-item" :class="{'cert-audited': cert.auditStatus && cert.auditStatus !== '0'}">
:name="'cert' + cert.qualificationId">
<div class="certificate-item" :class="{ 'cert-audited': cert.auditStatus && cert.auditStatus !== '0' }">
<div class="cert-header">
<div class="cert-title">
<span>{{ cert.certName || cert.qualificationType || '未命名证书' }}</span>
<dict-tag
v-if="cert.auditStatus && cert.auditStatus !== '0'"
:options="dict.type.audit_status"
:value="cert.auditStatus"
class="cert-status-tag"
/>
<el-tag
v-else
type="warning"
size="small"
class="cert-status-tag"
effect="dark"
>
<dict-tag v-if="cert.auditStatus && cert.auditStatus !== '0'" :options="dict.type.audit_status"
:value="cert.auditStatus" class="cert-status-tag" />
<el-tag v-else type="warning" size="small" class="cert-status-tag" effect="dark">
<i class="el-icon-time"></i> 待审核
</el-tag>
</div>
<div class="cert-info">
<span><strong>证书编号</strong>{{ cert.certificateNo || '-' }}</span>
<span><strong>发证机构</strong>{{ cert.issueOrg || '-' }}</span>
<span><strong>资质类型</strong>{{ cert.qualificationType || '-' }}</span>
<span><strong>证书类型</strong>{{ cert.certType || '-' }}</span>
<span><strong>资质类型</strong>
<dict-tag :options="dict.type.qualification_type" :value="cert.qualificationType" />
</span>
<span><strong>经营范围</strong>
<div class="jyfw">
<dict-tag style="display: grid;grid-template-columns: 1fr 1fr; row-gap: 5px;"
:options="dict.type.scope_names" :value="cert.scopeIds" />
</div>
</span>
<span><strong>颁发日期</strong>{{ parseTime(cert.issueDate, '{y}-{m}-{d}') || '-' }}</span>
<span><strong>到期日期</strong>{{ parseTime(cert.expireDate, '{y}-{m}-{d}') || '-' }}</span>
<span><strong>证书状态</strong>{{ cert.certStatus || '-' }}</span>
</div>
<div v-if="cert.certImage" class="cert-image-section">
@ -262,12 +177,8 @@
<strong>证书图片</strong>
</div>
<div class="image-preview">
<el-image
style="width: 200px; height: 150px;"
:src="baseUrl + cert.certImage"
:preview-src-list="[baseUrl + cert.certImage]"
fit="contain"
>
<el-image style="width: 200px; height: 150px;" :src="baseUrl + cert.certImage"
:preview-src-list="[baseUrl + cert.certImage]" fit="contain">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
<div>图片加载失败</div>
@ -281,12 +192,8 @@
<strong>其他附件</strong>
</div>
<div class="files-list">
<el-button
type="text"
icon="el-icon-download"
@click="downloadFile(cert.certificateFiles)"
class="download-btn"
>
<el-button type="text" icon="el-icon-download" @click="downloadFile(cert.certificateFiles)"
class="download-btn">
{{ getFileName(cert.certificateFiles) }}
</el-button>
</div>
@ -294,13 +201,11 @@
</div>
<div class="cert-audit-form">
<el-form :ref="'certForm' + cert.qualificationId"
:model="certAuditForms[cert.qualificationId]"
:rules="certAuditRules"
label-width="100px">
<el-form :ref="'certForm' + cert.qualificationId" :model="certAuditForms[cert.qualificationId]"
:rules="certAuditRules" label-width="100px">
<el-form-item label="审核结果" prop="auditStatus">
<el-radio-group v-model="certAuditForms[cert.qualificationId].auditStatus"
@change="handleCertAuditChange(cert.qualificationId)">
@change="handleCertAuditChange(cert.qualificationId)">
<el-radio label="1">审核通过</el-radio>
<el-radio label="2">审核不通过</el-radio>
</el-radio-group>
@ -308,15 +213,10 @@
<dict-tag :options="dict.type.audit_status" :value="cert.auditStatus" />
</span>
</el-form-item>
<el-form-item label="审核意见" prop="auditOpinion" v-if="certAuditForms[cert.qualificationId].auditStatus === '2'">
<el-input
v-model="certAuditForms[cert.qualificationId].auditOpinion"
type="textarea"
:rows="4"
placeholder="请输入审核意见"
:maxlength="200"
show-word-limit
/>
<el-form-item label="审核意见" prop="auditOpinion"
v-if="certAuditForms[cert.qualificationId].auditStatus === '2'">
<el-input v-model="certAuditForms[cert.qualificationId].auditOpinion" type="textarea" :rows="4"
placeholder="请输入审核意见" :maxlength="200" show-word-limit />
</el-form-item>
</el-form>
</div>
@ -337,12 +237,7 @@
</el-dialog>
<!-- 详情对话框 -->
<el-dialog
:title="detailTitle"
:visible.sync="detailVisible"
width="80%"
append-to-body
>
<el-dialog :title="detailTitle" :visible.sync="detailVisible" width="80%" append-to-body>
<div v-if="loadingDetail" class="tab-loading">
<i class="el-icon-loading"></i>
<div>加载详情信息...</div>
@ -357,13 +252,14 @@
<el-descriptions-item label="用户昵称">{{ detailData.nickName || '-' }}</el-descriptions-item>
<el-descriptions-item label="真实姓名">{{ detailData.realName || '-' }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ detailData.gender || '-' }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ parseTime(detailData.birthday, '{y}-{m}-{d}') || '-' }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ parseTime(detailData.birthday, '{y}-{m}-{d}') || '-'
}}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ detailData.idCard || '-' }}</el-descriptions-item>
<el-descriptions-item label="职称">{{ detailData.title || '-' }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ detailData.phone || '-' }}</el-descriptions-item>
<el-descriptions-item label="电子邮箱">{{ detailData.email || '-' }}</el-descriptions-item>
<el-descriptions-item label="专家类型">
<dict-tag :options="dict.type.expert_type" :value="detailData.expertType"/>
<dict-tag :options="dict.type.expert_type" :value="detailData.expertType" />
</el-descriptions-item>
<el-descriptions-item label="所属医院">{{ detailData.hospital || '-' }}</el-descriptions-item>
<el-descriptions-item label="联系地址">{{ detailData.address || '-' }}</el-descriptions-item>
@ -385,30 +281,29 @@
<h3>资质证书列表 {{ detailCertificates.length }} 个证书</h3>
<el-tabs v-model="detailCertActiveTab" type="card" class="cert-tabs">
<el-tab-pane
v-for="(cert, index) in detailCertificates"
:key="cert.qualificationId"
<el-tab-pane v-for="(cert, index) in detailCertificates" :key="cert.qualificationId"
:label="cert.certName || cert.qualificationType || `证书${index + 1}`"
:name="'detailCert' + cert.qualificationId"
>
:name="'detailCert' + cert.qualificationId">
<div class="certificate-item view-only">
<div class="cert-header">
<div class="cert-title">
<span>{{ cert.certName || cert.qualificationType || '未命名证书' }}</span>
<dict-tag
:options="dict.type.audit_status"
:value="cert.auditStatus"
class="cert-status-tag"
/>
<dict-tag :options="dict.type.audit_status" :value="cert.auditStatus" class="cert-status-tag" />
</div>
<div class="cert-info">
<span><strong>证书编号</strong>{{ cert.certificateNo || '-' }}</span>
<span><strong>发证机构</strong>{{ cert.issueOrg || '-' }}</span>
<span><strong>资质类型</strong>{{ cert.qualificationType || '-' }}</span>
<span><strong>证书类型</strong>{{ cert.certType || '-' }}</span>
<span><strong>资质类型</strong>
<dict-tag :options="dict.type.qualification_type" :value="cert.qualificationType" />
</span>
<span><strong>经营范围</strong>
<div class="jyfw">
<dict-tag style="display: grid;grid-template-columns: 1fr 1fr; row-gap: 5px;"
:options="dict.type.scope_names" :value="cert.scopeIds" />
</div>
</span>
<span><strong>颁发日期</strong>{{ parseTime(cert.issueDate, '{y}-{m}-{d}') || '-' }}</span>
<span><strong>到期日期</strong>{{ parseTime(cert.expireDate, '{y}-{m}-{d}') || '-' }}</span>
<span><strong>证书状态</strong>{{ cert.certStatus || '-' }}</span>
<span><strong>审核意见</strong>{{ cert.auditOpinion || '-' }}</span>
<span><strong>审核时间</strong>{{ parseTime(cert.auditTime) || '-' }}</span>
</div>
@ -418,12 +313,8 @@
<strong>证书图片</strong>
</div>
<div class="image-preview">
<el-image
style="width: 200px; height: 150px;"
:src="baseUrl + cert.certImage"
:preview-src-list="[baseUrl + cert.certImage]"
fit="contain"
>
<el-image style="width: 200px; height: 150px;" :src="baseUrl + cert.certImage"
:preview-src-list="[baseUrl + cert.certImage]" fit="contain">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
<div>图片加载失败</div>
@ -437,12 +328,8 @@
<strong>其他附件</strong>
</div>
<div class="files-list">
<el-button
type="text"
icon="el-icon-download"
@click="downloadFile(cert.certificateFiles)"
class="download-btn"
>
<el-button type="text" icon="el-icon-download" @click="downloadFile(cert.certificateFiles)"
class="download-btn">
{{ getFileName(cert.certificateFiles) }}
</el-button>
</div>
@ -469,7 +356,7 @@ import axios from 'axios'
export default {
name: "Info",
dicts: ['expert_type', 'audit_status'],
dicts: ['expert_type', 'audit_status', 'qualification_type', 'scope_names'],
data() {
return {
loading: true,
@ -553,7 +440,7 @@ export default {
isAllAuditSelected() {
// 12
if (!this.basicAuditForm.auditStatus ||
(this.basicAuditForm.auditStatus !== '1' && this.basicAuditForm.auditStatus !== '2')) {
(this.basicAuditForm.auditStatus !== '1' && this.basicAuditForm.auditStatus !== '2')) {
return false
}
@ -563,7 +450,7 @@ export default {
const cert = this.certificateList[i]
const form = this.certAuditForms[cert.qualificationId]
if (!form || !form.auditStatus ||
(form.auditStatus !== '1' && form.auditStatus !== '2')) {
(form.auditStatus !== '1' && form.auditStatus !== '2')) {
return false
}
}
@ -721,7 +608,7 @@ export default {
submitAllAudit() {
//
if (!this.basicAuditForm.auditStatus ||
(this.basicAuditForm.auditStatus !== '1' && this.basicAuditForm.auditStatus !== '2')) {
(this.basicAuditForm.auditStatus !== '1' && this.basicAuditForm.auditStatus !== '2')) {
this.$message.warning('请选择基本信息审核结果')
this.activeAuditTab = 'basic'
return
@ -745,7 +632,7 @@ export default {
const certName = cert.certName || cert.qualificationType || `证书${i + 1}`
if (!form || !form.auditStatus ||
(form.auditStatus !== '1' && form.auditStatus !== '2')) {
(form.auditStatus !== '1' && form.auditStatus !== '2')) {
unselectedCertNames.push(certName)
} else if (form.auditStatus === '2' && !form.auditOpinion) {
invalidOpinionCertNames.push(certName)
@ -761,7 +648,7 @@ export default {
const firstUnselectedCert = this.certificateList.find(cert => {
const form = this.certAuditForms[cert.qualificationId]
return !form || !form.auditStatus ||
(form.auditStatus !== '1' && form.auditStatus !== '2')
(form.auditStatus !== '1' && form.auditStatus !== '2')
})
if (firstUnselectedCert) {
this.activeCertTab = 'cert' + firstUnselectedCert.qualificationId
@ -837,7 +724,7 @@ export default {
this.certificateList.forEach(cert => {
const form = this.certAuditForms[cert.qualificationId]
if (form && form.auditStatus &&
(form.auditStatus === '1' || form.auditStatus === '2')) {
(form.auditStatus === '1' || form.auditStatus === '2')) {
selectedCount++
}
})
@ -974,7 +861,7 @@ export default {
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
}).catch(() => { })
},
getAuditStatusText(status) {
@ -1088,16 +975,20 @@ export default {
</script>
<style>
.el-tooltip__popper{
.el-tooltip__popper {
width: 300px !important;
}
</style>
<style scoped>
::v-deep .pagestyle .el-input{
::v-deep .pagestyle .el-input {
width: auto !important;
}
::v-deep .jyfw .el-tag:nth-child(1) {
width: 70px !important;
margin-left: 10px;
}
</style>
<style scoped lang="scss">

2
chenhai-ui/src/views/vet/info/index.vue

@ -159,7 +159,7 @@
<!-- 显示兽医基本信息 -->
<el-descriptions title="兽医基本信息" :column="2" border>
<el-descriptions-item label="真实姓名">{{ detailData.realName || '-' }}</el-descriptions-item>
<el-descriptions-item label="用户昵称">{{ detailData.realName || '-' }}</el-descriptions-item>
<el-descriptions-item label="用户昵称">{{ detailData.nickName || '-' }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ detailData.gender || '-' }}</el-descriptions-item>
<el-descriptions-item label="出生日期">{{ detailData.birthday || '-' }}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ detailData.idCard || '-' }}</el-descriptions-item>

815
chenhai-ui/src/views/vet/qualification/index.vue

@ -14,24 +14,8 @@
:value="dict.value" />
</el-select>
</el-form-item>
<!-- <el-form-item label="资质类型" prop="qualificationType">-->
<!-- <el-input-->
<!-- v-model="queryParams.qualificationType"-->
<!-- placeholder="请输入资质类型"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="证书编号" prop="certificateNo">-->
<!-- <el-input-->
<!-- v-model="queryParams.certificateNo"-->
<!-- placeholder="请输入证书编号"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="审核状态" prop="auditStatus">
<el-select v-model="queryParams.auditStatus" placeholder="审核状态" clearable>
<el-select v-model="queryParams.auditStatus" placeholder="审核状态" clearable style="width: 100px">
<el-option v-for="dict in dict.type.qualification_shenhe" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
@ -43,129 +27,257 @@
</el-form>
<!-- 表格 -->
<el-table v-loading="loading" :data="qualificationList" border style="width: 100%">
<el-table v-loading="loading" :data="qualificationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="certName" label="证书名称" align="center" width="150" :show-overflow-tooltip="true"/>
<el-table-column prop="certificateNo" label="证书编号" align="center" width="150" :show-overflow-tooltip="true"/>
<el-table-column label="发证机构" align="center" prop="issueOrg" width="150" :show-overflow-tooltip="true" />
<el-table-column label="资质类型" align="center" prop="issueOrg" width="150" :show-overflow-tooltip="true" >
<el-table-column label="真实姓名" align="center" prop="realName" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.realName">{{ scope.row.realName }}</span>
<span v-else style="color: #909399">-</span>
</template>
</el-table-column>
<el-table-column label="身份证号" align="center" prop="idCard">
<template slot-scope="scope">
<span v-if="scope.row.idCard">{{ scope.row.idCard }}</span>
<span v-else style="color: #909399">-</span>
</template>
</el-table-column>
<el-table-column label="资质类型" align="center" prop="qualificationType">
<template slot-scope="scope">
<dict-tag :options="dict.type.qualification_type" :value="scope.row.qualificationType" />
</template>
</el-table-column>
<el-table-column label="经营范围" align="center" prop="scopeIds" width="200">
<template slot-scope="scope">
<dict-tag style="display: grid; grid-template-columns: 1fr 1fr; row-gap: 10px;" :options="dict.type.scope_names"
:value="scope.row.scopeIds" />
</template>
</el-table-column>
<el-table-column prop="issueDate" label="发证日期" align="center" width="150">
<el-table-column label="申请时间" align="center" prop="applyTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.issueDate, '{y}-{m}-{d}') }}</span>
<span v-if="scope.row.applyTime">{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
<span v-else style="color: #909399">-</span>
</template>
</el-table-column>
<el-table-column prop="expireDate" label="到期日期" align="center" width="150">
<el-table-column label="审核时间" align="center" prop="auditTime">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.expireDate, '{y}-{m}-{d}') }}</span>
<span v-if="scope.row.auditTime">{{ parseTime(scope.row.auditTime, '{y}-{m}-{d}') }}</span>
<span v-else style="color: #909399">-</span>
</template>
</el-table-column>
<el-table-column label="证书状态" align="center" prop="certStatus" width="100">
<el-table-column label="审核状态" align="center" prop="auditStatus">
<template slot-scope="scope">
<el-tag :type="getCertStatusType(scope.row.certStatus)" size="small">
{{ getCertStatusLabel(scope.row.certStatus) }}
<el-tag :type="getAuditStatusType(scope.row.auditStatus)" size="small">
{{ getDictLabel('qualification_shenhe', scope.row.auditStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="300">
<template slot-scope="scope">
<el-button v-if="!detailData.auditStatus || detailData.auditStatus === '0' || detailData.auditStatus === '2'"
size="mini" type="text" icon="el-icon-edit" style="color: #42B983" @click="handleUpdate(scope.row)"
v-hasPermi="['vet:qualification:edit']" class="info-btn alter-btn">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)"
v-hasPermi="['vet:qualification:query']" class="info-btn view-btn">资质详情</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagestyle">
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
</div>
<!-- 图片预览弹窗 -->
<el-dialog :visible.sync="previewDialogVisible" width="80%" append-to-body>
<div style="text-align: center; padding: 20px;">
<img :src="getImageUrl(previewFileUrl)" style="max-width: 100%; max-height: 70vh; height: auto;" preview-teleported
:preview-src-list="[getImageUrl(previewFileUrl)]" />
<div class="pagestyle">
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="closeimage"> </el-button>
</div>
</el-dialog>
<!-- 添加或修改兽医资质弹窗-->
<el-dialog :title="title" :visible.sync="open" width="80%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- <el-form-item label="真实姓名" prop="realName">-->
<!-- <el-input v-model="form.realName" placeholder="请输入真实姓名" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="身份证号" prop="idCard">-->
<!-- <el-input v-model="form.idCard" placeholder="请输入身份证号" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="资质类型" prop="qualificationType">-->
<!-- <el-select-->
<!-- v-model="form.qualificationType"-->
<!-- placeholder="请选择资质类型"-->
<!-- style="width: 100%;"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.qualification_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="证书编号" prop="certificateNo">
<el-input v-model="form.certificateNo" placeholder="请输入证书编号" />
</el-form-item>
<el-form-item label="证书名称" prop="certName">
<el-input v-model="form.certName" placeholder="请输入证书名称" />
</el-form-item>
<el-form-item label="发证机构" prop="issueOrg">
<el-input v-model="form.issueOrg" placeholder="请输入发证机构" />
</el-form-item>
<el-form-item label="发证日期" prop="issueDate">
<el-date-picker clearable v-model="form.issueDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择发证日期"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="到期日期" prop="expireDate">
<el-date-picker clearable v-model="form.expireDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择到期日期"
style="width: 100%">
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="证书图片" prop="certImage">-->
<!-- <image-upload v-model="form.certImage"/>-->
<!-- </el-form-item>-->
<el-form-item label="证书文件" prop="certificateFiles">
<!--&lt;!&ndash; <el-input v-model="form.certificateFiles" type="textarea" placeholder="请输入内容" />&ndash;&gt;-->
<file-upload v-model="form.certificateFiles" :limit="1" :file-type="['pdf', 'png', 'jpg', 'jpeg']" />
</el-form-item>
<!-- <el-form-item label="提前提醒天数" prop="remindDays">-->
<!-- <el-input v-model="form.remindDays" placeholder="请输入提前提醒天数" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="备注" prop="remark">-->
<!-- <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />-->
<!-- </el-form-item>-->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="resubmitForm">重新提交审核</el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
<!-- 显示资质证书信息弹窗 -->
<el-dialog :title="title" :visible.sync="openDetail" width="80%" append-to-body>
<div v-if="detailData" style="padding: 20px;">
<!-- 显示实名信息摘要 -->
<el-card class="auth-info-card" style="margin-bottom: 20px; background-color: #f0f9eb;" v-if="authInfo">
<div slot="header" class="clearfix">
<span><i class="el-icon-success" style="color: #67C23A;"></i> 实名认证信息</span>
</div>
<div class="auth-info-content">
<el-row :gutter="20">
<el-col :span="8">
<span class="auth-label">真实姓名</span>
<span class="auth-value">{{ detailData.realName || '-' }}</span>
</el-col>
<el-col :span="16">
<span class="auth-label">身份证号</span>
<span class="auth-value">{{ detailData.idCard || '-' }}</span>
</el-col>
</el-row>
</div>
</el-card>
<div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['vet:qualification:add']">新增</el-button>
</el-col>
</el-row>
<el-alert v-if="!certificateList || certificateList.length === 0" title="暂无资质证书" type="info" :closable="false"
style="margin-bottom: 20px;" />
<el-table v-else :data="certificateList" border style="width: 100%">
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="certificateNo" label="证书编号" align="center" width="150" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span>{{ scope.row.certificateNo }}</span>
</template>
</el-table-column>
<el-table-column prop="certName" label="证书名称" align="center" width="150" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span>{{ scope.row.certName }}</span>
</template>
</el-table-column>
<el-table-column label="发证机构" align="center" prop="issueOrg" width="150" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.issueOrg">{{ scope.row.issueOrg }}</span>
<span v-else style="color: #909399">-</span>
</template>
</el-table-column>
<el-table-column label="证书文件" prop="certificateFiles" align="center" width="100">
<template slot-scope="scope">
<span v-if="scope.row.certificateFiles">
<template v-if="isImageFile(scope.row.certificateFiles)">
<el-button type="text" icon="el-icon-view" @click="previewCertificate(scope.row.certificateFiles)"
style="color: #409EFF;font-size: 20px">
</el-button>
</template>
<template v-else-if="isPdfFile(scope.row.certificateFiles)">
<el-button type="text" icon="el-icon-download" @click="downloadFile(scope.row.certificateFiles)"
style="color: #287c07;font-size: 20px">
</el-button>
</template>
<template v-else>
{{ getImageUrl(scope.row.certificateFiles) }}
</template>
</span>
<span v-else style="color: #909399">-</span>
</template>
</el-table-column>
<el-table-column prop="issueDate" label="发证日期" align="center" width="150">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.issueDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column prop="expireDate" label="到期日期" align="center" width="150">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.expireDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="证书状态" align="center" prop="certStatus" width="100">
<template slot-scope="scope">
<el-tag :type="getCertStatusType(scope.row.certStatus)" size="small">
{{ getCertStatusLabel(scope.row.certStatus) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="300">
<template slot-scope="scope">
<el-button
v-if="!detailData.auditStatus || detailData.auditStatus === '0' || detailData.auditStatus === '2'"
size="mini" type="text" icon="el-icon-edit" style="color: #42B983" @click="handleUpdate(scope.row)"
v-hasPermi="['vet:qualification:edit']" class="info-btn alter-btn">修改</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="closeDetail"> </el-button>
</div>
</el-dialog>
<!-- 图片预览弹窗 -->
<el-dialog :visible.sync="previewDialogVisible" width="80%" append-to-body>
<div style="text-align: center; padding: 20px;">
<img :src="getImageUrl(previewFileUrl)" style="max-width: 100%; max-height: 70vh; height: auto;"
preview-teleported :preview-src-list="[getImageUrl(previewFileUrl)]" />
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="closeimage"> </el-button>
</div>
</el-dialog>
<!-- 添加或修改兽医资质弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="80%" append-to-body>
<!-- 实名认证提示 -->
<el-alert v-if="authInfo" type="success" :closable="false" show-icon style="margin-bottom: 20px;">
<span>已通过实名认证姓名和身份证已自动填充并锁定</span>
</el-alert>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- 真实姓名 - 根据实名认证状态决定是否只读 -->
<el-form-item label="真实姓名" prop="realName">
<el-input v-model="form.realName" placeholder="请输入真实姓名" :readonly="realNameReadOnly"
:disabled="realNameReadOnly">
<template v-if="realNameReadOnly" slot="suffix">
<el-tooltip content="已通过实名认证" placement="top">
<i class="el-icon-success" style="color: #67C23A; line-height: 32px;"></i>
</el-tooltip>
</template>
</el-input>
</el-form-item>
<!-- 身份证号 - 根据实名认证状态决定是否只读 -->
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="form.idCard" placeholder="请输入身份证号" :readonly="idCardReadOnly" :disabled="idCardReadOnly">
<template v-if="idCardReadOnly" slot="suffix">
<el-tooltip content="已通过实名认证" placement="top">
<i class="el-icon-success" style="color: #67C23A; line-height: 32px;"></i>
</el-tooltip>
</template>
</el-input>
</el-form-item>
<el-form-item label="证书编号" prop="certificateNo">
<el-input v-model="form.certificateNo" placeholder="请输入证书编号" />
</el-form-item>
<el-form-item label="证书名称" prop="certName">
<el-input v-model="form.certName" placeholder="请输入证书名称" />
</el-form-item>
<el-form-item label="发证机构" prop="issueOrg">
<el-input v-model="form.issueOrg" placeholder="请输入发证机构" />
</el-form-item>
<el-form-item label="发证日期" prop="issueDate">
<el-date-picker clearable v-model="form.issueDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择发证日期"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="到期日期" prop="expireDate">
<el-date-picker clearable v-model="form.expireDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择到期日期"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="证书文件" prop="certificateFiles">
<file-upload v-model="form.certificateFiles" :limit="1" :file-type="['pdf', 'png', 'jpg', 'jpeg']" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<!-- 新增模式显示"提交审核"修改模式显示"重新提交审核" -->
<el-button type="primary" @click="submitForm">{{ isAddMode ? '提交审核' : '重新提交审核' }}</el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listQualification, getQualificationCertificate, delQualification, getQualificationCertificates, updateAndSubmitQualification, listQualificationCertificates } from "@/api/vet/qualification"
import {
listQualification,
getQualificationCertificate,
delQualification,
getQualificationCertificates,
updateAndSubmitQualification,
listQualificationCertificates,
addqualification
} from "@/api/vet/qualification"
import { getUserInfo } from "@/api/system/user"
export default {
name: "Qualification",
dicts: ['qualification_shenhe', 'expert_type', 'qualification_type'],
dicts: ['qualification_shenhe', 'expert_type', 'qualification_type', 'scope_names'],
data() {
return {
baseUrl: process.env.VUE_APP_BASE_API,
@ -196,6 +308,18 @@ export default {
open: false,
openDetail: false,
previewDialogVisible: false,
// ========== ==========
//
authInfo: null,
//
realNameReadOnly: false,
idCardReadOnly: false,
//
authInfoFetched: false,
//
isAddMode: true,
//
queryParams: {
pageNum: 1,
@ -212,17 +336,8 @@ export default {
},
//
form: {},
//
// -
rules: {
// realName: [
// { required: true, message: "", trigger: "blur" }
// ],
// idCard: [
// { required: true, message: "", trigger: "blur" }
// ],
// qualificationType: [
// { required: true, message: "", trigger: "change" }
// ],
certificateNo: [
{ required: true, message: "证书编号不能为空", trigger: "blur" }
],
@ -244,16 +359,77 @@ export default {
}
}
},
created() {
this.getList()
this.getUserAuthInfo() //
},
// ========== watch ==========
watch: {
open(val) {
if (val) {
//
this.$nextTick(() => {
this.fillAuthInfoToForm()
})
}
}
},
methods: {
// ========== ==========
async getUserAuthInfo() {
if (this.authInfoFetched) return //
try {
const res = await getUserInfo()
if (res.code === 200) {
const userInfo = res.data
console.log(1111,userInfo);
//
if (userInfo.authStatus === '已认证') {
this.authInfo = userInfo
this.realNameReadOnly = true
this.idCardReadOnly = true
this.authInfoFetched = true
console.log('已获取实名认证信息:', this.authInfo)
//
if (this.open) {
this.fillAuthInfoToForm()
}
} else if (userInfo.authStatus === '未认证') {
console.log('用户未完成实名认证')
this.authInfoFetched = true
}
}
} catch (error) {
console.error('获取用户实名信息失败:', error)
}
},
// ========== ==========
fillAuthInfoToForm() {
if (this.authInfo) {
console.log(4444,this.authInfo);
// 使 Vue.set
this.$set(this.form, 'realName', this.authInfo.realName)
this.$set(this.form, 'idCard', this.authInfo.idCard)
console.log('已填充实名信息到表单:', this.form.realName, this.form.idCard)
}
},
//
getList() {
this.loading = true
listQualification(this.queryParams).then(response => {
this.qualificationList = response.rows[0].certificates
console.log(2222, this.qualificationList);
this.qualificationList = response.rows
this.total = response.total
this.loading = false
})
@ -282,21 +458,10 @@ export default {
//
getAuditStatusType(status) {
const map = {
'0': 'info', // -
'1': 'success', // - 绿
'2': 'danger', // -
'3': 'warning' // -
}
return map[status] || 'info'
},
//
formatQualificationType(status) {
const map = {
'1': '执业兽医师',
'2': '执业助理兽医',
'3': '官方兽医',
'4': '乡村兽医'
'0': 'info',
'1': 'success',
'2': 'danger',
'3': 'warning'
}
return map[status] || 'info'
},
@ -332,127 +497,68 @@ export default {
const fullUrl = this.getImageUrl(filePath);
const link = document.createElement('a');
link.href = fullUrl;
const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this.$modal.msgSuccess('开始下载文件');
},
/** 下架操作 */
// handleUnshelf(row) {
// this.$prompt('', '', {
// confirmButtonText: '',
// cancelButtonText: '',
// inputPlaceholder: '',
// inputValidator: (value) => {
// if (!value || value.trim().length < 2) {
// return '2'
// }
// if (value.trim().length > 200) {
// return '200'
// }
// return true
// }
// }).then(({ value }) => {
// this.loading = true
// unshelfQualification(row.qualificationId, value).then(response => {
// this.loading = false
// if (response.code === 200) {
// this.$modal.msgSuccess('')
// this.getList() //
// } else {
// this.$modal.msgError(response.msg || '')
// }
// }).catch(error => {
// this.loading = false
// this.$modal.msgError(error.msg || '')
// })
// }).catch(() => {
// //
// })
// },
/** 上架操作 */
// handleShelf(row) {
// this.$confirm('', '', {
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning'
// }).then(() => {
// this.loading = true
// shelfQualification(row.qualificationId).then(response => {
// this.loading = false
// if (response.code === 200) {
// this.$modal.msgSuccess('')
// this.getList() //
// } else {
// this.$modal.msgError(response.msg || '')
// }
// }).catch(error => {
// this.loading = false
// this.$modal.msgError(error.msg || '')
// })
// }).catch(() => {
// //
// })
// },
/** 提交审核操作 */
// handleSubmitAudit(row) {
// this.$modal.confirm(' "' + row.realName + '" ').then(() => {
// //
// const submitData = {
// qualificationId: row.qualificationId,
// realName: row.realName,
// idCard: row.idCard,
// qualificationType: row.qualificationType,
// certificateNo: row.certificateNo,
// certName: row.certName,
// issueOrg: row.issueOrg,
// issueDate: row.issueDate,
// expireDate: row.expireDate,
// certImage: row.certImage,
// certificateFiles: row.certificateFiles,
// remark: row.remark,
// // (0)
// auditStatus: '0'
// }
//
// return submitQualification(submitData)
// }).then(response => {
// if (response.code === 200) {
// this.$modal.msgSuccess("")
// this.getList()
// } else {
// this.$modal.msgError(response.msg || "")
// }
// }).catch(() => {
// })
// },
//
resubmitForm() {
// ========== isAddMode ==========
submitForm() {
if (this.isAddMode) {
this.handleAddSubmit()
} else {
this.handleResubmit()
}
},
//
handleAddSubmit() {
this.$refs["form"].validate(valid => {
if (valid) {
let certId = this.form.certId || this.form.certificateId || this.form.id
if (certId && typeof certId === 'object') {
certId = certId.value || certId.id || certId.certificateId
}
certId = String(certId || '')
if (!certId || certId === 'null' || certId === 'undefined' || certId === 'NaN') {
this.$modal.msgError("证书ID无效:" + certId)
return
//
const submitData = {
realName: this.form.realName || (this.authInfo ? this.authInfo.realName : null),
idCard: this.form.idCard || (this.authInfo ? this.authInfo.idCard : null),
certificateNo: this.form.certificateNo,
certName: this.form.certName,
issueOrg: this.form.issueOrg,
issueDate: this.form.issueDate,
expireDate: this.form.expireDate,
certificateFiles: this.form.certificateFiles,
remark: this.form.remark,
//
auditStatus: '0'
}
addqualification(submitData).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess("提交审核成功")
this.open = false
this.getList()
this.reset()
} else {
this.$modal.msgError(response.msg || "提交审核失败")
}
}).catch(error => {
console.error('提交审核失败:', error)
this.$modal.msgError("提交审核失败,请稍后重试")
})
}
})
},
// - updateAndSubmitQualification
handleResubmit() {
this.$refs["form"].validate(valid => {
if (valid) {
const submitData = {
certId: certId,
certId: this.form.certId || this.form.certificateId || this.form.id,
qualificationId: this.form.qualificationId,
realName: this.form.realName,
idCard: this.form.idCard,
realName: this.form.realName || (this.authInfo ? this.authInfo.realName : null),
idCard: this.form.idCard || (this.authInfo ? this.authInfo.idCard : null),
qualificationType: this.form.qualificationType,
certificateNo: this.form.certificateNo,
certName: this.form.certName,
@ -472,27 +578,11 @@ export default {
this.open = false
this.getList()
//
if (this.openDetail && this.detailData && this.detailData.qualificationId) {
getQualificationCertificates(this.detailData.qualificationId).then(response => {
if (response.code === 200) {
this.certificateList = response.rows || [];
const updatedCertificate = this.certificateList.find(cert =>
cert.certificateId === certId || cert.certId === certId
);
if (updatedCertificate) {
this.certificateList = this.certificateList.map(cert => {
if (cert.certificateId === certId || cert.certId === certId) {
return {
...cert,
auditStatus: '0',
applyTime: new Date().toISOString(),
auditTime: null,
auditOpinion: null
}
}
return cert;
});
}
}
})
}
@ -505,66 +595,17 @@ export default {
})
},
/** 查看详情 */
// handleView(row) {
// //
// let detailContent = `
// <table style="width:100%; border-collapse: collapse;">
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.realName || '-'}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.idCard || '-'}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.certificateNo || '-'}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.certName || '-'}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.issueOrg || '-'}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.expireDate ? this.parseTime(row.expireDate, '{y}-{m}-{d}') : '-'}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${this.getCertStatusLabel(row.certStatus)}</td>
// </tr>
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${this.getDictLabel('qualification_shenhe', row.auditStatus) || '-'}</td>
// </tr>`
//
// //
// if (row.auditOpinion) {
// detailContent += `
// <tr>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee; color: #666;"></td>
// <td style="padding:8px 5px; border-bottom: 1px solid #eee;">${row.auditOpinion}</td>
// </tr>`
// }
//
// detailContent += `</table>`
//
// this.$alert(detailContent, '', {
// dangerouslyUseHTMLString: true,
// confirmButtonText: '',
// width: '550px',
// customClass: 'qualification-detail-dialog'
// })
// },
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.isAddMode = true //
this.title = "添加资质信息"
},
//
handleView(row) {
console.log(1111, row);
console.log(22323232322, row);
this.openDetail = true
this.detailData = row
this.title = "资质证书详情"
@ -574,6 +615,7 @@ export default {
this.detailLoading = false
if (response.code === 200) {
this.certificateList = response.rows || [];
console.log(4444, this.certificateList);
}
})
},
@ -595,7 +637,7 @@ export default {
this.previewDialogVisible = false
},
//
// ========== reset ==========
reset() {
this.form = {
qualificationId: null,
@ -621,9 +663,20 @@ export default {
remindDays: 30,
lastRemindTime: null,
scopeIds: null,
scopeNames: null
scopeNames: null,
certId: null,
certificateId: null,
id: null
}
this.resetForm("form")
//
if (this.authInfo) {
this.$nextTick(() => {
this.fillAuthInfoToForm()
})
}
},
//
@ -645,64 +698,50 @@ export default {
this.multiple = !selection.length
},
//
handleAdd() {
// ========== handleAdd ==========
async handleAdd() {
this.reset()
this.open = true
this.isAddMode = true //
this.title = "添加兽医资质"
this.form.auditStatus = null
//
if (!this.authInfoFetched) {
await this.getUserAuthInfo()
}
//
this.fillAuthInfoToForm()
if (this.authInfo) {
this.$nextTick(() => {
this.$message.success('已自动填充实名信息')
})
}
},
//
handleUpdate(row) {
// ========== handleUpdate ==========
async handleUpdate(row) {
this.reset()
let certId = row.certId || row.certificateId || row.id
if (certId && typeof certId === 'object') {
certId = certId.value || certId.id || certId.certificateId
this.isAddMode = false //
// 使 row
this.form = row
console.log(111,this.form);
//
if (!this.authInfoFetched) {
await this.getUserAuthInfo()
}
certId = String(certId || '')
if (!certId || certId === 'null' || certId === 'undefined' || certId === 'NaN') {
this.$modal.msgError("证书ID无效:" + certId)
return
}
//
this.fillAuthInfoToForm()
getQualificationCertificate(certId).then(response => {
if (response.code === 200 && response.data) {
this.form = response.data
this.open = true
this.title = "修改兽医资质证书信息"
} else {
this.$modal.msgError(response.msg || "获取证书信息失败")
}
}).catch(error => {
console.error('获取证书信息失败:', error)
this.$modal.msgError("获取证书信息失败")
})
this.open = true
this.title = "修改兽医资质证书信息"
},
/** 提交按钮 */
// submitForm() {
// this.$refs["form"].validate(valid => {
// if (valid) {
// if (this.form.qualificationId != null) {
// updateQualification(this.form).then(response => {
// this.$modal.msgSuccess("")
// this.open = false
// this.getList()
// })
// } else {
// this.form.auditStatus = null
// addQualification(this.form).then(response => {
// this.$modal.msgSuccess("")
// this.open = false
// this.getList()
// })
// }
// }
// })
// },
//
handleDelete(row) {
const qualificationIds = row.qualificationId || this.ids
@ -714,13 +753,6 @@ export default {
}).catch(() => { })
},
//
// handleExport() {
// this.download('vet/qualification/export', {
// ...this.queryParams
// }, `qualification_${new Date().getTime()}.xlsx`)
// },
//
getDictLabel(dictType, value) {
const dict = this.dict.type[dictType]
@ -759,6 +791,35 @@ export default {
background-color: #f8fafc;
}
/* 实名信息卡片样式 */
.auth-info-card {
border-radius: 8px;
border-left: 4px solid #67C23A;
}
.auth-info-card .el-card__header {
background-color: #f0f9eb;
border-bottom: 1px solid #e1f3d8;
padding: 12px 20px;
font-weight: 600;
color: #67C23A;
}
.auth-info-content {
padding: 12px 0;
}
.auth-label {
color: #606266;
font-size: 14px;
}
.auth-value {
color: #303133;
font-weight: 500;
font-size: 14px;
}
/* 详情对话框样式 */
::v-deep .qualification-detail-dialog .el-message-box__content {
max-height: 400px;
@ -871,4 +932,4 @@ export default {
border-top: 1px solid #eef2f7;
border-radius: 0 0 12px 12px;
}
</style>
</style>
Loading…
Cancel
Save