You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

575 lines
13 KiB

8 months ago
  1. <template>
  2. <mNavbar title="服务时间" :leftClick="leftClick">
  3. </mNavbar>
  4. <view class="box">
  5. <van-dropdown-menu>
  6. <van-dropdown-item @change='changeServer' v-model="serviceTitle" :options="techniService" />
  7. <van-dropdown-item @change="change" :options="operationList">
  8. <template #title>快捷操作</template>
  9. </van-dropdown-item>
  10. </van-dropdown-menu>
  11. <view v-show="serviceTitle == 0" class="time">
  12. <view class="date-list">
  13. <view :class="{'date-item' : true, act : i == index}" v-for="(item, index) in dateList"
  14. @click="selectDate(item, index)">
  15. <view>
  16. {{ item.format('dddd') }}
  17. </view>
  18. <view>
  19. {{ item.format('MM-DD') }}
  20. </view>
  21. </view>
  22. </view>
  23. <view style="display: flex;justify-content: center;" v-if="loading">
  24. <van-loading />
  25. </view>
  26. <view class="time-list" v-else-if="timeList.length">
  27. <view :class="{'time-item' : true , no : !item.timeOut && item.isDelete == 'Y' , timeOut : item.timeout }" v-for="(item, index) in timeList"
  28. @click="selectTime({time : item, date : dateList[i]})">
  29. <van-checkbox-group v-model="checked">
  30. <view v-if="multipleChoice" class="checked">
  31. <van-checkbox :name="item.id" :disabled="item.timeout"></van-checkbox>
  32. </view>
  33. <view>
  34. {{ item.timeName }}
  35. </view>
  36. <view class="status">
  37. {{ item.timeout ? '过时' : item.isDelete != 'Y' ? '打开' : '关闭' }}
  38. </view>
  39. </van-checkbox-group>
  40. </view>
  41. </view>
  42. <van-empty v-else image="/static/empty/data.png" image-size="400rpx" description="无数据请上线初始化"/>
  43. </view>
  44. <view v-show="serviceTitle == 1" class="project">
  45. <view v-if="projectList.length > 0" class="server-list">
  46. <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" ref="list"
  47. @load="onLoad">
  48. <van-checkbox-group v-model="checked">
  49. <view v-for="item in projectList" class="server-item">
  50. <view v-if="multipleChoice" class="checked">
  51. <van-checkbox :name="item.shopObject.id"></van-checkbox>
  52. </view>
  53. <view class="img-box">
  54. <image :src="item.shopObject.image" mode="aspectFill"></image>
  55. </view>
  56. <view class="server-info">
  57. <view class="server-title">{{ item.shopObject.title }}</view>
  58. <view class="time-coupon">
  59. <image src="@/static/home/time-icon.png"></image>
  60. <view class="time">{{ item.shopObject.times }}分钟</view>
  61. </view>
  62. <view class="price">
  63. <view class="current-price">
  64. <text class="unit"></text>{{ item.shopObject.price }}
  65. </view>
  66. <view class="original-price">
  67. <text class="unit"></text>{{ item.shopObject.oldPrice }}
  68. </view>
  69. </view>
  70. <view class="sales-volume">
  71. <image src="@/static/icons/icon1.png"></image>
  72. <view class="desc">已售出{{ item.shopObject.payNum }}+</view>
  73. </view>
  74. </view>
  75. <view class="selective-technician">
  76. <view @click.stop="selectProject(item)" class="btn">
  77. {{ item.isDelete == 'Y' ? '取消项目' : '选择项目'}}
  78. </view>
  79. </view>
  80. </view>
  81. </van-checkbox-group>
  82. </van-list>
  83. </view>
  84. <van-empty v-else image="/static/empty/data.png" image-size="400rpx" description="无数据请上线初始化"/>
  85. </view>
  86. </view>
  87. </template>
  88. <script>
  89. import mNavbar from '@/components/base/m-navbar.vue'
  90. export default {
  91. name: "serverTime",
  92. components: {
  93. mNavbar,
  94. },
  95. data() {
  96. return {
  97. i: 0,
  98. dateList: [],
  99. timeList: [],
  100. loading: false,
  101. projectList: [],
  102. finished: false,
  103. serviceTitle: 0,
  104. techniService: [{
  105. text: '服务时间',
  106. value: 0
  107. },
  108. {
  109. text: '服务项目',
  110. value: 1
  111. }
  112. ],
  113. checked: [],
  114. multipleChoice: false, //是否开启多选
  115. operationList: [{
  116. text: '打开',
  117. value: 0
  118. }, {
  119. text: '关闭',
  120. value: 1
  121. },
  122. {
  123. text: '开启多选',
  124. value: 2
  125. },
  126. {
  127. text: '全选',
  128. value: 3
  129. }
  130. ],
  131. today : null,
  132. selDate : null,
  133. isInit : false
  134. };
  135. },
  136. onShow() {
  137. if(this.dateList.length >= 7) return; //防止多次添加日期,onShow这个钩子每次离开页面然后回来都会调用一下
  138. this.today = this.dayjs()
  139. this.dateList.push(this.today)
  140. for (let i = 1; i < 7; i++) {
  141. this.dateList.push(this.today.add(i, 'day'))
  142. }
  143. this.selectDate(this.today,0)
  144. this.getProjectList()
  145. },
  146. methods: {
  147. // 选择日期
  148. selectDate(item, index) {
  149. this.i = index
  150. this.loading = true
  151. this.$api('getVipTenOrderList', {
  152. tenId: this.$route.query.uid,
  153. name: item.format('dddd')
  154. }, res => {
  155. if (res.code == 200) {
  156. res.result.forEach(time => {
  157. if(this.isFormerly({ time, date : this.dateList[this.i] })){ //判断时间是否超时了
  158. time.timeout = true
  159. }else{
  160. time.timeout = false
  161. }
  162. })
  163. this.timeList = res.result;
  164. this.selDate = item
  165. }
  166. this.loading = false
  167. })
  168. },
  169. //选择时间
  170. selectTime(item) {
  171. if(item.time.timeout){ //判断是否是过去时间
  172. return uni.showToast({
  173. title: '选择时间已过时',
  174. duration: 2000
  175. });
  176. }
  177. if (this.multipleChoice) {
  178. if (this.checked.includes(item.time.id)) {
  179. this.checked = this.checked.filter(id => id !== item.time.id);
  180. } else {
  181. this.checked.push(item.time.id);
  182. }
  183. return
  184. }
  185. this.updateTerTime([item.time.id], item.time.isDelete == 'Y' ? 'N' : 'Y');
  186. },
  187. //返回个人中心
  188. leftClick() {
  189. uni.switchTab({
  190. url: '/pages/index/center'
  191. })
  192. },
  193. //修改上钟时间
  194. updateTerTime(selectTimeArr, isDelete) {
  195. let data = {
  196. ids: selectTimeArr.toString(),
  197. isDelete
  198. }
  199. this.$api('updateTerTime', data, res => {
  200. if (res.code == 200) {
  201. this.selectDate(this.selDate, this.i)
  202. }
  203. })
  204. },
  205. //获取项目列表
  206. getProjectList() {
  207. this.$api('queryTerProject', this.queryParams, res => {
  208. if (res.code == 200) {
  209. this.projectList = res.result;
  210. }
  211. })
  212. },
  213. //开启或关闭项目
  214. updateTerProject(selectTimeArr, isDelete) {
  215. let data = {
  216. ids: selectTimeArr.toString(),
  217. isDelete
  218. }
  219. this.$api('updateTerProject', data, res => {
  220. if(res.code == 200){
  221. this.getProjectList()
  222. }
  223. })
  224. },
  225. //切换选择
  226. changeServer() {
  227. this.checked = []; //清空已经选择的时间id或项目id
  228. },
  229. //打开关闭时间、项目
  230. operationItem(isOpen) {
  231. if (this.serviceTitle == 0) { //打开关闭时间 isOpen 是否打开(打开Y 关闭N)
  232. this.updateTerTime(this.checked, isOpen)
  233. } else { //打开关闭项目
  234. this.updateTerProject(this.checked, isOpen)
  235. }
  236. },
  237. //选择项目
  238. selectProject(item) {
  239. if (this.multipleChoice) {
  240. if (this.checked.includes(item.id)) {
  241. this.checked = this.checked.filter( id => id !== item.id);
  242. } else {
  243. this.checked.push(item.id);
  244. }
  245. return
  246. }
  247. this.updateTerProject([item.id], item.isDelete == 'Y' ? 'N' : 'Y')
  248. },
  249. //区分不同操作列表不同操作(全选,打开,关闭等)
  250. change(value) {
  251. if (value == 0) {
  252. this.operationItem('Y')
  253. } else if (value == 1) {
  254. this.operationItem('N')
  255. } else if (value == 2) {
  256. this.multipleChoice = !this.multipleChoice
  257. this.operationList[2].text = this.multipleChoice ? '取消多选' : '开启多选'
  258. this.checked = []
  259. if (this.operationList[3].text == '取消全选') { //取消全选逻辑
  260. this.operationList[3].text = '全选'
  261. }
  262. } else if (value == 3) { //全选
  263. if (!this.multipleChoice) {
  264. return uni.showToast({
  265. title: '请开启多选',
  266. icon: 'none'
  267. })
  268. }
  269. if (this.operationList[3].text == '取消全选') { //取消全选逻辑
  270. this.operationList[3].text = '全选'
  271. return this.checked = []
  272. }
  273. let arr = []
  274. if (this.serviceTitle == 0) { //遍历时间列表
  275. this.timeList.forEach(time => {
  276. if(!time.timeout){ //筛选掉已过时的
  277. arr.push(time.id)
  278. }
  279. })
  280. } else {
  281. this.projectList.forEach(project => {
  282. arr.push(project.shopObject.id)
  283. })
  284. }
  285. this.checked = arr
  286. this.operationList[3].text = '取消全选'
  287. }
  288. },
  289. //项目滑动到底部
  290. onLoad(){},
  291. //判断时间是否为过去时间
  292. isFormerly(e){
  293. let day = e.date.format('YYYY-MM-DD')
  294. let selectTime = this.dayjs(`${day} ${e.time.timeName}`)
  295. let nowTime = this.dayjs()
  296. if(selectTime.isBefore(nowTime)){
  297. return true
  298. }
  299. return false
  300. }
  301. }
  302. }
  303. </script>
  304. <style lang="scss" scoped>
  305. .box {
  306. box-sizing: border-box;
  307. .date-list {
  308. display: flex;
  309. width: 100%;
  310. overflow: hidden;
  311. overflow-x: scroll;
  312. padding: 30rpx 0rpx;
  313. text-align: center;
  314. font-size: 24rpx;
  315. .date-item {
  316. flex-shrink: 0;
  317. padding: 10rpx;
  318. margin: 0 10rpx;
  319. &>view {
  320. padding: 6rpx 10rpx;
  321. }
  322. }
  323. .act {
  324. background-color: #50a2a7;
  325. color: #fff;
  326. border-radius: 10rpx;
  327. }
  328. }
  329. .time-list {
  330. display: flex;
  331. width: 100%;
  332. text-align: center;
  333. font-size: 24rpx;
  334. flex-wrap: wrap;
  335. height: calc(100% - 200rpx);
  336. overflow: hidden;
  337. overflow-y: scroll;
  338. .time-item {
  339. position: relative;
  340. padding: 20rpx;
  341. width: calc(25% - 20rpx);
  342. background-color: #E4E4E4;
  343. box-sizing: border-box;
  344. margin: 10rpx;
  345. border-radius: 16rpx;
  346. position: relative;
  347. line-height: 40rpx;
  348. color: #777;
  349. .status {
  350. color: #EBA44B;
  351. }
  352. &.no {
  353. background-color: #50a2a7;
  354. color: #fff;
  355. .status {
  356. color: #fff;
  357. }
  358. }
  359. &.timeOut {
  360. background: #ccc;
  361. color: #FFFFFF;
  362. .status{
  363. color: #FFFFFF;
  364. }
  365. }
  366. .checked {
  367. position: absolute;
  368. top: 10rpx;
  369. left: 10rpx;
  370. }
  371. }
  372. .act {
  373. background-color: #fff;
  374. color: #55B16E;
  375. border-radius: 10rpx;
  376. }
  377. }
  378. .server-list {
  379. padding-bottom: 80rpx;
  380. .server-item {
  381. position: relative;
  382. display: flex;
  383. flex-wrap: wrap;
  384. justify-content: space-between;
  385. background: white;
  386. border-radius: 15rpx;
  387. box-sizing: border-box;
  388. padding: 15rpx;
  389. margin: 20rpx 0rpx;
  390. .img-box {
  391. width: 180rpx;
  392. height: 180rpx;
  393. border-radius: 10rpx;
  394. overflow: hidden;
  395. image {
  396. width: 100%;
  397. height: 100%;
  398. }
  399. }
  400. .server-info {
  401. width: calc(100% - 320rpx);
  402. box-sizing: border-box;
  403. padding: 0 15rpx;
  404. .server-title {}
  405. .time-coupon,
  406. .price {
  407. display: flex;
  408. flex-wrap: wrap;
  409. align-items: center;
  410. }
  411. .time-coupon {
  412. margin: 10rpx 0rpx;
  413. font-size: 26rpx;
  414. image {
  415. width: 25rpx;
  416. height: 25rpx;
  417. }
  418. .time {
  419. color: #B8B8B8;
  420. margin-left: 6rpx;
  421. }
  422. .coupon {
  423. display: flex;
  424. justify-content: center;
  425. align-items: center;
  426. background: #F29E45;
  427. color: white;
  428. width: 140rpx;
  429. height: 45rpx;
  430. border-radius: 10rpx;
  431. margin-left: 10rpx;
  432. }
  433. }
  434. .price {
  435. font-size: 26rpx;
  436. color: #B8B8B8;
  437. .current-price {
  438. font-size: 30rpx;
  439. font-weight: 600;
  440. color: #D34430;
  441. }
  442. .unit {
  443. font-size: 20rpx;
  444. }
  445. }
  446. .sales-volume {
  447. display: flex;
  448. align-items: center;
  449. color: #B8B8B8;
  450. font-size: 26rpx;
  451. image {
  452. width: 25rpx;
  453. height: 25rpx;
  454. }
  455. }
  456. }
  457. .selective-technician {
  458. display: flex;
  459. flex-wrap: wrap;
  460. align-items: center;
  461. width: 140rpx;
  462. .btn {
  463. background: linear-gradient(178deg, #4FD3BC, #60C285);
  464. color: white;
  465. width: 100%;
  466. height: 60rpx;
  467. line-height: 60rpx;
  468. border-radius: 40rpx;
  469. font-size: 26rpx;
  470. text-align: center;
  471. }
  472. }
  473. .checked {
  474. position: absolute;
  475. left: 15rpx;
  476. top: 15rpx;
  477. z-index: 1;
  478. }
  479. }
  480. }
  481. .select-button {
  482. position: fixed;
  483. display: flex;
  484. align-items: center;
  485. justify-content: center;
  486. bottom: 0;
  487. left: 0;
  488. height: 100rpx;
  489. width: 750rpx;
  490. margin: 0 auto;
  491. box-shadow: -2px -2px 10px rgba(0, 0, 0, .1);
  492. padding: 0 10rpx;
  493. box-sizing: border-box;
  494. .btn {
  495. display: flex;
  496. align-items: center;
  497. justify-content: center;
  498. flex: 3;
  499. height: 80rpx;
  500. margin: 0 10rpx;
  501. background: #50a2a7;
  502. border-radius: 42.5rpx;
  503. color: white;
  504. font-size: 28rpx;
  505. }
  506. }
  507. }
  508. </style>