Prechádzať zdrojové kódy

Merge branch 'master' of http://36.137.93.232:3000/hf/byte-sailing-new

lxf 2 rokov pred
rodič
commit
30f91b20d3

+ 1 - 1
package.json

@@ -30,7 +30,7 @@
     "@vueup/vue-quill": "^1.0.0-alpha.40",
     "@vueuse/core": "9.5.0",
     "axios": "0.27.2",
-    "echarts": "5.4.0",
+    "echarts": "^5.4.0",
     "element-plus": "2.2.27",
     "file-saver": "2.0.5",
     "fuse.js": "6.6.2",

+ 9 - 12
src/components/product/treeList.vue

@@ -268,18 +268,15 @@ const handleMouseOver = (data) => {
     height: calc(100vh - 270px);
     overflow-y: auto;
     overflow-x: auto;
+    .el-tree {
+      // .el-tree-node__content {
+      //   display: block;
+      // }
+
+      .el-tree-node > .el-tree-node__children {
+        overflow: visible;
+      }
+    }
   }
 }
-.el-tree-node__content {
-  display: block;
-  // padding-left: 24px !important;
-  // position: relative;
-}
-.el-tree-node__content > .el-tree-node__expand-icon {
-  // position: absolute;
-  // left: 0px;
-}
-.el-tree-node > .el-tree-node__children {
-  overflow: visible;
-}
 </style>

+ 5 - 3
src/views/WDLY/basic/product/index.vue

