소스 검색

Merge branch 'dev0.3' into stage

cz 1 년 전
부모
커밋
cab4641e21

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 14805 - 5167
src/assets/icons/iconfont/demo_index.html


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1687 - 3
src/assets/icons/iconfont/iconfont.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
src/assets/icons/iconfont/iconfont.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2947 - 0
src/assets/icons/iconfont/iconfont.json


BIN
src/assets/icons/iconfont/iconfont.ttf


BIN
src/assets/icons/iconfont/iconfont.woff


BIN
src/assets/icons/iconfont/iconfont.woff2


+ 2 - 11
src/components/process/Contract.vue

@@ -106,17 +106,8 @@
                     placeholder="国家"
                     filterable
                     @change="(val) => getCityData(val, '20', true)"
-                  >
-                    <el-option
-                      v-for="item in countryData"
-                      :label="
-                        formData.data.contractType == '2'
-                          ? item.chineseName
-                          : item.name
-                      "
-                      :value="item.id"
-                    >
-                    </el-option>
+                    :no-match-text="'无数据,请联系管理员添加'">
+                    <el-option v-for="item in countryData" :key="item.id" :label="item.chineseName + '(' + item.name + ')'" :value="item.id"> </el-option>
                   </el-select>
                 </el-form-item>
               </el-col>

+ 2 - 7
src/components/process/PriceSheet.vue

@@ -103,13 +103,8 @@
                     placeholder="国家"
                     filterable
                     @change="(val) => getCityData(val, '20', true)"
-                  >
-                    <el-option
-                      v-for="item in countryData"
-                      :label="item.name"
-                      :value="item.id"
-                    >
-                    </el-option>
+                    :no-match-text="'无数据,请联系管理员添加'">
+                    <el-option v-for="item in countryData" :key="item.id" :label="item.chineseName + '(' + item.name + ')'" :value="item.id"> </el-option>
                   </el-select>
                 </el-form-item>
               </el-col>

+ 2 - 7
src/components/process/ServiceContract.vue

@@ -117,13 +117,8 @@
                     placeholder="国家"
                     filterable
                     @change="(val) => getCityData(val, '20', true)"
-                  >
-                    <el-option
-                      v-for="item in countryData"
-                      :label="item.chineseName"
-                      :value="item.id"
-                    >
-                    </el-option>
+                    :no-match-text="'无数据,请联系管理员添加'">
+                    <el-option v-for="item in countryData" :key="item.id" :label="item.chineseName + '(' + item.name + ')'" :value="item.id"> </el-option>
                   </el-select>
                 </el-form-item>
               </el-col>

+ 10 - 11
src/components/selectCity/index.vue

@@ -1,12 +1,21 @@
 <template>
   <div class="select-city">
-    <el-select clearable filterable allow-create :placeholder="placeholder" @change="getCityData" @clear="getCityData" v-model="showModel" style="width: 100%">
+    <el-select
+      clearable
+      filterable
+      :placeholder="placeholder"
+      @change="getCityData"
+      v-model="showModel"
+      style="width: 100%"
+      :no-match-text="'无数据,请联系管理员添加'"
+      :no-data-text="'无数据,请联系管理员添加'">
       <el-option v-for="item in data" :label="item.name" :value="item.id"> </el-option>
     </el-select>
   </div>
 </template>
 <script setup>
 import { reactive, ref } from "vue";
+
 const { proxy } = getCurrentInstance();
 const showModel = ref("");
 const emit = defineEmits(["update:modelValue", "change"]);
@@ -62,25 +71,15 @@ watch(
   }
 );
 const getCityData = (val) => {
-  let isAddCity = true;
   //判断val是否在data里面
   proxy.data.forEach((item) => {
     if (item.id == val) {
-      isAddCity = false;
       formData.value[proxy.addressId || "provinceId"] = item.id;
       formData.value[proxy.addressName || "provinceName"] = item.name;
-      console.log(formData.value);
       emit("update:modelValue", formData.value);
       showModel.value = item.id;
       emit("change", item.id);
     }
   });
-  if (isAddCity) {
-    formData.value[proxy.addressId || "provinceId"] = null;
-    formData.value[proxy.addressName || "provinceName"] = val;
-    showModel.value = val;
-    emit("update:modelValue", formData.value);
-    emit("change", val);
-  }
 };
 </script>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 138 - 507
src/views/customer/file/index.vue


+ 132 - 488
src/views/customer/highseas/index.vue

@@ -1,9 +1,7 @@
 <template>
   <div class="tenant">
     <div style="padding: 20px; background: #fff; margin-bottom: 20px">
-      <el-button type="primary" style="margin-left: 10px" @click="openModal()"
-        >添加客户</el-button
-      >
+      <el-button type="primary" style="margin-left: 10px" @click="openModal()">添加客户</el-button>
     </div>
 
     <byTable
@@ -16,22 +14,11 @@
       highlight-current-row
       @moreSearch="moreSearch"
       @get-list="getList"
-      ref="table"
-    >
+      ref="table">
       <template #isTop="{ item }">
         <div>
-          <img
-            style="cursor: pointer; width: 20px; transform: translateY(5px)"
-            :src="'/img/isTop.png'"
-            @click="deleteTop(item)"
-            v-if="item.isTop === 1"
-          />
-          <img
-            style="cursor: pointer; width: 20px; transform: translateY(5px)"
-            :src="'/img/noTop.png'"
-            @click="addTop(item)"
-            v-else
-          />
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/isTop.png'" @click="deleteTop(item)" v-if="item.isTop === 1" />
+          <img style="cursor: pointer; width: 20px; transform: translateY(5px)" :src="'/img/noTop.png'" @click="addTop(item)" v-else />
         </div>
       </template>
       <template #address="{ item }">
@@ -40,23 +27,13 @@
         <span v-if="item.cityName"> ,{{ item.cityName }}</span>
       </template>
       <template #name="{ item }">
-        <div
-          style="cursor: pointer; color: #409eff; word-break: break-all"
-          @click="handleClickName(item)"
-        >
+        <div style="cursor: pointer; color: #409eff; word-break: break-all" @click="handleClickName(item)">
           {{ item.name }}
         </div>
       </template>
       <template #tags="{ item }">
         <div style="width: 100%">
-          <el-tag
-            style="margin-right: 8px"
-            type="success"
-            v-for="(tag, index) in item.tag"
-            closable
-            :key="index"
-            @close="tagClose(tag, item)"
-          >
+          <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tag" closable :key="index" @close="tagClose(tag, item)">
             {{ dictValueLabel(tag, customerTag) }}
           </el-tag>
           <template v-if="item.tag.length !== customerTag.length">
@@ -68,36 +45,17 @@
                 (val) => {
                   return changeTag(val, item);
                 }
-              "
-            >
-              <el-option
-                v-for="tag in customerTag"
-                :key="tag.value"
-                :label="tag.label"
-                :value="tag.value"
-                :disabled="judgeTagSelect(item.tag, tag.value)"
-              />
+              ">
+              <el-option v-for="tag in customerTag" :key="tag.value" :label="tag.label" :value="tag.value" :disabled="judgeTagSelect(item.tag, tag.value)" />
             </el-select>
-            <el-tag
-              style="cursor: pointer"
-              type="success"
-              @click="showSelect(item)"
-              v-else
-            >
-              +
-            </el-tag>
+            <el-tag style="cursor: pointer" type="success" @click="showSelect(item)" v-else> + </el-tag>
           </template>
         </div>
       </template>
       <template #follow="{ item }">
         <div :class="'getWidth' + item.id" style="width: 100%">
           <div style="width: 100%; display: flex">
-            <template
-              v-if="
-                item.customerFollowRecordsList &&
-                item.customerFollowRecordsList.length > 0
-              "
-            >
+            <template v-if="item.customerFollowRecordsList && item.customerFollowRecordsList.length > 0">
               <div
                 :style="
                   index > 2
@@ -105,59 +63,35 @@
                     : 'line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer'
                 "
                 v-for="(record, index) in item.customerFollowRecordsList"
-                :key="record.id"
-              >
-                <el-popover
-                  placement="bottom"
-                  :width="300"
-                  trigger="hover"
-                  @show="recordShow(record)"
-                >
+                :key="record.id">
+                <el-popover placement="bottom" :width="300" trigger="hover" @show="recordShow(record)">
                   <template #reference>
                     <div>
-                      <span v-if="record.date">{{
-                        record.date.substr(0, 10)
-                      }}</span>
-                      <el-icon
-                        style="margin-left: 8px; transform: translateY(2px)"
-                        @click="deleteFollow(record)"
-                        ><DeleteFilled
-                      /></el-icon>
+                      <span v-if="record.date">{{ record.date.substr(0, 10) }}</span>
+                      <el-icon style="margin-left: 8px; transform: translateY(2px)" @click="deleteFollow(record)"><DeleteFilled /></el-icon>
                     </div>
                   </template>
                   <template #default>
                     <div style="width: 100%">
-                      <div style="color: #909399; margin: 8px 0">
-                        跟进时间: {{ record.date }}
-                      </div>
+                      <div style="color: #909399; margin: 8px 0">跟进时间: {{ record.date }}</div>
                       <div style="margin: 8px 0">
                         跟进人:
                         {{ dictValueLabel(record.createUser, userList) }}
                       </div>
                       <div v-if="record.type == '30'">
-                        <div
-                          style="word-wrap: break-word; margin: 8px 0"
-                          v-html="getStyle(record.content)"
-                          v-if="record.content"
-                        ></div>
+                        <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
                         <div v-else>跟进记录:</div>
                       </div>
                       <div v-else>
                         <div style="word-wrap: break-word; margin: 8px 0">
                           <!-- {{ getContent(record) }} -->
-                          <span v-if="record.type === '10'"
-                            >跟进记录:报价单总金额
-                          </span>
-                          <span v-if="record.type === '20'"
-                            >跟进记录:合同总金额
-                          </span>
+                          <span v-if="record.type === '10'">跟进记录:报价单总金额 </span>
+                          <span v-if="record.type === '20'">跟进记录:合同总金额 </span>
                           <span>{{ moneyFormat(record.amount, 2) }}</span>
                           <span
                             v-if="record.type === '10' && record.code"
                             :class="{ 'code-class': isHave }"
-                            @click="
-                              isHaveOne ? handlePushRoute(record) : () => {}
-                            "
+                            @click="isHaveOne ? handlePushRoute(record) : () => {}"
                             >({{ record.code }})</span
                           >
                           <span
@@ -168,21 +102,11 @@
                           >
                         </div>
                       </div>
-                      <div
-                        style="margin: 8px 0; display: flex"
-                        v-if="record.fileList && record.fileList.length > 0"
-                      >
+                      <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
                         <div style="width: 36px">附件:</div>
                         <div style="width: calc(100% - 36px)">
-                          <div
-                            v-for="(file, index) in record.fileList"
-                            :key="index"
-                          >
-                            <a
-                              style="color: #409eff; cursor: pointer"
-                              @click="openFile(file.fileUrl)"
-                              >{{ file.fileName }}</a
-                            >
+                          <div v-for="(file, index) in record.fileList" :key="index">
+                            <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
                           </div>
                         </div>
                       </div>
@@ -191,17 +115,9 @@
                 </el-popover>
               </div>
               <div
-                style="
-                  line-height: 32px;
-                  margin-right: 8px;
-                  padding: 0 8px;
-                  background-color: #eeeeee;
-                  border-radius: 4px;
-                  cursor: pointer;
-                "
+                style="line-height: 32px; margin-right: 8px; padding: 0 8px; background-color: #eeeeee; border-radius: 4px; cursor: pointer"
                 @click="clickMore(item)"
-                v-if="item.customerFollowRecordsList.length >= 3"
-              >
+                v-if="item.customerFollowRecordsList.length >= 3">
                 更多
               </div>
             </template>
@@ -210,20 +126,8 @@
       </template>
     </byTable>
 
-    <el-dialog
-      :title="modalType == 'add' ? '新增' : '编辑'"
-      v-if="dialogVisible"
-      v-model="dialogVisible"
-      width="800"
-      v-loading="loadingOperation"
-    >
-      <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="800" v-loading="loadingOperation">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
         <template #address>
           <el-row style="width: 100%">
             <el-col :span="8">
@@ -233,13 +137,8 @@
                   placeholder="国家"
                   filterable
                   @change="(val) => getCityData(val, '20', true)"
-                >
-                  <el-option
-                    v-for="item in countryData"
-                    :label="item.chineseName"
-                    :value="item.id"
-                  >
-                  </el-option>
+                  :no-match-text="'无数据,请联系管理员添加'">
+                  <el-option v-for="item in countryData" :key="item.id" :label="item.chineseName + '(' + item.name + ')'" :value="item.id"> </el-option>
                 </el-select>
               </el-form-item>
             </el-col>
@@ -251,28 +150,20 @@
                   addressId="provinceId"
                   addressName="provinceName"
                   v-model="formData.data"
-                  :data="provinceData"
-                >
+                  :data="provinceData">
                 </selectCity>
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item prop="cityName">
-                <selectCity
-                  placeholder="城市"
-                  addressId="cityId"
-                  addressName="cityName"
-                  v-model="formData.data"
-                  :data="cityData"
-                ></selectCity>
+                <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-input v-model="formData.data.address" type="textarea"> </el-input>
               </el-form-item>
             </el-col>
           </el-row>
@@ -280,18 +171,11 @@
         <template #person>
           <div style="width: 100%">
             <el-button type="primary" @click="clickAddPerson">添 加</el-button>
-            <el-table
-              :data="formData.data.customerUserList"
-              style="width: 100%; margin-top: 16px"
-            >
+            <el-table :data="formData.data.customerUserList" style="width: 100%; margin-top: 16px">
               <el-table-column label="联系人" width="160">
                 <template #default="{ row, $index }">
                   <div style="width: 100%">
-                    <el-form-item
-                      :prop="'customerUserList.' + $index + '.name'"
-                      :rules="rules.name2"
-                      :inline-message="true"
-                    >
+                    <el-form-item :prop="'customerUserList.' + $index + '.name'" :rules="rules.name2" :inline-message="true">
                       <el-input v-model="row.name" placeholder="请输入联系人" />
                     </el-form-item>
                   </div>
