Commit f047343b by wuqian
parents c3d44811 19a60471
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
"rules": { "rules": {
"vue/require-default-prop": "off", "vue/require-default-prop": "off",
"vue/multi-word-component-names": "off", "vue/multi-word-component-names": "off",
"no-console": "off","no-unused-vars": "off", "no-console": "off",
"@typescript-eslint/no-explicit-any": "error"
}, },
"overrides": [{ "files": "*.vue", "rules": { "no-undef": "off" } }] "overrides": [{ "files": "*.vue", "rules": { "no-undef": "off" } }]
} }
...@@ -32,7 +32,6 @@ declare module 'vue' { ...@@ -32,7 +32,6 @@ declare module 'vue' {
ElImage: typeof import('element-plus/es')['ElImage'] ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput'] ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
...@@ -65,6 +64,7 @@ declare module 'vue' { ...@@ -65,6 +64,7 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Select: typeof import('./src/components/Form/Select.vue')['default'] Select: typeof import('./src/components/Form/Select.vue')['default']
ShipmentOrderDetail: typeof import('./src/components/ShipmentOrderDetail.vue')['default'] ShipmentOrderDetail: typeof import('./src/components/ShipmentOrderDetail.vue')['default']
SideBar: typeof import('./src/components/SideBar.vue')['default']
SplitDiv: typeof import('./src/components/splitDiv/splitDiv.vue')['default'] SplitDiv: typeof import('./src/components/splitDiv/splitDiv.vue')['default']
'Switch ': typeof import('./src/components/Form/Switch .vue')['default'] 'Switch ': typeof import('./src/components/Form/Switch .vue')['default']
TableView: typeof import('./src/components/TableView.vue')['default'] TableView: typeof import('./src/components/TableView.vue')['default']
......
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"element-plus": "^2.6.0", "element-plus": "^2.6.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"luxon": "^3.7.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"qrcode": "^1.5.4",
"splitpanes": "^3.1.5", "splitpanes": "^3.1.5",
"vue": "^3.4.19", "vue": "^3.4.19",
"vue-dompurify-html": "^5.1.0", "vue-dompurify-html": "^5.1.0",
...@@ -28,6 +30,8 @@ ...@@ -28,6 +30,8 @@
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@types/luxon": "^3.7.1",
"@types/qrcode": "^1.5.5",
"@types/splitpanes": "^2.2.6", "@types/splitpanes": "^2.2.6",
"@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1", "@typescript-eslint/parser": "^7.1.1",
......
...@@ -60,6 +60,12 @@ export function getFilePath() { ...@@ -60,6 +60,12 @@ export function getFilePath() {
import.meta.env.VITE_API_BASE_URL + import.meta.env.VITE_API_BASE_UPLOAD_URL import.meta.env.VITE_API_BASE_URL + import.meta.env.VITE_API_BASE_UPLOAD_URL
) )
} }
export function getFileCnPath() {
if (!/(http|https):\/\/([^/]+)/i.test(import.meta.env.BASE_URL)) {
return location.origin
}
return import.meta.env.VITE_API_BASE_URL
}
export function getWsUrl() { export function getWsUrl() {
if (location.protocol === 'https:') { if (location.protocol === 'https:') {
return 'wss://' + location.host return 'wss://' + location.host
...@@ -68,5 +74,6 @@ export function getWsUrl() { ...@@ -68,5 +74,6 @@ export function getWsUrl() {
} }
} }
export const filePath = getFilePath() export const filePath = getFilePath()
export const FileCnPath = getFileCnPath()
export default axios export default axios
import { BaseRespData } from '@/types/api' import { BaseRespData } from '@/types/api'
import axios from './axios' import axios from './axios'
import { LogisticsData } from '@/types/api/order' import { LogisticsData } from '@/types/api/order'
import { LogisticBill } from '@/types/api/podMakeOrder'
import { userData } from '@/types/api/user' import { userData } from '@/types/api/user'
import { VersionImageList } from '@/types/api/typesetting' import { VersionImageList } from '@/types/api/typesetting'
...@@ -12,9 +14,7 @@ export function getLogisticsCompanyList() { ...@@ -12,9 +14,7 @@ export function getLogisticsCompanyList() {
} }
// 获取客户 // 获取客户
export function getUserMarkList() { export function getUserMarkList() {
return axios.get<never, BaseRespData<string[]>>( return axios.get<never, BaseRespData<string[]>>('dbDiyUser/getUserMarkList')
'dbDiyUser/getUserMarkList',
)
} }
// 获取用户 // 获取用户
...@@ -35,3 +35,17 @@ export function uploadFileApi(data: FormData) { ...@@ -35,3 +35,17 @@ export function uploadFileApi(data: FormData) {
data, data,
) )
} }
// 打印物流面单 US
export function getLogisticUSApi(content: string) {
return axios.get<never, BaseRespData<LogisticBill>>(
`factory/podJomallOrderUs/getOrderByFactorySubOrderNumber?factorySubOrderNumber=${content}`,
)
}
// 打印物流面单 CN
export function getLogisticCNApi(content: string) {
return axios.get<never, BaseRespData<LogisticBill>>(
`factory/podJomallOrder/getOrderByThirdSubOrderNumber?thirdSubOrderNumber=${content}`,
)
}
...@@ -2,11 +2,11 @@ import { BasePaginationData, BaseRespData } from '@/types/api' ...@@ -2,11 +2,11 @@ import { BasePaginationData, BaseRespData } from '@/types/api'
import axios from './axios' import axios from './axios'
import { ExternalAuthListData } from '@/types/api/externalAuth' import { ExternalAuthListData } from '@/types/api/externalAuth'
export function getExternalAuthorisationListApi( export function getExternalAuthorisationListApi(
data: { data?: {
type: string type?: string
}, },
page: number, page?: number,
pageSize: number, pageSize?: number,
) { ) {
return axios.post<never, BasePaginationData<ExternalAuthListData>>( return axios.post<never, BasePaginationData<ExternalAuthListData>>(
'factory/baseExternalAccount/list_page', 'factory/baseExternalAccount/list_page',
...@@ -36,6 +36,12 @@ export function deleteExternalAuthorisationApi(ids: string) { ...@@ -36,6 +36,12 @@ export function deleteExternalAuthorisationApi(ids: string) {
`factory/baseExternalAccount/delete?ids=${ids}`, `factory/baseExternalAccount/delete?ids=${ids}`,
) )
} }
export function baseExternalAccountLogsApi(params: { ids: string }) {
return axios.get<never, BaseRespData<never>>(
`factory/baseExternalAccount/logs`,
{ params },
)
}
export function addExternalAuthorisationApi( export function addExternalAuthorisationApi(
url: string, url: string,
data: ExternalAuthListData, data: ExternalAuthListData,
......
...@@ -144,6 +144,12 @@ export function getUniuniList() { ...@@ -144,6 +144,12 @@ export function getUniuniList() {
}, },
) )
} }
// 获取tictok物流承运商
export function getTiktokCarrier() {
return axios.get<never, BaseRespData<{ name: string; id: number }[]>>(
'logisticsWay/getTiktokShippingProvider',
)
}
/** /**
* @description 发货地址 * @description 发货地址
......
...@@ -196,9 +196,9 @@ export function getPodJomallOrderByFactoryNumber(factoryOrderNumber: string) { ...@@ -196,9 +196,9 @@ export function getPodJomallOrderByFactoryNumber(factoryOrderNumber: string) {
return axios.get<never, BaseRespData<OrderData>>( return axios.get<never, BaseRespData<OrderData>>(
'factory/podJomallOrder/getPodJomallOrderByFactoryNumber', 'factory/podJomallOrder/getPodJomallOrderByFactoryNumber',
{ {
params:{ params: {
factoryOrderNumber factoryOrderNumber,
} },
}, },
) )
} }
...@@ -247,3 +247,9 @@ export function completeDeliveryApi( ...@@ -247,3 +247,9 @@ export function completeDeliveryApi(
{ productIdList, ...data }, { productIdList, ...data },
) )
} }
export function exportStatementApi(data: SearchForm, status: string) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrder/exportPodJomallReconciliation',
{ ...data, status },
)
}
...@@ -8,10 +8,17 @@ import { ...@@ -8,10 +8,17 @@ import {
ProductionClient, ProductionClient,
WarehouseListData, WarehouseListData,
LogisticsData, LogisticsData,
ExportParams,
InterceptStateGroupData,
} from '@/types/api/podUsOrder' } from '@/types/api/podUsOrder'
import axios from './axios' import axios from './axios'
import { PodMakeOrderData } from '@/types/api/podMakeOrder' import { PodMakeOrderData } from '@/types/api/podMakeOrder'
export function exportPodUSInfo(data: ExportParams) {
return axios.post<never, BasePaginationData<never>>(
'factory/podJomallOrderUs/exportPodUsOrder',
data,
)
}
// 同步收货地址 // 同步收货地址
export function syncReceiverAddress(data: number[]) { export function syncReceiverAddress(data: number[]) {
return axios.post<never, BaseRespData<never>>( return axios.post<never, BaseRespData<never>>(
...@@ -37,12 +44,19 @@ export function getOrderTabData() { ...@@ -37,12 +44,19 @@ export function getOrderTabData() {
'/factory/podJomallOrderUs/findStateGroupList', '/factory/podJomallOrderUs/findStateGroupList',
) )
} }
// 拦截状态数量
export function getgetInterceptStateGroupList() {
return axios.get<never, BaseRespData<InterceptStateGroupData>>(
'factory/podJomallOrderUs/findInterceptStateGroupList',
)
}
export function getOrderList( export function getOrderList(
params: SearchForm, params: SearchForm,
currentPage: number, currentPage: number,
pageSize: number, pageSize: number,
) { ) {
return axios.post<never, BasePaginationData<PodUsOrderListData[]>>( return axios.post<never, BasePaginationData<PodUsOrderListData>>(
'/factory/podJomallOrderUs/list_page', '/factory/podJomallOrderUs/list_page',
{ {
...params, ...params,
...@@ -332,7 +346,7 @@ export function createLogisticsOrderApi(params: { ...@@ -332,7 +346,7 @@ export function createLogisticsOrderApi(params: {
) )
} }
// 创建物流 // 物流面单上传
export function uploadExpressSheet(params: { export function uploadExpressSheet(params: {
trackingNumber: string trackingNumber: string
file: File file: File
...@@ -341,7 +355,8 @@ export function uploadExpressSheet(params: { ...@@ -341,7 +355,8 @@ export function uploadExpressSheet(params: {
'factory/podJomallOrderUs/uploadExpressSheet', 'factory/podJomallOrderUs/uploadExpressSheet',
params, params,
) )
} // 创建物流 }
// 更新物流信息确认
export function updateSelfLogistics(params: { export function updateSelfLogistics(params: {
trackingNumber: string trackingNumber: string
expressSheet: string expressSheet: string
...@@ -355,7 +370,7 @@ export function updateSelfLogistics(params: { ...@@ -355,7 +370,7 @@ export function updateSelfLogistics(params: {
} }
// 更改物流 // 更改物流
export function composingDesignImages(data: number[],type:string) { export function composingDesignImages(data: number[], type: string) {
return axios.post<never, BaseRespData<never>>( return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/composingDesignImages?type=${type}`, `factory/podJomallOrderUs/composingDesignImages?type=${type}`,
data, data,
...@@ -443,3 +458,119 @@ export function getListCraftApi() { ...@@ -443,3 +458,119 @@ export function getListCraftApi() {
`factory/podJomallOrderProductUs/listCraft`, `factory/podJomallOrderProductUs/listCraft`,
) )
} }
// 批量下载 列表
export function batchDownloadApi(currentPage: number, pageSize: number) {
return axios.post<never, BaseRespData<never>>(
`factory/podUsBatchDownload/list_page`,
{
currentPage,
pageSize,
},
)
}
// 批量下载 下载
export function batchDownloadDownloadApi(params: { id: number; type: string }) {
return axios.get<never, BaseRespData<never>>(
`factory/podUsBatchDownload/download`,
{
params,
},
)
}
// 批量下载 删除
export function batchDownloadDeleteApi(params: { ids?: string }) {
return axios.get<never, BaseRespData<never>>(
`factory/podUsBatchDownload/delete`,
{
params,
},
)
}
// 批量下载 重新排版
export function batchDownloadRecomposingApi(params: { id: number }) {
return axios.get<never, BaseRespData<never>>(
`factory/podUsBatchDownload/reComposingDesignImages`,
{
params,
},
)
}
// 生产完成
export function updateToWaitShipmentApi(params: {
usUpdateParams: Array<{
id: number | string
podJomallOrderUsId: number | string
factorySubOrderNumber: number | string
version: number | string
}>
}) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/updateToWaitShipment`,
params,
)
}
// 拦截状态改变
export function interceptUpdateApi(params: {
orderIds: (string | number)[]
interceptStatus: number
}) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/updateInterceptStatus`,
params,
)
}
// 驳回
export function rejectToApi(params: {
orderStatus: string
productList: ProductList[]
reasonStr: string
}) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/rejectTo`,
params,
)
}
// 状态推送
export function statusPushApi(params: (string | number)[]) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/statusPush`,
params,
)
}
// 完成发货
export function completeDeliveryApi(params: {
orderIdList: (string | number)[]
}) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/completeDelivery`,
params,
)
}
// 物流轨迹
export function get17TrackInfoApi(params: { id: string | number }) {
return axios.get(`factory/podJomallOrderUs/get17TrackInfo`, { params })
}
// 获取riin 权限
export function getAccountCodeByFactoryIdApi(params: { token: string }) {
return axios.get(`factory/baseExternalAccount/getAccountCodeByFactoryId`, {
params,
})
}
// 打印拣货单item
export function printPickPdfByBatchNumberApi(params: {
batchArrangeNumber: string
}) {
return axios.get<never, BaseRespData<never>>(
`factory/podJomallOrderProductUs/printPickPdfByBatchNumber`,
{
params,
},
)
}
...@@ -9,7 +9,7 @@ import { ...@@ -9,7 +9,7 @@ import {
ILocation, ILocation,
AnyObject, AnyObject,
InterProductList, InterProductList,
ExportInWarehouseInfo ExportInWarehouseInfo,
} from '@/types/api/warehouse' } from '@/types/api/warehouse'
export interface LogListData { export interface LogListData {
createTime: string createTime: string
...@@ -60,7 +60,18 @@ export interface factoryWarehouseInfo { ...@@ -60,7 +60,18 @@ export interface factoryWarehouseInfo {
remark?: string remark?: string
idList?: string | number[] idList?: string | number[]
} }
export interface factoryLocation {
locationId?: string
idList?: string | number[]
}
export interface productNo {
productNo?: string
idList?: string | number[]
}
export interface customSku {
customSku?: string
idList?: string | number[]
}
export interface ExportFactoryWarehouseInfo { export interface ExportFactoryWarehouseInfo {
pageSize?: number pageSize?: number
currentPage?: number currentPage?: number
...@@ -120,6 +131,9 @@ export interface WarehouseWarning { ...@@ -120,6 +131,9 @@ export interface WarehouseWarning {
productNumber: string productNumber: string
number: string number: string
locationName: string locationName: string
warehouseId: string | number
customSku?: string
productNo?: string
} }
export interface positionInfo { export interface positionInfo {
...@@ -143,7 +157,12 @@ export interface positionFormInfo { ...@@ -143,7 +157,12 @@ export interface positionFormInfo {
remark: string remark: string
status: number status: number
} }
export interface loactionData {
id?: number
warehouseId?: number | string
warehouseName?: string
locationCode?: number | string
}
interface WarehouseWarningData { interface WarehouseWarningData {
id: number id: number
factoryId: number factoryId: number
...@@ -173,6 +192,28 @@ export function getFactoryLocation(data: factoryWarehouseInfo) { ...@@ -173,6 +192,28 @@ export function getFactoryLocation(data: factoryWarehouseInfo) {
data, data,
) )
} }
// 修改库位
export function updateLocationApi(data: factoryLocation) {
return axios.post<never, BasePaginationData<never>>(
'factoryWarehouseInventory/updateLocation',
data,
)
}
// 修改款号
export function updateProductNoApi(data: productNo) {
return axios.post<never, BasePaginationData<never>>(
'factoryWarehouseInventory/updateProductNo',
data,
)
}
// 修改自定义sku
export function updateCustomSkuApi(data: customSku) {
return axios.post<never, BasePaginationData<never>>(
'factoryWarehouseInventory/updateCustomSku',
data,
)
}
export function exportWarehouseInfo(data: ExportFactoryWarehouseInfo) { export function exportWarehouseInfo(data: ExportFactoryWarehouseInfo) {
return axios.post<never, BasePaginationData<positionInfo>>( return axios.post<never, BasePaginationData<positionInfo>>(
'factoryWarehouseInventory/inventory', 'factoryWarehouseInventory/inventory',
...@@ -240,6 +281,14 @@ export function warehouseInfoGetAll() { ...@@ -240,6 +281,14 @@ export function warehouseInfoGetAll() {
'/factoryWarehouseInfo/getAll', '/factoryWarehouseInfo/getAll',
) )
} }
export function LocationInfoGetAll(wareHouseId?: string | number) {
return axios.get<never, BaseRespData<loactionData[]>>(
'/factoryWarehouseLocation/getByWareHouse',
{
params: { wareHouseId },
},
)
}
export function createWarehouseInventoryApi(data: WarehouseWarningData) { export function createWarehouseInventoryApi(data: WarehouseWarningData) {
return axios.post<never, BaseRespData<never>>( return axios.post<never, BaseRespData<never>>(
......
...@@ -76,36 +76,40 @@ import type { TypesettingListData } from '../types/api/typesetting' ...@@ -76,36 +76,40 @@ import type { TypesettingListData } from '../types/api/typesetting'
// 定义通用字段接口,用于处理动态属性 // 定义通用字段接口,用于处理动态属性
interface CommonFields { interface CommonFields {
[key: string]: unknown; [key: string]: unknown
variantImage?: string; variantImage?: string
mainImage?: string; mainImage?: string
sku?: string; sku?: string
productName?: string; productName?: string
} }
// 定义图片列表项接口 // 定义图片列表项接口
interface ImageListItem { interface ImageListItem {
[key: string]: unknown; [key: string]: unknown
imagePath?: string; imagePath?: string
} }
// 创建一个工具类型,用于使用字符串索引访问对象属性 // 创建一个工具类型,用于使用字符串索引访问对象属性
type IndexableObject = Record<string, unknown>; type IndexableObject = Record<string, unknown>
// 扩展现有类型以确保它们有通用字段 // 扩展现有类型以确保它们有通用字段
type CardItem = PodProductList | CardOrderData | TypesettingListData | CommonFields; type CardItem =
| PodProductList
| CardOrderData
| TypesettingListData
| CommonFields
// 定义 props 类型 // 定义 props 类型
interface Props { interface Props {
cardItem: CardItem; cardItem: CardItem
active?: boolean; active?: boolean
showSelectIcon?: boolean; showSelectIcon?: boolean
showSku?: boolean; showSku?: boolean
showProductInfo?: boolean; showProductInfo?: boolean
showImageList?: boolean; showImageList?: boolean
imageField?: string; imageField?: string
imageListField?: string; imageListField?: string
imagePathField?: string; imagePathField?: string
} }
// 定义默认值 // 定义默认值
...@@ -122,45 +126,45 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -122,45 +126,45 @@ const props = withDefaults(defineProps<Props>(), {
// 获取主图片源 // 获取主图片源
const mainImageSrc = computed<string>(() => { const mainImageSrc = computed<string>(() => {
const item = props.cardItem as IndexableObject; const item = props.cardItem as IndexableObject
// 使用索引访问避免联合类型的属性访问问题 // 使用索引访问避免联合类型的属性访问问题
if ( if (
props.imageField === 'variantImage' && props.imageField === 'variantImage' &&
typeof item[props.imageField] === 'string' typeof item[props.imageField] === 'string'
) { ) {
return item[props.imageField] as string; return item[props.imageField] as string
} }
if ( if (
props.imageField === 'mainImage' && props.imageField === 'mainImage' &&
typeof item[props.imageField] === 'string' typeof item[props.imageField] === 'string'
) { ) {
return item[props.imageField] as string; return item[props.imageField] as string
} }
// 默认返回空字符串 // 默认返回空字符串
return ''; return ''
}) })
// 获取图片列表 // 获取图片列表
const imageList = computed<ImageListItem[]>(() => { const imageList = computed<ImageListItem[]>(() => {
const item = props.cardItem as IndexableObject; const item = props.cardItem as IndexableObject
const list = item[props.imageListField]; const list = item[props.imageListField]
return Array.isArray(list) ? list as ImageListItem[] : []; return Array.isArray(list) ? (list as ImageListItem[]) : []
}) })
// 判断是否有图片列表 // 判断是否有图片列表
const hasImageList = computed<boolean>(() => { const hasImageList = computed<boolean>(() => {
return imageList.value.length > 0; return imageList.value.length > 0
}) })
// 获取图片列表项的图片路径 // 获取图片列表项的图片路径
function getItemImagePath(item: IndexableObject): string { function getItemImagePath(item: IndexableObject): string {
return (item[props.imagePathField] as string) || ''; return (item[props.imagePathField] as string) || ''
} }
const copy = (text: string) => { const copy = (text: string) => {
navigator.clipboard.writeText(text); navigator.clipboard.writeText(text)
ElMessage.success('复制成功'); ElMessage.success('复制成功')
} }
</script> </script>
...@@ -174,11 +178,16 @@ const copy = (text: string) => { ...@@ -174,11 +178,16 @@ const copy = (text: string) => {
.commodity-card-image { .commodity-card-image {
position: relative; position: relative;
border: 1px solid #eee;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
.img_top_left { .img_top_left {
position: absolute; position: absolute;
top: 5px; top: 5px;
left: 5px; left: 5px;
display: flex;
align-items: center;
gap: 4px;
} }
.img_top_right { .img_top_right {
......
<template> <template>
<div class="log-list"> <div class="log-list">
<div <div v-for="l in logList" :key="l.id" class="log-item flex">
v-for="l in logList"
:key="l.id"
class="log-item flex"
>
<div class="log-item-icon"> <div class="log-item-icon">
<Icon name="a-2labadianji3x" /> <Icon name="a-2labadianji3x" />
</div> </div>
<div class="log-item-time"> <div class="log-item-time">
<span>{{ l.createTime }}</span> <span>{{ l.local && `${l.local}:` }}{{ l.createTime }}</span>
</div> </div>
<div v-if="l.employeeName" class="log-item-name"> <div v-if="l.employeeName" class="log-item-name">
<span>{{ l.employeeName }}</span> <span>{{ l.employeeName }}</span>
...@@ -45,7 +41,7 @@ defineProps({ ...@@ -45,7 +41,7 @@ defineProps({
} }
.log-item-time { .log-item-time {
width: 140px; // width: 220px;
} }
.log-item-name { .log-item-name {
......
...@@ -34,7 +34,11 @@ ...@@ -34,7 +34,11 @@
</el-sub-menu> </el-sub-menu>
</template> </template>
</el-menu> </el-menu>
<SideBar />
<div v-if="userInfo" class="user-info"> <div v-if="userInfo" class="user-info">
<span class="user-avatar" style="color: #fff; font-size: 14px">
工厂: {{ userInfo.factoryCode }}
</span>
<span class="user-avatar"> <span class="user-avatar">
<el-icon><User /></el-icon> <el-icon><User /></el-icon>
</span> </span>
...@@ -175,9 +179,15 @@ import { ...@@ -175,9 +179,15 @@ import {
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import Menu from '@/router/menu' import Menu from '@/router/menu'
import userUserStore from '@/store/user' import userUserStore from '@/store/user'
import type { FormRules } from 'element-plus' import type { FormRules } from 'element-plus'
import { useValue } from '@/utils/hooks/useValue' import { useValue } from '@/utils/hooks/useValue'
import { changePasswordApi } from '@/api/auth' import { changePasswordApi } from '@/api/auth'
import { ElMessage } from 'element-plus'
import SideBar from './SideBar.vue'
interface MenuItem { interface MenuItem {
index: string index: string
id: number id: number
...@@ -530,4 +540,8 @@ onUnmounted(() => { ...@@ -530,4 +540,8 @@ onUnmounted(() => {
border: none !important; border: none !important;
} }
} }
.user-info {
display: flex;
align-items: center;
}
</style> </style>
...@@ -198,15 +198,6 @@ export default defineComponent({ ...@@ -198,15 +198,6 @@ export default defineComponent({
</div> </div>
)} )}
<div style={{ display: 'flex', alignItems: 'center' }}> <div style={{ display: 'flex', alignItems: 'center' }}>
{props.isSearchBtn && (
<ElButton
class="btn"
type="primary"
onClick={() => emit('search', searchForm.value)}
>
查询
</ElButton>
)}
{props.isResetBtn && ( {props.isResetBtn && (
<ElButton <ElButton
class="btn" class="btn"
...@@ -215,10 +206,23 @@ export default defineComponent({ ...@@ -215,10 +206,23 @@ export default defineComponent({
// emit('update:modelValue', {}) // emit('update:modelValue', {})
emit('reset') emit('reset')
}} }}
link
> >
<span title="重置查询条件" style={{ fontSize: '12px' }}>
重置 重置
</span>
</ElButton> </ElButton>
)} )}
{props.isSearchBtn && (
<ElButton
class="btn"
type="primary"
onClick={() => emit('search', searchForm.value)}
>
查询
</ElButton>
)}
{props.isAddBtn && ( {props.isAddBtn && (
<ElButton class="btn" type="success" onClick={() => emit('add')}> <ElButton class="btn" type="success" onClick={() => emit('add')}>
新增 新增
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
:data="paginatedData" :data="paginatedData"
border border
:stripe="stripe" :stripe="stripe"
v-bind="attrs"
header-align="center" header-align="center"
height="100%" height="100%"
v-bind="attrs"
> >
<ElTableColumn <ElTableColumn
v-if="selectionable" v-if="selectionable"
type="selection" type="selection"
width="50" width="40"
fixed="left" fixed="left"
header-align="center" header-align="center"
align="center" align="center"
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
v-if="serialNumberable" v-if="serialNumberable"
label="序号" label="序号"
type="index" type="index"
width="60" width="55"
fixed="left" fixed="left"
header-align="center" header-align="center"
align="center" align="center"
......
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
/> />
<div class="custom-tip"> <div class="custom-tip">
<span>请上传Excel文件(.xls 或 .xlsx)</span> <span>请上传Excel文件(.xls 或 .xlsx)</span>
<div class="down-load" @click="downloadTemplate">
<el-icon><Download /></el-icon>
<span> 下载{{ importName }}模板</span>
</div>
</div> </div>
</div> </div>
<div v-if="fileList.length > 0"> <div v-if="fileList.length > 0">
...@@ -54,7 +58,12 @@ import { ...@@ -54,7 +58,12 @@ import {
computed, computed,
defineExpose, defineExpose,
} from 'vue' } from 'vue'
import { UploadFilled, Document, Close } from '@element-plus/icons-vue' import {
UploadFilled,
Document,
Close,
Download,
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { uploadFileApi } from '@/api/common' import { uploadFileApi } from '@/api/common'
interface FileItem { interface FileItem {
...@@ -64,6 +73,8 @@ interface FileItem { ...@@ -64,6 +73,8 @@ interface FileItem {
const props = defineProps<{ const props = defineProps<{
modelValue: string modelValue: string
importType: string importType: string
importName: string
importUrl:string
}>() }>()
const emit = defineEmits(['update:modelValue', 'imported']) const emit = defineEmits(['update:modelValue', 'imported'])
...@@ -149,7 +160,6 @@ const onFileChange = async (e: Event) => { ...@@ -149,7 +160,6 @@ const onFileChange = async (e: Event) => {
emit('imported', { path: file.name, data: jsonData }) emit('imported', { path: file.name, data: jsonData })
fileList.value = [{ path: file.name, filename: file.name }] fileList.value = [{ path: file.name, filename: file.name }]
value.value = file.name || '' value.value = file.name || ''
ElMessage.success('导入成功')
loading.value = false loading.value = false
} }
reader.readAsBinaryString(file) reader.readAsBinaryString(file)
...@@ -189,7 +199,20 @@ const fileUpload = async (file: File) => { ...@@ -189,7 +199,20 @@ const fileUpload = async (file: File) => {
loading.value = false loading.value = false
} }
} }
const downloadTemplate = () => {
// 获取当前日期
const currentDate = new Date()
const year = currentDate.getFullYear()
const month = String(currentDate.getMonth() + 1).padStart(2, '0') // 月份从0开始,需要加1
const day = String(currentDate.getDate()).padStart(2, '0')
// 生成文件名
const fileName = `${props.importName}模板_${year}${month}${day}.xlsx`
// 设置链接的href和download属性
const link = document.createElement('a')
link.href = props.importUrl // 服务器上的文件路径
link.download = fileName // 设置下载文件的文件名
link.click() // 触发下载
}
const removeFile = (idx: number) => { const removeFile = (idx: number) => {
fileList.value.splice(idx, 1) fileList.value.splice(idx, 1)
value.value = '' value.value = ''
...@@ -262,9 +285,17 @@ const removeFile = (idx: number) => { ...@@ -262,9 +285,17 @@ const removeFile = (idx: number) => {
display: flex; display: flex;
align-items: center; align-items: center;
color: #666; color: #666;
margin-top: 12px; padding-top: 15px;
i { .down-load {
margin-right: 6px; display: flex;
align-items: center;
color: #409eff;
text-decoration: none;
}
.down-load:hover {
cursor: pointer;
text-decoration: underline; /* 鼠标划过时添加下划线 */
} }
} }
} }
......
...@@ -51,12 +51,17 @@ export default defineComponent({ ...@@ -51,12 +51,17 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
otherAttrs: {
type: Object,
default: () => ({}),
},
}, },
emits: ['update:modelValue', 'checkbox-change', 'getCheckboxRecords'], emits: ['update:modelValue', 'checkbox-change', 'getCheckboxRecords'],
setup(props, { emit, attrs }) { setup(props, { emit, attrs }) {
const tableRef = ref<VxeTableInstance | null>(null) const tableRef = ref<VxeTableInstance | null>(null)
const tableData = ref<Record<string, unknown>[]>([]) const tableData = ref<Record<string, unknown>[]>([])
const tableColumns = ref<TableColumn[]>([]) const tableColumns = ref<TableColumn[]>([])
const editConfig = computed(() => { const editConfig = computed(() => {
return { return {
trigger: 'dblclick', trigger: 'dblclick',
...@@ -139,10 +144,21 @@ export default defineComponent({ ...@@ -139,10 +144,21 @@ export default defineComponent({
{...this.attrs} {...this.attrs}
> >
{this.isShowCheckBox && ( {this.isShowCheckBox && (
<vxe-column type="checkbox" width="50" align="center"></vxe-column> <vxe-column
type="checkbox"
width="50"
align="center"
{...this.otherAttrs}
></vxe-column>
)} )}
<vxe-column align="center" type="seq" width="50" title="序号" /> <vxe-column
align="center"
type="seq"
width="50"
title="序号"
{...this.otherAttrs}
/>
{this.tableColumns.map((item: TableColumn, index: number) => ( {this.tableColumns.map((item: TableColumn, index: number) => (
<vxe-column <vxe-column
key={index} key={index}
......
...@@ -10,7 +10,7 @@ const props = defineProps({ ...@@ -10,7 +10,7 @@ const props = defineProps({
type: String || Number, type: String || Number,
}, },
otherSize: { otherSize: {
default: 20, default: '20',
type: String || Number, type: String || Number,
}, },
}) })
...@@ -19,7 +19,7 @@ const domSize = ref<string>('0') ...@@ -19,7 +19,7 @@ const domSize = ref<string>('0')
function domResize() { function domResize() {
const father = document.getElementsByClassName('splitpanes')[0] const father = document.getElementsByClassName('splitpanes')[0]
const top = document.getElementById('top') const top = document.getElementById('top')
if(top && father){ if (top && father) {
const v = ((top.clientHeight / father?.clientHeight) * 100).toFixed(2) const v = ((top.clientHeight / father?.clientHeight) * 100).toFixed(2)
if (props.size === '') { if (props.size === '') {
...@@ -28,9 +28,8 @@ function domResize() { ...@@ -28,9 +28,8 @@ function domResize() {
domSize.value = props.size domSize.value = props.size
} }
} }
} }
onUnmounted(()=>{ onUnmounted(() => {
window.removeEventListener('resize', domResize) window.removeEventListener('resize', domResize)
}) })
onMounted(() => { onMounted(() => {
...@@ -38,7 +37,7 @@ onMounted(() => { ...@@ -38,7 +37,7 @@ onMounted(() => {
domResize() domResize()
}) })
defineExpose({ defineExpose({
domResize domResize,
}) })
</script> </script>
...@@ -48,7 +47,6 @@ defineExpose({ ...@@ -48,7 +47,6 @@ defineExpose({
<div id="top"> <div id="top">
<slot name="top"></slot> <slot name="top"></slot>
</div> </div>
</pane> </pane>
<pane style="flex: 1; flex-shrink: 0"> <pane style="flex: 1; flex-shrink: 0">
<div id="bottom"> <div id="bottom">
...@@ -67,15 +65,15 @@ defineExpose({ ...@@ -67,15 +65,15 @@ defineExpose({
#top { #top {
height: fit-content; height: fit-content;
} }
#other-pane{ #other-pane {
height: 100%; height: 100%;
} }
#bottom { #bottom {
height: 100%; height: 100%;
} }
#top, #bottom { #top,
#bottom {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
...@@ -99,11 +97,11 @@ defineExpose({ ...@@ -99,11 +97,11 @@ defineExpose({
transform: translate(-50%); transform: translate(-50%);
width: 30px; width: 30px;
height: 1px; height: 1px;
content: ""; content: '';
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
transition: background-color .3s; transition: background-color 0.3s;
} }
&::after { &::after {
...@@ -112,11 +110,11 @@ defineExpose({ ...@@ -112,11 +110,11 @@ defineExpose({
transform: translate(-50%); transform: translate(-50%);
width: 30px; width: 30px;
height: 1px; height: 1px;
content: ""; content: '';
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
transition: background-color .3s; transition: background-color 0.3s;
} }
} }
......
...@@ -7,13 +7,18 @@ import './styles/index.scss' ...@@ -7,13 +7,18 @@ import './styles/index.scss'
import VxeUITable from 'vxe-table' import VxeUITable from 'vxe-table'
import 'vxe-table/lib/style.css' import 'vxe-table/lib/style.css'
import { isPermissionBtn } from '@/utils/index'
// 确保在渲染用户提供的HTML内容时,不会执行任何潜在的恶意脚本,从而提高应用的安全性 // 确保在渲染用户提供的HTML内容时,不会执行任何潜在的恶意脚本,从而提高应用的安全性
import vueDomPurifyHTMLPlugin from 'vue-dompurify-html' import vueDomPurifyHTMLPlugin from 'vue-dompurify-html'
createApp(App) const app = createApp(App)
app
.use(vueDomPurifyHTMLPlugin) .use(vueDomPurifyHTMLPlugin)
.use(router) .use(router)
.use(store) .use(store)
.use(VxeUITable) .use(VxeUITable)
.mount('#app') .mount('#app')
app.config.globalProperties.$isPermissionBtn = isPermissionBtn
...@@ -74,6 +74,13 @@ const router = createRouter({ ...@@ -74,6 +74,13 @@ const router = createRouter({
component: PodUsOrderList, component: PodUsOrderList,
}, },
{ {
path: '/pod-us-order/orderTracking',
meta: {
title: 'POD(US)订单跟踪',
},
component: () => import('@/views/order/orderTracking/index.vue'),
},
{
path: '/pod-delivery-note/list', path: '/pod-delivery-note/list',
meta: { meta: {
title: 'POD发货单', title: 'POD发货单',
...@@ -95,6 +102,28 @@ const router = createRouter({ ...@@ -95,6 +102,28 @@ const router = createRouter({
component: UserPage, component: UserPage,
}, },
{ {
path: '/system/downloadClient',
meta: {
title: '下载生产客户端',
},
component: () => {},
beforeEnter() {
// 假设你的下载链接是这个
const downloadLink = '/exeFiles/JomallProductionAssistantSetup.exe'
// 创建一个 a 标签来触发下载
const a = document.createElement('a')
a.href = downloadLink
a.download = '生产客户端.exe' // 你可以指定文件名,或者保持为空来自动使用原始文件名
// 不显示 a 标签,直接触发下载
a.style.display = 'none'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
},
},
{
path: '/system/external-authorisation', path: '/system/external-authorisation',
meta: { meta: {
title: '外部授权', title: '外部授权',
...@@ -228,82 +257,11 @@ const router = createRouter({ ...@@ -228,82 +257,11 @@ const router = createRouter({
component: WarehousePosition, component: WarehousePosition,
}, },
{ {
path: '/logistics/logisticsMethod', path: '/setting/settingIndex',
meta: {
title: '物流方式',
},
component: () => import('@/views/logistics/logisticsMethod.vue'),
},
{
path: '/logistics/shippingAddress',
meta: {
title: '发货地址',
},
component: () => import('@/views/logistics/shippingAddress.vue'),
},
{
path: '/logistics/logisticsQuotation',
meta: {
title: '物流报价',
},
component: () => import('@/views/logistics/logisticsQuotation.vue'),
},
{
path: '/logistics/declarationRule',
meta: {
title: '申报规则',
},
component: () => import('@/views/logistics/declarationRule.vue'),
},
{
path: '/logistics/logisticsPartition',
meta: {
title: '物流分区',
},
component: () => import('@/views/logistics/logisticsPartition.vue'),
},
{
path: '/logistics/logisticsCalculate',
meta: { meta: {
title: '运费试算', title: '设置',
}, },
component: () => import('@/views/logistics/logisticsCalculate.vue'), component: () => import('@/views/setting/settingIndex.vue'),
},
{
path: '/warehouse/manage',
meta: {
title: '仓库管理',
},
component: WarehouseManage,
},
{
path: '/warehouse/receipt-doc',
meta: {
title: '入库单',
},
component: receiptDoc,
},
// {
// path: '/warehouse/issue-doc',
// meta: {
// title: '出库单',
// },
// component: issueDoc,
// },
{
path: '/warehouse/warning',
meta: {
title: '仓库预警',
},
component: WarehouseWarning,
},
{
path: '/warehouse/position',
meta: {
title: '库位管理',
},
component: WarehousePosition,
}, },
], ],
}, },
......
...@@ -117,6 +117,11 @@ const menu: MenuItem[] = [ ...@@ -117,6 +117,11 @@ const menu: MenuItem[] = [
id: 8, id: 8,
label: 'POD订单(US)', label: 'POD订单(US)',
}, },
{
index: '/pod-us-order/orderTracking',
id: 8,
label: 'POD(US)订单跟踪',
},
], ],
}, },
...@@ -171,6 +176,11 @@ const menu: MenuItem[] = [ ...@@ -171,6 +176,11 @@ const menu: MenuItem[] = [
label: '用户管理', label: '用户管理',
}, },
{ {
index: '/system/downloadClient',
id: 4,
label: '下载生产客户端',
},
{
index: '/system/external-authorisation', index: '/system/external-authorisation',
id: 5, id: 5,
label: '外部授权', label: '外部授权',
...@@ -182,6 +192,11 @@ const menu: MenuItem[] = [ ...@@ -182,6 +192,11 @@ const menu: MenuItem[] = [
}, },
], ],
}, },
{
index: '/setting/settingIndex',
id: 7,
label: '设置',
},
// { // {
// index: '', // index: '',
......
import { defineStore } from 'pinia'
const usePermissionBtnStore = defineStore('permissionBtn', {
state: () => ({
permissionBtns: [] as string[], // 权限按钮数组
}),
actions: {
setBtn(state: string[]) {
this.permissionBtns = state
},
},
})
export default usePermissionBtnStore
...@@ -30,8 +30,15 @@ const useUserStore = defineStore('user', { ...@@ -30,8 +30,15 @@ const useUserStore = defineStore('user', {
async login(data: LoginReq) { async login(data: LoginReq) {
try { try {
const resp = await loginApi(data) const resp = await loginApi(data)
console.log(33, resp)
this.setUser(resp.data.sysUser) this.setUser(resp.data.sysUser)
setToken(resp.data.token) setToken(resp.data.token)
localStorage.setItem(
'baseExternalAccountTypes',
JSON.stringify(resp.data.sysUser.baseExternalAccountTypes),
)
router.push({ path: '/dashboard' }) router.push({ path: '/dashboard' })
} catch (error) { } catch (error) {
// showError(error) // showError(error)
......
...@@ -24,6 +24,7 @@ export interface SysUser { ...@@ -24,6 +24,7 @@ export interface SysUser {
factoryCode: string factoryCode: string
status: number status: number
factory: Factory factory: Factory
baseExternalAccountTypes?: []
} }
export interface Factory { export interface Factory {
......
...@@ -16,4 +16,5 @@ export interface ExternalAuthListData { ...@@ -16,4 +16,5 @@ export interface ExternalAuthListData {
token?: string token?: string
refreshToken?: string refreshToken?: string
refreshTokenFailureTime?: string refreshTokenFailureTime?: string
enable?: boolean
} }
...@@ -200,6 +200,7 @@ export interface LogListData { ...@@ -200,6 +200,7 @@ export interface LogListData {
employeeName?: string employeeName?: string
description?: string description?: string
createTime?: string createTime?: string
local?: string
} }
export interface QaData { export interface QaData {
......
...@@ -27,6 +27,7 @@ export interface OrderData { ...@@ -27,6 +27,7 @@ export interface OrderData {
printResult?: string printResult?: string
remark?: string remark?: string
version?: number version?: number
factoryOrderNumber?: number | string
} }
export interface ProductList { export interface ProductList {
...@@ -44,4 +45,24 @@ export interface ProductList { ...@@ -44,4 +45,24 @@ export interface ProductList {
power?: boolean power?: boolean
variantImage?: string variantImage?: string
podJomallUsNo?: string podJomallUsNo?: string
previewImgs?: { sort: string | number; title: string; url: string }[]
}
export interface LogisticBill {
expressSheet?: string
salesPlatform?: string
orderStatus?: string
shopWay?: string
blocked?: boolean
logisticsCompanyName?: string
logisticsWayNameId?: string
shopNumber?: string
id?: string
shopId?: string
orderId?: string
orderNumber?: string
trackingNumber?: string
systemWeight?: number | string
purchaseNumber?: number
productList?: ProductList[]
} }
...@@ -21,6 +21,8 @@ export interface SearchForm { ...@@ -21,6 +21,8 @@ export interface SearchForm {
endTime?: string | null endTime?: string | null
internalMemo?: string internalMemo?: string
productionFileId?: string productionFileId?: string
interceptedStatus?: boolean
platform?: string
} }
export interface CardOrderData { export interface CardOrderData {
id: number id: number
......
...@@ -3,29 +3,38 @@ export interface Tab { ...@@ -3,29 +3,38 @@ export interface Tab {
statusName?: string statusName?: string
quantity?: number quantity?: number
} }
export interface ExportParams extends SearchForm {
idList?: number[]
exportAll: boolean
status?: string
}
export interface SearchForm { export interface SearchForm {
timeType: number | null timeType?: number | null
shopNumber: string shopNumber?: string
shipmentType: string shipmentType?: string
userMark: string userMark?: string
logisticsTracking: string processNumber?: string
baseSku: string trackingNumber?: string
factoryOrderNumber: string baseSku?: string
sku: string factoryOrderNumber?: string
factorySubOrderNumber: string sku?: string
status: string factorySubOrderNumber?: string
customizedQuantity: string status?: string
multi: boolean | null customizedQuantity?: string
startTime: string | null multi?: boolean | null
endTime: string | null startTime?: string | null
exceptionHandling: number | undefined endTime?: string | null
platform: string exceptionHandling?: number | undefined
productionClient: string platform?: string
warehouseId: string | number productionClient?: string
thirdSkuCode: string warehouseId?: string | number
supplierProductNo: string thirdSkuCode?: string
batchArrangeNumber: string supplierProductNo?: string
craftCode: string batchArrangeNumber?: string
craftCode?: string
thirdStockSku?: string
interceptStatus?: number | string
} }
export interface PodUsOrderListData { export interface PodUsOrderListData {
id: number id: number
...@@ -56,7 +65,7 @@ export interface PodUsOrderListData { ...@@ -56,7 +65,7 @@ export interface PodUsOrderListData {
paymentTime?: string paymentTime?: string
startStockingTime?: string startStockingTime?: string
finishTime?: string finishTime?: string
shipmentType?: string shipmentType?: number
expressSheet?: string expressSheet?: string
trackingNumber?: string trackingNumber?: string
processNumber?: string processNumber?: string
...@@ -69,11 +78,14 @@ export interface PodUsOrderListData { ...@@ -69,11 +78,14 @@ export interface PodUsOrderListData {
orderNumber?: string orderNumber?: string
logisticsWayId?: number | null logisticsWayId?: number | null
logisticsWayName?: string logisticsWayName?: string
url?: string | null
tiffUrl?: string | null
} }
export interface ProductList { export interface ProductList {
id: number id: number
podJomallOrderUsId: number podJomallOrderUsId: number
thirdSubOrderNumber?: string thirdSubOrderNumber?: string
thirdStockSku?: string
factorySubOrderNumber?: string factorySubOrderNumber?: string
factoryCode?: string factoryCode?: string
productName?: string productName?: string
...@@ -83,7 +95,10 @@ export interface ProductList { ...@@ -83,7 +95,10 @@ export interface ProductList {
templatePrice?: number templatePrice?: number
variantImage?: string variantImage?: string
craftPrice?: number craftPrice?: number
craftCode?: string
platform?: string
imageAry?: string imageAry?: string
previewImgs?: []
designImages?: string designImages?: string
categoryId?: number categoryId?: number
categoryName?: string categoryName?: string
...@@ -113,6 +128,7 @@ export interface ProductList { ...@@ -113,6 +128,7 @@ export interface ProductList {
supplierProductNo?: string | null supplierProductNo?: string | null
replenishmentSumNum?: number | null replenishmentSumNum?: number | null
batchArrangeNumber?: string | null batchArrangeNumber?: string | null
interceptStatus?: number | null
} }
export interface cardImages { export interface cardImages {
title: string title: string
...@@ -128,6 +144,7 @@ export interface LogListData { ...@@ -128,6 +144,7 @@ export interface LogListData {
description: string description: string
deleteContent: string deleteContent: string
createTime: string createTime: string
local?: string
} }
export interface ProductionClient { export interface ProductionClient {
code?: string code?: string
...@@ -187,3 +204,12 @@ export interface CraftListData { ...@@ -187,3 +204,12 @@ export interface CraftListData {
craftName: string craftName: string
craftCode: string craftCode: string
} }
export interface InterceptStateGroupData {
shipment: {
[key: string]: number
}
production: {
[key: string]: number
}
}
...@@ -12,3 +12,7 @@ export function useValue<T extends object>( ...@@ -12,3 +12,7 @@ export function useValue<T extends object>(
return [value, resetToDefault] return [value, resetToDefault]
} }
export function getLastSegment(str: string): string {
const lastIndex = str.lastIndexOf('_')
return lastIndex !== -1 ? str.slice(lastIndex + 1) : str
}
import { get } from 'lodash-es' import { get } from 'lodash-es'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { DateTime } from 'luxon'
import usePermissionBtnStore from '@/store/permission'
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export function val<T>(data: T, key: string | ((data: T) => any)) { export function val<T>(data: T, key: string | ((data: T) => any)) {
if (typeof key === 'function') return key(data) if (typeof key === 'function') return key(data)
...@@ -20,3 +23,29 @@ export function copyText(text: string) { ...@@ -20,3 +23,29 @@ export function copyText(text: string) {
document.body.removeChild(oInput) document.body.removeChild(oInput)
ElMessage.success('复制成功') ElMessage.success('复制成功')
} }
/**
* 将本地时间转换为北京时间(自动检测时区)
* @param {string} localTime - 本地时间字符串,格式 YYYY-MM-DD HH:mm:ss
* @returns {string} 北京时间,格式 YYYY-MM-DD HH:mm:ss
*/
export function convertToChinaTime(
timeString: string,
currentZone: string = 'local',
targetZone: string = 'Asia/Shanghai',
) {
// 将输入的时间字符串解析为本地时间,假设输入时间是本地时间
const inputTime = DateTime.fromFormat(timeString, 'yyyy-MM-dd HH:mm:ss', {
zone: currentZone,
})
const chinaTime = inputTime.setZone(targetZone)
return chinaTime.toFormat('yyyy-MM-dd HH:mm:ss')
}
export function isPermissionBtn(key: string) {
const permissionBtns = usePermissionBtnStore().permissionBtns
if (!permissionBtns) return false
return permissionBtns.includes(key)
}
...@@ -76,31 +76,27 @@ ...@@ -76,31 +76,27 @@
<ElFormItem> <ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton> <ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem> </ElFormItem>
</ElForm> <ElFormItem v-if="nodeId === 10">
</div> <el-button type="primary" @click="confirmOrder">
<div class="btn-list">
<el-button
v-if="nodeId === 10"
type="primary"
@click="confirmOrder"
>
确认对账单 确认对账单
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeId === 10" <ElFormItem v-if="nodeId === 10">
type="warning" <el-button type="warning" @click="rejectOrder">
@click="rejectOrder"
>
驳回 驳回
</el-button> </el-button>
<el-button type="success" @click="exportExcel"> 导出 </el-button> </ElFormItem>
<el-button <ElFormItem>
v-if="nodeId === 30" <el-button type="success" @click="exportExcel">
type="danger" 导出
@click="auditOrder('archive')" </el-button>
> </ElFormItem>
<ElFormItem v-if="nodeId === 30">
<el-button type="danger" @click="auditOrder('archive')">
归档 归档
</el-button> </el-button>
</ElFormItem>
</ElForm>
</div> </div>
<div <div
class="delivery-note-content flex-1 flex-column overflow-hidden" class="delivery-note-content flex-1 flex-column overflow-hidden"
......
...@@ -20,7 +20,7 @@ import NavMenu from '@/components/NavMenu.vue' ...@@ -20,7 +20,7 @@ import NavMenu from '@/components/NavMenu.vue'
.container { .container {
flex: 1; flex: 1;
padding: 0 10px 10px; padding: 0 50px 10px 10px;
background-color: #f6f6f6; background-color: #f6f6f6;
overflow: hidden; overflow: hidden;
} }
......
...@@ -29,7 +29,7 @@ let timer: number | undefined ...@@ -29,7 +29,7 @@ let timer: number | undefined
const second = ref(5) const second = ref(5)
const router = useRouter() const router = useRouter()
props.showBtn && props.showBtn &&
(timer = setInterval(() => { (timer = window.setInterval(() => {
if (second.value === 0) { if (second.value === 0) {
clearInterval(timer) clearInterval(timer)
router.go(-1) router.go(-1)
......
...@@ -21,6 +21,7 @@ const styles = { ...@@ -21,6 +21,7 @@ const styles = {
display: 'flex', display: 'flex',
padding: '10px', padding: '10px',
justifyContent: 'flex-start', justifyContent: 'flex-start',
flexWrap: 'wrap',
backgroundColor: '#efefef', backgroundColor: '#efefef',
}, },
} as const } as const
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
v-model="editForm" v-model="editForm"
:config="formConfig" :config="formConfig"
form-item-width="100%" form-item-width="100%"
labelWidth="125" labelWidth="110"
> >
</CustomizeForm> </CustomizeForm>
...@@ -76,16 +76,18 @@ import { ...@@ -76,16 +76,18 @@ import {
updateLogisticsWay, updateLogisticsWay,
updateStatusLogisticsWay, updateStatusLogisticsWay,
deleteLogisticsWay, deleteLogisticsWay,
getWarehouseList,
getRuleList, getRuleList,
getPlatformList, getPlatformList,
getLogisticsLog, getLogisticsLog,
getLogisticsCompanyList, getLogisticsCompanyList,
getUniuniList, getUniuniList,
getTiktokCarrier,
} from '@/api/logistics' } from '@/api/logistics'
import { WarehouseListData } from '@/types/api/podUsOrder'
import { ISeachFormConfig } from '@/types/searchType' import { ISeachFormConfig } from '@/types/searchType'
import { TableColumn } from '@/components/VxeTable' import { TableColumn } from '@/components/VxeTable'
// import type { PromiseSettledResult } from 'types' import { loadWarehouseListApi } from '@/api/podUsOrder'
import type { import type {
LogisticsMethod, LogisticsMethod,
platformObj, platformObj,
...@@ -98,12 +100,14 @@ import { IFormConfig } from '@/components/CustomizeForm.tsx' ...@@ -98,12 +100,14 @@ import { IFormConfig } from '@/components/CustomizeForm.tsx'
import usePageList from '@/utils/hooks/usePageList' import usePageList from '@/utils/hooks/usePageList'
import { useValue } from './hooks/useValue' import { useValue } from './hooks/useValue'
import { showConfirm } from '@/utils/ui' import { showConfirm } from '@/utils/ui'
import { Edit, Delete, List } from '@element-plus/icons-vue' import { Edit, Delete, List, WarningFilled } from '@element-plus/icons-vue'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import UPARCELImage from '@/assets/images/UPARCEL物流编码.png'
const [searchForm] = useValue({}) const [searchForm] = useValue({})
const [editForm, resetEditForm] = useValue<LogisticsMethod>({ const [editForm, resetEditForm] = useValue<LogisticsMethod>({
platformList: [{ platform: '', logisticsName: '', showPlatform: [] }], platformList: [
{ platform: '', logisticsName: '', showPlatform: ['default'] },
],
ruleRef: { ruleId: '', ruleName: '' }, ruleRef: { ruleId: '', ruleName: '' },
status: 1, status: 1,
}) })
...@@ -131,6 +135,14 @@ const dialogVisible = ref(false) ...@@ -131,6 +135,14 @@ const dialogVisible = ref(false)
const logDialogVisible = ref(false) const logDialogVisible = ref(false)
const editFormRef = ref<InstanceType<typeof CustomizeForm> | null>(null) const editFormRef = ref<InstanceType<typeof CustomizeForm> | null>(null)
const selection = ref([]) const selection = ref([])
const warehouseList = ref<WarehouseListData[]>([])
interface ImageList {
[key: string]: string
}
const imgeList = ref<ImageList>({
UPARCEL: UPARCELImage,
})
const searchConfig = ref<ISeachFormConfig[]>([ const searchConfig = ref<ISeachFormConfig[]>([
{ {
prop: 'name', prop: 'name',
...@@ -166,48 +178,13 @@ const searchConfig = ref<ISeachFormConfig[]>([ ...@@ -166,48 +178,13 @@ const searchConfig = ref<ISeachFormConfig[]>([
}, },
]) ])
const platformList = ref([]) const platformList = ref([])
const warehouseList = ref([])
const ruleNameList = ref([]) const ruleNameList = ref([])
const uniuniList = ref([]) const uniuniList = ref([])
const logisticsCompanyList = ref([]) const logisticsCompanyList = ref([])
const formConfig = computed<IFormConfig[]>(() => [ const formConfig = computed<IFormConfig[]>(() => [
{ title: '物流基础信息' }, { title: '物流基础信息' },
{ {
prop: 'name',
type: 'input',
label: '物流名称',
attrs: {
placeholder: '请输入物流名称',
},
rules: [
{
required: true,
message: '请输入物流名称',
},
],
},
{
prop: 'warehouseId',
type: 'select',
label: '仓库名称',
attrs: {
placeholder: '请选择仓库名称',
label: 'name',
value: 'id',
options: [...(warehouseList.value || [])],
onChange: (value: { name: string; id: string | number }) => {
editForm.value.warehouseName = value.name
},
},
rules: [
{
required: true,
message: '请选择仓库名称',
},
],
},
{
prop: 'companyId', prop: 'companyId',
type: 'select', type: 'select',
label: '物流公司', label: '物流公司',
...@@ -282,15 +259,51 @@ const formConfig = computed<IFormConfig[]>(() => [ ...@@ -282,15 +259,51 @@ const formConfig = computed<IFormConfig[]>(() => [
}, },
], ],
}, },
{ {
prop: 'serviceCode', prop: 'serviceCode',
type: 'input',
label: '物流编码', label: '物流编码',
fixed: 'last', fixed: 'last',
attrs: { render: () => {
placeholder: '请输入物流编码', const company = editForm.value.company
return (
<div style="display: flex; width:100%;height: 100%">
<el-input
v-model={editForm.value.serviceCode}
placeholder="请输入物流编码"
/>
<el-popover
placement="bottom-end"
width={1050}
v-slots={{
default: () => (
<div style="width: 100%; height: 100%;">
<div style="font-size: 20px; font-weight: bold;margin-bottom: 10px;">
{company ? `${company}物流编码来源图:` : '请先选择物流公司'}
</div>
{company && imgeList.value[company] && (
<img
src={imgeList.value[company]}
style={{ width: '100%' }}
alt={`${company}物流编码图`}
/>
)}
</div>
),
reference: () => (
<el-icon
style={{ marginLeft: '10px', height: '100%' }}
size={25}
>
<WarningFilled />
</el-icon>
),
}}
></el-popover>
</div>
)
}, },
rules: [ rules: [
{ {
required: true, required: true,
...@@ -299,6 +312,37 @@ const formConfig = computed<IFormConfig[]>(() => [ ...@@ -299,6 +312,37 @@ const formConfig = computed<IFormConfig[]>(() => [
], ],
}, },
{ {
prop: 'name',
type: 'input',
label: '物流名称',
fixed: 'last',
attrs: {
placeholder: '请输入物流名称',
},
rules: [
{
required: true,
message: '请输入物流名称',
},
],
},
{
prop: 'warehouseId',
type: 'select',
label: '仓库名称',
fixed: 'last',
attrs: {
placeholder: '请选择仓库名称',
label: 'name',
value: 'id',
options: [...(warehouseList.value || [])],
onChange: (item: WarehouseListData) => {
editForm.value.warehouseName = item.name
},
},
},
{
prop: 'siteUrl', prop: 'siteUrl',
type: 'input', type: 'input',
label: '查询网址', label: '查询网址',
...@@ -351,12 +395,43 @@ const formConfig = computed<IFormConfig[]>(() => [ ...@@ -351,12 +395,43 @@ const formConfig = computed<IFormConfig[]>(() => [
collapse-tags collapse-tags
collapse-tags-tooltip collapse-tags-tooltip
v-model={item['showPlatform']} v-model={item['showPlatform']}
disabled={index === 0}
> >
{platformList.value?.map((el, idx) => ( {platformList.value?.map((el, idx) => (
<el-option label={el} value={el} key={idx}></el-option> <el-option label={el} value={el} key={idx}></el-option>
))} ))}
</el-select> </el-select>
</el-form-item> </el-form-item>
{item['showPlatform'].length === 1 &&
item['showPlatform'][0] === 'TIKTOK' ? (
<el-form-item
key={index}
class="renderItem"
label="物流名称"
style="display: flex;flex:50%"
prop={`platformList.${index}.logisticsName`}
rules={[
{
required: true,
message: '请输入物流名称',
trigger: 'blur',
},
]}
>
<el-select
v-model={item.logisticsName}
placeholder="请选择物流名称"
>
{tiktokCarriers.value?.map((el) => (
<el-option
label={el.name}
value={el.name}
key={el.id}
></el-option>
))}{' '}
</el-select>
</el-form-item>
) : (
<el-form-item <el-form-item
key={index} key={index}
class="renderItem" class="renderItem"
...@@ -376,7 +451,8 @@ const formConfig = computed<IFormConfig[]>(() => [ ...@@ -376,7 +451,8 @@ const formConfig = computed<IFormConfig[]>(() => [
placeholder="请输入物流名称" placeholder="请输入物流名称"
/> />
</el-form-item> </el-form-item>
<div style="display: flex;flex:20%"> )}
<div style="display: flex;flex:17%">
{(formData?.platformList as platformObj[])?.length - 1 === {(formData?.platformList as platformObj[])?.length - 1 ===
index && ( index && (
<el-button <el-button
...@@ -531,6 +607,7 @@ const tableConfig = ref<TableColumn[]>([ ...@@ -531,6 +607,7 @@ const tableConfig = ref<TableColumn[]>([
onMounted(() => { onMounted(() => {
getAllList() getAllList()
getTiktokCarriers()
}) })
/** /**
...@@ -674,7 +751,7 @@ const save = debounce(async () => { ...@@ -674,7 +751,7 @@ const save = debounce(async () => {
return return
} }
} }
}, 400) }, 200)
/** /**
* @description: 新增按钮打开弹窗 * @description: 新增按钮打开弹窗
...@@ -751,14 +828,20 @@ function deleteCol(index: number) { ...@@ -751,14 +828,20 @@ function deleteCol(index: number) {
async function getAllList() { async function getAllList() {
try { try {
const res = await Promise.allSettled([ const res = await Promise.allSettled([
getWarehouseList(), loadWarehouseListApi(),
getRuleList(), getRuleList(),
getPlatformList(), getPlatformList(),
getLogisticsCompanyList(), getLogisticsCompanyList(),
getUniuniList(), getUniuniList(),
]) ])
res.forEach( res.forEach(
(item: PromiseSettledResult<{ code: number; data: never[] }>, index) => { (
item: PromiseSettledResult<{
code: number
data: WarehouseListData[] | never[]
}>,
index,
) => {
if (item.status === 'fulfilled') { if (item.status === 'fulfilled') {
if (item.value.code === 200) { if (item.value.code === 200) {
if (index == 0) { if (index == 0) {
...@@ -766,13 +849,13 @@ async function getAllList() { ...@@ -766,13 +849,13 @@ async function getAllList() {
} else if (index == 1) { } else if (index == 1) {
console.log(758, item.value.data) console.log(758, item.value.data)
ruleNameList.value = item.value.data || [] ruleNameList.value = (item.value.data as never[]) || []
} else if (index == 2) { } else if (index == 2) {
platformList.value = item.value.data || [] platformList.value = (item.value.data as never[]) || []
} else if (index == 3) { } else if (index == 3) {
logisticsCompanyList.value = item.value.data || [] logisticsCompanyList.value = (item.value.data as never[]) || []
} else if (index == 4) { } else if (index == 4) {
uniuniList.value = item.value.data || [] uniuniList.value = (item.value.data as never[]) || []
} }
} }
} }
...@@ -785,6 +868,15 @@ async function getAllList() { ...@@ -785,6 +868,15 @@ async function getAllList() {
} }
} }
const tiktokCarriers = ref<{ name: string; id: number }[]>([])
/**
* @description: 获取tictok物流承运商
*/
async function getTiktokCarriers() {
const { data } = await getTiktokCarrier()
tiktokCarriers.value = data
}
/** /**
* @description: 日志弹窗 * @description: 日志弹窗
*/ */
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
align="center" align="center"
border="full" border="full"
@getCheckboxRecords="handleCheckboxRecords" @getCheckboxRecords="handleCheckboxRecords"
:otherAttrs="{
fixed: 'left',
}"
></CustomizeTable> ></CustomizeTable>
</div> </div>
</div> </div>
...@@ -58,7 +61,6 @@ import { ...@@ -58,7 +61,6 @@ import {
updateLogisticsZone, updateLogisticsZone,
deleteLogisticsZone, deleteLogisticsZone,
importLogisticsZone, importLogisticsZone,
exportExcelLogisticsZone,
getlogisticsWayAllList, getlogisticsWayAllList,
} from '@/api/logistics' } from '@/api/logistics'
...@@ -217,7 +219,11 @@ async function getList(data?: { ...@@ -217,7 +219,11 @@ async function getList(data?: {
logisticsIdList?: string[] | string logisticsIdList?: string[] | string
codePrefix?: string codePrefix?: string
}) { }) {
loading.value = true const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
try { try {
const res = await getLogisticsZoneList({ const res = await getLogisticsZoneList({
...data, ...data,
...@@ -232,6 +238,7 @@ async function getList(data?: { ...@@ -232,6 +238,7 @@ async function getList(data?: {
{ {
prop: 'zoneName', prop: 'zoneName',
label: '分区', label: '分区',
attrs: { 'min-width': '100px', fixed: 'left' },
}, },
] ]
const newConfig = [] const newConfig = []
...@@ -243,6 +250,7 @@ async function getList(data?: { ...@@ -243,6 +250,7 @@ async function getList(data?: {
label: key, label: key,
attrs: { attrs: {
'edit-render': {}, 'edit-render': {},
'min-width': '300px',
}, },
render: { render: {
edit: ({ edit: ({
...@@ -296,7 +304,7 @@ async function getList(data?: { ...@@ -296,7 +304,7 @@ async function getList(data?: {
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} finally { } finally {
loading.value = false loading.close()
} }
} }
...@@ -387,13 +395,11 @@ function onBeforeUploadImage(file: File) { ...@@ -387,13 +395,11 @@ function onBeforeUploadImage(file: File) {
*/ */
async function downloadExcel() { async function downloadExcel() {
try { try {
const res = await exportExcelLogisticsZone()
const blob = new Blob([res as unknown as BlobPart])
const filename = '物流分区模版.xlsx'
const link = document.createElement('a') const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob) link.href = '/files/logisticsZoning.xlsx'
link.download = filename link.download = '物流分区模版.xlsx'
link.click() link.click()
document.body.removeChild(link)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }
...@@ -410,10 +416,11 @@ async function exportExcel(file: { file: File }) { ...@@ -410,10 +416,11 @@ async function exportExcel(file: { file: File }) {
const res = await importLogisticsZone(formData) const res = await importLogisticsZone(formData)
if (res.code === 200) { if (res.code === 200) {
ElMessage.success('导入成功!') ElMessage.success('导入成功!')
getList(searchForm.value)
} }
} catch (error) { } catch (error) {
ElMessage.error('导入失败!') ElMessage.error('导入失败!')
} finally {
getList(searchForm.value)
} }
} }
......
...@@ -30,7 +30,13 @@ export default function useShipment(callback?: () => void) { ...@@ -30,7 +30,13 @@ export default function useShipment(callback?: () => void) {
const shipmentLoading = ref(false) const shipmentLoading = ref(false)
const shipmentOrderRef = ref<ShipmentType>() const shipmentOrderRef = ref<ShipmentType>()
const searchShipmentByOrderNumber = async () => { const searchShipmentByOrderNumber = async () => {
const code = productionOrderNumber.value let code = productionOrderNumber.value
// AAAB_60527128-9_1_JMSC250121017 新版示例
const regex = /^[A-Z]{4}_/ //是否以四个大写字母加下划线开头
if (regex.test(code)) {
code =
code.split('_')[0] + '-' + code.split('_')[code.split('_').length - 1]
}
shipmentVisible.value = true shipmentVisible.value = true
if (!code) { if (!code) {
isLock.value = false isLock.value = false
......
import { getQaOrderBySubOrderNumber, qaFinishedApi } from '@/api/order' import { getQaOrderBySubOrderNumber, qaFinishedApi } from '@/api/order'
import { InspectionData, QaData, shopRemark } from '@/types/api/order' import { InspectionData, QaData, shopRemark } from '@/types/api/order'
import { useValue } from '@/utils/hooks/useValue' import { useValue, getLastSegment } from '@/utils/hooks/useValue'
import { showConfirm } from '@/utils/ui' import { showConfirm } from '@/utils/ui'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
...@@ -45,9 +45,10 @@ export default function useQuarantine() { ...@@ -45,9 +45,10 @@ export default function useQuarantine() {
return indexList return indexList
} }
const searchQaByOrderNumber = () => { const searchQaByOrderNumber = () => {
const uid = shipmentUid.value const uid = shipmentUid.value
const code = qaCode.value const code = qaCode.value.startsWith('GCSC')
? qaCode.value
: getLastSegment(qaCode.value)
if (!code) { if (!code) {
isLock.value = false isLock.value = false
playAudio('picking_warning') playAudio('picking_warning')
...@@ -83,7 +84,12 @@ export default function useQuarantine() { ...@@ -83,7 +84,12 @@ export default function useQuarantine() {
// 查找是否已经存在 // 查找是否已经存在
const row = sourceData.value.find( const row = sourceData.value.find(
(item) => (item) =>
(uid === item.shipmentUid && (code1 === item.subOrderNumber || item.factorySubOrderNumber == code1)) || (!uid && (item.factorySubOrderNumber == code1 || item.subOrderNumber == code1)), (uid === item.shipmentUid &&
(code1 === item.subOrderNumber ||
item.factorySubOrderNumber == code1)) ||
(!uid &&
(item.factorySubOrderNumber == code1 ||
item.subOrderNumber == code1)),
) )
if (row) { if (row) {
// 质检数量不能大于发货数量 // 质检数量不能大于发货数量
...@@ -100,7 +106,10 @@ export default function useQuarantine() { ...@@ -100,7 +106,10 @@ export default function useQuarantine() {
offset: window.innerHeight / 2, offset: window.innerHeight / 2,
}) })
} }
const len = sourceData.value.filter(el => el.factorySubOrderNumber == code1 || code1 === el.subOrderNumber) const len = sourceData.value.filter(
(el) =>
el.factorySubOrderNumber == code1 || code1 === el.subOrderNumber,
)
const scansNum = sourceData.value[index].scansNum || 0 const scansNum = sourceData.value[index].scansNum || 0
const indexList = findAllIndex(code1) const indexList = findAllIndex(code1)
...@@ -111,7 +120,6 @@ export default function useQuarantine() { ...@@ -111,7 +120,6 @@ export default function useQuarantine() {
sourceData.value[i]['scansNum'] = scansNum + 1 sourceData.value[i]['scansNum'] = scansNum + 1
} }
}) })
} else { } else {
if (row.shipmentNum !== scansNum) { if (row.shipmentNum !== scansNum) {
sourceData.value[index]['scansNum'] = scansNum + 1 sourceData.value[index]['scansNum'] = scansNum + 1
...@@ -163,17 +171,32 @@ export default function useQuarantine() { ...@@ -163,17 +171,32 @@ export default function useQuarantine() {
Number(e.shipmentNum || 0) === Number(e.shipmentNum || 0) ===
Number(e.passNum || 0) + Number(e.notPassNum || 0), Number(e.passNum || 0) + Number(e.notPassNum || 0),
).length ).length
const row = sourceData.value.find(item => { const row = sourceData.value.find((item) => {
return (uid === item.shipmentUid && (code1 === item.subOrderNumber || item.factorySubOrderNumber == code1)) || (!uid && (item.factorySubOrderNumber == code1 || item.subOrderNumber == code1)) return (
(uid === item.shipmentUid &&
(code1 === item.subOrderNumber ||
item.factorySubOrderNumber == code1)) ||
(!uid &&
(item.factorySubOrderNumber == code1 ||
item.subOrderNumber == code1))
)
}) })
const index = sourceData.value.findIndex(item => { const index = sourceData.value.findIndex((item) => {
return (uid === item.shipmentUid && (code1 === item.subOrderNumber || item.factorySubOrderNumber == code1)) || (!uid && (item.factorySubOrderNumber == code1 || item.subOrderNumber == code1)) return (
(uid === item.shipmentUid &&
(code1 === item.subOrderNumber ||
item.factorySubOrderNumber == code1)) ||
(!uid &&
(item.factorySubOrderNumber == code1 ||
item.subOrderNumber == code1))
)
}) })
if (row) { if (row) {
// row.passNum += 1 // row.passNum += 1
currentRow.value = row currentRow.value = row
cloneRow.value = JSON.parse(JSON.stringify(currentRow.value)) cloneRow.value = JSON.parse(JSON.stringify(currentRow.value))
if (!row.inspectionStatus && !sourceData.value[index].scansNum) sourceData.value[index].scansNum = 1 if (!row.inspectionStatus && !sourceData.value[index].scansNum)
sourceData.value[index].scansNum = 1
} }
qaInputRef.value.focus() qaInputRef.value.focus()
isLock.value = false isLock.value = false
......
import { getOrderBySubOrderNumber, saveOrder } from '@/api/order' import { getOrderBySubOrderNumber, saveOrder } from '@/api/order'
import { ICompareObjects, OrderData, ProductList, ShipmentForm, ShipmentOrderRes } from '@/types/api/order' import {
import { useValue } from '@/utils/hooks/useValue' ICompareObjects,
OrderData,
ProductList,
ShipmentForm,
ShipmentOrderRes,
} from '@/types/api/order'
import { useValue, getLastSegment } from '@/utils/hooks/useValue'
import { nextTick, ref } from 'vue' import { nextTick, ref } from 'vue'
import { ShipmentType } from '../Shipment.vue' import { ShipmentType } from '../Shipment.vue'
...@@ -24,7 +30,10 @@ export default function useShipment(callback?: () => void) { ...@@ -24,7 +30,10 @@ export default function useShipment(callback?: () => void) {
const shipmentLoading = ref(false) const shipmentLoading = ref(false)
const shipmentOrderRef = ref<ShipmentType>() const shipmentOrderRef = ref<ShipmentType>()
const searchShipmentByOrderNumber = async () => { const searchShipmentByOrderNumber = async () => {
const code = productionOrderNumber.value // const code = getLastSegment(productionOrderNumber.value)
const code = productionOrderNumber.value.startsWith('GCSC')
? productionOrderNumber.value
: getLastSegment(productionOrderNumber.value)
shipmentVisible.value = true shipmentVisible.value = true
if (!code) { if (!code) {
isLock.value = false isLock.value = false
...@@ -98,8 +107,7 @@ export default function useShipment(callback?: () => void) { ...@@ -98,8 +107,7 @@ export default function useShipment(callback?: () => void) {
ElMessageBox.confirm('不能加入,地址信息不一致!', '重要提示', { ElMessageBox.confirm('不能加入,地址信息不一致!', '重要提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
type: 'warning', type: 'warning',
}).catch(() => { }).catch(() => {})
})
} else { } else {
canJoin(res.data, code) canJoin(res.data, code)
} }
...@@ -213,7 +221,7 @@ export default function useShipment(callback?: () => void) { ...@@ -213,7 +221,7 @@ export default function useShipment(callback?: () => void) {
try { try {
const res = await saveOrder(data, shipmentForm.value) const res = await saveOrder(data, shipmentForm.value)
fetch(res.message || '') fetch(res.message || '')
.then(response => { .then((response) => {
// 确保响应是 OK // 确保响应是 OK
if (!response.ok) { if (!response.ok) {
throw new Error('网络响应错误') throw new Error('网络响应错误')
...@@ -221,14 +229,16 @@ export default function useShipment(callback?: () => void) { ...@@ -221,14 +229,16 @@ export default function useShipment(callback?: () => void) {
// 返回图片的二进制数据(Blob) // 返回图片的二进制数据(Blob)
return response.blob() return response.blob()
}) })
.then(blob => { .then((blob) => {
const a = document.createElement('a') const a = document.createElement('a')
a.href = window.URL.createObjectURL(blob) a.href = window.URL.createObjectURL(blob)
a.target = '_blank' a.target = '_blank'
a.download = (res.message as string).split('/')[ (res.message as string).split('/').length - 1] a.download = (res.message as string).split('/')[
(res.message as string).split('/').length - 1
]
a.click() a.click()
}) })
.catch(error => { .catch((error) => {
console.error('下载图片时出错:', error) console.error('下载图片时出错:', error)
}) })
ElMessage.success('发货成功') ElMessage.success('发货成功')
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
v-model="searchForm.mainSku" v-model="searchForm.mainSku"
placeholder=" SKU" placeholder=" SKU"
clearable clearable
style="width: 130px" style="width: 125px"
@blur="searchForm.mainSku = searchForm.mainSku.trim()" @blur="searchForm.mainSku = searchForm.mainSku.trim()"
></ElInput> ></ElInput>
</ElFormItem> </ElFormItem>
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
v-model="searchForm.endProductId" v-model="searchForm.endProductId"
placeholder="请输入成品ID" placeholder="请输入成品ID"
clearable clearable
style="width: 130px" style="width: 125px"
@blur=" @blur="
searchForm.endProductId = searchForm.endProductId.trim() searchForm.endProductId = searchForm.endProductId.trim()
" "
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
v-model="searchForm.subOrderNumber" v-model="searchForm.subOrderNumber"
placeholder="生产单号" placeholder="生产单号"
clearable clearable
style="width: 130px" style="width: 125px"
@blur=" @blur="
searchForm.subOrderNumber = searchForm.subOrderNumber.trim() searchForm.subOrderNumber = searchForm.subOrderNumber.trim()
" "
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
v-model="searchForm.orderNumber" v-model="searchForm.orderNumber"
placeholder="订单号" placeholder="订单号"
clearable clearable
style="width: 130px" style="width: 125px"
@blur="searchForm.orderNumber = searchForm.orderNumber.trim()" @blur="searchForm.orderNumber = searchForm.orderNumber.trim()"
></ElInput> ></ElInput>
</ElFormItem> </ElFormItem>
...@@ -91,7 +91,7 @@ ...@@ -91,7 +91,7 @@
v-model="searchForm.shopNumber" v-model="searchForm.shopNumber"
placeholder="店铺单号" placeholder="店铺单号"
clearable clearable
style="width: 130px" style="width: 125px"
@blur="searchForm.shopNumber = searchForm.shopNumber.trim()" @blur="searchForm.shopNumber = searchForm.shopNumber.trim()"
></ElInput> ></ElInput>
</ElFormItem> </ElFormItem>
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
v-model="searchForm.internalMemo" v-model="searchForm.internalMemo"
placeholder="内部标签" placeholder="内部标签"
clearable clearable
style="width: 130px" style="width: 125px"
@blur=" @blur="
searchForm.internalMemo = searchForm.internalMemo.trim() searchForm.internalMemo = searchForm.internalMemo.trim()
" "
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
v-model="searchForm.logisticsTracking" v-model="searchForm.logisticsTracking"
placeholder="物流跟踪号" placeholder="物流跟踪号"
clearable clearable
style="width: 130px" style="width: 125px"
@blur=" @blur="
searchForm.logisticsTracking = searchForm.logisticsTracking =
searchForm.logisticsTracking.trim() searchForm.logisticsTracking.trim()
...@@ -123,7 +123,7 @@ ...@@ -123,7 +123,7 @@
v-model="searchForm.billNumber" v-model="searchForm.billNumber"
placeholder="发货单号" placeholder="发货单号"
clearable clearable
style="width: 130px" style="width: 125px"
@blur="searchForm.billNumber = searchForm.billNumber.trim()" @blur="searchForm.billNumber = searchForm.billNumber.trim()"
></ElInput> ></ElInput>
</ElFormItem> </ElFormItem>
...@@ -132,7 +132,7 @@ ...@@ -132,7 +132,7 @@
v-model="searchForm.lanshouName" v-model="searchForm.lanshouName"
placeholder="收货人" placeholder="收货人"
clearable clearable
style="width: 130px" style="width: 125px"
></ElInput> ></ElInput>
</ElFormItem> </ElFormItem>
<ElFormItem label="排序"> <ElFormItem label="排序">
...@@ -152,39 +152,13 @@ ...@@ -152,39 +152,13 @@
<!-- <ElFormItem>--> <!-- <ElFormItem>-->
<!-- <ElButton @click="resetSearchForm">重置</ElButton>--> <!-- <ElButton @click="resetSearchForm">重置</ElButton>-->
<!-- </ElFormItem>--> <!-- </ElFormItem>-->
</ElForm> <ElFormItem v-if="statusCode === 2">
</div>
<div class="header-filter-tab">
<div class="tabs">
<div
v-for="item in tabsNav"
:key="item.statusCode"
class="tabs-node"
:class="
item.statusCode === statusCode ? 'tabs-node_active' : ''
"
@click="changeTab(item)"
>
<span class="tabs-node_label">{{ item.statusName }}</span>
<span class="tabs-node_count">{{ `(${item.quantity})` }}</span>
</div>
</div>
</div>
</div>
</template>
<template #bottom>
<div class="order-content flex-1 flex-column overflow-hidden">
<!-- 操作按钮 -->
<div class="order-operate-btn">
<span v-if="statusCode === 2" class="item">
<ElButton type="success" @click="confirmProduce" <ElButton type="success" @click="confirmProduce"
>确认生产</ElButton >确认生产</ElButton
> >
</span> </ElFormItem>
<ElFormItem
<span
v-if="statusCode === 2 || statusCode === 3 || statusCode === 4" v-if="statusCode === 2 || statusCode === 3 || statusCode === 4"
class="item"
> >
<ElButton <ElButton
:disabled=" :disabled="
...@@ -195,10 +169,9 @@ ...@@ -195,10 +169,9 @@
@click="downloadManuscript" @click="downloadManuscript"
>下载稿件</ElButton >下载稿件</ElButton
> >
</span> </ElFormItem>
<span <ElFormItem
v-if="statusCode === 2 || statusCode === 3 || statusCode === 4" v-if="statusCode === 2 || statusCode === 3 || statusCode === 4"
class="item"
> >
<ElButton <ElButton
:disabled=" :disabled="
...@@ -210,10 +183,9 @@ ...@@ -210,10 +183,9 @@
@click="reGenerateManuscript" @click="reGenerateManuscript"
>重新打包稿件 >重新打包稿件
</ElButton> </ElButton>
</span> </ElFormItem>
<span <ElFormItem
v-if="statusCode === 2 || statusCode === 3 || statusCode === 4" v-if="statusCode === 2 || statusCode === 3 || statusCode === 4"
class="item"
> >
<ElButton <ElButton
:disabled=" :disabled="
...@@ -225,10 +197,9 @@ ...@@ -225,10 +197,9 @@
@click="reCreateManuscript" @click="reCreateManuscript"
>重新生成稿件 >重新生成稿件
</ElButton> </ElButton>
</span> </ElFormItem>
<span <ElFormItem
v-if="statusCode === 2 || statusCode === 3 || statusCode === 4" v-if="statusCode === 2 || statusCode === 3 || statusCode === 4"
class="item"
> >
<ElButton <ElButton
:loading="btnLoading" :loading="btnLoading"
...@@ -237,35 +208,56 @@ ...@@ -237,35 +208,56 @@
@click="printManuscript" @click="printManuscript"
>打印生产单</ElButton >打印生产单</ElButton
> >
</span> </ElFormItem>
<span <ElFormItem
v-if="statusCode === 2 || statusCode === 3 || statusCode === 7" v-if="statusCode === 2 || statusCode === 3 || statusCode === 7"
class="item"
> >
<ElButton type="success" dark @click="exportManuscript" <ElButton type="success" dark @click="exportManuscript"
>导出生产单</ElButton >导出生产单</ElButton
> >
</span> </ElFormItem>
<span class="item"> <ElFormItem>
<ElButton type="warning" @click="addInternalTag" <ElButton type="warning" @click="addInternalTag"
>添加内部标签</ElButton >添加内部标签</ElButton
> >
</span> </ElFormItem>
<span <ElFormItem
v-if="statusCode === 2 || statusCode === 3 || statusCode === 4" v-if="statusCode === 2 || statusCode === 3 || statusCode === 4"
class="item"
> >
<ElButton type="primary" @click="refreshProduct" <ElButton type="primary" @click="refreshProduct"
>刷新商品信息</ElButton >刷新商品信息</ElButton
> >
</span> </ElFormItem>
<span v-if="statusCode === 3 || statusCode === 4" class="item"> <ElFormItem v-if="statusCode === 3 || statusCode === 4">
<ElButton type="success" @click="confirmDelivery">发货</ElButton> <ElButton type="success" @click="confirmDelivery"
</span> >发货</ElButton
<span v-if="statusCode === 6" class="item"> >
</ElFormItem>
<ElFormItem v-if="statusCode === 6">
<ElButton type="success" @click="confirmCheck">质检</ElButton> <ElButton type="success" @click="confirmCheck">质检</ElButton>
</span> </ElFormItem>
</ElForm>
</div>
<div class="header-filter-tab">
<div class="tabs">
<div
v-for="item in tabsNav"
:key="item.statusCode"
class="tabs-node"
:class="
item.statusCode === statusCode ? 'tabs-node_active' : ''
"
@click="changeTab(item)"
>
<span class="tabs-node_label">{{ item.statusName }}</span>
<span class="tabs-node_count">{{ `(${item.quantity})` }}</span>
</div>
</div>
</div> </div>
</div>
</template>
<template #bottom>
<div class="order-content flex-1 flex-column overflow-hidden">
<div <div
ref="tableWrapperRef" ref="tableWrapperRef"
v-loading="loading" v-loading="loading"
......
...@@ -392,8 +392,20 @@ watch( ...@@ -392,8 +392,20 @@ watch(
{ url: d.negativeImage, title: '反面', id: d.negativeDesignId }, { url: d.negativeImage, title: '反面', id: d.negativeDesignId },
].filter((el) => el.url) ].filter((el) => el.url)
} else { } else {
arr = arr = Array.isArray(d.imageAry)
typeof d.imageAry == 'string' ? JSON.parse(d.imageAry) : d.imageAry ? d.imageAry
: typeof d.imageAry === 'string'
? (() => {
try {
const parsed = JSON.parse(d.imageAry)
return parsed
} catch {
return [{ url: d.imageAry }]
}
})()
: [d.imageAry]?.filter?.((v) => v != null) || []
// arr =
// typeof d.imageAry == 'string' ? JSON.parse(d.imageAry) : d.imageAry
arr = arr.concat([ arr = arr.concat([
{ url: d.negativeImage, title: '反面', id: d.negativeDesignId }, { url: d.negativeImage, title: '反面', id: d.negativeDesignId },
]) ])
...@@ -579,7 +591,7 @@ const trackcodeInput = async () => { ...@@ -579,7 +591,7 @@ const trackcodeInput = async () => {
localStorage.setItem('historyData', JSON.stringify(historyData.value)) localStorage.setItem('historyData', JSON.stringify(historyData.value))
} }
const orderNumber = TrackingNumber.value let orderNumber = TrackingNumber.value
TrackingNumber.value = '' TrackingNumber.value = ''
if (props.type === 1) { if (props.type === 1) {
if (isAutoSure.value) { if (isAutoSure.value) {
...@@ -588,9 +600,17 @@ const trackcodeInput = async () => { ...@@ -588,9 +600,17 @@ const trackcodeInput = async () => {
} else { } else {
await setData(orderNumber) await setData(orderNumber)
} }
// AAAB_60527128-9_1_JMSC250121017 新版示例
const regex = /^[A-Z]{4}_/ //是否以四个大写字母加下划线开头
if (regex.test(orderNumber)) {
orderNumber =
orderNumber.split('_')[0] +
'-' +
orderNumber.split('_')[orderNumber.split('_').length - 1]
}
try { try {
const res = await getSubOrderBySubOrderNumber(orderNumber) const res = await getSubOrderBySubOrderNumber(orderNumber)
if(!res.data){ if (!res.data) {
return ElMessage.error('生产单不存在') return ElMessage.error('生产单不存在')
} }
const d = JSON.parse(JSON.stringify(res.data)) const d = JSON.parse(JSON.stringify(res.data))
...@@ -607,10 +627,28 @@ const trackcodeInput = async () => { ...@@ -607,10 +627,28 @@ const trackcodeInput = async () => {
{ url: d.negativeImage, title: '反面', id: d.negativeDesignId }, { url: d.negativeImage, title: '反面', id: d.negativeDesignId },
].filter((el) => el.url) ].filter((el) => el.url)
} else { } else {
arr = typeof d.imageAry == 'string' ? JSON.parse(d.imageAry) : d.imageAry arr = Array.isArray(d.imageAry)
? d.imageAry
: typeof d.imageAry === 'string'
? (() => {
try {
const parsed = JSON.parse(d.imageAry)
return parsed
} catch {
return [{ url: d.imageAry }]
}
})()
: [d.imageAry]?.filter?.((v) => v != null) || []
// arr = typeof d.imageAry == 'string' ? JSON.parse(d.imageAry) : d.imageAry
arr = arr.concat([ arr = arr.concat([
{ url: d.negativeImage, title: '反面', id: d.negativeDesignId }, { url: d.negativeImage, title: '反面', id: d.negativeDesignId },
]) ])
arr.forEach((item: { url: string; id: string; title: string }) => {
if (item.url && item.url.startsWith('/')) {
item.url = 'https://img.jomalls.com/upload/erp' + item.url
}
})
} }
const result = [] const result = []
arr = arr.filter((el: ImageItemInter) => el.url) arr = arr.filter((el: ImageItemInter) => el.url)
......
...@@ -6,7 +6,12 @@ ...@@ -6,7 +6,12 @@
:fullscreen="true" :fullscreen="true"
:close-on-click-modal="false" :close-on-click-modal="false"
@opened="onOpened" @opened="onOpened"
@close="emit('close')" @close="
() => {
emit('onSuccess')
emit('close')
}
"
> >
<div class="detail-div"> <div class="detail-div">
<div class="detail-content"> <div class="detail-content">
...@@ -85,12 +90,26 @@ ...@@ -85,12 +90,26 @@
<p> <p>
{{ detail?.factorySubOrderNumber }} {{ detail?.factorySubOrderNumber }}
</p> </p>
<el-icon
v-if="detail?.factorySubOrderNumber"
class="icon"
@click="copy(detail?.factorySubOrderNumber || '')"
>
<DocumentCopy />
</el-icon>
</div> </div>
<div :title="detail?.thirdSubOrderNumber || ''" class="div-item"> <div :title="detail?.thirdSubOrderNumber || ''" class="div-item">
<span>第三方生产单号</span> <span>第三方生产单号</span>
<p> <p>
{{ detail?.thirdSubOrderNumber }} {{ detail?.thirdSubOrderNumber }}
</p> </p>
<el-icon
v-if="detail?.thirdSubOrderNumber"
class="icon"
@click="copy(detail?.thirdSubOrderNumber || '')"
>
<DocumentCopy />
</el-icon>
</div> </div>
<div :title="String(detail?.craftName)" class="div-item"> <div :title="String(detail?.craftName)" class="div-item">
<span>生产工艺</span> <span>生产工艺</span>
...@@ -120,6 +139,13 @@ ...@@ -120,6 +139,13 @@
<div :title="detail?.shopNumber ?? ''" class="div-item"> <div :title="detail?.shopNumber ?? ''" class="div-item">
<span>店铺单号</span> <span>店铺单号</span>
<p>{{ detail?.shopNumber ?? '' }}</p> <p>{{ detail?.shopNumber ?? '' }}</p>
<el-icon
v-if="detail?.shopNumber"
class="icon"
@click="copy(detail?.shopNumber || '')"
>
<DocumentCopy />
</el-icon>
</div> </div>
<div :title="detail?.createTime" class="div-item"> <div :title="detail?.createTime" class="div-item">
...@@ -198,6 +224,8 @@ import { ...@@ -198,6 +224,8 @@ import {
getSubOrderBySubOrderNumber, getSubOrderBySubOrderNumber,
downloadMaterialApi, downloadMaterialApi,
} from '@/api/podUsOrder' } from '@/api/podUsOrder'
import { DocumentCopy } from '@element-plus/icons-vue'
import { cardImages, PodOrderRes } from '@/types/api/podUsOrder' import { cardImages, PodOrderRes } from '@/types/api/podUsOrder'
import { showConfirm } from '@/utils/ui' import { showConfirm } from '@/utils/ui'
import { filePath } from '@/api/axios' import { filePath } from '@/api/axios'
...@@ -313,22 +341,27 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => { ...@@ -313,22 +341,27 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => {
type: 'warning', type: 'warning',
}) })
.then(async () => { .then(async () => {
try {
TrackingNumber.value = el.orderNumber TrackingNumber.value = el.orderNumber
await trackCodeInput() await trackCodeInput()
await setData(el.orderNumber) await setData(el.orderNumber)
ElMessage.success('生产完成')
// ElMessage.success('生产完成')
} catch (error) {
console.log(777)
console.log(error)
removeFromHistory()
} finally {
if (len[i + 1]) { if (len[i + 1]) {
confirmQuery(len, i + 1) confirmQuery(len, i + 1)
} }
}
}) })
.catch(() => { .catch(() => {
const index = historyData.value.findIndex( removeFromHistory()
(item: HistoryDataItem) => item.orderNumber === el.orderNumber,
)
if (index >= 0) {
historyData.value.splice(index, 1)
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
if (len[i + 1]) { if (len[i + 1]) {
confirmQuery(len, i + 1) confirmQuery(len, i + 1)
} }
...@@ -336,6 +369,11 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => { ...@@ -336,6 +369,11 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => {
}) })
} }
const removeFromHistory = () => {
historyData.value = []
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
const changeStatus = async () => { const changeStatus = async () => {
if (!detail.value || Object.keys(detail.value).length <= 1) { if (!detail.value || Object.keys(detail.value).length <= 1) {
return ElMessage.warning('请扫码生产单号') return ElMessage.warning('请扫码生产单号')
...@@ -353,19 +391,46 @@ const setData = async (orderNumber: string) => { ...@@ -353,19 +391,46 @@ const setData = async (orderNumber: string) => {
try { try {
const id = detail.value.id const id = detail.value.id
const podJomallOrderUsId = detail.value.podJomallOrderUsId const podJomallOrderUsId = detail.value.podJomallOrderUsId
await productionQueryApi(id, podJomallOrderUsId) if (
detail.value?.num !== undefined &&
detail.value?.passNum !== undefined
) {
const { num, passNum } = detail.value
if (num == passNum) {
await showConfirm('该生产单已经完成生产,请勿重复生产', {
confirmButtonText: '确定',
if (orderNumber) { type: 'warning',
const index = historyData.value.findIndex( })
(el: HistoryDataItem) => el.orderNumber === orderNumber, TrackingNumber.value = ''
isDownloadImage.value = false
trackingNumberRef.value && trackingNumberRef.value.focus()
throw new Error()
} else if (num < passNum) {
await showConfirm(
`生产单号:${detail.value.factorySubOrderNumber} 已经重复生产${
passNum - num
}件,请检查!`,
{
confirmButtonText: '确定',
type: 'warning',
},
) )
if (index >= 0) { TrackingNumber.value = ''
// 扫单完成删除 isDownloadImage.value = false
historyData.value.splice(index, 1) trackingNumberRef.value && trackingNumberRef.value.focus()
localStorage.setItem('historyUsData', JSON.stringify(historyData.value)) throw new Error()
} else {
await productionQueryApi(id, podJomallOrderUsId)
ElMessage.success('生产完成')
} }
} }
emit('onSuccess') console.log(999)
if (orderNumber) {
removeFromHistory()
}
playAudio('weight_success') playAudio('weight_success')
detail.value = { detail.value = {
id: -1, id: -1,
...@@ -377,13 +442,19 @@ const setData = async (orderNumber: string) => { ...@@ -377,13 +442,19 @@ const setData = async (orderNumber: string) => {
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
} catch (e) { } catch (e) {
console.error(e) console.error(e)
if (orderNumber) {
removeFromHistory()
}
detail.value = { detail.value = {
id: -1, id: -1,
podJomallOrderUsId: -1, podJomallOrderUsId: -1,
imgList: [] as cardImages[], imgList: [] as cardImages[],
} }
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
playAudio('weight_search_error') throw e
// playAudio('weight_search_error')
} }
} }
...@@ -453,29 +524,32 @@ const trackCodeInput = async () => { ...@@ -453,29 +524,32 @@ const trackCodeInput = async () => {
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
return return
} }
const item = historyData.value.find(
(el: HistoryDataItem) => el.orderNumber === TrackingNumber.value,
)
if (!item) {
// 记录扫单
historyData.value.push({
orderNumber: TrackingNumber.value,
finished: false,
})
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
const orderNumber = TrackingNumber.value const orderNumber = TrackingNumber.value
try {
if (isAutoSure.value) { if (isAutoSure.value) {
await setData( await setData(
historyData.value[historyData.value.length - 1].orderNumber || '', historyData.value[historyData.value.length - 1]?.orderNumber || '',
) )
} }
} catch (error) {
console.log(error)
}
// 记录扫单
historyData.value = [
{
orderNumber,
finished: false,
},
]
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
try { try {
const res = await getSubOrderBySubOrderNumber(orderNumber) const res = await getSubOrderBySubOrderNumber(orderNumber)
if (!res.data) { if (!res.data) {
removeFromHistory()
return ElMessage.error('生产单不存在') return ElMessage.error('生产单不存在')
} }
const d = JSON.parse(JSON.stringify(res.data)) const d = JSON.parse(JSON.stringify(res.data))
...@@ -496,11 +570,11 @@ const trackCodeInput = async () => { ...@@ -496,11 +570,11 @@ const trackCodeInput = async () => {
download() download()
} }
playAudio('weight_search_success') playAudio('weight_search_success')
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
TrackingNumber.value = '' TrackingNumber.value = ''
} catch (e) { } catch (e) {
console.error(e) console.error(549, e)
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
TrackingNumber.value = '' TrackingNumber.value = ''
} }
...@@ -508,6 +582,15 @@ const trackCodeInput = async () => { ...@@ -508,6 +582,15 @@ const trackCodeInput = async () => {
const onOpened = () => { const onOpened = () => {
trackingNumberRef.value && trackingNumberRef.value.focus() trackingNumberRef.value && trackingNumberRef.value.focus()
} }
const copy = (text: string) => {
try {
navigator.clipboard.writeText(text)
ElMessage.success('复制成功')
} catch (err) {
console.error('复制失败:', err)
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.sure-btn { .sure-btn {
......
<template>
<div>
<ElDialog
v-model="visible"
title="质检包装"
fullscreen
:close-on-click-modal="false"
:close-on-press-escape="false"
style="top: 60px"
center
modal-class="pod-make-order-dialog"
>
<div class="detail-div">
<div class="left">
<div class="left-images">
<div
class="imagBox"
v-for="(item, index) in detail?.imgList"
:key="index"
>
<div
v-show="item?.title && item?.url"
style="font-size: 30px; font-weight: 700; text-align: center"
>
{{ item?.title }}
</div>
<img :src="item.url" alt="" />
</div>
</div>
<div class="tips">
<div>第一次扫码:就绪</div>
<div>第二次扫码:完成</div>
<div>
单子为就绪状态,如果下一个单子状态为完成,则从就绪变为错误
</div>
</div>
</div>
<div class="right">
<div class="input">
<el-input
ref="trackingNumberRef"
v-model="TrackingNumber"
:placeholder="placeholderText"
style="margin-right: 10px"
clearable
@keydown.enter="trackCodeInput()"
></el-input>
<el-button type="primary" @click="trackCodeInput()">
查询
</el-button>
</div>
<div class="printerContent">
<div class="qr">
二维码:<span style="color: #ff0000">{{ 111 }}</span>
</div>
<el-form style="display: flex; gap: 10px">
<el-form-item label="打印机:" style="flex: 1">
<ElSelect
v-model="sheetPrinter"
placeholder="请选择打印机"
@change="handlePrinterChange"
>
<ElOption
v-for="item in printDeviceList"
:key="item"
:label="item"
:value="item"
/>
</ElSelect>
</el-form-item>
<el-form-item label="标签尺寸:" style="flex: 1">
<ElSelect
v-model="sheetPrinter"
placeholder="请选择标签尺寸"
@change="handlePrinterChange"
>
<ElOption
v-for="item in printDeviceList"
:key="item"
:label="item"
:value="item"
/>
</ElSelect>
</el-form-item>
</el-form>
<div class="canvas-container">
<canvas id="canvas" ref="canvas"></canvas>
</div>
</div>
<div class="printQueue">
<div style="font-size: 18px; font-weight: 700; margin-bottom: 10px">
打印队列
</div>
<ul>
<li
v-for="value in 10"
:key="value"
:style="{
color:
value == 1 ? `#006000` : value == 2 ? `#ff0000` : '#000',
}"
>
value
</li>
</ul>
</div>
</div>
</div></ElDialog
>
</div>
</template>
<script setup lang="ts">
import QRCode from 'qrcode'
const visible = ref(false)
const TrackingNumber = ref('')
const placeholderText = ref('扫描枪输入生产单号')
const sheetPrinter = ref('')
const printDeviceList = ref([])
const trackingNumberRef = ref()
const detail = ref({
imgList: [
{
title: 'A',
id: '',
url: 'https://pic3.zhimg.com/v2-e52354ffdbd94a8e0a7649eacd34a788_r.jpg?source=1940ef5c',
},
{
title: 'b',
id: '',
url: 'https://bpic.588ku.com/element_origin_min_pic/23/07/11/d32dabe266d10da8b21bd640a2e9b611.jpg!r650',
},
],
})
function trackCodeInput() {
QRCode.toCanvas(document.getElementById('canvas'), '11', function (error) {
if (error) console.error(error)
console.log('QR code generated!')
})
}
function handlePrinterChange() {}
function open() {
visible.value = true
}
defineExpose({ open })
</script>
<style scoped lang="scss">
.detail-div {
display: flex;
height: 100%;
gap: 20px;
justify-content: space-between;
.left {
flex: 5;
display: flex;
flex-direction: column;
align-items: center;
.left-images {
flex: 1;
display: flex;
height: 100%;
gap: 10px;
.imagBox {
width: 50%;
}
}
.tips {
font-size: 25px;
color: #afafaf;
}
}
.right {
flex: 3;
gap: 20px;
flex-direction: column;
display: flex;
.input {
display: flex;
}
.printerContent {
flex: 6;
border: 1px solid #dcdfe6;
padding: 10px;
padding-bottom: 0;
.qr {
margin-bottom: 10px;
}
}
.printQueue {
flex: 5;
border: 1px solid #dcdfe6;
padding: 10px;
}
}
}
:deep() {
.el-dialog {
.el-dialog__header {
.el-dialog__title {
font-size: 30px !important;
font-weight: 700 !important;
}
}
}
}
.el-form-item {
margin-bottom: 0;
}
.canvas-container {
position: relative;
width: 100%;
height: calc(100% - 61px); /* 1:1 宽高比 */
}
#canvas {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: auto !important;
height: 100% !important;
}
</style>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<el-dialog <el-dialog
title="处理结果" title="处理结果"
v-model="resultDialog" v-model="resultDialog"
width="600px" width="1200px"
:close-on-click-modal="false" :close-on-click-modal="false"
@closed="closedFn" @closed="closedFn"
> >
...@@ -33,8 +33,17 @@ ...@@ -33,8 +33,17 @@
<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">
{{ '工厂订单号:' + item.factoryOrderNumber + ' ' + item.message }} <span
style="
display: inline-block;
width: 100%;
white-space: wrap;
line-height: 22px;
"
> <span>订单号:{{item.factoryOrderNumber}},</span>{{ item.message }}</span
>
</el-checkbox> </el-checkbox>
</div> </div>
</el-checkbox-group> </el-checkbox-group>
...@@ -131,16 +140,12 @@ function closedFn() { ...@@ -131,16 +140,12 @@ function closedFn() {
} }
// 监听弹窗状态 // 监听弹窗状态
// watch( watch(
// () => resultDialog.value, () => resultDialog.value,
// (v) => { (v) => {
// if (v) { console.log(v)
// console.log(127, props.list) },
)
// resultfilter(true)
// }
// },
// )
watch( watch(
() => props.list, () => props.list,
(v) => { (v) => {
......
<script setup lang="ts"> <script setup lang="ts">
import { defineModel } from 'vue' import { defineModel } from 'vue'
import { updateAddressApi } from '@/api/podUsOrder.ts' import { updateAddressApi } from '@/api/podUsOrder.ts'
import {AddressInfo} from '@/types/api/podUsOrder.ts' import { AddressInfo } from '@/types/api/podUsOrder.ts'
const emits = defineEmits(['success']) const emits = defineEmits(['success'])
defineProps<{ defineProps<{
...@@ -45,7 +45,7 @@ const submitForm = async () => { ...@@ -45,7 +45,7 @@ const submitForm = async () => {
visible.value = false visible.value = false
emits('success') emits('success')
await ElMessageBox.alert( await ElMessageBox.alert(
'请修改/刷新地址后取消物流重新创建物流订单、获取跟踪号、获取打印面单。', '请修改/刷新地址后取消物流或者更换物流在重新创建物流订单、获取跟踪号、获取打印面单',
'提示', '提示',
{ {
type: 'warning', type: 'warning',
...@@ -117,6 +117,8 @@ const submitForm = async () => { ...@@ -117,6 +117,8 @@ const submitForm = async () => {
v-model="form.receiverAddress1" v-model="form.receiverAddress1"
clearable clearable
placeholder="请输入地址1" placeholder="请输入地址1"
maxlength="50"
show-word-limit
/> />
</el-form-item> </el-form-item>
<el-form-item label="地址2" prop="receiverAddress2"> <el-form-item label="地址2" prop="receiverAddress2">
...@@ -124,6 +126,8 @@ const submitForm = async () => { ...@@ -124,6 +126,8 @@ const submitForm = async () => {
v-model="form.receiverAddress2" v-model="form.receiverAddress2"
clearable clearable
placeholder="请输入地址2" placeholder="请输入地址2"
maxlength="50"
show-word-limit
/> />
</el-form-item> </el-form-item>
<el-form-item label="邮政编码" prop="receiverPostCode"> <el-form-item label="邮政编码" prop="receiverPostCode">
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -79,32 +79,24 @@ ...@@ -79,32 +79,24 @@
<ElFormItem> <ElFormItem>
<ElButton @click="reset">重置</ElButton> <ElButton @click="reset">重置</ElButton>
</ElFormItem> </ElFormItem>
</ElForm> <ElFormItem v-if="nodeId === 15">
</div> <el-button type="warning" @click="rejectOrder">
<div class="btn-list">
<!-- <el-button
v-if="nodeId === 10"
type="primary"
@click="confirmOrder()"
>
确认
</el-button> -->
<el-button
v-if="nodeId === 15"
type="warning"
@click="rejectOrder"
>
驳回 驳回
</el-button> </el-button>
<el-button type="success" @click="exportExcel"> 导出</el-button> </ElFormItem>
<el-button <ElFormItem>
v-if="nodeId === 30" <el-button type="success" @click="exportExcel">
type="danger" 导出</el-button
@click="auditOrder('archive')"
> >
</ElFormItem>
<ElFormItem v-if="nodeId === 30">
<el-button type="danger" @click="auditOrder('archive')">
归档 归档
</el-button> </el-button>
</ElFormItem>
</ElForm>
</div> </div>
<div <div
class="delivery-note-content flex-1 flex-column overflow-hidden" class="delivery-note-content flex-1 flex-column overflow-hidden"
> >
...@@ -685,8 +677,8 @@ ...@@ -685,8 +677,8 @@
layout="total, sizes, prev, pager, next, jumper" layout="total, sizes, prev, pager, next, jumper"
:total="detailPager.total" :total="detailPager.total"
style="margin: 10px auto 0; text-align: right" style="margin: 10px auto 0; text-align: right"
@size-change="handleSizeChange" @size-change="handleDetailSizeChange"
@current-change="handleCurrentChange" @current-change="handleDetailCurrentChange"
></ElPagination> ></ElPagination>
</el-tab-pane> </el-tab-pane>
<el-tab-pane name="1" label="操作日志"> <el-tab-pane name="1" label="操作日志">
...@@ -994,6 +986,15 @@ const getSelectionsProperty = (property: keyof AccountStatementNote) => { ...@@ -994,6 +986,15 @@ const getSelectionsProperty = (property: keyof AccountStatementNote) => {
.join(',') .join(',')
} }
const handleDetailSizeChange = (size: number) => {
detailPager.value.rows = size
searchDetail()
}
const handleDetailCurrentChange = (size: number) => {
detailPager.value.page = size
searchDetail()
}
const nodeId = ref<number | string>(0) const nodeId = ref<number | string>(0)
const treeRef = ref<InstanceType<typeof ElTree>>() const treeRef = ref<InstanceType<typeof ElTree>>()
const { const {
...@@ -1196,7 +1197,7 @@ const submitPodPrice = async () => { ...@@ -1196,7 +1197,7 @@ const submitPodPrice = async () => {
try { try {
const res = await apiSetCraftData({ const res = await apiSetCraftData({
id: currentRow.value?.id, id: currentRow.value?.id,
craftTotalPrice:currentRow.value?.craft_total_amount, craftTotalPrice: currentRow.value?.craft_total_amount,
recNumber: currentRow.value?.rec_number, recNumber: currentRow.value?.rec_number,
craftPriceList: filteredList, craftPriceList: filteredList,
}) })
......
<script setup lang="ts">
import { reactive, ref } from 'vue'
import cardWrapper from './cardWrapper.vue'
const queryParams = reactive({
name: "",
sku: "",
diy_sku: "",
print_type: "",
category_id: "",
});
const pager = reactive({
page:1,
size:100,
loading: false ,
count: 0,
lists: [] ,
extend: {}
})
const setCurrentImg = (item: any, val: string) => {
item.img_url = val;
};
const categoryTree = ref([])
const resetPage = () => {
}
</script>
<template>
<div class="product">
<el-card>
<el-form
ref="formRef"
class="searchForm"
label-width="80px"
:model="queryParams"
:inline="true"
>
<el-form-item label="商品名称">
<el-input
v-model="queryParams.name"
clearable
maxlength="40"
style="width: 150px"
show-word-limit
placeholder="请输入商品名称"
/>
</el-form-item>
<el-form-item label="SKU">
<el-input
v-model="queryParams.sku"
clearable
style="width: 150px"
placeholder="请输入sku"
/>
</el-form-item>
<el-form-item label="印花类型">
<el-select
v-model="queryParams.print_type"
style="width: 150px"
clearable
placeholder="请选择"
>
<el-option
v-for="(item, index) in ['满印', '局部印']"
:key="index"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="商品分类">
<el-cascader
ref="categoryCascader"
v-model="queryParams.category_id"
:options="categoryTree"
clearable
style="width: 150px"
:props="{
label: 'name',
value: 'id',
emitPath: false,
}"
:show-all-levels="false"
></el-cascader>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="product-list">
<el-card
style="flex: 1; flex-shrink: 0; overflow: hidden"
class="!border-none"
shadow="never"
>
<div
v-loading="pager.loading"
class="eltable"
element-loading-text="加载中..."
>
<div v-if="pager.lists.length > 0" id="shopline" class="card-mode">
<div
v-for="(item, index) in pager.lists"
:key="index"
class="card-item"
>
<card-wrapper
:data="item"
:index="index"
is-show-home-sku="bottom"
:is-sku-image-list="true"
:has-width="true"
:is-show-sku="false"
:is-show-sales="false"
:is-custom="true"
@set-current-img="(val) => setCurrentImg(item, val)"
>
<template #operations>
<!-- <img-->
<!-- title="操作日志"-->
<!-- width="24"-->
<!-- height="24"-->
<!-- src="@/assets/images/log.png"-->
<!-- alt=""-->
<!-- @click.stop="viewTheLog(item.id)"-->
<!-- />-->
<img
title="编辑"
width="24"
height="24"
src="@/assets/images/edit.png"
alt=""
@click.stop="editInfo(item, 'edit')"
/>
</template>
<template #price>
<span
style="margin: 0 5px"
class="price"
:title="'建议零售价' + item.sales_price"
>
{{ item.sales_price ? "¥" : ""
}}{{ item.sales_price }}&nbsp;
</span>
</template>
<template #level-time>
<div
class="create-time"
:title="`上架时间:${item.create_time}`"
>
<span>{{ item.create_time }}</span>
</div>
</template>
<template #synthesizeStatus>
<div title="印花状态" style="position: absolute; right: 0">
<el-tag :type="item.print_type == 0 ? '' : 'warning'">
{{ item.print_type == 0 ? "满印" : "局部印" }}
</el-tag>
</div>
</template>
<template #otherContent>
<div class="sds-keyid">
<div class="product-id" @click.stop="copy(item.id)">
<img
:title="'复制' + item.id"
width="20"
src="@/assets/images/id.png"
alt=""
/>
<span :title="item.id">
{{ item.id }}
</span>
</div>
<div class="product-sku" @click.stop="copy(item.sku)">
<span :title="item.sku">
{{ item.sku }}
</span>
</div>
</div>
</template>
</card-wrapper>
</div>
</div>
<div v-else class="empty">暂无数据</div>
</div>
<div class="flex justify-center mt-4">
<div
style="
display: flex;
align-items: center;
margin-left: 20px;
width: max-content;
"
>
<span>一行展示</span>
<el-input
v-model="rowNumber"
type="number"
style="width: 80px; margin: 0 10px"
placeholder="请输入"
clearable
@change="changeRowNumber"
/>
<span>条</span>
</div>
&emsp;&emsp;&emsp;
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</div>
</template>
<style scoped lang="scss">
.product{
display: flex;
flex-direction: column;
height: 100%;
}
.searchForm{
::v-deep(.el-form-item){
margin-bottom: 0;
}
}
.justify-center{
display: flex;
justify-content: center;
}
.product-list{
flex: 1;
margin-top: 10px;
flex-shrink: 0;
::v-deep(.el-card){
height: 100%;
.el-card__body{
display: flex;
height: 100%;
flex-direction: column;
.eltable{
flex: 1;
flex-shrink: 0;
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
</style>
<template>
<div
class="user-page flex-column card h-100 overflow-hidden"
style="position: relative"
>
<div class="card-header">
<span>系统配置</span>
</div>
<div class="cardBox">
<div v-for="(item, index) in formList" style="width: 600px" :key="index">
<el-form
v-if="item.type === 'RIIN'"
class="form"
ref="formRef"
label-width="120"
:model="item"
>
<div class="formBox">
<el-form-item label="转至RIIN生产">
<el-switch
v-model="item.enable"
class="ml-2"
style="--el-switch-on-color: #42b983"
/>
</el-form-item>
<div class="formContent" v-if="item.enable">
<el-form-item
label="账号"
prop="appKey"
:rules="[{ required: true, message: '请输入RIIN账号' }]"
>
<ElInput
ref="productionOrderRef"
v-model="item.appKey"
placeholder="请输入RIIN账号"
clearable
style="width: 100%"
/></el-form-item>
<el-form-item
label="App Secret"
prop="appSecret"
:rules="[{ required: true, message: '请输入App Secret' }]"
>
<ElInput
ref="productionOrderRef"
v-model="item.appSecret"
placeholder="请输入App Secret"
clearable
style="width: 100%"
/></el-form-item>
</div>
</div>
<ElButton
class="btn"
color="#42b983"
@click="saveConfiguration(item, index)"
>保存配置</ElButton
>
</el-form>
<el-form
v-if="item.type === 'TRACK'"
class="form"
ref="formRef"
label-width="120"
:model="item"
>
<div class="formBox">
<el-form-item label="物流轨迹跟踪">
<el-switch
v-model="item.enable"
class="ml-2"
style="--el-switch-on-color: #42b983"
/>
</el-form-item>
<div class="formContent" v-if="item.enable">
<el-form-item
label="17Track账号"
prop="appKey"
:rules="[{ required: true, message: '请输入17Track账号' }]"
>
<ElInput
ref="productionOrderRef"
v-model="item.appKey"
placeholder="请输入17Track账号"
clearable
style="width: 100%"
/></el-form-item>
<el-form-item
label="账号Token"
prop="token"
:rules="[{ required: true, message: '请输入账号Token' }]"
>
<ElInput
ref="productionOrderRef"
v-model="item.token"
placeholder="请输入账号Token"
clearable
style="width: 100%"
/></el-form-item>
</div>
</div>
<ElButton
class="btn"
color="#42b983"
@click="saveConfiguration(item, index)"
>保存配置</ElButton
>
</el-form>
</div>
</div>
<div class="logBox">
<div>操作日志</div>
<LogList :log-list="logList" style="font-size: 14px; height: 90%" />
</div>
</div>
</template>
<script setup lang="ts">
import {
addExternalAuthorisationApi,
getExternalAuthorisationListApi,
baseExternalAccountLogsApi,
} from '@/api/externalAuth'
import { ExternalAuthListData } from '@/types/api/externalAuth'
interface formType {
id?: number
enable?: boolean
appKey?: string
appSecret?: string
type?: string
}
const formRef = ref()
const logList = ref([])
async function saveConfiguration(item: formType, index: number) {
let loading
try {
await formRef.value[index]?.validate()
const params = { ...item }
const url = !params.id
? 'factory/baseExternalAccount/add'
: 'factory/baseExternalAccount/update'
loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
const res = await addExternalAuthorisationApi(url, params)
console.log(res)
// ElMessage.success('保存配置成功')
await ElMessageBox.confirm('保存配置成功!!需重新登录才能生效', '提示', {
confirmButtonText: '确定',
showCancelButton: false,
type: 'success',
})
await getDetail()
handleClick()
} catch (error) {
console.log(error)
} finally {
loading?.close()
}
}
const formList = ref<ExternalAuthListData[]>([])
async function getDetail() {
let loading
try {
loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
const res = await getExternalAuthorisationListApi({}, 1, 100)
const records = res.data.records || []
const newArr = records.filter((el) => el.type)
const typeSet = new Set(newArr.map((el) => el.type))
const hasRIIN = typeSet.has('RIIN')
const hasTRACK = typeSet.has('TRACK')
if (newArr.length === 0) {
formList.value = [{ type: 'RIIN' }, { type: 'TRACK' }]
} else {
const result = [...newArr]
if (!hasRIIN) result.push({ type: 'RIIN' })
if (!hasTRACK) result.push({ type: 'TRACK' })
formList.value = result
}
console.log('Form list:', formList.value)
} catch (error) {
console.error('Failed to get external authorizations:', error)
} finally {
loading?.close()
}
}
async function handleClick() {
try {
let ids = ''
const idList = formList.value.map((el) => el.id).filter((el) => el)
console.log(222, idList)
if (idList.length) {
ids = idList.join(',')
}
console.log(205, ids)
const res = await baseExternalAccountLogsApi({
ids,
})
logList.value = res.data
console.log(res)
} catch (error) {
console.log(error)
}
}
onMounted(async () => {
await getDetail()
handleClick()
})
</script>
<style lang="scss" scoped>
.card-header {
margin-left: 200px;
font-size: 30px;
margin-bottom: 20px;
}
:deep() {
.demo-tabs {
height: calc(100% - 60px);
}
.cardBox {
flex: 3;
overflow-y: scroll;
height: 100%;
.el-card__footer {
border: none !important;
}
.formBox {
width: 100%;
margin-bottom: 15px;
padding: 20px;
border: 1px solid #ebebeb;
border-radius: 8px;
&:last-child {
margin-bottom: 0;
}
.formContent {
padding: 20px;
background-color: #f9f9f9;
border-radius: 5px;
.el-form-item:last-child {
margin-bottom: 0 !important;
}
}
}
.btn {
color: #fff;
}
}
.logBox {
border-top: 1px solid #ebebeb;
padding-top: 10px;
height: 200px;
}
.form {
margin-bottom: 15px;
}
}
</style>
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
<div class="search-form"> <div class="search-form">
<ElForm <ElForm
:model="searchForm" :model="searchForm"
size="large"
inline inline
@submit.prevent @submit.prevent
@keyup.enter="search" @keyup.enter="search"
...@@ -59,12 +58,12 @@ ...@@ -59,12 +58,12 @@
></ElInput> ></ElInput>
</ElFormItem> --> </ElFormItem> -->
<ElFormItem> <ElFormItem>
<ElButton type="primary" size="large" @click="search" <ElButton type="primary" @click="search"
>查询</ElButton >查询</ElButton
> >
</ElFormItem> </ElFormItem>
<ElFormItem v-if="treeId === '201'"> <ElFormItem v-if="treeId === '201'">
<el-button size="large" type="danger" @click="reject" <el-button type="danger" @click="reject"
>驳回</el-button >驳回</el-button
> >
</ElFormItem> </ElFormItem>
......
...@@ -93,62 +93,52 @@ ...@@ -93,62 +93,52 @@
<ElFormItem> <ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton> <ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem> </ElFormItem>
</ElForm> <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
</div> <el-button type="primary" @click="addDialog(1, null)">
<div class="btn-list">
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="primary"
@click="addDialog(1, null)"
>
新增 新增
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_AUDIT'" <ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
type="danger" <el-button type="danger" @click="rejectedInRecord">
@click="rejectedInRecord"
>
驳回 驳回
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_SUBMIT'" <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
type="danger" <el-button type="danger" @click="handleBatchDelete">
@click="handleBatchDelete"
>
删除 删除
</el-button> </el-button>
<el-button type="success" @click="handleExport"> 导出 </el-button> </ElFormItem>
<el-button type="primary" @click="printProductTag"> <ElFormItem>
打印库存SKU标签 <el-button type="success" @click="handleExport">
导出
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_AUDIT'" <ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
type="warning" <el-button type="warning" @click="auditOrder('audit')">
@click="auditOrder('audit')"
>
审核 审核
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_SUBMIT'" <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
type="success" <el-button type="success" @click="auditOrder('submitAudit')">
@click="auditOrder('submitAudit')"
>
提交审核 提交审核
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_AUDIT'" <ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
type="danger" <el-button type="danger" @click="auditOrder('invalid')">
@click="auditOrder('invalid')"
>
作废 作废
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'COMPLETED'" <ElFormItem v-if="nodeCode === 'COMPLETED'">
type="success" <el-button type="success" @click="auditOrder('archiving')">
@click="auditOrder('archiving')"
>
归档 归档
</el-button> </el-button>
</ElFormItem>
<ElFormItem>
<el-button type="primary" @click="printProductTag">
打印库存SKU标签
</el-button>
</ElFormItem>
</ElForm>
</div> </div>
<div <div
class="delivery-note-content flex-1 flex-column overflow-hidden" class="delivery-note-content flex-1 flex-column overflow-hidden"
...@@ -321,7 +311,7 @@ ...@@ -321,7 +311,7 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="供应货号" label="号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn <ElTableColumn
...@@ -395,21 +385,17 @@ ...@@ -395,21 +385,17 @@
</div> </div>
<ElDialog <ElDialog
v-model="importDialogVisible" v-model="importDialogVisible"
title="导入" title="导入出库单"
width="500px" width="500px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<div class="import-dialog"> <div class="import-dialog">
<div class="import-header">
<el-button type="primary" link @click="downloadTemplate">
<el-icon><Download /></el-icon>
下载模板
</el-button>
</div>
<div class="import-content"> <div class="import-content">
<UploadExcel <UploadExcel
v-model="importedFileUrl" v-model="importedFileUrl"
:import-type="'localAndXlsx'" :import-type="'localAndXlsx'"
:import-name="'出库单'"
:import-url="'/files/outboundOrder.xlsx'"
@imported="handleLocalImport" @imported="handleLocalImport"
/> />
</div> </div>
...@@ -500,7 +486,7 @@ ...@@ -500,7 +486,7 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="供应货号" label="号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn <ElTableColumn
...@@ -616,7 +602,7 @@ ...@@ -616,7 +602,7 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="供应货号" label="号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn <ElTableColumn
...@@ -748,7 +734,7 @@ ...@@ -748,7 +734,7 @@
<el-table-column <el-table-column
align="center" align="center"
prop="supplierItemNo" prop="supplierItemNo"
label="供应货号" label="号"
></el-table-column> ></el-table-column>
<el-table-column align="center" prop="number" label="打印数量"> <el-table-column align="center" prop="number" label="打印数量">
<template #default="{ row }"> <template #default="{ row }">
...@@ -797,7 +783,7 @@ ...@@ -797,7 +783,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ElMessage, ElRadioGroup, ElTree } from 'element-plus' import { ElMessage, ElRadioGroup, ElTree } from 'element-plus'
import { CirclePlusFilled,Download } from '@element-plus/icons-vue' import { CirclePlusFilled } from '@element-plus/icons-vue'
import splitDiv from '@/components/splitDiv/splitDiv.vue' import splitDiv from '@/components/splitDiv/splitDiv.vue'
import { ElTable } from 'element-plus' import { ElTable } from 'element-plus'
import usePageList from '@/utils/hooks/usePageList' import usePageList from '@/utils/hooks/usePageList'
...@@ -957,14 +943,6 @@ function getStartTime() { ...@@ -957,14 +943,6 @@ function getStartTime() {
const day = date.getDate() const day = date.getDate()
return `${year}-${month}-${day} 00:00:00` return `${year}-${month}-${day} 00:00:00`
} }
const downloadTemplate = () => {
const link = document.createElement('a')
link.href = '/files/outboundOrder.xlsx'
link.download = 'outboundOrder.xlsx'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
const selectSku = ref('') const selectSku = ref('')
const treeData = ref<InterWarehouseTree[]>() const treeData = ref<InterWarehouseTree[]>()
const [searchForm, resetSearchForm] = useValue<warehouseSearchForm>({}) const [searchForm, resetSearchForm] = useValue<warehouseSearchForm>({})
...@@ -1171,9 +1149,9 @@ const handleLocalImport = async ({ ...@@ -1171,9 +1149,9 @@ const handleLocalImport = async ({
.filter((item) => item.warehouseSku) .filter((item) => item.warehouseSku)
if (importedData.length === 0) { if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的库存SKU'); ElMessage.warning('导入数据中没有有效的库存SKU')
importDialogVisible.value = false; importDialogVisible.value = false
return; return
} }
// 2. 提取导入的 SKU 列表 // 2. 提取导入的 SKU 列表
...@@ -1183,10 +1161,10 @@ const handleLocalImport = async ({ ...@@ -1183,10 +1161,10 @@ const handleLocalImport = async ({
const filteredSkusList = await batchAddCommodity(importedSkus) const filteredSkusList = await batchAddCommodity(importedSkus)
if (filteredSkusList.length === 0) { if (filteredSkusList.length === 0) {
ElMessage.warning('导入的库存SKU已存在或无效'); ElMessage.warning('导入的库存SKU已存在或无效')
importedFileUrl.value = path; importedFileUrl.value = path
importDialogVisible.value = false; importDialogVisible.value = false
return; return
} }
// 4. 将备注信息合并到获取到的商品列表中 // 4. 将备注信息合并到获取到的商品列表中
...@@ -1999,11 +1977,6 @@ $border: solid 1px #ddd; ...@@ -1999,11 +1977,6 @@ $border: solid 1px #ddd;
} }
.import-dialog { .import-dialog {
.import-header {
display: flex;
justify-content: flex-end;
}
.import-content { .import-content {
padding-bottom: 20px; padding-bottom: 20px;
} }
......
...@@ -14,7 +14,6 @@ import { ...@@ -14,7 +14,6 @@ import {
importWarehouseLocation, importWarehouseLocation,
} from '@/api/warehouse.ts' } from '@/api/warehouse.ts'
const uploadExcelRef = ref() const uploadExcelRef = ref()
import { Download } from '@element-plus/icons-vue'
import { nextTick, ref } from 'vue' import { nextTick, ref } from 'vue'
import SplitDiv from '@/components/splitDiv/splitDiv.vue' import SplitDiv from '@/components/splitDiv/splitDiv.vue'
import { filePath } from '@/api/axios.ts' import { filePath } from '@/api/axios.ts'
...@@ -55,14 +54,6 @@ const handleLocalImport = async ({ ...@@ -55,14 +54,6 @@ const handleLocalImport = async ({
importedFileUrl.value = '' importedFileUrl.value = ''
} }
} }
const downloadTemplate = () => {
const link = document.createElement('a')
link.href = '/files/warehouseLocationTemplate.xlsx'
link.download = 'warehouseLocationTemplate.xlsx'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
// const importLoading = ref(false) // const importLoading = ref(false)
const searchForm = ref({ const searchForm = ref({
warehouseId: '', warehouseId: '',
...@@ -492,22 +483,18 @@ getWarehouse() ...@@ -492,22 +483,18 @@ getWarehouse()
</split-div> </split-div>
<ElDialog <ElDialog
v-model="importDialogVisible" v-model="importDialogVisible"
title="导入" title="导入库位"
width="500px" width="500px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<div class="import-dialog"> <div class="import-dialog">
<div class="import-header">
<el-button type="primary" link @click="downloadTemplate">
<el-icon><Download /></el-icon>
下载模板
</el-button>
</div>
<div class="import-content"> <div class="import-content">
<UploadExcel <UploadExcel
ref="uploadExcelRef" ref="uploadExcelRef"
v-model="importedFileUrl" v-model="importedFileUrl"
:import-type="'localAndUpload'" :import-type="'localAndUpload'"
:import-name="'库位'"
:import-url="'/files/warehouseLocationTemplate.xlsx'"
@imported="handleLocalImport" @imported="handleLocalImport"
/> />
</div> </div>
......
...@@ -93,55 +93,47 @@ ...@@ -93,55 +93,47 @@
<ElFormItem> <ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton> <ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem> </ElFormItem>
</ElForm> <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
</div> <el-button type="primary" @click="addDialog(1, null)">
<div class="btn-list">
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="primary"
@click="addDialog(1, null)"
>
新增 新增
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_AUDIT'" <ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
type="danger" <el-button type="danger" @click="rejectedInRecord">
@click="rejectedInRecord"
>
驳回 驳回
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_SUBMIT'" <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
type="danger" <el-button type="danger" @click="handleBatchDelete">
@click="handleBatchDelete"
>
删除 删除
</el-button> </el-button>
<el-button type="success" @click="handleExport"> 导出</el-button> </ElFormItem>
<el-button type="primary" @click="printProductTag"> <ElFormItem>
打印库存SKU标签 <el-button type="success" @click="handleExport">
</el-button> 导出</el-button
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="warning"
@click="auditOrder('audit')"
> >
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="warning" @click="auditOrder('audit')">
审核 审核
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_SUBMIT'" <ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
type="success" <el-button type="success" @click="auditOrder('submitAudit')">
@click="auditOrder('submitAudit')"
>
提交审核 提交审核
</el-button> </el-button>
<el-button </ElFormItem>
v-if="nodeCode === 'PENDING_AUDIT'" <ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
type="danger" <el-button type="danger" @click="auditOrder('invalid')">
@click="auditOrder('invalid')"
>
作废 作废
</el-button> </el-button>
</ElFormItem>
<ElFormItem>
<el-button type="primary" @click="printProductTag">
打印库存SKU标签
</el-button>
</ElFormItem>
<ElFormItem>
<el-button <el-button
v-if="nodeCode === 'COMPLETED'" v-if="nodeCode === 'COMPLETED'"
type="success" type="success"
...@@ -149,6 +141,8 @@ ...@@ -149,6 +141,8 @@
> >
归档 归档
</el-button> </el-button>
</ElFormItem>
</ElForm>
</div> </div>
<div <div
class="delivery-note-content flex-1 flex-column overflow-hidden" class="delivery-note-content flex-1 flex-column overflow-hidden"
...@@ -329,7 +323,7 @@ ...@@ -329,7 +323,7 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="供应货号" label="号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn <ElTableColumn
...@@ -427,21 +421,17 @@ ...@@ -427,21 +421,17 @@
</div> </div>
<ElDialog <ElDialog
v-model="importDialogVisible" v-model="importDialogVisible"
title="导入" title="导入入库单"
width="500px" width="500px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<div class="import-dialog"> <div class="import-dialog">
<div class="import-header">
<el-button type="primary" link @click="downloadTemplate">
<el-icon><Download /></el-icon>
下载模板
</el-button>
</div>
<div class="import-content"> <div class="import-content">
<UploadExcel <UploadExcel
v-model="importedFileUrl" v-model="importedFileUrl"
:import-type="'localAndXlsx'" :import-type="'localAndXlsx'"
:import-name="'入库单'"
:import-url="'/files/warehousingEntry.xlsx'"
@imported="handleLocalImport" @imported="handleLocalImport"
/> />
</div> </div>
...@@ -532,7 +522,7 @@ ...@@ -532,7 +522,7 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="供应货号" label="号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn align="center" label="入库数量" prop="buyStored"> <ElTableColumn align="center" label="入库数量" prop="buyStored">
...@@ -646,7 +636,7 @@ ...@@ -646,7 +636,7 @@
<ElTableColumn <ElTableColumn
show-overflow-tooltip show-overflow-tooltip
align="center" align="center"
label="供应货号" label="号"
prop="productNo" prop="productNo"
/> />
<ElTableColumn <ElTableColumn
...@@ -778,7 +768,7 @@ ...@@ -778,7 +768,7 @@
<el-table-column <el-table-column
align="center" align="center"
prop="supplierItemNo" prop="supplierItemNo"
label="供应货号" label="号"
></el-table-column> ></el-table-column>
<el-table-column align="center" prop="number" label="打印数量"> <el-table-column align="center" prop="number" label="打印数量">
<template #default="{ row }"> <template #default="{ row }">
...@@ -827,7 +817,7 @@ ...@@ -827,7 +817,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ElMessage, ElRadioGroup, ElTree } from 'element-plus' import { ElMessage, ElRadioGroup, ElTree } from 'element-plus'
import { CirclePlusFilled, Download } from '@element-plus/icons-vue' import { CirclePlusFilled } from '@element-plus/icons-vue'
import splitDiv from '@/components/splitDiv/splitDiv.vue' import splitDiv from '@/components/splitDiv/splitDiv.vue'
import { ElTable } from 'element-plus' import { ElTable } from 'element-plus'
import usePageList from '@/utils/hooks/usePageList' import usePageList from '@/utils/hooks/usePageList'
...@@ -987,14 +977,6 @@ function getStartTime() { ...@@ -987,14 +977,6 @@ function getStartTime() {
const day = date.getDate() const day = date.getDate()
return `${year}-${month}-${day} 00:00:00` return `${year}-${month}-${day} 00:00:00`
} }
const downloadTemplate = () => {
const link = document.createElement('a')
link.href = '/files/warehousingEntry.xlsx'
link.download = 'warehousingEntry.xlsx'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
const selectSku = ref('') const selectSku = ref('')
const treeData = ref<InterWarehouseTree[]>() const treeData = ref<InterWarehouseTree[]>()
const [searchForm, resetSearchForm] = useValue<warehouseSearchForm>({}) const [searchForm, resetSearchForm] = useValue<warehouseSearchForm>({})
...@@ -1156,7 +1138,7 @@ const excelFieldMap: Record<string, keyof InterProductList> = { ...@@ -1156,7 +1138,7 @@ const excelFieldMap: Record<string, keyof InterProductList> = {
入库数量: 'buyStored', 入库数量: 'buyStored',
// '成本价(¥)': 'costPrice', // '成本价(¥)': 'costPrice',
// '总成本(¥)': 'totalPrice', // '总成本(¥)': 'totalPrice',
// 库位: 'locationCode', 库位编码: 'locationCode',
备注: 'remark', 备注: 'remark',
} }
...@@ -1201,6 +1183,7 @@ const handleLocalImport = async ({ ...@@ -1201,6 +1183,7 @@ const handleLocalImport = async ({
return obj return obj
}) })
.filter((item) => item.warehouseSku) .filter((item) => item.warehouseSku)
// console.log('@', importedData, data)
if (importedData.length === 0) { if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的商品SKU') ElMessage.warning('导入数据中没有有效的商品SKU')
importDialogVisible.value = false importDialogVisible.value = false
...@@ -1222,13 +1205,16 @@ const handleLocalImport = async ({ ...@@ -1222,13 +1205,16 @@ const handleLocalImport = async ({
const importedItem = importedData.find( const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.sku, (item) => item.warehouseSku === skuItem.sku,
) )
const target = locationList.value.find((item: InterProductList) => {
return item.locationCode == importedItem?.locationCode
})
return { return {
skuImage: skuItem.image, skuImage: skuItem.image,
warehouseSku: skuItem.sku, warehouseSku: skuItem.sku,
skuName: skuItem.skuName, skuName: skuItem.skuName,
productNo: skuItem.productNo, productNo: skuItem.productNo,
locationCode: skuItem.locationCode ?? '', locationCode: skuItem.locationCode ?? '',
locationId: skuItem.locationId ?? null, locationId: skuItem.locationId || target?.locationId,
costPrice: skuItem.factoryPrice, costPrice: skuItem.factoryPrice,
buyStored: importedItem?.buyStored ?? null, buyStored: importedItem?.buyStored ?? null,
totalPrice: new BigNumber( totalPrice: new BigNumber(
...@@ -1535,6 +1521,7 @@ const addOtherCurrency = async () => { ...@@ -1535,6 +1521,7 @@ const addOtherCurrency = async () => {
ElMessage.error('请至少选择一条数据') ElMessage.error('请至少选择一条数据')
return return
} }
for (let i = 0; i < arr.length; i++) { for (let i = 0; i < arr.length; i++) {
if (!arr[i].buyStored) { if (!arr[i].buyStored) {
ElMessage.error('请输入入库数量') ElMessage.error('请输入入库数量')
...@@ -1544,6 +1531,12 @@ const addOtherCurrency = async () => { ...@@ -1544,6 +1531,12 @@ const addOtherCurrency = async () => {
ElMessage.error('请选择库位') ElMessage.error('请选择库位')
return return
} }
const found = locationList.value.find(
(item: InterProductList) => item.locationId === arr[i].locationId,
)
if (!arr[i].locationCode) {
arr[i].locationCode = found ? found?.locationCode : ''
}
} }
if (!formId.value) { if (!formId.value) {
addSection() addSection()
...@@ -1554,7 +1547,7 @@ const addOtherCurrency = async () => { ...@@ -1554,7 +1547,7 @@ const addOtherCurrency = async () => {
const filterSkuData = computed(() => { const filterSkuData = computed(() => {
const skuList = otherPurchaseData.value.map((el) => el.warehouseSku) const skuList = otherPurchaseData.value.map((el) => el.warehouseSku)
console.log(skuList, skuData.value) // console.log(skuList, skuData.value)
return skuData.value.filter((el) => !skuList.includes(el.sku)) return skuData.value.filter((el) => !skuList.includes(el.sku))
}) })
const addSection = async () => { const addSection = async () => {
...@@ -1959,11 +1952,6 @@ $border: solid 1px #ddd; ...@@ -1959,11 +1952,6 @@ $border: solid 1px #ddd;
} }
.import-dialog { .import-dialog {
.import-header {
display: flex;
justify-content: flex-end;
}
.import-content { .import-content {
padding-bottom: 20px; padding-bottom: 20px;
} }
......
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