Browse Source

兽医PC端资质、消息通知等

master
王妍洁 1 month ago
parent
commit
bceec04573
  1. 84
      chenhai-ui/src/api/vet/article.js
  2. 10
      chenhai-ui/src/api/vet/certificate.js
  3. 32
      chenhai-ui/src/api/vet/notification.js
  4. 43
      chenhai-ui/src/api/vet/qualification.js
  5. 1
      chenhai-ui/src/api/vet/review.js
  6. BIN
      chenhai-ui/src/assets/images/tongzhi.png
  7. BIN
      chenhai-ui/src/assets/images/zhixiang.png
  8. 3
      chenhai-ui/src/permission.js
  9. 22
      chenhai-ui/src/router/index.js
  10. 384
      chenhai-ui/src/views/index.vue
  11. 13
      chenhai-ui/src/views/login.vue
  12. 11
      chenhai-ui/src/views/loginGld.vue
  13. 868
      chenhai-ui/src/views/syd.vue
  14. 611
      chenhai-ui/src/views/vet/article/index.vue
  15. 6
      chenhai-ui/src/views/vet/certificate/index.vue
  16. 7
      chenhai-ui/src/views/vet/info/index.vue
  17. 536
      chenhai-ui/src/views/vet/notification/index.vue
  18. 154
      chenhai-ui/src/views/vet/qualification/index.vue
  19. 7
      chenhai-ui/vue.config.js

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

