index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <div id="order-check">
  3. <div class="order-check-body" v-loading.fullscreen.lock="fullscreenLoading">
  4. <div class="order-management-body">
  5. <div class="order-management-inner">
  6. <span>下单时间:</span>
  7. <el-date-picker size="large" v-model="searchDate" type="daterange" unlink-panels range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions2" value-format="yyyy-MM-dd" align="center">
  8. </el-date-picker>
  9. <span>支付平台交易号:</span>
  10. <el-input @keyup.enter.native="_searchOrderData(1)" ref="searchTradeNum" v-model="searchTradeNum" value="" placeholder="交易号"></el-input>
  11. <div class="base-info">
  12. <span>订单号:</span>
  13. <el-input @keyup.enter.native="_searchOrderData(1)" ref="searchOrderNumber" v-model="searchOrderNumber" value="" placeholder="订单号"></el-input>
  14. <span>手机号:</span>
  15. <el-input @keyup.enter.native="_searchOrderData(1)" ref="searchPhone" v-model="searchPhone" value="" placeholder="手机号"></el-input>
  16. <span>快递号:</span>
  17. <el-input @keyup.enter.native="_searchOrderData(1)" ref="searchExpressNum" v-model="searchExpressNum" value="" placeholder="快递号"></el-input>
  18. <el-button type="primary" @click="_searchOrderData(1)" color='red'>筛选</el-button>
  19. </div>
  20. </div>
  21. <div class="order-check_bottom">
  22. <div class="order-management-table">
  23. <div class="order-check_tab">
  24. <ul>
  25. <li v-for="(item,index) in tabs" :key="index" :class="{'order-check_tab_li_active':item.idx==tabIndex}" @click="clickTabItem(item.idx)">{{item.name}}<span v-if="item.idx != 3" style="margin:0 10px;color: #999;font-weight: normal;">/</span></li>
  26. </ul>
  27. <div style="float: right;vertical-align: middle;">
  28. <!-- <el-select v-model="selectValue" placeholder="请选择">
  29. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
  30. </el-option>
  31. </el-select> -->
  32. <el-button type="primary" @click="_exportExcelForOrder" color='red'>导出</el-button>
  33. </div>
  34. </div>
  35. <el-table ref="order_table" @expand-change="_getOrderDetail" class='e-table' :data="orders" style="width: 100%">
  36. <el-table-column label="时间">
  37. <template slot-scope="scope">
  38. <div>{{new Date(scope.row.orderTime).format('yyyy-MM-dd hh:mm:ss')}}</div>
  39. </template>
  40. </el-table-column>
  41. <el-table-column prop="orderSn" label="订单号">
  42. </el-table-column>
  43. <el-table-column prop="userName" label="手机号/用户名">
  44. </el-table-column>
  45. <el-table-column prop="totalAmount" label="订单金额(元)">
  46. </el-table-column>
  47. <el-table-column prop="paymentTypeName" label="支付方式">
  48. <template slot-scope="scope">
  49. <div>{{payMap[scope.row.paymentTypeName]}}</div>
  50. </template>
  51. </el-table-column>
  52. <el-table-column prop="tradeNum" label="支付平台交易号">
  53. </el-table-column>
  54. <el-table-column prop="orderStatus" label="订单状态">
  55. <template slot-scope="scope">
  56. <div>{{paymentStatusMap[scope.row.paymentStatus]}}</div>
  57. </template>
  58. </el-table-column>
  59. <el-table-column type="expand" prop="operation" label="操作" width="150">
  60. <template slot-scope="scope">
  61. <div class="order_check_row">
  62. <div class="product_info">
  63. <div class="product_info_title">
  64. 商品信息
  65. </div>
  66. <div class="product_info_body" v-for="(item, i) in scope.row.items" :key="i">
  67. <div class="product_info_body_img">
  68. <img :src="item.product.url" class="product_img">
  69. </div>
  70. <div class="product_info_body_info">
  71. <div class="product_info_body_info_item">
  72. <span class="product_info_body_info_item_title">商品名称</span>
  73. <span class="product_info_body_info_item_content">{{item.product.name}}</span>
  74. </div>
  75. <div class="product_info_body_info_item">
  76. <span class="product_info_body_info_item_title">套餐</span>
  77. <span class="product_info_body_info_item_content" v-html="item.product.packageName"></span>
  78. </div>
  79. <div class="product_info_body_info_item">
  80. <span class="product_info_body_info_item_title">数量</span>
  81. <span class="product_info_body_info_item_content">{{item.product.count}}</span>
  82. </div>
  83. <div class="product_info_body_info_item">
  84. <span class="product_info_body_info_item_title">商品单价</span>
  85. <span class="product_info_body_info_item_content">{{item.product.amount}}</span>
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. <div class="order_info">
  91. <div class="order_info_title">
  92. 下单信息
  93. </div>
  94. <div class="order_info_body" v-if="scope.row.items.length">
  95. <div class="order_info_body_info">
  96. <div class="order_info_body_info_item">
  97. <span class="order_info_body_info_item_title">顾客姓名</span>
  98. <span class="order_info_body_info_item_content">{{scope.row.items[0].receive.name}}</span>
  99. </div>
  100. <div class="order_info_body_info_item">
  101. <span class="order_info_body_info_item_title">电话</span>
  102. <span class="order_info_body_info_item_content">{{scope.row.items[0].receive.phone}}</span>
  103. </div>
  104. <div class="order_info_body_info_item">
  105. <span class="order_info_body_info_item_title">收货地址</span>
  106. <span class="order_info_body_info_item_content">{{scope.row.shipAreaPath}}{{scope.row.items[0].receive.address}}</span>
  107. </div>
  108. <div class="order_info_body_info_item">
  109. <span class="order_info_body_info_item_title">发票</span>
  110. <span class="order_info_body_info_item_content fix-order_info_body_info_item_content">{{scope.row.items[0].receive.invoice ? '需要发票' : '不需要发票'}}</span>
  111. </div>
  112. <div class="order_info_body_info_item" v-if="scope.row.paymentStatus != 'unpaid'">
  113. <span class="order_info_body_info_item_title">快递类别</span>
  114. <span class="order_info_body_info_item_content">
  115. <el-input
  116. v-model="scope.row.items[0].receive.expressName" maxlength="15" placeholder="请输入快递类别"
  117. type="text" v-if="scope.row.items[0].shippingStatus != 'shipped'" disabled>
  118. </el-input>
  119. {{scope.row.items[0].shippingStatus == 'shipped'?scope.row.items[0].receive.expressName:""}}
  120. </span>
  121. </div>
  122. <div class="order_info_body_info_item" v-if="scope.row.paymentStatus != 'unpaid'">
  123. <span class="order_info_body_info_item_title">快递单号</span>
  124. <span class="order_info_body_info_item_content">
  125. <el-input
  126. v-model="scope.row.items[0].receive.expressNum" maxlength="15" placeholder="请输入15位顺丰快单号"
  127. type="text" v-if="scope.row.items[0].shippingStatus != 'shipped'">
  128. </el-input>
  129. {{scope.row.items[0].shippingStatus == 'shipped'?scope.row.items[0].receive.expressNum:""}}
  130. </span>
  131. </div>
  132. <div class="order_info_body_info_item" v-if="scope.row.paymentStatus != 'unpaid'&& scope.row.items[0].shippingStatus != 'shipped'">
  133. <span class="order_info_body_info_item_title"></span>
  134. <span class="order_info_body_info_item_content"><el-button @click="saveRow(scope.row, scope.row.items)" type="primary">保存</el-button><el-button @click="hideRow(scope.row)">取消</el-button></span>
  135. </div>
  136. </div>
  137. </div>
  138. </div>
  139. </div>
  140. <!-- <div v-if="">暂无数据</div> -->
  141. </template>
  142. </el-table-column>
  143. </el-table>
  144. </div>
  145. <div class="order-management-pagination">
  146. <el-pagination @current-change="handleCurrentChange" :current-page.sync="currentPage" :page-size="10" layout="total, prev, pager, next, jumper" :total="total">
  147. </el-pagination>
  148. </div>
  149. </div>
  150. </div>
  151. </div>
  152. </div>
  153. </template>
  154. <script>
  155. export default {
  156. name: 'order-check',
  157. data () {
  158. return {
  159. statusMap: {
  160. unprocessed: '未处理',
  161. processed: '已确认',
  162. completed: '已完成',
  163. invalid: '已取消'
  164. },
  165. payMap: {
  166. '0': '微信',
  167. '1': '支付宝',
  168. '2': 'paypal',
  169. '3': '其他',
  170. '4': '货到付款'
  171. },
  172. paymentStatusMap: {
  173. unpaid: '未付款',
  174. paid: '已付款',
  175. cancel: '已取消',
  176. partPayment: '部分支付',
  177. partRefund: '部分退款',
  178. refunded: '全额退款'
  179. },
  180. tabs: [{ name: '全部', idx: -1 }, { name: '未支付', idx: 0 }, { name: '待发货', idx: 1 }, { name: '已发货', idx: 2 }, { name: '已完成', idx: 3 }],
  181. expandedArr: [],
  182. orders: [],
  183. currentPage: 1,
  184. key_input: '',
  185. fullscreenLoading: false,
  186. product: {
  187. 'name': '',
  188. 'packageName': '',
  189. 'count': '',
  190. 'amount': '',
  191. 'url': ''
  192. },
  193. receive: {
  194. 'name': '',
  195. 'phone': '',
  196. 'address': '',
  197. 'invoice': '',
  198. 'expressNum': ''
  199. },
  200. total: 0,
  201. options: [{
  202. value: undefined,
  203. label: '全部筛选订单'
  204. }, {
  205. value: 0,
  206. label: '未支付筛选订单'
  207. }, {
  208. value: 1,
  209. label: '待发货筛选订单'
  210. }, {
  211. value: 2,
  212. label: '已发货筛选订单'
  213. }, {
  214. value: 3,
  215. label: '已完成筛选订单'
  216. }],
  217. selectValue: '',
  218. // expressNum_input: "",
  219. searchDate: [],
  220. searchOrderNumber: '',
  221. searchTradeNum:'',
  222. searchPhone: '',
  223. searchExpressNum: '',
  224. hasClickSearch: false,
  225. tabIndex: -1,
  226. pickerOptions2: {
  227. shortcuts: [{
  228. text: '最近一周',
  229. onClick (picker) {
  230. const end = new Date()
  231. const start = new Date()
  232. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  233. picker.$emit('pick', [start, end])
  234. }
  235. }, {
  236. text: '最近一个月',
  237. onClick (picker) {
  238. const end = new Date()
  239. const start = new Date()
  240. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
  241. picker.$emit('pick', [start, end])
  242. }
  243. }, {
  244. text: '最近三个月',
  245. onClick (picker) {
  246. const end = new Date()
  247. const start = new Date()
  248. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
  249. picker.$emit('pick', [start, end])
  250. }
  251. }]
  252. }
  253. }
  254. },
  255. methods: {
  256. handleClick (row) {
  257. console.log(this.status)
  258. console.log(this.selectValue)
  259. },
  260. async saveRow (row, items) {
  261. let item = items[0]
  262. let orderItemIds = items.map(item => item.id).join(',')
  263. let expressNum = item.receive.expressNum
  264. var pattern = /^[\u4E00-\u9FA5]{1,5}$/
  265. console.log(item.receive.expressNum)
  266. if (!expressNum) {
  267. return this.$alert('请输入快递单号', '提示', {
  268. confirmButtonText: '确定',
  269. callback: action => {
  270. }
  271. })
  272. } else if (pattern.test(expressNum)) {
  273. return this.$alert('快递单号不能为中文', '提示', {
  274. confirmButtonText: '确定',
  275. callback: action => {
  276. }
  277. })
  278. }
  279. let data = await this.$http.post('/manager/order/confirmDelivery', {
  280. orderId: row.id,
  281. orderItemIds: orderItemIds,
  282. expressName: item.receive.expressName,
  283. expressNum: expressNum
  284. })
  285. if (data.code === 0) {
  286. this.$message({
  287. message: '发货成功!',
  288. type: 'success'
  289. })
  290. } else {
  291. this.$alert('保存失败', '提示', {
  292. confirmButtonText: '确定',
  293. callback: action => {}
  294. })
  295. }
  296. // request['saveExpressNum']({
  297. // orderId,
  298. // expressNum
  299. // }, 'get').then(res => {
  300. // if (res === 1) {
  301. // // this.$refs.order_table.toggleRowExpansion(row, false)
  302. // row.status = '已发货'
  303. // this.$message({
  304. // message: '发货成功!',
  305. // type: 'success'
  306. // })
  307. // } else {
  308. // this.$alert('保存失败', '提示', {
  309. // confirmButtonText: '确定',
  310. // callback: action => {
  311. // }
  312. // })
  313. // }
  314. // })
  315. },
  316. hideRow (row) {
  317. this.$refs.order_table.toggleRowExpansion(row, false)
  318. },
  319. handleCurrentChange (val) {
  320. let page = val
  321. if (this.total > 0 && !this.hasClickSearch) {
  322. this._searchOrderData(page)
  323. } else {
  324. this._searchOrderData(page)
  325. }
  326. },
  327. clickTabItem (idx) {
  328. this.tabIndex = idx
  329. this.hasClickSearch = false
  330. this.total = 0
  331. this.currentPage = 1
  332. this.status = this.tabIndex === -1 ? null : this.tabIndex
  333. if (!this.searchDate || this.expressNum || !this.userName || !this.orderNum) {
  334. this._searchOrderData()
  335. }
  336. },
  337. async _searchOrderData (page) {
  338. this.hasClickSearch = true
  339. let date1, date2, userName, expressNum, orderNum,tradeNum
  340. this.date1 = this.searchDate ? this.searchDate[0] : null
  341. this.date2 = this.searchDate ? this.searchDate[1] : null
  342. date1 = this.date1 ? (this.date1 + ' 00:00:00') : null
  343. date2 = this.date2 ? (this.date2 + ' 23:59:59') : null
  344. this.userName = userName = this.searchPhone || null
  345. this.expressNum = expressNum = this.searchExpressNum || null
  346. this.orderNum = orderNum = this.searchOrderNumber || null
  347. this.tradeNum = tradeNum = this.searchTradeNum || null
  348. // console.log(searchDate,searchPhone,searchExpressNum,searchOrderNumber)
  349. this.fullscreenLoading = true
  350. let status = this.status
  351. let data = (await this.$http.post('/manager/order/list', {
  352. pageNum: page,
  353. type: status,
  354. startDate: date1,
  355. endDate: date2,
  356. orderSn: orderNum,
  357. phoneNum: userName,
  358. expressNum,
  359. tradeNum,
  360. pageSize: 10
  361. })).data
  362. this.fullscreenLoading = false
  363. let temp = data.list
  364. for (var i = 0; i < temp.length; i++) {
  365. // temp[i]['expressNum_input'] = "";
  366. temp[i].items = []
  367. }
  368. this.orders = temp
  369. this.currentPage = page
  370. this.total = data.total
  371. },
  372. _exportExcelForOrder () {
  373. let date1, date2, userName, expressNum, orderNum,tradeNum
  374. this.date1 = this.searchDate ? this.searchDate[0] : null
  375. this.date2 = this.searchDate ? this.searchDate[1] : null
  376. date1 = this.date1 ? (this.date1 + ' 00:00:00') : null
  377. date2 = this.date2 ? (this.date2 + ' 23:59:59') : null
  378. this.userName = userName = this.searchPhone || null
  379. this.expressNum = expressNum = this.searchExpressNum || null
  380. this.orderNum = orderNum = this.searchOrderNumber || null
  381. this.tradeNum = tradeNum = this.searchTradeNum || null
  382. let data = {
  383. 'type': this.status,
  384. 'startDate': date1,
  385. 'endDate': date2,
  386. 'orderSn': orderNum,
  387. 'phoneNum': userName,
  388. 'expressNum': expressNum,
  389. 'tradeNum':tradeNum
  390. }
  391. this.fullscreenLoading = true
  392. console.error(data)
  393. this.$confirm('确定当前标签下的订单记录?', '导出订单', {
  394. confirmButtonText: '确定',
  395. cancelButtonText: '取消',
  396. type: 'warning'
  397. }).then(async () => {
  398. let exec = await this.$http({
  399. methods: 'get',
  400. params: data,
  401. url: '/manager/order/export',
  402. responseType: 'arraybuffer'
  403. })
  404. try {
  405. let blob = new Blob([exec], {type: 'application/vnd.ms-excel'})
  406. let url = URL.createObjectURL(blob)
  407. location.href = url
  408. } catch (e) {
  409. console.error(e)
  410. }
  411. this.fullscreenLoading = false
  412. }).catch(() => {
  413. this.$message({
  414. type: 'info',
  415. message: '已取消导出'
  416. })
  417. this.fullscreenLoading = false
  418. })
  419. },
  420. async _getOrderDetail (row) {
  421. this.fullscreenLoading = true
  422. let data = (await this.$http.post('/manager/order/detail', {orderId: row.id})).data
  423. let temp = this.orders.find(item => item.id === row.id)
  424. temp.items = data.orderItems.map(item => {
  425. return {
  426. ...item,
  427. product: {
  428. url: item.pic,
  429. name: item.goodsName,
  430. packageName: item.description,
  431. count: item.goodsCount,
  432. amount: item.goodsPrice
  433. },
  434. receive: {
  435. name: data.shipName,
  436. phone: data.shipMobile,
  437. address: data.shipAddress,
  438. invoice: data.invoice,
  439. expressNum: item.expressNum,
  440. expressName: item.expressName
  441. }
  442. }
  443. })
  444. console.log(temp)
  445. this.fullscreenLoading = false
  446. }
  447. },
  448. mounted () {
  449. // console.log(window.location.origin)
  450. // window.open(window.location.origin+'/main')
  451. this._searchOrderData(1)
  452. }
  453. }
  454. </script>
  455. <style scoped>
  456. @import url('./style.css');
  457. .el-icon-s-flag {
  458. cursor: pointer;
  459. }
  460. </style>
  461. <style type="text/css">
  462. .el-table__expand-icon--expanded {
  463. transform: rotate(0) !important;
  464. }
  465. .el-table__expand-icon>i {
  466. display: none !important;
  467. }
  468. .el-table__expand-icon:after {
  469. content: "\8BE6\7EC6";
  470. color: #09e1c0;
  471. cursor: pointer;
  472. }
  473. </style>