Jelajahi Sumber

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

Min 11 bulan lalu
induk
melakukan
0197ee0c9e

+ 75 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/api.ts

@@ -0,0 +1,75 @@
+import { post, get } from '@/utils/request';
+import { dayjs } from 'element-plus';
+
+// String startDate, String endDate, String userId,Integer departmentId
+
+export type RequestProps = {
+  startDate?: string;
+  endDate?: string;
+  type?: 0 | 1;
+  userId?: number;
+  departmentId?: number;
+};
+
+export async function getOverallData(payload?: RequestProps): Promise<any> {
+  return await post('report/getCustomerTotalCount', payload);
+}
+
+export async function getConversionData(payload?: RequestProps): Promise<any> {
+  return await post('report/getCustomerTransferRate', payload);
+}
+
+export async function getDepartmentData(): Promise<any> {
+  return await get('/department/normalList');
+}
+
+export async function getStaffData(): Promise<any> {
+  return await get('/user/getSimpleActiveUserList');
+}
+
+export const dateCollections = [
+  {
+    name: '当日',
+    start_time: dayjs().startOf('date').toISOString(),
+    end_time: dayjs().endOf('date').toISOString()
+  },
+  {
+    name: '昨日',
+    start_time: dayjs().startOf('date').subtract(1, 'day').toISOString(),
+    end_time: dayjs().endOf('date').subtract(1, 'day').toISOString()
+  },
+  {
+    name: '本周',
+    start_time: dayjs().startOf('week').add(1, 'day').toISOString(),
+    end_time: dayjs().endOf('week').add(1, 'day').toISOString()
+  },
+  {
+    name: '上周',
+    start_time: dayjs()
+      .add(-1, 'week')
+      .startOf('week')
+      .add(1, 'day')
+      .toISOString(),
+    end_time: dayjs().add(-1, 'week').endOf('week').add(1, 'day').toISOString()
+  },
+  {
+    name: '本月',
+    start_time: dayjs().startOf('month').toISOString(),
+    end_time: dayjs().endOf('month').toISOString()
+  },
+  {
+    name: '上月',
+    start_time: dayjs().add(-1, 'month').startOf('month').toISOString(),
+    end_time: dayjs().add(-1, 'month').endOf('month').toISOString()
+  },
+  {
+    name: '本季度',
+    start_time: dayjs().month(0).toISOString(),
+    end_time: dayjs().month(2).endOf('month').toISOString()
+  },
+  {
+    name: '上季度',
+    start_time: dayjs().add(-1, 'year').month(9).toISOString(),
+    end_time: dayjs().add(-1, 'year').month(11).endOf('month').toISOString()
+  }
+];

+ 140 - 56
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/corpreport/index.vue

@@ -3,30 +3,33 @@ import { ref, reactive, onMounted, watchEffect } from 'vue';
 
 import Echarts from '@/components/ReEcharts/index.vue';
 import { EChartsOption } from 'echarts';
+import {
+  type RequestProps,
+  getOverallData,
+  getDepartmentData,
+  getStaffData,
+  dateCollections,
+  getConversionData
+} from './api';
 
-const chartOptions: EChartsOption = {
+const dataSource = ref([]);
+const form = reactive({ type: undefined, date: undefined, member: undefined });
+const memberOptions = ref([]);
+// 0 客户总量  1 客户转化率
+const dataType = ref<0 | 1>(0);
+
+const chartOptions: EChartsOption = reactive({
   grid: { bottom: 30 },
   legend: {},
   tooltip: {},
   dataset: {
-    dimensions: ['product', '2015', '2016', '2017'],
-    source: [
-      { product: 'Matcha Latte', 2015: 43.3, 2016: 85.8, 2017: 93.7 },
-      { product: 'Milk Tea', 2015: 83.1, 2016: 73.4, 2017: 55.1 },
-      { product: 'Cheese Cocoa', 2015: 86.4, 2016: 65.2, 2017: 82.5 },
-      { product: 'Walnut Brownie', 2015: 72.4, 2016: 53.9, 2017: 39.1 }
-    ]
+    dimensions: [],
+    source: []
   },
   xAxis: { type: 'category' },
   yAxis: {},
-  // Declare several bar series, each will be mapped
-  // to a column of dataset.source by default.
-  series: [
-    { type: 'bar', barWidth: 20 },
-    { type: 'bar', barWidth: 20 },
-    { type: 'bar', barWidth: 20 }
-  ]
-};
+  series: []
+});
 
 const dateOptions = [
   { label: '今天', value: '1' },
@@ -38,36 +41,86 @@ const dateOptions = [
   { label: '本季度', value: '7' },
   { label: '上季度', value: '8' }
 ];
-const dataSource = [
-  {
-    date: '2016-05-03',
-    name: 'Tom',
-    address: 'No. 189, Grove St, Los Angeles'
-  },
-  {
-    date: '2016-05-02',
-    name: 'Tom',
-    address: 'No. 189, Grove St, Los Angeles'
-  },
-  {
-    date: '2016-05-04',
-    name: 'Tom',
-    address: 'No. 189, Grove St, Los Angeles'
-  },
-  {
-    date: '2016-05-01',
-    name: 'Tom',
-    address: 'No. 189, Grove St, Los Angeles'
-  }
-];
+
+const onSubmit = () => {
+  const payload = {
+    startDate: form.date && dateCollections[form.date - 1].start_time,
+    endDate: form.date && dateCollections[form.date - 1].end_time,
+    type: form.type,
+    userId: form.type === 1 ? form.member : undefined,
+    departmentId: form.type === 1 ? undefined : form.member
+  } as RequestProps;
+
+  dataType.value === 0 ? queryOverall(payload) : queryConversion(payload);
+};
+
+const queryOverall = async (payload?: RequestProps) => {
+  const { data = [] } = await getOverallData(payload);
+
+  dataSource.value = data.map((d) => ({
+    name: d.name,
+    dealRate: d.dealRate * 100,
+    customerDeal: d.customerDeal,
+    customertotal: d.customertotal
+  }));
+
+  // @ts-ignore
+  chartOptions.series = [
+    { type: 'bar', barWidth: 20 },
+    { type: 'bar', barWidth: 20, color: '#b91c1c' }
+  ];
+  // @ts-ignore
+  chartOptions.dataset.dimensions = ['name', '成交客户数', '新增客户数'];
+  // @ts-ignore
+  chartOptions.dataset.source = data.map((d) => ({
+    name: d.name,
+    ['成交客户数']: d.customerDeal,
+    ['新增客户数']: d.customertotal
+  }));
+  chartOptions.legend = {};
+};
+
+const queryConversion = async (payload?: RequestProps) => {
+  const { data = [] } = await getConversionData(payload);
+
+  dataSource.value = data.map((d) => ({
+    name: d.name,
+    dealRate: d.dealRate * 100
+  }));
+
+  // @ts-ignore
+  chartOptions.series = [{ type: 'bar', barWidth: 20 }];
+  // @ts-ignore
+  chartOptions.dataset.dimensions = ['name', '客户转化率(%)'];
+  // @ts-ignore
+  chartOptions.dataset.source = data.map((d) => ({
+    name: d.name,
+    ['客户转化率(%)']: d.dealRate * 100
+  }));
+  chartOptions.legend = undefined;
+};
+
+watchEffect(() => {
+  dataType.value === 0 ? queryOverall() : queryConversion();
+});
+
+watchEffect(async () => {
+  const { data = [] } =
+    form.type === 1 ? await getStaffData() : await getDepartmentData();
+
+  memberOptions.value = data.map((d) => ({
+    name: form.type === 1 ? d.name : d.departmentName,
+    id: form.type === 1 ? d.id : d.departmentId
+  }));
+});
 </script>
 
 <template>
   <div class="m-5 bg-white h-full p-4 rounded">
     <div class="flex justify-between">
-      <el-form class="flex gap-4">
+      <el-form :model="form" class="flex gap-4">
         <el-form-item class="w-28">
-          <el-select>
+          <el-select clearable v-model="form.date">
             <el-option
               v-for="date in dateOptions"
               :key="date.value"
@@ -77,33 +130,64 @@ const dataSource = [
           </el-select>
         </el-form-item>
         <el-form-item class="w-28">
-          <el-select>
-            <el-option label="按部门" value="1" />
-            <el-option label="按员工" value="2" />
+          <el-select
+            clearable
+            v-model="form.type"
+            @change="form.member = undefined"
+          >
+            <el-option label="按部门" :value="0" />
+            <el-option label="按员工" :value="1" />
           </el-select>
         </el-form-item>
         <el-form-item class="w-52">
-          <el-select></el-select>
+          <el-select
+            clearable
+            v-model="form.member"
+            placeholder="选择部门(默认为本部门及下属部门)"
+          >
+            <el-option
+              v-for="date in memberOptions"
+              :key="date.id"
+              :label="date.name"
+              :value="date.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit">搜索</el-button>
         </el-form-item>
-        <el-button type="primary">搜索</el-button>
       </el-form>
-      <el-tabs type="card">
-        <el-tab-pane label="客户总量分析" name="first" />
-        <el-tab-pane label="客户转化率分析" name="first" />
-        <el-tab-pane label="合同数量分析" name="first" />
+      <el-tabs
+        type="card"
+        v-model="dataType"
+        @tab-change="
+          () => {
+            form.date = undefined;
+            form.member = undefined;
+            form.type = undefined;
+            dataSource = [];
+          }
+        "
+      >
+        <el-tab-pane label="客户总量分析" :name="0" />
+        <el-tab-pane label="客户转化率分析" :name="1" />
       </el-tabs>
-      <!-- <span class="mr-12 font-bold text-gray-900">客户总量分析</span> -->
     </div>
     <div class="h-96">
       <Echarts :option="chartOptions"></Echarts>
     </div>
     <el-table :data="dataSource">
-      <el-table-column prop="date" label="员工姓名" />
-      <el-table-column prop="date" label="新增客户数" />
-      <el-table-column prop="date" label="成交客户数" />
-      <el-table-column prop="date" label="客户成交率(%)" />
-      <el-table-column prop="date" label="合同总金额" />
-      <el-table-column prop="date" label="回款金额" />
+      <el-table-column prop="name" label="员工姓名" />
+      <el-table-column
+        prop="dealRate"
+        label="客户转化率(%)"
+        v-if="dataType === 1"
+      />
+      <template v-else>
+        <el-table-column prop="customertotal" label="新增客户数" />
+        <el-table-column prop="customerDeal" label="成交客户数" />
+        <el-table-column prop="dealRate" label="客户成交率(%)" />
+      </template>
     </el-table>
   </div>
 </template>

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/vite.config.ts

@@ -3,7 +3,7 @@ import vue from '@vitejs/plugin-vue';
 
 import { resolve } from 'path';
 
-const target = 'http://192.168.2.8:10010';
+const target = 'http://192.168.2.142:10010';
 // const target = "http://127.0.0.1:10010";
 // const target = "http://192.168.2.178:10010";
 // const target = 'http://47.101.180.183:10010';