book-audit.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <template>
  2. <view class="book-audit" @click="playGlobalSound">
  3. <view class="bg-white flex flex-a-c" style="padding: 20rpx; border-radius: 10rpx">
  4. <image :src="detail.cover" mode="aspectFill" style="width: 80px; height: 100px"></image>
  5. <view class="flex flex-d flex-1 ml-20">
  6. <text class="common-title mb-20">{{ detail.bookName }}</text>
  7. <text class="text-sm"
  8. >ISBN: <text class="color-primary">{{ detail.isbn }}</text>
  9. </text>
  10. <text class="text-sm mt-6"
  11. >作者: <text>{{ detail.author }}</text>
  12. </text>
  13. <text class="text-sm mt-6"
  14. >出版社: <text>{{ detail.publish }}</text>
  15. </text>
  16. </view>
  17. </view>
  18. <view class="mt-20 bg-white price-info" style="border-radius: 10rpx">
  19. <view class="flex">
  20. <view class="flex flex-a-c flex-1">
  21. <text class="label">定价</text>
  22. <text class="content">¥{{ detail.price }}</text>
  23. </view>
  24. <view class="flex flex-a-c flex-1">
  25. <text class="label">回收折扣</text>
  26. <text class="content">{{ detail.recycleDiscount }}折</text>
  27. </view>
  28. </view>
  29. <view class="flex flex-a-c">
  30. <view class="flex flex-a-c flex-1">
  31. <text class="label">预估金额</text>
  32. <text class="content">¥{{ auditBook.expectMoney }}</text>
  33. </view>
  34. <view class="flex flex-a-c flex-1">
  35. <text class="label">审核金额</text>
  36. <text class="content">¥{{ auditBook.finalMoney || 0 }}</text>
  37. </view>
  38. </view>
  39. </view>
  40. <view class="mt-20">
  41. <u-subsection
  42. :list="list"
  43. mode="subsection"
  44. :current="current"
  45. @change="handleSectionChange"
  46. ></u-subsection>
  47. <AuditInfo
  48. v-show="current == 0"
  49. :detail="auditBook"
  50. :auditList="auditBook.auditCommentList"
  51. ref="auditInfoRef"
  52. />
  53. <FileInfo v-show="current == 2" :orderId="orderId" :annexType="2" :isbn="isbnScan" />
  54. </view>
  55. <view class="fixed-bottom">
  56. <u-button type="warning" size="large" @click="handleScanCode">扫码</u-button>
  57. <u-button type="primary" size="large" @click="handleAudit">确定</u-button>
  58. </view>
  59. </view>
  60. </template>
  61. <script setup>
  62. import { ref, nextTick } from "vue";
  63. import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
  64. import AuditInfo from "./components/AuditInfo.vue";
  65. import FileInfo from "./components/FileInfo.vue";
  66. const detail = ref({});
  67. function playGlobalSound(){
  68. uni.$u.playClickSound()
  69. }
  70. // 获取图书详情 /app/book/getSimpleBookInfoByIsbn/{isbn}
  71. const getBookInfo = (isbn) => {
  72. uni.$u.http.get(`/app/book/getBookByIsbn/${isbn}`).then((res) => {
  73. if (res.code == 200) {
  74. detail.value = res.data;
  75. }
  76. });
  77. };
  78. //获取图书信息和审核信息
  79. const auditBook = ref({});
  80. const getBookInfoAndAuditInfo = (isbn, orderId) => {
  81. uni.$u.http.get(`/app/orderinfo/getBookCheckInfo?isbn=${isbn}&&orderId=${orderId}`).then((res) => {
  82. if (res.code == 200) {
  83. auditBook.value = res.data;
  84. nextTick(() => {
  85. auditInfoRef.value?.initAuditList(auditBook.value);
  86. });
  87. }
  88. });
  89. };
  90. const list = ref(["图书审核", "绑码", "附件信息"]);
  91. const current = ref(0);
  92. const handleSectionChange = (index) => {
  93. current.value = index;
  94. };
  95. //图书审核
  96. const auditData = ref([]);
  97. const handleAuditSelected = (data) => {
  98. auditData.value = data.map((item, index) => {
  99. item.idx = index;
  100. item.com = Array.isArray(item.com) ? item.com.join(",") : item.com;
  101. return item;
  102. });
  103. };
  104. //存储已经扫码的图书
  105. const scannedBooks = ref([]);
  106. //isbn正则校验是否符合
  107. function checkIsbn(isbn) {
  108. const isbn13Regex = /^(?:97[89]-?\d{1,5}-?\d{1,7}-?\d{1,6}-?\d)$/;
  109. if (isbn13Regex.test(isbn)) {
  110. return true;
  111. }
  112. return false;
  113. }
  114. //扫码之后的逻辑
  115. function handleScan(isbn) {
  116. if (!checkIsbn(isbn)) {
  117. let text = `不是正确的ISBN码`;
  118. uni.$u.ttsModule.speak(text);
  119. return;
  120. }
  121. //取 isbn 的后四位字符串进行播报
  122. let isbnStr = `${isbn.slice(-4)}`;
  123. let isbns = orderDetail.value.detailVoList.map((item) => item.isbn);
  124. if (isbns.includes(isbn)) {
  125. let book = orderDetail.value.detailVoList.find((item) => item.isbn == isbn);
  126. if (book.auditCommentList?.length > 0) {
  127. let noAuditNum = book.auditCommentList.filter((item) => item.sts == 0).length;
  128. console.log(noAuditNum, 'noAuditNum')
  129. if (noAuditNum == 0) {
  130. let text = `${isbnStr}已超出订单中的数量`;
  131. uni.$u.ttsModule.speak(text);
  132. return;
  133. }
  134. //扫描到套装书
  135. if (book.suit == 1) {
  136. let text = `${isbnStr}请注意套装书是否齐全`;
  137. uni.$u.ttsModule.speak(text);
  138. }
  139. //扫描到需要取出的书
  140. if (book.bookWarn == 1) {
  141. let text = `请注意${isbnStr}需要取出`;
  142. uni.$u.ttsModule.speak(text);
  143. }
  144. scannedBooks.value.push(isbn);
  145. uni.setStorageSync("scannedBooks", scannedBooks.value);
  146. uni.redirectTo({
  147. url: `/pages/index/detail/batch-audit?orderId=${orderId.value}`,
  148. });
  149. }
  150. } else {
  151. let text = `此订单中不存在${isbnStr}这本书 `;
  152. uni.$u.ttsModule.speak(text);
  153. }
  154. }
  155. //扫码
  156. function handleScanCode() {
  157. uni.scanCode({
  158. success: (res) => {
  159. handleScan(res.result);
  160. },
  161. });
  162. }
  163. const auditInfoRef = ref();
  164. //审核 /app/orderinfo/checkOrder
  165. const handleAudit = () => {
  166. let checkList = auditInfoRef.value?.formatReason(auditData.value);
  167. let checkUserInfo = uni.getStorageSync("checkUserInfo");
  168. if (checkUserInfo.userId) {
  169. checkUserId.value = checkUserInfo.userId;
  170. } else {
  171. uni.$u.toast("请先选择审核人");
  172. }
  173. //审核极差的必须选择原因
  174. let poorList = checkList.filter((item) => item.sts == 3);
  175. if (poorList.length > 0 && !poorList.every((item) => item.com)) {
  176. uni.$u.ttsModule.speak("请选择品相");
  177. return;
  178. }
  179. uni.$u.http
  180. .post("/app/orderinfo/checkOrder", {
  181. checkUserId: checkUserId.value,
  182. orderId: orderId.value,
  183. checkList: checkList,
  184. })
  185. .then((res) => {
  186. if (res.code == 200) {
  187. uni.showToast({ title: "审核成功", icon: "none" });
  188. uni.$u.ttsModule.speak("审核成功");
  189. uni.navigateBack();
  190. } else {
  191. uni.$u.toast(res.msg);
  192. }
  193. });
  194. };
  195. const checkUserId = ref();
  196. const orderId = ref();
  197. const orderDetail = ref({});
  198. let isbnScan = ref("");
  199. onLoad((options) => {
  200. options.isbn && getBookInfo(options.isbn);
  201. scannedBooks.value = [options.isbn];
  202. isbnScan.value = options.isbn;
  203. orderId.value = options.orderId;
  204. getBookInfoAndAuditInfo(options.isbn, options.orderId);
  205. orderDetail.value = uni.getStorageSync("orderDetail");
  206. // #ifdef APP-PLUS
  207. uni.$u.useGlobalEvent((e) => {
  208. if (e.barcode) {
  209. handleScan(e.barcode);
  210. }
  211. });
  212. // #endif
  213. });
  214. onShow(() => {
  215. if (isbnScan.value) {
  216. checkUserId.value = uni.getStorageSync("userInfo")?.userId;
  217. orderDetail.value = uni.getStorageSync("orderDetail");
  218. }
  219. uni.$u.updateActivePageOnShow();
  220. });
  221. onUnload(() => {
  222. uni.$u.cleanupOnPageUnload();
  223. });
  224. </script>
  225. <style lang="scss" scoped>
  226. .book-audit {
  227. padding: 20rpx;
  228. box-sizing: border-box;
  229. padding-bottom: 140rpx;
  230. .price-info {
  231. border-radius: 10rpx;
  232. .label {
  233. width: 150rpx;
  234. background-color: #cecece;
  235. padding: 16rpx 10rpx;
  236. text-align: center;
  237. border: 1rpx solid #e6e6e6;
  238. }
  239. .content {
  240. flex: 1;
  241. text-align: center;
  242. padding: 16rpx 10rpx;
  243. border: 1rpx solid #e6e6e6;
  244. }
  245. }
  246. }
  247. </style>