@@ -822,7 +822,11 @@ const getDept = () => {
 const getDtl = (row) => {
   modalType.value = "edit";
   proxy.post("/productInfo/detail", { id: row.id }).then((res) => {
-    deptIdCopy.value = parse(res.victoriatouristJson).deptId.value;
+    if (res.victoriatouristJson) {
+      if (res.victoriatouristJson.deptId) {
+        deptIdCopy.value = parse(res.victoriatouristJson).deptId.value;
+      }
+    }
     fileList.value = row.fileList.map((x) => ({ ...x, url: x.fileUrl }));
     fileListCopy.value = [...fileList.value];
     res.type = res.type + ""; //type回显
@@ -830,7 +834,6 @@ const getDtl = (row) => {
     res.victoriatouristJson = res.victoriatouristJson
       ? JSON.parse(res.victoriatouristJson)
       : {};
-    // res.victoriatouristJson.deptId =
     res.combination = res.victoriatouristJson.combination
       ? res.victoriatouristJson.combination + ""
       : "0";
@@ -965,7 +968,6 @@ const getDict = () => {
   proxy.getDict(["unit", "product_type"]).then((res) => {
     productUnit.value = res["unit"];
     productType.value = res["product_type"];
-    console.log(res, "wqasd");
     formConfig.value[1].data = productType.value.map((x) => ({
       label: x.dictValue,
       value: x.dictKey,

+ 1 - 0
src/views/WDLY/purchaseManage/alreadyPurchase/index.vue

@@ -262,6 +262,7 @@ const config = computed(() => {
       attrs: {
         label: "采购时间",
         prop: "createTime",
+        width: 160,
       },
     },
     {

+ 137 - 30
src/views/customer/file/index.vue

@@ -14,37 +14,81 @@
             action: () => openModal('add'),
           },
         ]"
-        @get-list="getList">
+        @get-list="getList"
+      >
         <template #address="{ item }">
           <span>{{ item.countryName }}</span>
           <span v-if="item.provinceName"> ,{{ item.provinceName }}</span>
           <span v-if="item.cityName"> ,{{ item.cityName }}</span>
         </template>
+        <template #name="{ item }">
+          <div
+            style="cursor: pointer; color: #409eff"
+            @click="handleClickName(item)"
+          >
+            {{ item.name }}
+          </div>
+        </template>
       </byTable>
     </div>
 
-    <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">
               <el-form-item prop="countryId">
-                <el-select v-model="formData.data.countryId" placeholder="国家" @change="(val) => getCityData(val, '20', true)">
-                  <el-option v-for="item in countryData" :label="item.chineseName" :value="item.id"> </el-option>
+                <el-select
+                  v-model="formData.data.countryId"
+                  placeholder="国家"
+                  @change="(val) => getCityData(val, '20', true)"
+                >
+                  <el-option
+                    v-for="item in countryData"
+                    :label="item.chineseName"
+                    :value="item.id"
+                  >
+                  </el-option>
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item prop="provinceId">
-                <el-select v-model="formData.data.provinceId" placeholder="省/洲" @change="(val) => getCityData(val, '30', true)">
-                  <el-option v-for="item in provinceData" :label="item.name" :value="item.id"> </el-option>
+                <el-select
+                  v-model="formData.data.provinceId"
+                  placeholder="省/洲"
+                  @change="(val) => getCityData(val, '30', true)"
+                >
+                  <el-option
+                    v-for="item in provinceData"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item prop="cityId">
                 <el-select v-model="formData.data.cityId" placeholder="城市">
-                  <el-option v-for="item in cityData" :label="item.name" :value="item.id"> </el-option>
+                  <el-option
+                    v-for="item in cityData"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
                 </el-select>
               </el-form-item>
             </el-col>
@@ -52,7 +96,8 @@
           <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>
@@ -60,29 +105,65 @@
         <template #person>
           <div>
             <el-button type="primary" @click="clickAddPerson"> 添加 </el-button>
-            <byTable :source="formData.data.customerUserList" :config="configPerson" hideSearch hidePagination> </byTable>
+            <byTable
+              :source="formData.data.customerUserList"
+              :config="configPerson"
+              hideSearch
+              hidePagination
+            >
+            </byTable>
           </div>
         </template>
       </byForm>
       <template #footer>
         <el-button @click="dialogVisible = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitForm('submit')" size="large" :loading="submitLoading"> 确 定 </el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('submit')"
+          size="large"
+          :loading="submitLoading"
+        >
+          确 定
+        </el-button>
       </template>
     </el-dialog>
 
     <el-dialog title="添加联系人" v-model="openPerson" width="400">
-      <byForm :formConfig="formConfigPerson" :formOption="formOption" v-model="formPerson.data" :rules="rulesPerson" ref="person"> </byForm>
+      <byForm
+        :formConfig="formConfigPerson"
+        :formOption="formOption"
+        v-model="formPerson.data"
+        :rules="rulesPerson"
+        ref="person"
+      >
+      </byForm>
       <template #footer>
         <el-button @click="openPerson = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitPerson('person')" size="large"> 确 定 </el-button>
+        <el-button type="primary" @click="submitPerson('person')" size="large">
+          确 定
+        </el-button>
       </template>
     </el-dialog>
 
     <el-dialog title="分配" v-model="openAllocation" width="300">
-      <byForm :formConfig="formConfigAllocation" :formOption="formOption" v-model="formAllocation.data" ref="allocation"> </byForm>
+      <byForm
+        :formConfig="formConfigAllocation"
+        :formOption="formOption"
+        v-model="formAllocation.data"
+        ref="allocation"
+      >
+      </byForm>
       <template #footer>
-        <el-button @click="openAllocation = false" size="large">取 消</el-button>
-        <el-button type="primary" @click="submitAllocation('allocation')" size="large"> 确 定 </el-button>
+        <el-button @click="openAllocation = false" size="large"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          @click="submitAllocation('allocation')"
+          size="large"
+        >
+          确 定
+        </el-button>
       </template>
     </el-dialog>
   </div>
@@ -149,6 +230,7 @@ const config = computed(() => {
       attrs: {
         label: "客户名称",
         prop: "name",
+        slot: "name",
       },
     },
     {
@@ -251,11 +333,15 @@ const config = computed(() => {
             },
             el: "button",
             click() {
-              ElMessageBox.confirm("此操作将永久删除该数据, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-              }).then(() => {
+              ElMessageBox.confirm(
+                "此操作将永久删除该数据, 是否继续?",
+                "提示",
+                {
+                  confirmButtonText: "确定",
+                  cancelButtonText: "取消",
+                  type: "warning",
+                }
+              ).then(() => {
                 proxy
                   .post("/customer/delete", {
                     id: row.id,
@@ -555,7 +641,10 @@ const submitAllocation = () => {
 };
 const submitPerson = () => {
   person.value.handleSubmit(() => {
-    if (formData.data.customerUserList && formData.data.customerUserList.length > 0) {
+    if (
+      formData.data.customerUserList &&
+      formData.data.customerUserList.length > 0
+    ) {
       formData.data.customerUserList.push({
         name: formPerson.data.name,
         phone: formPerson.data.phone,
@@ -573,7 +662,10 @@ const submitPerson = () => {
 };
 const submitForm = () => {
   submit.value.handleSubmit(() => {
-    if (formData.data.customerUserList && formData.data.customerUserList.length > 0) {
+    if (
+      formData.data.customerUserList &&
+      formData.data.customerUserList.length > 0
+    ) {
       submitLoading.value = true;
       proxy.post("/customer/" + modalType.value, formData.data).then(
         () => {
@@ -626,17 +718,32 @@ const getDict = () => {
         };
       });
     });
-  proxy.get("/tenantUser/list", { pageNum: 1, pageSize: 10000, tenantId: useUserStore().user.tenantId }).then((res) => {
-    userList.value = res.rows.map((item) => {
-      return {
-        label: item.nickName,
-        value: item.userId,
-      };
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
     });
-  });
 };
 getDict();
 getList();
+
+const handleClickName = (row) => {
+  proxy.$router.push({
+    path: "/customer/customer/portrait",
+    query: {
+      id: row.id,
+    },
+  });
+};
 </script>
 
 <style lang="scss" scoped>

+ 168 - 0
src/views/customer/portrait/com/CustomerInfo.vue

@@ -0,0 +1,168 @@
+<template>
+  <div class="content" v-loading="loading">
+    <!-- <div class="company">
+      <i class="el-icon-office-building icon"> </i>
+      <span class="company-name"> {{ detailsData.corporateName }} </span>
+    </div> -->
+    <div class="line">
+      <span class="title_">客户代码:</span
+      ><span>{{ detailsData.customerCode }}</span>
+      <span class="title_" style="margin: 0 6px">|</span>
+      <span class="title_"> 客户类型:</span
+      ><span>{{ dictDataEcho(detailsData.status, customerStatus) }}</span>
+    </div>
+    <div class="line">
+      <span class="title_">客户来源:</span>
+      <span>{{ dictDataEcho(detailsData.source, customerSource) }}</span>
+    </div>
+    <div class="line">
+      <span class="title_">地址:</span>
+      <span
+        >{{ detailsData.countryName }} , {{ detailsData.provinceName }} ,
+        {{ detailsData.cityName }}
+        <span v-show="detailsData.address"> , {{ detailsData.address }}</span>
+      </span>
+    </div>
+    <div class="contacts" v-if="detailsData.customerUserList.length > 0">
+      <div>相关联系人:</div>
+      <div>
+        <div
+          v-for="(item, index) in detailsData.customerUserList"
+          :key="index"
+          class="item"
+          v-show="!(index > 1)"
+        >
+          <div class="img">
+            <i
+              class="iconfont icon-iconm_kehd"
+              style="font-size: 26px; color: #cccccc; margin-top: 2px"
+            ></i>
+          </div>
+          <div class="details">
+            <div>
+              <span> {{ item.name }} </span>
+              <!-- <span> {{ item.position }} </span> -->
+            </div>
+            <div class="information">
+              <div class="first">
+                <span class="val">Tel:</span>{{ item.phone }}
+              </div>
+              <div><span class="val">Email:</span>{{ item.mailbox }}</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+  
+<script setup>
+import useUserStore from "@/store/modules/user";
+const props = defineProps({
+  customerId: {
+    type: String,
+  },
+});
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+let detailsData = ref({
+  customerUserList: [],
+});
+const getData = () => {
+  loading.value = true;
+  proxy.post("/customer/detail", { id: props.customerId }).then((res) => {
+    detailsData.value = res;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+const customerSource = ref([]);
+const customerStatus = ref([]);
+const getDict = () => {
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "customer_source",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      customerSource.value = res.rows;
+    });
+
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "customer_status",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      customerStatus.value = res.rows;
+    });
+};
+getDict();
+onMounted(() => {
+  if (props.customerId) {
+    getData();
+  }
+});
+</script>
+  
+<style lang="scss" scoped>
+.content {
+  font-size: 12px;
+  padding: 10px;
+  .company {
+    margin-bottom: 10px;
+  }
+  .company-name {
+    font-weight: 600;
+    font-size: 13px;
+
+    color: #333333;
+  }
+  .contacts {
+    margin-top: 15px;
+    .item {
+      padding: 10px;
+      display: flex;
+      margin: 6px 0px;
+      border: 1px dashed #dddddd;
+      .img {
+        width: 40px;
+        height: 40px;
+        border-radius: 50%;
+        background: #eeeeee;
+        text-align: center;
+        line-height: 40px;
+      }
+      .details {
+        margin-left: 10px;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        .information {
+          display: flex;
+          .first {
+            margin-right: 10px;
+          }
+          .val {
+            color: #999999;
+          }
+        }
+      }
+    }
+    .more {
+      text-align: right;
+    }
+  }
+}
+.title_ {
+  color: #999999;
+}
+.line {
+  margin-bottom: 6px;
+}
+</style>

+ 128 - 0
src/views/customer/portrait/com/LineTrend.vue

@@ -0,0 +1,128 @@
+<template>
+  <div v-loading="loading">
+    <div ref="echartDom" style="height: 200px"></div>
+  </div>
+</template>
+
+<script setup>
+import * as echarts from "echarts";
+const props = defineProps({
+  customerId: {
+    type: String,
+  },
+});
+const { proxy } = getCurrentInstance();
+const echartDom = ref(null);
+const loading = ref(false);
+let myChart = null;
+const option = reactive({
+  data: {
+    tooltip: {
+      trigger: "axis",
+    },
+    grid: {
+      left: "4%",
+      right: "4%",
+      bottom: "0%",
+      top: "15px",
+      containLabel: true,
+    },
+    xAxis: {
+      type: "category",
+      boundaryGap: false,
+      data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+      splitLine: {
+        lineStyle: {
+          type: "dashed",
+          // 设置背景横线
+          color: "#ccc",
+        },
+      },
+    },
+    yAxis: {
+      type: "value",
+      splitLine: {
+        lineStyle: {
+          type: "dashed",
+          // 设置背景横线
+          color: "#ccc",
+        },
+      },
+    },
+    series: [
+      {
+        data: [820, 932, 901, 934, 1290, 1330, 1320],
+        type: "line",
+        smooth: true,
+        areaStyle: {
+          color: "#FCE5CA",
+          opacity: 0.4,
+        },
+        emphasis: {
+          focus: "series",
+        },
+        itemStyle: {
+          normal: {
+            color: "#FF9315", //改变折线点的颜色
+            lineStyle: {
+              color: "#FF9315", //改变折线颜色
+            },
+          },
+        },
+      },
+      {
+        data: [210, 885, 644, 934, 1290, 1330, 1320],
+        type: "line",
+        smooth: true,
+        areaStyle: {
+          color: "#D9EDFF",
+          opacity: 0.4,
+        },
+        emphasis: {
+          focus: "series",
+        },
+        itemStyle: {
+          normal: {
+            color: "#0084FF", //改变折线点的颜色
+            lineStyle: {
+              color: "#0084FF", //改变折线颜色
+            },
+          },
+        },
+      },
+    ],
+  },
+});
+const getData = () => {
+  loading.value = true;
+  proxy
+    .post("/saleQuotation/salesTrend", { id: props.customerId })
+    .then((res) => {
+      let months = res.contractList.map((x) => x.month);
+      let dataOne = res.contractList.map((x) => x.contractAmount);
+      let dataTwo = res.saleQuotationList.map((x) => x.saleAmount);
+      option.data.xAxis.data = months;
+      option.data.series[0].data = dataOne;
+      option.data.series[1].data = dataTwo;
+      myChart.setOption(option.data);
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+onMounted(() => {
+  myChart = echarts.init(echartDom.value);
+  if (props.customerId) {
+    getData();
+  }
+  window.addEventListener("resize", () => {
+    myChart.resize();
+  });
+});
+</script>
+
+<style lang="scss" scoped>
+// .dom {
+//   height: calc(100% - 50px);
+// }
+</style>

+ 31 - 8
src/views/customer/portrait/com/SaleStatistics.vue

@@ -3,9 +3,9 @@
     <div class="item first">
       <div class="left_">
         <div class="money">
-          {{ moneyFormat(saleData.salesAmount, 2) }}
+          {{ moneyFormat(detailsData.amount, 2) }}
         </div>
-        <div>销售额()</div>
+        <div>销售额({{ detailsData.currency }})</div>
       </div>
       <div class="right_">
         <div class="icon">
@@ -16,7 +16,7 @@
     <div class="item two">
       <div class="left_">
         <div class="money">
-          {{ moneyFormat(saleData.profitAmount, 2) }}
+          {{ moneyFormat(detailsData.profitAmount, 2) }}
         </div>
         <div>利润额(¥)</div>
       </div>
@@ -29,7 +29,7 @@
     <div class="item three">
       <div class="left_">
         <div class="money">
-          {{ saleData.mailCount }}
+          {{ detailsData.mailCount || 0 }}
         </div>
         <div>往来邮件(封)</div>
       </div>
@@ -42,7 +42,7 @@
     <div class="item four">
       <div class="left_">
         <div class="money">
-          {{ saleData.reportPriceCount }}
+          {{ detailsData.count }}
         </div>
         <div>报价次数(次)</div>
       </div>
@@ -55,7 +55,7 @@
     <div class="item five">
       <div class="left_">
         <div class="money">
-          {{ saleData.contractCount }}
+          {{ detailsData.contractCount }}
         </div>
         <div>成交合同(单)</div>
       </div>
@@ -69,12 +69,35 @@
 </template>
 
 <script setup>
-const saleData = ref({});
+const props = defineProps({
+  customerId: {
+    type: String,
+  },
+});
+const loading = ref(false);
+let detailsData = ref({});
+const { proxy } = getCurrentInstance();
+const getData = () => {
+  loading.value = true;
+  proxy
+    .post("/saleQuotation/salesStatistics", { id: props.customerId })
+    .then((res) => {
+      detailsData.value = res.contractVo;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+onMounted(() => {
+  if (props.customerId) {
+    getData();
+  }
+});
 </script>
 
 <style lang="scss" scoped>
 .details {
-  margin-top: 10px;
+  // margin-top: 10px;
   display: flex;
   justify-content: space-around;
   .item {

+ 42 - 28
src/views/customer/portrait/com/SalesDetails.vue

@@ -13,10 +13,19 @@
         @get-list="getList"
         :hideSearch="true"
       >
-        <template #address="{ item }">
+        <template #advanceCharge="{ item }">
           <div>
-            {{ item.countryName }}, {{ item.provinceName }} ,
-            {{ item.cityName }}, {{ item.areaDetail }}
+            {{ item.currency
+            }}{{ moneyFormat(item.advanceCharge, 2) }}(预付款比列:{{
+              item.advanceRatio
+            }}%)
+          </div>
+        </template>
+        <template #buyContactName="{ item }">
+          <div>
+            客户联系人:<span style="cursor: pointer; color: #409eff">{{
+              item.buyContactName
+            }}</span>
           </div>
         </template>
       </byTable>
@@ -26,6 +35,11 @@
   
 <script setup>
 import byTable from "@/components/byTable/index";
+const props = defineProps({
+  customerId: {
+    type: String,
+  },
+});
 const loading = ref(false);
 const sourceList = ref({
   data: [],
@@ -35,7 +49,6 @@ const sourceList = ref({
     pageSize: 10,
   },
 });
-
 const { proxy } = getCurrentInstance();
 const selectConfig = reactive([]);
 const config = computed(() => {
@@ -43,56 +56,57 @@ const config = computed(() => {
     {
       attrs: {
         label: "时间",
-        prop: "type",
-      },
-    },
-    {
-      attrs: {
-        label: "样品单",
-        prop: "code",
+        prop: "createTime",
       },
     },
+    // {
+    //   attrs: {
+    //     label: "样品单",
+    //     prop: "type",
+    //   },
+    //   render(type) {
+    //     return type == 10 ? "报价单" : type == 20 ? "合同" : "";
+    //   },
+    // },
     {
       attrs: {
         label: "业务员",
-        prop: "name",
+        prop: "userName",
       },
     },
     {
       attrs: {
         label: "预付款",
-        prop: "remarks",
-        slot: "address",
+        prop: "advanceCharge",
+        slot: "advanceCharge",
       },
     },
     {
       attrs: {
         label: "客户",
-        prop: "contactPerson",
+        prop: "buyContactName",
+        slot: "buyContactName",
       },
     },
   ];
 });
-
-const getList = async (req) => {
-  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+const getData = () => {
   loading.value = true;
   proxy
-    .post("/supplierInfo/pageByWdly", sourceList.value.pagination)
-    .then((message) => {
-      console.log(message);
-      sourceList.value.data = message.rows.map((x) => ({
-        ...x,
-        ...JSON.parse(x.victoriatouristJson),
-      }));
-      sourceList.value.pagination.total = message.total;
+    .post("/saleQuotation/saleDetail", { id: props.customerId })
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
       setTimeout(() => {
         loading.value = false;
       }, 200);
     });
 };
-
-getList();
+onMounted(() => {
+  if (props.customerId) {
+    getData();
+  }
+});
 </script>
   
 <style lang="scss" scoped>

+ 31 - 7
src/views/customer/portrait/index.vue

@@ -6,7 +6,12 @@
           <div class="title-box">
             <TitleInfo :content="titleList[0]"></TitleInfo>
           </div>
-          <div class="content-box">0</div>
+          <div class="content-box">
+            <CustomerInfo
+              :customerId="customerId"
+              :key="customerId"
+            ></CustomerInfo>
+          </div>
         </div>
       </div>
 
@@ -26,7 +31,10 @@
             <TitleInfo :content="titleList[2]"></TitleInfo>
           </div>
           <div class="content-box">
-            <SaleStatistics></SaleStatistics>
+            <SaleStatistics
+              :customerId="customerId"
+              :key="customerId"
+            ></SaleStatistics>
           </div>
         </div>
       </div>
@@ -36,7 +44,9 @@
           <div class="title-box">
             <TitleInfo :content="titleList[3]"></TitleInfo>
           </div>
-          <div class="content-box">3</div>
+          <div class="content-box">
+            <LineTrend :customerId="customerId" :key="customerId"></LineTrend>
+          </div>
         </div>
       </div>
 
@@ -46,7 +56,10 @@
             <TitleInfo :content="titleList[4]"></TitleInfo>
           </div>
           <div class="content-box">
-            <SalesDetails></SalesDetails>
+            <SalesDetails
+              :customerId="customerId"
+              :key="customerId"
+            ></SalesDetails>
           </div>
         </div>
       </div>
@@ -56,10 +69,18 @@
 
 <script setup>
 import TitleInfo from "@/components/TitleInfo/index.vue";
+import CustomerInfo from "./com/CustomerInfo.vue";
 import SalesDetails from "./com/SalesDetails.vue";
+import LineTrend from "./com/LineTrend.vue";
 import SaleStatistics from "./com/SaleStatistics.vue";
 
+const route = useRoute();
 const titleList = ["客户信息", "最新跟进", "销售统计", "销售走势", "销售明细"];
+const customerId = ref("");
+
+onMounted(() => {
+  customerId.value = route.query.id;
+});
 </script>
 
 <style lang="scss" scoped>
@@ -88,14 +109,17 @@ const titleList = ["客户信息", "最新跟进", "销售统计", "销售走势
     display: flex;
     flex-direction: column;
     height: calc(100vh - 120px);
-    .box-one,
+    .box-one {
+      // padding-bottom: 10px;
+    }
     .box-three {
       // flex: 1;
-      height: 200px;
+      min-height: 200px;
     }
     .box-two {
-      flex: 1;
       margin: 10px 0;
+      flex: 1;
+      box-sizing: border-box;
     }
   }
 }