Commit 92f1ca67 by qinjianhui

feat: 工厂订单页面整体布局

parent 731d8d3c
import axios from './axios'
import type { BasePaginationData, BaseRespData } from '@/types/api'
import type {
FactoryOrderNewListData,
LogListData,
ProductListData,
SearchForm,
StatusTreeNode,
} from '@/types/api/factoryOrderNew'
// 左侧状态树 - 先保留接口定义,实际数据在前端写死
export function getStatusTreeApi() {
return axios.get<never, BaseRespData<StatusTreeNode[]>>(
'factory/orderNew/getStatusTree',
)
}
export function getFactoryOrderNewListApi(
data: SearchForm,
currentPage: number,
pageSize: number,
statusCode?: string,
) {
return axios.post<never, BasePaginationData<FactoryOrderNewListData>>(
'factory/orderNew/list_page',
{
...data,
currentPage,
pageSize,
statusCode,
},
)
}
export function getFactoryOrderNewDetailApi(id: number | string) {
return axios.get<never, BaseRespData<ProductListData[]>>(
'factory/orderNew/detail',
{
params: { id },
},
)
}
export function getFactoryOrderNewLogApi(id: number | string) {
return axios.get<never, BaseRespData<LogListData[]>>(
'factory/orderNew/log',
{
params: { id },
},
)
}
export function confirmOrderApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<void>>(
'factory/orderNew/confirm',
{ ids },
)
}
export function cancelOrderApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<void>>(
'factory/orderNew/cancel',
{ ids },
)
}
export function refreshProductInfoApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<void>>(
'factory/orderNew/refreshProductInfo',
{ ids },
)
}
export function transferOldFlowApi(ids: (number | string)[]) {
return axios.post<never, BaseRespData<void>>(
'factory/orderNew/transferOldFlow',
{ ids },
)
}
export interface StatusTreeNode {
code: string
remark: string
count: number
children?: StatusTreeNode[]
}
export interface SearchForm {
platform?: string
craftCode?: string | string[]
stockSku?: string
styleNo?: string
batchNo?: string
orderNumber?: string
customerOrderNumber?: string
shopOrderNumber?: string
productType?: string | number
multi?: boolean | null
timeType?: number | null
startTime?: string | null
endTime?: string | null
logisticsWayCode?: string
receiverCountry?: string | string[]
factoryOrderNumber?: string
userMark?: string
sku?: string
trackingNumber?: string
replaceShipment?: number | string
shipmentType?: number | string
tagsIdArr?: string[]
productMark?: string
source?: string
size?: string
logisticsCompanyCode?: string
blocking?: boolean
standardDesignImage?: boolean
}
export interface FactoryOrderNewListData {
id: number
orderNumber?: string
customerOrderNumber?: string
shopOrderNumber?: string
status?: string
statusName?: string
customerTags?: { name: string }[]
logisticsWayCode?: string
logisticsWayName?: string
totalWeight?: number
totalProductNum?: number
logisticsSourceNo?: string
receiverName?: string
receiverPhone?: string
receiverCode?: string
receiverAddress?: string
createTime?: string
acceptTime?: string
finishTime?: string
}
export interface ProductListData {
id: number
orderId?: number
productImage?: string
productName?: string
variantSku?: string
stockSku?: string
craftCode?: string
craftName?: string
styleNo?: string
price?: number
quantity?: number
weight?: number
availableQuantity?: number
stockQuantity?: number
occupiedQuantity?: number
customsNameEnglish?: string
customsNameChinese?: string
customsWeight?: number
customsValue?: number
remark?: string
}
export interface LogListData {
id: number
bizId?: number | string
employeeName?: string
description?: string
createTime?: string
}
<template>
<div class="card flex-column h-100 overflow-hidden">
<div class="page card h-100 flex-gap-10 overflow-hidden flex">
<div class="order-status">
<ElTree
ref="treeRef"
default-expand-all
:expand-on-click-node="false"
:default-expanded-keys="['ALL']"
:highlight-current="true"
node-key="code"
:data="statusTree"
:props="{ children: 'children', label: 'remark' }"
class="status-tree"
@node-click="handleStatusNodeClick"
>
<template #default="{ node, data }">
<div class="tree-node">
<div class="tree-node-label-wrapper">
<span class="tree-node-label">{{ data.remark }}</span>
<span
v-if="data.code !== 'ALL' && (data.count || data.count === 0)"
class="tree-node-count"
>
{{ `(${data.count})` }}
</span>
</div>
<span
v-if="data.children && data.children.length"
class="tree-node-expand"
@click.stop="toggleExpand(node)"
>
<el-icon
><ArrowUp v-if="node.expanded" /><ArrowDown v-else
/></el-icon>
</span>
</div>
</template>
</ElTree>
</div>
<div class="order-content flex-1 flex-column overflow-hidden">
<div class="header">
<div class="header-filter-form">
<ElForm
class="search-form"
:model="searchForm"
:inline="true"
label-width="70px"
>
<ElFormItem label="平台">
<ElSelect
v-model="searchForm.platform"
placeholder="请选择"
clearable
filterable
popper-class="customize-select-style"
style="width: 140px"
>
<ElOption
v-for="(item, index) in platformJson"
:key="index"
:label="item.type"
:value="item.type"
style="width: 160px"
>
<img
:src="`/images/icon/${item.icon.split('/').pop()}`"
style="height: 20px; margin: 5px 10px 0 0"
/>
<span :title="item.type">{{ item.type }}</span>
</ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="工艺">
<ElSelect
v-model="craftCode"
placeholder="请选择"
clearable
filterable
style="width: 140px"
>
<ElOption
v-for="item in craftList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</ElSelect>
</ElFormItem>
<ElFormItem label="库存SKU">
<ElInput
v-model.trim="searchForm.stockSku"
placeholder="库存SKU"
clearable
style="width: 140px"
/>
</ElFormItem>
<ElFormItem label="款号">
<ElInput
v-model.trim="searchForm.styleNo"
placeholder="款号"
clearable
style="width: 140px"
/>
</ElFormItem>
<ElFormItem label="批次号">
<ElInput
v-model.trim="searchForm.batchNo"
placeholder="批次号"
clearable
style="width: 140px"
/>
</ElFormItem>
<ElFormItem label="操作单号">
<ElInput
v-model.trim="searchForm.orderNumber"
placeholder="操作单号"
clearable
style="width: 140px"
/>
</ElFormItem>
<ElFormItem label="商品类型">
<ElInput
v-model.trim="searchForm.customerOrderNumber"
placeholder="客户单号"
clearable
style="width: 140px"
/>
</ElFormItem>
<ElFormItem label="数量">
<el-radio-group v-model="searchForm.multi">
<el-radio-button :value="false">单件</el-radio-button>
<el-radio-button :value="true">多件</el-radio-button>
</el-radio-group>
</ElFormItem>
<ElFormItem>
<ElPopover placement="bottom" width="600" trigger="click">
<ElForm
ref="searchFormPopoverRef"
:model="searchForm"
size="default"
inline
label-width="100px"
>
<ElFormItem style="width: 100%; padding-right: 40px">
<div style="width: 100%; display: flex; flex-wrap: nowrap">
<el-select
v-model="searchForm.timeType"
clearable
:teleported="false"
placeholder="时间类型"
style="flex: 1; margin-right: 10px"
>
<el-option :value="1" label="创建时间"></el-option>
<el-option :value="2" label="确认时间"></el-option>
<el-option :value="3" label="完成时间"></el-option>
</el-select>
<el-date-picker
v-model="dateRange"
:teleported="false"
:default-time="[
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59),
]"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange"
style="width: 280px"
:shortcuts="pickerOptions.shortcuts"
start-placeholder="开始时间"
end-placeholder="结束时间"
clearable
/>
</div>
</ElFormItem>
<ElFormItem label="订单号">
<ElInput
v-model="searchForm.factoryOrderNumber"
placeholder="订单号"
clearable
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="客户">
<el-select
v-model="searchForm.userMark"
clearable
filterable
:teleported="false"
style="width: 150px"
placeholder="客户"
>
<el-option
v-for="item in userMarkList"
:key="item"
:value="item"
:label="item"
></el-option>
</el-select>
</ElFormItem>
<ElFormItem label="Variant SKU">
<ElInput
v-model.trim="searchForm.sku"
placeholder="Variant SKU"
clearable
style="width: 150px"
/>
</ElFormItem>
<ElFormItem label="物流跟踪号">
<ElInput
v-model.trim="searchForm.trackingNumber"
placeholder="物流跟踪号"
clearable
style="width: 150px"
/>
</ElFormItem>
<ElFormItem
v-if="
![
'TO_BE_ARRANGE',
'PICKING',
'TO_BE_REPLENISHMENT',
'IN_PRODUCTION',
].includes(status)
"
label="收件国家"
>
<ElSelect
v-model="searchForm.receiverCountry"
placeholder="收件国家"
clearable
multiple
:teleported="false"
style="width: 150px"
filterable
@change="changeReplaceShipment"
>
<ElOption
v-for="item in receiverCountryList"
:key="item.countryCode"
:value="item.countryCode"
:label="item.nameCn + '(' + item.countryCode + ')'"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="是否代发">
<ElSelect
v-model="searchForm.replaceShipment"
placeholder="是否代发"
clearable
:teleported="false"
style="width: 150px"
@change="changeReplaceShipment"
>
<ElOption
v-for="(item, index) in ['不代发', '代发']"
:key="index"
:value="index"
:label="item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
v-if="searchForm.replaceShipment === 0"
label="物流类型"
>
<ElSelect
v-model="searchForm.shipmentType"
placeholder="物流类型"
clearable
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(item, index) in ['自提', '快递']"
:key="index"
:value="index"
:label="item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
v-if="searchForm.replaceShipment === 1"
label="物流类型"
>
<ElSelect
v-model="searchForm.shipmentType"
placeholder="物流类型"
clearable
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(item, index) in ['自有物流', '工厂物流']"
:key="index"
:value="index"
:label="item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="ERP标签">
<ElSelect
v-model="searchForm.tagsIdArr"
placeholder="请选择ERP标签"
clearable
filterable
multiple
collapse-tags
collapse-tags-tooltip
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(item, index) in customTagList"
:key="index"
:value="item.id"
:label="item.name"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="订单来源">
<ElSelect
v-model="searchForm.source"
placeholder="请选择"
clearable
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(item, index) in sourceList"
:key="index"
:value="item.id"
:label="item.name"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="尺码筛选">
<ElSelect
v-model="searchForm.size"
placeholder="请选择"
clearable
filterable
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(item, index) in sizes"
:key="index"
:value="item"
:label="item"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="自有物流公司">
<ElSelect
v-model="searchForm.logisticsCompanyCode"
placeholder="请选择"
clearable
filterable
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(item, index) in allCodelist"
:key="index"
:value="item.code"
:label="item.basicsName"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem
v-if="status !== 'CANCEL' && status !== 'INTERCEPTED'"
label="拦截订单"
>
<ElSelect
v-model="searchForm.blocking"
placeholder="请选择"
clearable
filterable
:teleported="false"
style="width: 150px"
>
<ElOption
v-for="(_, index) in ['否', '是']"
:key="index"
:value="!!index"
:label="index === 0 ? '否' : '是'"
></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="规范素材">
<ElSelect
v-model="searchForm.standardDesignImage"
placeholder="请选择"
clearable
filterable
style="width: 150px"
>
<ElOption
v-for="(_, index) in ['否', '是']"
:key="index"
:value="!!index"
:label="index === 0 ? '否' : '是'"
></ElOption>
</ElSelect>
</ElFormItem>
</ElForm>
<template #reference>
<el-button
type="warning"
@click="searchVisible = !searchVisible"
>
<el-icon v-if="searchVisible">
<CaretTop />
</el-icon>
<el-icon v-else>
<CaretBottom />
</el-icon>
</el-button>
</template>
</ElPopover>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" @click="search"> 查询 </ElButton>
<ElButton @click="reset"> 重置 </ElButton>
</ElFormItem>
</ElForm>
</div>
</div>
<div class="operation-list">
<span class="item">
<ElButton
type="primary"
:disabled="!selectedRowIds.length"
@click="handleConfirmOrder"
>
确认接单
</ElButton>
</span>
</div>
<div class="table-content">
<splitDiv size="55">
<template #top>
<div class="table-list flex-1 overflow-hidden">
<TableView
ref="mainTableRef"
:paginated-data="tableData"
:columns="mainColumns"
serial-numberable
selectionable
@selection-change="handleMainSelectionChange"
@row-click="handleMainRowClick"
/>
</div>
<ElPagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[50, 100, 200, 300]"
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
style="margin: 10px auto 0"
@size-change="handlePageSizeChange"
@current-change="handleCurrentPageChange"
/>
</template>
<template #bottom>
<el-tabs v-model="activeTab" class="tabs-wrapper">
<el-tab-pane name="product" label="包含商品">
<div class="sub-table-wrapper">
<TableView
:paginated-data="productList"
:columns="productColumns"
serial-numberable
/>
</div>
</el-tab-pane>
<el-tab-pane name="log" label="操作日志">
<div class="detail-table-content">
<LogList :log-list="logList" />
<div class="empty-content">暂无数据</div>
</div>
</el-tab-pane>
</el-tabs>
</template>
</splitDiv>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {
ArrowDown,
ArrowUp,
CaretTop,
CaretBottom,
} from '@element-plus/icons-vue'
import { onMounted, ref, watch } from 'vue'
import {
ElForm,
ElFormItem,
ElMessage,
ElMessageBox,
ElTree,
} from 'element-plus'
import splitDiv from '@/components/splitDiv/splitDiv.vue'
import TableView from '@/components/TableView.vue'
import usePageList from '@/utils/hooks/usePageList'
import type { CustomColumn } from '@/types/table'
import type {
FactoryOrderNewListData,
LogListData,
ProductListData,
SearchForm,
StatusTreeNode,
} from '@/types/api/factoryOrderNew'
import platformJson from '../../../json/platform.json'
import {
confirmOrderApi,
getFactoryOrderNewDetailApi,
getFactoryOrderNewListApi,
getFactoryOrderNewLogApi,
} from '@/api/factoryOrderNew'
import {
getListCraftApi,
getCustomTagListCnApi,
allErpCodeListApi,
} from '@/api/podCnOrder'
import { getUserMarkList } from '@/api/common'
import { getAllCountryApi } from '@/api/logistics'
const defaultStatusTree: StatusTreeNode[] = [
{
code: 'ALL',
remark: '全部',
count: 0,
children: [
{ code: 'PENDING_ACCEPT', remark: '待接单', count: 0 },
{ code: 'PENDING_LOGISTICS', remark: '待创建物流', count: 0 },
{ code: 'PENDING_SCHEDULE', remark: '待排单', count: 0 },
{ code: 'BATCH_MANAGE', remark: '批次管理', count: 0 },
{ code: 'WAITING_RESTOCK', remark: '等待补货', count: 0 },
{
code: 'DISTRIBUTING',
remark: '配货中',
count: 0,
children: [
{ code: 'PENDING_PICK', remark: '待拣胚', count: 0 },
{ code: 'PENDING_REPLENISH', remark: '待补胚', count: 0 },
{ code: 'PRODUCING', remark: '生产中', count: 0 },
{ code: 'PENDING_DISTRIBUTE', remark: '待配货', count: 0 },
],
},
{ code: 'PRODUCING', remark: '生产中', count: 0 },
{ code: 'PENDING_DISTRIBUTE', remark: '待配货', count: 0 },
{ code: 'PENDING_SHIP', remark: '待发货', count: 0 },
{ code: 'COMPLETED', remark: '已完成', count: 0 },
{ code: 'SUSPENDED', remark: '挂起', count: 0 },
{ code: 'CANCELLED', remark: '已取消', count: 0 },
{ code: 'ARCHIVED', remark: '已归档', count: 0 },
],
},
]
const statusTree = ref<StatusTreeNode[]>(defaultStatusTree)
const status = ref<string>('PENDING_ACCEPT')
const treeRef = ref<InstanceType<typeof ElTree>>()
const searchForm = ref<SearchForm>({})
const dateRange = ref<string[]>([])
const craftCode = ref<string>('')
const searchVisible = ref(false)
const searchFormPopoverRef = ref()
const userMarkList = ref<string[]>([])
const receiverCountryList = ref<{ countryCode: string; nameCn: string }[]>([])
const customTagList = ref<{ id: string; name: string }[]>([])
interface LogisticsCodeItem {
code: string
basicsName: string
apiData: unknown
}
const allCodelist = ref<LogisticsCodeItem[]>([])
const sourceList = [
{ name: 'erp推送', id: 'jomall-erp' },
{ name: '第三方推送', id: 'third-party' },
]
const sizes = ['FS', 'XS', 'S', 'M', 'L', 'XL', 'XXL', '3XL', '4XL', '5XL']
const changeReplaceShipment = () => {
searchForm.value.shipmentType = ''
}
const getUserMark = async () => {
try {
const res = await getUserMarkList()
userMarkList.value = res.data
} catch (_e) {
/* empty */
}
}
const getReceiverCountryList = async () => {
try {
const res = await getAllCountryApi()
if (res.code !== 200) return
receiverCountryList.value = res.data
} catch (_e) {
/* empty */
}
}
const getCustomTagList = async () => {
try {
const res = await getCustomTagListCnApi()
if (res.code !== 200) return
customTagList.value = res.data
} catch (_e) {
/* empty */
}
}
const getLogisticsCompanyAllCodelist = async () => {
try {
const res = await allErpCodeListApi()
if (res.code !== 200) return
allCodelist.value = res.data
} catch (_e) {
/* empty */
}
}
type CraftOption = { id: string; name: string }
const craftList = ref<CraftOption[]>([])
type CraftApiItem = {
craftCode?: string | number
craftName?: string
id?: string | number
name?: string
}
const loadCraftList = async () => {
try {
const res = await getListCraftApi()
// 后端返回结构在不同模块里不完全一致,这里做一次宽松兼容
const root = res as unknown as { data?: unknown }
const data =
(root.data as { data?: unknown; list?: unknown } | undefined)?.data ??
(root.data as { list?: unknown } | undefined)?.list ??
root.data
const list = Array.isArray(data) ? (data as CraftApiItem[]) : []
craftList.value = list
.map((item) => ({
id: String(item.craftCode ?? item.id ?? ''),
name: String(item.craftName ?? item.name ?? ''),
}))
.filter((i) => i.id && i.name)
} catch (e) {
console.error(e)
craftList.value = []
}
}
const pickerOptions = {
shortcuts: [
{
text: '今日',
value: () => {
const start = new Date()
start.setHours(0, 0, 0, 0)
const end = new Date()
end.setHours(23, 59, 59, 999)
return [start, end]
},
},
{
text: '最近7天',
value: () => {
const end = new Date()
end.setHours(23, 59, 59, 999)
const start = new Date()
start.setDate(start.getDate() - 6)
start.setHours(0, 0, 0, 0)
return [start, end]
},
},
{
text: '最近30天',
value: () => {
const end = new Date()
end.setHours(23, 59, 59, 999)
const start = new Date()
start.setDate(start.getDate() - 29)
start.setHours(0, 0, 0, 0)
return [start, end]
},
},
],
}
const activeTab = ref<'product' | 'log'>('product')
const productList = ref<ProductListData[]>([])
const currentRow = ref<FactoryOrderNewListData | null>(null)
const selectedRowIds = ref<(number | string)[]>([])
const logList = ref<LogListData[]>([])
const mainTableRef = ref()
const mainColumns: CustomColumn<FactoryOrderNewListData>[] = [
{ key: 'orderNumber', prop: 'orderNumber', label: '订单编号', minWidth: 160 },
{
key: 'customerOrderNumber',
prop: 'customerOrderNumber',
label: '客户单号',
minWidth: 160,
},
{
key: 'shopOrderNumber',
prop: 'shopOrderNumber',
label: '店铺单号',
minWidth: 160,
},
{ key: 'statusName', prop: 'statusName', label: '订单状态', minWidth: 120 },
{
key: 'logisticsWayName',
prop: 'logisticsWayName',
label: '物流方式',
minWidth: 140,
},
{
key: 'totalWeight',
prop: 'totalWeight',
label: '总克重',
minWidth: 100,
},
{
key: 'totalProductNum',
prop: 'totalProductNum',
label: '商品总数量',
minWidth: 120,
},
{
key: 'receiverName',
prop: 'receiverName',
label: '收货人',
minWidth: 120,
},
{
key: 'receiverPhone',
prop: 'receiverPhone',
label: '收货人电话',
minWidth: 140,
},
{
key: 'receiverAddress',
prop: 'receiverAddress',
label: '收货地址',
minWidth: 220,
showOverflowTooltip: true,
},
{
key: 'createTime',
prop: 'createTime',
label: '创建时间',
minWidth: 180,
},
{
key: 'acceptTime',
prop: 'acceptTime',
label: '接单时间',
minWidth: 180,
},
{
key: 'finishTime',
prop: 'finishTime',
label: '完成时间',
minWidth: 180,
},
]
const productColumns: CustomColumn<ProductListData>[] = [
{
key: 'productImage',
prop: 'productImage',
label: '商品图片',
minWidth: 90,
align: 'center',
slot: 'productImage',
},
{
key: 'productName',
prop: 'productName',
label: '商品名称',
minWidth: 200,
showOverflowTooltip: true,
},
{
key: 'variantSku',
prop: 'variantSku',
label: '变体SKU',
minWidth: 160,
},
{
key: 'stockSku',
prop: 'stockSku',
label: '库存SKU',
minWidth: 160,
},
{
key: 'craftCode',
prop: 'craftCode',
label: '工艺',
minWidth: 120,
},
{
key: 'styleNo',
prop: 'styleNo',
label: '款号',
minWidth: 120,
},
{
key: 'price',
prop: 'price',
label: '价格',
minWidth: 100,
},
{
key: 'quantity',
prop: 'quantity',
label: '数量',
minWidth: 100,
},
{
key: 'weight',
prop: 'weight',
label: '克重',
minWidth: 100,
},
{
key: 'availableQuantity',
prop: 'availableQuantity',
label: '可用数量',
minWidth: 110,
},
{
key: 'stockQuantity',
prop: 'stockQuantity',
label: '库存数量',
minWidth: 110,
},
{
key: 'occupiedQuantity',
prop: 'occupiedQuantity',
label: '占用数量',
minWidth: 110,
},
]
const {
currentPage,
pageSize,
total,
data: tableData,
onCurrentPageChange,
onPageSizeChange,
refresh,
} = usePageList<FactoryOrderNewListData>({
query: (page, size) =>
getFactoryOrderNewListApi(
{
...searchForm.value,
craftCode: craftCode.value,
startTime: dateRange.value?.[0] || null,
endTime: dateRange.value?.[1] || null,
},
page,
size,
status.value === 'ALL' ? undefined : status.value,
).then((res) => res.data),
})
const search = () => {
onCurrentPageChange(1)
refresh()
}
const reset = () => {
searchForm.value = {}
dateRange.value = []
craftCode.value = ''
search()
}
const handleStatusNodeClick = (node: StatusTreeNode) => {
status.value = node.code
// refresh()
}
const toggleExpand = (node: { expanded?: boolean }) => {
node.expanded = !node.expanded
}
const handlePageSizeChange = (size: number) => {
onPageSizeChange(size)
}
const handleCurrentPageChange = (page: number) => {
onCurrentPageChange(page)
}
const handleMainSelectionChange = (rows: FactoryOrderNewListData[]) => {
selectedRowIds.value = rows.map((row) => row.id)
}
const loadSubTables = async () => {
if (!currentRow.value) {
productList.value = []
logList.value = []
return
}
try {
const [productRes, logRes] = await Promise.all([
getFactoryOrderNewDetailApi(currentRow.value.id),
getFactoryOrderNewLogApi(currentRow.value.id),
])
productList.value = productRes.data || []
logList.value = logRes.data || []
} catch (e) {
console.error(e)
}
}
const handleMainRowClick = (row: FactoryOrderNewListData) => {
currentRow.value = row
loadSubTables()
}
watch(
() => activeTab.value,
() => {
if (currentRow.value) {
loadSubTables()
}
},
)
const confirmBatchAction = async (message: string) => {
if (!selectedRowIds.value.length) {
ElMessage.warning('请先选择订单')
return false
}
await ElMessageBox.confirm(message, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
return true
}
const handleConfirmOrder = async () => {
const ok = await confirmBatchAction('确认接单所选订单?')
if (!ok) return
await confirmOrderApi(selectedRowIds.value)
ElMessage.success('操作成功')
refresh()
}
onMounted(() => {
if (treeRef.value) {
treeRef.value.setCurrentKey(status.value, true)
}
loadCraftList()
getUserMark()
getCustomTagList()
getLogisticsCompanyAllCodelist()
getReceiverCountryList()
})
</script>
<style scoped lang="scss">
.header-title {
font-size: 16px;
font-weight: 600;
padding: 12px 16px;
.page {
display: flex;
}
</style>
.order-status {
width: 180px;
:deep(.el-tree-node__content) {
height: 30px;
line-height: 30px;
}
:deep(.el-tree-node__expand-icon) {
display: none;
}
:deep(.status-tree .el-tree-node.is-current > .el-tree-node__content) {
background-color: #ecf5ff !important;
color: #409eff !important;
.tree-node-label,
.tree-node-count {
color: #409eff !important;
}
.el-icon {
color: #409eff !important;
}
}
}
.tree-node {
display: flex;
align-items: center;
gap: 4px;
font-size: 14px;
color: #333;
font-weight: 500;
width: 100%;
justify-content: space-between;
}
.tree-node-label {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.tree-node-count {
flex-shrink: 0;
}
.tree-node-expand {
flex-shrink: 0;
cursor: pointer;
display: inline-flex;
&:hover {
color: #409eff;
}
}
.right {
flex: 1;
flex-shrink: 0;
background: #fff;
overflow: hidden;
}
.btn-list {
padding: 0 10px 10px;
}
.main-table-wrapper {
height: 100%;
display: flex;
flex-direction: column;
min-height: 0;
}
.main-table-scroll {
flex: 1;
min-height: 0;
overflow: auto;
}
.main-table-scroll :deep(.table-view) {
height: 100%;
}
.main-table-pagination {
flex-shrink: 0;
margin: 10px auto 0;
}
.tabs-wrapper {
height: 100%;
:deep(.el-tabs__content) {
height: calc(100% - 40px);
}
:deep(.el-tab-pane) {
height: 100%;
display: flex;
flex-direction: column;
}
}
.sub-table-wrapper,
.log-table-wrapper {
flex: 1;
overflow: hidden;
}
.table-content {
flex: 1;
margin-top: 10px;
overflow: hidden;
:deep(#top) {
height: 100%;
}
}
.header-filter-form {
width: 100%;
min-width: 0;
}
.search-form {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0;
min-width: 0;
:deep(.el-form-item) {
margin-right: 10px;
margin-bottom: 10px;
}
:deep(.el-form-item__content) {
min-width: 0;
}
}
</style>
<style lang="scss">
.customize-select-style {
.el-select-dropdown__list {
width: 500px;
display: flex;
flex-wrap: wrap;
}
}
</style>
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