Commit 71f385c2 by qinjianhui

feat: 打印生产单等功能

parent 17e3c2c4
...@@ -36,6 +36,30 @@ export function getFactoryOrderNewListApi( ...@@ -36,6 +36,30 @@ export function getFactoryOrderNewListApi(
) )
} }
/** 请求体与 `factory/podOrder/list_page` 一致 */
export function getPodOrderAcceptedStatisticsApi(
data: SearchForm,
currentPage: number,
pageSize: number,
status?: string,
subStatus?: number,
) {
return axios.post<
never,
BaseRespData<{
acceptedOutOfStockCount?: number
pendingCount?: number
totalCount?: number
}>
>('factory/podOrder/acceptedStatistics', {
...data,
currentPage,
pageSize,
status,
acceptedStatus: subStatus,
})
}
export function getFactoryOrderNewDetailApi(id: number | string) { export function getFactoryOrderNewDetailApi(id: number | string) {
return axios.get<never, BaseRespData<ProductListData[]>>( return axios.get<never, BaseRespData<ProductListData[]>>(
'factory/podOrderProduct/getListByPodOrderId', 'factory/podOrderProduct/getListByPodOrderId',
...@@ -68,7 +92,7 @@ export function cancelOrderApi(ids: (number | string)[]) { ...@@ -68,7 +92,7 @@ export function cancelOrderApi(ids: (number | string)[]) {
export function refreshProductInfoApi(ids: (number | string)[]) { export function refreshProductInfoApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<void>>( return axios.post<never, BaseRespData<void>>(
'factory/orderNew/refreshProductInfo', 'factory/podOrderProduct/refreshProductInfo',
{ ids }, { ids },
) )
} }
...@@ -84,10 +108,17 @@ export function confirmOrderWithWarehouseApi( ...@@ -84,10 +108,17 @@ export function confirmOrderWithWarehouseApi(
ids: (number | string)[], ids: (number | string)[],
warehouseId: number | string, warehouseId: number | string,
) { ) {
return axios.post<never, BaseRespData<void>>( return axios.post<
'factory/podOrder/ordersAccepted', never,
{ podOrderIds: ids, warehouseId }, BaseRespData<
) {
factoryOrderNumber?: string
message?: string
id: number | string
status?: boolean
}[]
>
>('factory/podOrder/ordersAccepted', { podOrderIds: ids, warehouseId })
} }
export function cancelOrderWithReasonApi( export function cancelOrderWithReasonApi(
...@@ -129,7 +160,7 @@ export function archiveOrderApi(ids: (number | string)[]) { ...@@ -129,7 +160,7 @@ export function archiveOrderApi(ids: (number | string)[]) {
export function printPickOrderApi(ids: (number | string)[]) { export function printPickOrderApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<void>>( return axios.post<never, BaseRespData<void>>(
'factory/orderNew/printPickOrder', 'factory/podOrderOperation/printPickPdf',
{ ids }, { ids },
) )
} }
...@@ -159,8 +190,8 @@ export function restockCheckApi(id: number | string) { ...@@ -159,8 +190,8 @@ export function restockCheckApi(id: number | string) {
export function pickCompleteApi(ids: (number | string)[]) { export function pickCompleteApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<PickCompleteData[]>>( return axios.post<never, BaseRespData<PickCompleteData[]>>(
'factory/orderNew/pickComplete', 'factory/podOrderOperation/listByIds',
{ ids }, ids,
) )
} }
...@@ -265,7 +296,11 @@ export function arrangeFinishApi( ...@@ -265,7 +296,11 @@ export function arrangeFinishApi(
type?: string type?: string
}, },
) { ) {
return axios.post<never, BaseRespData<never>>(url, params) return axios.post<never, BaseRespData<never>>(url, {
operationIdList: params.productIdList,
templateWidth: params.templateWidth,
type: params.type,
})
} }
export function downloadMaterialApi(id: number[]) { export function downloadMaterialApi(id: number[]) {
......
<template> <template>
<div class="commodity-card" :class="{ active: active }"> <div class="commodity-card" :class="{ active: active }">
<div class="commodity-card-image"> <div class="commodity-card-image">
<div class="before"></div> <div class="before" :style="{ paddingTop: paddingTop }"></div>
<div class="image"> <div class="image">
<img :src="mainImageSrc" /> <img :src="mainImageSrc" />
</div> </div>
...@@ -110,6 +110,7 @@ interface Props { ...@@ -110,6 +110,7 @@ interface Props {
imageField?: string imageField?: string
imageListField?: string imageListField?: string
imagePathField?: string imagePathField?: string
paddingTop?: string
} }
// 定义默认值 // 定义默认值
...@@ -122,6 +123,7 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -122,6 +123,7 @@ const props = withDefaults(defineProps<Props>(), {
imageField: 'variantImage', imageField: 'variantImage',
imageListField: 'imageList', imageListField: 'imageList',
imagePathField: 'imagePath', imagePathField: 'imagePath',
paddingTop: '120%',
}) })
// 获取主图片源 // 获取主图片源
...@@ -217,7 +219,6 @@ const copy = (text: string) => { ...@@ -217,7 +219,6 @@ const copy = (text: string) => {
.before { .before {
height: 0; height: 0;
padding-top: 120%;
} }
.image { .image {
......
...@@ -33,6 +33,7 @@ export interface SearchForm { ...@@ -33,6 +33,7 @@ export interface SearchForm {
logisticsCompanyCode?: string logisticsCompanyCode?: string
interceptStatus?: boolean interceptStatus?: boolean
standardDesignImage?: number standardDesignImage?: number
productMarkList?: string[]
} }
export interface FactoryOrderNewListData { export interface FactoryOrderNewListData {
...@@ -86,29 +87,73 @@ export interface FactoryOrderNewListData { ...@@ -86,29 +87,73 @@ export interface FactoryOrderNewListData {
export interface ProductListData { export interface ProductListData {
id: number id: number
orderId?: number podOrderId: number
productImage?: string factoryCode?: string
productName?: string productName?: string
baseSku?: string
variantSku?: string variantSku?: string
stockSku?: string variantImage?: string
// 后端字段名兼容(部分接口返回 snake_case)
variant_image?: string
productMark?: 'custom_part'
diyId?: string
templateType?: number
customTemplateItemId?: number
endProductId?: string
craftSource?: number
craftCode?: string craftCode?: string
craftName?: string craftName?: string
styleNo?: string craftType?: string
price?: number customizedQuantity: number
quantity?: number categoryId?: number
categoryName?: string
productPrice?: number
templatePrice?: number
craftPrice?: number
imageAry?: string
designImages?: string
trimDesignImages?: string
sizeType?: number
num?: number
passNum?: number
notPassNum?: number
payAmount?: number
weight?: number weight?: number
availableQuantity?: number createTime?: string
stockQuantity?: number updateTime?: string
occupiedQuantity?: number version?: number
customsNameEnglish?: string
customsNameChinese?: string
customsWeight?: number
customsValue?: number
remark?: string remark?: string
} }
export interface operateOrderListData { export interface operateOrderListData {
id: number id: number
podOrderProductId: number operationNo?: string
podOrderId?: number
podOrderNo?: string
podOrderProductId?: number
baseSku?: string
variantSku?: string
variantImage?: string
thirdSpuCode?: string
thirdSkuCode?: string
supplierProductNo?: string
productName?: string
productMark?: string
customizedQuantity?: number
quantity?: number
isReplenishment?: boolean
totalProductionNum?: number
status?: string
outOfStock?: boolean
arrange?: boolean
version?: number
createTime?: string
updateTime?: string
factoryNo?: number
factoryCode?: string
factoryCountryCode?: string
warehouseId?: number
namespace?: string
statusName?: string
[key: string]: unknown [key: string]: unknown
} }
......
...@@ -26,12 +26,15 @@ export default function usePageList<T>(options: UsePageListOptions<T>) { ...@@ -26,12 +26,15 @@ export default function usePageList<T>(options: UsePageListOptions<T>) {
sumTotalPrice: 0, sumTotalPrice: 0,
sumNotPassNum: 0, sumNotPassNum: 0,
}) })
/** 防止快速切换查询条件时,旧请求晚返回覆盖新数据 */
const loadRequestId = ref(0)
const loadData = async () => { const loadData = async () => {
const { query } = options const { query } = options
const myId = ++loadRequestId.value
try { try {
loading.value = true loading.value = true
// Promise 链式调用
const res = await query(currentPage.value, pageSize.value) const res = await query(currentPage.value, pageSize.value)
if (myId !== loadRequestId.value) return
if (statistics.value) { if (statistics.value) {
totalData.value = res as never totalData.value = res as never
total.value = res.page!.total total.value = res.page!.total
...@@ -45,12 +48,15 @@ export default function usePageList<T>(options: UsePageListOptions<T>) { ...@@ -45,12 +48,15 @@ export default function usePageList<T>(options: UsePageListOptions<T>) {
data.value = res.records data.value = res.records
} }
} catch (error) { } catch (error) {
if (myId !== loadRequestId.value) return
console.error(error) console.error(error)
// showError(error) // showError(error)
} finally { } finally {
if (myId === loadRequestId.value) {
loading.value = false loading.value = false
} }
} }
}
const onCurrentPageChange = (page: number) => { const onCurrentPageChange = (page: number) => {
currentPage.value = page currentPage.value = page
......
...@@ -108,8 +108,8 @@ const handleSubmit = async () => { ...@@ -108,8 +108,8 @@ const handleSubmit = async () => {
ElMessage.success('操作成功') ElMessage.success('操作成功')
visible.value = false visible.value = false
emit('success') emit('success')
} catch (e: unknown) { } catch (e) {
ElMessage.error((e as Error)?.message || '排单失败') console.error(e)
} finally { } finally {
submitting.value = false submitting.value = false
} }
......
<template> <template>
<div v-loading="loading" class="card-layout"> <div v-loading="loading" class="card-layout">
<div v-if="cardData.length > 0" class="card-grid"> <div v-if="cardData.length > 0" class="card-content">
<div class="card-grid">
<div <div
v-for="item in cardData" v-for="item in cardData"
:key="item.id" :key="item.id"
...@@ -13,15 +14,15 @@ ...@@ -13,15 +14,15 @@
:show-sku="false" :show-sku="false"
:show-product-info="false" :show-product-info="false"
:image-field="'variantImage'" :image-field="'variantImage'"
:padding-top="'100%'"
> >
<template #bottom_left> <template #bottom_left>
<span <span
v-if="item.factorySubOrderNumber"
class="operation-number" class="operation-number"
:title="`操作单号:${item.factorySubOrderNumber}`" :title="`操作单号:${item.operationNo}`"
@click.stop="copyText(String(item.factorySubOrderNumber))" @click.stop="String(item.operationNo)"
> >
{{ item.factorySubOrderNumber }} {{ item.operationNo }}
</span> </span>
</template> </template>
<template #top_right> <template #top_right>
...@@ -32,9 +33,67 @@ ...@@ -32,9 +33,67 @@
height="60" height="60"
/> />
</template> </template>
<template #images>
<div class="flex-between">
<div class="images-position">
<div v-if="item.imageAry" class="images-container">
<div
v-for="(img, index) in JSON.parse(item.imageAry as string)"
:key="index"
:title="img.title"
class="item-image"
>
<el-image
:src="img?.url"
height="50"
:preview-src-list="JSON.parse(item.imageAry as string).map((i: { title: string; url: string }) => i.url)"
/>
</div>
</div>
</div>
<div class="flex-row flex-row-gap15">
<el-tooltip
class="item"
effect="dark"
:content="'用户编码: ' + item?.userMark"
placement="bottom"
>
<span
style="
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
display: inline-block;
"
@click.stop="copyText(String(item?.userMark || ''))"
>
{{ item?.userMark || 'AAAF' }}
</span>
</el-tooltip>
<img
v-if="item.platform"
:src="`/images/icon/${getPlatformImg(item.platform as string)}`"
style="width: 30px; height: 30px"
/>
</div>
</div>
</template>
<template #operations> <template #operations>
<div v-if="item.customizedQuantity" class="quantity-badge"> <div class="flex-row flex-row-gap6">
{{ item.customizedQuantity }} <div
v-if="item.customizedQuantity"
class="quantity-badge"
:class="
item.customizedQuantity === 1
? 'single-quantity-badge-color'
: 'multiple-quantity-badge-color'
"
:title="`类型:${
item.customizedQuantity === 1 ? '单面' : '双面'
}`"
>
{{ item.customizedQuantity === 1 ? '单' : '多' }}
</div> </div>
<Icon name="caozuorizhi" style="width: 28px; height: 28px"> <Icon name="caozuorizhi" style="width: 28px; height: 28px">
<template #title> <template #title>
...@@ -46,6 +105,7 @@ ...@@ -46,6 +105,7 @@
<title>查看详情</title> <title>查看详情</title>
</template> </template>
</Icon> </Icon>
</div>
</template> </template>
<template #info> <template #info>
<div class="card-info-grid"> <div class="card-info-grid">
...@@ -58,46 +118,70 @@ ...@@ -58,46 +118,70 @@
</span> </span>
</div> </div>
<div class="card-info-row"> <div class="card-info-row">
<span class="info-label">工艺:</span>
<span class="info-value">{{ item.craftName }}</span>
</div>
<div class="card-info-row">
<span class="info-label">店铺单号:</span>
<span class="info-value">{{ item.shopNumber }}</span>
</div>
<div class="card-info-row">
<span class="info-label">客户号:</span>
<span class="info-value">{{ item.userMark }}</span>
</div>
<div class="card-info-row">
<span class="info-label">变体SKU</span>
<span <span
class="info-value clickable ellipsis" class="info-value clickable ellipsis"
:title="(item.variantSku as string) || ''" :title="`变体SKU:${(item.variantSku as string) || ''}`"
@click.stop="copyText((item.variantSku as string) || '')" @click.stop="copyText((item.variantSku as string) || '')"
> >
{{ item.variantSku }} {{ item.variantSku }}
</span> </span>
</div> </div>
<div class="card-info-row"> <div class="card-info-row">
<span class="info-label">库存SKU</span> <span class="info-label">工艺:</span>
<span class="info-value">{{ item.craftName }}</span>
</div>
<div class="card-info-row">
<span <span
class="info-value clickable ellipsis" class="info-value clickable ellipsis"
:title="(item.thirdSkuCode as string) || ''" :title="`库存SKU:${(item.thirdSkuCode as string) || ''}`"
@click.stop="copyText((item.thirdSkuCode as string) || '')" @click.stop="copyText((item.thirdSkuCode as string) || '')"
> >
{{ item.thirdSkuCode }} {{ item.thirdSkuCode }}
</span> </span>
</div> </div>
<div class="card-info-row"> <div class="card-info-row">
<span class="info-label">店铺单号:</span>
<span
class="info-value clickable ellipsis"
:title="`店铺单号:${(item.shopNumber as string) || ''}`"
@click.stop="copyText((item.shopNumber as string) || '')"
>{{ item.shopNumber }}</span
>
</div>
<div class="card-info-row">
<span class="info-label">款号:</span> <span class="info-label">款号:</span>
<span class="info-value">{{ item.supplierProductNo }}</span> <span
class="info-value clickable ellipsis"
:title="`款号:${(item.supplierProductNo as string) || ''}`"
@click.stop="
copyText((item.supplierProductNo as string) || '')
"
>{{ item.supplierProductNo }}</span
>
</div> </div>
<div v-if="item.batchArrangeNumber" class="card-info-row"> <div class="card-info-row">
<span class="info-label">批次号:</span> <span class="info-label">客户单号:</span>
<span class="info-value">{{ item.batchArrangeNumber }}</span> <span
class="info-value clickable ellipsis"
:title="`客户单号:${(item.thirdOrderNumber as string) || ''}`"
@click.stop="
copyText((item.thirdOrderNumber as string) || '')
"
>{{ item.thirdOrderNumber }}</span
>
</div> </div>
<div class="card-info-row"> <div class="card-info-row">
<span class="info-label">批次号:</span>
<span
class="info-value clickable ellipsis"
:title="`批次号:${(item.batchArrangeNumber as string) || ''}`"
@click.stop="
copyText((item.batchArrangeNumber as string) || '')
"
>{{ item.batchArrangeNumber }}</span
>
</div>
<div class="card-info-row" style="color: red">
<span class="info-label">状态:</span> <span class="info-label">状态:</span>
<span class="info-value">{{ item.statusName }}</span> <span class="info-value">{{ item.statusName }}</span>
</div> </div>
...@@ -106,6 +190,7 @@ ...@@ -106,6 +190,7 @@
</CommonCard> </CommonCard>
</div> </div>
</div> </div>
</div>
<div v-else class="card-empty">暂无数据</div> <div v-else class="card-empty">暂无数据</div>
<div class="card-pagination"> <div class="card-pagination">
...@@ -136,6 +221,7 @@ import { getCardLayoutListApi } from '@/api/factoryOrderNew' ...@@ -136,6 +221,7 @@ import { getCardLayoutListApi } from '@/api/factoryOrderNew'
import type { PaginationData } from '@/types/api' import type { PaginationData } from '@/types/api'
import usePageList from '@/utils/hooks/usePageList' import usePageList from '@/utils/hooks/usePageList'
import { operateOrderListData } from '@/types/api/factoryOrderNew' import { operateOrderListData } from '@/types/api/factoryOrderNew'
import platformJson from '../../../../json/platform.json'
const props = defineProps<{ const props = defineProps<{
status: string status: string
...@@ -161,7 +247,7 @@ const { ...@@ -161,7 +247,7 @@ const {
query: async (current, size) => { query: async (current, size) => {
const payload = { const payload = {
...props.queryPayload, ...props.queryPayload,
statusCode: props.status === 'ALL' ? undefined : props.status, status: props.status === 'ALL' ? undefined : props.status,
} }
const res = await getCardLayoutListApi(payload, current, size) const res = await getCardLayoutListApi(payload, current, size)
return res.data as unknown as PaginationData<operateOrderListData> return res.data as unknown as PaginationData<operateOrderListData>
...@@ -194,6 +280,16 @@ const clearSelection = () => { ...@@ -194,6 +280,16 @@ const clearSelection = () => {
} }
const getSelectedIds = () => selectedItems.value.map((i) => i.id) const getSelectedIds = () => selectedItems.value.map((i) => i.id)
const getPlatformImg = (code: string) => {
const lowerCode = code.toLowerCase()
const item = platformJson.find((el) =>
el.type.toLowerCase().includes(lowerCode),
)
if (item) {
return item.icon.split('/').pop()
}
return ''
}
defineExpose({ clearSelection, getSelectedIds, refresh }) defineExpose({ clearSelection, getSelectedIds, refresh })
</script> </script>
...@@ -205,14 +301,16 @@ defineExpose({ clearSelection, getSelectedIds, refresh }) ...@@ -205,14 +301,16 @@ defineExpose({ clearSelection, getSelectedIds, refresh })
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
} }
.card-content {
flex: 1;
overflow-y: auto;
}
.card-grid { .card-grid {
display: grid; display: grid;
grid-template-columns: repeat(6, 1fr); grid-template-columns: repeat(5, minmax(0, 1fr));
grid-template-rows: max-content; grid-template-rows: max-content;
gap: 10px; gap: 10px;
flex: 1;
overflow-y: auto;
padding: 5px; padding: 5px;
} }
...@@ -250,21 +348,20 @@ defineExpose({ clearSelection, getSelectedIds, refresh }) ...@@ -250,21 +348,20 @@ defineExpose({ clearSelection, getSelectedIds, refresh })
.operation-number { .operation-number {
font-size: 12px; font-size: 12px;
cursor: pointer; cursor: pointer;
color: #409eff;
&:hover {
text-decoration: underline;
}
} }
.quantity-badge { .quantity-badge {
background-color: #e6a23c; background-color: #f56c6c;
color: #fff; color: #fff;
padding: 2px 6px; padding: 5px 8px;
border-radius: 4px; border-radius: 4px;
font-size: 12px; font-size: 12px;
} }
.multiple-quantity-badge-color {
background-color: #e6a23c;
}
.card-info-grid { .card-info-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
...@@ -306,4 +403,53 @@ defineExpose({ clearSelection, getSelectedIds, refresh }) ...@@ -306,4 +403,53 @@ defineExpose({ clearSelection, getSelectedIds, refresh })
} }
} }
} }
.flex-between {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
overflow: hidden;
gap: 6px;
.images-position {
flex: 1;
overflow: auto hidden;
.images-container {
width: 100%;
display: flex;
gap: 6px;
}
.item-image {
width: 50px;
min-width: 50px;
height: 50px;
border: 1px solid #eee;
cursor: pointer;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
b {
margin-right: 5px;
font-size: 15px;
}
}
.flex-row {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.flex-row-gap15 {
gap: 15px;
}
.flex-row-gap6 {
gap: 6px;
}
</style> </style>
...@@ -36,14 +36,18 @@ ...@@ -36,14 +36,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import { loadWarehouseListApi } from '@/api/common' import { loadWarehouseListApi } from '@/api/common'
import { confirmOrderWithWarehouseApi } from '@/api/factoryOrderNew' import { confirmOrderWithWarehouseApi } from '@/api/factoryOrderNew'
import type { WarehouseListData } from '@/types' import type { WarehouseListData } from '@/types'
const emit = defineEmits<{ const emit = defineEmits<{
success: [] success: [data: {
factoryOrderNumber?: string
message?: string
id: number | string
status?: boolean
}[]]
}>() }>()
const visible = ref(false) const visible = ref(false)
...@@ -57,7 +61,9 @@ const form = reactive({ ...@@ -57,7 +61,9 @@ const form = reactive({
}) })
const rules: FormRules = { const rules: FormRules = {
warehouseId: [{ required: true, message: '请选择发货仓库', trigger: 'change' }], warehouseId: [
{ required: true, message: '请选择发货仓库', trigger: 'change' },
],
} }
const loadWarehouseList = async () => { const loadWarehouseList = async () => {
...@@ -85,14 +91,15 @@ const handleSubmit = async () => { ...@@ -85,14 +91,15 @@ const handleSubmit = async () => {
await formRef.value.validate() await formRef.value.validate()
submitLoading.value = true submitLoading.value = true
try { try {
await confirmOrderWithWarehouseApi(orderIds.value, form.warehouseId) const res = await confirmOrderWithWarehouseApi(
ElMessage.success('接单成功') orderIds.value,
form.warehouseId,
)
if (res.code !== 200) return
visible.value = false visible.value = false
emit('success') emit('success', res.data)
} catch (e: unknown) { } catch (e) {
ElMessageBox.alert((e as Error)?.message || '接单失败', '接单失败', { console.error(e)
type: 'error',
})
} finally { } finally {
submitLoading.value = false submitLoading.value = false
} }
......
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
> >
<template #skuImage="{ row }"> <template #skuImage="{ row }">
<el-image <el-image
v-if="row.skuImage" v-if="row.variantImage"
:src="row.skuImage" :src="row.variantImage"
style="width: 50px; height: 50px" style="width: 50px; height: 50px"
fit="contain" fit="contain"
:preview-src-list="[row.skuImage]" :preview-src-list="[row.variantImage]"
preview-teleported preview-teleported
/> />
</template> </template>
......
...@@ -6,12 +6,13 @@ ...@@ -6,12 +6,13 @@
:close-on-click-modal="false" :close-on-click-modal="false"
@close="handleClose" @close="handleClose"
> >
<ElForm ref="formRef" :model="form" :rules="rules" label-width="130px"> <ElForm ref="formRef" :model="form" :rules="rules" label-width="140px">
<ElFormItem label="挂起原因" prop="pauseReason"> <ElFormItem label="挂起原因" prop="pauseReason">
<ElSelect <ElSelect
v-model="form.pauseReason" v-model="form.pauseReason"
placeholder="请选择挂起原因" placeholder="请选择挂起原因"
style="width: 100%" style="width: 100%"
clearable
> >
<ElOption <ElOption
v-for="item in suspendReasons" v-for="item in suspendReasons"
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
v-model="form.needCustomerHandle" v-model="form.needCustomerHandle"
placeholder="请选择" placeholder="请选择"
style="width: 100%" style="width: 100%"
clearable
> >
<ElOption <ElOption
v-for="item in customerHandleOptions" v-for="item in customerHandleOptions"
......
...@@ -122,7 +122,7 @@ ...@@ -122,7 +122,7 @@
<ElFormItem label="商品类型"> <ElFormItem label="商品类型">
<ProductTypeFilter <ProductTypeFilter
v-model="searchForm.productMark" v-model="searchForm.productMarkList"
:options="productTypeGroups" :options="productTypeGroups"
:multiple="false" :multiple="false"
placeholder="请选择商品类型" placeholder="请选择商品类型"
...@@ -430,10 +430,7 @@ ...@@ -430,10 +430,7 @@
<!-- ====== 操作按钮栏 ====== --> <!-- ====== 操作按钮栏 ====== -->
<div v-if="!isSpecialLayout" class="operation-list"> <div v-if="!isSpecialLayout" class="operation-list">
<span v-if="status === 'PENDING_RECEIVE'" class="item"> <span v-if="status === 'PENDING_RECEIVE'" class="item">
<ElButton <ElButton type="success" @click="handleConfirmOrder">
type="success"
@click="handleConfirmOrder"
>
{{ {{
pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK' pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK'
? '重新接单' ? '重新接单'
...@@ -692,7 +689,7 @@ ...@@ -692,7 +689,7 @@
@click="handlePendingAcceptTabClick('ACCEPT_FAIL_OUT_OF_STOCK')" @click="handlePendingAcceptTabClick('ACCEPT_FAIL_OUT_OF_STOCK')"
> >
接单失败-缺货<span> 接单失败-缺货<span>
({{ pendingAcceptCounts.acceptFailOutOfStockCount }}) ({{ pendingAcceptCounts?.acceptedOutOfStockCount || 0 }})
</span> </span>
</div> </div>
</div> </div>
...@@ -706,7 +703,7 @@ ...@@ -706,7 +703,7 @@
/> />
<!-- 到派单、配货中子状态 --> <!-- 到派单、配货中子状态 -->
<div v-if="isCardLayout" class="card-content"> <div :key="status" v-if="isCardLayout" class="card-content">
<CardLayout <CardLayout
ref="cardLayoutRef" ref="cardLayoutRef"
:status="status" :status="status"
...@@ -738,7 +735,11 @@ ...@@ -738,7 +735,11 @@
size="small" size="small"
@click.stop="handleSingleConfirmOrder(row)" @click.stop="handleSingleConfirmOrder(row)"
> >
接单 {{
pendingAcceptSubTab === 'ACCEPT_FAIL_OUT_OF_STOCK'
? '重新接单'
: '接单'
}}
</ElButton> </ElButton>
</template> </template>
</TableView> </TableView>
...@@ -785,7 +786,7 @@ ...@@ -785,7 +786,7 @@
</div> </div>
<ConfirmOrderDialog <ConfirmOrderDialog
ref="confirmOrderDialogRef" ref="confirmOrderDialogRef"
@success="() => refreshCurrentView({ isRefreshTree: true })" @success="(data) => openResultInfoDialog(data)"
/> />
<CancelOrderDialog <CancelOrderDialog
ref="cancelOrderDialogRef" ref="cancelOrderDialogRef"
...@@ -852,18 +853,11 @@ import { ...@@ -852,18 +853,11 @@ import {
Edit, Edit,
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
import { computed, onMounted, ref, watch } from 'vue' import { computed, onMounted, ref, watch } from 'vue'
import {
ElButton,
ElForm,
ElFormItem,
ElMessage,
ElMessageBox,
ElTree,
} from 'element-plus'
import type { TabsPaneContext } from 'element-plus' import type { TabsPaneContext } from 'element-plus'
import splitDiv from '@/components/splitDiv/splitDiv.vue' import splitDiv from '@/components/splitDiv/splitDiv.vue'
import TableView from '@/components/TableView.vue' import TableView from '@/components/TableView.vue'
import usePageList from '@/utils/hooks/usePageList' import usePageList from '@/utils/hooks/usePageList'
import ResultInfo from '@/views/order/podCN/components/ResultInfo.vue'
import type { BaseRespData } from '@/types/api' import type { BaseRespData } from '@/types/api'
import type { import type {
FactoryOrderNewListData, FactoryOrderNewListData,
...@@ -877,6 +871,7 @@ import platformJson from '../../../json/platform.json' ...@@ -877,6 +871,7 @@ import platformJson from '../../../json/platform.json'
import { import {
getFactoryOrderNewDetailApi, getFactoryOrderNewDetailApi,
getFactoryOrderNewListApi, getFactoryOrderNewListApi,
getPodOrderAcceptedStatisticsApi,
getFactoryOrderNewLogApi, getFactoryOrderNewLogApi,
getSuspendListApi, getSuspendListApi,
getSuspendDetailApi, getSuspendDetailApi,
...@@ -953,9 +948,13 @@ const status = ref<string>('PENDING_RECEIVE') ...@@ -953,9 +948,13 @@ const status = ref<string>('PENDING_RECEIVE')
const pendingAcceptSubTab = ref<'PENDING_RECEIVE' | 'ACCEPT_FAIL_OUT_OF_STOCK'>( const pendingAcceptSubTab = ref<'PENDING_RECEIVE' | 'ACCEPT_FAIL_OUT_OF_STOCK'>(
'PENDING_RECEIVE', 'PENDING_RECEIVE',
) )
const pendingAcceptCounts = ref({ const pendingAcceptCounts = ref<{
acceptedOutOfStockCount?: number
pendingCount?: number
totalCount?: number
}>({
pendingCount: 0, pendingCount: 0,
acceptFailOutOfStockCount: 0, acceptedOutOfStockCount: 0,
}) })
const suspendedTabs = [ const suspendedTabs = [
{ label: '客户拦截', value: 'CUSTOMER_INTERCEPT', count: 0 }, { label: '客户拦截', value: 'CUSTOMER_INTERCEPT', count: 0 },
...@@ -972,7 +971,7 @@ const resultInfo = ref< ...@@ -972,7 +971,7 @@ const resultInfo = ref<
}[] }[]
>([]) >([])
const resultRefs = ref() const resultRefs = ref()
const treeRef = ref<InstanceType<typeof ElTree>>() const treeRef = ref()
const searchForm = ref<SearchForm>({}) const searchForm = ref<SearchForm>({})
const dateRange = ref<string[]>([]) const dateRange = ref<string[]>([])
const searchVisible = ref(false) const searchVisible = ref(false)
...@@ -1139,7 +1138,9 @@ const activeTab = ref<'product' | 'log'>('product') ...@@ -1139,7 +1138,9 @@ const activeTab = ref<'product' | 'log'>('product')
const productList = ref<ProductListData[]>([]) const productList = ref<ProductListData[]>([])
const currentRow = ref<FactoryOrderNewListData | null>(null) const currentRow = ref<FactoryOrderNewListData | null>(null)
const selectedRowIds = ref<(number | string)[]>([]) const selectedRowIds = ref<(number | string)[]>([])
// 主表格选中数据
const selectedRows = ref<FactoryOrderNewListData[]>([]) const selectedRows = ref<FactoryOrderNewListData[]>([])
// 卡片布局选中数据
const cardSelectList = ref<operateOrderListData[]>([]) const cardSelectList = ref<operateOrderListData[]>([])
const logList = ref<LogListData[]>([]) const logList = ref<LogListData[]>([])
const tableRef = ref() const tableRef = ref()
...@@ -1245,12 +1246,23 @@ const mainColumns = [ ...@@ -1245,12 +1246,23 @@ const mainColumns = [
const baseProductColumns = [ const baseProductColumns = [
{ {
key: 'productImage', key: 'variantImage',
prop: 'productImage', prop: 'variantImage',
label: '商品图片', label: '商品图片',
minWidth: 90, minWidth: 90,
align: 'center', align: 'center',
slot: 'productImage', render: (row: ProductListData) => {
return (
<div>
<el-image
src={row?.variantImage ?? ''}
previewSrcList={[row?.variantImage ?? '']}
style="width: 50px; height: 50px"
previewTeleported
/>
</div>
)
},
}, },
{ {
key: 'productName', key: 'productName',
...@@ -1259,64 +1271,106 @@ const baseProductColumns = [ ...@@ -1259,64 +1271,106 @@ const baseProductColumns = [
minWidth: 200, minWidth: 200,
showOverflowTooltip: true, showOverflowTooltip: true,
}, },
{ key: 'variantSku', prop: 'variantSku', label: '变体SKU', minWidth: 160 }, {
{ key: 'stockSku', prop: 'stockSku', label: '库存SKU', minWidth: 160 }, key: 'variantSku',
{ key: 'craftCode', prop: 'craftCode', label: '工艺', minWidth: 100 }, prop: 'variantSku',
{ key: 'styleNo', prop: 'styleNo', label: '款号', minWidth: 100 }, label: '变体SKU',
{ key: 'price', prop: 'price', label: '价格', minWidth: 100 }, minWidth: 160,
{ key: 'quantity', prop: 'quantity', label: '数量', minWidth: 100 }, align: 'center',
{ key: 'weight', prop: 'weight', label: '克重', minWidth: 100 }, },
{
key: 'thirdSkuCode',
prop: 'thirdSkuCode',
label: '库存SKU',
minWidth: 160,
align: 'center',
},
{
key: 'craftCode',
prop: 'craftCode',
label: '工艺',
minWidth: 100,
align: 'center',
},
{
key: 'styleNo',
prop: 'styleNo',
label: '款号',
minWidth: 100,
align: 'center',
},
{ key: 'price', prop: 'price', label: '价格', minWidth: 100, align: 'right' },
{
prop: 'num',
label: '数量',
minWidth: 100,
align: 'right',
},
{
prop: 'weight',
label: '克重',
minWidth: 100,
align: 'right',
},
{ {
key: 'availableQuantity', key: 'availableQuantity',
prop: 'availableQuantity', prop: 'availableQuantity',
label: '可用数量', label: '可用数量',
minWidth: 100, minWidth: 100,
align: 'right',
}, },
{ {
key: 'stockQuantity', key: 'stockQuantity',
prop: 'stockQuantity', prop: 'stockQuantity',
label: '库存数量', label: '库存数量',
minWidth: 100, minWidth: 100,
align: 'right',
}, },
{ {
key: 'occupiedQuantity', key: 'occupiedQuantity',
prop: 'occupiedQuantity', prop: 'occupiedQuantity',
label: '占用数量', label: '占用数量',
minWidth: 100, minWidth: 100,
align: 'right',
}, },
{ {
key: 'customsNameEnglish', key: 'customsNameEnglish',
prop: 'customsNameEnglish', prop: 'customsNameEnglish',
label: '英文报关名称', label: '英文报关名称',
width: 160, width: 160,
align: 'center',
}, },
{ {
key: 'customsNameChinese', key: 'customsNameChinese',
prop: 'customsNameChinese', prop: 'customsNameChinese',
label: '中文报关名称', label: '中文报关名称',
width: 160, width: 160,
align: 'center',
}, },
{ {
key: 'customsWeight', key: 'customsWeight',
prop: 'customsWeight', prop: 'customsWeight',
label: '申报重量(g)', label: '申报重量(g)',
width: 100, width: 100,
align: 'right',
}, },
{ {
key: 'customsValue', key: 'customsValue',
prop: 'customsValue', prop: 'customsValue',
label: '申报价值($)', label: '申报价值($)',
width: 100, width: 100,
align: 'right',
}, },
{ {
key: 'remark', key: 'remark',
prop: 'remark', prop: 'remark',
label: '备注', label: '备注',
width: 160, width: 160,
render: ({ row }: { row: ProductListData }) => { align: 'center',
render: (row: ProductListData) => {
return ( return (
<div style="display:flex;align-items:center;gap:4px"> <div style="display:flex;align-items:center;justify-content:center;gap:4px">
<span>{row?.remark || ''}</span> <span>{row?.remark ?? ''}</span>
<el-icon <el-icon
style="cursor:pointer;color:#409eff;flex-shrink:0" style="cursor:pointer;color:#409eff;flex-shrink:0"
onClick={(e: Event) => { onClick={(e: Event) => {
...@@ -1341,10 +1395,10 @@ const productColumns = computed(() => { ...@@ -1341,10 +1395,10 @@ const productColumns = computed(() => {
prop: 'operation', prop: 'operation',
label: '操作', label: '操作',
width: 120, width: 120,
fixed: 'right', fixed: 'center',
render: ({ row }: { row: ProductListData }) => { render: ({ row }: { row: ProductListData }) => {
return ( return (
<ElButton <el-button
type="warning" type="warning"
link link
size="small" size="small"
...@@ -1354,7 +1408,7 @@ const productColumns = computed(() => { ...@@ -1354,7 +1408,7 @@ const productColumns = computed(() => {
}} }}
> >
申请补胚 申请补胚
</ElButton> </el-button>
) )
}, },
}, },
...@@ -1369,6 +1423,13 @@ const getQueryPayload = () => ({ ...@@ -1369,6 +1423,13 @@ const getQueryPayload = () => ({
endTime: dateRange.value?.[1] || null, endTime: dateRange.value?.[1] || null,
}) })
const getListPageAcceptedSubStatus = () =>
status.value === 'PENDING_RECEIVE'
? pendingAcceptSubTab.value === 'PENDING_RECEIVE'
? 0
: 2
: undefined
const { const {
loading, loading,
currentPage, currentPage,
...@@ -1395,31 +1456,17 @@ const { ...@@ -1395,31 +1456,17 @@ const {
return res.data return res.data
}) })
} }
const currentSubStatus =
status.value === 'PENDING_RECEIVE'
? pendingAcceptSubTab.value === 'PENDING_RECEIVE'
? 0
: 2
: undefined
return getFactoryOrderNewListApi( return getFactoryOrderNewListApi(
getQueryPayload(), getQueryPayload(),
page, page,
size, size,
status.value === 'ALL' ? undefined : status.value, status.value === 'ALL' ? undefined : status.value,
currentSubStatus, getListPageAcceptedSubStatus(),
).then(async (res) => { ).then(async (res) => {
const records = Array.isArray(res.data?.records) ? res.data.records : [] const records = res.data.records
const extra = res.data as unknown as Record<string, unknown>
if (status.value === 'PENDING_RECEIVE') {
pendingAcceptCounts.value = {
pendingCount: (extra.pendingCount as number) ?? 0,
acceptFailOutOfStockCount:
(extra.acceptFailOutOfStockCount as number) ?? 0,
}
}
await nextTick(() => { await nextTick(() => {
tableRef.value.setCurrentRow(records[0]) tableRef.value.setCurrentRow(records[0])
currentRow.value = records[0] as never currentRow.value = (records[0] as never) || null
}) })
return res.data return res.data
}) })
...@@ -1469,10 +1516,12 @@ const refreshCurrentView = (options?: { isRefreshTree?: boolean }) => { ...@@ -1469,10 +1516,12 @@ const refreshCurrentView = (options?: { isRefreshTree?: boolean }) => {
cardLayoutRef.value?.refresh(true) cardLayoutRef.value?.refresh(true)
return return
} }
if (status.value === 'PENDING_RECEIVE') {
getPendingReceiveCounts()
}
refreshTableList() refreshTableList()
} }
const handleStatusNodeClick = (node: StatusTreeNode) => { const handleStatusNodeClick = (node: StatusTreeNode) => {
if (status.value === node.status) return
status.value = node.status status.value = node.status
if (node.status !== 'PENDING_RECEIVE') { if (node.status !== 'PENDING_RECEIVE') {
pendingAcceptSubTab.value = 'PENDING_RECEIVE' pendingAcceptSubTab.value = 'PENDING_RECEIVE'
...@@ -1548,17 +1597,21 @@ const getOrderDetailsById = async (tabName?: 'product' | 'log') => { ...@@ -1548,17 +1597,21 @@ const getOrderDetailsById = async (tabName?: 'product' | 'log') => {
} }
} }
watch(currentRow, (row) => { watch(currentRow, (row) => {
if (!row) return if (!row) {
productList.value = []
logList.value = []
return
}
if (!isTableLayout.value) return if (!isTableLayout.value) return
void getOrderDetailsById() void getOrderDetailsById()
}) })
const handleRowClick = (row: FactoryOrderNewListData) => { const handleRowClick = (row: FactoryOrderNewListData) => {
const isSameRow = currentRow.value?.id === row.id
currentRow.value = row currentRow.value = row
productList.value = [] if (isSameRow) {
logList.value = [] getOrderDetailsById()
selectedRowIds.value = [] return
selectedRows.value = [] }
cardSelectList.value = []
} }
const handleTabClick = (tab: TabsPaneContext) => { const handleTabClick = (tab: TabsPaneContext) => {
...@@ -1573,10 +1626,17 @@ const handleEditRemark = async (row: ProductListData) => { ...@@ -1573,10 +1626,17 @@ const handleEditRemark = async (row: ProductListData) => {
inputValue: row.remark || '', inputValue: row.remark || '',
confirmButtonText: '确认', confirmButtonText: '确认',
cancelButtonText: '取消', cancelButtonText: '取消',
inputPattern: /.+/,
inputErrorMessage: '请输入备注',
}) })
await updateRemarkApi(row.id, value) try {
const res = await updateRemarkApi(row.id, value)
if (res.code !== 200) return
ElMessage.success('备注修改成功') ElMessage.success('备注修改成功')
void getOrderDetailsById('product') getOrderDetailsById('product')
} catch (e) {
console.error(e)
}
} catch { } catch {
// cancelled // cancelled
} }
...@@ -1590,6 +1650,24 @@ const handleConfirmOrder = () => { ...@@ -1590,6 +1650,24 @@ const handleConfirmOrder = () => {
if (!ensureSelection()) return if (!ensureSelection()) return
confirmOrderDialogRef.value?.open(getSelectedIds()) confirmOrderDialogRef.value?.open(getSelectedIds())
} }
const openResultInfoDialog = (
data: {
factoryOrderNumber?: string
message?: string
id: number | string
status?: boolean
}[],
) => {
nextTick(() => {
resultInfo.value = data.map((item) => ({
id: item.id,
status: item.status ?? false,
factoryOrderNumber: item.factoryOrderNumber ?? '',
message: item.message ?? '',
}))
resultRefs.value?.showDialog()
})
}
const handleCancelOrder = () => { const handleCancelOrder = () => {
if (!ensureSelection()) return if (!ensureSelection()) return
cancelOrderDialogRef.value?.open(getSelectedIds()) cancelOrderDialogRef.value?.open(getSelectedIds())
...@@ -1602,7 +1680,8 @@ const handleRefreshProductInfo = async () => { ...@@ -1602,7 +1680,8 @@ const handleRefreshProductInfo = async () => {
background: 'rgba(0, 0, 0, 0.3)', background: 'rgba(0, 0, 0, 0.3)',
}) })
try { try {
await refreshProductInfoApi(getSelectedIds()) const res = await refreshProductInfoApi(getSelectedIds())
if (res.code !== 200) return
ElMessage.success('刷新商品信息成功') ElMessage.success('刷新商品信息成功')
refreshCurrentView() refreshCurrentView()
} catch (e) { } catch (e) {
...@@ -1688,7 +1767,7 @@ const handleArrange = async () => { ...@@ -1688,7 +1767,7 @@ const handleArrange = async () => {
.filter((n) => Number.isFinite(n)) as number[] .filter((n) => Number.isFinite(n)) as number[]
arrangeDialogRef.value?.open({ arrangeDialogRef.value?.open({
productIdList, productIdList,
requestUrl: 'factory/podOrder/updateLogisticsToArrange', requestUrl: 'factory/podOrderOperation/arrangeFinish',
showAutoSwitch: true, showAutoSwitch: true,
}) })
} }
...@@ -1851,15 +1930,15 @@ const downloadPDF = (url: string) => { ...@@ -1851,15 +1930,15 @@ const downloadPDF = (url: string) => {
} }
const handleDownloadMaterial = async () => { const handleDownloadMaterial = async () => {
if (!ensureSelection()) return if (!ensureSelection()) return
const usePodOrderDownloadStatuses = ['PENDING_SCHEDULE', 'PENDING_DELIVERY', 'SUSPEND'] const usePodOrderDownloadStatuses = [
'PENDING_DELIVERY',
'SUSPEND',
]
const usePodOrderDownload = usePodOrderDownloadStatuses.includes(status.value) const usePodOrderDownload = usePodOrderDownloadStatuses.includes(status.value)
const ids = usePodOrderDownload const ids = usePodOrderDownload
? selectedRows.value.map((row) => row.id) ? selectedRows.value.map((row) => row.id)
: cardSelectList.value.map((row) => row.podOrderProductId) : cardSelectList.value.map((row) => row.podOrderProductId)
if (!ids.length) { console.log(usePodOrderDownload,ids,cardSelectList.value.map((row) => row.podOrderProductId))
ElMessage.warning('未获取到可下载的素材ID')
return
}
const loading = ElLoading.service({ const loading = ElLoading.service({
fullscreen: true, fullscreen: true,
text: '操作中...', text: '操作中...',
...@@ -2100,6 +2179,21 @@ const handleStatusPush = () => { ...@@ -2100,6 +2179,21 @@ const handleStatusPush = () => {
if (!ensureSelection()) return if (!ensureSelection()) return
ElMessage.info('状态推送功能待集成') ElMessage.info('状态推送功能待集成')
} }
const getPendingReceiveCounts = async () => {
try {
const res = await getPodOrderAcceptedStatisticsApi(
getQueryPayload(),
currentPage.value,
pageSize.value,
status.value,
getListPageAcceptedSubStatus(),
)
if (res.code !== 200) return
pendingAcceptCounts.value = res.data || { pendingCount: 0, acceptedOutOfStockCount: 0 }
} catch (e) {
console.error(e)
}
}
onMounted(() => { onMounted(() => {
loadStatusTreeCounts() loadStatusTreeCounts()
loadCraftList() loadCraftList()
...@@ -2108,6 +2202,9 @@ onMounted(() => { ...@@ -2108,6 +2202,9 @@ onMounted(() => {
getLogisticsCompanyAllCodelist() getLogisticsCompanyAllCodelist()
getReceiverCountryList() getReceiverCountryList()
loadWarehouseList() loadWarehouseList()
if (status.value === 'PENDING_RECEIVE') {
getPendingReceiveCounts()
}
}) })
</script> </script>
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
<div style="margin: 15px 0"></div> <div style="margin: 15px 0"></div>
<el-checkbox-group v-model="selectedList" @change="checkChange"> <el-checkbox-group v-model="selectedList" @change="checkChange">
<div style="display: block" v-for="(item, index) in list" :key="index"> <div style="display: block" v-for="(item, index) in list" :key="index">
<el-checkbox :value="item"> <el-checkbox :value="item" style="user-select: text;">
{{ '工厂订单号:' + item.factoryOrderNumber + ' ' + item.message }} {{ '工厂订单号:' + item.factoryOrderNumber + ' ' + item.message }}
</el-checkbox> </el-checkbox>
</div> </div>
......
...@@ -1047,8 +1047,8 @@ ...@@ -1047,8 +1047,8 @@
<div class="header-filter-tab"> <div class="header-filter-tab">
<div class="tabs"> <div class="tabs">
<div <div
v-for="item in tabsNav" v-for="(item, tabIndex) in tabsNav"
:key="item.status" :key="`${tabIndex}-${item.status ?? ''}`"
class="tabs-node" class="tabs-node"
:class="item.status === status ? 'tabs-node_active' : ''" :class="item.status === status ? 'tabs-node_active' : ''"
@click="changeTab(item)" @click="changeTab(item)"
...@@ -2079,6 +2079,7 @@ ...@@ -2079,6 +2079,7 @@
</div> </div>
<div <div
v-else v-else
:key="status"
v-loading="loading" v-loading="loading"
element-loading-text="加载中..." element-loading-text="加载中..."
class="card-wrapper flex-1 flex-column overflow-hidden" class="card-wrapper flex-1 flex-column overflow-hidden"
...@@ -4845,9 +4846,9 @@ const cancelOrder = async () => { ...@@ -4845,9 +4846,9 @@ const cancelOrder = async () => {
} }
const cardSelection = ref<ProductList[]>([]) const cardSelection = ref<ProductList[]>([])
const cardClick = (data: ProductList) => { const cardClick = (data: ProductList) => {
const status = isSelectStatused(data) const selected = isSelectStatused(data)
if (status) { if (selected) {
cardSelection.value = cardSelection.value.filter( cardSelection.value = cardSelection.value.filter(
(item: ProductList) => item.id !== data.id, (item: ProductList) => item.id !== data.id,
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment