Browse Source

兽医PC端资质相关内容修改

master
王妍洁 3 weeks ago
parent
commit
9b4a810176
  1. 1
      chenhai-ui/package.json
  2. 181
      chenhai-ui/src/api/vet/article.js
  3. 53
      chenhai-ui/src/api/vet/qualification.js
  4. BIN
      chenhai-ui/src/assets/images/tz.png
  5. BIN
      chenhai-ui/src/assets/images/tz1.png
  6. 675
      chenhai-ui/src/views/syd.vue
  7. 2461
      chenhai-ui/src/views/vet/article/index.vue
  8. 1
      chenhai-ui/src/views/vet/info/index.vue
  9. 833
      chenhai-ui/src/views/vet/qualification/index.vue

1
chenhai-ui/package.json

@ -24,6 +24,7 @@
"url": "https://gitee.com/y_project/RuoYi-Vue.git"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.2",
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.28.1",
"clipboard": "2.0.8",

181
chenhai-ui/src/api/vet/article.js

@ -1,136 +1,159 @@
import request from '@/utils/request'
// 获取论坛首页文章列表
export function getForumHome(params) {
// 查询兽医经验文章列表(论坛首页)
export function listArticle(query) {
return request({
url: '/vet/article/forum/home',
url: '/vet/article/list',
method: 'get',
params
});
}
// 获取文章详情(自动增加浏览数)
export function getForumDetail(id) {
return request({
url: `/vet/article/forum/detail/${id}`,
method: 'get'
});
params: query
})
}
// 发布论坛文章
export function publishForumArticle(data) {
// 查询我的文章列表
export function listMyArticle(query) {
return request({
url: '/vet/article/forum/publish',
method: 'post',
data
});
url: '/vet/article/myList',
method: 'get',
params: query
})
}
// 获取当前用户的文章列表
export function getMyForumArticles(params) {
// 查询兽医经验文章详细(包含相关文章)
export function getArticle(id) {
return request({
url: '/vet/article/forum/myArticles',
method: 'get',
params
});
url: '/vet/article/' + id,
method: 'get'
})
}
// 点赞文章
export function likeForumArticle(id) {
// 新增兽医经验文章(发布文章)
export function addArticle(data) {
return request({
url: `/forum/${id}/like`,
method: 'post'
});
url: '/vet/article',
method: 'post',
data: data
})
}
// 收藏文章
export function collectForumArticle(id) {
// 修改兽医经验文章
export function updateArticle(data) {
return request({
url: `/forum/${id}/collect`,
method: 'post'
});
url: '/vet/article',
method: 'put',
data: data
})
}
// 搜索论坛文章
export function searchForumArticle(params) {
// 删除兽医经验文章
export function delArticle(id) {
return request({
url: '/forum/search',
method: 'get',
params: params
});
url: '/vet/article/' + id,
method: 'delete'
})
}
// 获取热门标签
export function getForumHotTags() {
// 获取分类选项
export function getCategoryOptions() {
return request({
url: '/forum/hotTags',
url: '/vet/article/options',
method: 'get'
});
})
}
// 根据分类查询文章
export function getArticlesByCategory(categoryId) {
// 获取标签选项
export function getTagOptions() {
return request({
url: '/vet/article/' + categoryId + '/articles',
url: '/vet/article/tags/options',
method: 'get'
});
})
}
// 获取分类列表
export function getArticleOptions() {
// 点赞文章
export function likeArticle(id) {
return request({
url: '/vet/article/options',
method: 'get'
});
url: '/vet/article/' + id + '/like',
method: 'post'
})
}
// 获取文章统计信息
export function getMySimpleStats() {
// 收藏文章
export function collectArticle(id) {
return request({
url: '/vet/article/my/simpleStats',
method: 'get'
});
url: '/vet/article/' + id + '/collect',
method: 'post'
})
}
// 查询兽医经验文章列表
export function listArticle(query) {
// 获取我的收藏文章列表
export function getMyCollections(query) {
return request({
url: '/vet/article/list',
url: '/vet/article/myCollections',
method: 'get',
params: query
})
}
// 查询兽医经验文章详细
export function getArticle(id) {
// 获取论坛统计信息
export function getStatistics() {
return request({
url: '/vet/article/' + id,
url: '/vet/article/statistics',
method: 'get'
})
}
// 新增兽医经验文章
export function addArticle(data) {
// 获取最新文章
export function getLatestArticles(limit = 10) {
return request({
url: '/vet/article',
method: 'post',
data: data
url: '/vet/article/latest',
method: 'get',
params: { limit }
})
}
// 修改兽医经验文章
export function updateArticle(data) {
// 搜索文章
export function searchArticles(keyword) {
return request({
url: '/vet/article',
method: 'put',
data: data
url: '/vet/article/search',
method: 'get',
params: { keyword }
})
}
// 删除兽医经验文章
export function delArticle(id) {
export function getForumHome() {
return request({
url: '/vet/article/' + id,
method: 'delete'
url: '/vet/article/statistics',
method: 'get'
})
}
// 论坛文章详情
export function getForumDetail(id) {
return getArticle(id)
}
// 发布论坛文章
export function publishForumArticle(data) {
return addArticle(data)
}
// 我的文章
export function getMyForumArticles(query) {
return listMyArticle(query)
}
// 点赞文章
export function likeForumArticle(id) {
return likeArticle(id)
}
// 收藏文章
export function collectForumArticle(id) {
return collectArticle(id)
}
// 搜索文章
export function searchForumArticles(query) {
return searchArticles(query.keyword)
}

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

@ -9,6 +9,23 @@ export function submitAuditQualification(data) {
})
}
// 获取兽医资质审核状态
export function getQualificationStatus() {
return request({
url: '/vet/qualification/checkNeedQualification',
method: 'get'
})
}
// 重新提交
export function resubmitQualification(data) {
return request({
url: '/vet/qualification/resubmit',
method: 'post',
data: data,
})
}
// 兽医资质提交审核
// export function submitAuditQualification(qualificationId) {
// return request({
@ -26,6 +43,14 @@ export function auditQualification(data) {
})
}
// 获取证书列表
export function getQualificationCertificates() {
return request({
url: '/vet/qualification/certificate/list',
method: 'get',
})
}
// 获取资质类型列表
export function getQualificationTypeOptions() {
return request({
@ -42,14 +67,12 @@ export function getScopeOptions() {
})
}
// 资质上传
export function uploadQualification(data) {
return request({
url: '/vet/qualification/upload',
method: 'post',
data: data,
headers: {
'Content-Type': 'multipart/form-data'
},
})
}
@ -63,9 +86,20 @@ export function listQualification(query) {
}
// 查询兽医资质详细
export function getQualification(qualificationId) {
export function getQualification(qualificationId, certId) {
return request({
url: '/vet/qualification/' + qualificationId,
method: 'get',
params: {
certId: certId
}
})
}
// 证书详情
export function getQualificationCertificate(certId) {
return request({
url: '/vet/qualification/certificate/' + certId,
method: 'get'
})
}
@ -96,7 +130,7 @@ export function delQualification(qualificationId) {
})
}
// 提交审核
export function submitQualification(data) {
return request({
url: '/vet/qualification/submit',
@ -105,5 +139,14 @@ export function submitQualification(data) {
})
}
// 重新提交
export function updateAndSubmitQualification(data) {
return request({
url: '/vet/qualification/certificate/updateAndSubmit',
method: 'post',
data: data
})
}

BIN
chenhai-ui/src/assets/images/tz.png

After

Width: 200  |  Height: 200  |  Size: 6.9 KiB

BIN
chenhai-ui/src/assets/images/tz1.png

After

Width: 200  |  Height: 200  |  Size: 7.0 KiB

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

@ -1,6 +1,5 @@
<template>
<div class="app-container">
<!-- 消息通知 -->
<div class="info-container">
<div class="card-container">
@ -13,10 +12,10 @@
<span class="info-title">通知</span>
<div class="status-container">
<div class="status-row">
<span class="status-text">未读{{ tjzs.unreadCount }}</span>
<span class="status-text">未读{{ tjzs.unreadCount || 0 }}</span>
</div>
<div class="status-row">
<span class="status-text">已读{{ tjzs.readCount }}</span>
<span class="status-text">已读{{ tjzs.readCount || 0 }}</span>
</div>
</div>
</div>
@ -27,7 +26,7 @@
</div>
<div class="card-text">
<div class="card-title">总数</div>
<div class="card-value">{{ tjzs.totalCount }}</div>
<div class="card-value">{{ tjzs.totalCount || 0 }}</div>
</div>
</div>
<div class="stat-card">
@ -36,7 +35,7 @@
</div>
<div class="card-text">
<div class="card-title">已读</div>
<div class="card-value">{{ tjzs.readCount }}</div>
<div class="card-value">{{ tjzs.readCount || 0 }}</div>
</div>
</div>
<div class="stat-card">
@ -45,7 +44,7 @@
</div>
<div class="card-text">
<div class="card-title">未读</div>
<div class="card-value">{{ tjzs.unreadCount }}</div>
<div class="card-value">{{ tjzs.unreadCount || 0 }}</div>
</div>
</div>
</div>
@ -53,7 +52,7 @@
<!-- 资质弹窗 -->
<el-dialog :title="title" :visible.sync="flag" width="800px" append-to-body>
<el-steps :active="activeStep" finish-status="success" simple style="margin-bottom: 10px;">
<el-steps :active="activeStep" finish-status="success" simple style="margin-bottom: 40px;">
<el-step title="选择经营范围"></el-step>
<el-step title="上传资质"></el-step>
<el-step title="提交审核"></el-step>
@ -84,9 +83,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="证书编号" prop="certificateNo">
<el-input v-model="qualificationForm.certificateNo" placeholder="请输入证书编号" />
</el-form-item>
<el-form-item label="经营范围" prop="scopeIds">
<el-select
v-model="qualificationForm.scopeIds"
@ -114,9 +111,16 @@
<div class="summary-item">
<span class="summary-label">资质类型</span>
<div class="scope-tags">
<!-- <el-tag-->
<!-- v-for="qualificationType in qualificationForm.qualificationType"-->
<!-- :key="qualificationType"-->
<!-- type="info"-->
<!-- size="small"-->
<!-- class="scope-tag"-->
<!-- >-->
<!-- {{ getQualificationTypeLabel(qualificationForm.qualificationType) }}-->
<!-- </el-tag>-->
<el-tag
v-for="qualificationType in qualificationForm.qualificationType"
:key="qualificationType"
type="info"
size="small"
class="scope-tag"
@ -143,36 +147,91 @@
<div style="margin-bottom: 15px; color: #f56c6c; font-size: 14px;">
<i class="el-icon-warning"></i>
需要您上传相关的资质文件
需要您上传相关的证书文件
</div>
<el-form>
<el-form-item label="资质文件" required>
<el-upload
ref="upload"
action="#"
:multiple="true"
:file-list="fileList"
:auto-upload="false"
:on-change="handleFileChange"
:on-remove="handleRemove"
:show-file-list="true"
accept=".jpg,.jpeg,.png,.pdf,.JPG,.JPEG,.PNG,.PDF"
>
<el-button type="primary">选择文件</el-button>
<div slot="tip" class="el-upload__tip">
请上传清晰的资质文件照片或扫描件支持JPGPNGPDF格式
<el-form ref="qualificationForm" :model="qualificationForm">
<div class="certificate-upload-container">
<div v-for="(certificate, index) in qualificationForm.certificateslist" :key="index" class="certificate-card">
<div class="certificate-header">
<span class="certificate-title">证书 {{ index + 1 }}</span>
<el-button
v-if="qualificationForm.certificateslist.length > 1"
type="danger"
icon="el-icon-delete"
circle
size="mini"
@click="removeCertificate(index)"
title="删除此证书"
></el-button>
</div>
</el-upload>
<div class="certificate-form">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="证书名称" :prop="'certificateslist.' + index + '.certName'">
<el-input v-model="certificate.certName" placeholder="请输入证书名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发证机构" :prop="'certificateslist.' + index + '.issueOrg'">
<el-input v-model="certificate.issueOrg" placeholder="请输入发证机构" />
</el-form-item>
</el-col>
</el-row>
<div v-if="uploadedFiles.length > 0" class="uploaded-files">
<div class="file-list-title">已上传文件</div>
<div v-for="(file, index) in uploadedFiles" :key="index" class="file-item">
<i class="el-icon-document"></i>
{{ file.name }}
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="证书编号" :prop="'certificateslist.' + index + '.certificateNo'">
<el-input v-model="certificate.certificateNo" placeholder="请输入证书编号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="发证日期" :prop="'certificateslist.' + index + '.issueDate'">
<el-date-picker
v-model="certificate.issueDate"
type="date"
placeholder="请选择发证日期"
style="width: 100%;"
value-format="yyyy-MM-dd"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="到期日期" :prop="'certificateslist.' + index + '.expireDate'">
<el-date-picker
v-model="certificate.expireDate"
type="date"
placeholder="请选择到期日期"
style="width: 100%;"
value-format="yyyy-MM-dd"
/>
</el-form-item>
</el-col>
</el-row>
<el-form>
<el-form-item label="资质文件" :prop="'certificateslist.' + index + '.certificateFiles'">
<file-upload
v-model="certificate.certificateFiles"
:limit="1"
:file-type="['pdf','png','jpg','jpeg']"
/>
</el-form-item>
</el-form>
</div>
</div>
</div>
<div class="add-certificate-btn">
<el-button type="primary" icon="el-icon-plus" @click="addCertificate" plain>
添加证书
</el-button>
<span class="certificate-count">
已添加 {{ qualificationForm.certificateslist.length }} 个证书
</span>
</div>
</el-form>
</div>
@ -189,12 +248,11 @@
<div style="margin-bottom: 8px;"><strong>基本信息</strong></div>
<div style="margin-bottom: 5px;">真实姓名{{ qualificationForm.realName }}</div>
<div style="margin-bottom: 5px;">身份证号{{ qualificationForm.idCard }}</div>
<div style="margin-bottom: 5px;">资质类型{{ qualificationForm.qualificationType }}</div>
<div>证书编号{{ qualificationForm.certificateNo }}</div>
<div style="margin-bottom: 5px;">资质类型{{ getQualificationTypeLabel(qualificationForm.qualificationType) }}</div>
</div>
<div style="margin-bottom: 15px; color: #606266;">
<div>经营范围</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<div style="margin-bottom: 8px;"><strong>经营范围</strong></div>
<div class="scope-tags">
<el-tag
v-for="scopeId in qualificationForm.scopeIds"
@ -208,14 +266,61 @@
</div>
</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<div style="margin-bottom: 8px;"><strong>上传文件</strong></div>
<div v-if="fileList.length > 0">
<div v-for="(file, index) in fileList" :key="index" style="margin-bottom: 5px;">
{{ file.name }}
<div style="background: #f8f9fa; border-radius: 4px; margin-bottom: 20px;">
<div v-if="qualificationForm.certificateslist.length > 0" style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<div style="margin-bottom: 15px;"><strong>证书信息</strong></div>
<div v-for="(certificate, index) in qualificationForm.certificateslist" :key="index" class="certificate-review">
<div style="font-weight: bold; margin-bottom: 8px; color: #409EFF;">
证书 {{ index + 1 }}
</div>
<el-row :gutter="20">
<el-col :span="8">
<div class="review-item">
<span class="review-label">证书名称</span>
<span class="review-value">{{ certificate.certName }}</span>
</div>
</el-col>
<el-col :span="8">
<div class="review-item">
<span class="review-label">发证机构</span>
<span class="review-value">{{ certificate.issueOrg }}</span>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="16">
<div class="review-item">
<span class="review-label">证书编号</span>
<span class="review-value">{{ certificate.certificateNo }}</span>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<div class="review-item">
<span class="review-label">发证日期</span>
<span class="review-value">{{ certificate.issueDate }}</span>
</div>
</el-col>
<el-col :span="8">
<div class="review-item">
<span class="review-label">到期日期</span>
<span class="review-value">{{ certificate.expireDate }}</span>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="16">
<div class="review-item">
<span class="review-label">证书文件</span>
<span class="review-value">{{ certificate.certificateFiles }}</span>
</div>
</el-col>
</el-row>
</div>
</div>
<div v-else style="color: #909399;">暂无文件</div>
</div>
</div>
@ -227,7 +332,7 @@
<div v-if="activeStep < 2">
<el-button type="primary" @click="nextStep">
{{ activeStep === 1 ? '下一步' : '下一步' }}
下一步
</el-button>
</div>
@ -243,7 +348,7 @@
</template>
<script>
import { submitAuditQualification, qualificationAudit, getQualificationTypeOptions, getScopeOptions, uploadQualification } from "../api/vet/qualification";
import { submitAuditQualification, getQualificationTypeOptions, getScopeOptions, getQualificationStatus } from "../api/vet/qualification";
import { getStatsCard } from "../api/vet/notification";
export default {
@ -252,11 +357,10 @@ export default {
return {
//
tjzs: {},
//
title: "兽医资质审核",
flag: true,
open: false,
// flag: true,
flag: false,
loading: false,
activeStep: 0,
qualificationForm: {
@ -264,17 +368,20 @@ export default {
realName: '',
idCard: '',
qualificationType: '',
certificateNo: '',
scopeIds: [],
certificateslist: [
{
certName: '',
issueOrg: '',
certificateNo: '',
issueDate: '',
expireDate: '',
certificateFiles: '',
}
],
},
fileList: [],
scopeOptions: [],
uploadedFiles: [],
qualificationTypeOptions: [],
selectedScopesDetail: '',
fileUploadResponses: [],
rules: {
realName: [
@ -286,23 +393,16 @@ export default {
qualificationType: [
{required: true, message: "请选择资质类型", trigger: "change"}
],
certificateNo : [
{required: true, message: "请输入证书编号", trigger: "blur"}
],
scopeIds: [
{
required: true,
type: 'array',
message: "请选择至少一个经营范围",
trigger: "change"
}
]
}
{required: true, type: 'array', message: "请选择至少一个经营范围", trigger: "change"}
],
},
}
},
created() {
this.initOptions();
this.getcountSummary()
this.getcountSummary();
this.getQualStatusAndHandle();
},
methods: {
//
@ -336,69 +436,6 @@ export default {
return scope ? scope.label : scopeId;
},
//
uploadSingleFile(file) {
return new Promise((resolve, reject) => {
const formData = new FormData();
formData.append('file', file.raw);
uploadQualification(formData)
.then(response => {
const filePath = response.data.filePath || response.data.path || response.data.url;
this.fileUploadResponses.push({
fileName: file.name,
filePath: filePath,
fileId: response.data.id || response.data.fileId
});
this.uploadedFiles.push({
name: file.name,
uid: file.uid,
path: filePath
});
this.$message.success(`${file.name} 上传成功`);
resolve(response);
})
.catch(error => {
reject(error);
});
});
},
//
handleFileChange(file, fileList) {
if (!file.raw ||
file.raw.size / 1024 / 1024 >= 10 ||
!['image/jpeg', 'image/png', 'application/pdf'].includes(file.raw.type)) {
let errorMsg = '';
if (!file.raw) errorMsg = '获取文件失败,请重新选择文件';
else if (file.raw.size / 1024 / 1024 >= 10) errorMsg = '文件大小不能超过10MB';
else errorMsg = '只能上传JPG、PNG或PDF格式的文件';
this.$message.error(errorMsg);
this.fileList = fileList.filter(item => item.uid !== file.uid);
return;
}
this.fileList = fileList;
if (file.status === 'ready') {
file.status = 'uploading';
this.uploadSingleFile(file)
.then(() => file.status = 'success')
.catch(() => file.status = 'fail');
}
},
//
handleRemove(file, fileList) {
this.fileList = fileList;
const showIndex = this.uploadedFiles.findIndex(f => f.name === file.name);
if (showIndex > -1) {
this.uploadedFiles.splice(showIndex, 1);
}
const resIndex = this.fileUploadResponses.findIndex(f => f.fileName === file.name);
if (resIndex > -1) {
this.fileUploadResponses.splice(resIndex, 1);
}
},
//
prevStep() {
if (this.activeStep > 0) {
@ -409,68 +446,101 @@ export default {
//
nextStep() {
if (this.activeStep === 0) {
this.$refs.qualificationForm.validate(valid => valid && (this.activeStep++));
this.$refs.qualificationForm.validate(valid => {
if (valid) this.activeStep++;
});
return;
}
if (this.activeStep === 1) {
if (!this.fileList.length) {
this.$message.warning('请上传资质文件');
return;
let isValid = true;
this.qualificationForm.certificateslist.forEach((item, index) => {
if (!item.certName || !item.issueOrg || !item.certificateNo || !item.issueDate || !item.expireDate || !item.certificateFiles) {
isValid = false;
this.$message.warning(`${index + 1}个证书信息不完整,请检查`);
} else if (new Date(item.expireDate) < new Date(item.issueDate)) {
isValid = false;
this.$message.warning(`${index + 1}个证书:到期日期不能早于发证日期`);
}
const anyUploading = this.fileList.some(file => file.status === 'uploading');
const anyFailed = this.fileList.some(file => file.status === 'fail');
const allSuccess = this.fileList.every(file => file.status === 'success');
if (anyUploading) {
this.$message.warning('文件正在上传中,请等待上传完成');
} else if (anyFailed) {
this.$message.warning('存在上传失败的文件,请重新上传或移除失败的文件');
} else if (!allSuccess) {
this.$message.warning('请确保所有文件都上传成功');
} else {
});
if (isValid) {
this.activeStep++;
}
}
},
//
getQualStatusAndHandle() {
getQualificationStatus()
.then(res => {
const statusData = res.data || {};
if (statusData.needPopup === true || statusData.status === 'empty') {
this.flag = true;
}
})
},
//
submitQualification() {
this.loading = true;
const certificates = this.qualificationForm.certificateslist.map(item => ({
certName: item.certName || '',
issueOrg: item.issueOrg || '',
certificateNo: item.certificateNo || '',
issueDate: item.issueDate,
expireDate: item.expireDate,
certificateFiles: item.certificateFiles || ''
}));
const requestData = {
realName: this.qualificationForm.realName,
idCard: this.qualificationForm.idCard,
qualificationType: this.qualificationForm.qualificationType,
certificateNo: this.qualificationForm.certificateNo,
scopeIds: this.qualificationForm.scopeIds || [],
certificateFiles: this.fileUploadResponses.map(item => item.fileUrl).join(','),
certificateFileIds: this.fileUploadResponses.map(item => item.fileId).join(',')
certificates: certificates,
};
// console.log(':', JSON.stringify(requestData, null, 2));
submitAuditQualification(requestData)
.then(response => {
this.$modal.msgSuccess('提交成功,请等待审核');
this.$message.success('提交成功,请等待审核');
this.flag = false;
this.resetForm();
setTimeout(() => {
this.$router.push('/VetQualification');
}, 300);
})
.catch(error => {
console.error('提交失败:', error);
console.error('错误详情:', error.response?.data);
if (error.response?.data?.message) {
this.$message.error('提交失败: ' + error.response.data.message);
} else {
this.$message.error('提交失败,请重试');
}
this.$message.error(error.response?.data?.message || '提交失败,请重试');
})
.finally(() => {
this.loading = false;
});
},
//
removeCertificate(index) {
if (this.qualificationForm.certificateslist.length > 1) {
this.qualificationForm.certificateslist.splice(index, 1);
} else {
this.$message.warning('至少需要保留一个证书的信息');
}
},
//
addCertificate() {
this.qualificationForm.certificateslist.push({
certName: '',
issueOrg: '',
certificateNo: '',
issueDate: '',
expireDate: '',
certificateFiles: ''
});
},
}
}
</script>
<style scoped lang="scss">
/* 轮播背景 */
.card-container {
@ -513,6 +583,7 @@ export default {
.shake {
animation: cardShake 1s infinite linear;
background-color: #fffde6 !important;
&:hover {
animation-play-state: paused;
background-color: #edeacd !important;
@ -570,15 +641,16 @@ export default {
.icon-total {
background: linear-gradient(135deg, #ff9a44 0%, #ff6b08 100%);
}
.icon-pending {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.icon-handled {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
/* 资质弹窗 */
/* 经营范围 */
.scope-choice {
color: #b6bbc6;
@ -616,6 +688,7 @@ export default {
.scope-tags {
display: flex;
flex-wrap: wrap;
padding-top: 10px;
gap: 5px;
}
@ -688,23 +761,277 @@ export default {
/* 抖动动画 */
@keyframes cardShake {
0% { transform: translateX(0); }
10% { transform: translateX(-5px) translateY(-2px); }
20% { transform: translateX(5px) translateY(2px); }
30% { transform: translateX(-5px) translateY(-2px); }
40% { transform: translateX(5px) translateY(2px); }
50% { transform: translateX(-3px) translateY(-1px); }
60% { transform: translateX(3px) translateY(1px); }
70% { transform: translateX(-3px) translateY(-1px); }
80% { transform: translateX(3px) translateY(1px); }
90% { transform: translateX(-2px) translateY(0); }
100% { transform: translateX(0); }
0% {
transform: translateX(0);
}
10% {
transform: translateX(-5px) translateY(-2px);
}
20% {
transform: translateX(5px) translateY(2px);
}
30% {
transform: translateX(-5px) translateY(-2px);
}
40% {
transform: translateX(5px) translateY(2px);
}
50% {
transform: translateX(-3px) translateY(-1px);
}
60% {
transform: translateX(3px) translateY(1px);
}
70% {
transform: translateX(-3px) translateY(-1px);
}
80% {
transform: translateX(3px) translateY(1px);
}
90% {
transform: translateX(-2px) translateY(0);
}
100% {
transform: translateX(0);
}
}
.shake {
animation: cardShake 1s infinite linear;
//.shake {
// animation: cardShake 1s infinite linear;
//
// &:hover {
// animation-play-state: paused;
// }
//}
/* 证书上传样式 */
.certificate-upload-container {
max-height: 500px;
overflow-y: auto;
padding-right: 10px;
}
.certificate-card {
border: 1px solid #e6e6e6;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
background: #fff;
transition: all 0.3s ease;
&:hover {
animation-play-state: paused;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-color: #409EFF;
}
&:last-child {
margin-bottom: 0;
}
}
.certificate-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px dashed #e6e6e6;
}
.certificate-title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.certificate-form {
margin-top: 15px;
}
.file-upload-area {
margin-bottom: 10px;
}
.file-info {
margin-top: 10px;
padding: 10px;
background: #f8f9fa;
border-radius: 4px;
border: 1px solid #e9ecef;
}
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
.file-name {
flex: 1;
margin-left: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-size {
color: #909399;
font-size: 12px;
margin: 0 15px;
}
.file-link {
color: #409EFF;
text-decoration: none;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
.upload-progress {
margin-top: 10px;
.progress-text {
display: block;
text-align: center;
color: #67C23A;
font-size: 12px;
margin-top: 5px;
}
}
.upload-tip {
color: #909399;
font-size: 12px;
margin-top: 5px;
}
.file-preview {
margin-top: 15px;
padding-top: 15px;
border-top: 1px dashed #e6e6e6;
.preview-title {
font-weight: bold;
margin-bottom: 10px;
color: #606266;
}
.preview-image {
max-width: 200px;
max-height: 200px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
transition: transform 0.3s ease;
&:hover {
transform: scale(1.05);
}
}
}
.add-certificate-btn {
text-align: center;
padding: 20px;
border: 2px dashed #dcdfe6;
border-radius: 8px;
margin-top: 20px;
background: #fafafa;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
border-color: #409EFF;
background: #ecf5ff;
}
.certificate-count {
margin-left: 15px;
color: #909399;
font-size: 14px;
}
}
/* 审核预览样式 */
.certificate-review {
padding: 15px;
background: #fff;
border-radius: 6px;
margin-bottom: 15px;
}
.review-item {
margin-bottom: 8px;
.review-label {
color: #606266;
min-width: 80px;
display: inline-block;
}
.review-value {
color: #303133;
font-weight: 500;
}
}
.preview-thumbnail {
position: relative;
width: 100px;
height: 100px;
cursor: pointer;
margin-top: 10px;
.thumbnail-image {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 4px;
border: 1px solid #ddd;
}
.thumbnail-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
color: white;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.3s ease;
border-radius: 4px;
font-size: 12px;
}
&:hover .thumbnail-overlay {
opacity: 1;
}
}
/* 滚动条样式 */
.certificate-upload-container::-webkit-scrollbar {
width: 6px;
}
.certificate-upload-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
.certificate-upload-container::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
}
.certificate-upload-container::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
</style>

2461
chenhai-ui/src/views/vet/article/index.vue
File diff suppressed because it is too large
View File

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

@ -446,6 +446,7 @@ export default {
this.$message.error('获取详情失败')
})
},
/** 新增按钮操作 */
handleAdd() {
this.reset()

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

@ -18,21 +18,36 @@
/>
</el-form-item>
<el-form-item label="资质类型" prop="qualificationType">
<el-input
<el-select
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
placeholder="请选择资质类型"
style="width: 100%;"
@keyup.enter.native="handleQuery"
>
<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="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 style="width: 100px">
<el-option
@ -82,58 +97,81 @@
v-hasPermi="['vet:qualification:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['vet:qualification:export']"
>导出</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="warning"-->
<!-- plain-->
<!-- icon="el-icon-download"-->
<!-- size="mini"-->
<!-- @click="handleExport"-->
<!-- v-hasPermi="['vet:qualification:export']"-->
<!-- >导出</el-button>-->
<!-- </el-col>-->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="qualificationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="资质ID" align="center" prop="qualificationId" v-if="false" />
<el-table-column label="真实姓名" align="center" prop="realName" />
<el-table-column label="身份证号" align="center" prop="idCard" />
<el-table-column label="资质类型" align="center" prop="qualificationType" width="120">
<!-- <el-table-column label="资质ID" align="center" prop="qualificationId" v-if="false" />-->
<!-- <el-table-column label="真实姓名" align="center" prop="realName" />-->
<!-- <el-table-column label="身份证号" align="center" prop="idCard" />-->
<el-table-column label="真实姓名" align="center" prop="realName" width="150">
<template slot-scope="scope">
<span>{{ formatQualificationType(scope.row.qualificationType) }}</span>
</template>
</el-table-column>
<el-table-column label="证书编号" align="center" prop="certificateNo" />
<!-- 新增的证书字段 -->
<el-table-column label="证书名称" align="center" prop="certName" width="150">
<template slot-scope="scope">
<span v-if="scope.row.certName">{{ scope.row.certName }}</span>
<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="issueOrg" width="150">
<el-table-column label="身份证号" align="center" prop="idCard" width="150">
<template slot-scope="scope">
<span v-if="scope.row.issueOrg">{{ scope.row.issueOrg }}</span>
<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="expireDate" width="180">
<template slot-scope="scope">
<span v-if="scope.row.expireDate">{{ parseTime(scope.row.expireDate, '{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="qualificationType" width="120">
<template slot-scope="scope">
<el-tag :type="getCertStatusType(scope.row.certStatus)" size="small">
{{ getCertStatusLabel(scope.row.certStatus) }}
</el-tag>
<span>{{ formatQualificationType(scope.row.qualificationType) }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="证书编号" align="center" prop="certificateNo" />-->
<!-- <el-table-column label="证书编号" align="center" prop="certificateNo" width="150">-->
<!-- <template slot-scope="scope">-->
<!-- <span v-if="scope.row.certificateNo">{{ scope.row.certificateNo }}</span>-->
<!-- <span v-else style="color: #909399">-</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- &lt;!&ndash; 新增的证书字段 &ndash;&gt;-->
<!-- <el-table-column label="证书名称" align="center" prop="certName" width="150">-->
<!-- <template slot-scope="scope">-->
<!-- <span v-if="scope.row.certName">{{ scope.row.certName }}</span>-->
<!-- <span v-else style="color: #909399">-</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="发证机构" align="center" prop="issueOrg" width="150">-->
<!-- <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">-->
<!-- <template slot-scope="scope">-->
<!--&lt;!&ndash; <span v-if="scope.row.certificateFiles">{{ scope.row.certificateFiles }}</span>&ndash;&gt;-->
<!-- <span v-if="scope.row.certificateFiles">{{ getImageUrl(scope.row.certificateFiles) }}</span>-->
<!-- <span v-else style="color: #909399">-</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="到期日期" align="center" prop="expireDate" width="180">-->
<!-- <template slot-scope="scope">-->
<!-- <span v-if="scope.row.expireDate">{{ parseTime(scope.row.expireDate, '{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">-->
<!-- <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" prop="applyTime" width="180">
<template slot-scope="scope">
<span v-if="scope.row.applyTime">{{ parseTime(scope.row.applyTime, '{y}-{m}-{d}') }}</span>
@ -163,41 +201,62 @@
icon="el-icon-view"
@click="handleView(scope.row)"
v-hasPermi="['vet:qualification:query']"
>查看</el-button>
>查看证书详情</el-button>
<!-- 修改按钮 -->
<el-button
v-if="!scope.row.auditStatus || scope.row.auditStatus === '0' || scope.row.auditStatus === '2'"
size="mini"
type="text"
icon="el-icon-edit"
style="color: #42B983"
@click="handleUpdate(scope.row)"
v-hasPermi="['vet:qualification:edit']"
>修改</el-button>
<!-- <el-button-->
<!-- v-if="!scope.row.auditStatus || scope.row.auditStatus === '0' || scope.row.auditStatus === '2'"-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- style="color: #42B983"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['vet:qualification:edit']"-->
<!-- >修改</el-button>-->
<!-- 提交/重新提交按钮 -->
<el-button
v-if="!scope.row.auditStatus || scope.row.auditStatus === '2'"
size="mini"
type="text"
icon="el-icon-s-check"
style="color: #409EFF"
@click="handleSubmitAudit(scope.row)"
v-hasPermi="['vet:qualification:edit']"
>{{ !scope.row.auditStatus ? '提交审核' : '重新提交' }}</el-button>
<!-- <el-button-->
<!-- v-if="!scope.row.auditStatus || scope.row.auditStatus === '2'"-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-s-check"-->
<!-- style="color: #409EFF"-->
<!-- @click="handleSubmitAudit(scope.row)"-->
<!-- v-hasPermi="['vet:qualification:edit']"-->
<!-- >{{ !scope.row.auditStatus ? '提交审核' : '重新提交' }}</el-button>-->
<!-- 下架按钮已上架状态显示 -->
<!-- <el-button-->
<!-- v-if="scope.row.auditStatus === '1'"-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-bottom"-->
<!-- style="color: #E6A23C"-->
<!-- @click="handleUnshelf(scope.row)"-->
<!-- v-hasPermi="['vet:qualification:unshelf']"-->
<!-- >下架</el-button>-->
<!-- 上架按钮已下架状态显示 -->
<!-- <el-button-->
<!-- v-if="scope.row.auditStatus === '3'"-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-top"-->
<!-- style="color: #67C23A"-->
<!-- @click="handleShelf(scope.row)"-->
<!-- v-hasPermi="['vet:qualification:shelf']"-->
<!-- >上架</el-button>-->
<!-- 删除按钮 -->
<el-button
v-if="!scope.row.auditStatus || scope.row.auditStatus === '2'"
size="mini"
type="text"
icon="el-icon-delete"
style="color: #f56c6c"
@click="handleDelete(scope.row)"
v-hasPermi="['vet:qualification:remove']"
>删除</el-button>
<!-- <el-button-->
<!-- v-if="!scope.row.auditStatus || scope.row.auditStatus === '2'"-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- style="color: #f56c6c"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['vet:qualification:remove']"-->
<!-- >删除</el-button>-->
</template>
</el-table-column>
</el-table>
@ -210,26 +269,141 @@
@pagination="getList"
/>
<!-- 显示资质证书信息 -->
<el-dialog :title="title" :visible.sync="openDetail" width="800px" append-to-body>
<div v-if="detailData" style="padding: 20px;">
<div style="margin-top: 30px;">
<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="200">
<template slot-scope="scope">
<span>{{ scope.row.certificateNo }}</span>
</template>
</el-table-column>
<el-table-column prop="certName" label="证书名称" align="center" width="180">
<template slot-scope="scope">
<span>{{ scope.row.certName }}</span>
</template>
</el-table-column>
<el-table-column label="发证机构" align="center" prop="issueOrg" width="150">
<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">
<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;"
>
</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;"
>
</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="120">
<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="120">
<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="!scope.row.auditStatus || scope.row.auditStatus === '0' || scope.row.auditStatus === '2'"
size="mini"
type="text"
icon="el-icon-edit"
style="color: #42B983"
@click="handleUpdate(scope.row)"
v-hasPermi="['vet:qualification:edit']"
>修改</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="60%" 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>
</el-dialog>
<!-- 添加或修改兽医资质对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" 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 label="兽医资格证" value="veterinarian" />
<el-option label="兽药师资格证" value="pharmacist" />
</el-select>
</el-form-item>
<!-- <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>
@ -254,22 +428,26 @@
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="证书图片" prop="certImage">
<image-upload v-model="form.certImage"/>
<!-- <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="certificateFiles">
<el-input v-model="form.certificateFiles" type="textarea" 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="submitForm"> </el-button>
<el-button type="primary" @click="resubmitForm">重新提交审核</el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
@ -277,16 +455,19 @@
</template>
<script>
import { listQualification, getQualification, delQualification, addQualification, updateQualification } from "@/api/vet/qualification"
import { submitQualification } from "@/api/vet/qualification"
import { listQualification, getQualificationCertificate, delQualification, getQualificationCertificates, updateAndSubmitQualification} from "@/api/vet/qualification"
export default {
name: "Qualification",
dicts: ['qualification_shenhe', 'expert_type'],
dicts: ['qualification_shenhe', 'expert_type', 'qualification_type'],
data() {
return {
baseUrl: process.env.VUE_APP_BASE_API,
//
previewFileUrl: '',
//
loading: true,
detailLoading: true,
//
ids: [],
//
@ -299,10 +480,16 @@ export default {
total: 0,
//
qualificationList: [],
//
certificateList: [],
//
detailData: null,
//
title: "",
//
open: false,
openDetail: false,
previewDialogVisible: false,
//
queryParams: {
pageNum: 1,
@ -321,18 +508,33 @@ export default {
form: {},
//
rules: {
realName: [
{ required: true, message: "真实姓名不能为空", trigger: "blur" }
// realName: [
// { required: true, message: "", trigger: "blur" }
// ],
// idCard: [
// { required: true, message: "", trigger: "blur" }
// ],
// qualificationType: [
// { required: true, message: "", trigger: "change" }
// ],
certificateNo: [
{ required: true, message: "证书编号不能为空", trigger: "blur" }
],
idCard: [
{ required: true, message: "身份证号不能为空", trigger: "blur" }
certName: [
{ required: true, message: "证书名称不能为空", trigger: "blur" }
],
qualificationType: [
{ required: true, message: "资质类型不能为空", trigger: "change" }
issueOrg: [
{ required: true, message: "发证机构不能为空", trigger: "blur" }
],
issueDate: [
{ required: true, message: "发证日期不能为空", trigger: "change" }
],
expireDate: [
{ required: true, message: "到期日期不能为空", trigger: "change" }
],
certificateFiles: [
{ required: true, message: "证书文件不能为空", trigger: "blur" }
],
certificateNo: [
{ required: true, message: "证书编号不能为空", trigger: "blur" }
]
}
}
},
@ -373,109 +575,297 @@ export default {
/** 获取审核状态标签类型 */
getAuditStatusType(status) {
const map = {
'0': 'primary', // -
'0': 'info', // -
'1': 'success', // - 绿
'2': 'danger', // -
'3': 'warning' // -
}
return map[status] || 'info'
},
/** 格式化资质类型显示 */
formatQualificationType(value) {
if (value === 'veterinarian') return '兽医资格证'
if (value === 'pharmacist') return '兽药师资格证'
return value
formatQualificationType(status) {
const map = {
'1': '执业兽医师',
'2': '执业助理兽医',
'3': '官方兽医',
'4': '乡村兽医'
}
return map[status] || 'info'
},
/** 获取完整的图片URL */
getImageUrl(filePath) {
return `${this.baseUrl}${filePath}`
},
isImageFile(filePath) {
if (!filePath) return false;
const imageExts = ['.png','.jpg','.jpeg'];
const ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();
return imageExts.includes(ext);
},
/** 判断是否为PDF文件 */
isPdfFile(filePath) {
if (!filePath) return false;
const ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();
return ext === '.pdf';
},
/** 预览图片 */
previewCertificate(filePath) {
this.previewFileUrl = filePath;
this.previewDialogVisible = true;
},
/** 下载文件 */
downloadFile(filePath) {
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(() => {
//
// 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() {
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 = {
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'
certId: certId,
qualificationId: this.form.qualificationId,
realName: this.form.realName,
idCard: this.form.idCard,
qualificationType: this.form.qualificationType,
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',
auditOpinion: null,
applyTime: new Date().toISOString(),
}
return submitQualification(submitData)
}).then(response => {
updateAndSubmitQualification(submitData).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess("提交审核成功")
this.$modal.msgSuccess("重新提交审核成功")
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;
});
}
}
})
}
this.reset()
} else {
this.$modal.msgError(response.msg || "提交审核失败")
this.$modal.msgError(response.msg || "重新提交审核失败")
}
}).catch(() => {})
})
}
})
},
/** 查看详情 */
// 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'
// })
// },
/** 资质证书详情 */
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>`
this.openDetail = true
this.detailData = row
this.title = "资质证书详情"
this.certificateList = []
this.detailLoading = true
getQualificationCertificates(row.qualificationId).then(response => {
this.detailLoading = false
if (response.code === 200) {
this.certificateList = response.rows || [];
}
detailContent += `</table>`
this.$alert(detailContent, '资质详情', {
dangerouslyUseHTMLString: true,
confirmButtonText: '关闭',
width: '550px',
customClass: 'qualification-detail-dialog'
})
},
@ -485,6 +875,12 @@ export default {
this.reset()
},
//
closeDetail(){
this.openDetail = false
this.reset()
},
//
reset() {
this.form = {
@ -546,36 +942,53 @@ export default {
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const qualificationId = row.qualificationId || this.ids
getQualification(qualificationId).then(response => {
let certId = row.certId || row.certificateId || row.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
}
getQualificationCertificate(certId).then(response => {
if (response.code === 200 && response.data) {
this.form = response.data
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()
})
this.title = "修改兽医资质证书信息"
} else {
this.form.auditStatus = null
addQualification(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
this.$modal.msgError(response.msg || "获取证书信息失败")
}
}).catch(error => {
console.error('获取证书信息失败:', error)
this.$modal.msgError("获取证书信息失败")
})
},
/** 提交按钮 */
// 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

Loading…
Cancel
Save