Ver código fonte

需求修改

cz 1 ano atrás
pai
commit
749dd28222

+ 10 - 3
src/assets/styles/index.scss

@@ -205,12 +205,12 @@ aside {
   content: '';
   display: inline-block;
   width: 4px;
-  height: 14px;
+  height: 16px;
   background: #409eff;
-  margin-right: 10px;
+  margin-right: 5px;
   position: absolute;
   left: 0;
-  top: 3px;
+  top: 8px;
 }
 
 .cp {
@@ -221,6 +221,13 @@ aside {
 .public_height_dialog {
   height: calc(100vh - 270px);
   overflow: auto;
+  padding-right: 10px;
+}
+
+//通用元素需点击类
+.el-click {
+  color: #409eff;
+  cursor: pointer;
 }
 
 

+ 47 - 7
src/components/byForm/index.vue

@@ -51,7 +51,7 @@
           <el-date-picker v-model="formData[i.prop]" :readonly="i.readonly ? i.readonly : false" v-else-if="i.type == 'date'" :type="i.itemType"
                           :placeholder="i.placeholder || $t('common.pleaseSelectTime')" @change="(e) => commonsEmit(e, i)"
                           :disabled="i.disabled ? i.disabled : false" :format="i.format ? i.format : dateFormatInit(i.itemType)"
-                          :value-format="i.format ? i.format : dateFormatInit(i.itemType)" />
+                          :value-format="i.format ? i.format : dateFormatInit(i.itemType)" :style="i.style?i.style:{width:'100%'}" />
           <el-switch :disabled="i.disabled ? i.disabled : false" v-else-if="i.type == 'switch'" :readonly="i.readonly ? i.readonly : false"
                      v-model="formData[i.prop]" />
           <el-checkbox-group v-else-if="i.type == 'checkbox'" v-model="formData[i.prop]" :readonly="i.readonly ? i.readonly : false"
@@ -61,9 +61,10 @@
             </el-checkbox>
           </el-checkbox-group>
           <el-radio-group v-else-if="i.type == 'radio'" v-model="formData[i.prop]" :readonly="i.readonly ? i.readonly : false"
-                          :disabled="i.disabled ? i.disabled : false">
-            <el-radio :border="i.border ? i.border : false" v-for="j in i.data" :key="j.id || j.value" :label="j.id || j.value" name="type">
-              {{ j.name || j.label }}
+                          :disabled="i.disabled ? i.disabled : false" @change="(e) => commonsEmit(e, i)">
+            <el-radio :border="i.border ? i.border : false" v-for="j in i.data" :key="j.id || j.value ||j.dictKey"
+                      :label="j.id ||j.dictKey || j.value" name="type">
+              {{j.dictValue || j.name || j.label }}
             </el-radio>
           </el-radio-group>
           <el-input-number v-else-if="i.type == 'number'" v-model="formData[i.prop]" :readonly="i.readonly ? i.readonly : false"
@@ -101,8 +102,8 @@
           </slot>
           <div class="upload" v-else-if="i.type == 'upload'">
             <el-upload :file-list="formData[i.prop]" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadData"
-                       :list-type="i.listType ? i.listType : 'text'" :accept="i.accept?i.accept :'.gif, .jpeg, .jpg, .png'"
-                       :on-success="handleSuccess" :before-upload="(file)=>handleBeforeUpload(file,i.prop)" :on-preview="onPreviewFile">
+                       :list-type="i.listType ? i.listType : 'text'" :accept="i.accept?i.accept :'.gif, .jpeg, .jpg, .png'" :limit="i.limit?i.limit:3"
+                       :before-upload="(file)=>handleBeforeUpload(file,i.prop)" :on-success="handleSuccess" :on-preview="onPreviewFile">
 
               <el-icon v-if="i.listType=='picture-card'">
                 <Plus />
@@ -110,6 +111,15 @@
               <el-button type="primary" plain v-else>点击上传</el-button>
             </el-upload>
           </div>
+          <div class="upload" v-else-if="i.type == 'uploadImg'">
+            <el-upload action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" accept=".gif, .jpeg, .jpg, .png" :show-file-list="false"
+                       :data="uploadData" :before-upload="(file)=>handleBeforeUploadOne(file,i.prop,i.imgProp)" :on-success="handleSuccess">
+              <img v-if="formData[i.imgProp]" :src="formData[i.imgProp]" class="pic" />
+              <el-icon v-else class="avatar-uploader-icon">
+                <Plus />
+              </el-icon>
+            </el-upload>
+          </div>
           <div v-else-if="i.type == 'table'" class="by-form-table" style="width: 100%">
             <el-table :data="formData[i.prop]" style="width: 100%">
               <el-table-column :prop="j.prop" :label="j.label" :width="i.width" v-for="(j, jindex) in i.column">
@@ -204,6 +214,20 @@ const onPreviewFile = (file) => {
   if (file && file.fileUrl) window.open(file.fileUrl, "_blank");
 };
 
+const handleBeforeUploadOne = async (file, prop, imgProp) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  formData.value[prop] = [
+    {
+      id: res.id,
+      fileName: res.fileName,
+      fileUrl: res.fileUrl,
+    },
+  ];
+  formData.value[imgProp] = res.fileUrl;
+  return true;
+};
+
 const isInit = ref(false);
 const { proxy } = getCurrentInstance();
 const emit = defineEmits(["update:modelValue"]);
@@ -401,7 +425,7 @@ loadInit();
   box-sizing: border-box;
 }
 .by-form .el-form--inline > .el-form-item {
-  padding: 0 20px 0 10px;
+  padding: 0 10px 0 0px;
 }
 .by-form .el-form--inline .formTitle {
   padding: 0px !important;
@@ -421,4 +445,20 @@ loadInit();
 /* .by-form-json {
   padding: 0px !important;
 } */
+
+.pic {
+  object-fit: contain;
+  width: 80px;
+  height: 80px;
+  cursor: pointer;
+  vertical-align: middle;
+}
+.el-icon.avatar-uploader-icon {
+  font-size: 20px;
+  color: #8c939d;
+  width: 80px;
+  height: 80px;
+  text-align: center;
+  border: 1px dashed var(--el-border-color);
+}
 </style>

+ 1 - 1
src/components/headerBar/header-bar.vue

@@ -158,7 +158,7 @@
               <Opportunity />
             </el-icon>
           </el-badge>
-          <div style="margin:15px 0 15px 0" v-else>
+          <div style="margin:15px 0 15px 0;cursor: pointer;" v-else @click="handleOpenDrawer">
             <el-icon :size="20" color="#fff">
               <Opportunity />
             </el-icon>

+ 248 - 512
src/components/process/EHSD/Contract.vue

@@ -6,9 +6,6 @@
           <el-button type="primary" v-if="
               [30].includes(route.query.processType) || !route.query.processType
             " @click="clickCopy(1)">复制合同</el-button>
-          <el-button type="primary" v-if="
-              [30].includes(route.query.processType) || !route.query.processType
-            " @click="clickCopy(2)">复制样品单</el-button>
         </div>
       </template>
       <template #seller>
@@ -21,17 +18,17 @@
           <el-form-item label="地址" class="wid100">
             <el-row style="width:100%">
               <el-col :span="8">
-                <el-form-item label="" prop="sellCountryName" label-width="0px" class="margin-b-0">
+                <el-form-item label="" prop="sellCountryName" label-width="0px" class="margin-b-0 wid100">
                   <el-input v-model="formData.data.sellCountryName" placeholder="请输入国家" />
                 </el-form-item>
               </el-col>
               <el-col :span="8">
-                <el-form-item label="" prop="sellProvinceName" label-width="0px" class="margin-b-0">
+                <el-form-item label="" prop="sellProvinceName" label-width="0px" class="margin-b-0 wid100">
                   <el-input v-model="formData.data.sellProvinceName" placeholder="请输入省/州" />
                 </el-form-item>
               </el-col>
               <el-col :span="8">
-                <el-form-item label="" prop="sellCityName" label-width="0px" class="margin-b-0">
+                <el-form-item label="" prop="sellCityName" label-width="0px" class="margin-b-0 wid100">
                   <el-input v-model="formData.data.sellCityName" placeholder="请输入城市" />
                 </el-form-item>
               </el-col>
@@ -110,9 +107,9 @@
           <el-form-item label="联系人" class="wid100" required>
             <el-row style="width: 100%">
               <el-col :span="8">
-                <el-form-item label="" prop="buyContactName" label-width="0px" class="margin-b-0">
-                  <el-autocomplete v-model="formData.data.buyContactName" :fetch-suggestions="querySearchPerson" clearable class="inline-input w-50"
-                                   placeholder="请输入联系人" @select="handlePerson">
+                <el-form-item label="" prop="buyContactName" label-width="0px" class="margin-b-0 wid100">
+                  <el-autocomplete v-model="formData.data.buyContactName" :fetch-suggestions="querySearchPerson" style="width:100%" clearable
+                                   class="inline-input w-50" placeholder="请输入联系人" @select="handlePerson">
                   </el-autocomplete>
                 </el-form-item>
               </el-col>
@@ -125,131 +122,10 @@
           </el-form-item>
         </div>
       </template>
-      <template #payment>
-        <div style="width: 100%">
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="6">
-              <el-form-item label="币种" prop="currency">
-                <el-select v-model="formData.data.currency" placeholder="请选择币种" style="width: 100%">
-                  <el-option v-for="item in accountCurrency" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="6">
-              <el-form-item label="汇率" prop="rate">
-                <el-input-number onmousewheel="return false;" v-model="formData.data.rate" placeholder="请输入汇率" style="width: 100%" :precision="4"
-                                 :controls="false" :min="0" :max="100" />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="6">
-              <el-form-item label="付款方式" prop="paymentMethod">
-                <el-select v-model="formData.data.paymentMethod" placeholder="请选择付款方式" style="width: 100%">
-                  <el-option v-for="item in fundsPaymentMethod" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="6">
-              <el-form-item label="预付比例 (%)" prop="advanceRatio">
-                <el-input-number onmousewheel="return false;" v-model="formData.data.advanceRatio" placeholder="请输入预付比例" style="width: 100%"
-                                 :precision="2" :controls="false" :min="0" :max="100" />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="18">
-              <el-form-item label="付款条件" prop="remark">
-                <el-input v-model="formData.data.remark" :rows="2" type="textarea" placeholder="请输入付款条件" />
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="9">
-              <el-form-item label="收款账号" prop="shroffAccountId">
-                <el-select v-model="formData.data.shroffAccountId" placeholder="请选择收款账号" style="width: 100%" @change="changeShroffAccount">
-                  <el-option v-for="item in accountList" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="9">
-              <el-form-item label="  ">
-                <el-button type="primary" @click="changeActiveName" text>
-                  <span v-if="activeName == '1'">收起</span>
-                  <span v-else>展开</span>
-                </el-button>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <div style="width: 100%; margin-top: 34px">
-            <el-collapse v-model="activeName" class="hideCollapse" accordion>
-              <el-collapse-item title="" name="1">
-                <el-row style="width: 100%">
-                  <el-col :span="9">
-                    <el-form-item label="Beneficiary Name" prop="beneficiaryName">
-                      <el-input v-model="formData.data.beneficiaryName" placeholder="请输入Beneficiary Name" />
-                    </el-form-item>
-                    <div style="height: 20px"></div>
-                    <el-form-item label="Beneficiary Bank" prop="beneficiaryBank">
-                      <el-input v-model="formData.data.beneficiaryBank" placeholder="请输入Beneficiary Bank" />
-                    </el-form-item>
-                    <div style="height: 20px"></div>
-                    <el-form-item label="Beneficiary Bank Address" prop="beneficiaryBankAddress">
-                      <el-input v-model="formData.data.beneficiaryBankAddress" placeholder="请输入Beneficiary Bank Address" />
-                    </el-form-item>
-                  </el-col>
-                  <el-col :span="9">
-                    <el-form-item label="Beneficiary Account Number" prop="beneficiaryAccountNumber">
-                      <el-input v-model="formData.data.beneficiaryAccountNumber" placeholder="请输入Beneficiary Account Number" />
-                    </el-form-item>
-                    <div style="height: 20px"></div>
-                    <el-form-item label="Swift Code" prop="swiftCode">
-                      <el-input v-model="formData.data.swiftCode" placeholder="请输入Swift Code" />
-                    </el-form-item>
-                    <div style="height: 20px"></div>
-                    <el-form-item label="Beneficiary Address" prop="beneficiaryAddress">
-                      <el-input v-model="formData.data.beneficiaryAddress" placeholder="请输入Beneficiary Address" />
-                    </el-form-item>
-                  </el-col>
-                </el-row>
-              </el-collapse-item>
-            </el-collapse>
-          </div>
-        </div>
-      </template>
-      <template #delivery>
-        <div style="width: 100%">
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="6">
-              <el-form-item label="报价有效期 (天)" prop="effective">
-                <el-input-number onmousewheel="return false;" v-model="formData.data.effective" placeholder="请输入有效期" style="width: 100%"
-                                 :precision="0" :controls="false" :min="0" />
-              </el-form-item>
-            </el-col>
-            <el-col :span="6">
-              <el-form-item label="交货期限" prop="deliveryTime">
-                <el-date-picker v-model="formData.data.deliveryTime" type="date" placeholder="请选择交货期限" value-format="YYYY-MM-DD" />
-              </el-form-item>
-            </el-col>
-            <el-col :span="6">
-              <el-form-item label="运输方式" prop="transportMethod">
-                <el-select v-model="formData.data.transportMethod" placeholder="请选择运输方式" style="width: 100%">
-                  <el-option v-for="item in shippingMethod" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="6">
-              <el-form-item label="运输说明" prop="transportRemark">
-                <el-input v-model="formData.data.transportRemark" placeholder="请输入运输说明" />
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </div>
-      </template>
+
       <template #commodity>
         <div style="width: 100%">
           <el-button type="primary" @click="openProductCompany = true" plain>标准产品库</el-button>
-          <el-button type="primary" @click="clickCustomerProduct()" plain>客户产品库</el-button>
           <el-table :data="formData.data.contractProductList" style="width: 100%; margin-top: 16px">
             <el-table-column label="商品图片" width="80">
               <template #default="{ row }">
@@ -259,42 +135,39 @@
                 <div v-else></div>
               </template>
             </el-table-column>
-            <el-table-column prop="productCnName" label="商品中文名" min-width="130" />
-            <el-table-column label="商品英文名" min-width="180">
+            <el-table-column prop="productCnName" label="商品名称" min-width="130" />
+            <el-table-column prop="productCnName" label="商品编码" width="130" />
+
+            <el-table-column label="尺寸 cm*cm*cm" width="140">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
-                  <el-form-item :prop="'contractProductList.' + $index + '.productName'" :rules="rules.productName" :inline-message="true"
-                                class="shrinkPadding">
-                    <el-input v-model="row.productName" placeholder="请输入商品名称" />
-                  </el-form-item>
+                  30*80*960
                 </div>
               </template>
             </el-table-column>
-            <el-table-column label="尺寸 cm*cm*cm" width="140">
+            <el-table-column label="设计图稿" width="180">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
-                  <el-form-item :prop="'contractProductList.' + $index + '.productModel'" :rules="rules.productModel" :inline-message="true"
-                                class="shrinkPadding">
-                    <el-input v-model="row.productModel" placeholder="请输入" />
-                  </el-form-item>
+                  <el-upload action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" accept=".gif, .jpeg, .jpg, .png" :show-file-list="false"
+                             :data="uploadData" :before-upload="(file)=>handleBeforeUpload(file,$index)" :on-success="handleSuccess"
+                             :on-preview="onPreviewFile">
+                    <img v-if="row.imageUrl" :src="row.imageUrl" class="pic" />
+                    <el-icon v-else class="avatar-uploader-icon">
+                      <Plus />
+                    </el-icon>
+                  </el-upload>
                 </div>
               </template>
             </el-table-column>
-            <el-table-column label="包装方式" width="180">
+            <el-table-column label="生产源文件" width="100">
               <template #default="{ row, $index }">
-                <div style="width: 100%">
-                  <el-form-item :prop="'contractProductList.' + $index + '.packMethod'" :rules="rules.packMethod" :inline-message="true"
-                                class="shrinkPadding">
-                    <el-input v-model="row.packMethod" placeholder="请输入" />
-                  </el-form-item>
-                </div>
+                <span class="el-click">点击上传</span>
               </template>
             </el-table-column>
             <el-table-column label="数量" width="130">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
-                  <el-form-item :prop="'contractProductList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true"
-                                class="shrinkPadding">
+                  <el-form-item :prop="'contractProductList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true">
                     <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入" style="width: 100%" :precision="0"
                                      :controls="false" :min="0" @change="calculationAmount('quantity')" />
                   </el-form-item>
@@ -304,11 +177,11 @@
             <el-table-column label="单价" width="140">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
-                  <el-form-item :prop="'contractProductList.' + $index + '.price'" :rules="rules.price" :inline-message="true" class="shrinkPadding">
+                  <el-form-item :prop="'contractProductList.' + $index + '.price'" :rules="rules.price" :inline-message="true">
                     <div style="display:flex;">
                       <el-input-number onmousewheel="return false;" v-model="row.price" placeholder="请输入" style="width: 100%" :precision="2"
                                        :controls="false" :min="0" @change="calculationAmount()" />
-                      <el-popover placement="top-start" :width="400" trigger="hover" @show="showEcharts(row,$index)">
+                      <!-- <el-popover placement="top-start" :width="400" trigger="hover" @show="showEcharts(row,$index)">
                         <template #default>
                           <div>
                             <div>
@@ -351,27 +224,13 @@
                             </el-icon>
                           </div>
                         </template>
-                      </el-popover>
+                      </el-popover> -->
                     </div>
                   </el-form-item>
-
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column label="贸易方式" width="140">
-              <template #default="{ row, $index }">
-                <div style="width: 100%">
-                  <el-form-item :prop="'contractProductList.' + $index + '.tradeMethods'" :rules="rules.tradeMethods" :inline-message="true"
-                                class="shrinkPadding">
-                    <el-select v-model="row.tradeMethods" placeholder="请选择" style="width: 100%">
-                      <el-option v-for="item in tradeMethods" :key="item.value" :label="item.label" :value="item.value" />
-                    </el-select>
-                  </el-form-item>
                 </div>
               </template>
             </el-table-column>
-
-            <el-table-column prop="amount" :label="'金额 ( ' + formData.data.currency + ' )'" width="130" />
+            <el-table-column prop="amount" label="小计" width="100" />
             <el-table-column label="操作" width="60" align="center" fixed="right">
               <template #default="{ row, $index }">
                 <el-button type="primary" link @click="handleRemove($index, row)">删除</el-button>
@@ -380,31 +239,16 @@
           </el-table>
         </div>
       </template>
-      <template #file>
-        <div style="width: 100%">
-          <el-upload v-model:fileList="formData.data.fileList" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadData" multiple
-                     :before-upload="uploadFile" :on-success="handleSuccess" :on-preview="onPreviewFile">
-            <el-button type="primary" plain>选择</el-button>
-          </el-upload>
-        </div>
-      </template>
-      <template #indication>
-        <div style="width: 100%">
-          <el-upload v-model:fileList="formData.data.packageFileList" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
-                     :data="indicationUploadData" multiple :before-upload="indicationUploadFile" :on-success="handleSuccess"
-                     :on-preview="onPreviewFile">
-            <el-button type="primary" plain>选择</el-button>
-          </el-upload>
-        </div>
-      </template>
+
       <template #otherCharge>
         <div style="width: 100%">
-          <el-button type="primary" @click="clickAdd()">添加行</el-button>
+          <el-button type="primary" @click="clickAdd()" plain>添加行</el-button>
           <el-table :data="formData.data.contractProjectList" style="width: 100%; margin-top: 16px">
             <el-table-column label="收费项目" width="220">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
-                  <el-form-item :prop="'contractProjectList.' + $index + '.payName'" :rules="rules.payName" :inline-message="true">
+                  <el-form-item :prop="'contractProjectList.' + $index + '.payName'" :rules="rules.payName" :inline-message="true"
+                                class="margin-b-0 wid100">
                     <el-autocomplete v-model="row.payName" :fetch-suggestions="querySearch" clearable class="inline-input w-50"
                                      placeholder="请输入收费项目" />
                   </el-form-item>
@@ -414,7 +258,7 @@
             <el-table-column label="备注">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
-                  <el-form-item :prop="'contractProjectList.' + $index + '.remark'">
+                  <el-form-item :prop="'contractProjectList.' + $index + '.remark'" class="margin-b-0 wid100">
                     <el-input v-model="row.remark" placeholder="请输入备注" />
                   </el-form-item>
                 </div>
@@ -424,7 +268,7 @@
               <template #default="{ row, $index }">
                 <div style="width: 100%">
                   <el-form-item :prop="'contractProjectList.' + $index + '.amount'" :rules="rules.amount" :inline-message="true"
-                                class="shrinkPadding">
+                                class="margin-b-0 wid100">
                     <el-input-number onmousewheel="return false;" v-model="row.amount" placeholder="请输入金额" style="width: 100%" :precision="2"
                                      :controls="false" :min="0" @change="totalAmount()" />
                   </el-form-item>
@@ -439,143 +283,16 @@
           </el-table>
         </div>
       </template>
-      <template #offerMoney>
-        <div style="width: 100%; display: flex">
-          <div style="width: calc(100% - 190px)"></div>
-          <div style="width: 130px; padding: 0 12px">
-            <el-form-item label="合同总金额" prop="amount" class="shrinkPadding">
-              <el-input v-model="formData.data.amount" placeholder="合同总金额" disabled />
-            </el-form-item>
-          </div>
-        </div>
-      </template>
-      <template #shipment>
-        <!-- <div style="width: 100%">
-          <el-table
-            :data="formData.data.contractShipmentList"
-            style="width: 100%; margin-top: 16px"
-          >
-            <el-table-column prop="productCode" label="商品编码" width="120" />
-            <el-table-column prop="productName" label="商品名称" />
-            <el-table-column label="出货日期" width="220">
-              <template #default="{ row, $index }">
-                <div style="width: 100%">
-                  <el-form-item
-                    :prop="'contractShipmentList.' + $index + '.shipmentTime'"
-                    :rules="rules.shipmentTime"
-                    :inline-message="true"
-                  >
-                    <el-date-picker
-                      v-model="row.shipmentTime"
-                      type="date"
-                      placeholder="请选择出货日期"
-                      value-format="YYYY-MM-DD"
-                    />
-                  </el-form-item>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column label="数量" width="160">
-              <template #default="{ row, $index }">
-                <div style="width: 100%">
-                  <el-form-item
-                    :prop="'contractShipmentList.' + $index + '.quantity'"
-                    :inline-message="true"
-                  >
-                    <el-input-number
-                      onmousewheel="return false;"
-                      v-model="row.quantity"
-                      placeholder="请输入数量"
-                      style="width: 100%"
-                      :precision="0"
-                      :controls="false"
-                      :min="0"
-                      @change="calculationAmount()"
-                    />
-                  </el-form-item>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column
-              align="center"
-              label="操作"
-              width="120"
-              fixed="right"
-            >
-              <template #default="{ row, $index }">
-                <el-button type="primary" link @click="clickSplit(row)"
-                  >拆分</el-button
-                >
-                <el-button type="primary" link @click="clickDelete($index)"
-                  >删除</el-button
-                >
-              </template>
-            </el-table-column>
-          </el-table>
-        </div> -->
-
-        <div style="width: 100%">
-          <el-row>
-            <el-col :span="10" style="border: 1px solid #ebeef5; padding: 10px">
-              <el-form-item label="出货日期" required>
-                <el-date-picker v-model="formData.data.shipmentTime" type="date" placeholder="请选择出货日期" value-format="YYYY-MM-DD" />
-              </el-form-item>
-              <el-table :data="formData.data.contractWaitShipmentList" @selection-change="handleSelectionChange" ref="tableDom"
-                        style="margin: 15px 0">
-                <el-table-column type="selection" width="55" />
-                <el-table-column prop="productCode" label="商品编号" width="90" />
-                <el-table-column prop="productName" label="商品名称" min-width="250" />
-                <el-table-column label="出货数量" width="160">
-                  <template #default="{ row, $index }">
-                    <div style="width: 100%">
-                      <el-form-item :prop="
-                          'contractWaitShipmentList.' + $index + '.quantity'
-                        " :inline-message="true">
-                        <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入数量" style="width: 100%" :precision="0"
-                                         :controls="false" :min="0" />
-                      </el-form-item>
-                    </div>
-                  </template>
-                </el-table-column>
-                <el-table-column prop="waitQuantity" label="剩余数量" />
-              </el-table>
-              <div style="text-align: center">
-                <el-button type="primary" @click="handleAddShipment">添加</el-button>
-              </div>
-            </el-col>
-            <el-col :span="14">
-              <div style="padding: 10px; margin-top: 77px">
-                <el-table :data="formData.data.contractShipmentList" :span-method="objectSpanMethod">
-                  <el-table-column prop="shipmentTime" label="出货日期" width="100">
-                    <template #default="{ row, $index }">
-                      <div>{{row.shipmentTime.slice(0,10)}}</div>
-                    </template>
-                  </el-table-column>
-                  <el-table-column prop="productCode" label="商品编码" width="90" />
-                  <el-table-column prop="productName" label="商品名称" min-width="250" />
-                  <el-table-column prop="quantity" label="出货数量" width="90">
-                  </el-table-column>
-                  <el-table-column align="center" label="操作" width="60" fixed="right">
-                    <template #default="{ row, $index }">
-                      <el-button type="primary" link @click="clickDelete($index)">删除</el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
-              </div>
-            </el-col>
-          </el-row>
-        </div>
-      </template>
     </byForm>
 
     <el-dialog v-if="openProductCompany" v-model="openProductCompany" title="公司产品库" width="90%" append-to-body>
       <SelectCompanyProduct @selectProduct="selectProduct" :alreadySelectData="formData.data.contractProductList"></SelectCompanyProduct>
     </el-dialog>
 
-    <el-dialog v-if="openProductCustomer" v-model="openProductCustomer" title="客户产品库" width="90%" append-to-body>
+    <!-- <el-dialog v-if="openProductCustomer" v-model="openProductCustomer" title="客户产品库" width="90%" append-to-body>
       <SelectCustomerProduct :buyCorporationId="formData.data.buyCorporationId" @selectProduct="selectProduct"
                              :alreadySelectData="formData.data.contractProductList"></SelectCustomerProduct>
-    </el-dialog>
+    </el-dialog> -->
 
     <el-dialog v-if="copyContract" v-model="copyContract" :title="copyType === 1 ? '合同选择' : '样品单选择'" width="90%" append-to-body>
       <SelectContract @select="selectContract" v-if="copyType === 1"></SelectContract>
@@ -668,19 +385,36 @@ const formConfig = computed(() => {
     },
     {
       type: "title",
-      title: "合同模板",
-      label: "",
+      title: "合同类型",
     },
     {
       type: "select",
-      label: "选择合同模板",
-      prop: "contractTemplateId",
-      data: templateList.value,
+      prop: "type",
+      label: "合同类型",
+      data: [
+        {
+          dictKey: "0",
+          dictValue: "内销",
+        },
+        {
+          dictKey: "1",
+          dictValue: "外销",
+        },
+      ],
       fn: (val) => {
-        changeTemplate(val);
+        // console.log(val, "ss");
+        if (val == "0") {
+          formData.data.aa = accountCurrency.value[0].dictKey;
+          formData.data.netWeight = 1;
+        }
       },
     },
     {
+      type: "title",
+      title: "贸易信息",
+      haveLine: true,
+    },
+    {
       type: "slot",
       slotName: "seller",
       label: "",
@@ -692,29 +426,167 @@ const formConfig = computed(() => {
       label: "",
       itemWidth: 50,
     },
-
     {
       type: "title",
       title: "付款信息",
       haveLine: true,
     },
     {
-      type: "slot",
-      slotName: "payment",
-      label: "",
+      type: "select",
+      prop: "aa",
+      label: "币种",
+      data: accountCurrency.value,
+      itemWidth: 25,
+      disabled: formData.data.type == "0",
+    },
+    {
+      type: "number",
+      prop: "netWeight",
+      label: "汇率",
+      precision: 2,
+      min: 0,
+      controls: false,
+      itemWidth: 25,
+      disabled: formData.data.type == "0",
+    },
+    {
+      type: "select",
+      prop: "aa",
+      label: "付款方式",
+      data: accountCurrency.value,
+      itemWidth: 25,
+    },
+    {
+      type: "number",
+      prop: "netWeight",
+      label: "预付款比列(%)",
+      precision: 2,
+      min: 0,
+      controls: false,
+      itemWidth: 25,
+    },
+    {
+      type: "input",
+      prop: "netWeightww",
+      label: "付款条件",
+      itemType: "textarea",
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "shroffAccountId",
+      label: "收款账号",
+      data: accountList.value,
+      itemWidth: 100,
+    },
+    {
+      type: "input",
+      prop: "beneficiaryName",
+      label: " ",
+      placeholder: "请输入Beneficiary Name",
+      itemWidth: 50,
+      isShow: formData.data.type == "1",
+    },
+    {
+      type: "input",
+      prop: "beneficiaryAccountNumber",
+      label: " ",
+      placeholder: "请输入Beneficiary Account Number",
+      itemWidth: 50,
+      isShow: formData.data.type == "1",
+    },
+    {
+      type: "input",
+      prop: "beneficiaryBank",
+      label: " ",
+      placeholder: "请输入Beneficiary Bank",
+      itemWidth: 50,
+      isShow: formData.data.type == "1",
+    },
+    {
+      type: "input",
+      prop: "swiftCode",
+      label: " ",
+      placeholder: "请输入Swift Code",
+      itemWidth: 50,
+      isShow: formData.data.type == "1",
+    },
+    {
+      type: "input",
+      prop: "beneficiaryBankAddress",
+      label: " ",
+      placeholder: "请输入Beneficiary Bank Address",
+      itemWidth: 50,
+      isShow: formData.data.type == "1",
+    },
+    {
+      type: "input",
+      prop: "beneficiaryAddress",
+      label: " ",
+      placeholder: "请输入Beneficiary Address",
+      itemWidth: 50,
+      isShow: formData.data.type == "1",
+    },
+    {
+      type: "input",
+      prop: "aasw",
+      label: "账户别名",
+      placeholder: "请输入账户别名",
+      itemWidth: 50,
+      isShow: formData.data.type == "0",
+    },
+    {
+      type: "input",
+      prop: "aasw",
+      label: "开户银行",
+      placeholder: "请输入开户银行",
+      itemWidth: 50,
+      isShow: formData.data.type == "0",
+    },
+    {
+      type: "input",
+      prop: "aasw",
+      label: "账户名",
+      placeholder: "请输入账户名",
+      itemWidth: 50,
+      isShow: formData.data.type == "0",
     },
 
+    // {
+    //   type: "slot",
+    //   slotName: "payment",
+    //   label: "",
+    // },
     {
       type: "title",
       title: "交付信息",
       haveLine: true,
     },
     {
-      type: "slot",
-      slotName: "delivery",
-      label: "",
+      type: "date",
+      prop: "wda",
+      label: "交货期限",
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "aa",
+      label: "运输方式",
+      data: accountCurrency.value,
+      itemWidth: 50,
     },
     {
+      type: "input",
+      prop: "wda",
+      label: "运输说明",
+      itemWidth: 50,
+    },
+    // {
+    //   type: "slot",
+    //   slotName: "delivery",
+    //   label: "",
+    // },
+    {
       type: "title",
       title: "商品信息",
       haveLine: true,
@@ -725,17 +597,6 @@ const formConfig = computed(() => {
       label: "",
     },
     {
-      type: "slot",
-      slotName: "file",
-      label: "交接单",
-    },
-    {
-      type: "slot",
-      slotName: "indication",
-      label: "包装指示",
-    },
-
-    {
       type: "title",
       title: "其他收费项目",
       haveLine: true,
@@ -746,19 +607,16 @@ const formConfig = computed(() => {
       label: "",
     },
     {
-      type: "slot",
-      slotName: "offerMoney",
-    },
-
-    {
       type: "title",
-      title: "出货计划",
+      title: "合同总金额",
       haveLine: true,
     },
     {
-      type: "slot",
-      slotName: "shipment",
-      label: "",
+      type: "input",
+      prop: "wda",
+      label: "合同总金额",
+      itemWidth: 25,
+      disabled: true,
     },
   ];
 });
@@ -1191,29 +1049,6 @@ const selectProduct = (goods) => {
     if (goods.fileList && goods.fileList.length > 0) {
       fileUrl = goods.fileList[0].fileUrl;
     }
-    let packMethod = "";
-    if (goods.innerPackMethod) {
-      let innerPackMethod = goods.innerPackMethod.split(",");
-      innerPackMethod.map((item) => {
-        if (packMethod) {
-          packMethod =
-            packMethod + "," + proxy.dictValueLabel(item, innerMethod.value);
-        } else {
-          packMethod = proxy.dictValueLabel(item, innerMethod.value);
-        }
-      });
-    }
-    if (goods.outerPackMethod) {
-      let outerPackMethod = goods.outerPackMethod.split(",");
-      outerPackMethod.map((item) => {
-        if (packMethod) {
-          packMethod =
-            packMethod + "," + proxy.dictValueLabel(item, outsideMethod.value);
-        } else {
-          packMethod = proxy.dictValueLabel(item, outsideMethod.value);
-        }
-      });
-    }
     if (
       formData.data.contractProductList &&
       formData.data.contractProductList.length > 0
@@ -1230,8 +1065,9 @@ const selectProduct = (goods) => {
         price: null,
         amount: "",
         tradeMethods: "",
-        packMethod: packMethod,
+
         selectType: goods.selectType,
+        fileList: [],
       });
     } else {
       formData.data.contractProductList = [
@@ -1251,29 +1087,21 @@ const selectProduct = (goods) => {
           price: null,
           amount: "",
           tradeMethods: "",
-          packMethod: packMethod,
+
           selectType: goods.selectType,
+          fileList: [],
         },
       ];
     }
-    changeProductPrice();
+
+    // changeProductPrice();
     //左侧待出货列表
-    formData.data.contractWaitShipmentList.push({
-      productCode: goods.code,
-      rowId,
-      productId: goods.id,
-      productName: goods.nameEnglish,
-      quantity: null,
-      waitQuantity: "",
-    });
-    ElMessage({
-      message: "添加成功!",
-      type: "success",
-    });
+
+    proxy.msgTip("添加成功", 1);
   } else {
-    return ElMessage("选择错误");
+    return proxy.msgTip("选择错误", 2);
   }
-  getDecisionAids();
+  // getDecisionAids();
 };
 
 const changeProductPrice = () => {
@@ -1571,12 +1399,7 @@ const indicationUploadFile = async (file) => {
   file.uploadState = true;
   return true;
 };
-const handleSuccess = (any, UploadFile) => {
-  UploadFile.raw.uploadState = false;
-};
-const onPreviewFile = (file) => {
-  window.open(file.raw.fileUrl, "_blank");
-};
+
 const clickSplit = (item) => {
   formData.data.contractShipmentList.push({
     productCode: item.code,
@@ -2165,111 +1988,32 @@ const selectContract = (businessId) => {
   }
 };
 
-const selectShipmentData = ref([]);
-const tableDom = ref(null);
-const handleSelectionChange = (data) => {
-  selectShipmentData.value = data;
-};
-const handleAddShipment = () => {
-  if (formData.data.shipmentTime) {
-    if (selectShipmentData.value && selectShipmentData.value.length > 0) {
-      // 校验
-      for (let i = 0; i < selectShipmentData.value.length; i++) {
-        const e = selectShipmentData.value[i];
-        if (!Number(e.quantity)) {
-          return ElMessage("请输入出货数量");
-        }
-        if (Number(e.quantity) > Number(e.waitQuantity)) {
-          return ElMessage(`${e.productName} 出货数量不能超过剩余数量`);
-        }
-      }
-      // push
-      for (let i = 0; i < selectShipmentData.value.length; i++) {
-        const e = selectShipmentData.value[i];
-        formData.data.contractShipmentList.push({
-          rowId: e.rowId,
-          productId: e.productId,
-          productCode: e.productCode,
-          productName: e.productName,
-          quantity: e.quantity,
-          shipmentTime: formData.data.shipmentTime,
-        });
-        e.quantity = 0;
-      }
-      // 清空选择的数据
-      tableDom.value.clearSelection();
-      formData.data.shipmentTime = "";
-      changeWaitQuantity();
-    } else {
-      ElMessage("请勾选数据");
-    }
-  } else {
-    ElMessage("请选择出货日期");
-  }
-};
-const changeWaitQuantity = () => {
-  for (let i = 0; i < formData.data.contractProductList.length; i++) {
-    if (formData.data.contractProductList[i].quantity) {
-      formData.data.contractWaitShipmentList[i].waitQuantity =
-        formData.data.contractProductList[i].quantity;
-    }
-  }
-  if (
-    formData.data.contractShipmentList &&
-    formData.data.contractShipmentList.length > 0
-  ) {
-    for (let i = 0; i < formData.data.contractWaitShipmentList.length; i++) {
-      const e = formData.data.contractWaitShipmentList[i];
-      let arr = formData.data.contractShipmentList.filter(
-        (x) => x.rowId === e.rowId
-      );
-      let quantity = 0;
-      for (let j = 0; j < arr.length; j++) {
-        quantity += arr[j].quantity;
-      }
-      e.waitQuantity = e.waitQuantity - quantity;
-    }
-  }
-};
-const flitterData = (arr) => {
-  let spanOneArr = [];
-  let concatOne = 0;
-  arr.forEach((item, index) => {
-    if (index === 0) {
-      spanOneArr.push(1);
-    } else {
-      //注意这里的quarterly是表格绑定的字段,根据自己的需求来改
-      if (item.shipmentTime === arr[index - 1].shipmentTime) {
-        //第一列需合并相同内容的判断条件
-        spanOneArr[concatOne] += 1;
-        spanOneArr.push(0);
-      } else {
-        spanOneArr.push(1);
-        concatOne = index;
-      }
-    }
-  });
-  return {
-    one: spanOneArr,
-  };
+const handleBeforeUpload = async (file, index) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  // file.id = res.id;
+  // file.fileName = res.fileName;
+  // file.fileUrl = res.fileUrl;
+  formData.data.contractProductList[index].fileList = [
+    {
+      id: res.id,
+      fileName: res.fileName,
+      fileUrl: res.fileUrl,
+    },
+  ];
+  formData.data.contractProductList[index].imageUrl = res.fileUrl;
+  return true;
 };
 
-const objectSpanMethod = ({ rowIndex, columnIndex }) => {
-  if (columnIndex === 0) {
-    const _row = flitterData(formData.data.contractShipmentList).one[rowIndex];
-    const _col = _row > 0 ? 1 : 0;
-    return {
-      rowspan: _row,
-      colspan: _col,
-    };
-  }
+const handleSuccess = (any, UploadFile) => {
+  UploadFile.raw.uploadState = false;
+};
+const onPreviewFile = (file) => {
+  if (file && file.fileUrl) window.open(file.fileUrl, "_blank");
 };
 </script>
 
 <style lang="scss" scoped>
-::v-deep(.el-input-number .el-input__inner) {
-  text-align: left;
-}
 .img {
   object-fit: contain;
   width: 16px;
@@ -2283,20 +2027,12 @@ const objectSpanMethod = ({ rowIndex, columnIndex }) => {
   cursor: pointer;
   vertical-align: middle;
 }
-.shrinkPadding {
-  padding-right: 0 !important;
-}
-.hideCollapse {
-  margin-top: -62px;
-  border: 0 !important;
-}
-::v-deep(.el-collapse-item__arrow) {
-  display: none !important;
-}
-::v-deep(.el-collapse-item__wrap) {
-  border: 0 !important;
-}
-::v-deep(.el-collapse-item__header) {
-  border: 0 !important;
+.el-icon.avatar-uploader-icon {
+  font-size: 20px;
+  color: #8c939d;
+  width: 50px;
+  height: 50px;
+  text-align: center;
+  border: 1px dashed var(--el-border-color);
 }
 </style>

+ 82 - 53
src/components/product/SelectCompanyProduct.vue

@@ -13,7 +13,7 @@
         }" :action-list="[]" @get-list="getList">
         <template #name="{ item }">
           <div>
-            <span style="color: #409eff; cursor: pointer; word-break: break-all" @click="handleOpenProductContract(item)">{{ item.name }}</span>
+            <span class="el-click">{{ item.name }}</span>
           </div>
         </template>
         <template #pic="{ item }">
@@ -23,21 +23,18 @@
           <div v-else></div>
         </template>
         <template #size="{ item }">
-          <div>
-            <span>{{ item.productLong }}cm</span>*
-            <span>{{ item.productWide }}cm</span>*
-            <span>{{ item.productHigh }}cm</span>
+          <div v-if="item['length'] && item.width && item.height">
+            <span>{{ item['length'] }}cm</span>*
+            <span>{{ item.width }}cm</span>*
+            <span>{{ item.height }}cm</span>
           </div>
+          <div v-else></div>
         </template>
         <template #price="{ item }">
-          <div>
-            <span v-if="item.price">{{ item.currency }} {{ item.price }}</span>
-          </div>
-        </template>
-        <template #costPrice="{ item }">
-          <div>
-            <span v-if="item.costPrice">{{ item.costCurrency }} {{ item.costPrice }}</span>
+          <div v-if="item.price">
+            <span>{{ item.currency }} {{ moneyFormat(item.price ,2)}}</span>
           </div>
+          <div v-else></div>
         </template>
       </byTable>
     </div>
@@ -177,40 +174,75 @@ const config = computed(() => {
         label: "图片",
         slot: "pic",
         align: "center",
-        width: 100,
+        width: 80,
+      },
+    },
+    {
+      attrs: {
+        label: "产品分类",
+        prop: "classifyName",
+        "min-width": 150,
       },
     },
     {
       attrs: {
         label: "产品编码",
-        prop: "code",
+        prop: "customCode",
+        width: 120,
       },
     },
     {
       attrs: {
         label: "产品名称",
         slot: "name",
+        "min-width": 150,
+      },
+    },
+    {
+      attrs: {
+        label: "产品英文名",
+        prop: "nameEnglish",
+        "min-width": 120,
+      },
+    },
+    {
+      attrs: {
+        label: "产品规格",
+        prop: "spec",
+        width: 120,
       },
     },
-
     {
       attrs: {
         label: "尺寸",
         slot: "size",
+        width: 150,
       },
     },
     {
       attrs: {
-        label: "销售指导价",
+        label: "净重",
+        prop: "netWeight",
+        width: 100,
+      },
+      render(val) {
+        if (val) {
+          return val + " kg";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "销售价",
         slot: "price",
-        width: 150,
+        width: 100,
       },
     },
     {
       attrs: {
-        label: "成本价",
-        slot: "costPrice",
-        width: 150,
+        label: "海关编码",
+        prop: "hsCode",
+        width: 100,
       },
     },
     {
@@ -412,42 +444,39 @@ const formConfig = computed(() => {
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy
-    .post("/productInfo/getConditionProductList", sourceList.value.pagination)
-    .then(
-      (message) => {
-        sourceList.value.data = message.rows.map((x) => ({
-          ...x,
-          fileList: [],
-          ...JSON.parse(x.ehsdJson),
-        }));
-        sourceList.value.pagination.total = message.total;
-        setTimeout(() => {
-          loading.value = false;
-        }, 200);
-        const productIdList = message.rows.map((x) => x.id);
-        // 请求文件数据并回显
-        if (productIdList.length > 0) {
-          proxy
-            .post("/fileInfo/getList", {
-              businessIdList: productIdList,
-            })
-            .then((fileObj) => {
-              for (let i = 0; i < sourceList.value.data.length; i++) {
-                const e = sourceList.value.data[i];
-                for (const key in fileObj) {
-                  if (e.id === key) {
-                    e.fileList = fileObj[key];
-                  }
+  proxy.post("/productInfo/page", sourceList.value.pagination).then(
+    (message) => {
+      sourceList.value.data = message.rows.map((x) => ({
+        ...x,
+        fileList: [],
+      }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+      const productIdList = message.rows.map((x) => x.id);
+      // 请求文件数据并回显
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: productIdList,
+          })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
                 }
               }
-            });
-        }
-      },
-      (err) => {
-        loading.value = false;
+            }
+          });
       }
-    );
+    },
+    (err) => {
+      loading.value = false;
+    }
+  );
 };
 
 const treeChange = (e) => {

+ 324 - 265
src/components/product/SelectMaterial.vue

@@ -7,77 +7,104 @@
     </div>
     <div class="content">
       <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
-               :selectConfig="selectConfig" :table-events="{
-          //element talbe事件都能传
-          select: select,
-        }" :action-list="[]" @get-list="getList">
+               :selectConfig="selectConfig" :action-list="[
+         
+        ]" @get-list="getList">
         <template #pic="{ item }">
           <div v-if="item.fileList.length > 0">
             <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
           </div>
           <div v-else></div>
         </template>
-      </byTable>
-    </div>
-    <div class="right">
-      <div style="margin-bottom:30px">
-        <TitleInfo :content="'已选择配件'"></TitleInfo>
-      </div>
-      <el-tag style="margin-right: 10px; margin-bottom: 10px" type="info" v-for="(good, index) in goodList" :key="good.productId">
-        {{  good.productName }}
-      </el-tag>
-    </div>
-    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-model="dialogVisible" width="500" v-loading="loading">
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
-        <template #productPic>
+        <template #name="{ item }">
           <div>
-            <el-upload v-model:fileList="fileList" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadData"
-                       list-type="picture-card" :on-remove="handleRemove" :on-success="handleSuccess" :before-upload="handleBeforeUpload">
-              <el-icon>
-                <Plus />
-              </el-icon>
-            </el-upload>
+            <span class="el-click">{{ item.name }}</span>
           </div>
         </template>
-      </byForm>
-      <template #footer>
-        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitForm('byform')" size="large" :loading="submitLoading">
-          确 定
-        </el-button>
-      </template>
-    </el-dialog>
-    <el-dialog title="Excel导入" v-model="openExcelDialog" width="400" v-loading="loading">
+        <template #size="{ item }">
+          <div v-if="item['length'] && item.width && item.height">
+            <span>{{ item['length'] }}cm</span>*
+            <span>{{ item.width }}cm</span>*
+            <span>{{ item.height }}cm</span>
+          </div>
+          <div v-else></div>
+        </template>
+        <template #price="{ item }">
+          <div v-if="item.price">
+            <span>{{ item.currency }} {{ moneyFormat(item.price ,2)}}</span>
+          </div>
+          <div v-else></div>
+        </template>
+        <template #costPrice="{ item }">
+          <div v-if="item.costPrice">
+            <span>{{ item.currency }} {{ moneyFormat(item.costPrice ,2)}}</span>
+          </div>
+          <div v-else></div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog :title="modalType == 'add' ? '添加物料' : '编辑物料'" v-model="dialogVisible" width="80%" destroy-on-close>
+      <div class="public_height_dialog">
+        <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
+          <template #size>
+            <div style="width: 100%">
+              <el-row>
+                <el-col :span="8">
+                  <el-form-item prop="length" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.length" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-form-item prop="width" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.width" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
+                  </el-form-item>
+                </el-col>
+                <el-col :span="8">
+                  <el-form-item prop="height" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.height" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
+                  </el-form-item>
+                </el-col>
+              </el-row>
+            </div>
+          </template>
+        </byForm>
+      </div>
+
       <template #footer>
-        <el-button @click="openExcelDialog = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitExcel()" size="large" :loading="submitLoading">
+        <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="defualt" :loading="submitLoading">
           确 定
         </el-button>
       </template>
     </el-dialog>
   </div>
 </template>
-  
+
 <script setup>
-/* eslint-disable vue/no-unused-components */
-import { ElMessage, ElMessageBox } from "element-plus";
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
 import treeList from "@/components/product/treeList";
-import TitleInfo from "@/components/TitleInfo/index.vue";
-
 const { proxy } = getCurrentInstance();
-const props = defineProps({
-  alreadySelectData: Array,
-});
-const goodList = ref([]);
-onMounted(() => {
-  goodList.value = proxy.deepClone(props.alreadySelectData);
-});
+const currencyData = computed(
+  () => proxy.useUserStore().allDict["account_currency"]
+);
+const materialUnitData = computed(
+  () => proxy.useUserStore().allDict["material_unit"]
+);
+const colorLayerData = computed(
+  () => proxy.useUserStore().allDict["color_layer"]
+);
+const backLinesData = computed(
+  () => proxy.useUserStore().allDict["back_lines"]
+);
+const frontLinesData = computed(
+  () => proxy.useUserStore().allDict["front_lines"]
+);
 const loading = ref(false);
 const submitLoading = ref(false);
-const materialUnit = ref([]);
-const materialType = ref([]);
 const sourceList = ref({
   data: [],
   pagination: {
@@ -90,86 +117,113 @@ const sourceList = ref({
     definition: "2",
   },
 });
-let dialogVisible = ref(false);
-let openExcelDialog = ref(false);
-
-let modalType = ref("add");
-let rules = ref({
+const dialogVisible = ref(false);
+const modalType = ref("add");
+const treeData = ref([]);
+const rules = ref({
   productClassifyId: [
     { required: true, message: "请选择物料分类", trigger: "change" },
   ],
-  type: [{ required: true, message: "请选择物料类型", trigger: "change" }],
   name: [{ required: true, message: "请输入物料名称", trigger: "blur" }],
-  unit: [{ required: true, message: "请选择单位", trigger: "change" }],
-});
-const selectConfig = computed(() => {
-  return [
-    {
-      label: "物料类型",
-      prop: "type",
-      data: materialType.value,
-    },
-  ];
+  customCode: [{ required: true, message: "请输入物料编码", trigger: "blur" }],
 });
+const selectConfig = computed(() => []);
 const config = computed(() => {
   return [
     {
       attrs: {
-        label: "物料类型",
-        prop: "type",
+        label: "图片",
+        slot: "pic",
+        align: "center",
+        width: 80,
       },
-      render(type) {
-        return proxy.dictValueLabel(type, materialType.value);
+    },
+    {
+      attrs: {
+        label: "物料分类",
+        prop: "classifyName",
+        "min-width": 150,
       },
     },
     {
       attrs: {
         label: "物料编码",
-        prop: "code",
+        prop: "customCode",
+        width: 120,
       },
     },
     {
       attrs: {
-        label: "物料名称",
-        prop: "name",
+        label: " 物料名称",
+        slot: "name",
+        "min-width": 150,
       },
     },
     {
       attrs: {
-        label: "图片",
-        slot: "pic",
+        label: "物料材质",
+        prop: "material",
+        width: 120,
+      },
+    },
+    {
+      attrs: {
+        label: "物料型号",
+        prop: "spec",
+        width: 120,
       },
     },
     {
       attrs: {
         label: "单位",
         prop: "unit",
+        width: 80,
       },
-      render(unit) {
-        return proxy.dictValueLabel(unit, materialUnit.value);
+      render(val) {
+        return proxy.dictKeyValue(val, materialUnitData.value);
       },
     },
     {
       attrs: {
-        label: "规格型号",
-        prop: "spec",
+        label: "尺寸",
+        slot: "size",
+        width: 150,
       },
     },
     {
       attrs: {
-        label: "物料备注",
-        prop: "remark",
+        label: "净重",
+        prop: "netWeight",
+        width: 100,
+      },
+      render(val) {
+        if (val) {
+          return val + " kg";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "成本价",
+        slot: "costPrice",
+        width: 100,
+      },
+    },
+    {
+      attrs: {
+        label: "销售价",
+        slot: "price",
+        width: 100,
       },
     },
 
     {
       attrs: {
         label: "操作",
-        width: "60",
+        width: "80",
         align: "center",
         fixed: "right",
       },
-      // 渲染 el-button,一般用在最后一列。
       renderHTML(row) {
         return [
           {
@@ -180,7 +234,7 @@ const config = computed(() => {
             },
             el: "button",
             click() {
-              handleSelect(row);
+              clickSelect(row);
             },
           },
         ];
@@ -188,147 +242,194 @@ const config = computed(() => {
     },
   ];
 });
-
-let formData = reactive({
+const formData = reactive({
   data: {},
 });
 const formOption = reactive({
   inline: true,
   labelWidth: 100,
   itemWidth: 100,
-  rules: [],
 });
-const byform = ref(null);
+const formDom = ref(null);
 const treeListData = ref([]);
 const formConfig = computed(() => {
   return [
     {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
       type: "treeSelect",
       prop: "productClassifyId",
       label: "物料分类",
-      data: [],
-    },
-    {
-      type: "select",
-      prop: "type",
-      label: "物料类型",
-      required: true,
-      data: [
-        {
-          label: "原料",
-          id: "1",
-        },
-        {
-          label: "辅料",
-          id: "2",
-        },
-        {
-          label: "配件",
-          id: "3",
-        },
-        {
-          label: "包材",
-          id: "4",
-        },
-        {
-          label: "其他",
-          id: "5",
-        },
-      ],
+      data: treeData.value,
+      itemWidth: 100,
+      disabled: false,
     },
     {
       type: "input",
       prop: "name",
       label: "物料名称",
+      itemWidth: 50,
+      disabled: false,
+    },
+    {
+      type: "input",
+      prop: "customCode",
+      label: "物料编码",
+      itemWidth: 50,
+      disabled: false,
+    },
+    {
+      type: "uploadImg",
+      // limit: 1,
+      // listType: "picture-card",
+      // accept: ".gif, .jpeg, .jpg, .png",
+      imgProp: "imageUrl",
+      prop: "fileList",
+      label: "物料缩略图",
+    },
+    {
+      type: "title1",
+      title: "材质特征",
+    },
+    {
+      type: "input",
+      prop: "material",
+      label: "材质",
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "spec",
-      label: "规格型号",
+      label: "型号",
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "frontalTexture",
+      label: "正面纹路",
+      data: frontLinesData.value,
+      itemWidth: 50,
+    },
+    {
+      type: "select",
+      prop: "reverseTexture",
+      label: "背面纹路",
+      data: backLinesData.value,
+      itemWidth: 50,
     },
     {
       type: "select",
       prop: "unit",
       label: "单位",
-      required: true,
-      data: [
-        {
-          label: "个",
-          id: "个",
-        },
-        {
-          label: "双",
-          id: "双",
-        },
-      ],
+      data: materialUnitData.value,
+      itemWidth: 50,
     },
     {
-      type: "slot",
-      slotName: "productPic",
-      prop: "fileList",
-      label: "产品图片",
+      type: "select",
+      prop: "colorLayer",
+      label: "色层",
+      data: colorLayerData.value,
+      itemWidth: 50,
+    },
+    // {
+    //   type: "input",
+    //   prop: "remark",
+    //   label: "备注",
+    //   itemType: "textarea",
+    // },
+    {
+      type: "title1",
+      title: "规格",
     },
-
     {
       type: "input",
-      prop: "remark",
-      label: "备注",
-      itemType: "textarea",
+      prop: "color",
+      label: "颜色",
+      itemWidth: 50,
+    },
+    {
+      type: "number",
+      prop: "stockThreshold",
+      label: "安全库存",
+      precision: 2,
+      min: 0,
+      controls: false,
+      itemWidth: 50,
+    },
+    {
+      type: "selectInput",
+      prop: "costPrice",
+      selectProp: "costCurrency",
+      label: "成本价",
+      itemWidth: 50,
+      disabledSelect: true,
+      data: currencyData.value,
+    },
+    {
+      type: "selectInput",
+      prop: "price",
+      selectProp: "currency",
+      label: "销售价",
+      itemWidth: 50,
+      disabledSelect: true,
+      data: currencyData.value,
+    },
+    {
+      type: "slot",
+      slotName: "size",
+      prop: "size",
+      label: "尺寸",
+      itemWidth: 50,
+      disabled: false,
+    },
+    {
+      type: "number",
+      prop: "netWeight",
+      label: "净重(kg)",
+      precision: 2,
+      min: 0,
+      controls: false,
+      itemWidth: 50,
     },
   ];
 });
-const newPassword = () => {
-  formData.data.password = generatePassword();
-};
-const generatePassword = () => {
-  var length = 12,
-    charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
-    password = "";
-  for (var i = 0, n = charset.length; i < length; ++i) {
-    password += charset.charAt(Math.floor(Math.random() * n));
-  }
-  return password;
-};
 
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy
-    .post("/productInfo/page", sourceList.value.pagination)
-    .then((message) => {
-      console.log(message);
-      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
-      sourceList.value.pagination.total = message.total;
-      setTimeout(() => {
-        loading.value = false;
-      }, 200);
+  proxy.post("/productInfo/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows.map((x) => ({ ...x, fileList: [] }));
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
 
-      const productIdList = message.rows.map((x) => x.id);
-      // 请求文件数据并回显
-      if (productIdList.length > 0) {
-        proxy
-          .post("/fileInfo/getList", { businessIdList: productIdList })
-          .then((fileObj) => {
-            for (let i = 0; i < sourceList.value.data.length; i++) {
-              const e = sourceList.value.data[i];
-              for (const key in fileObj) {
-                if (e.id === key) {
-                  e.fileList = fileObj[key];
-                }
+    const productIdList = res.rows.map((x) => x.id);
+    // 请求文件数据并回显
+    if (productIdList.length > 0) {
+      proxy
+        .post("/fileInfo/getList", { businessIdList: productIdList })
+        .then((fileObj) => {
+          for (let i = 0; i < sourceList.value.data.length; i++) {
+            const e = sourceList.value.data[i];
+            for (const key in fileObj) {
+              if (e.id === key) {
+                e.fileList = fileObj[key];
               }
             }
-          });
-      }
-    });
+          }
+        });
+    }
+  });
 };
-const uploadData = ref({});
-const fileList = ref([]);
-const fileListCopy = ref([]);
 
 const treeChange = (e) => {
-  console.log(e);
-  sourceList.value.pagination.productClassifyId = e.id;
-  getList({ productClassifyId: e.id });
+  if (e.id != undefined) {
+    sourceList.value.pagination.productClassifyId = e.id;
+    getList({ productClassifyId: e.id });
+  }
 };
 
 const openModal = () => {
@@ -338,40 +439,21 @@ const openModal = () => {
     definition: "2",
     fileList: [],
   };
-  fileList.value = [];
-  fileListCopy.value = [];
-};
-
-const openExcel = () => {
-  openExcelDialog.value = true;
-};
-const submitExcel = () => {
-  openExcelDialog.value = false;
-};
-const TreetenantId = ref("");
-const selection = ref({
-  data: [],
-});
-const select = (_selection, row) => {
-  selection.value.data = _selection;
-  console.log(_selection.length);
+  if (currencyData.value && currencyData.value.length > 0) {
+    formData.data.currency = currencyData.value[0].dictKey;
+    formData.data.costCurrency = currencyData.value[0].dictKey;
+  }
 };
 
-const tree = ref(null);
 const submitForm = () => {
-  console.log(byform.value);
-  byform.value.handleSubmit((valid) => {
-    formData.data.fileList = fileListCopy.value.map((x) => ({
-      id: x.id,
-      fileName: x.fileName,
-    }));
+  formDom.value.handleSubmit((valid) => {
+    if (!formData.data.fileList.length > 0) {
+      return proxy.msgTip("请上传图片", 2);
+    }
     submitLoading.value = true;
     proxy.post("/productInfo/" + modalType.value, formData.data).then(
       (res) => {
-        ElMessage({
-          message: modalType.value == "add" ? "添加成功" : "编辑成功",
-          type: "success",
-        });
+        proxy.msgTip("操作成功", 1);
         dialogVisible.value = false;
         submitLoading.value = false;
         getList();
@@ -387,92 +469,69 @@ const getTreeList = () => {
   proxy
     .post("/productClassify/tree", { parentId: "", name: "", definition: "2" })
     .then((message) => {
-      treeListData.value = message;
-      formConfig.value[0].data = message;
+      treeListData.value = [
+        {
+          id: "",
+          label: "全部",
+          parentId: "",
+          children: message,
+        },
+      ];
+      treeData.value = message;
     });
 };
 
 const getDtl = (row) => {
   modalType.value = "edit";
   proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
-    fileList.value = row.fileList.map((x) => ({ ...x, url: x.fileUrl }));
-    fileListCopy.value = [...fileList.value];
-    res.type = res.type + "";
-    res.definition = "2";
     formData.data = res;
+    formData.data.fileList = row.fileList.map((x) => ({
+      ...x,
+      url: x.fileUrl,
+      name: x.fileName,
+    }));
+    if (formData.data.fileList.length > 0) {
+      formData.data.imageUrl = formData.data.fileList[0].fileUrl;
+    }
     dialogVisible.value = true;
   });
 };
-getTreeList();
-getList();
-const handleBeforeUpload = async (file) => {
-  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
-  uploadData.value = res.uploadBody;
-  fileListCopy.value.push({
-    id: res.id,
-    fileName: res.fileName,
-    path: res.fileUrl,
-    url: res.fileUrl,
-    uid: file.uid,
-  });
-};
-
-const handleSuccess = (res, file, files) => {
-  // 查当前file的index值去赋值对应的copy变量的值
-  // let uid = file.uid;
-  // const index = fileList.value.findIndex((x) => x.uid === uid);
-  // fileListCopy.value[index].uid = uid;
-};
 
-const handleRemove = (file) => {
-  const index = fileListCopy.value.findIndex(
-    (x) => x.uid === file.uid || x.id === file.id
-  );
-  fileListCopy.value.splice(index, 1);
-};
+// const getDtlOne = (row) => {
+//   modalType.value = "add";
+//   proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
+//     fileList.value = [];
+//     fileListCopy.value = [];
+//     res.type = res.type + "";
+//     res.definition = "2";
+//     delete res.id;
+//     formData.data = res;
+//     dialogVisible.value = true;
+//   });
+// };
 
 const handleClickFile = (file) => {
   window.open(file.fileUrl, "_blank");
 };
 
-const handleSelect = (row) => {
-  goodList.value.push({
-    ...row,
-    productName: row.name,
-  });
-  proxy.$emit("handleSelect", row);
-};
+getTreeList();
+getList();
 
-const getDict = () => {
-  proxy.getDictOne(["material_unit", "material_type"]).then((res) => {
-    materialUnit.value = res["material_unit"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-    materialType.value = res["material_type"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-  });
+const clickSelect = (item) => {
+  proxy.$emit("selectMaterial", item);
 };
-getDict();
 </script>
-  
+
 <style lang="scss" scoped>
 .user {
-  padding: 20px;
+  // padding: 20px;
   display: flex;
   justify-content: space-between;
   .tree {
     width: 300px;
   }
   .content {
-    width: calc(100% - 320px - 170px);
-  }
-  .right {
-    padding-left: 10px;
-    width: 170px;
-    border-left: 1px solid #eee;
+    width: calc(100% - 320px);
   }
 }
 .pic {
@@ -482,4 +541,4 @@ getDict();
   cursor: pointer;
   vertical-align: middle;
 }
-</style>
+</style>

+ 485 - 0
src/components/product/SelectMaterialss.vue

@@ -0,0 +1,485 @@
+<template>
+  <div class="user">
+    <div class="tree">
+      <treeList title="物料分类" submitType="2" :data="treeListData" v-model="sourceList.pagination.productClassifyId" @change="treeChange"
+                @changeTreeList="getTreeList">
+      </treeList>
+    </div>
+    <div class="content">
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
+               :selectConfig="selectConfig" :table-events="{
+          //element talbe事件都能传
+          select: select,
+        }" :action-list="[]" @get-list="getList">
+        <template #pic="{ item }">
+          <div v-if="item.fileList.length > 0">
+            <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
+          </div>
+          <div v-else></div>
+        </template>
+      </byTable>
+    </div>
+    <div class="right">
+      <div style="margin-bottom:30px">
+        <TitleInfo :content="'已选择配件'"></TitleInfo>
+      </div>
+      <el-tag style="margin-right: 10px; margin-bottom: 10px" type="info" v-for="(good, index) in goodList" :key="good.productId">
+        {{  good.productName }}
+      </el-tag>
+    </div>
+    <el-dialog :title="modalType == 'add' ? '添加' : '编辑'" v-model="dialogVisible" width="500" v-loading="loading">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
+        <template #productPic>
+          <div>
+            <el-upload v-model:fileList="fileList" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadData"
+                       list-type="picture-card" :on-remove="handleRemove" :on-success="handleSuccess" :before-upload="handleBeforeUpload">
+              <el-icon>
+                <Plus />
+              </el-icon>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitForm('byform')" size="large" :loading="submitLoading">
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+    <el-dialog title="Excel导入" v-model="openExcelDialog" width="400" v-loading="loading">
+      <template #footer>
+        <el-button @click="openExcelDialog = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitExcel()" size="large" :loading="submitLoading">
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+  
+<script setup>
+/* eslint-disable vue/no-unused-components */
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import treeList from "@/components/product/treeList";
+import TitleInfo from "@/components/TitleInfo/index.vue";
+
+const { proxy } = getCurrentInstance();
+const props = defineProps({
+  alreadySelectData: Array,
+});
+const goodList = ref([]);
+onMounted(() => {
+  goodList.value = proxy.deepClone(props.alreadySelectData);
+});
+const loading = ref(false);
+const submitLoading = ref(false);
+const materialUnit = ref([]);
+const materialType = ref([]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    type: "",
+    productClassifyId: "",
+    keyword: "",
+    definition: "2",
+  },
+});
+let dialogVisible = ref(false);
+let openExcelDialog = ref(false);
+
+let modalType = ref("add");
+let rules = ref({
+  productClassifyId: [
+    { required: true, message: "请选择物料分类", trigger: "change" },
+  ],
+  type: [{ required: true, message: "请选择物料类型", trigger: "change" }],
+  name: [{ required: true, message: "请输入物料名称", trigger: "blur" }],
+  unit: [{ required: true, message: "请选择单位", trigger: "change" }],
+});
+const selectConfig = computed(() => {
+  return [
+    {
+      label: "物料类型",
+      prop: "type",
+      data: materialType.value,
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "物料类型",
+        prop: "type",
+      },
+      render(type) {
+        return proxy.dictValueLabel(type, materialType.value);
+      },
+    },
+    {
+      attrs: {
+        label: "物料编码",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "物料名称",
+        prop: "name",
+      },
+    },
+    {
+      attrs: {
+        label: "图片",
+        slot: "pic",
+      },
+    },
+    {
+      attrs: {
+        label: "单位",
+        prop: "unit",
+      },
+      render(unit) {
+        return proxy.dictValueLabel(unit, materialUnit.value);
+      },
+    },
+    {
+      attrs: {
+        label: "规格型号",
+        prop: "spec",
+      },
+    },
+    {
+      attrs: {
+        label: "物料备注",
+        prop: "remark",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "60",
+        align: "center",
+        fixed: "right",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "选择",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              handleSelect(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+
+let formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const treeListData = ref([]);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "treeSelect",
+      prop: "productClassifyId",
+      label: "物料分类",
+      data: [],
+    },
+    {
+      type: "select",
+      prop: "type",
+      label: "物料类型",
+      required: true,
+      data: [
+        {
+          label: "原料",
+          id: "1",
+        },
+        {
+          label: "辅料",
+          id: "2",
+        },
+        {
+          label: "配件",
+          id: "3",
+        },
+        {
+          label: "包材",
+          id: "4",
+        },
+        {
+          label: "其他",
+          id: "5",
+        },
+      ],
+    },
+    {
+      type: "input",
+      prop: "name",
+      label: "物料名称",
+    },
+    {
+      type: "input",
+      prop: "spec",
+      label: "规格型号",
+    },
+    {
+      type: "select",
+      prop: "unit",
+      label: "单位",
+      required: true,
+      data: [
+        {
+          label: "个",
+          id: "个",
+        },
+        {
+          label: "双",
+          id: "双",
+        },
+      ],
+    },
+    {
+      type: "slot",
+      slotName: "productPic",
+      prop: "fileList",
+      label: "产品图片",
+    },
+
+    {
+      type: "input",
+      prop: "remark",
+      label: "备注",
+      itemType: "textarea",
+    },
+  ];
+});
+const newPassword = () => {
+  formData.data.password = generatePassword();
+};
+const generatePassword = () => {
+  var length = 12,
+    charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
+    password = "";
+  for (var i = 0, n = charset.length; i < length; ++i) {
+    password += charset.charAt(Math.floor(Math.random() * n));
+  }
+  return password;
+};
+
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/productInfo/page", sourceList.value.pagination)
+    .then((message) => {
+      console.log(message);
+      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+
+      const productIdList = message.rows.map((x) => x.id);
+      // 请求文件数据并回显
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", { businessIdList: productIdList })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              const e = sourceList.value.data[i];
+              for (const key in fileObj) {
+                if (e.id === key) {
+                  e.fileList = fileObj[key];
+                }
+              }
+            }
+          });
+      }
+    });
+};
+const uploadData = ref({});
+const fileList = ref([]);
+const fileListCopy = ref([]);
+
+const treeChange = (e) => {
+  console.log(e);
+  sourceList.value.pagination.productClassifyId = e.id;
+  getList({ productClassifyId: e.id });
+};
+
+const openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formData.data = {
+    definition: "2",
+    fileList: [],
+  };
+  fileList.value = [];
+  fileListCopy.value = [];
+};
+
+const openExcel = () => {
+  openExcelDialog.value = true;
+};
+const submitExcel = () => {
+  openExcelDialog.value = false;
+};
+const TreetenantId = ref("");
+const selection = ref({
+  data: [],
+});
+const select = (_selection, row) => {
+  selection.value.data = _selection;
+  console.log(_selection.length);
+};
+
+const tree = ref(null);
+const submitForm = () => {
+  console.log(byform.value);
+  byform.value.handleSubmit((valid) => {
+    formData.data.fileList = fileListCopy.value.map((x) => ({
+      id: x.id,
+      fileName: x.fileName,
+    }));
+    submitLoading.value = true;
+    proxy.post("/productInfo/" + modalType.value, formData.data).then(
+      (res) => {
+        ElMessage({
+          message: modalType.value == "add" ? "添加成功" : "编辑成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => {
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+
+const getTreeList = () => {
+  proxy
+    .post("/productClassify/tree", { parentId: "", name: "", definition: "2" })
+    .then((message) => {
+      treeListData.value = message;
+      formConfig.value[0].data = message;
+    });
+};
+
+const getDtl = (row) => {
+  modalType.value = "edit";
+  proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
+    fileList.value = row.fileList.map((x) => ({ ...x, url: x.fileUrl }));
+    fileListCopy.value = [...fileList.value];
+    res.type = res.type + "";
+    res.definition = "2";
+    formData.data = res;
+    dialogVisible.value = true;
+  });
+};
+getTreeList();
+getList();
+const handleBeforeUpload = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  fileListCopy.value.push({
+    id: res.id,
+    fileName: res.fileName,
+    path: res.fileUrl,
+    url: res.fileUrl,
+    uid: file.uid,
+  });
+};
+
+const handleSuccess = (res, file, files) => {
+  // 查当前file的index值去赋值对应的copy变量的值
+  // let uid = file.uid;
+  // const index = fileList.value.findIndex((x) => x.uid === uid);
+  // fileListCopy.value[index].uid = uid;
+};
+
+const handleRemove = (file) => {
+  const index = fileListCopy.value.findIndex(
+    (x) => x.uid === file.uid || x.id === file.id
+  );
+  fileListCopy.value.splice(index, 1);
+};
+
+const handleClickFile = (file) => {
+  window.open(file.fileUrl, "_blank");
+};
+
+const handleSelect = (row) => {
+  goodList.value.push({
+    ...row,
+    productName: row.name,
+  });
+  proxy.$emit("handleSelect", row);
+};
+
+const getDict = () => {
+  proxy.getDictOne(["material_unit", "material_type"]).then((res) => {
+    materialUnit.value = res["material_unit"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    materialType.value = res["material_type"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
+};
+getDict();
+</script>
+  
+<style lang="scss" scoped>
+.user {
+  padding: 20px;
+  display: flex;
+  justify-content: space-between;
+  .tree {
+    width: 300px;
+  }
+  .content {
+    width: calc(100% - 320px - 170px);
+  }
+  .right {
+    padding-left: 10px;
+    width: 170px;
+    border-left: 1px solid #eee;
+  }
+}
+.pic {
+  object-fit: contain;
+  width: 50px;
+  height: 50px;
+  cursor: pointer;
+  vertical-align: middle;
+}
+</style>

+ 26 - 6
src/components/product/treeList.vue

@@ -18,17 +18,34 @@
         <template #default="{ node, data }">
           <div class="custom-tree-node">
             <div style="flex: 1">{{ node.label }}</div>
-            <div style="float: right; width: 71px; margin-left: 10px">
-              <el-icon :size="17" @click.stop="() => edit(node, data)" v-if="getShowIcon(data)">
+            <!-- <div style="float: right; width: 71px; margin-left: 10px" v-if="node.label != '全部'">
+              <el-icon :size="17" @click.stop.native="() => edit(node, data)" v-if="getShowIcon(data)">
                 <Edit />
               </el-icon>
-              <el-icon :size="17" style="margin-left: 10px" @click.stop="() => add(data)">
+              <el-icon :size="17" style="margin-left: 10px" @click.stop.native="() => add(data)">
                 <Plus />
               </el-icon>
-              <el-icon :size="17" style="margin-left: 10px" @click.stop="() => del(data)" v-if="getShowIcon(data)">
+              <el-icon :size="17" style="margin-left: 10px" @click.stop.native="() => del(data)" v-if="getShowIcon(data)">
                 <Delete />
               </el-icon>
-            </div>
+            </div> -->
+            <el-popover placement="bottom-start" title="" :width="100" trigger="hover">
+              <div default style="display: flex;justify-content:space-around">
+                <el-icon :size="17" style="cursor:pointer" @click.stop.native="() => edit(node, data)" v-if="getShowIcon(data)">
+                  <Edit />
+                </el-icon>
+                <el-icon :size="17" style="cursor:pointer" @click.stop.native="() => add(data)">
+                  <Plus />
+                </el-icon>
+                <el-icon :size="17" style="cursor:pointer" @click.stop.native="() => del(data)" v-if="getShowIcon(data)">
+                  <Delete />
+                </el-icon>
+              </div>
+              <template #reference>
+                <span class="iconfont icon_more iconColor" style="padding-bottom: 5px; margin-left: auto;margin-right:8px"
+                      v-if="node.label != '全部'">...</span>
+              </template>
+            </el-popover>
           </div>
         </template>
       </el-tree>
@@ -152,13 +169,13 @@ const add = (data) => {
 };
 
 const edit = (node, data) => {
-  console.log(node, data, "sssdd");
   treeModal.value = true;
   treeModalType.value = "edit";
   formData.data = {
     name: data.label,
     id: data.id,
     definition: props.submitType,
+    sort: data.sort,
   };
 };
 
@@ -269,4 +286,7 @@ const getShowIcon = (data) => {
     }
   }
 }
+.iconColor {
+  color: #666 !important;
+}
 </style>

+ 332 - 248
src/views/EHSD/productLibrary/companyProduct/index.vue

@@ -13,15 +13,14 @@
                 action: () => openExcel(),
                 disabled: false,
               },
-      {
+              {
                 text: '添加',
                 action: () => openModal('add'),
                 disabled: false,
-              },
-        ]" @get-list="getList">
+              },]" @get-list="getList">
         <template #name="{ item }">
           <div>
-            <span style="color: #409eff; cursor: pointer; word-break: break-all" @click="handleOpenProductContract(item)">{{ item.name }}</span>
+            <span class="el-click">{{ item.name }}</span>
           </div>
         </template>
         <template #pic="{ item }">
@@ -31,21 +30,18 @@
           <div v-else></div>
         </template>
         <template #size="{ item }">
-          <div>
-            <span>{{ item.productLong }}cm</span>*
-            <span>{{ item.productWide }}cm</span>*
-            <span>{{ item.productHigh }}cm</span>
+          <div v-if="item['length'] && item.width && item.height">
+            <span>{{ item['length'] }}cm</span>*
+            <span>{{ item.width }}cm</span>*
+            <span>{{ item.height }}cm</span>
           </div>
+          <div v-else></div>
         </template>
         <template #price="{ item }">
-          <div>
-            <span v-if="item.price">{{ item.currency }} {{ item.price }}</span>
-          </div>
-        </template>
-        <template #costPrice="{ item }">
-          <div>
-            <span v-if="item.costPrice">{{ item.costCurrency }} {{ item.costPrice }}</span>
+          <div v-if="item.price">
+            <span>{{ item.currency }} {{ moneyFormat(item.price ,2)}}</span>
           </div>
+          <div v-else></div>
         </template>
       </byTable>
     </div>
@@ -60,7 +56,6 @@
           </template>
           <template #productionFile>
             <div style="width: 100%">
-              <!-- <a href="ftp://192.168.1.13/" target="_blank" style="color:#409eff">点击上传</a> -->
               <span style="color:#409eff;cursor:pointer" @click="handleClickUpload">点击上传</span>
             </div>
           </template>
@@ -69,25 +64,25 @@
               <span style="color:#409eff;cursor:pointer" @click="handleClickUpload">点击上传</span>
             </div>
           </template>
-          <template #productLong>
+          <template #size>
             <div style="width: 100%">
               <el-row>
                 <el-col :span="8">
-                  <el-form-item prop="productLong" label-width="0px" class="margin-b-0 wid100">
-                    <el-input-number v-model="formData.data.productLong" placeholder="请输入" style="width: 100%" :precision="2" :controls="false"
+                  <el-form-item prop="length" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data['length']" placeholder="长 (cm)" style="width: 100%" :precision="2" :controls="false"
                                      :min="0" onmousewheel="return false;" />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item prop="productWide" label-width="0px" class="margin-b-0 wid100">
-                    <el-input-number v-model="formData.data.productWide" placeholder="请输入" style="width: 100%" :precision="2" :controls="false"
-                                     :min="0" onmousewheel="return false;" />
+                  <el-form-item prop="width" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.width" placeholder="宽 (cm)" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item prop="productHigh" label-width="0px" class="margin-b-0 wid100">
-                    <el-input-number v-model="formData.data.productHigh" placeholder="请输入" style="width: 100%" :precision="2" :controls="false"
-                                     :min="0" onmousewheel="return false;" />
+                  <el-form-item prop="height" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.height" placeholder="高 (cm)" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
                   </el-form-item>
                 </el-col>
               </el-row>
@@ -101,11 +96,57 @@
       </template>
     </el-dialog>
 
-    <el-dialog title="导入产品" v-model="openExcelDialog" width="400" v-loading="excelLoading">
-      <el-upload :action="actionUrl + '/productInfo/excelImportByEhsd'" :headers="headers" :on-success="handleSuccess" :on-progress="handleProgress"
-                 :show-file-list="false" :on-error="handleError" accept=".xlsx">
-        <el-button type="primary">点击导入</el-button>
-      </el-upload>
+    <el-dialog :title="'BOM 配置'" v-model="bomDialog" width="60%" destroy-on-close>
+      <!-- <div class="public_height_dialog"> -->
+      <byForm :formConfig="bomFormConfig" :formOption="bomFormOption" v-model="formData.bomData" :rules="bomRules" ref="bomFormDom"
+              v-loading="submitLoading">
+        <template #accessories>
+          <div style="width: 100%">
+            <el-button type="primary" @click="openSelectMaterial = true" plain>选择</el-button>
+            <el-table :data="formData.bomData.data" style="width: 100%; margin-top: 16px">
+              <el-table-column prop="productCnName" label="物料名称" min-width="130" />
+              <el-table-column prop="productCnName" label="物料编码" width="130" />
+              <el-table-column label="数量" width="130">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item :prop="'contractProductList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true"
+                                  class="margin-b-0 wid100">
+                      <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入" style="width: 100%" :precision="0"
+                                       :controls="false" :min="1" />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="60" align="center" fixed="right">
+                <template #default="{ $index }">
+                  <el-button type="primary" link @click="handleRemove($index)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <!-- </div> -->
+      <template #footer>
+        <el-button @click="bomDialog = false" size="defualt" v-debounce>取 消</el-button>
+        <el-button type="primary" @click="submitBomForm()" size="defualt" v-debounce>确 定</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog :title="'物料选择'" v-model="openSelectMaterial" width="80%" destroy-on-close>
+      <SelectMaterial @selectMaterial="selectMaterial"></SelectMaterial>
+      <template #footer>
+        <el-button @click="bomDialog = false" size="defualt" v-debounce>取 消</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog title="导入产品" v-model="openExcelDialog" width="400">
+      <div v-loading="excelLoading">
+        <el-upload :action="actionUrl + '/productInfo/excelImportByEhsd'" :headers="headers" :on-success="handleSuccess" :on-progress="handleProgress"
+                   :show-file-list="false" :on-error="handleError" accept=".xlsx">
+          <el-button type="primary">点击导入</el-button>
+        </el-upload>
+      </div>
       <template #footer>
         <el-button @click="openExcelDialog = false" size="large">取 消</el-button>
       </template>
@@ -118,21 +159,18 @@
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
 import treeList from "@/components/product/treeList";
+import SelectMaterial from "@/components/product/SelectMaterial.vue";
+import { getToken } from "@/utils/auth";
 const { proxy } = getCurrentInstance();
 const actionUrl = import.meta.env.VITE_APP_BASE_API;
 const loading = ref(false);
 const submitLoading = ref(false);
+const treeData = ref([]);
 const treeListData = ref([]);
-const innerMethon = computed(
-  () => proxy.useUserStore().allDict["inner_packaging_method_ehsd"]
-);
-const outsideMethon = computed(
-  () => proxy.useUserStore().allDict["outside_packaging_method_ehsd"]
-);
-const productUnit = computed(() => proxy.useUserStore().allDict["unit"]);
 const currencyData = computed(
   () => proxy.useUserStore().allDict["account_currency"]
 );
+const headers = ref({ Authorization: "Bearer " + getToken() });
 const sourceList = ref({
   data: [],
   pagination: {
@@ -154,35 +192,15 @@ const rules = ref({
     { required: true, message: "请选择产品分类", trigger: "change" },
   ],
   name: [{ required: true, message: "请输入产品名称", trigger: "blur" }],
-  nameEnglish: [
-    { required: true, message: "请输入产品英文名", trigger: "blur" },
-  ],
-  productLong: [
-    { required: true, message: "请输入长 (cm)", trigger: "blur" },
-  ],
-  productWide: [
-    { required: true, message: "请输入宽 (cm)", trigger: "blur" },
-  ],
-  productHigh: [
-    { required: true, message: "请输入高 (cm)", trigger: "blur" },
-  ],
-  innerPackMethod: [
-    { required: true, message: "请选择内包装方式", trigger: "change" },
-  ],
-  outerPackMethod: [
-    { required: true, message: "请选择外包装方式", trigger: "change" },
-  ],
+  customCode: [{ required: true, message: "请输入产品编号", trigger: "blur" }],
+  length: [{ required: true, message: "请输入长 (cm)", trigger: "blur" }],
+  width: [{ required: true, message: "请输入宽 (cm)", trigger: "blur" }],
+  height: [{ required: true, message: "请输入高 (cm)", trigger: "blur" }],
 });
 const props = defineProps({
   selectStatus: Boolean,
 });
-const selectConfig = reactive([
-  // {
-  //   label: "产品类型",
-  //   prop: "type",
-  //   data: [],
-  // },
-]);
+const selectConfig = computed(() => []);
 const config = computed(() => {
   return [
     {
@@ -190,111 +208,171 @@ const config = computed(() => {
         label: "图片",
         slot: "pic",
         align: "center",
-        width: 100,
+        width: 80,
+      },
+    },
+    {
+      attrs: {
+        label: "产品分类",
+        prop: "classifyName",
+        "min-width": 150,
       },
     },
     {
       attrs: {
         label: "产品编码",
         prop: "customCode",
+        width: 120,
       },
     },
     {
       attrs: {
         label: "产品名称",
         slot: "name",
+        "min-width": 150,
+      },
+    },
+    {
+      attrs: {
+        label: "产品英文名",
+        prop: "nameEnglish",
+        "min-width": 120,
+      },
+    },
+    {
+      attrs: {
+        label: "产品规格",
+        prop: "spec",
+        width: 120,
       },
     },
-
     {
       attrs: {
         label: "尺寸",
         slot: "size",
+        width: 150,
       },
     },
     {
       attrs: {
-        label: "销售指导价",
+        label: "净重",
+        prop: "netWeight",
+        width: 100,
+      },
+      render(val) {
+        if (val) {
+          return val + " kg";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "销售价",
         slot: "price",
         width: 100,
       },
     },
-
+    {
+      attrs: {
+        label: "海关编码",
+        prop: "hsCode",
+        width: 100,
+      },
+    },
+    {
+      attrs: {
+        label: "原材料",
+        prop: "hsCode",
+        width: 100,
+      },
+    },
+    {
+      attrs: {
+        label: "原材料编码",
+        prop: "hsCode",
+        width: 100,
+      },
+    },
     {
       attrs: {
         label: "操作",
-        width: "120",
+        width: "160",
         align: "center",
+        fixed: "right",
       },
-      // 渲染 el-button,一般用在最后一列。
       renderHTML(row) {
         return [
-          props.selectStatus
-            ? {
-                attrs: {
-                  label: "选择",
-                  type: "primary",
-                  text: true,
-                },
-                el: "button",
-                click() {
-                  clickSelect(row);
-                },
-              }
-            : {
-                attrs: {
-                  label: "修改",
-                  type: "primary",
-                  text: true,
-                },
-                el: "button",
-                click() {
-                  getDtl(row);
-                },
-              },
-          props.selectStatus
-            ? {}
-            : {
-                attrs: {
-                  label: "删除",
-                  type: "danger",
-                  text: true,
-                },
-                el: "button",
-                click() {
+          //  {
+          //     attrs: {
+          //       label: "选择",
+          //       type: "primary",
+          //       text: true,
+          //     },
+          //     el: "button",
+          //     click() {
+          //       clickSelect(row);
+          //     },
+          //   }
+          {
+            attrs: {
+              label: "BOM",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              bomSetting(row);
+            },
+          },
+          {
+            attrs: {
+              label: "修改",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              proxy
+                .msgConfirm()
+                .then((res) => {
                   proxy
-                    .msgConfirm()
-                    .then((res) => {
-                      proxy
-                        .post("/productInfo/delete", {
-                          id: row.id,
-                        })
-                        .then((res) => {
-                          proxy.msgTip("删除成功", 1);
-                          getList();
-                        });
+                    .post("/productInfo/delete", {
+                      id: row.id,
                     })
-                    .catch((err) => {});
-                },
-              },
+                    .then((res) => {
+                      proxy.msgTip("删除成功", 1);
+                      getList();
+                    });
+                })
+                .catch((err) => {});
+            },
+          },
         ];
       },
     },
   ];
 });
 
-const uploadData = ref({});
-const fileList = ref([]);
-const fileListCopy = ref([]);
 const formData = reactive({
   data: {},
+  bomData: {},
 });
 const formOption = reactive({
   disabled: false,
   inline: true,
   labelWidth: 100,
   itemWidth: 100,
-  rules: [],
 });
 const formDom = ref(null);
 const formConfig = computed(() => {
@@ -307,7 +385,7 @@ const formConfig = computed(() => {
       type: "treeSelect",
       prop: "productClassifyId",
       label: "产品分类",
-      data: treeListData.value,
+      data: treeData.value,
       itemWidth: 100,
       disabled: false,
     },
@@ -332,10 +410,12 @@ const formConfig = computed(() => {
       disabled: false,
     },
     {
-      type: "upload",
-      listType: "picture-card",
-      accept: ".gif, .jpeg, .jpg, .png",
+      type: "uploadImg",
+      // listType: "picture-card",
+      // limit: 1,
+      // accept: ".gif, .jpeg, .jpg, .png",
       prop: "fileList",
+      imgProp: "imageUrl",
       label: "产品缩略图",
     },
     {
@@ -352,7 +432,7 @@ const formConfig = computed(() => {
     },
     {
       type: "title1",
-      title: "价格信息",
+      title: "属性信息",
     },
     {
       type: "selectInput",
@@ -364,34 +444,14 @@ const formConfig = computed(() => {
       data: currencyData.value,
     },
     {
-      type: "title1",
-      title: "工艺",
-    },
-    {
       type: "select",
-      prop: "sss",
-      label: "工艺选择",
+      prop: "technologyId",
+      label: "生产工艺",
       itemWidth: 50,
       data: [],
       filterable: true,
-      // placeholder: "",
       disabled: false,
     },
-    // {
-    //   type: "selectInput",
-    //   prop: "costPrice",
-    //   selectProp: "costCurrency",
-    //   label: "成本价",
-    //   itemWidth: 50,
-    //   style: {
-    //     width: "100%",
-    //   },
-    //   data: currencyData.value,
-    // },
-    {
-      type: "title1",
-      title: "属性信息",
-    },
     {
       type: "input",
       prop: "spec",
@@ -401,8 +461,8 @@ const formConfig = computed(() => {
     },
     {
       type: "slot",
-      slotName: "productLong",
-      prop: "productLong",
+      slotName: "size",
+      prop: "size",
       label: "尺寸",
       itemWidth: 50,
       disabled: false,
@@ -466,46 +526,46 @@ const formConfig = computed(() => {
 const getList = (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy
-    .post("/productInfo/getConditionProductList", sourceList.value.pagination)
-    .then(
-      (res) => {
-        sourceList.value.data = res.rows.map((x) => ({
-          ...x,
-          fileList: [],
-        }));
-        sourceList.value.pagination.total = res.total;
-        setTimeout(() => {
-          loading.value = false;
-        }, 200);
-        let productIdList = res.rows.map((x) => x.id);
-        // 请求文件数据并回显
-        if (productIdList.length > 0) {
-          proxy
-            .post("/fileInfo/getList", {
-              businessIdList: productIdList,
-            })
-            .then((fileObj) => {
-              for (let i = 0; i < sourceList.value.data.length; i++) {
-                let e = sourceList.value.data[i];
-                for (let key in fileObj) {
-                  if (e.id === key) {
-                    e.fileList = fileObj[key];
-                  }
+  proxy.post("/productInfo/page", sourceList.value.pagination).then(
+    (res) => {
+      sourceList.value.data = res.rows.map((x) => ({
+        ...x,
+        fileList: [],
+      }));
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+      let productIdList = res.rows.map((x) => x.id);
+      // 请求文件数据并回显
+      if (productIdList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: productIdList,
+          })
+          .then((fileObj) => {
+            for (let i = 0; i < sourceList.value.data.length; i++) {
+              let e = sourceList.value.data[i];
+              for (let key in fileObj) {
+                if (e.id == key) {
+                  e.fileList = fileObj[key];
                 }
               }
-            });
-        }
-      },
-      (err) => {
-        loading.value = false;
+            }
+          });
       }
-    );
+    },
+    (err) => {
+      loading.value = false;
+    }
+  );
 };
 
 const treeChange = (e) => {
-  sourceList.value.pagination.productClassifyId = e.id;
-  getList({ productClassifyId: e.id });
+  if (e.id != undefined) {
+    sourceList.value.pagination.productClassifyId = e.id;
+    getList({ productClassifyId: e.id });
+  }
 };
 
 const openModal = () => {
@@ -515,11 +575,9 @@ const openModal = () => {
     definition: "1",
     fileList: [],
     currency: "",
-    costCurrency: "",
   };
   if (currencyData.value && currencyData.value.length > 0) {
     formData.data.currency = currencyData.value[0].dictKey;
-    formData.data.costCurrency = currencyData.value[0].dictKey;
   }
 };
 
@@ -538,7 +596,7 @@ const submitForm = () => {
     //   fileUrl: x.fileUrl,
     // }));
     submitLoading.value = true;
-    proxy.post(`/productInfo/${modalType.value}ByEhsd`, formData.data).then(
+    proxy.post("/productInfo/" + modalType.value, formData.data).then(
       (res) => {
         proxy.msgTip("操作成功", 1);
         dialogVisible.value = false;
@@ -555,43 +613,98 @@ const getTreeList = () => {
   proxy
     .post("/productClassify/tree", { parentId: "", name: "", definition: "1" })
     .then((message) => {
-      treeListData.value = message;
+      treeListData.value = [
+        {
+          id: "",
+          label: "全部",
+          parentId: "",
+          children: message,
+        },
+      ];
+      treeData.value = message;
     });
 };
 const getDtl = (row) => {
   modalType.value = "edit";
-  proxy.post("/productInfo/detailByEhsd", { id: row.id }).then((res) => {
-    res.definition = "1";
+  proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
     formData.data = res;
+    formData.data.fileList = row.fileList.map((x) => ({
+      ...x,
+      url: x.fileUrl,
+      name: x.fileName,
+    }));
+    if (formData.data.fileList.length > 0) {
+      formData.data.imageUrl = formData.data.fileList[0].fileUrl;
+    }
     dialogVisible.value = true;
-    proxy
-      .post("/fileInfo/getList", { businessIdList: [row.id] })
-      .then((fileObj) => {
-        if (fileObj[row.id]) {
-          formData.data.fileList = fileObj[row.id].map((x) => ({
-            ...x,
-            url: x.fileUrl,
-            name: x.fileName,
-          }));
-        } else {
-          formData.data.fileList = [];
-        }
-      });
   });
 };
-
-// watch(modalType, (val) => {
-//   if (val) {
-//     for (let i = 0; i < formConfig.value.length; i++) {
-//       const element = formConfig.value[i];
-//       if (element.type != "title" || element.type != "slot") {
-//         if (!isdisabled.includes(element.prop)) {
-//           element.disabled = val == "edit" ? true : false;
-//         }
-//       }
-//     }
-//   }
-// });
+const bomDialog = ref(false);
+const bomFormDom = ref(null);
+const bomFormOption = reactive({
+  disabled: false,
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+});
+const bomFormConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "technologyId",
+      label: "原材料",
+      itemWidth: 100,
+      data: [],
+      filterable: true,
+      disabled: false,
+    },
+    {
+      type: "slot",
+      slotName: "accessories",
+      label: "包材辅料",
+      itemWidth: 100,
+    },
+  ];
+});
+const bomRules = ref({
+  technologyId: [
+    { required: true, message: "请选择原材料", trigger: "change" },
+  ],
+});
+const bomSetting = () => {
+  formData.bomData = {
+    data: [],
+  };
+  bomDialog.value = true;
+};
+const submitBomForm = () => {
+  bomFormDom.value.handleSubmit((valid) => {
+    if (!formData.bomData.data.length > 0) {
+      return proxy.msgTip("请选择包材辅料", 2);
+    }
+    submitLoading.value = true;
+    proxy.post("/productInfo/", formData.bomData).then(
+      (res) => {
+        proxy.msgTip("操作成功", 1);
+        bomDialog.value = false;
+        submitLoading.value = false;
+      },
+      (err) => {
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+const openSelectMaterial = ref(false);
+const selectMaterial = (row) => {
+  formData.bomData.data.push({
+    ...row,
+  });
+  proxy.msgTip("选择成功");
+};
+const handleRemove = (index) => {
+  formData.bomData.data.splice(index, 1);
+};
 
 const handleClickFile = (file) => {
   window.open(file.fileUrl, "_blank");
@@ -600,57 +713,25 @@ const handleProgress = () => {
   excelLoading.value = true;
 };
 const handleError = (err) => {
-  ElMessage({
-    message: `${err},请重试!`,
-    type: "info",
-  });
+  proxy.msgTip(`${err},请重试`, 2);
   openExcelDialog.value = false;
   excelLoading.value = false;
 };
 const handleSuccess = (res) => {
   if (res.code != 200) {
-    return ElMessage({
-      message: `${res.msg},请重试!`,
-      type: "info",
-    });
+    return proxy.msgTip(`${err},请重试`, 2);
   } else {
-    ElMessage({
-      message: "导入成功!",
-      type: "success",
-    });
+    proxy.msgTip(`导入成功`, 1);
     openExcelDialog.value = false;
     excelLoading.value = false;
     getList();
   }
 };
 
-getTreeList();
-getList();
 const clickSelect = (item) => {
   proxy.$emit("selectProduct", item);
 };
 
-const handleKeypress = (event) => {
-  // 判断输入字符是否为中文字符
-  if (event.key.match(/[\u4e00-\u9fa5]/)) {
-    // 阻止输入
-    event.preventDefault();
-  }
-};
-const handleKeyup = (val) => {
-  // 过滤掉中文字符
-  formData.data.nameEnglish = formData.data.nameEnglish.replace(
-    /[\u4e00-\u9fa5]/g,
-    ""
-  );
-};
-
-const handlePreview = (file) => {
-  if (file && file.fileUrl) {
-    window.open(file.fileUrl, "_black");
-  }
-};
-
 const handleClickUpload = () => {
   let a = document.createElement("a");
   a.href = "printer://" + "ftp://192.168.1.13/123/";
@@ -659,6 +740,9 @@ const handleClickUpload = () => {
   a.click();
   document.body.removeChild(a);
 };
+
+getTreeList();
+getList();
 </script>
 
 <style lang="scss" scoped>

+ 70 - 56
src/views/finance/fundManage/account/index.vue

@@ -1,31 +1,25 @@
 <template>
   <div class="tenant">
     <div class="content">
-      <byTable
-        :source="sourceList.data"
-        :pagination="sourceList.pagination"
-        :config="config"
-        :loading="loading"
-        highlight-current-row
-        :action-list="[
+      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row :action-list="[
           {
             text: '添加账户',
             action: () => openModal('add'),
           },
-        ]"
-        @get-list="getList">
+        ]" @get-list="getList">
       </byTable>
     </div>
 
-    <el-dialog :title="modalType == 'add' ? '添加账户' : '编辑账户'" v-if="dialogVisible" v-model="dialogVisible" width="600" v-loading="loadingDialog">
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+    <el-dialog :title="modalType == 'add' ? '添加账户' : '编辑账户'" v-if="dialogVisible" v-model="dialogVisible" width="60%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit" v-loading="loadingDialog">
         <template #balance>
           <div style="width: 100%">
             <el-button type="primary" @click="clickBalance">添加</el-button>
             <el-table :data="formData.data.accountRemainderList" style="width: 100%; margin-top: 16px">
               <el-table-column label="币种">
                 <template #default="{ row, $index }">
-                  <el-form-item :prop="'accountRemainderList.' + $index + '.currency'" :rules="rules.currency" :inline-message="true">
+                  <el-form-item :prop="'accountRemainderList.' + $index + '.currency'" :rules="rules.currency" :inline-message="true"
+                                class="margin-b-0 wid100">
                     <el-select v-model="row.currency" placeholder="请选择币种" style="width: 100%" :disabled="row.id">
                       <el-option v-for="item in accountCurrency" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" />
                     </el-select>
@@ -34,16 +28,10 @@
               </el-table-column>
               <el-table-column label="余额">
                 <template #default="{ row, $index }">
-                  <el-form-item :prop="'accountRemainderList.' + $index + '.remainder'" :rules="rules.remainder" :inline-message="true">
-                    <el-input-number
-                      onmousewheel="return false;"
-                      v-model="row.remainder"
-                      placeholder="请输入余额"
-                      style="width: 100%"
-                      :precision="2"
-                      :controls="false"
-                      :min="0"
-                      :disabled="row.id" />
+                  <el-form-item :prop="'accountRemainderList.' + $index + '.remainder'" :rules="rules.remainder" :inline-message="true"
+                                class="margin-b-0 wid100">
+                    <el-input-number onmousewheel="return false;" v-model="row.remainder" placeholder="请输入余额" style="width: 100%" :precision="2"
+                                     :controls="false" :min="0" :disabled="row.id" />
                   </el-form-item>
                 </template>
               </el-table-column>
@@ -148,11 +136,15 @@ const config = computed(() => {
             },
             el: "button",
             click() {
-              ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-              }).then(() => {
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
                 proxy
                   .post("/accountManagement/delete", {
                     id: row.id,
@@ -186,26 +178,30 @@ const getDict = () => {
         accountCurrency.value = res.rows;
       }
     });
-  proxy.post("/corporation/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
-    corporationList.value = res.rows.map((item) => {
-      return {
-        ...item,
-        label: item.name,
-        value: item.id,
-      };
+  proxy
+    .post("/corporation/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      corporationList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
     });
-  });
 };
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy.post("/accountManagement/page", sourceList.value.pagination).then((res) => {
-    sourceList.value.data = res.rows;
-    sourceList.value.pagination.total = res.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
-  });
+  proxy
+    .post("/accountManagement/page", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
 };
 getDict();
 getList();
@@ -215,16 +211,15 @@ const loadingDialog = ref(false);
 const submit = ref(null);
 const formOption = reactive({
   inline: true,
-  labelWidth: 100,
+  labelWidth: 190,
   itemWidth: 100,
   rules: [],
 });
 const formConfig = computed(() => {
   return [
     {
-      type: "title",
+      type: "title1",
       title: "基本信息",
-      label: "",
     },
     {
       type: "select",
@@ -237,7 +232,7 @@ const formConfig = computed(() => {
       prop: "alias",
       label: "账户别名",
       required: true,
-      itemWidth: 100,
+      itemWidth: 50,
       itemType: "text",
     },
     {
@@ -245,7 +240,7 @@ const formConfig = computed(() => {
       prop: "openingBank",
       label: "开户银行",
       required: true,
-      itemWidth: 100,
+      itemWidth: 50,
       itemType: "text",
     },
     {
@@ -253,7 +248,7 @@ const formConfig = computed(() => {
       prop: "name",
       label: "账户名",
       required: true,
-      itemWidth: 100,
+      itemWidth: 50,
       itemType: "text",
     },
     {
@@ -261,7 +256,7 @@ const formConfig = computed(() => {
       prop: "accountOpening",
       label: "账号",
       required: true,
-      itemWidth: 100,
+      itemWidth: 50,
       itemType: "text",
     },
     {
@@ -269,13 +264,12 @@ const formConfig = computed(() => {
       prop: "interbankNumber",
       label: "联行号",
       required: true,
-      itemWidth: 100,
+      itemWidth: 50,
       itemType: "text",
     },
     {
-      type: "title",
+      type: "title1",
       title: "外汇信息",
-      label: "",
     },
     {
       type: "input",
@@ -283,6 +277,7 @@ const formConfig = computed(() => {
       label: "Beneficiary Name",
       required: true,
       itemType: "text",
+      itemWidth: 50,
     },
     {
       type: "input",
@@ -290,6 +285,7 @@ const formConfig = computed(() => {
       label: "Beneficiary Bank",
       required: true,
       itemType: "text",
+      itemWidth: 50,
     },
     {
       type: "input",
@@ -297,6 +293,7 @@ const formConfig = computed(() => {
       label: "Beneficiary Bank Address",
       required: true,
       itemType: "text",
+      itemWidth: 50,
     },
     {
       type: "input",
@@ -304,6 +301,7 @@ const formConfig = computed(() => {
       label: "Beneficiary Account Number",
       required: true,
       itemType: "text",
+      itemWidth: 50,
     },
     {
       type: "input",
@@ -311,6 +309,7 @@ const formConfig = computed(() => {
       label: "Swift Code",
       required: true,
       itemType: "text",
+      itemWidth: 50,
     },
     {
       type: "input",
@@ -318,6 +317,11 @@ const formConfig = computed(() => {
       label: "Beneficiary Address",
       required: true,
       itemType: "text",
+      itemWidth: 50,
+    },
+    {
+      type: "title1",
+      title: "账户余额",
     },
     {
       type: "slot",
@@ -333,7 +337,9 @@ const rules = ref({
   accountOpening: [{ required: true, message: "请输入账号", trigger: "blur" }],
   currency: [{ required: true, message: "请选择币种", trigger: "change" }],
   remainder: [{ required: true, message: "请输入账户余额", trigger: "blur" }],
-  corporationId: [{ required: true, message: "请选择归属公司", trigger: "change" }],
+  corporationId: [
+    { required: true, message: "请选择归属公司", trigger: "change" },
+  ],
 });
 const formData = reactive({
   data: {
@@ -349,13 +355,18 @@ const openModal = (val) => {
   dialogVisible.value = true;
 };
 const clickBalance = () => {
-  if (formData.data.accountRemainderList && formData.data.accountRemainderList.length > 0) {
+  if (
+    formData.data.accountRemainderList &&
+    formData.data.accountRemainderList.length > 0
+  ) {
     formData.data.accountRemainderList.push({
       currency: "",
       remainder: undefined,
     });
   } else {
-    formData.data.accountRemainderList = [{ currency: "", remainder: undefined }];
+    formData.data.accountRemainderList = [
+      { currency: "", remainder: undefined },
+    ];
   }
 };
 const handleRemove = (index) => {
@@ -371,7 +382,10 @@ const isRepeat = (arr) => {
 };
 const submitForm = () => {
   submit.value.handleSubmit(() => {
-    if (formData.data.accountRemainderList && formData.data.accountRemainderList.length > 0) {
+    if (
+      formData.data.accountRemainderList &&
+      formData.data.accountRemainderList.length > 0
+    ) {
       if (isRepeat(formData.data.accountRemainderList)) {
         return ElMessage("请勿重复添加货币余额");
       } else {

+ 188 - 197
src/views/product/material/index.vue

@@ -7,19 +7,8 @@
     </div>
     <div class="content">
       <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
-               :selectConfig="selectConfig" :table-events="{
-     
-        }" :action-list="[
-          props.selectStatus
-            ? {}
-            : {
-                text: 'Excel导入',
-                action: () => openExcel(),
-                disabled: false,
-              },
-          props.selectStatus
-            ? {}
-            : {
+               :selectConfig="selectConfig" :action-list="[
+              {
                 text: '添加物料',
                 action: () => openModal('add'),
                 disabled: false,
@@ -31,30 +20,55 @@
           </div>
           <div v-else></div>
         </template>
+        <template #name="{ item }">
+          <div>
+            <span class="el-click">{{ item.name }}</span>
+          </div>
+        </template>
+        <template #size="{ item }">
+          <div v-if="item['length'] && item.width && item.height">
+            <span>{{ item['length'] }}cm</span>*
+            <span>{{ item.width }}cm</span>*
+            <span>{{ item.height }}cm</span>
+          </div>
+          <div v-else></div>
+        </template>
+        <template #price="{ item }">
+          <div v-if="item.price">
+            <span>{{ item.currency }} {{ moneyFormat(item.price ,2)}}</span>
+          </div>
+          <div v-else></div>
+        </template>
+        <template #costPrice="{ item }">
+          <div v-if="item.costPrice">
+            <span>{{ item.currency }} {{ moneyFormat(item.costPrice ,2)}}</span>
+          </div>
+          <div v-else></div>
+        </template>
       </byTable>
     </div>
     <el-dialog :title="modalType == 'add' ? '添加物料' : '编辑物料'" v-model="dialogVisible" width="80%" destroy-on-close>
       <div class="public_height_dialog">
         <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
-          <template #productLong>
+          <template #size>
             <div style="width: 100%">
               <el-row>
                 <el-col :span="8">
-                  <el-form-item prop="productLong" label-width="0px" class="margin-b-0 wid100">
-                    <el-input-number v-model="formData.data.productLong" placeholder="请输入" style="width: 100%" :precision="2" :controls="false"
-                                     :min="0" onmousewheel="return false;" />
+                  <el-form-item prop="length" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.length" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item prop="productWide" label-width="0px" class="margin-b-0 wid100">
-                    <el-input-number v-model="formData.data.productWide" placeholder="请输入" style="width: 100%" :precision="2" :controls="false"
-                                     :min="0" onmousewheel="return false;" />
+                  <el-form-item prop="width" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.width" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
                   </el-form-item>
                 </el-col>
                 <el-col :span="8">
-                  <el-form-item prop="productHigh" label-width="0px" class="margin-b-0 wid100">
-                    <el-input-number v-model="formData.data.productHigh" placeholder="请输入" style="width: 100%" :precision="2" :controls="false"
-                                     :min="0" onmousewheel="return false;" />
+                  <el-form-item prop="height" label-width="0px" class="margin-b-0 wid100">
+                    <el-input-number v-model="formData.data.height" placeholder="请输入" style="width: 100%" :precision="2" :controls="false" :min="0"
+                                     onmousewheel="return false;" />
                   </el-form-item>
                 </el-col>
               </el-row>
@@ -70,14 +84,6 @@
         </el-button>
       </template>
     </el-dialog>
-    <el-dialog title="Excel导入" v-model="openExcelDialog" width="400" v-loading="loading">
-      <template #footer>
-        <el-button @click="openExcelDialog = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitExcel()" size="large" :loading="submitLoading">
-          确 定
-        </el-button>
-      </template>
-    </el-dialog>
   </div>
 </template>
 
@@ -89,6 +95,18 @@ const { proxy } = getCurrentInstance();
 const currencyData = computed(
   () => proxy.useUserStore().allDict["account_currency"]
 );
+const materialUnitData = computed(
+  () => proxy.useUserStore().allDict["material_unit"]
+);
+const colorLayerData = computed(
+  () => proxy.useUserStore().allDict["color_layer"]
+);
+const backLinesData = computed(
+  () => proxy.useUserStore().allDict["back_lines"]
+);
+const frontLinesData = computed(
+  () => proxy.useUserStore().allDict["front_lines"]
+);
 const loading = ref(false);
 const submitLoading = ref(false);
 const sourceList = ref({
@@ -104,20 +122,15 @@ const sourceList = ref({
   },
 });
 const dialogVisible = ref(false);
-const openExcelDialog = ref(false);
 const modalType = ref("add");
-const materialUnit = ref([]);
-const materialType = ref([]);
 const treeData = ref([]);
 const rules = ref({
   productClassifyId: [
     { required: true, message: "请选择物料分类", trigger: "change" },
   ],
-  type: [{ required: true, message: "请选择物料类型", trigger: "change" }],
   name: [{ required: true, message: "请输入物料名称", trigger: "blur" }],
-  unit: [{ required: true, message: "请选择单位", trigger: "change" }],
+  customCode: [{ required: true, message: "请输入物料编码", trigger: "blur" }],
 });
-
 const props = defineProps({
   selectStatus: Boolean,
 });
@@ -126,55 +139,93 @@ const config = computed(() => {
   return [
     {
       attrs: {
-        label: "物料类型",
-        prop: "type",
+        label: "图片",
+        slot: "pic",
+        align: "center",
+        width: 80,
       },
-      render(type) {
-        return proxy.dictValueLabel(type, materialType.value);
+    },
+    {
+      attrs: {
+        label: "物料分类",
+        prop: "classifyName",
+        "min-width": 150,
       },
     },
     {
       attrs: {
         label: "物料编码",
-        prop: "code",
+        prop: "customCode",
+        width: 120,
       },
     },
     {
       attrs: {
-        label: "图片",
-        prop: "unit",
-        slot: "pic",
+        label: " 物料名称",
+        slot: "name",
+        "min-width": 150,
       },
     },
     {
       attrs: {
-        label: "物料名称",
-        prop: "name",
+        label: "物料材质",
+        prop: "material",
+        width: 120,
       },
     },
     {
       attrs: {
-        label: "规格型号",
+        label: "物料型号",
         prop: "spec",
+        width: 120,
       },
     },
     {
       attrs: {
         label: "单位",
         prop: "unit",
+        width: 80,
       },
-      render(unit) {
-        return proxy.dictValueLabel(unit, materialUnit.value);
+      render(val) {
+        return proxy.dictKeyValue(val, materialUnitData.value);
       },
     },
     {
       attrs: {
-        label: "物料备注",
-        prop: "remark",
+        label: "尺寸",
+        slot: "size",
+        width: 150,
       },
     },
     {
       attrs: {
+        label: "净重",
+        prop: "netWeight",
+        width: 100,
+      },
+      render(val) {
+        if (val) {
+          return val + " kg";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "成本价",
+        slot: "costPrice",
+        width: 100,
+      },
+    },
+    {
+      attrs: {
+        label: "销售价",
+        slot: "price",
+        width: 100,
+      },
+    },
+
+    {
+      attrs: {
         label: "操作",
         width: "160",
         align: "center",
@@ -248,7 +299,6 @@ const config = computed(() => {
     },
   ];
 });
-
 const formData = reactive({
   data: {},
 });
@@ -256,7 +306,6 @@ const formOption = reactive({
   inline: true,
   labelWidth: 100,
   itemWidth: 100,
-  rules: [],
 });
 const formDom = ref(null);
 const treeListData = ref([]);
@@ -283,15 +332,17 @@ const formConfig = computed(() => {
     },
     {
       type: "input",
-      prop: "name",
+      prop: "customCode",
       label: "物料编码",
       itemWidth: 50,
       disabled: false,
     },
     {
-      type: "upload",
-      listType: "picture-card",
-      accept: ".gif, .jpeg, .jpg, .png",
+      type: "uploadImg",
+      // limit: 1,
+      // listType: "picture-card",
+      // accept: ".gif, .jpeg, .jpg, .png",
+      imgProp: "imageUrl",
       prop: "fileList",
       label: "物料缩略图",
     },
@@ -301,46 +352,42 @@ const formConfig = computed(() => {
     },
     {
       type: "input",
-      prop: "spec",
+      prop: "material",
       label: "材质",
       itemWidth: 50,
     },
     {
       type: "input",
-      prop: "barCode",
+      prop: "spec",
       label: "型号",
       itemWidth: 50,
     },
     {
       type: "select",
-      prop: "unit",
+      prop: "frontalTexture",
       label: "正面纹路",
-      required: true,
-      data: materialUnit.value,
+      data: frontLinesData.value,
       itemWidth: 50,
     },
     {
       type: "select",
-      prop: "unit",
+      prop: "reverseTexture",
       label: "背面纹路",
-      required: true,
-      data: materialUnit.value,
+      data: backLinesData.value,
       itemWidth: 50,
     },
     {
       type: "select",
       prop: "unit",
       label: "单位",
-      required: true,
-      data: materialUnit.value,
+      data: materialUnitData.value,
       itemWidth: 50,
     },
     {
       type: "select",
-      prop: "unit",
+      prop: "colorLayer",
       label: "色层",
-      required: true,
-      data: materialUnit.value,
+      data: colorLayerData.value,
       itemWidth: 50,
     },
     // {
@@ -355,20 +402,23 @@ const formConfig = computed(() => {
     },
     {
       type: "input",
-      prop: "barCode",
+      prop: "color",
       label: "颜色",
       itemWidth: 50,
     },
     {
-      type: "input",
-      prop: "barCode",
+      type: "number",
+      prop: "stockThreshold",
       label: "安全库存",
+      precision: 2,
+      min: 0,
+      controls: false,
       itemWidth: 50,
     },
     {
       type: "selectInput",
-      prop: "price",
-      selectProp: "currency",
+      prop: "costPrice",
+      selectProp: "costCurrency",
       label: "成本价",
       itemWidth: 50,
       disabledSelect: true,
@@ -385,8 +435,8 @@ const formConfig = computed(() => {
     },
     {
       type: "slot",
-      slotName: "productLong",
-      prop: "productLong",
+      slotName: "size",
+      prop: "size",
       label: "尺寸",
       itemWidth: 50,
       disabled: false,
@@ -402,57 +452,41 @@ const formConfig = computed(() => {
     },
   ];
 });
-const newPassword = () => {
-  formData.data.password = generatePassword();
-};
-const generatePassword = () => {
-  var length = 12,
-    charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
-    password = "";
-  for (var i = 0, n = charset.length; i < length; ++i) {
-    password += charset.charAt(Math.floor(Math.random() * n));
-  }
-  return password;
-};
 
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy
-    .post("/productInfo/page", sourceList.value.pagination)
-    .then((message) => {
-      console.log(message);
-      sourceList.value.data = message.rows.map((x) => ({ ...x, fileList: [] }));
-      sourceList.value.pagination.total = message.total;
-      setTimeout(() => {
-        loading.value = false;
-      }, 200);
+  proxy.post("/productInfo/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows.map((x) => ({ ...x, fileList: [] }));
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
 
-      const productIdList = message.rows.map((x) => x.id);
-      // 请求文件数据并回显
-      if (productIdList.length > 0) {
-        proxy
-          .post("/fileInfo/getList", { businessIdList: productIdList })
-          .then((fileObj) => {
-            for (let i = 0; i < sourceList.value.data.length; i++) {
-              const e = sourceList.value.data[i];
-              for (const key in fileObj) {
-                if (e.id === key) {
-                  e.fileList = fileObj[key];
-                }
+    const productIdList = res.rows.map((x) => x.id);
+    // 请求文件数据并回显
+    if (productIdList.length > 0) {
+      proxy
+        .post("/fileInfo/getList", { businessIdList: productIdList })
+        .then((fileObj) => {
+          for (let i = 0; i < sourceList.value.data.length; i++) {
+            const e = sourceList.value.data[i];
+            for (const key in fileObj) {
+              if (e.id === key) {
+                e.fileList = fileObj[key];
               }
             }
-          });
-      }
-    });
+          }
+        });
+    }
+  });
 };
-const uploadData = ref({});
-const fileList = ref([]);
-const fileListCopy = ref([]);
 
 const treeChange = (e) => {
-  sourceList.value.pagination.productClassifyId = e.id;
-  getList({ productClassifyId: e.id });
+  if (e.id != undefined) {
+    sourceList.value.pagination.productClassifyId = e.id;
+    getList({ productClassifyId: e.id });
+  }
 };
 
 const openModal = () => {
@@ -461,28 +495,13 @@ const openModal = () => {
   formData.data = {
     definition: "2",
     fileList: [],
-    // type: "1",
   };
-  fileList.value = [];
-  fileListCopy.value = [];
-};
-
-const openExcel = () => {
-  openExcelDialog.value = true;
-};
-const submitExcel = () => {
-  openExcelDialog.value = false;
-};
-const TreetenantId = ref("");
-const selection = ref({
-  data: [],
-});
-const select = (_selection, row) => {
-  selection.value.data = _selection;
-  console.log(_selection.length);
+  if (currencyData.value && currencyData.value.length > 0) {
+    formData.data.currency = currencyData.value[0].dictKey;
+    formData.data.costCurrency = currencyData.value[0].dictKey;
+  }
 };
 
-const tree = ref(null);
 const submitForm = () => {
   formDom.value.handleSubmit((valid) => {
     if (!formData.data.fileList.length > 0) {
@@ -507,7 +526,14 @@ const getTreeList = () => {
   proxy
     .post("/productClassify/tree", { parentId: "", name: "", definition: "2" })
     .then((message) => {
-      treeListData.value = message;
+      treeListData.value = [
+        {
+          id: "",
+          label: "全部",
+          parentId: "",
+          children: message,
+        },
+      ];
       treeData.value = message;
     });
 };
@@ -515,74 +541,39 @@ const getTreeList = () => {
 const getDtl = (row) => {
   modalType.value = "edit";
   proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
-    fileList.value = row.fileList.map((x) => ({ ...x, url: x.fileUrl }));
-    fileListCopy.value = [...fileList.value];
-    res.type = res.type + "";
-    res.definition = "2";
-    formData.data = res;
-    dialogVisible.value = true;
-  });
-};
-
-const getDtlOne = (row) => {
-  modalType.value = "add";
-  proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
-    fileList.value = [];
-    fileListCopy.value = [];
-    res.type = res.type + "";
-    res.definition = "2";
-    delete res.id;
     formData.data = res;
+    formData.data.fileList = row.fileList.map((x) => ({
+      ...x,
+      url: x.fileUrl,
+      name: x.fileName,
+    }));
+    if (formData.data.fileList.length > 0) {
+      formData.data.imageUrl = formData.data.fileList[0].fileUrl;
+    }
     dialogVisible.value = true;
   });
 };
 
-getTreeList();
-getList();
-const handleBeforeUpload = async (file) => {
-  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
-  uploadData.value = res.uploadBody;
-  fileListCopy.value.push({
-    id: res.id,
-    fileName: res.fileName,
-    path: res.fileUrl,
-    url: res.fileUrl,
-    uid: file.uid,
-  });
-};
-
-const handleSuccess = (res, file, files) => {
-  // 查当前file的index值去赋值对应的copy变量的值
-  // let uid = file.uid;
-  // const index = fileList.value.findIndex((x) => x.uid === uid);
-  // fileListCopy.value[index].uid = uid;
-};
-
-const handleRemove = (file) => {
-  const index = fileListCopy.value.findIndex(
-    (x) => x.uid === file.uid || x.id === file.id
-  );
-  fileListCopy.value.splice(index, 1);
-};
+// const getDtlOne = (row) => {
+//   modalType.value = "add";
+//   proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
+//     fileList.value = [];
+//     fileListCopy.value = [];
+//     res.type = res.type + "";
+//     res.definition = "2";
+//     delete res.id;
+//     formData.data = res;
+//     dialogVisible.value = true;
+//   });
+// };
 
 const handleClickFile = (file) => {
   window.open(file.fileUrl, "_blank");
 };
 
-const getDict = () => {
-  proxy.getDictOne(["material_unit", "material_type"]).then((res) => {
-    materialUnit.value = res["material_unit"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-    materialType.value = res["material_type"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-    selectConfig[0].data = materialType.value;
-  });
-};
-getDict();
+getTreeList();
+getList();
+
 const clickSelect = (item) => {
   proxy.$emit("selectMaterial", item);
 };

+ 3 - 3
src/views/production/project/processConfig/handleBtn.vue

@@ -16,9 +16,9 @@ let title = ref("");
 let getNode = inject("getNode");
 const node = getNode();
 title.value = node.store.data.label;
-// node.on("change:data", ({ current }) => {
-//   title.value = current.label;
-// });
+node.on("change:data", ({ current }) => {
+  title.value = current.title;
+});
 </script>
 <style lang="scss">
 .handle-btn {

+ 108 - 8
src/views/production/project/processConfig/vueFlow.vue

@@ -5,6 +5,21 @@
     <div id="graph-container"></div>
     <div id="minimap"></div>
   </div>
+  <el-dialog title="节点信息配置" v-model="dialogVisible" width="500" v-if="dialogVisible">
+    <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" v-loading="loading" :rules="rules" ref="byform">
+    </byForm>
+    <template #footer>
+      <div>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button type="danger" @click="deleteFlowDefinitionNodeObj()" size="large">
+          删 除
+        </el-button>
+        <el-button type="primary" @click="submitForm" size="large">
+          确 定
+        </el-button>
+      </div>
+    </template>
+  </el-dialog>
 </template>
 <script lang="ts" setup>
 import {
@@ -52,6 +67,38 @@ defineProps({
   },
 });
 const { proxy } = getCurrentInstance();
+const flowNodeObj = ref({});
+const dialogVisible = ref(false);
+const loading = ref(false);
+const byform = ref(null);
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "nodeName",
+      label: "工序名称",
+      required: true,
+      itemType: "text",
+    },
+  ];
+});
+const rules = reactive({
+  nodeName: [
+    {
+      required: true,
+      message: "请输入工序名称",
+      trigger: "blur",
+    },
+  ],
+});
 const flowDefinitionNodeObj = ref({});
 let graph;
 const submitFormData = {
@@ -62,6 +109,32 @@ const submitFormData = {
   lineObject: "",
   flowDefinitionNodeList: [],
 };
+
+const deleteFlowDefinitionNodeObj = () => {
+  graph.removeNode(formData.data.id);
+  delete flowNodeObj.value[formData.data.id];
+  dialogVisible.value = false;
+  // let productionId = formData.data.cell.store.data.productionId;
+  // type 1为自定义工序 0为固定工序
+  // proxy.$emit("removeRow", { id: productionId });
+};
+
+const submitForm = () => {
+  byform.value.handleSubmit((valid) => {
+    console.log(formData.data.nodeName, "sada");
+
+    formData.data.cell.setData({
+      title: formData.data.nodeName,
+    });
+    flowNodeObj.value[formData.data.id].nodeName = formData.data.nodeName;
+    dialogVisible.value = false;
+    // let cell = formData.data.cell;
+    // let productionId = cell.store.data.productionId;
+    // let name = cell.store.data.data.title;
+    // proxy.$emit("changeName", { productionId, name });
+  });
+};
+
 const submitAll = () => {
   const nodeList = graph.toJSON().cells;
   submitFormData.nodeObject = JSON.stringify(nodeList);
@@ -150,6 +223,21 @@ const pushRoom = (port: any) => {
   //     parentId: null,
   //   };
   // }
+  if (port.node.shape == "handle-btn") {
+    let nodeName = "";
+    if (
+      port.node.store &&
+      port.node.store.data &&
+      port.node.store.data.data &&
+      port.node.store.data.data.title
+    ) {
+      nodeName = port.node.store.data.data.title;
+    }
+    flowNodeObj.value[port.node.id] = {
+      nodeName: nodeName,
+      id: port.node.id,
+    };
+  }
 };
 
 //用于存储流程定义节点数据
@@ -310,14 +398,26 @@ const antvInit = async (data) => {
       return;
     }
     if (cell.shape === "handle-btn" || cell.shape === "edge") {
-      ElMessageBox.confirm("是否删除", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      }).then(() => {
-        graph.removeNode(cell.id);
-      });
-      return;
+      // ElMessageBox.confirm("是否删除", "提示", {
+      //   confirmButtonText: "确定",
+      //   cancelButtonText: "取消",
+      //   type: "warning",
+      // }).then(() => {
+      //   graph.removeNode(cell.id);
+      // });
+      // return;
+      formData.data.id = cell.id;
+      formData.data.cell = cell;
+      console.log(cell, "sss");
+
+      if (cell.store.data.data) {
+        formData.data.nodeName = cell.store.data.data.title;
+      } else if (cell.store.data) {
+        formData.data.nodeName = cell.store.data.label;
+      } else {
+        formData.data.nodeName = "";
+      }
+      dialogVisible.value = true;
     }
   });
   // #region 初始化图形

+ 17 - 17
src/views/production/project/processes/index.vue

@@ -107,22 +107,22 @@ const config = computed(() => {
         prop: "remarks",
       },
     },
-    {
-      attrs: {
-        label: "工序文件",
-        prop: "fileName",
-        slot: "fileSlot",
-      },
-      // render(fileName) {
-      //   return <div>fileName</div>;
-      // },
-    },
+    // {
+    //   attrs: {
+    //     label: "工序文件",
+    //     prop: "fileName",
+    //     slot: "fileSlot",
+    //   },
+    //   // render(fileName) {
+    //   //   return <div>fileName</div>;
+    //   // },
+    // },
 
     {
       attrs: {
         label: "操作",
-        width: "200",
-        align: "right",
+        width: "120",
+        align: "center",
       },
       // 渲染 el-button,一般用在最后一列。
       renderHTML(row) {
@@ -203,11 +203,11 @@ const formConfig = computed(() => {
       label: "工序说明",
       itemType: "textarea",
     },
-    {
-      type: "slot",
-      slotName: "slot",
-      label: "上传附件",
-    },
+    // {
+    //   type: "slot",
+    //   slotName: "slot",
+    //   label: "上传附件",
+    // },
   ];
 });
 const getList = async (req) => {

+ 40 - 12
src/views/production/project/technology/index.vue

@@ -8,7 +8,7 @@
           select: select,
         }" :action-list="[
           {
-            text: '添加工艺',
+            text: '添加产线',
             action: () => openModal('add'),
           },
         ]" @get-list="getList">
@@ -33,7 +33,7 @@
         </template>
       </byTable>
     </div>
-    <el-dialog :title="modalType == 'add' ? '添加工艺' : '编辑工艺'" v-model="dialogVisible" width="90%" destroy-on-close>
+    <el-dialog :title="modalType == 'add' ? '添加产线' : '编辑产线'" v-model="dialogVisible" width="90%" destroy-on-close>
       <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform" v-loading="submitLoading">
         <!-- <template #lineSlot>
           <el-transfer v-model="selectLine" filterable filter-placeholder="搜索" :data="lineData" :titles="['可选', '已选']" target-order="push">
@@ -59,7 +59,7 @@
               </div> -->
             </div>
             <div class="content">
-              <div class="commons-title">工艺路线</div>
+              <div class="commons-title">产线路线</div>
               <div class="chart-warp">
                 <vueFlow :nodeObject="nodeObject" ref="vueFlowDom"></vueFlow>
               </div>
@@ -86,7 +86,7 @@
       </template>
     </el-dialog>
 
-    <el-dialog :title=" '工艺适用产品'" v-model="dialogVisibleOne" width="50%" destroy-on-close>
+    <el-dialog :title=" '产线适用产品'" v-model="dialogVisibleOne" width="50%" destroy-on-close>
       <byForm :formConfig="formConfigOne" :formOption="formOption" v-model="formData.dataOne" ref="byformOne" v-loading="submitLoading">
         <template #productSlot>
           <div>
@@ -158,7 +158,7 @@ let dialogVisible = ref(false);
 let openProduct = ref(false);
 let modalType = ref("add");
 let rules = ref({
-  name: [{ required: true, message: "请输入工艺名称", trigger: "blur" }],
+  name: [{ required: true, message: "请输入产线名称", trigger: "blur" }],
 });
 const { proxy } = getCurrentInstance();
 const selectConfig = reactive([
@@ -185,7 +185,7 @@ const config = computed(() => {
   return [
     {
       attrs: {
-        label: "工艺名称",
+        label: "产线名称",
         prop: "name",
         width: 150,
       },
@@ -193,7 +193,7 @@ const config = computed(() => {
 
     {
       attrs: {
-        label: "工艺路线",
+        label: "产线路线",
         slot: "line",
       },
     },
@@ -205,7 +205,7 @@ const config = computed(() => {
     },
     {
       attrs: {
-        label: "工艺说明",
+        label: "产线说明",
         prop: "remarks",
       },
     },
@@ -299,13 +299,41 @@ const formConfig = computed(() => {
     {
       type: "input",
       prop: "name",
-      label: "工艺名称",
-      required: true,
+      label: "产线名称",
+    },
+    {
+      type: "radio",
+      prop: "radioaa",
+      label: "批量模式",
+      data: [
+        {
+          dictKey: "0",
+          dictValue: "关闭批量模式",
+        },
+        {
+          dictKey: "1",
+          dictValue: "开启批量模式",
+        },
+      ],
+      fn: (val) => {
+        if (val == "0") {
+          formData.data.unit = [];
+        }
+      },
+    },
+    {
+      type: "select",
+      prop: "unit",
+      label: "生产任务",
+      data: [],
+      itemWidth: 100,
+      multiple: true,
+      isShow: formData.data.radioaa == "1",
     },
     {
       type: "slot",
       slotName: "lineSlot",
-      label: "工艺路线",
+      label: "产线路线",
     },
     // {
     //   type: "slot",
@@ -315,7 +343,7 @@ const formConfig = computed(() => {
     {
       type: "input",
       prop: "remarks",
-      label: "工艺说明",
+      label: "产线说明",
       itemType: "textarea",
     },
   ];

+ 164 - 169
src/views/publicModule/companyConfig/index.vue

@@ -1,199 +1,142 @@
 <template>
   <div class="tenant">
-    <byTable
-      :source="sourceList.data"
-      :pagination="sourceList.pagination"
-      :config="config"
-      :loading="loading"
-      highlight-current-row
-      :selectConfig="selectConfig"
-      :table-events="{
+    <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
+             :selectConfig="selectConfig" :table-events="{
         select: select,
-      }"
-      :action-list="[
+      }" :action-list="[
         {
           text: '添加公司',
           action: () => openModal('add'),
         },
-      ]"
-      @get-list="getList">
+      ]" @get-list="getList">
       <template #timeSlot="{ item }"> {{ item.startDate }} - {{ item.stopDate }} </template>
     </byTable>
-    <el-dialog :title="modalType == 'add' ? '添加公司' : '编辑公司'" v-if="dialogVisible" v-model="dialogVisible" width="600" v-loading="loading">
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
+    <el-dialog :title="modalType == 'add' ? '添加公司' : '编辑公司'" v-if="dialogVisible" v-model="dialogVisible" width="80%">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform" v-loading="loading">
         <template #timeGanger>
           <div style="width: 100%">
-            <el-row :gutter="10">
-              <el-col :span="11">
-                <el-input v-model="formData.data.startDate" placeholder="请输入" />
-              </el-col>
-              <el-col :span="2" style="text-align: center"> To </el-col>
-              <el-col :span="11">
-                <el-input v-model="formData.data.stopDate" placeholder="请输入" />
-              </el-col>
-            </el-row>
+            <div style="display:flex">
+              <div style="width:calc((100% - 145px)/2)">
+                <el-form-item label="" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.startDate" placeholder="请输入" />
+                </el-form-item>
+              </div>
+              <div style="text-align: center;width:155px"> To </div>
+              <div style="width:calc((100% - 145px)/2)">
+                <el-form-item label="" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.stopDate" placeholder="请输入" />
+                </el-form-item>
+              </div>
+            </div>
           </div>
         </template>
         <template #allAddress>
           <el-row style="width: 100%;display: flex;justify-content: space-between;">
-            <el-col :span="7">
-              <el-form-item prop="countryId">
-                <el-select v-model="formData.data.countryId" placeholder="国家" filterable @change="(val) => getCityData(val, '20', true)">
+            <el-col :span="8">
+              <el-form-item prop="countryId" label-width="0px" class="margin-b-0 wid100">
+                <el-select v-model="formData.data.countryId" placeholder="国家" style="width:100%" filterable
+                           @change="(val) => getCityData(val, '20', true)">
                   <el-option v-for="item in countryData" :label="item.chineseName" :value="item.id"> </el-option>
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="7">
-              <el-form-item prop="provinceName">
-                <selectCity
-                  placeholder="省/洲"
-                  @change="(val) => getCityData(val, '30', true)"
-                  addressId="provinceId"
-                  addressName="provinceName"
-                  v-model="formData.data"
-                  :data="provinceData">
+            <el-col :span="8">
+              <el-form-item prop="provinceName" label-width="0px" class="margin-b-0 wid100">
+                <selectCity placeholder="省/洲" @change="(val) => getCityData(val, '30', true)" style="width:100%" addressId="provinceId"
+                            addressName="provinceName" v-model="formData.data" :data="provinceData">
                 </selectCity>
               </el-form-item>
             </el-col>
-            <el-col :span="7">
-              <el-form-item prop="cityName">
-                <selectCity placeholder="城市" addressId="cityId" addressName="cityName" v-model="formData.data" :data="cityData"></selectCity>
-              </el-form-item>
-            </el-col>
-          </el-row>
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="24">
-              <el-form-item prop="address">
-                <el-input v-model="formData.data.address" type="textarea"> </el-input>
+            <el-col :span="8">
+              <el-form-item prop="cityName" label-width="0px" class="margin-b-0 wid100">
+                <selectCity placeholder="城市" addressId="cityId" addressName="cityName" style="width:100%" v-model="formData.data" :data="cityData">
+                </selectCity>
               </el-form-item>
             </el-col>
           </el-row>
         </template>
         <template #allAddressEnglish>
-          <el-row style="width: 100%;display: flex;justify-content: space-between;">
-            <el-col :span="7">
-              <el-form-item prop="countryEnStr">
+          <el-row style="width: 100%;">
+            <el-col :span="8">
+              <el-form-item prop="countryEnStr" label-width="0px" class="margin-b-0 wid100">
                 <el-input v-model="formData.data.countryEnStr" placeholder="请输入国家 (英文)" />
               </el-form-item>
             </el-col>
-            <el-col :span="7">
-              <el-form-item prop="provinceEnStr">
+            <el-col :span="8">
+              <el-form-item prop="provinceEnStr" label-width="0px" class="margin-b-0 wid100">
                 <el-input v-model="formData.data.provinceEnStr" placeholder="请输入省/洲 (英文)" />
               </el-form-item>
             </el-col>
-            <el-col :span="7">
-              <el-form-item prop="cityEnStr">
+            <el-col :span="8">
+              <el-form-item prop="cityEnStr" label-width="0px" class="margin-b-0 wid100">
                 <el-input v-model="formData.data.cityEnStr" placeholder="请输入城市 (英文)" />
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row style="margin-top: 20px; width: 100%">
-            <el-col :span="24">
-              <el-form-item prop="addressEn">
-                <el-input v-model="formData.data.addressEn" type="textarea"> </el-input>
-              </el-form-item>
-            </el-col>
-          </el-row>
         </template>
         <template #file>
           <div style="width: 100%">
             <el-row style="width: 100%">
               <el-col :span="6">
                 <el-form-item label="企业logo">
-                  <el-upload
-                    class="avatar-uploader"
-                    action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
-                    :data="uploadDataOne"
-                    :show-file-list="false"
-                    :on-success="enterpriseLogoListSuccess"
-                    :before-upload="uploadFileOne">
-                    <el-image
-                      v-if="formData.data.enterpriseLogoList && formData.data.enterpriseLogoList.length > 0"
-                      :src="formData.data.enterpriseLogoList[0].fileUrl"
-                      fit="scale-down"
-                      class="avatar" />
-                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+                  <el-upload class="avatar-uploader" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadDataOne"
+                             :show-file-list="false" :on-success="enterpriseLogoListSuccess" :before-upload="uploadFileOne">
+                    <el-image v-if="formData.data.enterpriseLogoList && formData.data.enterpriseLogoList.length > 0"
+                              :src="formData.data.enterpriseLogoList[0].fileUrl" fit="scale-down" class="avatar" />
+                    <el-icon v-else class="avatar-uploader-icon">
+                      <Plus />
+                    </el-icon>
                   </el-upload>
-                  <el-button 
-                    class="delete-btn" 
-                    type="danger" 
-                    v-if="formData.data.enterpriseLogoList && formData.data.enterpriseLogoList.length > 0"
-                    @click="formData.data.enterpriseLogoList = []">
+                  <el-button class="delete-btn" type="danger" v-if="formData.data.enterpriseLogoList && formData.data.enterpriseLogoList.length > 0"
+                             @click="formData.data.enterpriseLogoList = []">
                     删除
                   </el-button>
                 </el-form-item>
               </el-col>
               <el-col :span="6">
                 <el-form-item label="法人签名">
-                  <el-upload
-                    class="avatar-uploader"
-                    action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
-                    :data="uploadDataTwo"
-                    :show-file-list="false"
-                    :on-success="larSignListSuccess"
-                    :before-upload="uploadFileTwo">
-                    <el-image
-                      v-if="formData.data.larSignList && formData.data.larSignList.length > 0"
-                      :src="formData.data.larSignList[0].fileUrl"
-                      fit="scale-down"
-                      class="avatar" />
-                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+                  <el-upload class="avatar-uploader" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadDataTwo"
+                             :show-file-list="false" :on-success="larSignListSuccess" :before-upload="uploadFileTwo">
+                    <el-image v-if="formData.data.larSignList && formData.data.larSignList.length > 0" :src="formData.data.larSignList[0].fileUrl"
+                              fit="scale-down" class="avatar" />
+                    <el-icon v-else class="avatar-uploader-icon">
+                      <Plus />
+                    </el-icon>
                   </el-upload>
-                  <el-button 
-                    class="delete-btn" 
-                    type="danger" 
-                    v-if="formData.data.larSignList && formData.data.larSignList.length > 0"
-                    @click="formData.data.larSignList = []">
+                  <el-button class="delete-btn" type="danger" v-if="formData.data.larSignList && formData.data.larSignList.length > 0"
+                             @click="formData.data.larSignList = []">
                     删除
                   </el-button>
                 </el-form-item>
               </el-col>
               <el-col :span="6">
                 <el-form-item label="公章">
-                  <el-upload
-                    class="avatar-uploader"
-                    action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
-                    :data="uploadDataThree"
-                    :show-file-list="false"
-                    :on-success="officialSealListSuccess"
-                    :before-upload="uploadFileThree">
-                    <el-image
-                      v-if="formData.data.officialSealList && formData.data.officialSealList.length > 0"
-                      :src="formData.data.officialSealList[0].fileUrl"
-                      fit="scale-down"
-                      class="avatar" />
-                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+                  <el-upload class="avatar-uploader" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadDataThree"
+                             :show-file-list="false" :on-success="officialSealListSuccess" :before-upload="uploadFileThree">
+                    <el-image v-if="formData.data.officialSealList && formData.data.officialSealList.length > 0"
+                              :src="formData.data.officialSealList[0].fileUrl" fit="scale-down" class="avatar" />
+                    <el-icon v-else class="avatar-uploader-icon">
+                      <Plus />
+                    </el-icon>
                   </el-upload>
-                  <el-button 
-                    class="delete-btn" 
-                    type="danger" 
-                     v-if="formData.data.officialSealList && formData.data.officialSealList.length > 0"
-                    @click="formData.data.officialSealList = []">
+                  <el-button class="delete-btn" type="danger" v-if="formData.data.officialSealList && formData.data.officialSealList.length > 0"
+                             @click="formData.data.officialSealList = []">
                     删除
                   </el-button>
                 </el-form-item>
               </el-col>
               <el-col :span="6">
                 <el-form-item label="合同章">
-                  <el-upload
-                    class="avatar-uploader"
-                    action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
-                    :data="uploadDataFour"
-                    :show-file-list="false"
-                    :on-success="contractSealListSuccess"
-                    :before-upload="uploadFileFour">
-                    <el-image
-                      v-if="formData.data.contractSealList && formData.data.contractSealList.length > 0"
-                      :src="formData.data.contractSealList[0].fileUrl"
-                      fit="scale-down"
-                      class="avatar" />
-                    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+                  <el-upload class="avatar-uploader" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadDataFour"
+                             :show-file-list="false" :on-success="contractSealListSuccess" :before-upload="uploadFileFour">
+                    <el-image v-if="formData.data.contractSealList && formData.data.contractSealList.length > 0"
+                              :src="formData.data.contractSealList[0].fileUrl" fit="scale-down" class="avatar" />
+                    <el-icon v-else class="avatar-uploader-icon">
+                      <Plus />
+                    </el-icon>
                   </el-upload>
-                  <el-button 
-                    class="delete-btn" 
-                    type="danger" 
-                    v-if="formData.data.contractSealList && formData.data.contractSealList.length > 0" 
-                    @click="formData.data.contractSealList = []">
+                  <el-button class="delete-btn" type="danger" v-if="formData.data.contractSealList && formData.data.contractSealList.length > 0"
+                             @click="formData.data.contractSealList = []">
                     删除
                   </el-button>
                 </el-form-item>
@@ -232,7 +175,9 @@ let modalType = ref("add");
 let rules = ref({
   name: [{ required: true, message: "请输入公司名称", trigger: "blur" }],
   countryId: [{ required: true, message: "请选择国家", trigger: "change" }],
-  countryEnStr: [{ required: true, message: "请输入国家 (英文)", trigger: "blur" }],
+  countryEnStr: [
+    { required: true, message: "请输入国家 (英文)", trigger: "blur" },
+  ],
 });
 const { proxy } = getCurrentInstance();
 const contactInformationType = ref([]);
@@ -328,11 +273,15 @@ const config = computed(() => {
             },
             el: "button",
             click() {
-              ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-              }).then(() => {
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
                 proxy
                   .post("/corporation/delete", {
                     id: row.id,
@@ -363,7 +312,7 @@ let formData = reactive({
 });
 const formOption = reactive({
   inline: true,
-  labelWidth: 100,
+  labelWidth: 125,
   itemWidth: 100,
   rules: [],
 });
@@ -371,36 +320,46 @@ const byform = ref(null);
 const formConfig = computed(() => {
   return [
     {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
       type: "input",
       prop: "name",
       label: "公司名称",
       required: true,
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "nameEn",
       label: "英文名",
+      itemWidth: 50,
     },
     {
       type: "select",
       prop: "type",
       label: "企业类型",
       data: enterpriseType.value,
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "uscCode",
       label: "统一社会信用代码",
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "legalPersonName",
       label: "法定代表人",
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "registeredCapital",
       label: "注册资本",
+      itemWidth: 50,
     },
     {
       type: "slot",
@@ -412,11 +371,27 @@ const formConfig = computed(() => {
       type: "slot",
       slotName: "allAddress",
       label: "公司地址",
+      itemWidth: 50,
+    },
+    {
+      type: "input",
+      // itemType: "textarea",
+      prop: "allAddress",
+      label: "详细地址",
+      itemWidth: 50,
     },
     {
       type: "slot",
       slotName: "allAddressEnglish",
       label: "公司地址 (英文)",
+      itemWidth: 50,
+    },
+    {
+      type: "input",
+      // itemType: "textarea",
+      prop: "addressEn",
+      label: "详细地址 (英文)",
+      itemWidth: 50,
     },
     {
       type: "input",
@@ -424,55 +399,67 @@ const formConfig = computed(() => {
       label: "公司电话",
       itemType: "text",
       placeholder: "请输入公司电话",
+      itemWidth: 50,
     },
     {
       type: "select",
       prop: "taxpayerQualification",
       label: "纳税人资质",
       data: contactInformationType.value,
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "iaeeCode",
       label: "进出口企业代码",
       required: true,
+      itemWidth: 50,
     },
     {
       type: "input",
       prop: "crCode",
       label: "海关注册代码",
       required: true,
+      itemWidth: 50,
+    },
+    {
+      type: "title1",
+      title: "签章",
     },
     {
       type: "slot",
       prop: "file",
       slotName: "file",
-      label: "签章",
+      label: "",
     },
   ];
 });
 const getDict = () => {
-  proxy.getDictOne(["enterprise_type", "taxpayer_qualification"]).then((res) => {
-    enterpriseType.value = res["enterprise_type"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-    contactInformationType.value = res["taxpayer_qualification"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-  });
+  proxy
+    .getDictOne(["enterprise_type", "taxpayer_qualification"])
+    .then((res) => {
+      enterpriseType.value = res["enterprise_type"].map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+      contactInformationType.value = res["taxpayer_qualification"].map((x) => ({
+        label: x.dictValue,
+        value: x.dictKey,
+      }));
+    });
 };
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy.post("/corporation/page", sourceList.value.pagination).then((message) => {
-    sourceList.value.data = message.rows;
-    sourceList.value.pagination.total = message.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
-  });
+  proxy
+    .post("/corporation/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
 };
 const countryData = ref([]);
 const provinceData = ref([]);
@@ -546,18 +533,26 @@ const getDtl = (row) => {
     if (formData.data.provinceId) {
       getCityData(formData.data.provinceId, "30");
     }
-    proxy.post("/fileInfo/getList", { businessIdList: [res.id], fileType: 1 }).then((resFile) => {
-      formData.data.enterpriseLogoList = resFile[res.id];
-    });
-    proxy.post("/fileInfo/getList", { businessIdList: [res.id], fileType: 2 }).then((resFile) => {
-      formData.data.larSignList = resFile[res.id];
-    });
-    proxy.post("/fileInfo/getList", { businessIdList: [res.id], fileType: 3 }).then((resFile) => {
-      formData.data.officialSealList = resFile[res.id];
-    });
-    proxy.post("/fileInfo/getList", { businessIdList: [res.id], fileType: 4 }).then((resFile) => {
-      formData.data.contractSealList = resFile[res.id];
-    });
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [res.id], fileType: 1 })
+      .then((resFile) => {
+        formData.data.enterpriseLogoList = resFile[res.id];
+      });
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [res.id], fileType: 2 })
+      .then((resFile) => {
+        formData.data.larSignList = resFile[res.id];
+      });
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [res.id], fileType: 3 })
+      .then((resFile) => {
+        formData.data.officialSealList = resFile[res.id];
+      });
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [res.id], fileType: 4 })
+      .then((resFile) => {
+        formData.data.contractSealList = resFile[res.id];
+      });
     dialogVisible.value = true;
   });
 };
@@ -638,7 +633,7 @@ const contractSealListSuccess = (response, uploadFile) => {
 <style lang="scss" scoped>
 .tenant {
   padding: 20px;
-  .delete-btn{
+  .delete-btn {
     margin-top: 10px;
     margin-left: 25px;
   }