| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188 |
- <template>
- <div class="container">
- <van-nav-bar
- title="退货登记"
- left-arrow
- @click-left="goBack"
- @click-right="init"
- >
- <template #left>
- <van-icon name="arrow-left" size="25" />
- <div class="left-btn">返回</div>
- </template>
- <template #right>
- <div class="nav-right right-btn">重置</div>
- </template>
- </van-nav-bar>
- <div class="content">
- <div v-if="showInitialPage" class="init-container">
- <div class="content-tips">
- <div style="flex: 1">
- <van-notice-bar left-icon="volume-o">请扫描退回单号</van-notice-bar>
- </div>
- </div>
- <div class="scan-returned-content">
- <div class="input-group">
- <van-field
- ref="scan-express-no-input"
- autofocus
- v-model="expressNo"
- autocomplete="off"
- placeholder="输入快递单号"
- clearable
- @keydown.enter="inputExpressNo"
- >
- </van-field>
- </div>
- <div class="button-group">
- <van-button
- @click="inputExpressNo"
- style="width: 100%"
- type="primary"
- class="confirm-btn"
- >确认
- </van-button>
- </div>
- </div>
- </div>
- <div v-else>
- <van-tabs>
- <van-tab title="退货信息">
- <div>
- <div class="content-tips">
- <div style="flex: 1">
- <van-notice-bar color="#1989fa" background="#ecf9ff"
- >{{ ownerQualityInspection }}
- </van-notice-bar>
- </div>
- </div>
- </div>
- <van-cell-group inset style="margin-top: 10px">
- <van-field
- v-model="params.returnNo"
- label="快递单号"
- readonly
- placeholder="请输入快递单号"
- />
- <van-field
- readonly
- clickable
- label="承运商"
- placeholder="选择承运商"
- :model-value="getLogisticName()"
- @click="logisticPickerShow = true"
- />
- <van-popup
- v-model:show="logisticPickerShow"
- position="bottom"
- destroy-on-close
- >
- <van-picker
- :columns="logistics"
- @cancel="logisticPickerShow = false"
- @confirm="selectedLogistic"
- />
- </van-popup>
- <van-field
- readonly
- clickable
- label="仓库"
- placeholder="选择仓库"
- :model-value="getWarehouseName()"
- @click="warehousePickerShow = true"
- />
- <van-popup
- v-model:show="warehousePickerShow"
- position="bottom"
- destroy-on-close
- >
- <van-picker
- :columns="warehouses"
- @cancel="warehousePickerShow = false"
- @confirm="selectedWarehouse"
- />
- </van-popup>
- <van-field
- readonly
- clickable
- label="货主"
- placeholder="选择货主"
- :model-value="getOwnerName(params.ownerCode)"
- @click="showOwnerSelectFunc"
- />
- <van-field
- readonly
- clickable
- label="店铺"
- placeholder="选择店铺"
- v-model="params.storeName"
- @click="storePickerShow = true"
- />
- <van-popup
- v-model:show="storePickerShow"
- position="bottom"
- destroy-on-close
- >
- <van-picker
- :columns="storeOptions"
- @cancel="storePickerShow = false"
- @confirm="selectedStore"
- />
- </van-popup>
- <van-field
- v-model="params.orderUpstream"
- label="上游平台"
- placeholder="上游平台"
- />
- <van-field
- v-model="params.arrivalPayment"
- label="到付费用"
- placeholder="到付费用"
- />
- <van-field
- v-model="params.remark"
- rows="1"
- autosize
- label="备注"
- type="textarea"
- placeholder="备注"
- />
- </van-cell-group>
- <van-cell-group inset style="margin-top: 10px">
- <van-field
- :model-value="params.originalNo"
- label="是否原单"
- readonly
- placeholder="是否原单"
- />
- <van-field
- v-model="params.upstreamNo"
- label="客户订单号"
- placeholder="客户订单号"
- />
- <van-field
- v-model="params.asnNo"
- label="ASN单号"
- readonly
- placeholder="ASN单号"
- />
- <van-field
- v-model="params.buyerName"
- label="客户姓名"
- readonly
- placeholder="客户姓名"
- />
- <van-field
- v-model="params.buyerPhone"
- label="电话号码"
- readonly
- placeholder="电话号码"
- />
- </van-cell-group>
- <van-cell-group inset style="margin-top: 20px; margin-bottom: 50px">
- <van-button type="primary" block @click="submit">提交</van-button>
- </van-cell-group>
- </van-tab>
- <van-tab title="商品信息" class="returned-detail-list">
- <div>
- <div class="content-tips">
- <div style="flex: 1">
- <van-notice-bar color="#1989fa" background="#ecf9ff"
- >{{ ownerQualityInspection }}
- </van-notice-bar>
- </div>
- </div>
- </div>
- <template v-if="!params.details || params.details.length === 0">
- <van-empty description="暂无信息请进行录入" />
- </template>
- <template v-for="(item, index) in params.details">
- <div class="card-div">
- <div class="card-div-content">
- <div class="info-row">
- <div class="info-label">sku</div>
- <div class="info-value">{{ item.sku }}</div>
- <div class="info-label">质量状态</div>
- <div class="info-value">
- <van-tag :color="getTagColor(item.qualityStatus)">
- {{ item.qualityStatus }}
- </van-tag>
- </div>
- </div>
- <div class="info-row">
- <div class="info-label">商品编号</div>
- <div class="info-value">{{ item.barCode }}</div>
- <div class="info-label">商品名称</div>
- <div class="info-value">
- <van-text-ellipsis
- :content="item.tradeName"
- rows="1"
- expand-text="展开"
- collapse-text="收起"
- />
- </div>
- </div>
- <div class="info-row">
- <div class="info-label">生产日期</div>
- <div class="info-value">
- {{ item.manufactureTime }}
- </div>
- <div class="info-label">失效日期</div>
- <div class="info-value">{{ item.validityTime }}</div>
- </div>
- <div class="info-row">
- <div class="info-label">批次号</div>
- <div class="info-value">{{ item.batchNumber }}</div>
- <div class="info-label">数量</div>
- <div class="info-value">{{ item.number }}</div>
- </div>
- </div>
- <div class="card-div-footer">
- <div class="product-description">
- {{ item.remark }}
- </div>
- </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}`"
- @click="
- previewImages(item.boxPhotos, 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}`"
- @click="
- previewImages(
- item.productPhotos,
- imgIndex,
- '内物图',
- )
- "
- width="100%"
- height="60"
- :src="i.src"
- />
- </van-col>
- </template>
- </van-row>
- </div>
- </template>
- <div class="card-div-footer-options">
- <div class="options-row">
- <div class="info-value">
- <van-button
- size="mini"
- type="danger"
- block
- plain
- @click="removeDetails(index)"
- >删除
- </van-button>
- </div>
- <div class="info-value">
- <van-button
- size="mini"
- type="default"
- block
- plain
- @click="editDetails(index)"
- >编辑
- </van-button>
- </div>
- </div>
- </div>
- </div>
- </template>
- <van-floating-bubble
- axis="xy"
- icon="add"
- magnetic="x"
- @click="showScancode"
- />
- </van-tab>
- </van-tabs>
- </div>
- </div>
- <van-dialog
- v-model:show="scancodeDialog"
- title="扫描条码"
- @open="openScanCode"
- @confirm="showQualityStatus"
- show-cancel-button
- >
- <van-field
- ref="scancodeInputRef"
- v-model="scancode"
- label="商品条码"
- autocomplete="off"
- @keyup.enter="showQualityStatus"
- placeholder="商品条码"
- />
- </van-dialog>
- <van-dialog
- v-model:show="qualityStatusDialog"
- title="质量状态"
- @confirm="queryBarcode"
- show-cancel-button
- >
- <van-radio-group v-model="qualityStatus">
- <template v-for="(item, index) in qualityStatusOptions">
- <van-cell
- :title="item.text"
- clickable
- @click="qualityStatus = item.value"
- >
- <template #right-icon>
- <van-radio :name="item.value" />
- </template>
- </van-cell>
- </template>
- </van-radio-group>
- </van-dialog>
- <van-dialog
- v-model:show="returnedDetailDialog"
- title="商品详情"
- show-cancel-button
- :lazy-render="true"
- :show-confirm-button="checkUploadImages()"
- @confirm="addDetails"
- @cancel="cancelReturnedDetailDialog"
- >
- <div style="max-height: 70vh; overflow-y: auto">
- <van-field
- v-model="selectDetail.sku"
- label="SKU"
- placeholder="SKU"
- clearable
- />
- <van-field
- readonly
- v-model="selectDetail.barCode"
- label="商品条码"
- placeholder="商品条码"
- clearable
- />
- <van-field
- v-model="selectDetail.tradeName"
- label="商品名称"
- placeholder="商品名称"
- readonly
- />
- <van-field
- readonly
- clickable
- label="质量状态"
- placeholder="质量状态"
- v-model="selectDetail.qualityStatus"
- @click="selectedDetailQualityStatus = true"
- />
- <van-popup
- v-model:show="selectedDetailQualityStatus"
- position="bottom"
- destroy-on-close
- >
- <van-picker
- :columns="qualityStatusOptions"
- @cancel="selectedDetailQualityStatus = false"
- @confirm="selectedDetailQualityStatusFunc"
- />
- </van-popup>
- <van-field
- is-link
- readonly
- name="datePicker"
- label="生产日期"
- :placeholder="selectDetail.manufactureTime ? '' : '请选择生产日期'"
- :model-value="formatDateDisplay(selectDetail.manufactureTime)"
- @click="showManufactureTime = true"
- />
- <van-popup
- v-model:show="showManufactureTime"
- destroy-on-close
- position="bottom"
- >
- <van-date-picker
- :max-date="maxDate"
- :min-date="minDate"
- :model-value="parseDateValue(selectDetail.manufactureTime)"
- @confirm="manufactureTimeConfirm"
- @cancel="showManufactureTime = false"
- />
- </van-popup>
- <van-field
- :model-value="formatDateDisplay(selectDetail.validityTime)"
- is-link
- readonly
- name="datePicker"
- label="失效日期"
- :placeholder="selectDetail.validityTime ? '' : '请选择失效日期'"
- @click="showValidityTime = true"
- />
- <van-popup
- v-model:show="showValidityTime"
- destroy-on-close
- position="bottom"
- >
- <van-date-picker
- :max-date="maxDate"
- :min-date="minDate"
- :model-value="parseDateValue(selectDetail.validityTime)"
- @confirm="validityTimeConfirm"
- @cancel="showValidityTime = false"
- />
- </van-popup>
- <van-field
- autocomplete="off"
- v-model="selectDetail.batchNumber"
- label="批次号"
- placeholder="批次号"
- clearable
- />
- <van-field
- v-model="selectDetail.number"
- label="数量"
- type="digit"
- placeholder="数量"
- clearable
- />
- <van-field
- v-model="selectDetail.remark"
- label="备注"
- placeholder="备注"
- label-align="top"
- />
- <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>
- <p style="font-size: 12px">
- 请检查商品: 【<span style="color: #ff2020">{{
- selectDetail.sku
- }}</span
- >】 {{ selectDetail.tradeName }} 配件
- </p>
- </div>
- </van-row>
- <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="4">
- <van-image
- :key="`product-photos-${index}`"
- width="100%"
- height="50"
- :src="getImageUrl(item, '内物图')"
- @click="showPhotosImagePreview(index)"
- />
- </van-col>
- </template>
- </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
- type="primary"
- block
- @click="invokeCameraToCapture('外箱图')"
- >外箱图录入
- </van-button>
- </van-col>
- <van-col span="12">
- <van-button
- type="primary"
- block
- @click="invokeCameraToCapture('内物图')"
- >内物图录入
- </van-button>
- </van-col>
- </van-row>
- <input
- type="file"
- id="outer-carton-box-input"
- capture="user"
- accept="image/*"
- hidden
- @change="outerCartonInput"
- />
- <input
- type="file"
- id="inner-contents-input"
- capture="user"
- accept="image/*"
- hidden
- @change="innerContentsInput"
- />
- </div>
- </van-dialog>
- <van-popup
- v-model:show="showOwnerSelect"
- destroy-on-close
- round
- position="bottom"
- >
- <van-picker
- :model-value="getOwnerName(params.ownerCode)"
- :columns="ownerSelectedOptions"
- @cancel="showOwnerSelect = false"
- @confirm="selectOwner"
- />
- </van-popup>
- <owner ref="ownerRef" @onOwner="onOwner" />
- </div>
- </template>
- <script setup>
- import { ref, computed, nextTick, onMounted } from 'vue'
- import {
- showFailToast,
- showNotify,
- showLoadingToast,
- closeToast,
- showConfirmDialog,
- showImagePreview
- } from 'vant'
- import { getHeader, goBack, scanError, scanSuccess } from '@/utils/android'
- import {
- deleteDetails,
- getQualityInspection,
- getQualityInspectionBy,
- getQualityStatus,
- getReturnedByExpress,
- getTagColorBy,
- listAsn,
- matchAsnBy,
- matchCarrierCode,
- matchOrderBy,
- register,
- searchBarcode,
- searchOwnerBarcode,
- shops,
- validateDate
- } from '@/api/returned/index.ts'
- import { carrierOptions, getOwner, getWarehouse } from '@/api/basic/index.ts'
- import { useStore } from '@/store/modules/user'
- import { getStatus } from '@/utils/returned.ts'
- import Owner from '@/components/Owner.vue'
- try {
- getHeader()
- } catch (error) {
- console.log(error)
- }
- const minDate = ref(new Date(new Date().getFullYear() - 5, 0, 1))
- const maxDate = ref(new Date((new Date().getFullYear() + 50, 0, 1)))
- const showInitialPage = ref(true)
- const expressNo = ref(null)
- const store = useStore()
- const warehouse = store.warehouse
- // 当前选择的货主
- const title = computed(() => {
- if (expressNo.value && showInitialPage.value === false) {
- return '退货登记:' + params.value.returnNo
- }
- return '退货登记'
- })
- const qualityStatusOptions = ref([])
- // 货主
- const owners = ref([])
- // 仓库
- const warehouses = ref([])
- // 承运商
- const logistics = ref([])
- // 店铺
- const storeOptions = ref([])
- // 选中相关信息的下标
- const selectDetailIndex = ref(-1)
- const ownerMap = ref({})
- const warehousesMap = ref({})
- const logisticsMap = ref({})
- const asnList = ref({})
- // 外箱图
- const boxFiles = ref([])
- // 内物图
- const productFiles = ref([])
- onMounted(() => {
- const now = new Date()
- const currentYear = now.getFullYear()
- const currentCentury = Math.floor(currentYear / 100) * 100
- const endOfCenturyYear = currentCentury + 99
- maxDate.value = new Date(endOfCenturyYear, 0, 1)
- minDate.value = new Date(currentCentury, 0, 1)
- console.log(warehouse)
- getOwner().then((res) => {
- const { data } = res
- owners.value = data.map((item) => {
- return { value: item.code, text: item.name }
- })
- const map = {}
- data.forEach((item) => {
- map[item.code] = item.name
- })
- ownerMap.value = map
- })
- getQualityStatus().then((res) => {
- const { data } = res
- qualityStatusOptions.value = data
- .filter((item) => {
- return item !== '机损'
- })
- .map((item) => {
- return { value: item, text: item }
- })
- })
- getWarehouse().then((res) => {
- const { data } = res
- warehouses.value = data.map((item) => {
- return { value: item.code, text: item.name }
- })
- const map = {}
- data.forEach((item) => {
- map[item.code] = item.name
- })
- warehousesMap.value = map
- })
- carrierOptions().then((res) => {
- const { data } = res
- logistics.value = data.map((item) => {
- return { value: item.name, text: item.name }
- })
- const map = {}
- data.forEach((item) => {
- map[item.name] = item.name
- })
- logisticsMap.value = map
- })
- })
- // 商品外箱图
- 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 []
- }
- 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 []
- }
- return productFiles.value.filter((item) => {
- return productPhotos.includes(item.fileName)
- })
- }
- // 获取对应的店铺信息
- async function getStoreOptionsBy(owner) {
- const results = await shops(owner)
- const { data } = results
- if (!data || data.length === 0) {
- storeOptions.value = []
- return
- }
- storeOptions.value = data.map((item) => {
- return { value: item.name, text: item.name }
- })
- }
- const qualityInspection = ref(null)
- // 初始化质检状态
- function initQualityInspection(owner) {
- getQualityInspection(owner).then((res) => {
- qualityInspection.value = res.data
- })
- }
- const ownerQualityInspection = computed(() => {
- return getQualityInspectionBy(qualityInspection.value)
- })
- // 扫描商品条码
- const scancode = ref('')
- // 商品质量状态
- const qualityStatus = ref('')
- // 提交的商品信息
- const params = ref({
- id: null,
- returnNo: null,
- warehouseCode: warehouse,
- logisticsName: null,
- storeName: null,
- upstreamNo: null,
- ownerCode: null,
- orderUpstream: null,
- orderUpSteam: null,
- arrivalPayment: null,
- buyerName: null,
- asnNo: null,
- buyerPhone: null,
- originalNo: null,
- remark: null,
- details: []
- })
- // 商品信息
- const selectDetail = ref({
- id: null,
- rejectHeadId: null,
- rejectPushTaskNo: null,
- status: null,
- detailStatus: null,
- isGenuine: null,
- qualityMark: null,
- sku: '',
- barCode: '',
- tradeName: '',
- qualityStatus: '',
- manufactureTime: '',
- validityTime: '',
- batchNumber: '',
- remark: '',
- asnNo: null,
- number: 0,
- warehouse: null,
- warehouseBin: null,
- boxPhotos: [],
- productPhotos: [],
- files: null,
- pieceTag: null,
- createTime: null,
- creatorId: null,
- updateTime: null,
- updaterId: null,
- deleteTime: null,
- version: null,
- repairableType: null,
- repairableTypes: null,
- operatorId: null,
- operatorName: null,
- operatorTime: null,
- skuImage: null,
- orginSkuImage: null
- })
- function initDetail() {
- selectDetail.value = {
- id: null,
- rejectHeadId: null,
- rejectPushTaskNo: null,
- status: null,
- detailStatus: null,
- isGenuine: null,
- qualityMark: null,
- sku: '',
- barCode: '',
- tradeName: '',
- qualityStatus: '',
- manufactureTime: '',
- validityTime: '',
- batchNumber: '',
- remark: '',
- asnNo: null,
- number: null,
- warehouse: null,
- warehouseBin: null,
- boxPhotos: [],
- productPhotos: [],
- files: null,
- pieceTag: null,
- createTime: null,
- creatorId: null,
- updateTime: null,
- updaterId: null,
- deleteTime: null,
- version: null,
- repairableType: null,
- repairableTypes: null,
- operatorId: null,
- operatorName: null,
- operatorTime: null,
- skuImage: null,
- orginSkuImage: null
- }
- }
- // 承运商选择
- const logisticPickerShow = ref(false)
- const selectedLogistic = (row) => {
- const { selectedOptions } = row
- logisticPickerShow.value = false
- params.value.logisticsName = selectedOptions[0].text
- }
- // 货主选择
- const ownerPickerShow = ref(false)
- const ownerName = ref('')
- const selectedOwner = (row) => {
- const { selectedValues, selectedOptions } = row
- ownerPickerShow.value = false
- params.value.ownerCode = selectedOptions[0].value
- ownerName.value = selectedOptions[0].text
- initQualityInspection(params.value.ownerCode)
- }
- // 仓库选择
- const warehousePickerShow = ref(false)
- const selectedWarehouse = (row) => {
- const { selectedOptions } = row
- warehousePickerShow.value = false
- params.value.warehouseCode = selectedOptions[0].value
- }
- // 店铺选择
- const storePickerShow = ref(false)
- const selectedStore = (row) => {
- const { selectedOptions } = row
- storePickerShow.value = false
- params.value.storeName = selectedOptions[0].text
- }
- // 承运商名称
- function getLogisticName() {
- return params.value.logisticsName
- }
- // 货主名
- function getOwnerName(owner) {
- return ownerMap.value[owner]
- }
- // 仓库名
- function getWarehouseName() {
- console.log(params.value.warehouseCode)
- return warehousesMap.value[params.value.warehouseCode]
- }
- // 输入快递单号
- function inputExpressNo() {
- const no = expressNo.value
- const isSuccess = checkExpressNo(no)
- if (!isSuccess) {
- return
- }
- const express_no = initExpressNo(no)
- if (!express_no || express_no.length === 0) {
- showFailToast('快递单号异常')
- scanError()
- return
- }
- params.value.returnNo = express_no
- params.value.warehouseCode = warehouse
- listAsn(express_no).then((res) => {
- if (res.data) {
- asnList.value = res.data
- }
- })
- matchReturned(express_no)
- }
- function matchReturned(express_no) {
- getReturnedByExpress(express_no).then((res) => {
- const { data } = res
- if (!data) {
- matchOrder(express_no)
- return
- }
- const { id, headStatus, returnNo, warehouseCode } = data
- if (!id) {
- matchOrder(express_no)
- expressNo.value = null
- showInitialPage.value = false
- return
- }
- if (id) {
- if (['已入仓', '已拆包'].includes(headStatus)) {
- showNotify({
- type: 'primary',
- message: `当前退回单号${returnNo}--${headStatus}`
- })
- init(false)
- params.value.id = id
- params.value.returnNo = returnNo
- params.value.warehouseCode = warehouseCode
- params.value.warehousingStatus = null
- selectDetailIndex.value = -1
- matchOrder(express_no)
- expressNo.value = null
- showInitialPage.value = false
- scanSuccess()
- } else {
- showNotify({
- type: 'danger',
- message: '当前退回单号已进行过登记 如需修改请前往PC端进行'
- })
- scanSuccess()
- }
- }
- })
- }
- // 匹配原单信息
- function matchOrder(expressNo) {
- matchOrderBy(expressNo).then((res) => {
- const { data } = res
- if (!data) {
- console.log('未匹配到订单信息')
- matchAsn(expressNo)
- return
- }
- console.log('匹配到订单信息')
- if (data) {
- const {
- upstreamNo,
- shopName,
- ownerCode,
- recipientName,
- phone,
- logisticName,
- details
- } = data
- showNotify({ type: 'success', message: '匹配到原单信息' })
- params.value.upstreamNo = upstreamNo
- params.value.ownerCode = ownerCode
- params.value.warehouseCode = warehouse
- params.value.storeName = shopName
- params.value.logisticsName = logisticName
- params.value.buyerName = handlerLongText(recipientName)
- params.value.buyerPhone = handlerLongText(phone)
- params.value.originalNo = '原单退回'
- params.value.sendNo = null
- initQualityInspection(params.value.ownerCode)
- getStoreOptionsBy(ownerCode)
- if (!details || details.length === 0) {
- return
- }
- const list = []
- details.forEach((item) => {
- const {
- sku,
- barCode,
- detailAmount,
- name,
- productionDate,
- expirationDate,
- batchNumber,
- quality,
- attributeBin
- } = item
- let qualityStatus
- if (quality) {
- if (quality === 'ZP') {
- qualityStatus = '正品'
- qualityStatus = '正品'
- } else if (quality === 'CP') {
- qualityStatus = '次品'
- } else {
- qualityStatus = '正品'
- }
- } else {
- qualityStatus = '正品'
- }
- list.push({
- sku: sku,
- tradeName: name,
- barCode: barCode,
- number: detailAmount,
- manufactureTime: productionDate,
- validityTime: expirationDate,
- batchNumber: batchNumber,
- warehouse: attributeBin,
- qualityStatus: qualityStatus,
- isOriginal: true
- })
- params.value.details = list
- matchCarrier(expressNo)
- })
- } else {
- matchAsn(expressNo)
- }
- })
- }
- function matchCarrier(expressNo) {
- matchCarrierCode(expressNo).then((res) => {
- const { data } = res
- if (!data || data.length === 0) {
- showNotify({
- type: 'primary',
- message: '请手动选择承运商'
- })
- } else {
- params.value.logisticsName = data
- }
- })
- }
- // 转化加密
- function handlerLongText(text) {
- return text && text.length > 15 ? '加密' : text ? text : null
- }
- // 匹配对应的ASN
- function matchAsn(expressNo) {
- matchAsnBy(expressNo).then((res) => {
- const { data } = res
- if (!data) {
- console.log('未匹配asn单信息')
- matchCarrier(expressNo)
- return
- }
- const {
- ownerCode,
- phone,
- shopName,
- recipientName,
- logisticName,
- upstreamNo
- } = data
- params.value.returnNo = expressNo
- params.value.upstreamNo = upstreamNo
- params.value.ownerCode = ownerCode
- params.value.warehouseCode = warehouse
- params.value.storeName = shopName
- params.value.logisticsName = logisticName
- params.value.buyerName = handlerLongText(recipientName)
- params.value.buyerPhone = handlerLongText(phone)
- params.value.originalNo = null
- params.value.sendNo = null
- params.value.details = []
- matchCarrier(expressNo)
- getStoreOptionsBy(ownerCode)
- initQualityInspection(params.value.ownerCode)
- initDetail()
- })
- }
- // 校验快递单号格式
- function checkExpressNo(no) {
- if (!no || no.length === 0) {
- showFailToast('单号长度异常')
- scanError()
- return false
- }
- if (no.startsWith('http')) {
- showFailToast('扫描到了错误的条码')
- scanError()
- return false
- }
- if (no.endsWith('.com')) {
- showFailToast('扫描到了错误的条码')
- scanError()
- return false
- }
- const length = no.length
- if (length > 30 || length < 5) {
- showFailToast('单号长度异常')
- scanError()
- return false
- }
- return true
- }
- // 处理快递单号相关问题
- function initExpressNo(no) {
- // 处理扫描快递单号
- if (!no) {
- return no
- }
- if (no.includes('-')) {
- no = no.substring(0, no.indexOf('-')) // 京东快递异常
- }
- return no
- .replaceAll('-', '')
- .replaceAll(' ', '')
- .replaceAll('R02Z', '')
- .replaceAll('R02T', '') // 圆通退回单号异常
- }
- // 重置提交 恢复到扫描快递单号页面
- function init(showInputPage = true) {
- ownerName.value = null
- clearImageFileCache()
- params.value = {
- orderUpstream: null,
- returnNo: null,
- warehouseCode: warehouse,
- logisticsName: null,
- storeName: null,
- orderUpSteam: null,
- arrivalPayment: null,
- buyerName: null,
- asnNo: null,
- upstreamNo: null,
- buyerPhone: null,
- originalNo: null,
- remark: null,
- details: []
- }
- storeOptions.value = []
- expressNo.value = null
- showInitialPage.value = showInputPage
- initDetail()
- }
- // 扫码弹框
- const scancodeDialog = ref(false)
- const scancodeInputRef = ref(false)
- const qualityStatusDialog = ref(false)
- // 扫描条码dialog
- function showScancode() {
- scancodeDialog.value = true
- }
- function openScanCode() {
- nextTick(() => {
- setTimeout(() => {
- const input = scancodeInputRef.value?.$el?.querySelector('input')
- input?.focus()
- input?.setSelectionRange(0, input.value.length)
- }, 150)
- })
- }
- // 选择质量状态
- function showQualityStatus() {
- const barcode = scancode.value
- if (!barcode) {
- showFailToast('商品条码异常')
- scancodeDialog.value = true
- return
- }
- scanSuccess()
- qualityStatusDialog.value = true
- qualityStatus.value = '正品'
- }
- // 查询商品
- async function queryBarcode() {
- showLoadingToast({
- duration: 0,
- forbidClick: true,
- message: '查询商品信息中.....'
- })
- const barcode = scancode.value
- const { ownerCode, details } = params.value
- if (ownerCode) {
- const result = await queryOwnerBarcode(ownerCode, barcode)
- if (result) {
- scanSuccess()
- scancodeDialog.value = false
- qualityStatusDialog.value = false
- closeToast()
- return
- }
- }
- if (!details || details.length === 0) {
- await queryBarcodeBy(barcode)
- scancodeDialog.value = false
- qualityStatusDialog.value = false
- closeToast()
- }
- }
- // 根据获取查询信息
- async function queryOwnerBarcode(ownerCode, barcode) {
- try {
- const results = await searchOwnerBarcode({ ownerCode, barcode })
- const {
- data: { basSku }
- } = results
- if (!basSku) {
- return false
- }
- addDetailByBasSku(basSku)
- return true
- } catch (err) {
- closeToast()
- console.log(err.message)
- }
- return false
- }
- async function queryBarcodeBy(barcode) {
- try {
- const results = await searchBarcode({ barcode })
- const { data } = results
- const { basSku, ownerCodes } = data
- if (ownerCodes && ownerCodes.length > 1) {
- showOwnerSelectDialog(ownerCodes)
- return null
- }
- if (!basSku) {
- scanError()
- return null
- }
- addDetailByBasSku(basSku)
- scanSuccess()
- return null
- } catch (err) {
- closeToast()
- scanError()
- console.log(err.message)
- }
- scanError()
- return null
- }
- // 添加详情
- function addDetailByBasSku(basSku) {
- const { sku, barCode, ownerCode, tradeName, accessories } = basSku
- selectDetailIndex.value = -1
- selectDetail.value.sku = sku
- if (
- !params.value.ownerCode ||
- !params.value.details ||
- params.value.details.length === 0
- ) {
- params.value.ownerCode = ownerCode
- initQualityInspection(params.value.ownerCode)
- getStoreOptionsBy(params.value.ownerCode)
- }
- selectDetail.value.barCode = barCode
- selectDetail.value.qualityStatus = qualityStatus.value
- selectDetail.value.tradeName = tradeName
- selectDetail.value.number = 1
- scancodeDialog.value = false
- qualityStatusDialog.value = false
- returnedDetailDialog.value = true
- // 显示
- showAccessoriesItems(accessories)
- }
- const accessories = ref([])
- const showAccessories = ref(false)
- function showAccessoriesItems(items) {
- if (!items || items.length === 0) {
- accessories.value = []
- showAccessories.value = false
- return
- }
- accessories.value = items
- showAccessories.value = true
- }
- // 质量状态
- const returnedDetailDialog = ref(false)
- const selectedDetailQualityStatus = ref(false)
- const selectedDetailQualityStatusFunc = (row) => {
- const { selectedOptions } = row
- selectedDetailQualityStatus.value = false
- selectDetail.value.qualityStatus = selectedOptions[0].text
- }
- // 辅助函数:格式化日期显示(可选)
- const formatDateDisplay = (dateString) => {
- if (!dateString) return ''
- return dateString.replace(/-/g, '/') // 将 2023-05-01 显示为 2023/05/01
- }
- // 辅助函数:将日期字符串转换为数组格式 [年, 月, 日]
- const parseDateValue = (dateString) => {
- if (!dateString) return []
- const [year, month, day] = dateString.split('-')
- return [year, month, day]
- }
- // 生产日期
- const showManufactureTime = ref(false)
- const manufactureTimeConfirm = async (result) => {
- if (!result.selectedValues) {
- showManufactureTime.value = false
- return
- }
- // 正确解构参数
- const { selectedValues } = result
- const [year, month, day] = selectedValues
- const formatted_month = month.padStart(2, '0')
- const formatted_day = day.padStart(2, '0')
- const manufactureTime = `${year}-${formatted_month}-${formatted_day}`
- const { sku } = selectDetail.value
- const { ownerCode } = params.value
- const check_validate_date = await checkValidateDate(
- ownerCode,
- sku,
- manufactureTime,
- 'manufactureTime'
- )
- if (!check_validate_date) {
- console.log('检验出现异常')
- return
- }
- selectDetail.value.manufactureTime = manufactureTime
- showManufactureTime.value = false
- }
- // 失效日期
- const showValidityTime = ref(false)
- const validityTimeConfirm = async (result) => {
- if (!result.selectedValues) {
- showValidityTime.value = false
- return
- }
- // 正确解构参数
- const { selectedValues } = result
- const [year, month, day] = selectedValues
- const formatted_month = month.padStart(2, '0')
- const formatted_day = day.padStart(2, '0')
- const validityTime = `${year}-${formatted_month}-${formatted_day}`
- const { sku } = selectDetail.value
- const { ownerCode } = params.value
- const check_validate_date = await checkValidateDate(
- ownerCode,
- sku,
- validityTime,
- 'validityTime'
- )
- if (!check_validate_date) {
- return
- }
- selectDetail.value.validityTime = `${year}-${formatted_month}-${formatted_day}`
- showValidityTime.value = false
- }
- // 质量状态标签
- function getTagColor(qualityStatus) {
- return getTagColorBy(qualityStatus)
- }
- const cancelReturnedDetailDialog = async () => {
- returnedDetailDialog.value = false
- initDetail()
- }
- const addDetails = async () => {
- const isCheck = checkUploadImages()
- if (!isCheck) {
- returnedDetailDialog.value = true
- return false
- }
- const index = selectDetailIndex.value
- const detail = JSON.parse(JSON.stringify(selectDetail.value))
- if (index > -1) {
- params.value.details[index] = detail
- initDetail()
- return true
- }
- const {
- sku: detail_sku,
- batchNumber: detail_batch_number,
- validityTime: detail_validity_time,
- manufactureTime: detail_manufacture_time,
- qualityStatus: detail_quality_status,
- number: detailNumber
- } = selectDetail.value
- if (['次品', '待修复'].includes(detail_quality_status)) {
- params.value.details.push(detail)
- initDetail()
- return
- }
- const searchIndex = params.value.details.findIndex((item) => {
- const { sku, batchNumber, qualityStatus, validityTime, manufactureTime } =
- item
- return (
- sku === detail_sku &&
- batchNumber === detail_batch_number &&
- detail_validity_time === validityTime &&
- detail_manufacture_time === manufactureTime &&
- detail_quality_status === qualityStatus
- )
- })
- if (searchIndex > -1) {
- showConfirmDialog({
- title: '系统提示',
- message: '查询到有对应的商品详情是否进行合并'
- })
- .then(() => {
- const { number } = params.value.details[searchIndex]
- params.value.details[searchIndex].number =
- Number(detailNumber) + Number(number)
- showNotify({ type: 'success', message: '合并成功' })
- })
- .catch(() => {
- params.value.details.push(detail)
- showNotify({ type: 'success', message: '添加成功' })
- })
- } else {
- params.value.details.push(detail)
- }
- initDetail()
- return true
- }
- // 删除对应的详情
- function removeDetails(index) {
- if (null === index) {
- showFailToast('未找到对应的详情')
- return
- }
- showConfirmDialog({
- title: '系统提示',
- message: '是否删除当前登记信息'
- })
- .then(() => {
- const { id } = params.value.details[index]
- if (!id) {
- params.value.details.splice(index, 1)
- showNotify({ type: 'success', message: '删除成功' })
- } else {
- deleteDetails(id).then((res) => {
- if (res.data) {
- params.value.details.splice(index, 1)
- showNotify({ type: 'success', message: '删除成功' })
- } else {
- showNotify({ type: 'danger', message: '删除失败' })
- }
- })
- }
- })
- .catch(() => {
- showNotify({ type: 'primary', message: '取消删除' })
- })
- }
- function selectOwner({ selectedValues }) {
- const ownerCode = selectedValues[0]
- params.value.ownerCode = ownerCode
- showOwnerSelect.value = false
- ownerSelectedOptions.value = []
- getStoreOptionsBy(ownerCode)
- queryOwnerBarcode(params.value.ownerCode, scancode.value)
- }
- const ownerRef = ref(null)
- function showOwnerSelectFunc() {
- ownerRef.value?.show(1)
- }
- // 指定货主
- const onOwner = (item, type) => {
- params.value.ownerCode = item.code
- getStoreOptionsBy(item.code)
- }
- const showOwnerSelect = ref(false)
- const ownerSelectedOptions = ref([])
- // 多货主选择
- function showOwnerSelectDialog(items) {
- if (!items || items.length === 0) {
- ownerSelectedOptions.value = owners.value.map((item) => {
- JSON.parse(JSON.stringify(item))
- })
- showOwnerSelect.value = true
- return
- }
- ownerSelectedOptions.value = owners.value
- .filter((item) => {
- const { value } = item
- return items.includes(value)
- })
- .map((item) => JSON.parse(JSON.stringify(item)))
- showOwnerSelect.value = true
- }
- // 校验日期
- async function checkValidateDate(ownerCode, sku, newDate, fieldName) {
- if (['NOSKU', 'NOBARCODE'].includes(sku)) {
- return true
- }
- const type = fieldName === 'manufactureTime' ? '生产日期' : '失效日期'
- try {
- await validateDate({
- newDate: newDate,
- fieldName: fieldName,
- ownerCode: ownerCode,
- sku: sku
- })
- showNotify({
- type: 'success',
- message: `${type} 状态校验成功 `
- })
- return true
- } catch (error) {
- showNotify({
- type: 'danger',
- message: `校验${type}出现异常`
- })
- return false
- }
- }
- function blobToBase64(blob) {
- return new Promise((resolve, reject) => {
- const fileReader = new FileReader()
- fileReader.onload = (e) => {
- resolve(e.target.result)
- }
- fileReader.readAsDataURL(blob)
- fileReader.onerror = () => {
- reject(new Error('blobToBase64 error'))
- }
- })
- }
- // 编辑等级详情
- function editDetails(index) {
- selectDetailIndex.value = index
- const { details } = params.value
- selectDetail.value = JSON.parse(JSON.stringify(details[index]))
- returnedDetailDialog.value = true
- }
- // 写入当前商品详情
- function pushImageItem(event, type) {
- const file = event.target.files[0]
- if (!file) return
- if (!file.type.startsWith('image/')) {
- alert('请选择图片文件!')
- return
- }
- const filename = file.name
- const item = {
- src: URL.createObjectURL(file),
- file: file,
- fileName: filename,
- type
- }
- if (type === '外箱图') {
- if (!selectDetail.value.boxPhotos) {
- selectDetail.value.boxPhotos = []
- }
- blobToBase64(file).then((_) => {
- const some = boxFiles.value.some((item) => {
- return filename === item.fileName
- })
- if (some) {
- showFailToast('录入重复图片')
- } else {
- boxFiles.value.push(item)
- selectDetail.value.boxPhotos.push(filename)
- }
- })
- } else if (type === '内物图') {
- if (!selectDetail.value.productPhotos) {
- selectDetail.value.productPhotos = []
- }
- blobToBase64(file).then((_) => {
- const some = productFiles.value.some((item) => {
- return filename === item.fileName
- })
- if (some) {
- showFailToast('录入重复图片')
- } else {
- productFiles.value.push(item)
- selectDetail.value.productPhotos.push(filename)
- }
- })
- }
- }
- // 触发拍照
- function invokeCameraToCapture(type) {
- const { sku } = selectDetail.value
- if (!sku) {
- showFailToast('当前没有可录入的商品信息')
- return
- }
- if (type === '外箱图') {
- document.getElementById('outer-carton-box-input').click()
- } else if (type === '内物图') {
- document.getElementById('inner-contents-input').click()
- }
- }
- function getImageUrl(file_name, type) {
- let list = []
- if (type === '外箱图') {
- list = boxFiles.value
- } else if (type === '内物图') {
- list = productFiles.value
- }
- for (let i = 0; i < list.length; i++) {
- const item = list[i]
- const { src, fileName } = item
- if (file_name === fileName) {
- return src
- }
- }
- return null
- }
- // 外箱图事件
- function outerCartonInput(event) {
- pushImageItem(event, '外箱图')
- }
- // 内物图异常
- function innerContentsInput(event) {
- pushImageItem(event, '内物图')
- }
- function submit() {
- const { ownerCode, logisticsName, returnNo, warehouseCode } = params.value
- if (!ownerCode || ownerCode.length === 0) {
- showNotify({
- type: 'warning',
- message: '没有对应的退件详情!请录入对应的退件详情'
- })
- return
- } else if (!logisticsName || logisticsName.length === 0) {
- showNotify({
- type: 'warning',
- message: '请录入承运商'
- })
- return
- } else if (!returnNo || ownerCode.length === 0) {
- showNotify({
- type: 'warning',
- message: '请录入退件单号'
- })
- return
- } else if (!warehouseCode || warehouseCode.length === 0) {
- showNotify({
- type: 'warning',
- message: '请选择登记仓库'
- })
- return
- }
- console.log('checkDetailNumber')
- if (checkDetailNumber()) {
- return
- }
- const formData = new FormData()
- const boxItems = boxFiles && boxFiles.value ? boxFiles.value : []
- const productItems =
- productFiles && productFiles.value ? productFiles.value : []
- const files = [...boxItems, ...productItems]
- const filenames = []
- if (files && files.length > 0) {
- files.forEach((item) => {
- const { file, fileName } = item
- if (!filenames.includes(fileName)) {
- formData.append('files', file)
- filenames.push(fileName)
- }
- })
- }
- handleDetails(params.value.details)
- formData.append('body', JSON.stringify(JSON.parse(JSON.stringify(params.value))))
- console.log(formData)
- showLoadingToast({
- duration: 0,
- forbidClick: true,
- message: '提交登记中.....'
- })
- register(formData)
- .then((res) => {
- const { data } = res
- const { accumulateTaskMap } = data
- closeToast()
- if (data) {
- 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
- }
- })
- .catch(() => {
- closeToast()
- })
- }
- function checkDetailNumber() {
- const { details } = params.value
- if (!details || details.length === 0) {
- showNotify({
- type: 'warning',
- message: '登记详情不能为空'
- })
- return true
- }
- const check = details.some((item) => {
- const { number } = item
- return Number.isNaN(number) || Number(number) <= 0
- })
- if (check) {
- showNotify({
- type: 'warning',
- message: '登记数量不能为 0 和 空 '
- })
- }
- return check
- }
- function handleDetails(details) {
- for (let i = 0; i < details.length; i++) {
- const { qualityStatus } = details[i]
- const { isGenuineValue, qualityMark } = getStatus(qualityStatus)
- details[i].isGenuine = isGenuineValue
- details[i].qualityMark = qualityMark
- }
- }
- 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(startPhotosPosition.value, 1)
- showNotify({ type: 'success', message: '删除成功' })
- if (selectDetail.value.productPhotos.length === 0) {
- showPhotosPreview.value = false
- } else if (
- startPhotosPosition.value >= selectDetail.value.productPhotos.length
- ) {
- startPhotosPosition.value = selectDetail.value.productPhotos.length - 1
- }
- })
- .catch(() => {
- showNotify({ type: 'primary', message: '取消删除' })
- })
- }
- 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)
- showNotify({ type: 'success', message: '删除成功' })
- if (selectDetail.value.boxPhotos.length === 0) {
- showBoxPreview.value = false
- } else if (
- startBoxPosition.value >= selectDetail.value.boxPhotos.length
- ) {
- startBoxPosition.value = selectDetail.value.boxPhotos.length - 1
- }
- })
- .catch(() => {
- showNotify({ type: 'primary', message: '取消删除' })
- })
- }
- 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 productFiles.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
- }
- if (!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')
- }
- function clearImageFileCache() {
- if (productFiles.value && productFiles.value.length > 0) {
- productFiles.value
- .map((item) => item.src)
- .forEach((item) => URL.revokeObjectURL(item))
- }
- if (boxFiles.value && boxFiles.value.length > 0) {
- boxFiles.value
- .map((item) => item.src)
- .forEach((item) => URL.revokeObjectURL(item))
- }
- }
- function previewImages(filenames, index, type) {
- let list = []
- if (type === '外箱图') {
- list = boxFiles.value
- } else if (type === '内物图') {
- list = productFiles.value
- }
- const images = []
- for (let i = 0; i < list.length; i++) {
- const item = list[i]
- const { src, fileName } = item
- if (filenames.includes(fileName)) {
- images.push(src)
- }
- }
- if (!images || images.length === 0) {
- return
- }
- showImagePreview({
- images: images,
- startPosition: index
- })
- }
- </script>
- <style scoped lang="sass">
- .van-nav-bar
- .left-btn
- color: #fff
- height: 46px
- padding-right: 20px
- line-height: 46px
- .right-btn
- color: #fff
- .container
- .init-container
- width: 100%
- .scan-returned-content
- padding: 10px
- .input-group
- padding: 5px
- .button-group
- padding: 5px
- .content
- width: 100%
- .scan-returned-no
- align-items: center
- padding: 15px
- .returned-detail-list
- .card-div
- background: #fff
- border-radius: 12px
- overflow: hidden
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05)
- margin: 5px 0
- padding: 5px 0
- .card-div-content
- padding: 3px
- .info-row
- display: flex
- margin-bottom: 12px
- font-size: 12px
- .info-label
- width: 100px
- color: #969799
- .info-value
- flex: 1
- color: #333333
- font-weight: 500
- .card-div-footer
- padding: 5px
- background: #fafafa
- border-top: 1px solid #f5f5f5
- color: #646566
- font-size: 14px
- line-height: 1.5
- .card-div-footer-images
- padding: 5px
- background: #fafafa
- border-top: 1px solid #f5f5f5
- color: #646566
- font-size: 14px
- line-height: 1.5
- .card-div-footer-options
- background: #fafafa
- border-top: 1px solid #f5f5f5
- color: #646566
- font-size: 14px
- .options-row
- display: flex
- font-size: 12px
- .info-label
- width: 100px
- color: #969799
- .info-value
- flex: 1
- color: #333333
- font-weight: 500
- .returned-details
- .van-field
- padding: 0
- </style>
|