| | |
| | | <el-input v-model="query.productName" placeholder="请输入产品名称" clearable style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="行业领域" class="col-25"> |
| | | <el-select v-model="query.industry" placeholder="请选择行业领域" clearable style="width: 100%"> |
| | | <el-select v-model="query.industry" placeholder="请选择行业领域" clearable style="width: 100%" @change="handleIndustryChange"> |
| | | <el-option v-for="item in industryOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="" class="col-17"> |
| | | <el-select v-model="query.unitProject" placeholder="请选择单位工程" clearable style="width: 100%"> |
| | | <el-option v-for="item in unitProjectOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | <!-- <el-select v-model="query.unitProject" placeholder="请选择单位工程" clearable style="width: 100%">--> |
| | | <!-- <el-option v-for="item in unitProjectOptions" :key="item.value" :label="item.label" :value="item.value" />--> |
| | | <!-- </el-select>--> |
| | | <el-tree-select |
| | | ref="areaIdTreeRef" |
| | | v-model="query.unitProject" |
| | | :data="unitProjectOptions" |
| | | placeholder="请选择单位工程" |
| | | multiple |
| | | collapse-tags |
| | | collapse-tags-tooltip |
| | | clearable |
| | | :default-expand-all="true" |
| | | :render-after-expand="false" |
| | | show-checkbox |
| | | style="width: 170px;" |
| | | @change="importantAreaCh" |
| | | @clear="importantAreaClear" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="交易状态" class="col-30"> |
| | | <el-select v-model="query.status" placeholder="全部" style="width: 100%"> |
| | |
| | | <el-input v-model="query.orderNo" placeholder="请输入订单编号" clearable style="width: 100%" /> |
| | | </el-form-item> |
| | | <el-form-item label="产品类型" class="col-25"> |
| | | <el-select v-model="query.productType" placeholder="请选择产品类型" clearable style="width: 100%"> |
| | | <el-select v-model="query.productType" placeholder="请选择产品类型" clearable style="width: 100%" @change="handleProductTypeChange"> |
| | | <el-option v-for="item in productTypeOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="" class="col-17"> |
| | | <el-select v-model="query.productSubType" placeholder="请选择产品类型子级" clearable style="width: 100%"> |
| | | <el-option v-for="item in productSubTypeOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <!-- <el-form-item label="" class="col-17">--> |
| | | <!-- <el-select v-model="query.productSubType" placeholder="请选择产品类型子级" clearable style="width: 100%">--> |
| | | <!-- <el-option v-for="item in productSubTypeOptions" :key="item.value" :label="item.label" :value="item.value" />--> |
| | | <!-- </el-select>--> |
| | | <!-- </el-form-item>--> |
| | | <el-form-item label="申请时间" class="col-30"> |
| | | <el-date-picker |
| | | v-model="query.dateRange" |
| | |
| | | <!-- 第三行:操作按钮(右对齐) --> |
| | | <div class="form-row actions"> |
| | | <el-form-item class="row-actions"> |
| | | <el-button type="primary" @click="handleSearch" :icon="Search">查询</el-button> |
| | | <el-button @click="reset" :icon="Refresh">重置</el-button> |
| | | <el-button type="primary" @click="handleSearch" icon="Search">查询</el-button> |
| | | <el-button @click="reset" icon="Refresh">重置</el-button> |
| | | </el-form-item> |
| | | </div> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <div class="buttonDiv"> |
| | | <el-row> |
| | | <el-col :span="6" style="margin-top: 10px"> </el-col> |
| | | <el-col :span="18" align="right" style="margin-top: 10px"> |
| | | <div class="btnBox"> |
| | | <div |
| | | class="btnDiv" |
| | | :class="{ btnDivClass: workFlowStatus.btnClassShow == 'trade_point0' }" |
| | | @click="btnClick('0','trade_point')" |
| | | > |
| | | <span class="numjx">积分待办</span> |
| | | <span class="count-num">({{ workFlowStatus.tradePointDealData }})</span> |
| | | </div> |
| | | <div |
| | | class="btnDiv" |
| | | :class="{ btnDivClass: workFlowStatus.btnClassShow == 'trade_point1' }" |
| | | @click="btnClick('1','trade_point')" |
| | | > |
| | | <span class="numjx">积分已办</span> |
| | | <span class="count-num">({{ workFlowStatus.tradePointCompletedData }})</span> |
| | | </div> |
| | | <div |
| | | class="btnDiv" |
| | | :class="{ btnDivClass: workFlowStatus.btnClassShow == 'trade_agreement0' }" |
| | | @click="btnClick('0','trade_agreement')" |
| | | > |
| | | <span class="numjx">协议待办</span> |
| | | <span class="count-num">({{ workFlowStatus.tradeAgreementDealData }})</span> |
| | | </div> |
| | | <div |
| | | class="btnDiv" |
| | | :class="{ btnDivClass: workFlowStatus.btnClassShow == 'trade_agreement1' }" |
| | | @click="btnClick('1','trade_agreement')" |
| | | > |
| | | <span class="numjx">协议已办</span> |
| | | <span class="count-num">({{ workFlowStatus.tradeAgreementCompletedData }})</span> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | |
| | | <!-- 订单列表区域 --> |
| | | <el-card class="mt15" shadow="never"> |
| | |
| | | <template #default="{ row }"> |
| | | <div v-if="row.isMainOrder" class="main-order-info"> |
| | | <div class="order-header"> |
| | | <div class="order-item status-item"> |
| | | <el-tag :type="getStatusType(row.status)" size="small">{{ row.statusName }}</el-tag> |
| | | </div> |
| | | <div class="order-item"> |
| | | <span class="label">申请时间:</span> |
| | | <span class="value">{{ row.applyTime }}</span> |
| | |
| | | <div class="order-item"> |
| | | <span class="label">供应方:</span> |
| | | <span class="value">{{ row.supplySide }}</span> |
| | | </div> |
| | | <div class="order-item status-item"> |
| | | <el-tag :type="getStatusType(row.status)" size="small">{{ row.statusName }}</el-tag> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </el-table-column> |
| | | </el-table-column> |
| | | |
| | | <!-- 总价 --> |
| | | <el-table-column label="总价" align="center"> |
| | | <el-table-column label="单价" prop="unitPrice" width="90"> |
| | | <!-- 单价(与“期限(年)”保持相同的父子表头结构) --> |
| | | <el-table-column label="单价" align="center" width="80"> |
| | | <el-table-column label="" prop="unitPrice" width="80"> |
| | | <template #default="{ row }"> |
| | | <div v-if="row.isSpacer" class="spacer-cell"></div> |
| | | <div v-else-if="!row.isMainOrder" class="price-info"> |
| | |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数量" prop="quantity" width="50"> |
| | | </el-table-column> |
| | | |
| | | <!-- 数量(与“期限(年)”保持相同的父子表头结构) --> |
| | | <el-table-column label="数量" align="center" width="80"> |
| | | <el-table-column label="" prop="quantity" width="80" align="center"> |
| | | <template #default="{ row }"> |
| | | <div v-if="row.isSpacer" class="spacer-cell"></div> |
| | | <div v-else-if="!row.isMainOrder" class="quantity">{{ row.quantity }}</div> |
| | |
| | | |
| | | <!-- 期限(年) --> |
| | | <el-table-column label="期限(年)" align="center" width="80"> |
| | | <el-table-column label="" prop="period" width="80"> |
| | | <el-table-column label="" prop="period" width="80" align="center"> |
| | | <template #default="{ row }"> |
| | | <div v-if="row.isSpacer" class="spacer-cell"></div> |
| | | <div v-else-if="!row.isMainOrder" class="period-info"> |
| | |
| | | <div class="action-buttons"> |
| | | <template v-for="action in getAvailableActions(row.parentOrder)" :key="action.type"> |
| | | <el-button |
| | | v-if="action.type === ActionType.AUTHORIZE" |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleAction(action, row.parentOrder)" |
| | | > |
| | | 授权 |
| | | </el-button> |
| | | <el-button |
| | | v-else-if="action.type === ActionType.VIEW" |
| | | 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.AUTHORIZE" |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleAction(action, row.parentOrder)" |
| | | > |
| | | 授权 |
| | | </el-button> |
| | | <el-button |
| | | v-else-if="action.type === ActionType.WAIT_APPROVAL_AUTHORIZE" |
| | | type="primary" |
| | | link |
| | | size="small" |
| | | @click="handleAction(action, row.parentOrder)" |
| | | > |
| | | |
| | | 审批 |
| | | </el-button> |
| | | </template> |
| | | </div> |
| | |
| | | </el-card> |
| | | |
| | | <!-- 订单状态对话框 --> |
| | | <ProductOrderStatusDialog |
| | | v-model="orderStatusDialogVisible" |
| | | :order-id="currentOrderId" |
| | | /> |
| | | <!-- <ProductOrderStatusDialog --> |
| | | <!-- v-model="orderStatusDialogVisible" --> |
| | | <!-- :order-id="currentOrderId" --> |
| | | <!-- />--> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { onMounted, reactive, ref } from 'vue' |
| | | import { useRouter } from 'vue-router' |
| | | import { Search, Refresh } from '@element-plus/icons-vue' |
| | | import { fetchApprovalPage } from '@/api/approvalManage' |
| | | import orderApi from '@/api/orderApi' |
| | | import { authorizeApproval, fetchApprovalByOrderId } from '@/api/approvalManage' |
| | | import { ElMessage } from 'element-plus' |
| | | import { fetchApprovalPage, fetchApprovalPageWithProductConditions } from '@/api/approvalManage' |
| | | import productApi from '@/api/productApi' |
| | | import { useUserInfo } from '@/stores/modules/userInfo' |
| | | import ProductOrderStatusDialog from '@/views/productManage/productOrderStatusDialog/index.vue' |
| | | import { OrderWorkflowController, OrderStatus, ActionType, PageType, StatusMapper } from '@/utils/orderWorkflow' |
| | | import { queryUserDetail } from '@/api/userInfo' |
| | | |
| | | const router = useRouter() |
| | | const userStore = useUserInfo() |
| | | const areaIdTreeRef=ref<any>() |
| | | |
| | | // 状态选项(更新为新的工作流程状态) |
| | | const statusOptions = [ |
| | |
| | | { label: '已评价', value: 'EVALUATED' }, |
| | | ] |
| | | |
| | | // 行业领域选项 |
| | | const industryOptions = [ |
| | | { label: '建筑工程', value: 'construction' }, |
| | | { label: '交通工程', value: 'transportation' }, |
| | | { label: '水利工程', value: 'water' }, |
| | | { label: '电力工程', value: 'power' }, |
| | | ] |
| | | |
| | | // 单位工程选项 |
| | | const unitProjectOptions = [ |
| | | { label: '土建工程', value: 'civil' }, |
| | | { label: '安装工程', value: 'installation' }, |
| | | { label: '装饰工程', value: 'decoration' }, |
| | | ] |
| | | |
| | | // 产品类型选项 |
| | | const productTypeOptions = [ |
| | | { label: '企业私有SaaS版许可', value: 'enterprise_private' }, |
| | | { label: '企业公有SaaS版许可', value: 'enterprise_public' }, |
| | | { label: '项目公有SaaS版许可', value: 'project_public' }, |
| | | { label: '个人公有SaaS版许可', value: 'personal_public' }, |
| | | ] |
| | | |
| | | // 产品类型子级选项 |
| | | const productSubTypeOptions = [ |
| | | { label: '基础版', value: 'basic' }, |
| | | { label: '标准版', value: 'standard' }, |
| | | { label: '高级版', value: 'premium' }, |
| | | ] |
| | | // 动态选项数据 |
| | | const industryOptions = ref<any[]>([]) |
| | | const unitProjectOptions = ref<any[]>([]) |
| | | const productTypeOptions = ref<any[]>([]) |
| | | const productSubTypeOptions = ref<any[]>([]) |
| | | |
| | | // 查询条件 |
| | | const query = reactive({ |
| | | productName: '', |
| | | industry: '', |
| | | unitProject: '', |
| | | unitProject: [] as string[], |
| | | productType: '', |
| | | productSubType: '', |
| | | importantDistrictIdList: [] as string[], |
| | | orderNo: '', |
| | | status: '', |
| | | dateRange: [], |
| | | dateRange: [] as string[], |
| | | }) |
| | | |
| | | // 分页信息 |
| | |
| | | // 订单状态对话框相关 |
| | | const orderStatusDialogVisible = ref(false) |
| | | const currentOrderId = ref<string>('') |
| | | |
| | | const workFlowStatus = reactive<any>({ |
| | | btnClassShow: 'trade_point0', |
| | | workFlowType: 0, |
| | | businessType: 'trade_point', // trade_point |
| | | // 订单数量统计 |
| | | tradePointDealData: 1, // 积分待办数量 - 临时测试数据 |
| | | tradePointCompletedData: 0, // 积分已办数量 |
| | | tradeAgreementDealData: 2, // 协议待办数量 - 临时测试数据 |
| | | tradeAgreementCompletedData: 0 // 协议已办数量 |
| | | }) |
| | | |
| | | // 使用工作流程控制器的状态映射 |
| | | const statusUiToServer: Record<string, string> = { |
| | |
| | | [OrderStatus.WAIT_CONFIRM]: 'WAIT_CONFIRM', |
| | | [OrderStatus.COMPLETED]: 'COMPLETED', |
| | | [OrderStatus.EVALUATED]: 'EVALUATED', |
| | | [OrderStatus.CANCELED]: 'CANCELED' |
| | | } |
| | | |
| | | const formatDateTime = (val?: string) => { |
| | |
| | | return 'currency' |
| | | } |
| | | |
| | | const importantAreaCh=()=>{ |
| | | let checkedKeys = areaIdTreeRef.value!.getCheckedNodes(false, true) |
| | | if(checkedKeys&&checkedKeys.length>0&& query.unitProject.length>0){ |
| | | query.importantDistrictIdList=[] as string[] |
| | | checkedKeys.forEach((item:any)=>{ |
| | | if(item.children&&item.children.length>0){ |
| | | query.importantDistrictIdList.push(item.value) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const importantAreaClear=()=>{ |
| | | query.unitProject = [] as string[] |
| | | query.importantDistrictIdList = [] as string[] |
| | | areaIdTreeRef.value.setCheckedKeys([]) |
| | | } |
| | | |
| | | // 获取行业领域选项 |
| | | const getIndustryOptions = async () => { |
| | | try { |
| | | const res = await productApi.getCategoryByParent({ parentCode: 'business_direction' }) |
| | | if (res?.code === 200 && res.data) { |
| | | industryOptions.value = res.data.map((item: any) => ({ |
| | | label: item.name, |
| | | value: item.id |
| | | })) |
| | | } |
| | | } catch (error) { |
| | | console.error('获取行业领域选项失败:', error) |
| | | } |
| | | } |
| | | |
| | | // 获取产品类型选项 |
| | | const getProductTypeOptions = async () => { |
| | | try { |
| | | const res = await productApi.getCategoryByParent({ parentCode: 'ProductTechnologyType' }) |
| | | if (res?.code === 200 && res.data) { |
| | | productTypeOptions.value = res.data.map((item: any) => ({ |
| | | label: item.name, |
| | | value: item.id |
| | | })) |
| | | } |
| | | } catch (error) { |
| | | console.error('获取产品类型选项失败:', error) |
| | | } |
| | | } |
| | | |
| | | // 根据行业领域获取单位工程选项 |
| | | const getUnitProjectOptions = async (industryCode: string) => { |
| | | if (!industryCode) { |
| | | unitProjectOptions.value = [] |
| | | return |
| | | } |
| | | try { |
| | | const res = await productApi.getCategoryByParent({ parentId: industryCode }) |
| | | if (res?.code === 200 && res.data) { |
| | | unitProjectOptions.value = handleIndustryData(res.data) |
| | | } |
| | | } catch (error) { |
| | | console.error('获取单位工程选项失败:', error) |
| | | unitProjectOptions.value = [] |
| | | } |
| | | } |
| | | |
| | | const handleIndustryData=(list:any)=>{ |
| | | if(list&& list.length>0){ |
| | | let data=list.map((item:any)=>{ |
| | | return { |
| | | label:item.name, |
| | | value:item.id, |
| | | parentId:item.parentId, |
| | | parentName:item.parentName, |
| | | children:item.childrenList?handleIndustryChildData(item,item.childrenList):[] |
| | | } |
| | | }) |
| | | return data |
| | | } |
| | | } |
| | | const handleIndustryChildData=(parentItem:any,childList:any)=>{ |
| | | if(childList&& childList.length>0){ |
| | | let data=childList.map((item:any)=>{ |
| | | return { |
| | | parentId:parentItem.id, |
| | | parentName:parentItem.name, |
| | | label:item.name, |
| | | value:item.id, |
| | | children:item.childrenList?handleIndustryChildData(item,item.childrenList):[] |
| | | } |
| | | }) |
| | | return data |
| | | } |
| | | } |
| | | |
| | | // 根据产品类型获取产品子级选项 |
| | | const getProductSubTypeOptions = async (productTypeCode: string) => { |
| | | if (!productTypeCode) { |
| | | productSubTypeOptions.value = [] |
| | | return |
| | | } |
| | | try { |
| | | const res = await productApi.getCategoryByParent({ parentId: productTypeCode }) |
| | | if (res?.code === 200 && res.data) { |
| | | productSubTypeOptions.value = res.data.map((item: any) => ({ |
| | | label: item.name, |
| | | value: item.id |
| | | })) |
| | | } |
| | | } catch (error) { |
| | | console.error('获取产品子级选项失败:', error) |
| | | productSubTypeOptions.value = [] |
| | | } |
| | | } |
| | | |
| | | // 处理行业领域变化 |
| | | const handleIndustryChange = async (value: string) => { |
| | | // 清空单位工程选择 |
| | | query.unitProject = [] as string[] |
| | | // 获取对应的单位工程选项 |
| | | await getUnitProjectOptions(value) |
| | | } |
| | | |
| | | // 处理产品类型变化 |
| | | const handleProductTypeChange = async (value: string) => { |
| | | // 清空产品子级选择 |
| | | query.productSubType = '' |
| | | // 获取对应的产品子级选项 |
| | | // await getProductSubTypeOptions(value) |
| | | } |
| | | |
| | | // 获取状态类型 |
| | | const getStatusType = (status: string) => { |
| | | const statusMap: Record<string, 'warning' | 'danger' | 'success' | 'info'> = { |
| | |
| | | WAIT_CONFIRM: 'warning', |
| | | COMPLETED: 'success', |
| | | EVALUATED: 'success', |
| | | CANCELED: 'danger' |
| | | } |
| | | return statusMap[status] || 'info' |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // 根据当前选中的按钮类型更新对应的数量 |
| | | const updateButtonCount = (total: number) => { |
| | | const { workFlowType, businessType } = workFlowStatus |
| | | |
| | | console.log('updateButtonCount 被调用:', { |
| | | total: total, |
| | | workFlowType: workFlowType, |
| | | businessType: businessType, |
| | | currentButton: `${businessType}${workFlowType}` |
| | | }) |
| | | |
| | | if (businessType === 'trade_point') { |
| | | if (workFlowType == 0) { // 使用 == 而不是 === 来处理字符串和数字的比较 |
| | | // 积分待办 |
| | | workFlowStatus.tradePointDealData = total |
| | | console.log('更新积分待办数量为:', total) |
| | | } else if (workFlowType == 1) { // 使用 == 而不是 === 来处理字符串和数字的比较 |
| | | // 积分已办 |
| | | workFlowStatus.tradePointCompletedData = total |
| | | console.log('更新积分已办数量为:', total) |
| | | } |
| | | } else if (businessType === 'trade_agreement') { |
| | | if (workFlowType == 0) { // 使用 == 而不是 === 来处理字符串和数字的比较 |
| | | // 协议待办 |
| | | workFlowStatus.tradeAgreementDealData = total |
| | | console.log('更新协议待办数量为:', total) |
| | | } else if (workFlowType == 1) { // 使用 == 而不是 === 来处理字符串和数字的比较 |
| | | // 协议已办 |
| | | workFlowStatus.tradeAgreementCompletedData = total |
| | | console.log('更新协议已办数量为:', total) |
| | | } |
| | | } |
| | | |
| | | console.log('更新后的按钮数量:', { |
| | | tradePointDealData: workFlowStatus.tradePointDealData, |
| | | tradePointCompletedData: workFlowStatus.tradePointCompletedData, |
| | | tradeAgreementDealData: workFlowStatus.tradeAgreementDealData, |
| | | tradeAgreementCompletedData: workFlowStatus.tradeAgreementCompletedData |
| | | }) |
| | | } |
| | | |
| | | // 获取订单统计数据(用于初始化和条件查询后更新) |
| | | const getOrderCounts = async () => { |
| | | try { |
| | | // 获取统计数据时使用当前的搜索条件,但不包括状态筛选 |
| | | const getCountForType = async (workFlowType: number, businessType: string) => { |
| | | const payload: any = { |
| | | pageNum: 1, |
| | | pageSize: 10, // 与handleSearch保持一致 |
| | | userId: userStore.getUserId, |
| | | unitId: userStore.getUnitId, |
| | | workFlowType: workFlowType, |
| | | businessType: businessType, |
| | | departmentId: userStore.getDepartmentId |
| | | } |
| | | |
| | | // 添加产品条件查询(与handleSearch完全保持一致) |
| | | if (query.industry) payload.industryId = query.industry |
| | | if (query.unitProject.length > 0) payload.unitProjectId = query.unitProject |
| | | if (query.importantDistrictIdList.length > 0) payload.importantDistrictId = query.importantDistrictIdList |
| | | if (query.productType) payload.productTypeId = query.productType |
| | | if (query.productSubType) payload.productSubTypeId = query.productSubType |
| | | if (query.productName) payload.productName = query.productName |
| | | if (query.orderNo) payload.orderId = query.orderNo |
| | | // 包含状态筛选条件,确保统计数据反映当前的筛选条件 |
| | | 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] |
| | | } |
| | | |
| | | // 根据是否有产品条件选择不同的API(与handleSearch保持一致) |
| | | const hasProductConditions = query.industry || query.unitProject.length > 0 || query.productType || query.productSubType |
| | | const apiMethod = hasProductConditions ? fetchApprovalPageWithProductConditions : fetchApprovalPage |
| | | |
| | | console.log(`统计数据-${businessType}${workFlowType}查询参数:`, payload) |
| | | const res = await apiMethod(payload) as any |
| | | console.log(`统计数据-${businessType}${workFlowType}API响应:`, res) |
| | | return res?.data?.total || 0 |
| | | } |
| | | |
| | | // 并行获取所有统计数据 |
| | | const [pointDealCount, pointCompletedCount, agreementDealCount, agreementCompletedCount] = await Promise.all([ |
| | | getCountForType(0, 'trade_point'), // 积分待办 |
| | | getCountForType(1, 'trade_point'), // 积分已办 |
| | | getCountForType(0, 'trade_agreement'), // 协议待办 |
| | | getCountForType(1, 'trade_agreement') // 协议已办 |
| | | ]) |
| | | |
| | | workFlowStatus.tradePointDealData = pointDealCount |
| | | workFlowStatus.tradePointCompletedData = pointCompletedCount |
| | | workFlowStatus.tradeAgreementDealData = agreementDealCount |
| | | workFlowStatus.tradeAgreementCompletedData = agreementCompletedCount |
| | | |
| | | console.log('更新后的统计数据:', { |
| | | tradePointDealData: workFlowStatus.tradePointDealData, |
| | | tradePointCompletedData: workFlowStatus.tradePointCompletedData, |
| | | tradeAgreementDealData: workFlowStatus.tradeAgreementDealData, |
| | | tradeAgreementCompletedData: workFlowStatus.tradeAgreementCompletedData |
| | | }) |
| | | } catch (error) { |
| | | console.error('获取统计数据失败:', error) |
| | | // 如果获取失败,使用默认值 |
| | | workFlowStatus.tradePointDealData = 0 |
| | | workFlowStatus.tradePointCompletedData = 0 |
| | | workFlowStatus.tradeAgreementDealData = 0 |
| | | workFlowStatus.tradeAgreementCompletedData = 0 |
| | | } |
| | | } |
| | | |
| | | // 搜索处理(接入真实后端) |
| | | const handleSearch = async () => { |
| | | const payload: any = { |
| | |
| | | pageSize: page.size, |
| | | productName: query.productName || undefined, |
| | | orderId: query.orderNo || undefined, |
| | | userId: userStore.getUserId, |
| | | unitId: userStore.getUnitId, |
| | | workFlowType: workFlowStatus.workFlowType, |
| | | businessType: workFlowStatus.businessType, |
| | | departmentId: userStore.getDepartmentId |
| | | } |
| | | 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] |
| | | } |
| | | |
| | | // 添加产品条件查询 |
| | | if (query.industry) payload.industryId = query.industry |
| | | if (query.unitProject.length > 0) payload.unitProjectId = query.unitProject |
| | | if (query.importantDistrictIdList.length > 0) payload.importantDistrictId = query.importantDistrictIdList |
| | | if (query.productType) payload.productTypeId = query.productType |
| | | if (query.productSubType) payload.productSubTypeId = query.productSubType |
| | | |
| | | const res = (await fetchApprovalPage(payload)) as any |
| | | // 根据是否有产品条件选择不同的API |
| | | const hasProductConditions = query.industry || query.unitProject.length > 0 || query.productType || query.productSubType |
| | | const apiMethod = hasProductConditions ? fetchApprovalPageWithProductConditions : fetchApprovalPage |
| | | |
| | | const res = (await apiMethod(payload)) as any |
| | | const pageData = res?.data |
| | | const list: any[] = Array.isArray(pageData?.list) ? pageData.list : [] |
| | | page.total = Number(pageData?.total || 0) |
| | | |
| | | console.log('搜索参数:', payload) |
| | | console.log('API响应:', res) |
| | | console.log('列表数据:', list) |
| | | console.log('总记录数:', page.total) |
| | | console.log('当前页记录数:', list.length) |
| | | |
| | | // 并发获取每个订单的详情(用于构造子订单行) |
| | | 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: '', |
| | | supplySide: order.providerName || '', |
| | | status: uiStatus, |
| | | statusName: order.orderStatus || '', |
| | | orderStatus: StatusMapper.toUIStatus(order.orderStatus), // 转换为标准状态枚举 |
| | | } |
| | | 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: '', |
| | | supplySide: order.providerName || '', |
| | | status: uiStatus, |
| | | statusName: order.orderStatus || '', |
| | | orderStatus: StatusMapper.toUIStatus(order.orderStatus), // 转换为标准状态枚举 |
| | | workFlowId: order.workflowId || '', |
| | | taskId: order.taskId || '' |
| | | } |
| | | |
| | | const detail = detailsArr[idx] |
| | | const subOrders: any[] = Array.isArray(detail?.orderDetails) |
| | | ? detail.orderDetails.map((d: any, i: number) => ({ |
| | | const subOrders: any[] = Array.isArray(order?.orderDetails) |
| | | ? order?.orderDetails.map((d: any, i: number) => ({ |
| | | id: `${order.orderId}-${i + 1}`, |
| | | isMainOrder: false, |
| | | productName: order.productName || '', |
| | |
| | | }) |
| | | |
| | | orderList.value = flatData |
| | | |
| | | // 条件查询后,重新获取所有4种类型的订单总数并更新按钮显示 |
| | | await getOrderCounts() |
| | | } |
| | | |
| | | const btnClick = (workFlowType?: any,businessType?: any) => { |
| | | workFlowStatus.btnClassShow = businessType+workFlowType |
| | | workFlowStatus.workFlowType = Number(workFlowType) // 确保转换为数字类型 |
| | | workFlowStatus.businessType = businessType |
| | | |
| | | // 获取list数据 |
| | | handleSearch() |
| | | } |
| | | |
| | | // 重置 |
| | |
| | | Object.assign(query, { |
| | | productName: '', |
| | | industry: '', |
| | | unitProject: '', |
| | | unitProject: [], |
| | | productType: '', |
| | | productSubType: '', |
| | | orderNo: '', |
| | | status: '', |
| | | dateRange: [], |
| | | }) |
| | | // 清空动态选项 |
| | | unitProjectOptions.value = [] |
| | | productSubTypeOptions.value = [] |
| | | page.current = 1 |
| | | handleSearch() |
| | | } |
| | |
| | | const toApprove = (row: any) => router.push({ name: 'tradeApproval', params: { id: row.id } }) |
| | | const toCheckFiles = (row: any) => router.push({ name: 'tradeCheckFiles', params: { id: row.id } }) |
| | | const toDetail = (row: any) => router.push({ name: 'tradeOrderDetail', params: { id: row.id } }) |
| | | const toTrack = (row: any) => { |
| | | if (!row.workFlowId) { |
| | | ElMessage.warning('该订单暂无工作流信息') |
| | | return |
| | | } |
| | | router.push({ name: 'tradeTrack', params: { id: row.workFlowId } }) |
| | | } |
| | | |
| | | // 追踪订单 - 显示订单状态对话框 |
| | | const showOrderTrack = (row: any) => { |
| | |
| | | toDetail(order) |
| | | break |
| | | case ActionType.TRACK: |
| | | showOrderTrack(order) |
| | | toTrack(order) |
| | | break |
| | | case ActionType.WAIT_APPROVAL_AUTHORIZE: |
| | | case ActionType.AUTHORIZE: |
| | | toAuthorize(order) |
| | | break |
| | |
| | | |
| | | // 授权:跳转到授权页面 |
| | | const toAuthorize = (row: any) => { |
| | | router.push({ name: 'tradeAuthorization', params: { id: row.id } }) |
| | | router.push({ name: 'tradeAuthorization', params: { id: row.id, taskId: row.taskId } }) |
| | | } |
| | | |
| | | onMounted(handleSearch) |
| | | onMounted(async ()=>{ |
| | | // 获取用户信息 |
| | | if (!userStore.getUserId) { |
| | | try { |
| | | const res: any = await queryUserDetail() |
| | | if (res?.code === 200 && res.data) { |
| | | userStore.updateUserDetail(res.data) |
| | | } else { |
| | | ElMessage.error(res?.msg || '无法获取用户信息,请先登录') |
| | | return |
| | | } |
| | | } catch (e) { |
| | | console.error('获取用户详情失败:', e) |
| | | ElMessage.error('获取用户信息失败,请稍后重试') |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 获取初始选项数据 |
| | | await Promise.all([ |
| | | getIndustryOptions(), |
| | | getProductTypeOptions() |
| | | ]) |
| | | |
| | | // 获取初始统计数据 |
| | | await getOrderCounts() |
| | | |
| | | // 执行搜索 |
| | | handleSearch() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | gap: 20px; |
| | | align-items: center; |
| | | overflow: hidden; |
| | | |
| | | |
| | | .status-item{ |
| | | flex-direction: row-reverse; |
| | | } |
| | | .order-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 8px; |
| | | flex-shrink: 0; |
| | | flex: 1; |
| | | |
| | | .label { |
| | | color: #909399; |
| | |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | |
| | | &.status-item { |
| | | justify-content: flex-start; |
| | | margin-left: 0; |
| | | } |
| | | } |
| | | } |
| | |
| | | .period-info { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | gap: 8px; |
| | | font-size: 12px; |
| | | |
| | |
| | | padding-bottom: 0 !important; |
| | | border-bottom: 2px solid #e4e7ed; // 显示分隔边框线 |
| | | } |
| | | .buttonDiv { |
| | | width: 100%; |
| | | height: 33px; |
| | | } |
| | | .btnBox { |
| | | width: 505px; |
| | | height: 33px; |
| | | //background-color: pink; |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | .btnDivClass { |
| | | background-color: #2f4589 !important; |
| | | color: #fff; |
| | | |
| | | .count-num { |
| | | color: #fff !important; |
| | | } |
| | | } |
| | | |
| | | .btnDiv { |
| | | width: 120px; |
| | | height: 33px; |
| | | border-radius: 5px; |
| | | border: 1px solid #ebeef5; |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 14px; |
| | | //color: #919399; |
| | | cursor: pointer; |
| | | background-color: #FFFFFF; |
| | | |
| | | .numjx { |
| | | padding-right: 5px; |
| | | } |
| | | |
| | | .count-num { |
| | | color: #f04844; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | span :nth-child(2) { |
| | | color: #f04844; |
| | | } |
| | | } |
| | | |
| | | .elFormDiv { |
| | | width: 100%; |
| | | height: 100px; |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | .searchFormDiv { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | } |
| | | |
| | | .searchBtnDiv { |
| | | //width: 20%; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | } |
| | | } |
| | | } |
| | | .numjx { |
| | | padding-right: 5px; |
| | | } |
| | | </style> |
| | | |
| | | |