Quellcode durchsuchen

feat: 数据看板 - 数据循环统计 - 权限控制逻辑

zhengxy vor 2 Jahren
Ursprung
Commit
e3ae8effdc

+ 136 - 80
project/src/components/dataBoard/regRangeReport.vue

@@ -1,83 +1,94 @@
1 1
 <template>
2
-  <div v-loading="loading">
3
-    <div class="screenBox flex">
4
-      <switchMpAdq v-model="order_type" @change="init(1);handleGetUpdateTime();" />
5
-      <el-button type="primary" size="mini" @click="init(1, 'export')">导出Excel</el-button>
6
-    </div>
7
-    <div class="screenBox flex">
8
-      <div class="flex">
9
-        <date-picker :reset="reset" title="自定义" :quickFlag='true' :afferent_time="default_time" :clearFlag='false'
10
-          @changeTime="changeTime"></date-picker>
11
-        <!-- 推广类型 -->
12
-        <selfChannel :reset="reset" title="推广类型" type="promotionType" @channelDefine="(val)=>{plat_order_type=val;init(1);handleGetUpdateTime();}" />
13
-        <!-- 收益截止日期 -->
14
-        <div style="margin-left: 30px;" class="common-screen-item">
15
-          <label class="common-screen-label">收益截止日期</label>
16
-          <el-date-picker v-model="closing_date" value-format="yyyy-MM-dd" type="date" placeholder="选择日期" size="small" style="width:150px" @change="onChangeClosingDate" />
2
+  <div class="regRangeReport-wrap" v-loading="loading">
3
+    <!-- S 无权限 -->
4
+    <el-empty class="empty-wrap" v-if="isShowEmpty" description="暂无数据权限" />
5
+    <!-- E 无权限 -->
6
+
7
+    <template v-else>
8
+      <div class="screenBox flex">
9
+        <switchMpAdq
10
+          v-model="order_type"
11
+          :isShowAdqBtn="isShowAdqBtn"
12
+          :isShowMpBtn="isShowMpBtn"
13
+          @change="init(1);handleGetUpdateTime();"
14
+        />
15
+        <el-button v-if="isCanExport" type="primary" size="mini" @click="init(1, 'export')">导出Excel</el-button>
16
+      </div>
17
+      <div class="screenBox flex">
18
+        <div class="flex">
19
+          <date-picker :reset="reset" title="自定义" :quickFlag='true' :afferent_time="default_time" :clearFlag='false'
20
+            @changeTime="changeTime"></date-picker>
21
+          <!-- 推广类型 -->
22
+          <selfChannel :reset="reset" title="推广类型" type="promotionType" @channelDefine="(val)=>{plat_order_type=val;init(1);handleGetUpdateTime();}" />
23
+          <!-- 收益截止日期 -->
24
+          <div style="margin-left: 30px;" class="common-screen-item">
25
+            <label class="common-screen-label">收益截止日期</label>
26
+            <el-date-picker v-model="closing_date" value-format="yyyy-MM-dd" type="date" placeholder="选择日期" size="small" style="width:150px" @change="onChangeClosingDate" />
27
+          </div>
17 28
         </div>
18 29
       </div>
19
-    </div>
20
-    <!-- S 新增区间筛选项 -->
21
-    <div class="screenBox filter-wrap">
22
-      <input-range v-model="firstDayRoi" label="首日ROI" />
23
-      <input-range v-model="firstOrderCost " label="下单成本" />
24
-      <input-range v-model="firstOrderCostUnique" label="下单成本(去重)" />
25
-      <input-range v-model="perFollowCost" label="企微成本" />
26
-      <input-range v-model="totalRoi" label="回本率" />
27
-      <input-range v-model="paid" label="消耗" />
28
-      <div>
29
-        <el-button size="mini" type="primary" plain @click="init(1);handleGetUpdateTime();">确定</el-button>
30
-        <el-button size="mini" plain @click="handleReset">重置</el-button>
30
+      <!-- S 新增区间筛选项 -->
31
+      <div class="screenBox filter-wrap">
32
+        <input-range v-model="firstDayRoi" label="首日ROI" />
33
+        <input-range v-model="firstOrderCost " label="下单成本" />
34
+        <input-range v-model="firstOrderCostUnique" label="下单成本(去重)" />
35
+        <input-range v-model="perFollowCost" label="企微成本" />
36
+        <input-range v-model="totalRoi" label="回本率" />
37
+        <input-range v-model="paid" label="消耗" />
38
+        <div>
39
+          <el-button size="mini" type="primary" plain @click="init(1);handleGetUpdateTime();">确定</el-button>
40
+          <el-button size="mini" plain @click="handleReset">重置</el-button>
41
+        </div>
31 42
       </div>
32
-    </div>
33
-    <!-- S 新增区间筛选项 -->
34
-    <!-- S 数据更新时间 -->
35
-    <div class="update-time"><i class="el-icon-warning-outline" />数据更新时间:{{ updateTime || '-' }}</div>
36
-    <!-- E 数据更新时间 -->
37
-    <!-- S 汇总表 summaryTable -->
38
-    <ux-grid style="margin-top:10px" ref="summaryTable" :border="false" @row-click="() => { return }" :header-cell-style="() => { return { backgroundColor: '#FFFFFF !important', border: 'none!important' } }" show-footer-overflow="tooltip" show-overflow="tooltip" size="mini">
39
-      <ux-table-column v-for="item in summaryTableCol" :key="item.column + item.name" :resizable="true" :field="item.column" :title="item.name" :min-width="item.min_width ? item.min_width : 140" :fixed="item.fixed ? item.fixed : ''" align="center">
40
-        <template #header>
41
-          <div class="flex-align-jus-center">
42
-            {{ item.name }}
43
-            <el-tooltip v-if="item.notes" :content="item.notes" placement="top">
44
-              <div><i class="el-icon-question"></i></div>
45
-            </el-tooltip>
46
-          </div>
47
-        </template>
48
-        <template v-slot="{ row }">
49
-          <span>{{ (row[item.column] || row[item.column] == 0) ? $formatNum(row[item.column]) : '-' }}</span>
50
-        </template>
51
-      </ux-table-column>
52
-    </ux-grid>
53
-    <!-- E 汇总表 summaryTable -->
43
+      <!-- S 新增区间筛选项 -->
44
+      <!-- S 数据更新时间 -->
45
+      <div class="update-time"><i class="el-icon-warning-outline" />数据更新时间:{{ updateTime || '-' }}</div>
46
+      <!-- E 数据更新时间 -->
47
+      <!-- S 汇总表 summaryTable -->
48
+      <ux-grid style="margin-top:10px" ref="summaryTable" :border="false" @row-click="() => { return }" :header-cell-style="() => { return { backgroundColor: '#FFFFFF !important', border: 'none!important' } }" show-footer-overflow="tooltip" show-overflow="tooltip" size="mini">
49
+        <ux-table-column v-for="item in summaryTableCol" :key="item.column + item.name" :resizable="true" :field="item.column" :title="item.name" :min-width="item.min_width ? item.min_width : 140" :fixed="item.fixed ? item.fixed : ''" align="center">
50
+          <template #header>
51
+            <div class="flex-align-jus-center">
52
+              {{ item.name }}
53
+              <el-tooltip v-if="item.notes" :content="item.notes" placement="top">
54
+                <div><i class="el-icon-question"></i></div>
55
+              </el-tooltip>
56
+            </div>
57
+          </template>
58
+          <template v-slot="{ row }">
59
+            <span>{{ (row[item.column] || row[item.column] == 0) ? $formatNum(row[item.column]) : '-' }}</span>
60
+          </template>
61
+        </ux-table-column>
62
+      </ux-grid>
63
+      <!-- E 汇总表 summaryTable -->
54 64
 
