bills.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. <template>
  2. <basic-container>
  3. <avue-crud :option="option"
  4. :table-loading="loading"
  5. :data="data"
  6. :page.sync="page"
  7. :permission="permissionList"
  8. :before-open="beforeOpen"
  9. v-model="form"
  10. ref="crud"
  11. @row-update="rowUpdate"
  12. @row-save="rowSave"
  13. @row-del="rowDel"
  14. @search-change="searchChange"
  15. @search-reset="searchReset"
  16. @selection-change="selectionChange"
  17. @current-change="currentChange"
  18. @size-change="sizeChange"
  19. @refresh-change="refreshChange"
  20. @on-load="onLoad">
  21. <template slot-scope="{type,size}" slot="createTimeSearch">
  22. <el-radio-group v-model="query.createTime" :size="size" style="float: left">
  23. <el-radio-button @click="searchStateChange" :label="-1">全部</el-radio-button>
  24. <el-radio-button @click="searchStateChange" :label="1">今天</el-radio-button>
  25. <el-radio-button @click="searchStateChange" :label="2">昨天</el-radio-button>
  26. <el-radio-button @click="searchStateChange" :label="3">最近七天</el-radio-button>
  27. <el-radio-button @click="searchStateChange" :label="4">最近30天</el-radio-button>
  28. <el-radio-button @click="searchStateChange" :label="5">本月</el-radio-button>
  29. <el-radio-button @click="searchStateChange" :label="6">本年</el-radio-button>
  30. </el-radio-group>
  31. <avue-date v-model="query.createTimeRange" type="datetimerange" format="yyyy年MM月dd日 hh:mm:ss"
  32. value-format="yyyy-MM-dd hh:mm:ss" placeholder="请选择日期"
  33. :size="size"
  34. @change="searchStateChange"
  35. style="width: 280px;margin-left:5px;float: left"
  36. range-separator="-"
  37. start-placeholder="开始日期"
  38. end-placeholder="结束日期"></avue-date>
  39. </template>
  40. <template slot-scope="{type,size}" slot="typeSearch">
  41. <el-radio-group v-model="query.type" :size="size" @change="searchStateChange">
  42. <el-radio-button :label="select.value" v-for="(select,index) in option.column.find(ele=>{
  43. return ele.prop==='type';
  44. }).dicData" :key="index">{{ select.label }}
  45. </el-radio-button>
  46. </el-radio-group>
  47. </template>
  48. <template slot-scope="{type,size}" slot="payStatusSearch">
  49. <el-radio-group v-model="query.payStatus" :size="size" @change="searchStateChange">
  50. <el-radio-button :label="select.value" v-for="(select,index) in option.column.find(ele=>{
  51. return ele.prop==='payStatus';
  52. }).dicData" :key="index">{{ select.label }}
  53. </el-radio-button>
  54. </el-radio-group>
  55. </template>
  56. <template slot-scope="{type,size}" slot="keySearch">
  57. <el-input type="text" placeholder="订单ID" v-model="query.key" :size="size"
  58. style="width: 300px;margin: 1px 5px 1px 0;">
  59. <el-button type="primary" :size="size" icon="el-icon-search" slot="append"
  60. @click="searchStateChange"></el-button>
  61. </el-input>
  62. <el-button type="primary" :size="size" icon="el-icon-top" @click="generateListAndDownload">生成列表</el-button>
  63. <!-- <el-button type="primary" :size="size">导出已生成列表</el-button>-->
  64. </template>
  65. <template slot="menuLeft">
  66. <avue-data-panel :option="censusOption"></avue-data-panel>
  67. </template>
  68. <!-- <template slot-scope="scope" slot="dataInfo">-->
  69. <!-- <div v-if="scope.row.payStatus==='付款成功'">-->
  70. <!-- 优惠金额:-->
  71. <!-- <div-->
  72. <!-- style="background-color: #0baaee;color: white; border-radius: 5px; margin:10px; padding:0 10px 0 10px ; display:inline;">-->
  73. <!-- {{parseFloat(scope.row.totalPrice-scope.row.price).toFixed(2)}}-->
  74. <!-- </div>-->
  75. <!-- </div>-->
  76. <!-- </template>-->
  77. </avue-crud>
  78. </basic-container>
  79. </template>
  80. <script>
  81. import {getList, censusPrice, getDetail, add, update, remove, generateList} from "@/api/ldt_bills/bills";
  82. import {mapGetters} from "vuex";
  83. import moment from "moment";
  84. import FileUtil from "@/util/fileUtil";
  85. export default {
  86. data() {
  87. return {
  88. form: {},
  89. query: {
  90. createTime: -1,
  91. createTimeRange: [],
  92. payStatus: -1,
  93. type: -1,
  94. },
  95. loading: true,
  96. page: {
  97. pageSize: 10,
  98. currentPage: 1,
  99. total: 0
  100. },
  101. selectionList: [],
  102. option: {
  103. height: 'auto',
  104. calcHeight: 30,
  105. tip: false,
  106. searchShow: true,
  107. searchMenuSpan: 6,
  108. border: true,
  109. index: true,
  110. addBtn: false,
  111. delBtn: false,
  112. editBtn: false,
  113. viewBtn: true,
  114. selection: true,
  115. searchBtn: false,
  116. emptyBtn: false,
  117. dialogClickModal: false,
  118. column: [
  119. {
  120. label: "付款方",
  121. prop: "payId",
  122. hide: true,
  123. rules: [{
  124. required: true,
  125. message: "请输入付款方",
  126. trigger: "blur"
  127. }]
  128. },
  129. /*{
  130. prop: "dataInfo",
  131. slot: true,
  132. width: 250,
  133. display: false,
  134. label: "数据统计"
  135. },*/
  136. {
  137. label: "付款方",
  138. prop: "payerName",
  139. rules: [{
  140. required: true,
  141. message: "请输入付款方",
  142. trigger: "blur"
  143. }]
  144. },
  145. {
  146. label: "收款方",
  147. hide: true,
  148. prop: "receiveId",
  149. rules: [{
  150. required: true,
  151. message: "请输入收款方",
  152. trigger: "blur"
  153. }]
  154. },
  155. {
  156. label: "收款方",
  157. prop: "receiverName",
  158. rules: [{
  159. required: true,
  160. message: "请输入收款方",
  161. trigger: "blur"
  162. }]
  163. },
  164. {
  165. label: "金额原价",
  166. prop: "cost",
  167. rules: [{
  168. required: true,
  169. message: "请输入金额原价",
  170. trigger: "blur"
  171. }]
  172. },
  173. {
  174. label: "折扣",
  175. prop: "discount",
  176. hide: true,
  177. rules: [{
  178. required: true,
  179. message: "请输入折扣",
  180. trigger: "blur"
  181. }]
  182. },
  183. {
  184. label: "实付金额",
  185. prop: "price",
  186. rules: [{
  187. required: true,
  188. message: "请输入实付金额",
  189. trigger: "blur"
  190. }]
  191. },
  192. {
  193. label: "总金额",
  194. prop: "totalPrice",
  195. rules: [{
  196. required: true,
  197. message: "请输入实付金额",
  198. trigger: "blur"
  199. }]
  200. },
  201. {
  202. label: "交易类型",
  203. prop: "type",
  204. search: true,
  205. searchSpan: 24,
  206. searchslot: true,
  207. searchOrder: 1,
  208. dicData: [{
  209. label: "全部",
  210. value: -1
  211. }, {
  212. label: "用户付款",
  213. value: "USER_PAY"
  214. }, {
  215. label: "代理充值",
  216. value: "AGENT_CHARGE"
  217. }, {
  218. label: "微信充值",
  219. value: "WECHAT_PAY"
  220. }, {
  221. label: "商家充值",
  222. value: "MALL_RECHARGE"
  223. }],
  224. rules: [{
  225. required: true,
  226. message: "请输入交易类型(用户付款,代理充值,商场充值)",
  227. trigger: "blur"
  228. }]
  229. },
  230. {
  231. label: "付款方式",
  232. prop: "payway",
  233. rules: [{
  234. required: true,
  235. message: "请输入付款方式",
  236. trigger: "blur"
  237. }]
  238. },
  239. {
  240. label: "付款插件",
  241. prop: "payPlugin",
  242. hide: true,
  243. rules: [{
  244. required: true,
  245. message: "请输入付款插件",
  246. trigger: "blur"
  247. }]
  248. },
  249. {
  250. label: "渠道积分id",
  251. prop: "channelId",
  252. hide: true,
  253. rules: [{
  254. required: true,
  255. message: "请输入渠道积分id",
  256. trigger: "blur"
  257. }]
  258. },
  259. {
  260. label: "支付状态",
  261. prop: "payStatus",
  262. type: "select",
  263. search: true,
  264. searchSpan: 24,
  265. searchslot: true,
  266. searchOrder: 2,
  267. dicData: [{
  268. label: "全部",
  269. value: -1
  270. }, {
  271. label: "待付款",
  272. value: "待付款"
  273. }, {
  274. label: "付款成功",
  275. value: "付款成功"
  276. }, {
  277. label: "已完结",
  278. value: "已完结"
  279. }, {
  280. label: "取消付款",
  281. value: "取消付款"
  282. }],
  283. rules: [{
  284. required: true,
  285. message: "请输入待付款,付款成功,取消付款",
  286. trigger: "blur"
  287. }]
  288. },
  289. {
  290. label: "订单标题",
  291. prop: "title",
  292. rules: [{
  293. required: true,
  294. message: "请输入订单标题",
  295. trigger: "blur"
  296. }]
  297. },
  298. {
  299. label: "订单描述",
  300. prop: "billDesc",
  301. hide: true,
  302. rules: [{
  303. required: true,
  304. message: "请输入订单描述",
  305. trigger: "blur"
  306. }]
  307. },
  308. {
  309. label: "订单超时时间",
  310. prop: "exTime",
  311. hide: true,
  312. rules: [{
  313. required: true,
  314. message: "请输入订单超时时间",
  315. trigger: "blur"
  316. }]
  317. },
  318. {
  319. label: "appid",
  320. prop: "appid",
  321. hide: true,
  322. rules: [{
  323. required: true,
  324. message: "请输入appid",
  325. trigger: "blur"
  326. }]
  327. },
  328. {
  329. label: "openid",
  330. prop: "openid",
  331. hide: true,
  332. rules: [{
  333. required: true,
  334. message: "请输入openid",
  335. trigger: "blur"
  336. }]
  337. },
  338. {
  339. label: "消耗积分",
  340. prop: "pointNum",
  341. rules: [{
  342. required: true,
  343. message: "请输入消耗积分",
  344. trigger: "blur"
  345. }]
  346. },
  347. {
  348. label: "消耗余额",
  349. prop: "balanceNum",
  350. rules: [{
  351. required: true,
  352. message: "请输入消耗余额",
  353. trigger: "blur"
  354. }]
  355. },
  356. {
  357. label: "第三方平台订单号",
  358. prop: "thirdOrderId",
  359. hide: true,
  360. rules: [{
  361. required: true,
  362. message: "请输入第三方平台订单号",
  363. trigger: "blur"
  364. }]
  365. },
  366. {
  367. label: "收取的服务费",
  368. prop: "fee",
  369. rules: [{
  370. required: true,
  371. message: "请输入收取的服务费",
  372. trigger: "blur"
  373. }]
  374. },
  375. {
  376. label: "积分交易费",
  377. prop: "pointFee",
  378. rules: [{
  379. required: true,
  380. message: "请输入积分交易费",
  381. trigger: "blur"
  382. }]
  383. },
  384. {
  385. label: "创建时间",
  386. prop: "createTime",
  387. type: "datetime",
  388. format: "yyyy-MM-dd hh:mm:ss",
  389. valueFormat: "yyyy-MM-dd hh:mm:ss",
  390. searchRange: true,
  391. addDisplay: false,
  392. editDisplay: false,
  393. search: true,
  394. searchSpan: 24,
  395. searchOrder: 0,
  396. searchslot: true,
  397. rules: [{
  398. required: true,
  399. message: "请输入通知时间",
  400. trigger: "blur"
  401. }]
  402. },
  403. {
  404. label: "关键字",
  405. prop: "key",
  406. hide: true,
  407. search: true,
  408. searchslot: true,
  409. searchOrder: 5,
  410. searchSpan: 24,
  411. editDisplay: false,
  412. },
  413. ]
  414. },
  415. data: [],
  416. censusOption: {
  417. span: 8,
  418. data: [
  419. {
  420. title: '用户付款',
  421. prop: "USER_PAY",
  422. count: 0,
  423. decimals: 2,
  424. icon: 'el-icon-message',
  425. color: '#00a7d0',
  426. },
  427. {
  428. title: '代理充值',
  429. prop: "AGENT_CHARGE",
  430. count: 0,
  431. decimals: 2,
  432. icon: 'el-icon-info',
  433. color: 'rgb(27, 201, 142)',
  434. },
  435. {
  436. title: '商场充值',
  437. prop: "MALL_RECHARGE",
  438. count: 0,
  439. decimals: 2,
  440. icon: 'el-icon-success',
  441. color: 'rgb(230, 71, 88)',
  442. }
  443. ]
  444. }
  445. };
  446. },
  447. computed: {
  448. ...mapGetters(["permission"]),
  449. permissionList() {
  450. return {
  451. addBtn: this.vaildData(this.permission.bills_add, false),
  452. viewBtn: this.vaildData(this.permission.bills_view, false),
  453. delBtn: this.vaildData(this.permission.bills_delete, false),
  454. editBtn: this.vaildData(this.permission.bills_edit, false)
  455. };
  456. },
  457. ids() {
  458. let ids = [];
  459. this.selectionList.forEach(ele => {
  460. ids.push(ele.id);
  461. });
  462. return ids.join(",");
  463. }
  464. },
  465. watch: {
  466. //监听创建时间变化
  467. "query.createTime": {
  468. handler(value) {
  469. //防止重复调用
  470. if (value !== undefined) {
  471. this.query.createTimeRange = [];
  472. switch (value) {
  473. case -1:
  474. this.query.createTimeStart = undefined;
  475. this.query.createTimeEnd = undefined;
  476. break;
  477. case 1: //今天
  478. this.query.createTimeStart = moment().format("yyyy-MM-DD 00:00:00");
  479. this.query.createTimeEnd = moment().format("yyyy-MM-DD HH:mm:ss");
  480. break;
  481. case 2: //昨天
  482. this.query.createTimeStart = moment().subtract(1, 'days').format("yyyy-MM-DD 00:00:00");
  483. this.query.createTimeEnd = moment().subtract(1, 'days').format("yyyy-MM-DD 23:59:59");
  484. break;
  485. case 3: //近7天
  486. this.query.createTimeStart = moment().subtract(7, 'days').format("yyyy-MM-DD HH:mm:ss");
  487. this.query.createTimeEnd = moment().format("yyyy-MM-DD HH:mm:ss");
  488. break;
  489. case 4: //近30天
  490. this.query.createTimeStart = moment().subtract(30, 'days').format("yyyy-MM-DD HH:mm:ss");
  491. this.query.createTimeEnd = moment().format("yyyy-MM-DD HH:mm:ss");
  492. break;
  493. case 5: //本月
  494. this.query.createTimeStart = moment().format("yyyy-MM-01 00:00:00");
  495. this.query.createTimeEnd = moment().format(`yyyy-MM-DD HH:mm:ss`);
  496. break;
  497. case 6: //本年
  498. this.query.createTimeStart = moment().format("yyyy-01-01 00:00:00");
  499. this.query.createTimeEnd = moment().format(`yyyy-MM-DD HH:mm:ss`);
  500. break;
  501. default:
  502. break;
  503. }
  504. }
  505. }
  506. },
  507. //监听创建时间变化
  508. "query.createTimeRange": {
  509. handler(value) {
  510. //防止重复调用
  511. if (value.length === 2) {
  512. this.query.createTimeStart = value[0];
  513. this.query.createTimeEnd = value[1];
  514. this.query.createTime = undefined;
  515. }
  516. }
  517. },
  518. },
  519. created() {
  520. this.getCensusPrice();
  521. },
  522. methods: {
  523. rowSave(row, done, loading) {
  524. add(row).then(() => {
  525. this.onLoad(this.page);
  526. this.$message({
  527. type: "success",
  528. message: "操作成功!"
  529. });
  530. done();
  531. }, error => {
  532. loading();
  533. window.console.log(error);
  534. });
  535. },
  536. rowUpdate(row, index, done, loading) {
  537. update(row).then(() => {
  538. this.onLoad(this.page);
  539. this.$message({
  540. type: "success",
  541. message: "操作成功!"
  542. });
  543. done();
  544. }, error => {
  545. loading();
  546. console.log(error);
  547. });
  548. },
  549. rowDel(row) {
  550. this.$confirm("确定将选择数据删除?", {
  551. confirmButtonText: "确定",
  552. cancelButtonText: "取消",
  553. type: "warning"
  554. })
  555. .then(() => {
  556. return remove(row.id);
  557. })
  558. .then(() => {
  559. this.onLoad(this.page);
  560. this.$message({
  561. type: "success",
  562. message: "操作成功!"
  563. });
  564. });
  565. },
  566. handleDelete() {
  567. if (this.selectionList.length === 0) {
  568. this.$message.warning("请选择至少一条数据");
  569. return;
  570. }
  571. this.$confirm("确定将选择数据删除?", {
  572. confirmButtonText: "确定",
  573. cancelButtonText: "取消",
  574. type: "warning"
  575. })
  576. .then(() => {
  577. return remove(this.ids);
  578. })
  579. .then(() => {
  580. this.onLoad(this.page);
  581. this.$message({
  582. type: "success",
  583. message: "操作成功!"
  584. });
  585. this.$refs.crud.toggleSelection();
  586. });
  587. },
  588. beforeOpen(done, type) {
  589. if (["edit", "view"].includes(type)) {
  590. getDetail(this.form.id).then(res => {
  591. this.form = res.data.data;
  592. });
  593. }
  594. done();
  595. },
  596. searchReset() {
  597. this.query = {};
  598. this.onLoad(this.page);
  599. },
  600. searchChange(params, done) {
  601. this.query = params;
  602. this.page.currentPage = 1;
  603. this.onLoad(this.page, params);
  604. done();
  605. },
  606. selectionChange(list) {
  607. this.selectionList = list;
  608. },
  609. selectionClear() {
  610. this.selectionList = [];
  611. this.$refs.crud.toggleSelection();
  612. },
  613. currentChange(currentPage) {
  614. this.page.currentPage = currentPage;
  615. },
  616. sizeChange(pageSize) {
  617. this.page.pageSize = pageSize;
  618. },
  619. refreshChange() {
  620. this.onLoad(this.page, this.query);
  621. },
  622. onLoad(page, params = {}) {
  623. let values = {
  624. ...params,
  625. };
  626. values.createTime = null;
  627. values.createTimeRange = null;
  628. this.loading = true;
  629. getList(page.currentPage, page.pageSize, values).then(res => {
  630. const data = res.data.data;
  631. this.page.total = data.total;
  632. this.data = data.records;
  633. this.loading = false;
  634. this.selectionClear();
  635. });
  636. },
  637. getCensusPrice() {
  638. censusPrice().then(res => {
  639. res.data.data.forEach(ele => {
  640. this.censusOption.data.find(ele2=>{
  641. return ele2.prop === ele.type;
  642. }).count = ele.price;
  643. })
  644. });
  645. // <span style="font-family: '宋体'">
  646. // 用户付款总额:
  647. // <span style="background-color: #8c70b6;color: white; border-radius: 5px; margin:10px; padding:0 10px 0 10px ;">
  648. // {{parseFloat(parseFloat(censusPrice.USER_PAY!==undefined?censusPrice.USER_PAY:0) + parseFloat(censusPrice.WECHAT_PAY!==undefined?censusPrice.WECHAT_PAY:0)).toFixed(2)}}
  649. // </span>
  650. // </span>&nbsp;
  651. // <span type="warning" style="font-family: '宋体'">
  652. // 代理充值总额:
  653. // <span style="background-color: #a9c985;color: white; border-radius: 5px; margin:10px; padding:0 10px 0 10px ;">
  654. // {{parseFloat(censusPrice.AGENT_CHARGE!==undefined?censusPrice.AGENT_CHARGE:0).toFixed(2)}}
  655. // </span>
  656. // </span>&nbsp;
  657. // <span type="info" style="font-family: '宋体'">
  658. // 商场充值总额:
  659. // <span style="background-color: #d50e71;color: white; border-radius: 5px; margin:10px; padding:0 10px 0 10px ;">
  660. // {{parseFloat(censusPrice.MALL_RECHARGE!==undefined?censusPrice.MALL_RECHARGE:0).toFixed(2)}}
  661. // </span>
  662. // </span>
  663. },
  664. //搜索状态改变
  665. searchStateChange() {
  666. setTimeout(() => {
  667. const newQuery = {};
  668. this.page.currentPage = 1;
  669. for (const item in this.query) {
  670. if (this.query[item] !== undefined && this.query[item] !== -1) {
  671. newQuery[item] = this.query[item];
  672. }
  673. }
  674. this.onLoad(this.page, newQuery);
  675. }, 100);
  676. },
  677. //生成列表并到处
  678. generateListAndDownload() {
  679. const newQuery = {};
  680. for (const item in this.query) {
  681. if (this.query[item] !== undefined && this.query[item] !== -1) {
  682. newQuery[item] = this.query[item];
  683. }
  684. }
  685. newQuery.createTime = null;
  686. newQuery.createTimeRange = null;
  687. //获取列表键值对
  688. newQuery.keyValue = {};
  689. this.option.column.forEach(ele => {
  690. newQuery.keyValue[ele.prop] = ele.label;
  691. });
  692. newQuery.keyValue = JSON.stringify(newQuery.keyValue);
  693. this.loading = true;
  694. //生成列表
  695. generateList(this.page.currentPage, this.page.pageSize, newQuery).then(res => {
  696. FileUtil.download(res.data, {
  697. type: "application/vnd.ms-excel"
  698. }, `生成付款账单-${moment().format("yyyy-MM-DD HH:mm:ss")}.xls`);
  699. }).finally(() => {
  700. this.loading = false;
  701. });
  702. },
  703. }
  704. };
  705. </script>
  706. <style>
  707. </style>