feat(approval): 添加已审批列表功能
- 新增已审批列表接口类型定义 CompletedApprovalItem 和 CompletedListParams - 实现已审批列表 Tab 页面,支持待审批和已审批切换- 添加已审批列表数据加载和分页逻辑 - 实现已审批详情页只读模式展示- 更新税率输入框禁用逻辑,支持只读模式- 优化审批按钮显示控制,只读模式下隐藏审批按钮 - 调整搜索功能,支持待审批和已审批分别搜索- 更新状态标签样式,区分待审批、已审批状态显示 - 添加已审批列表空状态提示和刷新功能master
parent
3f221a1216
commit
3271644a01
|
|
@ -1,5 +1,5 @@
|
||||||
import http from '@/utils/http'
|
import http from '@/utils/http'
|
||||||
import type { ApiResponse, Order, OrderDetailResponse, ListParams, ApprovalParams } from '@/types'
|
import type { ApiResponse, Order, OrderDetailResponse, ListParams, ApprovalParams, CompletedApprovalItem, CompletedListParams } from '@/types'
|
||||||
import type { AxiosResponse } from 'axios'
|
import type { AxiosResponse } from 'axios'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -63,3 +63,21 @@ export const submitApproval = (params: any): Promise<AxiosResponse<ApiResponse<a
|
||||||
|
|
||||||
return http.post('/project/order/order/approve', formData)
|
return http.post('/project/order/order/approve', formData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已审批列表
|
||||||
|
*/
|
||||||
|
export const getCompletedOrderList = (params: CompletedListParams): Promise<AxiosResponse<ApiResponse<{
|
||||||
|
total: number
|
||||||
|
rows: CompletedApprovalItem[]
|
||||||
|
}>>> => {
|
||||||
|
// 创建FormData对象
|
||||||
|
const formData = new FormData()
|
||||||
|
|
||||||
|
// 添加参数到FormData
|
||||||
|
formData.append('page', params.page.toString())
|
||||||
|
formData.append('pageSize', params.pageSize.toString())
|
||||||
|
if (params.businessName) formData.append('businessName', params.businessName)
|
||||||
|
|
||||||
|
return http.post('/flow/completed/list', formData)
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import type { Order, OrderDetailResponse, ListParams } from '@/types'
|
import type { Order, OrderDetailResponse, ListParams, CompletedApprovalItem, CompletedListParams } from '@/types'
|
||||||
import { getOrderList, getOrderDetail } from '@/api/order'
|
import { getOrderList, getOrderDetail, getCompletedOrderList } from '@/api/order'
|
||||||
|
|
||||||
interface OrderState {
|
interface OrderState {
|
||||||
// 列表相关
|
// 待审批列表相关
|
||||||
orderList: Order[]
|
orderList: Order[]
|
||||||
loading: boolean
|
loading: boolean
|
||||||
finished: boolean
|
finished: boolean
|
||||||
|
|
@ -12,6 +12,15 @@ interface OrderState {
|
||||||
total: number
|
total: number
|
||||||
keyword: string
|
keyword: string
|
||||||
|
|
||||||
|
// 已审批列表相关
|
||||||
|
completedList: CompletedApprovalItem[]
|
||||||
|
completedLoading: boolean
|
||||||
|
completedFinished: boolean
|
||||||
|
completedCurrentPage: number
|
||||||
|
completedPageSize: number
|
||||||
|
completedTotal: number
|
||||||
|
completedKeyword: string
|
||||||
|
|
||||||
// 详情相关
|
// 详情相关
|
||||||
currentOrder: any | null // 临时改为any来避免类型问题
|
currentOrder: any | null // 临时改为any来避免类型问题
|
||||||
detailLoading: boolean
|
detailLoading: boolean
|
||||||
|
|
@ -19,6 +28,7 @@ interface OrderState {
|
||||||
|
|
||||||
export const useOrderStore = defineStore('order', {
|
export const useOrderStore = defineStore('order', {
|
||||||
state: (): OrderState => ({
|
state: (): OrderState => ({
|
||||||
|
// 待审批列表状态
|
||||||
orderList: [],
|
orderList: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
finished: false,
|
finished: false,
|
||||||
|
|
@ -27,6 +37,15 @@ export const useOrderStore = defineStore('order', {
|
||||||
total: 0,
|
total: 0,
|
||||||
keyword: '',
|
keyword: '',
|
||||||
|
|
||||||
|
// 已审批列表状态
|
||||||
|
completedList: [],
|
||||||
|
completedLoading: false,
|
||||||
|
completedFinished: false,
|
||||||
|
completedCurrentPage: 1,
|
||||||
|
completedPageSize: 20,
|
||||||
|
completedTotal: 0,
|
||||||
|
completedKeyword: '',
|
||||||
|
|
||||||
currentOrder: null,
|
currentOrder: null,
|
||||||
detailLoading: false
|
detailLoading: false
|
||||||
}),
|
}),
|
||||||
|
|
@ -41,8 +60,11 @@ export const useOrderStore = defineStore('order', {
|
||||||
// 获取当前用户信息
|
// 获取当前用户信息
|
||||||
currentUser: (state) => state.currentOrder?.user,
|
currentUser: (state) => state.currentOrder?.user,
|
||||||
|
|
||||||
// 检查是否还有更多数据
|
// 检查待审批是否还有更多数据
|
||||||
hasMore: (state) => state.orderList.length < state.total
|
hasMore: (state) => state.orderList.length < state.total,
|
||||||
|
|
||||||
|
// 检查已审批是否还有更多数据
|
||||||
|
completedHasMore: (state) => state.completedList.length < state.completedTotal
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
@ -78,16 +100,17 @@ export const useOrderStore = defineStore('order', {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.total = total
|
this.total = total
|
||||||
this.currentPage++
|
|
||||||
|
|
||||||
// 判断是否已加载完所有数据
|
// 判断是否已加载完所有数据
|
||||||
if (this.orderList.length >= total) {
|
if (this.orderList.length >= total || rows.length === 0) {
|
||||||
this.finished = true
|
this.finished = true
|
||||||
|
} else {
|
||||||
|
// 只有当还有更多数据时才递增页码
|
||||||
|
this.currentPage++
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载订单列表失败:', error)
|
|
||||||
throw error
|
throw error
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
@ -107,30 +130,24 @@ export const useOrderStore = defineStore('order', {
|
||||||
*/
|
*/
|
||||||
async fetchOrderDetail(id: string | number) {
|
async fetchOrderDetail(id: string | number) {
|
||||||
this.detailLoading = true
|
this.detailLoading = true
|
||||||
console.log('开始获取订单详情,ID:', id)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await getOrderDetail(id)
|
const response = await getOrderDetail(id)
|
||||||
console.log('API响应:', response)
|
|
||||||
console.log('响应数据:', response.data)
|
|
||||||
console.log('实际数据:', response.data.data)
|
|
||||||
|
|
||||||
// 直接获取数据对象
|
// 直接获取数据对象
|
||||||
const orderData = response.data.data
|
const orderData = response.data.data
|
||||||
console.log('订单数据对象:', orderData)
|
|
||||||
|
|
||||||
// 确保数据存在再赋值
|
// 确保数据存在再赋值
|
||||||
if (orderData) {
|
if (orderData) {
|
||||||
this.currentOrder = orderData
|
this.currentOrder = orderData
|
||||||
console.log('赋值后的存储数据:', this.currentOrder)
|
|
||||||
console.log('项目订单信息:', this.currentOrder.projectOrderInfo)
|
|
||||||
} else {
|
|
||||||
console.error('订单数据为空')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取订单详情失败:', error)
|
|
||||||
throw error
|
throw error
|
||||||
} finally {
|
} finally {
|
||||||
this.detailLoading = false
|
this.detailLoading = false
|
||||||
|
|
@ -144,16 +161,95 @@ export const useOrderStore = defineStore('order', {
|
||||||
this.currentOrder = null
|
this.currentOrder = null
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载已审批列表
|
||||||
|
*/
|
||||||
|
async loadCompletedOrderList(refresh = false) {
|
||||||
|
|
||||||
|
// 如果已经加载完所有数据且不是刷新操作,直接返回
|
||||||
|
if (this.completedFinished && !refresh) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refresh) {
|
||||||
|
this.completedCurrentPage = 1
|
||||||
|
this.completedFinished = false
|
||||||
|
this.completedList = []
|
||||||
|
}
|
||||||
|
|
||||||
|
this.completedLoading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const params: CompletedListParams = {
|
||||||
|
page: this.completedCurrentPage,
|
||||||
|
pageSize: this.completedPageSize,
|
||||||
|
businessName: this.completedKeyword || undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const response = await getCompletedOrderList(params)
|
||||||
|
|
||||||
|
const { total, rows } = response.data
|
||||||
|
|
||||||
|
|
||||||
|
if (refresh) {
|
||||||
|
this.completedList = rows
|
||||||
|
} else {
|
||||||
|
this.completedList.push(...rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.completedTotal = total
|
||||||
|
|
||||||
|
// 判断是否已加载完所有数据
|
||||||
|
if (this.completedList.length >= total || rows.length === 0) {
|
||||||
|
this.completedFinished = true
|
||||||
|
console.log('已审批列表加载完成')
|
||||||
|
} else {
|
||||||
|
// 只有当还有更多数据时才递增页码
|
||||||
|
this.completedCurrentPage++
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载已审批列表失败:', error)
|
||||||
|
// 发生错误时重置加载状态,但不标记为完成
|
||||||
|
this.completedLoading = false
|
||||||
|
throw error
|
||||||
|
} finally {
|
||||||
|
this.completedLoading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索已审批订单
|
||||||
|
*/
|
||||||
|
async searchCompletedOrders(keyword: string) {
|
||||||
|
this.completedKeyword = keyword
|
||||||
|
await this.loadCompletedOrderList(true)
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置列表状态
|
* 重置列表状态
|
||||||
*/
|
*/
|
||||||
resetListState() {
|
resetListState() {
|
||||||
|
// 重置待审批列表状态
|
||||||
this.orderList = []
|
this.orderList = []
|
||||||
this.currentPage = 1
|
this.currentPage = 1
|
||||||
this.finished = false
|
this.finished = false
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.keyword = ''
|
this.keyword = ''
|
||||||
this.total = 0
|
this.total = 0
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置已审批列表状态
|
||||||
|
*/
|
||||||
|
resetCompletedListState() {
|
||||||
|
this.completedList = []
|
||||||
|
this.completedCurrentPage = 1
|
||||||
|
this.completedFinished = false
|
||||||
|
this.completedLoading = false
|
||||||
|
this.completedKeyword = ''
|
||||||
|
this.completedTotal = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -197,3 +197,45 @@ export interface ApprovalParams {
|
||||||
updateTime?: string
|
updateTime?: string
|
||||||
[property: string]: any
|
[property: string]: any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 已审批列表项类型
|
||||||
|
export interface CompletedApprovalItem {
|
||||||
|
allApproveUserName: string
|
||||||
|
applyTime: string
|
||||||
|
applyUserName: string
|
||||||
|
approveOpinion: string
|
||||||
|
approveStatus: ApprovalStatus
|
||||||
|
approveTime: string
|
||||||
|
approveUser: string
|
||||||
|
approveUserName: string
|
||||||
|
businessId: number
|
||||||
|
businessKey: string
|
||||||
|
businessName: string
|
||||||
|
createBy?: string
|
||||||
|
createTime?: string
|
||||||
|
extendField1?: string
|
||||||
|
extendField2?: string
|
||||||
|
formKey?: string
|
||||||
|
id?: number
|
||||||
|
nextAllApproveUserName: string
|
||||||
|
processInstanceId: string
|
||||||
|
processKey: string
|
||||||
|
processName: string
|
||||||
|
recoveryType?: number
|
||||||
|
remark?: string
|
||||||
|
roleName: string
|
||||||
|
taskId: string
|
||||||
|
taskName: string
|
||||||
|
taxRateData?: any
|
||||||
|
todoId: string
|
||||||
|
updateBy?: string
|
||||||
|
updateTime?: string
|
||||||
|
variables?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已审批列表查询参数
|
||||||
|
export interface CompletedListParams {
|
||||||
|
businessName?: string
|
||||||
|
page: number
|
||||||
|
pageSize: number
|
||||||
|
}
|
||||||
|
|
@ -17,9 +17,12 @@
|
||||||
<div class="project-title">
|
<div class="project-title">
|
||||||
{{ currentOrderInfo.projectName }}REV.{{ currentOrderInfo.versionCode }}
|
{{ currentOrderInfo.projectName }}REV.{{ currentOrderInfo.versionCode }}
|
||||||
</div>
|
</div>
|
||||||
<div class="project-status">
|
<div class="project-status" v-if="route.query.readonly !== 'true'">
|
||||||
待审批
|
待审批
|
||||||
</div>
|
</div>
|
||||||
|
<div class="project-status completed" v-else>
|
||||||
|
已审批
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab标签页 -->
|
<!-- Tab标签页 -->
|
||||||
|
|
@ -191,7 +194,7 @@
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
v-model="product.taxRate"
|
v-model="product.taxRate"
|
||||||
:disabled="!isBusinessApproval"
|
:disabled="isTaxRateDisabled"
|
||||||
@change="updateTaxRate(product)"
|
@change="updateTaxRate(product)"
|
||||||
class="tax-rate-input"
|
class="tax-rate-input"
|
||||||
/>
|
/>
|
||||||
|
|
@ -236,7 +239,7 @@
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
v-model="product.taxRate"
|
v-model="product.taxRate"
|
||||||
:disabled="!isBusinessApproval"
|
:disabled="isTaxRateDisabled"
|
||||||
@change="updateTaxRate(product)"
|
@change="updateTaxRate(product)"
|
||||||
class="tax-rate-input"
|
class="tax-rate-input"
|
||||||
/>
|
/>
|
||||||
|
|
@ -281,7 +284,7 @@
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
v-model="product.taxRate"
|
v-model="product.taxRate"
|
||||||
:disabled="!isBusinessApproval"
|
:disabled="isTaxRateDisabled"
|
||||||
@change="updateTaxRate(product)"
|
@change="updateTaxRate(product)"
|
||||||
class="tax-rate-input"
|
class="tax-rate-input"
|
||||||
/>
|
/>
|
||||||
|
|
@ -514,6 +517,11 @@ const isBusinessApproval = computed(() => {
|
||||||
return currentOrder.value?.todo?.taskName?.startsWith('商务')
|
return currentOrder.value?.todo?.taskName?.startsWith('商务')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 是否禁用税率输入框
|
||||||
|
const isTaxRateDisabled = computed(() => {
|
||||||
|
return !isBusinessApproval.value || route.query.readonly === 'true'
|
||||||
|
})
|
||||||
|
|
||||||
// Tab页签
|
// Tab页签
|
||||||
const activeTab = ref('order')
|
const activeTab = ref('order')
|
||||||
|
|
||||||
|
|
@ -528,7 +536,11 @@ const hasProductInfo = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const showApprovalButtons = computed(() => {
|
const showApprovalButtons = computed(() => {
|
||||||
// 直接展示审批按钮,无需条件控制
|
// 如果是只读模式(来自已审批列表),则不显示审批按钮
|
||||||
|
if (route.query.readonly === 'true') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 其他情况显示审批按钮
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -867,6 +879,12 @@ onMounted(async () => {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
border: 1px solid #FFD591;
|
border: 1px solid #FFD591;
|
||||||
|
|
||||||
|
&.completed {
|
||||||
|
background: #F6FFED;
|
||||||
|
color: #52C41A;
|
||||||
|
border: 1px solid #B7EB8F;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<van-search
|
<van-search
|
||||||
v-model="searchKeyword"
|
v-model="searchKeyword"
|
||||||
placeholder="搜索订单编号、客户名称"
|
:placeholder="currentTab === 'pending' ? '搜索订单编号、客户名称' : '搜索合同名称'"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@clear="handleClear"
|
@clear="handleClear"
|
||||||
class="custom-search"
|
class="custom-search"
|
||||||
|
|
@ -18,67 +18,129 @@
|
||||||
</van-search>
|
</van-search>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 下拉刷新 -->
|
<!-- Tab切换 -->
|
||||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
<van-tabs v-model:active="currentTab" @change="onTabChange" class="approval-tabs">
|
||||||
<!-- 订单列表 -->
|
<!-- 待审批Tab -->
|
||||||
<van-list
|
<van-tab name="pending" title="待审批">
|
||||||
v-model:loading="loading"
|
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||||
:finished="finished"
|
<van-list
|
||||||
finished-text="没有更多了"
|
v-model:loading="loading"
|
||||||
@load="onLoad"
|
:finished="finished"
|
||||||
>
|
finished-text="没有更多了"
|
||||||
<div v-for="order in orderList" :key="order.id" class="order-item" @click="goToDetail(order.id)">
|
@load="onLoad"
|
||||||
<div class="order-header">
|
>
|
||||||
<div class="order-code">{{ order.orderCode }}</div>
|
<div v-for="order in orderList" :key="order.id" class="order-item" @click="goToDetail(order.id)">
|
||||||
<div class="status-tag pending">
|
<div class="order-header">
|
||||||
待审批
|
<div class="order-code">{{ order.orderCode }}</div>
|
||||||
</div>
|
<div class="status-tag pending">
|
||||||
</div>
|
待审批
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="order-info">
|
<div class="order-info">
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<span class="label">项目名称:</span>
|
<span class="label">项目名称:</span>
|
||||||
<span class="value">{{ order.projectName }}</span>
|
<span class="value">{{ order.projectName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">客户名称:</span>
|
||||||
|
<span class="value">{{ order.customerName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">订单金额:</span>
|
||||||
|
<span class="value amount">{{ formatAmount(order.shipmentAmount) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">创建时间:</span>
|
||||||
|
<span class="value">{{ formatDate(order.createTime, 'YYYY-MM-DD HH:mm') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">客户名称:</span>
|
|
||||||
<span class="value">{{ order.customerName }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">订单金额:</span>
|
|
||||||
<span class="value amount">{{ formatAmount(order.shipmentAmount) }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">创建时间:</span>
|
|
||||||
<span class="value">{{ formatDate(order.createTime, 'YYYY-MM-DD HH:mm') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
<div v-if="!loading && orderList.length === 0" class="empty-state">
|
<div v-if="!loading && orderList.length === 0" class="empty-state">
|
||||||
<van-empty description="暂无订单数据" />
|
<van-empty description="暂无待审批数据" />
|
||||||
</div>
|
</div>
|
||||||
</van-list>
|
</van-list>
|
||||||
</van-pull-refresh>
|
</van-pull-refresh>
|
||||||
|
</van-tab>
|
||||||
|
|
||||||
|
<!-- 已审批Tab -->
|
||||||
|
<van-tab name="completed" title="已审批">
|
||||||
|
<van-pull-refresh v-model="completedRefreshing" @refresh="onCompletedRefresh">
|
||||||
|
<van-list
|
||||||
|
v-model:loading="completedLoading"
|
||||||
|
:finished="completedFinished"
|
||||||
|
finished-text="没有更多了"
|
||||||
|
@load="onCompletedLoad"
|
||||||
|
>
|
||||||
|
<div v-for="item in completedList" :key="item.todoId" class="order-item" @click="goToCompletedDetail(item.businessId)">
|
||||||
|
<div class="order-header">
|
||||||
|
<div class="order-code">{{ item.businessKey }}</div>
|
||||||
|
<div class="status-tag" :class="getCompletedStatusClass(item.approveStatus)">
|
||||||
|
{{ getCompletedStatusText(item.approveStatus) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="order-info">
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">合同名称:</span>
|
||||||
|
<span class="value">{{ item.businessName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">流程名称:</span>
|
||||||
|
<span class="value">{{ item.processName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">发起人:</span>
|
||||||
|
<span class="value">{{ item.applyUserName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">审批时间:</span>
|
||||||
|
<span class="value">{{ item.approveTime }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="item.approveOpinion" class="info-row">
|
||||||
|
<span class="label">审批意见:</span>
|
||||||
|
<span class="value">{{ item.approveOpinion }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<div v-if="!completedLoading && completedList.length === 0" class="empty-state">
|
||||||
|
<van-empty description="暂无已审批数据" />
|
||||||
|
</div>
|
||||||
|
</van-list>
|
||||||
|
</van-pull-refresh>
|
||||||
|
</van-tab>
|
||||||
|
</van-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, watch } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useOrderStore } from '@/store/order'
|
import { useOrderStore } from '@/store/order'
|
||||||
import { formatOrderStatus, formatAmount, formatDate } from '@/utils'
|
import { formatOrderStatus, formatAmount, formatDate } from '@/utils'
|
||||||
import type { OrderStatus } from '@/types'
|
import type { OrderStatus, ApprovalStatus } from '@/types'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const orderStore = useOrderStore()
|
const orderStore = useOrderStore()
|
||||||
|
|
||||||
|
// 待审批列表相关状态
|
||||||
const { orderList, loading, finished } = storeToRefs(orderStore)
|
const { orderList, loading, finished } = storeToRefs(orderStore)
|
||||||
|
|
||||||
|
// 已审批列表相关状态
|
||||||
|
const { completedList, completedLoading, completedFinished } = storeToRefs(orderStore)
|
||||||
|
|
||||||
|
// Tab相关
|
||||||
|
const currentTab = ref('pending')
|
||||||
|
|
||||||
// 搜索相关
|
// 搜索相关
|
||||||
const searchKeyword = ref('')
|
const searchKeyword = ref('')
|
||||||
const refreshing = ref(false)
|
const refreshing = ref(false)
|
||||||
|
const completedRefreshing = ref(false)
|
||||||
|
|
||||||
// 获取状态样式类
|
// 获取状态样式类
|
||||||
const getStatusClass = (status: OrderStatus) => {
|
const getStatusClass = (status: OrderStatus) => {
|
||||||
|
|
@ -110,10 +172,57 @@ const onRefresh = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tab切换处理
|
||||||
|
const onTabChange = (name: string) => {
|
||||||
|
currentTab.value = name
|
||||||
|
searchKeyword.value = ''
|
||||||
|
|
||||||
|
if (name === 'completed' && completedList.value.length === 0) {
|
||||||
|
// 首次加载已审批列表
|
||||||
|
onCompletedLoad()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已审批列表加载
|
||||||
|
const onCompletedLoad = async () => {
|
||||||
|
console.log('=== van-list 触发 onCompletedLoad ===')
|
||||||
|
console.log('当前状态:', {
|
||||||
|
loading: completedLoading.value,
|
||||||
|
finished: completedFinished.value,
|
||||||
|
listLength: completedList.value.length,
|
||||||
|
currentPage: orderStore.completedCurrentPage
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
await orderStore.loadCompletedOrderList()
|
||||||
|
console.log('onCompletedLoad 执行完成')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载已审批列表失败:', error)
|
||||||
|
// 确保在出错时也能重置loading状态
|
||||||
|
orderStore.completedLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已审批列表刷新
|
||||||
|
const onCompletedRefresh = async () => {
|
||||||
|
try {
|
||||||
|
await orderStore.loadCompletedOrderList(true)
|
||||||
|
completedRefreshing.value = false
|
||||||
|
} catch (error) {
|
||||||
|
completedRefreshing.value = false
|
||||||
|
console.error('刷新已审批列表失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 搜索处理
|
// 搜索处理
|
||||||
const handleSearch = async () => {
|
const handleSearch = async () => {
|
||||||
try {
|
try {
|
||||||
await orderStore.searchOrders(searchKeyword.value.trim())
|
const keyword = searchKeyword.value.trim()
|
||||||
|
if (currentTab.value === 'pending') {
|
||||||
|
await orderStore.searchOrders(keyword)
|
||||||
|
} else {
|
||||||
|
await orderStore.searchCompletedOrders(keyword)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('搜索失败:', error)
|
console.error('搜索失败:', error)
|
||||||
}
|
}
|
||||||
|
|
@ -123,20 +232,53 @@ const handleSearch = async () => {
|
||||||
const handleClear = async () => {
|
const handleClear = async () => {
|
||||||
searchKeyword.value = ''
|
searchKeyword.value = ''
|
||||||
try {
|
try {
|
||||||
await orderStore.searchOrders('')
|
if (currentTab.value === 'pending') {
|
||||||
|
await orderStore.searchOrders('')
|
||||||
|
} else {
|
||||||
|
await orderStore.searchCompletedOrders('')
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('清空搜索失败:', error)
|
console.error('清空搜索失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 已审批状态文本转换
|
||||||
|
const getCompletedStatusText = (status: ApprovalStatus) => {
|
||||||
|
const statusMap = {
|
||||||
|
2: '驳回',
|
||||||
|
3: '通过'
|
||||||
|
}
|
||||||
|
return statusMap[status] || '提交'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已审批状态样式类
|
||||||
|
const getCompletedStatusClass = (status: ApprovalStatus) => {
|
||||||
|
const classMap = {
|
||||||
|
2: 'rejected',
|
||||||
|
3: 'approved'
|
||||||
|
}
|
||||||
|
return classMap[status] || 'pending'
|
||||||
|
}
|
||||||
|
|
||||||
// 跳转到详情页
|
// 跳转到详情页
|
||||||
const goToDetail = (id: number) => {
|
const goToDetail = (id: number) => {
|
||||||
router.push(`/detail/${id}`)
|
router.push(`/detail/${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 跳转到已审批详情页(只读模式)
|
||||||
|
const goToCompletedDetail = (businessId: number) => {
|
||||||
|
router.push({
|
||||||
|
path: `/detail/${businessId}`,
|
||||||
|
query: { readonly: 'true' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 重置状态并加载数据
|
// 重置状态并加载数据
|
||||||
orderStore.resetListState()
|
orderStore.resetListState()
|
||||||
|
orderStore.resetCompletedListState()
|
||||||
onLoad()
|
onLoad()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -144,10 +286,33 @@ onMounted(() => {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.order-list-page {
|
.order-list-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: #ffffff;
|
background-color: var(--van-background-color);
|
||||||
padding: 16px;
|
}
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
// Tab相关样式
|
||||||
|
.approval-tabs {
|
||||||
|
:deep(.van-tabs__wrap) {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-tabs__content) {
|
||||||
|
padding: 16px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
min-height: calc(100vh - 120px);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-tab) {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-tab--active) {
|
||||||
|
color: var(--van-primary-color);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-item {
|
.order-item {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue