snow 4 months ago
parent
commit
6339af1424

File diff suppressed because it is too large
+ 0 - 0
dist/index.html


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.4ec5320d.js


BIN
dist/static/js/app.4ec5320d.js.gz


BIN
dist/static/js/app.cc2c78c2.js.gz


+ 14 - 0
src/api/newEarning.js

@@ -0,0 +1,14 @@
+
+// 物业管理员
+import http from "@/api/axios";
+import { reportApi } from "@/config";
+const api = "admin/";
+
+const onlineReportApi = "http://rep.report.caixiao365.com/admin/everyday/"
+
+const onlineApi = "http://rep.report.caixiao365.com/"
+
+export default {
+  orderNum: (data, params) => http(onlineReportApi + "companyStat", data, "post", params),
+  noAddrOrders: (data, params) => http(onlineApi + "purchease/sale/saleNoAddrListExport", data, "post", params, { responseType: 'blob' }),
+};

+ 152 - 0
src/components/newReporting/CommonReporting.vue

@@ -0,0 +1,152 @@
+<template>
+  <ElTable
+    border 
+    size="mini" 
+    :data="data" 
+    :span-method="objectSpanMethod"  
+    :row-class-name="tableRowClassName"
+    style="width: 100%"
+  >
+    
+    <ElTableColumn
+      fixed="left"
+      width="120px" 
+      label="业务公司" 
+      prop="companyName"  
+      show-overflow-tooltip 
+    />
+
+    <ElTableColumn 
+      label="年度" 
+      prop="year" 
+      width="50px" 
+      show-overflow-tooltip 
+    />
+
+    <template v-for="column in columns">
+      <ElTableColumn 
+          align="center"
+          v-bind="column"
+          v-if="column.children"
+          >
+          <ElTableColumn
+            v-for="child in column.children" 
+            v-bind="child"
+          >
+            <template slot-scope="scope">
+              <!-- <ElPopconfirm 
+                :title="`是否确认下载 ${generateChildTitle(column, child, scope.row)}`" 
+                placement="top"
+              >
+                <template slot="reference">
+                  <ElButton type="text" size="mini">
+                 
+                  </ElButton>
+                </template>
+              </ElPopconfirm> -->
+              {{ scope.row[child.prop] }}
+            </template>
+          </ElTableColumn>
+        </ElTableColumn>
+
+        <ElTableColumn  v-else v-bind="column">
+          <template slot-scope="scope">
+            <!-- <ElPopconfirm 
+              :title="`是否确认下载 ${generateTitle(column, scope.row)}`" 
+              @confirm="handleDownload(column, scope.row)"
+            >
+              <template slot="reference">
+                <ElButton type="text" size="mini">
+               
+                </ElButton>
+              </template>
+            </ElPopconfirm> -->
+            {{ scope.row[column.prop] }}
+          </template>
+        </ElTableColumn>
+    </template>
+  </ElTable>
+</template>
+
+
+<script>
+import { mapModeToColumns } from "./columns"
+export default {
+  props: {
+    data: { type: Array, default: () => ([]) },
+    mode: { type: 'String', default: 'express' }
+  },
+  computed: { columns(){ return mapModeToColumns[this.mode] } },
+  methods: {
+    async handleDownload(column, data){
+      if(data.year === '合计'){
+        const parameter = { 
+          'start_date': '2023-01-01', 
+          'end_date': '2024-12-31', 
+          companyNo: data.companyNo,
+          depart_id: '',
+          order_type: '',
+          status: ''
+        }
+
+        await column.api(parameter)
+      }
+
+    },
+    generateChildTitle(column, child ,data){
+      if(data.year === '合计'){
+        return `${data.companyName}${column.label}(${child.label})合计明细`
+      } else {
+        return `${data.companyName} ${data.year}年${column.label}(${child.label})明细`
+      }
+    },
+    generateTitle(column, data){
+      if(data.year === '合计'){
+        return `${data.companyName} ${column.label}合计明细`
+      } else {
+        return `${data.companyName} ${data.year}年${column.label}明细`
+      }
+    },
+    getSpanNumber(data, prop = '') {
+      //数组的长度,有时候后台可能返回个null而不是[]
+      let length = Array.isArray(data) ? data.length : 0;
+      if (length > 0) {
+        //用于标识位置
+        let position = 0;
+        //用于对比的数据
+        let temp = data[0][prop];
+        //要返回的结果
+        let result = [1];
+        //假设数据是AABCC,我们的目标就是返回20120
+        for (let i = 1; i < length; i++) {
+          if (data[i][prop] == temp) {
+            //标识位置的数据加一
+            result[position] += 1;
+            //当前位置添0
+            result[i] = 0;
+          } else {
+            //不相同时,修改标识位置,该位置设为1,修改对比值
+            position = i;
+            result[i] = 1;
+            temp = data[i][prop];
+          }
+        }
+        //返回结果
+        return result;
+      } else {
+        return [0];
+      }
+    },
+    tableRowClassName({ row }){
+      if(row.year === '合计') return 'bg__warning_1'
+    },
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex == 0) {
+        let nameSpan = this.getSpanNumber(this.data, "companyName");
+        return { rowspan: nameSpan[rowIndex], colspan: 1 };
+      }
+    },
+  }
+}
+</script>
+

