cz 1 anno fa
parent
commit
a43f1daf73

+ 4 - 16
src/components/Editor/index.vue

@@ -3,23 +3,10 @@
     <div class="ql-editor"></div>
   </div> -->
   <div class="ql-editor">
-    <QuillEditor
-      ref="myQuillEditor"
-      theme="snow"
-      v-model:content="content"
-      :options="data.editorOption"
-      contentType="html"
-      :read-only="readOnly"
-      @update:content="setValue()"
-    />
+    <QuillEditor ref="myQuillEditor" theme="snow" v-model:content="content" :options="data.editorOption" contentType="html" :read-only="readOnly"
+                 @update:content="setValue()" />
     <!-- 使用自定义图片上传 -->
-    <input
-      type="file"
-      hidden
-      accept=".jpg,.png"
-      ref="fileBtn"
-      @change="handleUpload"
-    />
+    <input type="file" hidden accept=".jpg,.png" ref="fileBtn" @change="handleUpload" />
   </div>
 </template>
 
@@ -127,6 +114,7 @@ defineExpose({
 <style scoped lang="scss">
 :deep(.ql-editor) {
   min-height: 180px;
+  // overflow: auto;
 }
 :deep(.ql-formats) {
   height: 21px;

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

@@ -150,7 +150,7 @@
       </div>
     </header>
 
-    <el-drawer v-model="openDrawer" direction="rtl" :show-close="false" custom-class="drawerClass" modal-class="modelClass">
+    <el-drawer v-model="openDrawer" direction="rtl" :show-close="false" close-on-click-modal custom-class="drawerClass" modal-class="modelClass">
       <!-- <template #header>
         <h4>set title by slot</h4>
       </template> -->

+ 13 - 8
src/components/process/SF/Contract.vue

@@ -175,7 +175,7 @@
                 </div>
               </template>
             </el-table-column>
-            <el-table-column label="单价" width="150">
+            <el-table-column label="单价" width="180">
               <template #default="{ row, $index }">
                 <div style="width: 100%">
                   <el-form-item :prop="'contractProductList.' + $index + '.price'" :rules="rules.price" :inline-message="true"
@@ -183,7 +183,7 @@
                     <div style="display:flex;">
                       <el-input-number onmousewheel="return false;" v-model="row.price" placeholder="请输入" style="width: 100%" :precision="2"
                                        :controls="false" :min="0" @change="calculationAmount()" />
-                      <!-- <el-popover placement="top-start" :width="400" trigger="hover" @show="showEcharts(row,$index)">
+                      <el-popover placement="top-start" :width="400" trigger="hover" @show="showEcharts(row,$index)">
                         <template #default>
                           <div>
                             <div>
@@ -226,7 +226,7 @@
                             </el-icon>
                           </div>
                         </template>
-                      </el-popover> -->
+                      </el-popover>
                     </div>
                   </el-form-item>
                 </div>
@@ -310,8 +310,8 @@ import selectCity from "@/components/selectCity/index.vue";
 import { useRoute } from "vue-router";
 import SelectContract from "@/components/contractCom/selectContract.vue";
 import SelectSample from "@/components/contractCom/selectSample.vue";
-// import * as echarts from "echarts";
-// import $bus from "@/bus/index.js";
+import * as echarts from "echarts";
+import $bus from "@/bus/index.js";
 const route = useRoute();
 const { proxy } = getCurrentInstance();
 // 接收父组件的传值
@@ -860,6 +860,7 @@ const selectProduct = (goods) => {
       fileList: [],
     });
     proxy.msgTip("添加成功", 1);
+    changeProductPrice();
   } else {
     return proxy.msgTip("选择错误", 2);
   }
@@ -885,14 +886,14 @@ const changeProductPrice = () => {
               iele.saleCostPrice = res[key].costPrice;
               iele.contractProductList = res[key].contractProductList
                 .map((x) => ({
-                  createTime: x.createTime,
+                  createTime: x.createTime || "",
                   price: x.price,
                   currency: x.currency,
                 }))
                 .filter((y, index) => index < 3);
               iele.contractProductListOne = res[key].contractProductList.map(
                 (x) => ({
-                  createTime: x.createTime,
+                  createTime: x.createTime || "",
                   price: x.price,
                   currency: x.currency,
                 })
@@ -900,7 +901,7 @@ const changeProductPrice = () => {
               iele.customerContractProductList = res[
                 key
               ].customerContractProductList.map((x) => ({
-                createTime: x.createTime,
+                createTime: x.createTime || "",
                 price: x.price,
                 currency: x.currency,
               }));
@@ -1125,6 +1126,9 @@ const getAllData = (businessId) => {
     res.countryId = res.buyCountryId;
     res.provinceId = res.buyProvinceId;
     res.cityId = res.buyCityId;
+    if (res.grossProfitInfoList && res.grossProfitInfoList.length > 0) {
+      $bus.emit("getGrossData", res.grossProfitInfoList);
+    }
     for (const key in res) {
       formData.data[key] = res[key];
     }
@@ -1169,6 +1173,7 @@ const getAllData = (businessId) => {
             }
           }
         });
+      changeProductPrice();
     }
     if (formData.data.countryId) {
       getCityData(formData.data.countryId, "20");

+ 1062 - 0
src/components/process/SF/Purchase.vue

@@ -0,0 +1,1062 @@
+<template>
+  <div style="width: 100%; padding: 0px 15px">
+    <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom">
+      <template #btn>
+        <div>
+          <el-button type="primary" v-if="
+              [30].includes(route.query.processType) || !route.query.processType
+            " @click="clickCopy(1)">复制合同</el-button>
+        </div>
+      </template>
+      <template #seller>
+        <div style="width: 100%">
+          <el-form-item prop="buyCorporationId" label="买方信息" class="wid100">
+            <el-select v-model="formData.data.buyCorporationId" placeholder="请选择买方公司" style="width: 100%" @change="buyCorporationIdChange" filterable>
+              <el-option v-for="item in corporationList" :key="item.value" :label="item.label" :value="item.value" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="地址" class="wid100">
+            <el-row style="width:100%">
+              <el-col :span="8">
+                <el-form-item label="" prop="buyCountryName" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.buyCountryName" placeholder="请输入国家" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="" prop="buyProvinceName" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.buyProvinceName" placeholder="请输入省/州" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="" prop="buyCityName" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.buyCityName" placeholder="请输入城市" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form-item>
+
+          <el-form-item label="详细地址" prop="buyAddress" class="wid100">
+            <el-input v-model="formData.data.buyAddress" type="textarea">
+            </el-input>
+          </el-form-item>
+
+          <el-form-item label="联系人" class="wid100">
+            <el-row style="width:100%">
+              <el-col :span="8">
+                <el-form-item label="" prop="buyContactName" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.buyContactName" placeholder="请输入联系人" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="16">
+                <el-form-item label="" prop="buyContactNumber" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.buyContactNumber" placeholder="请输入联系人电话" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form-item>
+        </div>
+      </template>
+      <template #buyer>
+        <div style="width: 100%">
+          <el-form-item label="卖方信息" prop="sellCorporationId" class="wid100">
+            <el-select v-model="formData.data.sellCorporationId" filterable remote reserve-keyword placeholder="请输入关键字" remote-show-suffix
+                       :remote-method="remoteMethod" :loading="loadingSearch" @input="remoteMethod" style="width: 100%" @change="changeSupplier" v-if="
+                  [30].includes(route.query.processType) ||
+                  !route.query.processType
+                ">
+              <el-option v-for="item in supplierList" :key="item.value" :label="item.label" :value="item.value" />
+            </el-select>
+            <el-select v-model="formData.data.sellCorporationName" disabled v-else style="width: 100%">
+            </el-select>
+          </el-form-item>
+          <el-form-item label="地址" class="wid100" required>
+            <el-row style="width: 100%">
+              <el-col :span="6">
+                <el-form-item label="" prop="countryId" class="margin-b-0">
+                  <el-select v-model="formData.data.countryId" placeholder="国家" filterable @change="(val) => getCityData(val, '20', true)">
+                    <el-option v-for="item in countryData" :label="item.name" :value="item.id">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="" prop="provinceName" class="margin-b-0">
+                  <selectCity placeholder="省/洲" @change="(val) => getCityData(val, '30', true)" addressId="provinceId" addressName="provinceName"
+                              v-model="formData.data" :data="provinceData">
+                  </selectCity>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="" prop="cityName" class="margin-b-0">
+                  <selectCity placeholder="城市" addressId="cityId" addressName="cityName" v-model="formData.data" :data="cityData">
+                  </selectCity>
+                </el-form-item>
+              </el-col>
+              <el-col :span="6">
+                <el-form-item label="" prop="sellPostalCode" class="margin-b-0">
+                  <el-input v-model="formData.data.sellPostalCode" placeholder="请输入邮编" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form-item>
+
+          <el-form-item label="详细地址" prop="sellAddress" class="wid100">
+            <el-input v-model="formData.data.sellAddress" type="textarea">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="联系人" class="wid100" required>
+            <el-row style="width: 100%">
+              <el-col :span="8">
+                <el-form-item label="" prop="sellContactName" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.sellContactName" clearable placeholder="请输入联系人">
+                  </el-input>
+                </el-form-item>
+              </el-col>
+              <el-col :span="16">
+                <el-form-item label="" prop="sellContactNumber" label-width="0px" class="margin-b-0 wid100">
+                  <el-input v-model="formData.data.sellContactNumber" placeholder="请输入联系人电话" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form-item>
+        </div>
+      </template>
+
+      <template #commodity>
+        <div style="width: 100%">
+          <el-table :data="formData.data.purchaseProductList" style="width: 100%; ">
+            <el-table-column label="商品图片" width="80">
+              <template #default="{ row }">
+                <div v-if="row.fileUrl">
+                  <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
+                </div>
+                <div v-else></div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="productName" label="商品名称" min-width="130" />
+            <el-table-column prop="productCode" label="商品编码" width="130" />
+            <el-table-column label="尺寸 cm*cm*cm" width="180">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="数量" prop="subscribeCount" width="100" v-if="route.query.ids" />
+            <el-table-column label="已采购数量" prop="purchaseCount" width="100" v-if="route.query.ids" />
+            <el-table-column label="采购数量" width="150">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'purchaseProductList.' + $index + '.quantity'" :rules="rules.quantity" :inline-message="true"
+                                class="margin-b-0 wid100">
+                    <el-input-number onmousewheel="return false;" v-model="row.quantity" placeholder="请输入" style="width: 100%" :precision="0"
+                                     :controls="false" :min="0" @change="calculationAmount('quantity')" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="单价" width="180">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'purchaseProductList.' + $index + '.price'" :rules="rules.price" :inline-message="true"
+                                class="margin-b-0 wid100">
+                    <div style="display:flex;">
+                      <el-input-number onmousewheel="return false;" v-model="row.price" placeholder="请输入" style="width: 100%" :precision="2"
+                                       :controls="false" :min="0" @change="calculationAmount()" />
+                      <el-popover placement="top-start" :width="400" trigger="hover" @show="showEcharts(row,$index)">
+                        <template #default>
+                          <div>
+                            <div>
+                              <img src="@/assets/images/money1.png" alt="" class="img" />
+                              <span style="font-size:14px;font-weight:700;color:#000"> 该供应商近期采购单价:</span>
+                              <div style="padding:5px 0px 0px 20px">
+                                <div v-for="(item,index) in row.supplyPurchaseProductPriceList" :key="index">
+                                  <span>{{item.createTime.slice(0,10)}} </span>
+                                  <span style="margin-left:40px">CNY {{moneyFormat(item.price,2)}} </span>
+                                </div>
+                              </div>
+                            </div>
+
+                            <div style="margin-top:15px">
+                              <img src="@/assets/images/money2.png" alt="" class="img" />
+                              <span style="font-size:14px;font-weight:700;color:#000"> 供货推荐:</span>
+                              <div style="padding:5px 0px 0px 20px">
+                                <div v-for="(item,index) in row.topPriceList   " :key="index">
+                                  <span>{{item.supplierName}} </span>
+                                  <span style="margin-left:40px"> CNY {{moneyFormat(item.price,2)}} </span>
+                                </div>
+                              </div>
+                            </div>
+
+                            <div style="margin-top:15px">
+                              <img src="@/assets/images/money3.png" alt="" class="img" />
+                              <span style="font-size:14px;font-weight:700;color:#000"> 近期采购单价:</span>
+                              <div style="padding:5px 0px 0px 20px">
+                                <div v-for="(item,index) in row.purchaseProductPriceList   " :key="index">
+                                  <span>{{item.createTime.slice(0,10)}} </span>
+                                  <span style="margin-left:40px"> CNY {{moneyFormat(item.price,2)}} </span>
+                                </div>
+                              </div>
+                            </div>
+                            <div :ref="row.productId+$index" :id="row.productId+$index" style="height:180px">
+                            </div>
+                          </div>
+                        </template>
+                        <template #reference>
+                          <div style="margin-left:10px;cursor:pointer;position:relative;top:4px">
+                            <el-icon :size="20" color="#85c1a6">
+                              <WarningFilled />
+                            </el-icon>
+                          </div>
+                        </template>
+                      </el-popover>
+                    </div>
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="amount" label="小计" width="120" />
+            <el-table-column label="操作" width="120" align="center" fixed="right" v-if="!judgeStatus()">
+              <template #default="{ $index }">
+                <el-button type="primary" link @click="handleRemove($index)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+
+      <template #otherCharge>
+        <div style="width: 100%">
+          <el-button type="primary" @click="clickAdd()" plain style="margin-bottom: 16px" v-if="!judgeStatus()">添加行</el-button>
+          <el-table :data="formData.data.purchaseProjectList" style="width: 100%;">
+            <el-table-column label="收费项目" width="220">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'purchaseProjectList.' + $index + '.payName'" :rules="rules.payName" :inline-message="true"
+                                class="margin-b-0 wid100">
+                    <el-autocomplete v-model="row.payName" :fetch-suggestions="querySearch" clearable class="inline-input w-50"
+                                     placeholder="请输入收费项目" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="备注">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'purchaseProjectList.' + $index + '.remark'" class="margin-b-0 wid100">
+                    <el-input v-model="row.remark" placeholder="请输入备注" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column :label="'金额'" width="130">
+              <template #default="{ row, $index }">
+                <div style="width: 100%">
+                  <el-form-item :prop="'purchaseProjectList.' + $index + '.amount'" :rules="rules.amount" :inline-message="true"
+                                class="margin-b-0 wid100">
+                    <el-input-number onmousewheel="return false;" v-model="row.amount" placeholder="请输入金额" style="width: 100%" :precision="2"
+                                     :controls="false" :min="0" @change="totalAmount()" />
+                  </el-form-item>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="60" align="center" fixed="right" v-if="!judgeStatus()">
+              <template #default="{ $index }">
+                <el-button type="primary" link @click="handleDelete($index)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </template>
+
+      <template #contractClause>
+        <div style="width: 100%">
+          <el-row style=" width: 100%">
+            <el-col :span="8">
+              <el-form-item label="合同模板" prop="contractTemplateId" class="wid100">
+                <el-select v-model="formData.data.contractTemplateId" style="width: 100%" @change="changeContractTemplate">
+                  <el-option v-for="item in templateList" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <div style=" width: 100%">
+            <el-form-item label="条款内容" prop="remark" class="margin-b-0 wid100">
+              <Editor style="width: 100%" :value="formData.data.remark" @updateValue="updateContent" :readOnly="judgeStatus()" ref="remarkEditor" />
+            </el-form-item>
+          </div>
+        </div>
+      </template>
+
+    </byForm>
+
+  </div>
+</template>
+
+<script setup>
+import byForm from "@/components/byForm/index";
+import selectCity from "@/components/selectCity/index.vue";
+import { useRoute } from "vue-router";
+import Editor from "@/components/Editor/index.vue";
+import * as echarts from "echarts";
+import $bus from "@/bus/index.js";
+const route = useRoute();
+const { proxy } = getCurrentInstance();
+// 接收父组件的传值
+const props = defineProps({
+  queryData: Object,
+});
+const invoiceType = computed(
+  () => proxy.useUserStore().allDict["invoice_type"]
+);
+const fundsPaymentMethod = computed(
+  () => proxy.useUserStore().allDict["funds_payment_method"]
+);
+const shippingMethod = computed(
+  () => proxy.useUserStore().allDict["shipping_method"]
+);
+// const companyId = computed(() => proxy.useUserStore().user.companyId);
+const deliveryType = ref([
+  {
+    label: "买方地址",
+    value: "1",
+  },
+  {
+    label: "工厂交付",
+    value: "2",
+  },
+  {
+    label: "其他",
+    value: "3",
+  },
+]);
+const supplierList = ref([]);
+const corporationList = ref([]);
+const templateList = ref([]);
+const customerUserList = ref([]);
+const countryData = ref([]);
+const provinceData = ref([]);
+const cityData = ref([]);
+
+const openProductCompany = ref(false);
+const copyType = ref(1);
+const copyContract = ref(false);
+const formData = reactive({
+  data: {
+    remark: "",
+  },
+});
+const uploadData = ref({});
+const formDom = ref(null);
+const judgeStatus = () => {
+  if (route.query.processType == 20 || route.query.processType == 10) {
+    return true;
+  }
+  if (props.queryData.recordList && props.queryData.recordList.length > 0) {
+    let data = props.queryData.recordList.filter(
+      (item) => item.status === 2 && item.nodeType !== 1
+    );
+    if (data && data.length > 0) {
+      return true;
+    }
+  }
+  return false;
+};
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  disabled: false,
+});
+const formConfig = computed(() => {
+  return [
+    // {
+    //   type: "slot",
+    //   slotName: "btn",
+    //   label: "",
+    //   itemWidth: 50,
+    // },
+    {
+      type: "title",
+      title: "贸易信息",
+      haveLine: false,
+    },
+    {
+      type: "slot",
+      slotName: "seller",
+      label: "",
+      itemWidth: 50,
+    },
+    {
+      type: "slot",
+      slotName: "buyer",
+      label: "",
+      itemWidth: 50,
+    },
+    {
+      type: "title",
+      title: "付款信息",
+      haveLine: true,
+    },
+    {
+      type: "select",
+      prop: "paymentMethod",
+      label: "付款方式",
+      data: fundsPaymentMethod.value,
+      itemWidth: 25,
+    },
+    {
+      type: "select",
+      prop: "invoiceType",
+      label: "发票类型",
+      data: invoiceType.value,
+      itemWidth: 25,
+    },
+    {
+      type: "title",
+      title: "交付信息",
+      haveLine: true,
+    },
+    // {
+    //   type: "radio",
+    //   prop: "ss",
+    //   label: "交货类型",
+    //   border: true,
+    //   data: deliveryType.value,
+    //   itemWidth: 50,
+    // },
+    {
+      type: "select",
+      prop: "deliveryType",
+      label: "交货类型",
+      border: true,
+      data: deliveryType.value,
+      itemWidth: 50,
+    },
+    {
+      type: "input",
+      prop: "address",
+      itemType: "textarea",
+      label: "详细地址",
+      itemWidth: 50,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "deliveryTime",
+      label: "交付日期",
+      itemWidth: 50,
+    },
+    {
+      type: "number",
+      prop: "warranty",
+      label: "质保期 (天)",
+      precision: 0,
+      min: 0,
+      controls: false,
+      itemWidth: 50,
+    },
+    // {
+    //   type: "select",
+    //   prop: "transportMethod",
+    //   label: "运输方式",
+    //   data: shippingMethod.value,
+    //   itemWidth: 50,
+    // },
+
+    // {
+    //   type: "slot",
+    //   slotName: "delivery",
+    //   label: "",
+    // },
+    {
+      type: "title",
+      title: "采购明细",
+      haveLine: true,
+    },
+    {
+      type: "slot",
+      slotName: "commodity",
+      label: "",
+    },
+    {
+      type: "title",
+      title: "其他收费项目",
+      haveLine: true,
+    },
+    {
+      type: "slot",
+      slotName: "otherCharge",
+      label: "",
+    },
+    {
+      type: "title",
+      title: "合同总金额",
+      haveLine: true,
+    },
+    {
+      type: "input",
+      prop: "amount",
+      label: "合同总金额",
+      itemWidth: 25,
+      disabled: true,
+    },
+    {
+      type: "title",
+      title: "合同条款",
+      haveLine: true,
+    },
+    {
+      type: "slot",
+      slotName: "contractClause",
+      label: "",
+    },
+  ];
+});
+const rules = ref({
+  buyCorporationId: [
+    { required: true, message: "请选择买方公司", trigger: "change" },
+  ],
+  buyAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
+  buyContactName: [
+    { required: true, message: "请输入联系人", trigger: ["change", "blur"] },
+  ],
+  buyContactNumber: [
+    { required: true, message: "请输入联系电话", trigger: "blur" },
+  ],
+  sellCorporationId: [
+    { required: true, message: "请选择卖方公司", trigger: "change" },
+  ],
+  countryId: [{ required: true, message: "请选择国家", trigger: "change" }],
+  sellAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
+  sellContactName: [
+    { required: true, message: "请输入联系人", trigger: ["change", "blur"] },
+  ],
+  sellContactNumber: [
+    { required: true, message: "请输入联系电话", trigger: "blur" },
+  ],
+  quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
+  price: [{ required: true, message: "请输入单价", trigger: "blur" }],
+  invoiceType: [
+    { required: true, message: "请选择发票类型", trigger: "change" },
+  ],
+  paymentMethod: [
+    { required: true, message: "请选择付款方式", trigger: "change" },
+  ],
+  deliveryType: [
+    { required: true, message: "请选择交货类型", trigger: "change" },
+  ],
+  address: [{ required: true, message: "请输入详细地址", trigger: ["blur"] }],
+  deliveryTime: [
+    { required: true, message: "请选择交付日期", trigger: "change" },
+  ],
+  warranty: [{ required: true, message: "请选择质保期 (天)", trigger: "blur" }],
+  payName: [{ required: true, message: "请输入收费项目", trigger: ["blur"] }],
+  amount: [{ required: true, message: "请输入金额", trigger: "blur" }],
+  remark: [{ required: true, message: "请输入条款内容", trigger: "blur" }],
+});
+const getDict = () => {
+  proxy
+    .post("/supplierInfo/page", {
+      pageNum: 1,
+      pageSize: 50,
+    })
+    .then((res) => {
+      supplierList.value = res.rows.map((x) => ({
+        ...x,
+        label: x.name,
+        value: x.id,
+      }));
+    });
+
+  proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
+    corporationList.value = res.rows.map((item) => {
+      return {
+        ...item,
+        label: item.name,
+        value: item.id,
+      };
+    });
+  });
+  proxy
+    .post("/contractTemplate/page", { pageNum: 1, pageSize: 999 })
+    .then((res) => {
+      templateList.value = res.rows.map((item) => {
+        return {
+          ...item,
+          label: item.templateName,
+          value: item.id,
+        };
+      });
+    });
+};
+const getCityData = (id, type, isChange) => {
+  proxy.post("/customizeArea/list", { parentId: id }).then((res) => {
+    if (type === "20") {
+      provinceData.value = res;
+      if (isChange) {
+        formData.data.provinceId = "";
+        formData.data.provinceName = "";
+        formData.data.cityId = "";
+        formData.data.cityName = "";
+      }
+    } else if (type === "30") {
+      cityData.value = res;
+      if (isChange) {
+        formData.data.cityId = "";
+        formData.data.cityName = "";
+      }
+    } else {
+      countryData.value = res;
+    }
+  });
+};
+getDict();
+getCityData("0");
+
+const buyCorporationIdChange = (val) => {
+  if (val) {
+    proxy.post("/corporation/detail", { id: val }).then((res) => {
+      formData.data.buyCountryName = res.countryName;
+      formData.data.buyProvinceName = res.provinceName;
+      formData.data.buyCityName = res.cityName;
+      formData.data.buyAddress = res.address;
+    });
+  }
+};
+
+const changeSupplier = (val) => {
+  changeProductPrice();
+  formData.data.countryId = "";
+  formData.data.provinceId = "";
+  formData.data.cityId = "";
+  formData.data.sellAddress = "";
+  formData.data.sellContactName = "";
+  formData.data.sellContactNumber = "";
+  if (val) {
+    let data = supplierList.value.filter((item) => item.id === val);
+    if (data && data.length > 0) {
+      formData.data.countryId = data[0].countryId;
+      formData.data.provinceId = data[0].provinceId;
+      formData.data.cityId = data[0].cityId;
+      formData.data.sellAddress = data[0].areaDetail;
+      formData.data.sellContactName = data[0].contactPerson;
+      formData.data.sellContactNumber = data[0].contactNumber;
+      if (formData.data.countryId) {
+        getCityData(formData.data.countryId, "20");
+      }
+      if (formData.data.provinceId) {
+        getCityData(formData.data.provinceId, "30");
+      }
+    }
+  }
+};
+
+const changeProductPrice = () => {
+  let productIds = formData.data.purchaseProductList.map((x) => x.productId);
+  if (productIds && productIds.length > 0) {
+    proxy
+      .post("/ehsdPurchase/getProductPriceInfo", {
+        productIds: productIds,
+        sellCorporationId: formData.data.sellCorporationId
+          ? formData.data.sellCorporationId
+          : "",
+      })
+      .then((resOne) => {
+        for (let i = 0; i < formData.data.purchaseProductList.length; i++) {
+          const iele = formData.data.purchaseProductList[i];
+          for (const key in resOne) {
+            if (iele.productId == key) {
+              iele.purchaseProductPriceList = resOne[key].purchaseProductList
+                .map((x) => ({
+                  createTime: x.createTime || "",
+                  price: x.price,
+                }))
+                .filter((y, index) => index < 3);
+              iele.purchaseProductPriceListOne = resOne[
+                key
+              ].purchaseProductList.map((x) => ({
+                createTime: x.createTime || "",
+                price: x.price,
+              }));
+              iele.topPriceList = resOne[key].topPriceList
+                .map((x) => ({
+                  supplierName: x.supplierName,
+                  price: x.price,
+                }))
+                .filter((y, index) => index < 3);
+
+              iele.supplyPurchaseProductPriceList = resOne[
+                key
+              ].supplyPurchaseProductList
+                .map((x) => ({
+                  createTime: x.createTime || "",
+                  price: x.price,
+                }))
+                .filter((y, index) => index < 3);
+            }
+          }
+        }
+      });
+  }
+};
+const onPicture = (path) => {
+  window.open(path, "_blank");
+};
+const handleRemove = (index) => {
+  formData.data.purchaseProductList.splice(index, 1);
+  totalAmount();
+};
+const calculationAmount = (att = "") => {
+  nextTick(() => {
+    if (
+      formData.data.purchaseProductList &&
+      formData.data.purchaseProductList.length > 0
+    ) {
+      for (let i = 0; i < formData.data.purchaseProductList.length; i++) {
+        let money = 0;
+        money = parseFloat(
+          Number(formData.data.purchaseProductList[i].quantity) *
+            Number(formData.data.purchaseProductList[i].price)
+        ).toFixed(2);
+        formData.data.purchaseProductList[i].amount = money;
+      }
+    }
+    nextTick(() => {
+      totalAmount();
+    });
+  });
+};
+
+const totalAmount = () => {
+  let money = 0;
+  if (
+    formData.data.purchaseProductList &&
+    formData.data.purchaseProductList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.purchaseProductList.length; i++) {
+      if (formData.data.purchaseProductList[i].amount) {
+        money = parseFloat(
+          Number(money) + Number(formData.data.purchaseProductList[i].amount)
+        ).toFixed(2);
+      }
+    }
+  }
+  if (
+    formData.data.purchaseProjectList &&
+    formData.data.purchaseProjectList.length > 0
+  ) {
+    for (let i = 0; i < formData.data.purchaseProjectList.length; i++) {
+      if (formData.data.purchaseProjectList[i].amount) {
+        money = parseFloat(
+          Number(money) + Number(formData.data.purchaseProjectList[i].amount)
+        ).toFixed(2);
+      }
+    }
+  }
+  formData.data.amount = money;
+};
+const clickAdd = () => {
+  if (
+    formData.data.purchaseProjectList &&
+    formData.data.purchaseProjectList.length > 0
+  ) {
+    formData.data.purchaseProjectList.push({
+      payName: "",
+      amount: null,
+      remark: "",
+    });
+  } else {
+    formData.data.purchaseProjectList = [
+      { payName: "", amount: null, remark: "" },
+    ];
+  }
+};
+const handleDelete = (index) => {
+  formData.data.purchaseProjectList.splice(index, 1);
+  totalAmount();
+};
+
+const querySearch = (queryString, callback) => {
+  proxy.post("/quotationPay/page", { payName: queryString }).then((res) => {
+    if (res.rows && res.rows.length > 0) {
+      res.rows = res.rows.map((item) => {
+        return {
+          ...item,
+          value: item.payName,
+        };
+      });
+      callback(res.rows);
+    } else {
+      callback([]);
+    }
+  });
+};
+
+const loadingSearch = ref(false);
+const remoteMethod = (keyword) => {
+  if (keyword && typeof keyword === "string") {
+    loadingSearch.value = true;
+    proxy.post("/supplierInfo/page", { keyword }).then((res) => {
+      supplierList.value = res.rows.map((x) => ({
+        ...x,
+        label: x.name,
+        value: x.id,
+      }));
+      loadingSearch.value = false;
+    });
+  }
+  return;
+};
+
+const handleSubmit = async () => {
+  let flag = await formDom.value.handleSubmit(() => {});
+  if (flag) {
+    return true;
+  } else {
+    setTimeout(() => {
+      const errorDiv = document.getElementsByClassName("is-error");
+      errorDiv[0].scrollIntoView();
+    }, 0);
+  }
+  return flag;
+};
+
+const updateContent = (val) => {
+  formData.data.remark = val;
+};
+const remarkEditor = ref(null);
+const changeContractTemplate = (val) => {
+  if (val) {
+    proxy.post("/contractTemplate/detail", { id: val }).then((res) => {
+      remarkEditor.value.changeHtml(res.templateContent);
+    });
+  }
+};
+
+const getFormData = () => {
+  return proxy.deepClone(formData.data);
+};
+// 向父组件暴露
+defineExpose({
+  getFormData,
+  handleSubmit,
+});
+
+const getAllData = (businessId) => {
+  if (businessId) {
+    proxy.post("/ehsdPurchase/detail", { id: businessId }).then((res) => {
+      res.countryId = res.sellCountryId;
+      res.provinceId = res.sellProvinceId;
+      res.cityId = res.sellCityId;
+      if (res.grossProfitInfoList && res.grossProfitInfoList.length > 0) {
+        $bus.emit("getGrossData", res.grossProfitInfoList);
+      }
+      for (let key in res) {
+        if (!["ehsdPurchaseProductList", "purchaseArrivalList"].includes(key)) {
+          formData.data[key] = res[key];
+        }
+      }
+      remarkEditor.value.changeHtml(formData.data.remark);
+      if (
+        formData.data.purchaseProductList &&
+        formData.data.purchaseProductList.length > 0
+      ) {
+        let ids = formData.data.purchaseProductList.map((x) => x.productId);
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: ids,
+          })
+          .then((fileObj) => {
+            for (let i = 0; i < formData.data.purchaseProductList.length; i++) {
+              const e = formData.data.purchaseProductList[i];
+              for (const key in fileObj) {
+                if (e.productId === key) {
+                  e.fileList = fileObj[key] || [];
+                  if (e.fileList && e.fileList.length > 0) {
+                    e.fileUrl = e.fileList[0].fileUrl;
+                  }
+                }
+              }
+            }
+          });
+        changeProductPrice();
+      }
+      if (formData.data.countryId) {
+        getCityData(formData.data.countryId, "20");
+      }
+      if (formData.data.provinceId) {
+        getCityData(formData.data.provinceId, "30");
+      }
+    });
+  }
+};
+
+const getProductList = (ids) => {
+  if (ids && ids.length > 0) {
+    proxy.post("/subscribeDetail/detail", { ids }).then((res) => {
+      if (res && res.length > 0) {
+        formData.data.purchaseProductList = res.map((item) => {
+          let dataResourceId =
+            item.dataType == 0 ? item.id : item.contractDetailId;
+          return {
+            productId: item.productId,
+            contractId: item.contractId,
+            productName: item.productName,
+            productCode: item.productCustomCode,
+            productLength: item.productLength,
+            productWidth: item.productWidth,
+            productHeight: item.productHeight,
+            subscribeCount: item.count || 0,
+            purchaseCount: item.purchaseCount || 0,
+            quantity: null,
+            price: "",
+            amount: "",
+            remark: "",
+            fileUrl: "",
+            dataResource: item.dataType,
+            dataResourceId: dataResourceId,
+            subscribeDetailId: item.id,
+          };
+        });
+        formData.data.dataResource =
+          formData.data.purchaseProductList[0].dataResource;
+        formData.data.dataResourceId = res[0].contractId;
+        let productIdList = res.map((x) => x.productId);
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: productIdList,
+          })
+          .then((fileObj) => {
+            for (let i = 0; i < formData.data.purchaseProductList.length; i++) {
+              const e = formData.data.purchaseProductList[i];
+              for (const key in fileObj) {
+                if (e.productId === key) {
+                  if (fileObj[key] && fileObj[key].length > 0) {
+                    e.fileUrl = fileObj[key][0].fileUrl;
+                  }
+                }
+              }
+            }
+          });
+
+        changeProductPrice();
+      }
+    });
+  }
+};
+onMounted(() => {
+  formOption.disabled = judgeStatus();
+  if (route.query && route.query.ids) {
+    let ids = route.query.ids.split(",");
+    getProductList(ids);
+  }
+  if (route.query.businessId && route.query.processType) {
+    getAllData(route.query.businessId);
+  }
+});
+
+// watch(
+//   () => props.queryData,
+//   (val) => {
+//     nextTick(() => {
+//       formOption.disabled = judgeStatus();
+//     });
+//     if (val.businessId && val.processType) {
+//       getAllData(val.businessId);
+//     }
+//   },
+//   {
+//     deep: true,
+//     immediate: true,
+//   }
+// );
+
+const optionTwo = reactive({
+  data: {
+    tooltip: {
+      trigger: "axis",
+    },
+    // legend: {
+    //   data: ["价格"],
+    // },
+    grid: {
+      left: "3%",
+      right: "4%",
+      top: "10%",
+      bottom: "3%",
+      containLabel: true,
+    },
+    // toolbox: {
+    //   feature: {
+    //     saveAsImage: {},
+    //   },
+    // },
+    xAxis: {
+      type: "category",
+      boundaryGap: false,
+      data: [],
+    },
+    yAxis: {
+      type: "value",
+    },
+    series: [
+      {
+        name: "价格",
+        type: "line",
+        data: [],
+      },
+    ],
+  },
+});
+const showEcharts = (row, index) => {
+  let myChart = null;
+  myChart = echarts.init(document.getElementById(row.productId + index));
+  window.addEventListener("resize", () => {
+    myChart.resize();
+  });
+  if (
+    row.purchaseProductPriceListOne &&
+    row.purchaseProductPriceListOne.length > 0
+  ) {
+    optionTwo.data.xAxis.data = row.purchaseProductPriceListOne.map((item) => {
+      return item.createTime.slice(0, 10);
+    });
+    optionTwo.data.series[0].data = row.purchaseProductPriceListOne.map(
+      (item) => {
+        return item.price;
+      }
+    );
+  } else {
+    optionTwo.data.xAxis.data = [];
+    optionTwo.data.series[0].data = [];
+  }
+  myChart.setOption(optionTwo.data);
+  myChart.resize();
+};
+
+const clickCopy = (type) => {
+  copyType.value = type;
+  copyContract.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+.img {
+  object-fit: contain;
+  width: 16px;
+  height: 16px;
+  vertical-align: middle;
+}
+.pic {
+  object-fit: contain;
+  width: 50px;
+  height: 50px;
+  cursor: pointer;
+  vertical-align: middle;
+}
+
+.ql-editor {
+  padding: 0px;
+}
+</style>

+ 1 - 1
src/main.js

@@ -138,7 +138,7 @@ app.use(ElementPlus, {
   size: Cookies.get('size') || 'default'
 })
 // 是否可以通过点击 modal 关闭 Dialog
-// app._context.components.ElDialog.props.closeOnClickModal.default = false;
+app._context.components.ElDialog.props.closeOnClickModal.default = false;
 // 当关闭 Dialog 时,销毁其中的元素
 app._context.components.ElDialog.props.destroyOnClose.default = true;
 app.mount('#app')

+ 3 - 3
src/views/EHSD/procurement/purchasedEHSD/index.vue

@@ -355,15 +355,15 @@ const printObj = ref({
 });
 
 const handleClickCode = (row) => {
-  let submitType = row.dataResource > 0 ? "10" : "20";
+  // let submitType = row.dataResource > 0 ? "10" : "20";
   proxy.$router.push({
     path: "/platform_manage/process/processApproval",
     query: {
-      flowKey: submitType == "10" ? "ehsd_purchase_flow" : "purchase_flow",
+      flowKey: "purchase_flow",
       id: row.flowId,
       processType: 20,
       businessId: row.id,
-      submitType,
+      // submitType,
     },
   });
 };

+ 38 - 24
src/views/process/processApproval/index.vue

@@ -38,8 +38,9 @@
 
         <!-- 样品单采购、交接单采购 -->
         <template v-else-if="flowForm.flowKey == 'ehsd_purchase_flow'">
-          <PurchaseEHSD ref="makeDom" :queryData="queryData.data" v-if="flowForm.submitType === '10'" @auxiliaryChange="(e) => getAuxiliaryData(e)">
-          </PurchaseEHSD>
+
+          <!-- <PurchaseEHSD ref="makeDom" :queryData="queryData.data" v-if="flowForm.submitType === '10'" @auxiliaryChange="(e) => getAuxiliaryData(e)">
+          </PurchaseEHSD> -->
           <!-- <SendPurchase
             ref="makeDom"
             :queryData="queryData.data"
@@ -49,7 +50,8 @@
         </template>
 
         <template v-else-if="flowForm.flowKey == 'purchase_flow'">
-          <SendPurchase ref="makeDom" :queryData="queryData.data" @auxiliaryChange="(e) => getAuxiliaryData(e)"></SendPurchase>
+          <Purchase ref="makeDom" :queryData="queryData.data"> </Purchase>
+          <!-- <SendPurchase ref="makeDom" :queryData="queryData.data" @auxiliaryChange="(e) => getAuxiliaryData(e)"></SendPurchase> -->
         </template>
 
         <PurchaseChangeEHSD ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'ehsd_purchase_update_flow'"
@@ -114,9 +116,7 @@
       <el-tabs v-model="activeName" class="demo-tabs">
         <el-tab-pane label="处理意见" name="first" v-if="isShowSubmitDom">
           <div style="overflow: auto; height: calc(100vh - 200px)">
-            <div style="padding-bottom:50px"
-                 v-if="(userInfo.roles.includes('ceo') || userInfo.roles.includes('salesDirector') ||
-                 userInfo.roles.includes('financeOfficer') || userInfo.roles.includes('approve_ accountant')) && (route.query.processType==10 || route.query.processType==30) &&(chartData && chartData.length>0)">
+            <div style="padding-bottom:50px" v-if="showChart">
               <div style="margin-bottom:10px;">
                 <TitleInfo :content="'利润预算波动'"></TitleInfo>
               </div>
@@ -219,7 +219,7 @@ import useTagsViewStore from "@/store/modules/tagsView.js";
 import { useRouter, useRoute } from "vue-router";
 import Contract from "@/components/process/SF/Contract";
 import PriceSheet from "@/components/process/SF/PriceSheet";
-
+import Purchase from "@/components/process/SF/Purchase";
 // 消息提示
 import { ElMessage, ElMessageBox } from "element-plus";
 //决策辅助
@@ -520,6 +520,7 @@ const skipPage = () => {
     subscribe_flow: "Subscribe",
     contract_flow: "Contract",
     sale_quotation_flow: "Quotation",
+    purchase_flow: "Purchased",
   };
   const useTagsStore = useTagsViewStore();
   useTagsStore.delVisitedView(router.currentRoute.value);
@@ -637,7 +638,17 @@ const optionTwo = reactive({
     ],
   },
 });
+const showChart = ref(false);
 onMounted(async () => {
+  if (
+    (userInfo.roles.includes("ceo") ||
+      userInfo.roles.includes("salesDirector") ||
+      userInfo.roles.includes("financeOfficer") ||
+      userInfo.roles.includes("approve_ accountant")) &&
+    (route.query.processType == 10 || route.query.processType == 30)
+  ) {
+    showChart.value = true;
+  }
   // 路由进入
   if (route.query && route.query.flowKey) {
     //processType 10 为修改 20为查看 30回退发起
@@ -665,23 +676,26 @@ onMounted(async () => {
   }
 
   $bus.on("getGrossData", (data) => {
-    // if (data && data.length > 1) {
-    //   myChart = echarts.init(chartDom.value);
-    //   window.addEventListener("resize", () => {
-    //     myChart.resize();
-    //   });
-    //   chartData.value = data.slice(1, data.length);
-    //   optionTwo.data.xAxis.data = chartData.value.map((item) => {
-    //     return item.createTime.slice(0, 10);
-    //   });
-    //   optionTwo.data.series[0].data = chartData.value.map((item) => {
-    //     return item.gross;
-    //   });
-    //   myChart.setOption(optionTwo.data);
-    //   myChart.resize();
-    // } else {
-    //   return;
-    // }
+    nextTick(() => {
+      if (data && data.length > 1 && showChart.value) {
+        myChart = echarts.init(chartDom.value);
+        window.addEventListener("resize", () => {
+          myChart.resize();
+        });
+        chartData.value = data;
+        // chartData.value = data.slice(1, data.length);
+        optionTwo.data.xAxis.data = chartData.value.map((item) => {
+          return item.createTime.slice(0, 10);
+        });
+        optionTwo.data.series[0].data = chartData.value.map((item) => {
+          return item.gross;
+        });
+        myChart.setOption(optionTwo.data);
+        myChart.resize();
+      } else {
+        return;
+      }
+    });
   });
 });
 

+ 38 - 43
src/views/process/processConfig/processChart.vue

@@ -1,57 +1,52 @@
 <template>
-	<div class="processChart">
-		<div class="from">
-			<div class="commons-title">基础配置</div>
-			<div>
-				<el-form labelPosition='top'>
-					<el-form-item label="流程标题" label-width="80px">
-						<el-input v-model="title" placeholder="请输入流程标题"></el-input>
-						
-					</el-form-item>
-				</el-form>
-			</div>
-		</div>
-		<div class="content">
-			<div class="commons-title">流程节点配置</div>
-			<div class="chart-warp">
-				<vueFlow :title='title'></vueFlow>
-			</div>
-		</div>
-	</div>
+  <div class="processChart">
+    <div class="from">
+      <div class="commons-title">基础配置</div>
+      <div>
+        <el-form labelPosition='top'>
+          <el-form-item label="流程标题" label-width="80px">
+            <el-input v-model="title" placeholder="请输入流程标题"></el-input>
+
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+    <div class="content">
+      <div class="commons-title">流程节点配置</div>
+      <div class="chart-warp">
+        <vueFlow :title='title'></vueFlow>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script setup name="ProcessChart">
-
-import vueFlow from '@/views/process/processConfig/vueFlow.vue'
-const title = ref('')
-onMounted(() => {
-	
-})
+import vueFlow from "@/views/process/processConfig/vueFlow.vue";
+const title = ref("");
+onMounted(() => {});
 </script>
 
 <style lang="scss" scoped>
 .processChart {
-	padding: 20px;
-	display: flex;
-	justify-content: space-between;
-	.from {
-		width: 400px;
-		background: #fff;
-		border-radius: 5px;
-		padding: 20px;
-	}
-	.content {
-		width: calc(100% - 420px);
-		border-radius: 5px;
-		padding: 20px;
-		background: #fff;
-	}
+  padding: 10px;
+  display: flex;
+  justify-content: space-between;
+  .from {
+    width: 230px;
+    background: #fff;
+    border-radius: 5px;
+    padding: 15px;
+  }
+  .content {
+    width: calc(100% - 240px);
+    border-radius: 5px;
+    padding: 15px;
+    background: #fff;
+  }
 }
 .chart-warp {
-	height: calc(100vh - 280px);
+  height: calc(100vh - 190px);
 }
-
 </style>
 <style>
-
 </style>

+ 13 - 6
src/views/process/processConfig/vueFlow.vue

@@ -5,7 +5,7 @@
 		<div id="graph-container"></div>
 		<div id="minimap"></div>
 	</div>
-	<el-button @click="submitAll" type="primary">保存</el-button>
+	<el-button @click="submitAll" type="primary" style="margin-top:15px">保存</el-button>
 	<el-dialog
 		title="节点信息配置"
 		v-model="dialogVisible"
@@ -588,7 +588,7 @@ const antvInit = (data) => {
       },
     ],
     layoutOptions: {
-      columns: 2,
+      columns: 1,
       columnWidth: 170,
       rowHeight: 100,
     },
@@ -975,7 +975,7 @@ onMounted(() => {
   }, 500);
 });
 </script>
-<style lang="scss">
+<style lang="scss" scope>
 #minimap .x6-widget-minimap {
   border: 1px solid #dcdcdc;
 }
@@ -987,6 +987,10 @@ onMounted(() => {
 }
 .x6-widget-stencil-content {
   top: 0 !important;
+  &::-webkit-scrollbar {
+    width: 2px !important;
+    height: 2px !important;
+  }
 }
 .vueFlow {
   position: relative;
@@ -1000,10 +1004,10 @@ onMounted(() => {
   #stencil {
     position: fixed;
     top: 250px;
-    left: 40px;
+    left: 30px;
     z-index: 100;
-    width: 360px;
-    height: 500px;
+    width: 190px;
+    height: 550px;
     background: #fff;
     overflow: hidden;
     background: #eee;
@@ -1018,4 +1022,7 @@ onMounted(() => {
     top: 0;
   }
 }
+#stencil .x6-widget-stencil-content .x6-widget-stencil-group-content .x6-graph {
+  // height: 900px !important;
+}
 </style>

+ 38 - 43
src/views/production/project/processConfig/processChart.vue

@@ -1,57 +1,52 @@
 <template>
-	<div class="processChart">
-		<div class="from">
-			<div class="commons-title">基础配置</div>
-			<div>
-				<el-form labelPosition='top'>
-					<el-form-item label="流程标题" label-width="80px">
-						<el-input v-model="title" placeholder="请输入流程标题"></el-input>
-						
-					</el-form-item>
-				</el-form>
-			</div>
-		</div>
-		<div class="content">
-			<div class="commons-title">流程节点配置</div>
-			<div class="chart-warp">
-				<vueFlow :title='title' @changeTitle="e => title = e"></vueFlow>
-			</div>
-		</div>
-	</div>
+  <div class="processChart">
+    <div class="from">
+      <div class="commons-title">基础配置</div>
+      <div>
+        <el-form labelPosition='top'>
+          <el-form-item label="流程标题" label-width="80px">
+            <el-input v-model="title" placeholder="请输入流程标题"></el-input>
+
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+    <div class="content">
+      <div class="commons-title">流程节点配置</div>
+      <div class="chart-warp">
+        <vueFlow :title='title' @changeTitle="e => title = e"></vueFlow>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script setup name="ProcessChart">
-
-import vueFlow from '@/views/process/processConfig/vueFlow.vue'
-const title = ref('')
-onMounted(() => {
-	
-})
+import vueFlow from "@/views/process/processConfig/vueFlow.vue";
+const title = ref("");
+onMounted(() => {});
 </script>
 
 <style lang="scss" scoped>
 .processChart {
-	padding: 20px;
-	display: flex;
-	justify-content: space-between;
-	.from {
-		width: 400px;
-		background: #fff;
-		border-radius: 5px;
-		padding: 20px;
-	}
-	.content {
-		width: calc(100% - 420px);
-		border-radius: 5px;
-		padding: 20px;
-		background: #fff;
-	}
+  // padding: 20px;
+  display: flex;
+  justify-content: space-between;
+  .from {
+    width: 400px;
+    background: #fff;
+    border-radius: 5px;
+    padding: 15px;
+  }
+  .content {
+    width: calc(100% - 420px);
+    border-radius: 5px;
+    padding: 15px;
+    background: #fff;
+  }
 }
 .chart-warp {
-	height: calc(100vh - 280px);
+  height: calc(100vh - 280px);
 }
-
 </style>
 <style>
-
 </style>

+ 28 - 17
src/views/production/project/processConfig/vueFlow.vue

@@ -1,5 +1,5 @@
 <template >
-  <div class="vueFlow">
+  <div class="vueFlow1">
     <div id="container"></div>
     <div id="stencil"></div>
     <div id="graph-container"></div>
@@ -306,11 +306,17 @@ const antvInit = async (data) => {
       },
     },
   });
