index.vue 12 KB

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