zengjun vor 7 Monaten
Ursprung
Commit
8ab62e009f
3 geänderte Dateien mit 443 neuen und 86 gelöschten Zeilen
  1. 12 0
      src/api/basic/index.ts
  2. 1 1
      src/static/setting.txt
  3. 430 85
      src/views/returned/register/index.vue

+ 12 - 0
src/api/basic/index.ts

@@ -36,3 +36,15 @@ export function getWarehouse(){
   })
 }
 
+
+
+/**
+ * 全部承运商
+ */
+export function carrierOptions() {
+  return request({
+    url: '/api/base/carrier/options',
+    method: 'get',
+    params: { type: null }
+  })
+}

+ 1 - 1
src/static/setting.txt

@@ -1 +1 @@
-64
+66

+ 430 - 85
src/views/returned/register/index.vue

@@ -53,7 +53,9 @@
             <div>
               <div class="content-tips">
                 <div style="flex: 1">
-                  <van-notice-bar color="#1989fa" background="#ecf9ff">{{ ownerQualityInspection }}</van-notice-bar>
+                  <van-notice-bar color="#1989fa" background="#ecf9ff"
+                    >{{ ownerQualityInspection }}
+                  </van-notice-bar>
                 </div>
               </div>
             </div>
@@ -210,7 +212,9 @@
             <div>
               <div class="content-tips">
                 <div style="flex: 1">
-                  <van-notice-bar color="#1989fa" background="#ecf9ff">{{ ownerQualityInspection }}</van-notice-bar>
+                  <van-notice-bar color="#1989fa" background="#ecf9ff"
+                    >{{ ownerQualityInspection }}
+                  </van-notice-bar>
                 </div>
               </div>
             </div>
@@ -266,13 +270,42 @@
                     {{ item.remark }}
                   </div>
                 </div>
-                <div class="card-div-footer-images">
-                  <van-image
-                    width="100"
-                    height="100"
-                    src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
-                  />
-                </div>
+
+                <template v-if="hasBoxItems(item)">
+                  <div>
+                    <van-divider content-position="left">外箱图</van-divider>
+                    <van-row>
+                      <template v-for="(i, imgIndex) in getBoxItems(item)">
+                        <van-col span="4">
+                          <van-image
+                            :key="`box-photos-${index}-${imgIndex}`"
+                            width="100%"
+                            height="50"
+                            :src="i.src"
+                          />
+                        </van-col>
+                      </template>
+                    </van-row>
+                  </div>
+                </template>
+
+                <template v-if="hasProductItems(item)">
+                  <div>
+                    <van-divider content-position="left">内物图</van-divider>
+                    <van-row>
+                      <template v-for="(i, imgIndex) in getProductItems(item)">
+                        <van-col span="4">
+                          <van-image
+                            :key="`product-photos-${index}-${imgIndex}`"
+                            width="100%"
+                            height="50"
+                            :src="i.src"
+                          />
+                        </van-col>
+                      </template>
+                    </van-row>
+                  </div>
+                </template>
 
                 <div class="card-div-footer-options">
                   <div class="options-row">
@@ -351,8 +384,11 @@
             v-model:show="returnedDetailDialog"
             title="商品详情"
             show-cancel-button
+            :show-confirm-button="checkUploadImages()"
             @confirm="addDetails"
           >
+
+
             <div style="max-height: 70vh; overflow-y: auto">
               <van-field
                 v-model="selectDetail.sku"
@@ -456,43 +492,126 @@
                 label-align="top"
               />
 
-              <van-row>
-                <template
-                  v-if="
-                    selectDetail.boxPhotos && selectDetail.boxPhotos.length > 0
-                  "
-                >
-                  <template v-for="(item, index) in selectDetail.boxPhotos">
-                    <van-col span="4">
-                      <van-image
-                        :key="`box-photos-${index}`"
-                        width="100"
-                        height="100"
-                        :src="getImageUrl(item, '外箱图')"
-                      />
-                    </van-col>
+              <van-row v-if="showAccessories">
+                <div style="font-size: 12px;">
+                  <template v-for="(item,index) in accessories">
+                    <p>
+                      配件条码:
+                      [<span style="color: #2ca547">{{ item.accessory }}</span>]
+                      [<span style="color: #277b39 ">{{ item.descrC }}</span>]
+                      数量:
+                      [<span style="color: #2ca547">{{ item.qty }}</span>]件
+                    </p>
                   </template>
-                </template>
+                  <p style="font-size: 12px">
+                    请检查商品:
+                    【<span style="color: #ff2020">{{ selectDetail.sku}}</span>】
+                    {{ selectDetail.tradeName }} 配件
+                  </p>
+                </div>
+
               </van-row>
-              <van-row>
-                <template
-                  v-if="
-                    selectDetail.productPhotos &&
-                    selectDetail.productPhotos.length > 0
-                  "
-                >
+
+              <template
+                v-if="
+                  selectDetail.boxPhotos && selectDetail.boxPhotos.length > 0
+                "
+              >
+                <van-divider content-position="left" style="margin: 0px">外箱图</van-divider>
+                <van-row>
+                  <template
+                    v-if="
+                      selectDetail.boxPhotos &&
+                      selectDetail.boxPhotos.length > 0
+                    "
+                  >
+                    <template v-for="(item, index) in selectDetail.boxPhotos">
+                      <van-col span="4">
+                        <van-image
+                          :key="`box-photos-${index}`"
+                          width="100%"
+                          height="50"
+                          :src="getImageUrl(item, '外箱图')"
+                          @click="showBoxImagePreview(index)"
+                        />
+                      </van-col>
+                    </template>
+
+                    <van-image-preview
+                      v-model:show="showBoxPreview"
+                      :images="detailBoxImages"
+                      :start-position="startBoxPosition"
+                      @change="onBoxPreviewChange"
+                      closeable
+                    >
+                      <template #index>
+                        <div class="custom-toolbar">
+                          <span
+                            >{{ startPhotosPosition + 1 }}/{{
+                              selectDetail.boxPhotos.length
+                            }}</span
+                          >
+                          <van-button
+                            icon="delete"
+                            type="danger"
+                            @click.stop="handleBoxDelete"
+                            size="mini"
+                            >删除
+                          </van-button>
+                        </div>
+                      </template>
+                    </van-image-preview>
+                  </template>
+                </van-row>
+              </template>
+
+              <template
+                v-if="
+                  selectDetail.productPhotos &&
+                  selectDetail.productPhotos.length > 0
+                "
+              >
+                <van-divider content-position="left" style="margin: 0px">内物图</van-divider>
+                <van-row>
                   <template v-for="(item, index) in selectDetail.productPhotos">
-                    <van-col span="12">
+                    <van-col span="4">
                       <van-image
                         :key="`product-photos-${index}`"
-                        width="100"
-                        height="100"
+                        width="100%"
+                        height="50"
                         :src="getImageUrl(item, '内物图')"
+                        @click="showPhotosImagePreview(index)"
                       />
                     </van-col>
                   </template>
-                </template>
-              </van-row>
+                </van-row>
+
+                <van-image-preview
+                  v-model:show="showPhotosPreview"
+                  :images="detailProductImages"
+                  :start-position="startPhotosPosition"
+                  @change="onPhotosPreviewChange"
+                  closeable
+                >
+                  <template #index>
+                    <div class="custom-toolbar">
+                      <span>
+                        {{ startPhotosPosition + 1 }}/{{
+                          selectDetail.productPhotos.length
+                        }}
+                      </span>
+                      <van-button
+                        icon="delete"
+                        type="danger"
+                        @click.stop="handlePhotosDelete"
+                        size="mini"
+                        >删除
+                      </van-button>
+                    </div>
+                  </template>
+                </van-image-preview>
+              </template>
+
               <van-row>
                 <van-col span="12">
                   <van-button
@@ -511,6 +630,7 @@
                   </van-button>
                 </van-col>
               </van-row>
+
               <input
                 type="file"
                 id="outer-carton-box-input"
@@ -533,7 +653,6 @@
         </van-tabs>
       </div>
     </div>
-
     <van-popup
       v-model:show="showOwnerSelect"
       destroy-on-close
@@ -558,10 +677,14 @@ import {
   showNotify,
   showLoadingToast,
   closeToast,
+  showConfirmDialog,
+  showToast,
 } from 'vant'
 import { getHeader, goBack } from '@/utils/android'
 import {
-  deleteDetails, getQualityInspection, getQualityInspectionBy,
+  deleteDetails,
+  getQualityInspection,
+  getQualityInspectionBy,
   getQualityStatus,
   getReturnedByExpress,
   getTagColorBy,
@@ -573,9 +696,9 @@ import {
   searchBarcode,
   searchOwnerBarcode,
   shops,
-  validateDate
+  validateDate,
 } from '@/api/returned/index.ts'
-import { getOwner, getWarehouse } from '@/api/basic/index.ts'
+import { carrierOptions, getOwner, getWarehouse } from '@/api/basic/index.ts'
 import { useStore } from '@/store/modules/user'
 import { getStatus } from '@/utils/returned.ts'
 
@@ -597,8 +720,6 @@ const title = computed(() => {
   return '退货登记'
 })
 
-
-
 const qualityStatusOptions = ref([])
 // 货主
 const owners = ref([])
@@ -614,6 +735,7 @@ const selectDetailIndex = ref(-1)
 const ownerMap = ref({})
 
 const warehousesMap = ref({})
+const logisticsMap = ref({})
 
 const asnList = ref({})
 // 外箱图
@@ -649,12 +771,75 @@ onMounted(() => {
     })
     warehousesMap.value = map
   })
