Bladeren bron

销售端优化提交

yjwang 2 dagen geleden
bovenliggende
commit
381bd56f01
2 gewijzigde bestanden met toevoegingen van 217 en 82 verwijderingen
  1. 33 4
      src/components/Editor/wang.vue
  2. 184 78
      src/views/store/storeProduct/index.vue

+ 33 - 4
src/components/Editor/wang.vue

@@ -1,5 +1,5 @@
 <template>  
-    <div>
+    <div :class="{ 'is-wang-disabled': disabled }">
       <div  ref='editor1' class="myedit"></div>
     </div> 
 </template>  
@@ -7,14 +7,26 @@
 <script>  
   import E from 'wangeditor'
   import { getToken } from '@/utils/auth'
-  export default {  
-    name: 'editoritem',  
+    export default {  
+    name: 'editoritem',
+    props: {
+      // 只读禁用,修改弹窗等场景用于锁定说明书/详情
+      disabled: {
+        type: Boolean,
+        default: false
+      }
+    },
     data() {  
       return {
         uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadWang",
         editor: null
       }  
     },
+    watch: {
+      disabled(val) {
+        this.syncDisabled(val);
+      }
+    },
     created() {
        
       
@@ -129,9 +141,21 @@
                 }
             }
             this.editor.create()
+            this.syncDisabled(this.disabled);
         }
         this.editor.txt.html("");
       },
+      // 同步只读状态,不影响通过 setText 回填内容
+      syncDisabled(disabled) {
+        if (!this.editor) {
+          return;
+        }
+        if (disabled) {
+          this.editor.disable();
+        } else {
+          this.editor.enable();
+        }
+      },
       setText(text){
         if(this.editor==null){
           this.initEditor()
@@ -142,7 +166,7 @@
         else{
           this.editor.txt.html(text);
         }
-        
+        this.syncDisabled(this.disabled);
       },
      }
    
@@ -163,5 +187,10 @@
 .w-e-text-container{
   z-index: 1 !important;
 }
+/* 禁用时工具栏与编辑区发灰,避免仍可点选 */
+.is-wang-disabled {
+  pointer-events: none;
+  opacity: 0.65;
+}
  
 </style>

+ 184 - 78
src/views/store/storeProduct/index.vue

@@ -471,19 +471,19 @@
           </div>
         </div>
       </template>
-      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px" :class="{ 'is-edit-readonly': isEditLocked }">
         <el-row>
           <el-col :span="12">
-            <el-form-item label="商品分类" prop="cateId">
+            <el-form-item label="商品分类" prop="cateId" :class="{ 'is-disabled-cate': deviceCategoryLocked }">
               <treeselect v-model="form.cateId" :options="categoryOptions" :normalizer="normalizer"
-                          placeholder="请选择上级分类"/>
+                          placeholder="请选择上级分类" :disabled="deviceCategoryLocked"/>
             </el-form-item>
           </el-col>
 
           <el-col :span="12">
             <el-form-item label="商品类型" prop="productType">
               <el-select style="width: 240px" v-model="form.productType" placeholder="请选择商品类型" clearable
-                       size="small">
+                       size="small" :disabled="isEditLocked">
               <el-option v-for="item in productTypeOptions" :key="item.dictValue"
                          :label="item.dictLabel" :value="item.dictValue"/>
               </el-select>
@@ -500,7 +500,7 @@
 
           <el-col :span="12">
             <el-form-item label="通用名称" prop="commonName" v-if="!isMedicalDeviceCategory">
-              <el-input v-model="form.commonName" placeholder="请输入通用名称"/>
+              <el-input v-model="form.commonName" placeholder="请输入通用名称" :disabled="isEditLocked"/>
             </el-form-item>
           </el-col>
 
@@ -510,14 +510,14 @@
           <!-- 存储条件 -->
           <el-col :span="12">
             <el-form-item label="存储条件" prop="storageConditions" v-if="!isMedicalDeviceCategory">