@@ -300,35 +184,16 @@
               <el-table-column label="电子邮箱">
                 <template #default="{ row, $index }">
                   <div style="width: 100%">
-                    <el-form-item
-                      :prop="'customerUserList.' + $index + '.email'"
-                      :rules="rules.email"
-                      :inline-message="true"
-                    >
-                      <el-input
-                        v-model="row.email"
-                        placeholder="请输入电子邮箱"
-                      />
+                    <el-form-item :prop="'customerUserList.' + $index + '.email'" :rules="rules.email" :inline-message="true">
+                      <el-input v-model="row.email" placeholder="请输入电子邮箱" />
                     </el-form-item>
                   </div>
                 </template>
               </el-table-column>
-              <el-table-column
-                align="center"
-                label="操作"
-                width="120"
-                fixed="right"
-              >
+              <el-table-column align="center" label="操作" width="120" fixed="right">
                 <template #default="{ row, $index }">
-                  <el-button
-                    type="primary"
-                    link
-                    @click="clickInformationMore(row, $index)"
-                    >更多</el-button
-                  >
-                  <el-button type="primary" link @click="clickDelete($index)"
-                    >删除</el-button
-                  >
+                  <el-button type="primary" link @click="clickInformationMore(row, $index)">更多</el-button>
+                  <el-button type="primary" link @click="clickDelete($index)">删除</el-button>
                 </template>
               </el-table-column>
             </el-table>
@@ -337,28 +202,12 @@
       </byForm>
       <template #footer>
         <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button
-          type="primary"
-          @click="submitForm()"
-          size="large"
-          :loading="submitLoading"
-          >确 定</el-button
-        >
+        <el-button type="primary" @click="submitForm()" size="large" :loading="submitLoading">确 定</el-button>
       </template>
     </el-dialog>
 
-    <el-dialog
-      title="更多联系方式"
-      v-if="openPerson"
-      v-model="openPerson"
-      width="700"
-    >
-      <el-form
-        :label-position="'top'"
-        :model="formPerson.data"
-        :rules="rulesPerson"
-        ref="person"
-      >
+    <el-dialog title="更多联系方式" v-if="openPerson" v-model="openPerson" width="700">
+      <el-form :label-position="'top'" :model="formPerson.data" :rules="rulesPerson" ref="person">
         <el-form-item label="联系人" prop="name">
           <el-input v-model="formPerson.data.name" />
         </el-form-item>
@@ -367,32 +216,14 @@
         </el-form-item>
         <el-form-item label="更多联系方式">
           <div style="width: 100%">
-            <el-button type="primary" @click="clickAddMoreInformation"
-              >添 加</el-button
-            >
-            <el-table
-              :data="formPerson.data.contact"
-              style="width: 100%; margin-top: 16px"
-            >
+            <el-button type="primary" @click="clickAddMoreInformation">添 加</el-button>
+            <el-table :data="formPerson.data.contact" style="width: 100%; margin-top: 16px">
               <el-table-column label="类型" width="180">
                 <template #default="{ row, $index }">
                   <div style="width: 100%">
-                    <el-form-item
-                      :prop="'contact.' + $index + '.type'"
-                      :rules="rulesPerson.type"
-                      :inline-message="true"
-                    >
-                      <el-select
-                        v-model="row.type"
-                        placeholder="请选择类型"
-                        style="width: 100%"
-                      >
-                        <el-option
-                          v-for="item in contactType"
-                          :key="item.value"
-                          :label="item.label"
-                          :value="item.value"
-                        />
+                    <el-form-item :prop="'contact.' + $index + '.type'" :rules="rulesPerson.type" :inline-message="true">
+                      <el-select v-model="row.type" placeholder="请选择类型" style="width: 100%">
+                        <el-option v-for="item in contactType" :key="item.value" :label="item.label" :value="item.value" />
                       </el-select>
                     </el-form-item>
                   </div>
@@ -401,32 +232,15 @@
               <el-table-column label="联系号码">
                 <template #default="{ row, $index }">
                   <div style="width: 100%">
-                    <el-form-item
-                      :prop="'contact.' + $index + '.contactNo'"
-                      :rules="rulesPerson.contactNo"
-                      :inline-message="true"
-                    >
-                      <el-input
-                        v-model="row.contactNo"
-                        placeholder="请输入联系号码"
-                      />
+                    <el-form-item :prop="'contact.' + $index + '.contactNo'" :rules="rulesPerson.contactNo" :inline-message="true">
+                      <el-input v-model="row.contactNo" placeholder="请输入联系号码" />
                     </el-form-item>
                   </div>
                 </template>
               </el-table-column>
-              <el-table-column
-                align="center"
-                label="操作"
-                width="120"
-                fixed="right"
-              >
+              <el-table-column align="center" label="操作" width="120" fixed="right">
                 <template #default="{ $index }">
-                  <el-button
-                    type="primary"
-                    link
-                    @click="clickInformationDelete($index)"
-                    >删除</el-button
-                  >
+                  <el-button type="primary" link @click="clickInformationDelete($index)">删除</el-button>
                 </template>
               </el-table-column>
             </el-table>
@@ -435,26 +249,12 @@
       </el-form>
       <template #footer>
         <el-button @click="openPerson = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitPerson()" size="large"
-          >确 定</el-button
-        >
+        <el-button type="primary" @click="submitPerson()" size="large">确 定</el-button>
       </template>
     </el-dialog>
 
-    <el-dialog
-      title="添加跟进记录"
-      v-if="openFollow"
-      v-model="openFollow"
-      width="500"
-      destroy-on-close
-    >
-      <byForm
-        :formConfig="formConfigAFollow"
-        :formOption="formOption"
-        v-model="formFollow.data"
-        :rules="rulesFollow"
-        ref="follow"
-      >
+    <el-dialog title="添加跟进记录" v-if="openFollow" v-model="openFollow" width="500" destroy-on-close>
+      <byForm :formConfig="formConfigAFollow" :formOption="formOption" v-model="formFollow.data" :rules="rulesFollow" ref="follow">
         <template #fileSlot>
           <div style="width: 100%">
             <el-upload
@@ -463,8 +263,7 @@
               :data="uploadData"
               multiple
               :before-upload="uploadFile"
-              :on-preview="onPreviewFile"
-            >
+              :on-preview="onPreviewFile">
               <el-button type="primary">文件上传</el-button>
             </el-upload>
           </div>
@@ -472,73 +271,35 @@
       </byForm>
       <template #footer>
         <el-button @click="openFollow = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitFollow()" size="large"
-          >确 定</el-button
-        >
+        <el-button type="primary" @click="submitFollow()" size="large">确 定</el-button>
       </template>
     </el-dialog>
 
-    <el-dialog
-      title="跟进记录"
-      v-if="openRecordMore"
-      v-model="openRecordMore"
-      width="800"
-      destroy-on-close
-    >
+    <el-dialog title="跟进记录" v-if="openRecordMore" v-model="openRecordMore" width="800" destroy-on-close>
       <div>
         <div style="padding: 8px 0">
-          <el-button type="primary" @click="clickFollowUp(rowData)" plain
-            >添加跟进记录</el-button
-          >
+          <el-button type="primary" @click="clickFollowUp(rowData)" plain>添加跟进记录</el-button>
         </div>
         <div style="padding-top: 16px">
-          <div
-            v-infinite-scroll="infiniteScroll"
-            class="infinite-scroll"
-            :infinite-scroll-disabled="judgeTotal()"
-          >
+          <div v-infinite-scroll="infiniteScroll" class="infinite-scroll" :infinite-scroll-disabled="judgeTotal()">
             <el-timeline>
-              <el-timeline-item
-                v-for="(record, index) in recordList"
-                :key="index"
-                :timestamp="record.date"
-                hide-timestamp
-              >
+              <el-timeline-item v-for="(record, index) in recordList" :key="index" :timestamp="record.date" hide-timestamp>
                 <div>
-                  <div
-                    style="
-                      padding: 0 0 8px 0;
-                      display: flex;
-                      justify-content: space-between;
-                    "
-                  >
-                    <span>{{
-                      dictValueLabel(record.createUser, userList)
-                    }}</span>
+                  <div style="padding: 0 0 8px 0; display: flex; justify-content: space-between">
+                    <span>{{ dictValueLabel(record.createUser, userList) }}</span>
                     <span>{{ record.date }}</span>
                   </div>
                   <div v-if="record.type == '30'">
-                    <div
-                      style="word-wrap: break-word; margin: 8px 0"
-                      v-html="getStyle(record.content)"
-                      v-if="record.content"
-                    ></div>
+                    <div style="word-wrap: break-word; margin: 8px 0" v-html="getStyle(record.content)" v-if="record.content"></div>
                     <div v-else>跟进记录:</div>
                   </div>
                   <div v-else>
                     <div style="word-wrap: break-word; margin: 8px 0">
                       <!-- {{ getContent(record) }} -->
-                      <span v-if="record.type === '10'"
-                        >跟进记录:报价单总金额
-                      </span>
-                      <span v-if="record.type === '20'"
-                        >跟进记录:合同总金额
-                      </span>
+                      <span v-if="record.type === '10'">跟进记录:报价单总金额 </span>
+                      <span v-if="record.type === '20'">跟进记录:合同总金额 </span>
                       <span>{{ moneyFormat(record.amount, 2) }}</span>
-                      <span
-                        v-if="record.type === '10' && record.code"
-                        :class="{ 'code-class': isHave }"
-                        @click="isHaveOne ? handlePushRoute(record) : () => {}"
+                      <span v-if="record.type === '10' && record.code" :class="{ 'code-class': isHave }" @click="isHaveOne ? handlePushRoute(record) : () => {}"
                         >({{ record.code }})</span
                       >
                       <span
@@ -549,21 +310,11 @@
                       >
                     </div>
                   </div>
-                  <div
-                    style="margin: 8px 0; display: flex"
-                    v-if="record.fileList && record.fileList.length > 0"
-                  >
+                  <div style="margin: 8px 0; display: flex" v-if="record.fileList && record.fileList.length > 0">
                     <div style="width: 36px">附件:</div>
                     <div style="width: calc(100% - 36px)">
-                      <div
-                        v-for="(file, index) in record.fileList"
-                        :key="index"
-                      >
-                        <a
-                          style="color: #409eff; cursor: pointer"
-                          @click="openFile(file.fileUrl)"
-                          >{{ file.fileName }}</a
-                        >
+                      <div v-for="(file, index) in record.fileList" :key="index">
+                        <a style="color: #409eff; cursor: pointer" @click="openFile(file.fileUrl)">{{ file.fileName }}</a>
                       </div>
                     </div>
                   </div>
@@ -574,24 +325,12 @@
         </div>
       </div>
       <template #footer>
-        <el-button @click="openRecordMore = false" size="large"
-          >关 闭</el-button
-        >
+        <el-button @click="openRecordMore = false" size="large">关 闭</el-button>
       </template>
     </el-dialog>
 
-    <el-dialog
-      title="高级检索"
-      v-if="openSearch"
-      v-model="openSearch"
-      width="600"
-      :before-close="cancelSearch"
-    >
-      <byForm
-        :formConfig="formSearchConfig"
-        :formOption="formOption"
-        v-model="sourceList.pagination"
-      >
+    <el-dialog title="高级检索" v-if="openSearch" v-model="openSearch" width="600" :before-close="cancelSearch">
+      <byForm :formConfig="formSearchConfig" :formOption="formOption" v-model="sourceList.pagination">
         <template #address>
           <el-row style="width: 100%">
             <el-col :span="8">
@@ -602,13 +341,8 @@
                   clearable
                   filterable
                   @change="(val) => getCitySearchData(val, '20', true)"
-                >
-                  <el-option
-                    v-for="item in countrySearchData"
-                    :label="item.chineseName"
-                    :value="item.id"
-                  >
-                  </el-option>
+                  :no-match-text="'无数据,请联系管理员添加'">
+                  <el-option v-for="item in countryData" :key="item.id" :label="item.chineseName + '(' + item.name + ')'" :value="item.id"> </el-option>
                 </el-select>
               </el-form-item>
             </el-col>
@@ -620,72 +354,39 @@
                   addressId="provinceId"
                   addressName="provinceName"
                   v-model="sourceList.pagination"
-                  :data="provinceSearchData"
-                >
+                  :data="provinceSearchData">
                 </selectCity>
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item prop="cityName">
-                <selectCity
-                  placeholder="城市"
-                  addressId="cityId"
-                  addressName="cityName"
-                  v-model="sourceList.pagination"
-                  :data="citySearchData"
-                ></selectCity>
+                <selectCity placeholder="城市" addressId="cityId" addressName="cityName" v-model="sourceList.pagination" :data="citySearchData"></selectCity>
               </el-form-item>
             </el-col>
           </el-row>
         </template>
         <template #tags>
           <div style="width: 100%">
-            <el-tag
-              style="margin-right: 8px"
-              type="info"
-              v-for="(tag, index) in sourceList.pagination.tags"
-              closable
-              :key="index"
-              @close="tagSearchClose(tag)"
-            >
+            <el-tag style="margin-right: 8px" type="info" v-for="(tag, index) in sourceList.pagination.tags" closable :key="index" @close="tagSearchClose(tag)">
               {{ dictValueLabel(tag, customerTag) }}
             </el-tag>
-            <template
-              v-if="sourceList.pagination.tags.length !== customerTag.length"
-            >
-              <el-select
-                v-if="addTagSearchShow"
-                v-model="addSearchTag"
-                style="margin-top: 8px"
-                @change="changeSearchTag"
-              >
+            <template v-if="sourceList.pagination.tags.length !== customerTag.length">
+              <el-select v-if="addTagSearchShow" v-model="addSearchTag" style="margin-top: 8px" @change="changeSearchTag">
                 <el-option
                   v-for="tag in customerTag"
                   :key="tag.value"
                   :label="tag.label"
                   :value="tag.value"
-                  :disabled="
-                    judgeTagSelect(sourceList.pagination.tags, tag.value)
-                  "
-                />
+                  :disabled="judgeTagSelect(sourceList.pagination.tags, tag.value)" />
               </el-select>
-              <el-tag
-                style="cursor: pointer"
-                type="info"
-                @click="addTagSearchShow = true"
-                v-else
-              >
-                +
-              </el-tag>
+              <el-tag style="cursor: pointer" type="info" @click="addTagSearchShow = true" v-else> + </el-tag>
             </template>
           </div>
         </template>
       </byForm>
       <template #footer>
         <el-button @click="cancelSearch()" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitSearch()" size="large"