55
-    <!-- S 明细表 detailsTable -->
56
-    <ux-grid style="margin-top:10px" ref="detailsTable" :border="false" @row-click="() => { return }" :header-cell-style="() => { return { backgroundColor: '#FFFFFF !important', border: 'none!important' } }" :height="height" show-footer-overflow="tooltip" show-overflow="tooltip" size="mini">
57
-      <ux-table-column v-for="item in detailsTableCol" :key="item.column + item.name" :resizable="true" :field="item.column" :title="item.name" :min-width="item.min_width ? item.min_width : 140" :fixed="item.fixed ? item.fixed : ''" align="center">
58
-        <template #header>
59
-          <div class="flex-align-jus-center">
60
-            {{ item.name }}
61
-            <el-tooltip v-if="item.notes" :content="item.notes" placement="top">
62
-              <div><i class="el-icon-question"></i></div>
63
-            </el-tooltip>
64
-            <div v-if="item.enable_to_sort" class="sort-wrap">
65
-              <i class="el-icon-caret-top" :class="{ 'active': sort_field === item.column && sort_type === 'asc' }" @click="onClickSort(item.column, 'asc')" />
66
-              <i class="el-icon-caret-bottom" :class="{ 'active': sort_field === item.column && sort_type === 'desc' }" @click="onClickSort(item.column, 'desc')" />
65
+      <!-- S 明细表 detailsTable -->
66
+      <ux-grid style="margin-top:10px" ref="detailsTable" :border="false" @row-click="() => { return }" :header-cell-style="() => { return { backgroundColor: '#FFFFFF !important', border: 'none!important' } }" :height="height" show-footer-overflow="tooltip" show-overflow="tooltip" size="mini">
67
+        <ux-table-column v-for="item in detailsTableCol" :key="item.column + item.name" :resizable="true" :field="item.column" :title="item.name" :min-width="item.min_width ? item.min_width : 140" :fixed="item.fixed ? item.fixed : ''" align="center">
68
+          <template #header>
69
+            <div class="flex-align-jus-center">
70
+              {{ item.name }}
71
+              <el-tooltip v-if="item.notes" :content="item.notes" placement="top">
72
+                <div><i class="el-icon-question"></i></div>
73
+              </el-tooltip>
74
+              <div v-if="item.enable_to_sort" class="sort-wrap">
75
+                <i class="el-icon-caret-top" :class="{ 'active': sort_field === item.column && sort_type === 'asc' }" @click="onClickSort(item.column, 'asc')" />
76
+                <i class="el-icon-caret-bottom" :class="{ 'active': sort_field === item.column && sort_type === 'desc' }" @click="onClickSort(item.column, 'desc')" />
77
+              </div>
67 78
             </div>
68
-          </div>
69
-        </template>
70
-        <template v-slot="{ row }">
71
-          <span>{{ (row[item.column] || row[item.column] == 0) ? $formatNum(row[item.column]) : '-' }}</span>
72
-        </template>
73
-      </ux-table-column>
74
-    </ux-grid>
75
-    <div class="pagination" v-show="total > 0">
76
-      <el-pagination background :current-page="page" @current-change="handleCurrentChange" layout="prev, pager, next"
77
-        :page-count='Number(pages)'>
78
-      </el-pagination>
79
-    </div>
80
-    <!-- E 明细表 detailsTable -->
79
+          </template>
80
+          <template v-slot="{ row }">
81
+            <span>{{ (row[item.column] || row[item.column] == 0) ? $formatNum(row[item.column]) : '-' }}</span>
82
+          </template>
83
+        </ux-table-column>
84
+      </ux-grid>
85
+      <div class="pagination" v-show="total > 0">
86
+        <el-pagination background :current-page="page" @current-change="handleCurrentChange" layout="prev, pager, next"
87
+          :page-count='Number(pages)'>
88
+        </el-pagination>
89
+      </div>
90
+      <!-- E 明细表 detailsTable -->
91
+    </template>
81 92
   </div>
82 93
 </template>
83 94
 <script>
@@ -111,12 +122,13 @@ export default {
111 122
       totalRoi: ['', ''], // 回本率(范围)
112 123
       paid: ['', ''], // 消耗(范围)
113 124
       reset: false,
114
-      order_type: orderTypeOptions.ADQ, // MP/ADQ
125
+      order_type: '', // MP/ADQ
115 126
       plat_order_type: '', // 推广类型
116 127
       closing_date: '', // 收益截止日期
117 128
       sort_field: 'date', // 排序字段 默认 时间 & 降序
118 129
       sort_type: 'desc', // 升序/降序
119 130
       updateTime: '', // 数据更新时间
131
+      isShowEmpty: false, // 是否展示空页面 => 无任何权限时展示
120 132
     }
