detail.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. <template>
  2. <view class="container">
  3. <!-- 车牌号区域 -->
  4. <view class="box">
  5. <view class="left">车牌号</view>
  6. <view class="right2">
  7. <view class="item">
  8. <view :class="['select', form.selectValue != 0 ? 'selected' : '']" @tap="handleMultiple(form.selectIndex)">
  9. {{ form.selectValue != 0 ? form.selectValue : '请选择' }}
  10. </view>
  11. </view>
  12. <view class="right-img"><img src="../../static/bottom.png" /></view>
  13. </view>
  14. <!-- 车牌号选项弹窗区域 -->
  15. <transition>
  16. <multiple-picker
  17. title="请选择"
  18. :show="selectMultiple.show"
  19. :columns="selectMultiple.columns"
  20. :defaultIndex="selectMultiple.index"
  21. @confirm="confirmMultiple"
  22. @cancel="selectMultiple.show = false"
  23. @change="changeMultiple"
  24. ></multiple-picker>
  25. </transition>
  26. </view>
  27. <!-- 人数区域 -->
  28. <view class="box">
  29. <view class="left">容量</view>
  30. <view class="right">{{ info.contain }}</view>
  31. </view>
  32. <!-- 发车日期区域 -->
  33. <view class="box">
  34. <view class="left">发车日期</view>
  35. <view class="right">{{ info.yy_date }}</view>
  36. </view>
  37. <!-- 发车时间区域 -->
  38. <view class="box">
  39. <view class="left">发车时间</view>
  40. <picker style="width: 40%;" @change="bindPickerChange($event, 1)" mode="time" :value="info.ci_time" :start="getCurrentTime()">
  41. <view :class="['right', info.ci_time != 0 ? '' : 'unSelect']">
  42. {{ info.ci_time != 0 ? info.ci_time : '请选择' }}
  43. <view class="right-img"><img src="../../static/bottom.png" /></view>
  44. </view>
  45. </picker>
  46. </view>
  47. <!-- 扫码开始时间区域 -->
  48. <view class="box">
  49. <view class="left">扫码开始时间</view>
  50. <picker style="width: 40%;" @change="bindPickerChange($event, 4)" mode="time" :value="info.sm_start">
  51. <view :class="['right', info.sm_start != 0 ? '' : 'unSelect']">
  52. {{ info.sm_start != 0 ? info.sm_start : '请选择' }}
  53. <view class="right-img"><img src="../../static/bottom.png" /></view>
  54. </view>
  55. </picker>
  56. </view>
  57. <!-- 扫码结束时间区域 -->
  58. <view class="box">
  59. <view class="left">扫码结束时间</view>
  60. <picker style="width: 40%;" @change="bindPickerChange($event, 5)" mode="time" :value="info.sm_end">
  61. <view :class="['right', info.sm_end != 0 ? '' : 'unSelect']">
  62. {{ info.sm_end != 0 ? info.sm_end : '请选择' }}
  63. <view class="right-img"><img src="../../static/bottom.png" /></view>
  64. </view>
  65. </picker>
  66. </view>
  67. <!-- 路线区域 -->
  68. <view class="box">
  69. <view class="left">路线</view>
  70. <picker style="width: 60%;" @change="bindPickerChange($event, 2)" :range="pathList" range-key="route">
  71. <view :class="['right', info.route ? '' : 'unSelect']">
  72. {{ info.route ? info.route : '请选择' }}
  73. <view class="right-img"><img src="../../static/bottom.png" /></view>
  74. </view>
  75. </picker>
  76. </view>
  77. <!-- 终点站区域 -->
  78. <view class="box">
  79. <view class="left">终点站</view>
  80. <picker style="width: 60%;" @change="bindPickerChange($event, 3)" :range="endList" range-key="route_end">
  81. <view :class="['right', info.route_end ? '' : 'unSelect']">
  82. {{ info.route_end ? info.route_end : '请选择' }}
  83. <view class="right-img"><img src="../../static/bottom.png" /></view>
  84. </view>
  85. </picker>
  86. </view>
  87. <!-- 状态区域 -->
  88. <view class="box">
  89. <view class="left">状态</view>
  90. <view class="right">{{ info.state_str }}</view>
  91. </view>
  92. <!-- 提前一天预约区域 -->
  93. <view class="box">
  94. <view class="left">可否提前一天预约</view>
  95. <view class="right">{{ info.before_state == 0 ? '不可以' : '可以' }}</view>
  96. </view>
  97. <!-- 保存按钮区域 -->
  98. <view class="saveBtn" @click="handleSave">保存</view>
  99. <!-- 人员名单区域 -->
  100. <view class="list">
  101. <view class="list-title" v-if="info.user_num != 0">人员名单({{ info.user_num }}/{{ info.contain }})</view>
  102. <view class="list-item" v-for="(item, index) in listData" :key="index">
  103. <view class="item-img"><img src="../../static/man.png" /></view>
  104. <view class="item-info">
  105. <view class="info-name">
  106. <view>{{ item.user_name }}</view>
  107. </view>
  108. <view class="info-mes">
  109. {{ item.user_zz }}
  110. <span>{{ item.yy_time }}</span>
  111. </view>
  112. </view>
  113. <view class="item-type"><img src="../../static/subscribe.png" /></view>
  114. </view>
  115. </view>
  116. </view>
  117. </template>
  118. <script setup>
  119. import { ref } from 'vue'
  120. import { onLoad } from '@dcloudio/uni-app'
  121. import { myRequest } from '@/util/api.js'
  122. import { isWeixin } from '@/util/isWeixin.js'
  123. import { time_to_sec, time_change } from '@/util/formatTime.js'
  124. onLoad(options => {
  125. if (isWeixin()) {
  126. let userInfo = JSON.parse(uni.getStorageSync('bus-userInfo'))
  127. if (userInfo.user_zz !== '车队长') {
  128. uni.redirectTo({
  129. url: '/pages/404/404?message=暂无权限'
  130. })
  131. } else {
  132. info.value = JSON.parse(options.info)
  133. // console.log(info.value)
  134. // 获取人员列表
  135. getData(info.value)
  136. // 获取路线数组
  137. getPathList()
  138. // 获取终点站列表
  139. getEndList()
  140. // 获取车牌号列表
  141. getBusList()
  142. // 获取发车时间提前推迟多少分钟可以扫码数据
  143. getTimeConfig()
  144. // 处理车牌号数据
  145. form.value.selectValue = info.value.car_number
  146. setTimeout(() => {
  147. let temList = []
  148. selectMultiple.value.columns.forEach(item => {
  149. if (item.label == form.value.selectValue) {
  150. temList.push(item.value)
  151. }
  152. })
  153. form.value.selectIndex = temList
  154. }, 500)
  155. }
  156. } else {
  157. uni.redirectTo({
  158. url: '/pages/404/404?message=请在微信客户端打开链接'
  159. })
  160. }
  161. })
  162. // 带过来的预约详情数据
  163. const info = ref({})
  164. // 车牌号绑定数据
  165. const form = ref({
  166. selectValue: '',
  167. selectIndex: []
  168. })
  169. // 车牌号数组相关数据
  170. const selectMultiple = ref({
  171. show: false,
  172. index: [],
  173. columns: []
  174. })
  175. // 路线数组
  176. const pathList = ref([])
  177. // 终点站数组
  178. const endList = ref([])
  179. // 人员列表数组
  180. const listData = ref([])
  181. // 发车时间提前多少分钟可以扫码
  182. const time_early = ref(null)
  183. // 发车时间推迟多少分钟可以扫码
  184. const time_late = ref(null)
  185. // 获取路线数组请求
  186. const getPathList = async () => {
  187. const res = await myRequest({
  188. url: '/appqueryRoute.action'
  189. })
  190. // console.log(res);
  191. pathList.value = res.data
  192. }
  193. // 获取终点站数组请求
  194. const getEndList = async () => {
  195. const res = await myRequest({
  196. url: '/appqueryEndRoutes.action',
  197. data: {
  198. route: info.value.route
  199. }
  200. })
  201. // console.log(res);
  202. endList.value = res.data
  203. }
  204. // 获取车牌号数组请求
  205. const getBusList = async () => {
  206. const res = await myRequest({
  207. url: '/appqueryCarInfos.action'
  208. })
  209. // console.log(res);
  210. if (res.data.length) {
  211. let temList = []
  212. res.data.forEach((item, index) => {
  213. temList.push({
  214. label: item.car_number,
  215. value: index.toString()
  216. })
  217. })
  218. selectMultiple.value.columns = temList
  219. }
  220. }
  221. // 获取人员名单请求
  222. const getData = async value => {
  223. const { route, route_end, yy_date, ci_time, car_number } = value
  224. const res = await myRequest({
  225. url: '/appqueryAppointeds.action',
  226. data: {
  227. route,
  228. route_end,
  229. yy_date,
  230. ci_time,
  231. car_number
  232. }
  233. })
  234. // console.log(res)
  235. listData.value = res.data
  236. }
  237. // 保存按钮回调
  238. const handleSave = () => {
  239. if (info.value.car_number == 0) {
  240. uni.showToast({
  241. title: '请选择车牌号',
  242. icon: 'none'
  243. })
  244. return
  245. }
  246. if (info.value.ci_time == 0) {
  247. uni.showToast({
  248. title: '请选择发车时间',
  249. icon: 'none'
  250. })
  251. return
  252. }
  253. if (!info.value.sm_start) {
  254. uni.showToast({
  255. title: '请选择扫码开始时间',
  256. icon: 'none'
  257. })
  258. return
  259. }
  260. if (!info.value.sm_end) {
  261. uni.showToast({
  262. title: '请选择扫码结束时间',
  263. icon: 'none'
  264. })
  265. return
  266. }
  267. if (time_to_sec(info.value.sm_start) >= time_to_sec(info.value.ci_time)) {
  268. uni.showToast({
  269. title: '扫码开始时间不能晚于发车时间',
  270. icon: 'none',
  271. duration: 2000
  272. })
  273. return
  274. }
  275. if (time_to_sec(info.value.sm_end) < time_to_sec(info.value.ci_time)) {
  276. uni.showToast({
  277. title: '扫码结束时间不能早于发车时间',
  278. icon: 'none',
  279. duration: 2000
  280. })
  281. return
  282. }
  283. if (!info.value.route) {
  284. uni.showToast({
  285. title: '请选择路线',
  286. icon: 'none'
  287. })
  288. return
  289. }
  290. if (!info.value.route_end) {
  291. uni.showToast({
  292. title: '请选择终点站',
  293. icon: 'none'
  294. })
  295. return
  296. }
  297. uni.showModal({
  298. title: '提示',
  299. content: '确定保存吗?',
  300. success: res => {
  301. if (res.confirm) {
  302. handleSaveRequest()
  303. } else if (res.cancel) {
  304. }
  305. }
  306. })
  307. }
  308. // 保存请求
  309. const handleSaveRequest = () => {
  310. // console.log(info.value)
  311. const { id, car_number, ci_time, route, route_end, contain, sm_start, sm_end } = info.value
  312. uni.request({
  313. url: '/carstop/carbook/scheupdate.action',
  314. method: 'post',
  315. data: {
  316. id,
  317. car_number,
  318. ci_time,
  319. route,
  320. route_end,
  321. contain,
  322. sm_start,
  323. sm_end
  324. },
  325. success: res => {
  326. if (res.data.code == 200) {
  327. uni.showToast({
  328. title: res.data.message
  329. })
  330. setTimeout(() => {
  331. uni.redirectTo({
  332. url: '/pages/record/record'
  333. })
  334. }, 1500)
  335. } else {
  336. uni.showToast({
  337. title: res.data.message,
  338. icon: 'error'
  339. })
  340. }
  341. }
  342. })
  343. }
  344. // 点击车牌号下拉框回调
  345. const handleMultiple = val => {
  346. // console.log(val);
  347. selectMultiple.value.index = val || []
  348. selectMultiple.value.show = true
  349. }
  350. // 车牌号下拉框确定按钮回调
  351. const confirmMultiple = e => {
  352. // console.log(e);
  353. // console.log(e.value);
  354. if (selectMultiple.value.index != e.value) {
  355. let temp = []
  356. e.selected.forEach(item => {
  357. temp.push(item.label)
  358. })
  359. form.value.selectValue = temp.toString()
  360. info.value.car_number = temp.toString()
  361. }
  362. form.value.selectIndex = e.value
  363. selectMultiple.value.show = false
  364. // 获取汽车容量
  365. getBusContain()
  366. }
  367. // 获取汽车容量请求
  368. const getBusContain = async () => {
  369. const res = await myRequest({
  370. url: '/appqueryCarContain.action',
  371. data: {
  372. car_number: form.value.selectValue
  373. }
  374. })
  375. // console.log(res);
  376. info.value.contain = res.data
  377. }
  378. // 获取发车时间提前推迟多少分钟可以扫码数据
  379. const getTimeConfig = async () => {
  380. const res = await myRequest({
  381. url: '/cnqueryHb.action'
  382. })
  383. // console.log(res)
  384. time_early.value = res.sm_end
  385. time_late.value = res.sm_start
  386. }
  387. // 下拉框选择时的回调
  388. const changeMultiple = e => {
  389. // console.log(e);
  390. }
  391. // 原生下拉框的选择回调事件
  392. const bindPickerChange = (e, type) => {
  393. if (type == 1) {
  394. info.value.ci_time = e.detail.value
  395. info.value.sm_start = time_change(info.value.ci_time, time_early.value * -1)
  396. info.value.sm_end = time_change(info.value.ci_time, time_late.value)
  397. } else if (type == 2) {
  398. info.value.route = pathList.value[e.detail.value].route
  399. getEndList()
  400. info.value.route_end = ''
  401. } else if (type == 3) {
  402. info.value.route_end = endList.value[e.detail.value].route_end
  403. } else if (type == 4) {
  404. info.value.sm_start = e.detail.value
  405. } else if (type == 5) {
  406. info.value.sm_end = e.detail.value
  407. }
  408. }
  409. // 获取当前时间 hh:mm
  410. const getCurrentTime = () => {
  411. const date = new Date()
  412. let H = (date.getHours() + '').padStart(2, '0')
  413. let M = (date.getMinutes() + '').padStart(2, '0')
  414. return `${H}:${M}`
  415. }
  416. </script>
  417. <style lang="scss" scoped>
  418. .container {
  419. background-color: #fff;
  420. .box {
  421. display: flex;
  422. justify-content: space-between;
  423. align-items: center;
  424. padding: 0 30rpx;
  425. height: 98rpx;
  426. font-size: 28rpx;
  427. border-bottom: 1rpx solid #e6e6e6;
  428. .left {
  429. flex: 1;
  430. color: #999999;
  431. }
  432. .right {
  433. flex: 1;
  434. display: flex;
  435. justify-content: flex-end;
  436. .right-img {
  437. margin-left: 27rpx;
  438. margin-top: -5rpx;
  439. width: 17rpx;
  440. height: 12rpx;
  441. img {
  442. width: 100%;
  443. height: 100%;
  444. }
  445. }
  446. }
  447. .right2 {
  448. flex: 2;
  449. display: flex;
  450. justify-content: flex-end;
  451. align-items: center;
  452. .item {
  453. flex: 1;
  454. padding: 20rpx 0;
  455. .select {
  456. width: 100%;
  457. padding-top: 6px;
  458. padding-bottom: 6px;
  459. padding-left: 9px;
  460. border-radius: 4px;
  461. font-size: 15px;
  462. text-align: end;
  463. box-sizing: border-box;
  464. color: #cccccc;
  465. line-height: 26px;
  466. &.selected {
  467. color: black;
  468. }
  469. }
  470. }
  471. .right-img {
  472. margin-left: 27rpx;
  473. margin-top: -30rpx;
  474. width: 17rpx;
  475. height: 12rpx;
  476. img {
  477. width: 100%;
  478. height: 100%;
  479. }
  480. }
  481. }
  482. .unSelect {
  483. color: #ccc;
  484. }
  485. }
  486. .saveBtn {
  487. margin: 20rpx 30rpx;
  488. line-height: 100rpx;
  489. text-align: center;
  490. color: #fff;
  491. font-size: 34rpx;
  492. border-radius: 15rpx;
  493. background: linear-gradient(180deg, #8684ff 0%, #3c50e8 100%);
  494. }
  495. .list {
  496. padding: 13rpx 30rpx;
  497. .list-title {
  498. height: 41rpx;
  499. color: #999999;
  500. font-size: 28rpx;
  501. }
  502. .list-item {
  503. display: flex;
  504. align-items: center;
  505. box-sizing: border-box;
  506. padding: 29rpx 0 26rpx 0;
  507. height: 155rpx;
  508. border-bottom: 1rpx solid #e6e6e6;
  509. .item-img {
  510. width: 100rpx;
  511. height: 100rpx;
  512. border-radius: 50%;
  513. img {
  514. width: 100%;
  515. height: 100%;
  516. }
  517. }
  518. .item-info {
  519. flex: 1;
  520. display: flex;
  521. flex-direction: column;
  522. justify-content: space-evenly;
  523. margin-left: 6rpx;
  524. height: 100rpx;
  525. .info-name {
  526. display: flex;
  527. align-items: center;
  528. font-size: 32rpx;
  529. .info-name-img {
  530. margin-left: 26rpx;
  531. width: 30rpx;
  532. height: 35rpx;
  533. img {
  534. width: 100%;
  535. height: 100%;
  536. }
  537. }
  538. }
  539. .info-mes {
  540. font-size: 24rpx;
  541. color: #999999;
  542. span {
  543. margin-left: 26rpx;
  544. color: #a6a6a6;
  545. }
  546. }
  547. }
  548. .item-type {
  549. width: 104rpx;
  550. height: 41rpx;
  551. img {
  552. width: 100%;
  553. height: 100%;
  554. }
  555. }
  556. }
  557. }
  558. }
  559. .v-enter-active,
  560. .v-leave-active {
  561. transition: opacity 0.5s ease;
  562. }
  563. .v-enter-from,
  564. .v-leave-to {
  565. opacity: 0;
  566. }
  567. </style>