You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

667 lines
22 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <div class="app-container">
  3. <!-- 搜索部分 -->
  4. <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="90px">
  5. <el-form-item label="真实姓名" prop="realName">
  6. <el-input
  7. v-model="queryParams.realName"
  8. placeholder="请输入真实姓名"
  9. clearable
  10. @keyup.enter.native="handleQuery"
  11. />
  12. </el-form-item>
  13. <!-- <el-form-item label="性别" prop="gender">-->
  14. <!-- <el-input-->
  15. <!-- v-model="queryParams.gender"-->
  16. <!-- placeholder="请输入性别"-->
  17. <!-- clearable-->
  18. <!-- @keyup.enter.native="handleQuery"-->
  19. <!-- />-->
  20. <!-- </el-form-item>-->
  21. <el-form-item label="身份证号" prop="idCard">
  22. <el-input
  23. v-model="queryParams.idCard"
  24. placeholder="请输入身份证号"
  25. clearable
  26. @keyup.enter.native="handleQuery"
  27. />
  28. </el-form-item>
  29. <!-- <el-form-item label="工作经验" prop="workExperience">-->
  30. <!-- <el-input-->
  31. <!-- v-model="queryParams.workExperience"-->
  32. <!-- placeholder="请输入工作经验"-->
  33. <!-- clearable-->
  34. <!-- @keyup.enter.native="handleQuery"-->
  35. <!-- />-->
  36. <!-- </el-form-item>-->
  37. <el-form-item label="所属医院" prop="hospital">
  38. <el-input
  39. v-model="queryParams.hospital"
  40. placeholder="请输入所属医院"
  41. clearable
  42. @keyup.enter.native="handleQuery"
  43. />
  44. </el-form-item>
  45. <el-form-item>
  46. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  47. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  48. </el-form-item>
  49. </el-form>
  50. <el-row :gutter="10" class="mb8">
  51. <el-col :span="1.5">
  52. <el-button
  53. type="primary"
  54. plain
  55. icon="el-icon-plus"
  56. size="mini"
  57. @click="handleAdd"
  58. v-hasPermi="['vet:info:add']"
  59. >新增</el-button>
  60. </el-col>
  61. <el-col :span="1.5">
  62. <el-button
  63. type="success"
  64. plain
  65. icon="el-icon-edit"
  66. size="mini"
  67. :disabled="single"
  68. @click="handleUpdate"
  69. v-hasPermi="['vet:info:edit']"
  70. >修改</el-button>
  71. </el-col>
  72. <el-col :span="1.5">
  73. <el-button
  74. type="danger"
  75. plain
  76. icon="el-icon-delete"
  77. size="mini"
  78. :disabled="multiple"
  79. @click="handleDelete"
  80. v-hasPermi="['vet:info:remove']"
  81. >删除</el-button>
  82. </el-col>
  83. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  84. </el-row>
  85. <!-- 表格部分 -->
  86. <el-table v-loading="loading" :data="infoList" @selection-change="handleSelectionChange">
  87. <el-table-column type="selection" width="55" align="center" />
  88. <el-table-column label="用户昵称" align="center" prop="nickName" />
  89. <el-table-column label="真实姓名" align="center" prop="realName" width="150" :show-overflow-tooltip="true"/>
  90. <el-table-column label="性别" align="center" prop="gender" />
  91. <el-table-column label="出生日期" align="center" prop="birthday" width="100">
  92. <template slot-scope="scope">
  93. <span>{{ parseTime(scope.row.birthday, '{y}-{m}-{d}') }}</span>
  94. </template>
  95. </el-table-column>
  96. <el-table-column label="身份证号" align="center" prop="idCard" width="200"/>
  97. <el-table-column label="擅长领域" align="center" prop="specialty" width="150" :show-overflow-tooltip="true"/>
  98. <el-table-column label="工作经验" align="center" prop="workExperience"/>
  99. <el-table-column label="职称" align="center" prop="title" width="150"/>
  100. <el-table-column label="联系电话" align="center" prop="phone" width="200"/>
  101. <el-table-column label="电子邮箱" align="center" prop="email" width="200"/>
  102. <el-table-column label="专家类型" align="center" prop="expertType" width="150"/>
  103. <el-table-column label="所属医院" align="center" prop="hospital" width="150" :show-overflow-tooltip="true"/>
  104. <el-table-column label="联系地址" align="center" prop="address" width="150" :show-overflow-tooltip="true"/>
  105. <el-table-column label="个人简介" align="center" prop="introduction" width="150" :show-overflow-tooltip="true"/>
  106. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="300">
  107. <template slot-scope="scope">
  108. <el-button
  109. size="mini"
  110. type="text"
  111. icon="el-icon-view"
  112. class = "info-btn view-btn"
  113. @click="handleView(scope.row)"
  114. v-hasPermi="['vet:info:view']"
  115. >详情</el-button>
  116. <el-button
  117. size="mini"
  118. type="text"
  119. icon="el-icon-edit"
  120. style="color: #42B983"
  121. class = "info-btn alter-btn"
  122. @click="handleUpdate(scope.row)"
  123. v-hasPermi="['vet:info:edit']"
  124. >修改</el-button>
  125. <el-button
  126. size="mini"
  127. type="text"
  128. icon="el-icon-delete"
  129. style="color: #f28888"
  130. class = "info-btn delete-btn"
  131. @click="handleDelete(scope.row)"
  132. v-hasPermi="['vet:info:remove']"
  133. >删除</el-button>
  134. </template>
  135. </el-table-column>
  136. </el-table>
  137. <div class="pagestyle">
  138. <pagination
  139. v-show="total>0"
  140. :total="total"
  141. :page.sync="queryParams.pageNum"
  142. :limit.sync="queryParams.pageSize"
  143. @pagination="getList"
  144. />
  145. </div>
  146. <!-- 添加或修改兽医个人信息对话框 -->
  147. <el-dialog :title="title" :visible.sync="open" width="80%" append-to-body>
  148. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  149. <el-form-item label="真实姓名" prop="realName">
  150. <el-input v-model="form.realName" placeholder="请输入真实姓名" />
  151. </el-form-item>
  152. <el-form-item label="性别" prop="gender">
  153. <el-select v-model="form.gender" placeholder="请选择性别" clearable>
  154. <el-option label="男" value="男" />
  155. <el-option label="女" value="女" />
  156. </el-select>
  157. </el-form-item>
  158. <el-form-item label="出生日期" prop="birthday">
  159. <el-date-picker clearable
  160. v-model="form.birthday"
  161. type="date"
  162. value-format="yyyy-MM-dd"
  163. placeholder="请选择出生日期">
  164. </el-date-picker>
  165. </el-form-item>
  166. <el-form-item label="职称" prop="title">
  167. <el-input v-model="form.title" placeholder="请输入职称" />
  168. </el-form-item>
  169. <el-form-item label="手机号" prop="phone">
  170. <el-input v-model="form.phone" placeholder="请输入手机号" />
  171. </el-form-item>
  172. <el-form-item label="电子邮箱" prop="email">
  173. <el-input v-model="form.email" placeholder="请输入电子邮箱" />
  174. </el-form-item>
  175. <el-form-item label="专家类型" prop="expertType">
  176. <el-select v-model="form.expertType" placeholder="请选择专家类型" clearable>
  177. <el-option v-for="dict in dict.type.expert_type" :key="dict.value" :label="dict.label" :value="dict.value"/>
  178. </el-select>
  179. </el-form-item>
  180. <el-form-item label="身份证号" prop="idCard">
  181. <el-input v-model="form.idCard" placeholder="请输入身份证号" />
  182. </el-form-item>
  183. <el-form-item label="擅长领域" prop="specialty">
  184. <el-input v-model="form.specialty" placeholder="请输入内容" />
  185. </el-form-item>
  186. <el-form-item label="工作经验" prop="workExperience">
  187. <el-input v-model="form.workExperience" placeholder="请输入工作经验" />
  188. </el-form-item>
  189. <el-form-item label="所属医院" prop="hospital">
  190. <el-input v-model="form.hospital" placeholder="请输入所属医院" />
  191. </el-form-item>
  192. <el-form-item label="联系地址" prop="address">
  193. <el-input v-model="form.address" placeholder="请输入联系地址" />
  194. </el-form-item>
  195. <el-form-item label="个人简介" prop="introduction">
  196. <el-input v-model="form.introduction" type="textarea" placeholder="请输入内容" />
  197. </el-form-item>
  198. </el-form>
  199. <div slot="footer" class="dialog-footer">
  200. <el-button type="primary" @click="submitForm"> </el-button>
  201. <el-button @click="cancel"> </el-button>
  202. </div>
  203. </el-dialog>
  204. <!-- 详情对话框 -->
  205. <el-dialog :title="detailTitle" :visible.sync="detailVisible" width="80%" append-to-body>
  206. <div v-if="detailData" style="padding: 20px;">
  207. <!-- 显示兽医基本信息 -->
  208. <el-descriptions title="兽医基本信息" :column="2" border>
  209. <el-descriptions-item label="真实姓名">{{ detailData.realName || '-' }}</el-descriptions-item>
  210. <el-descriptions-item label="性别">{{ detailData.gender || '-' }}</el-descriptions-item>
  211. <el-descriptions-item label="出生日期">{{ detailData.birthday || '-' }}</el-descriptions-item>
  212. <el-descriptions-item label="身份证号">{{ detailData.idCard || '-' }}</el-descriptions-item>
  213. <el-descriptions-item label="擅长领域">{{ detailData.specialty || '-' }}</el-descriptions-item>
  214. <el-descriptions-item label="工作经验">{{ detailData.workExperience ? detailData.workExperience + '年' : '-' }}</el-descriptions-item>
  215. <el-descriptions-item label="职称">{{ detailData.title || '-' }}</el-descriptions-item>
  216. <el-descriptions-item label="联系电话">{{ detailData.phone || '-' }}</el-descriptions-item>
  217. <el-descriptions-item label="电子邮箱">{{ detailData.email || '-' }}</el-descriptions-item>
  218. <el-descriptions-item label="专家类型">
  219. <dict-tag :options="dict.type.expert_type" :value="detailData.expertType"/>
  220. </el-descriptions-item>
  221. <el-descriptions-item label="所属医院">{{ detailData.hospital || '-' }}</el-descriptions-item>
  222. <el-descriptions-item label="联系地址" :span="2">{{ detailData.address || '-' }}</el-descriptions-item>
  223. <el-descriptions-item label="个人简介" :span="2">{{ detailData.introduction || '-' }}</el-descriptions-item>
  224. </el-descriptions>
  225. <!-- 显示资质证书信息 -->
  226. <div style="margin-top: 30px;">
  227. <h3 style="margin-bottom: 15px;color: #303133;font-weight: bold;">资质证书信息</h3>
  228. <el-alert
  229. v-if="!certificateList || certificateList.length === 0"
  230. title="暂无资质证书"
  231. type="info"
  232. :closable="false"
  233. style="margin-bottom: 20px;"
  234. />
  235. <el-table v-else :data="certificateList" border style="width: 100%">
  236. <!-- <el-table-column prop="qualificationName" label="资质名称" align="center" width="180"></el-table-column>-->
  237. <el-table-column prop="certName" label="证书名称" align="center" width="180"></el-table-column>
  238. <el-table-column prop="certificateNo" label="证书编号" align="center" width="200"></el-table-column>
  239. <el-table-column prop="issueDate" label="颁发日期" align="center" width="120">
  240. <template slot-scope="scope">
  241. <span>{{ parseTime(scope.row.issueDate, '{y}-{m}-{d}') }}</span>
  242. </template>
  243. </el-table-column>
  244. <el-table-column prop="expireDate" label="到期日期" align="center" width="120">
  245. <template slot-scope="scope">
  246. <span>{{ parseTime(scope.row.expireDate, '{y}-{m}-{d}') }}</span>
  247. </template>
  248. </el-table-column>
  249. <el-table-column prop="auditStatus" label="审核状态" align="center" width="100">
  250. <template slot-scope="scope">
  251. <el-tag :type="getAuditStatusTagType(scope.row.auditStatus)">
  252. {{ getAuditStatusText(scope.row.auditStatus) }}
  253. </el-tag>
  254. </template>
  255. </el-table-column>
  256. <el-table-column prop="certStatus" label="证书状态" align="center" width="100">
  257. <template slot-scope="scope">
  258. <el-tag :type="getCertStatusTagType(scope.row.certStatus)">
  259. {{ getCertStatusText(scope.row.certStatus) }}
  260. </el-tag>
  261. </template>
  262. </el-table-column>
  263. </el-table>
  264. </div>
  265. </div>
  266. <div slot="footer" class="dialog-footer">
  267. <el-button @click="closeDetail"> </el-button>
  268. </div>
  269. </el-dialog>
  270. </div>
  271. </template>
  272. <script>
  273. import { listInfo, getInfo, getfull, delInfo, addInfo, updateInfo } from "@/api/vet/info"
  274. export default {
  275. name: "Info",
  276. dicts: ['expert_type'],
  277. data() {
  278. return {
  279. // 遮罩层
  280. loading: true,
  281. // 选中数组
  282. ids: [],
  283. // 非单个禁用
  284. single: true,
  285. // 非多个禁用
  286. multiple: true,
  287. // 显示搜索条件
  288. showSearch: true,
  289. // 总条数
  290. total: 0,
  291. // 兽医个人信息表格数据
  292. infoList: [],
  293. // 资质证书列表
  294. certificateList: [],
  295. // 弹出层标题
  296. title: "",
  297. // 详情弹出层标题
  298. detailTitle: "",
  299. // 是否显示新增/修改弹出层
  300. open: false,
  301. // 是否显示详情弹出层
  302. detailVisible: false,
  303. // 详情数据
  304. detailData: null,
  305. // 查询参数
  306. queryParams: {
  307. pageNum: 1,
  308. pageSize: 10,
  309. userId: null,
  310. realName: null,
  311. gender: null,
  312. birthday: null,
  313. idCard: null,
  314. specialty: null,
  315. workExperience: null,
  316. hospital: null,
  317. address: null,
  318. introduction: null,
  319. },
  320. // 表单参数
  321. form: {},
  322. // 表单校验
  323. rules: {
  324. realName: [
  325. { required: true, message: "真实姓名不能为空", trigger: "blur" }
  326. ],
  327. gender: [
  328. { required: true, message: "性别不能为空", trigger: "change" }
  329. ],
  330. idCard: [
  331. { required: true, message: "身份证号不能为空", trigger: "blur" }
  332. ]
  333. }
  334. }
  335. },
  336. created() {
  337. this.getList()
  338. },
  339. mounted() {
  340. // 显示完善信息的提示
  341. if (this.$route.query.needCompleteInfo === 'true') {
  342. this.$message.warning('请完善您的个人信息');
  343. this.$router.replace({
  344. ...this.$route,
  345. query: {}
  346. });
  347. }
  348. },
  349. methods: {
  350. /** 查询兽医个人信息列表 */
  351. getList() {
  352. this.loading = true
  353. listInfo(this.queryParams).then(response => {
  354. this.infoList = response.rows
  355. this.total = response.total
  356. this.loading = false
  357. })
  358. },
  359. // 取消按钮
  360. cancel() {
  361. this.open = false
  362. this.reset()
  363. },
  364. // 关闭详情对话框
  365. closeDetail() {
  366. this.detailVisible = false
  367. this.detailData = null
  368. this.certificateList = []
  369. },
  370. // 表单重置
  371. reset() {
  372. this.form = {
  373. id: null,
  374. userId: null,
  375. realName: null,
  376. gender: null,
  377. birthday: null,
  378. idCard: null,
  379. specialty: null,
  380. workExperience: null,
  381. hospital: null,
  382. address: null,
  383. introduction: null,
  384. title: null,
  385. phone: null,
  386. email: null,
  387. expertType: null,
  388. createBy: null,
  389. createTime: null,
  390. updateBy: null,
  391. updateTime: null
  392. }
  393. this.resetForm("form")
  394. },
  395. /** 搜索按钮操作 */
  396. handleQuery() {
  397. this.queryParams.pageNum = 1
  398. this.getList()
  399. },
  400. /** 重置按钮操作 */
  401. resetQuery() {
  402. this.resetForm("queryForm")
  403. this.handleQuery()
  404. },
  405. // 多选框选中数据
  406. handleSelectionChange(selection) {
  407. this.ids = selection.map(item => item.id)
  408. this.single = selection.length!==1
  409. this.multiple = !selection.length
  410. },
  411. /** 详情按钮操作 */
  412. handleView(row) {
  413. this.detailVisible = true
  414. this.detailTitle = "兽医详情信息"
  415. const id = row.id || this.ids
  416. getfull(id).then(response => {
  417. if (response.code === 200) {
  418. const data = response.data
  419. console.log('详情返回数据:', data)
  420. if (data.vetInfo) {
  421. this.detailData = data.vetInfo
  422. this.certificateList = data.qualifications || []
  423. } else if (data.personalInfo) {
  424. this.detailData = data.personalInfo
  425. this.certificateList = data.certificates || data.qualifications || []
  426. } else {
  427. this.detailData = data
  428. this.certificateList = data.qualifications || []
  429. }
  430. if (this.certificateList.length === 0) {
  431. console.log('没有证书数据')
  432. }
  433. } else {
  434. this.$message.error(response.msg || '获取详情失败')
  435. }
  436. }).catch(error => {
  437. console.error('获取详情失败:', error)
  438. this.$message.error('获取详情失败')
  439. })
  440. },
  441. /** 新增按钮操作 */
  442. handleAdd() {
  443. this.reset()
  444. this.open = true
  445. this.title = "添加兽医个人信息"
  446. },
  447. /** 修改按钮操作 */
  448. handleUpdate(row) {
  449. this.reset()
  450. const id = row.id || this.ids
  451. getInfo(id).then(response => {
  452. this.form = response.data
  453. this.open = true
  454. this.title = "修改兽医个人信息"
  455. })
  456. },
  457. /** 提交按钮 */
  458. submitForm() {
  459. this.$refs["form"].validate(valid => {
  460. if (valid) {
  461. if (this.form.id != null) {
  462. updateInfo(this.form).then(response => {
  463. this.$modal.msgSuccess("修改成功")
  464. this.open = false
  465. this.getList()
  466. })
  467. } else {
  468. addInfo(this.form).then(response => {
  469. this.$modal.msgSuccess("新增成功")
  470. this.open = false
  471. this.getList()
  472. })
  473. }
  474. }
  475. })
  476. },
  477. /** 删除按钮操作 */
  478. handleDelete(row) {
  479. const ids = row.id || this.ids
  480. this.$modal.confirm('是否确认删除兽医个人信息编号为"' + ids + '"的数据项?').then(function() {
  481. return delInfo(ids)
  482. }).then(() => {
  483. this.getList()
  484. this.$modal.msgSuccess("删除成功")
  485. }).catch(() => {})
  486. },
  487. // 获取审核状态文本
  488. getAuditStatusText(status) {
  489. const statusMap = {
  490. '0': '待审核',
  491. '1': '审核通过',
  492. '2': '审核不通过'
  493. }
  494. return statusMap[status] || '未知'
  495. },
  496. // 获取审核状态标签类型
  497. getAuditStatusTagType(status) {
  498. const typeMap = {
  499. '0': 'warning',
  500. '1': 'success',
  501. '2': 'danger'
  502. }
  503. return typeMap[status] || 'info'
  504. },
  505. // 获取证书状态文本
  506. getCertStatusText(status) {
  507. const statusMap = {
  508. '0': '有效',
  509. '1': '即将过期',
  510. '2': '已过期'
  511. }
  512. return statusMap[status] || '未知'
  513. },
  514. // 获取证书状态标签类型
  515. getCertStatusTagType(status) {
  516. const typeMap = {
  517. '0': 'success',
  518. '1': 'warning',
  519. '2': 'danger'
  520. }
  521. return typeMap[status] || 'info'
  522. }
  523. }
  524. }
  525. </script>
  526. <style scoped>
  527. ::v-deep .el-descriptions-item__cell{
  528. width: 90px;
  529. }
  530. ::v-deep .pagestyle .el-input{
  531. width: auto !important;
  532. }
  533. ::v-deep .el-descriptions-row th{
  534. text-align: center !important;color: #7b7c7f;
  535. background: #faf7f7;
  536. }
  537. ::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
  538. border: 1px solid #bcbbbb;
  539. padding: 12px 10px;
  540. }
  541. </style>
  542. <style scoped lang="scss">
  543. // 操作按钮样式
  544. .info-btn {
  545. padding: 6px 10px;
  546. border-radius: 4px;
  547. margin: 0 10px;
  548. transition: all 0.3s ease;
  549. }
  550. .view-btn:hover {
  551. background-color: rgb(216, 238, 248);
  552. transform: translateY(-1px);
  553. }
  554. .alter-btn:hover{
  555. background-color: rgb(230, 255, 238);
  556. transform: translateY(-1px);
  557. }
  558. .delete-btn:hover {
  559. background-color: rgba(245, 108, 108, 0.1);
  560. transform: translateY(-1px);
  561. }
  562. // 新增/修改的弹窗
  563. ::v-deep .el-dialog {
  564. border-radius: 12px;
  565. overflow: hidden;
  566. box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12);
  567. animation: dialogFadeIn 0.3s ease;
  568. }
  569. ::v-deep .el-dialog__header {
  570. background: linear-gradient(135deg, #42b983 0%, #83df92 100%);
  571. padding: 18px 24px;
  572. border-bottom: none;
  573. position: relative;
  574. }
  575. ::v-deep .el-dialog__title {
  576. font-size: 17px;
  577. font-weight: 600;
  578. color: white;
  579. letter-spacing: 0.5px;
  580. }
  581. ::v-deep .el-dialog__headerbtn:hover .el-dialog__close {
  582. color: #ffd04b;
  583. transform: rotate(90deg);
  584. }
  585. ::v-deep .el-dialog__body {
  586. padding: 28px 24px 20px;
  587. background-color: #f8fafc;
  588. max-height: 70vh;
  589. overflow-y: auto;
  590. }
  591. ::v-deep .el-form-item {
  592. margin-bottom: 20px;
  593. transition: all 0.3s;
  594. }
  595. ::v-deep .el-form-item__label {
  596. font-weight: 500;
  597. color: #2d3748;
  598. font-size: 14px;
  599. transition: color 0.3s;
  600. }
  601. ::v-deep .el-input,
  602. ::v-deep .el-textarea,
  603. ::v-deep .el-select {
  604. width: 100%;
  605. }
  606. ::v-deep .el-input__inner,
  607. ::v-deep .el-textarea__inner {
  608. border-radius: 8px;
  609. border: 1px solid #dcdfe6;
  610. font-size: 14px;
  611. transition: all 0.3s;
  612. background-color: #fcfdfe;
  613. }
  614. ::v-deep .el-input__inner:focus,
  615. ::v-deep .el-textarea__inner:focus {
  616. border-color: #42B983;
  617. box-shadow: 0 0 0 3px rgb(230, 255, 238);
  618. background-color: white;
  619. }
  620. ::v-deep .el-select .el-input__inner {
  621. padding-right: 35px;
  622. }
  623. ::v-deep .el-dialog__footer {
  624. padding: 20px 24px;
  625. background-color: #f8fafc;
  626. border-top: 1px solid #eef2f7;
  627. border-radius: 0 0 12px 12px;
  628. }
  629. </style>