Commit 9498e00e by zhuzhequan

Merge branch 'dev' into 'master'

Dev

See merge request !105
parents ad9c9103 9deae37e
......@@ -85,6 +85,23 @@ export function getCardOrderList(
},
)
}
export function uploadPRNFile(
id: number,
data: FormData,
) {
return axios.post<never, BaseRespData<string>>(
`/factory/podBatchDownload/uploadPRNFile?id=${id}`,
data
)
}
export function updatePRNDownloadStatus(
id: number
) {
return axios.get<never, BaseRespData<string>>(
`/factory/podBatchDownload/updatePRNDownloadStatus?id=${id}`
)
}
export function confirmOrderApi(
data: number[],
productionClient: string,
......
import { BasePaginationData, BaseRespData } from '@/types/api'
import axios from './../axios'
import {
IListPage,
IsupplierType,
} from '@/views/supply/supplierManagement/types/index'
//供应商分页查询
export function getSupplierListApi(params: IListPage) {
return axios.get<never, BasePaginationData<never>>(
'/factory/supplier/list_page',
{ params },
)
}
// 删除供应商
export function deleteSupplierApi(params: { ids: string }) {
return axios.get<never, BaseRespData<never>>('/factory/supplier/delete', {
params,
})
}
// 编辑回显接口
export function getSupplierDetailApi(id: string | number) {
return axios.get<never, BaseRespData<never>>('factory/supplier/get', {
params: { id },
})
}
// 根据分类id获取属性信息
export function getPropertyByCateIdApi(cateId: string | number) {
return axios.get<never, BaseRespData<never>>(
'/factory/supplier/getPropertyByCateId',
{
params: { cateId },
},
)
}
// 根据spu获取商品信息
export function getProductInfoBySpuApi(spu: string | number) {
return axios.get<never, BaseRespData<never>>(
'/factory/supplier/getProductInfoBySpu',
{
params: { spu },
},
)
}
// 获取币种接口
export function getBaseCurrencyInfoApi() {
return axios.get<never, BaseRespData<never>>(
'factory/supplier/getBaseCurrencyInfo',
)
}
//新增
export function addSupplierApi(params: IsupplierType) {
return axios.post<never, BaseRespData<never>>('/factory/supplier/add', params)
}
//修改
export function updateSupplierApi(params: IsupplierType) {
return axios.post<never, BaseRespData<never>>(
'/factory/supplier/update',
params,
)
}
......@@ -16,7 +16,7 @@ type SimpleFormData = Record<string, unknown>
// 定义表单项配置接口
export interface IFormConfig {
fixed?: string
title?: string
title?: string | boolean
prop?: string
label?: string
type?: string
......@@ -190,17 +190,19 @@ export default defineComponent({
flexWrap: 'wrap',
}}
>
<div
style={{
width: '100%',
textAlign: 'center',
fontWeight: 700,
marginBottom: '20px',
fontSize: '16px',
}}
>
{item.title}
</div>
{typeof item.title === 'string' && item.title !== '' && (
<div
style={{
width: '100%',
textAlign: 'center',
fontWeight: 700,
marginBottom: '20px',
fontSize: '16px',
}}
>
{item.title}
</div>
)}
{item.render && item.render(item, this.formData)}
</div>
) : (
......
......@@ -110,6 +110,13 @@ export default defineComponent({
emit('getCheckboxRecords', selectRecords)
}
}
//获取设置多选框
const setCheckboxRow = (row: TableRowData, checked: boolean) => {
const $table = tableRef.value
if ($table) {
$table.setCheckboxRow(row, checked)
}
}
//设置高亮行
const selectRowEvent = (row: TableRowData) => {
const $table = tableRef.value
......@@ -129,6 +136,7 @@ export default defineComponent({
editConfig,
getSelectEvent,
selectRowEvent,
setCheckboxRow,
attrs,
}
},
......
......@@ -131,7 +131,7 @@ const router = createRouter({
meta: {
title: '下载生产客户端',
},
component: () => { },
component: () => {},
beforeEnter() {
// 假设你的下载链接是这个
const downloadLink = '/exeFiles/JomallProductionAssistantSetup.exe'
......@@ -317,6 +317,15 @@ const router = createRouter({
name: 'MyDownloads',
component: () => import('@/views/MyDownloads.vue'),
},
{
path: '/supply/supplierManagement',
meta: {
title: '供应商管理',
},
name: 'supplierManagement',
component: () =>
import('@/views//supply/supplierManagement/index.vue'),
},
],
},
// 登录
......
......@@ -150,6 +150,18 @@ const menu: MenuItem[] = [
},
{
index: '12',
id: 4,
label: '供应',
children: [
{
index: '/supply/supplierManagement',
id: 1,
label: '供应商管理',
},
],
},
{
index: '11',
id: 3,
label: '对账单',
......
......@@ -48,8 +48,11 @@ export interface SearchForm {
export interface PodUsOrderListData {
id: number
thirdOrderNumber?: string
prnUrl?: string
factoryOrderNumber?: string
prnDownloadStatus?: boolean
shopNumber?: string
isUpload?: boolean
factoryOnlineId?: number | null
factoryNo?: number | null
factoryCode?: string | null
......
......@@ -997,7 +997,8 @@
style="display: flex; flex-direction: column"
>
<div
v-for="img in item.productMark !== 'normal'
v-for="img in item.productMark !== 'normal' &&
item.productMark !== 'custom_normal'
? item.previewImgs
: [{ url: item.variantImage }]"
:key="img"
......
......@@ -379,14 +379,14 @@
<ElFormItem>
<span>
<ElButton link style="font-size: 12px" @click="resetSearchForm"
><span title="重置查询条件">重置</span></ElButton
><span title="重置查询条件">重置</span></ElButton
>
</span>
</ElFormItem>
<ElFormItem>
<span>
<ElButton ref="searchBtnRef" type="primary" @click="search"
>查询</ElButton
>查询</ElButton
>
</span>
</ElFormItem>
......@@ -399,33 +399,43 @@
>
<ElDropdown>
<el-button type="primary">
DTF排版<el-icon class="el-icon--right"><ArrowDown /></el-icon>
DTF排版
<el-icon class="el-icon--right">
<ArrowDown />
</el-icon>
</el-button>
<template #dropdown>
<ElDropdownMenu>
<ElDropdownItem
:loading="tifDownloadLoading"
@click="downloadTif('tiff', 42)"
>TIF(40+2cm)</ElDropdownItem
>TIF(40+2cm)
</ElDropdownItem
>
<ElDropdownItem
:loading="tifDownloadLoading"
@click="downloadTif('tiff', 60)"
>TIF(60cm)</ElDropdownItem
>TIF(60cm)
</ElDropdownItem
>
<ElDropdownItem
:loading="pngDownloadLoading"
@click="downloadTif('png', 42)"
>PNG(40+2cm)</ElDropdownItem
>PNG(40+2cm)
</ElDropdownItem
>
<ElDropdownItem
:loading="pngDownloadLoading"
@click="downloadTif('png', 60)"
>PNG(60cm)</ElDropdownItem
>PNG(60cm)
</ElDropdownItem
>
</ElDropdownMenu></template
></ElDropdown
></ElFormItem
</ElDropdownMenu>
</template
>
</ElDropdown
>
</ElFormItem
>
<!-- <ElFormItem
v-if="
......@@ -609,7 +619,7 @@
<ElFormItem v-if="status === 'WAIT_SHIPMENT'">
<span class="item">
<ElButton type="primary" @click="completeDelivery()"
>完成发货</ElButton
>完成发货</ElButton
>
</span>
</ElFormItem>
......@@ -629,7 +639,7 @@
selection.some((item) => item.shipmentType !== 1)
"
@click="getOrderByIdApi('createLogisticsOrder')"
>创建物流订单</ElDropdownItem
>创建物流订单</ElDropdownItem
>
<ElDropdownItem
:disabled="
......@@ -637,7 +647,7 @@
selection.some((item) => item.shipmentType !== 1)
"
@click="getOrderByIdApi('getTrackingNumber')"
>获取跟踪号</ElDropdownItem
>获取跟踪号</ElDropdownItem
>
<ElDropdownItem
:disabled="
......@@ -645,7 +655,7 @@
selection.some((item) => item.shipmentType !== 1)
"
@click="getOrderByIdApi('getPrintOrder')"
>获取打印面单</ElDropdownItem
>获取打印面单</ElDropdownItem
>
<ElDropdownItem
:disabled="
......@@ -653,7 +663,7 @@
selection.some((item) => item.shipmentType !== 1)
"
@click="getOrderByIdApi('cancelLogisticsOrder')"
>取消物流订单</ElDropdownItem
>取消物流订单</ElDropdownItem
>
<!-- <ElDropdownItem
:disabled="
......@@ -690,7 +700,7 @@
>
<span class="item">
<ElButton type="primary" @click="downloadMaterial"
>下载素材</ElButton
>下载素材</ElButton
>
</span>
</ElFormItem>
......@@ -766,7 +776,7 @@
selection.length === 0 && cardSelection.length === 0
"
@click="rejectOrder('TO_BE_CONFIRMED')"
>待确认</ElDropdownItem
>待确认</ElDropdownItem
>
<ElDropdownItem
v-if="
......@@ -778,7 +788,7 @@
selection.length === 0 && cardSelection.length === 0
"
@click="rejectOrder('CREATE_LOGISTICS')"
>待创建物流</ElDropdownItem
>待创建物流</ElDropdownItem
>
<ElDropdownItem
v-if="status === 'PICKING' || status === 'IN_PRODUCTION'"
......@@ -786,7 +796,7 @@
selection.length === 0 && cardSelection.length === 0
"
@click="rejectOrder('TO_BE_ARRANGE')"
>待排单</ElDropdownItem
>待排单</ElDropdownItem
>
<ElDropdownItem
v-if="status === 'IN_PRODUCTION'"
......@@ -794,7 +804,7 @@
selection.length === 0 && cardSelection.length === 0
"
@click="rejectOrder('PICKING')"
>待拣胚</ElDropdownItem
>待拣胚</ElDropdownItem
>
</ElDropdownMenu>
</template>
......@@ -822,7 +832,7 @@
<ElFormItem v-if="status === 'BATCH_DOWNLOAD'">
<span class="item">
<ElButton type="danger" @click="handleBatchDelete('batch')"
>批量删除</ElButton
>批量删除</ElButton
>
</span>
</ElFormItem>
......@@ -850,7 +860,7 @@
blue: item.quantity && item.quantity > 0,
red: item.status === 'EXCEPTION_ORDER',
}"
>{{ item.quantity }}</span
>{{ item.quantity }}</span
>
<span
v-if="
......@@ -859,9 +869,9 @@
interceptionStatus.shipment['0'])
"
class="tabs-node-quantity"
>+{{
>+{{
(interceptionStatus.production['0'] || 0) +
(interceptionStatus.shipment['0'] || 0) || ''
(interceptionStatus.shipment['0'] || 0) || ''
}}</span
>
</div>
......@@ -931,11 +941,11 @@
@click="handleWaitTrackCommand(1)"
>
<span class="sub-status-item-label">{{
trackRegisterCount[0]?.name
}}</span>
trackRegisterCount[0]?.name
}}</span>
<span class="tabs-node_count">{{
trackRegisterCount[0]?.count || 0
}}</span>
trackRegisterCount[0]?.count || 0
}}</span>
</div>
<div
class="sub-status-item"
......@@ -943,11 +953,11 @@
@click="handleWaitTrackCommand(2)"
>
<span class="sub-status-item-label">{{
trackRegisterCount[1]?.name
}}</span>
trackRegisterCount[1]?.name
}}</span>
<span class="tabs-node_count blue">{{
trackRegisterCount[1]?.count || 0
}}</span>
trackRegisterCount[1]?.count || 0
}}</span>
</div>
<div
class="sub-status-item"
......@@ -955,11 +965,11 @@
@click="handleWaitTrackCommand(3)"
>
<span class="sub-status-item-label">{{
trackRegisterCount[2]?.name
}}</span>
trackRegisterCount[2]?.name
}}</span>
<span class="tabs-node_count green">{{
trackRegisterCount[2]?.count || 0
}}</span>
trackRegisterCount[2]?.count || 0
}}</span>
</div>
<div
class="sub-status-item"
......@@ -967,11 +977,11 @@
@click="handleWaitTrackCommand(4)"
>
<span class="sub-status-item-label">{{
trackRegisterCount[3]?.name
}}</span>
trackRegisterCount[3]?.name
}}</span>
<span class="tabs-node_count yellow">{{
trackRegisterCount[3]?.count || 0
}}</span>
trackRegisterCount[3]?.count || 0
}}</span>
</div>
<div
class="sub-status-item"
......@@ -979,11 +989,11 @@
@click="handleWaitTrackCommand(5)"
>
<span class="sub-status-item-label">{{
trackRegisterCount[4]?.name
}}</span>
trackRegisterCount[4]?.name
}}</span>
<span class="tabs-node_count red">{{
trackRegisterCount[4]?.count || 0
}}</span>
trackRegisterCount[4]?.count || 0
}}</span>
</div>
</div>
<div v-if="status === 'INTERCEPTED'" class="sub-status mb-10">
......@@ -996,7 +1006,7 @@
<span
v-if="interceptionStatus.production['0']"
class="tabs-node_count blue"
>{{ interceptionStatus.production['0'] }}</span
>{{ interceptionStatus.production['0'] }}</span
>
</div>
<div
......@@ -1008,7 +1018,7 @@
<span
v-if="interceptionStatus.production['1']"
class="tabs-node_count blue"
>{{ interceptionStatus.production['1'] }}</span
>{{ interceptionStatus.production['1'] }}</span
>
</div>
<div
......@@ -1020,7 +1030,7 @@
<span
v-if="interceptionStatus.production['2']"
class="tabs-node_count red"
>{{ interceptionStatus.production['2'] }}</span
>{{ interceptionStatus.production['2'] }}</span
>
</div>
<div
......@@ -1032,7 +1042,7 @@
<span
v-if="interceptionStatus.shipment['0']"
class="tabs-node_count blue"
>{{ interceptionStatus.shipment['0'] }}</span
>{{ interceptionStatus.shipment['0'] }}</span
>
</div>
<div
......@@ -1044,7 +1054,7 @@
<span
v-if="interceptionStatus.shipment['1']"
class="tabs-node_count blue"
>{{ interceptionStatus.shipment['1'] }}</span
>{{ interceptionStatus.shipment['1'] }}</span
>
</div>
<div
......@@ -1056,7 +1066,7 @@
<span
v-if="interceptionStatus.shipment['2']"
class="tabs-node_count red"
>{{ interceptionStatus.shipment['2'] }}</span
>{{ interceptionStatus.shipment['2'] }}</span
>
</div>
</div>
......@@ -1255,7 +1265,7 @@
</div>
<div class="goods-item-info-item">
<span class="goods-item-info-item-label"
>第三方生产单号:</span
>第三方生产单号:</span
>
<span
class="goods-item-info-item-value"
......@@ -1305,14 +1315,14 @@
>
<!-- <span class="goods-item-info-item-label">补胚状态:</span> -->
<el-tag size="small" effect="dark" type="danger"
>补胚中
>补胚中
</el-tag>
</div>
</div>
<div class="goods-item-info">
<div class="goods-item-info-item">
<span class="goods-item-info-item-label"
>商品单价($):</span
>商品单价($):</span
>
<span class="goods-item-info-item-value">
{{ item.productPrice }}
......@@ -1339,14 +1349,14 @@
<div class="goods-item-info-item">
<span class="goods-item-info-item-label">{{
status === 'EXCEPTION_ORDER' ||
status === 'PICKING' ||
status === 'TO_BE_CONFIRMED' ||
status === 'STOCK_OUT' ||
status === 'CREATE_LOGISTICS'
? '数量:'
: '已生产数量:'
}}</span>
status === 'EXCEPTION_ORDER' ||
status === 'PICKING' ||
status === 'TO_BE_CONFIRMED' ||
status === 'STOCK_OUT' ||
status === 'CREATE_LOGISTICS'
? '数量:'
: '已生产数量:'
}}</span>
<span class="goods-item-info-item-value">
{{
status === 'EXCEPTION_ORDER' ||
......@@ -1417,7 +1427,7 @@
type="success"
style="height: 23px"
@click="applyForReplenishment(item)"
>申请补胚
>申请补胚
</el-button>
</div>
......@@ -1436,7 +1446,7 @@
type="primary"
style="height: 23px; padding: 0"
@click="downloadMaterialItem(item)"
>下载素材
>下载素材
</el-button>
<el-button
......@@ -1445,7 +1455,7 @@
type="warning"
style="height: 23px; margin: 0"
@click="showArrange(3, item)"
>排版
>排版
</el-button>
</div>
<div
......@@ -1465,7 +1475,7 @@
type="success"
style="height: 23px"
@click="printProductionOrder(1, item)"
>打印生产单
>打印生产单
</el-button>
</div>
</div>
......@@ -1569,9 +1579,9 @@
{{
row.source
? {
'jomall-erp': 'erp推送',
'third-party': '第三方推送',
}[row.source as 'jomall-erp' | 'third-party']
'jomall-erp': 'erp推送',
'third-party': '第三方推送',
}[row.source as 'jomall-erp' | 'third-party']
: ''
}}
</span>
......@@ -1687,17 +1697,17 @@
<el-timeline-item
:color="row.createTime ? '#409EFF' : ''"
:timestamp="row.createTime"
>创建时间
>创建时间
</el-timeline-item>
<el-timeline-item
:color="row.startStockingTime ? '#E6A23C' : ''"
:timestamp="row.startStockingTime"
>确认时间
>确认时间
</el-timeline-item>
<el-timeline-item
:color="row.finishTime ? '#67C23A' : ''"
:timestamp="row.finishTime"
>发货时间
>发货时间
</el-timeline-item>
<el-timeline-item
v-if="status === 'IN_TRANSIT'"
......@@ -1781,6 +1791,26 @@
{{ row.automaticComposing ? '是' : '否' }}
</div>
</template>
<template #prn="{ row }">
<div style="display: flex">
<span :title="fileName(row)" class="flex-1">{{ fileName(row) }}</span>
<el-link :disabled="row.isUpload" underline="never" type="success" @click="uploadFile(row)">上传</el-link>
<el-icon v-if="row.isUpload" style="right: 0;top:5px;" class="is-loading"
>
<Loading
/>
</el-icon>
<el-link
:disabled="!row.prnUrl" style="margin-left: 8px" underline="never" type="primary"
@click="downloadRowProFile(row)">下载
</el-link>
<el-icon v-if="row.prnDownloadStatus" style="right: -2px" class="check-icon"
>
<CircleCheckFilled
/>
</el-icon>
</div>
</template>
<template #composingParam="{ row }">
<div style="white-space: pre-line">
{{ row.composingParam?.split(';').join('\n') }}
......@@ -1809,7 +1839,7 @@
下载
</ElButton>
<el-icon v-if="row.downloadStatus" class="check-icon"
><CircleCheckFilled
><CircleCheckFilled
/></el-icon>
</span>
<!-- <span class="operate-item">
......@@ -1825,36 +1855,39 @@
<span class="operate-item">
<ElButton
link
title="打印拣货单"
type="primary"
@click="printPickingOrderItem(row, 1)"
>
打印拣货单
拣货单
</ElButton>
<el-icon v-if="row.printPickOrder" class="check-icon"
><CircleCheckFilled
><CircleCheckFilled
/></el-icon>
</span>
<span class="operate-item">
<ElButton
link
title="打印生产单"
type="primary"
@click="printPickingOrderItem(row, 2)"
>
打印生产单
生产单
</ElButton>
<el-icon v-if="row.printProductOrder" class="check-icon"
><CircleCheckFilled
><CircleCheckFilled
/></el-icon>
</span>
<span class="operate-item">
<ElButton
:disabled="row.productNum > 50"
link
title="重新排版"
type="warning"
:loading="reComposingLoadingMap[row.id]"
@click="showArrange(1, row)"
>
新排版
</ElButton>
</span>
<span class="operate-item">
......@@ -1896,7 +1929,7 @@
class="operate-item"
>
<ElButton link type="warning" @click="updateTrackingNumber(row)"
>修改跟踪号</ElButton
>修改跟踪号</ElButton
>
</span>
<!-- <span
......@@ -1972,7 +2005,7 @@
class="operate-item"
>
<ElButton link type="primary" @click="logTrajectory(row)"
>物流轨迹</ElButton
>物流轨迹</ElButton
>
</span>
</div>
......@@ -1994,8 +2027,8 @@
<div
v-for="(cardItem) in tableData as ProductList[]"
:key="cardItem.id"
class="card-list-item"
ref="cardRefs"
class="card-list-item"
@click="cardClick(cardItem)"
@mouseleave="handleChangeImages(null, cardItem)"
>
......@@ -2043,26 +2076,27 @@
type="primary"
:title="item.name || ''"
style="margin-bottom: 2px"
>{{ item.name || '' }}</el-tag
>{{ item.name || '' }}
</el-tag
>
</div>
</template>
<div
class="flex"
v-if="cardItem.customTagList?.length"
ref="tagRefs"
class="flex"
style="gap: 5px; overflow: hidden"
v-if="cardItem.customTagList?.length"
>
<el-tag
size="small"
type="primary"
v-for="(item, index) in cardItem.customTagList.slice(
0,
3,
)"
:key="index"
><span
style="
size="small"
type="primary"
><span
style="
width: 50px;
text-align: center;
overflow: hidden;
......@@ -2070,15 +2104,16 @@
text-overflow: ellipsis;
display: inline-block;
"
:title="item.name || ''"
>{{ item.name || '' }}</span
></el-tag
:title="item.name || ''"
>{{ item.name || '' }}</span
></el-tag
>
<el-tag
v-if="cardItem.customTagList?.slice(3)?.length"
size="small"
type="primary"
v-if="cardItem.customTagList?.slice(3)?.length"
>+{{ cardItem.customTagList.slice(3).length }}</el-tag
>+{{ cardItem.customTagList.slice(3).length }}
</el-tag
>
</div>
</el-tooltip>
......@@ -2163,7 +2198,7 @@
:title="`商品名称:${cardItem?.productName || ''}`"
>
<span class="grid-item-value"
>{{ cardItem?.productName }}
>{{ cardItem?.productName }}
</span>
</div>
<div
......@@ -2306,7 +2341,7 @@
</div>
<div v-if="cardItem.isReplenishment" class="grid-item">
<el-tag size="small" type="danger" effect="dark"
>补胚中
>补胚中
</el-tag>
</div>
</div>
......@@ -2319,10 +2354,10 @@
<div class="pagination">
<div class="total">
<span
>已选择
>已选择
<span style="color: red">{{
selection.length || cardSelection.length
}}</span>
selection.length || cardSelection.length
}}</span>
条数据</span
>
</div>
......@@ -2339,15 +2374,15 @@
></ElPagination>
<div class="pageSize">
<span
>自定义条数
>自定义条数
<span
><el-input
v-model="pageSize"
type="number"
style="width: 100px"
clearable
@blur="inputBlur"
></el-input
><el-input
v-model="pageSize"
type="number"
style="width: 100px"
clearable
@blur="inputBlur"
></el-input
></span>
/</span
>
......@@ -2459,7 +2494,7 @@
link
style="margin-left: 10px"
@click="changeChinaTime('Asia/Shanghai')"
>北京时间
>北京时间
</el-button>
<el-button
:type="timeType === 'America/New_York' ? 'primary' : ''"
......@@ -2467,7 +2502,7 @@
link
style="margin-left: 10px"
@click="changeChinaTime('America/New_York')"
>新泽西时间
>新泽西时间
</el-button>
<el-button
:type="timeType === 'America/Los_Angeles' ? 'primary' : ''"
......@@ -2475,7 +2510,7 @@
link
style="margin-left: 10px"
@click="changeChinaTime('America/Los_Angeles')"
>洛杉矶时间
>洛杉矶时间
</el-button>
</div>
</div>
......@@ -2639,8 +2674,8 @@
v-model:form="currentRow"
v-model:visible="updateAddVisible"
:country-list="countryList"
@success="search"
:type="updateAddressType"
@success="search"
></UpdateAddress>
<ElDialog
v-model="exceptionDialogVisible"
......@@ -2774,7 +2809,7 @@
:loading="exportLoading"
type="primary"
@click="submitExportForm"
>确认</el-button
>确认</el-button
>
</span>
</template>
......@@ -2842,7 +2877,8 @@
typesettingVisible = false
}
"
>取消</el-button
>取消
</el-button
>
<el-button type="primary" @click="submitTypesetting">确认</el-button>
</template>
......@@ -2903,6 +2939,7 @@ import {
} from '@element-plus/icons-vue'
import {
getCardOrderList,
uploadPRNFile,
getOrderList,
getOrderTabData,
confirmOrderApi,
......@@ -2964,7 +3001,7 @@ import {
getCustomTagListApi,
getLogisticsWayApi,
printNormalPickPdfApi,
reissueOrderApi
reissueOrderApi, updatePRNDownloadStatus,
} from '@/api/podUsOrder'
import { BaseRespData } from '@/types/api'
......@@ -2997,6 +3034,7 @@ import { showConfirm } from '@/utils/ui'
import {
DocumentCopy,
EditPen,
Loading,
CircleCheckFilled,
} from '@element-plus/icons-vue'
import { Column, ElFormItem } from 'element-plus'
......@@ -3025,7 +3063,7 @@ import {
declare global {
interface Window {
ActiveXObject: {
new (type: string): XMLHttpRequest
new(type: string): XMLHttpRequest
}
VBS_BinaryToArray: {
(data: unknown): { toArray(): number[] }
......@@ -3134,10 +3172,10 @@ const submitExportForm = async () => {
...params,
...(resourceType === 2
? {
...searchForm.value,
startTime: timeRange.value?.[0] || null,
endTime: timeRange.value?.[1] || null,
}
...searchForm.value,
startTime: timeRange.value?.[0] || null,
endTime: timeRange.value?.[1] || null,
}
: {}),
})
ElMessage.success('请求成功,请稍后到右上角[我的下载]中查看')
......@@ -3552,6 +3590,12 @@ const tableColumns = computed(() => {
prop: 'automaticComposing',
slot: 'automaticComposing',
align: 'center',
}, {
label: 'PRN文件',
width: 300,
prop: 'automaticComposing',
slot: 'prn',
align: 'right',
},
{
label: '排版参数',
......@@ -3563,7 +3607,7 @@ const tableColumns = computed(() => {
{
label: '操作',
slot: 'operate',
width: 350,
width: 300,
align: 'center',
fixed: 'right',
prop: 'operate',
......@@ -3789,16 +3833,16 @@ const loadTabData = async () => {
// 发货拦截数量
const shipmentCount = (statusRes.data as InterceptStateGroupData)?.shipment
? Object.values(
(statusRes.data as InterceptStateGroupData).shipment,
).reduce((sum: number, value: unknown) => sum + (Number(value) || 0), 0)
(statusRes.data as InterceptStateGroupData).shipment,
).reduce((sum: number, value: unknown) => sum + (Number(value) || 0), 0)
: 0
// 生产拦截数量
const productionCount = (statusRes.data as InterceptStateGroupData)
?.production
? Object.values(
(statusRes.data as InterceptStateGroupData).production,
).reduce((sum: number, value: unknown) => sum + (Number(value) || 0), 0)
(statusRes.data as InterceptStateGroupData).production,
).reduce((sum: number, value: unknown) => sum + (Number(value) || 0), 0)
: 0
tabsNav.value.splice(completeIndex + 1, 0, {
......@@ -3967,7 +4011,10 @@ watch(
},
{ deep: true, immediate: true }, // 添加immediate确保初始化时执行
)
const fileName = (row: PodUsOrderListData) => {
if (!row.prnUrl) return ''
return row.prnUrl.split('/')[row.prnUrl.split('/').length - 1]
}
const search = () => {
selection.value = []
cardSelection.value = []
......@@ -4145,6 +4192,37 @@ const productionClientVisible = ref(false)
// productionClientVisible.value = true
// }
const downloadRowProFile = async (row: PodUsOrderListData) => {
const url =
`https://factory.jomalls.com/upload/factory` + row.prnUrl
window.open(url, '_blank')
await updatePRNDownloadStatus(
row.id,
)
search()
}
const uploadFile = (row: PodUsOrderListData) => {
const input = document.createElement('input')
input.style.display = 'none'
input.type = 'file'
input.multiple = false
input?.click()
row.isUpload = true
input.onchange = async function() {
try {
if (input.files && input.files.length) {
const fm = new FormData()
fm.append('file', input.files?.[0])
const res = await uploadPRNFile(row.id, fm)
row.prnUrl = res.message
}
} finally {
row.isUpload = false
}
}
}
const downloadTif = async (type: string, templateWidth: number) => {
if (!cardSelection.value.length) {
return ElMessage.warning('请选择数据')
......@@ -4189,8 +4267,8 @@ const downloadTif = async (type: string, templateWidth: number) => {
a.href = window.URL.createObjectURL(blob)
a.target = '_blank'
a.download = (res.message as string).split('/')[
(res.message as string).split('/').length - 1
]
(res.message as string).split('/').length - 1
]
a.click()
pngDownloadLoading.value = false
})
......@@ -5200,8 +5278,8 @@ const rejectOrder = async (type: string) => {
orderStatus: type,
productList: selection.value.length
? selection.value.flatMap(
(item: PodUsOrderListData) => item.productList || [],
)
(item: PodUsOrderListData) => item.productList || [],
)
: cardSelection.value,
reasonStr: value,
})
......@@ -6188,8 +6266,8 @@ const interceptChange = async (status: boolean) => {
? 1
: 3
: interceptCurrent.value === 1
? 2
: 4
? 2
: 4
try {
const res = await interceptUpdateApi({
orderIds: selection.value.map((item) => item.id),
......@@ -6412,11 +6490,11 @@ const printNormal = async () => {
selection.value.forEach((s) => {
s.productList &&
s.productList.forEach((p) => {
if (p.productMark === 'normal' || p.productMark === 'custom_normal') {
arr.push(p.id)
}
})
s.productList.forEach((p) => {
if (p.productMark === 'normal' || p.productMark === 'custom_normal') {
arr.push(p.id)
}
})
})
console.log(3661, arr)
......@@ -6562,6 +6640,7 @@ const printNormal = async () => {
background: rgb(255 243 205);
color: rgb(91, 99, 18);
}
.empty {
height: 100%;
display: flex;
......@@ -6765,13 +6844,16 @@ const printNormal = async () => {
color: white;
font-weight: bold;
}
.triangle-container-wrap {
position: absolute;
top: 0;
right: 0;
}
.triangle-container {
position: relative;
.triangle-marker {
width: 0;
height: 0;
......@@ -6779,6 +6861,7 @@ const printNormal = async () => {
border-right: 18px solid #e74c3c;
border-top: 18px solid #e74c3c;
}
.content {
position: absolute;
top: 0;
......@@ -6790,13 +6873,16 @@ const printNormal = async () => {
font-size: 12px;
}
}
.triangle-container-wrap {
position: absolute;
top: 0;
right: 0;
}
.triangle-container {
position: relative;
.triangle-marker {
width: 0;
height: 0;
......@@ -6804,6 +6890,7 @@ const printNormal = async () => {
border-right: 18px solid #e74c3c;
border-top: 18px solid #e74c3c;
}
.content {
position: absolute;
top: 0;
......@@ -6839,8 +6926,8 @@ const printNormal = async () => {
}
.el-timeline
> .el-timeline-item:first-child
.el-timeline-item__timestamp.is-top {
> .el-timeline-item:first-child
.el-timeline-item__timestamp.is-top {
color: #409eff;
}
......@@ -6849,6 +6936,7 @@ const printNormal = async () => {
justify-content: space-between;
align-items: center;
}
.tabs-node-quantity {
position: relative;
color: red;
......@@ -6856,6 +6944,7 @@ const printNormal = async () => {
top: -10px;
right: 0px;
}
.operate-item {
position: relative;
}
......@@ -6867,4 +6956,12 @@ const printNormal = async () => {
top: 30%;
transform: translateY(-50%);
}
.flex-1 {
flex: 1;
flex-shrink: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
import { defineComponent, ref } from 'vue'
import { ElDialog } from 'element-plus'
export default defineComponent({
name: 'CustomizeForm',
props: {
modelValue: {
type: Boolean,
default: false,
},
title: {
type: String,
default: '',
},
dialogWidth: {
type: String,
default: '600px',
},
},
emits: ['update:modelValue', 'close'],
setup(props, { emit, attrs, slots }) {
const formRef = ref<InstanceType<typeof ElDialog> | null>(null)
const isShow = ref(false)
watch(
() => props.modelValue,
(val) => {
isShow.value = val
},
{ immediate: true },
)
return () => {
return (
<div>
<ElDialog
ref={formRef}
v-model={isShow.value}
title={props.title}
width={props.dialogWidth}
onClose={() => {
emit('close')
}}
destroy-on-close={true}
close-on-click-modal={false}
{...attrs}
>
<div class="dialog-form">
{slots.default?.()}
{slots.footer?.()}
</div>
</ElDialog>
</div>
)
}
},
})
<template>
<div class="user-page flex-column card h-100 overflow-hidden">
<div class="header-filter-form">
<ElButton type="success" @click="showDialog">新增供应商</ElButton>
<ElButton type="danger" @click="deleteFn">删除</ElButton>
</div>
<div class="user-content flex-1 flex-column overflow-hidden">
<div class="user-list flex-1 overflow-hidden" v-loading="loading">
<CustomizeTable
border
v-model="tableData"
:config="tableConfig"
align="center"
@getCheckboxRecords="handleCheckboxRecords"
></CustomizeTable>
</div>
<ElPagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[100, 200, 300, 400, 500]"
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
style="margin: 10px auto 0; text-align: right"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></ElPagination>
</div>
</div>
<Dialog
:title="editForm['id'] ? '编辑供应商' : '新增供应商'"
v-model="dialogVisible"
@close="cancelFn"
width="75%"
>
<CustomizeForm
v-loading="editLoading"
ref="editFormRef"
v-model="editForm"
:config="formConfig"
formItemWidth="100%"
:labelWidth="100"
>
</CustomizeForm>
<template #footer>
<div style="text-align: center">
<ElButton @click="cancelFn">取消</ElButton>
<ElButton type="primary" @click="saveSupplierFn">保存</ElButton>
</div>
</template>
</Dialog>
<Dialog
title="管理供应价格"
v-model="priceDialogVisible"
width="65%"
v-loading="priceLoading"
@close="cancelPiceFn"
teleported
>
<div style="display: flex; margin-bottom: 10px">
<div style="display: flex; align-items: center; gap: 20px">
<div><span style="color: red">*</span> 结算币种</div>
<el-select
style="width: 300px; flex: 1"
v-model="currentGoods.currencyCode"
@change="
(v:string) => {
currentGoods.currencyName =
currencyOptions?.find((el) => v == el.currencyCode)
?.currencyName || ''
console.log(73,currentGoods.currencyName);
}
"
>
<el-option
v-for="(item, index) in currencyOptions"
:key="index"
:label="`${item.currencyName}(${item.currencyCode})`"
:value="item.currencyCode"
>
</el-option>
</el-select>
</div>
</div>
<div
style="border-top: 1px solid #eee; margin-bottom: 10px"
v-if="showColorList.length"
>
<div style="font-size: 20px; font-weight: bold; margin: 10px 0">
颜色(Color)
</div>
<div class="flex" style="flex-wrap: wrap; gap: 5px">
<el-tag
:title="`${item.cnname}(${item.enname})`"
:color="item.bgColor"
v-for="(item, index) in showColorList"
:key="index"
:style="{ color: item.fontColor }"
class="tabBox"
:class="{ active: colorIndex === item.code }"
@click="optionSelection(item, 'color')"
>{{ item.cnname }}({{ item.enname }})</el-tag
>
</div>
</div>
<div
style="border-top: 1px solid #eee; margin-bottom: 10px"
v-if="showSizeList.length"
>
<div style="font-size: 20px; font-weight: bold; margin: 10px 0">
尺码(Size)
</div>
<div class="flex" style="flex-wrap: wrap; gap: 5px">
<el-tag
class="tabBox"
color="#ffff87"
style="color: #333"
effect="dark"
type="info"
v-for="(item, index) in showSizeList"
:key="index"
:class="{ active: sizeIndex === item.code }"
@click="optionSelection(item, 'size')"
>
{{ item.cnname }}</el-tag
>
</div>
</div>
<div
style="
display: flex;
justify-content: end;
border-top: 1px solid #eee;
"
>
<div style="margin: 10px 0">
<el-input
placeholder="请输入供应价格"
style="width: 200px; margin-right: 10px"
size="small"
v-model="supplierPirce"
clearable
></el-input
><ElButton type="primary" @click="updatePrices" size="small"
>批量更新供应价格</ElButton
>
<span style="color: #f56c6c; vertical-align: middle"
>(请注意!该操作会覆盖已有供应价格)</span
>
</div>
</div>
<CustomizeTable
ref="tableRef"
border
style="margin-bottom: 20px"
v-model="pricetableData"
:config="priceTableConfig"
align="center"
height="500px"
@getCheckboxRecords="selectPirce"
></CustomizeTable>
<template #footer>
<div style="text-align: center">
<ElButton @click="cancelPiceFn">取消</ElButton>
<ElButton type="primary" @click="savePiceFn">保存</ElButton>
</div>
</template>
</Dialog>
</template>
<script setup lang="tsx">
defineOptions({
name: 'DeclarationRule',
})
import {
getSupplierListApi,
deleteSupplierApi,
getSupplierDetailApi,
getPropertyByCateIdApi,
getProductInfoBySpuApi,
getBaseCurrencyInfoApi,
addSupplierApi,
updateSupplierApi,
} from '@/api/supplier/supplierManagement.ts'
import Dialog from './components/dialog.tsx'
import CustomizeForm from '@/components/CustomizeForm.tsx'
import CustomizeTable from '@/components/VxeTable.tsx'
import { IFormConfig } from '@/components/CustomizeForm.tsx'
import usePageList from '@/utils/hooks/usePageList'
import { useValue } from '@/utils/hooks/useValue'
import { showConfirm } from '@/utils/ui'
import { debounce, cloneDeep } from 'lodash-es'
import { Edit, CirclePlus } from '@element-plus/icons-vue'
import { TableColumn } from '@/components/VxeTable'
import {
IgoodsType,
IsupplierType,
IcurrencyCode,
IcolorType,
IsizeType,
IPropertyResponseItem,
Iprice,
} from './types/index.ts'
const [editForm, resetEditForm] = useValue<IsupplierType>({})
const {
loading,
currentPage,
pageSize,
total,
data: tableData,
refresh: search,
onCurrentPageChange: handleCurrentChange,
onPageSizeChange: handleSizeChange,
} = usePageList({
query: (page, pageSize) =>
getSupplierListApi({
pageSize: pageSize,
currentPage: page,
}).then(({ data }) => {
console.log(130, data)
return data
}),
})
const dialogVisible = ref(false)
const editLoading = ref(false)
const goodsTableData = ref([])
const supplierTableData = ref<IgoodsType[]>([])
const priceDialogVisible = ref(false)
const pricetableData = ref<Iprice[]>([])
const editFormRef = ref<InstanceType<typeof CustomizeForm> | null>(null)
const selection = ref<Iprice[]>([])
interface IOption {
[key: string]: unknown
}
//表单
const formConfig = computed<IFormConfig[]>(() => [
{
prop: 'supplierName',
type: 'input',
label: '供应商名称',
attrs: {
placeholder: '请输入供应商名称',
width: '33.333%',
},
rules: [
{
required: true,
message: '请输入供应商名称',
},
],
},
{
prop: 'contacts',
type: 'input',
label: '联系人',
attrs: {
placeholder: '请输入联系人',
width: '33.333%',
},
rules: [
{
required: true,
message: '请输入联系人',
},
],
},
{
prop: 'contactsNumber',
type: 'input',
label: '联系电话',
attrs: {
placeholder: '请输入联系电话',
width: '33.333%',
},
rules: [
{
required: true,
message: '请输入联系电话',
},
],
},
{
prop: 'address',
type: 'input',
label: '地址',
attrs: {
placeholder: '请输入地址',
},
rules: [
{
required: true,
message: '请输入地址',
},
],
},
{
prop: 'remark',
type: 'input',
label: '备注',
attrs: {
placeholder: '请输入备注',
type: 'textarea',
rows: 4,
},
},
{
prop: 'table',
title: true,
type: '',
label: '',
render: () => {
return (
<div style={{ width: '100%' }}>
<div class="flex" style={{ justifyContent: 'space-between' }}>
<div
style={{
display: 'flex',
flexWrap: 'nowrap',
alignItems: 'center',
gap: '20px',
marginBottom: '20px',
}}
>
<div>管理供应商品</div>
<el-input
v-model={searchSupplierGoods.value}
clearable
placeholder="九猫商品SPU"
style={{ width: '200px' }}
></el-input>
<el-popover
placement="bottom"
trigger="click"
width="750"
disabled={isShowSearch.value}
v-slots={{
reference: () => (
<el-button
type="primary"
onclick={() => searchSupplyGoodsFn()}
>
查询
</el-button>
),
}}
>
<CustomizeTable
v-loading={goodsLoading.value}
isShowCheckBox={false}
modelValue={goodsTableData.value}
config={searchTableConfig.value}
{...{ height: '400px', align: 'center', border: true }}
style={{ marginBottom: '20px' }}
></CustomizeTable>
</el-popover>
</div>
<div>
<el-button type="danger" onclick={() => deleteSupplyGoodsFn()}>
删除
</el-button>
</div>
</div>
<CustomizeTable
modelValue={supplierTableData.value}
config={formTableConfig.value}
{...{ height: '400px', align: 'center', border: true }}
style={{ marginBottom: '20px' }}
onGetCheckboxRecords={(v) => getSupplierItem(v)}
></CustomizeTable>
</div>
)
},
},
])
//列表表格
const tableConfig = ref<TableColumn[]>([
{
prop: 'supplierName',
label: '供应商名称',
},
{
prop: 'contacts',
label: '联系人',
},
{
prop: 'contactsNumber',
label: '联系电话',
},
{
prop: 'address',
label: '地址',
},
{
prop: 'remark',
label: '备注',
},
{
prop: 'opeare',
label: '操作',
attrs: {
align: 'center',
},
render: {
default: ({ row }: { row: IsupplierType }) => (
<div>
<el-icon
size="24"
title="编辑"
color="#EF6C00"
style="cursor: pointer; vertical-align: middle"
onclick={() => editSupplier(row.id as string)}
>
<Edit />
</el-icon>
</div>
),
},
},
])
//表单表格
const formTableConfig = ref<TableColumn[]>([
{
prop: 'productName',
label: '商品名称',
},
{
prop: 'productNo',
label: '款号',
},
{
prop: 'productSpu',
label: '商品SPU',
},
{
prop: 'productImage',
label: '商品图片',
render: {
default: ({ row }: { row: IgoodsType }) => (
<div>
<el-image style="width: 50px; height: 50px" src={row.productImage} />
</div>
),
},
},
{
prop: 'currencyCode',
label: '币种',
},
{
prop: 'supplyPrice',
label: '供应价格',
render: {
default: ({ row }: { row: IgoodsType }) => (
<div>{getSupplyPrice(row)}</div>
),
},
},
{
prop: 'opeare',
label: '操作',
attrs: {
align: 'center',
},
render: {
default: ({ row }: { row: IgoodsType }) => (
<el-button type="primary" onclick={() => addPice(row)} size="small">
管理供应价格
</el-button>
),
},
},
])
//查询商品表格
const searchTableConfig = ref<TableColumn[]>([
{
prop: 'name',
label: '商品名称',
},
{
prop: 'productNo',
label: '款号',
},
{
prop: 'sku',
label: '商品SPU',
},
{
prop: 'imgUrl',
label: '商品图片',
render: {
default: ({ row }: { row: IgoodsType }) => (
<div>
<el-image style="width: 50px; height: 50px" src={row.imgUrl} />
</div>
),
},
},
{
prop: 'opeare',
label: '操作',
attrs: {
align: 'center',
width: '65px',
},
render: {
default: ({ row }: { row: IgoodsType }) => (
<div>
<el-icon
size="24"
title="新增"
color="#EF6C00"
style="cursor: pointer; vertical-align: middle"
onclick={() => addGoods(row)}
>
<CirclePlus />
</el-icon>
</div>
),
},
},
])
//管理供应价格表格
const priceTableConfig = ref<TableColumn[]>([
{
prop: 'productItemImage',
label: 'SKU图片',
render: {
default: ({ row }: { row: Iprice }) => (
<div>
<el-image
style="width: 50px; height: 50px"
src={row.productItemImage}
/>
</div>
),
},
},
{
prop: 'productItemSku',
label: 'SKU码',
},
{
prop: 'opeare',
label: '供应价格',
attrs: {
align: 'center',
width: '230px',
},
render: {
default: ({ row }: { row: Iprice }) => (
<div>
<el-input
modelValue={row.supplyPrice}
onInput={(v: string | number) => {
v = String(v).replace(/[^\d.]/g, '')
const parts = v.split('.')
if (parts.length > 2) v = parts[0] + '.' + parts.slice(1).join('')
row.supplyPrice = Number(v)
}}
clearable
placeholder="请输入更新价格"
style="width: 200px; margin-right: 20px"
size="small"
></el-input>
</div>
),
},
},
])
const searchSupplierGoods = ref('')
/**
* @description: 取消按钮
*/
function cancelFn() {
dialogVisible.value = false
searchSupplierGoods.value = ''
editFormRef.value?.resetFields()
resetEditForm()
}
/**
* @description: 取消供应价格按钮
*/
function cancelPiceFn() {
priceDialogVisible.value = false
}
//保存供应价格
function savePiceFn() {
if (!currentGoods.value.currencyCode) {
return ElMessage({
message: '请选择结算币种',
type: 'warning',
})
}
const hasEmptyPrice = pricetableData.value.some(
(item) =>
!item.supplyPrice ||
String(item.supplyPrice).trim() === '' ||
Number(item.supplyPrice) <= 0,
)
if (hasEmptyPrice) {
ElMessage.warning('供应价格为必填项,且必须大于0')
return
}
ElMessage({
message: '保存成功',
type: 'success',
})
supplierTableData.value.forEach((el) => {
if (el.id === currentGoods.value.id) {
el.currencyCode = currentGoods.value.currencyCode
el.currencyName = currentGoods.value.currencyName
el.supplierPriceItemList = [...pricetableData.value]
}
})
console.log('supplierTableData', supplierTableData.value)
cancelPiceFn()
}
/**
* @description: 检查数据
*/
async function checkData(): Promise<{
isValid: boolean
postData: IsupplierType
}> {
try {
// 1. 表单验证
await editFormRef.value?.validate()
// 2. 准备数据
const postData = { ...editForm.value }
const hasEmptyPriceItemList = supplierTableData.value?.some(
(product) => !product.supplierPriceItemList,
)
if (hasEmptyPriceItemList) {
ElMessage({
message: '请填写所有供应价格',
type: 'warning',
})
return { isValid: false, postData }
}
// 检查所有供应价格是否已填写
const hasEmptyPrice = supplierTableData.value?.some((product) =>
product.supplierPriceItemList?.some(
(item) => !item.supplyPrice && item.supplyPrice !== 0,
),
)
console.log(656, hasEmptyPrice)
// return
if (hasEmptyPrice) {
ElMessage({
message: '请填写所有供应价格',
type: 'warning',
})
return { isValid: false, postData }
}
if (supplierTableData.value?.length) {
postData.supplierProductInfoList = [...supplierTableData.value].map(
(el) => {
el.createTime && delete el.createTime
el.updateTime && delete el.updateTime
return {
...el,
}
},
)
}
// 所有验证通过
return { isValid: true, postData }
} catch (error) {
console.error('表单验证失败:', error)
// 表单验证失败时,仍然返回数据
const postData = { ...editForm.value }
return { isValid: false, postData }
}
}
/**
* @description: 保存按钮
*/
const saveSupplierFn = debounce(async () => {
const { isValid, postData } = await checkData()
if (isValid) {
try {
if (!postData.id) {
await addSupplierApi({
...postData,
})
} else {
await updateSupplierApi({
...postData,
})
}
ElMessage({
message: postData.id ? '更新成功' : '新增成功',
type: 'success',
})
cancelFn()
search()
} catch (e) {
return
}
}
}, 400)
/**
* @description: 获取选中数据
*/
function handleCheckboxRecords(value: never[]) {
selection.value = value
}
/**
* @description: 多选删除按钮
*/
async function deleteFn() {
if (!selection.value.length) {
return ElMessage({
message: '请选择供应商',
type: 'warning',
})
}
try {
await showConfirm('是否删除供应商', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
} catch {
return
}
try {
const ids = {
ids: selection.value.map((item: IOption) => item.id).join(','),
}
await deleteSupplierApi(ids)
ElMessage({
message: '删除成功',
type: 'success',
})
search()
} catch (e) {
search()
// showError(e)
}
}
/**
* @description: 新增供应商
*/
async function showDialog() {
dialogVisible.value = true
supplierTableData.value = []
supplierSeletctions.value = []
}
/**
* @description: 编辑供应商
*/
async function editSupplier(id: string | number) {
dialogVisible.value = true
editLoading.value = true
supplierTableData.value = []
supplierSeletctions.value = []
try {
const { data } = await getSupplierDetailApi(id)
editForm.value = data
supplierTableData.value = cloneDeep(
editForm.value.supplierProductInfoList || [],
).map((product) => {
const customMap = new Map(
product.customProductInfo?.customProductItemList?.map((item) => [
item.id,
item,
]) || [],
)
product.supplierPriceItemList?.forEach((priceItem) => {
const customItem = customMap.get(priceItem.productItemId)
if (customItem) {
priceItem.propertyCode1 = customItem.propertyCode1
priceItem.propertyCode2 = customItem.propertyCode2
}
})
return product
})
console.log(728, editForm.value)
} catch (error) {
console.log(error)
} finally {
editLoading.value = false
}
}
//查询spu
const goodsLoading = ref(false)
const isShowSearch = ref(false)
const supplierSeletctions = ref<IgoodsType[]>([])
async function searchSupplyGoodsFn() {
if (!searchSupplierGoods.value) {
ElMessage.warning('请输入SPU')
isShowSearch.value = true
return
} else {
isShowSearch.value = false
goodsLoading.value = true
try {
const { data } = await getProductInfoBySpuApi(searchSupplierGoods.value)
goodsTableData.value = [data]
console.log(604, data)
} catch (error) {
console.log(error)
} finally {
goodsLoading.value = false
}
}
}
//删除商品
function deleteSupplyGoodsFn() {
if (!supplierSeletctions.value.length) {
return ElMessage.warning(`请勾选商品`)
}
const deleteIds = supplierSeletctions.value.map((el) => el.productSpu)
supplierTableData.value = supplierTableData.value.filter(
(el) => !deleteIds.includes(el.productSpu),
)
}
function getSupplierItem(v: IgoodsType[]) {
supplierSeletctions.value = v
}
const priceLoading = ref(false)
const currencyOptions = ref<IcurrencyCode[]>([])
const colorList = ref<IcolorType[]>([])
const showColorList = ref<IcolorType[]>([])
const sizeList = ref<IsizeType[]>([])
const showSizeList = ref<IsizeType[]>([])
const currentGoods = ref()
//管理供应价格按钮
async function addPice(product: IgoodsType) {
supplierPirce.value = ''
colorIndex.value = null
sizeIndex.value = null
priceDialogVisible.value = true
priceLoading.value = true
currentGoods.value = cloneDeep(product)
console.log('product', currentGoods.value)
const tempArr = product.supplierPriceItemList || product.customProductItemList
pricetableData.value = cloneDeep(
tempArr?.map((el) => {
return {
...el,
productItemImage: el.productItemImage || el.image,
productItemSku: el.productItemSku || el.sku,
productItemId: el.id || '',
}
}) || [],
)
try {
const [currencyResponse, propertyResponse] = await Promise.all([
getBaseCurrencyInfoApi(),
getPropertyByCateIdApi(
(product.categoryId || product.customProductInfo?.categoryId) as string,
),
])
currencyOptions.value = currencyResponse.data || []
const propertyData: IPropertyResponseItem[] = propertyResponse.data || []
colorList.value = propertyData.find((el) => el.id == 1)?.valueList || []
sizeList.value = propertyData.find((el) => el.id == 2)?.valueList || []
if (!currentGoods.value.propertyList?.length) {
currentGoods.value.propertyList = product.customProductInfo?.propertyList
}
// 创建属性映射
const propertyMap = createPropertyMap(currentGoods.value.propertyList || [])
console.log(758, propertyMap)
// 过滤显示的颜色和尺寸
showColorList.value = filterPropertyList(
colorList.value,
propertyMap.get(1) || [],
)
showSizeList.value = filterPropertyList(
sizeList.value,
propertyMap.get(2) || [],
)
} catch (error) {
console.log(error)
} finally {
priceLoading.value = false
}
}
// 辅助函数:创建属性映射
function createPropertyMap(propertyList: any[]): Map<number, number[]> {
const map = new Map<number, number[]>()
propertyList.forEach((item) => {
if (item.propertyId && item.valueId) {
if (!map.has(item.propertyId)) {
map.set(item.propertyId, [])
}
map.get(item.propertyId)!.push(item.valueId)
}
})
return map
}
// 辅助函数:过滤属性列表
function filterPropertyList<T extends { id?: number | string }>(
sourceList: T[],
targetIds: number[],
): T[] {
return sourceList.filter((item) => {
const itemId = typeof item.id === 'string' ? parseInt(item.id) : item.id
return itemId !== undefined && targetIds.includes(itemId as number)
})
}
//新增商品
function addGoods(data: IgoodsType) {
data.productImage = data.productImage || data.imgUrl || ''
data.productSpu = data.productSpu || data.sku || ''
data.productName = data.productName || data.name || ''
data.currencyCode = ''
data.currencyName = ''
data.productId = data.id || undefined
const idSet = new Set(supplierTableData.value.map((item) => item.productSpu))
if (idSet.has(data.productSpu)) {
ElMessage.warning(`商品已存在,请勿重复添加`)
return
}
supplierTableData.value.push(data)
ElMessage.success('商品添加成功')
}
const selectPirceList = ref<Iprice[]>([])
const supplierPirce = ref('')
function selectPirce(value: never[]) {
selectPirceList.value = value
}
//批量供应价格
function updatePrices() {
if (!supplierPirce.value) {
ElMessage.warning(`请输入供应价格`)
return
}
if (selectPirceList.value.length) {
selectPirceList.value.forEach((el) => {
el.supplyPrice = supplierPirce.value
})
} else {
ElMessage.warning(`请先勾选需要修改价格的商品`)
}
}
//获取颜色和尺寸
const colorIndex = ref()
const sizeIndex = ref()
const tableRef = ref()
const optionSelection = (row: IcolorType, type: 'color' | 'size') => {
updateSelectionIndex(row, type)
updateTableSelection()
}
// 更新选中索引的函数
const updateSelectionIndex = (row: IcolorType, type: 'color' | 'size') => {
if (type === 'color') {
colorIndex.value = colorIndex.value === row.code ? null : row.code
} else if (type === 'size') {
sizeIndex.value = sizeIndex.value === row.code ? null : row.code
}
}
// 更新表格选中状态的函数
const updateTableSelection = () => {
pricetableData.value.forEach((item) => {
tableRef.value.setCheckboxRow(item, false)
})
const rowsToSelect = getRowsToSelect()
rowsToSelect.forEach((item) => {
tableRef.value.setCheckboxRow(item, true)
})
console.log('rowsToSelect', rowsToSelect)
selection.value = [...(rowsToSelect || [])]
}
// 获取应该选中的行
const getRowsToSelect = () => {
return pricetableData.value.filter((item) => {
if (colorIndex.value && sizeIndex.value) {
return (
item.propertyCode1 === colorIndex.value &&
item.propertyCode2 === sizeIndex.value
)
}
if (colorIndex.value) {
return item.propertyCode1 === colorIndex.value
}
if (sizeIndex.value) {
return item.propertyCode2 === sizeIndex.value
}
return false
})
}
//获取供应价格区间
function getSupplyPrice(row: IgoodsType) {
let range = ''
const arr = row.supplierPriceItemList
if (arr?.length) {
const prices = arr
.map((item) => {
// 尝试转换为数字
const price = parseFloat(item.supplyPrice as string)
return isNaN(price) ? null : price
})
.filter((price) => price !== null) as number[]
if (prices.length === 0) {
range = '' // 或者根据需求返回默认值
}
// 计算最小值和最大值
const minPrice = Math.min(...prices)
const maxPrice = Math.max(...prices)
// 判断是否需要范围格式
if (minPrice === maxPrice) {
// 所有价格相同或只有一个价格
range = minPrice.toString()
} else {
// 价格有范围
range = `${minPrice}-${maxPrice}`
}
} else {
range = ''
}
row.supplyPriceRange = range as string
return range
}
</script>
<style lang="scss" scoped>
.header-filter-form {
margin-bottom: 20px;
:deep(.el-form-item) {
margin-right: 14px;
margin-bottom: 10px;
}
}
.user-operate-btn {
margin-bottom: 10px;
}
.dialog-footer {
text-align: center;
}
.tabBox {
cursor: pointer;
}
.active {
border: 2px solid rgb(0, 140, 255);
}
</style>
export interface IListPage {
pageSize: number | string
currentPage: number | string
}
export interface IgoodsType {
imgUrl?: string
productImage?: string
sku?: string
productSpu?: string
productNo?: string
id?: string
productId?: string
categoryId?: string
currencyCode?: string
currencyName?: string
name?: string
productName?: string
createTime?: string
updateTime?: string
customProductItemList?: Iprice[]
supplierPriceItemList?: Iprice[]
customProductInfo?: IgoodsType
propertyList?: []
supplyPriceRange?: string
}
export interface IsupplierType {
supplierName?: string
contacts?: string
contactsNumber?: string
address?: string
id?: string
supplierProductInfoList?: IgoodsType[]
remark?: string
}
export interface IcurrencyCode {
currencyName?: string
currencyCode?: string
id?: string
}
export interface IcolorType {
bgColor?: string
code?: string
fontColor?: string
cnname?: string
enname?: string
id?: string | number
}
export interface IsizeType {
code?: string
cnname?: string
id?: string | number
}
export interface IPropertyResponseItem {
id: string | number
valueList: IcolorType[] | IsizeType[]
}
export interface Iprice {
productItemSku?: string
productItemImage?: string
sku?: string
id?: string
image?: string
supplyPrice?: string | number
propertyCode1?: string
propertyCode2?: string
productItemId?: string
}
export interface IListPage {
pageSize: number | string
currentPage: number | string
}
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