564 lines
13 KiB
Vue
564 lines
13 KiB
Vue
|
|
<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>
|