| | |
| | | <span class="label">需求方:</span> |
| | | <span class="value">{{ row.demandSide }}</span> |
| | | </div> |
| | | <div class="order-item"> |
| | | <span class="label">供应方:</span> |
| | | <span class="value">{{ row.supplySide }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div v-else-if="row.isSpacer" class="spacer-cell"></div> |
| | |
| | | <div v-if="row.isSpacer" class="spacer-cell"></div> |
| | | <div v-else-if="!row.isMainOrder" class="price-info"> |
| | | <span v-if="row.priceType === 'points'" class="price-points"> |
| | | {{ row.unitPrice }} |
| | | 积分 {{ row.unitPrice }} |
| | | </span> |
| | | <span v-else-if="row.priceType === 'currency'" class="price-currency"> |
| | | {{ row.unitPrice }} |
| | | 货币 {{ row.unitPrice }} |
| | | </span> |
| | | <span v-else-if="row.priceType === 'agreement'" class="price-agreement"> |
| | | {{ row.unitPrice }} |
| | | 协议 |
| | | </span> |
| | | <span v-else-if="row.priceType === 'free'" class="price-free"> |
| | | {{ row.unitPrice }} |
| | | 免费 |
| | | </span> |
| | | </div> |
| | | </template> |
| | |
| | | <template #default="{ row }"> |
| | | <div v-if="row.isSpacer" class="spacer-cell"></div> |
| | | <div v-else-if="!row.isMainOrder" class="period-info"> |
| | | <span>{{ row.period }}</span> |
| | | <span v-if="row.isPermanent" class="permanent">永久</span> |
| | | <span v-if="row.period === 0" class="permanent">永久</span> |
| | | <span v-else>{{ row.period }}</span> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | <div v-if="row.parentOrder && row.parentOrder.subOrders && row.parentOrder.subOrders.findIndex((sub: any) => sub.id === row.id) === 0" class="all-actions"> |
| | | <div class="action-item"> |
| | | <div class="action-buttons"> |
| | | <span v-if="row.parentOrder.status === 'WAIT_CONFIRM'" class="op-text warning">待交易确认</span> |
| | | <span v-else-if="row.parentOrder.status === 'WAIT_EVALUATE'" class="op-text warning">待评价</span> |
| | | <span v-else-if="row.parentOrder.status === 'FINISH'" class="op-text">已完成</span> |
| | | <el-button type="primary" link size="small" @click="toDetail(row.parentOrder)">查看</el-button> |
| | | <template v-for="action in getAvailableActions(row.parentOrder)" :key="action.type"> |
| | | <el-button |
| | | v-if="action.type === ActionType.VIEW" |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleAction(action, row.parentOrder)" |
| | | > |
| | | 查看 |
| | | </el-button> |
| | | <el-button |
| | | v-else-if="action.type === ActionType.TRACK" |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleAction(action, row.parentOrder)" |
| | | > |
| | | 追踪 |
| | | </el-button> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | /> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 订单状态对话框 --> |
| | | <ProductOrderStatusDialog |
| | | v-model="orderStatusDialogVisible" |
| | | :order-id="currentOrderId" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import { onMounted, reactive, ref } from 'vue' |
| | | import { useRouter } from 'vue-router' |
| | | import { Search, Refresh } from '@element-plus/icons-vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import orderApi from '@/api/orderApi' |
| | | import { useUserInfo } from '@/stores/modules/userInfo' |
| | | import ProductOrderStatusDialog from '@/views/productManage/productOrderStatusDialog/index.vue' |
| | | import { OrderWorkflowController, OrderStatus, ActionType, PageType, StatusMapper } from '@/utils/orderWorkflow' |
| | | |
| | | const router = useRouter() |
| | | const userStore = useUserInfo() |
| | | |
| | | // 状态选项 |
| | | // 状态选项(更新为新的工作流程状态) |
| | | const statusOptions = [ |
| | | { label: '全部', value: '' }, |
| | | { label: '待上传文件', value: 'WAIT_UPLOAD' }, |
| | | { label: '待授权', value: 'WAIT_AUTHORIZE' }, |
| | | { label: '待交易确认', value: 'WAIT_CONFIRM' }, |
| | | { label: '待评价', value: 'WAIT_EVALUATE' }, |
| | | { label: '已完成', value: 'FINISH' }, |
| | | { label: '已完成', value: 'COMPLETED' }, |
| | | { label: '已评价', value: 'EVALUATED' }, |
| | | ] |
| | | |
| | | // 行业领域选项 |
| | |
| | | // 分页信息 |
| | | const page = reactive({ current: 1, size: 10, total: 0 }) |
| | | |
| | | // 订单列表数据 |
| | | // 订单列表数据(包含主订单和子订单) |
| | | const orderList = ref<any[]>([]) |
| | | |
| | | // 模拟数据用于展示 |
| | | const mockData = [ |
| | | { |
| | | id: '1', |
| | | isMainOrder: true, |
| | | applyTime: '2025-05-21 10:00:00', |
| | | orderNo: '4348442557619205545', |
| | | demandSide: '中国路桥工程有限公司', |
| | | supplySide: '中交方远科技有限公司', |
| | | status: 'WAIT_CONFIRM', |
| | | statusName: '待交易确认', |
| | | subOrders: [ |
| | | { |
| | | id: '1-1', |
| | | isMainOrder: false, |
| | | productName: '中交方远智能实测实量管理系统', |
| | | suiteName: '企业私有SaaS版许可', |
| | | salesForm: '买断', |
| | | accountCount: 50, |
| | | demandSide: '中国路桥工程有限公司', |
| | | customerObject: '企业', |
| | | concurrentCount: 50, |
| | | priceType: 'points', |
| | | unitPrice: '积分: 50,000/套', |
| | | quantity: 1, |
| | | period: 1, |
| | | isPermanent: true, |
| | | status: 'WAIT_CONFIRM', |
| | | }, |
| | | { |
| | | id: '1-2', |
| | | isMainOrder: false, |
| | | productName: '中交方远智能实测实量管理系统', |
| | | suiteName: '企业私有SaaS版OTA升级服务', |
| | | salesForm: 'OTA服务', |
| | | accountCount: 50, |
| | | demandSide: '中国路桥工程有限公司', |
| | | customerObject: '企业', |
| | | concurrentCount: 50, |
| | | priceType: 'currency', |
| | | unitPrice: '货币: 7,500/套/年', |
| | | quantity: 1, |
| | | period: 1, |
| | | isPermanent: false, |
| | | status: 'WAIT_CONFIRM', |
| | | }, |
| | | { |
| | | id: '1-3', |
| | | isMainOrder: false, |
| | | productName: '中交方远智能实测实量管理系统', |
| | | suiteName: '企业私有SaaS版用户增量包', |
| | | salesForm: '私有增量包', |
| | | accountCount: 100, |
| | | demandSide: '中国路桥工程有限公司', |
| | | customerObject: '企业', |
| | | concurrentCount: 100, |
| | | priceType: 'agreement', |
| | | unitPrice: '协议:/年', |
| | | quantity: 1, |
| | | period: 1, |
| | | isPermanent: false, |
| | | status: 'WAIT_CONFIRM', |
| | | }, |
| | | { |
| | | id: '1-4', |
| | | isMainOrder: false, |
| | | productName: '中交方远智能实测实量管理系统', |
| | | suiteName: '个人公有SaaS版许可', |
| | | salesForm: '私有增量包', |
| | | accountCount: 50, |
| | | demandSide: '中国路桥工程有限公司', |
| | | customerObject: '个人', |
| | | concurrentCount: 50, |
| | | priceType: 'free', |
| | | unitPrice: '免费:/年', |
| | | quantity: 3, |
| | | period: 3, |
| | | isPermanent: true, |
| | | status: 'WAIT_CONFIRM', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: '2', |
| | | isMainOrder: true, |
| | | applyTime: '2025-05-20 10:00:00', |
| | | orderNo: '4347442557619205545', |
| | | demandSide: '中交公路规划设计院有限公司', |
| | | supplySide: '华为软件技术有限公司', |
| | | status: 'WAIT_CONFIRM', |
| | | statusName: '待交易确认', |
| | | subOrders: [ |
| | | { |
| | | id: '2-1', |
| | | isMainOrder: false, |
| | | productName: '基于国产芯片宽窄融合自组网设备的应用', |
| | | suiteName: '企业公有SaaS版许可', |
| | | salesForm: '租赁', |
| | | accountCount: 100, |
| | | demandSide: '中交公路规划设计院有限公司', |
| | | customerObject: '企业', |
| | | concurrentCount: 100, |
| | | priceType: 'currency', |
| | | unitPrice: '货币: 80,000/年', |
| | | quantity: 1, |
| | | period: 2, |
| | | isPermanent: false, |
| | | status: 'WAIT_CONFIRM', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: '3', |
| | | isMainOrder: true, |
| | | applyTime: '2025-05-19 10:00:00', |
| | | orderNo: '4347342557619205545', |
| | | demandSide: '中交第四航务工程局有限公司', |
| | | supplySide: '中交第四航务工程局有限公司', |
| | | status: 'WAIT_CONFIRM', |
| | | statusName: '待交易确认', |
| | | subOrders: [ |
| | | { |
| | | id: '3-1', |
| | | isMainOrder: false, |
| | | productName: '高桩码头辅助出图工具箱', |
| | | suiteName: '项目公有SaaS版许可', |
| | | salesForm: '租赁', |
| | | accountCount: 50, |
| | | demandSide: '中交第四航务工程局有限公司', |
| | | customerObject: '项目部', |
| | | concurrentCount: 50, |
| | | priceType: 'currency', |
| | | unitPrice: '货币: 60,000/年', |
| | | quantity: 1, |
| | | period: 3, |
| | | isPermanent: false, |
| | | status: 'WAIT_CONFIRM', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: '4', |
| | | isMainOrder: true, |
| | | applyTime: '2025-05-18 10:00:00', |
| | | orderNo: '4347442557619205545', |
| | | demandSide: '中交公路规划设计院有限公司', |
| | | supplySide: '中交公路规划设计院有限公司', |
| | | status: 'WAIT_EVALUATE', |
| | | statusName: '待评价', |
| | | subOrders: [ |
| | | { |
| | | id: '4-1', |
| | | isMainOrder: false, |
| | | productName: '公路数字化方案设计系统', |
| | | suiteName: '企业公有SaaS版许可', |
| | | salesForm: '租赁', |
| | | accountCount: 100, |
| | | demandSide: '中交公路规划设计院有限公司', |
| | | customerObject: '企业', |
| | | concurrentCount: 100, |
| | | priceType: 'currency', |
| | | unitPrice: '货币: 80,000/年', |
| | | quantity: 1, |
| | | period: 1, |
| | | isPermanent: false, |
| | | status: 'WAIT_EVALUATE', |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | id: '5', |
| | | isMainOrder: true, |
| | | applyTime: '2025-05-17 10:00:00', |
| | | orderNo: '4347342557619205545', |
| | | demandSide: '中交第四航务工程局有限公司', |
| | | supplySide: '中交第三航务工程局有限公司', |
| | | status: 'FINISH', |
| | | statusName: '已完成', |
| | | subOrders: [ |
| | | { |
| | | id: '5-1', |
| | | isMainOrder: false, |
| | | productName: '基于无人机的企业级可视化项目管理系统', |
| | | suiteName: '项目公有SaaS版许可', |
| | | salesForm: '租赁', |
| | | accountCount: 50, |
| | | demandSide: '中交第四航务工程局有限公司', |
| | | customerObject: '项目部', |
| | | concurrentCount: 50, |
| | | priceType: 'free', |
| | | unitPrice: '免费:/年', |
| | | quantity: 1, |
| | | period: 1, |
| | | isPermanent: true, |
| | | status: 'FINISH', |
| | | }, |
| | | ], |
| | | }, |
| | | ] |
| | | // 订单状态对话框相关 |
| | | const orderStatusDialogVisible = ref(false) |
| | | const currentOrderId = ref<string>('') |
| | | |
| | | // 使用工作流程控制器的状态映射 |
| | | const statusUiToServer: Record<string, string> = { |
| | | WAIT_UPLOAD: OrderStatus.WAIT_UPLOAD, |
| | | WAIT_AUTHORIZE: OrderStatus.WAIT_AUTHORIZE, |
| | | WAIT_CONFIRM: OrderStatus.WAIT_CONFIRM, |
| | | COMPLETED: OrderStatus.COMPLETED, |
| | | EVALUATED: OrderStatus.EVALUATED, |
| | | } |
| | | |
| | | const statusServerToUi: Record<string, string> = { |
| | | [OrderStatus.WAIT_UPLOAD]: 'WAIT_UPLOAD', |
| | | [OrderStatus.WAIT_AUTHORIZE]: 'WAIT_AUTHORIZE', |
| | | [OrderStatus.WAIT_CONFIRM]: 'WAIT_CONFIRM', |
| | | [OrderStatus.COMPLETED]: 'COMPLETED', |
| | | [OrderStatus.EVALUATED]: 'EVALUATED', |
| | | } |
| | | |
| | | const formatDateTime = (val?: string) => { |
| | | if (!val) return '' |
| | | return val.replace('T', ' ').slice(0, 19) |
| | | } |
| | | |
| | | const normalizePriceType = (val?: string): 'points' | 'currency' | 'agreement' | 'free' => { |
| | | if (!val) return 'currency' |
| | | const s = String(val) |
| | | if (/(积分|points)/i.test(s)) return 'points' |
| | | if (/(协议|agreement)/i.test(s)) return 'agreement' |
| | | if (/(免费|free)/i.test(s)) return 'free' |
| | | return 'currency' |
| | | } |
| | | |
| | | |
| | | |
| | | // 获取状态类型 |
| | | const getStatusType = (status: string) => { |
| | | const statusMap: Record<string, 'warning' | 'danger' | 'success' | 'info'> = { |
| | | WAIT_UPLOAD: 'warning', |
| | | WAIT_AUTHORIZE: 'warning', |
| | | WAIT_CONFIRM: 'warning', |
| | | WAIT_EVALUATE: 'warning', |
| | | FINISH: 'success', |
| | | COMPLETED: 'success', |
| | | EVALUATED: 'success', |
| | | } |
| | | return statusMap[status] || 'info' |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // 搜索处理 |
| | | // 搜索处理(接入真实后端) |
| | | const handleSearch = async () => { |
| | | // 使用模拟数据 |
| | | const flatData: any[] = [] |
| | | mockData.forEach(order => { |
| | | flatData.push(order) |
| | | if (order.subOrders) { |
| | | order.subOrders.forEach((subOrder: any) => { |
| | | flatData.push({ ...subOrder, parentOrder: order }) |
| | | }) |
| | | try { |
| | | // 获取用户ID作为providerId,如果没有则使用默认值 |
| | | const userId = userStore.getUserId |
| | | const providerId = userId ? Number(userId) : 1 // 使用默认值1作为临时解决方案 |
| | | |
| | | const payload: any = { |
| | | pageNum: page.current, |
| | | pageSize: page.size, |
| | | productName: query.productName || undefined, |
| | | orderId: query.orderNo || undefined, |
| | | providerId: providerId, |
| | | } |
| | | // 在每个订单块的末尾插入一个分隔空行 |
| | | flatData.push({ isSpacer: true, isMainOrder: false, parentOrder: order }) |
| | | }) |
| | | |
| | | orderList.value = flatData |
| | | page.total = mockData.length |
| | | if (query.status) payload.orderStatus = statusUiToServer[query.status] |
| | | if (Array.isArray(query.dateRange) && query.dateRange.length === 2) { |
| | | payload.applyTimeStart = query.dateRange[0] |
| | | payload.applyTimeEnd = query.dateRange[1] |
| | | } |
| | | |
| | | const res = (await orderApi.getSellerOrderPage(payload)) as any |
| | | const pageData = res?.data |
| | | const list: any[] = Array.isArray(pageData?.list) ? pageData.list : [] |
| | | page.total = Number(pageData?.total || 0) |
| | | |
| | | // 并发获取每个订单的详情(用于构造子订单行) |
| | | const detailsArr = await Promise.all( |
| | | list.map(async (order: any) => { |
| | | try { |
| | | const detailRes = (await orderApi.getOrderDetail(order.orderId)) as any |
| | | return detailRes?.data |
| | | } catch (e) { |
| | | return null |
| | | } |
| | | }) |
| | | ) |
| | | |
| | | const flatData: any[] = [] |
| | | list.forEach((order: any, idx: number) => { |
| | | const uiStatus = statusServerToUi[order.orderStatus] || 'WAIT_UPLOAD' |
| | | const mainRow: any = { |
| | | id: order.orderId, |
| | | isMainOrder: true, |
| | | applyTime: formatDateTime(order.applyTime || ''), |
| | | orderNo: order.orderId, |
| | | demandSide: order.demandSideName || '', |
| | | supplySide: order.providerName || '', |
| | | status: uiStatus, |
| | | statusName: order.orderStatus || '', |
| | | orderStatus: StatusMapper.toUIStatus(order.orderStatus), // 转换为标准状态枚举 |
| | | } |
| | | |
| | | const detail = detailsArr[idx] |
| | | const subOrders: any[] = Array.isArray(detail?.orderDetails) |
| | | ? detail.orderDetails.map((d: any, i: number) => ({ |
| | | id: `${order.orderId}-${i + 1}`, |
| | | isMainOrder: false, |
| | | productName: order.productName || '', |
| | | suiteName: d.suiteName, |
| | | salesForm: d.salesForm, |
| | | accountCount: d.accountLimit, |
| | | customerObject: d.customerType, |
| | | concurrentCount: d.concurrentNodes, |
| | | priceType: normalizePriceType(d.priceType), |
| | | unitPrice: d.unitPrice, |
| | | quantity: d.quantity, |
| | | period: d.duration, |
| | | })) |
| | | : [] |
| | | |
| | | ;(mainRow as any).subOrders = subOrders |
| | | |
| | | flatData.push(mainRow) |
| | | subOrders.forEach((sub) => flatData.push({ ...sub, parentOrder: mainRow })) |
| | | flatData.push({ isSpacer: true, isMainOrder: false, parentOrder: mainRow }) |
| | | }) |
| | | |
| | | orderList.value = flatData |
| | | } catch (error: any) { |
| | | console.error('查询卖家订单列表失败:', error) |
| | | ElMessage.error(error?.message || '查询卖家订单列表失败') |
| | | orderList.value = [] |
| | | page.total = 0 |
| | | } |
| | | } |
| | | |
| | | // 重置 |
| | |
| | | handleSearch() |
| | | } |
| | | |
| | | // 获取可用操作列表 |
| | | const getAvailableActions = (order: any) => { |
| | | if (!order.orderStatus) return [] |
| | | return OrderWorkflowController.getAvailableActions(PageType.SELLER_CENTER, order.orderStatus) |
| | | } |
| | | |
| | | // 追踪订单 - 显示订单状态对话框 |
| | | const showOrderTrack = (row: any) => { |
| | | currentOrderId.value = row.id |
| | | orderStatusDialogVisible.value = true |
| | | } |
| | | |
| | | // 处理操作点击 |
| | | const handleAction = (action: any, order: any) => { |
| | | switch (action.type) { |
| | | case ActionType.VIEW: |
| | | toDetail(order) |
| | | break |
| | | case ActionType.TRACK: |
| | | showOrderTrack(order) |
| | | break |
| | | default: |
| | | console.warn('未知的操作类型:', action.type) |
| | | } |
| | | } |
| | | |
| | | // 路由跳转 |
| | | const toDetail = (row: any) => router.push({ name: 'tradeOrderDetail', params: { id: row.id } }) |
| | | |