浏览代码

RING:绩效大体完成

ringcode 3 年之前
父节点
当前提交
6aa04ad250
共有 9 个文件被更改,包括 911 次插入62 次删除
  1. 2 1
      package.json
  2. 51 0
      src/api/index.ts
  3. 7 0
      src/main.ts
  4. 5 1
      src/plugins/install.ts
  5. 14 3
      src/router/async.ts
  6. 132 0
      src/views/_pageOptions/table_data.ts
  7. 432 0
      src/views/data/performance-detail.vue
  8. 214 48
      src/views/data/performance.vue
  9. 54 9
      yarn.lock

+ 2 - 1
package.json

@@ -7,11 +7,12 @@
     "build": "vue-cli-service build"
   },
   "dependencies": {
-    "@antv/g2plot": "^2.3.21",
+    "@antv/g2plot": "^2.3.26",
     "ant-design-vue": "^2.0.0-beta.15",
     "axios": "^0.21.0",
     "clipboard": "^2.0.6",
     "core-js": "^3.6.5",
+    "element-plus": "^1.0.2-beta.54",
     "qrcode": "^1.4.4",
     "smooth-dnd": "^0.12.1",
     "vue": "^3.0.0",

+ 51 - 0
src/api/index.ts

@@ -903,3 +903,54 @@ export const pushMaterial = (
   return axios("/material/sync", { params: query });
 };
 
+// 员工绩效
+/**
+ * 获取员工绩效列表
+ * @param
+ */
+export const getStuffPerformance = (
+  query: {
+    start_date: string,
+    end_date: string,
+    uname: string,
+    uid?: string | number,
+    type: string,
+    model: string,
+    value: string | number,
+    page: number,
+  }
+): any => {
+  return axios("/promoter/stat", { params: query });
+};
+
+/**
+ * 获取员工绩效曲线图数据
+ * @param
+ */
+export const getStuffPerformanceChart = (
+  query: {
+    start_date: string,
+    end_date: string,
+    uname: string,
+    uid?: string | number,
+    type: string,
+    model: string,
+    value: string | number,
+  }
+): any => {
+  return axios("/promoter/statAll", { params: query });
+};
+
+/**
+ * 获取员工绩效总览
+ * @param
+ */
+export const getStuffPerformanceSum = (
+  query: {
+    start_date: string,
+    end_date: string,
+    uid: any,
+  }
+): any => {
+  return axios("/promoter/statSum", { params: query });
+};

+ 7 - 0
src/main.ts

@@ -10,12 +10,19 @@ import store from "./store";
 import install from "@/plugins/install";
 import createGlobalData from "./plugins/createGlobal";
 
+import ElementPlus from 'element-plus';
+import 'element-plus/lib/theme-chalk/index.css';
+import 'dayjs/locale/zh-cn'
+import locale from 'element-plus/lib/locale/lang/zh-cn'
+
 const app = createApp(App);
 
 // 初始化三方库和插件
 install(app);
 createGlobalData(app);
 
+
+app.use(ElementPlus, { locale })
 app.use(store).use(router);
 
 router.isReady().then((_) => app.mount("#app"));

+ 5 - 1
src/plugins/install.ts

@@ -35,6 +35,8 @@ import {
   Spin,
   Progress,
   Cascader,
+  Breadcrumb,
+  Divider
 } from "ant-design-vue";
 
 import VueClipboard3 from "./vue-clipboard";
@@ -82,7 +84,9 @@ const install = (app: App<Element>) => {
     .use(Spin)
     .use(Upload)
     .use(Progress)
-    .use(Cascader);
+    .use(Cascader)
+    .use(Breadcrumb)
+    .use(Divider);
 };
 
 export default install;

+ 14 - 3
src/router/async.ts

@@ -164,6 +164,17 @@ export const QuickApp: RouteConfig = {
   component: () => import("@/views/read/quick-app.vue")
 };
 
+export const PerformanceDetial: RouteConfig = {
+  name: "PerformanceDetial",
+  path: "/data/performanceDetail",
+  meta: {
+    title: "查看详情",
+    activeMenu: "/data/performance",
+  },
+  hidden: true,
+  component: () => import("@/views/data/performance-detail.vue")
+};
+
 export const Performance: RouteConfig = {
   name: "Performance",
   path: "/data/performance",
@@ -171,7 +182,6 @@ export const Performance: RouteConfig = {
     title: "员工绩效",
     noMenu: true
   },
-  // children: [PutAdAcountL, PutAdGroup, PutAdPlan],
   component: () => import("@/views/data/performance.vue")
 };
 export const DataAnalysis: RouteConfig = {
@@ -186,6 +196,7 @@ export const DataAnalysis: RouteConfig = {
   ],
   component: () => import("@/views/data/index.vue")
 };
+
 export const VideoMaterial: RouteConfig = {
   name: "VideoMaterial",
   path: "/material/video",
@@ -235,7 +246,7 @@ export const ForgetPwd: RouteConfig = {
 
 
 
-// const asyncRoutes: RouteConfig[] = [AccountManager, DataAnalysis, PutManager, Financial, QuickApp, ForgetPwd, MaterialCenter];
-const asyncRoutes: RouteConfig[] = [AccountManager, PutManager, Financial, QuickApp, ForgetPwd, MaterialCenter];
+const asyncRoutes: RouteConfig[] = [AccountManager, DataAnalysis, PutManager, Financial, QuickApp, PerformanceDetial, ForgetPwd, MaterialCenter];
+// const asyncRoutes: RouteConfig[] = [AccountManager, PutManager, Financial, QuickApp, ForgetPwd, MaterialCenter];
 
 export default asyncRoutes;

+ 132 - 0
src/views/_pageOptions/table_data.ts

@@ -0,0 +1,132 @@
+// 员工绩效列表
+export const TableColumnOfStuffPerformance = [
+  {
+    title: '推广员',
+    dataIndex: 'uname',
+    fixed: 'left',
+    width: 150
+  },
+  {
+    title: '成本合计(元)',
+    dataIndex: 'cost_amount',
+  },
+  {
+    title: '回本(元)',
+    dataIndex: 'back_amount',
+    sorter: (a: any, b: any) => a.back_amount - b.back_amount,
+  },
+  {
+    title: '提现合计(元)',
+    dataIndex: 'cash_withdrawal_amount',
+  },
+  {
+    title: '提现(元)M+0',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'wm0' },
+    width: 140
+  },
+  {
+    title: '提现(元)M+1',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'wm1' },
+    width: 140
+  },
+  {
+    title: '提现(元)M+2',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'wm2' },
+    width: 140
+  },
+  {
+    title: '用户充值(元)',
+    dataIndex: 'user_charge_amount_sum',
+  },
+  {
+    title: '用户充值(元)M+0',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'cm0' },
+    width: 140
+  },
+  {
+    title: '用户充值(元)M+1',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'cm1' },
+    width: 140
+  },
+  {
+    title: '用户充值(元)M+2',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'cm2' },
+    width: 140
+  },
+  {
+    title: '操作',
+    dataIndex: 'operation',
+    slots: { customRender: 'operation' },
+    fixed: 'right',
+  },
+]
+
+// 员工绩效明细
+export const TableColumnOfStuffDetail = [
+  {
+    title: '日期',
+    dataIndex: 'date',
+    fixed: 'left',
+    width: 150
+  },
+  {
+    title: '成本合计(元)',
+    dataIndex: 'cost_amount',
+  },
+  {
+    title: '回本(元)',
+    dataIndex: 'back_amount',
+    sorter: (a: any, b: any) => a.back_amount - b.back_amount,
+  },
+  {
+    title: '提现合计(元)',
+    dataIndex: 'cash_withdrawal_amount',
+  },
+  {
+    title: '提现(元)M+0',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'wm0' },
+    width: 140
+  },
+  {
+    title: '提现(元)M+1',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'wm1' },
+    width: 140
+  },
+  {
+    title: '提现(元)M+2',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'wm2' },
+    width: 140
+  },
+  {
+    title: '用户充值(元)',
+    dataIndex: 'user_charge_amount_sum',
+  },
+  {
+    title: '用户充值(元)M+0',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'cm0' },
+    width: 140
+  },
+  {
+    title: '用户充值(元)M+1',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'cm1' },
+    width: 140
+  },
+  {
+    title: '用户充值(元)M+2',
+    dataIndex: 'cash_withdrawal_amount',
+    slots: { customRender: 'cm2' },
+    width: 140
+  },
+]
+

