<template>
  <div class="recipe-acupoint-wrapper">
    <!-- 处方 tab + 按钮同一行 -->
    <div class="prescription-header flex-vertical-between">
      <div class="table-label flex-vertical-center-l">
        <div
          class="label-item flex-center"
          v-for="(item, index) in prescriptions"
          :key="index"
        >
          <el-tooltip :content="item.itemName" placement="top" :open-delay="300">
            <span
              :class="{ l_active: activeIndex === index }"
              @click="switchTab(index)"
            >{{ item.itemName }}</span>
          </el-tooltip>
          <div
            @click.stop="removePrescription(index)"
            v-show="!isPrescriptionPaid(index)"
          >X</div>
          <img
            :src="require('../../../assets/new-icon/isPay.png')"
            v-show="isPrescriptionPaid(index)"
          />
        </div>
      </div>
      <div class="top-btns">
        <el-button size="mini" type="warning" @click="openAddDialog()"
          >新增处方</el-button
        >
        <el-button size="mini" type="warning" @click="clearAll();$emit('clear')" v-if="!isLocked">清空处方</el-button>
      </div>
    </div>

    <!--新增适宜技术处方弹窗 -->
    <el-dialog
      :visible.sync="showAddDialog"
      width="800px"
      top="10vh"
      :show-close="false"
      :close-on-click-modal="false"
      append-to-body
      custom-class="add-prescription-dialog"
    >
      <div slot="title" class="add-dialog-header">
        <span>新增适宜技术处方</span>
        <div class="close-btn" @click="showAddDialog = false">+</div>
      </div>
      <div class="add-dialog-body">
        <div class="add-form-row">
          <span class="label">分类：</span>
          <el-select
            size="mini"
            v-model="addForm.category"
            placeholder="请选择"
            clearable
            style="flex: 1"
            @change="onCategoryChange"
          >
            <el-option
              v-for="item in classifyOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
          <span class="label"
            ><span style="color: red">*</span> 项目名称：</span
          >
          <el-select
            ref="itemSelect"
            size="mini"
            v-model="addForm.itemId"
            filterable
            :filter-method="searchItem"
            :loading="itemLoading"
            loading-text="搜索中..."
            no-data-text="暂无数据"
            placeholder="请搜索选择"
            style="flex: 1"
            @change="onItemSelected"
            @visible-change="onItemSelectVisibleChange"
          >
            <el-option
              v-for="item in itemOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            ></el-option>
          </el-select>
        </div>
      </div>
      <div class="add-dialog-btns">
        <div class="confirm-btn" :class="{ 'is-disabled': addLoading }" @click="confirmAdd()">确定</div>
      </div>
    </el-dialog>

    <div class="recipe-acupoint">
      <div
        class="table-toolbar flex-vertical-center-l flex-wrap"
        v-if="prescriptions.length"
      >
        <div class="toolbar-item flex-vertical-center-l" v-if="showEditable">
          <span><span style="color: red">*</span> 是否可修改：</span>
          <el-select
            size="mini"
            v-model="innerIsEditable"
            placeholder="请选择"
            style="width: 80px"
            @change="onEditableChange"
          >
            <el-option label="是" value="1"></el-option>
            <el-option label="否" value="0"></el-option>
          </el-select>
        </div>
        <div class="toolbar-item flex-vertical-center-l">
          <span
            ><span v-if="detailRequired" style="color: red">*</span>
            详情：</span
          >
          <el-checkbox-group
            v-model="innerDetailTypes"
            size="mini"
            :disabled="isLocked"
            @change="onDetailTypesChange"
          >
            <el-checkbox label="经络">经络</el-checkbox>
            <el-checkbox label="穴位">穴位</el-checkbox>
            <el-checkbox label="耳穴">耳穴</el-checkbox>
            <el-checkbox label="部位">部位</el-checkbox>
            <el-checkbox label="其他详情">其他详情</el-checkbox>
            <el-checkbox label="无详情">无详情</el-checkbox>
          </el-checkbox-group>
        </div>
      </div>

      <div class="table-container" v-if="prescriptions.length">
        <!-- 表格 -->
        <div
          v-for="detailType in activeDetailTypes"
          :key="detailType"
          class="detail-table-section"
        >
          <div class="detail-section-label" v-if="prescriptions.length">
            {{ detailType }}
          </div>
          <div class="table-show flex-vertical-between">
            <!-- 左侧表格 -->
            <div class="table-left">
              <el-table
                :data="getLeftList(detailType)"
                border
                size="mini"
                style="width: 100%"
              >
                <el-table-column
                  prop="id"
                  label="序号"
                  width="50"
                  align="center"
                ></el-table-column>
                <el-table-column :label="detailType" min-width="100">
                  <template slot-scope="scope">
                    <el-select
                      v-if="detailType !== '其他详情' && detailType !== '部位'"
                      size="mini"
                      :value="scope.row.name"
                      remote
                      filterable
                      :filter-method="getFilterMethod(detailType)"
                      placeholder="请选择"
                      :disabled="isLocked"
                      @change="onItemChange($event, scope, detailType)"
                      @focus="searchByType('', detailType)"
                    >
                      <el-option
                        v-for="(item, idx) in getSearchOptions(detailType)"
                        :key="idx"
                        :label="item.acuname"
                        :value="item.acuid"
                      ></el-option>
                    </el-select>
                    <el-input
                      v-else
                      size="mini"
                      v-model="scope.row.name"
                      placeholder="请输入"
                      :disabled="isLocked"
                      @change="onDetailInput(scope, detailType)"
                    ></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="数量" width="80" align="center">
                  <template slot-scope="scope">
                    <el-input-number
                      size="mini"
                      v-model="scope.row.count"
                      :min="1"
                      :controls="false"
                      style="width: 100%"
                      :disabled="isLocked"
                    ></el-input-number>
                  </template>
                </el-table-column>
                <el-table-column label="备注" min-width="80">
                  <template slot-scope="scope">
                    <el-input
                      size="mini"
                      v-model="scope.row.remark"
                      placeholder="请输入"
                      :disabled="isLocked"
                    ></el-input>
                  </template>
                </el-table-column>
                <el-table-column
                  label="主配穴"
                  width="100"
                  align="center"
                  v-if="detailType === '穴位'"
                >
                  <template slot-scope="scope">
                    <el-select
                      size="mini"
                      v-model="scope.row.mainType"
                      style="width: 100%"
                    >
                      <el-option label="主穴" value="1"></el-option>
                      <el-option label="配穴" value="2"></el-option>
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="100" fixed="right">
                  <template slot-scope="scope" v-if="scope.row.name">
                    <div class="operate">
                      <img
                        src="~@/assets/add.png"
                        alt
                        :class="{ 'operate-disabled': isLocked }"
                        @click="!isLocked && addDetailRow(scope, detailType)"
                      />
                      <img
                        src="~@/assets/delete1.png"
                        alt
                        :class="{ 'operate-disabled': isDeleteDisabled(scope.row, detailType) }"
                        @click="!isDeleteDisabled(scope.row, detailType) && deleteDetailRow(scope, detailType)"
                      />
                      <img
                        v-if="
                          detailType !== '其他详情' && detailType !== '部位'
                        "
                        src="~@/assets/find.png"
                        alt
                        @click="find(scope, detailType)"
                      />
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </div>

            <!-- 右侧表格 -->
            <div class="table-left">
              <el-table
                :data="getRightList(detailType)"
                border
                size="mini"
                style="width: 100%"
              >
                <el-table-column
                  prop="id"
                  label="序号"
                  width="50"
                  align="center"
                ></el-table-column>
                <el-table-column :label="detailType" min-width="100">
                  <template slot-scope="scope">
                    <el-select
                      v-if="detailType !== '其他详情' && detailType !== '部位'"
                      size="mini"
                      :value="scope.row.name"
                      remote
                      filterable
                      :filter-method="getFilterMethod(detailType)"
                      placeholder="请选择"
                      :disabled="isLocked"
                      @change="onItemChange($event, scope, detailType)"
                      @focus="searchByType('', detailType)"
                    >
                      <el-option
                        v-for="(item, idx) in getSearchOptions(detailType)"
                        :key="idx"
                        :label="item.acuname"
                        :value="item.acuid"
                      ></el-option>
                    </el-select>
                    <el-input
                      v-else
                      size="mini"
                      v-model="scope.row.name"
                      placeholder="请输入"
                      :disabled="isLocked"
                      @change="onDetailInput(scope, detailType)"
                    ></el-input>
                  </template>
                </el-table-column>
                <el-table-column label="数量" width="80" align="center">
                  <template slot-scope="scope">
                    <el-input-number
                      size="mini"
                      v-model="scope.row.count"
                      :min="1"
                      :controls="false"
                      style="width: 100%"
                      :disabled="isLocked"
                    ></el-input-number>
                  </template>
                </el-table-column>
                <el-table-column label="备注" min-width="80">
                  <template slot-scope="scope">
                    <el-input
                      size="mini"
                      v-model="scope.row.remark"
                      placeholder="请输入"
                      :disabled="isLocked"
                    ></el-input>
                  </template>
                </el-table-column>
                <el-table-column
                  label="主配穴"
                  width="100"
                  align="center"
                  v-if="detailType === '穴位'"
                >
                  <template slot-scope="scope">
                    <el-select
                      size="mini"
                      v-model="scope.row.mainType"
                      style="width: 100%"
                    >
                      <el-option label="主穴" value="1"></el-option>
                      <el-option label="配穴" value="2"></el-option>
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="100" fixed="right">
                  <template slot-scope="scope" v-if="scope.row.name">
                    <div class="operate">
                      <img
                        src="~@/assets/add.png"
                        alt
                        :class="{ 'operate-disabled': isLocked }"
                        @click="!isLocked && addDetailRow(scope, detailType)"
                      />
                      <img
                        src="~@/assets/delete1.png"
                        alt
                        :class="{ 'operate-disabled': isDeleteDisabled(scope.row, detailType) }"
                        @click="!isDeleteDisabled(scope.row, detailType) && deleteDetailRow(scope, detailType)"
                      />
                      <img
                        v-if="
                          detailType !== '其他详情' && detailType !== '部位'
                        "
                        src="~@/assets/find.png"
                        alt
                        @click="find(scope, detailType)"
                      />
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </div>

      <div class="no-data-tip" v-else>
        <span>暂无项目，请先点击"新增"添加项目</span>
      </div>

      <!-- 底部统计 -->
      <div class="table-bottom" v-if="prescriptions.length">
        <div class="table-b-header">
          <div class="header-about">
              <div
              class="item flex-vertical-center-l"
              style="align-items: flex-start;"
              v-if="showGuide"
            >
              <span><span style="opacity:0">*</span> 配穴指南：</span>
              <div style="flex: 1;">
                <el-input
                  size="mini"
                  placeholder="请输入"
                  v-model="pointMatchGuide"
                  type="textarea"
                  :autosize="{ minRows: 1, maxRows: 3 }"
                  :disabled="isLocked"
                  @input="emitStatistics"
                ></el-input>
              </div>
            </div>
            <div
              class="item flex-vertical-center-l"
              style="align-items: flex-start;"
            >
              <span><span style="color: red">*</span> 操作指南：</span>
              <div style="flex: 1;">
                <el-input
                  size="mini"
                  placeholder="请输入"
                  v-model="operationGuide"
                  type="textarea"
                  :autosize="{ minRows: 1, maxRows: 3 }"
                  :disabled="isLocked"
                  @input="emitStatistics"
                ></el-input>
              </div>
            </div>
            <div
              class="item flex-vertical-center-l"
              style="align-items: flex-start;"
              v-if="showEntrust"
            >
              <span><span style="opacity:0">*</span> 嘱托：</span>
              <div style="flex: 1;">
                <el-input
                  size="mini"
                  placeholder="请输入"
                  v-model="command"
                  type="textarea"
                  :autosize="{ minRows: 1, maxRows: 3 }"
                  :disabled="isLocked"
                  @input="emitStatistics"
                ></el-input>
              </div>
            </div>
          </div>
          <div class="header-about">
            <div class="stat-row flex-vertical-center-l flex-wrap">
              <div class="stat-field flex-vertical-center-l">
                <span><span style="color: red">*</span> 单次：</span>
                <el-input-number
                  size="mini"
                  v-model="singleCount"
                  :min="1"
                  :controls="false"
                  style="width: 60px"
                  @change="onSingleCountChange"
                  placeholder="请输入"
                ></el-input-number>
                <span class="stat-unit">{{ currentPricingUnit }}</span>
              </div>
              <div class="stat-field flex-vertical-center-l">
                <span><span v-if="requiredTreatFields" style="color: red">*</span> 治疗次数：</span>
                <el-input-number
                  size="mini"
                  v-model="treatCount"
                  :min="0"
                  :controls="false"
                  style="width: 60px"
                  :disabled="isLocked"
                  @change="updatePrice"
                ></el-input-number>
              </div>
              <div class="stat-field flex-vertical-center-l">
                <span><span v-if="requiredTreatFields" style="color: red">*</span> 频次：</span>
                <el-input-number
                  size="mini"
                  v-model="frequency"
                  :min="0"
                  :controls="false"
                  style="width: 60px"
                  :disabled="isLocked"
                  @change="emitStatistics"
                  placeholder="请输入"
                ></el-input-number>
                <span class="stat-unit">天</span>
                <el-input-number
                  size="mini"
                  v-model="frequencyUnit"
                  :min="0"
                  :controls="false"
                  style="width: 60px"
                  :disabled="isLocked"
                  @change="emitStatistics"
                  placeholder="请输入"
                ></el-input-number>
                <span class="stat-unit">次</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 底部金额 - 固定在最底部 -->
    <div class="table-b-bottom flex-vertical-between">
      <div class="t-b-b-left flex-vertical-center-l flex-wrap">
        <div class="t-b-l-item">
          单次金额：<span>{{ singlePrice || "0.00" }}元</span>
        </div>
        <div class="t-b-l-item">
          疗程金额：<span>{{ coursePrice || "0.00" }}元</span>
        </div>
        <div class="t-b-l-item" v-if="showAgreementTotal">
          协定方总金额：<span>{{ totalPrice || "0.00" }}元</span>
        </div>
      </div>
      <div class="t-b-b-right flex-vertical-center-r" v-if="!isLocked || (showSaveWhenLocked && isNonEditableLock)">
        <el-button
          type="primary"
          size="mini"
          :loading="saveLoading"
          @click="handleSave"
          >保存</el-button
        >
      </div>
    </div>

    <!-- 查看详情弹窗 -->
    <el-dialog
      :visible.sync="showDetailDialog"
      width="50%"
      top="5vh"
      :title="detailType + '详情'"
      append-to-body
      custom-class="detail-dialog"
    >
      <div class="drug-body">
        <!-- 穴位详情 -->
        <template v-if="detailType === '穴位'">
          <div class="drug-item">
            <span>穴位名称：</span>
            <div>{{ detailData.acuname }}</div>
          </div>
          <div class="drug-item">
            <span>定位：</span>
            <div>{{ detailData.acuposotion }}</div>
          </div>
          <div class="drug-item">
            <span>解剖：</span>
            <div>{{ detailData.acudiscection }}</div>
          </div>
          <div class="drug-item">
            <span>主治：</span>
            <div>{{ detailData.acumaintreat }}</div>
          </div>
          <div class="drug-item">
            <span>操作：</span>
            <div>{{ detailData.acuoperation }}</div>
          </div>
          <div class="drug-item">
            <span>针刺：</span>
            <div>{{ detailData.acuneedling }}</div>
          </div>
          <div class="drug-item" v-if="detailData.acuimg">
            <span>图示：</span>
            <div class="detail-img"><img :src="detailData.acuimg" /></div>
          </div>
        </template>
        <!-- 经络详情 -->
        <template v-else-if="detailType === '经络'">
          <div class="drug-item">
            <span>经络名称：</span>
            <div>{{ detailData.mername }}</div>
          </div>
          <div class="drug-item">
            <span>类型：</span>
            <div>{{ merTypeMap[detailData.mertype] || "-" }}</div>
          </div>
          <div class="drug-item" v-if="detailData.mermaindisease">
            <span>主要病候：</span>
            <div v-html="detailData.mermaindisease"></div>
          </div>
          <div class="drug-item" v-if="detailData.mermaintreat">
            <span>主治概要：</span>
            <div v-html="detailData.mermaintreat"></div>
          </div>
          <div class="drug-item" v-if="detailData.merimg">
            <span>图片：</span>
            <div class="detail-img"><img :src="detailData.merimg" /></div>
          </div>
        </template>
        <!-- 耳穴详情 -->
        <template v-else-if="detailType === '耳穴'">
          <div class="drug-item">
            <span>名称：</span>
            <div>{{ detailData.name }}</div>
          </div>
          <div class="drug-item" v-if="detailData.area">
            <span>定位：</span>
            <div>{{ detailData.area }}</div>
          </div>
          <div class="drug-item" v-if="detailData.effect">
            <span>功能：</span>
            <div>{{ detailData.effect }}</div>
          </div>
          <div class="drug-item" v-if="detailData.mainTreat">
            <span>主治：</span>
            <div>{{ detailData.mainTreat }}</div>
          </div>
          <div class="drug-item" v-if="detailData.photo">
            <span>图片：</span>
            <div class="detail-img"><img :src="detailData.photo" /></div>
          </div>
        </template>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  getXueweiList,
  collateralChannels,
  getAcupointD,
  getMerD,
  getAcuMeridianList,
  getAcuMeridianDetail,
} from "@/api/knowledge.js";
import {
  getMappedNondrugItemList,
  getNondrugItemDetail,
} from "@/api/technology.js";
import popup from "@/components/Propup.vue";

