detail.vue 12 KB

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