+ 432 - 0
src/views/data/performance-detail.vue

@@ -0,0 +1,432 @@
+<template>
+  <div class="performance-detail">
+    <div class="title-box-common title-box">
+      <a-breadcrumb>
+        <a-breadcrumb-item
+          ><a href="javascript:;" @click="$router.go(-1)"
+            >员工绩效</a
+          ></a-breadcrumb-item
+        >
+        <a-breadcrumb-item>查看详情</a-breadcrumb-item>
+      </a-breadcrumb>
+      <h3 style="font-size: 20px">{{ uname }}</h3>
+    </div>
+    <div class="padding-box-common">
+      <div class="search-box data-box">
+        <h3>绩效总览</h3>
+        <div class="detail-data-item">
+          <p>成本合计(元)</p>
+          <p>{{ sum.cost_amount }}</p>
+        </div>
+        <a-divider type="vertical" />
+        <div class="detail-data-item">
+          <p>提现合计(元)</p>
+          <p>{{ sum.cash_withdrawal_amount }}</p>
+        </div>
+        <a-divider type="vertical" />
+        <div class="detail-data-item">
+          <p>回本(元)</p>
+          <p>{{ sum.back_amount }}</p>
+        </div>
+        <a-divider type="vertical" />
+        <div class="detail-data-item">
+          <p>用户充值(元)</p>
+          <p>{{ sum.user_charge_amount_sum }}</p>
+        </div>
+      </div>
+      <div class="search-box" style="border: none">
+        <h3>绩效明细</h3>
+        <div class="right-search">
+          <span v-show="search.type === 'month'">自定义月数:</span>
+          <span v-show="search.type === 'day'">自定义天数:</span>
+          <a-input
+            v-model:value="search.value"
+            placeholder="请输入"
+            style="width: 100px"
+            type="number"
+            :min="0"
+            @keyup.enter="getList"
+          />&nbsp;
+          <a-select
+            style="width: 100px"
+            v-model:value="search.type"
+            @change="onTypeChange"
+          >
+            <a-select-option value="month">按月查询</a-select-option>
+            <a-select-option value="day">按日查询</a-select-option> </a-select
+          >&nbsp;
+          <el-date-picker
+            v-if="search.type === 'month'"
+            v-model="search.date_arr"
+            type="monthrange"
+            range-separator="-"
+            start-placeholder="开始月份"
+            end-placeholder="结束月份"
+            @change="getList"
+            size="small"
+            style="width: 240px"
+            value-format="YYYY-MM"
+          >
+          </el-date-picker>
+          <el-date-picker
+            v-else
+            v-model="search.date_arr"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            @change="getList"
+            size="small"
+            style="width: 240px"
+            value-format="YYYY-MM-DD"
+          >
+          </el-date-picker>
+        </div>
+      </div>
+      <div id="chart-container" v-if="!loading"></div>
+      <div class="chart-loading" v-show="loading">加载中......</div>
+      <div class="table-box">
+        <a-radio-group
+          v-model:value="search.model"
+          @change="getList"
+          style="margin: 10px 0"
+        >
+          <a-radio-button value="natural">自然日数据</a-radio-button>
+          <a-radio-button value="precise">顺延24小时数据</a-radio-button>
+        </a-radio-group>
+        <a-table
+          bordered
+          :scroll="{ x: 1500 }"
+          :data-source="list"
+          :columns="columns"
+          @change="getList"
+          rowKey="uid"
+          :loading="loading"
+          :pagination="tablePageOptions"
+        >
+          <template #wm0="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[0].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[0].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[0].back_rate }}
+            </p>
+          </template>
+          <template #wm1="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[1].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[1].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[1].back_rate }}
+            </p>
+          </template>
+          <template #wm2="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[2].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[2].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[2].back_rate }}
+            </p>
+          </template>
+          <template #cm0="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[0].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[0].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[0].back_rate }}
+            </p>
+          </template>
+          <template #cm1="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[1].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[1].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[1].back_rate }}
+            </p>
+          </template>
+          <template #cm2="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[2].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[2].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[2].back_rate }}
+            </p>
+          </template>
+          <template #operation="{ record }">
+            <a-button type="link" @click="toDetial(record)">查看详情</a-button>
+          </template>
+        </a-table>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+import { Line } from "@antv/g2plot";
+import usePagination from "@/hooks/usePagination";
+import { defineComponent, reactive, toRefs, ref } from "vue";
+import { Moment } from "moment";
+import { TableColumnOfStuffDetail } from "../_pageOptions/table_data";
+//getPromotionList
+import {
+  getStuffPerformance,
+  getStuffPerformanceSum,
+  getStuffPerformanceChart,
+} from "@/api";
+import { message } from "ant-design-vue";
+const PerformanceDetial = defineComponent({
+  components: {},
+  setup() {
+    let { tablePageOptions } = usePagination();
+    const state = reactive({
+      search: {
+        uid: 0,
+        uname: "", // 推广员名称
+        type: "month", // 时间类型 day/month
+        model: "natural", // 计算方式 自然日:natural/ 顺延24小时:precise
+        value: ref<any[number | string]>(3), // 自定义月数、天数
+        date_arr: ref<any[]>([]),
+      },
+      loading: false,
+      list: ref<any[]>([]),
+      columns: TableColumnOfStuffDetail,
+      sum: {
+        back_amount: 0, // 回本
+        cash_withdrawal_amount: 0, // 体现合计
+        cost_amount: 0, // 成本合计
+        user_charge_amount_sum: 0, // 用户充值
+      },
+      uname: "",
+    });
+    return {
+      ...toRefs(state),
+      tablePageOptions,
+    };
+  },
+  mounted() {
+    this.search.uid = Number(this.$route.query.uid);
+    this.uname = String(this.$route.query.uname);
+    // this.getList({ current: 1 });
+    this.getSum();
+    this.onTypeChange("month");
+
+    console.log("ccc", this.$route.query.uid);
+  },
+  methods: {
+    // 获取推广链接数据
+    async getList(page?: any, filter?: any, sorter?: any) {
+      console.log("SORT", sorter);
+      this.loading = true;
+      let param: any = {
+        start_date: this.search.date_arr ? this.search.date_arr[0] : "",
+        end_date: this.search.date_arr ? this.search.date_arr[1] : "",
+        ...this.search,
+      };
+      delete param.date_arr;
+      console.log("请求参数", param);
+      let { data } = await getStuffPerformance({
+        page: page ? page.current : 1,
+        ...param,
+      });
+      let chartData = await getStuffPerformanceChart(param);
+      console.log("请求结果", data);
+      console.log("CHART结果", chartData.data);
+      this.loading = false;
+      this.$nextTick(() => {
+        this.renderChart(chartData.data);
+      });
+      this.list = data.list;
+    },
+    // 获取绩总览
+    async getSum() {
+      let { data } = await getStuffPerformanceSum({
+        start_date: this.search.date_arr ? this.search.date_arr[0] : "",
+        end_date: this.search.date_arr ? this.search.date_arr[1] : "",
+        uid: this.$route.query.uid,
+      });
+      console.log("总览", data);
+      this.sum.back_amount = data.back_amount; // 回本
+      this.sum.cash_withdrawal_amount = data.cash_withdrawal_amount; // 体现合计
+      this.sum.cost_amount = data.cost_amount; // 成本合计
+      this.sum.user_charge_amount_sum = data.user_charge_amount_sum; // 用户充值
+    },
+    // 月、日查询类型改变
+    onTypeChange(val: string) {
+      var date = new Date();
+      console.log(val);
+      if (val === "month") {
+        this.search.value = 3;
+        var list = this.getDateRange(date, 30, true);
+        console.log(list[0].substring(0, 7));
+        this.search.date_arr = [
+          list[0].substring(0, 7),
+          list[1].substring(0, 7),
+        ];
+      } else {
+        this.search.value = "";
+        var list = this.getDateRange(date, 7, true);
+        this.search.date_arr = list;
+      }
+      this.getList();
+    },
+    // 渲染图表
+    renderChart(data: any) {
+      console.log("CHART DATA:", data);
+      const linePlot = new Line("chart-container", {
+        data,
+        xField: "date",
+        yField: "value",
+        seriesField: "name",
+        yAxis: {
+          label: {
+            formatter: (v: any) => v,
+          },
+        },
+        legend: {
+          position: "top",
+        },
+        smooth: true,
+        // @TODO 后续会换一种动画方式
+        animation: {
+          appear: {
+            animation: "path-in",
+            duration: 2000,
+          },
+        },
+      });
+      console.log("渲染");
+      linePlot.render();
+      // fetch(
+      //   "https://gw.alipayobjects.com/os/bmw-prod/e00d52f4-2fa6-47ee-a0d7-105dd95bde20.json"
+      // )
+      //   .then((res: any) => res.json())
+      //   .then((data: any) => {
+      //     console.log("CHART DATA:", data);
+      //     const linePlot = new Line("chart-container", {
+      //       data,
+      //       xField: "year",
+      //       yField: "gdp",
+      //       seriesField: "name",
+      //       yAxis: {
+      //         label: {
+      //           formatter: (v: any) => `${(v / 10e8).toFixed(1)} B`,
+      //         },
+      //       },
+      //       legend: {
+      //         position: "top",
+      //       },
+      //       smooth: true,
+      //       // @TODO 后续会换一种动画方式
+      //       animation: {
+      //         appear: {
+      //           animation: "path-in",
+      //           duration: 3000,
+      //         },
+      //       },
+      //     });
+
+      //     linePlot.render();
+      //   });
+    },
+    // 工具函数:获取最近日期
+    getDateRange(dateNow: any, intervalDays: any, bolPastTime: any) {
+      let oneDayTime = 24 * 60 * 60 * 1000;
+      let list = [];
+      let lastDay;
+
+      if (bolPastTime == true) {
+        lastDay = new Date(dateNow.getTime() - intervalDays * oneDayTime);
+        list.push(this.formateDate(lastDay));
+        list.push(this.formateDate(dateNow));
+      } else {
+        lastDay = new Date(dateNow.getTime() + intervalDays * oneDayTime);
+        list.push(this.formateDate(dateNow));
+        list.push(this.formateDate(lastDay));
+      }
+      return list;
+    },
+    formateDate(time: any) {
+      let year = time.getFullYear();
+      let month = time.getMonth() + 1;
+      let day = time.getDate();
+      if (month < 10) {
+        month = "0" + month;
+      }
+      if (day < 10) {
+        day = "0" + day;
+      }
+      return year + "-" + month + "-" + day + "";
+    },
+    // 查看详情
+    toDetial(item: any) {
+      console.log("查看详情", item);
+    },
+  },
+});
+
+export default PerformanceDetial;
+</script>
+<style lang="scss" scoped>
+@import "@/assets/common-style/frame.scss";
+.performance-detail {
+  .title-box {
+    display: block;
+    padding-top: 4px;
+    h3 {
+      margin-top: 10px;
+    }
+  }
+  .search-box {
+    display: flex;
+    justify-content: space-between;
+    padding: 0 20px;
+  }
+  .table-box {
+    padding: 0 20px;
+  }
+  h3 {
+    font-weight: bold;
+  }
+  .data-box {
+    display: block;
+    height: auto;
+    overflow: hidden;
+    padding: 20px 20px;
+    margin-bottom: 10px;
+    .ant-divider,
+    .ant-divider-vertical {
+      float: left;
+      height: 20px;
+      background-color: #cfcfce;
+      margin-right: 30px;
+      margin-top: 14px;
+    }
+    .detail-data-item {
+      width: 110px;
+      float: left;
+      color: gray;
+      font-size: 13px;
+    }
+  }
+  #chart-container {
+    margin: 0 auto;
+    height: 300px;
+    background: white;
+    padding: 10px 20px 20px;
+    overflow: hidden;
+  }
+  .chart-loading {
+    font-size: 16px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    background: white;
+    color: rgb(185, 184, 184);
+  }
+}
+</style>