-              <el-input v-model="form.storageConditions" placeholder="请输入存储条件" style="width: calc(100% - 120px);"/>
+              <el-input v-model="form.storageConditions" placeholder="请输入存储条件" style="width: calc(100% - 120px);" :disabled="isEditLocked"/>
             </el-form-item>
             </el-col>
           <!-- 器械编码和显示器免按钮 -->
           <el-col :span="12">
             <el-form-item label="器械编码" prop="medicalDeviceCode" v-if="showMedicalDeviceCode">
-              <el-input v-model="form.medicalDeviceCode" @blur="handleMedicalDeviceCodeBlur" placeholder="请输入器械编码" style="width: calc(100% - 120px);"/>
-              <el-button type="primary" @click="showExemptDeviceDialog" style="margin-left: 10px;" v-if="showExemptDeviceButton">显示器免</el-button>
+              <el-input v-model="form.medicalDeviceCode" @blur="handleMedicalDeviceCodeBlur" placeholder="请输入器械编码" style="width: calc(100% - 120px);" :disabled="isEditLocked"/>
+              <el-button type="primary" @click="showExemptDeviceDialog" style="margin-left: 10px;" v-if="showExemptDeviceButton" :disabled="isEditLocked">显示器免</el-button>
             </el-form-item>
           </el-col>
         </el-row>
@@ -525,12 +525,12 @@
         <el-row>
           <el-col :span="12">
             <el-form-item label="关键字" prop="keyword">
-              <el-input v-model="form.keyword" placeholder="请输入关键字"/>
+              <el-input v-model="form.keyword" placeholder="请输入关键字" :disabled="isEditLocked"/>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="单位名" prop="unitName">
-              <el-input v-model="form.unitName" placeholder="请输入单位名"/>
+              <el-input v-model="form.unitName" placeholder="请输入单位名" :disabled="isEditLocked"/>
             </el-form-item>
           </el-col>
         </el-row>
@@ -539,7 +539,7 @@
           <el-col :span="12">
             <!-- 当分类包含"器械"时隐藏是否药品选项 -->
             <el-form-item label="是否药品" prop="isDrug" v-if="!isMedicalDeviceCategory">
-              <el-radio-group v-model="form.isDrug">
+              <el-radio-group v-model="form.isDrug" :disabled="isEditLocked">
                 <el-radio
                   v-for="item in isDrugOptions"
                   :key="item.dictValue"
@@ -551,14 +551,14 @@
           </el-col>
         </el-row>
         <div v-if="form.isDrug === '1' ">
-          <el-form-item label="头图展示" prop="drugImage">
+          <el-form-item label="头图展示" prop="drugImage" :class="{ 'is-upload-disabled': isEditLocked }">
             <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="请输入药品注册证书编号"/>
+                  <el-input v-model="form.drugRegCertNo" placeholder="请输入药品注册证书编号" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -566,7 +566,7 @@
             <el-row>
               <el-col :span="12">
                 <el-form-item label="剂型" prop="dosageForm" v-if="!isMedicalDeviceCategory">
-                  <el-input v-model="form.dosageForm" placeholder="请输入剂型"/>
+                  <el-input v-model="form.dosageForm" placeholder="请输入剂型" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
               <el-col :span="12">
@@ -585,12 +585,12 @@
 <!--              </el-col>-->
               <el-col :span="12">
                 <el-form-item :label="isMedicalDeviceCategory ? '规格/型号' : '包装规格'" prop="prescribeSpec">
-                  <el-input v-model="form.prescribeSpec" :placeholder="isMedicalDeviceCategory ? '请输入规格/型号':'请输入包装规格'"/>
+                  <el-input v-model="form.prescribeSpec" :placeholder="isMedicalDeviceCategory ? '请输入规格/型号':'请输入包装规格'" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
               <el-col :span="12">
                 <el-form-item label="规格" v-if="!isMedicalDeviceCategory" prop="specification">
-                  <el-input v-model="form.specification" placeholder="请输入规格"/>
+                  <el-input v-model="form.specification" placeholder="请输入规格" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -598,12 +598,12 @@
             <el-row>
               <el-col :span="12">
                 <el-form-item :label="isMedicalDeviceCategory ? '注册人/备案人' : '上市许可持有人'" prop="mah">
-                  <el-input v-model="form.mah" :placeholder= "isMedicalDeviceCategory ? '请输入注册人/备案人' : '请输入上市许可持有人'"/>
+                  <el-input v-model="form.mah" :placeholder= "isMedicalDeviceCategory ? '请输入注册人/备案人' : '请输入上市许可持有人'" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
               <el-col :span="12">
                 <el-form-item :label="isMedicalDeviceCategory ? '注册人/备案人地址' : '持有人地址'" prop="mahAddress">
-                  <el-input v-model="form.mahAddress" :placeholder= "isMedicalDeviceCategory ? '请输入注册人/备案人地址' : '请输入持有人地址'"/>
+                  <el-input v-model="form.mahAddress" :placeholder= "isMedicalDeviceCategory ? '请输入注册人/备案人地址' : '请输入持有人地址'" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -611,12 +611,12 @@
             <el-row>
               <el-col :span="12">
                 <el-form-item label="生产企业" prop="manufacturer">
-                  <el-input v-model="form.manufacturer" placeholder="请输入生产企业"/>
+                  <el-input v-model="form.manufacturer" placeholder="请输入生产企业" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
               <el-col :span="12">
                 <el-form-item label="企业地址" prop="manufacturerAddress">
-                  <el-input v-model="form.manufacturerAddress" placeholder="请输入生产企业地址"/>
+                  <el-input v-model="form.manufacturerAddress" placeholder="请输入生产企业地址" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -632,65 +632,65 @@
 <!--                </el-form-item>-->
 
                 <el-form-item label="生产许可证或者备案凭证编号" prop="prodLicenseNo" v-if="isMedicalDeviceCategory">
-                  <el-input v-model="form.prodLicenseNo" type="textarea" placeholder="请输入生产许可证或者备案凭证编号"/>
+                  <el-input v-model="form.prodLicenseNo" type="textarea" placeholder="请输入生产许可证或者备案凭证编号" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="产品技术要求编号" prop="prodTechReqNo" v-if="isMedicalDeviceCategory">
-                  <el-input v-model="form.prodTechReqNo" type="textarea" placeholder="请输入产品技术要求编号"/>
+                  <el-input v-model="form.prodTechReqNo" type="textarea" placeholder="请输入产品技术要求编号" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="结构及组成" prop="productStructure" v-if="isMedicalDeviceCategory">
-                  <el-input v-model="form.productStructure" type="textarea" placeholder="请输入结构及组成"/>
+                  <el-input v-model="form.productStructure" type="textarea" placeholder="请输入结构及组成" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="功能主治/适用范围" prop="indications">
-                  <el-input v-model="form.indications" type="textarea" placeholder="请输入功能主治/适用范围"/>
+                  <el-input v-model="form.indications" type="textarea" placeholder="请输入功能主治/适用范围" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="禁忌症" prop="contraindications">
-                  <el-input v-model="form.contraindications" type="textarea" placeholder="请输入禁忌症"/>
+                  <el-input v-model="form.contraindications" type="textarea" placeholder="请输入禁忌症" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="成分" prop="ingredient" v-if="!isMedicalDeviceCategory">
-                  <el-input v-model="form.ingredient" type="textarea" placeholder="请输入成分"/>
+                  <el-input v-model="form.ingredient" type="textarea" placeholder="请输入成分" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="用法用量" prop="dosage" v-if="!isMedicalDeviceCategory">
-                  <el-input v-model="form.dosage" type="textarea" placeholder="请输入用法用量"/>
+                  <el-input v-model="form.dosage" type="textarea" placeholder="请输入用法用量" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="不良反应" prop="adverseReactions" v-if="!isMedicalDeviceCategory" >
-                  <el-input v-model="form.adverseReactions" type="textarea" placeholder="请输入不良反应"/>
+                  <el-input v-model="form.adverseReactions" type="textarea" placeholder="请输入不良反应" :disabled="isEditLocked"/>
                 </el-form-item>
 
                 <el-form-item label="注意事项" prop="precautions" v-if="!isMedicalDeviceCategory">
