income.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. <template>
  2. <div class="m-container">
  3. <h2>
  4. <div class="squrt"></div>
  5. 订单管理
  6. </h2>
  7. <div class="m-core">
  8. <div
  9. class="newBand"
  10. @click="onOrderExport"
  11. v-permission="{ child: 'export/orderList', parent: '/income' }"
  12. >
  13. 报表导出
  14. </div>
  15. <!-- 搜索类型 -->
  16. <save-form
  17. :inline="true"
  18. class="searchForm"
  19. :model="searchForm"
  20. @submit="search"
  21. @reset="onReSet"
  22. >
  23. <el-form-item>
  24. <el-input
  25. placeholder="学生编号/姓名/手机号"
  26. type="text"
  27. clearable
  28. v-model.trim="searchForm.search"
  29. ></el-input>
  30. </el-form-item>
  31. <el-form-item>
  32. <el-input
  33. placeholder="交易流水号"
  34. clearable
  35. type="text"
  36. v-model.trim="searchForm.transNo"
  37. ></el-input>
  38. </el-form-item>
  39. <el-form-item>
  40. <el-input
  41. placeholder="订单号"
  42. clearable
  43. type="text"
  44. v-model.trim="searchForm.orderNo"
  45. ></el-input>
  46. </el-form-item>
  47. <el-form-item>
  48. <el-input
  49. placeholder="收款账户"
  50. clearable
  51. type="text"
  52. v-model.trim="searchForm.merNos"
  53. ></el-input>
  54. </el-form-item>
  55. <el-form-item>
  56. <el-input
  57. placeholder="余额支付大于等于"
  58. clearable
  59. type="number"
  60. @mousewheel.native.prevent
  61. v-model.trim="searchForm.balancePaymentAmount"
  62. ></el-input>
  63. </el-form-item>
  64. <el-form-item>
  65. <el-input
  66. placeholder="现金支付大于等于"
  67. clearable
  68. type="number"
  69. @mousewheel.native.prevent
  70. v-model.trim="searchForm.actualAmount"
  71. ></el-input>
  72. </el-form-item>
  73. <el-form-item>
  74. <el-input
  75. placeholder="余额支付小于等于"
  76. clearable
  77. type="number"
  78. @mousewheel.native.prevent
  79. v-model.trim="searchForm.lessBalancePaymentAmount"
  80. ></el-input>
  81. </el-form-item>
  82. <el-form-item>
  83. <el-input
  84. placeholder="现金支付小于等于"
  85. clearable
  86. type="number"
  87. @mousewheel.native.prevent
  88. v-model.trim="searchForm.lessActualAmount"
  89. ></el-input>
  90. </el-form-item>
  91. <el-form-item prop="organId">
  92. <el-select
  93. class="multiple"
  94. v-model.trim="searchForm.organId"
  95. filterable
  96. clearable
  97. @clear="onClear('organId')"
  98. placeholder="请选择分部"
  99. >
  100. <el-option
  101. v-for="(item, index) in selects.branchs"
  102. :key="index"
  103. :label="item.name"
  104. :value="item.id"
  105. ></el-option>
  106. </el-select>
  107. </el-form-item>
  108. <el-form-item>
  109. <el-date-picker
  110. v-model="searchForm.orderDate"
  111. style="width: 410px"
  112. type="daterange"
  113. value-format="yyyy-MM-dd"
  114. range-separator="至"
  115. :picker-options="{
  116. firstDayOfWeek: 1,
  117. }"
  118. start-placeholder="订单开始日期"
  119. end-placeholder="订单结束日期"
  120. ></el-date-picker>
  121. </el-form-item>
  122. <el-form-item>
  123. <el-select
  124. v-model.trim="searchForm.paymentType"
  125. clearable
  126. filterable
  127. @clear="onClear('paymentType')"
  128. placeholder="交易类型"
  129. >
  130. <el-option
  131. v-for="(item, index) in orderStatus"
  132. :key="index"
  133. :label="item.label"
  134. :value="item.value"
  135. ></el-option>
  136. </el-select>
  137. </el-form-item>
  138. <el-form-item>
  139. <el-select
  140. v-model.trim="searchForm.paymentStatus"
  141. clearable
  142. filterable
  143. @clear="onClear('paymentStatus')"
  144. placeholder="交易状态"
  145. >
  146. <el-option
  147. v-for="(item, index) in dealStatus"
  148. :key="index"
  149. :label="item.label"
  150. :value="item.value"
  151. ></el-option>
  152. </el-select>
  153. </el-form-item>
  154. <el-form-item>
  155. <el-button native-type="submit" type="danger">搜索</el-button>
  156. <el-button native-type="reset" type="primary">重置</el-button>
  157. </el-form-item>
  158. </save-form>
  159. <!-- 列表 -->
  160. <!-- totalUserBalance: 20452784.02
  161. totalExpectAmount: 0
  162. totalActualAmount: 0
  163. totalAdvanceAmount: 0
  164. totalRevenueAmount: 0 -->
  165. <div style="font-size: 14px; color: #f85043; padding-bottom: 10px">
  166. <!-- 应收总金额:{{ totalExpectAmount }}元 &nbsp;&nbsp;&nbsp;&nbsp;
  167. 现金实收总额:{{ totalActualAmount }}元 &nbsp;&nbsp;&nbsp;&nbsp;
  168. 余额实收总额:{{ Number((totalExpectAmount - totalActualAmount).toFixed(2)) }}元 -->
  169. <!-- 营收金额=2-3
  170. 实收金额=应收总额(包含余额支付)
  171. 预收金额=充值总额(发生消费,记负数)
  172. 预收余额=充值总余额 -->
  173. 营收金额:{{ totalRevenueAmount | moneyFormat }}元<i
  174. style="width: 10px; display: inline-block"
  175. ></i>
  176. 实收金额:{{ totalActualAmount | moneyFormat }}元<i
  177. style="width: 10px; display: inline-block"
  178. ></i>
  179. 预收金额:{{ totalAdvanceAmount | moneyFormat }}元<i
  180. style="width: 10px; display: inline-block"
  181. ></i>
  182. 预收余额:{{ totalUserBalance | moneyFormat }}元
  183. </div>
  184. <div class="tableWrap">
  185. <el-table
  186. :data="tableList"
  187. :header-cell-style="{ background: '#EDEEF0', color: '#444' }"
  188. >
  189. <el-table-column
  190. align="center"
  191. prop="transNo"
  192. label="所属分部"
  193. >
  194. <template slot-scope="scope">
  195. <div>
  196. <copy-text>{{ scope.row.organName }}</copy-text>
  197. </div>
  198. </template>
  199. </el-table-column>
  200. <el-table-column
  201. align="center"
  202. width="180px"
  203. prop="transNo"
  204. label="交易流水号"
  205. >
  206. <template slot-scope="scope">
  207. <div>
  208. <copy-text>{{ scope.row.transNo }}</copy-text>
  209. </div>
  210. </template>
  211. </el-table-column>
  212. <el-table-column
  213. align="center"
  214. width="210px"
  215. prop="orderNo"
  216. label="订单号"
  217. >
  218. <template slot-scope="scope">
  219. <div>
  220. <copy-text>{{ scope.row.orderNo }}</copy-text>
  221. </div>
  222. </template>
  223. </el-table-column>
  224. <el-table-column
  225. align="center"
  226. width="150"
  227. prop="createTime"
  228. label="订单日期"
  229. >
  230. <template slot-scope="scope">{{
  231. scope.row.createTime | dateForMinFormat
  232. }}</template>
  233. </el-table-column>
  234. <el-table-column align="center" width="100px" label="交易类型">
  235. <template slot-scope="scope">{{
  236. scope.row.type | orderType
  237. }}</template>
  238. </el-table-column>
  239. <el-table-column align="center" prop="expectAmount" label="应付金额">
  240. <template slot-scope="scope">
  241. <div>
  242. {{ scope.row.expectAmount | moneyFormat }}
  243. </div>
  244. </template>
  245. </el-table-column>
  246. <el-table-column
  247. align="center"
  248. prop="balancePaymentAmount"
  249. label="余额支付"
  250. >
  251. <template slot-scope="scope">
  252. <div>
  253. {{ scope.row.balancePaymentAmount | moneyFormat }}
  254. </div>
  255. </template>
  256. </el-table-column>
  257. <el-table-column align="center" prop="actualAmount" label="现金支付">
  258. <template slot-scope="scope">
  259. <div>
  260. {{ scope.row.actualAmount | moneyFormat }}
  261. </div>
  262. </template>
  263. </el-table-column>
  264. <el-table-column align="center" label="学员姓名">
  265. <template slot-scope="scope">
  266. <copy-text> {{ scope.row.user.username }}</copy-text>
  267. <span v-if="scope.row.user.username && scope.row.user.phone"
  268. >/</span
  269. >
  270. <copy-text>
  271. {{ scope.row.user.phone }}
  272. </copy-text>
  273. </template>
  274. </el-table-column>
  275. <el-table-column
  276. align="center"
  277. prop="paymentChannel"
  278. label="交易方式"
  279. >
  280. <template slot-scope="scope">{{
  281. scope.row.paymentChannel | paymentChannelStatus
  282. }}</template>
  283. </el-table-column>
  284. <!-- <el-table-column align="center"
  285. label="收款账户">
  286. <template slot-scope="scope">{{ scope.row.merNos }}</template>
  287. </el-table-column> -->
  288. <el-table-column align="center" label="交易状态">
  289. <template slot-scope="scope">{{
  290. scope.row.status | dealStatus
  291. }}</template>
  292. </el-table-column>
  293. <el-table-column align="center" label="备注">
  294. <template slot-scope="scope">{{
  295. scope.row.memo ? scope.row.memo : "-"
  296. }}</template>
  297. </el-table-column>
  298. <el-table-column align="center" width="150px" label="操作">
  299. <template slot-scope="scope">
  300. <el-button
  301. v-if="
  302. scope.row.status != 'SUCCESS' && scope.row.actualAmount > 0
  303. "
  304. v-permission="'order/getOrderStatus'"
  305. @click="onGetOrderStatus(scope.row)"
  306. type="text"
  307. >查询订单状态</el-button
  308. >
  309. </template>
  310. </el-table-column>
  311. </el-table>
  312. <pagination
  313. sync
  314. :total.sync="pageInfo.total"
  315. :page.sync="pageInfo.page"
  316. :limit.sync="pageInfo.limit"
  317. :page-sizes="pageInfo.page_size"
  318. @pagination="getList"
  319. />
  320. </div>
  321. </div>
  322. </div>
  323. </template>
  324. <script>
  325. import pagination from "@/components/Pagination/index";
  326. import { orderQueryPage, getOrderStatus } from "@/api/orderManager";
  327. import { getEmployeeOrgan } from "@/api/buildTeam";
  328. import store from "@/store";
  329. import cleanDeep from "clean-deep";
  330. import { orderStatus, dealStatus } from "@/utils/searchArray";
  331. import axios from "axios";
  332. import qs from "qs";
  333. import { getToken } from "@/utils/auth";
  334. import load from "@/utils/loading";
  335. import { getTimes } from "@/utils";
  336. export default {
  337. components: { pagination },
  338. name: "income",
  339. data() {
  340. return {
  341. orderStatus: orderStatus,
  342. dealStatus: dealStatus,
  343. searchForm: {
  344. search: null,
  345. orderStartDate: null,
  346. orderEndDate: null,
  347. paymentStatus: "SUCCESS",
  348. paymentType: null,
  349. organId: null,
  350. actualAmount: null,
  351. balancePaymentAmount: null,
  352. orderNo: null,
  353. transNo: null,
  354. merNos: null,
  355. lessBalancePaymentAmount: null,
  356. lessActualAmount: null,
  357. orderDate: [],
  358. },
  359. tableList: [],
  360. organList: [],
  361. pageInfo: {
  362. // 分页规则
  363. limit: 10, // 限制显示条数
  364. page: 1, // 当前页
  365. total: 0, // 总条数
  366. page_size: [10, 20, 40, 50], // 选择限制显示条数
  367. },
  368. totalUserBalance: 0,
  369. totalActualAmount: 0,
  370. totalAdvanceAmount: 0,
  371. totalRevenueAmount: 0,
  372. };
  373. },
  374. created(){
  375. if (this.searchForm.orderDate?.length < 1) {
  376. var now = new Date();
  377. var startDate = new Date(
  378. Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())
  379. )
  380. .toISOString()
  381. .slice(0, 10);
  382. // + " 00:00:00" + " 23:59:59"
  383. var endDate = new Date(
  384. Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())
  385. )
  386. .toISOString()
  387. .slice(0, 10);
  388. this.searchForm.orderDate = [];
  389. this.searchForm.orderDate.push(startDate);
  390. this.searchForm.orderDate.push(endDate);
  391. }
  392. },
  393. mounted() {
  394. this.$store.dispatch("setBranchs");
  395. this.getList();
  396. },
  397. methods: {
  398. onClear(type) {
  399. if (type == "paymentType") {
  400. this.searchForm.paymentType = null;
  401. } else if (type == "paymentStatus") {
  402. this.searchForm.paymentStatus = null;
  403. } else if (type == "organId") {
  404. this.searchForm.organId = null;
  405. }
  406. },
  407. onOrderExport() {
  408. // 报表导出
  409. let url = "/api-web/export/orderList";
  410. let searchForm = this.searchForm;
  411. let data = {
  412. orderType: 0,
  413. search: searchForm.search,
  414. orderNo: searchForm.orderNo,
  415. transNo: searchForm.transNo,
  416. merNos: searchForm.merNos,
  417. actualAmount: searchForm.actualAmount,
  418. balancePaymentAmount: searchForm.balancePaymentAmount,
  419. paymentStatus: searchForm.paymentStatus,
  420. paymentType: searchForm.paymentType,
  421. organId: searchForm.organId,
  422. lessBalancePaymentAmount: searchForm.lessBalancePaymentAmount,
  423. lessActualAmount: searchForm.lessActualAmount,
  424. };
  425. if (this.searchForm.orderDate && this.searchForm.orderDate.length > 0) {
  426. data.orderStartDate = this.searchForm.orderDate[0];
  427. data.orderEndDate = this.searchForm.orderDate[1];
  428. } else {
  429. data.orderStartDate = null;
  430. data.orderEndDate = null;
  431. }
  432. const options = {
  433. method: "POST",
  434. headers: {
  435. Authorization: getToken(),
  436. },
  437. data: qs.stringify(cleanDeep(data)),
  438. url,
  439. responseType: "blob",
  440. };
  441. this.$confirm("您确定导出报表", "提示", {
  442. confirmButtonText: "确定",
  443. cancelButtonText: "取消",
  444. type: "warning",
  445. })
  446. .then(() => {
  447. load.startLoading();
  448. axios(options)
  449. .then((res) => {
  450. let blob = new Blob([res.data], {
  451. // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
  452. type: "application/vnd.ms-excel;charset=utf-8",
  453. //word文档为application/msword,pdf文档为application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
  454. });
  455. let text = new Response(blob).text();
  456. text.then((res) => {
  457. // 判断是否报错
  458. if (res.indexOf("code") != -1) {
  459. let json = JSON.parse(res);
  460. this.$message.error(json.msg);
  461. } else {
  462. let objectUrl = URL.createObjectURL(blob);
  463. let link = document.createElement("a");
  464. let nowTime = new Date();
  465. let ymd =
  466. nowTime.getFullYear() +
  467. "" +
  468. (nowTime.getMonth() + 1) +
  469. "" +
  470. nowTime.getDate() +
  471. "" +
  472. nowTime.getHours() +
  473. "" +
  474. nowTime.getMinutes();
  475. let fname = "报表导出" + new Date().getTime()+'.xls'; //下载文件的名字
  476. link.href = objectUrl;
  477. link.setAttribute("download", fname);
  478. document.body.appendChild(link);
  479. link.click();
  480. }
  481. });
  482. load.endLoading();
  483. })
  484. .catch((error) => {
  485. this.$message.error("导出数据失败,请联系管理员");
  486. load.endLoading();
  487. });
  488. })
  489. .catch(() => {});
  490. },
  491. search() {
  492. this.pageInfo.page = 1;
  493. this.getList();
  494. },
  495. getList() {
  496. let { orderDate, ...rest } = this.searchForm;
  497. let params = {
  498. ...rest,
  499. page: this.pageInfo.page,
  500. rows: this.pageInfo.limit,
  501. ...getTimes(orderDate, ["orderStartDate", "orderEndDate"]),
  502. };
  503. // let params = JSON.parse(JSON.stringify(this.searchForm));
  504. // params.rows = this.pageInfo.limit;
  505. // params.page = this.pageInfo.page;
  506. // params.orderNo = params.orderNo ? params.orderNo : null;
  507. // params.transNo = params.transNo ? params.transNo : null;
  508. // params.merNos = params.merNos ? params.merNos : null;
  509. // params.actualAmount = params.actualAmount ? params.actualAmount : null;
  510. // params.balancePaymentAmount = params.balancePaymentAmount
  511. // ? params.balancePaymentAmount
  512. // : null;
  513. // if (this.orderDate && this.orderDate.length > 0) {
  514. // params.orderStartDate = this.orderDate[0];
  515. // params.orderEndDate = this.orderDate[1];
  516. // } else {
  517. // params.orderStartDate = null;
  518. // params.orderEndDate = null;
  519. // }
  520. orderQueryPage(cleanDeep(params)).then((res) => {
  521. let result = res.data;
  522. if (res.code == 200) {
  523. this.tableList = result.rows;
  524. this.pageInfo.total = result.total;
  525. this.totalUserBalance = result.totalUserBalance
  526. ? result.totalUserBalance
  527. : 0;
  528. this.totalActualAmount = result.totalActualAmount
  529. ? result.totalActualAmount
  530. : 0;
  531. this.totalAdvanceAmount = result.totalAdvanceAmount
  532. ? result.totalAdvanceAmount
  533. : 0;
  534. this.totalRevenueAmount = result.totalRevenueAmount
  535. ? result.totalRevenueAmount
  536. : 0;
  537. }
  538. });
  539. },
  540. onGetOrderStatus(row) {
  541. this.$confirm("您确定查询该订单状态", "提示", {
  542. confirmButtonText: "确定",
  543. cancelButtonText: "取消",
  544. type: "warning",
  545. })
  546. .then(() => {
  547. getOrderStatus({ id: row.id }).then((res) => {
  548. this.getList();
  549. });
  550. })
  551. .catch((err) => {});
  552. },
  553. onReSet() {
  554. // 重置搜索
  555. this.searchForm = {
  556. search: null,
  557. orderStartDate: null,
  558. orderEndDate: null,
  559. paymentStatus: null,
  560. paymentType: null,
  561. organId: null,
  562. actualAmount: null,
  563. balancePaymentAmount: null,
  564. orderNo: null,
  565. transNo: null,
  566. merNos: null,
  567. lessBalancePaymentAmount: null,
  568. lessActualAmount: null,
  569. orderDate:[]
  570. };
  571. this.getList();
  572. },
  573. },
  574. };
  575. </script>
  576. <style lang="scss">
  577. </style>