| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372 |
- <template>
- <div class="local-expert-tech">
- <!-- 顶部筛选 -->
- <div class="screening">
- <div class="screening-title flex-vertical-center-l">
- <img src="~@/assets/filters.png" alt />
- </div>
- <div class="screening-form flex-vertical-center-l flex-wrap">
- <div class="screening-item flex-vertical-center-l">
- <span>方名:</span>
- <div class="input">
- <el-input size="mini" v-model="searchData.name" placeholder="请输入" clearable></el-input>
- </div>
- </div>
- <div class="screening-item flex-vertical-center-l">
- <span>涵盖项目:</span>
- <div class="input">
- <el-select size="mini" v-model="searchData.includeItem" placeholder="请搜索选择" clearable filterable :loading="projectLoading" loading-text="搜索中..." :filter-method="searchProject" @focus="searchProject('')">
- <el-option v-for="item in projectOptions" :key="item.pid" :label="item.itemName" :value="item.pid"></el-option>
- </el-select>
- </div>
- </div>
- <div class="screening-item flex-vertical-center-l">
- <span>中医病名:</span>
- <div class="input">
- <el-select size="mini" v-model="searchData.chineseDisease" placeholder="请搜索选择" clearable filterable :loading="diseaseLoading" loading-text="搜索中..." :filter-method="searchDisease" @focus="searchDisease('')">
- <el-option v-for="(item, idx) in diseaseOptions" :key="idx" :label="item.disname" :value="String(item.disid)"></el-option>
- </el-select>
- </div>
- </div>
- <div class="screening-item flex-vertical-center-l">
- <span>西医病名:</span>
- <div class="input">
- <el-select size="mini" v-model="searchData.westernDisease" placeholder="请搜索选择" clearable filterable :loading="westernDiseaseLoading" loading-text="搜索中..." :filter-method="searchWesternDisease" @focus="searchWesternDisease('')">
- <el-option v-for="(item, idx) in westernDiseaseOptions" :key="idx" :label="item.westname" :value="String(item.westcode)"></el-option>
- </el-select>
- </div>
- </div>
- <div class="screening-item flex-vertical-center-l">
- <span>专家:</span>
- <div class="input">
- <el-input size="mini" v-model="searchData.expert" placeholder="请输入" clearable></el-input>
- </div>
- </div>
- <div class="screening-btn-group">
- <el-button type="primary" size="mini" @click="search()">搜索</el-button>
- <el-button type="warning" size="mini" @click="clearFilter()">清空</el-button>
- <el-button type="primary" size="mini" @click="openEditDialog()">新增</el-button>
- </div>
- </div>
- </div>
- <!-- 底部表格数据 -->
- <div class="table">
- <div class="today-table">
- <div class="table-container">
- <el-table
- :data="tableData"
- stripe
- style="width: 100%"
- border
- height="100%"
- row-key="pid"
- :expand-row-keys="expandRows"
- @expand-change="handleExpandChange"
- v-loading="tableLoading"
- >
- <el-table-column type="expand">
- <template slot-scope="props">
- <div class="expand-table">
- <el-table :data="props.row.subList" border size="mini" style="width: 100%">
- <el-table-column prop="index" label="序号" width="60" align="center"></el-table-column>
- <el-table-column prop="treatItemName" label="项目名称" align="center"></el-table-column>
- <el-table-column label="穴位/部位/耳穴/经络" align="center">
- <template slot-scope="scope">
- {{ formatDetailList(scope.row) }}
- </template>
- </el-table-column>
- <el-table-column prop="isUpdate" label="是否可修改" width="100" align="center">
- <template slot-scope="scope">
- {{ scope.row.isUpdate === '1' ? '是' : '否' }}
- </template>
- </el-table-column>
- </el-table>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="index" label="序号" width="60" align="center"></el-table-column>
- <el-table-column prop="name" label="方名" min-width="120" align="center"></el-table-column>
- <el-table-column prop="efficacy" label="功效与适应症" min-width="180" align="center" show-overflow-tooltip></el-table-column>
- <el-table-column prop="chineseDisease" label="中医病名" width="120" align="center"></el-table-column>
- <el-table-column prop="cardType" label="证型" width="120" align="center"></el-table-column>
- <el-table-column prop="westernDisease" label="西医病名" width="120" align="center"></el-table-column>
- <el-table-column prop="expert" label="专家" width="100" align="center"></el-table-column>
- <el-table-column prop="status" label="应用" width="90" align="center">
- <template slot-scope="scope">
- <el-switch
- :value="scope.row.status === 0"
- :disabled="scope.row.createUser != currentUserId"
- active-color="#5386f6"
- inactive-color="#dcdfe6"
- @change="handleStatusChange(scope.row, $event)"
- ></el-switch>
- </template>
- </el-table-column>
- <el-table-column label="操作" width="180" align="center">
- <template slot-scope="scope">
- <div class="flex-center">
- <div class="find-detail find-fill" @click="openEditDialog(scope.row)">编辑</div>
- <div class="find-detail find-fill1" @click="handleDelete(scope.row)">删除</div>
- <div class="find-detail find-fill2" @click="handleView(scope.row)">查看</div>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div class="flex-vertical-center-r today-page">
- <el-pagination
- background
- layout=" prev, pager, next, jumper, total"
- :total="total"
- :page-size="limit"
- @current-change="sizeC($event)"
- ></el-pagination>
- </div>
- </div>
- </div>
- <!-- 新增/编辑弹窗 -->
- <popup
- distanceTop="5vh"
- fullscreen
- :showBtns="false"
- :showDialog.sync="showEditDialog"
- :loading="editLoading"
- :title="editData.pid ? '编辑本地专家适宜技术' : '新增本地专家适宜技术'"
- >
- <div slot="body" class="dialog-body-wrapper">
- <div class="dialog-back-btn" @click="handleEditBack">返回</div>
- <div class="dialog-scroll-area">
- <div class="dialog-form flex-wrap">
- <div class="form-item flex flex-col-center">
- <div class="name"><span style="color: red">*</span> 方名:</div>
- <div class="input">
- <el-input size="mini" v-model="editData.name" placeholder="请输入"></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">专家:</div>
- <div class="input">
- <el-input size="mini" v-model="editData.expert" placeholder="请输入"></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">专家名衔:</div>
- <div class="input">
- <el-select size="mini" v-model="editData.expertTitle" placeholder="请选择" clearable>
- <el-option
- :label="item.value"
- :value="item.value"
- v-for="(item,index) in titlesList"
- :key="index"
- ></el-option>
- </el-select>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">功效与适应症:</div>
- <div class="input">
- <el-input size="mini" v-model="editData.efficacy" placeholder="请输入"></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">中医病名:</div>
- <div class="input">
- <el-popover placement="bottom" width="180" trigger="focus" :close-delay="100">
- <el-input
- :class="{invalid: editData.chineseDiseaseName && (!editData.disCode)}"
- size="mini"
- slot="reference"
- :placeholder="key1?key1:'中医病名'"
- v-model="key1"
- ref="zybm"
- @input="getDiseaseList(key1)"
- @focus="handleFocus('bm')"
- @keydown.enter.native="handleEnter('bm')"
- >
- <div slot="suffix" class="suffix">
- <i class="el-icon-arrow-down" v-if="!key1"></i>
- <i class="el-icon-circle-close" v-else @click="clearBm"></i>
- </div>
- </el-input>
- <ul class="option-list">
- <li
- v-for="item in diseaseList"
- :key="item.$uid"
- :class="{ active: editData.chineseDiseaseName === item.$name }"
- @click="handleBm(item)"
- >{{ item.$name }}</li>
- </ul>
- </el-popover>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">证型:</div>
- <div class="input">
- <el-popover placement="bottom" width="180" trigger="focus" :close-delay="100">
- <el-input
- :class="{invalid: editData.symptomName && !editData.symptomCode}"
- size="mini"
- slot="reference"
- :placeholder="key2?key2:'中医证型'"
- v-model="key2"
- ref="zhengxing"
- @input="getSymptomList(key2)"
- @focus="handleFocus('zx')"
- @keydown.enter.native="handleEnter('zx')"
- >
- <div slot="suffix" class="suffix">
- <i class="el-icon-arrow-down" v-if="!key2"></i>
- <i class="el-icon-circle-close" v-else @click="clearZx"></i>
- </div>
- </el-input>
- <ul class="option-list">
- <li
- v-for="item in symptomList"
- :key="item.$uid"
- :class="{ active: editData.symptomName === item.$name, matched: item.isMatched }"
- @click="handleZx(item)"
- >{{ item.$name }}</li>
- </ul>
- </el-popover>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">治法:</div>
- <div class="input">
- <el-popover placement="bottom" width="180" trigger="focus" :close-delay="100" v-model="popoverZF">
- <el-input
- :class="{invalid: editData.therapyName && !editData.therapyCode}"
- size="mini"
- slot="reference"
- :placeholder="key3?key3:'中医治法'"
- v-model="key3"
- ref="zhifa"
- @input="getTherapyList(key3)"
- @focus="handleFocus('zf')"
- @keydown.enter.native="handleEnter('zf')"
- >
- <div slot="suffix" class="suffix">
- <i class="el-icon-arrow-down" v-if="!key3"></i>
- <i class="el-icon-circle-close" v-else @click="clearZf"></i>
- </div>
- </el-input>
- <ul class="option-list">
- <li
- v-for="item in therapyList"
- :key="item.$uid"
- :class="{ active: editData.therapyName === item.$name, matched: item.isMatched }"
- @click="handleZf(item)"
- >{{ item.$name }}</li>
- </ul>
- </el-popover>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <span style="opacity:0">*</span>
- <div class="name">西医诊断:</div>
- <div class="input">
- <div class="western-disease-input-wrapper" @click="$refs.wdAutocomplete.focus()">
- <el-tag
- v-for="code in editData.westernDisease"
- :key="code"
- size="mini"
- closable
- @close="removeWesternDisease(code)"
- >{{ westernDiseaseNameMap[code] || code }}</el-tag>
- <el-autocomplete
- ref="wdAutocomplete"
- size="mini"
- v-model="westernDiseaseSearch"
- :fetch-suggestions="queryWesternDisease"
- value-key="westname"
- :placeholder="editData.westernDisease.length ? '' : '请搜索选择'"
- clearable
- :trigger-on-focus="true"
- @select="onWesternDiseaseSelect"
- >
- <template slot-scope="{ item }">
- <div :class="{ 'autocomplete-disabled': item._disabled }">
- {{ item.westname }}
- </div>
- </template>
- </el-autocomplete>
- </div>
- </div>
- </div>
- <div class="form-item flex flex-col-center" style="width: 100%">
- <span style="opacity:0">*</span>
- <div class="name">方解:</div>
- <div class="input">
- <el-input size="mini" type="textarea" v-model="editData.mechanismPre" placeholder="请输入"></el-input>
- </div>
- </div>
- </div>
- <!-- 配穴表格 -->
- <AcupointTable
- ref="acupointTable"
- v-model="editData.acupoints"
- :isEditable.sync="editData.isEditable"
- :detailTypes.sync="editData.detailTypes"
- :statistics.sync="editData.statistics"
- :showGuide="false"
- @save="onAcupointSave"
- />
- </div>
- </div>
- </popup>
- <!-- 查看详情弹窗 -->
- <popup
- distanceTop="5vh"
- fullscreen
- :showBtns="false"
- :showDialog.sync="showViewDialog"
- :loading="viewLoading"
- title="查看本地专家适宜技术"
- >
- <div slot="body" class="dialog-body-wrapper">
- <div class="dialog-back-btn" @click="showViewDialog = false">返回</div>
- <div class="dialog-scroll-area">
- <div class="dialog-form flex-wrap">
- <div class="form-item flex flex-col-center">
- <div class="name">方名:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.name" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">专家:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.expert" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">专家名衔:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.expertTitle" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">功效与适应症:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.effect" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">中医病名:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.disName" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">证型:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.synName" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">治法:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.theName" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center">
- <div class="name">西医诊断:</div>
- <div class="input">
- <el-input size="mini" v-model="viewData.westernDiag" placeholder="-" disabled></el-input>
- </div>
- </div>
- <div class="form-item flex flex-col-center" style="width: 100%">
- <div class="name">方解:</div>
- <div class="input">
- <el-input size="mini" type="textarea" v-model="viewData.mechanismPre" placeholder="-" disabled></el-input>
- </div>
- </div>
- </div>
- <SuitableTechDetail ref="techDetail" :detailData="viewData" />
- </div>
- </div>
- </popup>
- </div>
- </template>
- <script>
- import popup from "@/components/Propup.vue";
- import AcupointTable from "./components/AcupointTable.vue";
- import {
- getDiseaseListMethod,
- getSymptomListMethod,
- getTherapyListMethod,
- } from "@/request/api.illness.js";
- import {
- getDiseaseListMethod as getDiseaseListMethodApi,
- getSymptomListMethod as getSymptomListMethodApi,
- getTherapyListMethod as getTherapyListMethodApi,
- } from "@/request/api";
- import { getLocalSuitableTechList, deleteLocalSuitableTech, saveLocalSuitableTech, getLocalSuitableTechInfo, getMappedNondrugItemList, changeLocalExpertTechStatus } from "@/api/technology.js";
- import { getXDiseaseName } from "@/api/knowledge.js";
- import SuitableTechDetail from "./components/SuitableTechDetail.vue";
- export default {
- name: 'LocalExpertTech',
- components: { popup, AcupointTable, SuitableTechDetail },
- data() {
- return {
- searchData: {
- name: '',
- includeItem: '',
- chineseDisease: '',
- westernDisease: '',
- expert: ''
- },
- // 搜索区域下拉
- diseaseOptions: [],
- westernDiseaseOptions: [],
- westernDiseasePage: 1,
- westernDiseaseHasMore: true,
- projectOptions: [],
- // 弹窗内下拉(popover 方式)
- diseaseList: [],
- symptomList: [],
- therapyList: [],
- popoverZF: false,
- key1: "",
- key2: "",
- key3: "",
- westernDiseaseSearch: "",
- westernDiseaseNameMap: {},
- titlesList: [
- { key: "1", value: "国医大师" },
- { key: "2", value: "国家级名老中医" },
- { key: "3", value: "省级名老中医" },
- { key: "4", value: "名医" }
- ],
- // 下拉加载状态
- diseaseLoading: false,
- westernDiseaseLoading: false,
- projectLoading: false,
- // 表格数据
- tableData: [],
- tableLoading: false,
- expandRows: [],
- page: 1,
- limit: 10,
- total: 0,
- // 弹窗相关
- showEditDialog: false,
- editLoading: false,
- editData: {
- statistics: {},
- westernDisease: [],
- chineseDiseaseName: "",
- symptomName: "",
- therapyName: "",
- },
- // 查看详情弹窗
- showViewDialog: false,
- viewLoading: false,
- viewData: {},
- }
- },
- computed: {
- currentUserId() {
- const userInfo = this.$store.state.user.userInfo || {};
- return userInfo.pid;
- },
- },
- created() {
- this.getList()
- },
- watch: {
- key1: {
- handler(value, oldVal) {
- if (this.key1 === "") {
- this.editData.chineseDisease = ""
- this.editData.chineseDiseaseName = ""
- this.editData.disCode = ""
- }
- if (!value && oldVal) {
- this.getSymptomList()
- this.getTherapyList()
- }
- }
- },
- key2: {
- handler(value, oldVal) {
- if (this.key2 === "") {
- this.editData.symptomName = ""
- this.editData.symptomid = ""
- this.editData.symptomCode = ""
- }
- if (!value && oldVal) {
- this.getSymptomList()
- this.getTherapyList()
- }
- }
- },
- key3: {
- handler(value, oldVal) {
- if (this.key3 === "") {
- this.editData.therapyName = ""
- this.editData.therapyCode = ""
- }
- if (!value && oldVal) {
- this.getTherapyList()
- }
- }
- },
- },
- methods: {
- // ========== 搜索区域:中医病名 ==========
- async searchDisease(query) {
- this.diseaseLoading = true
- try {
- const { list } = await getDiseaseListMethod(1, 9999, { keyword: query || '' })
- this.diseaseOptions = list || []
- } catch (e) {
- console.error('搜索中医病名失败', e)
- } finally {
- this.diseaseLoading = false
- }
- },
- // ========== 弹窗:focus/enter ==========
- handleFocus(type) {
- if (type === 'bm' && this.diseaseList.length === 0) this.getDiseaseList(this.key1);
- else if (type === 'zx' && this.symptomList.length === 0) this.getSymptomList(this.key2);
- else if (type === 'zf' && this.therapyList.length === 0) this.getTherapyList(this.key3);
- },
- handleEnter(type) {
- if (type === 'bm' && this.diseaseList.length) this.handleBm(this.diseaseList[0]);
- else if (type === 'zx' && this.symptomList.length) this.handleZx(this.symptomList[0]);
- else if (type === 'zf' && this.therapyList.length) this.handleZf(this.therapyList[0]);
- },
- // ========== 弹窗:中医病名(popover) ==========
- async getDiseaseList(keyword = '') {
- const { total, list } = await getDiseaseListMethodApi(1, 9999, { keyword }).catch(() => ({ total: 0, list: [] }));
- this.diseaseList = list;
- },
- async handleBm(item) {
- this.editData.chineseDisease = String(item.disid);
- this.editData.chineseDiseaseName = item.$name;
- this.editData.disCode = item.$code;
- this.key1 = item.$name;
- this.$refs.zybm.blur();
- this.clearZx();
- if (!this.key1) return;
- this.$refs.zhengxing && this.$refs.zhengxing.focus();
- await this.getSymptomList();
- },
- clearBm() {
- this.editData.chineseDisease = "";
- this.editData.chineseDiseaseName = "";
- this.editData.disCode = "";
- this.key1 = "";
- this.clearZx();
- },
- // ========== 弹窗:证型(popover) ==========
- async getSymptomList(keyword = '') {
- const { total, list } = await getSymptomListMethodApi(1, 9999, {
- keyword,
- disid: this.editData.chineseDisease,
- disCode: this.editData.disCode,
- }).catch(() => ({ total: 0, list: [] }));
- this.symptomList = list;
- },
- async handleZx(item) {
- this.editData.symptomName = item.$name;
- this.editData.symptomid = item.$code;
- this.editData.symptomCode = item.$code;
- this.key2 = item.$name;
- this.$refs.zhengxing.blur();
- this.clearZf();
- this.$refs.zhifa && this.$refs.zhifa.focus();
- await this.getTherapyList();
- },
- clearZx() {
- this.editData.symptomName = "";
- this.editData.symptomid = "";
- this.editData.symptomCode = "";
- this.key2 = "";
- this.clearZf();
- },
- // ========== 弹窗:治法(popover) ==========
- async getTherapyList(keyword = '') {
- const { total, list } = await getTherapyListMethodApi(1, 9999, {
- keyword,
- disCode: this.editData.disCode,
- symptomCode: this.editData.symptomid,
- symid: this.editData.symptomid,
- }).catch(() => ({ total: 0, list: [] }));
- this.therapyList = list;
- },
- handleZf(item) {
- this.editData.therapyName = item.$name;
- this.editData.therapyCode = item.$code;
- this.key3 = item.$name;
- this.$nextTick(() => {
- this.$refs.zhifa && this.$refs.zhifa.blur();
- this.popoverZF = false;
- });
- },
- clearZf() {
- this.editData.therapyName = "";
- this.editData.therapyCode = "";
- this.key3 = "";
- },
- // ========== 西医诊断搜索(搜索区域 + 弹窗共用) ==========
- async searchWesternDisease(query) {
- this.westernDiseasePage = 1
- this.westernDiseaseHasMore = true
- this._wdQuery = query || ''
- this.westernDiseaseLoading = true
- try {
- const pinyin = /^[A-Za-z]+$/g
- const serchtype = query && pinyin.test(query) ? '1' : ''
- const res = await getXDiseaseName({
- pageid: 1,
- pagesize: 200,
- keyword: query || '',
- serchtype,
- })
- if (res.code == 0) {
- const list = res.data?.wests || []
- // 保留已选中但不在搜索结果中的选项
- const selectedCodes = Array.isArray(this.editData.westernDisease)
- ? this.editData.westernDisease
- : []
- const resultCodes = new Set(list.map(i => i.westcode))
- const preserved = selectedCodes
- .filter(code => !resultCodes.has(code))
- .map(code => ({
- westcode: code,
- westname: this.westernDiseaseNameMap[code] || code,
- }))
- this.westernDiseaseOptions = [...preserved, ...list]
- this.westernDiseaseHasMore = list.length >= 200
- list.forEach((item) => {
- if (item.westcode && item.westname) {
- this.westernDiseaseNameMap[item.westcode] = item.westname
- }
- })
- }
- } catch (e) {
- console.error('搜索西医诊断失败', e)
- } finally {
- this.westernDiseaseLoading = false
- }
- },
- // 弹窗:西医诊断 autocomplete 回调
- async queryWesternDisease(queryString, cb) {
- await this.searchWesternDisease(queryString)
- if (this.westernDiseaseOptions.length > 0) {
- cb(this.westernDiseaseOptions)
- } else {
- cb([{ westname: "暂无数据", _disabled: true }])
- }
- },
- onWesternDiseaseSelect(item) {
- if (item._disabled) {
- this.$nextTick(() => {
- this.westernDiseaseSearch = ""
- })
- return
- }
- const code = String(item.westcode)
- if (!this.editData.westernDisease.includes(code)) {
- this.editData.westernDisease.push(code)
- this.westernDiseaseNameMap[code] = item.westname
- this.updateWesternDiseaseName()
- }
- this.westernDiseaseSearch = ""
- this.$nextTick(() => {
- this.searchWesternDisease("")
- })
- },
- removeWesternDisease(code) {
- this.editData.westernDisease = this.editData.westernDisease.filter((c) => c !== code)
- this.updateWesternDiseaseName()
- },
- updateWesternDiseaseName() {
- const names = this.editData.westernDisease
- .map((code) => this.westernDiseaseNameMap[code] || "")
- .filter(Boolean)
- this.editData.westernDiseaseName = names.join(",")
- },
- // 涵盖项目远程模糊搜索
- async searchProject(query) {
- this.projectLoading = true
- try {
- const res = await getMappedNondrugItemList({
- pageNum: 1,
- pageSize: 100,
- itemName: query || undefined,
- })
- if (res.ResultCode === 0) {
- this.projectOptions = res.Data?.Items || res.Data || []
- }
- } catch (e) {
- console.error('搜索涵盖项目失败', e)
- } finally {
- this.projectLoading = false
- }
- },
- search() {
- this.page = 1
- this.getList()
- },
- clearFilter() {
- this.searchData = {
- name: '',
- includeItem: '',
- chineseDisease: '',
- westernDisease: '',
- expert: ''
- }
- this.getList()
- },
- sizeC(e) {
- this.page = e
- this.getList()
- },
- handleExpandChange(row, expandedRows) {
- this.expandRows = expandedRows.map(item => item.pid)
- },
- async handleStatusChange(row, val) {
- const status = val ? 0 : 1;
- try {
- const res = await changeLocalExpertTechStatus({ pid: row.pid, status });
- if (res.ResultCode === 0) {
- this.$message.success(status === 0 ? '已启用' : '已禁用');
- row.status = status;
- }
- } catch (e) {
- this.$message.error('操作失败');
- }
- },
- formatDetailList(row) {
- const parts = []
- const extractNames = (arr) => {
- if (!Array.isArray(arr) || !arr.length) return ''
- return arr.map(item => item.name || '').filter(Boolean).join('、')
- }
- const pointNames = extractNames(row.detailPoint)
- if (pointNames) parts.push('穴位: ' + pointNames)
- const meridianNames = extractNames(row.detailMeridian)
- if (meridianNames) parts.push('经络: ' + meridianNames)
- const earNames = extractNames(row.detailEarPoint)
- if (earNames) parts.push('耳穴: ' + earNames)
- const bodyNames = extractNames(row.detailBodyPart)
- if (bodyNames) parts.push('部位: ' + bodyNames)
- const otherNames = extractNames(row.detailOther)
- if (otherNames) parts.push('其他: ' + otherNames)
- return parts.join(';') || '-'
- },
- handleEditBack() {
- if (!this.editData.pid) {
- this.$confirm("协定方未保存,返回则会清空当前编辑内容", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- this.showEditDialog = false;
- })
- .catch(() => {});
- } else {
- this.showEditDialog = false;
- }
- },
- async openEditDialog(row) {
- if (row) {
- this.editLoading = true
- let detail = row
- try {
- const res = await getLocalSuitableTechInfo(row.pid)
- if (res.ResultCode === 0) {
- detail = res.Data || row
- }
- } catch (e) {
- console.error('获取详情失败', e)
- } finally {
- this.editLoading = false
- }
- // 初始化搜索关键字,用于回显
- this.key1 = detail.disName || ""
- this.key2 = detail.synName || ""
- this.key3 = detail.theName || ""
- // 加载下拉列表数据
- if (this.key1) this.getDiseaseList(this.key1)
- if (this.key2) this.getSymptomList(this.key2)
- if (this.key3) this.getTherapyList(this.key3)
- if (detail.westernCode) {
- const codes = String(detail.westernCode).split(",")
- const names = detail.westernDiag
- ? String(detail.westernDiag).split(",")
- : []
- this.westernDiseaseOptions = codes.map((code, idx) => ({
- westcode: code.trim(),
- westname: (names[idx] || "").trim() || code.trim(),
- }))
- } else {
- this.westernDiseaseOptions = []
- }
- // 同步到名称映射
- this.westernDiseaseNameMap = {}
- this.westernDiseaseOptions.forEach((item) => {
- if (item.westcode && item.westname) {
- this.westernDiseaseNameMap[item.westcode] = item.westname
- }
- })
- this.editData = {
- ...detail,
- efficacy: detail.effect || '',
- chineseDisease: detail.disId != null ? String(detail.disId) : '',
- chineseDiseaseName: detail.disName || '',
- disCode: detail.disCode || '',
- symptomid: detail.synCode != null ? String(detail.synCode) : '',
- symptomName: detail.synName || '',
- symptomCode: detail.synCode || '',
- therapyCode: detail.theCode != null ? String(detail.theCode) : '',
- therapyName: detail.theName || '',
- westernDisease: detail.westernCode
- ? String(detail.westernCode).split(',').map(s => s.trim())
- : [],
- westernDiseaseName: detail.westernDiag || '',
- acupoints: detail.acupoints || [],
- detailTypes: detail.detailTypes || ['穴位'],
- statistics: detail.statistics || {},
- }
- this.showEditDialog = true
- // 弹窗显示后回填 treatmentList 到 AcupointTable
- this.$nextTick(() => {
- if (this.$refs.acupointTable && detail.treatmentList) {
- this.$refs.acupointTable.loadFromServerData(detail.treatmentList)
- }
- })
- } else {
- this.editData = {
- name: '',
- treater: '',
- expert: '',
- expertTitle: '',
- efficacy: '',
- chineseDisease: '',
- chineseDiseaseName: '',
- disCode: '',
- symptomid: '',
- symptomName: '',
- symptomCode: '',
- therapyCode: '',
- therapyName: '',
- westernDisease: [],
- westernDiseaseName: '',
- mechanismPre: '',
- isEditable: '1',
- detailTypes: ['穴位'],
- acupoints: [],
- statistics: {},
- }
- this.key1 = ""
- this.key2 = ""
- this.key3 = ""
- this.diseaseList = []
- this.symptomList = []
- this.therapyList = []
- this.showEditDialog = true
- }
- },
- async submitEditData() {
- // 保存
- this.$refs.acupointTable.handleSave()
- },
- async onAcupointSave(treatmentList, institutionInfo) {
- // 从下拉选项中查找选中项的名称
- const selectedDisease = this.diseaseList.find(
- (o) => String(o.disid) === this.editData.chineseDisease,
- )
- const selectedSymptom = this.symptomList.find(
- (o) => o.$code === this.editData.symptomid,
- )
- const selectedTherapy = this.therapyList.find(
- (o) => o.$code === this.editData.therapyCode,
- )
- const params = {
- name: this.editData.name,
- // 本地专家特有字段
- treater: this.editData.treater || '',
- expert: this.editData.expert || '',
- expertTitle: this.editData.expertTitle || '',
- mechanismPre: this.editData.mechanismPre || '',
- // 基本信息
- effect: this.editData.efficacy || '',
- // 疾病信息
- disId: this.editData.chineseDisease || undefined,
- disName: selectedDisease
- ? selectedDisease.$name
- : this.editData.chineseDiseaseName || '',
- disCode: this.editData.disCode || '',
- // 证型信息
- synName: selectedSymptom
- ? selectedSymptom.$name
- : this.editData.symptomName || '',
- synCode: this.editData.symptomid || '',
- // 治法信息
- theCode: this.editData.therapyCode || '',
- theName: selectedTherapy
- ? selectedTherapy.$name
- : this.editData.therapyName || '',
- // 西医诊断
- westernCode: Array.isArray(this.editData.westernDisease)
- ? this.editData.westernDisease.join(',')
- : (this.editData.westernDisease || ''),
- westernDiag: this.editData.westernDiseaseName || '',
- // 总金额
- totalAmount: parseFloat(this.editData.statistics?.totalPrice) || 0,
- // 机构信息
- ygtid: institutionInfo?.ygtid || this.editData.ygtid || '',
- departmentId: institutionInfo?.departmentId || this.editData.departmentId || '',
- stitutionsId: institutionInfo?.stitutionsId || this.editData.stitutionsId || '',
- stitutionsName: institutionInfo?.stitutionsName || this.editData.stitutionsName || '',
- // 治疗明细项列表
- treatmentList,
- }
- if (this.editData.pid) {
- params.pid = this.editData.pid
- }
- try {
- const res = await saveLocalSuitableTech(params)
- if (res.ResultCode === 0) {
- this.$message.success(this.editData.pid ? '编辑成功' : '新增成功')
- this.showEditDialog = false
- this.getList()
- }
- } catch (e) {
- console.error('保存失败', e)
- } finally {
- if (this.$refs.acupointTable) {
- this.$refs.acupointTable.saveDone()
- }
- }
- },
- handleDelete(row) {
- this.$confirm('确认删除该条记录?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(async () => {
- try {
- const res = await deleteLocalSuitableTech({ pid: row.pid })
- if (res.ResultCode === 0) {
- this.$message.success('删除成功')
- this.getList()
- } else {
- this.$message.error(res.ResultInfo || '删除失败')
- }
- } catch (e) {
- console.error('删除失败', e)
- this.$message.error('删除失败')
- }
- }).catch(() => {})
- },
- async handleView(row) {
- this.viewLoading = true
- this.showViewDialog = true
- this.viewData = {}
- try {
- const res = await getLocalSuitableTechInfo(row.pid)
- if (res.ResultCode === 0) {
- this.viewData = res.Data || {}
- }
- } catch (e) {
- console.error('获取详情失败', e)
- } finally {
- this.viewLoading = false
- }
- },
- async getList() {
- this.tableLoading = true
- try {
- const params = {
- pageNum: this.page,
- pageSize: this.limit,
- name: this.searchData.name || undefined,
- coverageContent: this.searchData.includeItem || undefined,
- disId: this.searchData.chineseDisease || undefined,
- disName: this.searchData.chineseDisease
- ? (this.diseaseOptions.find(o => String(o.disid) === this.searchData.chineseDisease)?.disname || undefined)
- : undefined,
- expert: this.searchData.expert || undefined,
- westernCode: this.searchData.westernDisease || undefined,
- westernDiag: this.searchData.westernDisease
- ? (this.westernDiseaseOptions.find(o => String(o.westcode) === this.searchData.westernDisease)?.westname || undefined)
- : undefined,
- }
- const res = await getLocalSuitableTechList(params)
- if (res.ResultCode === 0) {
- const list = res.Data?.Items || []
- this.total = res.Data?.totalRecordCount || 0
- this.tableData = list.map((item, index) => ({
- ...item,
- index: (this.page - 1) * this.limit + index + 1,
- efficacy: item.effect || '',
- chineseDisease: item.disName || '',
- cardType: item.synName || '',
- westernDisease: item.westernDiag || '',
- expert: item.expert || '',
- subList: (item.treatmentList || []).map((sub, sIdx) => ({
- ...sub,
- index: sIdx + 1,
- })),
- }))
- }
- } catch (e) {
- console.error('获取列表失败', e)
- } finally {
- this.tableLoading = false
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- @import "../../style/common.scss";
- @import "../../style/base.scss";
- .local-expert-tech {
- width: 100%;
- height: 100%;
- }
- .local-expert-tech ::v-deep .popup-container {
- display: flex;
- flex-direction: column;
- overflow: hidden !important;
- height: calc(100vh - 60px) !important;
- }
- .dialog-body-wrapper {
- display: flex;
- flex-direction: column;
- height: 100%;
- }
- .dialog-back-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 14px;
- color: #333;
- background: #fff;
- border: 1px solid #ccc;
- border-radius: 4px;
- padding: 4px 16px;
- cursor: pointer;
- margin-bottom: 10px;
- width: fit-content;
- &:hover {
- opacity: 0.8;
- }
- }
- .dialog-form {
- display: flex;
- flex-wrap: wrap;
- flex-shrink: 0;
- .form-item {
- width: 25%;
- box-sizing: border-box;
- padding: 0 10px;
- margin-bottom: 10px;
- .name {
- width: 110px;
- min-width: 110px;
- font-size: 14px;
- white-space: nowrap;
- text-align: right;
- margin-right: 5px;
- }
- .input {
- flex: 1;
- min-width: 0;
- .el-input,
- .el-select,
- .el-autocomplete {
- width: 100%;
- }
- .el-popover__reference-wrapper {
- display: block !important;
- width: 100%;
- .el-input {
- width: 100%;
- }
- }
- }
- }
- }
- .dialog-scroll-area {
- flex: 1;
- min-height: 0;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- }
- .autocomplete-disabled {
- color: #999 !important;
- cursor: not-allowed !important;
- pointer-events: none;
- }
- .el-input.invalid::v-deep {
- input {
- color: #ff0000;
- }
- }
- .option-list {
- margin: -12px -12px;
- max-height: 300px;
- overflow: auto;
- .active {
- color: #5386f6;
- }
- li {
- padding: 8px 12px;
- list-style: none;
- font-size: 14px;
- box-sizing: border-box;
- width: 100%;
- color: #606266;
- font-weight: 500;
- cursor: pointer;
- }
- li:hover {
- background: #f5f7fa;
- }
- }
- .suffix {
- height: 100%;
- padding-right: 5px;
- display: flex;
- align-items: center;
- i {
- cursor: pointer;
- color: #c0c4cc;
- }
- i:hover {
- color: #909399;
- }
- }
- .western-disease-input-wrapper {
- border: 1px solid #dcdfe6;
- border-radius: 4px;
- padding: 2px 4px;
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- min-height: 28px;
- cursor: text;
- .el-tag {
- margin: 2px 4px 2px 0;
- max-width: 200px;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .el-autocomplete {
- flex: 1;
- min-width: 80px;
- }
- ::v-deep .el-input__inner {
- border: none !important;
- padding: 0 4px;
- height: 24px;
- line-height: 24px;
- background: transparent;
- }
- ::v-deep .el-input__suffix {
- display: flex;
- align-items: center;
- }
- &:hover {
- border-color: #c0c4cc;
- }
- &:focus-within {
- border-color: #409eff;
- }
- }
- .dialog-scroll-area ::v-deep .recipe-acupoint-wrapper {
- flex: 1;
- display: flex;
- flex-direction: column;
- min-height: 0;
- }
- .dialog-scroll-area ::v-deep .recipe-acupoint {
- flex: 1;
- min-height: 0;
- }
- .screening-btn-group {
- display: flex;
- align-items: center;
- margin: 5px 0;
- }
- .expand-table {
- padding: 10px 20px;
- }
- .table {
- padding: 10px 10px;
- background: #ffffff;
- border-radius: 5px;
- margin-top: 10px;
- height: 70vh;
- .table-container {
- height: 90%;
- }
- .today-table {
- height: 100%;
- .find-detail {
- width: 60px;
- height: 24px;
- border: 1px solid #ffae45;
- border-radius: 2px;
- text-align: center;
- color: #fff;
- font-size: 14px;
- cursor: pointer;
- margin: 0 2px;
- background: #ffae45;
- }
- .find-fill {
- background: #5386f6 !important;
- color: #fff !important;
- border: 1px solid #5386f6;
- }
- .find-fill1 {
- background: #ff6245;
- color: #fff !important;
- border: 1px solid #ff6245;
- }
- .find-fill2 {
- background: #68a8ff !important;
- color: #fff !important;
- border: 1px solid #68a8ff;
- }
- }
- }
- </style>
- <style lang="scss" scoped>
- @media screen and (min-width: 1681px) and (max-width: 1920px) {
- .table {
- height: 81vh;
- .table-container {
- height: 94%;
- }
- }
- .today-table::v-deep .el-table td {
- padding: 18px 0;
- }
- .today-table::v-deep .el-table th {
- padding: 18px 0;
- }
- }
- @media screen and (min-width: 1601px) and (max-width: 1680px) {
- .table {
- height: 80vh;
- .table-container {
- height: 94%;
- }
- }
- .today-table::v-deep .el-table td {
- padding: 18px 0;
- }
- .today-table::v-deep .el-table th {
- padding: 18px 0;
- }
- }
- @media screen and (min-width: 1361px) and (max-width: 1600px) {
- .table {
- height: 72vh;
- .table-container {
- height: 90%;
- }
- }
- .today-table::v-deep .el-table td {
- padding: 5px 0;
- }
- .today-table::v-deep .el-table th {
- padding: 5px 0;
- }
- }
- @media screen and (min-width: 1281px) and (max-width: 1360px) {
- .table {
- height: 72vh;
- .table-container {
- height: 90%;
- }
- }
- .today-table::v-deep .el-table td {
- padding: 5px 0;
- }
- .today-table::v-deep .el-table th {
- padding: 5px 0;
- }
- }
- </style>
|