<template>
  <view class="safe-area-inset-bottom page-bg">
    <!-- #ifdef MP-WEIXIN -->
    <page-container
      :if="pageBackGuardShow"
      :overlay="false"
      @leave="onPageBackGuardLeave"
    />
    <!-- #endif -->
    <!-- 导航栏 -->
    <u-navbar class="navbar" :is-back="true" :title="navbarTitle" :custom-back="boundCustomBack" title-color="#000" background="{ background: '#fff' }">
    </u-navbar>

    <!-- 处方类型Tab切换 -->
    <view v-if="!isSalespersonTransferMode" class="tabs flex p-32 flex-ali-center flex-jus-sp shadow-sm" style="overflow-x: auto; position: relative; z-index: 10;">
      <u-button
          :throttle-time="0"
          :plain="true"
          :type="activeCategory === category.value ? 'success' : 'default'"
          v-for="(category, index) in prescriptionCategories"
          :key="category.value"
          :custom-style="tabsBtnStyle"
          @click="handleSwitchCategory(category.value)"
          :hairline="true"
          :hoverStayTime="0"
          :style="{
          display: (index === 0 && identity === 2) || identity === 1 ? 'block' : 'none',
          marginLeft: '10rpx',
        }">
        {{ category.label }}
      </u-button>
    </view>

    <view v-if="!isSalespersonTransferMode && registerModeHint" class="register-mode-hint mx-32 m-t-12">
      <text class="register-mode-hint__text">{{ registerModeHint }}</text>
    </view>

    <view
      v-if="!isSalespersonTransferMode && hasSpecialPrescriptionRecord"
      class="special-rx-card mx-32 m-t-12"
    >
      <view class="special-rx-card__inner flex-row flex-ali-center">
        <u-image
          v-if="specialPrescriptionRecord.special_prescription && specialPrescriptionRecord.special_prescription.cover_image"
          width="96rpx"
          height="96rpx"
          border-radius="12"
          :src="specialPrescriptionRecord.special_prescription.cover_image"
        />
        <view class="flex-1 m-l-16">
          <view class="fs-28 font-bold text-gray">
            {{ (specialPrescriptionRecord.special_prescription && specialPrescriptionRecord.special_prescription.name) || '特色方' }}
          </view>
          <view class="fs-24 color-sub">
            剂量：{{ specialPrescriptionRecord.dose_count }} 剂
          </view>
          <view class="fs-24 color-sub">
            规格：{{ specialPrescriptionPurchaseLabel }}
          </view>
          <view class="">
            <u-tag
              v-if="Number(specialPrescriptionRecord.status) === 0"
              text="待导入"
              type="warning"
              size="mini"
            />
            <u-tag
              v-else-if="Number(specialPrescriptionRecord.status) === 1"
              text="已应用"
              type="success"
              size="mini"
            />
            <u-tag v-else text="已完成" type="info" size="mini" />
          </view>
        </view>
      </view>
      <view class="special-rx-card__action m-t-16">
        <u-button
          size="default"
          type="primary"
          :loading="applyingSpecialPrescription"
          :custom-style="{ backgroundColor: '#6ACDBB', color: '#fff', border: 'none', width: '100%' }"
          @click="handleApplySpecialPrescription"
        >
          导入
        </u-button>
      </view>
    </view>

    <view v-if="!isSalespersonTransferMode && allowInsuranceCategory" class="mx-32 m-t-12 flex flex-ali-center">
      <u-button size="mini" :type="feeCategory === 1 ? 'success' : 'default'" @click="feeCategory = 1">自费</u-button>
      <u-button size="mini" class="m-l-16" :type="feeCategory === 2 ? 'success' : 'default'" @click="feeCategory = 2">医保</u-button>
    </view>

    <view v-if="!isSalespersonTransferMode && activeCategory === 1 && hasSalespersonTransfer" class="mx-32 m-t-12">
      <u-button size="mini" type="primary" plain @click="openSalespersonTransfer">查看传方</u-button>
    </view>

    <!-- 诊断输入区域（传方模式不展示） -->
    <view v-if="!isSalespersonTransferMode" class="top white p-32 flex-col m-t-16 radius-12 mx-32">
      <view class="top_title flex-row flex-ali-center">
        <image :src="require('@/static/image/js.png')" class="size-32"></image>
        <d-text text="临床诊断" className="fs-32 m-l-16 font-bold" color="#333"></d-text>
      </view>
      <view class="m-t-16 flex flex-wrap">
        <view class="m-r-16 m-t-16" v-for="(item, i) in diagnoses" :key="item.id">
          <u-tag
              shape="circle"
              :text="item.name"
              bg-color="#E8F6F4"
              color="#6ACDBB"
              border-color="#E8F6F4"
              close-color="#6ACDBB"
              :closeable="true"
              @close="handleRemoveDiagnosis(i)" />
        </view>
      </view>
      <view class="m-t-24">
        <u-input
            disabled
            placeholder="请选择或输入疾病诊断"
            :custom-style="illnessStyle"
            @click="handleOpenDiagnosisModal" />
      </view>
    </view>

    <!-- 滚动内容区域 -->
    <scroll-view :style="scrollStyle" scroll-y="true">

      <!-- 在线复诊 + 中药：证候/治法/中医疾病（接口 diseases_id、method_id、syndrome_id，与 PC 在线问诊处方一致） -->
      <view v-if="activeCategory === 1 && isOnlineRevisit" class="white p-32 radius-12 mx-32 m-t-24 flex-col">
        <view class="top_title flex-row flex-ali-center m-b-16">
          <image :src="require('@/static/image/js.png')" class="size-32"></image>
          <d-text text="中医辨证" className="fs-32 m-l-16 font-bold" color="#333"></d-text>
        </view>
        <view class="m-t-8">
          <d-text text="中医证候" className="fs-26 color-sub"></d-text>
          <u-input
              disabled
              :value="onlineTcmDiseasesLabel"
              placeholder="请点击选择中医证候"
              :custom-style="illnessStyle"
              class="m-t-8"
              @click="handleOpenTcmPicker('diseases')" />
        </view>
        <view class="m-t-24">
          <d-text text="中医治法" className="fs-26 color-sub"></d-text>
          <u-input
              disabled
              :value="onlineTcmMethodLabel"
              placeholder="请点击选择中医治法"
              :custom-style="illnessStyle"
              class="m-t-8"
              @click="handleOpenTcmPicker('method')" />
        </view>
        <view class="m-t-24">
          <d-text text="中医疾病" className="fs-26 color-sub"></d-text>
          <u-input
              disabled
              :value="onlineTcmSyndromeLabel"
              placeholder="请点击选择中医疾病"
              :custom-style="illnessStyle"
              class="m-t-8"
              @click="handleOpenTcmPicker('syndrome')" />
        </view>
      </view>

      <!-- 西药列表 -->
      <view class="mx-32 m-t-24" v-if="activeCategory === 2">
        <view class="flex-row flex-jus-sp flex-ali-center m-b-24">
          <view class="flex-row flex-ali-center">
            <view class="rp-icon">Rp</view>
            <text class="fs-28 text-gray m-l-8">西药处方</text>
          </view>
          <view class="flex-row" style="height: 50rpx;">
            <u-button
                v-if="!isCommonPrescription && supportsCommonPrescriptionTemplate"
                :throttle-time="0"
                shape="circle"
                size="mini"
                :custom-style="{backgroundColor: 'transparent !important',border:'1px solid #6ACDBB',color:'#6ACDBB'}"
                plain
                @click="handleOpenCommonPrescriptionModal"
                :ripple="true">
              常用方
            </u-button>
            <view v-if="!isSpecialPrescriptionCartLocked" class="m-l-16">
              <u-button
                  :throttle-time="0"
                  shape="circle"
                  size="mini"
                  :custom-style="{ backgroundColor:'#6ACDBB',color:'#fff', border: 'none' }"
                  @click="handleOpenWesternMedicineModal">
                <u-icon name="plus" size="22" class="m-r-4"></u-icon> 添加药品
              </u-button>
            </view>
          </view>
        </view>

        <!-- 西药卡片设计 -->
        <view class="medicine-card" v-for="(item, index) in currentDrugs" :key="item.index_id">
          <view class="flex-row">
            <image
                v-if="item.image"
                :src="item.image"
                class="drug-image-modern"
                mode="aspectFill"
            ></image>
            <view class="flex-1 m-l-24 flex-col">
              <view class="flex-row flex-jus-sp flex-ali-start">
                <text class="fs-30 font-bold color-title line-clamp-2 w-70">{{index+1}}. {{item.drug_name}}</text>
                <text class="fs-32 font-bold color-price">￥{{parseFloat(item.price || 0).toFixed(2)}}</text>
              </view>
              <view class="flex-row flex-jus-sp flex-ali-center m-t-12">
                <text class="fs-24 color-sub">规格：{{item.specification || '--'}}</text>
                <text class="fs-26 color-title font-bold">×{{item.select_number || item.number}}盒</text>
              </view>
              <view class="m-t-16 usage-capsule">
                <u-icon name="info-circle" size="24" color="#6ACDBB" class="m-r-8"></u-icon>
                <text class="fs-24" style="color:#008771">{{formatDrugUsage(item) || '请设置用法用量'}}</text>
              </view>
            </view>
          </view>
          <!-- 内敛的卡片操作区 -->
          <view class="card-actions flex-row flex-jus-sp flex-ali-center">
            <view v-if="!isSpecialPrescriptionCartLocked" class="action-btn-text danger" @click="handleRemoveDrug(index)">
              <u-icon name="trash" size="28"></u-icon> 删除
            </view>
            <view v-if="!isSpecialPrescriptionCartLocked" class="action-btn-ghost primary" @click="handleEditWesternDrug(item, index)">
              调整用量
            </view>
          </view>
        </view>

        <view class="white p-32 radius-12 m-t-24 flex-col" v-if="currentDrugs.length > 0 && !isSalespersonTransferMode">
          <view class="flex-jus-sp flex-row flex-ali-center">
            <d-text text="医嘱补充" color="#333" className="font-bold"></d-text>
            <d-text @click="handleOpenDoctorOrderModal" text="选择常用医嘱" color="#6ACDBB"></d-text>
          </view>
          <u-input v-model="medicalAdvice" placeholder="请输入医嘱注意事项..." :custom-style="entrustStyle" />
        </view>
        <view class="flex-row flex-jus-center m-t-64" v-if="currentDrugs.length === 0 && !isSpecialPrescriptionCartLocked">
          <d-empty @click="handleOpenWesternMedicineModal"></d-empty>
        </view>
      </view>

      <!-- 中药列表 -->
      <view class="mx-32 m-t-24" v-if="activeCategory === 1">
        <view class="flex-row flex-jus-sp flex-ali-center m-b-24">
          <view class="flex-row flex-ali-center">
            <view class="rp-icon">Rp</view>
            <text class="fs-28 text-gray m-l-8">中药处方</text>
          </view>
          <view class="flex-row" style="height: 50rpx;">
            <u-button
                v-if="!isSalespersonTransferMode && !isCommonPrescription && supportsCommonPrescriptionTemplate"
                :throttle-time="0"
                shape="circle"
                size="mini"
                :custom-style="{backgroundColor: 'transparent !important',border:'1px solid #6ACDBB',color:'#6ACDBB'}"
                plain
                @click="handleOpenCommonPrescriptionModal"
                :ripple="true">
              常用方
            </u-button>
            <view v-if="!isSpecialPrescriptionCartLocked" class="m-l-16">
              <u-button
                  :throttle-time="0"
                  :custom-style="{ backgroundColor:'#6ACDBB',color:'#fff', border: 'none' }"
                  shape="circle"
                  size="mini"
                  @click="handleOpenChineseMedicineModal">
                <u-icon name="plus" size="22" class="m-r-4"></u-icon> 添加药材
              </u-button>
            </view>
          </view>
        </view>

        <!-- 中药极简高密度标签云设计 -->
        <view class="white radius-12 p-32" v-if="currentDrugs.length > 0">
          <view class="flex-row flex-jus-sp flex-ali-center m-b-24">
            <view class="flex-col">
              <text class="fs-28 font-bold color-title">药材清单 (共{{currentDrugs.length}}味)</text>
              <text
                v-if="!isSpecialPrescriptionCartLocked"
                class="fs-22 text-gray m-t-4"
              >先煎/后下请在「选择中药」中设置</text>
            </view>
            <view class="flex-row">
              <template v-if="!isSpecialPrescriptionCartLocked">
                <text class="fs-26 color-primary m-r-32" @click="handleOpenChineseMedicineModal">修改剂量</text>
                <text class="fs-26 color-danger" @click="handleRemoveAllDrugs">清空</text>
              </template>
              <text
                v-else
                class="fs-26 color-danger"
                @click="handleClearPrescriptionCart"
              >清空药方</text>
            </view>
          </view>

          <view class="tcm-tag-cloud">
            <view
                class="tcm-tag"
                v-for="(it, tcmIndex) in currentDrugs"
                :key="tcmTagKey(it, tcmIndex)"
                :data-idx="tcmIndex"
                @longpress.stop="!isSpecialPrescriptionCartLocked && onTcmTagLongPress">
              <text class="tcm-name">{{it.drug_name || it.name}}</text>
              <text class="tcm-weight">{{String(it.number)}}{{it.unit ? it.unit.name : 'g'}}</text>
              <!-- 展示药材级先煎/后下（在选择中药弹窗设置） -->
              <text v-if="getTcmWayLabel(it)" class="tcm-way">{{ getTcmWayLabel(it) }}</text>
              <text
                v-if="seeRate == 1 && getChineseItemMargin(it) !== '--'"
                class="tcm-margin"
              >毛利率{{ getChineseItemMargin(it) }}%</text>
            </view>
          </view>
        </view>

        <view class="flex-row flex-jus-center m-t-64" v-else-if="!isSpecialPrescriptionCartLocked">
          <d-empty @click="handleOpenChineseMedicineModal"></d-empty>
        </view>
      </view>

      <!-- 简单产品列表（保健食品、产品服务包、非药品、医疗器械） -->
      <view class="mx-32 m-t-24" v-if="[3, 5, 6, 7].includes(activeCategory)">
        <view class="flex-row flex-jus-sp flex-ali-center m-b-24">
          <view class="flex-row flex-ali-center">
            <view class="rp-icon">Rp</view>
            <text class="fs-28 text-gray m-l-8">产品/器械</text>
          </view>
          <view class="flex-row m-l-163" style="height: 50rpx;">
            <view v-if="!isSpecialPrescriptionCartLocked" class="m-l-16">
              <u-button
                  :throttle-time="0"
                  :custom-style="{ backgroundColor:'#6ACDBB',color:'#fff', border: 'none' }"
                  shape="circle"
                  size="mini"
                  @click="handleOpenSimpleProductModal">
                <u-icon name="plus" size="22" class="m-r-4"></u-icon> 添加商品
              </u-button>
            </view>
          </view>
        </view>

        <!-- 简单产品卡片设计 -->
        <view class="medicine-card" v-for="(item, index) in currentDrugs" :key="item.index_id">
          <view class="flex-row">
            <image
                v-if="item.image"
                :src="item.image"
                class="drug-image-modern"
                mode="aspectFill"
            ></image>
            <view class="flex-1 m-l-24 flex-col">
              <view class="flex-row flex-jus-sp flex-ali-start">
                <text class="fs-30 font-bold color-title line-clamp-2 w-70">{{index+1}}. {{item.drug_name}}</text>
                <text class="fs-32 font-bold color-price">￥{{parseFloat(item.price || 0).toFixed(2)}}</text>
              </view>
              <view class="flex-row flex-jus-sp flex-ali-center m-t-12">
                <text class="fs-24 color-sub">规格：{{item.specification || '--'}}</text>

                <!-- 精致步进器 -->
                <view class="modern-stepper flex-row flex-ali-center">
                  <view class="stepper-btn" @click.stop="handleDecrementSimpleProduct(index)">-</view>
                  <text class="stepper-val fs-26">{{item.select_number || item.number}}{{getProductUnit(activeCategory)}}</text>
                  <view class="stepper-btn" @click.stop="handleIncrementSimpleProduct(index)">+</view>
                </view>
              </view>
            </view>
          </view>
          <view class="card-actions flex-row flex-jus-end">
            <view v-if="!isSpecialPrescriptionCartLocked" class="action-btn-text danger" @click="handleRemoveDrug(index)">
              <u-icon name="trash" size="28"></u-icon> 删除
            </view>
          </view>
        </view>

        <view class="white p-32 radius-12 m-t-24 flex-col" v-if="currentDrugs.length > 0 && !isSalespersonTransferMode">
          <view class="flex-jus-sp flex-row flex-ali-center">
            <d-text text="医嘱补充" color="#333" className="font-bold"></d-text>
            <d-text @click="handleOpenDoctorOrderModal" text="选择常用医嘱" color="#6ACDBB"></d-text>
          </view>
          <u-input v-model="medicalAdvice" placeholder="请输入注意事项..." :custom-style="entrustStyle" />
        </view>
        <view class="flex-row flex-jus-center m-t-64" v-if="currentDrugs.length === 0">
          <d-empty @click="handleOpenSimpleProductModal"></d-empty>
        </view>
      </view>

      <!-- 医嘱输入区域（传方模式不展示） -->
      <view class="flex-col white p-32 radius-12 mx-32 m-t-24" v-if="activeCategory === 1 && currentDrugs.length > 0 && !isSalespersonTransferMode">
        <view class="flex-jus-sp flex-row flex-ali-center">
          <d-text text="医嘱补充" color="#333" className="font-bold"></d-text>
          <d-text @click="handleOpenDoctorOrderModal" text="选择常用医嘱" color="#6ACDBB" />
        </view>
        <u-input
          v-model="medicalAdvice"
          placeholder="请输入服药注意事项..."
          :custom-style="entrustStyle"
        />
      </view>

      <!-- 中药配置区域 -->
      <view class="white radius-12 p-32 mx-32 m-t-24" v-if="activeCategory === 1">
        <ChineseMedicineConfig
            :config="chineseConfig"
            :disabled="isSpecialPrescriptionCartLocked"
            :processRuleList="processRuleList"
            :childProcessRuleList="childProcessRuleList"
            :processRuleNoteList="processRuleNoteList"
            @update:config="handleUpdateChineseConfig"
        />
      </view>

      <!-- 费用计算区域 -->
      <view class="fee-summary white radius-12 p-32 mx-32 m-t-24 m-b-40">
        <view v-if="isTransferFeeHidden" class="transfer-fee-hidden-tip flex-col">
          <text class="fs-28 color-title font-bold">本店已关闭推广员查看费用</text>
          <text class="fs-24 color-sub m-t-8">提交后由接诊医生确认价格</text>
        </view>
        <template v-else>
          <view v-if="!isSalespersonTransferMode" class="flex-row flex-jus-sp flex-ali-center m-b-24">
            <text class="fs-28 color-sub">诊疗费</text>
            <view class="flex-row flex-ali-center">
              <text class="fs-28 m-r-8">￥</text>
              <u-input
                  v-model="treatmentPrice"
                  placeholder="0.00"
                  input-align="right"
                  :custom-style="priceInputStyle" />
            </view>
          </view>

          <view
              v-if="!isSalespersonTransferMode && processingFee > 0"
              class="flex-row flex-jus-sp flex-ali-center m-b-24">
            <text class="fs-28 color-sub">加工费</text>
            <text class="fs-30 color-title font-bold">￥{{processingFee.toFixed(2)}}</text>
          </view>

          <view class="flex-row flex-jus-sp flex-ali-center m-b-32">
            <view class="flex-col">
              <text class="fs-28 color-sub">商品计费</text>
              <text
                v-if="grossMarginText"
                class="fs-24 color-primary m-t-8"
              >毛利率 {{ grossMarginText }}%</text>
            </view>
            <text
              v-if="canPreSendPriceAdjust"
              class="fs-30 color-title font-bold price-link"
              @click="openPreSendOrderPriceAdjust"
            >￥{{totalProductCost.toFixed(2)}}</text>
            <text v-else class="fs-30 color-title font-bold">￥{{totalProductCost.toFixed(2)}}</text>
          </view>

          <view
            v-if="canPreSendPriceAdjust && currentDrugs.length > 0"
            class="flex-row flex-jus-sp flex-ali-center m-b-24"
          >
            <text class="fs-26 color-sub">当前浮动：{{ preSendDiscountLabel || '无' }}</text>
            <text
              v-if="priceDiscount !== 100"
              class="fs-26 color-primary"
              @click="clearPreSendPriceDiscount"
            >清除浮动</text>
          </view>

          <view
              class="total-price-bar flex-row flex-jus-sp flex-ali-center pt-32 border-t-dashed"
              v-if="currentDrugs.length > 0">
            <text class="fs-30 font-bold color-title">合计</text>
            <text class="fs-48 font-bold color-price">￥{{totalPrice}}</text>
          </view>
        </template>
      </view>

      <!-- 提示信息（传方模式不展示） -->
      <view v-if="!isSalespersonTransferMode" class="ac p-b-40 p-x-32 flex-row flex-jus-center">
        <u-icon name="shield-check" color="#B0B6C2" size="28" class="m-r-8"></u-icon>
        <text class="fs-24 color-sub">请确认患者已在实体医院就诊，并有明确诊断</text>
      </view>
    </scroll-view>

    <!-- 底部操作栏 -->
    <view class="bottom flex-jus-sp flex-ali-center safe-area-inset-bottom">
      <view
        v-if="!isSalespersonTransferMode && !isCommonPrescription && supportsCommonPrescriptionTemplate"
        class="flex-row flex-ali-center"
      >
        <view @click="handleSaveAsCommonPrescription" class="btnText">另存常用方</view>
      </view>
      <u-button
          :throttle-time="0"
          @click="handleSendPrescription"
          shape="circle"
          :custom-style="{
          backgroundColor: isSubmitting ? '#A5DCD2' : '#6ACDBB',
          color: '#fff',
          height: '86rpx',
          width: bottomSendBtnWidth
        }"
          :disabled="isSubmitting">
        {{ isCommonPrescription ? '保存常用方' : (isSalespersonTransferMode ? '提交传方' : '发送处方') }}
      </u-button>
    </view>

    <TraditionalTermPickerModal
        v-model="showTcmPicker"
        :title="tcmPickerTitle"
        :options="tcmPickerList"
        :selected-id="tcmPickerCurrentSelectedId"
        @confirm="handleTcmPickerConfirm"
    />

    <!-- 诊断选择弹窗 -->
    <DiagnosisModal
        v-model="showDiagnosisModal"
        :selectedDiagnosis="diagnosisText"
        :salesperson-transfer-mode="isSalespersonTransferMode"
        @confirm="handleDiagnosisConfirm"
    />

    <!-- 医嘱选择弹窗 -->
    <DoctorOrderModal
        v-model="showDoctorOrderModal"
        :selectedDoctorOrder="medicalAdvice"
        @confirm="handleDoctorOrderConfirm"
    />

    <!-- 常用方选择弹窗 -->
    <CommonPrescriptionModal
        v-model="showCommonPrescriptionModal"
        :prescriptionType="activeCategory"
        @select="handleSelectCommonPrescription"
    />

    <!-- 西药选择弹窗 -->
    <WesternMedicineModal
        v-model="showWesternMedicineModal"
        :currentDrugs="currentDrugs"
        :initial-search-key="westernModalInitialKeyword"
        @select="handleSelectWesternDrug"
    />

    <!-- 中药选择弹窗 -->
    <ChineseMedicineModal
        v-model="showChineseMedicineModal"
        :currentDrugs="currentDrugs"
        :initial-search-key="chineseModalInitialKeyword"
        :register-id="registerId"
        :see-rate="seeRate"
        :salesperson-transfer-mode="isSalespersonTransferMode"
        :show-drug-price="showSalespersonTransferPrice"
        :drug-use-way-list="drugUseList.drug_use_way || []"
        @select="handleSelectChineseDrug"
    />

    <TransferPatientDrawer
        v-model="showTransferPatientDrawer"
        :submitting="transferDrawerSubmitting"
        ref="transferPatientDrawer"
        @confirm="handleTransferPatientConfirm"
    />

    <!-- 在线复诊：卡片选配送仓 -->
    <WarehouseSelectDrawer
        v-model="showWarehouseSelectDrawer"
        :rows="warehouseSelectRows"
        @confirm="onWarehouseSelectConfirm"
        @cancel="onWarehouseSelectCancel"
    />

    <!-- 简单产品选择弹窗 -->
    <SimpleProductModal
        v-model="showSimpleProductModal"
        :productType="activeCategory"
        :currentProducts="currentDrugs"
        @select="handleSelectSimpleProduct"
    />

    <!-- 西药用法用量设置弹窗 -->
    <WesternMedicineUsageModal
        v-model="showWesternUsageModal"
        :drug="editingDrug"
        @confirm="handleConfirmWesternUsage"
    />

    <!-- 保存常用方弹窗 -->
    <u-modal
        v-model="showSaveCommonPrescriptionModal"
        :show-cancel-button="true"
        :mask-close-able="true"
        title="保存常用方"
        @confirm="handleConfirmSaveCommonPrescription"
        @cancel="showSaveCommonPrescriptionModal = false">
      <view class="slot-content" style="padding: 20rpx;">
        <u-input
            v-model="commonPrescriptionName"
            placeholder="请输入处方名称"
            type="text"
            :border="true" />
      </view>
    </u-modal>

    <order-price-percent-adjust-popup
      :visible="priceAdjustVisible"
      :current-discount="priceDiscount"
      :quick-options="priceAdjustQuickOptions"
      @close="closePreSendPriceAdjust"
      @confirm="onPreSendPriceAdjustConfirm"
    />
  </view>
</template>

<script>
// 注意：这部分保持你原有的逻辑代码，不进行任何修改，确保业务完全正常
import {
  addWestPrescription,
  getDeliveryWarehouseOptionsByDrugs,
  checkChineseMedicineConflictApi,
  getDiseaseList,
  getDrugUseList,
  getProductListDoctorReception,
  getPatientInfoByPatientId,
  getPatientItem,
  applySpecialPrescriptionApi,
  getProcessRuleList,
  getCommonPrescriptionListApi,
  saveWestCommonPrescriptionApi,
  saveChineseCommonPrescriptionApi,
  getCurrentStoreTypeApi,
  getPriceAdjustConfigApi,
  getSalespersonTransferByRegisterApi,
  getPrescriptionInfoApi,
  getTraditionalChineseMedicineJson
} from '@/api/reception.js';
import { parseTransferPrescriptionContent } from '@/subPackages/sub_online_reception/utils/transferPrescriptionImport.js';
import { getChatRoomByRegisterApi, sendToUserHttpApi } from '@/api/chat.js';
import { PrescriptionStorage } from './utils/prescriptionStorage.js';
import { PrescriptionCalculator } from './utils/prescriptionCalculator.js';
import { PrescriptionValidator } from './utils/prescriptionValidator.js';
import DiagnosisModal from './components/modals/DiagnosisModal.vue';
import DoctorOrderModal from './components/modals/DoctorOrderModal.vue';
import CommonPrescriptionModal from './components/modals/CommonPrescriptionModal.vue';
import WesternMedicineModal from './components/modals/WesternMedicineModal.vue';
import ChineseMedicineModal from './components/modals/ChineseMedicineModal.vue';
import SimpleProductModal from './components/modals/SimpleProductModal.vue';
import WesternMedicineUsageModal from './components/modals/WesternMedicineUsageModal.vue';
import ChineseMedicineConfig from './components/ChineseMedicineConfig.vue';
import TraditionalTermPickerModal from './components/modals/TraditionalTermPickerModal.vue';
import TransferPatientDrawer from './components/modals/TransferPatientDrawer.vue';
import WarehouseSelectDrawer from './components/modals/WarehouseSelectDrawer.vue';
import OrderPricePercentAdjustPopup from '@/subPackages/sub_business_shared/components/OrderPricePercentAdjustPopup.vue';
import { applyRatioToDrugs, formatPriceDiscountLabel, normalizeQuickOptions } from '@/subPackages/sub_business_shared/common/pricePercentAdjust.js';
import {
  createClinicSalespersonTransferPrescription,
  getClinicSalespersonSeePriceConfig,
  getClinicSalespersonProcessRuleList,
} from '@/api/clinicSalesperson.js';
import {
  pickSpecialPrescriptionRecord,
  applySpecialPrescriptionPayload,
  resolveSpecialPrescriptionPurchaseLabel,
  clearAppliedSpecialPrescription,
  isSpecialPrescriptionCartLocked,
  guardSpecialPrescriptionCartEdit,
} from './utils/specialPrescription.js';

const PENDING_RX_FROM_CHAT = 'xk_pending_rx_from_chat';
const SALESPERSON_TRANSFER_STORAGE_KEY = 'salesperson_transfer';
const SALESPERSON_HOME_URL = '/subPackages/sub_clinic_salesperson/home/index';

/** 与 closeTopOverlayIfAny 一致：任意为 true 时启用微信小程序 page-container 返回拦截 */
const PRESCRIPTION_OVERLAY_KEYS = [
  'showWesternUsageModal',
  'showTcmPicker',
  'showWesternMedicineModal',
  'showChineseMedicineModal',
  'showSimpleProductModal',
  'showCommonPrescriptionModal',
  'showDiagnosisModal',
  'showDoctorOrderModal',
  'showSaveCommonPrescriptionModal',
  'showTransferPatientDrawer',
  'showWarehouseSelectDrawer',
];

export default {
  name: 'PrescriptionV2',
  components: {
    DiagnosisModal,
    DoctorOrderModal,
    CommonPrescriptionModal,
    WesternMedicineModal,
    ChineseMedicineModal,
    SimpleProductModal,
    WesternMedicineUsageModal,
    ChineseMedicineConfig,
    TraditionalTermPickerModal,
    TransferPatientDrawer,
    WarehouseSelectDrawer,
    OrderPricePercentAdjustPopup,
  },
  data() {
    return {
      registerId: '',
      patientId: '',
      pendingReusePrescriptionId: '',
      patientInfo: null,
      prescriptionCategories: [
        { label: '中药', value: 1 },
        { label: '西（中成）药', value: 2 },
        { label: '保健食品', value: 3 },
        { label: '产品服务包', value: 5 },
        { label: '非药品', value: 6 },
        { label: '医疗器械', value: 7 }
      ],
      activeCategory: 2,
      currentDrugs: [],
      diagnoses: [],
      diagnosisText: '',
      medicalAdvice: '',
      treatmentPrice: '',
      chineseConfig: {
        ruleType: 1,
        packageMethodId: null,
        processRuleId: null,
        childProcessRuleId: null,
        processRuleNoteId: null,
        dosage: 7,
        dayDosage: 2
      },
      processRuleList: [],
      childProcessRuleList: [],
      processRuleNoteList: [],
      drugUseList: {
        drug_use_num: [],
        drug_use_frequency: [],
        drug_use_type: [],
        drug_unit: [],
        drug_time: [],
        drug_use_way: []
      },
      showDiagnosisModal: false,
      showDoctorOrderModal: false,
      showCommonPrescriptionModal: false,
      showWesternMedicineModal: false,
      westernModalInitialKeyword: '',
      showChineseMedicineModal: false,
      chineseModalInitialKeyword: '',
      showSimpleProductModal: false,
      showWesternUsageModal: false,
      showSaveCommonPrescriptionModal: false,
      editingDrug: null,
      editingDrugIndex: -1,
      commonPrescriptionName: '',
      isCommonPrescription: false,
      _presetActiveCategory: null,
      /** URL/传方指定了分类时，禁止被诊所类型默认覆盖 */
      _categoryLockedByQuery: false,
      isSubmitting: false,
      identity: uni.getStorageSync('role'),
      registerStoreInfo: null,
      feeCategory: 1,
      salespersonTransferPrescriptionId: 0,
      hasSalespersonTransfer: false,
      /** 是否可查看毛利率 0/1（xk-api see_rate） */
      seeRate: 0,
      enableOrderPricePercentAdjust: 0,
      priceAdjustVisible: false,
      priceDiscount: 100,
      priceAdjustQuickOptions: [],
      priceAdjustScopeMode: 'sale_only',
      sendMode: 0,
      selectedStoreId: null,
      registerOrderType: null,
      specialPrescriptionRecord: null,
      applyingSpecialPrescription: false,
      pendingImportSpecial: false,
      /** 医生已导入的特色方 ID，仅 >0 时提交走特色方计价 */
      appliedSpecialPrescriptionId: 0,
      appliedSpecialPrescriptionFreeShipping: false,
      /** 特色方 apply 返回的套餐/贴数总价，用于底部合计 */
      appliedSpecialPrescriptionExpectedTotal: null,

      /** 在线复诊中药：术语表（HTTP 拉取，内存缓存） */
      traditionalTcmData: null,
      traditionalTcmLoadPromise: null,
      showTcmPicker: false,
      tcmPickerTitle: '',
      tcmPickerField: '',
      tcmPickerList: [],
      /** 与 PC prescriptionStore 提交字段一致：diseases_id←证候(diseases)；method_id←治法；syndrome_id←中医疾病(syndrome) */
      onlineTcmDiseasesId: null,
      onlineTcmMethodId: null,
      onlineTcmSyndromeId: null,

      // UI Styles
      tabsBtnStyle: {
        padding: '8rpx 32rpx',
        height: '60rpx',
        fontSize: '28rpx',
        borderRadius: '30rpx'
      },
      illnessStyle: {
        fontSize: '28rpx',
        backgroundColor: '#F7F8FA',
        borderRadius: '16rpx',
        height: '76rpx',
        padding: '0 32rpx'
      },
      entrustStyle: {
        fontSize: '28rpx',
        backgroundColor: '#F7F8FA',
        height: '80rpx',
        padding: '0 24rpx',
        borderRadius: '12rpx',
        marginTop: '20rpx'
      },
      priceInputStyle: {
        fontSize: '32rpx',
        fontWeight: 'bold',
        color: '#333',
        width: '160rpx',
        height: '60rpx',
        backgroundColor: '#F7F8FA',
        borderRadius: '8rpx',
        padding: '0 16rpx'
      },
      /** 微信小程序 page-container：有抽屉/弹层时为 true，拦截侧滑等返回 */
      pageBackGuardShow: false,
      /** 程序化隐藏 page-container 时抑制 @leave，避免误触发页面退出确认 */
      _suppressPageBackGuardLeave: false,
      /** 推广员传方模式 */
      isSalespersonTransferMode: false,
      /** 推广员是否可查看售价 0/1（门店 salesperson see_price） */
      salespersonSeePrice: 0,
      showTransferPatientDrawer: false,
      transferDrawerSubmitting: false,
      /** 在线复诊选仓抽屉 */
      showWarehouseSelectDrawer: false,
      warehouseSelectRows: [],
      /** resolvePharmacyWarehouseMap 的 Promise resolve；false=取消，null=无需选，map=已选 */
      _warehouseSelectResolve: null,
    };
  },
  computed: {
    allowInsuranceCategory() {
      return Number(this.registerStoreInfo?.allow_insurance_category ?? 0) === 1;
    },
    canPreSendPriceAdjust() {
      return Number(this.enableOrderPricePercentAdjust) === 1
        && this.currentDrugs.length > 0
        && !this.isSpecialPrescriptionCartLocked;
    },
    preSendDiscountLabel() {
      return formatPriceDiscountLabel(this.priceDiscount);
    },
    effectivePriceAdjustStoreId() {
      return this.selectedStoreId
        || this.registerStoreInfo?.store_id
        || uni.getStorageSync('store_id')
        || null;
    },
    totalProductCost() {
      if (this.currentDrugs.length === 0) return 0;
      if (this.activeCategory === 1) {
        return PrescriptionCalculator.calculateChineseMedicineProductPrice(this.currentDrugs, this.chineseConfig.dosage);
      } else if (this.activeCategory === 2) {
        return PrescriptionCalculator.calculateWesternMedicineProductPrice(this.currentDrugs);
      } else if ([3, 5, 6, 7].includes(this.activeCategory)) {
        return PrescriptionCalculator.calculateSimpleProductPrice(this.currentDrugs);
      }
      return 0;
    },
    processingFee() {
      if (this.activeCategory !== 1 || this.chineseConfig.ruleType !== 2) return 0;
      const processRule = this.childProcessRuleList.find(item => item.id === this.chineseConfig.childProcessRuleId);
      if (!processRule) return 0;
      const totalDrugQuantity = this.currentDrugs.reduce((sum, drug) => sum + parseFloat(drug.number || 1), 0);
      return PrescriptionCalculator.calculateProcessingFee(processRule, this.chineseConfig.dosage, totalDrugQuantity);
    },
    totalPrice() {
      const expected = this.appliedSpecialPrescriptionExpectedTotal;
      if (expected != null && !Number.isNaN(Number(expected)) && Number(expected) > 0) {
        const base = parseFloat(expected);
        const fee = parseFloat(this.treatmentPrice || 0);
        const process = this.activeCategory === 1 ? parseFloat(this.processingFee || 0) : 0;
        return (base + fee + process).toFixed(2);
      }
      const total = PrescriptionCalculator.calculateTotalPrice({
        category: this.activeCategory,
        drugs: this.currentDrugs,
        dosage: this.chineseConfig.dosage,
        processingFee: this.processingFee,
        treatmentPrice: parseFloat(this.treatmentPrice || 0)
      });
      return total.toFixed(2);
    },
    grossMarginText() {
      if (this.activeCategory !== 1 || Number(this.seeRate) !== 1) {
        return '';
      }
      return PrescriptionCalculator.calculateChineseTotalGrossMarginPercent(
        this.currentDrugs,
        this.chineseConfig.dosage
      );
    },
    showSalespersonTransferPrice() {
      return !this.isSalespersonTransferMode || Number(this.salespersonSeePrice) === 1;
    },
    isTransferFeeHidden() {
      return this.isSalespersonTransferMode && Number(this.salespersonSeePrice) === 0;
    },
    supportsCommonPrescriptionTemplate() {
      return [1, 2].includes(this.activeCategory);
    },
    isOnlineRevisit() {
      const t = Number(this.registerOrderType);
      return t === 2 || t === 3;
    },
    registerModeHint() {
      if (this.registerOrderType === null || this.registerOrderType === undefined || this.registerOrderType === '') return '';
      return this.isOnlineRevisit ? '当前：在线复诊开方（提交后将向患者发送处方消息）' : '当前：线下开方';
    },
    hasSpecialPrescriptionRecord() {
      return !!this.specialPrescriptionRecord;
    },
    /** 导入卡片：SKU 名或单剂 */
    specialPrescriptionPurchaseLabel() {
      return resolveSpecialPrescriptionPurchaseLabel(this.specialPrescriptionRecord);
    },
    /** 已导入特色方时锁定药方不可编辑 */
    isSpecialPrescriptionCartLocked() {
      return isSpecialPrescriptionCartLocked(this);
    },
    /** 底部发送按钮宽度（左侧仅「另存常用方」时需留出空间） */
    bottomSendBtnWidth() {
      if (this.isSalespersonTransferMode || this.isCommonPrescription) {
        return '686rpx';
      }
      if (this.supportsCommonPrescriptionTemplate) {
        return '400rpx';
      }
      return '686rpx';
    },
    navbarTitle() {
      if (this.isSalespersonTransferMode) {
        return '传方';
      }
      if (this.registerOrderType === null || this.registerOrderType === undefined || this.registerOrderType === '') {
        return '开方';
      }
      return this.isOnlineRevisit ? '开方 · 在线复诊' : '开方 · 线下';
    },
    hasTransferDraft() {
      if (!this.isSalespersonTransferMode) return false;
      return this.currentDrugs.length > 0
        || this.diagnoses.length > 0
        || !!(this.medicalAdvice && String(this.medicalAdvice).trim());
    },
    shouldEnablePageBackGuard() {
      return this.hasPrescriptionOverlay;
    },
    scrollStyle() {
      try {
        const sys = uni.getSystemInfoSync();
        const rpxRatio = sys.windowWidth / 750;
        const topRpx = this.isSalespersonTransferMode ? 500 : 600;
        const bottomRpx = 200;
        const heightPx = sys.windowHeight - topRpx * rpxRatio - bottomRpx * rpxRatio;
        return {
          height: `${Math.max(Math.floor(heightPx), 200)}px`,
          marginBottom: '200rpx',
        };
      } catch (e) {
        const topRpx = this.isSalespersonTransferMode ? 500 : 600;
        return {
          height: `calc(100vh - ${topRpx}rpx)`,
          marginBottom: '200rpx',
        };
      }
    },
    onlineTcmDiseasesLabel() {
      const data = this.traditionalTcmData;
      const id = this.onlineTcmDiseasesId;
      if (!data || id == null || id === '') return '';
      const row = (data.diseases || []).find((x) => Number(x.id) === Number(id));
      return row ? row.name : '';
    },
    onlineTcmMethodLabel() {
      const data = this.traditionalTcmData;
      const id = this.onlineTcmMethodId;
      if (!data || id == null || id === '') return '';
      const row = (data.method || []).find((x) => Number(x.id) === Number(id));
      return row ? row.name : '';
    },
    onlineTcmSyndromeLabel() {
      const data = this.traditionalTcmData;
      const id = this.onlineTcmSyndromeId;
      if (!data || id == null || id === '') return '';
      const row = (data.syndrome || []).find((x) => Number(x.id) === Number(id));
      return row ? row.name : '';
    },
    tcmPickerCurrentSelectedId() {
      if (this.tcmPickerField === 'diseases') return this.onlineTcmDiseasesId;
      if (this.tcmPickerField === 'method') return this.onlineTcmMethodId;
      if (this.tcmPickerField === 'syndrome') return this.onlineTcmSyndromeId;
      return null;
    },
    hasPrescriptionOverlay() {
      for (let i = 0; i < PRESCRIPTION_OVERLAY_KEYS.length; i++) {
        if (this[PRESCRIPTION_OVERLAY_KEYS[i]]) return true;
      }
      return false;
    }
  },
  watch: {
    showWesternMedicineModal(val) {
      if (!val) this.westernModalInitialKeyword = '';
    },
    showChineseMedicineModal(val) {
      if (!val) this.chineseModalInitialKeyword = '';
    },
    // #ifdef MP-WEIXIN
    shouldEnablePageBackGuard(val) {
      this.setPageBackGuardShow(!!val, { suppressLeave: !val });
      this.syncSalespersonTransferUnloadAlert();
    },
    hasTransferDraft() {
      this.syncSalespersonTransferUnloadAlert();
    },
    // #endif
  },
  created() {
    // u-navbar 在小程序内 bind($parent) 可能拿不到页面实例，用箭头函数固定 this
    this.boundCustomBack = () => this.handleCustomBack();
  },
  onLoad(options) {
    this.isSalespersonTransferMode = String(options.salesperson_transfer) === '1';
    if (this.isSalespersonTransferMode) {
      this.registerId = SALESPERSON_TRANSFER_STORAGE_KEY;
      this._presetActiveCategory = 1;
      this._categoryLockedByQuery = true;
      // 传方模式默认自制剂 + 剂包
      this.chineseConfig = {
        ...this.chineseConfig,
        ruleType: 1,
        packageMethodId: 2,
      };
    } else {
      this.registerId = options.register_id || '';
    }
    this.patientId = options.patient_id || '';
    this.pendingReusePrescriptionId = options.reuse_prescription_id ? String(options.reuse_prescription_id) : '';
    this.pendingImportSpecial = String(options.import_special) === '1';
    this.isCommonPrescription = String(options.save_common) === '1';
    if (!this.isCommonPrescription) {
      uni.removeStorageSync('add');
    }
    if (options.initial_category !== undefined && options.initial_category !== '') {
      const n = parseInt(options.initial_category, 10);
      if (!Number.isNaN(n)) {
        this._presetActiveCategory = n;
        this._categoryLockedByQuery = true;
      }
    }
    this.initializePageData();
  },
  async onShow() {
    this.loadCurrentCategoryDrugs();
    if (this.activeCategory === 1 && this.chineseConfig.ruleType === 2) {
      await this.hydrateChineseProcessRuleListsFromConfig();
    }
    if (!this.isSalespersonTransferMode && this.activeCategory === 1) {
      await this.checkAndShowTransferTip();
    }
  },
  onUnload() {
    if (this.isCommonPrescription) {
      uni.removeStorageSync('add');
    }
    // #ifdef MP-WEIXIN
    if (this.isSalespersonTransferMode) {
      uni.disableAlertBeforeUnload();
    }
    // #endif
  },
  methods: {
    // #ifdef MP-WEIXIN
    setPageBackGuardShow(show, { suppressLeave = false } = {}) {
      if (suppressLeave) this._suppressPageBackGuardLeave = true;
      this.pageBackGuardShow = !!show;
    },
    syncSalespersonTransferUnloadAlert() {
      if (!this.isSalespersonTransferMode) return;
      if (this.hasTransferDraft && !this.hasPrescriptionOverlay) {
        uni.enableAlertBeforeUnload({ message: '有未提交的传方内容，确定退出？' });
      } else {
        uni.disableAlertBeforeUnload();
      }
    },
    // #endif
    async initializePageData() {
      try {
        this.restoreFromLocalStorage();
        if (this.isSalespersonTransferMode) {
          await this.loadSalespersonTransferConfig();
          await this.loadBasicConfigDataForTransfer();
        } else {
          await this.loadPatientInfo();
          await this.loadRegisterOrderType();
          await this.loadBasicConfigData();
          await this.loadRegisterStoreInfo();
          // 无 URL/上次切换/草稿时，按诊所类型兜底中药或西药 Tab
          this.applyDefaultCategoryByClinicType();
        }
        this.loadCurrentCategoryDrugs();
        if (this.activeCategory === 1 && this.chineseConfig.ruleType === 2) {
          await this.hydrateChineseProcessRuleListsFromConfig();
        }
        if (this.isSalespersonTransferMode) {
          this.ensureSalespersonTransferPackageMethodDefault();
        }
        if (!this.isSalespersonTransferMode) {
          await this.maybeApplyReusePrescription();
          if (this.activeCategory === 1) await this.checkAndShowTransferTip();
          this.applyPendingExperienceDrugFromChat();
          if (this.pendingImportSpecial && this.hasSpecialPrescriptionRecord) {
            await this.handleApplySpecialPrescription();
            this.pendingImportSpecial = false;
          }
        }
        // #ifdef MP-WEIXIN
        this.$nextTick(() => {
          this.setPageBackGuardShow(this.shouldEnablePageBackGuard);
          this.syncSalespersonTransferUnloadAlert();
        });
        // #endif
      } catch (error) {
        console.error('初始化页面数据失败:', error);
        this.$toast('初始化失败，请重试');
      }
    },
    async loadSalespersonTransferConfig() {
      try {
        const wrap = await getClinicSalespersonSeePriceConfig();
        if (wrap && wrap.ok) {
          this.salespersonSeePrice = Number(wrap.data?.see_price ?? 0);
        }
      } catch (error) {
        console.error('获取推广员价格配置失败:', error);
      }
    },
    async loadBasicConfigDataForTransfer() {
      try {
        if (this.activeCategory === 1 && this.processRuleList.length === 0) {
          await this.loadProcessRuleList(0, 0);
        }
      } catch (error) {
        console.error('加载基础配置数据失败:', error);
      }
    },
    /**
     * 传方模式：草稿未保存包法时默认剂包（id=2）
     */
    ensureSalespersonTransferPackageMethodDefault() {
      if (!this.isSalespersonTransferMode || this.activeCategory !== 1) return;
      if (!this.chineseConfig.packageMethodId) {
        this.chineseConfig = {
          ...this.chineseConfig,
          ruleType: 1,
          packageMethodId: 2,
        };
      }
    },
    restoreFromLocalStorage() {
      if (this._presetActiveCategory !== null && this._presetActiveCategory !== undefined && !Number.isNaN(this._presetActiveCategory)) {
        this.activeCategory = this._presetActiveCategory;
        this._presetActiveCategory = null;
        // 保留 _categoryLockedByQuery，避免随后被诊所类型默认覆盖
        return;
      }
      const savedCategory = PrescriptionStorage.getActiveCategory(this.registerId);
      if (savedCategory) {
        this.activeCategory = savedCategory;
      } else {
        const categories = [1, 2, 3, 5, 6, 7];
        for (const category of categories) {
          const data = PrescriptionStorage.loadPrescriptionData(category, this.registerId);
          if (data && data.drugs && data.drugs.length > 0) {
            this.activeCategory = category;
            break;
          }
        }
      }
    },
    /**
     * 开方默认 Tab 兜底：仅当无 URL 锁定、无上次切换分类、无任何药品草稿时，
     * 按诊所类型设中药(1)/西药(2)。优先级：URL > 上次切换 > 草稿 > clinic_type
     */
    applyDefaultCategoryByClinicType() {
      if (this.isSalespersonTransferMode || this._categoryLockedByQuery) return;
      if (!this.registerId) return;
      // 最后切换的分类优先，不再用诊所类型覆盖
      if (PrescriptionStorage.getActiveCategory(this.registerId)) return;
      // 任一类有草稿则沿用 restore 结果
      if (PrescriptionStorage.hasDraftWithDrugs(this.registerId)) return;
      const clinicType = Number(this.registerStoreInfo?.clinic_type ?? 0);
      let next = 0;
      if (clinicType === 2) {
        next = 1; // 中医诊所 → 中药
      } else if (clinicType === 1) {
        next = 2; // 西医诊所 → 西（中成）药
      }
      if (!next || next === this.activeCategory) return;
      this.activeCategory = next;
      PrescriptionStorage.saveActiveCategory(next, this.registerId);
    },
    loadCurrentCategoryDrugs() {
      const data = PrescriptionStorage.loadPrescriptionData(this.activeCategory, this.registerId);
      if (data) {
        this.currentDrugs = data.drugs || [];
        this.diagnoses = data.diagnoses || [];
        this.diagnosisText = data.diagnosisText || '';
        this.medicalAdvice = data.medicalAdvice || '';
        this.treatmentPrice = data.treatmentPrice || '';
        if (data.chineseConfig) this.chineseConfig = { ...this.chineseConfig, ...data.chineseConfig };
        if (this.activeCategory === 1) {
          if (data.onlineTcmDiseasesId !== undefined && data.onlineTcmDiseasesId !== null) this.onlineTcmDiseasesId = data.onlineTcmDiseasesId;
          else this.onlineTcmDiseasesId = null;
          if (data.onlineTcmMethodId !== undefined && data.onlineTcmMethodId !== null) this.onlineTcmMethodId = data.onlineTcmMethodId;
          else this.onlineTcmMethodId = null;
          if (data.onlineTcmSyndromeId !== undefined && data.onlineTcmSyndromeId !== null) this.onlineTcmSyndromeId = data.onlineTcmSyndromeId;
          else this.onlineTcmSyndromeId = null;
        } else {
          this.onlineTcmDiseasesId = null;
          this.onlineTcmMethodId = null;
          this.onlineTcmSyndromeId = null;
        }
      } else {
        this.currentDrugs = [];
        this.onlineTcmDiseasesId = null;
        this.onlineTcmMethodId = null;
        this.onlineTcmSyndromeId = null;
      }
    },
    /**
     * 从 chineseConfig 中的 ID 拉取委托调剂三级列表（本地缓存只存 ID，不存列表）
     */
    async hydrateChineseProcessRuleListsFromConfig() {
      if (this.activeCategory !== 1 || this.chineseConfig.ruleType !== 2) return;
      if (!this.processRuleList || this.processRuleList.length === 0) {
        await this.loadProcessRuleList(0, 0);
      }
      if (this.chineseConfig.processRuleId) {
        await this.loadProcessRuleList(this.chineseConfig.processRuleId, 0);
      }
      if (this.chineseConfig.childProcessRuleId) {
        await this.loadProcessRuleList(0, this.chineseConfig.childProcessRuleId);
      }
    },
    saveToLocalStorage() {
      const data = {
        drugs: this.currentDrugs,
        diagnoses: this.diagnoses,
        diagnosisText: this.diagnosisText,
        medicalAdvice: this.medicalAdvice,
        treatmentPrice: this.treatmentPrice,
        chineseConfig: this.activeCategory === 1 ? this.chineseConfig : null,
        onlineTcmDiseasesId: this.activeCategory === 1 ? this.onlineTcmDiseasesId : undefined,
        onlineTcmMethodId: this.activeCategory === 1 ? this.onlineTcmMethodId : undefined,
        onlineTcmSyndromeId: this.activeCategory === 1 ? this.onlineTcmSyndromeId : undefined
      };
      PrescriptionStorage.savePrescriptionData(this.activeCategory, this.registerId, data);
      PrescriptionStorage.saveActiveCategory(this.activeCategory, this.registerId);
    },
    async loadPatientInfo() {
      if (!this.patientId) return;
      try {
        const res = await getPatientInfoByPatientId(this.patientId);
        const data = res.result || res.data || res;
        if (data && data.user_patient) {
          this.patientInfo = {
            id: data.user_patient.id || this.patientId,
            name: data.user_patient.name,
            mobile: data.user_patient.mobile,
            age: data.user_patient.age,
            sex: data.user_patient.sex
          };
        }
      } catch (error) {
        console.error('获取患者信息失败:', error);
      }
    },
    async loadRegisterOrderType() {
      if (!this.registerId) {
        this.registerOrderType = null;
        this.specialPrescriptionRecord = null;
        return;
      }
      try {
        const res = await getPatientItem(this.registerId);
        const data = res.result || res.data || res;
        if (data && data.type !== undefined && data.type !== null) {
          this.registerOrderType = data.type;
        } else {
          this.registerOrderType = null;
        }
        this.specialPrescriptionRecord = pickSpecialPrescriptionRecord(data);
      } catch (e) {
        console.warn(e);
        this.registerOrderType = null;
        this.specialPrescriptionRecord = null;
      }
    },
    async loadBasicConfigData() {
      try {
        const drugUseRes = await getDrugUseList();
        if (drugUseRes) {
          const inner = drugUseRes.result || drugUseRes.data;
          this.drugUseList = inner && (inner.drug_time != null || inner.drug_use_type != null || inner.drug_use_way != null) ? inner : drugUseRes;
        }
        if (this.activeCategory === 1 && this.processRuleList.length === 0) {
          await this.loadProcessRuleList(0, 0);
        }
      } catch (error) {
        console.error('加载基础配置数据失败:', error);
      }
    },
    getChineseItemMargin(drug) {
      if (Number(this.seeRate) !== 1) {
        return '';
      }
      return PrescriptionCalculator.calculateItemGrossMarginPercent(
        drug.price,
        drug.buy_price
      );
    },
    async loadPriceAdjustConfigForStore(storeId) {
      try {
        const res = await getPriceAdjustConfigApi(storeId);
        if (res) {
          this.priceAdjustScopeMode = res.order_price_adjust_scope === 'both' ? 'both' : 'sale_only';
          this.priceAdjustQuickOptions = normalizeQuickOptions(res.order_discount_quick_options);
          if (res.enable_order_price_percent_adjust != null) {
            this.enableOrderPricePercentAdjust = Number(res.enable_order_price_percent_adjust);
          }
        }
      } catch (e) {
        console.error('获取调价配置失败:', e);
      }
    },
    snapshotDrugOrigins(drugs) {
      return (drugs || []).map((drug) => ({
        ...drug,
        origin_price: drug.origin_price ?? drug.price,
        origin_buy_price: drug.origin_buy_price ?? drug.buy_price,
      }));
    },
    prepareDrugForCart(drug) {
      const [prepared] = applyRatioToDrugs(
        this.snapshotDrugOrigins([drug]),
        this.priceDiscount,
        this.priceAdjustScopeMode,
      );
      return prepared;
    },
    applyPreSendPriceDiscount(discount) {
      this.priceDiscount = discount;
      const scope = this.priceAdjustScopeMode;
      this.currentDrugs = applyRatioToDrugs(this.snapshotDrugOrigins(this.currentDrugs), discount, scope);
      uni.showToast({ title: discount === 100 ? '已清除浮动' : '调价成功', icon: 'none' });
    },
    clearPreSendPriceDiscount() {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      this.applyPreSendPriceDiscount(100);
    },
    openPreSendOrderPriceAdjust() {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      if (!this.canPreSendPriceAdjust) return;
      this.currentDrugs = this.snapshotDrugOrigins(this.currentDrugs);
      this.priceAdjustVisible = true;
    },
    closePreSendPriceAdjust() {
      this.priceAdjustVisible = false;
    },
    onPreSendPriceAdjustConfirm(payload) {
      this.applyPreSendPriceDiscount(payload.priceDiscount);
      this.closePreSendPriceAdjust();
    },
    async fetchStoreSeeRate() {
      try {
        const storeId = uni.getStorageSync('store_id');
        const params = {};
        if (storeId) {
          params.store_id = storeId;
        }
        if (this.registerId) {
          params.register_id = this.registerId;
        }
        if (!params.store_id && !params.register_id) {
          return;
        }
        const res = await getCurrentStoreTypeApi(params);
        if (res) {
          this.seeRate = Number(res.see_rate ?? 0);
          this.enableOrderPricePercentAdjust = Number(res.enable_order_price_percent_adjust ?? 0);
          await this.loadPriceAdjustConfigForStore(params.store_id || storeId);
        }
      } catch (error) {
        console.error('获取毛利率权限失败:', error);
      }
    },
    async loadRegisterStoreInfo() {
      if (!this.registerId) {
        await this.fetchStoreSeeRate();
        return;
      }
      try {
        const storeId = uni.getStorageSync('store_id');
        const res = await getCurrentStoreTypeApi({
          register_id: this.registerId,
          ...(storeId ? { store_id: storeId } : {})
        });
        if (res) {
          this.registerStoreInfo = res;
          this.seeRate = Number(res.see_rate ?? 0);
          if (Number(res.allow_insurance_category ?? 0) !== 1) {
            this.feeCategory = 1;
          }
          this.checkSalespersonTransfer();
          if (res.is_from_transfer === 1 && res.delegate_store_id) {
            this.selectedStoreId = res.delegate_store_id;
            this.sendMode = 1;
          } else if (res.store_id) {
            this.selectedStoreId = res.store_id;
            this.sendMode = res.can_change ? 1 : 0;
          }
          const priceStoreId = this.selectedStoreId || res.store_id || storeId;
          this.enableOrderPricePercentAdjust = Number(res.enable_order_price_percent_adjust ?? 0);
          await this.loadPriceAdjustConfigForStore(priceStoreId);
        }
      } catch (error) {
        console.error('获取挂号诊所信息失败:', error);
      }
    },
    async checkSalespersonTransfer() {
      if (!this.registerId) {
        this.hasSalespersonTransfer = false;
        return;
      }
      try {
        const res = await getSalespersonTransferByRegisterApi(this.registerId);
        const list = res?.result || res?.data || res;
        this.hasSalespersonTransfer = Array.isArray(list) && list.length > 0;
      } catch {
        this.hasSalespersonTransfer = false;
      }
    },
    async openSalespersonTransfer() {
      try {
        const res = await getSalespersonTransferByRegisterApi(this.registerId);
        const list = res?.result || res?.data || res;
        if (!Array.isArray(list) || !list.length) {
          this.$toast('暂无待导入传方');
          return;
        }
        const item = list[0];
        const parsed = parseTransferPrescriptionContent(item);
        if (!parsed || !parsed.drugList?.length) {
          this.$toast('传方数据无效');
          return;
        }
        this.salespersonTransferPrescriptionId = item.id;
        this.activeCategory = 1;
        parsed.drugList.forEach((drug) => {
          this.currentDrugs.push(this.prepareDrugForCart({
            index_id: drug.index_id ?? drug.drug_id ?? drug.id,
            id: drug.drug_id || drug.id,
            drug_id: drug.drug_id || drug.id,
            drug_name: drug.drug_name || drug.name,
            name: drug.drug_name || drug.name,
            number: drug.number || 1,
            way_id: drug.way_id || 0,
            price: drug.price ?? 0,
            buy_price: drug.buy_price,
          }));
        });
        if (parsed.clinical_diagnose) {
          this.diagnoses = [{ id: Date.now(), name: parsed.clinical_diagnose }];
        }
        if (parsed.doctor_order) this.medicalAdvice = parsed.doctor_order;
        this.saveToLocalStorage();
        this.$toast('传方已导入');
      } catch (e) {
        console.error(e);
        this.$toast('加载传方失败');
      }
    },
    async handleSwitchCategory(category) {
      this.saveToLocalStorage();
      this.activeCategory = category;
      this.loadCurrentCategoryDrugs();
      if (category === 1) {
        await this.checkSalespersonTransfer();
        await this.checkAndShowTransferTip();
        if (this.processRuleList.length === 0) await this.loadProcessRuleList(0, 0);
      }
    },
    async checkAndShowTransferTip() {
      try {
        if (!this.registerStoreInfo) await this.loadRegisterStoreInfo();
        const storeInfo = this.registerStoreInfo;
        if (!storeInfo) return;
        if (storeInfo.clinic_type === 1 && storeInfo.delegate_store) {
          const delegateStore = storeInfo.delegate_store;
          const doctorName = delegateStore.doctor?.name || '委托医生';
          const storeName = delegateStore.name || '委托诊所';
          uni.showModal({
            title: '转诊提示',
            content: `检测到当前诊所为西医诊所，本次处方开具后自动转接到【${storeName}】的【${doctorName}】的在线复诊中`,
            showCancel: false,
            confirmText: '我知道了'
          });
        }
      } catch (error) {
        console.error('获取诊所信息失败:', error);
      }
    },
    handleOpenDiagnosisModal() {
      this.showDiagnosisModal = true;
    },
    async ensureTraditionalTcmData() {
      if (this.traditionalTcmData) return this.traditionalTcmData;
      if (this.traditionalTcmLoadPromise) return this.traditionalTcmLoadPromise;
      this.traditionalTcmLoadPromise = getTraditionalChineseMedicineJson()
          .then((d) => {
            this.traditionalTcmData = d;
            return d;
          })
          .finally(() => {
            this.traditionalTcmLoadPromise = null;
          });
      return this.traditionalTcmLoadPromise;
    },
    async handleOpenTcmPicker(field) {
      if (!this.isOnlineRevisit || this.activeCategory !== 1) return;
      try {
        uni.showLoading({ title: '加载中', mask: true });
        await this.ensureTraditionalTcmData();
        uni.hideLoading();
        this.tcmPickerField = field;
        this.tcmPickerTitle = field === 'diseases' ? '中医证候' : field === 'method' ? '中医治法' : '中医疾病';
        const d = this.traditionalTcmData;
        this.tcmPickerList = field === 'diseases' ? (d.diseases || []) : field === 'method' ? (d.method || []) : (d.syndrome || []);
        this.showTcmPicker = true;
      } catch (e) {
        uni.hideLoading();
        console.error(e);
        uni.showToast({ title: '术语表加载失败', icon: 'none' });
      }
    },
    handleTcmPickerConfirm(id) {
      const nid = id != null ? Number(id) : null;
      if (this.tcmPickerField === 'diseases') this.onlineTcmDiseasesId = nid;
      else if (this.tcmPickerField === 'method') this.onlineTcmMethodId = nid;
      else if (this.tcmPickerField === 'syndrome') this.onlineTcmSyndromeId = nid;
      this.saveToLocalStorage();
      this.showTcmPicker = false;
    },
    handleDiagnosisConfirm(diagnosisText) {
      this.diagnosisText = diagnosisText;
      if (diagnosisText) {
        const diagnosisNames = diagnosisText.split('，').filter(Boolean);
        this.diagnoses = diagnosisNames.map((name, index) => ({ id: `temp_${index}`, name: name }));
      } else {
        this.diagnoses = [];
      }
      this.saveToLocalStorage();
    },
    handleRemoveDiagnosis(index) {
      this.diagnoses.splice(index, 1);
      this.diagnosisText = this.diagnoses.map(item => item.name).join('，');
      this.saveToLocalStorage();
    },
    handleOpenDoctorOrderModal() {
      this.showDoctorOrderModal = true;
    },
    handleDoctorOrderConfirm(doctorOrderText) {
      this.medicalAdvice = doctorOrderText;
      this.saveToLocalStorage();
    },
    handleOpenCommonPrescriptionModal() { this.showCommonPrescriptionModal = true; },
    async handleApplySpecialPrescription() {
      if (!this.registerId || this.applyingSpecialPrescription) return;
      this.applyingSpecialPrescription = true;
      try {
        const res = await applySpecialPrescriptionApi({ register_id: this.registerId });
        const data = res.result || res.data || res;
        applySpecialPrescriptionPayload(this, data);
        await this.loadRegisterOrderType();
        this.$toast(`已导入特色方：${data.special_prescription_name || ''}`);
        if (data.price_hint) {
          uni.showModal({
            title: '价格提示',
            content: data.price_hint,
            showCancel: false,
          });
        }
      } catch (error) {
        console.error('导入特色方失败:', error);
        this.$toast('导入特色方失败，请稍后重试');
      } finally {
        this.applyingSpecialPrescription = false;
      }
    },
    async handleSelectCommonPrescription(item) {
      try {
        clearAppliedSpecialPrescription(this);
        const payload = item && item.apply_payload;
        if (!payload || !Array.isArray(payload.drugs)) {
          this.$toast('常用方数据异常');
          return;
        }
        this.currentDrugs.splice(0, this.currentDrugs.length, ...payload.drugs);
        if (payload.diagnosisText) {
          this.diagnosisText = payload.diagnosisText;
          const names = payload.diagnosisText.split('，').filter(Boolean);
          this.diagnoses = names.map((name, index) => ({ id: `temp_${index}`, name }));
        }
        if (payload.medicalAdvice) this.medicalAdvice = payload.medicalAdvice;
        if (this.activeCategory === 1 && payload.chineseConfig) {
          this.chineseConfig = { ...this.chineseConfig, ...payload.chineseConfig };
          if (this.chineseConfig.processRuleId) await this.loadProcessRuleList(this.chineseConfig.processRuleId, 0);
          if (this.chineseConfig.childProcessRuleId) await this.loadProcessRuleList(0, this.chineseConfig.childProcessRuleId);
        }
        this.saveToLocalStorage();
        this.$toast('常用方已填充');
      } catch (error) {
        console.error('选择常用方失败:', error);
        this.$toast('选择常用方失败');
      }
    },
    getCommonPrescriptionType(category) {
      if (category === 1) return 'chinese';
      else if (category === 2) return 'west';
      else return 'granular';
    },
    applyPendingExperienceDrugFromChat() {
      let raw;
      try {
        raw = uni.getStorageSync(PENDING_RX_FROM_CHAT);
      } catch (e) {
        return;
      }
      if (!raw) return;
      let p;
      try {
        p = typeof raw === 'string' ? JSON.parse(raw) : raw;
      } catch (e2) {
        try {
          uni.removeStorageSync(PENDING_RX_FROM_CHAT);
        } catch (e3) {}
        return;
      }
      if (!p || String(p.register_id) !== String(this.registerId)) return;

      if (p.source === 'register_drugs' && Array.isArray(p.drugs) && p.drugs.length > 0) {
        try {
          uni.removeStorageSync(PENDING_RX_FROM_CHAT);
        } catch (e4) {}
        this.activeCategory = 2;
        this.saveToLocalStorage();
        this.loadCurrentCategoryDrugs();
        this.mergeWesternRowsFromRegisterDrugs(p.drugs);
        return;
      }

      if (p.source === 'transfer_import' && Array.isArray(p.drugs) && p.drugs.length > 0) {
        try {
          uni.removeStorageSync(PENDING_RX_FROM_CHAT);
        } catch (e5) {}
        this.activeCategory = 1;
        this.saveToLocalStorage();
        this.loadCurrentCategoryDrugs();
        this.mergeTransferChineseRows(p.drugs);
        if (p.diagnosisText) {
          this.diagnosisText = String(p.diagnosisText);
          const names = this.diagnosisText.split('，').filter(Boolean);
          this.diagnoses = names.map((name, index) => ({ id: `temp_${index}`, name }));
        }
        if (p.medicalAdvice != null && String(p.medicalAdvice).trim() !== '') {
          this.medicalAdvice = String(p.medicalAdvice);
        }
        this.saveToLocalStorage();
        return;
      }

      try {
        uni.removeStorageSync(PENDING_RX_FROM_CHAT);
      } catch (e4) {}
      this.activeCategory = 2;
      this.westernModalInitialKeyword = String(p.drug_name || '').trim();
      this.saveToLocalStorage();
      this.loadCurrentCategoryDrugs();
      this.$nextTick(() => {
        this.showWesternMedicineModal = true;
      });
    },
    mergeWesternRowsFromRegisterDrugs(rows) {
      let added = 0;
      for (const row of rows) {
        const d = row.drug || {};
        const qtyRaw = row.purchase_quantity != null ? Number(row.purchase_quantity) : null;
        const qty =
          qtyRaw != null && !Number.isNaN(qtyRaw) && qtyRaw >= 1 ? Math.min(99, qtyRaw) : Number(d.number || 1) || 1;
        const drugId = row.drug_id || d.id;
        const synthetic = {
          id: drugId,
          drug_id: drugId,
          drug_name: d.drug_name,
          number: qty,
          select_number: qty,
          price: parseFloat(row.price) || 0,
          specification: d.specification || '',
          image: d.image || '',
          instruction: d.instruction || '',
          time_id: d.time_id || 0,
          type_id: d.type_id || 0,
          frequency_id: d.frequency_id || 0,
          unit_id: d.unit_id || 0,
          drug: d
        };
        if (PrescriptionValidator.isDrugExists(this.currentDrugs, synthetic)) {
          continue;
        }
        const newDrug = {
          index_id: row.id,
          id: drugId,
          drug_id: drugId,
          drug_name: d.drug_name,
          number: qty,
          select_number: qty,
          price: parseFloat(row.price) || 0,
          specification: d.specification || '',
          image: d.image || '',
          instruction: d.instruction || '',
          time_id: d.time_id || 0,
          type_id: d.type_id || 0,
          frequency_id: d.frequency_id || 0,
          unit_id: d.unit_id || 0,
          use_num: this.drugUseList.drug_time?.find((item) => item.id === (d.time_id || 0)),
          use_type: this.drugUseList.drug_use_type?.find((item) => item.id === (d.type_id || 0)),
          use_frequency: this.drugUseList.drug_use_frequency?.find((item) => item.id === (d.frequency_id || 0)),
          unit: this.drugUseList.drug_unit?.find((item) => item.id === (d.unit_id || 0))
        };
        this.currentDrugs.push(this.prepareDrugForCart(newDrug));
        added++;
      }
      this.saveToLocalStorage();
      if (added > 0) {
        this.$toast(`已添加 ${added} 个药品`);
      } else {
        this.$toast('药品已在列表中或未能匹配');
      }
    },
    mergeTransferChineseRows(rows) {
      let added = 0;
      for (const product of rows) {
        if (PrescriptionValidator.isDrugExists(this.currentDrugs, product)) {
          continue;
        }
        this.currentDrugs.push(this.prepareDrugForCart({ ...product }));
        added++;
      }
      this.saveToLocalStorage();
      if (added > 0) {
        this.$toast(`已添加 ${added} 味药`);
      } else {
        this.$toast('药品已在列表中');
      }
    },
    handleOpenWesternMedicineModal() {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      this.westernModalInitialKeyword = '';
      this.showWesternMedicineModal = true;
    },
    handleSelectWesternDrug(drug) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      if (PrescriptionValidator.isDrugExists(this.currentDrugs, drug)) {
        this.$toast('该药品已在列表中');
        return;
      }
      const newDrug = {
        index_id: drug.id,
        id: drug.drug_id || drug.drug?.id || drug.id,
        drug_id: drug.drug_id || drug.drug?.id || drug.id,
        drug_name: drug.drug_name || drug.drug?.drug_name,
        number: drug.number || 1,
        select_number: drug.select_number || 1,
        price: drug.price || 0,
        specification: drug.specification || drug.drug?.specification || '',
        image: drug.image || drug.drug?.image || '',
        instruction: drug.instruction || drug.drug?.instruction || '',
        time_id: drug.time_id || drug.drug?.time_id || 0,
        type_id: drug.type_id || drug.drug?.type_id || 0,
        frequency_id: drug.frequency_id || drug.drug?.frequency_id || 0,
        unit_id: drug.unit_id || drug.drug?.unit_id || 0,
        use_num: this.drugUseList.drug_time?.find(item => item.id === (drug.time_id || drug.drug?.time_id)),
        use_type: this.drugUseList.drug_use_type?.find(item => item.id === (drug.type_id || drug.drug?.type_id)),
        use_frequency: this.drugUseList.drug_use_frequency?.find(item => item.id === (drug.frequency_id || drug.drug?.frequency_id)),
        unit: this.drugUseList.drug_unit?.find(item => item.id === (drug.unit_id || drug.drug?.unit_id))
      };
      this.currentDrugs.push(this.prepareDrugForCart(newDrug));
      const index = this.currentDrugs.length - 1;
      this.handleEditWesternDrug(this.currentDrugs[index], index);
      this.saveToLocalStorage();
      this.$toast(`已添加 ${newDrug.drug_name}`);
    },
    handleOpenChineseMedicineModal() {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      this.chineseModalInitialKeyword = '';
      this.showChineseMedicineModal = true;
    },
    /** 微信小程序 :key 中勿写 it.id || it.index_id 等表达式，会编译异常 */
    tcmTagKey(it, tcmIndex) {
      if (it && it.id != null && it.id !== '') return `tcm-${it.id}`;
      if (it && it.index_id != null && it.index_id !== '') return `tcm-i-${it.index_id}`;
      return `tcm-idx-${tcmIndex}`;
    },
    /**
     * 中药标签长按菜单（小程序 showActionSheet 回调里勿依赖闭包 item，用 dataset.idx + currentDrugs）
     */
    onTcmTagLongPress(e) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      const raw = e && e.currentTarget && e.currentTarget.dataset ? e.currentTarget.dataset.idx : undefined;
      const idx = raw === undefined || raw === '' ? NaN : Number(raw);
      if (Number.isNaN(idx) || idx < 0 || idx >= this.currentDrugs.length) return;
      uni.showActionSheet({
        itemList: ['编辑', '删除'],
        success: (res) => {
          const row = this.currentDrugs[idx];
          if (!row) return;
          if (res.tapIndex === 0) {
            this.chineseModalInitialKeyword = String(row.drug_name || row.name || '').trim();
            this.showChineseMedicineModal = true;
          } else if (res.tapIndex === 1) {
            this.handleRemoveDrug(idx);
          }
        }
      });
    },
    handleSelectChineseDrug(drugs) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      this.currentDrugs = applyRatioToDrugs(
        this.snapshotDrugOrigins(drugs || []),
        this.priceDiscount,
        this.priceAdjustScopeMode,
      );
      this.saveToLocalStorage();
    },
    handleOpenSimpleProductModal() {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      this.showSimpleProductModal = true;
    },
    handleSelectSimpleProduct(product) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      if (PrescriptionValidator.isDrugExists(this.currentDrugs, product)) {
        this.$toast('该产品已在列表中');
        return;
      }
      const newProduct = {
        index_id: product.id,
        id: product.drug_id || product.drug?.id || product.id,
        drug_name: product.drug_name || product.drug?.drug_name || product.name,
        number: 1,
        price: product.price || 0,
        image: product.image || product.drug?.image || '',
        instruction: product.instruction || product.drug?.instruction || '',
        type: product.drug?.type || product.type || this.activeCategory,
        select_number: 1
      };
      this.currentDrugs.push(this.prepareDrugForCart(newProduct));
      this.saveToLocalStorage();
      this.$toast(`已添加 ${newProduct.drug_name}`);
    },
    handleEditWesternDrug(drug, index) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      this.editingDrug = JSON.parse(JSON.stringify(drug));
      this.editingDrugIndex = index;
      this.showWesternUsageModal = true;
    },
    handleConfirmWesternUsage(usageData) {
      if (this.editingDrugIndex >= 0) {
        const drug = this.currentDrugs[this.editingDrugIndex];
        drug.time_id = usageData.time_id;
        drug.type_id = usageData.type_id;
        drug.frequency_id = usageData.frequency_id;
        drug.unit_id = usageData.unit_id;
        drug.number = usageData.number;
        drug.select_number = usageData.select_number || drug.select_number;
        drug.use_num = usageData.use_num;
        drug.use_type = usageData.use_type;
        drug.use_frequency = usageData.use_frequency;
        drug.unit = usageData.unit;
        this.saveToLocalStorage();
      }
      this.editingDrug = null;
      this.editingDrugIndex = -1;
    },
    handleRemoveDrug(index) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      uni.showModal({
        title: '移除药品',
        content: '确定要从处方中移除该药品吗？',
        confirmColor: '#FC3636',
        success: ({ confirm }) => {
          if (confirm) {
            this.currentDrugs.splice(index, 1);
            this.saveToLocalStorage();
          }
        }
      });
    },
    handleIncrementSimpleProduct(index) {
      if (index >= 0 && index < this.currentDrugs.length) {
        const product = this.currentDrugs[index];
        const currentNumber = product.select_number || product.number || 1;
        this.$set(product, 'select_number', currentNumber + 1);
        this.saveToLocalStorage();
      }
    },
    handleDecrementSimpleProduct(index) {
      if (index >= 0 && index < this.currentDrugs.length) {
        const product = this.currentDrugs[index];
        const currentNumber = product.select_number || product.number || 1;
        if (currentNumber > 1) {
          this.$set(product, 'select_number', currentNumber - 1);
          this.saveToLocalStorage();
        } else {
          this.handleRemoveDrug(index);
        }
      }
    },
    handleRemoveAllDrugs() {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      uni.showModal({
        title: '清空药材',
        content: '确定要清空所有中药材吗？',
        confirmColor: '#FC3636',
        success: ({ confirm }) => {
          if (confirm) {
            this.currentDrugs = [];
            this.saveToLocalStorage();
          }
        }
      });
    },
    async handleUpdateChineseConfig(config) {
      if (guardSpecialPrescriptionCartEdit(this)) return;
      const oldRuleType = this.chineseConfig.ruleType;
      const oldProcessRuleId = this.chineseConfig.processRuleId;
      const oldChildProcessRuleId = this.chineseConfig.childProcessRuleId;

      if (config.ruleType === 2 && config.ruleType !== oldRuleType) {
        if (this.processRuleList.length === 0) await this.loadProcessRuleList(0, 0);
      }
      if (config.ruleType === 1 && oldRuleType === 2) {
        config.processRuleId = null;
        config.childProcessRuleId = null;
        config.processRuleNoteId = null;
        this.processRuleList = [];
        this.childProcessRuleList = [];
        this.processRuleNoteList = [];
      }
      if (config.processRuleId && config.processRuleId !== oldProcessRuleId) {
        config.childProcessRuleId = null;
        config.processRuleNoteId = null;
        this.childProcessRuleList = [];
        this.processRuleNoteList = [];
      }
      if (config.childProcessRuleId && config.childProcessRuleId !== oldChildProcessRuleId) {
        config.processRuleNoteId = null;
        this.processRuleNoteList = [];
      }
      this.chineseConfig = { ...this.chineseConfig, ...config };
      if (config.processRuleId && config.processRuleId !== oldProcessRuleId) {
        await this.loadProcessRuleList(config.processRuleId, 0);
      }
      if (config.childProcessRuleId && config.childProcessRuleId !== oldChildProcessRuleId) {
        await this.loadProcessRuleList(0, config.childProcessRuleId);
      }
      this.saveToLocalStorage();
    },
    async loadProcessRuleList(pid = 0, ruleId = 0) {
      try {
        const data = ruleId === 0 ? { pid } : { rule_id: ruleId };
        let list = [];
        if (this.isSalespersonTransferMode) {
          const wrap = await getClinicSalespersonProcessRuleList(data);
          if (wrap && wrap.ok) {
            list = Array.isArray(wrap.data) ? wrap.data : [];
          }
        } else {
          const res = await getProcessRuleList(data);
          list = res?.data || res?.result || res || [];
        }
        if (ruleId !== 0) {
          this.processRuleNoteList = list;
        } else if (pid === 0) {
          this.processRuleList = list;
        } else {
          this.childProcessRuleList = list;
        }
      } catch (error) {
        console.error('加载加工规则列表失败:', error);
        this.$toast('加载加工规则列表失败');
      }
    },
    parsePrescriptionDetailContent(detail) {
      let c = detail && detail.content;
      if (typeof c === 'string') {
        try { c = JSON.parse(c); } catch (e) { c = {}; }
      }
      return c && typeof c === 'object' ? c : {};
    },
    mapWestRepiceToProduct(recipe) {
      if (!recipe) return null;
      let drugObj = {};
      try {
        const raw = recipe.content;
        drugObj = typeof raw === 'string' ? JSON.parse(raw) : (raw || {});
      } catch (e) { return null; }
      const drugId = Number(drugObj.id);
      if (!drugId) return null;

      const selectNumber = Math.max(1, Number(recipe.number ?? drugObj.select_number ?? drugObj.number ?? 1) || 1);
      const grainNumber = Math.max(1, Number(drugObj.number ?? drugObj.grain_number ?? recipe.grain_number ?? 1) || 1);
      const timeId = recipe.time_id ?? drugObj.time_id;
      const typeId = recipe.type_id ?? drugObj.type_id;
      const freqId = recipe.f_id ?? drugObj.frequency_id;
      const unitId = recipe.wu_id ?? drugObj.unit_id;
      const list = this.drugUseList || {};
      const wayId = drugObj.way_id;

      return {
        index_id: drugId, id: drugId,
        drug_name: drugObj.drug_name || drugObj.name || '',
        number: grainNumber,
        use_num: (list.drug_time || []).find((item) => item.id === timeId),
        use_type: (list.drug_use_type || []).find((item) => item.id === typeId),
        use_frequency: (list.drug_use_frequency || []).find((item) => item.id === freqId),
        unit: (list.drug_unit || []).find((item) => item.id === unitId),
        price: Number(drugObj.sell_price ?? drugObj.price ?? 0),
        way_id: wayId,
        use_ways: (list.drug_use_way || []).find((item) => item.id === wayId),
        time_id: timeId, type_id: typeId, frequency_id: freqId, unit_id: unitId,
        image: drugObj.image || '', instruction: drugObj.instruction || '',
        type: drugObj.type, select_number: selectNumber, specification: drugObj.specification || ''
      };
    },
    async applyHistoricalPrescriptionDetail(detail) {
      const content = this.parsePrescriptionDetailContent(detail);
      const pt = Number(detail.prescription_type);
      if (![1, 2, 3, 5, 6, 7].includes(pt)) {
        this.$toast('该处方类型暂不支持复用');
        return false;
      }
      if (!this.patientId) {
        this.$toast('患者信息异常');
        return false;
      }

      this.saveToLocalStorage();
      this.activeCategory = pt;
      PrescriptionStorage.saveActiveCategory(pt, this.registerId);

      const repiceList = Array.isArray(content.repice) ? content.repice : [];
      if (pt === 1) {
        const rep0 = repiceList[0];
        if (!rep0) return false;
        let rows = [];
        try {
          const raw = rep0.content;
          rows = typeof raw === 'string' ? JSON.parse(raw) : (raw || []);
        } catch (e) { return false; }
        if (!Array.isArray(rows) || rows.length === 0) return false;

        const list = this.drugUseList || {};
        this.currentDrugs = rows.map((d) => {
          const drugId = Number(d.drug_id ?? d.id);
          const wayId = d.way_id ?? d.use_way?.id ?? d.useWay?.id ?? d.order;
          const unitId = d.unit_id;
          return {
            index_id: d.id ?? drugId, id: drugId,
            drug_name: d.name || d.drug_name || '',
            number: d.number ?? 1, price: Number(d.price ?? 0),
            way_id: wayId,
            use_ways: (list.drug_use_way || []).find((item) => item.id === wayId) ?? d.use_way ?? d.useWay,
            use_num: (list.drug_time || []).find((item) => item.id === d.time_id),
            use_type: (list.drug_use_type || []).find((item) => item.id === d.type_id),
            use_frequency: (list.drug_use_frequency || []).find((item) => item.id === d.frequency_id),
            unit: (list.drug_unit || []).find((item) => item.id === unitId) || d.unit,
            time_id: d.time_id, type_id: d.type_id, frequency_id: d.frequency_id, unit_id: unitId,
            image: d.image || '', instruction: d.instruction || '', type: d.type
          };
        });

        const ruleType = rep0.deployment === 2 ? 1 : 2;
        this.chineseConfig = {
          ...this.chineseConfig, ruleType,
          dosage: Number(rep0.dosage ?? 7), dayDosage: Number(rep0.consumption ?? 2),
          packageMethodId: rep0.package_method_id ?? 2,
          processRuleId: rep0.process_rule_id && Number(rep0.process_rule_id) > 0 ? rep0.process_rule_id : null,
          childProcessRuleId: rep0.child_process_rule_id && Number(rep0.child_process_rule_id) > 0 ? rep0.child_process_rule_id : null,
          processRuleNoteId: rep0.process_rule_note_id && Number(rep0.process_rule_note_id) > 0 ? rep0.process_rule_note_id : null
        };
        if (ruleType === 2) await this.hydrateChineseProcessRuleListsFromConfig();
      } else {
        const mapped = [];
        for (const recipe of repiceList) {
          const row = this.mapWestRepiceToProduct(recipe);
          if (row) mapped.push(row);
        }
        if (mapped.length === 0) return false;
        this.currentDrugs = mapped;
      }

      const dx = detail.clinical_diagnose ?? content.clinical_diagnose ?? '';
      this.diagnosisText = dx;
      if (dx) {
        const names = String(dx).split('，').filter(Boolean);
        this.diagnoses = names.map((name, index) => ({ id: `temp_${index}`, name }));
      } else {
        this.diagnoses = [];
      }
      const fallbackOrder = Array.isArray(detail.doctor_order)
        ? detail.doctor_order.join('|')
        : (detail.doctor_order ?? '');
      this.medicalAdvice = content.doctor_order ?? fallbackOrder ?? '';
      this.saveToLocalStorage();
      return true;
    },
    async maybeApplyReusePrescription() {
      const rawId = this.pendingReusePrescriptionId;
      if (!rawId) return;
      this.pendingReusePrescriptionId = '';
      const pid = parseInt(rawId, 10);
      if (!pid || !this.registerId) return;
      const hasDraft = PrescriptionStorage.hasDraftWithDrugs(this.registerId);
      const run = async () => {
        try {
          const res = await getPrescriptionInfoApi(pid);
          if (res && ((typeof res.code === 'number' && res.code !== 0) || (typeof res.errcode === 'number' && res.errcode !== 0))) {
            this.$toast(res.msg || res.message || '加载处方详情失败');
            return;
          }
          const detail = res.result || res.data || res;
          const ok = await this.applyHistoricalPrescriptionDetail(detail);
          if (ok) this.$toast('已复用历史处方，请核对后发送');
        } catch (e) {
          console.error('复用处方失败:', e);
          this.$toast('加载处方详情失败');
        }
      };

      if (hasDraft) {
        uni.showModal({
          title: '覆盖当前草稿？', content: '当前处方清单中有药品，复用将替换为所选历史处方内容。',
          success: (r) => { if (r.confirm) run(); }
        });
      } else {
        await run();
      }
    },
    formatDrugUsage(drug) {
      if (!drug.use_type || !drug.use_frequency || !drug.use_num || !drug.unit) return '';
      return `${drug.use_type.name}，${drug.use_frequency.name}，${drug.use_num.name}，每次${drug.number}${drug.unit.name}`;
    },
    getProductUnit(category) {
      if (category === 5) return '周期';
      return '件';
    },
    validatePrescriptionData() {
      return PrescriptionValidator.validatePrescriptionData({
        category: this.activeCategory,
        drugs: this.currentDrugs,
        diagnoses: this.diagnoses,
        medicalAdvice: this.medicalAdvice,
        chineseConfig: this.activeCategory === 1 ? this.chineseConfig : null,
        requireOnlineTcm: this.activeCategory === 1 && this.isOnlineRevisit,
        onlineTcmDiseasesId: this.onlineTcmDiseasesId,
        onlineTcmMethodId: this.onlineTcmMethodId,
        onlineTcmSyndromeId: this.onlineTcmSyndromeId,
        skipDiagnosisAndAdvice: this.isSalespersonTransferMode,
      });
    },
    async checkChineseMedicineConflict() {
      if (this.activeCategory !== 1) return { hasConflict: false };
      try {
        const names = this.currentDrugs.map((item) => item.drug_name || item.name);
        const res = await checkChineseMedicineConflictApi({ names });
        if (res && res.is_exist === true) return { hasConflict: true, message: res.message || '检测到该处方内具有药物相冲' };
        return { hasConflict: false };
      } catch (error) {
        console.error('检查中药相冲失败:', error);
        return { hasConflict: false };
      }
    },
    async handleSendPrescription(doctorSecondSign = 0) {
      if (this.isSubmitting) { this.$toast('正在处理中，请勿重复提交'); return; }
      if (this.isCommonPrescription) { this.handleSaveAsCommonPrescription(); return; }

      const validation = this.validatePrescriptionData();
      if (!validation.valid) { this.$toast(validation.message); return; }

      if (this.isSalespersonTransferMode) {
        this.showTransferPatientDrawer = true;
        return;
      }

      this.isSubmitting = true;
      try {
        if (!this.registerStoreInfo) await this.loadRegisterStoreInfo();
        if (this.activeCategory === 1) {
          const conflictCheck = await this.checkChineseMedicineConflict();
          if (conflictCheck.hasConflict) {
            uni.showModal({
              title: '药物相冲提示',
              content: conflictCheck.message || '检测到该处方内具有药物相冲，是否继续开方？',
              showCancel: true,
              success: ({ confirm }) => {
                if (confirm) this.handleSendPrescriptionWithStoreSelection(1);
                else this.isSubmitting = false;
              }
            });
            return;
          }
        }
        await this.handleSendPrescriptionWithStoreSelection(doctorSecondSign);
      } catch (error) {
        console.error('发送处方失败:', error);
        this.$toast('发送处方失败，请重试');
        this.isSubmitting = false;
      }
    },
    async handleSendPrescriptionWithStoreSelection(doctorSecondSign = 0) {
      const storeInfo = this.registerStoreInfo;
      if (storeInfo?.is_from_transfer === 1 && storeInfo?.delegate_store_id) {
        await this.executeSendPrescription(doctorSecondSign, 1, storeInfo.delegate_store_id);
      } else if (storeInfo?.can_change) {
        const registerStoreName = storeInfo?.store_name || '挂号诊所';
        const registerStoreId = storeInfo?.store_id;
        const currentStoreName = storeInfo?.current_store_name || '当前诊所';
        uni.showModal({
          title: '选择诊所',
          content: `请选择使用哪个诊所开方：\n\n挂号诊所：${registerStoreName}\n当前诊所：${currentStoreName}`,
          confirmText: '使用挂号诊所',
          cancelText: '使用当前诊所',
          success: ({ confirm, cancel }) => {
            if (confirm) this.executeSendPrescription(doctorSecondSign, 1, registerStoreId);
            else if (cancel) this.executeSendPrescription(doctorSecondSign, 0, null);
            else this.isSubmitting = false;
          },
          fail: () => { this.isSubmitting = false; }
        });
      } else {
        await this.executeSendPrescription(doctorSecondSign, 0, null);
      }
    },
    /**
     * 主界面药材清单展示先煎/后下文案（在选择中药弹窗设置；默认煎服不展示）
     */
    getTcmWayLabel(drug) {
      if (!drug) return '';
      const wayId = Number(drug.way_id ?? drug.use_ways?.id ?? 0);
      if (!wayId) return '';
      const list = (this.drugUseList && this.drugUseList.drug_use_way) || [];
      const hit = list.find((w) => Number(w.id) === wayId);
      const name = (hit && hit.name) || (drug.use_ways && drug.use_ways.name) || '';
      if (!name || name === '煎服') return '';
      return name;
    },
    /**
     * 在线复诊：有仓药绑定时弹卡片选仓；默认最低价；取消返回 false
     */
    async resolvePharmacyWarehouseMap() {
      if (!this.isOnlineRevisit) {
        return null;
      }
      const drugs = this.currentDrugs || [];
      const drugIds = [];
      const needQtyMap = {};
      for (const d of drugs) {
        const id = Number(d?.id || 0);
        const qty = Number(d?.select_number || d?.number || 0);
        if (id <= 0 || qty <= 0) continue;
        drugIds.push(id);
        needQtyMap[id] = (needQtyMap[id] || 0) + qty;
      }
      if (!drugIds.length) {
        return null;
      }
      try {
        const res = await getDeliveryWarehouseOptionsByDrugs({
          drug_ids: drugIds.join(','),
          need_qty_map: needQtyMap,
        });
        const map = (res && (res.result || res.data || res)) || {};
        const rows = [];
        for (const d of drugs) {
          const id = Number(d?.id || 0);
          if (id <= 0) continue;
          const options = map[String(id)] || map[id] || [];
          if (!Array.isArray(options) || !options.length) continue;
          rows.push({
            drug_id: id,
            // 优先用仓选项接口带回的药品信息，避免处方草稿未存规格/图
            drug_name: String(
              (options[0] && options[0].drug_name) ||
                d.drug_name ||
                d.name ||
                `药品#${id}`,
            ),
            image: String(
              (options[0] && options[0].image) ||
                d.image ||
                d._image ||
                (d.drug && d.drug.image) ||
                '',
            ),
            specification: String(
              (options[0] && options[0].specification) ||
                d.specification ||
                (d.drug && d.drug.specification) ||
                '',
            ),
            options: options.map((o) => ({
              warehouse_id: Number(o.warehouse_id),
              warehouse_name: String(o.warehouse_name || ''),
              quote: String(o.quote ?? '0'),
              available_stock: Number(o.available_stock ?? 0),
              // 保留药品展示字段，供抽屉从 options[0] 回退读取
              drug_name: String(o.drug_name || ''),
              image: String(o.image || ''),
              specification: String(o.specification || ''),
            })),
            warehouse_id: Number(options[0].warehouse_id),
          });
        }
        if (!rows.length) {
          return null;
        }
        this.warehouseSelectRows = rows;
        this.showWarehouseSelectDrawer = true;
        return new Promise((resolve) => {
          this._warehouseSelectResolve = resolve;
        });
      } catch (e) {
        console.error('加载配送仓库失败', e);
        this.$toast((e && e.message) || '加载配送仓库失败');
        return false;
      }
    },
    onWarehouseSelectConfirm(map) {
      const resolve = this._warehouseSelectResolve;
      this._warehouseSelectResolve = null;
      this.showWarehouseSelectDrawer = false;
      if (typeof resolve === 'function') resolve(map || {});
    },
    onWarehouseSelectCancel() {
      const resolve = this._warehouseSelectResolve;
      this._warehouseSelectResolve = null;
      this.showWarehouseSelectDrawer = false;
      if (typeof resolve === 'function') resolve(false);
    },
    async executeSendPrescription(doctorSecondSign = 0, sendMode = 0, customStoreId = null) {
      try {
        // 在线复诊有绑仓时先卡片选仓
        const warehouseMap = await this.resolvePharmacyWarehouseMap();
        if (warehouseMap === false) {
          this.isSubmitting = false;
          return;
        }
        if (this.activeCategory === 2) {
          if (!this.patientInfo || !this.patientId) {
            if (this.patientId && !this.patientInfo) await this.loadPatientInfo();
            if (!this.patientInfo || !this.patientId) {
              this.$toast('患者信息缺失，无法发送处方');
              this.isSubmitting = false; return;
            }
          }
          const invalidDrug = this.currentDrugs.find((drug) => {
            return !(drug.id && (drug.select_number || drug.number) && drug.time_id && drug.type_id && drug.frequency_id && drug.unit_id && drug.use_type && drug.use_type.name && drug.use_num && drug.use_num.name && drug.unit && drug.unit.name);
          });
          if (invalidDrug) { this.$toast('请先为西药设置完整的用法用量'); return; }
        }

        let finalSendMode = sendMode; let finalStoreId = customStoreId;
        const storeInfo = this.registerStoreInfo;
        if (storeInfo?.is_from_transfer === 1 && storeInfo?.delegate_store_id) {
          finalSendMode = 1; finalStoreId = storeInfo.delegate_store_id;
        }

        const clinical_diagnose = this.diagnosisText || this.diagnoses.map((item) => item.name).join(',');
        let doctorSecondSignValue = typeof doctorSecondSign === 'number' ? doctorSecondSign : (typeof doctorSecondSign === 'object' && doctorSecondSign !== null && typeof doctorSecondSign.value === 'number' ? doctorSecondSign.value : (typeof doctorSecondSign === 'string' ? parseInt(doctorSecondSign, 10) || 0 : (doctorSecondSign ? 1 : 0)));

        const patientData = { id: this.patientInfo.id || this.patientId, user_id: this.patientInfo.user_id || null, name: this.patientInfo.name || '', age: this.patientInfo.age || 0, sex: this.patientInfo.sex || 0, mobile: this.patientInfo.mobile || '' };

        let drugsData;
        if (this.activeCategory === 1) {
          drugsData = this.currentDrugs.map((drug) => ({ index_id: drug.index_id, id: drug.id, drug_name: drug.drug_name || drug.name, number: drug.number || drug._quantity || 0, price: drug.price || '0.0000', way_id: drug.way_id || 0, select_number: drug.select_number || 1 }));
        } else if ([3, 5, 6, 7].includes(this.activeCategory)) {
          drugsData = this.currentDrugs.map((drug) => {
            const cleanDrug = { index_id: drug.index_id, id: drug.id, drug_name: drug.drug_name || drug.name, number: drug.number || 1, price: drug.price || '0.0000', select_number: drug.select_number || 1 };
            if (drug.image) cleanDrug.image = drug.image;
            if (drug.instruction) cleanDrug.instruction = drug.instruction;
            if (drug.type) cleanDrug.type = drug.type;
            return cleanDrug;
          });
        } else {
          drugsData = this.currentDrugs.map(drug => {
            const drugData = { ...drug };
            if (!drugData.use_type || typeof drugData.use_type !== 'object' || !drugData.use_type.name) drugData.use_type = (drugData.type_id && this.drugUseList.drug_use_type) ? this.drugUseList.drug_use_type.find(item => item.id === drugData.type_id) || { name: '' } : { name: '' };
            if (!drugData.use_num || typeof drugData.use_num !== 'object' || !drugData.use_num.name) drugData.use_num = (drugData.time_id && this.drugUseList.drug_time) ? this.drugUseList.drug_time.find(item => item.id === drugData.time_id) || { name: '' } : { name: '' };
            if (!drugData.unit || typeof drugData.unit !== 'object' || !drugData.unit.name) drugData.unit = (drugData.unit_id && this.drugUseList.drug_unit) ? this.drugUseList.drug_unit.find(item => item.id === drugData.unit_id) || { name: '' } : { name: '' };
            return drugData;
          });
        }

        const params = {
          patient: patientData, drugs: drugsData, diagnosis: clinical_diagnose, medicalAdvice: this.medicalAdvice, total: parseFloat(this.totalPrice), category: this.feeCategory, drug_type: 2, register_id: parseInt(this.registerId), treatment_price: parseFloat(this.treatmentPrice || 0), prescription_type: this.activeCategory, doctor_second_sign: doctorSecondSignValue, send_mode: finalSendMode, custom_store_id: finalSendMode === 1 ? finalStoreId : null,
          salesperson_transfer_prescription_id: this.salespersonTransferPrescriptionId || undefined,
          price_discount: this.priceDiscount,
          special_prescription_id: Number(this.appliedSpecialPrescriptionId) || 0,
        };
        if (warehouseMap && typeof warehouseMap === 'object') {
          // 列表格式避免数字键对象在 form/部分环境序列化丢失
          params.warehouse_map = Object.keys(warehouseMap).map((drugId) => ({
            drug_id: Number(drugId),
            warehouse_id: Number(warehouseMap[drugId]),
          }));
        }
        if (this.activeCategory === 1) {
          params.package_method_id = this.chineseConfig.packageMethodId || null; params.process_rule_id = this.chineseConfig.processRuleId || null; params.process_rule_note_id = this.chineseConfig.processRuleNoteId || null; params.child_process_rule_id = this.chineseConfig.childProcessRuleId || null; params.process_rule_type = this.chineseConfig.ruleType || 1; params.processing_fee = this.processingFee; params.dosage = this.chineseConfig.dosage || 7; params.day_dosage = this.chineseConfig.dayDosage || 2;
          if (this.isOnlineRevisit) {
            params.diseases_id = this.onlineTcmDiseasesId;
            params.method_id = this.onlineTcmMethodId;
            params.syndrome_id = this.onlineTcmSyndromeId;
          }
        }

        const res = await addWestPrescription(params);
        if (res && (res.code === 0 || res.errcode === 0)) {
          this.$toast('发送成功');
          const needTransfer = res?.result?.need_transfer || res?.data?.need_transfer || res?.need_transfer;
          if (needTransfer) {
            const transferId = res?.result?.transfer_prescription_id || res?.data?.transfer_prescription_id || res?.transfer_prescription_id;
            if (transferId) {
              uni.showModal({
                title: '转诊提示', content: '该处方已触发转诊流程，转诊消息已发送给委托诊所的在线问诊医生。', showCancel: false, confirmText: '确定',
                success: () => { this.clearPrescriptionData(); PrescriptionStorage.clearAllPrescriptionData(this.registerId); this.safeNavigateBack(500); }
              });
              return;
            }
          }
          if (this.isOnlineRevisit) {
            try {
              await this.trySendPrescriptionChatMessage(res);
            } catch (e) {
              console.error('处方消息同步失败', e);
              uni.showToast({ title: '处方消息同步失败', icon: 'none' });
            }
          }
          this.clearPrescriptionData();
          PrescriptionStorage.clearAllPrescriptionData(this.registerId);
          this.safeNavigateBack(1500);
        } else {
          this.$toast(res.msg || res.message || '发送失败');
        }
      } catch (error) {
        console.error('发送处方失败:', error);
        this.$toast('发送处方失败，请重试');
        throw error;
      } finally {
        this.isSubmitting = false;
      }
    },
    async trySendPrescriptionChatMessage(res) {
      const inner = res && (res.result !== undefined ? res.result : res.data !== undefined ? res.data : null);
      if (!inner || typeof inner !== 'object') return;
      if (!this.registerId) return;
      const roomRes = await getChatRoomByRegisterApi(this.registerId);
      const roomPayload = roomRes && (roomRes.result || roomRes.data || roomRes);
      const roomId = roomPayload && roomPayload.room_id;
      const receiverUserId = roomPayload && roomPayload.receiver_user_id;
      if (!roomId || !receiverUserId) return;
      const doctorId = uni.getStorageSync('doctor_id') || uni.getStorageSync('user_id');
      if (!doctorId) return;
      const senderUserId = String(doctorId).startsWith('doctor-') ? String(doctorId) : `doctor-${doctorId}`;
      try {
        await sendToUserHttpApi({
          room_id: roomId,
          sender_user_id: senderUserId,
          receiver_user_id: receiverUserId,
          message_type: 4,
          message_content: JSON.stringify(inner),
          duration: 0
        });
      } catch (e) {
        console.warn('trySendPrescriptionChatMessage', e);
      }
    },
    clearPrescriptionData() {
      this.currentDrugs = []; this.diagnoses = []; this.diagnosisText = ''; this.medicalAdvice = ''; this.treatmentPrice = '';
      this.chineseConfig = { ruleType: 1, packageMethodId: null, processRuleId: null, childProcessRuleId: null, processRuleNoteId: null, dosage: 7, dayDosage: 2 };
      this.onlineTcmDiseasesId = null;
      this.onlineTcmMethodId = null;
      this.onlineTcmSyndromeId = null;
      clearAppliedSpecialPrescription(this);
    },
    /**
     * 清空药方（含特色方导入状态），与 PC 接诊「清空药方」一致
     */
    handleClearPrescriptionCart() {
      const hasContent = this.currentDrugs.length > 0
        || this.diagnoses.length > 0
        || !!(this.diagnosisText && String(this.diagnosisText).trim())
        || !!(this.medicalAdvice && String(this.medicalAdvice).trim())
        || Number(this.appliedSpecialPrescriptionId) > 0;
      if (!hasContent) {
        this.$toast('当前无药方内容');
        return;
      }
      uni.showModal({
        title: '清空药方',
        content: '确定清空当前药方吗？特色方将需重新导入。',
        confirmColor: '#FC3636',
        success: ({ confirm }) => {
          if (!confirm) return;
          this.clearPrescriptionData();
          this.saveToLocalStorage();
          PrescriptionStorage.clearAllPrescriptionData(this.registerId);
          this.$toast('已清空药方');
        },
      });
    },
    handleSaveAsCommonPrescription() {
      if (this.currentDrugs.length === 0) { this.$toast('请先添加药品后再保存为常用方'); return; }
      if (![1, 2].includes(this.activeCategory)) { this.$toast('当前分类不支持保存为常用方'); return; }
      this.showSaveCommonPrescriptionModal = true;
    },
    async handleConfirmSaveCommonPrescription() {
      if (!this.commonPrescriptionName || !this.commonPrescriptionName.trim()) { this.$toast('请输入常用方名称'); return; }
      if (![1, 2].includes(this.activeCategory)) { this.$toast('当前分类不支持保存为常用方'); return; }
      try {
        const storeId = uni.getStorageSync('store_id') || 11001;
        if (this.activeCategory === 1) {
          const drugs = this.currentDrugs.map((drug) => ({ drug_id: drug.id || drug.drug_id, drug_name: drug.drug_name || drug.name, number: drug.number || 1, price: drug.price || 0, way_id: drug.way_id || 0 }));
          const rt = this.chineseConfig.ruleType;
          const payload = { name: this.commonPrescriptionName.trim(), drugs, store_id: storeId, clinical_diagnose: this.diagnosisText || '', doctor_order: this.medicalAdvice || '', category: '1', dosage: this.chineseConfig.dosage || 7, day_dosage: this.chineseConfig.dayDosage || 2, rule_type: rt };
          if (rt === 1) payload.package_method_id = this.chineseConfig.packageMethodId;
          if (rt === 2) { payload.process_rule_id = this.chineseConfig.processRuleId || undefined; payload.child_process_rule_id = this.chineseConfig.childProcessRuleId || undefined; payload.process_rule_note_id = this.chineseConfig.processRuleNoteId || undefined; }
          const resCn = await saveChineseCommonPrescriptionApi(payload);
          if (!resCn || resCn.code !== 0) { this.$toast(resCn.msg || resCn.message || '保存失败'); return; }
        } else {
          const drugs = this.currentDrugs.map((drug) => ({ drug_id: drug.id || drug.drug_id, drug_name: drug.drug_name || drug.name, number: drug.number || 1, select_number: drug.select_number || 1, price: drug.price || 0, time_id: drug.time_id || 0, type_id: drug.type_id || 0, frequency_id: drug.frequency_id || 0, unit_id: drug.unit_id || 0, image: drug.image || '', instruction: drug.instruction || '', specification: drug.specification || '' }));
          const resW = await saveWestCommonPrescriptionApi({ name: this.commonPrescriptionName.trim(), drugs, store_id: storeId, clinical_diagnose: this.diagnosisText || '', doctor_order: this.medicalAdvice || '', category: '1' });
          if (!resW || resW.code !== 0) { this.$toast(resW.msg || resW.message || '保存失败'); return; }
        }
        this.$toast('保存成功');
        this.showSaveCommonPrescriptionModal = false; this.commonPrescriptionName = '';
        if (this.isCommonPrescription) { uni.removeStorageSync('add'); this.safeNavigateBack(400); }
      } catch (error) { console.error('保存常用方失败:', error); this.$toast('保存常用方失败，请重试'); }
    },
    buildSalespersonTransferPayload(patientData) {
      const drugs = this.currentDrugs.map((drug) => ({
        drug_id: drug.id || drug.drug_id || drug.index_id,
        drug_name: drug.drug_name || drug.name,
        number: drug.number || drug._quantity || 1,
        way_id: drug.way_id || 0,
      }));
      return {
        patient_name: patientData.patient_name,
        patient_mobile: patientData.patient_mobile,
        patient_address: patientData.patient_address,
        prescription_images: patientData.prescription_images || [],
        remark: patientData.remark || '',
        transfer_mode: 1,
        clinical_diagnose: '',
        doctor_order: '',
        dosage: this.chineseConfig.dosage || 7,
        day_dosage: this.chineseConfig.dayDosage || 2,
        drugs,
      };
    },
    async handleTransferPatientConfirm(patientData) {
      this.transferDrawerSubmitting = true;
      try {
        const wrap = await createClinicSalespersonTransferPrescription(
          this.buildSalespersonTransferPayload(patientData)
        );
        if (wrap && wrap.ok) {
          PrescriptionStorage.clearAllPrescriptionData(SALESPERSON_TRANSFER_STORAGE_KEY);
          this.showTransferPatientDrawer = false;
          if (this.$refs.transferPatientDrawer && this.$refs.transferPatientDrawer.resetForm) {
            this.$refs.transferPatientDrawer.resetForm();
          }
          // #ifdef MP-WEIXIN
          this.setPageBackGuardShow(false, { suppressLeave: true });
          uni.disableAlertBeforeUnload();
          // #endif
          this.$toast('提交成功');
          setTimeout(() => {
            uni.navigateTo({ url: '/subPackages/sub_clinic_salesperson/transfer-prescription/list' });
          }, 500);
        } else {
          this.$toast(wrap?.res?.msg || wrap?.res?.message || '提交失败');
        }
      } catch (error) {
        console.error('提交传方失败:', error);
        this.$toast('提交传方失败，请重试');
      } finally {
        this.transferDrawerSubmitting = false;
      }
    },
    tryLeaveSalespersonTransferPage(onConfirm) {
      if (this.hasTransferDraft) {
        uni.showModal({
          title: '提示',
          content: '有未提交的传方内容，确定退出？',
          success: ({ confirm }) => {
            if (confirm) {
              // #ifdef MP-WEIXIN
              this.setPageBackGuardShow(false, { suppressLeave: true });
              uni.disableAlertBeforeUnload();
              // #endif
              if (typeof onConfirm === 'function') onConfirm();
            } else {
              // #ifdef MP-WEIXIN
              this.setPageBackGuardShow(this.shouldEnablePageBackGuard, {
                suppressLeave: !this.shouldEnablePageBackGuard,
              });
              // #endif
            }
          },
        });
        return;
      }
      // #ifdef MP-WEIXIN
      this.setPageBackGuardShow(false, { suppressLeave: true });
      uni.disableAlertBeforeUnload();
      // #endif
      if (typeof onConfirm === 'function') onConfirm();
    },
    navigateToSalespersonWorkbench() {
      const pages = getCurrentPages();
      if (pages.length > 1) {
        this.safeNavigateBack(0);
        return;
      }
      // #ifdef MP-WEIXIN
      this.setPageBackGuardShow(false, { suppressLeave: true });
      uni.disableAlertBeforeUnload();
      // #endif
      uni.reLaunch({ url: SALESPERSON_HOME_URL });
    },
    /** 若有弹层打开则关闭第一个并返回 true（用于导航返回 / 微信 page-container leave 先关抽屉） */
    closeTopOverlayIfAny() {
      for (let i = 0; i < PRESCRIPTION_OVERLAY_KEYS.length; i++) {
        const k = PRESCRIPTION_OVERLAY_KEYS[i];
        if (this[k]) {
          this[k] = false;
          return true;
        }
      }
      return false;
    },
    /** 微信小程序：先关闭 page-container 拦截再退栈，避免 navigateBack 被吞 */
    safeNavigateBack(delayMs = 0) {
      const runNav = () => {
        // #ifdef MP-WEIXIN
        this.setPageBackGuardShow(false, { suppressLeave: true });
        setTimeout(() => {
          uni.navigateBack();
        }, 16);
        // #endif
        // #ifndef MP-WEIXIN
        uni.navigateBack();
        // #endif
      };
      if (delayMs > 0) {
        setTimeout(runNav, delayMs);
      } else {
        runNav();
      }
    },
    // #ifdef MP-WEIXIN
    onPageBackGuardLeave() {
      if (this._suppressPageBackGuardLeave) {
        this._suppressPageBackGuardLeave = false;
        return;
      }
      if (this.closeTopOverlayIfAny()) {
        this.$nextTick(() => {
          this.setPageBackGuardShow(this.shouldEnablePageBackGuard, { suppressLeave: true });
          this.syncSalespersonTransferUnloadAlert();
        });
        return;
      }
      this.setPageBackGuardShow(false);
      if (this.isSalespersonTransferMode) {
        this.tryLeaveSalespersonTransferPage(() => this.navigateToSalespersonWorkbench());
        return;
      }
      this.safeNavigateBack(0);
    },
    // #endif
    handleCustomBack() {
      if (this.closeTopOverlayIfAny()) return;
      if (this.isSalespersonTransferMode) {
        this.tryLeaveSalespersonTransferPage(() => this.navigateToSalespersonWorkbench());
        return;
      }
      this.safeNavigateBack(0);
    }
  }
};
</script>

<style lang="scss" scoped>
/* 基础与通用样式 */
.page-bg {
  background-color: #F4F6F8;
  min-height: 100vh;
}
.safe-area-inset-bottom { padding-bottom: env(safe-area-inset-bottom); }
.mx-32 { margin-left: 32rpx; margin-right: 32rpx; }
.m-x-32 { margin-left: 32rpx; margin-right: 32rpx; }
.m-b-24 { margin-bottom: 24rpx; }
.m-b-32 { margin-bottom: 32rpx; }
.m-b-40 { margin-bottom: 40rpx; }
.m-t-12 { margin-top: 12rpx; }
.m-t-16 { margin-top: 16rpx; }
.m-t-24 { margin-top: 24rpx; }
.m-t-64 { margin-top: 64rpx; }
.m-l-8 { margin-left: 8rpx; }
.m-l-16 { margin-left: 16rpx; }
.m-l-24 { margin-left: 24rpx; }
.m-l-32 { margin-left: 32rpx; }
.m-r-4 { margin-right: 4rpx; }
.m-r-8 { margin-right: 8rpx; }
.m-r-16 { margin-right: 16rpx; }
.m-r-32 { margin-right: 32rpx; }
.p-32 { padding: 32rpx; }
.p-b-40 { padding-bottom: 40rpx; }
.p-x-32 { padding-left: 32rpx; padding-right: 32rpx; }
.pt-20 { padding-top: 20rpx; }
.pt-32 { padding-top: 32rpx; }

/* 字体与颜色层级 */
.fs-24 { font-size: 24rpx; }
.fs-26 { font-size: 26rpx; }
.fs-28 { font-size: 28rpx; }
.fs-30 { font-size: 30rpx; }
.fs-32 { font-size: 32rpx; }
.fs-48 { font-size: 48rpx; }
.font-bold { font-weight: bold; }
.color-title { color: #2A2E35; }
.color-sub { color: #8A92A3; }
.color-primary { color: #00A88A; }
.color-danger { color: #FF4D4F; }
.color-price { color: #F53F3F; }
.price-link { color: #6ACDBB; text-decoration: underline; }
.text-gray { color: #6C7380; }

.white { background: #fff; }
.radius-12 { border-radius: 12rpx; }
.shadow-sm { box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.03); }
.border-t-dashed { border-top: 1px dashed #E2E8F0; }
.line-clamp-2 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.w-70 { width: 70%; }

/* Flex 布局辅助 */
.flex { display: flex; }
.flex-wrap { flex-wrap: wrap; }
.flex-row { display: flex; flex-direction: row; }
.flex-col { display: flex; flex-direction: column; }
.flex-jus-sp { justify-content: space-between; }
.flex-ali-center { align-items: center; }
.flex-ali-start { align-items: flex-start; }
.flex-jus-center { justify-content: center; }
.flex-1 { flex: 1; }
.ac { text-align: center; }

/* 定制化组件样式 */
.rp-icon {
  background: #2A2E35;
  color: #fff;
  font-size: 20rpx;
  font-weight: bold;
  padding: 4rpx 10rpx;
  border-radius: 6rpx 2rpx 6rpx 2rpx;
}

.tabs {
  background: #fff;
  border-bottom: 1px solid #F0F2F5;
}

/* 现代卡片设计 (西药 / 产品) */
.medicine-card {
  background: #fff;
  border-radius: 16rpx;
  padding: 24rpx;
  margin-bottom: 24rpx;
  box-shadow: 0 4rpx 16rpx rgba(42, 46, 53, 0.04);
  position: relative;
  overflow: hidden;
}

.drug-image-modern {
  width: 140rpx;
  height: 140rpx;
  border-radius: 12rpx;
  background-color: #F7F8FA;
  flex-shrink: 0;
  border: 1px solid #F0F2F5;
}

.usage-capsule {
  display: inline-flex;
  align-items: center;
  background: #E8F6F4;
  padding: 8rpx 16rpx;
  border-radius: 6rpx;
}

.card-actions {
  margin-top: 24rpx;
  padding-top: 20rpx;
  border-top: 1px dashed #F0F2F5;
}

.action-btn-text {
  display: flex;
  align-items: center;
  font-size: 26rpx;
  &.danger { color: #8A92A3; } /* 弱化删除，避免误触 */
}

.action-btn-ghost {
  padding: 10rpx 32rpx;
  border-radius: 30rpx;
  font-size: 26rpx;
  font-weight: bold;
  &.primary {
    color: #00A88A;
    background: #E8F6F4;
  }
}

/* 中药极简高密度标签云 */
.tcm-tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx;
}
.tcm-tag {
  display: inline-flex;
  align-items: center;
  background: #F7F8FA;
  padding: 12rpx 20rpx;
  border-radius: 8rpx;
  border: 1px solid #EBEFF5;
  transition: all 0.2s;

  .tcm-name {
    font-size: 28rpx;
    color: #2A2E35;
    font-weight: 500;
  }
  .tcm-weight {
    font-size: 26rpx;
    color: #00A88A;
    margin-left: 12rpx;
  }
  .tcm-way {
    font-size: 22rpx;
    color: #5b8ff9;
    margin-left: 8rpx;
    font-weight: 500;
  }
  .tcm-margin {
    font-size: 22rpx;
    color: #ff9800;
    margin-left: 8rpx;
    font-weight: bold;
  }
}

/* 简单产品精美步进器 */
.modern-stepper {
  background: #F7F8FA;
  border-radius: 8rpx;
  overflow: hidden;
  border: 1px solid #E2E8F0;
  .stepper-btn {
    width: 50rpx;
    height: 50rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #6C7380;
    font-size: 32rpx;
    font-weight: bold;
    background: #fff;
  }
  .stepper-val {
    min-width: 60rpx;
    text-align: center;
    color: #2A2E35;
    font-weight: bold;
  }
}

/* 底部操作栏（恢复原状） */
.register-mode-hint {
  padding: 16rpx 24rpx;
  background: #f0faf8;
  border-radius: 12rpx;
  border: 1rpx solid #d4efe8;
}
.register-mode-hint__text {
  font-size: 24rpx;
  color: #008771;
  line-height: 1.5;
}
.special-rx-card {
  padding: 20rpx 24rpx;
  background: #fffaf5;
  border-radius: 12rpx;
  border: 1rpx solid #ffe0c2;
}
.special-rx-card__inner {
  width: 100%;
}
.special-rx-card__action {
  width: 100%;
}
.bottom {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 32rpx;
  background: #fff;
  border-top: 1px solid #f0f0f0;
  z-index: 99;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}
.btnText {
  color: #6ACDBB;
  font-size: 28rpx;
  padding: 0 32rpx;
  flex-shrink: 0;
}
.btnText--danger {
  color: #FC3636;
}
</style>