// 详情默认值
const DETAIL_DEFAULT_MAP = {
  "1": "穴位",
  "2": "部位",
  "3": "耳穴",
  "4": "经络",
  "5": "其他详情",
  "6": "无详情",
};

function createEmptyRow(id) {
  return {
    id,
    acuid: "",
    acuname: "",
    name: "",
    count: 1,
    remark: "",
    mainType: "1",
  };
}

function createPrescriptionData(options = {}) {
  const {
    detailRequired = false,
    detailTypes = [],
    singleCount = 0,
    unitPrice = 0,
  } = options;
  const singlePrice = (singleCount * unitPrice).toFixed(2);
  const allTypes = ["经络", "穴位", "耳穴", "部位", "其他详情", "无详情"];
  const detailTables = {};
  allTypes.forEach((type) => {
    if (type === "无详情") {
      detailTables[type] = detailTypes.includes(type)
        ? [{ description: "" }]
        : [];
    } else {
      detailTables[type] = detailTypes.includes(type)
        ? [createEmptyRow(1)]
        : [];
    }
  });
  return {
    detailTables,
    innerIsEditable: "1",
    innerDetailTypes: detailTypes.length > 0 ? detailTypes : [],
    detailRequired: !!detailRequired,
    operationGuide: "",
    pointMatchGuide: "",
    command: "",
    singleCount,
    treatCount: 1,
    frequency: undefined,
    frequencyUnit: undefined,
    singlePrice,
    coursePrice: "0.00",
    totalPrice: "0.00",
    currentUnitPrice: unitPrice,
    _manualSingleCount: false,
    paystate: 0, // 每个处方独立的支付状态
    isPay: false,
  };
}

