valetbuy.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. <template>
  2. <view class="content">
  3. <view class="" style="background-color: #4076d6;height: 100rpx;">
  4. </view>
  5. <view class="good-info-wrap">
  6. <view class="good-list">
  7. <view class="empty" v-if="xmlist.length == 0" @click="chooseGoods">
  8. 选择项目
  9. </view>
  10. <!-- 商品详情 -->
  11. <view class="good-wrap" v-else>
  12. <view class="good" v-for="goodsitem in xmlist">
  13. <image :src="goodsitem.image" mode="" class="good-img"></image>
  14. <view class="good-info">
  15. <view class="good-name clamp2">
  16. {{goodsitem.name}}
  17. </view>
  18. <view class="good-price">
  19. {{goodsitem.price}}
  20. </view>
  21. </view>
  22. </view>
  23. </view>
  24. </view>
  25. <view class="mjly">
  26. <view class="ly-left">
  27. 买家留言
  28. </view>
  29. <input type="text" placeholder="请输入留言内容" class="ly-right" v-model="mjly">
  30. </view>
  31. <view class="mjly">
  32. <view class="ly-left">
  33. 优惠价格
  34. </view>
  35. <input type="digit" placeholder="请输入优惠价格" class="ly-right" v-model="yhjg">
  36. </view>
  37. </view>
  38. <view class="mj-info" @click="goPage('/pagesT/customer/selCustomer')">
  39. <view class="mjly" style="border-bottom: 1rpx solid #f7f8fa;">
  40. <view class="ly-left">
  41. 客户姓名
  42. </view>
  43. <input type="text" placeholder="请输入留言内容" class="ly-right" v-model="customerData.name" v-if="customerData.name" disabled>
  44. <image src="../../static/img/downright.png" mode="" v-else></image>
  45. </view>
  46. <view class="mjly" >
  47. <view class="ly-left">
  48. 联系方式
  49. </view>
  50. <input type="number" placeholder="请填写联系方式" class="ly-right" v-model="customerData.mobile" @click.stop="">
  51. </view>
  52. </view>
  53. <!-- 选择门店 -->
  54. <view class="sc-md">
  55. <view class="sc-tip">
  56. 选择门店
  57. </view>
  58. <view class="store-info" @click="openStoreChoose" v-if="choose_store">
  59. <image :src="choose_store.logo" mode="" class="store-logo"></image>
  60. <view class="info">
  61. <view class="store-name">
  62. {{choose_store.name}}
  63. </view>
  64. <view class="store-address" v-if="choose_store.area">
  65. {{choose_store.area.provinceName + choose_store.area.cityName + choose_store.area.districtName + choose_store.area.address}}
  66. </view>
  67. </view>
  68. <view class="float_right"><text class="ibonfont ibonjinru"></text></view>
  69. </view>
  70. </view>
  71. <!-- 门店列表弹出层 -->
  72. <!-- 预约 -->
  73. <its-calendar :sta_num="start_time" :end_num="end_time" :int_num="30" @getTime="getTime"></its-calendar>
  74. <!-- 结算 -->
  75. <!-- 指派 -->
  76. <scroll-view scroll-x="true" class="zp-wrap" v-if="timed">
  77. <view class="zp-item" v-for="ygitem in yg.list" @click="choosYg(ygitem)"
  78. :class="{'choose': ygitem.uid == choose_yg.uid}">
  79. <image :src="ygitem.avatar" mode="" class="zp-logo"></image>
  80. <view class="zp-name">{{ygitem.staffName}}</view>
  81. </view>
  82. </scroll-view>
  83. <!-- 填充 -->
  84. <view class="" style="height: 110rpx;"></view>
  85. <view class="tj-dd">
  86. <view class="">
  87. <text style="font-size: 26rpx;color: #999;">实际支付:</text>
  88. <text style="color: #CE372E;font-size: 44rpx;font-weight: bold;padding-left: 10rpx;" class="rmb">{{(all_price*1-yhjg*1).toFixed(2)}}</text>
  89. </view>
  90. <view class="tj-btn" :class="{'canpay': canpay}" @click="canpay?submitt(): ''">
  91. 提交
  92. </view>
  93. </view>
  94. <!-- 门店选择弹窗 -->
  95. <u-popup v-model="store_choose_show" mode="bottom" @close="close" @open="open" border-radius="14">
  96. <view>
  97. <scroll-view scroll-y="true" class="store-list" @scrolltolower="getStoreList()">
  98. <view class="store-info " :class="{'choose-stroe': storeitem.id == choose_store.id}"
  99. v-for="(storeitem,storeindex) in store.list" @click="chooseStore(storeitem)">
  100. <image :src="storeitem.logo" mode="" class="store-logo"></image>
  101. <view class="info">
  102. <view class="store-name">
  103. {{storeitem.name}}
  104. </view>
  105. <view class="store-address" v-if="storeitem.area">
  106. {{storeitem.area.provinceName + storeitem.area.cityName + storeitem.area.districtName + storeitem.area.address}}
  107. </view>
  108. </view>
  109. <view class="float_right"></text></view>
  110. </view>
  111. <u-loadmore :status="store.loadingType" />
  112. </scroll-view>
  113. </view>
  114. </u-popup>
  115. </view>
  116. </template>
  117. <script>
  118. import its from '@/components/its-calendar/its-calendar.vue'
  119. export default {
  120. components: {
  121. its
  122. },
  123. data() {
  124. return {
  125. pay_price: '',
  126. yhjg: 0,
  127. canpay: false,
  128. choose_time: '',
  129. choose_time_detail: '',
  130. store: {
  131. page: 1,
  132. page_size: 10,
  133. list: [],
  134. loadingType: 'loadmore',
  135. loaded: false,
  136. },
  137. choose_store: {},
  138. yg: {
  139. page: 1,
  140. page_size: 10,
  141. list: [],
  142. loadingType: 'loadmore',
  143. loaded: false,
  144. },
  145. choose_yg: {
  146. },
  147. timed: false, //是否选择完时间
  148. store_choose_show: false, //门店选择弹出层开关
  149. xmlist: [],
  150. mjly: '',
  151. customerData: {}
  152. }
  153. },
  154. computed: {
  155. all_price() {
  156. let price = 0
  157. if(this.xmlist.length > 0) {
  158. this.xmlist.forEach(item => {
  159. price +=item.price*1
  160. })
  161. }
  162. return price.toFixed(2)
  163. },
  164. project_id() {
  165. let dd = ''
  166. if(this.xmlist.length > 0) {
  167. this.xmlist.forEach(item => {
  168. dd = dd + item.id + ','
  169. })
  170. }
  171. return dd
  172. }
  173. },
  174. watch: {
  175. choose_store(newval, oldval) {
  176. this.choose_yg = {}
  177. if (newval.openTime.isAllDay != 1) {
  178. let start = newval.openTime.start.split(':')
  179. let end = newval.openTime.end.split(':')
  180. if (start[1] > 30) {
  181. this.start_time = start[0] * 1 + 1
  182. } else {
  183. this.start_time = start[0] * 1
  184. }
  185. this.end_time = end[0] * 1
  186. console.log(this.start_time)
  187. } else {
  188. this.start_time = 0
  189. this.end_time = 24
  190. console.log(this.start_time)
  191. }
  192. if (this.choose_time != '' && this.choose_time) {
  193. console.log(this.choose_time, 'this.choose_time ')
  194. this.getYgList('reload')
  195. }
  196. },
  197. choose_time(newval, oldval) {
  198. console.log('时间改变')
  199. this.getYgList('reload')
  200. },
  201. choose_yg(newval, oldval) {
  202. if (newval.staffName && newval.uid != 0) {
  203. console.log('调查choose_yg')
  204. this.getYgYyTimeArea()
  205. } else {
  206. if (newval.staffName == '随机指派' && this.choose_time) {
  207. this.canpay = true
  208. }
  209. }
  210. },
  211. choose_time_detail(newval, oldval) {
  212. console.log(this.choose_yg,'this.choose_yg+++++++++');
  213. if (this.choose_store && this.choose_yg.uid && this.choose_yg.uid != 0) {
  214. console.log('调查choose_time_detail')
  215. this.getYgYyTimeArea()
  216. }
  217. }
  218. },
  219. onLoad() {
  220. },
  221. onShow() {
  222. console.log(this.customerData)
  223. this.getStoreList()
  224. },
  225. onReachBottom() {
  226. },
  227. onReady() {
  228. },
  229. methods: {
  230. submitt() {
  231. let data = {
  232. "uid": this.choose_yg.uid, //店员userCenterId
  233. "customer_id": this.customerData.id,
  234. "project": this.project_id.slice(0,this.project_id.length-1),
  235. "discount_price": this.yhjg,
  236. "time": this.choose_time + ' ' + this.choose_time_detail,
  237. "remarks": this.mjly,
  238. }
  239. this.canpay = false
  240. this.$u.api.addYyItem(data).then(({data})=> {
  241. this.$u.toast('创建成功!');
  242. setTimeout(() => {
  243. uni.navigateBack()
  244. }, 1500);
  245. }).catch(err => {
  246. this.canpay = true
  247. })
  248. },
  249. cannot(title = '该员工不在工作时间') {
  250. // this.$u.toast(title);
  251. this.canpay = true
  252. },
  253. //获取员工列表
  254. getYgList(type) {
  255. let item = this.yg
  256. if (type == 'reload') {
  257. item.list = []
  258. item.loadingType = 'loadmore'
  259. }
  260. if (item.loadingType == 'loading' || item.loadingType == 'nomore') {
  261. return
  262. }
  263. item.loadingType = 'loading'
  264. this.$u.api.getTimeYgList({
  265. time: this.choose_time,
  266. 'SHOP-TOKEN': this.choose_store.token
  267. }).then(({
  268. data
  269. }) => {
  270. let arr = [{
  271. uid: 0,
  272. staffName: '随机指派'
  273. }]
  274. item.list = arr.concat(data)
  275. item.loadingType = 'nomore'
  276. })
  277. },
  278. chooseGoods() {
  279. uni.navigateTo({
  280. url: '/pagesS/goods/yygoods'
  281. })
  282. },
  283. getTime(e) {
  284. console.log(e);
  285. this.timed = true
  286. this.choose_time = e.time.split(' ')[0]
  287. this.choose_time_detail = e.time.split(' ')[1]
  288. },
  289. // 打开门店选择
  290. openStoreChoose() {
  291. console.log('打开门店选择')
  292. this.store_choose_show = true
  293. },
  294. //选择门店
  295. chooseStore(item) {
  296. this.choose_store = item
  297. this.close()
  298. },
  299. // 获取门店列表
  300. getStoreList() {
  301. console.log('获取门店列表')
  302. let item = this.store
  303. if (item.loadingType == 'loading' || item.loadingType == 'nomore') {
  304. return
  305. }
  306. item.loadingType = 'loading'
  307. this.$u.api.getStoreList({
  308. page: item.page,
  309. pageSize: item.page_size,
  310. }).then(({
  311. data
  312. }) => {
  313. console.log(data, '门店列表')
  314. item.list = item.list.concat(data)
  315. console.log(data,'列表+++++++');
  316. if (item.page == 1) {
  317. this.choose_store = item.list[0]
  318. console.log(this.choose_store,'this.choose_store')
  319. }
  320. item.page++
  321. if (item.page_size == data.length) {
  322. item.loadingType = 'loadmore'
  323. } else {
  324. item.loadingType = 'nomore'
  325. }
  326. })
  327. },
  328. close() {
  329. this.store_choose_show = false
  330. },
  331. open() {
  332. },
  333. choosYg(item) {
  334. this.choose_yg = item
  335. },
  336. //判断是否能预约员工
  337. getYgYyTimeArea() {
  338. let that = this
  339. that.$u.api.getYgYyTimeArea({
  340. time: that.choose_time,
  341. uid: that.choose_yg.uid
  342. }).then(({
  343. data
  344. }) => {
  345. console.log()
  346. let choose_time = that.choose_time_detail.replace(/\:/g, '')
  347. let worktime = [data.time_slot[0][0].replace(/\:/g, ''), data.time_slot[0][1].replace(/\:/g,
  348. '')]
  349. // 判断员工是否在工作时间
  350. console.log(choose_time, worktime[0], worktime[1])
  351. if (choose_time * 1 >= worktime[0] * 1 && choose_time * 1 <= worktime[1] * 1) {
  352. this.canpay = true
  353. } else {
  354. that.cannot()
  355. }
  356. if (data.reserved.length > 0) {
  357. for (let i = 0; i < data.reserved.length; i++) {
  358. if (that.choose_time_detail == data.reserved[i]) {
  359. console.log('该员工已有预约')
  360. that.cannot('该员工已有预约')
  361. break
  362. }
  363. }
  364. }
  365. })
  366. },
  367. }
  368. }
  369. </script>
  370. <style lang="scss">
  371. .good-info-wrap {
  372. margin:-50rpx auto 20rpx;
  373. width: 712rpx;
  374. min-height: 285rpx;
  375. background: #FFFFFF;
  376. border-radius: 10rpx;
  377. padding:10rpx 20rpx;
  378. .good-list {
  379. min-height: 177rpx;
  380. width: 100%;
  381. .good-wrap {
  382. min-height: 177rpx;
  383. .good {
  384. height: 177rpx;
  385. border-bottom: 1px solid #f7f8fa;
  386. display: flex;
  387. justify-content: flex-start;
  388. align-items: center;
  389. .good-info {
  390. height: 177rpx;
  391. width: 365rpx;
  392. padding:25rpx 0 25rpx 20rpx;
  393. display: flex;
  394. flex-direction: column;
  395. justify-content: space-between;
  396. align-items: flex-start;
  397. .good-name {
  398. font-size: 26rpx;
  399. font-weight: 500;
  400. color: #333333;
  401. }
  402. .good-price {
  403. margin-top: 20rpx;
  404. font-size: 34rpx;
  405. font-weight: bold;
  406. color: #CE372E;
  407. &::before {
  408. content: '¥';
  409. font-size: 24rpx;
  410. color: #CE372E;
  411. }
  412. }
  413. }
  414. .good-img {
  415. width: 133rpx;
  416. height: 133rpx;
  417. border-radius: 10rpx;
  418. background-color: #eee;
  419. }
  420. }
  421. }
  422. .empty {
  423. // display: ;
  424. font-size: 28rpx;
  425. height: 177rpx;
  426. background-color: #ecf1f7;
  427. text-align: center;
  428. line-height: 177rpx;
  429. color: #4472bd;
  430. border-radius: 10rpx;
  431. }
  432. }
  433. }
  434. .mj-info {
  435. width: 712rpx;
  436. height: 200rpx;
  437. background: #FFFFFF;
  438. border-radius: 10px;
  439. margin: 20rpx auto;
  440. padding:0 20rpx;
  441. }
  442. .mjly {
  443. height: 100rpx;
  444. display: flex;
  445. justify-content: space-between;
  446. align-items: center;
  447. font-size: 26rpx;
  448. .ly-left {
  449. font-weight: 500;
  450. color: #000;
  451. }
  452. .ly-right {
  453. width: 400rpx;
  454. text-align: right;
  455. }
  456. image {
  457. width: 15rpx;
  458. height: 28rpx;
  459. }
  460. }
  461. //指派
  462. .zp-wrap {
  463. margin-top: 20rpx;
  464. width: 750rpx;
  465. height: 216rpx;
  466. white-space: nowrap;
  467. .zp-item {
  468. display: inline-block;
  469. margin-right: 15rpx;
  470. padding-top: 34rpx;
  471. width: 172rpx;
  472. height: 216rpx;
  473. // background: #E02020;
  474. background-color: #fff;
  475. border-radius: 10rpx;
  476. .zp-logo {
  477. display: block;
  478. width: 106rpx;
  479. height: 106rpx;
  480. margin: auto;
  481. border-radius: 50%;
  482. background-color: #999999;
  483. }
  484. .zp-name {
  485. margin-top: 15rpx;
  486. width: 100%;
  487. text-align: center;
  488. font-size: 30rpx;
  489. font-weight: bold;
  490. color: #333333;
  491. }
  492. }
  493. .choose {
  494. background-color: #262261 !important;
  495. .zp-name {
  496. color: #fff !important;
  497. }
  498. }
  499. }
  500. .tj-dd {
  501. width: 750rpx;
  502. height: 100rpx;
  503. position: fixed;
  504. bottom: 0;
  505. display: flex;
  506. justify-content: space-between;
  507. align-items: center;
  508. background-color: #fff;
  509. padding: 0 20rpx;
  510. .tj-btn {
  511. width: 200rpx;
  512. height: 75rpx;
  513. line-height: 75rpx;
  514. color: #fff;
  515. background-color: #999;
  516. border-radius: 10rpx;
  517. text-align: center;
  518. font-size: 28rpx;
  519. font-weight: 500;
  520. }
  521. }
  522. .rmb {
  523. &::before {
  524. content: '¥';
  525. color: #CE372E;
  526. font-size: 30rpx;
  527. }
  528. }
  529. // 门店
  530. .sc-md {
  531. margin: 20rpx auto;
  532. width: 712rpx;
  533. height: 210rpx;
  534. background: #FFFFFF;
  535. border-radius: 10rpx;
  536. .sc-tip {
  537. padding-left: 20rpx;
  538. line-height: 70rpx;
  539. width: 712rpx;
  540. height: 70rpx;
  541. background: #e9e8ef;
  542. border-radius: 10rpx 10rpx 0px 0px;
  543. font-size: 26rpx;
  544. font-weight: 500;
  545. color: #262261;
  546. }
  547. }
  548. .store-info {
  549. display: flex;
  550. justify-content: flex-start;
  551. align-items: center;
  552. height: 140rpx;
  553. padding: 0 30rpx 0 20rpx;
  554. .store-logo {
  555. width: 61rpx;
  556. height: 61rpx;
  557. background-color: #eee;
  558. border-radius: 50%;
  559. }
  560. .info {
  561. flex-grow: 1;
  562. display: flex;
  563. flex-direction: column;
  564. justify-content: center;
  565. padding: 0 40rpx 0 20rpx;
  566. .store-name {
  567. font-size: 25rpx;
  568. font-weight: 500;
  569. color: #333333;
  570. }
  571. .store-address {
  572. margin-top: 15rpx;
  573. font-size: 22rpx;
  574. font-weight: 500;
  575. color: #999999;
  576. }
  577. }
  578. }
  579. .store-list {
  580. min-height: 280rpx;
  581. max-height: 450rpx;
  582. width: 750upx;
  583. padding-top: 1rpx;
  584. background-color: #fff;
  585. .store-info {
  586. width: 712rpx;
  587. margin: 20rpx auto;
  588. border: 1px solid #aaa;
  589. border-radius: 20rpx;
  590. }
  591. .choose-stroe {
  592. border: 2px solid #262261;
  593. }
  594. }
  595. .canpay {
  596. background-color: #d84840 !important;
  597. }
  598. </style>