detail.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <script setup>
  2. import { ref, computed } from 'vue'
  3. import { onLoad, onShow } from '@dcloudio/uni-app'
  4. import { getWeighing, updateWeighing, voidWeighing } from '@/api/db'
  5. import { weighingPhase, dash, formatWeight, nowYmdHms, todayYmd } from '@/utils/dbLabels'
  6. import { PAGE_PATHS } from '@/config/api'
  7. const id = ref('')
  8. const detail = ref(null)
  9. const showSecond = ref(false)
  10. const tareWeight = ref('')
  11. const acting = ref(false)
  12. const phase = computed(() => weighingPhase(detail.value))
  13. const canSecond = computed(() => phase.value.text === '一次过磅')
  14. const canVoid = computed(() => {
  15. if (!detail.value || Number(detail.value.isVoided) === 1) return false
  16. const t = String(detail.value.grossWeightTime || detail.value.createdAt || '')
  17. return t.startsWith(todayYmd())
  18. })
  19. const goBack = () => {
  20. uni.navigateBack({
  21. fail: () => uni.navigateTo({ url: PAGE_PATHS.dbWeighingList })
  22. })
  23. }
  24. const load = async () => {
  25. if (!id.value) return
  26. try {
  27. detail.value = await getWeighing(id.value)
  28. } catch (e) {
  29. uni.showToast({ title: e.message || '加载失败', icon: 'none' })
  30. }
  31. }
  32. const openSecond = () => {
  33. tareWeight.value = ''
  34. showSecond.value = true
  35. }
  36. const submitSecond = async () => {
  37. const tare = Number(tareWeight.value)
  38. if (!tare || tare <= 0) {
  39. uni.showToast({ title: '请填写皮重', icon: 'none' })
  40. return
  41. }
  42. const gross = Number(detail.value?.grossWeight) || 0
  43. const deduction = Number(detail.value?.deduction) || 0
  44. const net = Math.max(gross - tare - deduction, 0)
  45. acting.value = true
  46. try {
  47. await updateWeighing(id.value, {
  48. tareWeight: tare,
  49. tareWeightTime: nowYmdHms(),
  50. netWeight: net
  51. })
  52. uni.showToast({ title: '二次过磅已保存', icon: 'success' })
  53. showSecond.value = false
  54. load()
  55. } catch (e) {
  56. uni.showToast({ title: e.message || '保存失败', icon: 'none' })
  57. } finally {
  58. acting.value = false
  59. }
  60. }
  61. const onVoid = () => {
  62. uni.showModal({
  63. title: '作废地磅单',
  64. content: '仅支持作废当天单据,确认作废?',
  65. success: async (r) => {
  66. if (!r.confirm) return
  67. acting.value = true
  68. try {
  69. await voidWeighing(id.value)
  70. uni.showToast({ title: '已作废', icon: 'success' })
  71. load()
  72. } catch (e) {
  73. uni.showToast({ title: e.message || '作废失败', icon: 'none' })
  74. } finally {
  75. acting.value = false
  76. }
  77. }
  78. })
  79. }
  80. onLoad((q) => {
  81. id.value = q?.id || ''
  82. })
  83. onShow(() => load())
  84. </script>
  85. <template>
  86. <view class="mp-page mp-page--sub mp-page--with-bottom">
  87. <view class="mp-header mp-header--db">
  88. <text class="mp-subpage-back" @click="goBack">← 返回</text>
  89. <text class="mp-header__title" style="margin-top: 16rpx">地磅单详情</text>
  90. </view>
  91. <view v-if="detail" class="mp-detail-hero">
  92. <view class="mp-detail-hero__top">
  93. <view>
  94. <text class="mp-detail-hero__title">{{ dash(detail.vehicleNo) }}</text>
  95. <text class="mp-detail-hero__sub">{{ dash(detail.cargoName) }} · {{ dash(detail.businessType) }}</text>
  96. </view>
  97. <text class="mp-tag" :class="'mp-tag--' + phase.tag">{{ phase.text }}</text>
  98. </view>
  99. <view class="mp-detail-hero__meta">
  100. <text class="mp-detail-hero__chip">净重 {{ formatWeight(detail.netWeight) }}</text>
  101. <text class="mp-detail-hero__chip">{{ dash(detail.batchNo) }}</text>
  102. </view>
  103. </view>
  104. <view class="mp-block">
  105. <text class="mp-block__title">过磅数据</text>
  106. <view class="mp-block__panel">
  107. <view class="mp-kv"><text class="mp-kv__label">毛重</text><text class="mp-kv__value">{{ formatWeight(detail?.grossWeight) }}</text></view>
  108. <view class="mp-kv"><text class="mp-kv__label">毛重时间</text><text class="mp-kv__value">{{ dash(detail?.grossWeightTime) }}</text></view>
  109. <view class="mp-kv"><text class="mp-kv__label">皮重</text><text class="mp-kv__value">{{ formatWeight(detail?.tareWeight) }}</text></view>
  110. <view class="mp-kv"><text class="mp-kv__label">皮重时间</text><text class="mp-kv__value">{{ dash(detail?.tareWeightTime) }}</text></view>
  111. <view class="mp-kv"><text class="mp-kv__label">扣重</text><text class="mp-kv__value">{{ formatWeight(detail?.deduction) }}</text></view>
  112. <view class="mp-kv"><text class="mp-kv__label">净重</text><text class="mp-kv__value">{{ formatWeight(detail?.netWeight) }}</text></view>
  113. </view>
  114. </view>
  115. <view class="mp-block">
  116. <text class="mp-block__title">业务信息</text>
  117. <view class="mp-block__panel">
  118. <view class="mp-kv"><text class="mp-kv__label">计划号</text><text class="mp-kv__value">{{ dash(detail?.planNo) }}</text></view>
  119. <view class="mp-kv"><text class="mp-kv__label">规格</text><text class="mp-kv__value">{{ dash(detail?.specification) }}</text></view>
  120. <view class="mp-kv"><text class="mp-kv__label">供货单位</text><text class="mp-kv__value">{{ dash(detail?.supplier) }}</text></view>
  121. <view class="mp-kv"><text class="mp-kv__label">收货单位</text><text class="mp-kv__value">{{ dash(detail?.consignee) }}</text></view>
  122. <view class="mp-kv"><text class="mp-kv__label">过磅点</text><text class="mp-kv__value">{{ dash(detail?.weighingPoint) }}</text></view>
  123. <view class="mp-kv"><text class="mp-kv__label">备注</text><text class="mp-kv__value">{{ dash(detail?.remarks) }}</text></view>
  124. </view>
  125. </view>
  126. <view v-if="showSecond" class="mp-form-panel">
  127. <view class="mp-form-row">
  128. <text class="mp-form-label mp-form-label--req">皮重(kg)</text>
  129. <input v-model="tareWeight" class="mp-form-input" type="digit" placeholder="二次过磅皮重" />
  130. </view>
  131. <view class="mp-form-row" style="display: flex; gap: 16rpx">
  132. <view class="mp-btn mp-btn--ghost" style="flex: 1" @click="showSecond = false">取消</view>
  133. <view class="mp-btn mp-btn--primary" style="flex: 1" @click="submitSecond">
  134. {{ acting ? '…' : '确认保存' }}
  135. </view>
  136. </view>
  137. </view>
  138. <view class="mp-bottom-bar">
  139. <view v-if="canSecond" class="mp-btn mp-btn--primary" @click="openSecond">二次过磅</view>
  140. <view v-if="canVoid" class="mp-btn mp-btn--danger" @click="onVoid">作废</view>
  141. </view>
  142. </view>
  143. </template>