-                  <el-input v-model="form.precautions" type="textarea" placeholder="请输入注意事项"/>
+                  <el-input v-model="form.precautions" type="textarea" placeholder="请输入注意事项" :disabled="isEditLocked"/>
                 </el-form-item>
               </el-collapse-item>
             </el-collapse>
           </div>
         </div>
         <el-form-item label="说明书" prop="instructionManual">
-          <editor ref="instructionManualRef" @on-text-change="updateInstructionManualText"/>
+          <editor ref="instructionManualRef" @on-text-change="updateInstructionManualText" :disabled="isEditLocked"/>
         </el-form-item>
         <el-row>
           <el-col :span="24">
             <el-form-item label="商品简介" prop="productInfo">
-              <el-input v-model="form.productInfo" type="textarea" :rows="2" placeholder="请输入商品简介"/>
+              <el-input v-model="form.productInfo" type="textarea" :rows="2" placeholder="请输入商品简介" :disabled="isEditLocked"/>
             </el-form-item>
           </el-col>
         </el-row>
-        <el-form-item label="商品图片" prop="image">
+        <el-form-item label="商品图片" prop="image" :class="{ 'is-upload-disabled': isEditLocked }">
           <Material v-model="imageArr" type="image" :num="1" :width="150" :height="150"/>
         </el-form-item>
 
-        <el-form-item label="轮播图" prop="sliderImage">
+        <el-form-item label="轮播图" prop="sliderImage" :class="{ 'is-upload-disabled': isEditLocked }">
           <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-group v-model="form.specType" :disabled="isEditLocked">
                 <el-radio :label="0" class="radio">单包装规格</el-radio>
                 <el-radio :label="1">多包装规格</el-radio>
               </el-radio-group>
@@ -701,13 +701,13 @@
             <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-select v-model="form.selectRule" style="width: 23%;" :disabled="isEditLocked">
                     <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>
+                  <el-button style="margin-left:10px;" type="primary" class="mr20" @click="confirm" :disabled="isEditLocked">确认</el-button>
                 </div>
               </el-form-item>
             </el-col>
@@ -716,15 +716,15 @@
               <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>
+                    <i v-if="!isEditLocked" 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 type="dot" color="primary" v-for="(j, indexn) in item.detail" :key="indexn"
+                            :name="j" class="mr20" :closable="!isEditLocked" @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)">添加
+                              style="width: 200px" :disabled="isEditLocked">
+                      <el-button slot="append" type="primary" @click="createAttr(item.detail.attrsVal,index)" :disabled="isEditLocked">添加
                       </el-button>
                     </el-input>
                   </div>
@@ -734,24 +734,24 @@
 
             <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-button type="primary" size="small" icon="md-add" @click="addBtn" class="mr15" :disabled="isEditLocked">添加新包装规格</el-button>
+                <el-button type="success" size="small" @click="generate" :disabled="isEditLocked">立即生成</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-input placeholder="请输入包装规格/型号" v-model="formDynamic.attrsName" :disabled="isEditLocked"/>
                 </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-input v-model="formDynamic.attrsVal" placeholder="请输入包装规格值" :disabled="isEditLocked"/>
                 </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-button type="primary" @click="createAttrName" :disabled="isEditLocked">确定</el-button>
+                <el-button type="danger" @click="closeAttrName" :disabled="isEditLocked">取消</el-button>
               </el-col>
             </el-col>
             <!-- 多规格设置-->
@@ -764,7 +764,7 @@
                     <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">
+                        <div v-if="scope.column.property == 'image'" align="center" :class="{ 'is-upload-disabled': isEditLocked }">
                           <single-img v-model="scope.row[scope.column.property]" type="image" :num="1" :width="60"
                                       :height="60"/>
                         </div>
@@ -772,10 +772,12 @@
                           {{ scope.row[scope.column.property] }}
                         </div>
                         <div v-else-if="scope.column.property == 'action'" align="center">
-                          <a @click="delAttrTable(scope.$index)" align="center">删除</a>
+                          <a v-if="!isEditLocked" @click="delAttrTable(scope.$index)" align="center">删除</a>
+                          <span v-else>-</span>
                         </div>
                         <div v-else align="center">
-                          <el-input v-model="scope.row[scope.column.property]" align="center"/>
+                          <el-input v-model="scope.row[scope.column.property]" align="center"
+                                    :disabled="isSpecCellLocked(scope.column.property)"/>
                         </div>
                       </template>
                     </el-table-column>
@@ -792,7 +794,9 @@
               <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"/>
+                    <div :class="{ 'is-upload-disabled': isEditLocked }">
+                      <single-img v-model="scope.row.image" type="image" :num="1" :width="60" :height="60"/>
+                    </div>
                   </template>
                 </el-table-column>
                 <el-table-column prop="price" label="售价" align="center">
@@ -802,17 +806,17 @@
                 </el-table-column>
                 <el-table-column prop="agentPrice" label="代理价" align="center">
                   <template slot-scope="scope">
-                    <el-input type="text" v-model="scope.row.agentPrice"/>
+                    <el-input type="text" v-model="scope.row.agentPrice" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.cost" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.otPrice" :disabled="isEditLocked"/>
                   </template>
                 </el-table-column>
                 <el-table-column prop="stock" label="库存" align="center">
@@ -822,42 +826,42 @@
                 </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"/>
+                    <el-input type="text" v-model="scope.row.barCode" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.groupBarCode" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.weight" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.volume" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.integral" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.brokerage" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.brokerageTwo" :disabled="isEditLocked"/>
                   </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"/>
+                    <el-input type="text" v-model="scope.row.brokerageThree" :disabled="isEditLocked"/>
                   </template>
                 </el-table-column>
               </el-table>
@@ -866,7 +870,7 @@
           <el-col :span="24">
             <el-form-item label="运费模板:" prop="tempId">
               <div class="acea-row">
-                <el-select v-model="form.tempId" class="mr20">
+                <el-select v-model="form.tempId" class="mr20" :disabled="isEditLocked">
                   <el-option v-for="(item,index) in templateList" :value="item.id" :key="index" :label="item.name">
                   </el-option>
                 </el-select>
@@ -875,7 +879,7 @@
           </el-col>
         </el-row>
         <el-form-item label="商品详情" prop="description">
-          <editor ref="myeditor" @on-text-change="updateText"/>
+          <editor ref="myeditor" @on-text-change="updateText" :disabled="isEditLocked"/>
         </el-form-item>
         <el-row>
           <el-col :span="8">
@@ -949,7 +953,7 @@
 
         </el-row>
         <el-form-item label="推广分类" prop="tuiCateId">
-          <el-select style="width: 240px" v-model="form.tuiCateId" placeholder="请选择推广分类" clearable size="small">
+          <el-select style="width: 240px" v-model="form.tuiCateId" placeholder="请选择推广分类" clearable size="small" :disabled="isEditLocked">
             <el-option
               v-for="item in productTuiCateOptions"
               :key="item.dictValue"
@@ -973,7 +977,7 @@
         <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">
+        <el-form-item v-if="form.isShow === '1'" label="生产企业营业执照" prop="business" :class="{ 'is-upload-disabled': isEditLocked }">
           <Material v-model="businessArr" type="image" :num="1" :width="150" :height="150"/>
         </el-form-item>
 
@@ -982,7 +986,8 @@
             @change="switchChange()"
             v-model="businessValue"
             active-color="#13ce66"
-            inactive-color="#ff4949">
+            inactive-color="#ff4949"
+            :disabled="isEditLocked">
           </el-switch>
         </el-form-item>
 
@@ -993,11 +998,12 @@
             value-format="yyyy-MM-dd"
             range-separator="至"
             start-placeholder="开始日期"
-            end-placeholder="结束日期">
+            end-placeholder="结束日期"
+            :disabled="isEditLocked">
           </el-date-picker>
         </el-form-item>
 
