No Description

index.vue 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <template>
  2. <div class="app-container calendar-list-container">
  3. <div v-show="visible.firstLayer">
  4. <div class="app-container">
  5. <el-input @keyup.enter.native="handleFilter" style="width: 200px;" class="filter-item" placeholder="名稱" v-model="listQuery.name">
  6. </el-input>
  7. <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">搜尋</el-button>
  8. <el-button class="filter-item" @click="handleCreate" type="primary" icon="el-icon-edit">創建代理商</el-button>
  9. <el-input style='width:100px;' placeholder="輸入檔案名稱" prefix-icon="el-icon-document" v-model="filename"></el-input>
  10. <el-button style='margin-bottom:20px;' type="primary" icon="document" @click="handleDownload" :loading="downloadLoading">匯出 excel</el-button>
  11. </div>
  12. <el-table show-summary :summary-method="getSummaries" :data="list" v-loading.body="listLoading" element-loading-text="Loading" border fit highlight-current-row
  13. style="width: 100%">
  14. <!-- <el-table-column align="center" label='ID' >
  15. <template slot-scope="scope">
  16. {{scope.row.GambleMember.id}}
  17. </template>
  18. </el-table-column> -->
  19. <el-table-column label="名稱" align="center">
  20. <template slot-scope="scope">
  21. {{scope.row.name}}
  22. </template>
  23. </el-table-column>
  24. <el-table-column label="抽水%" align="center">
  25. <template slot-scope="scope">
  26. {{scope.row.feeRatio}}
  27. </template>
  28. </el-table-column>
  29. <el-table-column label="代理商上繳金額" prop="all" align="center">
  30. <template slot-scope="scope">
  31. <span :style="moneyColor(scope.row.all)">{{scope.row.all}}</span>
  32. </template>
  33. </el-table-column>
  34. <el-table-column label="抽水%" align="center">
  35. <template slot-scope="scope">
  36. {{scope.row.feeRatio2}}
  37. </template>
  38. </el-table-column>
  39. <el-table-column label="代理商上繳金額" prop="all" align="center">
  40. <template slot-scope="scope">
  41. <span :style="moneyColor(scope.row.all2)">{{scope.row.all2}}</span>
  42. </template>
  43. </el-table-column>
  44. <el-table-column label="上繳工作室金額70%" prop="all70" align="center">
  45. <template slot-scope="scope">
  46. <span :style="moneyColor(scope.row.all70)">{{scope.row.all70}}</span>
  47. </template>
  48. </el-table-column>
  49. <el-table-column label="總逞罰" prop="fredPunishment" align="center">
  50. <template slot-scope="scope">
  51. {{scope.row.fredPunishment}}
  52. </template>
  53. </el-table-column>
  54. <el-table-column align="center" label="操作">
  55. <template slot-scope="scope">
  56. <router-link to="/agent/index/gambleMemberManagement">
  57. <el-button type="primary" size="mini" icon="el-icon-tickets" @click="handlePage(scope.row)">會員管理</el-button>
  58. </router-link>
  59. </template>
  60. </el-table-column>
  61. </el-table>
  62. <div v-show="!listLoading" class="pagination-container">
  63. <!-- <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="listQuery.page"
  64. :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
  65. </el-pagination> -->
  66. </div>
  67. <el-dialog title="創建代理商" :visible.sync="dialogCreateFormVisible" :before-close="handleDialogClose" center>
  68. <el-form :rules="rules" ref="createForm" :model="createFormData" label-position="left" label-width="100px" style='width: 400px; margin-left:50px;'>
  69. <el-form-item label="名稱" prop="name">
  70. <el-input v-model="createFormData.name"></el-input>
  71. </el-form-item>
  72. <el-form-item label="抽水 % (代理商內)" prop="feeRatio">
  73. <el-input v-model="createFormData.feeRatio"></el-input>
  74. </el-form-item>
  75. <el-form-item label="抽水 % (只在列表顯示)" prop="feeRatio2">
  76. <el-input v-model="createFormData.feeRatio2"></el-input>
  77. </el-form-item>
  78. </el-form>
  79. <div slot="footer" class="dialog-footer">
  80. <el-button @click="handleDialogClose">取 消</el-button>
  81. <el-button type="primary" @click="createData">確 定</el-button>
  82. </div>
  83. </el-dialog>
  84. </div>
  85. <router-view></router-view>
  86. </div>
  87. </template>
  88. <script>
  89. import { mapGetters, mapActions } from 'vuex'
  90. import { fetchList, createAgent, fetchMemberList,fetchGroupAll } from '@/api/agnetManagement'
  91. import waves from '@/directive/waves' // 水波纹指令
  92. import moment from 'moment-timezone'
  93. import _ from 'lodash'
  94. import { Decimal } from 'decimal.js';
  95. export default {
  96. directives: {
  97. waves
  98. },
  99. data() {
  100. return {
  101. list: [],
  102. total: null,
  103. listLoading: true,
  104. downloadLoading: false,
  105. listQuery: {
  106. page: 1,
  107. limit: 9999999,
  108. name: ''
  109. // startAt: moment.utc(moment().day('sunday').hour(12).minute(0).second(0).subtract(1, 'weeks').day(7).hour(16).minute(0).second(0)).format(),
  110. // endAt: moment.utc(moment().day('sunday').hour(12).minute(0).second(0).day(7).hour(11).minute(59).second(59)).format()
  111. },
  112. filename: '',
  113. dialogCreateFormVisible: false,
  114. dialogStatus: '',
  115. // agent: {},
  116. rules: {
  117. // rewardChips: [{ pattern: /^-?\d+$/, required: true, message: '請輸入整數', trigger: 'change' }],
  118. // depositChips: [{ pattern: /^-?\d+$/, required: true, message: '請輸入整數', trigger: 'change' }],
  119. // chips: [{ pattern: /^(0|[1-9][0-9]*)$/, required: true, message: '請輸入整數', trigger: 'change' }],
  120. // name: [{ type: 'string', required: true, message: '必填', trigger: 'change' }]
  121. },
  122. createFormData: {
  123. name: '',
  124. feeRatio: '',
  125. feeRatio2: '',
  126. }
  127. }
  128. },
  129. created() {
  130. this.SetVisible(1)
  131. this.getList()
  132. },
  133. computed: {
  134. ...mapGetters([
  135. 'visible',
  136. 'data',
  137. ])
  138. },
  139. methods: {
  140. ...mapActions([
  141. 'SetVisible',
  142. 'SetData',
  143. ]),
  144. async getList() {
  145. this.listLoading = true
  146. fetchList(this.listQuery).then(async response => {
  147. // response.data.rows.map(agent => {
  148. for(const agent of response.data.rows) {
  149. let combine = []
  150. this.list = []
  151. if(this.visible.firstLayer === true) {
  152. fetchGroupAll(agent, this.listQuery).then(response => {
  153. console.log('response' , response.data)
  154. this.list.push({
  155. // id: agent.GambleMember.id,
  156. // GambleMember: {
  157. // id: agent.GambleMember.id,
  158. // name: agent.GambleMember.name
  159. // },
  160. id: agent.GambleMember.id,
  161. name: agent.GambleMember.name.slice(19),
  162. createdAt: agent.GambleMember.createdAt,
  163. feeRatio: response.data.feeRatio,
  164. feeRatio2: response.data.feeRatio2,
  165. all: response.data.all,
  166. all2: response.data.all2,
  167. all70: response.data.all70,
  168. fredPunishment: response.data.fredPunishment
  169. })
  170. })
  171. }
  172. // fetchMemberList(agent, this.listQuery).then(response => {
  173. // response.data.rows.map(member => {
  174. // let row = {
  175. // id: member.id,
  176. // name: member.name,
  177. // chips: member.chips,
  178. // totalUp: 0,
  179. // totalDown: 0,
  180. // totalReward: 0,
  181. // totalPunishment: 0,
  182. // bookieEarned: 0,
  183. // memberEarned: 0,
  184. // bookieWagerFee: 0,
  185. // bookieServiceFees: 0,
  186. // memberServiceFees: 0,
  187. // totalServiceFees: 0,
  188. // memberCheckOut: 0,
  189. // }
  190. // let bookie = _.groupBy(member['GambleGame-Bucket-MemberRecords'], 'isBookie')
  191. // if (bookie.false) {
  192. // row.memberEarned = _.sumBy(bookie.false, item => {
  193. // return Math.abs(item.earned)
  194. // });
  195. // row.memberServiceFees = _.sumBy(bookie.false, 'serviceFees')*agent.feeRatio/100;
  196. // }
  197. // if (bookie.true) {
  198. // row.bookieWagerFee = _.sumBy(bookie.true, (item) => {
  199. // return item.wagerServiceFees
  200. // }) * agent.feeRatio/100;
  201. // row.bookieEarned = _.sumBy(bookie.true, item => {
  202. // return Math.abs(item.earned)
  203. // });
  204. // row.bookieServiceFees = _.sumBy(bookie.true, (item) => { return item.serviceFees })*agent.feeRatio/100;
  205. // }
  206. // row.totalServiceFees = Number(new Decimal(row.bookieServiceFees).plus(row.memberServiceFees).plus(row.bookieWagerFee).valueOf())
  207. // let chipsLog = _.groupBy(member.GambleMemberChipsLogs, 'type')
  208. // if (chipsLog['0']) {
  209. // row.totalUp = _.sumBy(chipsLog['0'], (item) => {
  210. // return item.chips > 0 ? item.chips : 0
  211. // })
  212. // row.totalDown = _.sumBy(chipsLog['0'], (item) => {
  213. // return item.chips < 0 ? item.chips : 0
  214. // })
  215. // }
  216. // row.memberCheckOut = row.totalUp + row.totalDown - row.chips
  217. // if(chipsLog['1']) {
  218. // row.totalReward = _.sumBy(chipsLog['1'], (item) => {
  219. // return item.chips > 0 ? item.chips : 0
  220. // })
  221. // row.totalPunishment = _.sumBy(chipsLog['1'], (item) => {
  222. // return item.chips < 0 ? item.chips : 0
  223. // })
  224. // }
  225. // combine.push(row)
  226. // })
  227. // let allUp = _.sumBy(combine, 'totalUp')
  228. // let allDown = _.sumBy(combine, 'totalDown')
  229. // let allChips = _.sumBy(combine, 'chips')
  230. // let allEarned = _.sumBy(combine, (item) => {return item.bookieEarned + item.memberEarned})
  231. // let allServiceFees = _.sumBy(combine, (item) => {return item.totalServiceFees}).toFixed(2)
  232. // agent.all = (allUp+allDown-allChips-allServiceFees)*(-1)
  233. // this.list.push(agent)
  234. // this.listLoading = false
  235. // })
  236. // })
  237. }
  238. // this.total = response.data.count
  239. this.listLoading = false
  240. console.log('list', this.list)
  241. })
  242. },
  243. resetCreateData() {
  244. this.temp = {
  245. id: undefined,
  246. name: '',
  247. chips: '',
  248. depositChips: ''
  249. }
  250. },
  251. handleCreate() {
  252. this.resetCreateData()
  253. this.dialogCreateFormVisible = true
  254. this.$nextTick(() => {
  255. this.$refs['createForm'].clearValidate()
  256. })
  257. },
  258. createData() {
  259. this.$refs['createForm'].validate((valid) => {
  260. if (valid) {
  261. createAgent(this.createFormData).then((response) => {
  262. const agent = response.data.gambleAgentSetting;
  263. agent.GambleMember = response.data.agent
  264. this.list.unshift(agent)
  265. this.dialogCreateFormVisible = false
  266. this.$notify({
  267. title: '成功',
  268. message: '創建成功',
  269. type: 'success',
  270. duration: 2000
  271. })
  272. })
  273. }
  274. })
  275. },
  276. handleDownload() {
  277. this.downloadLoading = true
  278. import('@/vendor/Export2Excel').then(excel => {
  279. const tHeader = ['名稱', '抽水%', '代理商上繳金額', '上繳工作室金額70%' ]
  280. const filterVal = ['name', 'feeRatio', 'all', 'all70' ]
  281. const list = this.list
  282. const data = this.formatJson(filterVal, list)
  283. excel.export_json_to_excel(tHeader, data, this.filename)
  284. this.downloadLoading = false
  285. })
  286. },
  287. formatJson(filterVal, jsonData) {
  288. return jsonData.map(v => filterVal.map(j => {
  289. if (j === 'timestamp') {
  290. return parseTime(v[j])
  291. } else {
  292. return v[j]
  293. }
  294. }))
  295. },
  296. handleFilter() {
  297. this.listQuery.page = 1
  298. this.getList()
  299. },
  300. // handleSizeChange(val) {
  301. // this.listQuery.limit = val
  302. // this.getList()
  303. // },
  304. // handleCurrentChange(val) {
  305. // this.listQuery.page = val
  306. // this.getList()
  307. // },
  308. handleDialogClose() {
  309. this.dialogCreateFormVisible = false;
  310. },
  311. handlePage(row) {
  312. const temp = Object.assign({}, row) // copy obj
  313. this.SetVisible(2)
  314. this.SetData({layer:2, data: temp})
  315. // this.agent = temp
  316. },
  317. moneyColor(money) {
  318. return money >= 0 ? { color: '#67C23A' } : { color: '#FA5555' }
  319. },
  320. getSummaries(param) {
  321. let { columns, data } = param;
  322. let sums = [];
  323. data = data.filter(item => item.name !== '文')
  324. columns.forEach((column, index) => {
  325. if (index === 0) {
  326. sums[index] = '合計 ( 扣除文 ) ';
  327. return;
  328. }
  329. const values = data.map(item => Number(item[column.property]));
  330. if (!values.every(value => isNaN(value))) {
  331. sums[index] = values.reduce((prev, curr) => {
  332. const value = Number(curr);
  333. if (!isNaN(value)) {
  334. return new Decimal(prev).plus(curr);
  335. } else {
  336. return new Decimal(prev);
  337. }
  338. }, 0).valueOf();
  339. sums[index];
  340. } else {
  341. sums[index] = 'N/A';
  342. }
  343. });
  344. // this.allCombine.push({
  345. // name: (this.data.secondLayer.GambleMember.name).slice(19),
  346. // allUp: sums[2],
  347. // allDown: sums[3],
  348. // allChips: sums[1],
  349. // allEarned: sums[6],
  350. // allServiceFees: sums[13],
  351. // });
  352. // console.log('ewqewqeqweq', this.sums)
  353. return sums;
  354. }
  355. },
  356. }
  357. </script>