index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. <template>
  2. <view class="pos-order-list" ref="container">
  3. <view class="searchCon acea-row row-center-wrapper">
  4. <view class="search acea-row row-middle">
  5. <text class="iconfont icon-sousuo4"></text>
  6. <input class="inputs" placeholder='搜索订单号、收货人名称、手机号' placeholder-class='placeholder' confirm-type='search' name="search"
  7. v-model="where.keyword" @confirm="searchSubmit"></input>
  8. </view>
  9. </view>
  10. <view class="nav acea-row row-around row-middle">
  11. <view class="item" :class="where.status == 0 ? 'on' : ''" @click="changeStatus(0)">
  12. 待付款
  13. </view>
  14. <view class="item" :class="where.status == 1 ? 'on' : ''" @click="changeStatus(1)">
  15. 待发货
  16. </view>
  17. <view class="item" :class="where.status == 2 ? 'on' : ''" @click="changeStatus(2)">
  18. 待收货
  19. </view>
  20. <view class="item" :class="where.status == 3 ? 'on' : ''" @click="changeStatus(3)">
  21. 待评价
  22. </view>
  23. <view class="item" :class="where.status == 4 ? 'on' : ''" @click="changeStatus(4)">
  24. 已完成
  25. </view>
  26. <view class="item" :class="where.status == -3 ? 'on' : ''" @click="changeStatus(-3)">
  27. 退款
  28. </view>
  29. </view>
  30. <view class="list" v-if="list.length">
  31. <view class="item" v-for="(item, index) in list" :key="index">
  32. <view class="order-num acea-row row-between-wrapper" @click="toDetail(item)">
  33. <view>
  34. <view>订单号:{{ item.order_id }}</view>
  35. <view class="time">下单时间:{{ item.add_time }}</view>
  36. </view>
  37. <view class="state" :class="(item.refund_status==0 && where.status != 0 && item.refund.length)?'on':''">
  38. {{item.refund_status==1?'退款中':item.refund_status==2?'已退款':item.refund_status==3?'拒绝退款':item.status_name.status_name}}
  39. <text v-if="item.refund_status==0 && where.status != 0 && item.refund.length" >{{item.is_all_refund?',退款中':',部分退款中'}}</text>
  40. </view>
  41. </view>
  42. <view class="pos-order-goods" v-for="(val, key) in item._info" :key="key">
  43. <view class="goods acea-row row-between row-top" @click="toDetail(item)">
  44. <view class="picTxt acea-row row-between-wrapper">
  45. <view class="pictrue">
  46. <image :src="val.cart_info.productInfo.attrInfo?val.cart_info.productInfo.attrInfo.image:val.cart_info.productInfo.image" />
  47. </view>
  48. <view class="text acea-row row-between row-column">
  49. <view class="info line2">
  50. <text v-if="val.cart_info.is_gift == 1" class="label">[赠品]</text>
  51. {{ val.cart_info.productInfo.store_name }}
  52. </view>
  53. <view class="attr" v-if="val.cart_info.productInfo.attrInfo">
  54. {{ val.cart_info.productInfo.attrInfo.suk }}
  55. </view>
  56. </view>
  57. </view>
  58. <view class="money">
  59. <view class="x-money">¥{{ val.cart_info.productInfo.attrInfo?val.cart_info.productInfo.attrInfo.price:val.cart_info.productInfo.price }}</view>
  60. <view class="num">x{{ val.cart_info.cart_num }}</view>
  61. <!-- <view class="y-money">
  62. ¥{{ val.cart_info.productInfo.ot_price }}
  63. </view> -->
  64. <view class="info" v-if="val.cart_info.refund_num && item._status._type !=-2">{{val.cart_info.refund_num}}件退款中</view>
  65. </view>
  66. </view>
  67. </view>
  68. <view class="public-total">
  69. 共{{ item.total_num }}件商品,实付款
  70. <span class="money">¥{{ item.pay_price }}</span> ( 邮费 ¥{{
  71. item.pay_postage
  72. }}
  73. )
  74. </view>
  75. <view class="operation acea-row row-between-wrapper">
  76. <view class="more">
  77. <!-- <view class="iconfont icon-gengduo" @click="more(index)"></view>-->
  78. <!-- <view class="order" v-show="current === index">-->
  79. <!-- <view class="items">-->
  80. <!-- {{ where.status > 0 ? "删除" : "取消" }}订单-->
  81. <!-- </view>-->
  82. <!-- <view class="arrow"></view>-->
  83. <!-- </view>-->
  84. </view>
  85. <view class="acea-row row-middle">
  86. <view class="bnt" :class="openErp?'on':''" @click="modify(item, 0)" v-if="where.status == 0">
  87. 一键改价
  88. </view>
  89. <view class="bnt" @click="modify(item, 1)">订单备注</view>
  90. <!-- <view class="bnt" @click="modify(item, 0)" v-if="where.status == -3 && item.refund_status === 1">
  91. 立即退款
  92. </view> -->
  93. <view class="bnt" :class="openErp?'on':''" @click="modify(item, 2, 1)" v-if="(item.refund_type == 0 || item.refund_type == 1 || item.refund_type == 5 ) && where.status == -3 && parseFloat(item.pay_price) >= 0">
  94. 立即退款
  95. </view>
  96. <view class="bnt" :class="openErp?'on':''" @click="modify(item, 2, 0)" v-if="where.status == -3 && item.refund_type == 2">同意退货</view>
  97. <view class="wait" :class="openErp?'on':''" v-if="where.status == -3 && item.refund_type == 4">待用户发货</view>
  98. <view class="bnt cancel" :class="openErp?'on':''" v-if="item.pay_type === 'offline' && item.paid === 0" @click="offlinePay(item)">
  99. 确认付款
  100. </view>
  101. <view class="bnt" :class="openErp?'on':''" v-if="where.status == 1 && item.shipping_type === 1 && (item.pinkStatus === null || item.pinkStatus === 2)" @click="goDelivery(item)">去发货
  102. </view>
  103. </view>
  104. </view>
  105. </view>
  106. </view>
  107. <view v-else class="nothing">
  108. <image v-if="!loading" :src="imgHost + '/statics/images/no-thing.png'" alt="">
  109. <view v-if="!loading">暂无订单</view>
  110. </view>
  111. <Loading :loaded="loaded" :loading="loading"></Loading>
  112. <PriceChange :change="change" :orderInfo="orderInfo" :isRefund="isRefund" v-on:statusChange="statusChange($event)" v-on:closechange="changeclose($event)" v-on:savePrice="savePrice"
  113. :status="status"></PriceChange>
  114. </view>
  115. </template>
  116. <script>
  117. import {
  118. getAdminOrderList,
  119. setAdminOrderPrice,
  120. setAdminOrderRemark,
  121. setAdminRefundRemark,
  122. setOfflinePay,
  123. setOrderRefund,
  124. orderRefundAgree,
  125. adminRefundList
  126. } from "@/api/admin";
  127. import { erpConfig } from "@/api/esp.js";
  128. import Loading from '@/components/Loading/index'
  129. import PriceChange from '../components/PriceChange/index.vue'
  130. import { isMoney } from '@/utils/validate.js';
  131. import {HTTP_REQUEST_URL} from '@/config/app';
  132. export default {
  133. name: "AdminOrderList",
  134. components: {
  135. Loading,
  136. PriceChange
  137. },
  138. data() {
  139. return {
  140. openErp:false,
  141. current: "",
  142. change: false,
  143. types: 0,
  144. where: {
  145. page: 1,
  146. limit: 10,
  147. status: 0,
  148. keyword:''
  149. },
  150. list: [],
  151. loaded: false,
  152. loading: false,
  153. orderInfo: {},
  154. status: "",
  155. isRefund:0, //1是仅退款;0是退货退款
  156. imgHost:HTTP_REQUEST_URL
  157. };
  158. },
  159. onLoad(option) {
  160. let type = option.types;
  161. this.where.status = type;
  162. this.getErpConfig();
  163. },
  164. onShow(){
  165. this.init();
  166. },
  167. methods: {
  168. statusChange(e){
  169. this.status = e;
  170. },
  171. goDelivery(item){
  172. if(this.openErp) return
  173. uni.navigateTo({
  174. url:'/pages/admin/delivery/index?id='+item.order_id+'&listId='+item.id+'&totalNum='+item.total_num+'&orderStatus='+item._status+'&comeType=1&productType='+item.product_type
  175. })
  176. },
  177. getErpConfig(){
  178. erpConfig().then(res=>{
  179. this.openErp = res.data.open_erp;
  180. }).catch(err=>{
  181. this.$util.Tips({
  182. title: err
  183. })
  184. })
  185. },
  186. // 获取数据
  187. getIndex: function() {
  188. let that = this;
  189. if (that.loading || that.loaded) return;
  190. that.loading = true;
  191. let obj = '';
  192. if(this.where.status == -3){
  193. obj = adminRefundList(that.where);
  194. }else{
  195. obj = getAdminOrderList(that.where);
  196. }
  197. obj.then(
  198. res => {
  199. that.loading = false;
  200. that.loaded = res.data.length < that.where.limit;
  201. that.list.push.apply(that.list, res.data);
  202. that.where.page = that.where.page + 1;
  203. },
  204. err => {
  205. that.$util.Tips({
  206. title: err
  207. })
  208. }
  209. );
  210. },
  211. // 初始化
  212. init: function() {
  213. this.list = [];
  214. this.where.page = 1;
  215. this.loaded = false;
  216. this.loading = false;
  217. this.getIndex();
  218. this.current = "";
  219. },
  220. searchSubmit(){
  221. this.init();
  222. },
  223. // 导航切换
  224. changeStatus(val) {
  225. if (this.where.status != val) {
  226. this.where.status = val;
  227. this.init();
  228. }
  229. },
  230. // 商品操作
  231. modify: function(item, status,type) {
  232. if(this.openErp && status !=1) return
  233. this.change = true;
  234. this.status = status.toString();
  235. this.orderInfo = item;
  236. if(status==2){
  237. this.isRefund = type
  238. }
  239. },
  240. changeclose: function(msg) {
  241. this.change = msg;
  242. },
  243. objOrderRefund(data){
  244. let that = this;
  245. setOrderRefund(data).then(
  246. res => {
  247. that.change = false;
  248. that.$util.Tips({title: res.msg});
  249. that.init();
  250. },
  251. err => {
  252. that.change = false;
  253. that.$util.Tips({title: err});
  254. }
  255. );
  256. },
  257. async savePrice(opt) {
  258. let that = this,
  259. data = {},
  260. price = opt.price,
  261. refund_price = opt.refund_price,
  262. refund_status = that.orderInfo.refund_status,
  263. remark = opt.remark;
  264. data.order_id = that.orderInfo.order_id;
  265. if (that.status == 0) {
  266. if(!isMoney(price)){
  267. return that.$util.Tips({title: '请输入正确的金额'});
  268. }
  269. data.price = price;
  270. setAdminOrderPrice(data).then(
  271. res => {
  272. that.change = false;
  273. that.$util.Tips({
  274. title:'改价成功',
  275. icon:'success'
  276. })
  277. that.init();
  278. },
  279. err => {
  280. that.change = false;
  281. that.$util.Tips({
  282. title:'改价失败',
  283. icon:'none'
  284. })
  285. }
  286. );
  287. } else if (that.status == 2) {
  288. if(this.isRefund){
  289. if(!isMoney(refund_price)){
  290. return that.$util.Tips({title: '请输入正确的金额'});
  291. }
  292. data.price = refund_price;
  293. data.type = opt.type;
  294. this.objOrderRefund(data);
  295. // setOrderRefund(data).then(
  296. // res => {
  297. // that.change = false;
  298. // that.$util.Tips({title: res.msg});
  299. // that.init();
  300. // },
  301. // err => {
  302. // that.change = false;
  303. // that.$util.Tips({title: err});
  304. // }
  305. // );
  306. }else{
  307. if(opt.type == 1){
  308. orderRefundAgree(this.orderInfo.id).then(res=>{
  309. that.change = false;
  310. that.$util.Tips({
  311. title: res.msg
  312. });
  313. that.init();
  314. }).catch(err=>{
  315. that.change = false;
  316. that.$util.Tips({
  317. title: err
  318. });
  319. })
  320. }
  321. // else{
  322. // data.type = opt.type;
  323. // data.refuse_reason = opt.refuse_reason;
  324. // this.objOrderRefund(data);
  325. // }
  326. }
  327. } else if(that.status == 8){
  328. data.type = opt.type;
  329. data.refuse_reason = opt.refuse_reason;
  330. this.objOrderRefund(data);
  331. } else {
  332. if(!remark){
  333. return this.$util.Tips({
  334. title:'请输入备注'
  335. })
  336. }
  337. data.remark = remark;
  338. let obj = '';
  339. if(that.where.status == -3){
  340. obj = setAdminRefundRemark(data);
  341. }else{
  342. obj = setAdminOrderRemark(data);
  343. }
  344. obj.then(
  345. res => {
  346. that.change = false;
  347. this.$util.Tips({
  348. title:res.msg,
  349. icon:'success'
  350. })
  351. that.init();
  352. },
  353. err => {
  354. that.change = false;
  355. that.$util.Tips({title: err});
  356. }
  357. );
  358. }
  359. },
  360. toDetail(item){
  361. uni.navigateTo({
  362. url:`/pages/admin/orderDetail/index?id=${item.order_id}&types=${this.where.status}`
  363. })
  364. },
  365. offlinePay: function(item) {
  366. if(this.openErp) return
  367. setOfflinePay({ order_id: item.order_id }).then(
  368. res => {
  369. this.$util.Tips({title:res.msg,icon:"success"});
  370. this.init();
  371. },
  372. error => {
  373. this.$util.Tips(error);
  374. }
  375. );
  376. }
  377. },
  378. onReachBottom() {
  379. this.getIndex()
  380. }
  381. }
  382. </script>
  383. <style lang="scss">
  384. .pos-order-list{
  385. padding-bottom: calc(0rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
  386. padding-bottom: calc(0rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  387. }
  388. .searchCon{
  389. position: relative;
  390. z-index: 9;
  391. background-color: #fff;
  392. height: 88rpx;
  393. width: 100%;
  394. border-bottom: 1px solid #EBEEF5;
  395. .search{
  396. width: 690rpx;
  397. height: 64rpx;
  398. background: #F5F5F5;
  399. border-radius: 12rpx;
  400. padding: 0 24rpx;
  401. .iconfont{
  402. color: #999999;
  403. margin-right: 12rpx;
  404. }
  405. .inputs{
  406. width: 590rpx;
  407. font-size: 26rpx;
  408. }
  409. .placeholder{
  410. font-size: 26rpx;
  411. color: #ccc;
  412. }
  413. }
  414. }
  415. .pos-order-list .nav {
  416. width: 100%;
  417. height: 96upx;
  418. background-color: #fff;
  419. font-size: 30upx;
  420. color: #282828;
  421. position:sticky;
  422. top: 0;
  423. left: 0;
  424. z-index: 99;
  425. }
  426. .pos-order-list .nav .item.on {
  427. color: #2291f8;
  428. }
  429. .pos-order-list .list {
  430. margin-top: 24upx;
  431. }
  432. .pos-order-list .nothing{
  433. margin-top: 120upx;
  434. text-align: center;
  435. color: #cfcfcf;
  436. }
  437. .pos-order-list .list .item {
  438. background-color: #fff;
  439. width: 100%;
  440. }
  441. .pos-order-list .list .item~.item {
  442. margin-top: 24upx;
  443. }
  444. .pos-order-list .list .item .order-num {
  445. height: 124upx;
  446. border-bottom: 1px solid #eee;
  447. font-size: 30upx;
  448. font-weight: bold;
  449. color: #282828;
  450. padding: 0 30upx;
  451. }
  452. .pos-order-list .list .item .order-num .state{
  453. color: #2291f8;
  454. font-weight: normal;
  455. }
  456. .pos-order-list .list .item .order-num .state.on{
  457. font-size: 24rpx;
  458. width: 150rpx;
  459. text-align: right;
  460. }
  461. .pos-order-list .list .item .order-num .time {
  462. font-size: 26upx;
  463. font-weight: normal;
  464. color: #999;
  465. }
  466. .pos-order-list .list .item .operation {
  467. padding: 20upx 30upx;
  468. margin-top: 3upx;
  469. }
  470. .pos-order-list .list .item .operation .more {
  471. position: relative;
  472. }
  473. .pos-order-list .list .item .operation .icon-gengduo {
  474. font-size: 50upx;
  475. color: #aaa;
  476. }
  477. .pos-order-list .list .item .operation .order .arrow {
  478. width: 0;
  479. height: 0;
  480. border-left: 11upx solid transparent;
  481. border-right: 11upx solid transparent;
  482. border-top: 20upx solid #e5e5e5;
  483. position: absolute;
  484. left: 15upx;
  485. bottom: -18upx;
  486. }
  487. .pos-order-list .list .item .operation .order .arrow:before {
  488. content: '';
  489. width: 0;
  490. height: 0;
  491. border-left: 7upx solid transparent;
  492. border-right: 7upx solid transparent;
  493. border-top: 20upx solid #fff;
  494. position: absolute;
  495. left: -7upx;
  496. bottom: 0;
  497. }
  498. .pos-order-list .list .item .operation .order {
  499. width: 200upx;
  500. background-color: #fff;
  501. border: 1px solid #eee;
  502. border-radius: 10upx;
  503. position: absolute;
  504. top: -100upx;
  505. z-index: 9;
  506. }
  507. .pos-order-list .list .item .operation .order .items {
  508. height: 77upx;
  509. line-height: 77upx;
  510. text-align: center;
  511. }
  512. .pos-order-list .list .item .operation .order .items~.items {
  513. border-top: 1px solid #f5f5f5;
  514. }
  515. .pos-order-list .list .item .operation .bnt {
  516. font-size: 28upx;
  517. color: #5c5c5c;
  518. width: 170upx;
  519. height: 60upx;
  520. border-radius: 30upx;
  521. border: 1px solid #bbb;
  522. text-align: center;
  523. line-height: 60upx;
  524. &.on{
  525. color: #c5c8ce!important;
  526. background-color: #f7f7f7!important;
  527. border-color: #dcdee2!important;
  528. }
  529. }
  530. .pos-order-list .list .item .operation .bnt~.bnt {
  531. margin-left: 14upx;
  532. }
  533. .pos-order-list .list .item .operation .wait{
  534. margin-left: 30rpx;
  535. }
  536. .pos-order-goods {
  537. padding: 0 30upx;
  538. background-color: #fff;
  539. }
  540. .pos-order-goods .goods {
  541. padding: 28rpx 0;
  542. }
  543. .pos-order-goods .goods~.goods {
  544. border-top: 1px dashed #e5e5e5;
  545. }
  546. .pos-order-goods .goods .picTxt {
  547. width: 515upx;
  548. }
  549. .pos-order-goods .goods .picTxt .pictrue {
  550. width: 130upx;
  551. height: 130upx;
  552. }
  553. .pos-order-goods .goods .picTxt .pictrue image {
  554. width: 100%;
  555. height: 100%;
  556. border-radius: 6upx;
  557. }
  558. .pos-order-goods .goods .picTxt .text {
  559. width: 365upx;
  560. height: 130upx;
  561. }
  562. .pos-order-goods .goods .picTxt .text .info {
  563. width: 100%;
  564. font-size: 28upx;
  565. color: #282828;
  566. }
  567. .pos-order-goods .goods .picTxt .text .info .label{
  568. color: #ff4c3c;
  569. }
  570. .pos-order-goods .goods .picTxt .text .attr {
  571. width: 100%;
  572. overflow: hidden;
  573. white-space: nowrap;
  574. text-overflow: ellipsis;
  575. font-size: 24upx;
  576. color: #999;
  577. }
  578. .pos-order-goods .goods .money {
  579. width: 164upx;
  580. text-align: right;
  581. font-size: 28upx;
  582. }
  583. .pos-order-goods .goods .money .info{
  584. margin-top: 18rpx;
  585. font-size: 24rpx;
  586. }
  587. .pos-order-goods .goods .money .x-money {
  588. color: #282828;
  589. }
  590. .pos-order-goods .goods .money .num {
  591. color: #ff9600;
  592. margin: 5upx 0;
  593. }
  594. .pos-order-goods .goods .money .y-money {
  595. color: #999;
  596. text-decoration: line-through;
  597. }
  598. .public-total {
  599. font-size: 28upx;
  600. color: #282828;
  601. border-top: 1px solid #eee;
  602. height: 92upx;
  603. line-height: 92upx;
  604. text-align: right;
  605. padding: 0 30upx;
  606. background-color: #fff;
  607. }
  608. .public-total .money {
  609. color: #ff4c3c;
  610. }
  611. </style>