-  // graph.use(
-  //   new MiniMap({
-  //     container: document.getElementById("minimap"),
-  //   })
-  // );
+  // nextTick(() => {
+  //   graph.use(
+  //     new MiniMap({
+  //       container: document.getElementById("minimap"),
+  //       width: 200,
+  //       height: 160,
+  //       scalable: false,
+  //     })
+  //   );
+  // });
+
   const stencil = new Stencil({
     title: "流程图",
     target: graph,
@@ -324,7 +330,7 @@ const antvInit = async (data) => {
       },
     ],
     layoutOptions: {
-      columns: 2,
+      columns: 1,
       columnWidth: 170,
       rowHeight: 100,
     },
@@ -635,7 +641,7 @@ const antvInit = async (data) => {
   } else {
     graph.addNode({
       shape: "start-btn",
-      x: 500,
+      x: 300,
       y: 20,
       label: "开始",
       id: 1,
@@ -644,7 +650,7 @@ const antvInit = async (data) => {
 
     graph.addNode({
       shape: "end-btn",
-      x: 500,
+      x: 300,
       y: 300,
       label: "结束",
       id: 99,
@@ -685,7 +691,7 @@ defineExpose({
   submitAll,
 });
 </script>
-<style lang="scss">
+<style lang="scss" scope>
 #minimap .x6-widget-minimap {
   border: 1px solid #dcdcdc;
 }
@@ -697,8 +703,12 @@ defineExpose({
 }
 .x6-widget-stencil-content {
   top: 0 !important;
+  &::-webkit-scrollbar {
+    width: 2px !important;
+    height: 2px !important;
+  }
 }
-.vueFlow {
+.vueFlow1 {
   // position: relative;
   display: flex;
   justify-content: space-between;
@@ -710,15 +720,16 @@ defineExpose({
   #stencil {
     // position: fixed;
     position: absolute;
-    top: 90px;
-    left: 40px;
+    top: 50px;
+    left: 30px;
     z-index: 100;
-    width: 360px;
+    width: 190px;
     height: 600px;
     background: #fff;
     overflow: hidden;
-    background: #eee;
-    border-radius: 20px;
+    // background: #fff;
+    border-radius: 10px;
+    // border: 1px solid #eee;
   }
   #container {
   }
@@ -732,6 +743,6 @@ defineExpose({
 }
 
 #stencil .x6-widget-stencil-content .x6-widget-stencil-group-content .x6-graph {
-  height: 1000px !important;
+  height: 900px !important;
 }
 </style>

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

@@ -33,30 +33,23 @@
         </template>
       </byTable>
     </div>
-    <el-dialog :title="modalType == 'add' ? '添加产线' : '编辑产线'" v-model="dialogVisible" width="90%" destroy-on-close>
-      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform" v-loading="submitLoading">
-        <!-- <template #lineSlot>
-          <el-transfer v-model="selectLine" filterable filter-placeholder="搜索" :data="lineData" :titles="['可选', '已选']" target-order="push">
-            <template #default="{ option }">
-              <div class="parent">
-                <div :draggable="selectLine.includes(option.key)" @dragstart="dragStar($event, option)" @dragover="dragOver($event, option)"
-                     @drop="handleDrop($event)" style="cursor: default" :id="option.key">
-                  {{ option.label }}
-                </div>
-              </div>
-            </template>
-          </el-transfer>
-        </template> -->
-        <template #lineSlot>
+    <el-dialog :title="modalType == 'add' ? '添加产线' : '编辑产线'" v-model="dialogVisible" width="95%" destroy-on-close>
+      <div style="display:flex">
+        <div style="width:350px">
+          <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="byform" v-loading="submitLoading">
+          </byForm>
+          <div style="text-align:center">
+            <el-button @click="dialogVisible = false" size="default">取 消</el-button>
+            <el-button type="primary" @click="submitForm" size="default" :loading="submitLoading">
+              确 定
+            </el-button>
+          </div>
+
+        </div>
+        <div style="width:calc(100% - 350px)">
           <div class="processChart" style="width:100%">
             <div class="from">
               <div class="commons-title">工序</div>
-              <!-- <div>
-                <el-form labelPosition='top'>
-                  <el-form-item label="工序" label-width="80px">
-                  </el-form-item>
-                </el-form>
-              </div> -->
             </div>
             <div class="content">
               <div class="commons-title">产线路线</div>
@@ -65,16 +58,12 @@
               </div>
             </div>
           </div>
+        </div>
+      </div>
 
-        </template>
-
-      </byForm>
-      <template #footer>
-        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
-        <el-button type="primary" @click="submitForm" size="default" :loading="submitLoading">
-          确 定
-        </el-button>
-      </template>
+      <!-- <template #footer>
+     
+      </template> -->
     </el-dialog>
 
     <el-dialog v-model="openProduct" title="选择产品" width="70%" append-to-body>
@@ -297,6 +286,10 @@ const byform = ref(null);
 const formConfig = computed(() => {
   return [
     {
+      type: "title1",
+      title: "基本信息",
+    },
+    {
       type: "input",
       prop: "name",
       label: "产线名称",
@@ -330,11 +323,11 @@ const formConfig = computed(() => {
       multiple: true,
       isShow: formData.data.radioaa == "1",
     },
-    {
-      type: "slot",
-      slotName: "lineSlot",
-      label: "产线路线",
-    },
+    // {
+    //   type: "slot",
+    //   slotName: "lineSlot",
+    //   label: "产线路线",
+    // },
     // {
     //   type: "slot",
     //   slotName: "productSlot",
@@ -542,20 +535,20 @@ const swapItems = (sourceKey, targetKey) => {
 
 .processChart {
   border: 1px solid #ccc;
-  padding: 20px;
+  // padding: 20px;
   display: flex;
   justify-content: space-between;
   position: relative;
   .from {
-    width: 400px;
+    width: 230px;
     background: #fff;
     border-radius: 5px;
-    padding: 20px;
+    padding: 15px;
   }
   .content {
-    width: calc(100% - 420px);
+    width: calc(100% - 230px);
     border-radius: 5px;
-    padding: 20px;
+    padding: 15px;
     background: #fff;
   }
 }

+ 14 - 6
src/views/purchaseManage/purchaseManage/purchase/index.vue

@@ -6,7 +6,7 @@
                :selectConfig="selectConfig" :table-events="{
           //element talbe事件都能传
           select: selectRow,
-          'select-all': selectRow,
+       
         }" :action-list="[
           {
             text: '采购',
@@ -436,11 +436,19 @@ watch(selectData, (newVal, oldVal) => {
     });
   } else if (newVal.length == 1) {
     const current = newVal[0];
-    sourceList.value.data.forEach((x) => {
-      if (x.corporationId !== current.corporationId) {
-        x.isCheck = false;
-      }
-    });
+    if (current.contractId) {
+      sourceList.value.data.forEach((x) => {
+        if (x.contractId !== current.contractId) {
+          x.isCheck = false;
+        }
+      });
+    } else {
+      sourceList.value.data.forEach((x) => {
+        if (x.dataType !== current.dataType) {
+          x.isCheck = false;
+        }
+      });
+    }
   }
 });
 

+ 45 - 67
src/views/purchaseManage/purchaseManage/subscribe/index.vue

@@ -94,9 +94,12 @@
 import { ElMessage, ElMessageBox } from "element-plus";
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
-import { computed, defineComponent, ref } from "vue";
 import { getToken } from "@/utils/auth";
 
+const { proxy } = getCurrentInstance();
+const materialUnit = computed(
+  () => proxy.useUserStore().allDict["material_unit"]
+);
 const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
 const headers = ref({ Authorization: "Bearer " + getToken() });
 const uploadData = ref({});
@@ -109,6 +112,7 @@ const sourceList = ref({
     pageNum: 1,
     pageSize: 10,
     status: "",
+    dataType: 0,
   },
 });
 let dialogVisible = ref(false);
@@ -117,26 +121,33 @@ let fileList = ref([]);
 let rules = ref({
   name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
 });
-const { proxy } = getCurrentInstance();
-const selectConfig = reactive([
+const statusData = ref([
   {
-    label: "货品类型",
-    prop: "definition",
-    data: [
-      {
-        label: "产品",
-        value: "1",
-      },
-      {
-        label: "物料",
-        value: "2",
-      },
-    ],
+    label: "审批中",
+    value: "10",
+  },
+  {
+    label: "待采购",
+    value: "15",
+  },
+  {
+    label: "部分采购",
+    value: "30",
+  },
+  {
+    label: "已采购",
+    value: "20",
   },
   {
+    label: "已作废",
+    value: "99",
+  },
+]);
+const selectConfig = computed(() => [
+  {
     label: "状态",
     prop: "status",
-    data: [],
+    data: statusData.value,
   },
 ]);
 const config = computed(() => {
@@ -145,33 +156,37 @@ const config = computed(() => {
       attrs: {
         label: "申购单号",
         prop: "subscribeCode",
+        width: 150,
       },
     },
-    {
-      attrs: {
-        label: "货品类型",
-        prop: "productDefinition",
-      },
-      render(productDefinition) {
-        return productDefinition == 1 ? "产品" : "物料";
-      },
-    },
+    // {
+    //   attrs: {
+    //     label: "物料类型",
+    //     prop: "productDefinition",
+    //   },
+    //   render(productDefinition) {
+    //     return productDefinition == 1 ? "产品" : "物料";
+    //   },
+    // },
     {
       attrs: {
         label: "所属分类",
         prop: "productCategory",
+        "min-width": 130,
       },
     },
     {
       attrs: {
-        label: "货品编码",
+        label: "物料编码",
         prop: "productCode",
+        width: 150,
       },
     },
     {
       attrs: {
-        label: "货品名称",
+        label: "物料名称",
         prop: "productName",
+        "min-width": 130,
       },
     },
     {
@@ -181,19 +196,14 @@ const config = computed(() => {
         width: 60,
       },
       render(unit) {
-        return proxy.dictValueLabel(unit, productUnit.value);
+        return proxy.dictKeyValue(unit, materialUnit.value);
       },
     },
     {
       attrs: {
         label: "申购数量",
         prop: "count",
-      },
-    },
-    {
-      attrs: {
-        label: "审批状态",
-        prop: "count11",
+        width: 100,
       },
     },
     {
@@ -435,39 +445,7 @@ const handleRemove = (file) => {
 const handleClose = (index) => {
   fileList.value.splice(index, 1);
 };
-const statusData = ref([
-  {
-    label: "审批中",
-    value: "10",
-  },
-  {
-    label: "待采购",
-    value: "15",
-  },
-  {
-    label: "部分采购",
-    value: "30",
-  },
-  {
-    label: "已采购",
-    value: "20",
-  },
-  {
-    label: "已作废",
-    value: "99",
-  },
-]);
-selectConfig[1].data = statusData.value;
-const productUnit = ref([]);
-const getDict = () => {
-  proxy.getDictOne(["unit"]).then((res) => {
-    productUnit.value = res["unit"].map((x) => ({
-      label: x.dictValue,
-      value: x.dictKey,
-    }));
-  });
-};
-getDict();
+
 getList();
 </script>