export default {
  name: "适宜技术处方",
  components: { popup },
  props: {
    value: {
      type: Array,
      default: () => [],
    },
    isEditable: {
      type: String,
      default: "1",
    },
    showEditable: {
      type: Boolean,
      default: true,
    },
    detailTypes: {
      type: Array,
      default: () => ["经络"],
    },
    statistics: {
      type: Object,
      default: () => ({}),
    },
    showGuide: {
      type: Boolean,
      default: false,
    },
    showEntrust: {
      type: Boolean,
      default: false,
    },
    showAgreementTotal: {
      type: Boolean,
      default: true,
    },
    unitPrice: {
      type: Number,
      default: 0,
    },
    ownerType: {
      type: String,
      default: "",
    },
    requiredTreatFields: {
      type: Boolean,
      default: false,
    },
    reportAddRecipe: {
      type: Boolean,
      default: false,
    },
    useIsUpdateLock: {
      type: Boolean,
      default: false,
    },
    // 锁定(不可修改)时是否仍显示「保存」按钮（默认 false，保留原行为；仅需要的页面传 true）
    showSaveWhenLocked: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      name: "适宜技术处方",
      // 是否自拟处方
      isMyMade: true,
      // 配穴相关
      acupointList: [],
      meridianList: [],
      earAcupointList: [],
      detailTables: {
        经络: [createEmptyRow(1)],
        穴位: [],
        耳穴: [],
        部位: [],
        其他详情: [],
        无详情: [],
      },
      innerIsEditable: this.isEditable,
      innerDetailTypes: ["经络"],
      paystate: 0, // 云his 是否支付  0 否 1是(为否可以编辑)
      isPay: false,
      detailRequired: false,
      // 统计相关
      currentUnitPrice: 0,
      operationGuide: "",
      pointMatchGuide: "",
      command: "",
      singleCount: 0,
      treatCount: 1,
      frequency: undefined,
      frequencyUnit: undefined,
      singlePrice: "0.00",
      coursePrice: "0.00",
      totalPrice: "0.00",
      _manualSingleCount: false,
      // 处方 tab
      activeIndex: 0,
      prescriptionDataMap: {},
      // 新增处方弹窗
      showAddDialog: false,
      classifyOptions: [],
      itemOptions: [],
      itemLoading: false,
      addForm: {
        category: "",
        itemId: "",
        itemName: "",
        detailRequired: false,
      },
      addLoading: false,
      prescriptions: [],
      // 详情弹窗
      showDetailDialog: false,
      detailData: {},
      detailType: "",
      saveLoading: false,
      _isLoadingTab: false,
      merTypeMap: {
        1: "十二经脉",
        2: "奇经八脉",
        3: "经外奇穴",
        4: "阿是穴",
      },
    };
  },
  computed: {
    isLocked() {
      // 获取当前激活处方的支付状态
      const currentData = this.prescriptionDataMap[this.activeIndex];
      const paystate = currentData?.paystate ?? this.paystate;
      const isPay = currentData?.isPay ?? this.isPay;

      // 付费后不允许编辑（与旧版 SuitScience 逻辑保持一致）
      if (isPay || paystate == 1) {
        return true;
      }
      return this.useIsUpdateLock && this.innerIsEditable === "0";
    },
    // 已付费锁定（与 isLocked 付费分支一致；独立抽出供按钮显隐判断，不改动 isLocked）
    isPaidLock() {
      const currentData = this.prescriptionDataMap[this.activeIndex];
      const paystate = currentData?.paystate ?? this.paystate;
      const isPay = currentData?.isPay ?? this.isPay;
      return !!(isPay || paystate == 1);
    },
    // 仅因「不可修改」(后端 innerIsEditable==="0") 锁定、且未付费
    isNonEditableLock() {
      return this.useIsUpdateLock && this.innerIsEditable === "0" && !this.isPaidLock;
    },
    activeDetailTypes() {
      const validTypes = ["经络", "穴位", "耳穴", "部位", "其他详情"];
      return validTypes.filter((t) => this.innerDetailTypes.includes(t));
    },
    currentPricingUnit() {
      const p = this.prescriptions[this.activeIndex];
      return p?.pricingUnit || "";
    },
    currentSingleNumber() {
      const p = this.prescriptions[this.activeIndex];
      return p?.singleNumber || "0";
    },
    // 当前处方的计数系数
    currentCountCoefficient() {
      const p = this.prescriptions[this.activeIndex];
      return Number(p?.countCoefficient) || 1;
    },
    currentDetailCumulativeTypes() {
      const p = this.prescriptions[this.activeIndex];
      const val = p?.detailCumulative || "";
      if (!val) return [];
      const CUMULATIVE_MAP = {
        "1": "穴位",
        "2": "部位",
        "3": "耳穴",
        "4": "经络",
        "5": "其他详情",
      };
      return String(val)
        .split(/[,、]/)
        .filter(Boolean)
        .map((v) => CUMULATIVE_MAP[v.trim()])
        .filter(Boolean);
    },
    saveable() {
      // 过滤掉已付费的处方（与中药处方逻辑保持一致）
      const unpaidRecipes = this.prescriptions.filter((_, index) => {
        const data = this.prescriptionDataMap[index];
        return !data || (!data.isPay && data.paystate != 1);
      });
      return unpaidRecipes && unpaidRecipes.length > 0;
    },
    // 当前激活项目
    activeProject() {
      return this.prescriptions[this.activeIndex] || null;
    },
  },
  watch: {
    detailTables: {
      handler() {
        this.updatePrice();
      },
      deep: true,
    },
    // 激活项目变化时通知父组件（右侧「安全合理检测」只跟随当前选中项目）
    activeProject(val) {
      this.$emit("active-project-change", val);
    },
  },
  created() {
    this._prevDetailTypes = [...this.innerDetailTypes];
    this.getAcupointList();
    this.getMeridianList();
    this.getEarAcupointList();
    this.loadClassifyOptions();
  },
  methods: {
    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);
      }
    },

    saveCurrentTabData() {
      if (!this.prescriptions.length) return;
      this.$set(this.prescriptionDataMap, this.activeIndex, {
        detailTables: JSON.parse(JSON.stringify(this.detailTables)),
        innerIsEditable: this.innerIsEditable,
        innerDetailTypes: [...this.innerDetailTypes],
        detailRequired: this.detailRequired,
        operationGuide: this.operationGuide,
        pointMatchGuide: this.pointMatchGuide,
        command: this.command,
        singleCount: this.singleCount,
        treatCount: this.treatCount,
        frequency: this.frequency,
        frequencyUnit: this.frequencyUnit,
        singlePrice: this.singlePrice,
        coursePrice: this.coursePrice,
        totalPrice: this.totalPrice,
        currentUnitPrice: this.currentUnitPrice,
        _manualSingleCount: this._manualSingleCount,
        paystate: this.paystate, // 保存处方的支付状态
        isPay: this.isPay,
      });
    },
    cacheCurrentData() {
      this.saveCurrentTabData();
      this._cachedPrescriptions = JSON.parse(JSON.stringify(this.prescriptions));
      this._cachedPrescriptionDataMap = JSON.parse(JSON.stringify(this.prescriptionDataMap));
      this._cachedPaystate = this.paystate;
      this._cachedIsPay = this.isPay;
    },
    restoreCachedData() {
      if (!this._cachedPrescriptions) return false;
      this.prescriptions = this._cachedPrescriptions;
      this.prescriptionDataMap = this._cachedPrescriptionDataMap;
      this.paystate = this._cachedPaystate || 0;
      this.isPay = this._cachedIsPay || false;
      this.activeIndex = 0;
      this.loadTabData(0);
      this._cachedPrescriptions = null;
      this._cachedPrescriptionDataMap = null;
      this._cachedPaystate = null;
      this._cachedIsPay = null;
      return true;
    },
    loadTabData(index) {
      this._isLoadingTab = true;
      const data = this.prescriptionDataMap[index];
      if (data) {
        this.detailTables = JSON.parse(JSON.stringify(data.detailTables));
        this.innerIsEditable = data.innerIsEditable;
        this.innerDetailTypes = [...data.innerDetailTypes];
        this._prevDetailTypes = [...data.innerDetailTypes];
        this.detailRequired = data.detailRequired;
        this.operationGuide = data.operationGuide;
        this.pointMatchGuide = data.pointMatchGuide || "";
        this.command = data.command || "";
        this.singleCount = data.singleCount;
        this.treatCount = data.treatCount;
        this.frequency = data.frequency;
        this.frequencyUnit = data.frequencyUnit;
        this.singlePrice = data.singlePrice;
        this.coursePrice = data.coursePrice;
        this.totalPrice = data.totalPrice;
        this.currentUnitPrice = data.currentUnitPrice || 0;
        this._manualSingleCount = data._manualSingleCount || false;
        // 加载处方的支付状态
        this.paystate = data.paystate || 0;
        this.isPay = data.isPay || false;
      } else {
        const def = createPrescriptionData();
        this.detailTables = def.detailTables;
        this.innerIsEditable = def.innerIsEditable;
        this.innerDetailTypes = def.innerDetailTypes;
        this._prevDetailTypes = [...def.innerDetailTypes];
        this.detailRequired = def.detailRequired;
        this.operationGuide = def.operationGuide;
        this.pointMatchGuide = def.pointMatchGuide;
        this.singleCount = def.singleCount;
        this.treatCount = def.treatCount;
        this.frequency = def.frequency;
        this.frequencyUnit = def.frequencyUnit;
        this.singlePrice = def.singlePrice;
        this.coursePrice = def.coursePrice;
        this.totalPrice = def.totalPrice;
        this.currentUnitPrice = def.currentUnitPrice || 0;
        this._manualSingleCount = def._manualSingleCount || false;
      }
      this.$nextTick(() => {
        this._isLoadingTab = false;
        if (this.currentSingleNumber !== "0") {
          this.updatePrice();
        }
      });
    },
    // 判断处方是否已付费
    isPrescriptionPaid(index) {
      const data = this.prescriptionDataMap[index];
      if (data) {
        return data.isPay || data.paystate == 1;
      }
      return false;
    },
    switchTab(index) {
      if (this.activeIndex === index) return;
      this.saveCurrentTabData();
      this.activeIndex = index;
      this.loadTabData(index);
    },

    async openAddDialog() {
      this.addForm = {
        category: "",
        itemId: "",
        itemName: "",
        detailRequired: false,
      };
      this.itemOptions = [];
      this.showAddDialog = true;
      await this.fetchItemOptions();
    },
    async fetchItemOptions(query) {
      this.itemLoading = true;
      try {
        const params = {
          pageNum: 1,
          pageSize: 999,
        };
        if (this.addForm.category) {
          params.classify = this.addForm.category;
        }
        if (query) {
          if (/^[A-Za-z]+$/.test(query)) {
            params.py = query;
          } else {
            params.itemName = query;
          }
        }
        const res = await getMappedNondrugItemList(params);

        if (res.ResultCode == 0) {
          const list = res?.Data?.Items || [];
          this.itemOptions = list.map((item) => ({
            id: item.pid,
            name: item.itemName,
            detailRequired: item.detailIsnull === "1",
            detailDefault: item.detailDefault || "",
            detailCumulative: item.detailCumulative || "",
            classify: item.classify || "",
            price: item.price || 0,
            pricingUnit: item.pricingUnit || "",
            singleNumber: item.singleNumber || "",
            countCoefficient: item.countCoefficient || 1,
            minTreatmentDuration: item.minTreatmentDuration || 0,
          }));
        }
      } catch (e) {
        console.error("获取项目列表失败", e);
      } finally {
        this.itemLoading = false;
      }
    },
    onCategoryChange() {
      this.addForm.itemId = "";
      this.addForm.itemName = "";
      this.fetchItemOptions();
    },
    onItemSelectVisibleChange(visible) {
      if (visible) {
        this.fetchItemOptions();
      }
    },
    async searchItem(query) {
      await this.fetchItemOptions(query);
    },
    onItemSelected(id) {
      const item = this.itemOptions.find((i) => i.id === id);
      if (item) {
        this.addForm.itemName = item.name;
      }
    },
    async confirmAdd() {
      if (this.addLoading) return;
      if (!this.addForm.itemId) {
        this.$message.warning("请选择项目名称");
        return;
      }

      //不允许重复添加
      const isDuplicate = this.prescriptions.some(
        (p) => p.itemId === this.addForm.itemId,
      );
      if (isDuplicate) {
        this.$message.warning("该项目已添加，不能重复添加");
        return;
      }

      this.addLoading = true;
      let detailData = {};
      try {
        const res = await getNondrugItemDetail(this.addForm.itemId);
        if (res.ResultCode == 0) {
          detailData = res.Data || {};
        }
      } catch (e) {
        console.error("获取项目详情失败", e);
      }

      const categoryLabel =
        this.classifyOptions.find((c) => c.value === this.addForm.category)
          ?.label || "";

      const detailDefault = detailData.detailDefault || "";
      const detailTypeValues = detailDefault
        ? String(detailDefault).split(",")
        : [];
      const detailTypes = detailTypeValues
        .map((v) => DETAIL_DEFAULT_MAP[v.trim()])
        .filter(Boolean);

      // 详情是否必填
      const detailRequired = detailData.detailIsnull === "1";

      // 单次数量
      const singleNumber = detailData.singleNumber || "0";
      const singleCount = singleNumber === "0" ? 1 : 0;

      // 价格
      const price = detailData.price || 0;
      if (this.prescriptions.length > 0) {
        this.saveCurrentTabData();
      }

      const selectedItem = this.itemOptions.find(
        (i) => i.id === this.addForm.itemId,
      );

      const newIndex = this.prescriptions.length;
      this.prescriptions.push({
        category: this.addForm.category,
        categoryLabel,
        itemId: this.addForm.itemId,
        itemName: this.addForm.itemName,
        price,
        pricingUnit: detailData.pricingUnit || "",
        singleNumber,
        countCoefficient: detailData.countCoefficient || 1,
        minTreatmentDuration: detailData.minTreatmentDuration || 0,
        detailCumulative: detailData.detailCumulative || "",
        classify: selectedItem?.classify || "",
        ygtid: detailData.appId || "",
        departmentId: detailData.deptId || "",
        stitutionsId: detailData.institutionCode || "",
        stitutionsName: detailData.institutionName || "",
        //供右侧「安全合理检测」
        basisStitutionsnondrug: detailData || null,
      });

      this.prescriptionDataMap[newIndex] = createPrescriptionData({
        detailRequired,
        detailTypes,
        singleCount,
        unitPrice: price,
      });

      this.activeIndex = newIndex;
      this.loadTabData(newIndex);

      this.showAddDialog = false;
      this.addLoading = false;
      this.$emit("prescriptions-change", this.prescriptions);
      if (this.reportAddRecipe) this.$emit('add-recipe');
    },
    removePrescription(index) {
      this.$confirm("确认删除该处方？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.prescriptions.splice(index, 1);
          const oldMap = this.prescriptionDataMap;
          this.prescriptionDataMap = {};
          this.prescriptions.forEach((_, i) => {
            if (i < index) {
              this.prescriptionDataMap[i] = oldMap[i];
            } else {
              this.prescriptionDataMap[i] = oldMap[i + 1];
            }
          });

          if (this.prescriptions.length === 0) {
            this.activeIndex = 0;
            this.detailTables = {
              经络: [createEmptyRow(1)],
              穴位: [],
              耳穴: [],
              部位: [],
              其他详情: [],
            };
          } else {
            this.activeIndex = Math.min(index, this.prescriptions.length - 1);
            this.loadTabData(this.activeIndex);
          }

          this.$emit("prescriptions-change", this.prescriptions);
        })
        .catch(() => {});
    },
    clearAll() {
      if (!this.prescriptions.length) {
        this.detailTables = {
          经络: [createEmptyRow(1)],
          穴位: [],
          耳穴: [],
          部位: [],
          其他详情: [],
        };
        this.operationGuide = "";
        this.singleCount = 0;
        this.treatCount = 1;
        this.frequency = undefined;
        this.frequencyUnit = undefined;
        this.singlePrice = "0.00";
        this.coursePrice = "0.00";
        this.totalPrice = "0.00";
        this.currentUnitPrice = 0;
        this.innerIsEditable = "1";
        this.innerDetailTypes = ["经络"];
        this._prevDetailTypes = ["经络"];
        this.detailRequired = false;
        this.emitStatistics();
        return;
      }
      const p = this.prescriptions[this.activeIndex];
      const unitPrice = p?.price || 0;
      this.prescriptionDataMap[this.activeIndex] = createPrescriptionData({
        detailRequired: false,
        detailTypes: [],
        singleCount: 0,
        unitPrice,
      });
      this.loadTabData(this.activeIndex);
      this.updatePrice();
      this.$emit("prescriptions-change", this.prescriptions);
    },

    onEditableChange(val) {
      this.$emit("update:isEditable", val);
    },
    onDetailTypesChange(val) {
      const NO_DETAIL = "无详情";
      const lastSelected =
        val.length > this._prevDetailTypes?.length
          ? val.find((v) => !this._prevDetailTypes.includes(v))
          : null;

      if (lastSelected === NO_DETAIL) {
        val = [NO_DETAIL];
      } else if (
        lastSelected &&
        lastSelected !== NO_DETAIL &&
        val.includes(NO_DETAIL)
      ) {
        val = val.filter((v) => v !== NO_DETAIL);
      }
      this.innerDetailTypes = val;
      this._prevDetailTypes = [...val];

      val.forEach((type) => {
        const table = this.detailTables[type];
        const isEmpty = !table || table.length === 0;
        if (type === "无详情") {
          if (isEmpty) {
            this.$set(this.detailTables, type, [{ description: "" }]);
          }
        } else {
          if (isEmpty) {
            this.$set(this.detailTables, type, [createEmptyRow(1)]);
          }
        }
      });
      this.$emit("update:detailTypes", val);
    },

    getDetailTable(type) {
      if (!this.detailTables[type]) {
        this.$set(this.detailTables, type, [createEmptyRow(1)]);
      }
      return this.detailTables[type];
    },
    getLeftList(type) {
      return this.getDetailTable(type).filter((item) => item.id % 2 !== 0);
    },
    getRightList(type) {
      return this.getDetailTable(type).filter((item) => item.id % 2 === 0);
    },
    async getAcupointList(keyword = "", serchtype = "") {
      try {
        const res = await getXueweiList({
          pageid: 1,
          pagesize: 999,
          serchtype: serchtype,
          keyword: keyword,
        });
        if (res.code === 0) {
          this.acupointList = res.data.acupoints || [];
        }
      } catch (e) {
        console.error("获取穴位列表失败", e);
      }
    },
    async getMeridianList(keyword = "", serchtype = "") {
      try {
        const res = await collateralChannels({
          mertype: "1",
          pageid: 1,
          pagesize: 999,
          keyword: keyword,
          serchtype: serchtype,
        });
        if (res.code == 0) {
          this.meridianList = (res.data.meridians || []).map((item) => ({
            acuid: item.merid,
            acuname: item.mername,
          }));
        }
      } catch (e) {
        console.error("获取经络列表失败", e);
      }
    },
    async getEarAcupointList(keyword = "", serchtype = "") {
      try {
        const params = { page: 1, limit: 999, serchtype };
        if (keyword) params.keyWord = keyword;
        const res = await getAcuMeridianList(params);
        if (res.code == 0) {
          const list = res.data?.records || [];
          this.earAcupointList = (Array.isArray(list) ? list : []).map(
            (item) => ({
              acuid: item.id,
              acuname: item.name,
            }),
          );
        }
      } catch (e) {
        console.error("获取耳穴列表失败", e);
      }
    },
    getSearchOptions(type) {
      switch (type) {
        case "经络":
          return this.meridianList;
        case "耳穴":
          return this.earAcupointList;
        default:
          return this.acupointList;
      }
    },
    getFilterMethod(type) {
      return (query) => {
        this.searchByType(query, type);
      };
    },
    searchByType(query, type) {
      const pinyin = /^[A-Za-z]+$/g;
      const serchtype = pinyin.test(query) ? "1" : "";
      switch (type) {
        case "经络":
          this.getMeridianList(query, serchtype);
          break;
        case "耳穴":
          this.getEarAcupointList(query, serchtype);
          break;
        default:
          this.getAcupointList(query, serchtype);
      }
    },
    onItemChange(acuid, scope, detailType) {
      const row = scope.row;
      // 在任何修改之前记录该行是否已有值（区分修改和新增）
      const hadPreviousValue = !!row.acuid;

      const table = this.getDetailTable(detailType);
      const exists = table.find(
        (item) => item.acuid === acuid && item.id !== row.id,
      );
      if (exists) {
        this.$message.error("不可重复选择");
        return;
      }

      const optionsList = this.getSearchOptions(detailType);
      const selected = optionsList.find((item) => item.acuid === acuid);
      if (selected) {
        row.acuid = selected.acuid;
        row.acuname = selected.acuname;
        row.name = selected.acuname;
        if (
          detailType === "穴位" &&
          selected.num != null &&
          selected.num !== ""
        ) {
          row.count = Number(selected.num) || 1;
        }
      }
      // 只有新增（原来没有值）才添加新行，修改不添加
      if (!hadPreviousValue) {
        this.addDetailRow(scope, detailType);
      }
    },
    onDetailInput(scope, detailType) {
      if (scope.row.name) {
        this.addDetailRow(scope, detailType);
      }
    },
    addDetailRow(scope, detailType) {
      const table = this.getDetailTable(detailType);
      if (scope) {
        const index = scope.row.id - 1;
        if (index === table.length - 1) {
          table.push(createEmptyRow(1));
        } else {
          const rest = table.splice(scope.row.id);
          table.push(createEmptyRow(1));
          this.$set(this.detailTables, detailType, table.concat(rest));
        }
      } else {
        table.push(createEmptyRow(1));
      }
      this.reIndexDetail(detailType);
      this.searchByType("", detailType);
    },
    isDeleteDisabled(row, detailType) {
      if (this.isLocked) {
        if (detailType === '穴位') {
          return row.mainType === '1'; // 主穴不可删除
        }
        
        return true;
      }
      return false;
    },
    deleteDetailRow(scope, detailType) {
      if (this.isDeleteDisabled(scope.row, detailType)) return;
      const table = this.getDetailTable(detailType);
      const index = scope.row.id - 1;
      if (table.length === 1) {
        // 仅剩一行时清空内容（保留空行占位），否则点击删除无反应
        this.$set(table, 0, createEmptyRow(1));
        return;
      }
      table.splice(index, 1);
      this.reIndexDetail(detailType);
    },
    async find(scope, detailType) {
      const row = scope.row;
      if (!row.acuid) return;
      try {
        let res;
        if (detailType === "经络") {
          res = await getMerD({ merid: row.acuid });
        } else if (detailType === "耳穴") {
          res = await getAcuMeridianDetail(row.acuid);
        } else {
          res = await getAcupointD({ acuid: row.acuid });
        }
        if (res.code === 0 || res.ResultCode === 0) {
          this.detailData = res.data || res.Data || {};
          this.detailType = detailType;
          this.showDetailDialog = true;
        }
      } catch (e) {
        console.error("获取详情失败", e);
      }
    },
    copyDetailRow(scope, detailType) {
      const table = this.getDetailTable(detailType);
      const copy = { ...scope.row, id: 1 };
      const index = scope.row.id;
      table.splice(index, 0, copy);
      this.reIndexDetail(detailType);
    },
    reIndexDetail(detailType) {
      const table = this.getDetailTable(detailType);
      table.forEach((item, index) => {
        item.id = index + 1;
      });
    },

    onSingleCountChange(val) {
      if (val !== undefined && val !== null) {
        this._manualSingleCount = true;
      }
      this.updatePrice();
    },

    updatePrice() {
      if (this.currentSingleNumber !== "0" && !this._isLoadingTab && !this._manualSingleCount) {
        this.singleCount = this.calcTotalCount();
      }
      const price = this.currentUnitPrice || this.unitPrice || 0;
      this.singlePrice = (this.singleCount * price).toFixed(2);
      this.coursePrice = (
        this.treatCount * parseFloat(this.singlePrice)
      ).toFixed(2);
      this.saveCurrentTabData();
      let total = 0;
      Object.values(this.prescriptionDataMap).forEach((d) => {
        total += parseFloat(d.coursePrice) || 0;
      });
      this.totalPrice = total.toFixed(2);
      this.emitStatistics();
    },
    calcTotalCount() {
      let total = 0;
      const types = this.activeDetailTypes;
      types.forEach((type) => {
        const table = this.detailTables[type];
        if (table) {
          table.forEach((row) => {
            if (row.acuid || row.name) {
              total += row.count || 0;
            }
          });
        }
      });
      const coefficient = this.currentCountCoefficient;
      const result = coefficient > 0 ? total / coefficient : total;
      return Math.ceil(result);
    },
    emitStatistics() {
      this.$emit("update:statistics", {
        operationGuide: this.operationGuide,
        command: this.command,
        singleCount: this.singleCount,
        treatCount: this.treatCount,
        frequency: this.frequency,
        frequencyUnit: this.frequencyUnit,
        singlePrice: this.singlePrice,
        coursePrice: this.coursePrice,
        totalPrice: this.totalPrice,
      });
    },
    validate() {
      if (!this.prescriptions.length) {
        this.$message.warning("请先新增处方");
        return false;
      }
      if (this.detailRequired && this.innerDetailTypes.length === 0) {
        this.$message.warning("请至少勾选一个详情类型");
        return false;
      }
      if (!this.operationGuide.trim()) {
        this.$message.warning("请输入操作指南");
        return false;
      }
      if (!this.singleCount || this.singleCount <= 0) {
        this.$message.warning("请输入单次数量");
        return false;
      }
      if (this.requiredTreatFields) {
        if (!this.treatCount || this.treatCount <= 0) {
          this.$message.warning("请输入治疗次数");
          return false;
        }
        if (!this.frequency || this.frequency <= 0) {
          this.$message.warning("请输入频次");
          return false;
        }
        if (!this.frequencyUnit || this.frequencyUnit <= 0) {
          this.$message.warning("请输入频次次数");
          return false;
        }
      }
      return true;
    },
    handleSave() {
      if (!this.validate()) return;
      this.saveLoading = true;
      const treatmentList = this.buildTreatmentList();
      const firstP = this.prescriptions[0] || {};
      const institutionInfo = {
        ygtid: firstP.ygtid || "",
        departmentId: firstP.departmentId || "",
        stitutionsId: firstP.stitutionsId || "",
        stitutionsName: firstP.stitutionsName || "",
      };
      this.$emit("save", treatmentList, institutionInfo);
    },
    saveDone() {
      this.saveLoading = false;
    },
    buildTreatmentList() {
      this.saveCurrentTabData();
      const DETAIL_TYPE_MAP = {
        穴位: "1",
        经络: "2",
        耳穴: "3",
        部位: "4",
        其他详情: "5",
      };
      const TYPE_TO_FIELD = {
        穴位: "detailPoint",
        经络: "detailMeridian",
        耳穴: "detailEarPoint",
        部位: "detailBodyPart",
        其他详情: "detailOther",
      };

      // 过滤掉已付费的处方（与中药处方逻辑保持一致）
      return this.prescriptions
        .map((p, originalIndex) => ({ p, originalIndex }))
        .filter(({ originalIndex }) => {
          const data = this.prescriptionDataMap[originalIndex];
          return !data || (!data.isPay && data.paystate != 1);
        })
        .map(({ p, originalIndex }) => {
        const d = this.prescriptionDataMap[originalIndex] || createPrescriptionData();

        const detailPoint = [];
        const detailMeridian = [];
        const detailEarPoint = [];
        const detailBodyPart = [];
        const detailOther = [];
        const detailNone = [];
        const detailArrays = {
          穴位: detailPoint,
          经络: detailMeridian,
          耳穴: detailEarPoint,
          部位: detailBodyPart,
          其他详情: detailOther,
        };

        Object.keys(detailArrays).forEach((type) => {
          // 未勾选的详情类型不提交
          if (!d.innerDetailTypes.includes(type)) return;
          const table = d.detailTables[type] || [];
          table.forEach((row) => {
            if (row.acuid || row.name) {
              detailArrays[type].push({
                acupoint: type === "穴位" ? row.mainType || "0" : "0",
                name: row.acuname || row.name || "",
                num: row.count || 1,
                pointCode: "",
                pointId: row.acuid || "",
                remark: row.remark || "",
                seqn: String(row.id || ""),
                type: DETAIL_TYPE_MAP[type] || "1",
              });
            }
          });
        });
        return {
          treatItemId: p.itemId,
          treatItemName: p.itemName,
          treatClass: p.classify || "",
          isUpdate: d.innerIsEditable || "1",
          singleQty: d.singleCount || 0,
          singleAmount: parseFloat(d.singlePrice) || 0,
          treatNum: d.treatCount || 0,
          courseAmount: parseFloat(d.coursePrice) || 0,
          frequency:
            d.frequency && d.frequencyUnit
              ? `${d.frequency}天${d.frequencyUnit}次`
              : "",
          useExplain: d.operationGuide || "",
          command: d.command || "",
          pointMatchGuide: d.pointMatchGuide || "",
          seqn: originalIndex + 1,
          ownerType: this.ownerType || "1",
          detailPoint,
          detailMeridian,
          detailEarPoint,
          detailBodyPart,
          detailOther,
          detailNone: d.innerDetailTypes.includes("无详情")
            ? { description: "" }
            : null,
        };
      });
    },
    loadFromServerData(treatmentList) {
      if (!Array.isArray(treatmentList) || !treatmentList.length) return;

      const TYPE_VALUE_MAP = {
        "1": "穴位",
        "2": "经络",
        "3": "耳穴",
        "4": "部位",
        "5": "其他详情",
        "6": "无详情",
      };

      this.prescriptions = [];
      this.prescriptionDataMap = {};

      treatmentList.forEach((item, index) => {
        const unitPrice = Number(item.basisStitutionsnondrug?.price) || 0;
        const pricingUnit = item.basisStitutionsnondrug?.pricingUnit || "";
        this.prescriptions.push({
          category: "",
          categoryLabel: "",
          itemId: item.treatItemId || "",
          itemName: item.treatItemName || "",
          price: unitPrice,
          pricingUnit: pricingUnit,
          singleNumber: item.basisStitutionsnondrug?.singleNumber || "0",
          countCoefficient: item.basisStitutionsnondrug?.countCoefficient || 1,
          minTreatmentDuration:
            item.basisStitutionsnondrug?.minTreatmentDuration || 0,
          detailCumulative: item.basisStitutionsnondrug?.detailCumulative || "",
          // 右侧「安全合理检测」
          basisStitutionsnondrug: item.basisStitutionsnondrug || null,
        });

        const allDetails = [].concat(
          item.detailPoint || [],
          item.detailMeridian || [],
          item.detailEarPoint || [],
          item.detailBodyPart || [],
          item.detailOther || [],
        );

        const detailTables = {
          经络: [],
          穴位: [],
          耳穴: [],
          部位: [],
          其他详情: [],
          无详情: [],
        };
        const activeTypes = new Set();

        if (
          item.detailNone !== null &&
          item.detailNone !== undefined &&
          typeof item.detailNone === "object" &&
          !Array.isArray(item.detailNone)
        ) {
          activeTypes.add("无详情");
        }

        allDetails.forEach((d) => {
          const typeName = TYPE_VALUE_MAP[d.type] || "";
          if (typeName && detailTables[typeName]) {
            activeTypes.add(typeName);
            detailTables[typeName].push({
              id: detailTables[typeName].length + 1,
              acuid: d.pointId || "",
              acuname: d.name || "",
              name: d.name || "",
              count: d.num || 1,
              remark: d.remark || "",
              mainType: d.acupoint || "1",
            });
          }
        });

        ["经络", "穴位", "耳穴", "部位", "其他详情"].forEach((type) => {
          if (detailTables[type].length === 0) {
            detailTables[type] = [createEmptyRow(1)];
          }
        });
        if (!detailTables["无详情"]) {
          detailTables["无详情"] = [];
        }

        let parsedFreqDays = undefined;
        let parsedFreqTimes = undefined;
        if (item.frequency) {
          const match = String(item.frequency).match(/(\d+)天(\d+)次/);
          if (match) {
            parsedFreqDays = parseInt(match[1], 10);
            parsedFreqTimes = parseInt(match[2], 10);
          }
        }

        const singleNumber = item.basisStitutionsnondrug?.singleNumber || "0";
        this.prescriptionDataMap[index] = {
          detailTables,
          innerIsEditable: item.isUpdate || "1",
          innerDetailTypes: activeTypes.size > 0 ? [...activeTypes] : ["经络"],
          detailRequired: item.basisStitutionsnondrug?.detailIsnull === "1",
          operationGuide: item.useExplain || "",
          command: item.command || "",
          pointMatchGuide: item.pointMatchGuide || "",
          singleCount: item.singleQty || 0,
          treatCount: item.treatNum || 1,
          frequency: parsedFreqDays,
          frequencyUnit: parsedFreqTimes,
          singlePrice: String(item.singleAmount || "0.00"),
          coursePrice: (
            (item.treatNum || 1) * (item.singleAmount || 0)
          ).toFixed(2),
          totalPrice: "0.00",
          currentUnitPrice: unitPrice,
          _manualSingleCount: singleNumber !== "0",
          paystate: item.paystate || 0, // 从接口数据中获取支付状态
          isPay: item.isPay || false,
        };
      });

      this.activeIndex = 0;
      this.loadTabData(0);

      let total = 0;
      Object.values(this.prescriptionDataMap).forEach((d) => {
        total += parseFloat(d.coursePrice) || 0;
      });
      this.totalPrice = total.toFixed(2);

      this.$emit("prescriptions-change", this.prescriptions);
    },
    // 追加数据到当前处方（已存在但未支付的项目会覆盖）
    appendFromServerData(treatmentList) {
      if (!Array.isArray(treatmentList) || !treatmentList.length) return;

      const TYPE_VALUE_MAP = {
        "1": "穴位",
        "2": "经络",
        "3": "耳穴",
        "4": "部位",
        "5": "其他详情",
        "6": "无详情",
      };

      // 创建已存在项目的索引映射（用于覆盖）
      const existingIndexMap = {};
      this.prescriptions.forEach((p, i) => {
        if (p.itemName) {
          existingIndexMap[p.itemName] = i;
        }
      });

      treatmentList.forEach((item) => {
        const itemName = item.treatItemName || "";
        const unitPrice = Number(item.basisStitutionsnondrug?.price) || 0;
        const pricingUnit = item.basisStitutionsnondrug?.pricingUnit || "";

        const prescriptionData = {
          category: "",
          categoryLabel: "",
          itemId: item.treatItemId || "",
          itemName: itemName,
          price: unitPrice,
          pricingUnit: pricingUnit,
          singleNumber: item.basisStitutionsnondrug?.singleNumber || "0",
          countCoefficient: item.basisStitutionsnondrug?.countCoefficient || 1,
          minTreatmentDuration:
            item.basisStitutionsnondrug?.minTreatmentDuration || 0,
          detailCumulative: item.basisStitutionsnondrug?.detailCumulative || "",
          // 右侧「安全合理检测」
          basisStitutionsnondrug: item.basisStitutionsnondrug || null,
        };

        const allDetails = [].concat(
          item.detailPoint || [],
          item.detailMeridian || [],
          item.detailEarPoint || [],
          item.detailBodyPart || [],
          item.detailOther || [],
        );

        const detailTables = {
          经络: [],
          穴位: [],
          耳穴: [],
          部位: [],
          其他详情: [],
          无详情: [],
        };
        const activeTypes = new Set();

        if (
          item.detailNone !== null &&
          item.detailNone !== undefined &&
          typeof item.detailNone === "object" &&
          !Array.isArray(item.detailNone)
        ) {
          activeTypes.add("无详情");
        }

        allDetails.forEach((d) => {
          const typeName = TYPE_VALUE_MAP[d.type] || "";
          if (typeName && detailTables[typeName]) {
            activeTypes.add(typeName);
            detailTables[typeName].push({
              id: detailTables[typeName].length + 1,
              acuid: d.pointId || "",
              acuname: d.name || "",
              name: d.name || "",
              count: d.num || 1,
              remark: d.remark || "",
              mainType: d.acupoint || "1",
            });
          }
        });

        ["经络", "穴位", "耳穴", "部位", "其他详情"].forEach((type) => {
          if (detailTables[type].length === 0) {
            detailTables[type] = [createEmptyRow(1)];
          }
        });
        if (!detailTables["无详情"]) {
          detailTables["无详情"] = [];
        }

        let parsedFreqDays = undefined;
        let parsedFreqTimes = undefined;
        if (item.frequency) {
          const match = String(item.frequency).match(/(\d+)天(\d+)次/);
          if (match) {
            parsedFreqDays = parseInt(match[1], 10);
            parsedFreqTimes = parseInt(match[2], 10);
          }
        }

        const singleNumber = item.basisStitutionsnondrug?.singleNumber || "0";
        const newPrescriptionData = {
          detailTables,
          innerIsEditable: item.isUpdate || "1",
          innerDetailTypes: activeTypes.size > 0 ? [...activeTypes] : ["经络"],
          detailRequired: item.basisStitutionsnondrug?.detailIsnull === "1",
          operationGuide: item.useExplain || "",
          command: item.command || "",
          pointMatchGuide: item.pointMatchGuide || "",
          singleCount: item.singleQty || 0,
          treatCount: item.treatNum || 1,
          frequency: parsedFreqDays,
          frequencyUnit: parsedFreqTimes,
          singlePrice: String(item.singleAmount || "0.00"),
          coursePrice: (
            (item.treatNum || 1) * (item.singleAmount || 0)
          ).toFixed(2),
          totalPrice: "0.00",
          currentUnitPrice: unitPrice,
          _manualSingleCount: singleNumber !== "0",
          // 追加的项目默认为未支付状态
          paystate: 0,
          isPay: false,
        };

        // 检查项目是否已存在
        if (itemName && existingIndexMap[itemName] !== undefined) {
          // 覆盖已存在的项目
          const existingIndex = existingIndexMap[itemName];
          this.prescriptions[existingIndex] = prescriptionData;
          this.prescriptionDataMap[existingIndex] = newPrescriptionData;
        } else {
          // 追加新项目
          this.prescriptions.push(prescriptionData);
          this.prescriptionDataMap[this.prescriptions.length - 1] = newPrescriptionData;
        }
      });

      // 切换到第一个项目
      this.activeIndex = 0;
      this.loadTabData(0);

      // 更新总价
      let total = 0;
      Object.values(this.prescriptionDataMap).forEach((d) => {
        total += parseFloat(d.coursePrice) || 0;
      });
      this.totalPrice = total.toFixed(2);

      this.$emit("prescriptions-change", this.prescriptions);
    },
    getData() {
      if (!this.validate()) return null;
      this.saveCurrentTabData();
      return {
        prescriptions: this.prescriptions.map((p, i) => {
          const d = this.prescriptionDataMap[i] || createPrescriptionData();
          return {
            ...p,
            isEditable: d.innerIsEditable,
            detailTypes: d.innerDetailTypes,
            detailRequired: d.detailRequired,
            detailTables: d.detailTables,
            acupoints: (d.detailTables["穴位"] || []).filter(
              (item) => item.acuid,
            ),
            statistics: {
              operationGuide: d.operationGuide,
              singleCount: d.singleCount,
              treatCount: d.treatCount,
              frequency: d.frequency,
              frequencyUnit: d.frequencyUnit,
              singlePrice: d.singlePrice,
              coursePrice: d.coursePrice,
              totalPrice: d.totalPrice,
            },
          };
        }),
      };
    },
  },
};
</script>

<style lang="scss" scoped>
.recipe-acupoint-wrapper {
  display: flex;
  flex-direction: column;
  height: 100%;

  .prescription-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 2px solid #dedede;
    padding: 0px 0;
    flex-shrink: 0;

    .table-label {
      display: flex;
      align-items: center;
      flex: 1 1 auto;
      min-width: 0;
      overflow-x: auto;

      .label-item {
        cursor: pointer;
        min-width: 104px;
        max-width: 220px;
        flex-shrink: 0;
        border-right: 2px solid #eaeaea;
        display: flex;
        align-items: center;
        padding: 0 8px;

        span {
          font-size: 14px;
          font-family: PingFang SC;
          font-weight: 400;
          color: #666666;
          margin-left: 8px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }

        div {
          color: #666;
          font-size: 16px;
          margin-left: 8px;
          margin-top: 1px;
          font-weight: 600;
          flex-shrink: 0;
        }

        img {
          width: 20px;
          margin-left: 8px;
          flex-shrink: 0;
        }

        .l_active {
          color: #5386f6;
        }
      }
    }
  }

  .top-btns {
    display: flex;
    flex-shrink: 0;
    margin-left: auto;
  }

  .table-b-bottom {
    flex-shrink: 0;
    padding: 10px;
    border-top: 2px solid #dedede;
    background: #fff;

    .t-b-l-item {
      font-size: 14px;
      color: #333;
      margin-right: 20px;

      span {
        color: #ff6245;
      }
    }
  }
}

.recipe-acupoint {
  border: 2px solid #dedede;
  padding: 7px 0 0;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;

  .table-toolbar {
    margin-bottom: 10px;
    padding: 0 5px;
    flex-shrink: 0;

    .toolbar-item {
      margin-right: 30px;
      margin-bottom: 5px;

      span {
        font-size: 14px;
        color: #333;
        white-space: nowrap;
      }
    }
  }

  // 滚动容器
  .table-container {
    padding: 0 5px;
    flex: 1;
    min-height: 100px;
    overflow: auto;
  }

  .no-data-tip {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #999;
    font-size: 14px;
    padding: 40px 0;
  }

  // 详情表格区域
  .detail-table-section {
    margin-bottom: 10px;

    .detail-section-label {
      display: inline-block;
      padding: 2px 12px;
      border: 1px solid #ff6245;
      border-radius: 4px;
      color: #ff6245;
      font-size: 13px;
      margin-bottom: 6px;
    }
  }

  // 配穴表格
  .table-show {
    width: 100%;
    overflow: auto;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;

    .table-left {
      flex: 0 0 49.9%;
      overflow-y: auto;
      border: 1px solid #dedede;
      box-sizing: border-box;
    }
  }

  // 底部统计
  .table-bottom {
    flex-shrink: 0;
    padding: 0 5px;
    margin-top: 5px;

    .table-b-header {
      .header-about {
        .item {
          margin-right: 20px;
          margin-bottom: 10px;

          span {
            font-size: 14px;
            color: #333;
            white-space: nowrap;
          }
        }
      }
    }
  }

  .stat-row {
    .stat-field {
      margin-right: 50px;
      margin-bottom: 5px;

      span {
        font-size: 14px;
        color: #333;
        white-space: nowrap;
      }

      .stat-unit {
        margin: 0 4px;
      }
    }
  }

  .operate {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-around;

    img {
      width: 16px;
      cursor: pointer;
    }

    .operate-disabled {
      opacity: 0.4;
      cursor: not-allowed;
    }
  }
}

.recipe-acupoint ::v-deep .el-table .cell {
  text-align: center;
}

.recipe-acupoint ::v-deep .el-select {
  width: 100%;
}

.recipe-acupoint ::v-deep .el-table td {
  padding: 2px 0;
}

.recipe-acupoint ::v-deep .el-table th {
  padding: 2px 0;
}

.recipe-acupoint .table-show .table-left::v-deep .el-table__empty-block {
  min-height: 33px !important;
  height: 33px !important;
}

.drug-body {
  padding: 10px;

  .drug-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 12px;

    > span {
      min-width: 80px;
      font-size: 14px;
      color: #333;
      text-align: right;
      margin-right: 10px;
      flex-shrink: 0;
    }

    > div {
      flex: 1;
      font-size: 14px;
      color: #666;
      word-break: break-all;
      line-height: 1.6;
    }

    .detail-img {
      img {
        max-width: 100%;
        max-height: 300px;
      }
    }
  }
}
</style>

<style lang="scss">
.add-prescription-dialog {
  margin: 0 auto;

  .el-dialog__header {
    padding: 0;
  }

  .el-dialog__body {
    padding: 18px;
  }

  .add-dialog-header {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 34px;
    background: #5386f6;
    position: relative;

    span {
      font-size: 16px;
      font-family: PingFang SC;
      font-weight: 400;
      color: #fff;
    }

    .close-btn {
      transform: rotate(45deg);
      color: #fff;
      position: absolute;
      top: -13px;
      right: 20px;
      font-size: 44px;
      cursor: pointer;
    }
  }

  .add-dialog-body {
    min-height: 350px;

    .add-form-row {
      display: flex;
      align-items: center;
      margin-bottom: 16px;

      .label {
        font-size: 14px;
        color: #333;
        white-space: nowrap;
        min-width: 100px;
        text-align: right;
      }
    }
  }

  .add-dialog-btns {
    display: flex;
    justify-content: center;
    margin-top: 20px;

    .confirm-btn {
      width: 108px;
      height: 40px;
      line-height: 40px;
      text-align: center;
      background: #5386f6;
      color: #fff;
      border-radius: 3px;
      font-size: 18px;
      cursor: pointer;

      &.is-disabled {
        opacity: 0.6;
        cursor: not-allowed;
      }
    }
  }
}

.detail-dialog {
  margin: 0 auto;

  .el-dialog__header {
    padding: 0;
    background: #5386f6;
    text-align: center;
    height: 40px;
    line-height: 40px;
  }

  .el-dialog__title {
    font-size: 16px;
    color: #fff;
  }

  .el-dialog__headerbtn {
    top: 8px;
    right: 10px;
    font-size: 22px;
    .el-dialog__close {
      color: #fff;
      font-size: 22px;
    }
  }

  .el-dialog__body {
    padding: 18px;
    max-height: 75vh;
    overflow-y: auto;
  }

  .drug-body {
    padding: 10px;

    .drug-item {
      display: flex;
      align-items: flex-start;
      margin-bottom: 12px;

      > span {
        min-width: 80px;
        font-size: 14px;
        color: #333;
        text-align: right;
        margin-right: 10px;
        flex-shrink: 0;
      }

      > div {
        flex: 1;
        font-size: 14px;
        color: #666;
        word-break: break-all;
        line-height: 1.6;
      }

      .detail-img {
        img {
          max-width: 100%;
          max-height: 300px;
        }
      }
    }
  }
}
</style>
