Przeglądaj źródła

1.增加商品总库页面

Guos 1 miesiąc temu
rodzic
commit
5ceb2e7575

+ 148 - 0
src/api/hisStore/platformProduct.js

@@ -0,0 +1,148 @@
+import request from '@/utils/request'
+
+// 获取器免列表
+export function getExemptSecondMedicalDeviceList() {
+  return request({
+    url: '/store/store/exemptSecondMedicalDevice/getList',
+    method: 'get'
+  })
+}
+
+//产品成分校验
+export function selectForbiddenKeywords(fieldName, keywords) {
+  return request({
+    url: '/store/store/storeProduct/selectForbiddenKeywords',
+    method: 'post',
+    data: {
+      field: fieldName,
+      keywords: keywords
+    }
+  })
+}
+
+// 查询商品列表
+export function listStoreProduct(query) {
+  return request({
+    url: '/store/store/platformProduct/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 总后台商品总库协议过期提醒
+export function qualifications() {
+  return request({
+    url: '/store/store/platformProduct/productNoticeInfo',
+    method: 'get'
+  })
+}
+
+// 查询商品详细
+export function getStoreProduct(productId) {
+  return request({
+    url: '/store/store/platformProduct/' + productId,
+    method: 'get'
+  })
+}
+
+// 删除商品
+export function delStoreProduct(productId) {
+  return request({
+    url: '/store/store/platformProduct/' + productId,
+    method: 'delete'
+  })
+}
+
+//编辑商品
+export function addOrEdit(data) {
+  return request({
+    url: '/store/store/platformProduct/addOrEdit',
+    method: 'post',
+    data: data
+  })
+}
+
+//一键复制
+export function copyProduct(data) {
+  return request({
+    url: '/store/store/platformProduct/copyProduct',
+    method: 'post',
+    data: data
+  })
+}
+
+
+
+
+
+// 批量修改
+export function batchModify(param) {
+  return request({
+    url: '/store/store/storeProduct/batchModify',
+    method: 'post',
+    data: param
+  })
+}
+
+export function importTemplate() {
+  return request({
+    url: '/store/store/storeProduct/importTemplate',
+    method: 'get'
+  })
+}
+
+// 导出商品
+export function exportStoreProduct(query) {
+  return request({
+    url: '/store/store/storeProduct/export',
+    method: 'get',
+    params: query
+  })
+}
+
+export function exportDrugProduct(query) {
+  return request({
+    url: '/store/store/storeProduct/exportProduct',
+    method: 'get',
+    params: query
+  })
+}
+
+export function genFormatAttr(productId,json) {
+  return request({
+    url: '/store/store/storeProduct/genFormatAttr/'+productId,
+    method: 'post',
+    data: json
+  })
+}
+
+
+
+
+
+// 同步商品到580
+export function sync580(productId) {
+  return request({
+    url: '/store/store/storeProduct/sync580/'+productId,
+    method: 'post'
+  })
+}
+
+
+export function updateIsShow(productIds) {
+  return request({
+    url: '/store/store/storeProduct/updateFsStoreProductIsShowBatch/' + (Array.isArray(productIds) ? productIds.join(',') : productIds),
+    method: 'post'
+  })
+}
+
+
+
+// 查询商品详细
+export function getAuthInfo(productId) {
+  return request({
+    url: '/store/store/storeProduct/auditLog/' + productId,
+    method: 'get'
+  })
+}
+

+ 2800 - 0
src/views/hisStore/platformProduct/index.vue

@@ -0,0 +1,2800 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
+
+      <el-form-item label="商品分类" prop="cateId">
+        <treeselect v-model="queryParams.cateId" style="width:205.4px" :options="categoryOptions"
+                    :normalizer="normalizer" placeholder="请选择分类"/>
+      </el-form-item>
+
+      <el-form-item label="商品名称" prop="productName">
+        <el-input
+          v-model="queryParams.productName"
+          placeholder="请输入商品名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+
+      <el-form-item label="是否药品" prop="isDrug">
+        <el-select v-model="queryParams.isDrug" placeholder="请选择" clearable size="small">
+          <el-option
+            v-for="item in isDrugOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="商品类型" prop="productType">
+        <el-select v-model="queryParams.productType" placeholder="请选择商品类型" clearable size="small">
+          <el-option
+            v-for="item in productTypeOptions"
+            :key="item.dictValue"
+            :label="item.dictLabel"
+            :value="item.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+
+      <div v-if="medicalMallConfig.isAudit">
+        <el-form-item label="药品注册证书编号" prop="drugRegCertNo">
+          <el-input
+            v-model="queryParams.drugRegCertNo"
+            placeholder="请输入药品注册证书编号"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="通用名称" prop="commonName">
+          <el-input
+            v-model="queryParams.commonName"
+            placeholder="请输入通用名称"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="剂型" prop="dosageForm">
+          <el-input
+            v-model="queryParams.dosageForm"
+            placeholder="请输入剂型"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="单价" prop="unitPrice">
+          <el-input
+            v-model="queryParams.unitPrice"
+            placeholder="请输入单价"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="上市许可持有人" prop="mah">
+          <el-input
+            v-model="queryParams.mah"
+            placeholder="请输入上市许可持有人"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="持有人地址" prop="mahAddress">
+          <el-input
+            v-model="queryParams.mahAddress"
+            placeholder="请输入持有人地址"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="生产企业" prop="manufacturer">
+          <el-input
+            v-model="queryParams.manufacturer"
+            placeholder="请输入生产企业"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="生产企业地址" prop="manufacturerAddress">
+          <el-input
+            v-model="queryParams.manufacturerAddress"
+            placeholder="请输入生产企业地址"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="功能主治" prop="indications">
+          <el-input
+            v-model="queryParams.indications"
+            placeholder="请输入功能主治"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="用法用量" prop="dosage">
+          <el-input
+            v-model="queryParams.dosage"
+            placeholder="请输入用法用量"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="不良反应" prop="adverseReactions">
+          <el-input
+            v-model="queryParams.adverseReactions"
+            placeholder="请输入不良反应"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="禁忌" prop="contraindications">
+          <el-input
+            v-model="queryParams.contraindications"
+            placeholder="请输入禁忌"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+        <el-form-item label="注意事项" prop="precautions">
+          <el-input
+            v-model="queryParams.precautions"
+            placeholder="请输入注意事项"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+        <el-form-item label="规格" prop="prescribeSpec">
+          <el-input
+            v-model="queryParams.prescribeSpec"
+            placeholder="请输入规格"
+            clearable
+            size="small"
+          />
+        </el-form-item>
+
+      </div>
+
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['store:storeProduct:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="multiple"
+          @click="handleUpdate"
+          v-hasPermi="['store:storeProduct:edit']"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['store:storeProduct:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="info"
+          plain
+          icon="el-icon-upload2"
+          size="mini"
+          @click="handleImport"
+          v-hasPermi="['store:storeProduct:import']"
+        >导入
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['store:storePayment:export']"
+        >导出
+        </el-button>
+      </el-col>
+
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="primary"-->
+<!--          plain-->
+<!--          icon="el-icon-refresh"-->
+<!--          size="mini"-->
+<!--          :disabled="multiple"-->
+<!--          @click="handleSync"-->
+<!--          v-hasPermi="['store:storeProduct:sync']"-->
+<!--        >同步-->
+<!--        </el-button>-->
+<!--      </el-col>-->
+<!--      <el-col :span="1.5">-->
+<!--        <el-button-->
+<!--          type="danger"-->
+<!--          plain-->
+<!--          icon="el-icon-close"-->
+<!--          size="mini"-->
+<!--          :disabled="multiple"-->
+<!--          @click="handleBatchOff"-->
+<!--          v-hasPermi="['store:storeProduct:updateIsShow']"-->
+<!--        >批量下架-->
+<!--        </el-button>-->
+<!--      </el-col>-->
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-tabs type="card" v-model="activeName" @tab-click="handleClick">
+      <el-tab-pane label="全部商品" name="-1"></el-tab-pane>
+<!--      <el-tab-pane label="出售中" name="1"></el-tab-pane>-->
+<!--      <el-tab-pane label="待上架" name="0"></el-tab-pane>-->
+<!--      <el-tab-pane label="待审核" name="3"></el-tab-pane>-->
+<!--      <el-tab-pane label="已驳回" name="4"></el-tab-pane>-->
+    </el-tabs>
+
+    <el-table height="500" border v-loading="loading" :data="storeProductList"
+              @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="ID" align="center" prop="productId"/>
+      <el-table-column label="商品图片" align="center" width="120">
+        <template slot-scope="scope">
+          <el-popover
+            placement="right"
+            title=""
+            trigger="hover">
+            <img slot="reference" :src="scope.row.image" width="100">
+            <img :src="scope.row.image" style="max-width: 150px;">
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="productName"/>
+      <el-table-column label="分类" align="center" prop="cateName"/>
+      <el-table-column label="售价" align="center" prop="price">
+        <template slot-scope="scope">
+          <span v-if="scope.row.price!=null">{{ scope.row.price.toFixed(2) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="原价" align="center" prop="otPrice">
+        <template slot-scope="scope">
+          <span v-if="scope.row.otPrice!=null">{{ scope.row.otPrice.toFixed(2) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="销量" align="center" prop="sales"/>
+      <el-table-column label="库存" align="center" prop="stock"/>
+      <el-table-column label="类型" align="center" prop="productType">
+        <template slot-scope="scope">
+          <el-tag prop="productType" v-for="(item, index) in productTypeOptions"
+                  v-if="scope.row.productType==item.dictValue">{{ item.dictLabel }}
+          </el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="状态" align="center" prop="isShow">
+        <template slot-scope="scope">
+          <dict-tag :options="isShowOptions" :value="scope.row.isShow"/>
+        </template>
+      </el-table-column>
+
+<!--      <el-table-column label="同步状态" align="center" prop="pushStatus">-->
+<!--        <template slot-scope="scope">-->
+<!--          <el-tag :type="scope.row.pushStatus === 1 ? 'success' : scope.row.pushStatus === 2 ? 'danger' : 'warning'">-->
+<!--            {{-->
+<!--              scope.row.pushStatus === 0 ? '推送中' : scope.row.pushStatus === 1 ? '成功' : scope.row.pushStatus === 2 ? '失败' : '未同步'-->
+<!--            }}-->
+<!--          </el-tag>-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200px">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['store:storeProduct:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-postcard"
+            @click="showOperLog(scope.row)"
+            v-hasPermi="['his:storeProduct:auditLog']"
+          >审核记录
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['store:storeProduct:remove']"
+          >删除
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-document-copy"
+            @click="productCopy(scope.row)"
+            v-hasPermi="['his:storeProduct:copyProduct']"
+          >一键复制
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <el-dialog :title="title" :visible.sync="open1" width="580px" append-to-body>
+      <el-form ref="form1" :model="form1" :rules="rules" label-width="80px">
+        <el-form-item label="商品状态" prop="status">
+          <el-radio-group v-model="form1.isShow">
+            <el-radio :label="item.dictValue" v-for="item in isShowOptions">{{ item.dictLabel }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="商城展示" prop="isDisplay">
+          <el-radio-group v-model="form1.isDisplay">
+            <el-radio :label="item.dictValue" v-for="item in isDisplayOptions">{{ item.dictLabel }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm1">确 定</el-button>
+        <el-button @click="cancel1">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 添加或修改商品对话框 -->
+    <el-dialog :title="title" v-if="open" :fullscreen="isFullscreen" :visible.sync="open" width="1000px" append-to-body
+               :show-close="false">
+      <template v-slot:title>
+        <div style="display: flex; justify-content: space-between; align-items: center;">
+          <span>{{ title }}</span>
+          <div>
+            <!-- 全屏按钮 -->
+            <el-button type="text" @click="handleFullScreen" size="middle">
+              <i class="el-icon-full-screen"></i>
+            </el-button>
+            <!--关闭按钮-->
+            <el-button type="text" @click="open = false">
+              <i class="el-icon-close"></i>
+            </el-button>
+          </div>
+        </div>
+      </template>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="商品名称" prop="productName">
+              <el-input v-model="form.productName" @blur="handleProductNameBlur" placeholder="请输入商品名称"  @input="onProductNameInput"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="商品分类" prop="cateId">
+              <treeselect v-model="form.cateId" :options="categoryOptions" :normalizer="normalizer"
+                          placeholder="请选择上级分类" @input="onCategoryOrStoreChange"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="商品类型" prop="productType">
+              <el-select style="width: 240px" v-model="form.productType" placeholder="请选择商品类型" clearable
+                         size="small">
+                <el-option
+                  v-for="item in productTypeOptions"
+                  :key="item.dictValue"
+                  :label="item.dictLabel"
+                  :value="item.dictValue"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="器械编码" prop="medicalDeviceCode" v-if="showMedicalDeviceCode">
+              <el-input v-model="form.medicalDeviceCode" placeholder="请输入器械编码" @blur="onCategoryOrStoreChange" style="width: calc(100% - 120px);"/>
+              <el-button type="primary" @click="showExemptDeviceDialog" style="margin-left: 10px;" v-if="shouldShowExemptDeviceButton">显示器免</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="关键字" prop="keyword">
+              <el-input v-model="form.keyword" placeholder="请输入关键字"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="单位名" prop="unitName">
+              <el-input v-model="form.unitName" placeholder="请输入单位名"/>
+            </el-form-item>
+          </el-col>
+
+        </el-row>
+        <el-row :gutter="10">
+          <el-col :span="12">
+            <el-form-item label="是否药品" prop="isDrug" v-if="!isMedicalDeviceCategory">
+              <el-radio-group v-model="form.isDrug">
+                <el-radio
+                  v-for="item in isDrugOptions"
+                  :key="item.dictValue"
+                  :label="item.dictValue"
+                >{{ item.dictLabel }}
+                </el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <div v-if="form.isDrug === '1' ">
+          <el-form-item label="头图展示" prop="drugImage">
+            <Material v-model="drugImageArr" type="image" :num="1" :width="150" :height="150"/>
+          </el-form-item>
+          <div v-if="medicalMallConfig.isMedicalMall">
+            <el-row>
+              <el-col :span="12">
+                <el-form-item :label="isMedicalDeviceCategory ? '注册证号/备案凭证号' : '批准文号'" prop="drugRegCertNo">
+                  <el-input v-model="form.drugRegCertNo" :placeholder="isMedicalDeviceCategory ?'请输入注册证号/备案凭证号' : '请输入批准文号'"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="通用名称" prop="commonName" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.commonName" placeholder="请输入通用名称"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="剂型" prop="dosageForm" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.dosageForm" placeholder="请输入剂型"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="单价" prop="unitPrice">
+                  <el-input v-model="form.unitPrice" placeholder="请输入单价" type="number"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="规格" prop="prescribeSpec">
+                  <el-input v-model="form.prescribeSpec" placeholder="请输入规格"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="上市许可持有人" prop="mah">
+                  <el-input v-model="form.mah" placeholder="请输入上市许可持有人"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="持有人地址" prop="mahAddress">
+                  <el-input v-model="form.mahAddress" placeholder="请输入上市许可持有人地址"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="生产企业" prop="manufacturer">
+                  <el-input v-model="form.manufacturer" placeholder="请输入生产企业"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="企业地址" prop="manufacturerAddress">
+                  <el-input v-model="form.manufacturerAddress" placeholder="请输入生产企业地址"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-collapse v-model="activeValue" accordion>
+              <el-collapse-item title="" name="1">
+                <el-form-item label="功能主治" prop="indications" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.indications" type="textarea" placeholder="请输入功能主治"/>
+                </el-form-item>
+
+                <el-form-item label="成分" prop="ingredient" v-if="!isMedicalDeviceCategory">
+                  <el-input
+                    v-model="form.ingredient"
+                    type="textarea"
+                    placeholder="请输入成分"
+                    @blur="handleIngredientBlur"
+                    @input="onIngredientInput"
+                  />
+                  <div v-if="ingredientError" class="el-form-item__error">{{ ingredientError }}</div>
+                </el-form-item>
+
+                <el-form-item label="用法用量" prop="dosage" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.dosage" type="textarea" placeholder="请输入用法用量"/>
+                </el-form-item>
+
+                <el-form-item label="不良反应" prop="adverseReactions" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.adverseReactions" type="textarea" placeholder="请输入不良反应"/>
+                </el-form-item>
+
+                <el-form-item label="禁忌" prop="contraindications" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.contraindications" type="textarea" placeholder="请输入禁忌"/>
+                </el-form-item>
+
+                <el-form-item label="注意事项" prop="precautions" v-if="!isMedicalDeviceCategory">
+                  <el-input v-model="form.precautions" type="textarea" placeholder="请输入注意事项"/>
+                </el-form-item>
+              </el-collapse-item>
+            </el-collapse>
+          </div>
+          <el-form-item label="说明书" prop="instructionManual">
+            <editor ref="instructionManualRef" @on-text-change="updateInstructionManualText"/>
+          </el-form-item>
+        </div>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="商品简介" prop="productInfo">
+              <el-input v-model="form.productInfo" type="textarea" :rows="2" placeholder="请输入商品简介"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="商品图片" prop="image">
+          <Material v-model="imageArr" type="image" :num="1" :width="150" :height="150"/>
+        </el-form-item>
+
+        <el-form-item label="轮播图" prop="sliderImage">
+          <Material v-model="photoArr" type="image" :num="10" :width="150" :height="150"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="商品规格:" props="specType">
+              <el-radio-group v-model="form.specType">
+                <el-radio :label="0" class="radio">单规格</el-radio>
+                <el-radio :label="1">多规格</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <!-- 多规格添加-->
+          <el-col :span="24" v-if="form.specType === 1" class="noForm">
+            <el-col :span="24">
+              <el-form-item label="选择规格:" prop="">
+                <div class="acea-row row-middle">
+                  <el-select v-model="form.selectRule" style="width: 23%;">
+                    <el-option v-for="(item, index) in ruleList" :value="item.ruleName" :key="index">{{
+                        item.ruleName
+                      }}
+                    </el-option>
+                  </el-select>
+                  <el-button style="margin-left:10px;" type="primary" class="mr20" @click="confirm">确认</el-button>
+                </div>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="24">
+              <el-form-item v-if="attrs!=null&&attrs.length!==0">
+                <div v-for="(item, index) in attrs" :key="index">
+                  <div class="acea-row row-middle"><span class="mr5">{{ item.value }}</span>
+                    <i class="el-icon-circle-close" @click="handleRemoveRole(index)"></i>
+                  </div>
+                  <div class="rulesBox">
+                    <el-tag type="dot" closable color="primary" v-for="(j, indexn) in item.detail" :key="indexn"
+                            :name="j" class="mr20" @close="handleRemove2(item.detail,indexn)">{{ j }}
+                    </el-tag>
+                    <el-input placeholder="请输入属性名称" v-model="item.detail.attrsVal"
+                              style="width: 200px">
+                      <el-button slot="append" type="primary" @click="createAttr(item.detail.attrsVal,index)">添加
+                      </el-button>
+                    </el-input>
+                  </div>
+                </div>
+              </el-form-item>
+            </el-col>
+
+            <el-col :span="24" v-if="createBnt">
+              <el-form-item>
+                <el-button type="primary" size="small" icon="md-add" @click="addBtn" class="mr15">添加新规格</el-button>
+                <el-button type="success" size="small" @click="generate">立即生成</el-button>
+              </el-form-item>
+            </el-col>
+            <el-col :span="24" v-if="showIput">
+              <el-col :xl="6" :lg="9" :md="10" :sm="24" :xs="24">
+                <el-form-item label="规格:">
+                  <el-input placeholder="请输入规格" v-model="formDynamic.attrsName"/>
+                </el-form-item>
+              </el-col>
+              <el-col :xl="6" :lg="9" :md="10" :sm="24" :xs="24">
+                <el-form-item label="规格值:">
+                  <el-input v-model="formDynamic.attrsVal" placeholder="请输入规格值"/>
+                </el-form-item>
+              </el-col>
+              <el-col :xl="6" :lg="5" :md="10" :sm="24" :xs="24">
+                <el-button type="primary" @click="createAttrName">确定</el-button>
+                <el-button type="danger" @click="closeAttrName">取消</el-button>
+              </el-col>
+            </el-col>
+            <!-- 多规格设置-->
+            <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" v-if="manyFormValidate!=null&&manyFormValidate.length">
+              <!-- 多规格表格-->
+              <el-col :span="24">
+                <el-form-item label="商品属性:" class="labeltop">
+
+                  <el-table :data="manyFormValidate" size="small" style="width: 90%;" border>
+                    <el-table-column type="myindex" v-for="(item,index) in form.header" :key="index"
+                                     :width="item.minWidth" :label="item.title" :property="item.slot" align="center">
+                      <template slot-scope="scope">
+                        <div v-if="scope.column.property == 'image'" align="center">
+                          <single-img v-model="scope.row[scope.column.property]" type="image" :num="1" :width="60"
+                                      :height="60"/>
+                        </div>
+                        <div v-else-if="scope.column.property.indexOf('value') != -1" align="center">
+                          {{ scope.row[scope.column.property] }}
+                        </div>
+                        <div v-else-if="scope.column.property == 'action'" align="center">
+                          <a @click="delAttrTable(scope.$index)" align="center">删除</a>
+                        </div>
+                        <div v-else align="center">
+                          <el-input v-model="scope.row[scope.column.property]" align="center"/>
+                        </div>
+                      </template>
+                    </el-table-column>
+                  </el-table>
+
+                </el-form-item>
+              </el-col>
+            </el-col>
+          </el-col>
+
+          <!-- 单规格表格-->
+          <el-col :xl="23" :lg="24" :md="24" :sm="24" :xs="24" v-if="form.specType === 0" style="">
+            <el-form-item>
+              <el-table :data="oneFormValidate" size="small" border>
+                <el-table-column prop="image" label="图片" align="center">
+                  <template slot-scope="scope">
+                    <single-img v-model="scope.row.image" type="image" :num="1" :width="60" :height="60"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="price" label="售价" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.price"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="agentPrice" label="代理价" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.agentPrice"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="cost" label="成本价" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.cost"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="otPrice" label="原价" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.otPrice"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="stock" label="库存" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.stock" maxlength="7"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="barCode" label="商品条码" width="130px" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.barCode"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="barCode" label="组合编号" width="130px" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.groupBarCode"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="weight" label="重量(KG)" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.weight"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="volume" label="体积(m³)" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.volume"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="volume" label="所需积分" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.integral"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="volume" label="一级返佣" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.brokerage"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="volume" label="二级返佣" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.brokerageTwo"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="volume" label="三级返佣" align="center">
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model="scope.row.brokerageThree"/>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="运费模板:" prop="tempId">
+              <div class="acea-row">
+                <el-select v-model="form.tempId" class="mr20">
+                  <el-option v-for="(item,index) in templateList" :value="item.id" :key="index" :label="item.name">
+                  </el-option>
+                </el-select>
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="商品详情" prop="description">
+          <editor ref="myeditor" @on-text-change="updateText"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="商品状态" prop="isShow">
+              <el-radio-group v-model="form.isShow">
+                <el-radio
+                  :label="item.dictValue"
+                  v-for="item in isShowOptions"
+                  :key="item.dictValue"
+                  v-if="item.dictValue === '0' || item.dictValue === '1'">
+                  {{ item.dictLabel }}
+                </el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="是否热卖" prop="isHot">
+              <el-radio-group v-model="form.isHot">
+                <el-radio :label="item.dictValue" v-for="item in isHotOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="猜你喜欢" prop="isGood">
+              <el-radio-group v-model="form.isGood">
+                <el-radio :label="item.dictValue" v-for="item in isGoodOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="精品推荐" prop="isBest">
+              <el-radio-group v-model="form.isBest">
+                <el-radio :label="item.dictValue" v-for="item in isBestOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="新品首发" prop="isNew">
+              <el-radio-group v-model="form.isNew">
+                <el-radio :label="item.dictValue" v-for="item in isNewOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="返还积分">
+              <el-input-number v-model="form.giveIntegral" :min="0" placeholder="请输入积分"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="商城展示" prop="isDisplay">
+              <el-radio-group v-model="form.isDisplay">
+                <el-radio :label="item.dictValue" v-for="item in isDisplayOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+
+            <el-form-item label="排序" prop="sort">
+              <el-input-number :min="0" v-model="form.sort" placeholder="请输入排序"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="销量" prop="sales">
+              <el-input-number :min="0" v-model="form.sales" placeholder="请输入销量"/>
+            </el-form-item>
+          </el-col>
+
+        </el-row>
+        <el-form-item label="推广分类" prop="tuiCateId">
+          <el-select style="width: 240px" v-model="form.tuiCateId" placeholder="请选择推广分类" clearable size="small">
+            <el-option
+              v-for="item in productTuiCateOptions"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+
+        <div v-if="form.isDrug === '1'">
+        <el-form-item v-if="form.isShow==='1'" label="审核说明" prop="reviewAudit">
+          <el-select style="width: 240px" v-model="form.reviewAudit" placeholder="请选择审核说明" clearable
+                    size="small">
+            <el-option
+              v-for="item in reviewAuditOptions"
+              :key="item.dictValue"
+              :label="item.dictLabel"
+              :value="item.dictValue"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="非首营链接" prop="businessLink" v-if="form.reviewAudit === '1'">
+          <el-input :min="0" v-model="form.businessLink" placeholder="请输入非首营链接"/>
+        </el-form-item>
+
+        <!--    生产企业营业执照    -->
+        <el-form-item v-if="form.isShow === '1'" label="生产企业营业执照" prop="business">
+          <Material v-model="businessArr" type="image" :num="1" :width="150" :height="150"/>
+        </el-form-item>
+
+        <el-form-item v-if="form.isShow === '1' && businessArr.length > 0" label="生产企业营业执照是否长期有效" prop="isBusinessPermanent">
+          <el-switch v-model="businessValue" active-color="#13ce66" inactive-color="#ff4949" />
+        </el-form-item>
+
+          <el-form-item v-if="form.isShow === '1' && businessArr.length > 0 && !businessValue" prop="businessExpire">
+            <el-date-picker
+              v-model="form.businessExpire"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期">
+            </el-date-picker>
+          </el-form-item>
+
+        <!--生产企业的生产许可证/备案凭证-->
+        <el-form-item v-if="form.isShow === '1'" label="生产企业的生产许可证/备案凭证" prop="license">
+          <Material v-model="licenseArr" type="image" :num="1" :width="150" :height="150"/>
+        </el-form-item>
+
+        <el-form-item v-if="form.isShow === '1' && licenseArr.length > 0" label="生产企业的生产许可证/备案凭证是否长期有效" prop="isLicensePermanent">
+            <el-switch v-model="licenseValue" active-color="#13ce66" inactive-color="#ff4949" />
+        </el-form-item>
+
+          <el-form-item v-if="form.isShow === '1' && licenseArr.length > 0 && !licenseValue" prop="licenseExpire">
+            <el-date-picker
+              v-model="form.licenseExpire"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期">
+            </el-date-picker>
+          </el-form-item>
+
+        <!--商品注册证/备案凭证-->
+        <el-form-item v-if="form.isShow === '1'" label="商品注册证/备案凭证" prop="certificate">
+          <Material v-model="certificateArr" type="image" :num="1" :width="150" :height="150"/>
+        </el-form-item>
+
+        <el-form-item v-if="form.isShow === '1' && licenseArr.length > 0" label="商品注册证/备案凭证是否长期有效" prop="isCertificatePermanent">
+          <el-switch v-model="certificateValue" active-color="#13ce66" inactive-color="#ff4949" />
+        </el-form-item>
+
+        <el-form-item v-if="form.isShow === '1' && certificateArr.length > 0 && !certificateValue" prop="certificateExpire">
+          <el-date-picker
+              v-model="form.certificateExpire"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期">
+          </el-date-picker>
+        </el-form-item>
+        </div>
+
+        <el-form-item label="国药准字" v-if="form.productType==2" prop="prescribeCode">
+          <el-input v-model="form.prescribeCode" placeholder="请输入国药准字"/>
+        </el-form-item>
+        <el-form-item label="规格" v-if="form.productType==2" prop="prescribeSpec">
+          <el-input v-model="form.prescribeSpec" placeholder="请输入规格"/>
+        </el-form-item>
+        <el-form-item label="生产厂家" v-if="form.productType==2" prop="prescribeFactory">
+          <el-input v-model="form.prescribeFactory" placeholder="请输入生产厂家"/>
+        </el-form-item>
+        <el-form-item label="处方名" v-if="form.productType==2" prop="prescribeName">
+          <el-input v-model="form.prescribeName" placeholder="请输入处方名"/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+      <el-upload
+        ref="upload"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=' + upload.updateSupport"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+        <div class="el-upload__tip text-center" slot="tip">
+          <div class="el-upload__tip" slot="tip">
+            <!--     <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的数据 -->
+          </div>
+          <span>仅允许导入xls、xlsx格式文件。</span>
+          <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
+                   @click="importTemplate">下载模板
+          </el-link>
+        </div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFileForm">确 定</el-button>
+        <el-button @click="upload.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <el-dialog
+      title="首营资质消息提示"
+      :visible.sync="dialogVisible"
+      width="40%"
+      center>
+      <div v-for="(item,index) in promptList">({{ index + 1 }})、{{ item }}</div>
+      <span slot="footer" class="dialog-footer">
+       <el-button type="primary" @click="dialogVisible = false">已 知 晓</el-button>
+      </span>
+    </el-dialog>
+
+    <el-dialog
+      :title=titleValue
+      :visible.sync="authVisible"
+      width="50%"
+      :before-close="handleClose"
+      center>
+      <el-table :data="auditLogs" border>
+        <el-table-column label="描述" align="center" prop="des" :show-overflow-tooltip="true" />
+        <el-table-column label="操作人员" align="center" prop="operName" width="100" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
+        <el-table-column label="操作日期" align="center" prop="operTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.operTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="审核理由" align="center" prop="reason" ></el-table-column>
+        <el-table-column label="图片" align="center" prop="attachImage" width="100" >
+          <template slot-scope="scope">
+            <el-image
+              style="width: 100px"
+              :src="scope.row.attachImage"
+              :preview-src-list="[scope.row.attachImage]"
+              v-if="scope.row.attachImage">
+            </el-image>
+            <span v-else >无图片</span >
+          </template>
+        </el-table-column>
+      </el-table>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="authVisible = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+
+<!-- 免于经营备案的第二类医疗器械产品弹窗 -->
+<el-dialog title="免于经营备案的第二类医疗器械产品" :visible.sync="exemptDeviceDialogVisible" width="80%" append-to-body :modal-append-to-body="false" z-index="9999" top="5vh" custom-class="exempt-device-dialog">
+  <el-form :model="exemptDeviceQueryParams" ref="exemptDeviceQueryForm" :inline="true" label-width="80px">
+    <el-form-item label="产品名称">
+      <el-input v-model="exemptDeviceQueryParams.productName" placeholder="请输入产品名称" clearable size="small" @keyup.enter.native="handleExemptDeviceQuery" />
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" icon="el-icon-search" size="mini" @click="handleExemptDeviceQuery">搜索</el-button>
+      <el-button icon="el-icon-refresh" size="mini" @click="resetExemptDeviceQuery">重置</el-button>
+    </el-form-item>
+  </el-form>
+
+  <el-table v-loading="exemptDeviceLoading" :data="exemptDeviceList" border>
+    <el-table-column label="产品序号" align="center" prop="serialNumber" />
+    <el-table-column label="产品名称" align="center" prop="productName" />
+    <el-table-column label="目录名称" align="center" prop="directoryName" />
+    <el-table-column label="产品描述" align="center" prop="productDescription" />
+    <el-table-column label="产品用途" align="center" prop="usageStr" />
+  </el-table>
+
+  <div slot="footer" class="dialog-footer">
+    <el-button @click="exemptDeviceDialogVisible = false">关 闭</el-button>
+  </div>
+</el-dialog>
+
+    <!-- 溯源码管理弹窗 -->
+    <el-dialog
+      :title="titleVisible"
+      :visible.sync="verifyDialogVisible"
+      width="90%"
+      append-to-body
+      :before-close="handleVerifyDialogClose"
+    >
+      <VerifyCode
+        v-if="verifyDialogVisible"
+        :product-id="currentProductId"
+        ref="verifyCodeRef"
+      />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  genFormatAttr,
+  listStoreProduct,
+  getStoreProduct,
+  delStoreProduct,
+  addOrEdit,
+  exportStoreProduct,
+  importTemplate,
+  batchModify,
+  sync580,
+  updateIsShow, exportDrugProduct,getAuthInfo,copyProduct,selectForbiddenKeywords,checkStoreLicense,getExemptSecondMedicalDeviceList
+} from "@/api/hisStore/platformProduct";
+import {qualifications} from "@/api/hisStore/platformProduct";
+import {getAllStoreProductCategory} from "@/api/hisStore/storeProductCategory";
+import {getAllStoreProductRule} from "@/api/hisStore/storeProductRule";
+import {getAllShippingTemplates} from "@/api/hisStore/shippingTemplates";
+import {getToken} from "@/utils/auth";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import Editor from '@/components/Editor/wang';
+import Material from '@/components/Material'
+import singleImg from '@/components/Material/single'
+import {getCompanyList} from "@/api/company/company";
+import {listStore} from '@/api/hisStore/store'
+import {getConfigByKey} from '@/api/system/config'
+import VerifyCode from '@/views/hisStore/storeVerify/index.vue';
+
+export default {
+  name: "PlatFormProduct",
+  components: {
+    Treeselect,
+    Editor,
+    Material,
+    VerifyCode,
+    singleImg
+  },
+  created() {
+    this.$nextTick(() => {
+      this.handleNoticeInfo();
+    });
+    this.getDicts("sys_order_status").then(response => {
+      this.orderOptions = response.data;
+    });
+    this.getDicts("store_product_tui_cate").then((response) => {
+      this.productTuiCateOptions = response.data;
+    });
+    getConfigByKey("medicalMall.func.switch").then(response => {
+      if (response.data && response.data.configValue) {
+        this.medicalMallConfig = JSON.parse(response.data.configValue);
+      }
+    });
+    this.getDicts("store_product_enable").then((response) => {
+      this.isNewOptions = response.data;
+      this.isBestOptions = response.data;
+      this.isHotOptions = response.data;
+      this.isGoodOptions = response.data;
+      this.isDisplayOptions = response.data;
+    });
+    this.getDicts("store_product_type").then((response) => {
+      this.productTypeOptions = response.data;
+      // if (!this.medicalMallConfig.isMedicalMall &&
+      //   this.productTypeOptions.length === 4) {
+      //   //删除后两项
+      //   this.productTypeOptions.splice(2, 2);
+      // }
+    });
+    this.getDicts("store_product_is_show").then((response) => {
+      this.isShowOptions = response.data;
+    });
+    getAllShippingTemplates().then(response => {
+      this.templateList = response.data;
+    });
+    getAllStoreProductRule().then(response => {
+      this.ruleList = response.data;
+    });
+    getCompanyList().then(response => {
+      this.companyOptions = response.data;
+    });
+    listStore().then(response => {
+      this.storeOptions = response.rows;
+    });
+
+    this.getTreeselect();
+    this.getList();
+  },
+  computed: {
+    // 计算属性:是否显示显示器免按钮
+    shouldShowExemptDeviceButton() {
+      // 只有在显示器械编码输入框且不是III类器械时才显示按钮
+      return this.showMedicalDeviceCode &&
+             this.form.cateId &&
+             this.cateIdToNameMap[this.form.cateId] &&
+             !this.cateIdToNameMap[this.form.cateId].includes('III类器械');
+    },
+    // 判断当前分类是否为医疗器械分类
+    isMedicalDeviceCategory() {
+      const cateName = this.cateIdToNameMap[this.form.cateId];
+      return cateName !== undefined && cateName.includes('器械');
+    }
+  },
+  watch: {
+    businessArr(val) {
+      this.form.business = val.join(',');
+      this.$nextTick(() => {
+        // 1. 组件层面清除校验
+        if (this.$refs.form) {
+          this.$refs.form.clearValidate('business');
+        }
+        // 2. DOM层面强制移除错误提示
+        const errorDom = document.querySelector('.el-form-item__error[style*="business"]');
+        if (errorDom) {
+          errorDom.style.display = 'none'; // 隐藏提示
+          // 或彻底移除:errorDom.remove();
+        }
+      });
+    },
+      // 生产许可证
+      licenseArr(val) {
+        this.form.license = val.join(',');
+        this.$nextTick(() => {
+          // 1. 组件层面清除校验
+          if (this.$refs.form) {
+            this.$refs.form.clearValidate('license');
+          }
+          // 2. DOM层面强制移除错误提示
+          const errorDom = document.querySelector('.el-form-item__error[style*="license"]');
+          if (errorDom) {
+            errorDom.style.display = 'none'; // 隐藏提示
+            // 或彻底移除:errorDom.remove();
+          }
+        });
+      },
+      // 注册证书
+      certificateArr(val) {
+        this.form.certificate = val.join(',');
+        this.$nextTick(() => {
+          // 1. 组件层面清除校验
+          if (this.$refs.form) {
+            this.$refs.form.clearValidate('certificate');
+          }
+          // 2. DOM层面强制移除错误提示
+          const errorDom = document.querySelector('.el-form-item__error[style*="certificate"]');
+          if (errorDom) {
+            errorDom.style.display = 'none'; // 隐藏提示
+            // 或彻底移除:errorDom.remove();
+          }
+        });
+      },
+      // 其他字段(如drugImageArr等)按相同逻辑补充
+      drugImageArr(val) {
+        this.form.drugImage = val.join(',');
+        this.$nextTick(() => {
+          if (this.$refs.form) {
+            this.$refs.form.clearValidate('drugImage');
+            this.$refs.form.validateField('drugImage');
+          }
+        });
+      },
+    voucherArr(val) {
+      this.form.voucher = val.length > 0 ? val.join(',') : '';
+      this.$nextTick(() => {
+        this.$refs.form && this.$refs.form.validateField('voucher');
+        this.$refs.form && this.$refs.form.validateField('voucherExpire');
+      });
+    },
+    gmpAuthArr(val) {
+      this.form.gmpAuth = val.length > 0 ? val.join(',') : '';
+      this.$nextTick(() => {
+        this.$refs.form && this.$refs.form.validateField('gmpAuth');
+      });
+    },
+    imageArr(val) {
+      this.form.image = val.length > 0 ? val.join(',') : '';
+      this.$nextTick(() => {
+        this.$refs.form && this.$refs.form.validateField('image');
+      });
+    },
+    photoArr(val) {
+      this.form.sliderImage = val.length > 0 ? val.join(',') : '';
+      this.$nextTick(() => {
+        this.$refs.form && this.$refs.form.validateField('sliderImage');
+      });
+    },
+    qualificationArr(val) {
+      this.form.qualificationCertificate = val.length > 0 ? val.join(',') : '';
+      this.$nextTick(() => {
+        this.$refs.form && this.$refs.form.validateField('qualificationCertificate');
+      });
+    },
+    // 监听商品分类变化
+    'form.cateId': {
+      handler(newVal, oldVal) {
+        // 分类变化时动态修改验证规则
+        const cateName = this.cateIdToNameMap[newVal];
+        // 判断是否包含"器械"
+        if(cateName !== undefined && cateName.includes('器械')){
+          this.displayDemo = true;
+          // 当分类包含"器械"时,默认设置为药品
+          if (cateName.includes('器械')) {
+            this.form.isDrug = "1";
+          }
+        } else {
+          this.displayDemo = false;
+        }
+
+        // 判断是否为II类器械或III类器械,如果是则显示器械编码输入框
+        if (cateName !== undefined && (cateName.includes('II类器械') || cateName.includes('III类器械'))) {
+          this.showMedicalDeviceCode = true;
+          // 只有当商品分类为II类器械时才显示显示器免按钮
+          this.showExemptDeviceButton = cateName.includes('II类器械');
+        } else {
+          this.showMedicalDeviceCode = false;
+          this.showExemptDeviceButton = false;
+        }
+
+        // 判断是否包含"处方药"
+        const isPrescriptionDrug = cateName !== undefined && cateName.includes('处方药');
+
+        // 如果是处方药,则移除相关字段的必填校验
+        if (isPrescriptionDrug) {
+          // 移除必填校验规则
+          const fieldsToRemoveRequired = ['indications', 'ingredient', 'dosage', 'adverseReactions', 'contraindications', 'precautions'];
+          fieldsToRemoveRequired.forEach(field => {
+            if (this.rules[field]) {
+              // 过滤掉 required 规则
+              this.rules[field] = this.rules[field].filter(rule => rule.required !== true);
+            }
+          });
+        } else {
+          // 如果不是处方药,恢复默认的必填校验规则
+          // 恢复 ingredient 字段的必填规则
+          if (!this.rules.ingredient) {
+            this.rules.ingredient = [];
+          }
+          if (!this.rules.ingredient.some(rule => rule.required)) {
+            this.rules.ingredient.unshift({ required: true, message: "成分不能为空", trigger: "blur" });
+          }
+
+          // 恢复其他字段的必填规则
+          const requiredRules = {
+            indications: [{ required: true, message: "功能主治不能为空", trigger: "blur" }],
+            dosage: [{ required: true, message: "用法用量不能为空", trigger: "blur" }],
+            adverseReactions: [{ required: true, message: "不良反应不能为空", trigger: "blur" }],
+            contraindications: [{ required: true, message: "禁忌不能为空", trigger: "blur" }],
+            precautions: [{ required: true, message: "注意事项不能为空", trigger: "blur" }]
+          };
+
+          Object.keys(requiredRules).forEach(field => {
+            if (!this.rules[field]) {
+              this.rules[field] = [];
+            }
+            // 检查是否已有 required 规则,如果没有就添加
+            if (!this.rules[field].some(rule => rule.required)) {
+              this.rules[field] = [...requiredRules[field], ...this.rules[field]];
+            }
+          });
+        }
+
+        this.ingredientError = '';
+        // 清除验证状态
+        this.$nextTick(() => {
+          if (this.$refs.form) {
+            this.$refs.form.clearValidate([
+              'indications',
+              'ingredient',
+              'dosage',
+              'adverseReactions',
+              'contraindications',
+              'precautions'
+            ]);
+          }
+        });
+
+        // 只有当两个值都存在时才进行检查(排除初始化情况)
+        if (newVal && this.form.storeId && this.isFormInitialized) {
+          this.debounceCheckStoreLicense();
+        }
+        // 动态调整批号的验证规则
+        // this.$nextTick(() => {
+        //   if (this.isMedicalDeviceCategory) {
+        //     // 是器械时,批号为必填
+        //     if (!this.rules.batchNumber?.some(rule => rule.required)) {
+        //       this.rules.batchNumber = [{ required: true, message: "批号不能为空", trigger: "blur" }, ...(this.rules.batchNumber || [])];
+        //     }
+        //   } else {
+        //     // 非器械时,移除批号必填规则
+        //     if (this.rules.batchNumber) {
+        //       this.rules.batchNumber = this.rules.batchNumber.filter(rule => !rule.required);
+        //     }
+        //   }
+        // });
+      },
+      immediate: true
+    },
+    'form.isDrug': {
+      handler(newVal) {
+        if (newVal === '1') {
+          this.$nextTick(() => {
+            if (this.$refs.instructionManualRef) {
+              this.$refs.instructionManualRef.setText(this.form.instructionManual || "");
+            }
+          });
+        }
+    },
+    immediate: true
+  },
+    // 监听所属店铺变化
+    'form.storeId': {
+      handler(newVal, oldVal) {
+        // 只有当两个值都存在时才进行检查(排除初始化情况)
+        if (newVal && this.form.cateId && this.isFormInitialized) {
+          this.debounceCheckStoreLicense();
+        }
+      }
+    }
+  },
+  data() {
+    return {
+      ingredientError: '', // 成分禁止提示
+      productNameError: '', // 商品名称禁止提示
+      certificateValue:false,
+      licenseValue:false,
+      businessValue:false,
+      // 溯源码弹窗相关
+      titleVisible:'溯源管理:',
+      verifyDialogVisible: false, // 溯源码弹窗显示状态
+      currentProductId: null,     // 当前选中的商品ID
+      storeLicenseErrorMessage: '', // 店铺许可证错误信息
+      isFormInitialized: false, // 表单是否已初始化完成
+      licenseCheckTimer: null,  // 防抖定时器
+      storeLicenseCheckFailed: false, // 店铺许可证接口检查是否失败
+      auditLogs:[],
+      titleValue:null,
+      displayDemo: false,
+      cateIdToNameMap: {},
+      showMedicalDeviceCode: false, // 是否显示器械编码输入框
+      showExemptDeviceButton: false, // 是否显示显示器免按钮
+      businessArr: [],
+      licenseArr: [],
+      certificateArr: [],
+      voucherArr: [],
+      gmpAuthArr: [],
+      // 证书过期错误提示
+      businessExpireError: '',
+      licenseExpireError: '',
+      certificateExpireError: '',
+      activeValue: '1',
+      orderOptions: [],
+      medicalMallConfig: {},
+      promptList: [],
+      dialogVisible: false,
+      authVisible:false,
+      companyId: null,
+      storeId: null,
+      isAudit: null,
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
+      //videoAccept:"video/*",
+      upload: {
+        // 是否显示弹出层
+        open: false,
+        // 弹出层标题
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 设置上传的请求头部
+        headers: {Authorization: "Bearer " + getToken()},
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/store/storeProduct/importData"
+      },
+      // 添加药品相关字段
+      isDrugOptions: [
+        {dictValue: "0", dictLabel: "否"},
+        {dictValue: "1", dictLabel: "是"}
+      ],
+
+      // 头图展示
+      drugImageArr: [],
+
+      //首营资质上传图
+      qualificationArr: [],
+      productTuiCateOptions: [],
+      reviewAuditOptions: [
+        {dictValue: "0", dictLabel: "首营"},
+        {dictValue: "1", dictLabel: "非首营"}
+      ],
+      showIput: false,
+      createBnt: true,
+      // 规格数据
+      formDynamic: {
+        attrsName: '',
+        attrsVal: ''
+      },
+      open1: false,
+      form1: {},
+      isBtn: false,
+      columns: [],
+      attrs: [],
+      templateList: [],
+      ruleList: [],
+      // 多规格表格data
+      manyFormValidate: [],
+      // 单规格表格data
+      oneFormValidate: [
+        {
+          image: '',
+          price: 0,
+          cost: 0,
+          agentPrice: 0,
+          otPrice: 0,
+          stock: 0,
+          barCode: '',
+          weight: 0,
+          volume: 0,
+          integral: 0
+        }
+      ],
+      photoArr: [],
+      imageArr: [],
+      activeName: "-1",
+      productTypeOptions: [],
+      isDisplayOptions: [],
+      isGoodOptions: [],
+      isNewOptions: [],
+      isBestOptions: [],
+      isHotOptions: [],
+      isShowOptions: [],
+      categoryOptions: [],
+      // 企业列表
+      companyOptions: [],
+      storeOptions: [],
+      // 防抖定时器
+      categoryOrStoreChangeTimer: null,
+      // 免于经营备案的第二类医疗器械产品相关变量
+      exemptDeviceDialogVisible: false,
+      exemptDeviceList: [],
+      allExemptDeviceList: [], // 保存所有数据用于本地搜索
+      exemptDeviceLoading: false,
+      exemptDeviceTotal: 0,
+      exemptDeviceQueryParams: {
+        productName: null
+      },
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: false,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      isFullscreen: false,
+      // 总条数
+      total: 0,
+      // 商品表格数据
+      storeProductList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        productName: null,
+        productType: null,
+        isShow: "-1",
+        barCode: null,
+        // companyIds: null,
+        storeIds: null,
+        drugRegCertNo: null,
+        commonName: null,
+        dosageForm: null,
+        unitPrice: null,
+        batchNumber: null,
+        mah: null,
+        mahAddress: null,
+        manufacturer: null,
+        manufacturerAddress: null,
+        indications: null,
+        dosage: null,
+        adverseReactions: null,
+        contraindications: null,
+        precautions: null
+      },
+      // 表单参数
+      form: {
+        ingredient: null,
+        cateId: null,
+        businessExpire: null,
+        indications: '',
+        dosage: '',
+        instructionManual: null,
+        business:null,
+        licenseExpire:null,
+        license:null,
+        certificate:null,
+        certificateExpire:null,
+        voucher:null,
+        voucherExpire:null,
+        gmpAuth:null,
+        businessLink:null,
+        isGmpAuthPermanent:null,
+        isCertificatePermanent:null,
+        isLicensePermanent:null,
+        isBusinessPermanent:null,
+        medicalDeviceCode: null, // 器械编码
+      },
+      // 表单校验
+      rules: {
+        ingredient: [
+          { required: true, message: "成分不能为空", trigger: "blur" },
+          {
+            validator: (rule, value, callback) => {
+              if (this.ingredientError) {
+                callback(new Error(this.ingredientError));
+              } else {
+                callback();
+              }
+            },
+            trigger: "blur"
+          }
+        ],
+        image: [
+          {required: true, message: "商品图片不能为空", trigger: "blur"}
+        ],
+        sliderImage: [
+          {required: true, message: "轮播图不能为空", trigger: "blur"}
+        ],
+        productName: [
+          {required: true, message: "商品名称不能为空", trigger: "blur"},
+          {
+            validator: (rule, value, callback) => {
+              if (this.productNameError) {
+                callback(new Error(this.productNameError));
+              } else {
+                callback();
+              }
+            },
+            trigger: "blur"
+          }
+        ],
+        productInfo: [
+          {required: true, message: "商品简介不能为空", trigger: "blur"}
+        ],
+        unitName: [
+          {required: true, message: "单位名不能为空", trigger: "blur"}
+        ],
+        keyword: [
+          {required: true, message: "关键字不能为空", trigger: "blur"}
+        ],
+        cateId: [
+          {required: true, message: "分类id不能为空", trigger: "blur"}
+        ],
+        medicalDeviceCode: [
+          {required: true, message: "器械编码不能为空", trigger: "blur"}
+        ],
+        price: [
+          {required: true, message: "商品价格不能为空", trigger: "blur"}
+        ],
+        prescribeCode: [
+          {required: true, message: "国药准字不能为空", trigger: "blur"}
+        ],
+        prescribeSpec: [
+          {required: true, message: "规格不能为空", trigger: "blur"}
+        ],
+        prescribeFactory: [
+          {required: true, message: "生产厂家不能为空", trigger: "blur"}
+        ],
+        prescribeName: [
+          {required: true, message: "处方药不能为空", trigger: "blur"}
+        ],
+        // companyIds: [
+        //   { required: true, message: "销售公司不能为空", trigger: "blur" }
+        // ],
+        // 药品相关字段校验(仅在是药品时必填)
+        drugImage: [
+          {required: true, message: "药品展示图不能为空", trigger: "blur"}
+        ],
+        drugRegCertNo: [
+          {required: true, message: "药品注册证书编号不能为空", trigger: "blur"}
+        ],
+        commonName: [
+          {required: true, message: "通用名称不能为空", trigger: "blur"}
+        ],
+        dosageForm: [
+          {required: true, message: "剂型不能为空", trigger: "blur"}
+        ],
+        unitPrice: [
+          {required: true, message: "单价不能为空", trigger: "blur"}
+        ],
+        // batchNumber: [
+        //   {required: true, message: "批号不能为空", trigger: "blur"}
+        // ],
+        mah: [
+          {required: true, message: "上市许可持有人不能为空", trigger: "blur"}
+        ],
+        mahAddress: [
+          {required: true, message: "上市许可持有人地址不能为空", trigger: "blur"}
+        ],
+        manufacturer: [
+          {required: true, message: "生产企业不能为空", trigger: "blur"}
+        ],
+        manufacturerAddress: [
+          {required: true, message: "生产企业地址不能为空", trigger: "blur"}
+        ],
+        // reviewAudit: [
+        //   {required: true, message: "审核资质不能为空!", trigger: "blur"}
+        // ],
+        // businessLink: [
+        //   { required: true, message: "非首营链接不能为空!", trigger: "change" }
+        // ],
+        business: [
+          { required: true, message: "生产企业营业执照不能为空!", trigger: ["blur", "change"] },
+          { whitespace: true, message: "生产企业营业执照不能为空白!", trigger: ["blur", "change"] }
+        ],
+        license: [
+          { required: true, message: "生产企业的生产许可证/备案凭证不能为空!", trigger: ["blur", "change"] },
+          { whitespace: true, message: "生产企业的生产许可证/备案凭证不能为空白!", trigger: ["blur", "change"]}
+        ],
+        certificate: [
+          { required: true, message: "商品注册证/备案凭证不能为空!", trigger: ["blur", "change"] },
+          { whitespace: true, message: "商品注册证/备案凭证不能为空白!", trigger: ["blur", "change"]}
+        ],
+        businessExpire: [
+          { required: true, message: "生产企业营业执照有效期不能为空!", trigger: "change" }
+        ],
+        licenseExpire: [
+          { required: true, message: "生产企业的生产许可证/备案凭证有效期不能为空!", trigger: "change" }
+        ],
+        certificateExpire: [
+          { required: true, message: "商品注册证/备案凭证有效期不能为空!", trigger: "change" }
+        ],
+        voucher: [
+          { required: true, message: "Ⅰ类Ⅱ类备案凭证不能为空!", trigger: "change" }
+        ],
+        voucherExpire: [
+          { required: true, message: "Ⅰ类Ⅱ类备案凭证有效期不能为空!", trigger: "change" }
+        ],
+        // gmpAuth: [
+        //   { required: true, message: "GMP认证不能为空!", trigger: "blur"  }
+        // ],
+        indications: [
+          { required: true, message: "功能主治不能为空", trigger: "blur" }
+        ],
+        dosage: [
+          { required: true, message: "用法用量不能为空", trigger: "blur" }
+        ],
+        adverseReactions: [
+          { required: true, message: "不良反应不能为空", trigger: "blur" }
+        ],
+        contraindications: [
+          { required: true, message: "禁忌不能为空", trigger: "blur" }
+        ],
+        precautions: [
+          { required: true, message: "注意事项不能为空", trigger: "blur" }
+        ],
+      },
+    };
+  },
+  methods: {
+    // 防抖检查店铺许可证权限
+    debounceCheckStoreLicense() {
+      clearTimeout(this.licenseCheckTimer);
+      this.licenseCheckTimer = setTimeout(() => {
+        this.checkStoreLicensePermission();
+      }, 300);
+    },
+    // 检查店铺许可证权限
+    checkStoreLicensePermission() {
+      // 确保分类ID和店铺ID都存在
+      if (!this.form.cateId || !this.form.storeId) {
+        return;
+      }
+
+      // 获取分类名称
+      const cateName = this.cateIdToNameMap[this.form.cateId];
+
+      // 判断是否为II类器械或III类器械
+      const isMedicalDevice = cateName !== undefined && (cateName.includes('II类器械') || cateName.includes('III类器械'));
+
+      // 如果是II类或III类器械,需要检查器械编码是否为空
+      if (isMedicalDevice && (!this.form.medicalDeviceCode || this.form.medicalDeviceCode.trim() === '')) {
+        this.$message.error('请选择II类器械或III类器械分类时,器械编码不能为空');
+        this.storeLicenseCheckFailed = true;
+        this.storeLicenseErrorMessage = '请选择II类器械或III类器械分类时,器械编码不能为空';
+        return;
+      }
+      // 添加检查中标志,防止重复调用
+      if (this.isCheckingLicense) {
+        return;
+      }
+      this.isCheckingLicense = true;
+      // 准备请求参数
+      let cateId = this.form.cateId;
+      let medicalDeviceCode = null;
+      let productType = null;
+      // 如果是II类或III类器械,传递器械编码
+      if (isMedicalDevice) {
+        medicalDeviceCode = this.form.medicalDeviceCode;
+        productType = this.form.productType; // 添加商品类型参数
+      }
+      checkStoreLicense(this.form.storeId, cateId, medicalDeviceCode, productType).then(response => {
+        if (response.code === 200) {
+          if (!response.data.flag) {
+            // 权限检查失败
+            const errorMessage = response.data.message || '当前店铺无权限经营该类商品';
+            this.$message.error(errorMessage);
+            this.storeLicenseCheckFailed = true;
+            this.storeLicenseErrorMessage = errorMessage;
+          } else {
+            // 权限检查通过,清除之前的错误提示
+            this.storeLicenseCheckFailed = false;
+            this.storeLicenseErrorMessage = ''; // 清除错误信息
+            // 如果之前有显示错误信息的地方,也会被清除
+          }
+        } else {
+          const errorMessage = '店铺许可证检查接口调用失败';
+          this.$message.error(errorMessage);
+          this.storeLicenseCheckFailed = true;
+          this.storeLicenseErrorMessage = errorMessage;
+        }
+      }).catch(error => {
+        console.error('店铺许可证检查失败:', error);
+        const errorMessage = '店铺许可证检查失败';
+        this.$message.error(errorMessage);
+        this.storeLicenseCheckFailed = true;
+        this.storeLicenseErrorMessage = errorMessage;
+      }).finally(() => {
+        this.isCheckingLicense = false;
+      });
+    },
+    // 成分输入框失焦时的处理方法
+    handleIngredientBlur() {
+      this.checkForbiddenKeywords('ingredient', this.form.ingredient);
+    },
+    // 商品名称输入框失焦时的处理方法
+    handleProductNameBlur() {
+      this.checkForbiddenKeywords('productName', this.form.productName);
+    },
+    // 通用关键字检查方法 - 根据字段类型分别处理错误提示
+    checkForbiddenKeywords(fieldName, fieldValue) {
+      // 检查内容是否包含禁用关键字
+      if (fieldValue && fieldValue.trim() !== '') {
+        // 统一使用 keywords 参数传递当前失去焦点的值
+        selectForbiddenKeywords(fieldName,fieldValue).then(response => {
+          if (response.code === 200 && !response.data) {
+            // 包含禁用词
+            const errorMsg = response.msg || '内容包含禁用关键字';
+
+            // 根据字段类型设置不同的错误提示变量
+            if (fieldName === 'ingredient') {
+              this.ingredientError = errorMsg;
+            } else if (fieldName === 'productName') {
+              this.productNameError = errorMsg;
+            }
+
+            // 设置表单验证错误状态
+            this.$nextTick(() => {
+              if (this.$refs.form) {
+                this.$refs.form.validateField(fieldName);
+              }
+            });
+          } else {
+            // 清除对应字段的错误提示
+            if (fieldName === 'ingredient') {
+              this.ingredientError = '';
+            } else if (fieldName === 'productName') {
+              this.productNameError = '';
+            }
+
+            // 清除验证状态
+            this.$nextTick(() => {
+              if (this.$refs.form) {
+                this.$refs.form.clearValidate(fieldName);
+              }
+            });
+          }
+        }).catch(error => {
+          console.error('检查禁用关键字失败:', error);
+          this.$message.error('检查禁用关键字失败');
+        });
+      }
+    },
+    // 用来清除验证信息
+    onIngredientInput() {
+      if (this.ingredientError) {
+        this.ingredientError = '';
+        this.$nextTick(() => {
+          if (this.$refs.form) {
+            this.$refs.form.clearValidate('ingredient');
+          }
+        });
+      }
+    },
+    // 添加清除商品名称验证信息的方法
+    onProductNameInput() {
+      if (this.productNameError) {
+        this.productNameError = '';
+        this.$nextTick(() => {
+          if (this.$refs.form) {
+            this.$refs.form.clearValidate('productName');
+          }
+        });
+      }
+    },
+    // 当商品分类或所属店铺改变时触发
+    onCategoryOrStoreChange() {
+      // 使用防抖机制,避免频繁调用
+      clearTimeout(this.categoryOrStoreChangeTimer);
+      this.categoryOrStoreChangeTimer = setTimeout(() => {
+        this.checkStoreLicensePermission();
+      }, 500);
+    },
+
+    // 显示免于经营备案的第二类医疗器械产品弹窗
+    showExemptDeviceDialog() {
+      this.exemptDeviceDialogVisible = true;
+      // 重置搜索条件
+      this.exemptDeviceQueryParams = {
+        productName: null
+      };
+      // 只有在没有数据时才获取数据
+      if (this.allExemptDeviceList.length === 0) {
+        this.getExemptDeviceList();
+      } else {
+        // 如果已有数据,直接显示
+        this.exemptDeviceList = this.allExemptDeviceList;
+        this.exemptDeviceTotal = this.exemptDeviceList.length;
+      }
+    },
+    // 获取免于经营备案的第二类医疗器械产品列表
+    getExemptDeviceList() {
+      this.exemptDeviceLoading = true;
+      // 调用实际的API接口来获取数据
+      getExemptSecondMedicalDeviceList(this.exemptDeviceQueryParams).then(response => {
+        this.allExemptDeviceList = response.rows || response.data || [];
+        // 根据搜索条件过滤数据
+        if (this.exemptDeviceQueryParams.productName) {
+          const searchTerm = this.exemptDeviceQueryParams.productName.toLowerCase();
+          this.exemptDeviceList = this.allExemptDeviceList.filter(item =>
+            item.productName && item.productName.toLowerCase().includes(searchTerm)
+          );
+        } else {
+          this.exemptDeviceList = this.allExemptDeviceList;
+        }
+        this.exemptDeviceTotal = this.exemptDeviceList.length;
+        this.exemptDeviceLoading = false;
+      }).catch(error => {
+        console.error('获取免于经营备案的第二类医疗器械产品列表失败:', error);
+        this.$message.error('获取免于经营备案的第二类医疗器械产品列表失败');
+        this.exemptDeviceLoading = false;
+        this.exemptDeviceList = [];
+        this.allExemptDeviceList = [];
+        this.exemptDeviceTotal = 0;
+      });
+    },
+    // 搜索免于经营备案的第二类医疗器械产品
+    handleExemptDeviceQuery() {
+      // 在本地数据中搜索
+      if (this.exemptDeviceQueryParams.productName) {
+        const searchTerm = this.exemptDeviceQueryParams.productName.toLowerCase();
+        this.exemptDeviceList = this.allExemptDeviceList.filter(item =>
+          item.productName && item.productName.toLowerCase().includes(searchTerm)
+        );
+      } else {
+        this.exemptDeviceList = this.allExemptDeviceList;
+      }
+      this.exemptDeviceTotal = this.exemptDeviceList.length;
+    },
+    // 重置免于经营备案的第二类医疗器械产品搜索
+    resetExemptDeviceQuery() {
+      this.exemptDeviceQueryParams = {
+        productName: null
+      };
+      // 重置时显示所有数据
+      this.exemptDeviceList = this.allExemptDeviceList;
+      this.exemptDeviceTotal = this.exemptDeviceList.length;
+    },
+    handleNoticeInfo() {
+      qualifications()
+        .then(response => {
+          if (response.code === 200) {
+            this.promptList = response.data;
+            if (this.promptList && this.promptList.length > 0) {
+              this.dialogVisible = true;
+            }
+          }
+        })
+        .catch(err => {
+          this.$message.error("加载通知信息失败,请稍后重试");
+        });
+    },
+    cancel1() {
+      this.open1 = false;
+    },
+    submitForm1() {
+      let param = {}
+      param.productId = this.ids;
+      param.goodsStatus = this.form1.isShow;
+      param.goodsIsShow = this.form1.isDisplay;
+      // param.companyIds = this.companyId+''
+      batchModify(param).then(res => {
+        if (res.code === 200) {
+          this.$message.success("批量修改成功");
+          this.getList();
+        }
+      }).finally(() => {
+        this.open1 = false;
+        this.form1.isShow = null;
+        this.form1.isDisplay = null;
+        this.form1.companyId = null;
+      })
+    },
+    handleFullScreen() {
+      this.isFullscreen = !this.isFullscreen;
+    },
+    handleSuccess(response, file) {
+      // 上传成功后的回调函数
+      this.myloading.close();
+      //this.form.video = response.url;
+      this.$refs.upload.clearFiles();
+    },
+    beforeUpload(file) {
+      // 上传前的钩子函数,可以在这里对文件进行处理
+      // 返回 false 则取消上传
+
+      // 例如限制文件大小
+      const isLt2M = file.size / 1024 / 1024 < 200;
+      if (!isLt2M) {
+        this.$message.error('上传视频文件大小不能超过 200MB!');
+        return false;
+      }
+      this.myloading = this.$loading({
+        lock: true,
+        text: '上传中',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      });
+
+    },
+    // 提交上传文件
+    submitFileForm() {
+      this.$refs.upload.submit();
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
+      this.getList();
+    },
+    handleImport() {
+      this.upload.title = "商品导入";
+      this.upload.open = true;
+    },
+    importTemplate() {
+      importTemplate().then(response => {
+        this.download(response.msg);
+      });
+    },
+    // 删除表格中的属性
+    delAttrTable(index) {
+      this.manyFormValidate.splice(index, 1);
+    },
+    addBtn() {
+      this.clearAttr();
+      this.createBnt = false;
+      this.showIput = true;
+    },
+    //生成SKU
+    generate() {
+      genFormatAttr(this.form.productId, { attrs: this.attrs }).then(res => {
+        if (this.form.specType === 0) {
+          this.oneFormValidate = res.value;
+          this.form.header = res.header;
+          let header = res.header;
+          header.pop();
+          this.oneFormValidate.map((item) => {
+            if (this.imageArr.length > 0) {
+              item.image = this.imageArr[0]
+            }
+          });
+        } else if (this.form.specType === 1) {
+          this.manyFormValidate = res.value;
+          let headerdel = {
+            title: '操作',
+            slot: 'action',
+            fixed: 'right',
+            width: 220
+          };
+          res.header.push(headerdel);
+          this.form.header = res.header;
+          let header = res.header;
+          header.pop();
+          // this.manyFormValidate.map((item) => {
+          //   if(this.imageArr.length>0){
+          //     item.image = this.imageArr[0]
+          //   }
+          // });
+        }
+
+      }).catch(res => {
+      })
+    },
+    // 取消添加新规格
+    closeAttrName() {
+      this.showIput = false;
+      this.createBnt = true;
+    },
+    clearAttr() {
+      this.formDynamic.attrsName = '';
+      this.formDynamic.attrsVal = '';
+    },
+    // 删除规格
+    handleRemoveRole(index) {
+      this.attrs.splice(index, 1);
+      this.manyFormValidate.splice(index, 1);
+    },
+    // 删除属性
+    handleRemove2(item, index) {
+      item.splice(index, 1);
+    },
+    // 添加规则名称
+    createAttrName() {
+      if (this.formDynamic.attrsName && this.formDynamic.attrsVal) {
+        let data = {
+          value: this.formDynamic.attrsName,
+          detail: [
+            this.formDynamic.attrsVal
+          ]
+        };
+        this.attrs.push(data);
+        var hash = {};
+        this.attrs = this.attrs.reduce(function(item, next) {
+          hash[next.value] ? '' : hash[next.value] = true && item.push(next);
+          return item
+        }, [])
+        this.clearAttr();
+        this.showIput = false;
+        this.createBnt = true;
+      } else {
+        this.$message.warning('请添加完整的规格!');
+      }
+    },
+    // 添加属性
+    createAttr(num, idx) {
+      if (num) {
+        this.attrs[idx].detail.push(num);
+        var hash = {};
+        this.attrs[idx].detail = this.attrs[idx].detail.reduce(function(item, next) {
+          hash[next] ? '' : hash[next] = true && item.push(next);
+          return item
+        }, [])
+      } else {
+        this.$message.warning('请添加属性!');
+      }
+    },
+    confirm() {
+      let that = this;
+      that.createBnt = true;
+      if (that.form.selectRule == null || that.form.selectRule.trim().length <= 0) {
+        return this.$message({
+          message: '请选择属性',
+          type: 'error'
+        });
+      }
+      that.ruleList.forEach(function(item, index) {
+        if (item.ruleName === that.form.selectRule) {
+          that.attrs = JSON.parse(item.ruleValue);
+
+        }
+      });
+
+    },
+    updateText(text) {
+      this.form.description = text
+    },
+    updateInstructionManualText(text) {
+      this.form.instructionManual = text
+    },
+    handleClick(tab, event) {
+      this.queryParams.isShow = tab.name;
+      this.getList();
+    },
+    /** 转换商品分类数据结构 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.cateId,
+        label: node.cateName,
+        children: node.children
+      };
+    },
+    getTreeselect() {
+      getAllStoreProductCategory().then(response => {
+        this.categoryOptions = [];
+        const data = this.handleTree(response.data, "cateId", "pid");
+        this.categoryOptions = data;
+        this.buildCateMap(data);
+      });
+    },
+    buildCateMap(nodes) {
+      nodes.forEach(node => {
+        this.cateIdToNameMap[node.cateId] = node.cateName;
+        if (node.children && node.children.length) {
+          this.buildCateMap(node.children); // 递归处理子节点
+        }
+      });
+    },
+    /** 查询商品列表 */
+    getList() {
+      this.loading = true;
+      if (this.queryParams.storeIds !== null && this.queryParams.storeIds.length === 0) {
+        this.queryParams.storeIds = null;
+      }
+
+      listStoreProduct(this.queryParams).then(response => {
+        this.storeProductList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.initPrescriptionDrugRules(); // 重置处方药相关的校验规则
+      this.isFormInitialized = false; // 重置初始化标志
+      this.ingredientError = '';
+      this.form = {
+        ingredient: null,
+        productId: null,
+        image: null,
+        video: null,
+        sliderImage: null,
+        productName: null,
+        productInfo: null,
+        keyword: null,
+        barCode: null,
+        cateId: null,
+        price: null,
+        vipPrice: null,
+        otPrice: null,
+        postage: null,
+        unitName: null,
+        sort: null,
+        sales: null,
+        stock: null,
+        isShow: "0",
+        isHot: "0",
+        isBenefit: "0",
+        isBest: "0",
+        isNew: "0",
+        description: null,
+        instructionManual: null,
+        createTime: null,
+        updateTime: null,
+        isPostage: null,
+        isDel: null,
+        giveIntegral: null,
+        cost: null,
+        isGood: "0",
+        browse: null,
+        codePath: null,
+        tempId: "",
+        specType: 0,
+        isIntegral: null,
+        integral: null,
+        productType: "1",
+        prescribeCode: null,
+        prescribeSpec: null,
+        prescribeFactory: null,
+        prescribeName: null,
+        isDisplay: "1",
+        qualificationExpire: null,
+        // companyIds:[],
+        isDrug: "1", // 是否药品
+        drugImage: null, // 头图展示
+        drugRegCertNo: null, // 药品注册证书编号
+        commonName: null, // 通用名称
+        dosageForm: null, // 剂型
+        unitPrice: null, // 单价
+        batchNumber: null, // 批号
+        mah: null, // 上市许可持有人
+        mahAddress: null, // 上市许可持有人地址
+        manufacturer: null, // 生产企业
+        manufacturerAddress: null, // 生产企业地址
+        indications: null, // 功能主治
+        dosage: null, // 用法用量
+        adverseReactions: null, // 不良反应
+        contraindications: null, // 禁忌
+        precautions: null // 注意事项
+      };
+      // 重置药品展示图
+      this.drugImageArr = [];
+      this.resetForm("form");
+      this.oneFormValidate = [
+        {
+          image: '',
+          price: 0,
+          agentPrice: 0,
+          cost: 0,
+          otPrice: 0,
+          stock: 0,
+          barCode: '',
+          weight: 0,
+          volume: 0,
+          integral: 0,
+          brokerage: 0,
+          brokerageTwo: 0
+        }
+      ]
+      this.attrs = [];
+      this.photoArr = [];
+      this.imageArr = [];
+      this.qualificationArr = [];
+      this.businessArr = [];
+      this.licenseArr = [];
+      this.certificateArr = [];
+      this.voucherArr = [];
+      this.gmpAuthArr = [];
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      // this.queryParams.companyIds = this.companyId +''
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      // 查询参数
+      this.queryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        productName: null,
+        productType: null,
+        isShow: "1",
+        barCode: null,
+        // companyIds: null,
+        storeIds: null,
+        drugRegCertNo: null,
+        commonName: null,
+        dosageForm: null,
+        unitPrice: null,
+        batchNumber: null,
+        mah: null,
+        mahAddress: null,
+        manufacturer: null,
+        manufacturerAddress: null,
+        indications: null,
+        dosage: null,
+        adverseReactions: null,
+        contraindications: null,
+        precautions: null
+      }
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.productId)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.clearExpireErrors(); // 清空过期错误提示
+      this.isFormInitialized = true; // 新增时直接设置为已初始化
+      this.open = true;
+      this.title = "添加商品";
+      setTimeout(() => {
+        this.$refs.myeditor.setText("");
+        this.$refs.instructionManualRef.setText("");
+      }, 500);
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      if (this.ids.length > 1) {
+        this.title = "批量修改商品";
+        this.open1 = true;
+        return;
+      }
+      var that = this;
+      this.clearExpireErrors(); // 清空过期错误提示
+      const productId = row.productId || this.ids
+      getStoreProduct(productId).then(response => {
+        this.open = true;
+        this.title = "修改商品";
+        this.form = response.data;
+        this.form.isShow = response.data.isShow.toString();
+        this.form.isHot = response.data.isHot.toString();
+        this.form.isGood = response.data.isGood.toString();
+        this.form.isBest = response.data.isBest.toString();
+        this.form.isNew = response.data.isNew.toString();
+        this.form.productType = response.data.productType.toString();
+        this.form.isDisplay = response.data.isDisplay.toString();
+
+        if (this.form.business) {
+          this.businessArr = this.form.business.split(',');
+        }
+        if (this.form.license) {
+          this.licenseArr = this.form.license.split(',');
+        }
+        if (this.form.certificate) {
+          this.certificateArr = this.form.certificate.split(',');
+        }
+        if (this.form.voucher) {
+          this.voucherArr = this.form.voucher.split(',');
+        }
+        if (this.form.gmpAuth) {
+          this.gmpAuthArr = this.form.gmpAuth.split(',');
+        }
+        if (this.form.image != null) {
+          this.imageArr = this.form.image.split(",");
+        }
+        if (this.form.sliderImage != null) {
+          this.photoArr = this.form.sliderImage.split(",");
+        }
+        if (this.form.drugImage != null) {
+          this.drugImageArr = this.form.drugImage.split(",");
+        }
+        if (this.form.qualificationCertificate != null) {
+          this.qualificationArr = this.form.qualificationCertificate.split(",");
+        }
+        if (this.form.tuiCateId != null) {
+          this.form.tuiCateId = response.data.tuiCateId.toString();
+        }
+        if (this.form.reviewAudit != null) {
+          this.form.reviewAudit = response.data.reviewAudit.toString();
+        }
+
+        // this.form.isDrug = response.data.isDrug ? response.data.isDrug.toString() : "1";
+        this.form.isDrug = response.data.isDrug === 0 ? "0" :
+          (response.data.isDrug ? response.data.isDrug.toString() : "1");
+
+        if (this.form.isBusinessPermanent == 1) {
+          this.businessValue = true
+        } else {
+          this.businessValue = false
+        }
+
+        if (this.form.isLicensePermanent == 1) {
+          this.licenseValue = true
+        } else {
+          this.licenseValue = false
+        }
+
+        if (this.form.isCertificatePermanent == 1) {
+          this.certificateValue = true
+        } else {
+          this.certificateValue = false
+        }
+
+        const expireFieldMap = [
+          { expireKey: 'businessExpire', startKey: 'businessStart', endKey: 'businessEnd' },
+          { expireKey: 'licenseExpire', startKey: 'licenseStart', endKey: 'licenseEnd' },
+          { expireKey: 'certificateExpire', startKey: 'certificateStart', endKey: 'certificateEnd' },
+          { expireKey: 'voucherExpire', startKey: 'voucherStart', endKey: 'voucherEnd' },
+          {
+            expireKey: 'qualificationExpire',
+            startKey: 'qualificationCertificateStart',
+            endKey: 'qualificationCertificateEnd'
+          }
+        ];
+
+        expireFieldMap.forEach(item => {
+          const startVal = response.data[item.startKey];
+          const endVal = response.data[item.endKey];
+          if (startVal && endVal) {
+            this.$set(this.form, item.expireKey, [startVal, endVal]);
+          }
+        });
+
+        //组装attrs数据
+        if (response.attrs != null) {
+          this.attrs = [];
+          response.attrs.forEach(function(item, index) {
+            var data = { value: item.attrName, detail: item.attrValues.split(',') }
+            that.attrs.push(data);
+          });
+        }
+        const dateFields = [
+          'qualificationExpire'
+        ];
+        dateFields.forEach(field => {
+          const startField = field.replace('Expire', 'CertificateStart');  // qualificationCertificateStart
+          const endField = field.replace('Expire', 'CertificateEnd');      // qualificationCertificateEnd
+          if (this.form[startField] && this.form[endField]) {
+            this.$set(this.form, field, [this.form[startField], this.form[endField]]);
+          }
+        });
+        // // 组装companyIds
+        // if (response.data.companyIds != null && response.data.companyIds != undefined && response.data.companyIds.length > 0) {
+        //   this.form.companyIds = response.data.companyIds.split(',').map(Number);
+        // }
+        setTimeout(() => {
+          that.generate();
+        }, 200);
+        if (this.form.specType === 0) {
+          that.manyFormValidate = [];
+        } else {
+          that.createBnt = true;
+          that.oneFormValidate = [
+            {
+              image: '',
+              price: 0,
+              agentPrice: 0,
+              cost: 0,
+              otPrice: 0,
+              stock: 0,
+              barCode: '',
+              weight: 0,
+              volume: 0,
+              integral: 0,
+              brokerage: 0,
+              brokerageTwo: 0
+            }
+          ]
+        }
+
+        setTimeout(() => {
+          this.$refs.myeditor.setText(this.form.description==null?"":this.form.description);
+          this.$refs.instructionManualRef.setText(this.form.instructionManual == null?""
+            :this.form.instructionManual);
+        }, 200);
+
+        // 加载数据后立即校验过期状态
+        this.$nextTick(() => {
+          this.isFormInitialized = true;
+          // 首次加载后检查一次
+          if (this.form.storeId && this.form.cateId) {
+            this.checkStoreLicensePermission();
+          }
+        });
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      // 1. 先执行 Element UI 的表单验证
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          // 4. 检查店铺许可证权限
+          if (this.storeLicenseCheckFailed) {
+            this.$message.error('当前店铺无权限经营该类商品,请重新选择分类或店铺');
+            return;
+          }
+          // 5. 统一校验所有证书是否过期
+          const expireError = this.checkAllCertificatesExpire();
+          if (expireError) {
+            this.$message.error(expireError);
+            return;
+          }
+          // 6. 执行提交逻辑
+          this.executeSubmit();
+        }
+      });
+    },
+
+    //具体的提交逻辑
+    executeSubmit() {
+      let checkBoolean = false;
+      let itemErrMsg = "";
+
+      if (this.form.specType === 0) {
+        this.form.items = [];
+        this.form.values = this.oneFormValidate;
+      } else {
+        this.form.items = this.attrs;
+        this.form.values = this.manyFormValidate;
+      }
+
+      // 验证规格数据
+      const validateItem = (item) => {
+        if (item.barCode == null || item.barCode === '') {
+          return "规格/型号,商品条码不能为空!";
+        }
+        if (item.price == null || item.price === '' || item.price === 0) {
+          return "规格/型号,商品售价不能为空且不能为0!";
+        }
+        if (item.cost == null || item.cost === '') {
+          return "规格/型号,商品成本价不能为空!";
+        }
+        if (item.otPrice == null || item.otPrice === '') {
+          return "规格/型号,商品原价不能为空!";
+        }
+        return null;
+      };
+
+      // 遍历检查每个规格项
+      for (let i = 0; i < this.form.values.length; i++) {
+        const item = this.form.values[i];
+        const errorMsg = validateItem(item);
+        if (errorMsg) {
+          itemErrMsg = errorMsg;
+          checkBoolean = true;
+          break;
+        }
+      }
+
+      if (checkBoolean) {
+        this.$message.warning(itemErrMsg);
+        return;
+      }
+
+      if (this.form.specType === 1 && this.manyFormValidate.length === 0) {
+        this.$message.warning('请点击生成规格!');
+        return;
+      }
+
+      // 处理其他业务逻辑...
+      // 设置永久有效标识
+      this.form.isBusinessPermanent = this.businessValue ? 1 : 0;
+      this.form.isLicensePermanent = this.licenseValue ? 1 : 0;
+      this.form.isCertificatePermanent = this.certificateValue ? 1 : 0;
+
+      // 调用API提交数据
+      addOrEdit(this.form).then(response => {
+        if (response.code === 200) {
+          this.msgSuccess("操作成功!");
+          this.open = false;
+          this.getList();
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const productIds = row.productId || this.ids;
+      this.$confirm('是否确认删除商品编号为"' + productIds + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return delStoreProduct(productIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(function() {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有商品数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return exportStoreProduct(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+      }).catch(function() {
+      });
+    },
+    showOperLog(row) {
+      getAuthInfo(row.productId).then(response => {
+        this.auditLogs = response.auditLog;
+        this.titleValue = "商品:" + "《" + row.productName + "》" + "审核记录";
+        this.authVisible = true;
+      })
+    },
+    handleClose(done) {
+      this.$confirm('确认关闭?')
+        .then(_ => {
+          done();
+        })
+        .catch(_ => {
+        });
+    },
+    /**
+     * 复制商品
+     * **/
+    productCopy(row) {
+      this.$confirm('确认是否复制当前《' + row.productName + '》商品!', '复制商品', {
+        confirmButtonText: '确 认',
+        cancelButtonText: '取 消',
+        type: 'warning'
+      }).then(() => {
+        copyProduct(row).then(response => {
+          if (response.code === 200) {
+            this.$message.success("操作成功!")
+            this.getList();
+          }
+        })
+      }).catch(() => {
+
+      });
+    },
+
+    // 清空所有证书过期错误提示
+    clearExpireErrors() {
+      this.businessExpireError = '';
+      this.licenseExpireError = '';
+      this.certificateExpireError = '';
+    },
+    // 统一校验证书有效期(返回错误信息或null),新增如果选择长期按钮打开,验证就会跳过
+    checkCertificateExpire(dates, flag, certName) {
+      if(!flag) {
+        // 检查是否为空
+        if (!dates || !Array.isArray(dates) || dates.length !== 2) {
+          return `${certName}有效期不能为空`;
+        }
+        if (dates && dates.length === 2) {
+          const endDate = new Date(dates[1]);
+          const today = new Date();
+          today.setHours(0, 0, 0, 0);
+          if (endDate < today) {
+            return `${certName}已过期,请更新证书`;
+          }
+        }
+      }
+      return null;
+    },
+    // 检查所有证书是否过期(提交时使用)
+    checkAllCertificatesExpire() {
+      // 按顺序检查,返回第一个过期的证书错误信息
+      let error = null;
+      error = this.checkCertificateExpire(this.form.businessExpire, this.businessValue,'生产企业营业执照');
+      if (error) return error + '后再提交!';
+      error = this.checkCertificateExpire(this.form.licenseExpire, this.licenseValue,'生产企业的生产许可证/备案凭证');
+      if (error) return error + '后再提交!';
+      error = this.checkCertificateExpire(this.form.certificateExpire, this.certificateValue,'商品注册证/备案凭证');
+      if (error) return error + '后再提交!';
+      return null;
+    },
+
+    // 添加一个新的方法用于初始化处方药相关规则
+    initPrescriptionDrugRules() {
+      // 初始化处方药相关字段的校验规则
+      this.$set(this.rules, 'indications', [
+        { required: true, message: "功能主治不能为空", trigger: "blur" }
+      ]);
+
+      this.$set(this.rules, 'ingredient', [
+        { required: true, message: "成分不能为空", trigger: "blur" },
+        {
+          validator: (rule, value, callback) => {
+            if (this.ingredientError) {
+              callback(new Error(this.ingredientError));
+            } else {
+              callback();
+            }
+          },
+          trigger: "blur"
+        }
+      ]);
+
+      this.$set(this.rules, 'dosage', [
+        { required: true, message: "用法用量不能为空", trigger: "blur" }
+      ]);
+
+      this.$set(this.rules, 'adverseReactions', [
+        { required: true, message: "不良反应不能为空", trigger: "blur" }
+      ]);
+
+      this.$set(this.rules, 'contraindications', [
+        { required: true, message: "禁忌不能为空", trigger: "blur" }
+      ]);
+
+      this.$set(this.rules, 'precautions', [
+        { required: true, message: "注意事项不能为空", trigger: "blur" }
+      ]);
+    },
+    // 组件销毁前清理定时器
+    beforeDestroy() {
+      if (this.categoryOrStoreChangeTimer) {
+        clearTimeout(this.categoryOrStoreChangeTimer);
+      }
+    },
+    //打开溯源码页面
+    openVerify(row) {
+      if (row) {
+        this.currentProductId = row.productId;
+      } else if (this.ids.length > 0) {
+        this.currentProductId = this.ids[0];
+        if (this.ids.length > 1) {
+          this.$message.warning('溯源码管理仅支持单个商品操作,已默认选择第一个商品');
+        }
+      } else {
+        this.$message.error('请先选择需要管理溯源码的商品');
+        return;
+      }
+      this.titleVisible = this.titleVisible + '《' + row.productName + '》';
+      this.verifyDialogVisible = true;
+    },
+    /**
+     * 关闭溯源码弹窗
+     */
+    handleVerifyDialogClose() {
+      if (this.$refs.verifyCodeRef) {
+        this.$refs.verifyCodeRef.fullReset();
+      }
+      setTimeout(() => {
+        this.currentProductId = null;
+      }, 100);
+      this.getList();
+      this.verifyDialogVisible = false;
+      this.titleVisible = "溯源管理";
+    },
+  }
+};
+</script>
+
+<style scoped>
+.exempt-device-dialog {
+  z-index: 9999 !important;
+}
+
+.exempt-device-dialog .el-dialog {
+  z-index: 9999 !important;
+}
+
+.exempt-device-dialog .el-dialog__wrapper {
+  z-index: 9999 !important;
+}
+</style>

+ 153 - 0
src/views/hisStore/platformProduct/tuiList.vue

@@ -0,0 +1,153 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="商品名称" prop="productName">
+        <el-input
+
+          v-model="queryParams.productName"
+          placeholder="请输入商品名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="所属分类" prop="tuiCateId">
+        <el-select   v-model="queryParams.tuiCateId" placeholder="请选择分类" clearable size="small" >
+         <el-option
+                v-for="item in productTuiCateOptions"
+                :key="item.dictValue"
+                :label="item.dictLabel"
+                :value="item.dictValue"
+              />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table  height="500" border v-loading="loading" :data="storeProductList" >
+      <el-table-column label="ID" align="center" prop="productId" />
+      <el-table-column label="商品编码" show-overflow-tooltip align="center" prop="barCode" />
+      <el-table-column label="商品图片" align="center" width="120">
+        <template slot-scope="scope">
+          <el-popover
+            placement="right"
+            title=""
+            trigger="hover"
+          >
+            <img slot="reference" :src="scope.row.image" width="100">
+            <img :src="scope.row.image" style="max-width: 150px;">
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品名称" show-overflow-tooltip align="center" prop="productName" />
+      <el-table-column label="SKU" show-overflow-tooltip align="center" prop="sku" />
+      <el-table-column label="分类" align="center" prop="tuiCateId" >
+          <template slot-scope="scope">
+              <el-tag prop="tuiCateId" v-for="(item, index) in productTuiCateOptions"    v-if="scope.row.tuiCateId==item.dictValue">{{item.dictLabel}}</el-tag>
+          </template>
+      </el-table-column>
+      <el-table-column label="售价" align="center" prop="price" >
+          <template slot-scope="scope" >
+              <span v-if="scope.row.price!=null">{{scope.row.price.toFixed(2)}}</span>
+          </template>
+      </el-table-column>
+      <el-table-column label="原价" align="center" prop="otPrice" >
+          <template slot-scope="scope" >
+              <span v-if="scope.row.otPrice!=null">{{scope.row.otPrice.toFixed(2)}}</span>
+          </template>
+      </el-table-column>
+      <el-table-column label="一级分佣" align="center" prop="brokerage" >
+          <template slot-scope="scope" >
+              <span v-if="scope.row.brokerage!=null">{{scope.row.brokerage.toFixed(2)}}</span>
+          </template>
+      </el-table-column>
+      <el-table-column label="二级分佣" align="center" prop="brokerageTwo" >
+          <template slot-scope="scope" >
+              <span v-if="scope.row.brokerageTwo!=null">{{scope.row.brokerageTwo.toFixed(2)}}</span>
+          </template>
+      </el-table-column>
+      <el-table-column label="三级分佣" align="center" prop="brokerageThree" >
+          <template slot-scope="scope" >
+              <span v-if="scope.row.brokerageTwo!=null">{{scope.row.brokerageThree.toFixed(2)}}</span>
+          </template>
+      </el-table-column>
+      <el-table-column label="库存" show-overflow-tooltip align="center" prop="stock" />
+    </el-table>
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+  </div>
+</template>
+
+<script>
+import {getStoreTuiProductAttrValueList} from "@/api/hisStore/storeProduct";
+
+
+export default {
+  name: "HisTuiList",
+  data() {
+    return {
+      productTuiCateOptions:[],
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 商品表格数据
+      storeProductList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        productName: null,
+        tuiCateId: null,
+      },
+    };
+  },
+  created() {
+    this.getDicts("store_product_tui_cate").then((response) => {
+      this.productTuiCateOptions = response.data;
+    });
+    this.getList();
+  },
+  methods: {
+    /** 查询商品列表 */
+    getList() {
+      this.loading = true;
+      getStoreTuiProductAttrValueList(this.queryParams).then(response => {
+        this.storeProductList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+  }
+};
+</script>