index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. <template>
  2. <base-page>
  3. <view class="uni-flex uni-row page-height">
  4. <view class="common-wrap left-wrap" style="flex: 1;">
  5. <view class="header-box">
  6. <view class="order-time">
  7. <view class="title">消费时间</view>
  8. <uni-datetime-picker v-model="orderData.create_time" type="datetime" :clearIcon="false" />
  9. </view>
  10. <view class="header" v-if="memberInfo" :style="'background-image:url(' + $util.img('public/uniapp/cashier/member-bg.png') + ');background-repeat: no-repeat;'">
  11. <view class="headimg" @click="showMember">
  12. <image
  13. class="header-image"
  14. :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.img(defaultImg.head)"
  15. @error="memberInfo.headimg = defaultImg.head"
  16. ></image>
  17. </view>
  18. <view class="head-info" @click="showMember">
  19. <view class="head-info-top">
  20. <view class="name">
  21. <view class="text">{{ memberInfo.nickname }}</view>
  22. <view class="level" v-if="memberInfo.member_level">{{ memberInfo.member_level_name }}</view>
  23. </view>
  24. <view class="mobile">{{ memberInfo.mobile }}</view>
  25. </view>
  26. <view class="head-info-bottom">
  27. <view>积分:{{ memberInfo.point }}</view>
  28. <view>余额:{{ (parseFloat(memberInfo.balance_money) + parseFloat(memberInfo.balance)) | moneyFormat }}</view>
  29. </view>
  30. </view>
  31. <button class="switch primary-btn" @click="$refs.selectMember.open()">更换会员</button>
  32. <button class="switch primary-btn" @click="replaceMember()">散客</button>
  33. </view>
  34. <view class="header" v-else :style="'background-image:url(' + $util.img('public/uniapp/cashier/member-bg.png') + ');background-repeat: no-repeat;'">
  35. <view class="headimg"><image class="header-image" :src="$util.img(defaultImg.head)"></image></view>
  36. <view class="head-info"><view class="name">散客</view></view>
  37. <button class="switch primary-btn" @click="$refs.selectMember.open()">查询会员</button>
  38. </view>
  39. </view>
  40. <view class="content">
  41. <view class="title">
  42. <view>
  43. 结算清单(
  44. <text>{{ orderData.goods_num.toFixed(2) }}</text>
  45. </view>
  46. <view class="clear" @click="clearGoods">
  47. <text class="iconfont iconqingchushujuku"></text>
  48. <text>清空</text>
  49. </view>
  50. </view>
  51. <view class="content-list common-scrollbar">
  52. <block v-if="orderData.goods_list.length && Object.keys(goodsData).length">
  53. <view class="content-item" v-for="(item, index) in orderData.goods_list" :key="index" @click="callBox(item)">
  54. <view class="item-img">
  55. <image
  56. :src="$util.img(item.goods_image.split(',')[0], { size: 'small' })"
  57. mode="widthFix"
  58. @error="item.goods_image = $util.img('public/uniapp/default_img/goods.png')"
  59. ></image>
  60. </view>
  61. <view class="item-info">
  62. <view class="item-name">{{ item.sku_name }}</view>
  63. <view class="item-del" @click="deleteGoods(item)">删除</view>
  64. <view class="item-spe">{{ item.spec_name }}</view>
  65. <view class="card-name" v-if="item.card_item_id && goodsData['sku_name' + item.sku_id + 'item_id' + item.card_item_id]">
  66. 使用卡项:{{ goodsData['sku_name' + item.sku_id + 'item_id' + item.card_item_id].card_name }}
  67. </view>
  68. <view class="item-price">
  69. <text class="member-price" v-if="item.is_member_price">Svip</text>
  70. <text class="unit">¥</text>
  71. {{ item.price | moneyFormat }}
  72. </view>
  73. </view>
  74. <view class="item-num" v-if="item.goods_class != 6">
  75. <view class="num-dec" @click="dec(item)">-</view>
  76. <view class="num" v-if="item.card_item_id && goodsData['sku_' + item.sku_id + 'item_id' + item.card_item_id]">
  77. {{ goodsData['sku_' + item.sku_id + 'item_id' + item.card_item_id].num }}
  78. </view>
  79. <view class="num" v-else-if="goodsData['sku_' + item.sku_id]">{{ goodsData['sku_' + item.sku_id].num }}</view>
  80. <view class="num" v-else>{{ item.num }}</view>
  81. <view class="num-inc" @click="inc(item)">+</view>
  82. </view>
  83. <view class="item-num" v-if="item.goods_class == 6">
  84. <view class="num" v-if="item.card_item_id && goodsData['sku_' + item.sku_id + 'item_id' + item.card_item_id]">
  85. {{ goodsData['sku_' + item.sku_id + 'item_id' + item.card_item_id].num }}
  86. </view>
  87. <view class="num" v-else-if="goodsData['sku_' + item.sku_id]">{{ goodsData['sku_' + item.sku_id].num }}</view>
  88. <view class="num" v-else>{{ item.num }}</view>
  89. <view>{{item.unit}}</view>
  90. </view>
  91. <view class="card-deduction" v-if="item.card_info && Object.keys(item.card_info).length">
  92. 卡项抵扣:{{ item.card_info.goods_name }}抵扣¥{{ item.num * item.goods_money }}({{ item.num }}次)
  93. </view>
  94. </view>
  95. </block>
  96. <block v-else>
  97. <view class="empty">
  98. <image :src="$util.img('public/uniapp/cashier/cart_empty.png')" mode="widthFix"></image>
  99. <view class="tips">点击右侧商品,选择商品进行结账</view>
  100. </view>
  101. </block>
  102. </view>
  103. </view>
  104. <view class="bottom">
  105. <view class="bottom-info">
  106. <view class="bottom-left">
  107. <text>{{ orderData.goods_num.toFixed(2) }}</text>
  108. </view>
  109. <view class="bottom-right"></view>
  110. </view>
  111. <view class="bottom-btn">
  112. <button class="default-btn btn-left" :disabled="orderData.goods_num == 0" @click="pay('cash')">现金收款</button>
  113. <button class="primary-btn btn-right" :disabled="orderData.goods_num == 0" @click="pay('')">收款¥{{ orderData.pay_money | moneyFormat }}</button>
  114. </view>
  115. </view>
  116. <view class="pay-shade" v-show="type == 'pay'"></view>
  117. </view>
  118. <view class="uni-flex uni-row common-wrap" style="flex: 2;">
  119. <view class="comp-wrap" v-show="type != 'pay'">
  120. <button class=" comp-btn" :class="type == 'goods' ? 'primary-btn' : 'default-btn'" @click="type = 'goods'">商品</button>
  121. <button class=" comp-btn" :class="type == 'member' ? 'primary-btn' : 'default-btn'" @click="showMember">会员</button>
  122. <button class="comp-btn" :class="type == 'card' ? 'primary-btn' : 'default-btn'" @click="showMemberCard">会员卡项</button>
  123. <button class="default-btn comp-btn" @click="wholeOrderCancel()">整单取消</button>
  124. <view class="tag-parent">
  125. <button class="comp-btn" :class="type == 'order' ? 'primary-btn' : 'default-btn'" @click="hangingOrder">挂/取单</button>
  126. <text class="num-tag" v-if="orderNum > 0">{{ orderNum < 100 ? orderNum : '99+' }}</text>
  127. </view>
  128. </view>
  129. <view class="list-wrap" style="flex: 1;">
  130. <!-- 提单 -->
  131. <view v-show="type == 'order'"><nc-pend-order ref="order" @takeorder="takeorder"></nc-pend-order></view>
  132. <!-- 会员 -->
  133. <view class="content" v-show="type == 'member'">
  134. <nc-member-detail v-if="memberInfo" ref="memberDetail" :member-id="memberInfo.member_id"></nc-member-detail>
  135. </view>
  136. <!-- 会员卡项 -->
  137. <view class="content" v-show="type == 'card'"><nc-member ref="member" @selectGoods="selectMemberGoods"></nc-member></view>
  138. <!-- 商品 -->
  139. <view class="content" v-show="type == 'goods'"><nc-goods @select="selectGoods" :goods-ids="goodsIds" ref="goods"></nc-goods></view>
  140. <view class="content payment-content" v-show="type == 'pay'">
  141. <nc-payment ref="payment" :pay-money="orderData.pay_money" @cancel="cancelPayment" @success="paySuccess" :out-trade-no="outTradeNo"></nc-payment>
  142. </view>
  143. </view>
  144. </view>
  145. </view>
  146. <uni-popup ref="remarkPopup" type="center">
  147. <view class="remark-wrap">
  148. <view class="header">
  149. <text class="title">备注</text>
  150. <text class="iconfont iconguanbi1" @click="$refs.remarkPopup.close()"></text>
  151. </view>
  152. <view class="body"><textarea v-model="remark" placeholder="填写备注信息" placeholder-class="placeholder-class" /></view>
  153. <view class="footer"><button type="default" class="primary-btn" @click="remarkConfirm">确认</button></view>
  154. </view>
  155. <u-icon name="arrow-down"></u-icon>
  156. </uni-popup>
  157. <nc-select-member ref="selectMember"></nc-select-member>
  158. </base-page>
  159. </template>
  160. <script>
  161. import billing from './public/js/billing.js';
  162. import ncSelectMember from '@/components/nc-select-member/nc-select-member.vue';
  163. import ncMemberDetail from '@/components/nc-member-detail/nc-member-detail.vue';
  164. export default {
  165. components: { ncSelectMember, ncMemberDetail },
  166. onLoad() {
  167. uni.hideTabBar({});
  168. },
  169. data() {
  170. return {
  171. memberList: []
  172. };
  173. },
  174. mixins: [billing]
  175. };
  176. </script>
  177. <style>
  178. .header-box >>> .uni-select-lay-select {
  179. padding-right: 0.1rem !important;
  180. }
  181. .header-box >>> .uni-select-lay-icon {
  182. display: none !important;
  183. }
  184. .header-box >>> .uni-select-lay-input-close {
  185. display: none !important;
  186. }
  187. </style>
  188. <style lang="scss" scoped>
  189. .left-wrap {
  190. position: relative;
  191. max-width: 3.9rem;
  192. display: flex;
  193. flex-direction: column;
  194. .pay-shade {
  195. position: absolute;
  196. width: 100%;
  197. height: 100%;
  198. top: 0;
  199. left: 0;
  200. background-color: rgba($color: #fff, $alpha: 0.6);
  201. z-index: 10;
  202. }
  203. .header-box {
  204. padding: 0.15rem;
  205. border-bottom: 0.01rem solid #e6e6e6;
  206. .search-box {
  207. .head-search {
  208. display: flex;
  209. .search-switch {
  210. width: 0.7rem;
  211. }
  212. .search-input {
  213. margin-left: 0.1rem;
  214. display: flex;
  215. border-width: 0.01rem;
  216. border-style: solid;
  217. border-color: #e6e6e6;
  218. height: 0.3rem;
  219. align-items: center;
  220. padding-left: 0.05rem;
  221. width: calc(100% - 1.3rem);
  222. .iconfont {
  223. }
  224. input {
  225. margin-left: 0.05rem;
  226. }
  227. }
  228. .search-btn {
  229. width: 0.55rem;
  230. margin-left: 0.1rem;
  231. padding: 0 0.1rem;
  232. height: 0.32rem;
  233. font-size: 0.12rem;
  234. }
  235. }
  236. }
  237. }
  238. .header {
  239. margin-top: 0.15rem;
  240. height: 0.8rem;
  241. font-size: 0.2rem;
  242. display: flex;
  243. align-items: center;
  244. padding: 0 0.15rem;
  245. background-size: 100% 100%;
  246. border-radius: 0.03rem;
  247. .header-image {
  248. width: 0.5rem;
  249. height: 0.5rem;
  250. border-radius: 50%;
  251. }
  252. .head-info {
  253. flex: 1;
  254. margin-left: 0.1rem;
  255. .name {
  256. font-size: 0.16rem;
  257. color: #fff;
  258. display: flex;
  259. .level {
  260. background: #ffffff;
  261. border: 0.01rem solid $primary-color;
  262. border-radius: 0.02rem;
  263. font-size: 0.12rem;
  264. color: $primary-color;
  265. margin-left: 0.05rem;
  266. padding: 0.01rem 0.04rem;
  267. overflow: hidden;
  268. text-overflow: ellipsis;
  269. white-space: nowrap;
  270. }
  271. .text {
  272. max-width: 0.8rem;
  273. overflow: hidden;
  274. text-overflow: ellipsis;
  275. white-space: nowrap;
  276. }
  277. }
  278. .mobile {
  279. font-size: 0.14rem;
  280. color: #fff;
  281. margin-top: 0.04rem;
  282. }
  283. .head-info-bottom {
  284. display: flex;
  285. flex-wrap: wrap;
  286. justify-content: space-between;
  287. margin-top: 0.05rem;
  288. view {
  289. color: #fff;
  290. font-size: $uni-font-size-sm;
  291. }
  292. }
  293. }
  294. .switch {
  295. text-align: center;
  296. line-height: 0.3rem;
  297. margin-left: 0.08rem;
  298. padding: 0 0.05rem;
  299. overflow: hidden;
  300. font-size: $uni-font-size-sm;
  301. text-overflow: ellipsis;
  302. white-space: nowrap;
  303. }
  304. }
  305. .order-time {
  306. display: flex;
  307. align-items: center;
  308. .title {
  309. user-select: none;
  310. position: relative;
  311. z-index: 3;
  312. height: 0.3rem;
  313. padding: 0 0.1rem 0 0.1rem;
  314. box-sizing: border-box;
  315. border-radius: 0.02rem;
  316. border: 0.01rem solid #e5e5e5;
  317. display: flex;
  318. align-items: center;
  319. font-size: 0.14rem;
  320. color: #333;
  321. box-sizing: border-box;
  322. }
  323. .uni-date {
  324. flex: 1;
  325. margin-left: 0.1rem;
  326. }
  327. /deep/ .uni-date-x {
  328. height: 0.28rem;
  329. }
  330. }
  331. .content {
  332. padding: 0.15rem;
  333. color: #303133;
  334. flex: 1;
  335. height: 0;
  336. display: flex;
  337. flex-direction: column;
  338. .title {
  339. font-size: 0.14rem;
  340. display: flex;
  341. justify-content: space-between;
  342. }
  343. .clear {
  344. display: flex;
  345. align-items: center;
  346. text {
  347. &:nth-child(1) {
  348. font-size: 0.18rem;
  349. }
  350. &:nth-child(2) {
  351. margin-left: 0.03rem;
  352. font-size: 0.14rem;
  353. }
  354. }
  355. }
  356. .content-list {
  357. margin-top: 0.1rem;
  358. flex: 1;
  359. height: 0;
  360. overflow-y: scroll;
  361. .content-item {
  362. position: relative;
  363. .flex {
  364. display: flex;
  365. align-items: center;
  366. }
  367. display: flex;
  368. align-items: center;
  369. flex-wrap: wrap;
  370. justify-content: space-between;
  371. border-bottom: 0.01rem solid #e6e6e6;
  372. padding: 0.1rem 0;
  373. .item-img {
  374. width: 0.5rem;
  375. height: 0.5rem;
  376. display: flex;
  377. align-items: center;
  378. image {
  379. width: 100%;
  380. }
  381. }
  382. .item-info {
  383. flex: 1;
  384. margin-left: 0.1rem;
  385. width: 0;
  386. min-width: 0;
  387. .item-name {
  388. font-size: 0.14rem;
  389. white-space: nowrap;
  390. overflow: hidden;
  391. text-overflow: ellipsis;
  392. width: 2rem;
  393. }
  394. .del {
  395. margin-right: -0.8rem;
  396. margin-top: -0.2rem;
  397. color: #8558fa;
  398. font-size: 0.14rem;
  399. float: right;
  400. }
  401. .item-spe {
  402. font-size: 0.1rem;
  403. color: #999;
  404. margin-top: 0.05rem;
  405. }
  406. .card-name {
  407. font-size: 0.12rem;
  408. margin-top: 0.05rem;
  409. white-space: nowrap;
  410. overflow: hidden;
  411. text-overflow: ellipsis;
  412. color: #999;
  413. }
  414. .member-price {
  415. border-radius: 0.02rem;
  416. padding: 0.01rem 0.05rem;
  417. background-color: rgba($primary-color, $alpha: 0.1);
  418. color: #8558fa;
  419. font-size: 0.12rem;
  420. margin-right: 0.05rem;
  421. }
  422. .item-price {
  423. font-size: 0.14rem;
  424. margin-top: 0.05rem;
  425. margin-left: -0.03rem;
  426. .unit {
  427. font-size: 0.12rem;
  428. }
  429. }
  430. }
  431. .item-num {
  432. display: flex;
  433. align-items: center;
  434. margin-left: 0.1rem;
  435. margin-top: 0.3rem;
  436. .num-dec {
  437. width: 0.25rem;
  438. height: 0.25rem;
  439. background: #e6e6e6;
  440. border: 0.01rem solid #e6e6e6;
  441. border-radius: 30%;
  442. text-align: center;
  443. line-height: 0.23rem;
  444. font-size: 0.25rem;
  445. margin-right: 0.1rem;
  446. cursor: pointer;
  447. transition: 0.3s;
  448. }
  449. .num-inc {
  450. width: 0.25rem;
  451. height: 0.25rem;
  452. background: $primary-color;
  453. border: 0.01rem solid #e6e6e6;
  454. border-radius: 30%;
  455. text-align: center;
  456. line-height: 0.23rem;
  457. font-size: 0.25rem;
  458. margin-left: 0.1rem;
  459. cursor: pointer;
  460. transition: 0.3s;
  461. color: #fff;
  462. }
  463. }
  464. .item-total-price {
  465. font-size: 0.14rem;
  466. margin-left: 0.1rem;
  467. color: #fe2278;
  468. }
  469. .item-del {
  470. position: absolute;
  471. right: 0;
  472. color: $primary-color;
  473. cursor: pointer;
  474. margin-top: -0.2rem;
  475. font-size: 0.14rem;
  476. }
  477. .card-deduction {
  478. width: 100%;
  479. font-size: 0.12rem;
  480. margin-top: 0.05rem;
  481. color: #999;
  482. }
  483. }
  484. }
  485. .empty {
  486. text-align: center;
  487. image {
  488. width: 60%;
  489. margin-top: 0.4rem;
  490. }
  491. .tips {
  492. color: #999;
  493. margin-top: 0.15rem;
  494. }
  495. }
  496. }
  497. .bottom {
  498. width: 100%;
  499. padding: 0.15rem;
  500. box-sizing: border-box;
  501. background-color: #ffffff;
  502. border-top: 0.01rem solid #e6e6e6;
  503. .bottom-info {
  504. display: flex;
  505. align-items: center;
  506. justify-content: space-between;
  507. .bottom-left {
  508. font-size: 0.14rem;
  509. color: #303133;
  510. opacity: 0.8;
  511. .money {
  512. color: #fe2278;
  513. }
  514. }
  515. .bottom-right {
  516. font-size: 0.14rem;
  517. color: #303133;
  518. opacity: 0.8;
  519. i {
  520. font-size: 0.14rem;
  521. }
  522. }
  523. }
  524. .bottom-btn {
  525. display: flex;
  526. align-items: center;
  527. margin-top: 0.1rem;
  528. .btn-left {
  529. width: 1.3rem;
  530. height: 0.4rem;
  531. line-height: 0.4rem;
  532. }
  533. .btn-right {
  534. flex: 1;
  535. margin-left: 0.15rem;
  536. height: 0.4rem;
  537. line-height: 0.4rem;
  538. }
  539. }
  540. }
  541. }
  542. .comp-wrap {
  543. min-width: 1rem;
  544. border: 0.01rem solid #e6e6e6;
  545. border-radius: 0.02rem;
  546. padding: 0.2rem 0.17rem;
  547. .tag-parent {
  548. position: relative;
  549. .num-tag {
  550. position: absolute;
  551. background-color: #f00;
  552. color: #fff;
  553. height: 0.18rem;
  554. line-height: 0.18rem;
  555. padding: 0 0.06rem;
  556. border-radius: 0.1rem;
  557. font-size: 0.12rem;
  558. text-align: center;
  559. z-index: 1;
  560. top: 0;
  561. right: 0.12rem;
  562. transform: translateY(-50%) translateX(100%);
  563. }
  564. }
  565. .comp-btn {
  566. overflow: initial;
  567. margin-bottom: 0.2rem;
  568. }
  569. }
  570. .payment-content {
  571. border-left: 0.01rem solid #e6e6e6;
  572. padding-left: 0.17rem;
  573. }
  574. .list-wrap {
  575. padding: 0 0.2rem;
  576. border: 0.01rem solid #e6e6e6;
  577. border-radius: 0.02rem;
  578. height: 100%;
  579. border-left: 0;
  580. box-sizing: border-box;
  581. width: 0;
  582. .content {
  583. height: 100%;
  584. }
  585. .comp-btn {
  586. width: 80%;
  587. box-align: center;
  588. margin-top: 0.2rem;
  589. }
  590. .header {
  591. height: 0.66rem;
  592. line-height: 0.66rem;
  593. text-align: left;
  594. border-bottom: 0.01rem solid #e6e6e6;
  595. color: #303133;
  596. font-size: 0.14rem;
  597. }
  598. .body {
  599. padding: 0.3rem;
  600. }
  601. }
  602. .page-height {
  603. height: 100%;
  604. }
  605. .common-wrap {
  606. height: 100%;
  607. }
  608. .remark-wrap {
  609. width: 6rem;
  610. background-color: #fff;
  611. border-radius: 0.04rem;
  612. box-shadow: 0 0.01rem 0.12rem 0 rgba(0, 0, 0, 0.1);
  613. .header {
  614. display: flex;
  615. justify-content: space-between;
  616. align-items: center;
  617. padding: 0 0.15rem;
  618. height: 0.45rem;
  619. line-height: 0.45rem;
  620. border-bottom: 0.01rem solid #e8eaec;
  621. .iconfont {
  622. font-size: $uni-font-size-lg;
  623. }
  624. }
  625. .body {
  626. padding: 0.15rem 0.15rem 0.1rem;
  627. textarea {
  628. border: 0.01rem solid #e6e6e6;
  629. width: 100%;
  630. padding: 0.1rem;
  631. box-sizing: border-box;
  632. font-size: 0.14rem;
  633. }
  634. .placeholder-class {
  635. font-size: 0.14rem;
  636. }
  637. }
  638. .footer {
  639. height: 0.5rem;
  640. padding-bottom: 0.05rem;
  641. display: flex;
  642. align-items: center;
  643. justify-content: center;
  644. button {
  645. width: 95%;
  646. }
  647. }
  648. }
  649. </style>