+ 75 - 0
src/components/newReporting/columns.js

@@ -0,0 +1,75 @@
+import asyncRequest from "@/api/newEarning"
+
+
+export const expressColumns = [
+  { 
+    label: '无地址订单', 
+    prop: 'noAddrOrderNum', 
+    minWidth: '100px',
+    api: asyncRequest.noAddrOrders
+  },
+  { 
+    label: '未发货订单', 
+    prop: 'waitSendOrderNum', 
+    minWidth: '100px' 
+  },
+  { 
+    label: '未签收订单', 
+    minWidth: '100px', 
+    children: [
+      { label: '有物流信息', prop: 'noSignOrderExpressNum', minWidth: '100px' },
+      { label: '无物流信息', prop: 'noSignOrderNoExpressNum', minWidth: '100px' },
+      { label: '物流信息异常', prop: 'noSignOrderFailNum', minWidth: '100px' },
+      { label: '未签收订单总数', prop: 'noSignOrderNum', minWidth: '120px' },
+    ] 
+  }
+]
+
+export const purchaseOrderColumns = [
+  { 
+    label: '未对账采购单', 
+    children: [
+      { label: '通用订单', prop: 'noDzCgdNumComon', minWidth: '100px'  },
+      { label: '采购/源头订单', prop: 'noDzCgdNum', minWidth: '100px' },
+    ] 
+  },
+  {
+    label: '已对账未付款采购单',
+    children: [
+      { label: '通用订单', prop: 'dzNoPayCgdNumCom', minWidth: '100px'},
+      { label: '采购/源头订单', prop: 'dzNoPayCgdNum', minWidth: '100px' }
+    ]
+  },
+  {
+    label: '已对账未回票采购单',
+    children: [
+      { label: '通用订单', prop: 'dzNoInvCgdNumCom', minWidth: '100px' },
+      { label: '采购/源头订单', prop: 'dzNoInvCgdNum', minWidth: '100px' }
+    ]
+  },
+]
+
+
+export const saleOrderColumns = [
+  {
+    label: '未回款销售单',
+    children: [
+      { label: 'toB', prop: 'noPayQrdTobNum', minWidth: '100px' },
+      { label: 'toC', prop: 'noPayQrdTocNum', minWidth: '100px' }
+    ]
+  },
+  {
+    label: '未开票销售单',
+    children: [
+      { label: 'toB', prop: 'noInvQrdTobNum', minWidth: '100px' },
+      { label: 'toC', prop: 'noInvQrdTocNum', minWidth: '100px' }
+    ]
+  }
+]
+
+
+export const mapModeToColumns = {
+  'express': expressColumns,
+  'saleOrder': saleOrderColumns,
+  'purchaseOrder': purchaseOrderColumns
+}