121 133
   },
122 134
   computed: {
@@ -128,14 +140,44 @@ export default {
128 140
     isADQ() {
129 141
       return this.order_type === orderTypeOptions.ADQ
130 142
     },
143
+    // 是否有“ADQ”权限
144
+    isShowAdqBtn() {
145
+      return !!this.$store.state.dataBoardAuth.adq_auth
146
+    },
147
+    // 是否有“MP”权限
148
+    isShowMpBtn() {
149
+      return !!this.$store.state.dataBoardAuth.mp_auth
150
+    },
151
+    // 是否有“导出”权限
152
+    isCanExport() {
153
+      return !!this.$store.state.dataBoardAuth.can_export
154
+    },
131 155
   },
132 156
   created () {
133
-    this.height = document.documentElement.clientHeight - 200 > 400 ? document.documentElement.clientHeight - 200 : 400
134
-    this.time = this.default_time
135
-    this.init(1)
136
-    this.handleGetUpdateTime()
157
+    const isPermissioned = this.getDefaultOrderType() // 根据用户权限 获取order_type默认值
158
+    if (isPermissioned) { // 有权限 => 获取对应报表数据
159
+      this.height = document.documentElement.clientHeight - 200 > 400 ? document.documentElement.clientHeight - 200 : 400
160
+      this.time = this.default_time
161
+      this.init(1)
162
+      this.handleGetUpdateTime()
163
+    } else { // 无权限 => 展示空页面
164
+      this.isShowEmpty = true
165
+    }
137 166
   },
138 167
   methods: {
168
+    // 根据用户权限 获取 order_type 默认值
169
+    getDefaultOrderType() {
170
+      if (this.isShowAdqBtn) { // 有ADQ权限 => 默认值ADQ
171
+        this.order_type = orderTypeOptions.ADQ
172
+        return orderTypeOptions.ADQ
173
+      } else if (this.isShowMpBtn) { // 有MP权限 => 默认值MP
174
+        this.order_type = orderTypeOptions.MP
175
+        return orderTypeOptions.MP
176
+      } else { // 无以上权限 => 返回false
177
+        this.$message.warning('暂无数据权限')
178
+        return false
179
+      }
180
+    },
139 181
     // 获取"数据更新时间"
140 182
     async handleGetUpdateTime() {
141 183
       try {
@@ -155,7 +197,7 @@ export default {
155 197
     },
156 198
     handleReset() {
157 199
       this.reset = !this.reset
158
-      this.order_type = orderTypeOptions.ADQ
200
+      this.order_type = this.getDefaultOrderType()
159 201
       this.plat_order_type = ''
160 202
       this.closing_date = '',
161 203
       this.time = this.default_time
@@ -297,6 +339,20 @@ export default {
297 339
 }
298 340
 </script>
299 341
 <style lang="scss" scoped>
342
+.regRangeReport-wrap {
343
+  position: relative;
344
+  min-height: calc(100vh - 70px);
345
+  .empty-wrap {
346
+    position: absolute;
347
+    top: 50%;
348
+    left: 50%;
349
+    transform: translate(-50%, -50%);
350
+  }
351
+  /deep/ .common-screen-label {
352
+    flex-shrink: 0;
353
+  }
354
+}
355
+
300 356
 .screenBox {
301 357
   position: relative;
302 358
   background: #fff;

+ 0 - 208
project/src/components/dataBoard/regRangeReport_backup.vue

@@ -1,208 +0,0 @@
1
-<template>
2
-  <div v-loading="loading">
3
-    <div class="screenBox flex">
4
-      <div class="flex">
5
-        <date-picker :reset="reset" title="自定义" :quickFlag='true' :afferent_time="default_time" :clearFlag='false'
6
-          @changeTime="changeTime"></date-picker>
7
-      </div>
8
-      <el-button type="primary" size="mini" @click="init(1, 'export')">导出Excel</el-button>
9
-    </div>
10
-
11
-    <!-- S 新增区间筛选项 -->
12
-    <div class="screenBox filter-wrap">
13
-      <input-range v-model="firstDayRoi" label="首日ROI" />
14
-      <input-range v-model="firstOrderCost " label="下单成本" />
15
-      <input-range v-model="firstOrderCostUnique" label="下单成本(去重)" />
16
-      <input-range v-model="perFollowCost" label="企微成本" />
17
-      <input-range v-model="totalRoi" label="回本率" />
18
-      <div>
19
-        <el-button size="mini" type="primary" plain @click="init(1)">确定</el-button>
20
-        <el-button size="mini" plain @click="handleReset">重置</el-button>
21
-      </div>
22
-    </div>
23
-    <!-- S 新增区间筛选项 -->
24
-
25
-    <ux-grid style="margin-top:10px" ref="plxTable" :border="false" @row-click="() => { return }"
26
-      :header-cell-style="() => { return { backgroundColor: '#FFFFFF !important', border: 'none!important' } }"
27
-      :height="height" show-footer-overflow="tooltip" show-overflow="tooltip" size="mini">
28
-      <ux-table-column v-for="item in desCol" :key="item.column" :resizable="true" :field="item.column"
29
-        :title="item.name" :min-width="item.min_width ? item.min_width : 140"
30
-        :fixed="item.column == 'date' ? 'left' : ''" align="center">
31
-        <template #header>
32
-          <div class="flex-align-jus-center">{{ item.name }}
33
-            <el-tooltip v-if="item.notes" :content="item.notes" placement="top">
34
-              <div><i class="el-icon-question"></i></div>
35
-            </el-tooltip>
36
-          </div>
37
-        </template>
38
-        <template v-slot="{ row }">
39
-          <span>{{ row[item.column] ? $formatNum(row[item.column]) : '-' }}</span>
40
-        </template>
41
-      </ux-table-column>
42
-    </ux-grid>
43
-    <div class="pagination" v-show="total > 0">
44
-      <el-pagination background :current-page="page" @current-change="handleCurrentChange" layout="prev, pager, next"
45
-        :page-count='Number(pages)'>
46
-      </el-pagination>
47
-    </div>
48
-  </div>
49
-</template>
50
-<script>
51
-import datePicker from '@/components/assembly/screen/datePicker.vue'
52
-import inputRange from '@/components/dataBoard/inputRange.vue'
53
-export default {
54
-  components: { datePicker, inputRange },
55
-  data () {
56
-    return {
57
-      loading: false,
58
-      page: 1,
59
-      pages: 0,
60
-      total: 0,
61
-      page_size: 20,
62
-      sort_field: 'charge_total',
63
-      dataInfo: {},
64
-      default_time: [this.$getDay(-30, false), this.$getDay(0, false)],
65
-      time: [],
66
-      desCol: [],
67
-      height: '',
68
-
69
-      firstDayRoi: ['', ''], // 首日ROI(范围)
70
-      firstOrderCost: ['', ''], // 下单成本(范围)
71
-      firstOrderCostUnique: ['', ''], // 下单成本(去重)(范围)
72
-      perFollowCost: ['', ''], // 企微成本(范围)
73
-      totalRoi: ['', ''], // 回本率(范围)
74
-      reset: false,
75
-    }
76
-  },
77
-  created () {
78
-    this.height = document.documentElement.clientHeight - 200 > 400 ? document.documentElement.clientHeight - 200 : 400
79
-    this.time = this.default_time
80
-    this.init(1)
81
-  },
82
-  methods: {
83
-    handleReset() {
84
-      this.reset = !this.reset
85
-      this.time = this.default_time
86
-      this.firstDayRoi = ['', ''] // 首日ROI(范围)
87
-      this.firstOrderCost = ['', ''] // 下单成本(范围)
88
-      this.firstOrderCostUnique = ['', ''] // 下单成本(去重)(范围)
89
-      this.perFollowCost = ['', ''] // 企微成本(范围)
90
-      this.totalRoi = ['', ''] // 回本率(范围)
91
-      this.init(1)
92
-    },
93
-    changeTime (time) {//筛选时间变化
94
-      if (!time || time && time.length == 0) {
95
-        this.time = []
96
-      } else {
97
-        this.time = time
98
-      }
99
-      this.init(1)
100
-    },
101
-    init (page, type) {
102
-      if (type != 'export') {
103
-        this.page = page ? page : this.page;
104
-      } else {
105
-        if (this.total == 0) {
106
-          this.$message({
107
-            message: '暂无数据可导出',
108
-            type: "warning"
109
-          })
110
-          return
111
-        }
112
-      }
113
-      this.loading = true
114
-      this.$axios.get(`${this.URL.BASEURL}${this.URL.statistics_reg_range_report_new}`, {
115
-        params: {
116
-          begin_date: this.time[0],
117
-          end_date: this.time[1],
118
-          first_day_roi_min: this.firstDayRoi[0],
119
-          first_day_roi_max: this.firstDayRoi[1],
120
-          first_order_cost_min: this.firstOrderCost[0],
121
-          first_order_cost_max: this.firstOrderCost[1],
122
-          first_order_cost_unique_min: this.firstOrderCostUnique[0],
123
-          first_order_cost_unique_max: this.firstOrderCostUnique[1],
124
-          per_follow_cost_min: this.perFollowCost[0],
125
-          per_follow_cost_max: this.perFollowCost[1],
126
-          total_roi_min: this.totalRoi[0],
127
-          total_roi_max: this.totalRoi[1],
128
-          page: type == 'export' ? 1 : this.page,
129
-          page_size: type == 'export' ? this.$store.state.exportNumber : this.page_size,
130
-        }
131
-      }).then((res) => {
132
-        var res = res.data
133
-        this.loading = false
134
-        if (res && res.errno == 0) {
135
-          if (type == 'export') {
136
-            this.exportEvent(res.rst.data.list)
137
-          } else {
138
-            this.desCol = res.rst.data.head;
139
-            this.$nextTick((item) => {
140
-              this.datas = res.rst.data.list // 知道为啥datas不在 data()方法里面定义吗?嘻嘻
141
-              this.$refs.plxTable.reloadData(this.datas)
142
-            })
143
-            this.total = res.rst.pageInfo.total;
144
-            this.pages = res.rst.pageInfo.pages;
145
-          }
146
-        } else if (res.errno != 4002) {
147
-          this.$message({
148
-            message: res.err,
149
-            type: "warning"
150
-          })
151
-        }
152
-      }).catch((err) => {
153
-        this.loading = false
154
-      });
155
-    },
156
-    handleCurrentChange (val) {
157
-      this.init(val)
158
-    },
159
-    sortFieldEvent (type) {
160
-      this.sort_field = type;
161
-      this.init(1)
162
-    },
163
-    exportEvent (data) {
164
-      let list = data;
165
-      let tHeader = this.desCol.map((v) => {
166
-        return v.name;
167
-      })
168
-      let filterVal = this.desCol.map((v) => {
169
-        return v.column
170
-      })
171
-      let excelDatas = [
172
-        {
173
-          tHeader: tHeader, // sheet表一头部
174
-          filterVal: filterVal, // 表一的数据字段
175
-          tableDatas: list, // 表一的整体json数据
176
-          sheetName: ''// 表一的sheet名字
177
-        }
178
-      ]
179
-      this.$exportOrder({ excelDatas, name: `数据循环统计(导出时间:${this.$getDay(0)})` })
180
-    }
181
-  }
182
-}
183
-</script>
184
-<style lang="scss" scoped>
185
-.screenBox {
186
-  position: relative;
187
-  background: #fff;
188
-  padding: 5px 20px;
189
-}
190
-.ml-10 {
191
-  margin-left: 10px;
192
-}
193
-.filter-wrap {
194
-  display: flex;
195
-  align-items: center;
196
-  flex-wrap: wrap;
197
-  padding-bottom: 10px;
198
-  & > div {
199
-    margin: 0 10px 10px 0;
200
-  }
201
-  & > button {
202
-    margin: -10px 0 0 10px;
203
-  }
204
-  .el-button+.el-button {
205
-    margin-left: 5px;
206
-  }
207
-}
208
-</style>