handle.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. <template>
  2. <mobile-frame>
  3. <view class="main">
  4. <view class="one">
  5. <button size="mini" @tap="toDislog">查询条件</button>
  6. </view>
  7. <view class="two">
  8. <scroll-view scroll-y="true" class="scroll-view" @scrolltolower="toPage" @scroll="toScroll">
  9. <view class="list-scroll-view">
  10. <view class="list" v-for="(item,index) in list" :key="index">
  11. <view class="list_1">
  12. <view class="list_1_1">
  13. <view class="shopname">
  14. <text class="iconfont icon-shangdian"></text>
  15. <text>{{item.shop.name}}</text>
  16. </view>
  17. <view class="status">
  18. {{item.zhStatus||'暂无'}}
  19. </view>
  20. </view>
  21. <view class="list_1_2">
  22. <view class="goods">
  23. <view class="goods_1">
  24. <image class="image" v-if="item.spec.file&&item.spec.file.length>0"
  25. :src="item.spec.file&&item.spec.file.length>0?item.spec.file[0].url:''"
  26. mode=""></image>
  27. <image class="image" v-else
  28. :src="item.goods.file&&item.goods.file.length>0?item.goods.file[0].url:''"
  29. mode=""></image>
  30. </view>
  31. <view class="goods_2">
  32. <view class="goodsname textOver">
  33. {{item.goods.name}}
  34. </view>
  35. <view class="specs">
  36. {{item.spec.name}}
  37. </view>
  38. <view class="time">
  39. 购买者:{{item.customer.name}}
  40. </view>
  41. <view class="time">
  42. 购买时间:{{item.buy_time}}
  43. </view>
  44. </view>
  45. <view class="goods_3">
  46. <view class="price">
  47. ¥{{item.spec.price||0}}
  48. </view>
  49. <view class="num">
  50. ×{{item.num||0}}
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. <view class="other">
  56. <text>共{{item.num||0}}件商品</text>
  57. <text>实付款¥{{item.pay}}</text>
  58. </view>
  59. </view>
  60. <view class="btn">
  61. <button type="default" size="mini" @tap.stop="toView(item,'order')">详细信息</button>
  62. <button v-if="item.status=='2'||item.status=='3'||item.status=='2-'" size="mini"
  63. @tap.stop="toLogi(item)">查看物流</button>
  64. <button v-if="item.is_afterSale==true" size="mini" @tap.stop="toHandle(item)">售后处理</button>
  65. </view>
  66. </view>
  67. <view class="is_bottom" v-if="is_bottom">
  68. <text>{{config.bottom_title}}</text>
  69. </view>
  70. </view>
  71. </scroll-view>
  72. </view>
  73. <view class="dialog" v-if="dialog.show==true">
  74. <view class="dialog_1" v-if="dialog.type=='1'">
  75. <uni-forms ref="form" :modelValue="searchInfo" :rules="rules" label-width="auto">
  76. <uni-forms-item label="购买者" name="customer_name">
  77. <uni-easyinput type="text" v-model="searchInfo.customer_name" placeholder="请输入购买者姓名" />
  78. </uni-forms-item>
  79. <uni-forms-item label="状态" name="status">
  80. <picker class="picker" mode="selector" :range="statusList" @change="statusChange"
  81. range-key="label">
  82. <view>{{status_name||'请选择状态'}}</view>
  83. </picker>
  84. </uni-forms-item>
  85. </uni-forms>
  86. <view class="btn">
  87. <button type="primary" @click="onSubmit" size="mini">确定</button>
  88. <button type="primary" @click="dialogClose" size="mini">取消</button>
  89. </view>
  90. </view><view class="dialog_1" v-else-if="dialog.type=='2'">
  91. <uni-forms ref="form" :modelValue="afterInfo" :rules="rules" label-width="auto">
  92. <uni-forms-item label="售后类型" name="zhType">
  93. <uni-easyinput disabled type="text" v-model="afterInfo.zhType" placeholder="请输入售后类型" />
  94. </uni-forms-item>
  95. <uni-forms-item label="售后状态" name="zhStatus">
  96. <uni-easyinput disabled type="text" v-model="afterInfo.zhStatus" placeholder="请输入售后状态" />
  97. </uni-forms-item>
  98. <uni-forms-item label="申请理由" name="zhReason">
  99. <uni-easyinput disabled type="text" v-model="afterInfo.zhReason" placeholder="请输入申请理由" />
  100. </uni-forms-item>
  101. <uni-forms-item label="退款金额" name="money">
  102. <uni-easyinput disabled type="text" v-model="afterInfo.money" placeholder="请输入退款金额" />
  103. </uni-forms-item>
  104. <uni-forms-item label="售后申请时间" name="apply_time">
  105. <uni-easyinput disabled type="text" v-model="afterInfo.apply_time" placeholder="请输入售后申请时间" />
  106. </uni-forms-item>
  107. <uni-forms-item label="申请售后描述" name="desc">
  108. <uni-easyinput disabled type="textarea" v-model="afterInfo.desc" placeholder="请输入申请售后描述" />
  109. </uni-forms-item>
  110. </uni-forms>
  111. <view class="btn">
  112. <button type="primary" @click="toAgree(true)" size="mini">同意</button>
  113. <button type="primary" @click="toAgree(false)" size="mini">不同意</button>
  114. </view>
  115. </view>
  116. </view>
  117. </view>
  118. </mobile-frame>
  119. </template>
  120. <script>
  121. export default {
  122. data() {
  123. return {
  124. // 系统设置
  125. config: {},
  126. // 设备信息
  127. system: {},
  128. user: {},
  129. id: '',
  130. searchInfo: {},
  131. list: [],
  132. afterInfo:{},
  133. total: 0,
  134. skip: 0,
  135. limit: 6,
  136. page: 0,
  137. // 数据是否触底
  138. is_bottom: false,
  139. scrollTop: 0,
  140. // 字典表
  141. statusList: [],
  142. // 售后类型
  143. typeList:[],
  144. // 售后状态
  145. astatusList:[],
  146. // 理由
  147. reasonList:[],
  148. status_name: "",
  149. // 条件弹出框
  150. dialog: {
  151. show: false,
  152. type: '1'
  153. }
  154. };
  155. },
  156. onLoad: function(e) {
  157. const that = this;
  158. that.$set(that, `id`, e.id || '');
  159. that.searchConfig();
  160. },
  161. onShow: async function(e) {
  162. const that = this;
  163. await that.searchOther();
  164. await that.watchlogin();
  165. },
  166. onPullDownRefresh: async function() {
  167. const that = this;
  168. that.clearPage();
  169. await that.search();
  170. uni.stopPullDownRefresh();
  171. },
  172. methods: {
  173. // 查询基本设置
  174. searchConfig() {
  175. const that = this;
  176. uni.getStorage({
  177. key: 'config',
  178. success: function(res) {
  179. if (res.data) that.$set(that, `config`, res.data)
  180. // 设备平台信息
  181. let config = that.$config;
  182. that.$set(that, `system`, config.system);
  183. },
  184. fail: function(err) {
  185. console.log(err);
  186. }
  187. })
  188. },
  189. // 监听用户是否登录
  190. watchlogin() {
  191. const that = this;
  192. uni.getStorage({
  193. key: 'token',
  194. success: function(res) {
  195. let user = that.$jwt(res.data);
  196. if (user) {
  197. that.$set(that, `user`, user)
  198. that.search();
  199. }
  200. }
  201. })
  202. },
  203. async search() {
  204. const that = this;
  205. let info = {
  206. skip: that.skip,
  207. limit: that.limit,
  208. group: that.id
  209. }
  210. let res = await that.$api(`/groupOrder/userView`, 'GET', {
  211. ...info,
  212. ...that.searchInfo
  213. }, 'group');
  214. if (res.errcode == '0') {
  215. let list = [...that.list, ...res.data];
  216. for (let val of list) {
  217. if (val.status) val.zhStatus = that.searchStatus(val.status)
  218. }
  219. that.$set(that, `list`, list);
  220. that.$set(that, `total`, res.total)
  221. } else {
  222. uni.showToast({
  223. title: res.errmsg,
  224. icon: 'none'
  225. })
  226. }
  227. },
  228. // 查询状态
  229. searchStatus(e) {
  230. const that = this;
  231. let data = that.statusList.find((i) => i.value == e);
  232. if (data) return data.label
  233. else return '暂无'
  234. },
  235. // 订单详细信息
  236. toView(item) {
  237. const that = this;
  238. that.clearPage();
  239. uni.navigateTo({
  240. url: `/pagesMy/dough/info?id=${item._id}`
  241. })
  242. },
  243. // 分页
  244. toPage(e) {
  245. const that = this;
  246. let list = that.list;
  247. let limit = that.limit;
  248. if (that.total > list.length) {
  249. uni.showLoading({
  250. title: '加载中',
  251. mask: true
  252. })
  253. let page = that.page + 1;
  254. that.$set(that, `page`, page)
  255. let skip = page * limit;
  256. that.$set(that, `skip`, skip)
  257. that.search();
  258. uni.hideLoading();
  259. } else that.$set(that, `is_bottom`, true)
  260. },
  261. toScroll(e) {
  262. const that = this;
  263. let up = that.scrollTop;
  264. that.$set(that, `scrollTop`, e.detail.scrollTop);
  265. let num = Math.sign(up - e.detail.scrollTop);
  266. if (num == 1) that.$set(that, `is_bottom`, false);
  267. },
  268. // 查询条件
  269. toDislog() {
  270. const that = this;
  271. that.$set(that, `searchInfo`, {})
  272. that.$set(that, `status_name`, '')
  273. that.$set(that, `dialog`, {
  274. show: true,
  275. type: '1'
  276. })
  277. },
  278. // 售后处理
  279. async toHandle(e){
  280. const that = this;
  281. let res = await that.$api(`/groupAfterSale`, 'GET', {
  282. order:e._id,
  283. customer:e.customer._id
  284. }, 'group')
  285. if (res.errcode == '0') {
  286. for (let val of res.data) {
  287. let type = that.typeList.find(i => i.value == val.type)
  288. if (type) val.zhType = type.label;
  289. let status = that.astatusList.find(i => i.value == val.status)
  290. if (status) val.zhStatus = status.label;
  291. let reason = that.reasonList.find(i => i.value == val.reason)
  292. if (reason) val.zhReason = reason.label;
  293. }
  294. that.$set(that, `afterInfo`, res.data[0]);
  295. }
  296. that.$set(that, `dialog`, {
  297. show: true,
  298. type: '2'
  299. })
  300. },
  301. // 售后同意
  302. async toAgree(e){
  303. const that = this;
  304. uni.showModal({
  305. title: '提示',
  306. content: '确定处理该订单吗?',
  307. success: async function(res) {
  308. if (res.confirm) {
  309. let arr = await that.$api(`/groupAfterSale/${that.afterInfo._id}`, 'POST', {
  310. leader_suggest: e
  311. }, 'group')
  312. if (arr.errcode == '0') {
  313. uni.showToast({
  314. title: '处理完成',
  315. icon: 'none'
  316. })
  317. that.$set(that, `dialog`, {
  318. show: false,
  319. type: '2'
  320. })
  321. that.$set(that, `afterInfo`, {})
  322. that.clearPage();
  323. that.search();
  324. } else {
  325. uni.showToast({
  326. title: arr.errmsg,
  327. icon: 'none'
  328. })
  329. that.$set(that, `dialog`, {
  330. show: false,
  331. type: '2'
  332. })
  333. that.$set(that, `afterInfo`, {})
  334. that.clearPage();
  335. that.search();
  336. }
  337. }
  338. }
  339. });
  340. },
  341. // 状态选择
  342. statusChange(e) {
  343. const that = this;
  344. let data = that.statusList[e.detail.value];
  345. if (data) {
  346. that.$set(that.searchInfo, `status`, data.value);
  347. that.$set(that, `status_name`, data.label);
  348. }
  349. },
  350. // 关闭弹框
  351. dialogClose() {
  352. const that = this;
  353. that.clearPage();
  354. that.search();
  355. that.$set(that, `dialog`, {
  356. show: false,
  357. type: '1'
  358. })
  359. },
  360. // 查询
  361. onSubmit() {
  362. const that = this;
  363. that.clearPage();
  364. that.search();
  365. that.$set(that, `dialog`, {
  366. show: false,
  367. type: '1'
  368. })
  369. },
  370. // 查看物流
  371. toLogi(e) {
  372. const that = this;
  373. that.clearPage();
  374. uni.navigateTo({
  375. url: `/pagesMy/logistics/index?id=${e._id}&type=${'groupOrder'}`
  376. })
  377. },
  378. // 查询其他信息
  379. async searchOther() {
  380. const that = this;
  381. let res;
  382. // 查询状态
  383. res = await that.$api(`/dictData`, 'GET', {
  384. code: 'order_process'
  385. })
  386. if (res.errcode == '0') that.$set(that, `statusList`, res.data);
  387. res = await that.$api(`/dictData`, 'GET', {
  388. code: "afterSale_type"
  389. });
  390. if (res.errcode == '0') that.$set(that, `typeList`, res.data)
  391. res = await that.$api(`/dictData`, 'GET', {
  392. code: "afterSale_status"
  393. });
  394. if (res.errcode == '0') that.$set(that, `astatusList`, res.data)
  395. res = await that.$api(`/dictData`, 'GET', {
  396. code: "afterSale_reason"
  397. });
  398. if (res.errcode == '0') that.$set(that, `reasonList`, res.data)
  399. },
  400. // 清空列表
  401. clearPage() {
  402. const that = this;
  403. that.$set(that, `list`, [])
  404. that.$set(that, `skip`, 0)
  405. that.$set(that, `limit`, 6)
  406. that.$set(that, `page`, 0)
  407. }
  408. },
  409. }
  410. </script>
  411. <style lang="scss">
  412. .main {
  413. display: flex;
  414. flex-direction: column;
  415. width: 100vw;
  416. height: 100vh;
  417. .one {
  418. padding: 2vw;
  419. text-align: center;
  420. button {
  421. background-color: #23B67A;
  422. color: #ffffff;
  423. }
  424. }
  425. .two {
  426. position: relative;
  427. flex-grow: 1;
  428. background-color: var(--f9Color);
  429. .list {
  430. background-color: #fff;
  431. border: 1px solid var(--f5Color);
  432. padding: 2vw;
  433. margin: 0 2vw 2vw 2vw;
  434. border-radius: 5px;
  435. .list_1 {
  436. .list_1_1 {
  437. display: flex;
  438. justify-content: space-between;
  439. margin: 0 0 2vw 0;
  440. .shopname {
  441. text:last-child {
  442. padding: 0 0 0 2vw;
  443. }
  444. }
  445. .status {
  446. color: var(--ff0Color);
  447. }
  448. }
  449. .list_1_2 {
  450. border-bottom: 1px solid #f1f1f1;
  451. .goods {
  452. display: flex;
  453. padding: 0 0 2vw 0;
  454. .goods_1 {
  455. width: 20vw;
  456. height: 20vw;
  457. .image {
  458. width: 100%;
  459. height: 100%;
  460. border-radius: 5px;
  461. }
  462. }
  463. .goods_2 {
  464. width: 55vw;
  465. padding: 0 0 0 2vw;
  466. .goodsname {
  467. font-size: 16px;
  468. margin: 0 0 1vw 0;
  469. }
  470. .specs {
  471. font-size: 14px;
  472. color: #858585;
  473. }
  474. .time {
  475. font-size: 13px;
  476. color: #858585;
  477. }
  478. }
  479. .goods_3 {
  480. width: 15vw;
  481. text-align: right;
  482. .price {
  483. color: #ff0000;
  484. }
  485. }
  486. }
  487. }
  488. .other {
  489. padding: 0 0 2vw 0;
  490. margin: 2vw 0;
  491. text-align: right;
  492. border-bottom: 1px solid #f1f1f1;
  493. text {
  494. font-size: 14px;
  495. padding: 0 0 0 2vw;
  496. }
  497. }
  498. }
  499. .btn {
  500. text-align: right;
  501. button {
  502. margin: 0 1vw 0 0;
  503. }
  504. }
  505. }
  506. }
  507. }
  508. .dialog {
  509. position: fixed;
  510. width: 96vw;
  511. height: 100vh;
  512. background-color: #ffffff;
  513. z-index: 99999;
  514. display: flex;
  515. flex-direction: column;
  516. padding: 2vw;
  517. .uni-input {
  518. border: #f1f1ff 1px solid;
  519. padding: 2vw 2vw;
  520. border-radius: 1vw;
  521. }
  522. .picker {
  523. border: 1px solid #3333;
  524. border-radius: 5px;
  525. padding: 2vw;
  526. }
  527. .btn {
  528. text-align: center;
  529. button {
  530. margin: 0 2vw 2vw 2vw;
  531. background-color: #23B67A;
  532. color: #ffffff;
  533. }
  534. .name {
  535. color: var(--f85Color);
  536. font-size: var(--font14Size);
  537. }
  538. }
  539. }
  540. .scroll-view {
  541. position: absolute;
  542. top: 0;
  543. left: 0;
  544. right: 0;
  545. bottom: 0;
  546. .list-scroll-view {
  547. display: flex;
  548. flex-direction: column;
  549. }
  550. }
  551. .is_bottom {
  552. text-align: center;
  553. text {
  554. padding: 2vw 0;
  555. display: inline-block;
  556. color: #858585;
  557. font-size: 14px;
  558. }
  559. }
  560. </style>