+ 105 - 0
src/pages/_utils.js

@@ -0,0 +1,105 @@
+export const mapResponseType = {
+  '1':'自营',
+  '2':'渠道',
+  '3':'供应商端'
+}
+
+export const mapResponseCompanyName = {
+  '泓源':'泓源广诚',
+  '普润':'普润心堂',
+  '百辰':'百辰荣达',
+  '平台':'平台部'
+}
+
+export const mapResponseCompletionCompanyName = {
+  '泓源':'泓源广诚',
+  '普润':'普润心堂&锦兴弘昌',
+  '百辰':'百辰荣达',
+  '平台':'平台部'
+}
+
+export const getTypeLabel = value => mapResponseType[String(value)]
+export const getCompanyCompletionLabel = value => mapResponseCompletionCompanyName[String(value)]
+export const getCompanyLabel = value => mapResponseCompanyName[String(value)]
+
+/* 加法 **/ 
+export function addition(arg1, arg2) {
+  var r1, r2, m;
+  try {
+    r1 = arg1.toString().split(".")[1].length;
+  } catch (e) {
+    r1 = 0;
+  }
+  try {
+    r2 = arg2.toString().split(".")[1].length;
+  } catch (e) {
+    r2 = 0;
+  }
+  m = Math.pow(10, Math.max(r1, r2));
+  return (arg1 * m + arg2 * m) / m;
+}
+
+/* 除法 **/
+export function division(arg1, arg2) {
+  var t1 = 0,
+  t2 = 0,
+  r1,
+  r2;
+  try {
+    t1 = arg1.toString().split('.')[1].length;
+  } catch (e) {}
+  try {
+    t2 = arg2.toString().split('.')[1].length;
+  } catch (e) {}
+  r1 = Number(arg1.toString().replace('.', ''));
+  r2 = Number(arg2.toString().replace('.', ''));
+  return multiplication(r1 / r2, Math.pow(10, t2 - t1));
+}
+
+/* 乘法 **/
+export function multiplication(arg1,arg2){
+  var m = 0,
+    s1 = arg1.toString(),
+    s2 = arg2.toString();
+  try {
+    m += s1.split('.')[1].length;
+  } catch (e) {}
+  try {
+    m += s2.split('.')[1].length;
+  } catch (e) {}
+  return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m);
+}
+
+/* 减法 **/
+export function subtraction(arg1, arg2) {
+  var r1, r2, m, n;
+  try {
+    r1 = arg1.toString().split(".")[1].length;
+  } catch (e) {
+    r1 = 0;
+  }
+  try {
+    r2 = arg2.toString().split(".")[1].length;
+  } catch (e) {
+    r2 = 0;
+  }
+  m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
+  n = r1 >= r2 ? r1 : r2;
+  return ((arg1 * m - arg2 * m) / m).toFixed(n);
+}
+
+export function unit2TenThousand(value,isTenThound = true){
+  if(value === '--') return '--'
+  if(value === '-') return '-'
+  if(value === NaN || value === "NaN" || Number(value) === 0 || value === undefined) return '0'
+  if(!isTenThound) return value;
+  if(value < 1000 && value > 0 || value < 0 && value > -1000) return Number(value).toFixed(2)
+  return division(value, 10000).toFixed(2) + 'W'
+}
+
+export function unit2TenThousand2(value,isTenThound = true){
+  if(value === NaN || value === "NaN" || Number(value) === 0) return '0'
+  if(!isTenThound) return value;
+  if(value < 1000 && value > 0 || value < 0 && value > -1000) return Number(value).toFixed(2)
+  return division(value, 10000).toFixed(2)
+}