-        <el-form-item v-if="form.isShow === '1'" label="生产企业的生产许可证/备案凭证" prop="license">
+        <el-form-item v-if="form.isShow === '1'" label="生产企业的生产许可证/备案凭证" prop="license" :class="{ 'is-upload-disabled': isEditLocked }">
           <Material v-model="licenseArr" type="image" :num="1" :width="150" :height="150"/>
         </el-form-item>
 
@@ -1006,7 +1012,8 @@
             @change="switchChange()"
             v-model="licenseValue"
             active-color="#13ce66"
-            inactive-color="#ff4949">
+            inactive-color="#ff4949"
+            :disabled="isEditLocked">
           </el-switch>
         </el-form-item>
 
@@ -1017,11 +1024,12 @@
             value-format="yyyy-MM-dd"
             range-separator="至"
             start-placeholder="开始日期"
-            end-placeholder="结束日期">
+            end-placeholder="结束日期"
+            :disabled="isEditLocked">
           </el-date-picker>
         </el-form-item>
 
-        <el-form-item v-if="form.isShow === '1'" label="商品注册证/备案凭证" prop="certificate">
+        <el-form-item v-if="form.isShow === '1'" label="商品注册证/备案凭证" prop="certificate" :class="{ 'is-upload-disabled': isEditLocked }">
           <Material v-model="certificateArr" type="image" :num="1" :width="150" :height="150"/>
         </el-form-item>
 
@@ -1030,7 +1038,8 @@
             @change="switchChange()"
             v-model="certificateValue"
             active-color="#13ce66"
-            inactive-color="#ff4949">
+            inactive-color="#ff4949"
+            :disabled="isEditLocked">
           </el-switch>
         </el-form-item>
 
@@ -1041,7 +1050,8 @@
             value-format="yyyy-MM-dd"
             range-separator="至"
             start-placeholder="开始日期"
-            end-placeholder="结束日期">
+            end-placeholder="结束日期"
+            :disabled="isEditLocked">
           </el-date-picker>
         </el-form-item>
 
