Commit c3d44811 by wuqian
parents cf880a48 1570ee52
......@@ -39,6 +39,7 @@ declare module 'vue' {
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
......
import { BasePaginationData, BaseRespData } from '@/types/api'
import axios from './axios'
import { LoginReq, LoginResp } from '@/types/api/auth'
import { UserEditForm, userData, userSearchForm } from '@/types/api/user'
import {
UserEditForm,
userData,
customSearchForm,
userSearchForm,
customData,
} from '@/types/api/user'
import { NameSpaceList } from '@/types/api/deliveryNote'
export function loginApi(data: LoginReq) {
......@@ -50,7 +56,38 @@ export function deleteUserApi(ids: string) {
params: { ids: ids },
})
}
export function getRelList(
data: customSearchForm,
currentPage: number,
pageSize: number,
) {
return axios.post<never, BasePaginationData<customData>>(
'/dbDiyUser/getRelList',
{
...data,
currentPage,
pageSize,
},
)
}
export function getBySkuApi(sku: string) {
return axios.get<never, BaseRespData<customSearchForm>>(
'/dbDiyUser/getBySku',
{
params: { sku: sku },
},
)
}
export function addRelApi(userId?: number | string) {
return axios.get<never, BaseRespData<never>>('/dbDiyUser/addRel', {
params: { userId: userId },
})
}
export function removeRelApi(relId?: number) {
return axios.get<never, BaseRespData<never>>('/dbDiyUser/removeRel', {
params: { relId: relId },
})
}
export function getDetailsByIdApi(id: number) {
return axios.get<never, BaseRespData<UserEditForm>>(
'/factory/factoryUser/get',
......
......@@ -174,9 +174,17 @@ export function printPickingOrderApi(orderIds: number[]) {
)
}
export function stockOutCheckApi(orderIds: number[]) {
return axios.get<never, BaseRespData<number[]>>(
`factory/podJomallOrderUs/replenishVerify?ids=${orderIds.join(',')}`,
)
return axios.get<
never,
BaseRespData<
{
id: number
status: boolean
message?: string
factoryOrderNumber?: string
}[]
>
>(`factory/podJomallOrderUs/replenishVerify?ids=${orderIds.join(',')}`)
}
export function toBePickingApi(orderIds: number[]) {
return axios.get<never, BaseRespData<never>>(
......@@ -326,16 +334,16 @@ export function createLogisticsOrderApi(params: {
// 创建物流
export function uploadExpressSheet(params: {
trackingNumber:string
trackingNumber: string
file: File
}) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrderUs/uploadExpressSheet',
params,
)
}// 创建物流
} // 创建物流
export function updateSelfLogistics(params: {
trackingNumber:string
trackingNumber: string
expressSheet: string
processNumber: string
id?: string
......@@ -347,9 +355,9 @@ export function updateSelfLogistics(params: {
}
// 更改物流
export function composingDesignImages(data: number[]) {
export function composingDesignImages(data: number[],type:string) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrderUs/composingDesignImages',
`factory/podJomallOrderUs/composingDesignImages?type=${type}`,
data,
)
}
......@@ -362,6 +370,15 @@ export function updateLogisticsToPickingApi(params: { ids: string }) {
},
)
}
// 转至待排单
export function updateLogisticsToArrangeApi(params: { ids: string }) {
return axios.get<never, BaseRespData<never>>(
`factory/podJomallOrderUs/updateLogisticsToArrange`,
{
params,
},
)
}
//创建物流订单
export function createLogisticsOrdersApi(orderIds: (string | number)[]) {
return axios.post<never, BaseRespData<never>>(
......@@ -411,3 +428,18 @@ export function toOutOfStockApi(ids: number[]) {
ids,
)
}
// 排单完成
export function arrangeFinishApi(ids: number[]) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderProductUs/arrangeFinish`,
ids,
)
}
// 获取工艺
export function getListCraftApi() {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderProductUs/listCraft`,
)
}
......@@ -10,7 +10,7 @@
mode="horizontal"
background-color="#001529"
text-color="#fff"
style="border-bottom: none;"
style="border-bottom: none"
:default-active="defaultActive"
router
>
......@@ -178,7 +178,12 @@ import userUserStore from '@/store/user'
import type { FormRules } from 'element-plus'
import { useValue } from '@/utils/hooks/useValue'
import { changePasswordApi } from '@/api/auth'
interface MenuItem {
index: string
id: number
label: string
children?: MenuItem[]
}
interface PasswordForm {
oldPwd: string
newPwd: string
......@@ -409,6 +414,28 @@ watch(activeTab, (newTab) => {
watch(tabs, checkScrollArrows)
// 初始化时确保活动标签可见
onMounted(() => {
let showCustomerManagement = false
const userJson = localStorage.getItem('user')
if (userJson) {
try {
const user = JSON.parse(userJson)
if (user && user.factory && user.factory.type === 2) {
showCustomerManagement = true
}
} catch (e) {
// ignore
}
}
if (!showCustomerManagement) {
const systemSettingsMenu = menuList.find(
(item: MenuItem) => item.label === '系统设置',
)
if (systemSettingsMenu && systemSettingsMenu.children) {
systemSettingsMenu.children = systemSettingsMenu.children.filter(
(child: MenuItem) => child.index !== '/system/customers',
)
}
}
// 初始检查
checkScrollArrows()
......
......@@ -29,6 +29,7 @@ import WarehousePosition from '@/views/warehouse/position.vue'
import receiptDoc from '@/views/warehouse/receiptDoc.vue'
import issueDoc from '@/views/warehouse/issueDoc.vue'
import ExternalAuthorisationPage from '@/views/system/externalAuthorisationPage.vue'
import CustomersPage from '@/views/system/CustomersPage.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
......@@ -94,11 +95,18 @@ const router = createRouter({
component: UserPage,
},
{
path:'/system/external-authorisation',
path: '/system/external-authorisation',
meta: {
title:'外部授权'
title: '外部授权',
},
component: ExternalAuthorisationPage
component: ExternalAuthorisationPage,
},
{
path: '/system/customers',
meta: {
title: '客户管理',
},
component: CustomersPage,
},
{
path: '/system/delivery-note',
......@@ -134,7 +142,8 @@ const router = createRouter({
title: '物流方式',
},
component: () => import('@/views/logistics/logisticsMethod.vue'),
},{
},
{
path: '/logistics/logisticsCompany',
meta: {
title: '物流公司',
......@@ -176,7 +185,7 @@ const router = createRouter({
},
component: () => import('@/views/logistics/logisticsCalculate.vue'),
},
{
{
path: '/logistics/sortingConfiguration',
meta: {
title: '分拣配置',
......
......@@ -175,6 +175,11 @@ const menu: MenuItem[] = [
id: 5,
label: '外部授权',
},
{
index: '/system/customers',
id: 6,
label: '客户管理',
},
],
},
......@@ -191,5 +196,4 @@ const menu: MenuItem[] = [
// ]
// },
]
export default menu
......@@ -15,6 +15,7 @@ export interface SearchForm {
factorySubOrderNumber: string
status: string
customizedQuantity: string
multi: boolean | null
startTime: string | null
endTime: string | null
exceptionHandling: number | undefined
......@@ -22,7 +23,9 @@ export interface SearchForm {
productionClient: string
warehouseId: string | number
thirdSkuCode: string
supplierProductNo:string
supplierProductNo: string
batchArrangeNumber: string
craftCode: string
}
export interface PodUsOrderListData {
id: number
......@@ -109,6 +112,7 @@ export interface ProductList {
thirdSkuCode?: string | null
supplierProductNo?: string | null
replenishmentSumNum?: number | null
batchArrangeNumber?: string | null
}
export interface cardImages {
title: string
......@@ -179,3 +183,7 @@ export interface LogisticsFormData {
expressSheetUrl: string
expressSheet: File | null
}
export interface CraftListData {
craftName: string
craftCode: string
}
......@@ -20,3 +20,13 @@ export interface UserEditForm {
account: string
status: string | number
}
export interface customSearchForm {
sku?: string
userMark?: string
id?: number | string
}
export interface customData {
relId?: number
sku?: string
userMark?: string
}
......@@ -42,6 +42,7 @@
v-model="editForm"
:config="formConfig"
form-item-width="100%"
labelWidth="125"
>
</CustomizeForm>
......@@ -205,6 +206,7 @@ const formConfig = computed<IFormConfig[]>(() => [
},
],
},
{
prop: 'companyId',
type: 'select',
......@@ -223,6 +225,9 @@ const formConfig = computed<IFormConfig[]>(() => [
if (value.code === 'UINUIN') {
editFormRef.value?.refashConfig(['uinuinWarehouseId'])
editFormRef.value?.clearValidate()
} else if (value.code === 'YW') {
editFormRef.value?.refashConfig(['companyWarehouseCode'])
editFormRef.value?.clearValidate()
} else {
editFormRef.value?.refashConfig([])
editFormRef.value?.clearValidate()
......@@ -233,7 +238,7 @@ const formConfig = computed<IFormConfig[]>(() => [
rules: [
{
required: true,
message: '请选择仓库名称',
message: '请选择物流公司',
},
],
},
......@@ -255,28 +260,29 @@ const formConfig = computed<IFormConfig[]>(() => [
},
],
},
// {
// prop: 'ruleId',
// type: 'select',
// label: '申报规则',
// fixed: 'last',
// attrs: {
// placeholder: '请选择申报规则',
// label: 'name',
// value: 'id',
// options: [...(ruleNameList.value || [])],
// onChange: (value: { name: string; id: string | number }) => {
// editForm.value.ruleRef.ruleId = value.id
// editForm.value.ruleRef.ruleName = value.name
// },
// },
// rules: [
// {
// required: true,
// message: '请选择申报规则',
// },
// ],
// },
{
prop: 'companyWarehouseCode',
type: 'select',
label: '物流仓库编码',
isIncludeProp: true,
attrs: {
placeholder: '请选择物流仓库编码',
options: [
{ label: 'LAX01', value: 'LAX01' },
{ label: 'NJC01', value: 'NJC01' },
{ label: 'ORD01', value: 'ORD01' },
{ label: 'MIA01', value: 'MIA01' },
{ label: 'DFW01', value: 'DFW01' },
],
},
rules: [
{
required: true,
message: '请选择物流仓库编码',
},
],
},
{
prop: 'serviceCode',
type: 'input',
......@@ -599,11 +605,13 @@ async function editWay(item: LogisticsMethod) {
console.log(493, editForm.value)
dialogVisible.value = true
if (item.uinuinWarehouseId) {
nextTick(() => {
nextTick(() => {
if (item.uinuinWarehouseId) {
editFormRef.value?.refashConfig(['uinuinWarehouseId'])
})
}
} else if (item.companyWarehouseCode) {
editFormRef.value?.refashConfig(['companyWarehouseCode'])
}
})
} catch (e) {
console.log(e)
}
......
......@@ -263,7 +263,7 @@ async function getList(data?: {
editParams.value = {
zoneName: row.zoneName,
logistics: key,
codePrefix: e || '',
codePrefix: formatString(e) || '',
logisticsId: row[key].logisticsId,
}
}}
......@@ -315,7 +315,7 @@ function setCellStyle() {
const [cell, primaryCell] = ['.tableCell', '.primaryCell'].map((selector) =>
document.querySelectorAll(selector),
)
const getAncestor = (element: Element, level = 2) => {
const getAncestor = (element: Element, level = 3) => {
let current = element
while (level-- > 0 && current) {
current = current.parentElement as Element
......@@ -434,6 +434,18 @@ async function editClosed() {
editParams.value = {}
}
}
function formatString(input: string) {
// 1. 替换所有中文逗号为英文逗号
// 2. 移除所有空格
// 3. 将连续逗号替换为单个逗号
// 4. 去除首尾可能的逗号
return input
.replace(/,/g, ',') // 中文逗号转英文逗号
.replace(/\s+/g, '') // 移除所有空格
.replace(/,+/g, ',') // 连续逗号替换为单个逗号
.replace(/^,|,$/g, '') // 去除首尾逗号
}
</script>
<style lang="scss" scoped>
......@@ -451,4 +463,37 @@ async function editClosed() {
.dialog-footer {
text-align: center;
}
:deep() {
// .vxe-cell {
// padding: 15px 10px !important;
// }
.col--edit::after {
content: '双击修改';
display: none;
position: absolute;
top: 0;
z-index: 99;
left: 50%;
transform: translate(-50%);
// width: 85px;
// height: 20px;
font-size: 10px;
line-height: 1;
border-radius: 5px;
padding: 2px 5px;
opacity: 0.5;
background-color: black;
text-align: center; /* 使文本居中 */
color: white; /* 文本颜色 */
}
.col--edit:hover::after {
display: block;
}
.col--active:hover::after {
content: '单击其他单元格确认';
white-space: nowrap;
}
}
</style>
......@@ -13,6 +13,7 @@ export interface LogisticsMethod {
ruleId?: string | number
ruleList?: ruleRefObj[]
uinuinWarehouseId?: number | string | null
companyWarehouseCode?: number | string | null
}
export interface LogisticsMethodList {
......
......@@ -74,11 +74,10 @@ const resultDialog = ref(false)
const isIndeterminate = ref(false)
const checkAll = ref(false)
const selectedList = ref<IList[]>([])
let key = ''
// 显示弹窗
const showDialog = (type?: string) => {
console.log(type)
key = type || ''
resultDialog.value = true
selectedList.value = []
checkAll.value = false
......@@ -127,6 +126,7 @@ const copyAllCode = (field: string) => {
}
function closedFn() {
if (key === 'stockOut') return
emits('confirm', selectedList.value)
}
......
......@@ -30,21 +30,46 @@
>
</el-date-picker>
</ElFormItem>
<ElFormItem label="定制类型">
<ElFormItem label="类型">
<el-radio-group v-model="searchForm.customizedQuantity">
<el-radio-button label="single">单面</el-radio-button>
<el-radio-button label="multiple">多面</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem label="数量">
<el-radio-group v-model="searchForm.multi">
<el-radio-button :label="false">单件</el-radio-button>
<el-radio-button :label="true">多件</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem label="工艺">
<ElSelect
v-model="searchForm.customizedQuantity"
placeholder="定制类型"
v-model="searchForm.craftCode"
clearable
style="width: 100px"
filterable
placeholder="请输入工艺"
style="width: 150px"
>
<ElOption label="单面" value="single" />
<ElOption label="多面" value="multiple" />
<el-option
v-for="item in craftList"
:key="item.craftCode"
:label="item.craftName"
:value="item.craftCode"
></el-option>
</ElSelect>
</ElFormItem>
<ElFormItem label="库存SKU">
<ElInput
v-model.trim="searchForm.thirdSkuCode"
placeholder="库存SKU"
clearable
style="width: 150px"
></ElInput>
</ElFormItem>
<ElFormItem label="供应货号">
<ElInput
v-model="searchForm.supplierProductNo"
placeholder="生产单号"
placeholder="供应货号"
clearable
style="width: 150px"
/>
......@@ -65,6 +90,14 @@
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="批次号">
<ElInput
v-model="searchForm.batchArrangeNumber"
placeholder="批次号"
clearable
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="店铺单号">
<ElInput
v-model="searchForm.shopNumber"
......@@ -74,10 +107,6 @@
/>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" @click="search">查询</ElButton>
</ElFormItem>
<ElFormItem>
<ElPopover placement="bottom" width="600" trigger="click">
<ElForm
:model="searchForm"
......@@ -165,22 +194,14 @@
style="width: 150px"
></ElInput>
</ElFormItem>
<ElFormItem label="Base SKU">
<!-- <ElFormItem label="Base SKU">
<ElInput
v-model.trim="searchForm.baseSku"
placeholder=" Base SKU"
clearable
style="width: 150px"
></ElInput>
</ElFormItem>
<ElFormItem label="库存SKU">
<ElInput
v-model.trim="searchForm.thirdSkuCode"
placeholder="库存SKU"
clearable
style="width: 150px"
></ElInput>
</ElFormItem>
</ElFormItem> -->
<ElFormItem label="物流跟踪号">
<ElInput
v-model.trim="searchForm.logisticsTracking"
......@@ -207,12 +228,22 @@
</ElForm>
<template #reference>
<el-button type="warning" @click="searchVisible = !searchVisible">
<el-icon v-if="searchVisible"><CaretTop /></el-icon>
<el-icon v-else><CaretBottom /></el-icon>
<el-icon v-if="searchVisible">
<CaretTop />
</el-icon>
<el-icon v-else>
<CaretBottom />
</el-icon>
</el-button>
</template>
</ElPopover>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" @click="search">查询</ElButton>
</ElFormItem>
<ElFormItem>
<ElButton type="danger" @click="resetSearchForm">清空</ElButton>
</ElFormItem>
</ElForm>
</div>
<div class="header-filter-tab">
......@@ -296,11 +327,20 @@
<div class="operation-box mb-10">
<span v-if="status === 'PICKING'" class="item">
<ElButton
:loading="downloadLoading"
:loading="tifDownloadLoading"
type="warning"
@click="downloadTif('tiff')"
>
TIF排版
</ElButton>
</span>
<span v-if="status === 'PICKING'" class="item">
<ElButton
:loading="pngDownloadLoading"
type="warning"
@click="downloadTif"
@click="downloadTif('png')"
>
排版
PNG排版
</ElButton>
</span>
<span v-if="status === 'TO_BE_CONFIRMED'" class="item">
......@@ -393,7 +433,7 @@
</span>
<span v-if="status === 'CREATE_LOGISTICS'" class="item">
<ElButton type="warning" @click="logisticsToPicking">
转至待拣胚
转至待排单
</ElButton>
</span>
<span
......@@ -433,7 +473,9 @@
转至待创建物流
</ElButton>
</span>
<span v-if="status === 'TO_BE_ARRANGE'" class="item">
<ElButton type="warning" @click="arrangeFinish">排单完成</ElButton>
</span>
<span class="item">
<ElButton type="primary" @click="downloadMaterial">下载素材</ElButton>
</span>
......@@ -456,7 +498,8 @@
v-if="
status !== 'IN_PRODUCTION' &&
status !== 'PICKING' &&
status !== 'TO_BE_REPLENISHMENT'
status !== 'TO_BE_REPLENISHMENT' &&
status !== 'TO_BE_ARRANGE'
"
v-loading="loading"
element-loading-text="加载中..."
......@@ -466,7 +509,6 @@
<TableView
ref="tableRef"
:columns="tableColumns"
:stripe="true"
:serial-numberable="true"
:selectionable="true"
:paginated-data="tableData"
......@@ -601,8 +643,8 @@
>
<!-- <span class="goods-item-info-item-label">补胚状态:</span> -->
<el-tag size="small" effect="dark" type="danger"
>补胚中</el-tag
>
>补胚中
</el-tag>
</div>
</div>
<div class="goods-item-info">
......@@ -636,7 +678,8 @@
status === 'EXCEPTION_ORDER' ||
status === 'PICKING' ||
status === 'TO_BE_CONFIRMED' ||
status === 'STOCK_OUT'
status === 'STOCK_OUT' ||
status === 'CREATE_LOGISTICS'
? '数量:'
: '已生产数量:'
}}</span>
......@@ -645,7 +688,8 @@
status === 'EXCEPTION_ORDER' ||
status === 'PICKING' ||
status === 'TO_BE_CONFIRMED' ||
status === 'STOCK_OUT'
status === 'STOCK_OUT' ||
status === 'CREATE_LOGISTICS'
? item.num
: item.passNum
}}
......@@ -668,8 +712,8 @@
size="small"
type="success"
@click="applyForReplenishment(item)"
>申请补胚</el-button
>
>申请补胚
</el-button>
<!-- f -->
</div>
<div class="goods-item-info-item">
......@@ -1043,7 +1087,9 @@
<div
:style="{
visibility:
status === 'IN_PRODUCTION' || status === 'PICKING'
status === 'IN_PRODUCTION' ||
status === 'PICKING' ||
status === 'TO_BE_ARRANGE'
? 'visible'
: 'hidden',
}"
......@@ -1064,18 +1110,18 @@
{{ cardItem?.baseSku }}
</span>
</div>
<div class="grid-item">
<div v-if="status !== 'TO_BE_ARRANGE'" class="grid-item">
<span class="grid-item-label">补胚数量:</span>
<span class="grid-item-value">
{{ cardItem?.replenishmentNum || 0 }}
</span>
</div>
<div class="grid-item">
<!-- <div class="grid-item">
<span title="Variant SKU" class="grid-item-value">
{{ cardItem?.variantSku }}
</span>
</div>
</div> -->
<div class="grid-item" title="工艺">
<span class="grid-item-label">工艺:</span>
<span class="grid-item-value">
......@@ -1089,21 +1135,30 @@
</div>
<div class="grid-item">
<span class="grid-item-label">供应货号:</span>
<span title="供应货号" class="grid-item-value">
<span
:title="`供应货号: ${cardItem?.supplierProductNo}`"
class="grid-item-value"
>
{{ cardItem?.supplierProductNo }}
</span>
</div>
<div class="grid-item" title="店铺单号">
<span class="grid-item-value">
<span
class="grid-item-value"
@click="copy(cardItem?.shopNumber || '')"
>
{{ cardItem?.shopNumber }}
</span>
</div>
<div class="grid-item" title="订单号">
<span class="grid-item-value">
<!-- <div class="grid-item" title="订单号">
<span
class="grid-item-value"
@click="copy(cardItem?.factoryOrderNumber || '')"
>
{{ cardItem?.factoryOrderNumber }}
</span>
</div>
</div> -->
<div class="grid-item">
<span
......@@ -1116,10 +1171,22 @@
{{ cardItem?.thirdSubOrderNumber }}
</span>
</div>
<div
v-if="cardItem.batchArrangeNumber"
class="grid-item"
title="批次号"
>
<span
class="grid-item-value"
@click="copy(cardItem?.batchArrangeNumber || '')"
>
{{ cardItem?.batchArrangeNumber }}
</span>
</div>
<div v-if="cardItem.isReplenishment" class="grid-item">
<el-tag size="small" type="danger" effect="dark"
>补胚中</el-tag
>
>补胚中
</el-tag>
</div>
</div>
</template>
......@@ -1128,17 +1195,43 @@
</div>
<div v-else class="empty">暂无数据</div>
</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 class="pagination">
<div class="total">
<span
>已选择
<span style="color: red">{{
selection.length || cardSelection.length
}}</span>
条数据</span
>
</div>
<ElPagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[50, 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 class="pageSize">
<span
>自定义条数
<span
><el-input
v-model="pageSize"
type="number"
style="width: 100px"
clearable
@blur="inputBlur"
></el-input
></span>
/</span
>
</div>
</div>
</div>
</div>
<RightClickMenu
......@@ -1297,7 +1390,7 @@
<ResultInfo
ref="resultRefs"
:list="resultInfo"
@confirm="resultConfim"
@confirm="resultConfirm"
></ResultInfo>
<el-dialog
......@@ -1466,8 +1559,8 @@
<div v-if="logisticsForm.expressSheet" class="file">
<span>{{ logisticsForm.expressSheet.name }}</span>
<el-icon
@click="logisticsForm.expressSheet = null"
class="expressSheetClose"
@click="logisticsForm.expressSheet = null"
>
<Close></Close>
</el-icon>
......@@ -1516,7 +1609,8 @@ import {
composingDesignImages,
changeLogisticsApi,
createLogisticsOrderApi,
updateLogisticsToPickingApi,
// updateLogisticsToPickingApi,
updateLogisticsToArrangeApi,
createLogisticsOrdersApi,
syncReceiverAddress,
refreshAddressApi,
......@@ -1528,6 +1622,8 @@ import {
applyForReplenishmentApi,
replenishmentSuccessApi,
toOutOfStockApi,
arrangeFinishApi,
getListCraftApi,
} from '@/api/podUsOrder'
import { BaseRespData } from '@/types/api'
......@@ -1548,6 +1644,7 @@ import {
AddressInfo,
LogisticsData,
LogisticsFormData,
CraftListData,
} from '@/types/api/podUsOrder'
import usePageList from '@/utils/hooks/usePageList'
import { useValue } from '@/utils/hooks/useValue'
......@@ -1596,6 +1693,7 @@ const currentRow = ref<AddressInfo>({
})
const updateAddVisible = ref(false)
const initPageSize = ref(50)
const logisticsVisible = ref(false)
const logisticsFormRef = ref()
const logistics = {
......@@ -1607,7 +1705,8 @@ const logistics = {
const logisticsForm = ref<LogisticsFormData>(logistics)
const resultRefs = ref<InstanceType<typeof ResultInfo> | null>(null)
const confirmDialogShow = ref(false)
const downloadLoading = ref(false)
const tifDownloadLoading = ref(false)
const pngDownloadLoading = ref(false)
const isChangeWay = ref(false)
const confirmData = ref([])
const logisticsWayData = ref([])
......@@ -1616,7 +1715,7 @@ const confirmSelectionData = ref<LogisticsData[]>([])
const confirmRowData = ref<ProductList | null>(null)
const status = ref('TO_BE_CONFIRMED')
const detailData = ref({})
const [searchForm] = useValue<SearchForm>({
const [searchForm, resetSearchForm] = useValue<SearchForm>({
timeType: null,
shopNumber: '',
shipmentType: '',
......@@ -1628,6 +1727,7 @@ const [searchForm] = useValue<SearchForm>({
factorySubOrderNumber: '',
status: '',
customizedQuantity: '',
multi: null,
startTime: null,
endTime: null,
exceptionHandling: undefined,
......@@ -1635,7 +1735,9 @@ const [searchForm] = useValue<SearchForm>({
productionClient: '',
warehouseId: '',
thirdSkuCode: '',
supplierProductNo:''
supplierProductNo: '',
batchArrangeNumber: '',
craftCode: '',
})
const exceptionStatus = ref(1)
const userMarkList = ref<string[]>([])
......@@ -1742,7 +1844,7 @@ const tableColumns = computed(() => [
label: '商品',
prop: 'goods',
slot: 'goods',
minWidth: 800,
minWidth: 920,
},
{
label: '订单详情',
......@@ -1760,7 +1862,7 @@ const tableColumns = computed(() => [
{
label: '时间',
slot: 'time',
width: 300,
width: 180,
prop: 'time',
align: 'left',
},
......@@ -1796,8 +1898,8 @@ const rightClick = (e: MouseEvent) => {
const handleSelectionChange = (val: PodUsOrderListData[]) => {
selection.value = val
// 只在手动清空选择时,且当前没有补货成功的行时,才清除补货成功状态
if (val.length === 0 && stockOutSuccessIds.value.length === 0) {
// 当清空选择时,清除补货校验成功的状态
if (val.length === 0) {
stockOutSuccessIds.value = []
}
}
......@@ -1844,7 +1946,7 @@ const changeTab = (item: Tab) => {
selection.value = []
cardSelection.value = []
stockOutSuccessIds.value = []
search(true)
search()
}
const onCellStyle = ({ column }: { column: Column }) => {
if (
......@@ -1887,15 +1989,17 @@ const {
pageSize,
total,
data: tableData,
refresh: search,
refresh,
onCurrentPageChange: handleCurrentChange,
onPageSizeChange: handleSizeChange,
} = usePageList({
initPageSize: initPageSize.value,
query: (page, pageSize) => {
if (
status.value !== 'IN_PRODUCTION' &&
status.value !== 'PICKING' &&
status.value !== 'TO_BE_REPLENISHMENT'
status.value !== 'TO_BE_REPLENISHMENT' &&
status.value !== 'TO_BE_ARRANGE'
) {
return getOrderList(
{
......@@ -1938,6 +2042,11 @@ const {
},
})
const search = () => {
selection.value = []
cardSelection.value = []
refresh()
}
const currentChange = (row: LogisticsData) => {
if (row) {
confirmSelectionData.value = [row]
......@@ -2106,20 +2215,59 @@ const productionClientVisible = ref(false)
// productionClientVisible.value = true
// }
const downloadTif = async () => {
const downloadTif = async (type: string) => {
if (!cardSelection.value.length) {
return ElMessage.warning('请选择数据')
}
downloadLoading.value = true
if (type === 'tiff') {
tifDownloadLoading.value = true
} else {
pngDownloadLoading.value = true
}
try {
const res = await composingDesignImages(
cardSelection.value.map((el) => el.id),
type,
)
window.open('https://ps.jomalls.com/tiff/' + res.message, '_blank')
downloadLoading.value = false
const url =
type === 'tiff'
? `https://ps.jomalls.com/tiff/` + res.message
: filePath + res.message
if (type === 'tiff') {
window.open(url, '_blank')
tifDownloadLoading.value = false
} else {
fetch(url)
.then((response) => {
// 确保响应是 OK
if (!response.ok) {
throw new Error('网络响应错误')
}
// 返回图片的二进制数据(Blob)
return response.blob()
})
.then((blob) => {
const a = document.createElement('a')
a.href = window.URL.createObjectURL(blob)
a.target = '_blank'
a.download = (res.message as string).split('/')[
(res.message as string).split('/').length - 1
]
a.click()
pngDownloadLoading.value = false
})
.catch((error) => {
console.error('下载图片时出错:', error)
pngDownloadLoading.value = false
})
}
} catch (e) {
console.log(e)
downloadLoading.value = false
if (type === 'tiff') {
tifDownloadLoading.value = false
} else {
pngDownloadLoading.value = false
}
}
}
......@@ -2348,7 +2496,12 @@ const changeExceptionOrder = async () => {
currentOrderIds.value = selection.value.map((item) => item.id)
exceptionDialogVisible.value = true
}
const inputBlur = () => {
if (!pageSize.value || Number(pageSize.value) <= 0) {
pageSize.value = initPageSize.value
}
search()
}
const handleExceptionConfirm = async () => {
try {
await exceptionFormRef.value.validate()
......@@ -2437,7 +2590,8 @@ const rightChange = async (code: string) => {
const flat =
status.value !== 'IN_PRODUCTION' &&
status.value !== 'PICKING' &&
status.value !== 'TO_BE_REPLENISHMENT'
status.value !== 'TO_BE_REPLENISHMENT' &&
status.value !== 'TO_BE_ARRANGE'
if (code === 'select-all') {
if (flat) {
tableRef.value?.toggleAllSelection()
......@@ -2518,6 +2672,44 @@ const downloadMaterial = async () => {
loading.close()
}
}
// 排单完成
const arrangeFinish = async () => {
const selectedIds = cardSelection.value.map((item) => item.id)
if (selectedIds.length === 0) {
return ElMessage({
message: '请选择订单',
type: 'warning',
offset: window.innerHeight / 2,
})
}
try {
await ElMessageBox.confirm('确定排单完成吗?', '提示', {
cancelButtonText: '取消',
confirmButtonText: '确认',
type: 'warning',
})
} catch {
return
}
const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try {
const res = await arrangeFinishApi(selectedIds)
if (res.code !== 200) return
ElMessage.success('操作成功')
search()
loadTabData()
} catch (e) {
console.error(e)
} finally {
loading.close()
}
}
const logList = ref<LogListData[]>([])
const logVisible = ref(false)
const operationLog = async (id: number, e: MouseEvent | null) => {
......@@ -2588,7 +2780,7 @@ const getOrderByIdApi = async (type: string) => {
return
}
let loading
const operation = operationMap[type]
if (operation) {
try {
......@@ -2600,7 +2792,7 @@ const getOrderByIdApi = async (type: string) => {
const ids = selection.value.map((el) => el.id)
const loading = ElLoading.service({
loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
......@@ -2617,17 +2809,18 @@ const getOrderByIdApi = async (type: string) => {
factoryOrderNumber?: string
message: string
}[]) || []
resultRefs.value?.showDialog()
resultRefs.value?.showDialog()
} else if (isString(res.data)) {
window.open(filePath + res.data)
}
} else {
ElMessage.error(res.message)
}
loading.close()
} catch (e) {
resultInfo.value = []
console.error(e)
} finally {
loading && loading.close()
}
} else {
ElMessage.warning('未知操作类型')
......@@ -2642,7 +2835,7 @@ const resultInfo = ref<
message: string
}[]
>([])
const resultConfim = () => {
const resultConfirm = () => {
search()
loadTabData()
}
......@@ -2741,14 +2934,27 @@ const stockOutCheck = async () => {
const res = await stockOutCheckApi(selectedIds)
if (res.code !== 200) return
const successIds = res.data || []
if (successIds.length === 0) {
ElMessage.warning('未补到货')
return
const successIds = res.data.filter((e) => e.status).map((ee) => ee.id) || []
// if (successIds.length === 0) {
// ElMessage.warning('未补到货')
// return
// }
resultInfo.value =
(res.data as {
id: string | number
status: boolean
factoryOrderNumber?: string
message: string
}[]) || []
if (
Array.isArray(res.data) &&
(res.data as { status: boolean }[]).some((item) => !item.status)
) {
resultRefs.value?.showDialog('stockOut')
} else {
ElMessage.success('操作成功')
}
ElMessage.success('操作成功')
const { success, others } = (
tableData.value as PodUsOrderListData[]
).reduce(
......@@ -2765,11 +2971,11 @@ const stockOutCheck = async () => {
)
tableData.value = [...success, ...others]
// 更新补货成功的行ID
stockOutSuccessIds.value = successIds
// 等待DOM更新后再设置选中状态
await nextTick()
// 更新补货成功的行ID
stockOutSuccessIds.value = successIds
// 清除所有选中状态
tableRef.value?.clearSelection()
// 选中补货成功的行
......@@ -2807,30 +3013,44 @@ const toBePicking = async () => {
try {
const res = await toBePickingApi(selection.value.map((item) => item.id))
if (res.code !== 200) return
resultInfo.value =
(res.data as {
id: string | number
status: boolean
factoryOrderNumber?: string
message: string
}[]) || []
if (
Array.isArray(res.data) &&
(res.data as { status: boolean }[]).some((item) => !item.status)
) {
resultRefs.value?.showDialog()
} else {
search()
loadTabData()
}
ElMessage.success('操作成功')
search()
loadTabData()
} catch (e) {
console.error(e)
} finally {
loading.close()
}
}
//转至待拣胚
//转至待排单
const logisticsToPicking = async () => {
if (selection.value.length === 0) {
return ElMessage.warning('请选择数据')
}
if (
selection.value.some(
(el) =>
el.trackingNumber == null || String(el.trackingNumber).trim() === '',
)
) {
return ElMessage.warning('选中数据中有未创建物流的订单,请先创建物流')
}
// if (
// selection.value.some(
// (el) =>
// el.trackingNumber == null || String(el.trackingNumber).trim() === '',
// )
// ) {
// return ElMessage.warning('选中数据中有未创建物流的订单,请先创建物流')
// }
try {
await ElMessageBox.confirm('确定转至待拣胚吗?', '提示', {
await ElMessageBox.confirm('确定转至待排单吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
......@@ -2844,7 +3064,7 @@ const logisticsToPicking = async () => {
background: 'rgba(0, 0, 0, 0.3)',
})
try {
const res = await updateLogisticsToPickingApi({
const res = await updateLogisticsToArrangeApi({
ids: selection.value.map((item) => item.id).join(','),
})
if (res.code !== 200) return
......@@ -3085,6 +3305,18 @@ const loadWarehouseList = async () => {
console.error(e)
}
}
// 获取工艺列表
const craftList = ref<CraftListData[]>([])
const loadCraftList = async () => {
try {
const res = await getListCraftApi()
if (res.code !== 200) return
craftList.value = res.data
} catch (e) {
console.error(e)
}
}
const refreshMaterial = async () => {
if (status.value === 'PICKING' || status.value === 'TO_BE_REPLENISHMENT') {
if (cardSelection.value.length === 0) {
......@@ -3132,6 +3364,7 @@ onMounted(() => {
getUserMark()
loadProductionClient()
loadWarehouseList()
loadCraftList()
})
const expressSheetUpload = async (file: File) => {
......@@ -3305,7 +3538,7 @@ const replenishmentSuccess = async () => {
.goods-item {
display: grid;
grid-template-columns: 100px 1fr minmax(180px, 1fr) 140px;
grid-template-columns: 100px 1fr minmax(180px, 1fr) 180px;
gap: 20px;
.goods-item-img {
......@@ -3512,6 +3745,29 @@ const replenishmentSuccess = async () => {
}
}
}
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 15px;
margin: 10px 0;
:deep(.el-pagination) {
margin: 0 !important;
}
.total {
color: #606266;
font-size: 15px;
}
.pageSize {
line-height: 39px;
color: #606266;
font-size: 15px;
}
}
</style>
<style lang="scss">
.customize-select-style {
......
<template>
<div class="user-page flex-column card h-100 overflow-hidden">
<div class="header-filter-form">
<ElForm :model="searchForm" inline>
<ElFormItem label="客户识别码" prop="sku">
<ElInput
v-model="searchForm.sku"
placeholder="请输入客户识别码"
clearable
style="width: 200px"
/>
</ElFormItem>
<ElFormItem label="客户标识" prop="userMark">
<ElInput
v-model="searchForm.userMark"
placeholder="请输入客户标识"
clearable
style="width: 200px"
/>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" @click="search">查询</ElButton>
</ElFormItem>
<ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem>
<ElFormItem>
<ElButton type="success" @click="addUser">绑定客户</ElButton>
</ElFormItem>
</ElForm>
</div>
<div class="user-content flex-1 flex-column overflow-hidden">
<div class="user-list flex-1 overflow-hidden">
<ElTable
:data="tableData"
default-expand-all
style="width: 100%; height: 100%"
>
<ElTableColumn
type="index"
header-align="center"
align="center"
label="序号"
width="55"
/>
<ElTableColumn
prop="sku"
header-align="center"
align="center"
label="客户识别码"
/>
<ElTableColumn
prop="userMark"
header-align="center"
align="center"
label="客户标识"
/>
<ElTableColumn
label="操作"
width="130"
header-align="center"
align="center"
>
<template #default="scope">
<el-icon
size="24"
title="解除绑定"
color="#f56c6c"
style="cursor: pointer; vertical-align: middle"
@click="editUser(scope.row)"
>
<Delete />
</el-icon>
</template>
</ElTableColumn>
</ElTable>
</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>
<ElDialog
v-model="dialogVisible"
:title="!relId ? '绑定客户' : '解绑客户'"
width="600px"
:close-on-click-modal="false"
@opened="onOpenedUserForm"
>
<div class="dialog-form">
<ElForm
ref="editFormRef"
:model="editForm"
:rules="rules"
label-width="120px"
>
<ElFormItem label="客户识别码:" prop="sku">
<ElInput
v-if="!relId"
v-model="editForm.sku"
placeholder="请输入客户识别码"
clearable
>
<template #append>
<el-button :icon="Search" @click="getSkuByInfo"></el-button>
</template>
</ElInput>
<span v-else style="font-weight: bold">{{ editForm.sku }}</span>
</ElFormItem>
<ElFormItem label="客户标识:" prop="userMark">
<span style="font-weight: bold">{{ editForm.userMark }}</span>
</ElFormItem>
</ElForm>
</div>
<template #footer>
<div class="dialog-footer">
<ElButton @click="dialogVisible = false"> 取消 </ElButton>
<ElButton type="primary" @click="save">确定</ElButton>
</div>
</template>
</ElDialog>
</template>
<script setup lang="ts">
import { getBySkuApi, addRelApi, removeRelApi, getRelList } from '@/api/auth'
import { customData, customSearchForm } from '@/types/api/user'
import usePageList from '@/utils/hooks/usePageList'
import { useValue } from '@/utils/hooks/useValue'
import { Delete, Search } from '@element-plus/icons-vue'
import type { FormRules } from 'element-plus'
import { reactive, ref } from 'vue'
const [searchForm, resetSearchForm] = useValue<customSearchForm>({})
const [editForm, resetEditForm] = useValue<customSearchForm>({
sku: '',
userMark: '',
id: '',
})
const {
currentPage,
pageSize,
total,
data: tableData,
refresh: search,
onCurrentPageChange: handleCurrentChange,
onPageSizeChange: handleSizeChange,
} = usePageList({
query: (page, pageSize) =>
getRelList(searchForm.value, page, pageSize).then((res) => res.data),
})
const dialogVisible = ref(false)
const editFormRef = ref()
// const selection = ref<customData[]>([])
const rules = reactive<FormRules<customSearchForm>>({
sku: [
{
required: true,
message: '请输入客户识别码',
},
],
})
const getSkuByInfo = async () => {
if (!editForm.value.sku) {
return ElMessage({
message: '请输入sku',
type: 'warning',
offset: window.innerHeight / 2,
})
}
try {
const res = await getBySkuApi(editForm.value.sku)
if (res.code == 200) {
editForm.value.userMark = res.data?.userMark || ''
editForm.value.id = res.data?.id || ''
}
} catch (e) {
// showError(e)
}
}
const relId = ref<number | undefined>(undefined)
const addUser = () => {
relId.value = undefined
dialogVisible.value = true
resetEditForm()
}
const editUser = async (item: customData) => {
relId.value = item.relId
editForm.value.sku = item.sku
editForm.value.userMark = item.userMark
dialogVisible.value = true
}
const save = async () => {
try {
await editFormRef.value.validate()
} catch {
return
}
try {
if (!relId.value) {
if (!editForm.value.id) {
return ElMessage({
message: '请根据SKU查询对应的客户标识',
type: 'warning',
offset: window.innerHeight / 2,
})
}
await addRelApi(editForm.value.id)
} else {
await removeRelApi(relId.value)
}
ElMessage({
message: '保存成功',
type: 'success',
offset: window.innerHeight / 2,
})
dialogVisible.value = false
search()
} catch (e) {
return
}
}
const onOpenedUserForm = async () => {
editFormRef.value?.clearValidate()
}
// const handleSelectionChange = (s: customData[]) => {
// selection.value = s
// }
</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;
}
</style>
......@@ -146,11 +146,16 @@ const handleConfirm = async () => {
ElMessage.success('操作成功')
await getData()
}
const locationLabelVisible = ref(false)
const locationRadio = ref('PT001')
async function printLocationTag() {
if (!selections.value.length) {
return ElMessage.warning('请选择数据')
}
locationLabelVisible.value = true
}
async function submitLocationTag() {
const list = selections.value.map((item) => {
return {
locationName: item.locationCode,
......@@ -159,11 +164,11 @@ async function printLocationTag() {
})
const res = await factoryWarehouseInfoPrint({
list,
code: 'PT001',
code: locationRadio.value,
})
window.open(filePath + res.message, '_blank')
locationLabelVisible.value = false
}
const handleBatchDelete = async (row: positionInfo | null) => {
if (!row && !selections.value.length) {
return ElMessage.warning('请选择要删除的数据')
......@@ -508,6 +513,24 @@ getWarehouse()
</div>
</div>
</ElDialog>
<ElDialog
v-model="locationLabelVisible"
title="打印库位标签"
width="500px"
:close-on-click-modal="false"
>
<div class="mb-2 ml-4 location-box">
<span class="location-label">打印库位标签格式:</span>
<el-radio-group v-model="locationRadio">
<el-radio value="PT001" size="large">中文</el-radio>
<el-radio value="PT001_EN" size="large">英文</el-radio>
</el-radio-group>
</div>
<template #footer>
<el-button @click="locationLabelVisible = false">取消</el-button>
<el-button type="primary" @click="submitLocationTag">确定</el-button>
</template>
</ElDialog>
</template>
<style scoped lang="scss">
......@@ -516,6 +539,14 @@ getWarehouse()
height: 100%;
}
}
.location-box {
display: flex;
align-items: center;
.location-label {
color: #606266;
margin:0 15px;
}
}
.import-dialog {
.import-header {
display: flex;
......
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