+
+  carrierOptions().then((res) => {
+    const { data } = res
+    logistics.value = data.map((item) => {
+      return { value: item.id, text: item.name }
+    })
+    const map = {}
+    data.forEach((item) => {
+      map[item.name] = item.id
+    })
+    logisticsMap.value = map
+  })
   try {
     getHeader()
-  } catch (error) {
-  }
+  } catch (error) {}
 })
 
+// 商品外箱图
+function hasBoxItems(detail) {
+  const { boxPhotos } = detail
+  if (!boxPhotos || boxPhotos.length === 0) {
+    return false
+  }
+  return boxFiles.value.some((item) => {
+    return boxPhotos.includes(item.fileName)
+  })
+}
+
+// 商品外箱图
+function getBoxItems(detail) {
+  const { boxPhotos } = detail
+  if (!boxPhotos || boxPhotos.length === 0) {
+    return []
+  }
+  boxFiles.value.forEach((item) => {
+    console.log(item)
+    console.log(boxPhotos.includes(item.fileName))
+  })
+  console.log(boxFiles.value.filter((_) => true))
+  return boxFiles.value.filter((item) => boxPhotos.includes(item.fileName))
+}
+
+// 商品外箱图
+function hasProductItems(detail) {
+  const { productPhotos } = detail
+  if (!productPhotos || productPhotos.length === 0) {
+    return false
+  }
+  return productFiles.value.some((item) => {
+    return productPhotos.includes(item.fileName)
+  })
+}
+
+// 商品内物图
+function getProductItems(detail) {
+  const { productPhotos } = detail
+  if (!productPhotos || productPhotos.length === 0) {
+    return []
+  }
+  console.log(
+    productFiles.value.filter((item) => {
+      return productPhotos.includes(item.fileName)
+    }),
+  )
+  return productFiles.value.filter((item) => {
+    return productPhotos.includes(item.fileName)
+  })
+}
+
 // 获取对应的店铺信息
 async function getStoreOptionsBy(owner) {
   const results = await shops(owner)
@@ -668,11 +853,12 @@ async function getStoreOptionsBy(owner) {
   })
 }
 
-const qualityInspection =ref(null)
+const qualityInspection = ref(null)
 
 // 初始化质检状态
