|
@@ -0,0 +1,481 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="suit-tech-agreement-detail">
|
|
|
|
|
+ <Popup
|
|
|
|
|
+ :showDialog.sync="dialogVisible"
|
|
|
|
|
+ @cancle="handleClose"
|
|
|
|
|
+ distanceTop="5vh"
|
|
|
|
|
+ :title="title"
|
|
|
|
|
+ :showBtns="false"
|
|
|
|
|
+ :loading="loading"
|
|
|
|
|
+ width="750px"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template slot="body">
|
|
|
|
|
+ <!-- 基本信息 -->
|
|
|
|
|
+ <div class="info-row">
|
|
|
|
|
+ <span class="info-label">方 名:</span>
|
|
|
|
|
+ <span class="info-value">{{ detail.name }}</span>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ class="turn-btn"
|
|
|
|
|
+ @click="handleTurn"
|
|
|
|
|
+ >转方</el-button
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="info-row">
|
|
|
|
|
+ <span class="info-label">中医病名:</span>
|
|
|
|
|
+ <span class="info-value">{{ detail.disName }}</span>
|
|
|
|
|
+ <span class="info-label ml-40">西医诊断:</span>
|
|
|
|
|
+ <span class="info-value">{{ detail.westernDiag }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="info-row">
|
|
|
|
|
+ <span class="info-label">功效适应症:</span>
|
|
|
|
|
+ <span class="info-value">{{ detail.effect }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 涵盖项目 tabs -->
|
|
|
|
|
+ <div class="section-tabs">
|
|
|
|
|
+ <span class="tabs-label">涵盖项目</span>
|
|
|
|
|
+ <div class="tabs-list">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-for="(item, index) in treatmentList"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="tab-item"
|
|
|
|
|
+ :class="{ active: activeTab === index }"
|
|
|
|
|
+ @click="activeTab = index"
|
|
|
|
|
+ >{{ item.treatItemName }}</span
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 治疗项目详情 -->
|
|
|
|
|
+ <div class="treatment-detail" v-if="currentTreatment">
|
|
|
|
|
+ <div class="detail-row">
|
|
|
|
|
+ <span class="detail-label">分 类:</span>
|
|
|
|
|
+ <span class="detail-value">{{
|
|
|
|
|
+ getClassifyLabel(currentTreatment.treatClass)
|
|
|
|
|
+ }}</span>
|
|
|
|
|
+ <span class="detail-label ml-60">项目名称:</span>
|
|
|
|
|
+ <span class="detail-value">{{
|
|
|
|
|
+ currentTreatment.treatItemName
|
|
|
|
|
+ }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-row" v-if="hasAnyDetailData()">
|
|
|
|
|
+ <span class="detail-label">明 细:</span>
|
|
|
|
|
+ <div class="detail-value detail-group">
|
|
|
|
|
+ <div class="detail-sub" v-if="hasDetailData('detailPoint')">
|
|
|
|
|
+ <span class="detail-sub-label">穴位:</span>
|
|
|
|
|
+ <span class="acupoint-list">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-for="(point, pIdx) in currentTreatment.detailPoint"
|
|
|
|
|
+ :key="'point-' + pIdx"
|
|
|
|
|
+ class="acupoint-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ point.name }} {{ point.num }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-sub" v-if="hasDetailData('detailMeridian')">
|
|
|
|
|
+ <span class="detail-sub-label">经络:</span>
|
|
|
|
|
+ <span class="acupoint-list">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-for="(item, mIdx) in currentTreatment.detailMeridian"
|
|
|
|
|
+ :key="'meridian-' + mIdx"
|
|
|
|
|
+ class="acupoint-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.name }} {{ item.num }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-sub" v-if="hasDetailData('detailEarPoint')">
|
|
|
|
|
+ <span class="detail-sub-label">耳穴:</span>
|
|
|
|
|
+ <span class="acupoint-list">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-for="(item, eIdx) in currentTreatment.detailEarPoint"
|
|
|
|
|
+ :key="'earpoint-' + eIdx"
|
|
|
|
|
+ class="acupoint-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.name }} {{ item.num }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-sub" v-if="hasDetailData('detailBodyPart')">
|
|
|
|
|
+ <span class="detail-sub-label">部位:</span>
|
|
|
|
|
+ <span class="acupoint-list">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-for="(item, bIdx) in currentTreatment.detailBodyPart"
|
|
|
|
|
+ :key="'bodypart-' + bIdx"
|
|
|
|
|
+ class="acupoint-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.name }} {{ item.num }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-sub" v-if="hasDetailData('detailOther')">
|
|
|
|
|
+ <span class="detail-sub-label">其他详情:</span>
|
|
|
|
|
+ <span class="acupoint-list">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-for="(item, oIdx) in currentTreatment.detailOther"
|
|
|
|
|
+ :key="'other-' + oIdx"
|
|
|
|
|
+ class="acupoint-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item.name }} {{ item.num }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-row">
|
|
|
|
|
+ <span class="detail-label">操作指南:</span>
|
|
|
|
|
+ <span class="detail-value">{{ currentTreatment.useExplain }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-row">
|
|
|
|
|
+ <span class="detail-label">单 次:</span>
|
|
|
|
|
+ <span class="detail-value"
|
|
|
|
|
+ >{{ currentTreatment.singleQty
|
|
|
|
|
+ }}{{
|
|
|
|
|
+ (currentTreatment.basisStitutionsnondrug &&
|
|
|
|
|
+ currentTreatment.basisStitutionsnondrug.pricingUnit) ||
|
|
|
|
|
+ ""
|
|
|
|
|
+ }}</span
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-row">
|
|
|
|
|
+ <span class="detail-label">治疗次数:</span>
|
|
|
|
|
+ <span class="detail-value">{{ currentTreatment.treatNum }}次</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="detail-row">
|
|
|
|
|
+ <span class="detail-label">频 次:</span>
|
|
|
|
|
+ <span class="detail-value">{{ currentTreatment.frequency }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 底部信息:agreement=分享医生;recommend=方解+出处 -->
|
|
|
|
|
+ <div class="share-doctor" v-if="mode === 'agreement'">
|
|
|
|
|
+ <span class="share-label">分享医生:</span>
|
|
|
|
|
+ <span class="share-value">{{ detail.createUserName }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <template v-else>
|
|
|
|
|
+ <div class="share-doctor">
|
|
|
|
|
+ <span class="share-label">方 解:</span>
|
|
|
|
|
+ <span class="share-value">{{ detail.mechanismPre }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="share-doctor">
|
|
|
|
|
+ <span class="share-label">出 处:</span>
|
|
|
|
|
+ <span class="share-value"
|
|
|
|
|
+ >{{ detail.expert }}{{ detail.expertTitle }}</span
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 底部返回按钮(右侧推荐方案详情) -->
|
|
|
|
|
+ <div class="detail-back" v-if="showBackBtn">
|
|
|
|
|
+ <el-button type="primary" @click="handleClose">返回</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Popup>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import Popup from "@/components/Propup.vue";
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: "SuitTechAgreementDetail",
|
|
|
|
|
+ components: { Popup },
|
|
|
|
|
+ props: {
|
|
|
|
|
+ show: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false,
|
|
|
|
|
+ },
|
|
|
|
|
+ detail: {
|
|
|
|
|
+ type: Object,
|
|
|
|
|
+ default: () => ({}),
|
|
|
|
|
+ },
|
|
|
|
|
+ loading: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false,
|
|
|
|
|
+ },
|
|
|
|
|
+ // 弹窗标题(左侧协定方默认「我的协定方」,右侧推荐传「方案详情」)
|
|
|
|
|
+ title: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: "我的协定方",
|
|
|
|
|
+ },
|
|
|
|
|
+ // 模式:agreement(左侧协定方,底部显示分享医生) | recommend(右侧推荐,底部显示方解/出处)
|
|
|
|
|
+ mode: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: "agreement",
|
|
|
|
|
+ },
|
|
|
|
|
+ // 是否显示底部「返回」按钮(右侧推荐需要)
|
|
|
|
|
+ showBackBtn: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ activeTab: 0,
|
|
|
|
|
+ classifyOptions: [],
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ dialogVisible: {
|
|
|
|
|
+ get() {
|
|
|
|
|
+ return this.show;
|
|
|
|
|
+ },
|
|
|
|
|
+ set(val) {
|
|
|
|
|
+ this.$emit("update:show", val);
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ treatmentList() {
|
|
|
|
|
+ return this.detail.treatmentList || [];
|
|
|
|
|
+ },
|
|
|
|
|
+ currentTreatment() {
|
|
|
|
|
+ return this.treatmentList[this.activeTab] || null;
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ mounted() {
|
|
|
|
|
+ this.loadClassifyOptions();
|
|
|
|
|
+ },
|
|
|
|
|
+ watch: {
|
|
|
|
|
+ show(val) {
|
|
|
|
|
+ if (val) {
|
|
|
|
|
+ this.activeTab = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ handleClose() {
|
|
|
|
|
+ this.$emit("update:show", false);
|
|
|
|
|
+ },
|
|
|
|
|
+ handleTurn() {
|
|
|
|
|
+ this.$emit("turn");
|
|
|
|
|
+ },
|
|
|
|
|
+ async loadClassifyOptions() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await fetch(`${window.BASE_URL}data/classify.json`);
|
|
|
|
|
+ const data = await res.json();
|
|
|
|
|
+ this.classifyOptions = data.classify || [];
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error("加载分类选项失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ getClassifyLabel(value) {
|
|
|
|
|
+ if (
|
|
|
|
|
+ (value === "" || value === null || value === undefined) &&
|
|
|
|
|
+ value !== 0
|
|
|
|
|
+ )
|
|
|
|
|
+ return "-";
|
|
|
|
|
+ const sv = String(value);
|
|
|
|
|
+ const item = this.classifyOptions.find((o) => String(o.value) === sv);
|
|
|
|
|
+ return item ? item.label : value;
|
|
|
|
|
+ },
|
|
|
|
|
+ hasDetailData(detailType) {
|
|
|
|
|
+ if (!this.currentTreatment) return false;
|
|
|
|
|
+ const detail = this.currentTreatment[detailType];
|
|
|
|
|
+ return detail && Array.isArray(detail) && detail.length > 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ hasAnyDetailData() {
|
|
|
|
|
+ if (!this.currentTreatment) return false;
|
|
|
|
|
+ return (
|
|
|
|
|
+ this.hasDetailData("detailPoint") ||
|
|
|
|
|
+ this.hasDetailData("detailMeridian") ||
|
|
|
|
|
+ this.hasDetailData("detailEarPoint") ||
|
|
|
|
|
+ this.hasDetailData("detailBodyPart") ||
|
|
|
|
|
+ this.hasDetailData("detailOther")
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+/* 仅覆盖本弹窗的容器高度,不影响其他 Popup 组件 */
|
|
|
|
|
+.suit-tech-agreement-detail ::v-deep .popup-container {
|
|
|
|
|
+ height: auto;
|
|
|
|
|
+ max-height: 80vh;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.ml-40 {
|
|
|
|
|
+ margin-left: 40px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.ml-60 {
|
|
|
|
|
+ margin-left: 60px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.info-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 14px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ line-height: 22px;
|
|
|
|
|
+
|
|
|
|
|
+ .info-label {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .info-value {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .turn-btn {
|
|
|
|
|
+ margin-left: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.section-tabs {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-top: 24px;
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+
|
|
|
|
|
+ .tabs-label {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ margin-right: 16px;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .tabs-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 0;
|
|
|
|
|
+ overflow-x: auto;
|
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
|
|
+
|
|
|
|
|
+ &::-webkit-scrollbar {
|
|
|
|
|
+ height: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .tab-item {
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ padding: 5px 14px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ color: #1684fc;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ border: 1px solid #1684fc;
|
|
|
|
|
+ border-radius: 0;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: all 0.2s;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ // 项目之间无间隙:负边距合并相邻边框,避免接缝双线
|
|
|
|
|
+ margin-left: -1px;
|
|
|
|
|
+
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-left: 0;
|
|
|
|
|
+ border-top-left-radius: 5px;
|
|
|
|
|
+ border-bottom-left-radius: 5px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ border-top-right-radius: 5px;
|
|
|
|
|
+ border-bottom-right-radius: 5px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ color: #1684fc;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 只有选中的才有背景色;置顶层覆盖相邻边框
|
|
|
|
|
+ &.active {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ background: #1684fc;
|
|
|
|
|
+ border-color: #1684fc;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.treatment-detail {
|
|
|
|
|
+ // margin-top: 16px;
|
|
|
|
|
+ padding: 20px 20px 28px;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ border: 2px solid #dedede;
|
|
|
|
|
+ // border-radius: 4px;
|
|
|
|
|
+ min-height: 420px;
|
|
|
|
|
+
|
|
|
|
|
+ .detail-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: 18px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ line-height: 22px;
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-label {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-value {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+
|
|
|
|
|
+ &.acupoint-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+
|
|
|
|
|
+ .acupoint-item {
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &.detail-group {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+
|
|
|
|
|
+ .detail-sub {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+
|
|
|
|
|
+ &:last-child {
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .detail-sub-label {
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .acupoint-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 20px;
|
|
|
|
|
+
|
|
|
|
|
+ .acupoint-item {
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.share-doctor {
|
|
|
|
|
+ margin-top: 24px;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ line-height: 22px;
|
|
|
|
|
+
|
|
|
|
|
+ .share-label {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .share-value {
|
|
|
|
|
+ color: black;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.detail-back {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ margin-top: 24px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|