bean-withdraw.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. <template>
  2. <div class="page-box" v-loading="loading > 0">
  3. <Header :title="title"></Header>
  4. <div class="container">
  5. <div class="content">
  6. <!-- 表格 -->
  7. <div class="filter-box">
  8. <div class="filter">
  9. <div class="filter-item">
  10. <div class="label">审核状态</div>
  11. <el-select
  12. v-model="filter.status"
  13. size="small"
  14. class="select"
  15. placeholder="请选择"
  16. >
  17. <el-option
  18. v-for="item in statusType"
  19. :key="item.value"
  20. :label="item.name"
  21. :value="item.value"
  22. >
  23. </el-option>
  24. </el-select>
  25. </div>
  26. <!-- <div class="filter-item">
  27. <div class="label">审核状态</div>
  28. <el-select
  29. v-model="filter.way"
  30. size="small"
  31. class="select"
  32. placeholder="请选择"
  33. >
  34. <el-option
  35. v-for="item in wayType"
  36. :key="item.value"
  37. :label="item.name"
  38. :value="item.value"
  39. >
  40. </el-option>
  41. </el-select>
  42. </div> -->
  43. <div class="filter-item">
  44. <div class="label">用户ID:</div>
  45. <el-input
  46. class="input"
  47. v-model="filter.uid"
  48. placeholder="请输入内容"
  49. size="small"
  50. ></el-input>
  51. </div>
  52. <div class="filter-item">
  53. <div class="label">用户姓名:</div>
  54. <el-input
  55. class="input"
  56. style="width: 200px"
  57. v-model="filter.name"
  58. placeholder="请输入内容"
  59. size="small"
  60. ></el-input>
  61. </div>
  62. <div class="filter-item">
  63. <div class="label">创建时间:</div>
  64. <el-date-picker
  65. v-model="date"
  66. type="datetimerange"
  67. align="right"
  68. unlink-panels
  69. class="date-input"
  70. range-separator="至"
  71. start-placeholder="开始日期"
  72. end-placeholder="结束日期"
  73. value-format="yyyy-MM-dd HH:mm:ss"
  74. :default-time="['00:00:00', '23:59:59']"
  75. size="small"
  76. >
  77. </el-date-picker>
  78. </div>
  79. </div>
  80. <div class="btn-box">
  81. <button class="search" @click="search">筛选</button>
  82. <button class="reset" @click="reset">重置</button>
  83. </div>
  84. </div>
  85. <!-- <div class="filter-box filter-box2">
  86. <div class="btn-box btn-box2">
  87. <button class="search" @click="batchAuditBeanWithdraw(1)">通过</button>
  88. <button class="reset" @click="batchAuditBeanWithdraw(2)">驳回</button>
  89. </div>
  90. <div class="btn-box btn-box2">
  91. <button class="search" @click="order2excel">一键到账</button>
  92. <button class="reset" @click="order2excel">导出</button>
  93. </div>
  94. </div> -->
  95. <el-table
  96. :data="list"
  97. class="table no-border-table"
  98. ref="table"
  99. :header-cell-style="{
  100. border: 'none',
  101. color: '#333',
  102. background: '#f6f6f6',
  103. borderBottom: '1px solid #E8E8E8',
  104. height: '54px',
  105. }"
  106. :row-style="{
  107. height: '54px',
  108. }"
  109. @selection-change="handleSelectionChange"
  110. >
  111. <!-- <el-table-column type="selection" width="55" :selectable="selectable">
  112. </el-table-column> -->
  113. <el-table-column prop="created" align="center" label="提审时间">
  114. <div slot-scope="scope">
  115. {{ scope.row.created | dateFormat }}
  116. </div>
  117. </el-table-column>
  118. <el-table-column
  119. prop="uid"
  120. align="center"
  121. label="用户ID"
  122. ></el-table-column>
  123. <el-table-column
  124. prop="balance"
  125. align="center"
  126. label="变现金豆数量"
  127. ></el-table-column>
  128. <el-table-column prop="actualBalance" align="center" label="到账金额/元">
  129. <!-- <div slot-scope="scope">
  130. {{ statusMap[scope.row.status] }}
  131. </div> -->
  132. </el-table-column>
  133. <el-table-column
  134. prop="nickname"
  135. align="center"
  136. label="用户昵称"
  137. ></el-table-column>
  138. <el-table-column prop="oid" align="center" label="审核状态">
  139. <div slot-scope="scope">
  140. {{ statusMap[scope.row.status] }}
  141. </div></el-table-column
  142. >
  143. <el-table-column label="操作" align="center" width="300">
  144. <div
  145. slot-scope="scope"
  146. style="display: flex; justify-content: center"
  147. >
  148. <div
  149. style="display: flex; justify-content: center"
  150. v-if="scope.row.status === 1"
  151. >
  152. <button
  153. size="mini"
  154. class="table-btn"
  155. @click="passBeanWithdraw(scope.row.id)"
  156. >
  157. 通过
  158. </button>
  159. </div>
  160. <div
  161. style="display: flex; justify-content: center"
  162. v-if="scope.row.status === 1"
  163. >
  164. <button
  165. size="mini"
  166. class="table-btn"
  167. @click="refuteBeanWithdraw(scope.row.id)"
  168. >
  169. 驳回
  170. </button>
  171. </div>
  172. <div style="display: flex; justify-content: center">
  173. <button
  174. size="mini"
  175. class="table-btn"
  176. @click="toDetail(scope.row.id)"
  177. >
  178. 查看
  179. </button>
  180. </div>
  181. <div
  182. style="display: flex; justify-content: center"
  183. v-if="scope.row.status === 4"
  184. >
  185. <button
  186. size="mini"
  187. class="table-btn"
  188. @click="refuteBeanWithdraw(scope.row.id)"
  189. >
  190. 待驳回
  191. </button>
  192. </div>
  193. </div>
  194. </el-table-column>
  195. </el-table>
  196. </div>
  197. <!-- 分页按钮 -->
  198. <div class="footer">
  199. <el-pagination
  200. @current-change="handleCurrentChange"
  201. :current-page.sync="currentPage"
  202. background
  203. layout="total, prev, pager, next, jumper"
  204. :page-size="size"
  205. :total="total"
  206. ></el-pagination>
  207. </div>
  208. </div>
  209. <el-dialog
  210. title="提现详情"
  211. :visible.sync="detailShow"
  212. class="dialog"
  213. width="640px"
  214. top="25vh"
  215. >
  216. <div class="detail-box">
  217. <div class="detail-right">
  218. <div class="row row1">提现金额/元:{{ detail.balance }}</div>
  219. <div class="row row1">到账金额/元:{{ detail.actualBalance }}</div>
  220. <div class="row">
  221. <div class="label">ID:</div>
  222. {{ detail.uid }}
  223. </div>
  224. <div class="row">
  225. <div class="label">提现方式:</div>
  226. <!-- {{ wayMap[detail.way] }} -->
  227. 银行卡
  228. </div>
  229. <!-- <div v-if="detail.way === 1">
  230. <div class="row">
  231. <div class="label">姓名:</div>
  232. {{ detail.name }}
  233. </div>
  234. <div class="row">
  235. <div class="label">收款码:</div>
  236. <el-image
  237. class="img"
  238. style="width: 100px;height: 100px"
  239. :src="detail.wx_pic"
  240. fit="cover"
  241. :preview-src-list="[detail.wx_pic]"
  242. >
  243. </el-image>
  244. </div>
  245. </div>
  246. <div v-if="detail.way === 2">
  247. <div class="row">
  248. <div class="label">姓名:</div>
  249. {{ detail.name }}
  250. </div>
  251. <div class="row">
  252. <div class="label">收款码:</div>
  253. <el-image
  254. class="img"
  255. style="width: 100px;height: 100px"
  256. :src="detail.zfb_pic"
  257. fit="cover"
  258. :preview-src-list="[detail.zfb_pic]"
  259. >
  260. </el-image>
  261. </div>
  262. </div> -->
  263. <div>
  264. <div class="row">
  265. <div class="label">银行卡号:</div>
  266. {{ detail.card }}
  267. </div>
  268. <div class="row">
  269. <div class="label">开户银行:</div>
  270. {{ detail.openBank }}
  271. </div>
  272. <div class="row">
  273. <div class="label">姓名:</div>
  274. {{ detail.cardName }}
  275. </div>
  276. </div>
  277. </div>
  278. <div class="detail-left">
  279. <div class="row">
  280. <div class="label">审核状态:</div>
  281. {{ statusMap[detail.status] || "" }}
  282. </div>
  283. <!-- <div class="row">
  284. <div class="label">提现状态:</div>
  285. {{ wayMap[detail.way] || "" }}
  286. </div> -->
  287. <div class="row">
  288. <div class="label">创建时间:</div>
  289. {{ detail.created }}
  290. </div>
  291. <div class="row">
  292. <div class="label">审核时间:</div>
  293. {{ detail.auditTime }}
  294. </div>
  295. <!-- <div class="row">
  296. <div class="label">到账时间:</div>
  297. {{ detail.arrivalTime }}
  298. </div> -->
  299. </div>
  300. </div>
  301. </el-dialog>
  302. <el-dialog
  303. :show-close="false"
  304. :close-on-click-modal="false"
  305. title="生成中..."
  306. :visible.sync="showProgressDialog"
  307. width="30%"
  308. center
  309. >
  310. <el-progress
  311. :percentage="progress"
  312. :text-inside="true"
  313. :stroke-width="18"
  314. ></el-progress>
  315. </el-dialog>
  316. </div>
  317. </template>
  318. <script type="text/ecmascript-6">
  319. import Header from '../../components/common/header';
  320. import myUtils from '../../components/common/whatever2excel';
  321. import dayjs from 'dayjs';
  322. export default {
  323. components: {
  324. Header
  325. },
  326. name: 'user-manage',
  327. data() {
  328. return {
  329. currentPage: 1, // 当前页码
  330. size: 20, // 每页条数
  331. total: 0, // 总页数
  332. loading: 0, // 加载中
  333. title: {
  334. // 页面标题
  335. firstTitile: '资金管理',
  336. secondTitle: '金豆提现记录'
  337. },
  338. filter: {
  339. uid: null,
  340. status: 0,
  341. name: ''
  342. },
  343. statusType: [
  344. {
  345. name: '全部',
  346. value: 0
  347. },
  348. {
  349. name: '提现申请待审核(资金已冻结) ',
  350. value: 1
  351. },
  352. {
  353. name: '提现审核通过,待发放',
  354. value: 2
  355. },
  356. {
  357. name: '提现审核驳回',
  358. value: 3
  359. },
  360. {
  361. name: '发放失败,等待撤销',
  362. value: 4
  363. },
  364. {
  365. name: '发放失败,已撤销',
  366. value: 5
  367. },
  368. {
  369. name: '提现已发放',
  370. value: 6
  371. }
  372. ],
  373. wayType: [
  374. {
  375. name: '全部',
  376. value: -1
  377. },
  378. {
  379. name: '提现申请待审核(资金已冻结) ',
  380. value: 1
  381. },
  382. {
  383. name: '提现审核通过,待发放',
  384. value: 2
  385. },
  386. {
  387. name: '提现审核驳回',
  388. value: 3
  389. },
  390. {
  391. name: '发放失败,等待撤销',
  392. value: 4
  393. },
  394. {
  395. name: '发放失败,已撤销',
  396. value: 5
  397. },
  398. {
  399. name: '提现已发放',
  400. value: 6
  401. }
  402. ],
  403. statusMap: {
  404. 1: '提现申请待审核(资金已冻结) ',
  405. 2: '提现审核通过,待发放',
  406. 3: '提现审核驳回',
  407. 4: '发放失败,等待撤销',
  408. 5: '发放失败,已撤销',
  409. 6: '提现已发放'
  410. },
  411. wayMap: {
  412. 1: '微信',
  413. 2: '支付宝',
  414. 3: '银行卡'
  415. },
  416. list: [], // 用户列表
  417. date: [],
  418. showProgressDialog: false,
  419. progress: 0,
  420. multipleSelection: [],
  421. detailShow: false,
  422. detail: {}
  423. };
  424. },
  425. filters: {
  426. // 时间格式化
  427. dateFormat(date) {
  428. if (!date) return '请选择时间';
  429. let day = dayjs(date);
  430. return day.format('YYYY-MM-DD HH:mm:ss');
  431. }
  432. },
  433. async mounted() {
  434. // await this.getType();
  435. // 获取列表
  436. this.getList();
  437. },
  438. computed: {},
  439. methods: {
  440. // 切换页码
  441. handleCurrentChange(page) {
  442. this.multipleSelection = [];
  443. this.currentPage = page;
  444. this.getList();
  445. },
  446. selectable(row, index) {
  447. if (row.status === 1) return true;
  448. return false;
  449. },
  450. handleSelectionChange(val) {
  451. this.multipleSelection = val;
  452. },
  453. // 获取提现列表
  454. getList() {
  455. this.multipleSelection = [];
  456. this.filter.start = this.date[0] || '';
  457. this.filter.end = this.date[1] || '';
  458. this.loading++;
  459. this.httpGet(this.$root.getBeanWithdrawList, {
  460. page: this.currentPage,
  461. size: this.size,
  462. ...this.filter
  463. }).then(
  464. (res) => {
  465. this.loading--;
  466. this.list = res.list;
  467. this.total = res.total;
  468. },
  469. (res) => {
  470. this.loading--;
  471. this.$message.error(res);
  472. }
  473. );
  474. },
  475. // 过滤
  476. search() {
  477. this.currentPage = 1;
  478. this.multipleSelection = [];
  479. this.getList();
  480. },
  481. // 重置过滤
  482. reset() {
  483. this.filter = { uid: null, status: 0, name: '' };
  484. this.date = [];
  485. this.multipleSelection = [];
  486. this.getList();
  487. },
  488. toDetail(id) {
  489. // this.detail = detail;
  490. this.loading++;
  491. this.httpGet(this.$root.getBeanWithdrawInfo, {
  492. id
  493. }).then(
  494. (res) => {
  495. this.loading--;
  496. this.detail = res;
  497. this.detailShow = true;
  498. },
  499. (res) => {
  500. this.loading--;
  501. this.$message.error(res);
  502. }
  503. );
  504. },
  505. passBeanWithdraw(id) {
  506. this.$confirm(
  507. `<p class='title'><i class='icon el-icon-question'></i>提醒</p><p class='text'>确定要通过该审核吗?</p>`,
  508. {
  509. confirmButtonText: '确定',
  510. cancelButtonText: '取消',
  511. cancelButtonClass: 'cancel-btn',
  512. confirmButtonClass: 'confirm-btn',
  513. customClass: 'confirm-box',
  514. dangerouslyUseHTMLString: true,
  515. showClose: false,
  516. type: 'none'
  517. }
  518. ).then(() => {
  519. this.loading++;
  520. this.httpPut(this.$root.passBeanWithdraw, {
  521. id
  522. }).then(
  523. (res) => {
  524. this.$message({
  525. message: '操作成功',
  526. type: 'success'
  527. });
  528. this.loading--;
  529. this.getList();
  530. },
  531. (res) => {
  532. this.loading--;
  533. this.$message.error(res);
  534. }
  535. );
  536. });
  537. },
  538. refuteBeanWithdraw(id) {
  539. this.$confirm(
  540. `<p class='title'><i class='icon el-icon-question'></i>提醒</p><p class='text'>确定要驳回该审核吗?</p>`,
  541. {
  542. confirmButtonText: '确定',
  543. cancelButtonText: '取消',
  544. cancelButtonClass: 'cancel-btn',
  545. confirmButtonClass: 'confirm-btn',
  546. customClass: 'confirm-box',
  547. dangerouslyUseHTMLString: true,
  548. showClose: false,
  549. type: 'none'
  550. }
  551. ).then(() => {
  552. this.loading++;
  553. this.httpPut(this.$root.refuteBeanWithdraw, {
  554. id
  555. }).then(
  556. (res) => {
  557. this.$message({
  558. message: '操作成功',
  559. type: 'success'
  560. });
  561. this.loading--;
  562. this.getList();
  563. },
  564. (res) => {
  565. this.loading--;
  566. this.$message.error(res);
  567. }
  568. );
  569. });
  570. },
  571. batchAuditBeanWithdraw(status) {
  572. console.log(this.multipleSelection);
  573. if (!this.multipleSelection.length) {
  574. this.$message.error('请选择记录');
  575. return;
  576. }
  577. let str = '通过';
  578. if (status === 2) str = '驳回';
  579. this.$confirm(
  580. `<p class='title'><i class='icon el-icon-question'></i>提醒</p><p class='text'>确定要${str}该审核吗?</p>`,
  581. {
  582. confirmButtonText: '确定',
  583. cancelButtonText: '取消',
  584. cancelButtonClass: 'cancel-btn',
  585. confirmButtonClass: 'confirm-btn',
  586. customClass: 'confirm-box',
  587. dangerouslyUseHTMLString: true,
  588. showClose: false,
  589. type: 'none'
  590. }
  591. ).then(() => {
  592. this.loading++;
  593. this.httpPut(this.$root.batchAuditBeanWithdraw, {
  594. way: status,
  595. id: this.multipleSelection.map((item) => {
  596. return item.id;
  597. })
  598. }).then(
  599. (res) => {
  600. this.$message({
  601. message: '操作成功',
  602. type: 'success'
  603. });
  604. this.loading--;
  605. this.multipleSelection = [];
  606. this.getList();
  607. },
  608. (res) => {
  609. this.loading--;
  610. this.$message.error(res);
  611. }
  612. );
  613. });
  614. },
  615. async order2excel() {
  616. this.loading++;
  617. let list = [];
  618. let totalPage = null;
  619. let data = {
  620. page: this.currentPage,
  621. size: this.size,
  622. ...this.filter
  623. };
  624. await this.httpGet(this.$root.getBeanWithdrawList, data).then(
  625. (res) => {
  626. this.loading--;
  627. totalPage = Math.ceil(parseInt(res.total) / this.size);
  628. },
  629. () => {
  630. this.loading--;
  631. }
  632. );
  633. this.showProgressDialog = true;
  634. this.progress = 0;
  635. await this.getAllPages(totalPage, list).then(
  636. () => {
  637. this.showProgressDialog = false;
  638. this.jsonFormatAndToExcel(list);
  639. },
  640. (err) => {
  641. console.error(err);
  642. this.showProgressDialog = false;
  643. }
  644. );
  645. },
  646. async getAllPages(totalPage, list) {
  647. for (let i = 1; i <= totalPage; i++) {
  648. let data = {
  649. page: i,
  650. size: this.size,
  651. ...this.filter
  652. };
  653. await this.httpGet(this.$root.getBeanWithdrawList, data).then((res) => {
  654. list.push(...res.list);
  655. this.progress = Math.floor((i / totalPage) * 100);
  656. console.log('page' + i, list.length);
  657. });
  658. // console.log(5555, list);
  659. }
  660. },
  661. jsonFormatAndToExcel(list) {
  662. let formatList = [];
  663. list.forEach((item) => {
  664. let obj = {
  665. 用户ID: item.uid,
  666. 提现金额: item.balance,
  667. 身份证号: item.identityCard,
  668. 审核状态: this.statusMap[item.status],
  669. 提现状态: this.wayMap[item.way],
  670. 创建时间: item.created,
  671. 审核时间: item.auditTime,
  672. 到账时间: item.arrivalTime
  673. };
  674. formatList.push(obj);
  675. });
  676. myUtils.json2excel(formatList);
  677. }
  678. }
  679. };
  680. </script>
  681. <style lang="stylus" rel="stylesheet/stylus">
  682. @import '~assets/public.styl';
  683. </style>
  684. <style lang="stylus" rel="stylesheet/stylus" scoped>
  685. @import '~assets/main.styl';
  686. .page-box {
  687. height: 100%;
  688. width: 100%;
  689. flex-y(flex-start, flex-start);
  690. overflow-y: hidden;
  691. background: bg-color;
  692. .container {
  693. box-sizing: border-box;
  694. height: 100%;
  695. width: 100%;
  696. overflow-y: auto;
  697. flex-y(flex-start, flex-start);
  698. padding: 10px;
  699. // content 表格
  700. .content {
  701. flex: 1;
  702. width: 100%;
  703. font-size: 14px;
  704. background: white;
  705. box-sizing: border-box;
  706. padding: 24px 32px;
  707. border-radius: 2px;
  708. .filter-box2 {
  709. flex-x();
  710. .btn-box {
  711. width: auto;
  712. }
  713. }
  714. // 按钮
  715. .btn {
  716. width: 100px;
  717. height: 32px;
  718. line-height: 32px;
  719. confirm-btn();
  720. font-size: 14px;
  721. margin: 16px 0;
  722. }
  723. .import {
  724. flex-x(flex-end);
  725. margin-top: 16px;
  726. .import-btn {
  727. confirm-btn();
  728. height: 32px;
  729. padding: 0 15px;
  730. white-space: nowrap;
  731. }
  732. }
  733. // 表格按钮
  734. .table-btn {
  735. // width: 65px;
  736. height: 24px;
  737. line-height: 24px;
  738. color: gray3;
  739. font-size: 12px;
  740. margin-right: 8px;
  741. cancel-btn();
  742. padding: 0 8px;
  743. }
  744. .filter-item {
  745. margin-right: 12px;
  746. }
  747. .select, .input {
  748. width: 120px;
  749. }
  750. .date-input {
  751. width: 350px;
  752. }
  753. .btn-box {
  754. margin: 0;
  755. }
  756. .btn-box2 {
  757. width: 100%;
  758. flex-x(flex-start);
  759. margin-top: 8px;
  760. .search {
  761. width: 108px;
  762. }
  763. }
  764. .table {
  765. margin-top: 24px !important;
  766. }
  767. }
  768. }
  769. .footer {
  770. width: 100%;
  771. padding: 24px;
  772. box-sizing: border-box;
  773. flex-x(flex-end);
  774. background: white;
  775. word(14px, #999);
  776. span {
  777. word(20px, #333);
  778. font-weight: 600;
  779. margin-left: 3px;
  780. }
  781. }
  782. .dialog-content {
  783. flex-y();
  784. }
  785. .form {
  786. width: 100%;
  787. flex-center();
  788. margin: 8px 0;
  789. }
  790. .detail-box {
  791. padding: 0 16px 16px;
  792. flex-x(flex-start, flex-start);
  793. .detail-right, .detail-left {
  794. flex: 1;
  795. .row {
  796. width: 100%;
  797. line-height: 32px;
  798. word(14px, #333);
  799. flex-x(flex-start);
  800. .label {
  801. width: 72px;
  802. word(14px, #666);
  803. }
  804. }
  805. .row1 {
  806. word(16px, #333);
  807. }
  808. }
  809. }
  810. }
  811. </style>