index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <template>
  2. <view class="order-detail" :class="{ 'fixed-bottom-2': type == 2 }" @click="playGlobalSound">
  3. <scroll-view class="scroller" :scroll-into-view="toView" scroll-y="true" scroll-with-animation="true">
  4. <view class="flex flex-a-c flex-j-b bg-white bind-audit mb-16">
  5. <text>绑定审核员</text>
  6. <text class="text-center flex-1">{{
  7. orderDetail.auditUserName || selectedAuditor?.userName || ""
  8. }}</text>
  9. <text @click="showAuditorSelector = true" class="color-primary">绑定</text>
  10. </view>
  11. <OrderInfo :detail="orderDetail" @refresh="getOrderDetail" />
  12. <UserInfoCard :detail="orderDetail" />
  13. <view class="mt-16" style="padding: 0 6rpx">
  14. <u-subsection
  15. :list="list"
  16. mode="subsection"
  17. :current="current"
  18. @change="handleSectionChange"
  19. ></u-subsection>
  20. <BookInfo
  21. v-if="current == 0"
  22. :bookList="orderDetail.detailVoList"
  23. :detail="orderDetail"
  24. @get-all-firstLetter="onGetAllFirstLetter"
  25. />
  26. <LogisticsTimeline v-if="current == 1" :list="orderDetail.trackingVoList" />
  27. <FileInfo v-if="current == 2" :orderId="orderDetail.orderId" />
  28. </view>
  29. </scroll-view>
  30. <view class="fixed-left">
  31. <view class="bind-code common-bg" style="margin-bottom: 30px; padding: 20rpx" @click="handleBindCode"
  32. >绑码
  33. </view>
  34. <view class="common-bg flex flex-a-c flex-j-c flex-d">
  35. <view class="book-status-item" @click="scrollToView('good')">良好</view>
  36. <view class="book-status-item item-center" @click="scrollToView('average')">一般</view>
  37. <view class="book-status-item" @click="scrollToView('poor')">极差</view>
  38. </view>
  39. </view>
  40. <view class="fixed-right">
  41. <view class="letter-bg flex flex-a-c flex-j-c flex-d">
  42. <view class="letter-item"
  43. ><u-icon name="arrow-up-fill" size="20" color="#ffffff" @click="scrollToTop"></u-icon
  44. ></view>
  45. <view class="letter-item" v-for="item in allLetters" @click="scrollToView(item)">{{ item }}</view>
  46. </view>
  47. </view>
  48. <view class="common-bg fixed-bottom" v-if="type != 2">
  49. <u-button type="warning" size="large" v-if="orderDetail.status == 5" @click="handleLogisticsConfirm"
  50. >物流签收</u-button
  51. >
  52. <u-button type="primary" size="large" v-if="orderDetail.status == 6" @click="handleConfirm"
  53. >确认收货</u-button
  54. >
  55. <template v-if="orderDetail.status == 8 || orderDetail.status == 9 || orderDetail.status == 10">
  56. <u-button type="warning" size="large" @click="handleScanCode">扫码</u-button>
  57. <u-button type="primary" size="large" @click="handleComplete">完成</u-button>
  58. </template>
  59. </view>
  60. <AuditorSelector
  61. :show="showAuditorSelector"
  62. @update:show="showAuditorSelector = $event"
  63. @auditor-selected="handleAuditorSelected"
  64. />
  65. </view>
  66. </template>
  67. <script setup>
  68. import { ref } from "vue";
  69. import { onLoad, onShow } from "@dcloudio/uni-app";
  70. import AuditorSelector from "./components/AuditorSelector.vue";
  71. import OrderInfo from "./components/OrderInfo.vue";
  72. import UserInfoCard from "./components/UserInfoCard.vue";
  73. import LogisticsTimeline from "../express/components/LogisticsTimeline.vue";
  74. import BookInfo from "./components/BookInfo.vue";
  75. import FileInfo from "./components/FileInfo.vue";
  76. const showAuditorSelector = ref(false);
  77. const selectedAuditor = ref({});
  78. const handleAuditorSelected = (auditor) => {
  79. selectedAuditor.value = auditor;
  80. orderDetail.value.auditUserId = auditor.userId;
  81. orderDetail.value.auditUserName = auditor.userName;
  82. uni.setStorageSync("checkUserInfo", {
  83. userName: auditor.userName,
  84. userId: auditor.userId,
  85. });
  86. };
  87. //点击全局音效
  88. function playGlobalSound() {
  89. uni.$u.playClickSound();
  90. }
  91. //点击滚动的位置
  92. const toView = ref("");
  93. function scrollToView(to) {
  94. toView.value = to;
  95. uni.pageScrollTo({
  96. selector: "#" + to,
  97. duration: 200,
  98. });
  99. }
  100. //回到顶部
  101. function scrollToTop() {
  102. uni.pageScrollTo({
  103. top: 0,
  104. duration: 200,
  105. });
  106. }
  107. //绑码
  108. function handleBindCode() {
  109. uni.$u.toast("暂无开发");
  110. }
  111. const list = ref(["图书清单", "物流信息", "上传附件"]);
  112. const current = ref(0);
  113. const handleSectionChange = (index) => {
  114. current.value = index;
  115. };
  116. //监听书籍的首字母
  117. const allLetters = ref([]);
  118. function onGetAllFirstLetter(data) {
  119. allLetters.value = data;
  120. }
  121. //物流签收 /app/orderinfo/signLogistics
  122. function handleLogisticsConfirm() {
  123. uni.showModal({
  124. title: "提示",
  125. content: "是否确认物流签收?",
  126. success: (res) => {
  127. if (res.confirm) {
  128. uni.showLoading({ title: "加载中...", mask: true });
  129. uni.$u.http
  130. .post("/app/orderinfo/signLogistics", {
  131. searchType: 1,
  132. search: orderDetail.value.orderId,
  133. })
  134. .then((res) => {
  135. if (res.code == 200) {
  136. uni.showToast({ title: "签收成功", icon: "none" });
  137. uni.$u.ttsModule.speak("签收成功");
  138. uni.navigateBack();
  139. }
  140. })
  141. .finally(() => {
  142. uni.hideLoading();
  143. });
  144. }
  145. },
  146. });
  147. }
  148. //确认收货 /app/orderinfo/confirmOrder
  149. function handleConfirm() {
  150. uni.showLoading({ title: "加载中...", mask: true });
  151. uni.$u.http
  152. .post("/app/orderinfo/confirmOrder", {
  153. searchType: 1,
  154. search: orderDetail.value.orderId,
  155. })
  156. .then((res) => {
  157. if (res.code == 200) {
  158. uni.showToast({ title: "确认收货成功", icon: "none" });
  159. uni.$u.ttsModule.speak("确认收货成功");
  160. getOrderDetail();
  161. }
  162. })
  163. .finally(() => {
  164. uni.hideLoading();
  165. });
  166. }
  167. //完成
  168. function handleComplete() {
  169. let bookList = orderDetail.value.detailVoList;
  170. let bool = bookList.some((item) => item.auditCommentList?.length < item.num);
  171. if (bool) {
  172. let text = "还有未审核的书";
  173. uni.$u.toast(text);
  174. uni.$u.ttsModule.speak(text);
  175. return;
  176. } else {
  177. uni.$u.http
  178. .post("/app/orderinfo/checkOrderFinish", {
  179. checkUserId: orderDetail.value.auditUserId,
  180. orderId: orderDetail.value.orderId,
  181. })
  182. .then((res) => {
  183. if (res.code == 200) {
  184. uni.showToast({ title: "审核完成", icon: "none" });
  185. uni.$u.ttsModule.speak("审核完成");
  186. uni.navigateBack();
  187. }
  188. });
  189. }
  190. }
  191. const orderDetail = ref({ status: 0 });
  192. //获取订单详情
  193. function getOrderDetail() {
  194. if (!orderId.value) return;
  195. uni.showLoading({
  196. title: "加载中...",
  197. mask: true,
  198. });
  199. uni.$u.http
  200. .get("/app/orderinfo/getOrderInfoForCheck", {
  201. params: {
  202. searchType: 1,
  203. search: orderId.value,
  204. },
  205. })
  206. .then((res) => {
  207. if (res.code == 200) {
  208. orderDetail.value = res.data;
  209. getCheckUserInfo();
  210. if (res.data.auditUserId) {
  211. let auditUserInfo = {
  212. userName: res.data.auditUserName,
  213. userId: res.data.auditUserId,
  214. };
  215. uni.setStorageSync("checkUserInfo", auditUserInfo);
  216. } else {
  217. let userInfo = uni.getStorageSync("checkUserInfo");
  218. orderDetail.value.auditUserName = userInfo.userName;
  219. orderDetail.value.auditUserId = userInfo.userId;
  220. }
  221. if (isOnLoad.value) {
  222. if (res.data.manageRemark.length > 0 && res.data.status < 10) {
  223. uni.$u.ttsModule.speak("此订单有备注信息,请注意查看");
  224. }
  225. if (res.data.warnArea && res.data.warnArea.length > 0) {
  226. let text = `此订单来源于${res.data.warnArea}`;
  227. uni.$u.ttsModule.speak(text);
  228. }
  229. isOnLoad.value = false;
  230. }
  231. } else {
  232. uni.$u.toast(res.msg);
  233. }
  234. })
  235. .finally(() => {
  236. uni.hideLoading();
  237. });
  238. }
  239. //获取上一次绑定的审核员信息
  240. function getCheckUserInfo() {
  241. uni.$u.http.get("/app/orderinfo/getCheckUser").then((res) => {
  242. if (res.code == 200) {
  243. let userInfo = res.data;
  244. orderDetail.value.auditUserName = userInfo.userName;
  245. orderDetail.value.auditUserId = userInfo.userId;
  246. uni.setStorageSync("checkUserInfo", {
  247. userName: userInfo.userName,
  248. userId: userInfo.userId,
  249. });
  250. }
  251. });
  252. }
  253. //isbn正则校验是否符合
  254. function checkIsbn(isbn) {
  255. const isbn13Regex = /^(?:97[89]-?\d{1,5}-?\d{1,7}-?\d{1,6}-?\d)$/;
  256. if (isbn13Regex.test(isbn)) {
  257. return true;
  258. }
  259. return false;
  260. }
  261. //扫码之后的逻辑
  262. function handleScan(isbn) {
  263. if (!checkIsbn(isbn)) {
  264. let text = `不是正确的ISBN码`;
  265. uni.$u.ttsModule.speak(text);
  266. return;
  267. }
  268. if (orderDetail.value.status >= 10) {
  269. uni.$u.ttsModule.speak("订单已审核完成");
  270. return;
  271. }
  272. let isbns = orderDetail.value.detailVoList.map((item) => item.isbn);
  273. if (isbns.includes(isbn)) {
  274. let book = orderDetail.value.detailVoList.find((item) => item.isbn == isbn);
  275. //扫描到套装书
  276. if (book.suit == 1) {
  277. let text = `${isbn}请注意套装书是否齐全`;
  278. uni.$u.ttsModule.speak(text);
  279. }
  280. //扫描到需要取出的书
  281. if (book.bookWarn == 1) {
  282. let text = `请注意${isbn}需要取出`;
  283. uni.$u.ttsModule.speak(text);
  284. }
  285. uni.navigateTo({
  286. url: `/pages/index/detail/book-audit?isbn=${isbn}&orderId=${orderDetail.value.orderId}`,
  287. });
  288. uni.setStorageSync("auditBook", book);
  289. uni.setStorageSync("orderDetail", orderDetail.value);
  290. } else {
  291. let text = `此订单中不存在${isbn}这本书 `;
  292. uni.$u.ttsModule.speak(text);
  293. }
  294. }
  295. //扫码
  296. function handleScanCode() {
  297. uni.scanCode({
  298. success: (res) => {
  299. res.result && handleScan(res.result);
  300. },
  301. });
  302. }
  303. const orderId = ref("");
  304. const isOnLoad = ref(false);
  305. // 1 表示到货审核 2 表示查看订单
  306. const type = ref(1);
  307. onLoad((option) => {
  308. orderId.value = option.id;
  309. getOrderDetail();
  310. isOnLoad.value = true;
  311. type.value = option.type || 1;
  312. uni.removeStorageSync("scannedBooks");
  313. // #ifdef APP-PLUS
  314. uni.$u.useGlobalEvent((e) => {
  315. if (e.barcode) {
  316. handleScan(e.barcode);
  317. }
  318. });
  319. // #endif
  320. });
  321. onShow(() => {
  322. uni.$u.updateActivePageOnShow();
  323. getOrderDetail();
  324. });
  325. </script>
  326. <style>
  327. page {
  328. background-color: #f5f5f5;
  329. }
  330. </style>
  331. <style lang="scss" scoped>
  332. .order-detail {
  333. font-size: 30rpx;
  334. padding-bottom: 140rpx;
  335. position: relative;
  336. &.fixed-bottom-2 {
  337. padding-bottom: 30rpx;
  338. }
  339. .bind-audit {
  340. padding: 20rpx 30rpx;
  341. border-bottom: 1px solid #e5e5e5;
  342. }
  343. .fixed-left {
  344. position: fixed;
  345. left: 0;
  346. top: 11%;
  347. width: 100rpx;
  348. .common-bg {
  349. background-color: rgba(34, 172, 56, 0.7);
  350. border-radius: 0 30rpx 30rpx 0;
  351. font-weight: 500;
  352. color: #ffffff;
  353. }
  354. .book-status-item {
  355. padding: 20rpx;
  356. border-top: 1rpx solid #ffffff;
  357. border-bottom: 1rpx solid #ffffff;
  358. }
  359. }
  360. .fixed-right {
  361. position: fixed;
  362. right: 0;
  363. top: 12%;
  364. width: 70rpx;
  365. .letter-bg {
  366. background-color: rgba(34, 172, 56, 0.7);
  367. border-radius: 10rpx 0 0 10rpx;
  368. font-weight: 500;
  369. color: #ffffff;
  370. padding: 12rpx 0;
  371. padding-bottom: 6rpx;
  372. }
  373. .letter-item {
  374. padding-bottom: 12rpx;
  375. }
  376. }
  377. }
  378. </style>