@@ -1353,7 +1363,15 @@ export default {
     //商品分类
     'form.cateId': {
       handler(newVal) {
-        const cateName = this.cateIdToNameMap[newVal];
+        if (this.deviceCategoryLocked && this.originalDeviceCateId != null
+          && newVal != null && String(newVal) !== String(this.originalDeviceCateId)) {
+          this.$nextTick(() => {
+            this.form.cateId = this.originalDeviceCateId;
+          });
+          this.$message.warning('器械类商品不允许修改分类');
+          return;
+        }
+        const cateName = this.getCateNameById(newVal);
         // 分类变化时动态修改验证规则,当分类名称不为空,且包含器械时候
         if (cateName !== undefined && cateName.includes('器械')) {
           // this.rules.contraindications = [];
@@ -1421,10 +1439,17 @@ export default {
       // 确保只在II类器械时显示,不包括III类器械
       return cateName !== undefined && cateName.includes('II类器械') && !cateName.includes('III类器械');
     },
-    // 判断当前分类是否为医疗器械分类
+    // 判断当前分类是否为医疗器械分类(当前节点或上级名称带「器械」都算)
     isMedicalDeviceCategory() {
-      const cateName = this.cateIdToNameMap[this.form.cateId];
-      return cateName !== undefined && cateName.includes('器械');
+      if (!this.form || this.form.cateId == null || this.form.cateId === '') {
+        return false;
+      }
+      return this.isDeviceCategoryById(this.form.cateId);
+    },
+    // 修改弹窗只读开关:白名单字段不加 disabled;分类仍走器械锁定
+    isEditLocked() {
+      const productId = this.form && this.form.productId;
+      return productId !== null && productId !== undefined && Number(productId) > 0;
     }
   },
   data() {
@@ -1445,6 +1470,9 @@ export default {
       businessValue:false,
       displayDemo: false,
       cateIdToNameMap: {},
+      // 修改时锁定:进来时就是器械类,不允许改分类和类型
+      deviceCategoryLocked: false,
+      originalDeviceCateId: null,
       businessArr: [],
       licenseArr: [],
       certificateArr: [],
@@ -2073,6 +2101,60 @@ export default {
       this.queryParams.isShow = tab.name;
       this.getList();
     },
+    getCateNameById(cateId) {
+      if (cateId === null || cateId === undefined || cateId === '') {
+        return '';
+      }
+      const map = this.cateIdToNameMap || {};
+      return map[cateId] || map[String(cateId)] || map[Number(cateId)] || '';
+    },
+    isCateNameDevice(cateName) {
+      return !!(cateName && String(cateName).indexOf('器械') !== -1);
+    },
+    getCatePathNames(cateId) {
+      const walk = (nodes, path) => {
+        if (!nodes || !nodes.length) {
+          return null;
+        }
+        for (let i = 0; i < nodes.length; i++) {
+          const node = nodes[i];
+          const next = path.concat([node.cateName || '']);
+          if (String(node.cateId) === String(cateId)) {
+            return next;
+          }
+          const found = walk(node.children, next);
+          if (found) {
+            return found;
+          }
+        }
+        return null;
+      };
+      return walk(this.categoryOptions, []) || [];
+    },
+    isDeviceCategoryById(cateId) {
+      if (this.isCateNameDevice(this.getCateNameById(cateId))) {
+        return true;
+      }
+      const pathNames = this.getCatePathNames(cateId);
+      for (let i = 0; i < pathNames.length; i++) {
+        if (this.isCateNameDevice(pathNames[i])) {
+          return true;
+        }
+      }
+      return false;
+    },
+    syncDeviceCategoryLock(cateId, cateName) {
+      this.deviceCategoryLocked = this.isDeviceCategoryById(cateId) || this.isCateNameDevice(cateName);
+      this.originalDeviceCateId = this.deviceCategoryLocked ? cateId : null;
+    },
+    // 多规格表格:修改时只允许改售价、库存
+    isSpecCellLocked(property) {
+      if (!this.isEditLocked) {
+        return false;
+      }
+      const editableSpecFields = ['price', 'stock'];
+      return editableSpecFields.indexOf(property) === -1;
+    },
     /** 转换商品分类数据结构 */
     normalizer(node) {
       if (node.children && !node.children.length) {
@@ -2119,6 +2201,8 @@ export default {
     },
     // 表单重置
     reset() {
+      this.deviceCategoryLocked = false;
+      this.originalDeviceCateId = null;
       this.form = {
         ingredient: null, // 重置成分字段
         productId: null,
@@ -2307,6 +2391,7 @@ export default {
         }
         // 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");
+        this.syncDeviceCategoryLock(this.form.cateId, row && row.cateName);
         if (this.form.drugImage != null) {
           this.drugImageArr = this.form.drugImage.split(",");
         }
@@ -2379,6 +2464,7 @@ export default {
         // }
         setTimeout(() => {
           that.generate();
+          that.syncDeviceCategoryLock(that.form.cateId, row && row.cateName);
         }, 200);
         if (this.form.specType === 0) {
           that.manyFormValidate = [];
@@ -2753,3 +2839,23 @@ export default {
   }
 };
 </script>
+
+<style scoped>
+/* 器械分类锁定时,和 Element 禁用输入框一样发灰 */
+.is-disabled-cate ::v-deep .vue-treeselect--disabled .vue-treeselect__control {
+  background-color: #F5F7FA;
+  border-color: #E4E7ED;
+  cursor: not-allowed;
+}
+.is-disabled-cate ::v-deep .vue-treeselect--disabled .vue-treeselect__single-value,
+.is-disabled-cate ::v-deep .vue-treeselect--disabled .vue-treeselect__placeholder {
+  color: #C0C4CC;
+}
+.is-disabled-cate ::v-deep .vue-treeselect--disabled .vue-treeselect__control-arrow {
+  color: #C0C4CC;
+}
+.is-upload-disabled {
+  pointer-events: none;
+  opacity: 0.65;
+}
+</style>