detail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  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 } 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. form.value.selectValue = info.value.car_number
  144. setTimeout(() => {
  145. let temList = []
  146. selectMultiple.value.columns.forEach(item => {
  147. if (item.label == form.value.selectValue) {
  148. temList.push(item.value)
  149. }
  150. })
  151. form.value.selectIndex = temList
  152. }, 500)
  153. }
  154. } else {
  155. uni.redirectTo({
  156. url: '/pages/404/404?message=请在微信客户端打开链接'
  157. })
  158. }
  159. })
  160. // 带过来的预约详情数据
  161. const info = ref({})
  162. // 车牌号绑定数据
  163. const form = ref({
  164. selectValue: '',
  165. selectIndex: []
  166. })
  167. // 车牌号数组相关数据
  168. const selectMultiple = ref({
  169. show: false,
  170. index: [],
  171. columns: []
  172. })
  173. // 路线数组
  174. const pathList = ref([])
  175. // 终点站数组
  176. const endList = ref([])
  177. // 人员列表数组
  178. const listData = ref([])
  179. // 获取路线数组请求
  180. const getPathList = async () => {
  181. const res = await myRequest({
  182. url: '/appqueryRoute.action'
  183. })
  184. // console.log(res);
  185. pathList.value = res.data
  186. }
  187. // 获取终点站数组请求
  188. const getEndList = async () => {
  189. const res = await myRequest({
  190. url: '/appqueryEndRoutes.action',
  191. data: {
  192. route: info.value.route
  193. }
  194. })
  195. // console.log(res);
  196. endList.value = res.data
  197. }
  198. // 获取车牌号数组请求
  199. const getBusList = async () => {
  200. const res = await myRequest({
  201. url: '/appqueryCarInfos.action'
  202. })
  203. // console.log(res);
  204. if (res.data.length) {
  205. let temList = []
  206. res.data.forEach((item, index) => {
  207. temList.push({
  208. label: item.car_number,
  209. value: index.toString()
  210. })
  211. })
  212. selectMultiple.value.columns = temList
  213. }
  214. }
  215. // 获取人员名单请求
  216. const getData = async value => {
  217. const { route, route_end, yy_date, ci_time, car_number } = value
  218. const res = await myRequest({
  219. url: '/appqueryAppointeds.action',
  220. data: {
  221. route,
  222. route_end,
  223. yy_date,
  224. ci_time,
  225. car_number
  226. }
  227. })
  228. // console.log(res)
  229. listData.value = res.data
  230. }
  231. // 保存按钮回调
  232. const handleSave = () => {
  233. if (info.value.car_number == 0) {
  234. uni.showToast({
  235. title: '请选择车牌号',
  236. icon: 'none'
  237. })
  238. return
  239. }
  240. if (info.value.ci_time == 0) {
  241. uni.showToast({
  242. title: '请选择发车时间',
  243. icon: 'none'
  244. })
  245. return
  246. }
  247. if (!info.value.sm_start) {
  248. uni.showToast({
  249. title: '请选择扫码开始时间',
  250. icon: 'none'
  251. })
  252. return
  253. }
  254. if (!info.value.sm_end) {
  255. uni.showToast({
  256. title: '请选择扫码结束时间',
  257. icon: 'none'
  258. })
  259. return
  260. }
  261. if (time_to_sec(info.value.sm_start) >= time_to_sec(info.value.ci_time)) {
  262. uni.showToast({
  263. title: '扫码开始时间不能晚于发车时间',
  264. icon: 'none',
  265. duration: 2000
  266. })
  267. return
  268. }
  269. if (time_to_sec(info.value.sm_end) < time_to_sec(info.value.ci_time)) {
  270. uni.showToast({
  271. title: '扫码结束时间不能早于发车时间',
  272. icon: 'none',
  273. duration: 2000
  274. })
  275. return
  276. }
  277. if (!info.value.route) {
  278. uni.showToast({
  279. title: '请选择路线',
  280. icon: 'none'
  281. })
  282. return
  283. }
  284. if (!info.value.route_end) {
  285. uni.showToast({
  286. title: '请选择终点站',
  287. icon: 'none'
  288. })
  289. return
  290. }
  291. uni.showModal({
  292. title: '提示',
  293. content: '确定保存吗?',
  294. success: res => {
  295. if (res.confirm) {
  296. handleSaveRequest()
  297. } else if (res.cancel) {
  298. }
  299. }
  300. })
  301. }
  302. // 保存请求
  303. const handleSaveRequest = () => {
  304. // console.log(info.value)
  305. const { id, car_number, ci_time, route, route_end, contain, sm_start, sm_end } = info.value
  306. uni.request({
  307. url: '/carstop/carbook/scheupdate.action',
  308. method: 'post',
  309. data: {
  310. id,
  311. car_number,
  312. ci_time,
  313. route,
  314. route_end,
  315. contain,
  316. sm_start,
  317. sm_end
  318. },
  319. success: res => {
  320. if (res.data.code == 200) {
  321. uni.showToast({
  322. title: res.data.message
  323. })
  324. setTimeout(() => {
  325. uni.redirectTo({
  326. url: '/pages/record/record'
  327. })
  328. }, 1500)
  329. } else {
  330. uni.showToast({
  331. title: res.data.message,
  332. icon: 'error'
  333. })
  334. }
  335. }
  336. })
  337. }
  338. // 点击车牌号下拉框回调
  339. const handleMultiple = val => {
  340. // console.log(val);
  341. selectMultiple.value.index = val || []
  342. selectMultiple.value.show = true
  343. }
  344. // 车牌号下拉框确定按钮回调
  345. const confirmMultiple = e => {
  346. // console.log(e);
  347. // console.log(e.value);
  348. if (selectMultiple.value.index != e.value) {
  349. let temp = []
  350. e.selected.forEach(item => {
  351. temp.push(item.label)
  352. })
  353. form.value.selectValue = temp.toString()
  354. info.value.car_number = temp.toString()
  355. }
  356. form.value.selectIndex = e.value
  357. selectMultiple.value.show = false
  358. // 获取汽车容量
  359. getBusContain()
  360. }
  361. // 获取汽车容量请求
  362. const getBusContain = async () => {
  363. const res = await myRequest({
  364. url: '/appqueryCarContain.action',
  365. data: {
  366. car_number: form.value.selectValue
  367. }
  368. })
  369. // console.log(res);
  370. info.value.contain = res.data
  371. }
  372. // 下拉框选择时的回调
  373. const changeMultiple = e => {
  374. // console.log(e);
  375. }
  376. // 原生下拉框的选择回调事件
  377. const bindPickerChange = (e, type) => {
  378. if (type == 1) {
  379. info.value.ci_time = e.detail.value
  380. } else if (type == 2) {
  381. info.value.route = pathList.value[e.detail.value].route
  382. getEndList()
  383. info.value.route_end = ''
  384. } else if (type == 3) {
  385. info.value.route_end = endList.value[e.detail.value].route_end
  386. } else if (type == 4) {
  387. info.value.sm_start = e.detail.value
  388. } else if (type == 5) {
  389. info.value.sm_end = e.detail.value
  390. }
  391. }
  392. // 获取当前时间 hh:mm
  393. const getCurrentTime = () => {
  394. const date = new Date()
  395. let H = (date.getHours() + '').padStart(2, '0')
  396. let M = (date.getMinutes() + '').padStart(2, '0')
  397. return `${H}:${M}`
  398. }
  399. </script>
  400. <style lang="scss" scoped>
  401. .container {
  402. background-color: #fff;
  403. .box {
  404. display: flex;
  405. justify-content: space-between;
  406. align-items: center;
  407. padding: 0 30rpx;
  408. height: 98rpx;
  409. font-size: 28rpx;
  410. border-bottom: 1rpx solid #e6e6e6;
  411. .left {
  412. flex: 1;
  413. color: #999999;
  414. }
  415. .right {
  416. flex: 1;
  417. display: flex;
  418. justify-content: flex-end;
  419. .right-img {
  420. margin-left: 27rpx;
  421. margin-top: -5rpx;
  422. width: 17rpx;
  423. height: 12rpx;
  424. img {
  425. width: 100%;
  426. height: 100%;
  427. }
  428. }
  429. }
  430. .right2 {
  431. flex: 2;
  432. display: flex;
  433. justify-content: flex-end;
  434. align-items: center;
  435. .item {
  436. flex: 1;
  437. padding: 20rpx 0;
  438. .select {
  439. width: 100%;
  440. padding-top: 6px;
  441. padding-bottom: 6px;
  442. padding-left: 9px;
  443. border-radius: 4px;
  444. font-size: 15px;
  445. text-align: end;
  446. box-sizing: border-box;
  447. color: #cccccc;
  448. line-height: 26px;
  449. &.selected {
  450. color: black;
  451. }
  452. }
  453. }
  454. .right-img {
  455. margin-left: 27rpx;
  456. margin-top: -30rpx;
  457. width: 17rpx;
  458. height: 12rpx;
  459. img {
  460. width: 100%;
  461. height: 100%;
  462. }
  463. }
  464. }
  465. .unSelect {
  466. color: #ccc;
  467. }
  468. }
  469. .saveBtn {
  470. margin: 20rpx 30rpx;
  471. line-height: 100rpx;
  472. text-align: center;
  473. color: #fff;
  474. font-size: 34rpx;
  475. border-radius: 15rpx;
  476. background: linear-gradient(180deg, #8684ff 0%, #3c50e8 100%);
  477. }
  478. .list {
  479. padding: 13rpx 30rpx;
  480. .list-title {
  481. height: 41rpx;
  482. color: #999999;
  483. font-size: 28rpx;
  484. }
  485. .list-item {
  486. display: flex;
  487. align-items: center;
  488. box-sizing: border-box;
  489. padding: 29rpx 0 26rpx 0;
  490. height: 155rpx;
  491. border-bottom: 1rpx solid #e6e6e6;
  492. .item-img {
  493. width: 100rpx;
  494. height: 100rpx;
  495. border-radius: 50%;
  496. img {
  497. width: 100%;
  498. height: 100%;
  499. }
  500. }
  501. .item-info {
  502. flex: 1;
  503. display: flex;
  504. flex-direction: column;
  505. justify-content: space-evenly;
  506. margin-left: 6rpx;
  507. height: 100rpx;
  508. .info-name {
  509. display: flex;
  510. align-items: center;
  511. font-size: 32rpx;
  512. .info-name-img {
  513. margin-left: 26rpx;
  514. width: 30rpx;
  515. height: 35rpx;
  516. img {
  517. width: 100%;
  518. height: 100%;
  519. }
  520. }
  521. }
  522. .info-mes {
  523. font-size: 24rpx;
  524. color: #999999;
  525. span {
  526. margin-left: 26rpx;
  527. color: #a6a6a6;
  528. }
  529. }
  530. }
  531. .item-type {
  532. width: 104rpx;
  533. height: 41rpx;
  534. img {
  535. width: 100%;
  536. height: 100%;
  537. }
  538. }
  539. }
  540. }
  541. }
  542. .v-enter-active,
  543. .v-leave-active {
  544. transition: opacity 0.5s ease;
  545. }
  546. .v-enter-from,
  547. .v-leave-to {
  548. opacity: 0;
  549. }
  550. </style>