@ -1,5 +1,89 @@
import request from '@/utils/request'
// 获取论坛首页文章列表
export function getForumHome(params) {
return request({
url: '/vet/article/forum/home',
method: 'get',
params
});
}
// 获取文章详情(自动增加浏览数)
export function getForumDetail(id) {
return request({
url: `/vet/article/forum/detail/${id}`,
method: 'get'
});
}
// 发布论坛文章
export function publishForumArticle(data) {
return request({
url: '/vet/article/forum/publish',
method: 'post',
data
});
}
// 获取当前用户的文章列表
export function getMyForumArticles(params) {
return request({
url: '/vet/article/forum/myArticles',
method: 'get',
params
});
}
// 点赞文章
export function likeForumArticle(id) {
return request({
url: `/forum/${id}/like`,
method: 'post'
});
}
// 收藏文章
export function collectForumArticle(id) {
return request({
url: `/forum/${id}/collect`,
method: 'post'
});
}
// 搜索论坛文章
export function searchForumArticle(params) {
return request({
url: '/forum/search',
method: 'get',
params: params
});
}
// 获取热门标签
export function getForumHotTags() {
return request({
url: '/forum/hotTags',
method: 'get'
});
}
// 根据分类查询文章
export function getArticlesByCategory(categoryId) {
return request({
url: '/vet/article/' + categoryId + '/articles',
method: 'get'
});
}
// 获取分类列表
export function getArticleOptions() {
return request({
url: '/vet/article/options',
method: 'get'
});
}
// 查询兽医经验文章列表
export function listArticle(query) {
return request({

10
chenhai-ui/src/api/vet/certificate.js

@ -9,6 +9,16 @@ export function listCertificate(query) {
})
}
// 查询证书
export function listForDetail(userId) {
return request({
url: '/vet/certificate/listForDetail',
method: 'get',
params: { userId: userId }
})
}
// 查询兽医执业证书详细
export function getCertificate(id) {
return request({

32
chenhai-ui/src/api/vet/notification.js

@ -1,5 +1,37 @@
import request from '@/utils/request'
// 获取统计卡片
export function getStatsCard() {
return request({
url: '/vet/notification/stats/card',
method: 'get'
})
}
// 获取当前用户的未读通知数量
export function getUnreadCount() {
return request({
url: '/vet/notification/user/unread/count',
method: 'get'
})
}
// 标记所有已读
export function markAllread() {
return request({
url: '/vet/notification/user/mark-all-read',
method: 'put'
})
}
// 标记单个已读
export function markRead(id) {
return request({
url: '/vet/notification/' + id + '/read',
method: 'put'
})
}
// 查询兽医通知列表
export function listNotification(query) {
return request({

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

@ -1,14 +1,22 @@
import request from '@/utils/request'
// 兽医资质提交审核
export function submitAuditQualification(qualificationId) {
// 资质+审核
export function submitAuditQualification(data) {
return request({
url: '/vet/qualification/submitAudit/' + qualificationId,
url: '/vet/qualification/submit',
method: 'post',
data: data
data: data,
})
}
// 兽医资质提交审核
// export function submitAuditQualification(qualificationId) {
// return request({
// url: '/vet/qualification/submitAudit/' + qualificationId,
// method: 'post',
// })
// }
// 审核
export function auditQualification(data) {
return request({
@ -18,6 +26,33 @@ export function auditQualification(data) {
})
}
// 获取资质类型列表
export function getQualificationTypeOptions() {
return request({
url: '/vet/qualification//type/options',
method: 'get',
})
}
// 获取经营范围列表
export function getScopeOptions() {
return request({
url: '/vet/qualification/scope/options' ,
method: 'get',
})
}
export function uploadQualification(data) {
return request({
url: '/vet/qualification/upload',
method: 'post',
data: data,
headers: {
'Content-Type': 'multipart/form-data'
},
})
}
// 查询兽医资质列表
export function listQualification(query) {
return request({

1
chenhai-ui/src/api/vet/review.js

@ -1,5 +1,4 @@
import request from '@/utils/request'
// 查询兽医服务评价列表
export function listReview(query) {
return request({

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

After

Width: 200  |  Height: 200  |  Size: 6.8 KiB

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

After

Width: 200  |  Height: 200  |  Size: 3.9 KiB

3
chenhai-ui/src/permission.js

@ -24,9 +24,6 @@ router.beforeEach((to, from, next) => {
next({ path: '/index' })
NProgress.done()
}
// else if (to.path === '/loginGld') {
// next({ path: '/indexGld' })
// NProgress.done()
else if (isWhiteList(to.path)) {
next()
} else {

22
chenhai-ui/src/router/index.js

@ -73,30 +73,16 @@ export const constantRoutes = [
{
path: '/',
component: Layout,
redirect: 'indexGld',
redirect: 'index',
children: [
{
path: 'indexGld',
component: () => import('@/views/indexGld'),
name: 'IndexGld',
path: 'index',
component: () => import('@/views/index'),
name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true, requiresAuth: true}
}
]
},
// 兽医首页
// {
// path: '/',
// component: Layout,
// redirect: 'index',
// children: [
// {
// path: 'index',
// component: () => import('@/views/index'),
// name: 'Index',
// meta: { title: '兽医首页', icon: 'dashboard', affix: true}
// }
// ]
// },
{
path: '/user',
component: Layout,

384
chenhai-ui/src/views/index.vue

@ -1,386 +1,38 @@
<template>
<el-dialog
title="兽医资质认证"
:visible.sync="dialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
width="600px"
>
<!-- 步骤指示器 -->
<el-steps :active="activeStep" finish-status="success" simple style="margin-bottom: 20px;">
<el-step title="选择经营范围"></el-step>
<el-step title="上传资质"></el-step>
<el-step title="提交审核"></el-step>
</el-steps>
<!-- 步骤1选择经营范围 -->
<div v-if="activeStep === 0">
<el-form ref="scopeForm" :model="form" label-width="100px">
<el-form-item label="真实姓名" prop="realName" :rules="[{ required: true, message: '请输入真实姓名', trigger: 'blur' }]">
<el-input v-model="form.realName" placeholder="请输入您的真实姓名" />
</el-form-item>
<el-form-item label="身份证号" prop="idCard" :rules="[{ required: true, message: '请输入身份证号', trigger: 'blur' }]">
<el-input v-model="form.idCard" placeholder="请输入身份证号" />
</el-form-item>
<el-form-item label="资质类型" prop="qualificationType" :rules="[{ required: true, message: '请选择资质类型', trigger: 'change' }]">
<el-select v-model="form.qualificationType" placeholder="请选择资质类型" style="width: 100%;">
<el-option label="执业兽医" value="执业兽医" />
<el-option label="官方兽医" value="官方兽医" />
<el-option label="乡村兽医" value="乡村兽医" />
<el-option label="畜牧师" value="畜牧师" />
<el-option label="其他" value="其他" />
</el-select>
</el-form-item>
<el-form-item label="证书编号" prop="certificateNo" :rules="[{ required: true, message: '请输入证书编号', trigger: 'blur' }]">
<el-input v-model="form.certificateNo" placeholder="请输入证书编号" />
</el-form-item>
<el-form-item label="经营范围" prop="scopeIds" :rules="[{ required: true, message: '请选择至少一个经营范围', trigger: 'change' }]">
<el-select
v-model="selectedScopes"
multiple
placeholder="请选择经营范围"
style="width: 100%;"
@change="handleScopeChange"
>
<el-option
v-for="scope in scopeOptions"
:key="scope.value"
:label="scope.label"
:value="scope.value"
/>
</el-select>
<div style="color: #909399; font-size: 12px; margin-top: 5px;">
已选择{{ selectedScopes.length }}
<span v-if="selectedScopes.length > 0" style="color: #f56c6c; margin-left: 10px;">
请根据经营范围准备相应资质文件
</span>
</div>
</el-form-item>
</el-form>
</div>
<!-- 步骤2上传资质 -->
<div v-if="activeStep === 1">
<div style="margin-bottom: 15px; color: #606266;">
<div>已选择经营范围</div>
<el-tag
v-for="scope in selectedScopes"
:key="scope"
type="info"
style="margin-right: 5px; margin-top: 5px;"
>
{{ getScopeName(scope) }}
</el-tag>
</div>
<div style="margin-bottom: 15px; color: #f56c6c; font-size: 14px;">
<i class="el-icon-warning"></i>
根据您选择的经营范围需要上传以下资质文件
</div>
<div style="margin-bottom: 20px;">
<div v-for="scope in selectedScopes" :key="scope" style="margin-bottom: 10px;">
<div style="font-weight: bold; margin-bottom: 5px;">{{ getScopeName(scope) }}</div>
<div style="color: #606266; font-size: 13px; padding-left: 10px;">
{{ getRequiredQualifications(scope) }}
<!-- 跳转首页 -->
<div class="type">
<Syd v-if = "userRole === 'vetnotshenhe'"></Syd>
<Gld v-else></Gld>
</div>
</div>
</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"
>
<el-button type="primary">选择文件</el-button>
<div slot="tip" class="el-upload__tip">
请上传清晰的资质文件照片或扫描件支持JPGPNGPDF格式
</div>
</el-upload>
</el-form-item>
</el-form>
</div>
<!-- 步骤3确认提交 -->
<div v-if="activeStep === 2">
<div style="text-align: center; margin-bottom: 30px;">
<i class="el-icon-circle-check" style="font-size: 60px; color: #67C23A;"></i>
<div style="margin-top: 15px; font-size: 16px; color: #303133;">
请确认信息无误后提交审核
</div>
</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<div style="margin-bottom: 8px;"><strong>基本信息</strong></div>
<div style="margin-bottom: 5px;">真实姓名{{ form.realName }}</div>
<div style="margin-bottom: 5px;">身份证号{{ form.idCard }}</div>
<div style="margin-bottom: 5px;">资质类型{{ form.qualificationType }}</div>
<div>证书编号{{ form.certificateNo }}</div>
</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<div style="margin-bottom: 8px;"><strong>经营范围</strong></div>
<div>
<el-tag
v-for="scope in selectedScopes"
:key="scope"
type="info"
style="margin-right: 5px; margin-bottom: 5px;"
>
{{ getScopeName(scope) }}
</el-tag>
</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>
</div>
<div v-else style="color: #909399;">暂无文件</div>
</div>
</div>
<!-- 操作按钮 -->
<div slot="footer" class="dialog-footer">
<div v-if="activeStep > 0" style="float: left;">
<el-button @click="prevStep">上一步</el-button>
</div>
<div v-if="activeStep < 2">
<el-button @click="closeDialog">稍后填写</el-button>
<el-button type="primary" @click="nextStep">
{{ activeStep === 1 ? '下一步' : '下一步' }}
</el-button>
</div>
<div v-if="activeStep === 2">
<el-button @click="prevStep">上一步</el-button>
<el-button type="primary" @click="submitQualification" :loading="loading">
提交审核
</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import Gld from '@/views/gld.vue'
import Syd from '@/views/syd.vue'
export default {
name: 'QualificationPopup',
props: {
visible: {
type: Boolean,
default: false
}
name: "IndexGld",
components: {
Gld,
Syd
},
data() {
return {
dialogVisible: false,
activeStep: 0,
loading: false,
form: {
qualificationId: null,
realName: '',
idCard: '',
qualificationType: '',
certificateNo: '',
scopeIds: '',
certificateFiles: ''
},
scopeOptions: [],
selectedScopes: [],
fileList: []
}
},
watch: {
visible(val) {
this.dialogVisible = val
if (val) {
this.loadScopeOptions()
this.loadExistingData()
}
},
dialogVisible(val) {
this.$emit('update:visible', val)
if (!val) {
this.resetForm()
}
computed: {
userRole() {
return this.$store.state.user.roles[0];
}
},
methods: {
//
loadScopeOptions() {
this.$axios.get('/vet/qualification/scope/options')
.then(res => {
this.scopeOptions = res.data
})
},
//
loadExistingData() {
this.$axios.get('/vet/qualification/my')
.then(res => {
if (res.code === 200 && res.data) {
const data = res.data
this.form.qualificationId = data.qualificationId
this.form.realName = data.realName || ''
this.form.idCard = data.idCard || ''
this.form.qualificationType = data.qualificationType || ''
this.form.certificateNo = data.certificateNo || ''
if (data.scopeIds) {
this.selectedScopes = data.scopeIds.split(',')
this.form.scopeIds = data.scopeIds
}
}
})
goTarget(href) {
window.open(href, "_blank")
},
//
getScopeName(scopeId) {
const scope = this.scopeOptions.find(item => item.value === scopeId)
return scope ? scope.label : scopeId
},
//
getRequiredQualifications(scopeId) {
this.$axios.get(`/vet/qualification/scope/detail/${scopeId}`)
.then(res => {
if (res.code === 200) {
this.$message.info(`${res.data.scopeName}${res.data.requiredQualifications}`)
}
})
},
//
handleScopeChange(value) {
this.form.scopeIds = value.join(',')
},
//
handleFileChange(file, fileList) {
this.fileList = fileList
},
handleRemove(file, fileList) {
this.fileList = fileList
},
//
nextStep() {
if (this.activeStep === 0) {
this.$refs.scopeForm.validate(valid => {
if (valid) {
if (this.selectedScopes.length === 0) {
this.$message.warning('请选择至少一个经营范围')
return
}
this.activeStep++
}
})
} else if (this.activeStep === 1) {
if (this.fileList.length === 0) {
this.$message.warning('请上传资质文件')
return
}
this.activeStep++
}
},
//
prevStep() {
if (this.activeStep > 0) {
this.activeStep--
}
},
//
submitQualification() {
this.loading = true
//
if (this.fileList.length > 0) {
// URL
// 使
const fileUrls = this.fileList.map(file => file.name).join(',')
this.form.certificateFiles = fileUrls
}
this.$axios.post('/vet/qualification/quickSubmit', this.form)
.then(res => {
if (res.code === 200) {
this.$message.success('提交成功,请等待审核')
this.closeDialog()
} else {
this.$message.error(res.msg || '提交失败')
}
})
.finally(() => {
this.loading = false
})
},
//
closeDialog() {
this.dialogVisible = false
},
//
resetForm() {
this.activeStep = 0
this.loading = false
this.form = {
qualificationId: null,
realName: '',
idCard: '',
qualificationType: '',
certificateNo: '',
scopeIds: '',
certificateFiles: ''
}
this.selectedScopes = []
this.fileList = []
if (this.$refs.scopeForm) {
this.$refs.scopeForm.clearValidate()
}
if (this.$refs.upload) {
this.$refs.upload.clearFiles()
}
}
}
}
</script>
<style scoped>
::v-deep .el-dialog__header {
background: linear-gradient(90deg, #409EFF, #67C23A);
padding: 15px 20px;
}
::v-deep .el-dialog__title {
color: white;
font-weight: bold;
}
::v-deep .el-dialog__headerbtn .el-dialog__close {
color: white;
}
::v-deep .el-dialog__body {
padding: 20px;
}
<style scoped lang="scss">
</style>

13
chenhai-ui/src/views/login.vue

@ -15,7 +15,7 @@
<h3 class="title">"与牧同行"兽医端</h3>
<div class="slogan">
<div class="icon-info">
<svg t="1767603518204" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13872" width="20" height="20"><path d="M191.90624 190.952007l641.318274 0 0 448.933639L191.90624 639.885646 191.90624 190.952007 191.90624 190.952007zM868.691283 61.809741 156.493705 61.809741c-50.994418 0-92.339058 41.434691-92.339058 92.553952l0 520.745175c0 51.116191 41.336454 92.553952 92.339058 92.553952l223.89428 0 0 127.747499L222.537887 895.41032c-17.569144 0-31.81152 14.246469-31.81152 31.807427 0 17.569144 14.242376 31.815613 31.81152 31.815613L800.750915 959.033359c17.569144 0 31.815613-14.246469 31.815613-31.815613 0-17.560958-14.246469-31.807427-31.815613-31.807427L641.028167 895.41032 641.028167 767.663844l227.66414 0c50.998511 0 92.342128-41.437761 92.342128-92.553952L961.034435 154.363693C961.033411 103.252619 919.689794 61.809741 868.691283 61.809741L868.691283 61.809741zM898.61071 704.558597 127.961882 704.558597 127.961882 127.477346l770.647805 0L898.609687 704.558597 898.61071 704.558597zM898.61071 704.558597" fill="#CDCDCD" p-id="13873"></path></svg><path d="M384 768v42.666667h-42.325333C318.08 810.666667 298.666667 830.08 298.666667 853.674667c0 22.912 18.773333 42.325333 42.325333 42.325333h341.973333A42.666667 42.666667 0 0 0 725.333333 852.992 43.093333 43.093333 0 0 0 682.325333 810.666667H640v-42.666667h213.333333a85.333333 85.333333 0 0 0 85.333334-85.333333V213.333333a85.333333 85.333333 0 0 0-85.333334-85.333333H170.666667a85.333333 85.333333 0 0 0-85.333334 85.333333v469.333334a85.333333 85.333333 0 0 0 85.333334 85.333333h213.333333z m469.333333-85.333333H170.666667V213.333333h682.666666v469.333334z" p-id="12221" fill="#CDCDCD"></path></svg><path d="M191.90624 190.952007l641.318274 0 0 448.933639L191.90624 639.885646 191.90624 190.952007 191.90624 190.952007zM868.691283 61.809741 156.493705 61.809741c-50.994418 0-92.339058 41.434691-92.339058 92.553952l0 520.745175c0 51.116191 41.336454 92.553952 92.339058 92.553952l223.89428 0 0 127.747499L222.537887 895.41032c-17.569144 0-31.81152 14.246469-31.81152 31.807427 0 17.569144 14.242376 31.815613 31.81152 31.815613L800.750915 959.033359c17.569144 0 31.815613-14.246469 31.815613-31.815613 0-17.560958-14.246469-31.807427-31.815613-31.807427L641.028167 895.41032 641.028167 767.663844l227.66414 0c50.998511 0 92.342128-41.437761 92.342128-92.553952L961.034435 154.363693C961.033411 103.252619 919.689794 61.809741 868.691283 61.809741L868.691283 61.809741zM898.61071 704.558597 127.961882 704.558597 127.961882 127.477346l770.647805 0L898.609687 704.558597 898.61071 704.558597zM898.61071 704.558597" fill="#CDCDCD" p-id="7961"></path></svg>
<svg t="1767603518204" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13872" width="20" height="20"><path d="M191.90624 190.952007l641.318274 0 0 448.933639L191.90624 639.885646 191.90624 190.952007 191.90624 190.952007zM868.691283 61.809741 156.493705 61.809741c-50.994418 0-92.339058 41.434691-92.339058 92.553952l0 520.745175c0 51.116191 41.336454 92.553952 92.339058 92.553952l223.89428 0 0 127.747499L222.537887 895.41032c-17.569144 0-31.81152 14.246469-31.81152 31.807427 0 17.569144 14.242376 31.815613 31.81152 31.815613L800.750915 959.033359c17.569144 0 31.815613-14.246469 31.815613-31.815613 0-17.560958-14.246469-31.807427-31.815613-31.807427L641.028167 895.41032 641.028167 767.663844l227.66414 0c50.998511 0 92.342128-41.437761 92.342128-92.553952L961.034435 154.363693C961.033411 103.252619 919.689794 61.809741 868.691283 61.809741L868.691283 61.809741zM898.61071 704.558597 127.961882 704.558597 127.961882 127.477346l770.647805 0L898.609687 704.558597 898.61071 704.558597zM898.61071 704.558597" fill="#CDCDCD" p-id="13873"></path></svg><path d="M384 768v42.666667h-42.325333C318.08 810.666667 298.666667 830.08 298.666667 853.674667c0 22.912 18.773333 42.325333 42.325333 42.325333h341.973333A42.666667 42.666667 0 0 0 725.333333 852.992 43.093333 43.093333 0 0 0 682.325333 810.666667H640v-42.666667h213.333333a85.333333 85.333333 0 0 0 85.333334-85.333333V213.333333a85.333333 85.333333 0 0 0-85.333334-85.333333H170.666667a85.333333 85.333333 0 0 0-85.333334 85.333333v469.333334a85.333333 85.333333 0 0 0 85.333334 85.333333h213.333333z m469.333333-85.333333H170.666667V213.333333h682.666666v469.333334z" p-id="12221" fill="#CDCDCD"></path><path d="M191.90624 190.952007l641.318274 0 0 448.933639L191.90624 639.885646 191.90624 190.952007 191.90624 190.952007zM868.691283 61.809741 156.493705 61.809741c-50.994418 0-92.339058 41.434691-92.339058 92.553952l0 520.745175c0 51.116191 41.336454 92.553952 92.339058 92.553952l223.89428 0 0 127.747499L222.537887 895.41032c-17.569144 0-31.81152 14.246469-31.81152 31.807427 0 17.569144 14.242376 31.815613 31.81152 31.815613L800.750915 959.033359c17.569144 0 31.815613-14.246469 31.815613-31.815613 0-17.560958-14.246469-31.807427-31.815613-31.807427L641.028167 895.41032 641.028167 767.663844l227.66414 0c50.998511 0 92.342128-41.437761 92.342128-92.553952L961.034435 154.363693C961.033411 103.252619 919.689794 61.809741 868.691283 61.809741L868.691283 61.809741zM898.61071 704.558597 127.961882 704.558597 127.961882 127.477346l770.647805 0L898.609687 704.558597 898.61071 704.558597zM898.61071 704.558597" fill="#CDCDCD" p-id="7961"></path>
<div class="icon-text">一站通登筑牢账号防线</div>
</div>
<div class="icon-info">
@ -117,7 +117,6 @@
<svg-icon slot="prefix" icon-class="phone" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
@ -196,6 +195,7 @@ import { encrypt, decrypt } from '@/utils/jsencrypt'
export default {
name: "Login",
data() {
//
const equalToPassword = (rule, value, callback) => {
if (this.registerForm.password !== value) {
callback(new Error("两次输入的密码不一致"))
@ -280,6 +280,8 @@ export default {
// }
// })
// },
// Cookie
getCookie() {
const phone = Cookies.get("phone")
const password = Cookies.get("password")
@ -290,6 +292,8 @@ export default {
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
}
},
//
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
@ -304,7 +308,7 @@ export default {
Cookies.remove('rememberMe')
}
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$router.push({path: this.redirect || "/indexGld"}).catch(() => {
this.$router.push({path: this.redirect || "/index"}).catch(() => {
})
}).catch(() => {
this.loginloading = false
@ -315,9 +319,12 @@ export default {
}
})
},
//
unregistered(row) {
this.open = true
},
handleRegister() {
this.$refs.registerForm.validate(valid => {
if (valid) {

11
chenhai-ui/src/views/loginGld.vue

@ -44,7 +44,6 @@
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
@ -163,6 +162,8 @@ export default {
// }
// })
// },
// Cookie
getCookie() {
const username = Cookies.get("gld_username")
const password = Cookies.get("gld_password")
@ -173,6 +174,8 @@ export default {
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
}
},
//
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
@ -187,7 +190,7 @@ export default {
Cookies.remove('gld_rememberMe')
}
this.$store.dispatch("LoginGld", this.loginForm).then(() => {
this.$router.push({ path: this.redirect || '/indexGld' }).catch(()=>{})
this.$router.push({ path: this.redirect || '/index' }).catch(()=>{})
}).catch(() => {
this.loading = false
// if (this.captchaEnabled) {
@ -463,10 +466,6 @@ export default {
flex-direction: column;
}
.login-tips{
}
.login-btn-item {
margin-top: 20px;
margin-bottom: 0;

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

@ -1,197 +1,470 @@
<template>
<h1 class="vetnotshenhe-title">兽医端</h1>
<!-- <div class="app-container">-->
<!-- <el-dialog :title="title" :visible.sync="flag" width="800px" append-to-body>-->
<!-- &lt;!&ndash; 步骤指示器 &ndash;&gt;-->
<!-- <el-steps :active="activeStep" finish-status="success" simple style="margin-bottom: 20px;">-->
<!-- <el-step title="选择经营范围"></el-step>-->
<!-- <el-step title="上传资质"></el-step>-->
<!-- <el-step title="提交审核"></el-step>-->
<!-- </el-steps>-->
<!-- &lt;!&ndash; 步骤1选择经营范围 &ndash;&gt;-->
<!-- <div v-if="activeStep === 0">-->
<!-- <el-form ref="scopeForm" :model="form" label-width="100px">-->
<!-- <el-form-item label="真实姓名" prop="realName" :rules="[{ required: true, message: '请输入真实姓名', trigger: 'blur' }]">-->
<!-- <el-input v-model="form.realName" placeholder="请输入您的真实姓名" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="身份证号" prop="idCard" :rules="[{ required: true, message: '请输入身份证号', trigger: 'blur' }]">-->
<!-- <el-input v-model="form.idCard" placeholder="请输入身份证号" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="资质类型" prop="qualificationType" :rules="[{ required: true, message: '请选择资质类型', trigger: 'change' }]">-->
<!-- <el-select v-model="form.qualificationType" placeholder="请选择资质类型" style="width: 100%;">-->
<!-- <el-option label="执业兽医" value="执业兽医" />-->
<!-- <el-option label="官方兽医" value="官方兽医" />-->
<!-- <el-option label="乡村兽医" value="乡村兽医" />-->
<!-- <el-option label="畜牧师" value="畜牧师" />-->
<!-- <el-option label="其他" value="其他" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="证书编号" prop="certificateNo" :rules="[{ required: true, message: '请输入证书编号', trigger: 'blur' }]">-->
<!-- <el-input v-model="form.certificateNo" placeholder="请输入证书编号" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="经营范围" prop="scopeIds" :rules="[{ required: true, message: '请选择至少一个经营范围', trigger: 'change' }]">-->
<!-- <el-select-->
<!-- v-model="selectedScopes"-->
<!-- multiple-->
<!-- placeholder="请选择经营范围"-->
<!-- style="width: 100%;"-->
<!-- @change="handleScopeChange"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="scope in scopeOptions"-->
<!-- :key="scope.value"-->
<!-- :label="scope.label"-->
<!-- :value="scope.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- <div style="color: #909399; font-size: 12px; margin-top: 5px;">-->
<!-- 已选择{{ selectedScopes.length }} -->
<!-- <span v-if="selectedScopes.length > 0" style="color: #f56c6c; margin-left: 10px;">-->
<!-- 请根据经营范围准备相应资质文件-->
<!-- </span>-->
<!-- </div>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- </div>-->
<!-- &lt;!&ndash; 步骤2上传资质 &ndash;&gt;-->
<!-- <div v-if="activeStep === 1">-->
<!-- <div style="margin-bottom: 15px; color: #606266;">-->
<!-- <div>已选择经营范围</div>-->
<!-- <el-tag-->
<!-- v-for="scope in selectedScopes"-->
<!-- :key="scope"-->
<!-- type="info"-->
<!-- style="margin-right: 5px; margin-top: 5px;"-->
<!-- >-->
<!-- {{ getScopeName(scope) }}-->
<!-- </el-tag>-->
<!-- </div>-->
<!-- <div style="margin-bottom: 15px; color: #f56c6c; font-size: 14px;">-->
<!-- <i class="el-icon-warning"></i>-->
<!-- 根据您选择的经营范围需要上传以下资质文件-->
<!-- </div>-->
<!-- <div style="margin-bottom: 20px;">-->
<!-- <div v-for="scope in selectedScopes" :key="scope" style="margin-bottom: 10px;">-->
<!-- <div style="font-weight: bold; margin-bottom: 5px;">{{ getScopeName(scope) }}</div>-->
<!-- <div style="color: #606266; font-size: 13px; padding-left: 10px;">-->
<!-- {{ getRequiredQualifications(scope) }}-->
<!-- </div>-->
<!-- </div>-->
<!-- </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"-->
<!-- >-->
<!-- <el-button type="primary">选择文件</el-button>-->
<!-- <div slot="tip" class="el-upload__tip">-->
<!-- 请上传清晰的资质文件照片或扫描件支持JPGPNGPDF格式-->
<!-- </div>-->
<!-- </el-upload>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- </div>-->
<!-- &lt;!&ndash; 步骤3确认提交 &ndash;&gt;-->
<!-- <div v-if="activeStep === 2">-->
<!-- <div style="text-align: center; margin-bottom: 30px;">-->
<!-- <i class="el-icon-circle-check" style="font-size: 60px; color: #67C23A;"></i>-->
<!-- <div style="margin-top: 15px; font-size: 16px; color: #303133;">-->
<!-- 请确认信息无误后提交审核-->
<!-- </div>-->
<!-- </div>-->
<!-- <div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">-->
<!-- <div style="margin-bottom: 8px;"><strong>基本信息</strong></div>-->
<!-- <div style="margin-bottom: 5px;">真实姓名{{ form.realName }}</div>-->
<!-- <div style="margin-bottom: 5px;">身份证号{{ form.idCard }}</div>-->
<!-- <div style="margin-bottom: 5px;">资质类型{{ form.qualificationType }}</div>-->
<!-- <div>证书编号{{ form.certificateNo }}</div>-->
<!-- </div>-->
<!-- <div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">-->
<!-- <div style="margin-bottom: 8px;"><strong>经营范围</strong></div>-->
<!-- <div>-->
<!-- <el-tag-->
<!-- v-for="scope in selectedScopes"-->
<!-- :key="scope"-->
<!-- type="info"-->
<!-- style="margin-right: 5px; margin-bottom: 5px;"-->
<!-- >-->
<!-- {{ getScopeName(scope) }}-->
<!-- </el-tag>-->
<!-- </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>-->
<!-- </div>-->
<!-- <div v-else style="color: #909399;">暂无文件</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- &lt;!&ndash; 操作按钮 &ndash;&gt;-->
<!-- <div slot="footer" class="dialog-footer">-->
<!-- <div v-if="activeStep > 0" style="float: left;">-->
<!-- <el-button @click="prevStep">上一步</el-button>-->
<!-- </div>-->
<!-- <div v-if="activeStep < 2">-->
<!-- <el-button @click="closeDialog">稍后填写</el-button>-->
<!-- <el-button type="primary" @click="nextStep">-->
<!-- {{ activeStep === 1 ? '下一步' : '下一步' }}-->
<!-- </el-button>-->
<!-- </div>-->
<!-- <div v-if="activeStep === 2">-->
<!-- <el-button @click="prevStep">上一步</el-button>-->
<!-- <el-button type="primary" @click="submitQualification" :loading="loading">-->
<!-- 提交审核-->
<!-- </el-button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </el-dialog>-->
<!-- </div>-->
<div class="app-container">
<!-- 消息通知 -->
<div class="info-container">
<div class="card-container">
<div class="info-card stat-card"
@click="$router.push('/vet-info/VetNotification')"
:class="{ shake: tjzs.unreadCount > 0 }"
>
<img class="info-icon" :src="require('@/assets/images/tongzhi.png')">
<div class="info-content">
<span class="info-title">通知</span>
<div class="status-container">
<div class="status-row">
<span class="status-text">未读{{ tjzs.unreadCount }}</span>
</div>
<div class="status-row">
<span class="status-text">已读{{ tjzs.readCount }}</span>
</div>
</div>
</div>
</div>
<div class="stat-card">
<div class="card-icon icon-total">
<i class="el-icon-message"></i>
</div>
<div class="card-text">
<div class="card-title">总数</div>
<div class="card-value">{{ tjzs.totalCount }}</div>
</div>
</div>
<div class="stat-card">
<div class="card-icon icon-pending">
<i class="el-icon-check"></i>
</div>
<div class="card-text">
<div class="card-title">已读</div>
<div class="card-value">{{ tjzs.readCount }}</div>
</div>
</div>
<div class="stat-card">
<div class="card-icon icon-handled">
<i class="el-icon-bell"></i>
</div>
<div class="card-text">
<div class="card-title">未读</div>
<div class="card-value">{{ tjzs.unreadCount }}</div>
</div>
</div>
</div>
</div>
<!-- 资质弹窗 -->
<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-step title="选择经营范围"></el-step>
<el-step title="上传资质"></el-step>
<el-step title="提交审核"></el-step>
</el-steps>
<!-- 选择经营范围 -->
<div v-if="activeStep === 0">
<el-form ref="qualificationForm" :model="qualificationForm" :rules="rules" label-width="100px">
<el-form-item label="真实姓名" prop="realName">
<el-input v-model="qualificationForm.realName" placeholder="请输入您的真实姓名" />
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="qualificationForm.idCard" placeholder="请输入身份证号" />
</el-form-item>
<el-form-item label="资质类型" prop="qualificationType">
<el-select
v-model="qualificationForm.qualificationType"
placeholder="请选择资质类型"
style="width: 100%;"
>
<el-option
v-for="option in qualificationTypeOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</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"
multiple
placeholder="请选择经营范围"
style="width: 100%;"
>
<el-option
v-for="scope in scopeOptions"
:key="scope.value"
:label="scope.label"
:value="scope.value"
/>
</el-select>
<div class="scope-choice">
已选择{{ qualificationForm.scopeIds ? qualificationForm.scopeIds.length : 0 }}
</div>
</el-form-item>
</el-form>
</div>
<!-- 上传资质 -->
<div v-if="activeStep === 1">
<div class="step-summary">
<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>
</div>
</div>
<div class="summary-item">
<span class="summary-label">经营范围</span>
<div class="scope-tags">
<el-tag
v-for="scopeId in qualificationForm.scopeIds"
:key="scopeId"
type="info"
size="small"
class="scope-tag"
>
{{ getScopeLabel(scopeId) }}
</el-tag>
</div>
</div>
</div>
<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格式
</div>
</el-upload>
</el-form-item>
<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 }}
</div>
</div>
</el-form>
</div>
<!-- 提交审核 -->
<div v-if="activeStep === 2">
<div style="text-align: center; margin-bottom: 30px;">
<i class="el-icon-circle-check" style="font-size: 60px; color: #67C23A;"></i>
<div style="margin-top: 15px; font-size: 16px; color: #303133;">
请确认信息无误后提交审核
</div>
</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<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>
<div style="margin-bottom: 15px; color: #606266;">
<div>经营范围</div>
<div class="scope-tags">
<el-tag
v-for="scopeId in qualificationForm.scopeIds"
:key="scopeId"
type="info"
size="medium"
class="scope-tag"
>
{{ getScopeLabel(scopeId) }}
</el-tag>
</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>
</div>
<div v-else style="color: #909399;">暂无文件</div>
</div>
</div>
<!-- 操作按钮 -->
<div slot="footer" class="dialog-footer">
<div v-if="activeStep > 0" style="float: left;">
<el-button @click="prevStep">上一步</el-button>
</div>
<div v-if="activeStep < 2">
<el-button type="primary" @click="nextStep">
{{ activeStep === 1 ? '下一步' : '下一步' }}
</el-button>
</div>
<div v-if="activeStep === 2">
<el-button @click="prevStep">上一步</el-button>
<el-button type="primary" @click="submitQualification" :loading="loading">
提交审核
</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { submitAuditQualification, qualificationAudit, getQualificationTypeOptions, getScopeOptions, uploadQualification } from "../api/vet/qualification";
import { getStatsCard } from "../api/vet/notification";
export default {
name: "Syd",
data() {
return {
//
tjzs: {},
//
title: "兽医资质审核",
flag: true,
dialogVisible: false,
open: false,
loading: false,
activeStep: 0,
form: {
realName: "",
idCard: "",
qualificationType: "",
certificateNo: ""
qualificationForm: {
qualificationId: "",
realName: '',
idCard: '',
qualificationType: '',
certificateNo: '',
scopeIds: [],
certificateFiles: '',
},
selectedScopes: [],
scopeOptions: []
fileList: [],
scopeOptions: [],
uploadedFiles: [],
qualificationTypeOptions: [],
selectedScopesDetail: '',
fileUploadResponses: [],
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"}
],
scopeIds: [
{
required: true,
type: 'array',
message: "请选择至少一个经营范围",
trigger: "change"
}
]
}
}
},
created() {
this.initOptions();
this.getcountSummary()
},
methods: {
//
getcountSummary() {
getStatsCard().then(res => {
this.tjzs = res.data
})
},
//
initOptions() {
const fetchData = async () => {
const qtypeRes = await getQualificationTypeOptions();
this.qualificationTypeOptions = qtypeRes.data;
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;
},
//
getScopeLabel(scopeId) {
const scope = this.scopeOptions.find(item => item.value === scopeId);
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) {
this.activeStep--
}
},
//
nextStep() {
if (this.activeStep === 0) {
this.$refs.qualificationForm.validate(valid => valid && (this.activeStep++));
return;
}
if (this.activeStep === 1) {
if (!this.fileList.length) {
this.$message.warning('请上传资质文件');
return;
}
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 {
this.activeStep++;
}
}
},
//
submitQualification() {
this.loading = true;
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(',')
};
// console.log(':', JSON.stringify(requestData, null, 2));
submitAuditQualification(requestData)
.then(response => {
this.$modal.msgSuccess('提交成功,请等待审核');
this.flag = false;
this.resetForm();
})
.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('提交失败,请重试');
}
})
.finally(() => {
this.loading = false;
});
}
}
}
</script>
@ -199,8 +472,239 @@ export default {
<style scoped lang="scss">
.vetnotshenhe-title {
text-align: center;
/* 轮播背景 */
.card-container {
display: flex;
gap: 20px;
padding: 20px;
}
.stat-card {
flex: 1;
min-width: 0;
padding: 30px 20px;
border: 1px solid #e5e6eb;
border-radius: 16px;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
cursor: pointer;
transition: all 0.3s ease;
min-height: 180px;
transform-origin: center center;
&:hover {
transform: translateY(-5px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}
}
.info-card.stat-card {
background-color: #bbdefb;
color: #0d47a1;
display: flex;
align-items: center;
justify-content: space-around;
padding: 20px;
}
.shake {
animation: cardShake 1s infinite linear;
background-color: #fffde6 !important;
&:hover {
animation-play-state: paused;
background-color: #edeacd !important;
}
}
.info-card .info-icon {
width: 60%;
cursor: pointer;
}
.info-card .info-title {
font-size: 28px;
font-weight: bold;
color: #42B983;
margin-bottom: 0;
text-align: center;
cursor: pointer;
}
.card-icon {
width: 60px;
height: 60px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
}
.card-icon i {
font-size: 30px;
color: #fff;
}
.card-text {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.card-title {
font-size: 16px;
color: #333;
margin-bottom: 8px;
}
.card-value {
font-size: 24px;
font-weight: bold;
color: #333;
}
.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;
font-size: 12px;
margin-top: 5px;
}
.step-summary {
margin-bottom: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 4px;
}
.summary-item {
display: flex;
align-items: flex-start;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
.summary-label {
min-width: 80px;
color: #606266;
font-weight: bold;
}
.summary-value {
color: #303133;
}
.scope-tags {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.scope-tag {
margin-right: 5px;
margin-bottom: 5px;
}
.uploaded-files {
margin-top: 15px;
padding: 10px;
background: #f5f7fa;
border-radius: 4px;
}
.file-list-title {
font-weight: bold;
margin-bottom: 8px;
color: #303133;
}
.file-item {
padding: 5px 0;
color: #606266;
display: flex;
align-items: center;
i {
margin-right: 5px;
color: #409EFF;
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.card-container {
flex-direction: column;
padding: 10px;
gap: 15px;
}
.stat-card {
min-height: 150px;
padding: 20px 15px;
}
.card-icon {
width: 50px;
height: 50px;
margin-right: 15px;
i {
font-size: 24px;
}
}
.info-card .info-icon {
width: 40px;
height: 40px;
}
.info-card .info-title {
font-size: 20px;
}
.card-value {
font-size: 20px;
}
}
/* 抖动动画 */
@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); }
}
.shake {
animation: cardShake 1s infinite linear;
&:hover {
animation-play-state: paused;
}
}
</style>

611
chenhai-ui/src/views/vet/article/index.vue

@ -1,5 +1,13 @@
<template>
<div class="app-container">
<!-- 论坛标题 -->
<div class="forum-header">
<h1 class="forum-title">兽医经验分享论坛</h1>
<div class="forum-subtitle">专属于兽医相关从业者的交流站</div>
</div>
<!-- 搜索部分 -->
<div class="forum-filters">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="文章标题" prop="title">
<el-input
@ -9,102 +17,117 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="作者" prop="vetId">-->
<!-- <el-input-->
<!-- v-model="queryParams.vetId"-->
<!-- placeholder="请输入作者"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医姓名" prop="vetName">-->
<!-- <el-input-->
<!-- v-model="queryParams.vetName"-->
<!-- placeholder="请输入兽医姓名"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医头像" prop="vetAvatar">-->
<!-- <el-input-->
<!-- v-model="queryParams.vetAvatar"-->
<!-- placeholder="请输入兽医头像"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医职称" prop="vetTitle">-->
<!-- <el-input-->
<!-- v-model="queryParams.vetTitle"-->
<!-- placeholder="请输入兽医职称"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="分类ID" prop="categoryId">-->
<!-- <el-input-->
<!-- v-model="queryParams.categoryId"-->
<!-- placeholder="请输入分类ID"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- <el-form-item label="文章类别" prop="categoryName">-->
<!-- <el-select v-model="queryParams.categoryName" placeholder="请选择文章类别" clearable>-->
<!-- <el-option-->
<!-- v-for="item in categories"-->
<!-- :key="item.value"-->
<!-- :label="item.label"-->
<!-- :value="item.value"-->
<!-- ></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="分类名称" prop="categoryName">
<el-input
v-model="queryParams.categoryName"
placeholder="请输入分类名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="标签" prop="tags">
<el-input
v-model="queryParams.tags"
placeholder="请输入标签"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否置顶" prop="isTop">
<el-input
v-model="queryParams.isTop"
placeholder="请输入是否置顶"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否精选" prop="isFeatured">
<el-input
v-model="queryParams.isFeatured"
placeholder="请输入是否精选"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否包含敏感词" prop="isSensitive">
<el-input
v-model="queryParams.isSensitive"
placeholder="请输入是否包含敏感词"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="发布时间" prop="publishTime">
<el-date-picker clearable
v-model="queryParams.publishTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择发布时间">
</el-date-picker>
<el-form-item label="文章标签" prop="taglist">
<el-select v-model="queryParams.taglist" placeholder="请选择文章标签" clearable>
<el-option
v-for="item in taglist"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- 侧边栏 -->
<div class="forum-content">
<!-- 个人文章 -->
<div class="forum-sidebar">
<div class="sidebar-card my-articles">
<div class="card-header">
<i class="el-icon-user-solid card-icon"></i>
<span class="card-title">我的文章</span>
</div>
<div class="card-body">
<div class="stats-row">
<div class="stat-item">
<div class="stat-number">{{ myStats.published || 0 }}</div>
<div class="stat-label">已发布</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ myStats.likes || 0 }}</div>
<div class="stat-label">获赞</div>
</div>
<div class="stat-item">
<div class="stat-number">{{ myStats.collects || 0 }}</div>
<div class="stat-label">收藏</div>
</div>
</div>
<el-button
type="text"
icon="el-icon-collection"
@click="handleViewMyArticles"
class="view-all-btn"
>
查看我的所有文章
</el-button>
</div>
</div>
<!-- 文章类别 -->
<div class="sidebar-card categories">
<div class="card-header">
<i class="el-icon-folder file-multiple"></i>
<span class="card-title">文章分类</span>
</div>
<div class="card-body">
<div class="category-list">
<div
v-for="category in categories"
:key="category.value"
class="category-item"
:class="{ active: queryParams.categoryName === category.value }"
@click="handleCategoryClick(category.value)"
>
{{ category.label }}
</div>
</div>
</div>
</div>
<!-- 热门标签 -->
<div class="sidebar-card categories">
<div class="card-header">
<i class="el-icon-price-tag tag-card-icon"></i>
<span class="card-title">热门标签</span>
</div>
<div class="card-body">
<div class="category-list">
<div
v-for="tags in taglist"
:key="tags.value"
class="category-item"
:class="{ active: queryParams.taglistName === tags.value }"
@click="handleTagsClick(tags.value)"
>
{{ tags.label }}
</div>
</div>
</div>
</div>
</div>
<!-- 右侧文章列表 -->
<div class="forum-main">
<!-- 操作按钮 -->
<div class="forum-actions">
<!-- <el-row :gutter="10" class="mb8">-->
<!-- <el-col :span="1.5">-->
<el-button
type="primary"
plain
@ -112,8 +135,26 @@
size="mini"
@click="handleAdd"
v-hasPermi="['vet:article:add']"
>新增</el-button>
</el-col>
>发新帖</el-button>
<!-- </el-col>-->
<!-- </el-row>-->
</div>
</div>
</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:article:add']"-->
<!-- >发新帖</el-button>-->
<!-- </el-col>-->
<el-col :span="1.5">
<el-button
type="success"
@ -151,9 +192,13 @@
<el-table v-loading="loading" :data="articleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="主键ID" align="center" prop="id" />-->
<!-- <el-table-column label="主键ID" align="center" prop="id" />-->
<el-table-column label="文章标题" align="center" prop="title" />
<el-table-column label="文章内容" align="center" prop="content" />
<el-table-column label="文章内容" align="center" prop="content">
<template #default="scope">
<div v-html="scope.row.content"></div>
</template>
</el-table-column>
<el-table-column label="文章摘要" align="center" prop="summary" />
<el-table-column label="封面图片" align="center" prop="coverImage" width="100">
<template slot-scope="scope">
@ -161,18 +206,18 @@
</template>
</el-table-column>
<el-table-column label="文章图片" align="center" prop="images" />
<!-- <el-table-column label="作者" align="center" prop="vetId" />-->
<!-- <el-table-column label="兽医姓名" align="center" prop="vetName" />-->
<!-- <el-table-column label="兽医头像" align="center" prop="vetAvatar" />-->
<!-- <el-table-column label="兽医职称" align="center" prop="vetTitle" />-->
<!-- <el-table-column label="分类ID" align="center" prop="categoryId" />-->
<!-- <el-table-column label="作者" align="center" prop="vetId" />-->
<!-- <el-table-column label="兽医姓名" align="center" prop="vetName" />-->
<!-- <el-table-column label="兽医头像" align="center" prop="vetAvatar" />-->
<!-- <el-table-column label="兽医职称" align="center" prop="vetTitle" />-->
<!-- <el-table-column label="分类ID" align="center" prop="categoryId" />-->
<el-table-column label="分类名称" align="center" prop="categoryName" />
<el-table-column label="标签" align="center" prop="tags" />
<el-table-column label="是否置顶" align="center" prop="isTop" />
<el-table-column label="是否精选" align="center" prop="isFeatured" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column label="是否包含敏感词" align="center" prop="isSensitive" />
<el-table-column label="敏感词列表" align="center" prop="sensitiveWords" />
<!-- <el-table-column label="是否置顶" align="center" prop="isTop" />-->
<!-- <el-table-column label="是否精选" align="center" prop="isFeatured" />-->
<!-- <el-table-column label="状态" align="center" prop="status" />-->
<!-- <el-table-column label="是否包含敏感词" align="center" prop="isSensitive" />-->
<!-- <el-table-column label="敏感词列表" align="center" prop="sensitiveWords" />-->
<el-table-column label="发布时间" align="center" prop="publishTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>
@ -222,45 +267,45 @@
<el-form-item label="文章摘要" prop="summary">
<el-input v-model="form.summary" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="封面图片" prop="coverImage">
<el-form-item label="文章图片" prop="coverImage">
<image-upload v-model="form.coverImage"/>
</el-form-item>
<el-form-item label="文章图片" prop="images">
<el-input v-model="form.images" type="textarea" placeholder="请输入内容" />
</el-form-item>
<!-- <el-form-item label="作者" prop="vetId">-->
<!-- <el-input v-model="form.vetId" placeholder="请输入作者" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医姓名" prop="vetName">-->
<!-- <el-input v-model="form.vetName" placeholder="请输入兽医姓名" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医头像" prop="vetAvatar">-->
<!-- <el-input v-model="form.vetAvatar" placeholder="请输入兽医头像" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医职称" prop="vetTitle">-->
<!-- <el-input v-model="form.vetTitle" placeholder="请输入兽医职称" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="分类ID" prop="categoryId">-->
<!-- <el-input v-model="form.categoryId" placeholder="请输入分类ID" />-->
<!-- <el-form-item label="文章图片" prop="images">-->
<!-- <el-input v-model="form.images" type="textarea" placeholder="请输入内容" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="作者" prop="vetId">-->
<!-- <el-input v-model="form.vetId" placeholder="请输入作者" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医姓名" prop="vetName">-->
<!-- <el-input v-model="form.vetName" placeholder="请输入兽医姓名" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医头像" prop="vetAvatar">-->
<!-- <el-input v-model="form.vetAvatar" placeholder="请输入兽医头像" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="兽医职称" prop="vetTitle">-->
<!-- <el-input v-model="form.vetTitle" placeholder="请输入兽医职称" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="分类ID" prop="categoryId">-->
<!-- <el-input v-model="form.categoryId" placeholder="请输入分类ID" />-->
<!-- </el-form-item>-->
<el-form-item label="分类名称" prop="categoryName">
<el-input v-model="form.categoryName" placeholder="请输入分类名称" />
</el-form-item>
<el-form-item label="标签" prop="tags">
<el-input v-model="form.tags" placeholder="请输入标签" />
</el-form-item>
<el-form-item label="是否置顶" prop="isTop">
<el-input v-model="form.isTop" placeholder="请输入是否置顶" />
</el-form-item>
<el-form-item label="是否精选" prop="isFeatured">
<el-input v-model="form.isFeatured" placeholder="请输入是否精选" />
</el-form-item>
<el-form-item label="是否包含敏感词" prop="isSensitive">
<el-input v-model="form.isSensitive" placeholder="请输入是否包含敏感词" />
</el-form-item>
<el-form-item label="敏感词列表" prop="sensitiveWords">
<el-input v-model="form.sensitiveWords" type="textarea" placeholder="请输入内容" />
</el-form-item>
<!-- <el-form-item label="是否置顶" prop="isTop">-->
<!-- <el-input v-model="form.isTop" placeholder="请输入是否置顶" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否精选" prop="isFeatured">-->
<!-- <el-input v-model="form.isFeatured" placeholder="请输入是否精选" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否包含敏感词" prop="isSensitive">-->
<!-- <el-input v-model="form.isSensitive" placeholder="请输入是否包含敏感词" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="敏感词列表" prop="sensitiveWords">-->
<!-- <el-input v-model="form.sensitiveWords" type="textarea" placeholder="请输入内容" />-->
<!-- </el-form-item>-->
<el-form-item label="发布时间" prop="publishTime">
<el-date-picker clearable
v-model="form.publishTime"
@ -275,11 +320,90 @@
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 查看我的所有文章弹窗 -->
<!-- <el-dialog :title="title" :visible.sync="flag" width="50%" append-to-body>-->
<!-- <el-row :gutter="10" class="mb8">-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="success"-->
<!-- plain-->
<!-- icon="el-icon-edit"-->
<!-- size="mini"-->
<!-- :disabled="single"-->
<!-- @click="handleUpdate"-->
<!-- v-hasPermi="['vet:article:edit']"-->
<!-- >修改</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="danger"-->
<!-- plain-->
<!-- icon="el-icon-delete"-->
<!-- size="mini"-->
<!-- :disabled="multiple"-->
<!-- @click="handleDelete"-->
<!-- v-hasPermi="['vet:article:remove']"-->
<!-- >删除</el-button>-->
<!-- </el-col>-->
<!-- </el-row>-->
<!-- -->
<!-- <el-table v-loading="loading" :data="articleList" @selection-change="handleSelectionChange">-->
<!-- <el-table-column type="selection" width="55" align="center" />-->
<!-- <el-table-column label="文章标题" align="center" prop="title" />-->
<!-- <el-table-column label="文章摘要" align="center" prop="summary" />-->
<!-- <el-table-column label="封面图片" align="center" prop="coverImage" width="100">-->
<!-- <template slot-scope="scope">-->
<!-- <image-preview :src="scope.row.coverImage" :width="50" :height="50"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="分类名称" align="center" prop="categoryName" />-->
<!-- <el-table-column label="标签" align="center" prop="tags" />-->
<!-- <el-table-column label="发布时间" align="center" prop="publishTime" width="180">-->
<!-- <template slot-scope="scope">-->
<!-- <span>{{ parseTime(scope.row.publishTime, '{y}-{m}-{d}') }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">-->
<!-- <template slot-scope="scope">-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- style="color: #42B983"-->
<!-- class="article-btn alter-btn"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['vet:article:edit']"-->
<!-- >修改</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- style="color: #f28888"-->
<!-- class="article-btn delete-btn"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['vet:article:remove']"-->
<!-- >删除</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<!-- <pagination-->
<!-- v-show="total>0"-->
<!-- :total="total"-->
<!-- :page.sync="queryParams.pageNum"-->
<!-- :limit.sync="queryParams.pageSize"-->
<!-- @pagination="handleViewMyArticles"-->
<!-- />-->
<!-- </el-dialog>-->
</div>
</template>
<script>
import { listArticle, getArticle, delArticle, addArticle, updateArticle } from "@/api/vet/article"
import { listArticle, getForumHome, getArticle, delArticle, addArticle,
updateArticle, getForumDetail, publishForumArticle, getMyForumArticles,
likeForumArticle, collectForumArticle, getForumHotTags, getArticlesByCategory,
getArticleOptions} from "@/api/vet/article"
export default {
name: "Article",
@ -303,6 +427,7 @@ export default {
title: "",
//
open: false,
flag: false,
//
queryParams: {
pageNum: 1,
@ -318,6 +443,9 @@ export default {
vetTitle: null,
categoryId: null,
categoryName: null,
taglistName: null,
tags: null,
isTop: null,
isFeatured: null,
@ -339,13 +467,54 @@ export default {
vetId: [
{ required: true, message: "作者不能为空", trigger: "blur" }
],
}
},
//
myStats: {},
//
categories: [],
//
taglist: [],
}
},
created() {
this.getList()
// this.loadMyStats()
},
methods: {
/** 加载我的文章统计 */
// loadMyStats() {
//
// getStatsCard().then(res => {
// this.myStats = res.data
// })
// },
/* 分类点击事件 */
handleCategoryClick(category) {
this.queryParams.categoryName = category
this.handleQuery()
},
/* 查看我的所有文章 */
handleViewMyArticles() {
this.flag = true
this.queryParams.pageNum = 1
this.queryParams.vetId = this.$store.state.user.userId;
const query = {
pageNum: 1,
pageSize: 10,
vetId: this.$store.state.user.userId
}
getMyForumArticles(this.queryParams).then((response) => {
if (response.code === 200) {
this.articleList = response.data;
}
}).catch(() => {
});
},
/** 查询兽医经验文章列表 */
getList() {
this.loading = true
@ -456,12 +625,182 @@ export default {
this.download('vet/article/export', {
...this.queryParams
}, `article_${new Date().getTime()}.xlsx`)
}
},
}
}
</script>
<style scoped lang="scss">
/* 论坛标题 */
.forum-header {
margin-bottom: 30px;
text-align: center;
.forum-title {
font-size: 28px;
color: #333;
margin-bottom: 8px;
font-weight: bold;
}
.forum-subtitle {
font-size: 14px;
color: #666;
}
}
/* 搜索部分 */
.forum-filters {
background: white;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.04);
::v-deep .el-form-item {
margin-bottom: 0;
margin-right: 20px;
}
::v-deep .filter-select {
width: 150px;
}
}
/* 论坛部分 */
.forum-content{
display: flex
}
/* 左侧内容部分 */
.forum-sidebar {
width: 280px;
flex-shrink: 0;
.sidebar-card {
background: white;
border-radius: 8px;
margin-bottom: 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.04);
.card-header {
padding: 16px 20px;
border-bottom: 1px solid #f0f0f0;
display: flex;
align-items: center;
.card-icon {
margin-right: 8px;
color: #409EFF;
}
.file-multiple {
margin-right: 8px;
color: #42B983;
}
.tag-card-icon {
margin-right: 8px;
color: #f6c90e;
}
.card-title {
font-weight: 500;
color: #333;
}
}
.card-body {
padding: 20px;
}
&.my-articles {
.stats-row {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
.stat-item {
text-align: center;
.stat-number {
font-size: 24px;
font-weight: bold;
color: #409EFF;
line-height: 1;
margin-bottom: 4px;
}
.stat-label {
font-size: 12px;
color: #666;
}
}
}
.view-all-btn {
width: 100%;
text-align: center;
padding: 8px 0;
color: #409EFF;
&:hover {
color: #66b1ff;
}
}
}
&.categories {
.category-list {
.category-item {
padding: 8px 12px;
margin-bottom: 8px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
color: #666;
&:hover {
background: #f5f7fa;
color: #409EFF;
}
&.active {
background: #ecf5ff;
color: #409EFF;
font-weight: 500;
}
&:last-child {
margin-bottom: 0;
}
}
}
}
}
}
/* 右侧文章部分 */
/* 操作按钮 */
.forum-main {
flex: 1;
}
.forum-actions {
background: white;
padding: 16px 20px;
border-radius: 8px;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 12px rgba(0,0,0,0.04);
.action-buttons {
display: flex;
gap: 10px;
}
}
/* 操作按钮样式 */
.article-btn {
padding: 6px 10px;
@ -482,5 +821,3 @@ export default {
}
</style>

6
chenhai-ui/src/views/vet/certificate/index.vue

@ -236,7 +236,7 @@
</template>
<script>
import { listCertificate, getCertificate, delCertificate, addCertificate, updateCertificate } from "@/api/vet/certificate"
import { listCertificate, getCertificate, delCertificate, addCertificate, updateCertificate, listForDetail } from "@/api/vet/certificate"
export default {
name: "Certificate",
@ -299,8 +299,8 @@ export default {
/** 查询兽医执业证书列表 */
getList() {
this.loading = false
listCertificate(this.queryParams).then(response => {
this.certificateList = response.rows
listForDetail(this.queryParams).then(response => {
// this.certificateList = response.rows
this.total = response.total
this.loading = false
})

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

@ -224,7 +224,11 @@
<!-- 详情对话框 -->
<el-dialog :title="title" :visible.sync="flag" width="1000px" append-to-body>
<Certificate :form-list="form" :certificateList="certificateList"></Certificate>
<Certificate
:form-list="form"
:certificateList="certificateList"
>
</Certificate>
</el-dialog>
</div>
</template>
@ -351,7 +355,6 @@ export default {
const id = row.id || this.ids
getfull(id).then(response => {
this.flag = true
// this.form = response.data;
this.form = response.data.personalInfo;
this.certificateList = response.data.certificates;
});

536
chenhai-ui/src/views/vet/notification/index.vue

@ -1,14 +1,15 @@
<template>
<div class="app-container">
<!-- 搜索部分 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="接收用户ID" prop="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入接收用户ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="接收用户ID" prop="userId">-->
<!-- <el-input-->
<!-- v-model="queryParams.userId"-->
<!-- placeholder="请输入接收用户ID"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="通知标题" prop="title">
<el-input
v-model="queryParams.title"
@ -17,77 +18,84 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="关联ID" prop="relatedId">
<el-input
v-model="queryParams.relatedId"
placeholder="请输入关联ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否已读 0:未读 1:已读" prop="isRead">
<el-input
<!-- <el-form-item label="关联ID" prop="relatedId">-->
<!-- <el-input-->
<!-- v-model="queryParams.relatedId"-->
<!-- placeholder="请输入关联ID"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="是否已读" prop="isRead">
<el-select
v-model="queryParams.isRead"
placeholder="请输入是否已读 0:未读 1:已读"
placeholder="请选择是否已读"
clearable
@keyup.enter.native="handleQuery"
/>
style="width: 180px"
>
<el-option label="未读" value="0" />
<el-option label="已读" value="1" />
</el-select>
</el-form-item>
<el-form-item label="提醒级别 1:低 2:中 3:高" prop="remindLevel">
<el-input
<el-form-item label="提醒级别" prop="remindLevel">
<el-select
v-model="queryParams.remindLevel"
placeholder="请输入提醒级别 1:低 2:中 3:高"
placeholder="请选择提醒级别"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="阅读时间" prop="readTime">
<el-date-picker clearable
v-model="queryParams.readTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择阅读时间">
</el-date-picker>
style="width: 180px"
>
<el-option label="一般通知" value="1" />
<el-option label="重要通知" value="2" />
<el-option label="紧急通知" value="3" />
</el-select>
</el-form-item>
<!-- <el-form-item label="阅读时间" prop="readTime">-->
<!-- <el-date-picker clearable-->
<!-- v-model="queryParams.readTime"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择阅读时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<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:notification:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vet:notification:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vet:notification:remove']"
>删除</el-button>
</el-col>
<!-- <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:notification:add']"-->
<!-- >新增</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="success"-->
<!-- plain-->
<!-- icon="el-icon-edit"-->
<!-- size="mini"-->
<!-- :disabled="single"-->
<!-- @click="handleUpdate"-->
<!-- v-hasPermi="['vet:notification:edit']"-->
<!-- >修改</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="danger"-->
<!-- plain-->
<!-- icon="el-icon-delete"-->
<!-- size="mini"-->
<!-- :disabled="multiple"-->
<!-- @click="handleDelete"-->
<!-- v-hasPermi="['vet:notification:remove']"-->
<!-- >删除</el-button>-->
<!-- </el-col>-->
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="warning"-->
@ -98,19 +106,65 @@
<!-- v-hasPermi="['system:notification:export']"-->
<!-- >导出</el-button>-->
<!-- </el-col>-->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>-->
<!-- </el-row>-->
<!-- 消息轮播 -->
<div class="carousel-container" v-if="unreadCarouselList.length > 0">
<el-carousel
height="100px"
direction="vertical"
autoplay
:interval="3000"
indicator-position="none"
class="vertical-carousel"
>
<el-carousel-item v-for="item in unreadCarouselList" :key="item.id">
<div
class="carousel-item"
:style="{'background-color': getCarouselBgColor(item.remindLevel)}"
>
<div class="carousel-title">📢 {{ item.title }}</div>
<div class="carousel-content">
<img class="info-icon" :src="require('@/assets/images/zhixiang.png')">
<div class="carousel-text" v-html="item.content"></div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
<!-- 表格部分 -->
<el-table v-loading="loading" :data="notificationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" />
<el-table-column label="接收用户ID" align="center" prop="userId" />
<!-- <el-table-column type="index" width="55" align="center" label="序号"/>-->
<!-- <el-table-column label="主键ID" align="center" prop="id" />-->
<!-- <el-table-column label="接收用户ID" align="center" prop="userId" />-->
<el-table-column label="通知标题" align="center" prop="title" />
<el-table-column label="通知内容" align="center" prop="content" />
<el-table-column label="通知内容" align="center" prop="content">
<template #default="scope">
<div v-html="scope.row.content"></div>
</template>
</el-table-column>
<el-table-column label="通知类型" align="center" prop="type" />
<el-table-column label="关联ID" align="center" prop="relatedId" />
<el-table-column label="是否已读 0:未读 1:已读" align="center" prop="isRead" />
<el-table-column label="提醒级别 1:低 2:中 3:高" align="center" prop="remindLevel" />
<!-- <el-table-column label="关联ID" align="center" prop="relatedId" />-->
<el-table-column label="是否已读" align="center" prop="isRead">
<template #default="scope">
<el-tag :type="scope.row.isRead === 1 ? 'success' : 'info'">
{{ scope.row.isRead === 1 ? '已读' : '未读' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="提醒级别" align="center" prop="remindLevel">
<template #default="scope">
<el-tag
:type="scope.row.remindLevel === 3 ? 'danger' :
scope.row.remindLevel === 2 ? 'warning' : 'success'">
{{ scope.row.remindLevel === 3 ? '紧急通知' :
scope.row.remindLevel === 2 ? '重要通知' : '一般通知' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="阅读时间" align="center" prop="readTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.readTime, '{y}-{m}-{d}') }}</span>
@ -121,21 +175,31 @@
<el-button
size="mini"
type="text"
icon="el-icon-edit"
icon="el-icon-circle-check"
style="color: #42B983"
class = "notification-btn alter-btn"
@click="handleUpdate(scope.row)"
class="notification-btn read-btn"
@click="handleMarkRead(scope.row)"
v-hasPermi="['vet:certificate:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
style="color: #f28888"
class = "notification-btn delete-btn"
@click="handleDelete(scope.row)"
v-hasPermi="['vet:certificate:remove']"
>删除</el-button>
v-show="scope.row.isRead === 0"
>标记已读</el-button>
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-edit"-->
<!-- style="color: #42B983"-->
<!-- class = "notification-btn alter-btn"-->
<!-- @click="handleUpdate(scope.row)"-->
<!-- v-hasPermi="['vet:certificate:edit']"-->
<!-- >修改</el-button>-->
<!-- <el-button-->
<!-- size="mini"-->
<!-- type="text"-->
<!-- icon="el-icon-delete"-->
<!-- style="color: #f28888"-->
<!-- class = "notification-btn delete-btn"-->
<!-- @click="handleDelete(scope.row)"-->
<!-- v-hasPermi="['vet:certificate:remove']"-->
<!-- >删除</el-button>-->
</template>
</el-table-column>
</el-table>
@ -149,53 +213,55 @@
/>
<!-- 添加或修改兽医通知对话框 -->
<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="接收用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入接收用户ID" />
</el-form-item>
<el-form-item label="通知标题" prop="title">
<el-input v-model="form.title" placeholder="请输入通知标题" />
</el-form-item>
<el-form-item label="通知内容">
<editor v-model="form.content" :min-height="192"/>
</el-form-item>
<el-form-item label="关联ID" prop="relatedId">
<el-input v-model="form.relatedId" placeholder="请输入关联ID" />
</el-form-item>
<el-form-item label="是否已读 0:未读 1:已读" prop="isRead">
<el-input v-model="form.isRead" placeholder="请输入是否已读 0:未读 1:已读" />
</el-form-item>
<el-form-item label="提醒级别 1:低 2:中 3:高" prop="remindLevel">
<el-input v-model="form.remindLevel" placeholder="请输入提醒级别 1:低 2:中 3:高" />
</el-form-item>
<el-form-item label="阅读时间" prop="readTime">
<el-date-picker clearable
v-model="form.readTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择阅读时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</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="接收用户ID" prop="userId">-->
<!-- <el-input v-model="form.userId" placeholder="请输入接收用户ID" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="通知标题" prop="title">-->
<!-- <el-input v-model="form.title" placeholder="请输入通知标题" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="通知内容">-->
<!-- <editor v-model="form.content" :min-height="192"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="关联ID" prop="relatedId">-->
<!-- <el-input v-model="form.relatedId" placeholder="请输入关联ID" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="是否已读 0:未读 1:已读" prop="isRead">-->
<!-- <el-input v-model="form.isRead" placeholder="请输入是否已读 0:未读 1:已读" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="提醒级别 1:一般通知 2:重要通知 3:紧急通知" prop="remindLevel">-->
<!-- <el-input v-model="form.remindLevel" placeholder="请输入提醒级别 1:一般通知 2:重要通知 3:紧急通知" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="阅读时间" prop="readTime">-->
<!-- <el-date-picker clearable-->
<!-- v-model="form.readTime"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择阅读时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- <div slot="footer" class="dialog-footer">-->
<!-- <el-button type="primary" @click="submitForm"> </el-button>-->
<!-- <el-button @click="cancel"> </el-button>-->
<!-- </div>-->
<!-- </el-dialog>-->
</div>
</template>
<script>
import { listNotification, getNotification, delNotification, addNotification, updateNotification } from "@/api/vet/notification"
import { listNotification, getNotification, delNotification, addNotification, updateNotification, markAllread, markRead } from "@/api/vet/notification"
export default {
name: "Notification",
data() {
return {
//
unreadCarouselList: [],
//
loading: true,
//
//
ids: [],
//
single: true,
@ -241,20 +307,40 @@ export default {
this.getList()
},
methods: {
/** 查询兽医通知列表 */
//
getList() {
this.loading = true
listNotification(this.queryParams).then(response => {
this.notificationList = response.rows
this.total = response.total
this.unreadCarouselList = this.notificationList.filter(item => item.isRead === 0)
this.sortedNotificationList = this.sortNotifications(this.notificationList)
this.loading = false
})
},
//
getCarouselBgColor(remindLevel) {
switch (remindLevel) {
case 1:
return '#f0f9f0'
case 2:
return '#fffbeb'
case 3:
return '#fff2f2'
default:
return '#ffffff'
}
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
@ -271,29 +357,34 @@ export default {
}
this.resetForm("form")
},
/** 搜索按钮操作 */
//
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
//
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
//
handleAdd() {
this.reset()
this.open = true
this.title = "添加兽医通知"
},
/** 修改按钮操作 */
//
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
@ -303,7 +394,24 @@ export default {
this.title = "修改兽医通知"
})
},
/** 提交按钮 */
//
sortNotifications(notifications) {
return notifications.sort((a, b) => {
if (a.isRead !== b.isRead) {
return a.isRead - b.isRead
}
if (a.isRead === 1 && b.isRead === 1) {
if (!a.readTime && !b.readTime) return 0
if (!a.readTime) return 1
if (!b.readTime) return -1
return new Date(b.readTime) - new Date(a.readTime)
}
return 0
})
},
//
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
@ -323,7 +431,8 @@ export default {
}
})
},
/** 删除按钮操作 */
//
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除兽医通知编号为"' + ids + '"的数据项?').then(function() {
@ -333,17 +442,171 @@ export default {
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
//
handleExport() {
this.download('vet/notification/export', {
...this.queryParams
}, `notification_${new Date().getTime()}.xlsx`)
}
},
//
handleMarkRead(row) {
const id = row.id
if (!id) return
markRead(id).then(() => {
this.$modal.msgSuccess("标记已读成功")
this.getList()
})
},
}
}
</script>
<style scoped lang="scss">
/* 消息轮播 */
.carousel-container {
margin-bottom: 20px;
border: 1px solid #e4e7ed;
border-radius: 12px;
overflow: hidden;
box-shadow:
0 4px 20px rgba(0, 0, 0, 0.08),
inset 0 1px 1px rgba(255, 255, 255, 0.8);
background: linear-gradient(135deg, #f9fafb 0%, #ffffff 100%);
position: relative;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
rgba(0, 0, 0, 0.05) 50%,
transparent 100%);
z-index: 1;
}
}
.vertical-carousel {
.el-carousel__item {
height: 100%;
line-height: normal;
background: transparent;
}
}
.carousel-item {
padding: 10px 22px;
height: 100%;
box-sizing: border-box;
color: #333;
position: relative;
.status-row {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.info-icon {
width: 30px;
height: 30px;
margin-right: 15px;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
}
.carousel-title {
font-weight: 700;
font-size: 18px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #1f2937;
letter-spacing: 0.3px;
padding-bottom: 12px;
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
rgba(0, 0, 0, 0.12) 20%,
rgba(0, 0, 0, 0.12) 80%,
transparent 100%);
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
}
}
.carousel-content {
font-size: 14px;
height: 40px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
color: #4b5563;
line-height: 1.7;
font-weight: 400;
margin-top: 8px;
background: #f8f9fa;
border-radius: 8px;
border: 1px solid rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
.info-icon {
width: 50px;
height: 50px;
margin-right: 16px;
flex-shrink: 0;
align-self: center;
}
.carousel-text {
flex: 1;
display: flex;
align-items: center;
min-height: 50px;
}
}
}
//
@media (max-width: 768px) {
.carousel-container {
border-radius: 10px;
}
.carousel-item {
padding: 14px 18px;
.carousel-content {
padding: 12px;
.info-icon {
width: 40px;
height: 40px;
margin-right: 12px;
}
.carousel-text {
min-height: 40px;
}
}
}
}
/* 操作按钮 */
.notification-btn {
padding: 6px 10px;
border-radius: 4px;
@ -352,6 +615,11 @@ export default {
}
.read-btn:hover{
background-color: rgb(230, 255, 238);
transform: translateY(-1px);
}
.alter-btn:hover{
background-color: rgb(230, 255, 238);
transform: translateY(-1px);

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

@ -1,30 +1,30 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="兽医ID" prop="vetId">
<el-input
v-model="queryParams.vetId"
placeholder="请输入兽医ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="真实姓名" prop="realName">
<el-input
v-model="queryParams.realName"
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-form-item>
<!-- <el-form-item label="兽医ID" prop="vetId">-->
<!-- <el-input-->
<!-- v-model="queryParams.vetId"-->
<!-- placeholder="请输入兽医ID"-->
<!-- clearable-->
<!-- @keyup.enter.native="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="真实姓名" prop="realName">-->
<!-- <el-input-->
<!-- v-model="queryParams.realName"-->
<!-- 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-form-item>-->
<el-form-item label="资质类型" prop="qualificationType">
<el-input
v-model="queryParams.qualificationType"
@ -41,30 +41,30 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申请时间" prop="applyTime">
<el-date-picker clearable
v-model="queryParams.applyTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申请时间">
</el-date-picker>
</el-form-item>
<el-form-item label="审核时间" prop="auditTime">
<el-date-picker clearable
v-model="queryParams.auditTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择审核时间">
</el-date-picker>
</el-form-item>
<el-form-item label="审核人ID" prop="auditorId">
<el-input
v-model="queryParams.auditorId"
placeholder="请输入审核人ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="申请时间" prop="applyTime">-->
<!-- <el-date-picker clearable-->
<!-- v-model="queryParams.applyTime"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择申请时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="审核时间" prop="auditTime">-->
<!-- <el-date-picker clearable-->
<!-- v-model="queryParams.auditTime"-->
<!-- type="date"-->
<!-- value-format="yyyy-MM-dd"-->
<!-- placeholder="请选择审核时间">-->
<!-- </el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="审核人ID" prop="auditorId">-->
<!-- <el-input-->
<!-- v-model="queryParams.auditorId"-->
<!-- placeholder="请输入审核人ID"-->
<!-- 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>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@ -119,11 +119,22 @@
<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" />
<el-table-column label="兽医ID" align="center" prop="vetId" />
<el-table-column label="真实姓名" align="center" prop="realName" />
<el-table-column label="身份证号" align="center" prop="idCard" />
<el-table-column label="资质类型" align="center" prop="qualificationType" />
<!-- <el-table-column label="资质ID" align="center" prop="qualificationId" />-->
<!-- <el-table-column label="兽医ID" align="center" prop="vetId" />-->
<!-- <el-table-column label="真实姓名" align="center" prop="realName" />-->
<!-- <el-table-column label="身份证号" align="center" prop="idCard" />-->
<!-- <el-table-column label="资质类型" align="center" prop="qualificationType" />-->
<el-table-column label="资质类型" align="center" prop="qualificationType" width="120">
<template slot-scope="scope">
<el-tag
v-if="scope.row.qualificationType"
:type="getQualificationTypeTagType(scope.row.qualificationType)"
>
{{ formatQualificationType(scope.row.qualificationType) }}
</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="证书编号" align="center" prop="certificateNo" />
<el-table-column label="证书文件" align="center" prop="certificateFiles" />
<el-table-column label="申请时间" align="center" prop="applyTime" width="180">
@ -137,10 +148,10 @@
</template>
</el-table-column>
<el-table-column label="审核状态" align="center" prop="auditStatus" />
<el-table-column label="审核意见" align="center" prop="auditOpinion" />
<el-table-column label="审核人ID" align="center" prop="auditorId" />
<!-- <el-table-column label="审核意见" align="center" prop="auditOpinion" />-->
<!-- <el-table-column label="审核人ID" align="center" prop="auditorId" />-->
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="180">
<template slot-scope="scope">
<el-button
size="mini"
@ -174,12 +185,12 @@
<!-- <el-form-item label="兽医ID" prop="vetId">
<el-input v-model="form.vetId" placeholder="请输入兽医ID" />
</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="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="资质类型" proper="qualificationType" >
<el-input v-model="form.qualificationType" placeholder="请输入资质类型" />
</el-form-item>
@ -258,6 +269,7 @@ export default {
qualificationType: null,
certificateNo: null,
certificateFiles: null,
scope_names: null,
applyTime: null,
auditTime: null,
auditStatus: null,
@ -290,6 +302,9 @@ export default {
}
},
created() {
this.getDicts("qualification_type").then(response => {
this.qualificationTypeOptions = response.data
}),
this.getList()
},
methods: {
@ -302,6 +317,21 @@ export default {
this.loading = false
})
},
//
formatQualificationType(value) {
if (!value) return '-'
const dict = this.qualificationTypeOptions.find(item => item.dictValue === value)
return dict ? dict.dictLabel : value
},
getQualificationTypeTagType(value) {
const typeMap = {
'1': 'success',
'2': 'info',
'3': 'warning',
'4': 'danger'
}
return typeMap[value] || 'primary'
},
//
cancel() {
this.open = false

7
chenhai-ui/vue.config.js

@ -9,7 +9,12 @@ const CompressionPlugin = require('compression-webpack-plugin')
const name = process.env.VUE_APP_TITLE || '"与牧同行"' // 网页标题
const baseUrl = 'http://localhost:8082' // 后端接
const baseUrl = // 后端接口
// 'http://localhost:8081'
'http://192.168.101.105:8082'
// 'http://192.168.101.109:8080'
// 'http://192.168.101.111:8081'
const port = process.env.port || process.env.npm_config_port || 80 // 端口
// vue.config.js 配置说明

Loading…
Cancel
Save