Files
im-uniapp/pages/workbench/workflow/apply/apply.vue
2025-10-13 17:51:27 +08:00

564 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="app-container">
<!-- 流程列表 -->
<view class="list-container" v-if="ownProcessList.length > 0">
<view
v-for="(item, index) in ownProcessList"
:key="index"
class="list-item"
>
<!-- 1. 基础信息区 -->
<view class="base-info">
<view class="base-info__title">
<text class="label">流程标题</text>
<text class="value">{{ (item.procVars) || '无标题' }}</text>
</view>
<view class="base-info__other">
<view class="other-item">
<text class="label">流程名称</text>
<text class="value">{{ item.procDefName || '未知' }}</text>
</view>
<view class="other-item">
<text class="label">版本</text>
<view class="version-tag">v{{ item.procDefVersion || 1 }}</view>
<text class="sort">{{ item.sort || '' }}</text>
</view>
</view>
</view>
<!-- 2. 状态信息区 -->
<view class="status-info">
<view class="status-item">
<text class="label">当前节点</text>
<text class="value">{{ item.taskName || '无' }}</text>
</view>
<view class="status-item">
<text class="label">提交时间</text>
<text class="value">{{ item.createTime || '未知' }}</text>
</view>
<view class="status-item">
<text class="label">流程状态</text>
<view
class="status-tag"
:class="getStatusTagClass(item.processStatus)"
>
{{ getStatusText(item.processStatus) }}
</view>
</view>
<view class="status-item">
<text class="label">耗时</text>
<text class="value">{{ item.duration || '0' }}</text>
</view>
</view>
<!-- 3. 操作按钮区 -->
<view class="action-buttons">
<button
class="action-btn"
@click="handleFlowRecord(item)"
>
详情
</button>
<button
class="action-btn delete-btn"
@click="handleDelete(item)"
v-if="item.finishTime"
>
删除
</button>
<button
class="action-btn cancel-btn"
@click="handleStop(item)"
v-else
>
取消
</button>
<!-- <button
class="action-btn restart-btn"
@click="handleAgain(item)"
>
重新发起
</button> -->
</view>
</view>
</view>
<!-- 空数据提示 -->
<view class="empty-tip" v-if="!loading && ownProcessList.length === 0">
<view class="empty-icon">
<text class="icon">📦</text>
</view>
<text class="empty-text">暂无流程数据</text>
</view>
<!-- 分页控件原生实现 -->
<view class="pagination" v-if="total > queryParams.pageSize">
<button
class="page-btn"
@click="prevPage"
:disabled="queryParams.pageNum <= 1"
>
上一页
</button>
<view class="page-info">
{{ queryParams.pageNum }} / {{ totalPages }}
</view>
<button
class="page-btn"
@click="nextPage"
:disabled="queryParams.pageNum >= totalPages"
>
下一页
</button>
</view>
<uni-fab ref="fab" horizontal="right" vertical="bottom"
direction="horizontal" @fabClick="fabClick" />
<uni-popup ref="startpopup">
<view class="" style="background-color: white; display: flex; flex-wrap: wrap; gap: 3px; justify-content: space-evenly; padding: 20rpx;">
<view v-for="item in applyCategory" @click="jumpStart(item)" style="background-color: gainsboro; padding: 20rpx;">
{{ item.label }}
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { delProcess, listOwnProcess, stopProcess } from '@/api/oa/workflow/process';
const applyCategory = [
{
label: '用印申请',
name: 'seal',
path: '/workflow/process/start',
params: {
deploymentId: '743bf626-355e-11f0-b7d7-fa163e1573b1'
},
query: {
definitionId: 'Process_1741171051790%3A2%3A74715e09-355e-11f0-b7d7-fa163e1573b1'
}
},
// {
// label: '拨款申请',
// name: 'money',
// path: '/money/addMoney'
// },
// {
// label: '报销申请',
// name: 'claim',
// path: '/claim/addTripClaim'
// },
{
label: '请假申请',
name: 'absence',
path: '/workflow/process/start',
params: {
deploymentId: 'f16f31cf-9215-11f0-9545-d8f3bc6f4151'
},
query: {
definitionId: 'Process_1741158926906%3A10%3Af1d17612-9215-11f0-9545-d8f3bc6f4151'
}
},
{
label: '差旅申请',
name: 'trip',
path: '/workflow/process/start',
params: {
deploymentId: 'd7b3b7c2-355f-11f0-b7d7-fa163e1573b1'
},
query: {
definitionId: 'Process_1741509148283%3A2%3Ad7ba4775-355f-11f0-b7d7-fa163e1573b1'
}
},
{
label: '招待申请',
name: 'entertain',
path: '/workflow/process/start',
params: {
deploymentId: '81c87a72-355f-11f0-b7d7-fa163e1573b1'
},
query: {
definitionId: 'Process_1741172554061%3A3%3A81d60f05-355f-11f0-b7d7-fa163e1573b1'
}
},
{
label: '其他申请',
name: 'other',
path: '/workflow/process/start',
params: {
deploymentId: '003a0422-3560-11f0-b7d7-fa163e1573b1'
},
query: {
definitionId: 'Process_1741172337682%3A4%3A00454ec5-3560-11f0-b7d7-fa163e1573b1'
}
}
]
export default {
name: "OwnProcessList",
data() {
return {
loading: false, // 加载状态使用API控制不依赖组件
ownProcessList: [],
total: 0,
queryParams: {
pageNum: 1,
pageSize: 10,
processKey: undefined,
processName: undefined,
category: undefined,
description: undefined
},
dateRange: [],
applyCategory
};
},
computed: {
// 计算总页数
totalPages() {
return Math.ceil(this.total / this.queryParams.pageSize) || 1;
}
},
onLoad() {
this.getList();
},
methods: {
/** 获取列表数据(使用原生加载提示) */
getList() {
this.loading = true;
// 显示原生加载提示
uni.showLoading({
title: '加载中...',
mask: true
});
const params = this.addDateRange({ ...this.queryParams }, this.dateRange);
listOwnProcess(params)
.then(response => {
this.ownProcessList = response.rows || [];
this.total = response.total || 0;
})
.catch(err => {
console.error('获取流程列表失败:', err);
uni.showToast({ title: '加载失败', icon: 'none', duration: 2000 });
})
.finally(() => {
this.loading = false;
// 关闭原生加载提示
uni.hideLoading();
});
},
fabClick() {
this.$refs.startpopup.open('bottom')
},
/** 日期范围处理 */
addDateRange(params, dateRange) {
const result = { ...params };
if (Array.isArray(dateRange) && dateRange.length === 2) {
result.beginTime = dateRange[0];
result.endTime = dateRange[1];
}
return result;
},
/** 上一页 */
prevPage() {
if (this.queryParams.pageNum > 1) {
this.queryParams.pageNum--;
this.getList();
}
},
/** 下一页 */
nextPage() {
if (this.queryParams.pageNum < this.totalPages) {
this.queryParams.pageNum++;
this.getList();
}
},
/** 详情跳转 */
handleFlowRecord(row) {
console.log(row);
const definitionId = row.procDefId;
const deploymentId = row.deployId;
uni.navigateTo({
url: `/pages/workbench/workflow/detail/detail?definitionId=${definitionId}&deployId=${deploymentId}&processed=false`
});
},
/** 删除流程 */
handleDelete(row) {
const procInsId = row.procInsId;
uni.showModal({
title: '警告',
content: `是否确认删除流程编号为"${procInsId}"的数据?`,
confirmText: '确定',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
delProcess(procInsId)
.then(() => {
uni.showToast({ title: '删除成功', duration: 1500 });
this.getList();
})
.catch(err => {
console.error('删除失败:', err);
uni.showToast({ title: '删除失败', icon: 'none' });
});
}
}
});
},
/** 取消流程 */
handleStop(row) {
const params = { procInsId: row.procInsId };
stopProcess(params)
.then(response => {
uni.showToast({ title: response.msg || '取消成功', duration: 1500 });
this.getList();
})
.catch(err => {
console.error('取消失败:', err);
uni.showToast({ title: '取消失败', icon: 'none' });
});
},
/** 重新发起 */
handleAgain(row) {
uni.navigateTo({
url: `/pages/workflow/process/start/${row.deployId}?definitionId=${row.procDefId}&procInsId=${row.procInsId}`
});
},
jumpStart(row) {
const definitionId = row.query.definitionId;
const deploymentId = row.params.deploymentId;
uni.navigateTo({
url: `/pages/workbench/workflow/start/start?definitionId=${definitionId}&deployId=${deploymentId}&processed=false`
});
},
/** 状态标签样式原生实现替代uni-tag */
getStatusTagClass(status) {
switch (status) {
case 1: return 'status-tag--primary'; // 运行中
case 2: return 'status-tag--success'; // 已完成
case 3: return 'status-tag--danger'; // 已取消
default: return 'status-tag--info'; // 未知
}
},
/** 状态文本 */
getStatusText(status) {
switch (status) {
case 1: return '运行中';
case 2: return '已完成';
case 3: return '已取消';
default: return '未知状态';
}
}
}
};
</script>
<style scoped>
.app-container {
padding: 16rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
/* 列表容器 */
.list-container {
background-color: #fff;
border-radius: 16rpx;
overflow: hidden;
margin-bottom: 16rpx;
}
/* 列表项 */
.list-item {
padding: 20rpx;
border-bottom: 1rpx solid #eee;
}
.list-item:last-child {
border-bottom: none;
}
/* 基础信息区 */
.base-info {
margin-bottom: 20rpx;
}
.base-info__title {
font-size: 32rpx;
font-weight: 500;
margin-bottom: 10rpx;
line-height: 1.5;
}
.base-info__other {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
font-size: 28rpx;
color: #666;
}
.other-item {
display: flex;
align-items: center;
gap: 8rpx;
}
/* 版本标签(原生实现) */
.version-tag {
background-color: #e8f3ff;
color: #1677ff;
padding: 2rpx 10rpx;
border-radius: 4rpx;
font-size: 24rpx;
}
.sort {
margin-left: 8rpx;
color: #999;
}
/* 状态信息区 */
.status-info {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
font-size: 28rpx;
color: #666;
margin-bottom: 20rpx;
}
.status-item {
display: flex;
align-items: center;
gap: 8rpx;
}
/* 状态标签(原生实现) */
.status-tag {
padding: 2rpx 10rpx;
border-radius: 4rpx;
font-size: 24rpx;
}
.status-tag--primary {
background-color: #e8f3ff;
color: #1677ff;
}
.status-tag--success {
background-color: #f0fff4;
color: #00b42a;
}
.status-tag--danger {
background-color: #fff1f0;
color: #f53f3f;
}
.status-tag--info {
background-color: #f2f3f5;
color: #86909c;
}
/* 操作按钮区 */
.action-buttons {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
justify-content: flex-end;
}
.action-btn {
padding: 8rpx 20rpx;
font-size: 26rpx;
border: none;
background: transparent;
line-height: 1;
}
.delete-btn {
color: #f53f3f;
}
.cancel-btn {
color: #faad14;
}
.restart-btn {
color: #1677ff;
}
/* 空数据提示 */
.empty-tip {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 400rpx;
color: #999;
}
.empty-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
}
.empty-text {
font-size: 28rpx;
}
/* 分页控件 */
.pagination {
display: flex;
align-items: center;
justify-content: center;
gap: 30rpx;
padding: 30rpx 0;
}
.page-btn {
padding: 12rpx 30rpx;
background-color: #fff;
border: 1rpx solid #eee;
border-radius: 6rpx;
font-size: 28rpx;
color: #333;
}
.page-btn:disabled {
color: #ccc;
background-color: #f5f5f5;
}
.page-info {
font-size: 28rpx;
color: #666;
}
/* 通用样式 */
.label {
color: #999;
}
.value {
color: #333;
}
</style>