+ 214 - 48
src/views/data/performance.vue

@@ -9,31 +9,133 @@
           v-model:value="search.uname"
           placeholder="请输入推广员名称"
           style="width: 180px"
+          @keyup.enter="getList"
         />
         <div class="right-search">
-          <span>自定义月数:</span
-          ><a-input
+          <span v-show="search.type === 'month'">自定义月数:</span>
+          <span v-show="search.type === 'day'">自定义天数:</span>
+          <a-input
             v-model:value="search.value"
             placeholder="请输入"
-            style="width: 80px"
+            style="width: 100px"
             type="number"
             :min="0"
-          />
-          <a-select style="width: 100px" v-model:value="search.type">
+            @keyup.enter="getList"
+          />&nbsp;
+          <a-select
+            style="width: 100px"
+            v-model:value="search.type"
+            @change="onTypeChange"
+          >
             <a-select-option value="month">按月查询</a-select-option>
-            <a-select-option value="day">按日查询</a-select-option>
-          </a-select>
-          <a-range-picker
-            :placeholder="['开始月份', '结束月份']"
-            format="YYYY-MM"
-            :value="dateValue"
-            :mode="search.month_model"
-            @panelChange="handlePanelChange"
-            @change="handleChange"
-            style="width: 200px"
-          />
+            <a-select-option value="day">按日查询</a-select-option> </a-select
+          >&nbsp;
+          <el-date-picker
+            v-if="search.type === 'month'"
+            v-model="search.date_arr"
+            type="monthrange"
+            range-separator="-"
+            start-placeholder="开始月份"
+            end-placeholder="结束月份"
+            @change="getList"
+            size="small"
+            style="width: 240px"
+            value-format="YYYY-MM"
+          >
+          </el-date-picker>
+          <el-date-picker
+            v-else
+            v-model="search.date_arr"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            @change="getList"
+            size="small"
+            style="width: 240px"
+            value-format="YYYY-MM-DD"
+          >
+          </el-date-picker>
         </div>
       </div>
