Nessuna descrizione

index.vue 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <template>
  2. <div class="app-container">
  3. <div v-show="visible.secondLayer">
  4. <div class="app-container">
  5. <div class="block">
  6. <!-- <span class="demonstration">時間篩選</span> -->
  7. <el-date-picker
  8. v-model="date"
  9. type="datetimerange"
  10. :picker-options="pickerOptions"
  11. range-separator="至"
  12. start-placeholder="開始日期"
  13. end-placeholder="结束日期"
  14. align="right">
  15. </el-date-picker>
  16. <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">搜尋</el-button>
  17. </div>
  18. </div>
  19. <el-table :data="allCombine" v-loading.body="listLoading" element-loading-text="Loading" border fit highlight-current-row>
  20. <el-table-column label="代理商名稱" align="center">
  21. <template slot-scope="scope">
  22. <span>{{scope.row.name}}</span>
  23. </template>
  24. </el-table-column>
  25. <el-table-column label="總上分額" align="center">
  26. <template slot-scope="scope">
  27. <span>{{scope.row.allUp}}</span>
  28. </template>
  29. </el-table-column>
  30. <el-table-column label="總下分額" align="center">
  31. <template slot-scope="scope">
  32. <span>{{scope.row.allDown}}</span>
  33. </template>
  34. </el-table-column>
  35. <el-table-column label="所有會員點數" align="center">
  36. <template slot-scope="scope">
  37. <span>{{scope.row.allChips}}</span>
  38. </template>
  39. </el-table-column>
  40. <el-table-column label="有效投注量" align="center">
  41. <template slot-scope="scope">
  42. <span>{{scope.row.allEarned}}</span>
  43. </template>
  44. </el-table-column>
  45. <el-table-column label="總水量" align="center">
  46. <template slot-scope="scope">
  47. <span>{{scope.row.allServiceFees}}</span>
  48. </template>
  49. </el-table-column>
  50. <el-table-column label="上繳工作室金額" align="center">
  51. <template slot-scope="scope">
  52. <span :style="moneyColor(all(scope))">{{all(scope)}}</span>
  53. </template>
  54. </el-table-column>
  55. </el-table>
  56. <el-table show-summary :summary-method="getSummaries" :data="combine" v-loading.body="listLoading" element-loading-text="Loading" border fit highlight-current-row>
  57. <el-table-column :label="`${this.data.secondLayer.GambleMember.name}的會員`" align="center">
  58. <el-table-column label="名稱" align="center">
  59. <template slot-scope="scope">
  60. <span>{{scope.row.name}}</span>
  61. </template>
  62. </el-table-column>
  63. <el-table-column label="會員當前分數" prop="chips" align="center"></el-table-column>
  64. <el-table-column label="總上分額" prop="totalUp" align="center"></el-table-column>
  65. <el-table-column label="總下分額" prop="totalDown" align="center"></el-table-column>
  66. <el-table-column label="總獎勵" prop="totalReward" align="center"></el-table-column>
  67. <el-table-column label="總懲罰" prop="totalPunishment" align="center"></el-table-column>
  68. <el-table-column label="有效投注量" prop="effectiveTotal" align="center"></el-table-column>
  69. <!-- <el-table-column label="莊家贏錢" align="center">
  70. <template slot-scope="scope">
  71. <span :style="moneyColor(scope.row.bookieEarned)">{{scope.row.bookieEarned}}</span>
  72. </template>
  73. </el-table-column>
  74. <el-table-column label="閒家贏錢" align="center">
  75. <template slot-scope="scope">
  76. <span :style="moneyColor(scope.row.memberEarned)">{{scope.row.memberEarned}}</span>
  77. </template>
  78. </el-table-column> -->
  79. <el-table-column label="莊家總投注量抽水" prop="bookieWagerFee" align="center"></el-table-column>
  80. <el-table-column label="莊家總投注量退水" prop="bookieWagerFeeRatio" align="center"></el-table-column>
  81. <el-table-column label="莊家總抽水" prop="bookieServiceFees" align="center"></el-table-column>
  82. <el-table-column label="莊家退水" prop="bookieServiceFeesRatio" align="center"></el-table-column>
  83. <el-table-column label="閒家總抽水" prop="memberServiceFees" align="center"></el-table-column>
  84. <el-table-column label="閒家退水" prop="memberServiceFeesRatio" align="center"></el-table-column>
  85. <el-table-column label="總退水" prop="totalServiceFees" align="center"></el-table-column>
  86. <el-table-column label="會員結帳" prop="memberCheckOut" align="center">
  87. <template slot-scope="scope">
  88. <span :style="moneyColor((scope.row.memberCheckOut))">{{(scope.row.memberCheckOut)}}</span>
  89. </template>
  90. </el-table-column>
  91. <el-table-column align="center" label="操作" width="100">
  92. <template slot-scope="scope">
  93. <router-link to="/agent/index/gambleMemberManagement/index/gameHistory">
  94. <el-button type="primary" size="mini" icon="el-icon-tickets" @click="handlePersonDetail(scope.row)">紀錄</el-button>
  95. </router-link>
  96. </template>
  97. </el-table-column>
  98. </el-table-column>
  99. </el-table>
  100. </div>
  101. <router-view></router-view>
  102. </div>
  103. </template>
  104. <script>
  105. import { mapActions, mapGetters } from 'vuex'
  106. import { fetchMemberList } from '@/api/agnetManagement'
  107. import waves from '@/directive/waves' // 水波纹指令
  108. import moment from 'moment-timezone'
  109. import config from '../../../../config'
  110. import _ from 'lodash'
  111. import { Decimal } from 'decimal.js';
  112. export default {
  113. directives: {
  114. waves
  115. },
  116. data() {
  117. return {
  118. // chipLogList: [],
  119. // gameRecordList: [],
  120. list: [],
  121. // member: {},
  122. dialogList: null,
  123. total: null,
  124. listLoading: true,
  125. allCombine: [],
  126. combine: [],
  127. listQuery: {
  128. // page: 1,
  129. // limit: 20,
  130. startAt: moment.utc(moment().startOf('isoweek').subtract(1, 'weeks').day(7).hour(16).minute(0).second(0)).format(),
  131. endAt: moment.utc(moment().startOf('isoweek').day(7).hour(11).minute(59).second(59)).format()
  132. },
  133. pickerOptions: {
  134. shortcuts: [{
  135. text: '本週',
  136. onClick(picker) {
  137. const end = moment().startOf('isoweek').day(7).hour(11).minute(59).second(59)
  138. const start = moment().startOf('isoweek').subtract(1, 'weeks').day(7).hour(16).minute(0).second(0)
  139. picker.$emit('pick', [start, end])
  140. }
  141. }, {
  142. text: '上週',
  143. onClick(picker) {
  144. const end = moment().startOf('isoweek').subtract(1, 'weeks').day(7).hour(11).minute(59).second(59)
  145. const start = moment().startOf('isoweek').subtract(2, 'weeks').day(7).hour(16).minute(0).second(0)
  146. picker.$emit('pick', [start, end])
  147. }
  148. }]
  149. },
  150. date: null,
  151. dialogFormVisible: false
  152. }
  153. },
  154. created() {
  155. this.SetVisible(2)
  156. this.getList()
  157. },
  158. computed: {
  159. ...mapGetters([
  160. 'visible',
  161. 'data',
  162. ])
  163. },
  164. // props: ['agent'],
  165. methods: {
  166. ...mapActions([
  167. 'SetVisible',
  168. 'SetData',
  169. ]),
  170. async getList() {
  171. this.listLoading = true
  172. this.allCombine = []
  173. this.combine = []
  174. await fetchMemberList(this.data.secondLayer, this.listQuery).then(response => {
  175. response.data.rows.map(member => {
  176. let row = {
  177. id: member.id,
  178. name: member.name,
  179. chips: member.chips,
  180. totalUp: 0,
  181. totalDown: 0,
  182. totalReward: 0,
  183. totalPunishment: 0,
  184. effectiveTotal: 0,
  185. bookieEarned: 0,
  186. memberEarned: 0,
  187. bookieWagerFee: 0,
  188. bookieWagerFeeRatio: 0,
  189. bookieServiceFees: 0,
  190. bookieServiceFeesRatio: 0,
  191. memberServiceFees: 0,
  192. memberServiceFeesRatio: 0,
  193. totalServiceFees: 0,
  194. memberCheckOut: 0,
  195. feeRatio: new Decimal(this.data.secondLayer.feeRatio/100),
  196. }
  197. let bookie = _.groupBy(member['GambleGame-Bucket-MemberRecords'], 'isBookie')
  198. if (bookie.false) {
  199. row.memberEarned = _.sumBy(bookie.false, item => {
  200. return Math.abs(item.earned)
  201. });
  202. // console.log('membeEarned', row.memberEarned)
  203. row.memberServiceFees = _.sumBy(bookie.false, 'serviceFees');
  204. row.memberServiceFeesRatio = row.feeRatio.times(row.memberServiceFees).valueOf()
  205. }
  206. if (bookie.true) {
  207. row.bookieWagerFee = _.sumBy(bookie.true, (item) => {
  208. return item.wagerServiceFees
  209. });
  210. row.bookieWagerFeeRatio = row.feeRatio.times(row.bookieWagerFee).valueOf()
  211. // console.log('eeee', bookie.true)
  212. row.bookieEarned = _.sumBy(bookie.true, item => {
  213. return Math.abs(item.earned)
  214. });
  215. // console.log('bookieEarned' , row.bookieEarned)
  216. row.bookieServiceFees = _.sumBy(bookie.true, (item) => { return item.serviceFees});
  217. row.bookieServiceFeesRatio = row.feeRatio.times(row.bookieServiceFees).valueOf()
  218. }
  219. row.effectiveTotal = _.sumBy(member['GambleGame-Bucket-RoundRecords'], item => {
  220. return item.used_quota
  221. }) + row.memberEarned
  222. row.totalServiceFees = Number(new Decimal(row.bookieServiceFees).plus(row.memberServiceFees).plus(row.bookieWagerFee).times(row.feeRatio).valueOf())
  223. let chipsLog = _.groupBy(member.GambleMemberChipsLogs, 'type')
  224. // console.log('type', chipsLog)
  225. if (chipsLog['0'] || chipsLog['2']) {
  226. row.totalUp = _.sumBy(chipsLog['0'], (item) => {
  227. return item.chips > 0 ? item.chips : 0
  228. })
  229. row.totalDown = _.sumBy(chipsLog['0'], (item) => {
  230. return item.chips < 0 ? item.chips : 0
  231. }) + _.sumBy(chipsLog['2'], (item) => {
  232. return item.chips < 0 ? item.chips : 0
  233. })
  234. }
  235. row.memberCheckOut = (row.totalUp + row.totalDown - row.chips)*(-1)
  236. // TODO CHECK 是否需要
  237. if(chipsLog['1']) {
  238. row.totalReward = _.sumBy(chipsLog['1'], (item) => {
  239. return item.chips > 0 ? item.chips : 0
  240. })
  241. row.totalPunishment = _.sumBy(chipsLog['1'], (item) => {
  242. return item.chips < 0 ? item.chips : 0
  243. })
  244. }
  245. // console.log('www',row)
  246. this.combine.push(row)
  247. })
  248. // console.log('cimbine' , this.combine)
  249. this.allCombine.push({
  250. name: this.data.secondLayer.GambleMember.name,
  251. allUp: _.sumBy(this.combine, 'totalUp'),
  252. allDown: _.sumBy(this.combine, 'totalDown'),
  253. allChips: _.sumBy(this.combine, 'chips'),
  254. allEarned: _.sumBy(this.combine, (item) => {return item.bookieEarned + item.memberEarned}),
  255. allServiceFees: _.sumBy(this.combine, (item) => {return item.totalServiceFees }),
  256. })
  257. this.listLoading = false
  258. })
  259. },
  260. handlePersonDetail(row) {
  261. const temp = Object.assign({}, row) // copy obj
  262. this.SetVisible(3)
  263. this.SetData({layer:3, data: temp})
  264. },
  265. handleFilter() {
  266. this.listQuery.page = 1
  267. if (this.date) {
  268. this.listQuery.startAt = moment.utc(this.date[0]).format()
  269. this.listQuery.endAt = moment.utc(this.date[1]).format()
  270. } else {
  271. this.listQuery.startAt = null
  272. this.listQuery.endAt = null
  273. }
  274. this.getList()
  275. },
  276. handleSizeChange(val) {
  277. this.listQuery.limit = val
  278. this.getList()
  279. },
  280. handleCurrentChange(val) {
  281. this.listQuery.page = val
  282. this.getList()
  283. },
  284. moment(time) {
  285. return moment(time).tz('Asia/Taipei').format('YYYY-MM-DD HH:mm:ss')
  286. },
  287. // getSummaries() {
  288. // const sums = []
  289. // let totalWager = 0
  290. // let totalEarned = 0
  291. // let totalServiceFees = 0
  292. // if (this.dialogList) {
  293. // this.dialogList.map((memberRecord) => {
  294. // totalWager += memberRecord.wager
  295. // totalEarned += memberRecord.earned
  296. // totalServiceFees += memberRecord.serviceFees
  297. // })
  298. // }
  299. // sums[0] = '合計'
  300. // sums[1] = 'N/A'
  301. // sums[2] = totalWager
  302. // sums[3] = totalEarned
  303. // sums[4] = totalServiceFees
  304. // return sums
  305. // },
  306. moneyColor(money) {
  307. return money >= 0 ? { color: '#67C23A' } : { color: '#FA5555' }
  308. },
  309. all(scope) {
  310. return (scope.row.allUp+scope.row.allDown-scope.row.allChips-scope.row.allServiceFees)*(-1)
  311. },
  312. getSummaries(param) {
  313. const { columns, data } = param;
  314. const sums = [];
  315. columns.forEach((column, index) => {
  316. if (index === 0) {
  317. sums[index] = '合計';
  318. return;
  319. }
  320. const values = data.map(item => Number(item[column.property]));
  321. if (!values.every(value => isNaN(value))) {
  322. sums[index] = values.reduce((prev, curr) => {
  323. const value = Number(curr);
  324. if (!isNaN(value)) {
  325. return prev + curr;
  326. } else {
  327. return prev;
  328. }
  329. }, 0);
  330. sums[index];
  331. } else {
  332. sums[index] = 'N/A';
  333. }
  334. });
  335. return sums;
  336. }
  337. },
  338. destroyed() {
  339. this.SetVisible(1)
  340. }
  341. }
  342. </script>