Queue.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <template>
  2. <div class="queue">
  3. <van-nav-bar
  4. title="预约列表"
  5. right-text="营业时间"
  6. @click-left="toAdmin"
  7. @click-right="toOpen"
  8. left-text="添加预定"
  9. left-arrow
  10. />
  11. <van-cell-group>
  12. <van-cell v-for="(item, i) in queueList" :key="i">
  13. <template #title>
  14. <van-tag size="large" v-if="item.orderType === 1" type="success"
  15. >APP</van-tag
  16. >
  17. <van-tag size="large" v-else type="warning ">现场</van-tag>
  18. {{ item.userName }}
  19. {{ item.userPhone }}
  20. </template>
  21. <template #label>
  22. {{ item.orderTime }}
  23. </template>
  24. <template #default>
  25. <van-button
  26. v-if="i === 0"
  27. type="default"
  28. size="small"
  29. @click="skipUser"
  30. >
  31. 跳过
  32. </van-button>
  33. <van-button
  34. type="warning"
  35. size="small"
  36. v-if="i !== 0 && item.orderType === 1"
  37. @click="() => advancefun(item.id)"
  38. >
  39. 已到达
  40. </van-button>
  41. <van-button type="info" size="small" @click="() => nextItem(item.id)">
  42. 完成
  43. </van-button>
  44. <van-button
  45. type="warning"
  46. size="small"
  47. @click="() => removequeue(item.id, i)"
  48. >
  49. 删除
  50. </van-button>
  51. </template>
  52. </van-cell>
  53. </van-cell-group>
  54. <van-popup closeable v-model="open" position="right" class="open">
  55. <van-checkbox-group v-model="checkbox" v-if="showPopover.length">
  56. <van-row v-for="(item, i) in weeks" :key="i">
  57. <van-col span="8">
  58. <van-checkbox :name="i" style="height: 2em">
  59. {{ item }}
  60. </van-checkbox>
  61. </van-col>
  62. <van-col span="16">
  63. <van-popover
  64. style="width: 100%; text-align: center"
  65. v-model="showPopover[i]"
  66. trigger="click"
  67. >
  68. <div style="display: flex; padding: 10px">
  69. <div style="flex: 1; text-align: left">
  70. <van-button
  71. plain
  72. hairline
  73. type="default"
  74. size="small"
  75. @click="() => closeTime(i)"
  76. >
  77. 取消
  78. </van-button>
  79. </div>
  80. <div style="flex: 1; text-align: right">
  81. <van-button
  82. plain
  83. hairline
  84. type="info"
  85. size="small"
  86. @click="() => saveTime(i)"
  87. >
  88. 确认
  89. </van-button>
  90. </div>
  91. </div>
  92. <div
  93. style="
  94. width: 200px;
  95. display: flex;
  96. margin: 0 10px 10px 10px;
  97. border: 1px solid #eee;
  98. "
  99. >
  100. <van-datetime-picker
  101. style="flex: 1"
  102. v-model="time[i]"
  103. type="time"
  104. class="van-hairline--left"
  105. :show-toolbar="false"
  106. />
  107. <van-datetime-picker
  108. style="flex: 1; border-left: 1px solid #eee"
  109. v-model="time2[i]"
  110. :show-toolbar="false"
  111. type="time"
  112. />
  113. </div>
  114. <template #reference>
  115. <div class="timerange">
  116. {{ timerange[i] }}
  117. </div>
  118. </template>
  119. </van-popover>
  120. </van-col>
  121. </van-row>
  122. <br />
  123. <van-button
  124. :loading="load"
  125. @click="upRulefun"
  126. round
  127. type="info"
  128. loading-text="加载中..."
  129. block
  130. >
  131. 保 存
  132. </van-button>
  133. </van-checkbox-group>
  134. </van-popup>
  135. </div>
  136. </template>
  137. <script>
  138. // @ is an alias to /src
  139. import {
  140. Cell as vanCell,
  141. CellGroup as vanCellGroup,
  142. Button as vanButton,
  143. NavBar as vanNavBar,
  144. Popup as vanPopup,
  145. Col as vanCol,
  146. Row as vanRow,
  147. Checkbox as vanCheckbox,
  148. CheckboxGroup as vanCheckboxGroup,
  149. Popover as vanPopover,
  150. DatetimePicker as vanDatetimePicker,
  151. Tag as vanTag,
  152. Dialog,
  153. Notify,
  154. Toast,
  155. } from "vant";
  156. import "vant/lib/toast/style/index";
  157. import "vant/lib/tag/style/index";
  158. import "vant/lib/cell/style/index";
  159. import "vant/lib/cell-group/style/index";
  160. import "vant/lib/dialog/style/index";
  161. import "vant/lib/button/style/index";
  162. import "vant/lib/popup/style/index";
  163. import "vant/lib/col/style/index";
  164. import "vant/lib/row/style/index";
  165. import "vant/lib/notify/style/index";
  166. import "vant/lib/datetime-picker/style/index";
  167. import "vant/lib/popover/style/index";
  168. import "vant/lib/checkbox/style/index";
  169. import "vant/lib/checkbox-group/style/index";
  170. import "vant/lib/nav-bar/style/index";
  171. import {
  172. orderList,
  173. skip,
  174. nextone,
  175. cancel,
  176. advance,
  177. getRule,
  178. upRule,
  179. } from "../api/index";
  180. export default {
  181. name: "Queue",
  182. data() {
  183. return {
  184. today: new Date(),
  185. queueList: [],
  186. showPopover: [],
  187. open: false,
  188. time: [],
  189. time2: [],
  190. timerange: [],
  191. checkbox: [],
  192. weeks: [],
  193. load: false,
  194. load1: false,
  195. };
  196. },
  197. mounted() {
  198. this.reloadOrder();
  199. window.setInterval(() => {
  200. this.reloadOrder();
  201. }, 60000);
  202. },
  203. computed: {},
  204. methods: {
  205. closeTime(t) {
  206. const showP = JSON.parse(JSON.stringify(this.showPopover));
  207. this.time[t] = this.timerange[t].split(" - ")[0];
  208. this.time2[t] = this.timerange[t].split(" - ")[1];
  209. showP[t] = false;
  210. this.showPopover = showP;
  211. },
  212. saveTime(t) {
  213. let s = this.time[t].split(":"),
  214. e = this.time2[t].split(":");
  215. let sMin = Number(s[0] * 60 || 0) + Number(s[1] || 0);
  216. let eMin = Number(e[0] * 60 || 0) + Number(e[1] || 0);
  217. if (eMin < sMin) return Notify("结束时间应在开始时间之后");
  218. this.timerange[t] = this.time[t] + " - " + this.time2[t];
  219. this.closeTime(t);
  220. },
  221. upRulefun() {
  222. this.load = true;
  223. upRule({
  224. week: this.formatRule(),
  225. })
  226. .then(() => {
  227. this.load = false;
  228. Toast("保存成功");
  229. })
  230. .catch(() => {
  231. this.load = false;
  232. });
  233. },
  234. formatRule() {
  235. let li = [],
  236. week = {
  237. 周一: 1,
  238. 周二: 2,
  239. 周三: 3,
  240. 周四: 4,
  241. 周五: 5,
  242. 周六: 6,
  243. 周日: 7,
  244. },
  245. check = this.checkbox.join(",");
  246. for (let i = 0; i < this.showPopover.length; i++) {
  247. const time = this.time[i],
  248. time2 = this.time2[i],
  249. rex = new RegExp(i);
  250. li.push({
  251. week: week[this.weeks[i]],
  252. start: time,
  253. end: time2,
  254. status: rex.test(check) ? "OPEN" : "STOP",
  255. });
  256. }
  257. return li;
  258. },
  259. toOpen() {
  260. getRule().then(res => {
  261. const li = res || [],
  262. week = {
  263. 1: "一",
  264. 2: "二",
  265. 3: "三",
  266. 4: "四",
  267. 5: "五",
  268. 6: "六",
  269. 7: "日",
  270. };
  271. let W = [];
  272. let showPopover = [],
  273. timerange = [],
  274. time = [],
  275. time2 = [],
  276. checkbox = [];
  277. for (let i = 0; i < li.length; i++) {
  278. const v = li[i];
  279. let sT = v.start ? this.format(v.start) : "00:00";
  280. let eT = v.end ? this.format(v.end) : "00:00";
  281. W.push("周" + week[v.week]);
  282. showPopover.push(false);
  283. v.status === "OPEN" && checkbox.push(i);
  284. timerange.push(sT + " - " + eT);
  285. time.push(sT);
  286. time2.push(eT);
  287. }
  288. this.weeks = W;
  289. this.showPopover = showPopover;
  290. this.time = time;
  291. this.time2 = time2;
  292. this.timerange = timerange;
  293. this.checkbox = checkbox;
  294. this.open = true;
  295. });
  296. },
  297. format(T) {
  298. let o = T.split(":");
  299. o.splice(2, 1);
  300. return o.join(":");
  301. },
  302. reloadOrder() {
  303. if (this.load1) return;
  304. this.load1 = true;
  305. orderList({
  306. today: true,
  307. })
  308. .then(res => {
  309. this.queueList = res || [];
  310. this.load1 = false;
  311. })
  312. .catch(() => {
  313. this.load1 = false;
  314. });
  315. },
  316. toAdmin() {
  317. this.$router.push({ name: "Applyreal", params: { a: 0 } });
  318. },
  319. skipUser() {
  320. Dialog.confirm({
  321. message: "是否跳过该用户?",
  322. confirmButtonColor: "#2a7ef4",
  323. }).then(() => {
  324. skip().then(() => {
  325. this.reloadOrder();
  326. });
  327. });
  328. },
  329. advancefun(id) {
  330. Dialog.confirm({
  331. message: "请确认该用户已到达",
  332. confirmButtonColor: "#2a7ef4",
  333. }).then(() => {
  334. advance({ id }).then(() => {
  335. this.reloadOrder();
  336. });
  337. });
  338. },
  339. nextItem(id) {
  340. Dialog.confirm({
  341. message: "该服务是否已完成?",
  342. confirmButtonColor: "#2a7ef4",
  343. }).then(() => {
  344. nextone({
  345. id,
  346. }).then(() => {
  347. this.reloadOrder();
  348. });
  349. });
  350. },
  351. removequeue(id, i) {
  352. Dialog.confirm({
  353. message: "确定要删除该预约?",
  354. confirmButtonColor: "#2a7ef4",
  355. }).then(() => {
  356. // on confirm
  357. cancel({
  358. id,
  359. }).then(() => {
  360. let queueList = JSON.parse(JSON.stringify(this.queueList));
  361. queueList.splice(i, 1);
  362. this.queueList = queueList;
  363. });
  364. });
  365. },
  366. },
  367. beforeUnmount: function () {},
  368. components: {
  369. vanCell,
  370. vanCellGroup,
  371. vanButton,
  372. vanNavBar,
  373. vanPopup,
  374. vanCol,
  375. vanRow,
  376. vanCheckbox,
  377. vanCheckboxGroup,
  378. vanPopover,
  379. vanDatetimePicker,
  380. vanTag,
  381. },
  382. };
  383. </script>
  384. <style>
  385. .queue {
  386. width: 1200px;
  387. height: 100%;
  388. overflow-y: scroll;
  389. margin: 0 auto;
  390. background-color: #fff;
  391. }
  392. .queue .open {
  393. height: 100%;
  394. min-width: 500px;
  395. padding: 3.5em 1em 1em 2em;
  396. box-sizing: border-box;
  397. }
  398. .queue .van-col {
  399. height: 2.5em;
  400. line-height: 1.5em;
  401. }
  402. .queue .timerange {
  403. border-radius: 3px;
  404. padding: 3px 5px;
  405. width: 100%;
  406. box-sizing: border-box;
  407. border: 1px solid #eee;
  408. cursor: pointer;
  409. }
  410. .queue .van-cell {
  411. padding: 30px 16px;
  412. line-height: 50px;
  413. }
  414. .queue .van-cell__title {
  415. font-size: 50px;
  416. }
  417. .queue .van-cell__title {
  418. flex: 2;
  419. }
  420. .queue .van-button {
  421. font-size: 35px;
  422. height: 45px;
  423. }
  424. .queue .van-tag {
  425. vertical-align: middle;
  426. }
  427. .queue .van-hairline--bottom {
  428. height: 130px;
  429. line-height: 130px;
  430. }
  431. .queue .van-nav-bar__content {
  432. height: 130px;
  433. }
  434. .queue .van-nav-bar__title,
  435. .queue .van-nav-bar__text,
  436. .queue .van-nav-bar__left {
  437. line-height: 130px;
  438. font-size: 50px;
  439. }
  440. .queue .van-nav-bar__arrow {
  441. line-height: 130px;
  442. font-size: 50px;
  443. }
  444. .queue .van-cell__label {
  445. font-size: 35px;
  446. padding-top: 15px;
  447. padding-left: 60px;
  448. }
  449. </style>