-          >确 定</el-button
-        >
+        <el-button type="primary" @click="submitSearch()" size="large">确 定</el-button>
       </template>
     </el-dialog>
   </div>
@@ -1137,10 +838,7 @@ const getCityData = (id, type, isChange) => {
 };
 getCityData("0");
 const clickAddPerson = () => {
-  if (
-    formData.data.customerUserList &&
-    formData.data.customerUserList.length > 0
-  ) {
+  if (formData.data.customerUserList && formData.data.customerUserList.length > 0) {
     formData.data.customerUserList.push({
       name: "",
       email: "",
@@ -1167,29 +865,24 @@ const submitFollow = () => {
     } else {
       formFollow.data.fileList = [];
     }
-    proxy
-      .post("/customerFollowRecords/" + modalType.value, formFollow.data)
-      .then(
-        () => {
-          ElMessage({
-            message: modalType.value == "add" ? "添加成功" : "编辑成功",
-            type: "success",
-          });
-          openFollow.value = false;
-          getList();
-        },
-        (err) => {
-          console.log(err);
-        }
-      );
+    proxy.post("/customerFollowRecords/" + modalType.value, formFollow.data).then(
+      () => {
+        ElMessage({
+          message: modalType.value == "add" ? "添加成功" : "编辑成功",
+          type: "success",
+        });
+        openFollow.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+      }
+    );
   });
 };
 const submitForm = () => {
   submit.value.handleSubmit(() => {
-    if (
-      formData.data.customerUserList &&
-      formData.data.customerUserList.length > 0
-    ) {
+    if (formData.data.customerUserList && formData.data.customerUserList.length > 0) {
       formData.data.tag = formData.data.tags.join(",");
       submitLoading.value = true;
       proxy.post("/customer/" + modalType.value, formData.data).then(
@@ -1214,31 +907,24 @@ const submitForm = () => {
   });
 };
 const getDict = () => {
-  proxy
-    .getDictOne([
-      "customer_tag",
-      "customer_source",
-      "customer_status",
-      "contact_type",
-    ])
-    .then((res) => {
-      customerTag.value = res["customer_tag"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-      customerSource.value = res["customer_source"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-      customerStatus.value = res["customer_status"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-      contactType.value = res["contact_type"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    });
+  proxy.getDictOne(["customer_tag", "customer_source", "customer_status", "contact_type"]).then((res) => {
+    customerTag.value = res["customer_tag"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    customerSource.value = res["customer_source"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    customerStatus.value = res["customer_status"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+    contactType.value = res["contact_type"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
   proxy
     .get("/tenantUser/list", {
       pageNum: 1,
@@ -1365,24 +1051,14 @@ const getContent = (item) => {
   if (item.type === "10") {
     return "跟进记录: " + "报价单总金额 " + proxy.moneyFormat(item.amount, 2);
   } else if (item.type === "20") {
-    return (
-      "跟进记录: " +
-      "合同总金额 " +
-      proxy.moneyFormat(item.amount, 2) +
-      ` (${item.contractCode}) `
-    );
+    return "跟进记录: " + "合同总金额 " + proxy.moneyFormat(item.amount, 2) + ` (${item.contractCode}) `;
   }
 };
 const recordShow = (item) => {
-  if (
-    !(item.fileList && item.fileList.length > 0) &&
-    JSON.stringify(item.fileList) !== "[]"
-  ) {
-    proxy
-      .post("/fileInfo/getList", { businessIdList: [item.id] })
-      .then((fileObj) => {
-        item.fileList = fileObj[item.id] || [];
-      });
+  if (!(item.fileList && item.fileList.length > 0) && JSON.stringify(item.fileList) !== "[]") {
+    proxy.post("/fileInfo/getList", { businessIdList: [item.id] }).then((fileObj) => {
+      item.fileList = fileObj[item.id] || [];
+    });
   }
 };
 const openFile = (path) => {
@@ -1413,19 +1089,8 @@ const clickMore = (item) => {
       })
       .then((fileObj) => {
         for (let i = 0; i < res.rows.length; i++) {
-          recordList.value[
-            parseInt(
-              i + (queryParams.value.pageNum - 1) * queryParams.value.pageSize
-            )
-          ].fileList =
-            fileObj[
-              recordList.value[
-                parseInt(
-                  i +
-                    (queryParams.value.pageNum - 1) * queryParams.value.pageSize
-                )
-              ].id
-            ] || [];
+          recordList.value[parseInt(i + (queryParams.value.pageNum - 1) * queryParams.value.pageSize)].fileList =
+            fileObj[recordList.value[parseInt(i + (queryParams.value.pageNum - 1) * queryParams.value.pageSize)].id] || [];
         }
       });
   });
@@ -1436,10 +1101,7 @@ const infiniteScroll = () => {
   clickMore();
 };
 const judgeTotal = () => {
-  if (
-    queryParams.value.pageNum * queryParams.value.pageSize >=
-    queryParams.value.total
-  ) {
+  if (queryParams.value.pageNum * queryParams.value.pageSize >= queryParams.value.total) {
     return true;
   }
   return false;
@@ -1501,19 +1163,14 @@ const statisticalData = ref({
   customerList: [],
 });
 const obtainStatisticalData = () => {
-  proxy
-    .post("/customer/sourceStatistics", sourceList.value.paginationTwo)
-    .then((res) => {
-      statisticalData.value = res;
-    });
+  proxy.post("/customer/sourceStatistics", sourceList.value.paginationTwo).then((res) => {
+    statisticalData.value = res;
+  });
 };
 obtainStatisticalData();
 const getNum = (val) => {
   let num = 0;
-  if (
-    statisticalData.value.customerList &&
-    statisticalData.value.customerList.length > 0
-  ) {
+  if (statisticalData.value.customerList && statisticalData.value.customerList.length > 0) {
     statisticalData.value.customerList.map((item) => {
       if (sourceList.value.paginationTwo.statisticsType === 1) {
         if (item.source === val) {
@@ -1605,8 +1262,7 @@ const addTagSearchShow = ref(false);
 let copySearch = ref({});
 const moreSearch = () => {
   if (sourceList.value.pagination.tag) {
-    sourceList.value.pagination.tags =
-      sourceList.value.pagination.tag.split(",");
+    sourceList.value.pagination.tags = sourceList.value.pagination.tag.split(",");
   } else {
     sourceList.value.pagination.tags = [];
   }
@@ -1619,12 +1275,8 @@ const cancelSearch = () => {
   openSearch.value = false;
 };
 const submitSearch = () => {
-  if (
-    sourceList.value.pagination.tags &&
-    sourceList.value.pagination.tags.length > 0
-  ) {
-    sourceList.value.pagination.tag =
-      sourceList.value.pagination.tags.join(",");
+  if (sourceList.value.pagination.tags && sourceList.value.pagination.tags.length > 0) {
+    sourceList.value.pagination.tag = sourceList.value.pagination.tags.join(",");
   } else {
     sourceList.value.pagination.tag = "";
   }
@@ -1634,9 +1286,7 @@ const submitSearch = () => {
   getList();
 };
 const tagSearchClose = (val) => {
-  sourceList.value.pagination.tags = sourceList.value.pagination.tags.filter(
-    (item) => item !== val
-  );
+  sourceList.value.pagination.tags = sourceList.value.pagination.tags.filter((item) => item !== val);
 };
 const changeSearchTag = (val) => {
   sourceList.value.pagination.tags.push(val);
@@ -1645,18 +1295,12 @@ const changeSearchTag = (val) => {
 };
 // 判断当前用户有无销售合同页面权限
 const isHave = ref(false);
-if (
-  useUserStore().permissions &&
-  useUserStore().permissions.includes("contract")
-) {
+if (useUserStore().permissions && useUserStore().permissions.includes("contract")) {
   isHave.value = true;
 }
 // 判断当前用户有无报价单页面权限
 const isHaveOne = ref(false);
-if (
-  useUserStore().permissions &&
-  useUserStore().permissions.includes("priceSheet")
-) {
+if (useUserStore().permissions && useUserStore().permissions.includes("priceSheet")) {
   isHaveOne.value = true;
 }
 

+ 13 - 11
src/views/customer/portrait/com/CustomerInfo.vue

@@ -1,22 +1,24 @@
 <template>
   <div class="content" v-loading="loading">
-    <div  class="user-name">
-      <i class="iconfont icon-icon_factory1" style="color:#0084ff;margin-right:10px;"></i>{{ detailsData.name }}
-    </div>
+    <div class="user-name"><i class="iconfont icon-icon_factory1" style="color: #0084ff; margin-right: 10px"></i>{{ detailsData.name }}</div>
     <div class="line">
-      <span class="title_" v-if="detailsData.customerCode">客户代码:<span style="color:#000">{{ detailsData.customerCode }}</span></span>
+      <span class="title_" v-if="detailsData.customerCode">
+        客户代码:<span style="color: #000">{{ detailsData.customerCode }}</span>
+      </span>
       <span class="title_" v-if="detailsData.customerCode && detailsData.status" style="margin: 0 6px">|</span>
-      <span class="title_" v-if="detailsData.status">客户类型:<span style="color:#000">{{ dictValueLabel(detailsData.status, customerStatus) }}</span></span>
+      <span class="title_" v-if="detailsData.status">
+        客户类型:<span style="color: #000">{{ dictValueLabel(detailsData.status, customerStatus) }}</span>
+      </span>
     </div>
     <div class="line" v-if="detailsData.source">
       <span class="title_">客户来源:</span>
       <span>{{ dictValueLabel(detailsData.source, customerSource) }}</span>
     </div>
-    <div class="line">
+    <div class="line" style="word-break: break-all">
       <span class="title_">地址:</span>
-      <span
-        >{{ detailsData.countryName }} , {{ detailsData.provinceName }} ,
-        {{ detailsData.cityName }}
+      <i :class="'iconfont icon-' + detailsData.countryIcon" style="margin-right: 10px"></i>
+      <span>
+        {{ detailsData.countryName }} , {{ detailsData.provinceName }} , {{ detailsData.cityName }}
         <span v-show="detailsData.address"> , {{ detailsData.address }}</span>
       </span>
     </div>
@@ -323,9 +325,9 @@ const getPhone = (res) => {
 </script>
 
 <style lang="scss" scoped>
-.user-name{
+.user-name {
   font-weight: bold;
-  border-bottom:1px solid #dcdcdc;
+  border-bottom: 1px solid #dcdcdc;
   line-height: 30px;
   margin-bottom: 20px;
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 144 - 496
src/views/customer/privatesea/index.vue


+ 259 - 126
src/views/finance/fundManage/accountPayment/index.vue

@@ -13,7 +13,8 @@
         }"
         :action-list="[]"
         @moreSearch="moreSearch"
-        @get-list="getList">
+        @get-list="getList"
+      >
         <template #amount="{ item }">
           <div style="width: 100%">
             <span>{{ item.currency }} {{ item.amount }}</span>
@@ -21,8 +22,20 @@
         </template>
       </byTable>
     </div>
-    <el-dialog title="打款" v-if="dialogVisible" v-model="dialogVisible" width="500" v-loading="loading">
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform">
+    <el-dialog
+      title="打款"
+      v-if="dialogVisible"
+      v-model="dialogVisible"
+      width="500"
+      v-loading="loading"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
         <template #fileSlot>
           <div style="width: 100%">
             <el-upload
@@ -31,14 +44,18 @@
               :data="uploadData"
               multiple
               :before-upload="uploadFile"
-              :on-preview="onPreviewFile">
+              :on-preview="onPreviewFile"
+            >
               <el-button type="primary">文件上传</el-button>
             </el-upload>
           </div>
         </template>
         <template #isTransaction>
           <div style="width: 100%">
-            <el-radio-group v-model="formData.data.isTransaction" @change="changeIsTransaction">
+            <el-radio-group
+              v-model="formData.data.isTransaction"
+              @change="changeIsTransaction"
+            >
               <el-radio label="1" border>是</el-radio>
               <el-radio label="0" border>否</el-radio>
             </el-radio-group>
@@ -46,20 +63,49 @@
         </template>
         <template #transactionDeptId>
           <div style="width: 100%">
-            <el-select v-model="formData.data.transactionDeptId" placeholder="请选择往来单位" style="width: 100%" clearable>
-              <el-option v-for="item in departmentList" :key="item.value" :label="item.label" :value="item.value" />
+            <el-select
+              v-model="formData.data.transactionDeptId"
+              placeholder="请选择往来单位"
+              style="width: 100%"
+              clearable
+              @change="changeTransactionDept"
+            >
+              <el-option
+                v-for="item in departmentList"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
             </el-select>
           </div>
         </template>
       </byForm>
       <template #footer>
         <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitForm()" v-if="!formOption.disabled" size="large" :loading="submitLoading"> 确 定 </el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          v-if="!formOption.disabled"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
       </template>
     </el-dialog>
 
-    <el-dialog title="高级检索" v-if="openSearch" v-model="openSearch" width="600" :before-close="cancelSearch">
-      <byForm :formConfig="formSearchConfig" :formOption="formOptionTwo" v-model="sourceList.pagination">
+    <el-dialog
+      title="高级检索"
+      v-if="openSearch"
+      v-model="openSearch"
+      width="600"
+      :before-close="cancelSearch"
+    >
+      <byForm
+        :formConfig="formSearchConfig"
+        :formOption="formOptionTwo"
+        v-model="sourceList.pagination"
+      >
         <template #departmentId>
           <div>
             <el-tree-select
@@ -70,7 +116,8 @@
               node-key="deptId"
               style="width: 100%"
               :props="defaultProps"
-              clearable />
+              clearable
+            />
           </div>
         </template>
         <template #time>
@@ -82,7 +129,8 @@
                   type="datetime"
                   placeholder="请选择"
                   style="width: 100%"
-                  value-format="YYYY-MM-DD HH:mm:ss" />
+                  value-format="YYYY-MM-DD HH:mm:ss"
+                />
               </el-col>
               <el-col :span="2" style="text-align: center">到</el-col>
               <el-col :span="11">
@@ -91,7 +139,8 @@
                   type="datetime"
                   placeholder="请选择"
                   style="width: 100%"
-                  value-format="YYYY-MM-DD HH:mm:ss" />
+                  value-format="YYYY-MM-DD HH:mm:ss"
+                />
               </el-col>
             </el-row>
           </div>
@@ -105,7 +154,8 @@
                   type="datetime"
                   placeholder="请选择"
                   style="width: 100%"
-                  value-format="YYYY-MM-DD HH:mm:ss" />
+                  value-format="YYYY-MM-DD HH:mm:ss"
+                />
               </el-col>
               <el-col :span="2" style="text-align: center">到</el-col>
               <el-col :span="11">
@@ -114,7 +164,8 @@
                   type="datetime"
                   placeholder="请选择"
                   style="width: 100%"
-                  value-format="YYYY-MM-DD HH:mm:ss" />
+                  value-format="YYYY-MM-DD HH:mm:ss"
+                />
               </el-col>
             </el-row>
           </div>
@@ -130,7 +181,8 @@
                   style="width: 100%"
                   :precision="2"
                   :controls="false"
-                  :min="0" />
+                  :min="0"
+                />
               </el-col>
               <el-col :span="2" style="text-align: center">到</el-col>
               <el-col :span="11">
@@ -141,7 +193,8 @@
                   style="width: 100%"
                   :precision="2"
                   :controls="false"
-                  :min="0" />
+                  :min="0"
+                />
               </el-col>
             </el-row>
           </div>
@@ -149,7 +202,9 @@
       </byForm>
       <template #footer>
         <el-button @click="cancelSearch()" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitSearch()" size="large">确 定</el-button>
+        <el-button type="primary" @click="submitSearch()" size="large"
+          >确 定</el-button
+        >
       </template>
     </el-dialog>
 
@@ -161,26 +216,48 @@
       <template #footer>
         <el-button @click="openPrint = false" size="large">取消</el-button>
         <el-button v-print="printObj" size="large">打印</el-button>
-        <el-button type="primary" @click="clickDownload()" size="large">下载PDF</el-button>
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
       </template>
     </el-dialog>
 
-    <el-dialog title="冲销" v-if="openCancelledOut" v-model="openCancelledOut" width="500">
+    <el-dialog
+      title="冲销"
+      v-if="openCancelledOut"
+      v-model="openCancelledOut"
+      width="500"
+    >
       <byForm
         :formConfig="formCancelledOutConfig"
         :formOption="formOptionTwo"
         v-model="formCancelledOutData.data"
         :rules="rulesCancelledOut"
-        ref="cancelledOut">
+        ref="cancelledOut"
+      >
         <template #detail>
           <div style="width: 100%">
-            <el-button type="primary" style="margin-left: -15px" @click="clickDetail" text>查看详情</el-button>
+            <el-button
+              type="primary"
+              style="margin-left: -15px"
+              @click="clickDetail"
+              text
+              >查看详情</el-button
+            >
           </div>
         </template>
       </byForm>
       <template #footer>
-        <el-button @click="openCancelledOut = false" size="large">取 消</el-button>
-        <el-button type="danger" @click="submitCancelledOutForm()" size="large" :loading="submitCancelledOutLoading">冲 销</el-button>
+        <el-button @click="openCancelledOut = false" size="large"
+          >取 消</el-button
+        >
+        <el-button
+          type="danger"
+          @click="submitCancelledOutForm()"
+          size="large"
+          :loading="submitCancelledOutLoading"
+          >冲 销</el-button
+        >
       </template>
     </el-dialog>
   </div>
@@ -221,11 +298,15 @@ const sourceList = ref({
   },
 });
 let dialogVisible = ref(false);
+const submitType = ref("add");
 let rules = ref({
-  productClassifyId: [{ required: true, message: "请选择物料分类", trigger: "change" }],
-  type: [{ required: true, message: "请选择物料类型", trigger: "change" }],
-  isTransaction: [{ required: true, message: "请选择是否往来", trigger: "change" }],
-  transactionDeptId: [{ required: true, message: "请选择往来单位", trigger: "change" }],
+  isTransaction: [
+    { required: true, message: "请选择是否往来", trigger: "change" },
+  ],
+  transactionDeptId: [
+    { required: true, message: "请选择往来单位", trigger: "change" },
+  ],
+  amount: [{ required: true, message: "请输入付款金额", trigger: "blur" }],
 });
 const accountCurrency = ref([]);
 const accountList = ref([]);
@@ -330,7 +411,7 @@ const config = computed(() => {
       },
       renderHTML(row) {
         return [
-          row.status == "20"
+          row.status != "10"
             ? {
                 attrs: {
                   label: "打款",
@@ -340,6 +421,7 @@ const config = computed(() => {
                 el: "button",
                 click() {
                   formOption.disabled = false;
+                  submitType.value = "add";
                   getDtl(row);
                 },
               }
@@ -351,11 +433,15 @@ const config = computed(() => {
                 },
                 el: "button",
                 click(item) {
-                  ElMessageBox.confirm("冲销后,已生成的资金流水数据会被删除,且关联的数据状态会由“已打款”退回至“未打款”,并支持重新打款。是否继续?", "提示", {
-                    confirmButtonText: "继续",
-                    cancelButtonText: "取消",
-                    type: "warning",
-                  })
+                  ElMessageBox.confirm(
+                    "冲销后,已生成的资金流水数据会被删除,且关联的数据状态会由“已打款”退回至“未打款”,并支持重新打款。是否继续?",
+                    "提示",
+                    {
+                      confirmButtonText: "继续",
+                      cancelButtonText: "取消",
+                      type: "warning",
+                    }
+                  )
                     .then(() => {
                       rowData.value = item;
                       formCancelledOutData.data = {
@@ -387,6 +473,7 @@ const config = computed(() => {
             el: "button",
             click() {
               formOption.disabled = true;
+              submitType.value = "edit";
               getDtl(row);
             },
           },
@@ -416,7 +503,6 @@ const formOptionTwo = reactive({
   disabled: false,
 });
 const byform = ref(null);
-const treeListData = ref([]);
 const formConfig = computed(() => {
   return [
     {
@@ -483,24 +569,41 @@ const formConfig = computed(() => {
       label: "付款账户",
       required: true,
       data: accountList.value,
+      itemWidth: 50.1,
+      style: {
+        width: "100%",
+      },
     },
     {
-      type: "selectInput",
+      type: "select",
       label: "付款金额",
-      itemWidth: 60,
-      prop: "amount",
+      prop: "currency",
       data: accountCurrency.value,
-      placeholder: "请输入",
-      selectPlaceholder: "币种",
-      selectProp: "currency",
+      itemWidth: 50,
       disabled: true,
     },
     {
+      type: "number",
+      prop: "amount",
+      label: " ",
+      itemWidth: 50,
+      precision: 2,
+      min: 0,
+      controls: false,
+      style: {
+        width: "100%",
+      },
+    },
+    {
       type: "date",
       itemType: "datetime",
       prop: "expensesTime",
       label: "打款时间",
       format: "YYYY-MM-DD HH:mm:ss",
+      itemWidth: 50,
+      style: {
+        width: "100%",
+      },
     },
     formData.data.type != "20"
       ? {
@@ -557,46 +660,52 @@ const recursive = (data) => {
   });
 };
 const getDict = () => {
-  proxy.getDict(["account_currency", "founds_type", "funds_payment_method"]).then((res) => {
-    accountCurrency.value = res.account_currency.map((item) => {
-      return {
-        label: item.dictValue,
-        value: item.dictKey,
-      };
-    });
-    fundsType.value = res.founds_type.map((item) => {
-      return {
-        label: item.dictValue,
-        value: item.dictKey,
-      };
-    });
-    fundsPaymentMethod.value = res.funds_payment_method.map((item) => {
-      return {
-        label: item.dictValue,
-        value: item.dictKey,
-      };
-    });
-  });
-  proxy.post("/accountManagement/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
-    if (res.rows && res.rows.length > 0) {
-      accountList.value = res.rows.map((item) => {
+  proxy
+    .getDict(["account_currency", "founds_type", "funds_payment_method"])
+    .then((res) => {
+      accountCurrency.value = res.account_currency.map((item) => {
         return {
-          label: item.alias + " (" + item.name + ")",
-          value: item.id,
+          label: item.dictValue,
+          value: item.dictKey,
         };
       });
-    }
-  });
-  proxy.post("/corporation/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
-    if (res.rows && res.rows.length > 0) {
-      companyData.value = res.rows.map((item) => {
+      fundsType.value = res.founds_type.map((item) => {
         return {
-          label: item.name,
-          value: item.id,
+          label: item.dictValue,
+          value: item.dictKey,
         };
       });
-    }
-  });
+      fundsPaymentMethod.value = res.funds_payment_method.map((item) => {
+        return {
+          label: item.dictValue,
+          value: item.dictKey,
+        };
+      });
+    });
+  proxy
+    .post("/accountManagement/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        accountList.value = res.rows.map((item) => {
+          return {
+            label: item.alias + " (" + item.name + ")",
+            value: item.id,
+          };
+        });
+      }
+    });
+  proxy
+    .post("/corporation/page", { pageNum: 1, pageSize: 9999 })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        companyData.value = res.rows.map((item) => {
+          return {
+            label: item.name,
+            value: item.id,
+          };
+        });
+      }
+    });
   proxy
     .get("/tenantDept/list", {
       pageNum: 1,
@@ -632,31 +741,35 @@ const getDict = () => {
         });
       }
     });
-  proxy.get("/transactionDepartment/list", { pageNum: 1, pageSize: 999 }).then((res) => {
-    if (res.data && res.data.length > 0) {
-      departmentList.value = res.data.map((item) => {
-        return {
-          ...item,
-          label: item.name,
-          value: item.id,
-        };
-      });
-    } else {
-      departmentList.value = [];
-    }
-  });
+  proxy
+    .get("/transactionDepartment/list", { pageNum: 1, pageSize: 999 })
+    .then((res) => {
+      if (res.data && res.data.length > 0) {
+        departmentList.value = res.data.map((item) => {
+          return {
+            ...item,
+            label: item.name,
+            value: item.id,
+          };
+        });
+      } else {
+        departmentList.value = [];
+      }
+    });
 };
 getDict();
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
-  proxy.post("/accountPayment/page", sourceList.value.pagination).then((message) => {
-    sourceList.value.data = message.rows;
-    sourceList.value.pagination.total = message.total;
-    setTimeout(() => {
-      loading.value = false;
-    }, 200);
-  });
+  proxy
+    .post("/accountPayment/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
 };
 const paymentType = ref([
   {
@@ -664,6 +777,10 @@ const paymentType = ref([
     value: 10,
   },
   {
+    label: "部分打款",
+    value: 15,
+  },
+  {
     label: "未打款",
     value: 20,
   },
@@ -704,41 +821,40 @@ const submitForm = () => {
     );
   });
 };
-const getTreeList = () => {
-  proxy
-    .post("/productClassify/tree", {
-      parentId: "",
-      name: "",
-      definition: "2",
-    })
-    .then((message) => {
-      treeListData.value = message;
-      formConfig.value[0].data = message;
-    });
-};
+
 const getDtl = (row) => {
   proxy.post("/accountPayment/detail", { id: row.id }).then((res) => {
     formData.data = res;
+    if (submitType.value === "add") {
+      formData.data.expensesTime = moment().format("yyyy-MM-DD HH:mm:ss");
+      formData.data.currency = row.currency;
+      formData.data.amount = Number(
+        parseFloat(res.incomeAmount - res.amount).toFixed(2)
+      );
+    } else {
+      formData.data.expensesTime = formData.data.updateTime;
+    }
     formData.data.remark = proxy.deepClone(res.paymentRemark);
-    formData.data.expensesTime = moment().format("yyyy-MM-DD HH:mm:ss");
-    proxy.post("/fileInfo/getList", { businessIdList: [row.id] }).then((fileObj) => {
-      formData.data.fileList = fileObj[row.id] || [];
-      if (formData.data.fileList && formData.data.fileList.length > 0) {
-        fileList.value = formData.data.fileList.map((item) => {
-          return {
-            raw: item,
-            name: item.fileName,
-            url: item.fileUrl,
-          };
-        });
-      } else {
-        fileList.value = [];
-      }
-    });
+    proxy
+      .post("/fileInfo/getList", { businessIdList: [row.id] })
+      .then((fileObj) => {
+        formData.data.fileList = fileObj[row.id] || [];
+        if (formData.data.fileList && formData.data.fileList.length > 0) {
+          fileList.value = formData.data.fileList.map((item) => {
+            return {
+              raw: item,
+              name: item.fileName,
+              url: item.fileUrl,
+            };
+          });
+        } else {
+          fileList.value = [];
+        }
+      });
     dialogVisible.value = true;
   });
 };
-getTreeList();
+
 getList();
 const openSearch = ref(false);
 const formSearchConfig = computed(() => {
@@ -819,14 +935,16 @@ const submitSearch = () => {
   if (
     sourceList.value.pagination.startAmount &&
     sourceList.value.pagination.endAmount &&
-    Number(sourceList.value.pagination.startAmount) > Number(sourceList.value.pagination.endAmount)
+    Number(sourceList.value.pagination.startAmount) >
+      Number(sourceList.value.pagination.endAmount)
   ) {
     return ElMessage("交易金额输入错误");
   }
   if (
     sourceList.value.pagination.beginCreateTime &&
     sourceList.value.pagination.endCreateTime &&
-    sourceList.value.pagination.beginCreateTime > sourceList.value.pagination.endCreateTime
+    sourceList.value.pagination.beginCreateTime >
+      sourceList.value.pagination.endCreateTime
   ) {
     return ElMessage("开始时间不能大于结束时间");
   }
@@ -903,16 +1021,31 @@ const submitCancelledOutForm = () => {
 };
 const clickDetail = () => {
   formOption.disabled = true;
+  submitType.value = "edit";
   getDtl(rowData.value);
 };
 const printObj = ref({
   id: "printMe",
   popTitle: "",
-  extraCss: "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
   extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
 });
 const changeIsTransaction = () => {
   formData.data.transactionDeptId = "";
+  formData.data.deptType = "";
+};
+const changeTransactionDept = (val) => {
+  if (val) {
+    let list = departmentList.value.filter((item) => item.id === val);
+    if (list && list.length > 0) {
+      formData.data.deptType = list[0].deptType;
+    } else {
+      formData.data.deptType = "";
+    }
+  } else {
+    formData.data.deptType = "";
+  }
 };
 </script>
 

+ 33 - 3
src/views/finance/fundManage/accountStatement/index.vue

@@ -489,6 +489,7 @@ let transferMoneyModal = ref(false);
 const openTransferMoney = () => {
   formData2.data = {
     transactionTime: moment().format("yyyy-MM-DD HH:mm:ss"),
+    isTransaction: '0'
   };
   transferMoneyModal.value = true;
 };
@@ -563,8 +564,23 @@ const transferMoneyConfig = computed(() => {
       label: "其他信息",
     },
     {
-      type: "selectInput",
-      label: "手续费",
+      type: "radio",
+      prop: "isTransaction",
+      label: "是否往来",
+      data: [
+        {
+          label: "是",
+          value: '1',
+        },
+        {
+          label: "否",
+          value: '0',
+        },
+      ],
+    },
+    {
+			type: 'selectInput',
+			label: '手续费',
       prop: "commissionAmount",
       itemWidth: 60,
       data: accountCurrency.value,
@@ -732,7 +748,9 @@ const formConfig = computed(() => {
         },
       ],
       fn: (val) => {
-        formData.data.transactionDeptId = "";
+        formData.data.transactionDeptId = ''
+        formData.data.deptType = "";
+        formConfig.value[7].data = transactionDepartmentData.value
       },
     },
     {
@@ -741,6 +759,18 @@ const formConfig = computed(() => {
       label: "往来单位",
       data: transactionDepartmentData.value,
       isShow: formData.data.isTransaction == "1",
+      fn: (val) => {
+        if (val) {
+          let list = transactionDepartmentData.value.filter((item) => item.id === val);
+          if (list && list.length > 0) {
+            formData.data.deptType = list[0].deptType;
+          } else {
+            formData.data.deptType = "";
+          }
+        } else {
+          formData.data.deptType = "";
+        }
+      },
     },
     {
       type: "title",

+ 9 - 2
src/views/finance/fundManage/comeAndGo/index.vue

@@ -35,8 +35,8 @@
           <el-table-column label="备注" prop="remark" />
           <el-table-column label="操作" align="center" width="120" fixed="right">
             <template #default="{ row }">
-              <el-button type="primary" link @click="handleUpdate(row)">修改</el-button>
-              <el-button type="primary" link @click="handleDelete(row)">删除</el-button>
+              <el-button type="primary" v-if="row.deptType !== 1" link @click="handleUpdate(row)">修改</el-button>
+              <el-button type="primary" v-if="row.deptType !== 1" link @click="handleDelete(row)">删除</el-button>
             </template>
           </el-table-column>
         </el-table>
@@ -194,6 +194,13 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "归属公司",
+        prop: "corporationName",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
         label: "备注",
         prop: "remark",
         "min-width": 240,

+ 29 - 1
src/views/finance/fundManage/flow/index.vue

@@ -409,6 +409,7 @@ let transferMoneyModal = ref(false);
 const openTransferMoney = () => {
   formData2.data = {
     transactionTime: moment().format("yyyy-MM-DD HH:mm:ss"),
+    isTransaction: '0'
   };
   transferMoneyModal.value = true;
 };
@@ -499,6 +500,21 @@ const transferMoneyConfig = computed(() => {
       label: "其他信息",
     },
     {
+      type: "radio",
+      prop: "isTransaction",
+      label: "是否往来",
+      data: [
+        {
+          label: "是",
+          value: '1',
+        },
+        {
+          label: "否",
+          value: '0',
+        },
+      ],
+    },
+    {
 			type: 'selectInput',
 			label: '手续费',
       prop: "commissionAmount",
@@ -569,6 +585,7 @@ const formConfig = computed(() => {
       ],
       fn: (val) => {
         formData.data.transactionDeptId = ''
+        formData.data.deptType = "";
         formConfig.value[7].data = transactionDepartmentData.value
       },
     },
@@ -578,7 +595,18 @@ const formConfig = computed(() => {
       label: "往来单位",
       data: [],
       isShow: formData.data.isTransaction == 1,
-      
+      fn: (val) => {
+        if (val) {
+          let list = transactionDepartmentData.value.filter((item) => item.id === val);
+          if (list && list.length > 0) {
+            formData.data.deptType = list[0].deptType;
+          } else {
+            formData.data.deptType = "";
+          }
+        } else {
+          formData.data.deptType = "";
+        }
+      },
     },
     {
       type: "input",

+ 84 - 33
src/views/purchaseManage/supplier/supplier/index.vue

@@ -45,12 +45,20 @@
           <div>
             <el-select
               v-model="formData.data.countryId"
-              placeholder="国家"
-              @change="(val) => getCityData(val, '20', true)"
+              filterable
+              remote
+              reserve-keyword
+              placeholder="请输入关键字"
+              remote-show-suffix
+              no-data-text="无数据,请联系管理员添加"
+              :loading="loadingSearch"
+              :remote-method="(val) => remoteMethod(val, '0')"
+              @input="(val) => remoteMethod(val, '0')"
+              @change="(val) => getCityData(val, '20')"
             >
               <el-option
                 v-for="item in countryData"
-                :label="item.chineseName"
+                :label="item.name"
                 :value="item.id"
               >
               </el-option>
@@ -60,28 +68,50 @@
 
         <template #provinceId>
           <div>
-            <selectCity
-              placeholder="省/洲"
-              @change="(val) => getCityData(val, '30', true)"
-              addressId="provinceId"
-              addressName="provinceName"
-              v-model="formData.data"
-              :data="provinceData"
+            <el-select
+              v-model="formData.data.provinceId"
+              filterable
+              remote
+              reserve-keyword
+              placeholder="请输入关键字"
+              remote-show-suffix
+              no-data-text="无数据,请联系管理员添加"
+              :loading="loadingSearchProvince"
+              :remote-method="(val) => remoteMethod(val, '1')"
+              @input="(val) => remoteMethod(val, '1')"
+              @change="(val) => getCityData(val, '30')"
             >
-            </selectCity>
+              <el-option
+                v-for="item in provinceData"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
           </div>
         </template>
 
         <template #cityId>
           <div>
-            <selectCity
-              placeholder="城市"
-              addressId="cityId"
-              addressName="cityName"
-              v-model="formData.data"
-              :data="cityData"
+            <el-select
+              v-model="formData.data.cityId"
+              filterable
+              remote
+              reserve-keyword
+              placeholder="请输入关键字"
+              remote-show-suffix
+              no-data-text="无数据,请联系管理员添加"
+              :loading="loadingSearchCity"
+              :remote-method="(val) => remoteMethod(val, '2')"
+              @input="(val) => remoteMethod(val, '2')"
             >
-            </selectCity>
+              <el-option
+                v-for="item in cityData"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
           </div>
         </template>
 
@@ -513,24 +543,14 @@ const getDtl = (row) => {
 const countryData = ref([]);
 const provinceData = ref([]);
 const cityData = ref([]);
-const getCityData = (id, type, flag) => {
-  proxy.post("/customizeArea/list", { parentId: id }).then((res) => {
+const getCityData = (id, type) => {
+  proxy.post("/customizeArea/page", { parentId: id }).then((res) => {
     if (type === "20") {
-      provinceData.value = res;
-      if (flag) {
-        formData.data.provinceId = "";
-        formData.data.provinceName = "";
-        formData.data.cityId = "";
-        formData.data.cityName = "";
-      }
+      provinceData.value = res.rows;
     } else if (type === "30") {
-      cityData.value = res;
-      if (flag) {
-        formData.data.cityId = "";
-        formData.data.cityName = "";
-      }
+      cityData.value = res.rows;
     } else {
-      countryData.value = res;
+      countryData.value = res.rows;
     }
   });
 };
@@ -547,6 +567,37 @@ const getDict = () => {
 getDict();
 getCityData("0");
 getList();
+
+const loadingSearch = ref(false);
+const loadingSearchProvince = ref(false);
+const loadingSearchCity = ref(false);
+const remoteMethod = (keyword, type) => {
+  if (keyword && typeof keyword === "string") {
+    let parentId = "0";
+    if (type == "0") {
+      loadingSearch.value = true;
+    } else if (type == "1") {
+      parentId = formData.data.countryId;
+      loadingSearchProvince.value = true;
+    } else if (type == "2") {
+      parentId = formData.data.provinceId;
+      loadingSearchCity.value = true;
+    }
+    proxy.post("/customizeArea/page", { parentId, keyword }).then((res) => {
+      if (type == "0") {
+        countryData.value = res.rows;
+        loadingSearch.value = false;
+      } else if (type == "1") {
+        provinceData.value = res.rows;
+        loadingSearchProvince.value = false;
+      } else if (type == "2") {
+        cityData.value = res.rows;
+        loadingSearchCity.value = false;
+      }
+    });
+  }
+  return;
+};
 </script>
 
 <style lang="scss" scoped>

+ 1 - 1
src/views/salesMange/saleContract/middle/index.vue

@@ -563,7 +563,7 @@ const getList = async (req) => {
     }, 200);
   });
 };
-getDict();
+getDict(); 
 getList();
 const openPrint = ref(false);
 const printDetails = ref({

+ 399 - 0
src/views/salesMange/salesMange/invoice/index.vue

@@ -0,0 +1,399 @@
+<template>
+  <div class="tenant">
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      highlight-current-row
+      :selectConfig="selectConfig"
+      :table-events="{
+        select: select,
+      }"
+      :action-list="[
+        {
+          text: '添加发票',
+          action: () => openModal('add'),
+        },
+      ]"
+      @get-list="getList">
+    </byTable>
+
+    <el-dialog title="添加发票" v-if="dialogVisible" v-model="dialogVisible" width="600">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
+        <template #contract>
+          <div style="width: 100%">
+            <div style="margin-bottom: 10px">
+              <el-button @click="clickAdd">添加行</el-button>
+            </div>
+            <el-table :data="formData.data.invoiceDetailsList" style="width: 100%; margin-top: 16px">
+              <el-table-column label="合同编号" min-width="200">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item :prop="'invoiceDetailsList.' + $index + '.contractId'" :rules="rules.contractId" :inline-message="true">
+                      <el-select v-model="row.contractId" placeholder="请选择合同编号" style="width: 100%">
+                        <el-option v-for="item in contractList" :key="item.value" :label="item.label" :value="item.value" />
+                      </el-select>
+                    </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="'invoiceDetailsList.' + $index + '.money'" :rules="rules.money" :inline-message="true">
+                      <el-input-number
+                        onmousewheel="return false;"
+                        v-model="row.money"
+                        placeholder="请输入关联金额"
+                        style="width: 100%"
+                        :controls="false"
+                        :min="0"
+                        :precision="2" />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="操作" width="80" fixed="right">
+                <template #default="{ $index }">
+                  <el-button type="primary" link @click="handleRemove($index)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="large" :loading="submitLoading"> 确 定 </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import { computed, ref } from "vue";
+import useUserStore from "@/store/modules/user";
+
+const { proxy } = getCurrentInstance();
+const customerList = ref([]);
+const corporationList = ref([]);
+const contractList = ref([]);
+const invoiceType = ref([]);
+const loading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    corporationId: "",
+  },
+});
+const selectConfig = computed(() => {
+  return [
+    {
+      label: "归属公司",
+      prop: "corporationId",
+      data: corporationList.value,
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "归属公司",
+        prop: "corporationName",
+      },
+    },
+    {
+      attrs: {
+        label: "客户名称",
+        prop: "customerName",
+      },
+    },
+    {
+      attrs: {
+        label: "发票金额",
+        prop: "money",
+        width: 160,
+      },
+    },
+    {
+      attrs: {
+        label: "开票时间",
+        prop: "createTime",
+        width: 160,
+      },
+    },
+    {
+      attrs: {
+        label: "创建人",
+        prop: "userName",
+        width: 160,
+      },
+    },
+    {
+      attrs: {
+        label: "关联合同",
+        prop: "contractCodes",
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "80",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "删除",
+              type: "danger",
+              text: true,
+            },
+            el: "button",
+            click() {
+              ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+              }).then(() => {
+                proxy
+                  .post("/supplierInfo/delete", {
+                    id: row.id,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "删除成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const getDict = () => {
+  proxy.post("/customer/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      customerList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "invoice_type",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        invoiceType.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      corporationList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+};
+getDict();
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/contractInvoice/page", sourceList.value.pagination).then((message) => {
+    sourceList.value.data = message.rows;
+    sourceList.value.pagination.total = message.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getList();
+const dialogVisible = ref(false);
+const submit = ref(null);
+const submitLoading = ref(false);
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      label: "归属公司",
+      prop: "corporationId",
+      data: corporationList.value,
+      style: {
+        width: "100%",
+      },
+    },
+    {
+      type: "select",
+      label: "发票类型",
+      prop: "type",
+      data: invoiceType.value,
+      style: {
+        width: "100%",
+      },
+    },
+    {
+      type: "select",
+      label: "客户名称",
+      prop: "customerId",
+      data: customerList.value,
+      style: {
+        width: "100%",
+      },
+      fn: (val) => {
+        if (val) {
+          proxy.post("/contract/page", { pageNum: 1, pageSize: 9999, customerId: val }).then((res) => {
+            if (res.rows && res.rows.length > 0) {
+              contractList.value = res.rows.map((item) => {
+                return {
+                  label: item.code,
+                  value: item.id,
+                };
+              });
+            } else {
+              contractList.value = [];
+            }
+          });
+        } else {
+          contractList.value = [];
+        }
+        formData.data.invoiceDetailsList = [
+          {
+            contractId: "",
+            money: undefined,
+            remark: "",
+          },
+        ];
+      },
+    },
+    {
+      type: "number",
+      prop: "money",
+      label: "发票金额",
+      precision: 2,
+      min: 0,
+      controls: false,
+      style: {
+        width: "100%",
+      },
+    },
+    {
+      type: "input",
+      label: "发票明细",
+      prop: "remark",
+      itemType: "textarea",
+    },
+    {
+      type: "slot",
+      slotName: "contract",
+      label: "关联合同",
+    },
+  ];
+});
+const rules = ref({
+  corporationId: [{ required: true, message: "请选择归属公司", trigger: "change" }],
+  type: [{ required: true, message: "请选择发票类型", trigger: "change" }],
+  customerId: [{ required: true, message: "请选择客户名称", trigger: "change" }],
+  money: [{ required: true, message: "请输入金额", trigger: "blur" }],
+  contractId: [{ required: true, message: "请选择合同编号", trigger: "change" }],
+});
+const openModal = () => {
+  formData.data = {
+    invoiceDetailsList: [
+      {
+        contractId: "",
+        money: undefined,
+        remark: "",
+      },
+    ],
+  };
+  dialogVisible.value = true;
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    if (!(formData.data.invoiceDetailsList && formData.data.invoiceDetailsList.length > 0)) {
+      return ElMessage("请添加关联合同");
+    }
+    for (let i = 0; i < formData.data.invoiceDetailsList.length; i++) {
+      for (let j = i + 1; j < formData.data.invoiceDetailsList.length; j++) {
+        if (formData.data.invoiceDetailsList[i].contractId === formData.data.invoiceDetailsList[j].contractId) {
+          return ElMessage("关联合同重复选择");
+        }
+      }
+    }
+    submitLoading.value = true;
+    proxy.post("/contractInvoice/add", formData.data).then(
+      () => {
+        ElMessage({ message: "添加成功", type: "success" });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+const clickAdd = () => {
+  if (!(formData.data.invoiceDetailsList && formData.data.invoiceDetailsList.length > 0)) {
+    formData.data.invoiceDetailsList = [];
+  }
+  formData.data.invoiceDetailsList.push({
+    contractId: "",
+    money: undefined,
+    remark: "",
+  });
+};
+const handleRemove = (index) => {
+  formData.data.invoiceDetailsList.splice(index, 1);
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 107 - 0
src/views/salesMange/salesMange/profitSettlement/index.vue

@@ -8,6 +8,7 @@
       :config="config"
       :loading="loading"
       :selectConfig="selectConfig"
+      :statConfig='statConfig'
       highlight-current-row
       :action-list="[
         
@@ -384,6 +385,9 @@ const sourceList = ref({
   },
 });
 const loading = ref(false);
+
+let statConfig = ref([])
+
 const selectConfig = computed(() => {
   return [
     {
@@ -454,6 +458,7 @@ const getDict = () => {
 const getList = async (req) => {
   sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
   loading.value = true;
+  getTotal()
   proxy
     .post("/saleStatement/getProfitSettlement", sourceList.value.pagination)
     .then((res) => {
@@ -464,6 +469,108 @@ const getList = async (req) => {
       }, 200);
     });
 };
+//获取统计数据
+const getTotal = () => {
+  proxy.post("/saleStatement/getProfitSettlementHead", sourceList.value.pagination).then(
+    (res) => {
+      
+      statConfig.value = [{
+        label: '统计',
+        data:[
+          //一个卡牌多数据配置
+          {
+            label:'订单统计(CNY)',
+            type:2,
+            data:[
+              {
+                label:'订单数',
+                num:res.contractCount,
+                color:'#9E64ED',
+              },
+              {
+                label:'销售总金额',
+                num:res.contractSumAmount,
+                color:'#9E64ED',
+              },
+              {
+                label:'采购总金额',
+                num:res.purchaseSumAmount,
+                color:'#9E64ED',
+              },
+            ]
+          },
+          {
+            label:'收入统计(CNY)',
+            type:3,
+            data:[
+              {
+                label:'合同到账',
+                num:res.contractArrivalSumAmount,
+                color:'#FF9315',
+              },
+              {
+                label:'退税',
+                num:res.taxReturnMoneySumAmount,
+                color:'#FF9315',
+              },
+              {
+                label:'其他收入',
+                num:res.otherIncomeSumAmount,
+                color:'#FF9315',
+              },
+            ]
+          },
+          {
+            label:'支出统计(CNY)',
+            type:5,
+            data:[
+              {
+                label:'支付货款',
+                num:res.payForGoodsSumAmount,
+                color:'#F94539',
+              },
+              {
+                label:'其他支出',
+                num:res.otherExpensesSumAmount,
+                color:'#F94539',
+              },
+            ]
+          },
+          {
+            label:'收支统计(CNY)',
+            type:1,
+            data:[
+              {
+                label:'总收入',
+                num:res.totalIncomeSumAmount,
+                color:'#0084FF',
+              },
+              {
+                label:'总支出',
+                num:res.totalExpensesSumAmount,
+                color:'#0084FF',
+              },
+              {
+                label:'总毛利',
+                num:res.grossProfitSum,
+                color:'#0084FF',
+              },
+              {
+                label:'毛利率',
+                num:res.GrossProfitMargin + '%',
+                color:'#0084FF',
+              },
+            ]
+          },
+        ],
+      }]
+    },
+    (err) => {
+      
+    }
+  );
+}
+
 const rateStatus = ref(false);
 const judgeRate = () => {
   proxy.post("/currencyRate/list", {}).then(

+ 875 - 0
src/views/salesMange/shipmentMange/packing/index copy.vue

@@ -0,0 +1,875 @@
+<template>
+  <div class="tenant">
+    <!-- <Banner /> -->
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          //element talbe事件都能传
+          select: selectRow,
+          'select-all': selectRow,
+        }"
+        :action-list="[
+          {
+            text: '出货',
+            disabled: selectData.length === 0,
+            action: () => openModalOne(),
+          },
+          {
+            text: '产品装箱',
+            action: () => openModal(),
+          },
+        ]"
+        @get-list="getList">
+        <template #code="{ item }">
+          <div>
+            <div v-for="(item, index) in getData(item.codeAPName, 'code')" :key="index">
+              {{ item }}
+            </div>
+          </div>
+        </template>
+        <template #productName="{ item }">
+          <div>
+            <div v-for="(item, index) in getData(item.codeAPName, 'productName')" :key="index">
+              {{ item }}
+            </div>
+          </div>
+        </template>
+        <template #netWeight="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.netWeight + " kg" }}
+            </div>
+          </div>
+        </template>
+        <template #roughWeight="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.roughWeight + " kg" }}
+            </div>
+          </div>
+        </template>
+        <template #boxLong="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.boxLong + " cm" }}
+            </div>
+          </div>
+        </template>
+        <template #boxWide="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.boxWide + " cm" }}
+            </div>
+          </div>
+        </template>
+        <template #boxHigh="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.boxHigh + " cm" }}
+            </div>
+          </div>
+        </template>
+        <template #bomVolume="{ item }">
+          <div>
+            <div v-for="(i, index) in item.dataJsonListCopy" :key="index">
+              {{ i.bomVolume + " m³" }}
+            </div>
+          </div>
+        </template>
+      </byTable>
+    </div>
+    <el-dialog title="产品装箱" v-model="dialogVisible" width="80%" v-loading="loading">
+      <el-form :model="formData.data" :rules="rules" ref="formDom" label-position="top">
+        <el-row :gutter="10">
+          <el-col :span="8">
+            <el-form-item label="客户名称" prop="customerId">
+              <el-select v-model="formData.data.customerId" placeholder="请选择" @change="handleChangeCustomer" filterable style="width: 100%">
+                <el-option v-for="item in customerList" :label="item.name" :value="item.id"> </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="选择合同" prop="contractIds">
+          <el-select v-model="formData.data.contractIds" placeholder="请选择" @change="handleChangeContract" filterable style="width: 100%" multiple>
+            <el-option v-for="item in contractData" :label="item.code" :value="item.id"> </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="合同明细" prop="contractProductData">
+          <el-table :data="formData.data.contractProductData" @select="handleSelectProduct" @select-all="handleSelectProduct" ref="tableDom">
+            <el-table-column type="selection" label="" width="50" />
+            <el-table-column prop="contractCode" label="合同编码" width="160" />
+            <el-table-column prop="productName" label="产品名称" min-width="180" />
+            <el-table-column prop="productSpec" label="规格型号" min-width="140" />
+            <el-table-column prop="cpQuantity" label="合同数量" width="140" />
+            <el-table-column prop="waitQuantity" label="待装箱数量" width="140" />
+            <el-table-column prop="quantity" label="装箱数量" width="160">
+              <template #default="{ row, $index }">
+                <el-form-item :prop="'contractProductData.' + $index + '.quantity'" :inline-message="true">
+                  <el-input-number v-model="row.quantity" :precision="4" :controls="false" :min="0" onmousewheel="return false;" />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-button type="primary" style="margin-top: 10px; width: 100%" @click="handleClickPacking"> 装箱 </el-button>
+        </el-form-item>
+        <el-form-item label="装箱明细" prop="packDetailList">
+          <div class="box" v-for="(item, index) in formData.data.packDetailList" :key="index">
+            <div ref="" style="position: relative">
+              <span>箱规</span>
+              <el-button type="primary" style="position: absolute; right: 0px; top: 0px" @click="clickDelete(index)" text>删除</el-button>
+            </div>
+            <el-row :gutter="10">
+              <el-col :span="5">
+                <el-form-item label="箱数" :prop="'packDetailList.' + index + '.packQuantity'" :rules="rules.packQuantity">
+                  <el-input-number
+                    v-model="item.packQuantity"
+                    :precision="0"
+                    :controls="false"
+                    :min="1"
+                    placeholder="请输入"
+                    onmousewheel="return false;"
+                    @change="(val) => handleChangePackQuantity(val, index)" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="5">
+                <el-form-item label="净重(kg)" :prop="'packDetailList.' + index + '.netWeight'" :rules="rules.netWeight">
+                  <el-input-number v-model="item.netWeight" :precision="2" :controls="false" :min="0" placeholder="请输入" onmousewheel="return false;" />
+                </el-form-item>
+              </el-col>
+
+              <el-col :span="5">
+                <el-form-item label="毛重(kg)" :prop="'packDetailList.' + index + '.roughWeight'" :rules="rules.roughWeight">
+                  <el-input-number v-model="item.roughWeight" :precision="2" :controls="false" :min="0" placeholder="请输入" onmousewheel="return false;" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="9">
+                <el-row>
+                  <el-form-item label="尺寸(cm³)" required>
+                    <el-col :span="1"></el-col>
+                    <el-col :span="7">
+                      <el-form-item label="" :prop="'packDetailList.' + index + '.boxLong'" :rules="rules.boxLong">
+                        <el-input-number
+                          v-model="item.boxLong"
+                          placeholder="长"
+                          :precision="2"
+                          :controls="false"
+                          :min="0"
+                          onmousewheel="return false;"></el-input-number>
+                      </el-form-item>
+                    </el-col>
+                    <el-col :span="1" style="text-align: center"> * </el-col>
+                    <el-col :span="7">
+                      <el-form-item label="" :prop="'packDetailList.' + index + '.boxWide'" :rules="rules.boxWide">
+                        <el-input-number
+                          v-model="item.boxWide"
+                          placeholder="宽"
+                          :precision="2"
+                          :controls="false"
+                          :min="0"
+                          onmousewheel="return false;"></el-input-number>
+                      </el-form-item>
+                    </el-col>
+                    <el-col :span="1" style="text-align: center"> * </el-col>
+                    <el-col :span="7">
+                      <el-form-item label="" :prop="'packDetailList.' + index + '.boxHigh'" :rules="rules.boxHigh">
+                        <el-input-number
+                          v-model="item.boxHigh"
+                          placeholder="高"
+                          :precision="2"
+                          :controls="false"
+                          :min="0"
+                          onmousewheel="return false;"></el-input-number>
+                      </el-form-item>
+                    </el-col>
+                  </el-form-item>
+                </el-row>
+              </el-col>
+            </el-row>
+            <div class="line"></div>
+            <el-form-item label="关联合同产品">
+              <div class="flex-box">
+                <div class="item" v-for="(product, j) in item.packDetailProductList" :key="j">
+                  <div>合同编码:{{ product.contractCode }}</div>
+                  <div>产品名称:{{ product.productName }}</div>
+                  <div>每箱数量:{{ product.quantity }}</div>
+                </div>
+              </div>
+            </el-form-item>
+            <div class="bottom-arrow" v-show="!item.isShow" @click="item.isShow = !item.isShow">
+              <span style="margin-right: 5px"> 自定义装箱明细</span>
+              <el-icon><ArrowDownBold /></el-icon>
+            </div>
+            <div class="bottom-arrow" v-show="item.isShow" @click="item.isShow = !item.isShow">
+              <span style="margin-right: 5px"> 收起</span>
+              <el-icon><ArrowUpBold /></el-icon>
+            </div>
+            <el-form-item prop="packDetailGoodsList" v-show="item.isShow">
+              <el-button type="primary" style="margin-bottom: 10px" @click="handleCustomPush(index)"> 添加行 </el-button>
+              <el-table :data="item.packDetailGoodsList">
+                <el-table-column label="货物描述">
+                  <template #default="{ row, $index }">
+                    <el-form-item :prop="['packDetailList', index, 'packDetailGoodsList', $index, 'remark']" :rules="rules.remark" :inline-message="true">
+                      <el-input v-model="row.remark" placeholder="请输入" />
+                    </el-form-item>
+                  </template>
+                </el-table-column>
+                <el-table-column label="单位" width="150">
+                  <template #default="{ row, $index }">
+                    <el-form-item :prop="['packDetailList', index, 'packDetailGoodsList', $index, 'unit']" :rules="rules.unit" :inline-message="true">
+                      <el-input v-model="row.unit" placeholder="请输入" />
+                    </el-form-item>
+                  </template>
+                </el-table-column>
+                <el-table-column label="数量" width="150">
+                  <template #default="{ row, $index }">
+                    <el-form-item
+                      :prop="['packDetailList', index, 'packDetailGoodsList', $index, 'quantity']"
+                      :rules="rules.quantityOne"
+                      :inline-message="true">
+                      <el-input-number v-model="row.quantity" :precision="4" :controls="false" :min="0" onmousewheel="return false;" />
+                    </el-form-item>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="zip" label="操作" width="100">
+                  <template #default="{ $index }">
+                    <el-button type="primary" link @click="handleCustomRemove(index, $index)">删除</el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-form-item>
+          </div>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="handleClose" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="large" :loading="submitLoading"> 确 定 </el-button>
+      </template>
+    </el-dialog>
+    <el-dialog title="合并出货" v-model="dialogVisibleOne" width="400" v-loading="loadingOne">
+      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.dataOne" :rules="rules" ref="byform"> </byForm>
+      <template #footer>
+        <el-button @click="dialogVisibleOne = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitFormOne()" 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 FileUpload from "@/components/FileUpload/index";
+import { computed, defineComponent, ref } from "vue";
+import { getToken } from "@/utils/auth";
+
+const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
+const headers = ref({ Authorization: "Bearer " + getToken() });
+const uploadData = ref({});
+const loading = ref(false);
+const loadingOne = ref(false);
+
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    status: "",
+  },
+});
+let dialogVisible = ref(false);
+let dialogVisibleOne = ref(false);
+
+let modalType = ref("add");
+let fileList = ref([]);
+let rules = ref({
+  contractIds: [{ required: true, message: "请选择合同", trigger: "change" }],
+  packQuantity: [{ required: true, message: "请输入箱数", trigger: "blur" }],
+  netWeight: [{ required: true, message: "请输入净重", trigger: "blur" }],
+  roughWeight: [{ required: true, message: "请输入毛重", trigger: "blur" }],
+  boxLong: [{ required: true, message: "请输入长", trigger: "blur" }],
+  boxWide: [{ required: true, message: "请输入宽", trigger: "blur" }],
+  boxHigh: [{ required: true, message: "请输入高", trigger: "blur" }],
+  quantity: [{ required: true, message: "请输入装箱数量", trigger: "blur" }],
+  quantityOne: [{ required: true, message: "请输入数量", trigger: "blur" }],
+  unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
+  remark: [{ required: true, message: "请输入货物描述", trigger: "blur" }],
+
+  contractId: [{ required: true, message: "请选择主合同", trigger: "change" }],
+});
+
+const { proxy } = getCurrentInstance();
+const selectConfig = reactive([
+  {
+    label: "出货状态",
+    prop: "shipmentStatus",
+    data: [
+      {
+        label: "未出货",
+        value: "0",
+      },
+      {
+        label: "已出货",
+        value: "1",
+      },
+    ],
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      type: "selection",
+      attrs: {
+        checkAtt: "isCheck",
+      },
+    },
+    {
+      attrs: {
+        label: "合同号",
+        prop: "codeAPName",
+        slot: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "产品名称",
+        prop: "codeAPName",
+        slot: "productName",
+      },
+    },
+
+    {
+      attrs: {
+        label: "总箱数",
+        prop: "packQuantity",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "净重",
+        slot: "netWeight",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "毛重",
+        slot: "roughWeight",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "长",
+        slot: "boxLong",
+        width: 90,
+      },
+    },
+
+    {
+      attrs: {
+        label: "宽",
+        slot: "boxWide",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "高",
+        slot: "boxHigh",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "体积",
+        slot: "bomVolume",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "总净重",
+        prop: "netWeight",
+        width: 120,
+      },
+      render(netWeight) {
+        return netWeight + " kg";
+      },
+    },
+    {
+      attrs: {
+        label: "总毛重",
+        prop: "roughWeight",
+        width: 120,
+      },
+      render(roughWeight) {
+        return roughWeight + " kg";
+      },
+    },
+    {
+      attrs: {
+        label: "总体积",
+        prop: "bomVolume",
+        width: 120,
+      },
+      render(bomVolume) {
+        return bomVolume + " m³";
+      },
+    },
+    {
+      attrs: {
+        label: "出货状态",
+        prop: "shipmentStatus",
+        width: 90,
+      },
+      render(status) {
+        return status == 1 ? "已出货" : status == 0 ? "未出货" : "";
+      },
+    },
+    {
+      attrs: {
+        label: "出货时间",
+        prop: "shipmentTime",
+        width: 155,
+      },
+      render(shipmentTime) {
+        if (shipmentTime) {
+          return shipmentTime.slice(5, 10);
+        } else {
+          return "";
+        }
+      },
+    },
+    {
+      attrs: {
+        label: "操作",
+        width: "90",
+        align: "center",
+      },
+      // 渲染 el-button,一般用在最后一列。
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "删除",
+              type: "primary",
+              text: true,
+              disabled: false,
+            },
+            el: "button",
+            click() {
+              ElMessageBox.confirm("此操作将永久作废该数据, 是否继续?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+              }).then(() => {
+                // 删除
+                proxy
+                  .post("/pack/delete", {
+                    id: row.packId,
+                  })
+                  .then((res) => {
+                    ElMessage({
+                      message: "作废成功",
+                      type: "success",
+                    });
+                    getList();
+                  });
+              });
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const formDom = ref(null);
+let formData = reactive({
+  data: {},
+  dataOne: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const treeData = ref([]);
+const formConfig = reactive([
+  {
+    type: "select",
+    prop: "contractId",
+    label: "主合同",
+    required: true,
+    data: [],
+  },
+]);
+
+const getList = async (req) => {
+  selectData.value = [];
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/packDetail/page", sourceList.value.pagination).then((res) => {
+    for (let i = 0; i < res.rows.length; i++) {
+      const e = res.rows[i];
+      e.isCheck = e.shipmentStatus == 1 ? false : true;
+      let arr = [];
+      let newArr = [];
+      arr = e.dataJsonList.split("_");
+      for (let j = 0; j < arr.length; j++) {
+        const jele = arr[j];
+        const jarr = jele.split(",");
+        const obj = {
+          bomVolume: jarr[0],
+          boxLong: jarr[1],
+          boxWide: jarr[2],
+          boxHigh: jarr[3],
+          roughWeight: jarr[4],
+          netWeight: jarr[5],
+        };
+        let createArr = new Array(Number(jarr[6])).fill(obj);
+        newArr = [...newArr, ...createArr];
+      }
+      e.dataJsonListCopy = newArr;
+    }
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    loading.value = false;
+  });
+};
+
+const openModal = () => {
+  modalType.value = "add";
+  formData.data = {
+    packDetailList: [],
+    contractIds: [],
+  };
+  dialogVisible.value = true;
+  handleChangeCustomer("");
+};
+
+const openModalOne = () => {
+  formData.dataOne = {
+    ids: [],
+    contractId: "",
+  };
+  let ids = []; //合同id
+  let idsOne = []; //包装id
+  const list = selectData.value;
+  for (let i = 0; i < list.length; i++) {
+    const e = list[i];
+    ids = [...ids, ...e.contractIds.split(",")];
+    idsOne = [...idsOne, ...e.ids.split(",")];
+  }
+  formData.dataOne.ids = idsOne;
+  proxy.post(`/contract/getByIds`, ids).then((res) => {
+    formConfig[0].data = res.map((x) => ({
+      label: x.code,
+      value: x.id,
+    }));
+    dialogVisibleOne.value = true;
+  });
+};
+
+const submitForm = () => {
+  formDom.value.validate((vaild) => {
+    if (vaild) {
+      if (!formData.data.packDetailList.length > 0) {
+        return ElMessage({
+          message: "请添加装箱明细!",
+          type: "info",
+        });
+      }
+      submitLoading.value = true;
+      loadingOne.value = true;
+      for (let i = 0; i < formData.data.packDetailList.length; i++) {
+        const e = formData.data.packDetailList[i];
+        e.bomVolume = (e.boxLong * e.boxWide * e.boxHigh) / 1000000;
+      }
+      formData.data.contractIds = formData.data.contractIds.join(",");
+      proxy.post("/pack/" + modalType.value, formData.data).then(
+        (res) => {
+          ElMessage({
+            message: modalType.value == "add" ? "添加成功" : "编辑成功",
+            type: "success",
+          });
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          loadingOne.value = false;
+          getList();
+        },
+        (err) => {
+          submitLoading.value = false;
+          loading.value = false;
+        }
+      );
+    }
+  });
+};
+const table = ref(null);
+const submitFormOne = () => {
+  byform.value.handleSubmit((valid) => {
+    loading.value = true;
+    submitLoading.value = true;
+    proxy.post("/packDetail/shipment", formData.dataOne).then(
+      (res) => {
+        ElMessage({
+          message: "出货成功",
+          type: "success",
+        });
+        dialogVisibleOne.value = false;
+        submitLoading.value = false;
+        loading.value = false;
+        getList();
+        selectData.value = [];
+      },
+      (err) => {
+        submitLoading.value = false;
+        loading.value = false;
+      }
+    );
+  });
+};
+
+const selectData = ref([]);
+const selectRow = (data) => {
+  selectData.value = data;
+};
+const selectProductData = ref([]);
+const handleSelectProduct = (data) => {
+  selectProductData.value = data;
+};
+const tableDom = ref(null);
+const handleClickPacking = () => {
+  if (selectProductData.value.length > 0) {
+    const list = selectProductData.value;
+    for (let i = 0; i < list.length; i++) {
+      const e = list[i];
+      if (!e.quantity) {
+        return ElMessage({
+          message: "请输入装箱数量",
+          type: "info",
+        });
+      }
+    }
+    for (let i = 0; i < list.length; i++) {
+      const e = list[i];
+      for (let j = 0; j < formData.data.contractProductData.length; j++) {
+        const jele = formData.data.contractProductData[j];
+        if (e.id === jele.id && e.quantity > Number(jele.waitQuantity)) {
+          return ElMessage({
+            message: "装箱数量不可大于袋装箱数量",
+            type: "info",
+          });
+        }
+      }
+    }
+    const packDetailProductList = list.map((x) => ({
+      contractCode: x.contractCode,
+      contractId: x.contractId,
+      contractProductId: x.id,
+      quantity: x.quantity,
+      productId: x.productId,
+      productName: x.productName,
+    }));
+    const customerId = formData.data.customerId ? formData.data.customerId : "";
+    const contractIds = formData.data.contractIds ? formData.data.contractIds.join(",") : "";
+    let item = {
+      customerId: customerId,
+      contractIds: contractIds,
+      packQuantity: 1,
+      netWeight: null,
+      roughWeight: null,
+      boxLong: null,
+      boxWide: null,
+      boxHigh: null,
+      bomVolume: "",
+      remark: "",
+      packDetailGoodsList: [],
+      packDetailProductList: packDetailProductList,
+      isShow: false,
+    };
+    formData.data.packDetailList.push(item);
+    handleChangePackQuantity(item.packQuantity, formData.data.packDetailList.length - 1);
+    tableDom.value.clearSelection();
+    selectProductData.value = [];
+    table.value.clearSelection();
+  } else {
+    return ElMessage({
+      message: "请选择产品 !",
+      type: "info",
+    });
+  }
+};
+
+const handleChangePackQuantity = (val, index) => {
+  const obj = {};
+  for (let i = 0; i < formData.data.contractProductData.length; i++) {
+    const e = formData.data.contractProductData[i];
+    obj[e.contractId + "_" + e.productId + ""] = (Number(e.cpQuantity) - Number(e.sumPackQuantity)).toFixed(2);
+  }
+  // 计算数量 即装箱数量 * 箱数 新增字段放在最外层
+  for (let i = 0; i < formData.data.packDetailList.length; i++) {
+    const ele = formData.data.packDetailList[i];
+    for (let j = 0; j < ele.packDetailProductList.length; j++) {
+      const jele = ele.packDetailProductList[j];
+      ele[jele.contractId + "_" + jele.productId + ""] = (Number(ele.packQuantity) * jele.quantity).toFixed(2);
+    }
+  }
+  // 计算新的待装箱数量
+  for (let i = 0; i < formData.data.packDetailList.length; i++) {
+    const e = formData.data.packDetailList[i];
+    for (const key in obj) {
+      if (e.hasOwnProperty(key)) {
+        obj[key] = (obj[key] - e[key]).toFixed(2);
+        if (obj[key] < 0) {
+          e.packQuantity = null;
+          handleChangePackQuantity(null, index);
+          return ElMessage({
+            message: "装箱数量 * 箱数不可大于待装箱数量",
+            type: "info",
+          });
+        }
+      }
+    }
+  }
+  // 赋值
+  for (let i = 0; i < formData.data.contractProductData.length; i++) {
+    const e = formData.data.contractProductData[i];
+    for (const key in obj) {
+      if (e.contractId + "_" + e.productId + "" === key) {
+        e.waitQuantity = obj[key];
+      }
+    }
+  }
+  // }
+};
+
+const handleCustomPush = (index) => {
+  formData.data.packDetailList[index].packDetailGoodsList.push({
+    unit: "",
+    quantity: "",
+    remark: "",
+  });
+};
+
+const handleCustomRemove = (index, sonIndex) => {
+  formData.data.packDetailList[index].packDetailGoodsList.splice(sonIndex, 1);
+};
+const customerList = ref([]);
+const getSelectData = () => {
+  proxy.post("/customer/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    customerList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.name,
+        value: item.id,
+      };
+    });
+  });
+};
+const contractData = ref([]);
+const handleChangeCustomer = (val) => {
+  proxy.get(`/contract/getNoPackContractByCustomerId?customerId=${val}`).then((res) => {
+    contractData.value = res.data;
+    formData.data.contractIds = [];
+  });
+};
+const handleChangeContract = (val) => {
+  const customerId = formData.data.customerId ? formData.data.customerId : "";
+  proxy.get(`/contractProduct/getNoPackContractProductById?customerId=${customerId}&contractIds=${val}`).then((res) => {
+    formData.data.contractProductData = res.data.map((x) => ({
+      ...x,
+      waitQuantity: (Number(x.cpQuantity) - Number(x.sumPackQuantity)).toFixed(2),
+      quantity: null,
+    }));
+    handleChangePackQuantity();
+  });
+};
+
+const getData = (data, type) => {
+  if (!data) return [];
+  const arr = data.split(",");
+  if (arr && arr.length > 0) {
+    const arrOne = [];
+    for (let i = 0; i < arr.length; i++) {
+      const e = arr[i];
+      if (type === "code") {
+        arrOne.push(e.split("_")[0]);
+      } else if (type === "productName") {
+        arrOne.push(e.split("_")[1]);
+      }
+    }
+    return arrOne;
+  }
+  return [];
+};
+
+const handleClose = () => {
+  dialogVisible.value = false;
+  selectProductData.value = [];
+};
+getSelectData();
+getList();
+const clickDelete = (index) => {
+  formData.data.packDetailList.splice(index, 1);
+  handleChangePackQuantity();
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+:deep(.el-collapse-item__header) {
+  background-color: #fde6c8;
+  border: none;
+}
+:deep(.el-collapse-item__wrap) {
+  background-color: #fde6c8;
+  border: none;
+}
+
+.box {
+  padding: 15px;
+  background: #fde6c8;
+  border: 1px solid #7fb5e3;
+  margin-bottom: 10px;
+  width: 100%;
+  .flex-box {
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    .item {
+      width: 50%;
+      margin-bottom: 10px;
+      div {
+        line-height: 22px;
+      }
+    }
+  }
+  .line {
+    width: 100%;
+    height: 1px;
+    background: #7fb5e3;
+    margin: 20px 0;
+  }
+  .bottom-arrow {
+    text-align: center;
+    cursor: pointer;
+    color: #0084ff;
+  }
+}
+</style>

+ 324 - 7
src/views/salesMange/shipmentMange/packing/index.vue

@@ -84,7 +84,131 @@
         </template>
       </byTable>
     </div>
-    <el-dialog title="产品装箱" v-model="dialogVisible" width="80%" v-loading="loading">
+    <el-dialog title="产品装箱" v-model="dtlModalType" width="80%" v-loading="loading" @close="dtlModalClose">
+      <el-row :gutter="10">
+        <el-col :span="8">
+          <div class="common-title">箱规</div>
+          <el-form :model="boxFormData" :rules="rules" ref="formDom" label-position="top">
+            <el-form-item label="尺寸(cm³)" required>
+              <el-col :span="7">
+                <el-form-item label="" :prop="'boxLong'" :rules="rules.boxLong">
+                  <el-input-number
+                    v-model="boxFormData.boxLong"
+                    placeholder="长"
+                    :precision="2"
+                    :controls="false"
+                    :min="0"
+                    onmousewheel="return false;"></el-input-number>
+                </el-form-item>
+              </el-col>
+              <el-col :span="1" style="text-align: center"> * </el-col>
+              <el-col :span="7">
+                <el-form-item label="" :prop="'boxWide'" :rules="rules.boxWide">
+                  <el-input-number
+                    v-model="boxFormData.boxWide"
+                    placeholder="宽"
+                    :precision="2"
+                    :controls="false"
+                    :min="0"
+                    onmousewheel="return false;"></el-input-number>
+                </el-form-item>
+              </el-col>
+              <el-col :span="1" style="text-align: center"> * </el-col>
+              <el-col :span="7">
+                <el-form-item label="" :prop="'boxHigh'" :rules="rules.boxHigh">
+                  <el-input-number
+                    v-model="boxFormData.boxHigh"
+                    placeholder="高"
+                    :precision="2"
+                    :controls="false"
+                    :min="0"
+                    onmousewheel="return false;"></el-input-number>
+                </el-form-item>
+              </el-col>
+            </el-form-item>
+            <el-form-item label="体积" required>
+              <el-input-number
+                v-model="boxFormData.bomVolume"
+                placeholder="请输入"
+                :precision="4"
+                :controls="false"
+                :min="0"
+                disabled
+                onmousewheel="return false;"></el-input-number>
+            </el-form-item>
+            <el-form-item label="净重(kg)" :prop="'netWeight'" :rules="rules.netWeight">
+              <el-input-number
+                v-model="boxFormData.netWeight"
+                :precision="2"
+                :controls="false"
+                :min="0"
+                placeholder="请输入"
+                onmousewheel="return false;"></el-input-number>
+            </el-form-item>
+            <el-form-item label="毛重(kg)" :prop="'roughWeight'" :rules="rules.roughWeight">
+              <el-input-number
+                v-model="boxFormData.roughWeight"
+                :precision="2"
+                :controls="false"
+                :min="0"
+                placeholder="请输入"
+                onmousewheel="return false;"></el-input-number>
+            </el-form-item>
+            <el-form-item label="总箱数" :prop="'packQuantity'" :rules="rules.packQuantity">
+              <el-input-number
+                v-model="boxFormData.packQuantity"
+                :precision="0"
+                :controls="false"
+                :min="1"
+                placeholder="请输入"
+                onmousewheel="return false;"></el-input-number>
+            </el-form-item>
+          </el-form>
+        </el-col>
+        <el-col :span="16">
+          <!-- 添加行 -->
+          <div class="add-box" style="margin-bottom: 20px;">
+            <el-button type="primary" @click="packDetailProductListPush(boxIndex)"> 添加行 </el-button>
+            <el-button type="primary" @click="packDetailProductListPush(boxIndex)"> 自定义装箱 </el-button>
+          </div>
+          <el-table :data="boxFormData.packDetailProductList" @select="handleSelectProduct" @select-all="handleSelectProduct" ref="tableDom">
+              <el-table-column prop="productName" label="产品名称" min-width="180">
+                <template #default="{ row, $index }">
+                  <!-- 选择产品 -->
+                    <el-form-item 
+                      prop="mathId"  
+                      style="margin-bottom:0px" :inline-message="true">
+                      <el-select
+                        :model-value="boxFormData.packDetailProductList[$index].mathId" 
+                        placeholder="请选择" 
+                        @change="(e) => selectProduct(e,$index)" 
+                        filterable style="width: 100%"
+                        >
+                        <el-option v-for="item in formData.data.contractProductData" :disabled='item.disabled' :label="item.productName" :value="item.mathId"> </el-option>
+                      </el-select>
+                    </el-form-item>
+                  
+                </template>
+              </el-table-column>
+              <el-table-column prop="productSpec" label="规格型号" min-width="140" />
+              <el-table-column prop="cpQuantity" label="合同数量" width="140" />
+              <el-table-column prop="waitQuantity" label="待装箱数量" width="140" />
+              <el-table-column prop="quantity" label="装箱数量" width="160">
+                <template #default="{ row, $index }">
+                   
+                    <el-form-item prop="quantity" :inline-message="true">
+                      <el-input-number :max="row.waitQuantity" v-model="boxFormData.packDetailProductList[$index].quantity" :precision="4" :controls="false" :min="0" onmousewheel="return false;" />
+                    </el-form-item>
+                </template>
+              </el-table-column>
+          </el-table>
+        </el-col>
+      </el-row>
+      <template #footer>
+        <el-button type="primary" @click="submitBox()" size="large" :loading="submitLoading"> 确 定 </el-button>
+      </template>
+    </el-dialog>
+    <el-dialog title="产品装箱" v-model="dialogVisible" width="600" v-loading="loading">
       <el-form :model="formData.data" :rules="rules" ref="formDom" label-position="top">
         <el-row :gutter="10">
           <el-col :span="8">
@@ -100,6 +224,17 @@
             <el-option v-for="item in contractData" :label="item.code" :value="item.id"> </el-option>
           </el-select>
         </el-form-item>
+        <div class="box-icon-warp">
+          <div class="box-content"  v-for="(i,index) in formData.data.packDetailList"  :key="i.id" @click="openDtlUpdata(index)">
+            <div class="box-icon">
+              <i class="iconfont icon-iconm_daick"></i>
+            </div>
+            <div class="box-text"> * {{i.packQuantity}}</div>
+          </div>
+          <div class="add-box">
+            <i class="iconfont icon-iconm_tianjia1" @click="openDtlModal"></i>
+          </div>
+        </div>
         <el-form-item label="合同明细" prop="contractProductData">
           <el-table :data="formData.data.contractProductData" @select="handleSelectProduct" @select-all="handleSelectProduct" ref="tableDom">
             <el-table-column type="selection" label="" width="50" />
@@ -270,12 +405,10 @@ import FileUpload from "@/components/FileUpload/index";
 import { computed, defineComponent, ref } from "vue";
 import { getToken } from "@/utils/auth";
 
-const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
-const headers = ref({ Authorization: "Bearer " + getToken() });
-const uploadData = ref({});
+
 const loading = ref(false);
 const loadingOne = ref(false);
-
+const dtlModalType = ref(false);
 const submitLoading = ref(false);
 const sourceList = ref({
   data: [],
@@ -286,6 +419,148 @@ const sourceList = ref({
     status: "",
   },
 });
+
+const openDtlUpdata = (index) => {
+  boxIndex.value = index;
+  dtlModalType.value = true;
+};
+
+let boxFormData = ref({
+  packQuantity: null,
+  netWeight: null,
+  roughWeight: null,
+  boxLong: null,
+  boxWide: null,
+  boxHigh: null,
+  packDetailGoodsList: [],
+  packDetailProductList: [],
+  bomVolume: null,
+  //生成唯一id
+  id: Math.random().toString(36).substr(2),
+});
+
+const openDtlModal = () => {
+  boxFormData.value = {
+    packQuantity: null,
+    netWeight: null,
+    roughWeight: null,
+    boxLong: null,
+    boxWide: null,
+    boxHigh: null,
+    packDetailGoodsList: [],
+    packDetailProductList: [],
+    bomVolume: null,
+    //生成唯一id
+    id: Math.random().toString(36).substr(2),
+  };
+  boxIndex.value = formData.data.packDetailList.length - 1;
+  dtlModalType.value = true;
+
+};
+
+const dtlModalClose = () => {
+  dtlModalType.value = false;
+  //如果关闭删除本条数据
+  formData.data.packDetailList.splice(boxIndex.value, 1);
+  boxIndex.value = 0
+  console.log(formData.data.packDetailList)
+};
+
+const boxIndex = ref(0);
+
+const packDetailProductListPush = (index) => {
+  boxFormData.value.packDetailProductList.push({
+    contractId: null,
+    productName: null,
+    contractProductId: null,
+    quantity: null,
+    productId: null,
+    productModel: null,
+    remark:null,
+  });
+};
+
+const submitBox = () => {
+  formDom.value.validate((vaild) => {
+    if (vaild) {
+      if(boxFormData.value.packDetailProductList.length == 0){
+        ElMessage.error("请添加产品");
+        return;
+      }
+      for (let i = 0; i < boxFormData.value.packDetailProductList.length; i++) {
+        const item = boxFormData.value.packDetailProductList[j];
+        if (item.quantity == null) {
+          ElMessage.error("请填写装箱数量");
+          return;
+        }
+        if (item.productId == null) {
+            ElMessage.error("请填写选择产品");
+            return;
+        }
+      }
+      dtlModalType.value = false;
+      formData.data.packDetailList[boxIndex.value] = {
+        packQuantity: boxFormData.value.packQuantity,
+        netWeight: boxFormData.value.netWeight,
+        roughWeight: boxFormData.value.roughWeight,
+        boxLong: boxFormData.value.boxLong,
+        boxWide: boxFormData.value.boxWide,
+        boxHigh: boxFormData.value.boxHigh,
+        packDetailGoodsList: boxFormData.value.packDetailGoodsList,
+        packDetailProductList: boxFormData.value.packDetailProductList,
+        bomVolume: boxFormData.value.bomVolume,
+        id: boxFormData.value.id,
+      };
+    }
+  })
+  console.log(formData.data.packDetailList[boxIndex.value])
+  
+};
+
+const dtlformData = reactive({
+  data: {
+    customerId:null,
+    contractIds:null,
+    packQuantity:null,
+    netWeight:null,
+    roughWeight:null,
+    boxLong:null,
+    boxWide:null,
+    boxHigh:null,
+    remark:null,
+    packDetailGoodsList:[],
+    packDetailProductList:[],
+    bomVolume:null,
+  },
+});
+
+const selectProduct = (val,index) => {
+  let msg  = {...formData.data.contractProductData.find((item) => item.mathId == val)}
+  //根据val 禁用相应的下拉数据
+  console.log(msg,index)
+  boxFormData.value.packDetailProductList[index] = {
+    productId: msg.productId,
+    productName: msg.productName,
+    productSpec: msg.productSpec,
+    contractCode: msg.contractCode,
+    contractProductId: msg.contractProductId,
+    cpQuantity: msg.cpQuantity,
+    waitQuantity: msg.waitQuantity,
+    quantity: null,
+    mathId: msg.mathId,
+  }
+  formData.data.contractProductData.forEach((item) => {
+    item.disabled = false
+    boxFormData.value.packDetailProductList.forEach((item1) => {
+      if(item.mathId == item1.mathId){
+        item.disabled = true
+      }
+    })
+  });
+  console.log(formData.data.packDetailList)
+};
+
+
 let dialogVisible = ref(false);
 let dialogVisibleOne = ref(false);
 
@@ -303,8 +578,9 @@ let rules = ref({
   quantityOne: [{ required: true, message: "请输入数量", trigger: "blur" }],
   unit: [{ required: true, message: "请输入单位", trigger: "blur" }],
   remark: [{ required: true, message: "请输入货物描述", trigger: "blur" }],
-
+  productId: [{ required: true, message: "请选择产品", trigger: "change" }],
   contractId: [{ required: true, message: "请选择主合同", trigger: "change" }],
+  mathId: [{ required: true, message: "请选择产品", trigger: "change" }],
 });
 
 const { proxy } = getCurrentInstance();
@@ -582,7 +858,7 @@ const openModalOne = () => {
     dialogVisibleOne.value = true;
   });
 };
-
+const packDetailProductListDom = ref(null);
 const submitForm = () => {
   formDom.value.validate((vaild) => {
     if (vaild) {
@@ -794,6 +1070,8 @@ const handleChangeContract = (val) => {
       ...x,
       waitQuantity: (Number(x.cpQuantity) - Number(x.sumPackQuantity)).toFixed(2),
       quantity: null,
+      mathId: Math.random().toString(36).substr(2),
+      disabled: false,
     }));
     handleChangePackQuantity();
   });
@@ -842,6 +1120,45 @@ const clickDelete = (index) => {
   border: none;
 }
 
+.box-icon-warp{
+  width: 100%;
+  display: flex;
+  .add-box{
+    width: 33.33%;
+    height: 100px;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    i{
+      display: block;
+      width: 100px;
+      height: 100px;
+      border:1px solid #dcdcdc;
+      text-align: center;
+      line-height: 100px;
+      cursor: pointer;
+    }
+  }
+  .box-content{
+    width: 33.33%;
+    height: 100px;
+    border-radius: 50%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    .box-icon{
+      i{
+        font-size: 60px;
+      }
+      color: #f5a623;
+    }
+    .box-text{
+      font-size: 20px;
+      color: #f5a623;
+    }
+  }
+}
+
 .box {
   padding: 15px;
   background: #fde6c8;

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.