+ 10 - 9
src/pages/index.vue

@@ -14,15 +14,16 @@ export default {
   data(){
     return {
       routes:[
-        {label:'6.业务公司业绩报表', link: '/?path=newResults'},
-        {label: '8.结算订单业绩报表', link: '/?path=newEarningReport'},
-        {label:'2.利润看板', link: '/?path=report'},
-        {label:'3.应收账款', link: '/?path=accountsReceivable'},
-        {label:'4.订单情况', link: '/?path=newReport'},
-        {label:'5.发货情况', link: '/?path=stock'},
-        {label:'7.库存情况', link:'?path=newStock'},
-        {label:'1.业绩报表(2023版)', link: '/?path=results'},
-        {label: '测试', link: '/?path=newResultInfo'},
+        { label:'6.业务公司业绩报表', link: '/?path=newResults'},
+        { label:'8.结算订单业绩报表', link: '/?path=newEarningReport'},
+        { label:'2.利润看板', link: '/?path=report'},
+        { label:'3.应收账款', link: '/?path=accountsReceivable'},
+        { label:'4.订单情况', link: '/?path=newReport'},
+        { label:'5.发货情况', link: '/?path=stock'},
+        { label:'7.库存情况', link:'?path=newStock'},
+        { label:'1.业绩报表(2023版)', link: '/?path=results'},
+        { label: '测试', link: '/?path=newResultInfo'},
+        { label: '业务公司订单统计', link: '/?path=newReporting' }
       ]
     }
   },

+ 142 - 0
src/pages/newReporting.vue

@@ -0,0 +1,142 @@
+<template>
+  <div id="app" v-cloak v-loading="state.loading" style="min-height: 300px; padding: 10px">
+    <template v-if="!state.error && isShow">
+      <ElTabs>
+        <ElTabPane label="无地址&未发货&未签收">
+          <CommonReporting :data="orderNums" mode="express" />
+        </ElTabPane>
+
+        <ElTabPane label="采购单">
+          <CommonReporting :data="orderNums" mode="purchaseOrder" />
+        </ElTabPane>
+
+        <ElTabPane label="销售单">
+          <CommonReporting :data="orderNums" mode="saleOrder" />
+        </ElTabPane>
+      </ElTabs>
+    </template>
+
+    <template v-else-if="!state.loading">
+      <unusual-state :hasPermission="isShow" :message="state.message" path="results" />
+    </template>
+  </div>
+</template>
+<script>
+import asyncRequest from "@/api/newEarning"
+import UnusualState from "@/components/unusual/index.vue"
+import { getParameterByName, removeOpenid, getOpenid } from "../utils/auth"
+import CommonReporting from "../components/newReporting/CommonReporting.vue";
+import { addition } from "./_utils";
+
+export default {
+  name:'report',
+  components:{ UnusualState, CommonReporting },
+  data() {
+    return {
+      state:{ error: false, loading: false, message:'' },
+      hasPlatformDimension: false,
+      isShow : false,
+      companyArr:[],
+      orderNums:[],
+    }
+  },
+  async mounted(){
+    document.title = '业务公司订单统计'
+    this.requestUserinfo()
+  },
+  methods:{
+    async requestOrderNum(){
+      const result = await asyncRequest.orderNum()
+      if (result.code == 0){ 
+        const data = []
+        result.data.forEach(item => {
+          let total = {
+              "companyName": item.company,
+              'companyNo': item.companyNo,
+              "year": "合计",
+              "noAddrOrderNum": 0,
+              "waitSendOrderNum": 0,
+              "noSignOrderNum": 0,
+              "noDzCgdNumComon": 0,
+              "noDzCgdNum": 0,
+              "dzNoPayCgdNumCom": 0,
+              "dzNoPayCgdNum": 0,
+              "dzNoInvCgdNumCom": 0,
+              "dzNoInvCgdNum": 0,
+              'noPayQrdTobNum': 0,
+              'noPayQrdTocNum': 0,
+              'noInvQrdTobNum': 0,
+              'noInvQrdTocNum': 0,
+              'noSignOrderNoExpressNum': 0,
+              'noSignOrderExpressNum': 0,
+              'noSignOrderFailNum': 0
+          }
+
+          const noTotalProp = ['companyName', 'companyNo', 'year']
+          const keys = Object.keys(total).filter(key => !noTotalProp.includes(key))
+
+          item.data.forEach(companyData => {
+            keys.forEach(key => { total[key] = Number(addition(Number(companyData[key]).toFixed(2),Number(total[key]).toFixed(2))) })
+            data.push({ companyName: item.company, ...companyData })
+          })
+
+          data.push(total)
+        })
+
+        this.orderNums = data
+      } else {
+        this.$message.warning(result.message)
+      }
+    },
+    async requestData(){
+      this.state.loading = true
+      await this.requestOrderNum()
+      this.state.loading = false
+    },
+    async requestUserinfo(){
+      this.state.loading = true;
+      const openid = getOpenid()
+      const code = getParameterByName('code')
+      const result = await asyncRequest.userinfo({ ...( openid ? { openid } :  { code }) })
+      // const result ={
+      // "code": 0,
+      // "message": "获取成功",
+      // "data": {
+		  //     "id": "1",
+		  //     "openid": "oOpc26KiZFBKIm7SB8knFGvov1qg",
+		  //     "mobile": "",
+		  //     "gender": "0",
+		  //     "nickname": "雪寒",
+		  //     "avatar": "",
+		  //     "subscribe_time": "2022-12-21 15:52:14",
+		  //     "addr": "\/\/",
+		  //     "status": "1",
+		  //     "is_show": ["1", "2", "4", '9'],
+		  //     "companyArr": [
+      //       { "companyNo": "GS2302231125079621", "companyName": "北京百辰荣达国际科贸有限公司", "info": [1,2] }, 
+      //       { "companyNo": "GS2302231323386950", "companyName": "北京泓源广诚国际商贸有限公司", "info": [1,2] },
+      //       { "companyNo": "GS2304031312553746","companyName": "北京锦兴弘昌科技有限公司", "info": [1, 2] },
+      //       { "companyNo": "GS2302231124114965", "companyName": "北京普润心堂商贸有限公司", "info": [1, 2] },
+      //       { "companyNo": "GS2203161855277894","companyName": "北京万宇恒通国际科贸有限公司","info": [1, 2] }
+      //     ],
+		  //     "addtime": "2023-04-10 18:11:07",
+		  //     "updatetime": "2023-05-09 16:22:33"
+      // 	}
+      // }
+
+      this.state.loading = false
+      switch(Number(result.code)){
+        case 0:
+          this.isShow =  result.data.is_show.includes('9') || result.data.is_show.includes(9)
+          if(this.isShow) this.requestData()
+          break
+        default:
+          this.state.error = true
+          this.state.message = result.message
+          openid && removeOpenid()
+          break
+      }
+    }
+  }
+};
+</script>

+ 3 - 0
src/router/index.js

@@ -11,6 +11,8 @@ import NewResultInfo from "../pages/newResultsInfo.vue"
 import NewStock from "../pages/newStock.vue"
 import NewEarningReport from "../pages/newEarningReport.vue"
 
+import NewReporting from "../pages/newReporting.vue"
+
 import { getParameterByName } from "../utils/auth"
 
 const routes = [
@@ -25,6 +27,7 @@ const routes = [
   { path:'/newResultChart', component: NewResultChart },
   { path:'/newResultInfo', component: NewResultInfo },
   { path:'/newEarningReport', component: NewEarningReport },
+  { path:'/newReporting', component: NewReporting },
 ]
 
 const router = new VueRouter({routes, mode:'hash'})

Some files were not shown because too many files changed in this diff