-function initQualityInspection(owner){
-  getQualityInspection(owner).then(res=>{
+function initQualityInspection(owner) {
+  console.log(owner)
+  getQualityInspection(owner).then((res) => {
     qualityInspection.value = res.data
   })
 }
@@ -766,8 +952,8 @@ function initDetail() {
     number: null,
     warehouse: null,
     warehouseBin: null,
-    boxPhotos: null,
-    productPhotos: null,
+    boxPhotos: [],
+    productPhotos: [],
     files: null,
     pieceTag: null,
     createTime: null,
@@ -800,7 +986,7 @@ const ownerName = ref('')
 const selectedOwner = (row) => {
   const { selectedValues, selectedOptions } = row
   ownerPickerShow.value = false
-  params.value.ownerCode = selectedValues
+  params.value.ownerCode = selectedOptions[0].value
   ownerName.value = selectedOptions[0].text
   initQualityInspection(params.value.ownerCode)
 }
@@ -1085,7 +1271,6 @@ function init(showInputPage = true) {
   initDetail()
 }
 
-
 // 扫码弹框
 const scancodeDialog = ref(false)
 const scancodeInputRef = ref(false)
@@ -1130,7 +1315,7 @@ async function queryBarcode() {
   const { ownerCode } = params.value
   if (ownerCode) {
     const result = await queryOwnerBarcode(ownerCode, barcode)
-    if (!result) {
+    if (result) {
       scancodeDialog.value = false
       qualityStatusDialog.value = false
       closeToast()
@@ -1154,8 +1339,12 @@ async function queryBarcode() {
  */
 async function queryOwnerBarcode(ownerCode, barcode) {
   try {
+    console.log('queryOwnerBarcode')
     const results = await searchOwnerBarcode({ ownerCode, barcode })
-    const { basSku } = results
+    const {
+      data: { basSku },
+    } = results
+    console.log(results)
     if (!basSku) {
       return false
     }
@@ -1194,7 +1383,7 @@ async function queryBarcodeBy(barcode) {
 
 // 添加详情
 function addDetailByBasSku(basSku) {
-  const { sku, barCode, ownerCode, tradeName } = basSku
+  const { sku, barCode, ownerCode, tradeName, accessories } = basSku
   selectDetailIndex.value = -1
   selectDetail.value.sku = sku
   if (!params.value.ownerCode) {
@@ -1208,6 +1397,21 @@ function addDetailByBasSku(basSku) {
   scancodeDialog.value = false
   qualityStatusDialog.value = false
   returnedDetailDialog.value = true
+  // 显示
+  showAccessoriesItems(accessories)
+}
+const accessories = ref([])
+const showAccessories = ref(false)
+function showAccessoriesItems(items) {
+  console.log(items)
+  console.log(!items || items.length === 0)
+  if (!items || items.length === 0) {
+    accessories.value = []
+    showAccessories.value = false
+    return
+  }
+  accessories.value = items
+  showAccessories.value = true
 }
 
 // 质量状态
@@ -1293,22 +1497,24 @@ function getTagColor(qualityStatus) {
   return getTagColorBy(qualityStatus)
 }
 
-// 添加详情
-function addDetails() {
-  console.log(addDetails)
+const addDetails = async () => {
+  const isCheck = checkUploadImages()
+  if (!isCheck) {
+    returnedDetailDialog.value = true
+    return false
+  }
   const index = selectDetailIndex.value
-  console.log(index)
   const detail = JSON.parse(JSON.stringify(selectDetail.value))
-  console.log(detail)
   if (index > -1) {
     params.value.details[index] = detail
     initDetail()
-    return
+    return true
   }
   // 查找对应的详情进行合并
   params.value.details.push(detail)
   // 重置详情
   initDetail()
+  return true
 }
 
 // 删除对应的详情
@@ -1370,15 +1576,14 @@ async function checkValidateDate(ownerCode, sku, newDate, fieldName) {
   if (['NOSKU', 'NOBARCODE'].includes(sku)) {
     return true
   }
-  const params = {
-    newDate: newDate,
-    fieldName: fieldName,
-    ownerCode: ownerCode,
-    sku: sku,
-  }
   const type = fieldName === 'manufactureTime' ? '生产日期' : '失效日期'
   try {
-    await validateDate(params)
+    await validateDate({
+      newDate: newDate,
+      fieldName: fieldName,
+      ownerCode: ownerCode,
+      sku: sku,
+    })
     showNotify({
       type: 'success',
       message: `${type} 状态校验成功 `,
@@ -1539,37 +1744,55 @@ function submit() {
     return
   }
   const formData = new FormData()
-  const boxItems = (boxFiles && boxFiles.value) ? boxFiles.value : []
+  const boxItems = boxFiles && boxFiles.value ? boxFiles.value : []
   const productItems =
-    (productFiles && productFiles.value) ? productFiles.value : []
+    productFiles && productFiles.value ? productFiles.value : []
   const files = [...boxItems, ...productItems]
-  const fileName = []
+  const filenames = []
+
   if (files && files.length > 0) {
     files.forEach((item) => {
-      const { file, filename } = item
-      if (!fileName.includes(filename)) {
+      const { file, fileName } = item
+      if (!filenames.includes(fileName)) {
         formData.append('files', file)
-        fileName.push(filename)
+        filenames.push(fileName)
       }
     })
   }
+
   handleDetails(params.value.details)
-  formData.append('body', JSON.stringify(JSON.parse(JSON.stringify(params.value))))
+  formData.append('body', JSON.stringify(params.value))
+  console.log(formData)
   showLoadingToast({
     duration: 0,
     forbidClick: true,
     message: '提交登记中.....',
   })
-  console.log("register")
+
   register(formData)
     .then((res) => {
       const { data } = res
+      const { accumulateTaskMap } = data
       closeToast()
       if (data) {
-        showNotify({
-          type: 'success',
-          message: '成功提交',
-        })
+        if (accumulateTaskMap && accumulateTaskMap.length > 0) {
+          let messages = []
+          const ownerName = getOwnerName(params.value.ownerCode)
+          for (let i = 0; i < accumulateTaskMap.length; i++) {
+            const { quality, taskCode } = accumulateTaskMap[i]
+            messages.push(`进入${ownerName}新的${quality}攒单任务号${taskCode}`)
+          }
+          showConfirmDialog({
+            title: '提交成功',
+            message: messages.join('\r\n'),
+            theme: 'round-button',
+          })
+        } else {
+          showNotify({
+            type: 'success',
+            message: '成功提交',
+          })
+        }
         init()
         params.value.ownerCode = ownerCode
       }
@@ -1601,18 +1824,140 @@ function checkDetailNumber() {
   return check
 }
 
-function handleDetails(details){
+function handleDetails(details) {
   for (let i = 0; i < details.length; i++) {
-    const {qualityStatus} = details[i]
+    const { qualityStatus } = details[i]
     console.log(qualityStatus)
-    const {isGenuineValue,qualityMark} = getStatus(qualityStatus)
+    const { isGenuineValue, qualityMark } = getStatus(qualityStatus)
     details[i].isGenuine = isGenuineValue
     details[i].qualityMark = qualityMark
   }
 }
 
-window.onRefresh = async ()=>{
-  console.log("window.onRefresh")
+const showPhotosPreview = ref(false)
+const startPhotosPosition = ref(0)
+
+const showPhotosImagePreview = (index) => {
+  startPhotosPosition.value = index
+  showPhotosPreview.value = true
+}
+
+const onPhotosPreviewChange = (index) => {
+  startPhotosPosition.value = index
+}
+const handlePhotosDelete = () => {
+  showConfirmDialog({
+    title: '提示',
+    message: '确定要删除这张图片吗?',
+  })
+    .then(() => {
+      selectDetail.value.productPhotos.splice(startBoxPosition.value, 1)
+      showToast('删除成功')
+      if (selectDetail.value.productPhotos.length === 0) {
+        showPhotosPreview.value = false
+      } else if (
+        startPhotosPosition.value >= selectDetail.value.productPhotos.length
+      ) {
+        startPhotosPosition.value = selectDetail.value.productPhotos.length - 1
+      }
+
+      // 这里可以添加实际删除图片的API调用
+      // deleteImageAPI(deletedImage).then(...)
+    })
+    .catch(() => {
+      // 取消删除
+    })
+}
+
+const showBoxPreview = ref(false)
+const startBoxPosition = ref(0)
+
+const showBoxImagePreview = (index) => {
+  startBoxPosition.value = index
+  showBoxPreview.value = true
+}
+
+const onBoxPreviewChange = (index) => {
+  startBoxPosition.value = index
+}
+const handleBoxDelete = () => {
+  showConfirmDialog({
+    title: '提示',
+    message: '确定要删除这张图片吗?',
+  })
+    .then(() => {
+      selectDetail.value.boxPhotos.splice(startBoxPosition.value, 1)
+      showToast('删除成功')
+      if (selectDetail.value.boxPhotos.length === 0) {
+        showBoxPreview.value = false
+      } else if (
+        startBoxPosition.value >= selectDetail.value.boxPhotos.length
+      ) {
+        startBoxPosition.value = selectDetail.value.boxPhotos.length - 1
+      }
+
+      // 这里可以添加实际删除图片的API调用
+      // deleteImageAPI(deletedImage).then(...)
+    })
+    .catch(() => {
+      // 取消删除
+    })
+}
+
+const detailBoxImages = computed(() => {
+  const items = selectDetail.value.boxPhotos
+  if (!items || items.length === 0) {
+    return []
+  }
+  return boxFiles.value
+    .filter((item) => {
+      return items.includes(item.fileName)
+    })
+    .map((item) => item.src)
+})
+
+const detailProductImages = computed(() => {
+  const items = selectDetail.value.productPhotos
+  if (!items || items.length === 0) {
+    return []
+  }
+  return boxFiles.value
+    .filter((item) => {
+      return items.includes(item.fileName)
+    })
+    .map((item) => item.src)
+})
+
+// 校验是否上次图片
+function checkUploadImages() {
+  const status = ['次品', '待修复']
+  const { productPhotos, boxPhotos, qualityStatus } = selectDetail.value
+  if (!status.includes(qualityStatus)) {
+    return true
+  }
+  const boxPhotoIsNull = !boxPhotos || boxPhotos.length === 0
+  const productPhotoIsNull = !productPhotos || productPhotos.length === 0
+
+  if (boxPhotoIsNull) {
+    showNotify({
+      type: 'warning',
+      message: '请传入对应的外箱图',
+    })
+    return false
+  }
+
+  if (productPhotoIsNull) {
+    showNotify({
+      type: 'warning',
+      message: '请传入对应的内物图',
+    })
+    return false
+  }
+  return true
+}
+
+window.onRefresh = async () => {
+  console.log('window.onRefresh')
 }
 </script>