order.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('com-export-dialog', '@backend/views/components/common');
  4. ?>
  5. <div id="app" v-cloak>
  6. <el-card shadow="never" style="border:0;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  7. <div slot="header">
  8. <div>
  9. <span>开卡记录列表</span>
  10. <el-form size="small" :inline="true" style="float: right;margin-top: -5px;">
  11. <el-form-item>
  12. <com-export-dialog :field_list='exportList' :action_url="export_url" :params="searchData" @selected="exportConfirm"></com-export-dialog>
  13. </el-form-item>
  14. </el-form>
  15. </div>
  16. </div>
  17. <div class="table-body">
  18. 卡号:
  19. <div class="input-item">
  20. <el-input @keyup.enter.native="search" size="small" placeholder="请输入卡号" v-model="searchData.order_no" clearable @clear="search"></el-input>
  21. </div>
  22. 次卡名称:
  23. <div class="input-item">
  24. <el-input @keyup.enter.native="search" size="small" placeholder="请输入次卡名称" v-model="searchData.secondary_card_name" clearable @clear="search"></el-input>
  25. </div>
  26. 开卡方式:
  27. <el-select size="small" v-model="searchData.open_type" @change='search' class="select" style="float:none;width: 140px;">
  28. <el-option key="0" label="全部" value="0"></el-option>
  29. <el-option key="1" label="下单购买" value="1"></el-option>
  30. <el-option key="2" label="兑换码兑换" value="2"></el-option>
  31. </el-select>
  32. 选择日期:
  33. <el-date-picker
  34. size="small"
  35. v-model="searchData.date_time"
  36. type="datetimerange"
  37. range-separator="至"
  38. start-placeholder="开始时间"
  39. end-placeholder="结束时间"
  40. value-format="yyyy-MM-dd HH:mm:ss"
  41. >
  42. </el-date-picker>
  43. <div style="display: inline-block;margin-left: 10px;">
  44. <el-button type="primary" size="small" @click="search">查询</el-button>
  45. <el-button type="primary" size="small" @click="resetForm" style=" margin-left: 0px;background-color: #ef1818;border-color: #ef1818;">重置</el-button>
  46. </div>
  47. </div>
  48. <div class="table-body">
  49. <template>
  50. <el-table ref="multipleTable" :data="list" @sort-change="sortChange">
  51. <!-- 空数据 -->
  52. <template slot="empty">
  53. <el-empty description="暂无数据"></el-empty>
  54. </template>
  55. <el-table-column prop="user_id" label="会员ID" align="center"></el-table-column>
  56. <el-table-column label="开卡用户" width="200">
  57. <template slot-scope="scope">
  58. <div class="user_img" flex="cross:center">
  59. <el-image class="default-avatar" :src="scope.row.avatar_url">
  60. <div slot="error" class="image-slot">
  61. <com-image src="resources/img/mall/default_avatar_url.png"></com-image>
  62. </div>
  63. </el-image>
  64. <div class="uer-nickname over1" v-if="scope.row.nickname">{{scope.row.nickname}}
  65. <br/>{{scope.row.mobile}}
  66. </div>
  67. <div class="uer-nickname over1" v-else >ID:{{scope.row.user_id}}</div>
  68. </div>
  69. </template>
  70. </el-table-column>
  71. <el-table-column prop="order_no" label="卡号" align="center" width="200"></el-table-column>
  72. <el-table-column prop="clerk_code" label="核销码" align="center" width="150"></el-table-column>
  73. <el-table-column prop="verifiable_times" label="可核销次数" align="center" width="100"></el-table-column>
  74. <el-table-column prop="order_status" label="次卡状态" align="center">
  75. <template slot-scope="scope">
  76. {{order_status_list[scope.row.order_status] }}
  77. </template>
  78. </el-table-column>
  79. <el-table-column label="开卡时间" align="center" prop="open_time" width="200" sortable="open_time">
  80. <template slot-scope="scope">
  81. {{scope.row.open_time|dateTimeFormat('Y-m-d H:i:s')}}
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="open_type" label="开卡方式" align="center" width="100">
  85. <template slot-scope="scope">
  86. {{open_type_map[scope.row.open_type]}}
  87. </template>
  88. </el-table-column>
  89. <el-table-column prop="pay_money" label="购卡实收金额" align="center" width="200" sortable="pay_money"></el-table-column>
  90. <el-table-column prop="expire_time" label="到期时间" align="center" width="200" sortable="expire_time">
  91. <template slot-scope="scope">
  92. {{scope.row.expire_time|dateTimeFormat('Y-m-d H:i:s')}}
  93. </template>
  94. </el-table-column>
  95. <el-table-column prop="refund_money" label="退款金额" align="center">
  96. <template slot-scope="scope">
  97. <div v-if="scope.row.refund_money ==0">
  98. -
  99. </div>
  100. <div v-else>
  101. {{scope.row.refund_money}}
  102. </div>
  103. </template>
  104. </el-table-column>
  105. <el-table-column prop="refund_time" label="退款时间" align="center" width="200" sortable="refund_time">
  106. <template slot-scope="scope">
  107. {{scope.row.refund_time|dateTimeFormat('Y-m-d H:i:s')}}
  108. </template>
  109. </el-table-column>
  110. <el-table-column align="center" label="操作" width="200">
  111. <template slot-scope="scope">
  112. <el-button @click="toUseLog(scope.row.order_no)" type="text" size="small">使用记录</el-button>
  113. <el-button @click="changeOrderStatus(scope.row.id,4)" type="text" size="small" v-if="scope.row.order_status==0">停卡</el-button>
  114. <el-button @click="changeOrderStatus(scope.row.id,0)" type="text" size="small" v-if="scope.row.order_status==4">恢复</el-button>
  115. <el-button @click="openRefund(scope.row)" type="text" size="small" v-if="scope.row.order_status==2 && scope.row.pay_money>0 && scope.row.verifiable_times>0">退款</el-button>
  116. </template>
  117. </el-table-column>
  118. </el-table>
  119. </template>
  120. <!-- 分页 -->
  121. <el-row type="flex" class="page" justify="end">
  122. <el-pagination @current-change="pagination" background layout="prev, pager, next" :page-count="pageCount" v-if="list"></el-pagination>
  123. </el-row>
  124. </div>
  125. <el-dialog title="次卡退款确认" :visible.sync="dialogContent" >
  126. <el-form :model="codeForm" :rules="codeRules" ref="codeForm">
  127. <el-form-item label="退款卡号:" :label-width="formLabelWidth">
  128. <el-input v-model="codeForm.order_no" :readonly="true" :disabled="true"></el-input>
  129. </el-form-item>
  130. <el-form-item label="开卡用户:" :label-width="formLabelWidth">
  131. <el-input v-model="codeForm.nickname" :readonly="true" :disabled="true"></el-input>
  132. </el-form-item>
  133. <el-form-item label="退款金额:" :label-width="formLabelWidth" prop="refund_money">
  134. <el-input-number v-model="codeForm.refund_money" controls-position="right" :min="0" :max="100000"></el-input-number>
  135. </el-form-item>
  136. </el-form>
  137. <div slot="footer" class="dialog-footer">
  138. <el-button @click="dialogContent = false">取 消</el-button>
  139. <el-button type="primary" @click="postAdd('codeForm')" :loading="codeFormLoading">确 定</el-button>
  140. </div>
  141. </el-dialog>
  142. </div>
  143. </el-card>
  144. </div>
  145. <script>
  146. const app = new Vue({
  147. el: '#app',
  148. data() {
  149. return {
  150. loading: false,
  151. list: [],
  152. searchData: {
  153. secondary_card_name: '',
  154. secondary_card_id: '',
  155. order_no: '',
  156. open_type: '0',
  157. date_time: '',
  158. user_id: '',
  159. },
  160. pageCount: 0,
  161. page: 1,
  162. currentPage: null,
  163. listLoading: false,
  164. type: '',
  165. sort: '',
  166. order_status_list: {
  167. '0': "待核销",
  168. '1': "已失效",
  169. '2': "已过期",
  170. '3': "已退款",
  171. '4': "已停卡",
  172. },
  173. open_type_map:{
  174. '1': "下单购买",
  175. '2': "兑换码兑换",
  176. },
  177. exportList: {},
  178. export_url: 'secondary-card/default/order',
  179. dialogContent:false,
  180. codeForm:{
  181. id:'',
  182. refund_money:'',
  183. order_no:'',
  184. nickname:'',
  185. },
  186. codeRules: {
  187. refund_money: [
  188. { required: true, message: '请输入添加兑换码数量', trigger: 'blur' },
  189. ],
  190. },
  191. formLabelWidth: '150px',
  192. codeFormLoading:false,
  193. };
  194. },
  195. created() {
  196. this.searchData.secondary_card_name = getQuery('secondary_card_name')
  197. this.searchData.secondary_card_id = getQuery('secondary_card_id')
  198. this.searchData.order_no = getQuery('order_no')
  199. this.searchData.user_id = getQuery('user_id')
  200. },
  201. methods: {
  202. exportConfirm(){},
  203. sortChange( column, prop, order){
  204. this.sort_order = column.order;
  205. this.sort_column = column.prop;
  206. this.loadData();
  207. },
  208. search() {
  209. this.page = 1;
  210. this.loadData();
  211. },
  212. pagination(currentPage) {
  213. this.page = currentPage;
  214. this.loadData();
  215. },
  216. loadData() {
  217. this.listLoading = true;
  218. var param = {
  219. r: 'secondary-card/default/order',
  220. page: this.page,
  221. order_no: this.searchData.order_no,
  222. secondary_card_name: this.searchData.secondary_card_name,
  223. secondary_card_id: this.searchData.secondary_card_id,
  224. open_type: this.searchData.open_type,
  225. date_time: this.searchData.date_time,
  226. user_id: this.searchData.user_id,
  227. sort_column:this.sort_column,
  228. sort_order:this.sort_order,
  229. sort: this.sort,
  230. limit: 15
  231. }
  232. request({
  233. params: param,
  234. }).then(e => {
  235. if (e.data.code === 0) {
  236. this.list = e.data.data.list;
  237. this.exportList = e.data.data.export_list;
  238. this.pageCount = e.data.data.page_count;
  239. this.currentPage = e.data.data.pagination.current_page;
  240. } else {
  241. this.$message.error(e.data.msg);
  242. }
  243. this.listLoading = false;
  244. }).catch(e => {
  245. this.listLoading = false;
  246. });
  247. },
  248. //重置
  249. resetForm() {
  250. this.searchData.secondary_card_name = '';
  251. this.searchData.secondary_card_id = '';
  252. this.searchData.order_no = '';
  253. this.searchData.open_type = '0';
  254. this.searchData.date_time = '';
  255. this.searchData.user_id = '';
  256. },
  257. toEdit(id){
  258. this.$navigate({
  259. r: 'secondary-card/default/edit',
  260. id: id
  261. })
  262. },
  263. changeOrderStatus(id,order_status){
  264. let self = this;
  265. var title = '';
  266. if(order_status==4) {
  267. title = '是否停用?';
  268. }
  269. if(order_status==0) {
  270. title = '是否恢复?';
  271. }
  272. self.$confirm(title, '警告', {
  273. type: 'warning'
  274. }).then(() => {
  275. request({
  276. params: {
  277. r: 'secondary-card/default/change-order-status',
  278. },
  279. method: 'post',
  280. data: {
  281. id: id,
  282. order_status: order_status,
  283. },
  284. }).then(e => {
  285. if (e.data.code == 0) {
  286. self.$message.success(e.data.msg);
  287. self.loadData();
  288. } else {
  289. self.$message.error(e.data.msg);
  290. }
  291. }).catch(e => {
  292. console.log(e);
  293. });
  294. })
  295. },
  296. toUseLog(order_no){
  297. this.$navigate({
  298. r: 'secondary-card/default/use-log',
  299. order_no: order_no
  300. })
  301. },
  302. openRefund(row){
  303. this.dialogContent= true;
  304. this.codeForm.id= row.id;
  305. this.codeForm.order_no= row.order_no;
  306. this.codeForm.nickname= row.nickname;
  307. },
  308. postAdd(formName){
  309. let self = this;
  310. this.codeFormLoading = true;
  311. this.$refs[formName].validate((valid) => {
  312. if (valid) {
  313. request({
  314. params: {
  315. r: 'secondary-card/default/order-refund',
  316. },
  317. method: 'post',
  318. data: this.codeForm,
  319. }).then(e => {
  320. if (e.data.code == 0) {
  321. self.$message.success(e.data.msg);
  322. this.dialogContent = false;
  323. self.loadData();
  324. } else {
  325. self.$message.error(e.data.msg);
  326. }
  327. }).catch(e => {
  328. console.log(e);
  329. });
  330. this.codeFormLoading = false;
  331. } else {
  332. console.log('error submit!!');
  333. this.codeFormLoading = false;
  334. return false;
  335. }
  336. });
  337. },
  338. },
  339. mounted: function() {
  340. this.page = getQuery('page') ? getQuery('page') : 1;
  341. this.loadData();
  342. },
  343. });
  344. </script>
  345. <style>
  346. .table-body {
  347. padding: 20px;
  348. background-color: #fff;
  349. }
  350. /* .table-info .el-button {
  351. padding: 0 !important;
  352. border: 0;
  353. margin: 0 5px;
  354. } */
  355. .input-item {
  356. display: inline-block;
  357. width: 150px;
  358. margin: 0 0 20px;
  359. margin-right: 10px;
  360. }
  361. .input-item .el-input__inner {
  362. border-right: 1px solid #dcdfe6;
  363. }
  364. .input-item .el-input__inner:hover {
  365. border: 1px solid #dcdfe6;
  366. border-right: 0;
  367. outline: 0;
  368. }
  369. .input-item .el-input__inner:focus {
  370. border: 1px solid #dcdfe6;
  371. border-right: 0;
  372. outline: 0;
  373. }
  374. .input-item .el-input-group__append {
  375. background-color: #fff;
  376. border-left: 0;
  377. width: 10%;
  378. padding: 0;
  379. }
  380. .input-item .el-input-group__append .el-button {
  381. padding: 0;
  382. }
  383. .input-item .el-input-group__append .el-button {
  384. margin: 0;
  385. }
  386. .select {
  387. float: left;
  388. width: 100px;
  389. margin-right: 10px;
  390. }
  391. .el-table th>.cell {
  392. color: #333;
  393. font-weight: bold;
  394. font-size: 14px;
  395. }
  396. .el-table__footer-wrapper,
  397. .el-table__header-wrapper {
  398. border-bottom: 1.4px solid #D6D6D6;
  399. }
  400. .search-sort {
  401. display: inline-block;
  402. margin: 0px 10px;
  403. cursor: pointer;
  404. color: rgb(51, 51, 51);
  405. }
  406. .caret-wrapper {
  407. display: inline-flex;
  408. flex-direction: column;
  409. align-items: center;
  410. height: 25px;
  411. width: 11px;
  412. vertical-align: middle;
  413. cursor: pointer;
  414. overflow: initial;
  415. position: relative;
  416. }
  417. .caret-top {
  418. border: 5px solid transparent;
  419. margin: 1px 0;
  420. border-bottom-color: rgb(51, 51, 51);
  421. }
  422. .caret-bottom {
  423. border: 5px solid transparent;
  424. margin: 1px 0;
  425. border-top-color: rgb(51, 51, 51);
  426. }
  427. .active {
  428. border-top-color: rgb(41, 186, 156);
  429. }
  430. .ellipsis {
  431. font-size: 14px;
  432. color: #333;
  433. overflow: hidden;
  434. text-overflow: ellipsis;
  435. }
  436. .goods-wrapper {
  437. border: 2px solid #CCCCCC;
  438. display: inline-block
  439. }
  440. .goods-select {
  441. border: 2px solid #bb730c;
  442. }
  443. .goods-price {
  444. text-align: center;
  445. }
  446. .goods-price .number {
  447. color: red;
  448. font-weight: 600;
  449. font-size: 18px;
  450. }
  451. .goods-price .title {
  452. padding: 5px 0;
  453. color: #999;
  454. ;
  455. font-size: 10px;
  456. font-weight: 600;
  457. }
  458. .bottom-price .title {
  459. padding: 5px 0;
  460. color: #8b8888;
  461. ;
  462. font-size: 10px;
  463. }
  464. .bottom-price .number {
  465. color: #ff5100;
  466. font-size: 10px;
  467. }
  468. .goods-action {
  469. margin-top: 8px;
  470. }
  471. .goods-action .title {
  472. color: #0634aa;
  473. }
  474. .bottom-active {
  475. border-bottom-color: rgb(186, 41, 92);
  476. }
  477. .top-active {
  478. border-top-color: rgb(186, 41, 92);
  479. }
  480. .price {
  481. white-space: nowrap;
  482. }
  483. .goods-image {
  484. display: flex;
  485. justify-content: center;
  486. }
  487. .page {
  488. padding: 10px 0;
  489. }
  490. .user_img{
  491. position: relative;
  492. margin-right: 8px;
  493. /* height: 50px;
  494. width: 50px; */
  495. }
  496. .default-avatar{
  497. width: 50px;
  498. height: 50px;
  499. border-radius: 50%;
  500. margin-right: 8px;
  501. }
  502. .uer-nickname {
  503. flex: 1;
  504. }
  505. </style>