+      <div class="table-box">
+        <a-radio-group
+          v-model:value="search.model"
+          @change="getList"
+          style="margin: 10px 0"
+        >
+          <a-radio-button value="natural">自然日数据</a-radio-button>
+          <a-radio-button value="precise">顺延24小时数据</a-radio-button>
+        </a-radio-group>
+        <a-table
+          bordered
+          :scroll="{ x: 1500 }"
+          :data-source="list"
+          :columns="columns"
+          @change="getList"
+          rowKey="uid"
+          :loading="loading"
+          :pagination="tablePageOptions"
+        >
+          <template #wm0="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[0].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[0].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[0].back_rate }}
+            </p>
+          </template>
+          <template #wm1="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[1].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[1].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[1].back_rate }}
+            </p>
+          </template>
+          <template #wm2="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[2].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[2].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[2].back_rate }}
+            </p>
+          </template>
+          <template #cm0="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[0].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[0].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[0].back_rate }}
+            </p>
+          </template>
+          <template #cm1="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[1].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[1].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[1].back_rate }}
+            </p>
+          </template>
+          <template #cm2="{ record }">
+            <p class="detail-num">{{ record.cash_withdrawal[2].amount }}</p>
+            <p class="detail-num small-font">
+              累计提现: {{ record.cash_withdrawal[2].accruing_amount }}
+            </p>
+            <p class="detail-num small-font">
+              回本率: {{ record.cash_withdrawal[2].back_rate }}
+            </p>
+          </template>
+          <template #operation="{ record }">
+            <a-button type="link" @click="toDetial(record)">查看详情</a-button>
+          </template>
+        </a-table>
+      </div>
     </div>
   </div>
 </template>
@@ -41,9 +143,9 @@
 import usePagination from "@/hooks/usePagination";
 import { defineComponent, reactive, toRefs, ref } from "vue";
 import { Moment } from "moment";
-// import { TableColumnOfYuewen } from "../_pageOptions/table_yuewen";
+import { TableColumnOfStuffPerformance } from "../_pageOptions/table_data";
 //getPromotionList
-import {} from "@/api";
+import { getStuffPerformance } from "@/api";
 import { message } from "ant-design-vue";
 const Performance = defineComponent({
   components: {},
@@ -52,48 +154,44 @@ const Performance = defineComponent({
     const state = reactive({
       search: {
         uname: "", // 推广员名称
-        start_date: "", // 开始日期 月或日
-        end_date: "", // 结束日期 月或日
         type: "month", // 时间类型 day/month
         model: "natural", // 计算方式 自然日:natural/ 顺延24小时:precise
-        value: "", // 自定义月数、天数
-        month_model: ref<string[]>(["month", "month"]),
+        value: ref<any[number | string]>(3), // 自定义月数、天数
+        date_arr: ref<any[]>([]),
       },
-      dateValue: ref<Moment[]>([]),
+      loading: false,
+      list: ref<any[]>([]),
+      columns: TableColumnOfStuffPerformance,
     });
-    const handlePanelChange = (val: Moment[], mode: string[]) => {
-      state.dateValue = val;
-      state.search.month_model = [
-        mode[0] === "date" ? "month" : mode[0],
-        mode[1] === "date" ? "month" : mode[1],
-      ];
-      console.log(state.dateValue, state.search.month_model);
-    };
-    const handleChange = (val: Moment[]) => {
-      state.dateValue = val;
-      console.log(state.dateValue, state.search.month_model);
-    };
 
     return {
       ...toRefs(state),
       tablePageOptions,
-      handlePanelChange,
-      handleChange,
     };
   },
   mounted() {
-    this.getList({ current: 1 });
+    // this.getList({ current: 1 });
+    this.onTypeChange("month");
   },
   methods: {
-    // 重置搜索条件
-    resetSearch() {
-      // this.search.book_name = "";
-      // this.search.channel_name = "";
-      // this.search.channel_id = "";
-    },
     // 获取推广链接数据
-    async getList(page?: any) {
-      // this.loading = true;
+    async getList(page?: any, filters?: any, sorter?: any) {
+      console.log("SORT", page, filters, sorter);
+      this.loading = true;
+      let param: any = {
+        start_date: this.search.date_arr ? this.search.date_arr[0] : "",
+        end_date: this.search.date_arr ? this.search.date_arr[1] : "",
+        ...this.search,
+      };
+      delete param.date_arr;
+      console.log("请求参数", param);
+      let { data } = await getStuffPerformance({
+        page: page ? page.current : 1,
+        ...param,
+      });
+      console.log("请求结果", data);
+      this.list = data.list;
+      this.loading = false;
       // let { data } = await getPromotionList({
       //   page: page ? page.current : 1,
       //   ...this.search,
@@ -101,6 +199,61 @@ const Performance = defineComponent({
       // this.loading = false;
       // this.list = data.list;
     },
+    // 月、日查询类型改变
+    onTypeChange(val: string) {
+      var date = new Date();
+      console.log(val);
+      if (val === "month") {
+        this.search.value = 3;
+        var list = this.getDateRange(date, 30, true);
+        console.log(list[0].substring(0, 7));
+        this.search.date_arr = [
+          list[0].substring(0, 7),
+          list[1].substring(0, 7),
+        ];
+      } else {
+        this.search.value = "";
+        var list = this.getDateRange(date, 7, true);
+        this.search.date_arr = list;
+      }
+      this.getList();
+    },
+    // 工具函数:获取最近日期
+    getDateRange(dateNow: any, intervalDays: any, bolPastTime: any) {
+      let oneDayTime = 24 * 60 * 60 * 1000;
+      let list = [];
+      let lastDay;
+
+      if (bolPastTime == true) {
+        lastDay = new Date(dateNow.getTime() - intervalDays * oneDayTime);
+        list.push(this.formateDate(lastDay));
+        list.push(this.formateDate(dateNow));
+      } else {
+        lastDay = new Date(dateNow.getTime() + intervalDays * oneDayTime);
+        list.push(this.formateDate(dateNow));
+        list.push(this.formateDate(lastDay));
+      }
+      return list;
+    },
+    formateDate(time: any) {
+      let year = time.getFullYear();
+      let month = time.getMonth() + 1;
+      let day = time.getDate();
+      if (month < 10) {
+        month = "0" + month;
+      }
+      if (day < 10) {
+        day = "0" + day;
+      }
+      return year + "-" + month + "-" + day + "";
+    },
+    // 查看详情
+    toDetial(item: any) {
+      console.log("查看详情", item);
+      this.$router.push(
+        `/data/performanceDetail?uid=${item.uid}&uname=${item.uname}`
+      );
+    },
   },
 });
 
@@ -108,6 +261,19 @@ export default Performance;
 </script>
 <style lang="scss" scoped>
 @import "@/assets/common-style/frame.scss";
-// .performance {
-// }
+.performance {
+  .search-box {
+    display: flex;
+    justify-content: space-between;
+  }
+  .table-box {
+    padding: 0 10px;
+  }
+  .detail-num {
+    color: gray;
+  }
+  .small-font {
+    font-size: 13px;
+  }
+}
 </style>

+ 54 - 9
yarn.lock

@@ -160,10 +160,10 @@
     detect-browser "^5.0.0"
     tslib "^2.0.3"
 
-"@antv/g2@^4.1.0":
-  version "4.1.17"
-  resolved "https://registry.yarnpkg.com/@antv/g2/-/g2-4.1.17.tgz#d5ac405c37f29bcdebfeca9d0f04e472538db049"
-  integrity sha512-rtWywxfNglp7WXbuux6Q9MPIhdFqPybNllEuzOVYC8r0sOxJnC2QZxiIYGemjmw6tMT5ETGI33PCzUfiGEE5KA==
+"@antv/g2@^4.1.19":
+  version "4.1.20"
+  resolved "https://registry.yarnpkg.com/@antv/g2/-/g2-4.1.20.tgz#4495b626aa05272634bdb563fe83a7f335ddbe6c"
+  integrity sha512-Gs+Mlm/tiAIuRN7dQeQ51Vuou424ntds+sPGz+9k0SrHjPm5Q9+FnbUdmkDHqixrawupT6RNY6Cbmtt7s4BT0A==
   dependencies:
     "@antv/adjust" "^0.2.1"
     "@antv/attr" "^0.3.1"
@@ -181,15 +181,16 @@
     "@antv/util" "~2.0.5"
     tslib "^2.0.0"
 
-"@antv/g2plot@^2.3.21":
-  version "2.3.21"
-  resolved "https://registry.yarnpkg.com/@antv/g2plot/-/g2plot-2.3.21.tgz#f134046304294d94879c52d6db8bc1b70c72aebe"
-  integrity sha512-YNTeQobFiuSAI8e6pVMZhQISlfobHS/+/5jix6yBMQezO6zlu9DjEn3Uz6q+V3wfW/utKi7NRlFIkVuHGezQsA==
+"@antv/g2plot@^2.3.26":
+  version "2.3.26"
+  resolved "https://registry.yarnpkg.com/@antv/g2plot/-/g2plot-2.3.26.tgz#920bac99c0a5291ca8e510d72ebe93196be31087"
+  integrity sha512-ba2KgLoQ4w+mToUsDYqAC5nOfZWbJR8Nf6s/H7KYyno//Ig6QrnVhdPzV7QcC0tLL5X6ltyCGrVpZUYgGevCJA==
   dependencies:
     "@antv/event-emitter" "^0.1.2"
-    "@antv/g2" "^4.1.0"
+    "@antv/g2" "^4.1.19"
     d3-hierarchy "^2.0.0"
     d3-regression "^1.3.5"
+    pdfast "^0.2.0"
     size-sensor "^1.0.1"
     tslib "^2.0.3"
 
@@ -1194,6 +1195,11 @@
     mkdirp "^1.0.4"
     rimraf "^3.0.2"
 
+"@popperjs/core@^2.4.4":
+  version "2.9.2"
+  resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353"
+  integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==
+
 "@simonwep/pickr@~1.8.0":
   version "1.8.1"
   resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.8.1.tgz#e136cbd9c345ddbb7d71eb14af544c798165d495"
@@ -1296,6 +1302,11 @@
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
   integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
 
+"@types/lodash@^4.14.161":
+  version "4.14.171"
+  resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.171.tgz#f01b3a5fe3499e34b622c362a46a609fdb23573b"
+  integrity sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==
+
 "@types/lodash@^4.14.165":
   version "4.14.170"
   resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6"
@@ -3627,6 +3638,11 @@ dateformat@^2.0.0:
   resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062"
   integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=
 
+dayjs@1.x:
+  version "1.10.6"
+  resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63"
+  integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw==
+
 debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -3971,6 +3987,20 @@ electron-to-chromium@^1.3.723:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.737.tgz#196f2e9656f4f3c31930750e1899c091b72d36b5"
   integrity sha512-P/B84AgUSQXaum7a8m11HUsYL8tj9h/Pt5f7Hg7Ty6bm5DxlFq+e5+ouHUoNQMsKDJ7u4yGfI8mOErCmSH9wyg==
 
+element-plus@^1.0.2-beta.54:
+  version "1.0.2-beta.54"
+  resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-1.0.2-beta.54.tgz#70eda3fc0ef4c28a1cdc6bffec8f9c34ef83cc16"
+  integrity sha512-XXgZMnVt2ECtLyxJLVMq+faTxcYKNy9ZTaQ4cgbITgR/iGF5iXPHHjn1J1DWNLIKJ0XQRo8atAM1fyOpJsyJzw==
+  dependencies:
+    "@popperjs/core" "^2.4.4"
+    "@types/lodash" "^4.14.161"
+    async-validator "^3.4.0"
+    dayjs "1.x"
+    lodash "^4.17.20"
+    mitt "^2.1.0"
+    normalize-wheel "^1.0.1"
+    resize-observer-polyfill "^1.5.1"
+
 elliptic@^6.5.3:
   version "6.5.4"
   resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@@ -6292,6 +6322,11 @@ mississippi@^3.0.0:
     stream-each "^1.1.0"
     through2 "^2.0.0"
 
+mitt@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230"
+  integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==
+
 mixin-deep@^1.2.0:
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
@@ -6530,6 +6565,11 @@ normalize-url@^3.0.0:
   resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
   integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
 
+normalize-wheel@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45"
+  integrity sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=
+
 npm-run-path@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@@ -6992,6 +7032,11 @@ pbkdf2@^3.0.3:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
+pdfast@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/pdfast/-/pdfast-0.2.0.tgz#8cbc556e1bf2522177787c0de2e0d4373ba885c9"
+  integrity sha1-jLxVbhvyUiF3eHwN4uDUNzuohck=
+
 performance-now@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"