调整结构&待办任务页面
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<basic-container>
|
||||
<!-- 页面标题和已办计数 -->
|
||||
<div class="workflow-header">
|
||||
<h3 class="workflow-title">我的已办</h3>
|
||||
<el-tag type="success" size="large">已处理 {{ doneCount }} 项</el-tag>
|
||||
</div>
|
||||
|
||||
<avue-crud
|
||||
:option="option"
|
||||
:table-loading="loading"
|
||||
:data="data"
|
||||
:page="page"
|
||||
ref="crud"
|
||||
v-model="form"
|
||||
@search-change="searchChange"
|
||||
@search-reset="searchReset"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@refresh-change="refreshChange"
|
||||
@on-load="onLoad"
|
||||
>
|
||||
<!-- 处理结果列自定义(已办接口暂不提供,预留) -->
|
||||
<template #handleResult="{ row }">
|
||||
<el-tag :type="row.handleResult === '已同意' ? 'success' : 'danger'">
|
||||
{{ row.handleResult || '-' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<!-- 自定义操作列 -->
|
||||
<template #menu="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleView(scope.row)"
|
||||
>查看</el-button>
|
||||
<el-button
|
||||
type="info"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleTransfer(scope.row)"
|
||||
>流转</el-button>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<!-- 流转时间线弹窗 -->
|
||||
<el-dialog
|
||||
title="流程流转详情"
|
||||
v-model="transferDialogVisible"
|
||||
width="700px"
|
||||
append-to-body
|
||||
>
|
||||
<div class="transfer-process-name">{{ currentProcessName }}</div>
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(step, index) in currentTrackSteps"
|
||||
:key="index"
|
||||
:type="step.type || 'primary'"
|
||||
:timestamp="step.time"
|
||||
placement="top"
|
||||
>
|
||||
<el-card :body-style="{ padding: '12px 16px' }">
|
||||
<div class="step-header">
|
||||
<span class="step-name">{{ step.stepName }}</span>
|
||||
<el-tag
|
||||
:type="step.resultType || 'primary'"
|
||||
size="small"
|
||||
effect="dark"
|
||||
class="step-result"
|
||||
>
|
||||
{{ step.result }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="step-info">
|
||||
<span class="step-handler">
|
||||
<el-icon><User /></el-icon>
|
||||
{{ step.handler }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="step.remark" class="step-remark">
|
||||
<el-icon><ChatDotSquare /></el-icon>
|
||||
{{ step.remark }}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-dialog>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getDoneList, getDetail } from '@/api/workflow';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
loading: true,
|
||||
doneCount: 0,
|
||||
page: {
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0,
|
||||
},
|
||||
query: {},
|
||||
data: [],
|
||||
// 流转弹窗
|
||||
transferDialogVisible: false,
|
||||
currentProcessName: '',
|
||||
currentTrackSteps: [],
|
||||
// Avue 表格配置
|
||||
option: {
|
||||
height: 'auto',
|
||||
calcHeight: 32,
|
||||
tip: false,
|
||||
searchShow: true,
|
||||
searchMenuSpan: 6,
|
||||
border: true,
|
||||
index: true,
|
||||
selection: false,
|
||||
editBtn: false,
|
||||
addBtn: false,
|
||||
viewBtn: false,
|
||||
delBtn: false,
|
||||
menuWidth: 150,
|
||||
dialogClickModal: false,
|
||||
column: [
|
||||
{
|
||||
label: '流程名称',
|
||||
prop: 'processName',
|
||||
overHidden: true,
|
||||
},
|
||||
{
|
||||
label: '申请人',
|
||||
prop: 'tCreateUser',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '提交时间',
|
||||
prop: 'tSubmitTime',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
label: '当前节点',
|
||||
prop: 'currentApprovalNode',
|
||||
width: 140,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
searchReset() {
|
||||
this.query = {};
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
searchChange(params, done) {
|
||||
this.query = params;
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page, params);
|
||||
done();
|
||||
},
|
||||
currentChange(currentPage) {
|
||||
this.page.currentPage = currentPage;
|
||||
},
|
||||
sizeChange(pageSize) {
|
||||
this.page.pageSize = pageSize;
|
||||
},
|
||||
refreshChange() {
|
||||
this.onLoad(this.page, this.query);
|
||||
},
|
||||
onLoad(page, params = {}) {
|
||||
this.loading = true;
|
||||
const query = {
|
||||
...this.query,
|
||||
...params,
|
||||
};
|
||||
getDoneList(page.currentPage, page.pageSize, query).then(res => {
|
||||
const data = res.data.data;
|
||||
this.page.total = data.total;
|
||||
this.data = data.records;
|
||||
this.doneCount = data.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 查看详情
|
||||
handleView(row) {
|
||||
this.$message.info(`查看流程详情: ${row.processName}`);
|
||||
// TODO: 后续接入流程详情页面
|
||||
},
|
||||
// 流转查看(时间线弹窗)
|
||||
handleTransfer(row) {
|
||||
this.currentProcessName = row.processName;
|
||||
// 若接口提供 trackSteps 则直接展示,否则尝试通过 instanceCode 获取
|
||||
if (row.trackSteps && row.trackSteps.length) {
|
||||
this.currentTrackSteps = row.trackSteps;
|
||||
this.transferDialogVisible = true;
|
||||
} else {
|
||||
this.$message.info('暂无流转记录');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.workflow-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.workflow-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.transfer-process-name {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
color: #303133;
|
||||
}
|
||||
.step-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.step-name {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
.step-result {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.step-info {
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.step-handler {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.step-remark {
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
padding: 8px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 6px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.step-remark .el-icon {
|
||||
margin-top: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<basic-container>
|
||||
<!-- 页面标题和发起按钮 -->
|
||||
<div class="workflow-header">
|
||||
<h3 class="workflow-title">我的申请</h3>
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handleStart">
|
||||
发起新流程
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<avue-crud
|
||||
:option="option"
|
||||
:table-loading="loading"
|
||||
:data="data"
|
||||
:page="page"
|
||||
ref="crud"
|
||||
v-model="form"
|
||||
@search-change="searchChange"
|
||||
@search-reset="searchReset"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@refresh-change="refreshChange"
|
||||
@on-load="onLoad"
|
||||
>
|
||||
<!-- 状态列自定义 -->
|
||||
<template #status="{ row }">
|
||||
<el-tag
|
||||
:type="
|
||||
row.status === '已完成'
|
||||
? 'success'
|
||||
: row.status === '已驳回'
|
||||
? 'danger'
|
||||
: row.status === '待提交'
|
||||
? 'info'
|
||||
: 'warning'
|
||||
"
|
||||
:effect="row.status === '待提交' ? 'plain' : 'light'"
|
||||
>
|
||||
{{ row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<!-- 自定义操作列 -->
|
||||
<template #menu="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleView(scope.row)"
|
||||
>查看</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === '待提交'"
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleEdit(scope.row)"
|
||||
>编辑</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.status === '待提交'"
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleDelete(scope.row)"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<!-- 发起流程弹窗 -->
|
||||
<el-dialog
|
||||
title="选择流程类型"
|
||||
v-model="startDialogVisible"
|
||||
width="600px"
|
||||
append-to-body
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col
|
||||
:span="8"
|
||||
v-for="item in processTypes"
|
||||
:key="item.value"
|
||||
style="margin-bottom: 15px"
|
||||
>
|
||||
<el-card
|
||||
shadow="hover"
|
||||
:body-style="{ padding: '20px', textAlign: 'center', cursor: 'pointer' }"
|
||||
@click="selectProcessType(item)"
|
||||
>
|
||||
<el-icon size="32" style="margin-bottom: 10px">
|
||||
<Document />
|
||||
</el-icon>
|
||||
<div>{{ item.label }}</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getMyList, getProcessTypes } from '@/api/workflow';
|
||||
import { Document } from '@element-plus/icons-vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Document,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
loading: true,
|
||||
page: {
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0,
|
||||
},
|
||||
query: {},
|
||||
data: [],
|
||||
// 发起流程弹窗
|
||||
startDialogVisible: false,
|
||||
processTypes: [],
|
||||
// Avue 表格配置
|
||||
option: {
|
||||
height: 'auto',
|
||||
calcHeight: 32,
|
||||
tip: false,
|
||||
searchShow: false,
|
||||
searchMenuSpan: 6,
|
||||
border: true,
|
||||
index: true,
|
||||
selection: false,
|
||||
editBtn: false,
|
||||
addBtn: false,
|
||||
viewBtn: false,
|
||||
delBtn: false,
|
||||
menuWidth: 200,
|
||||
dialogClickModal: false,
|
||||
column: [
|
||||
{
|
||||
label: '流程名称',
|
||||
prop: 'processName',
|
||||
search: true,
|
||||
overHidden: true,
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'status',
|
||||
slot: true,
|
||||
width: 100,
|
||||
search: true,
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{ label: '待提交', value: '待提交' },
|
||||
{ label: '审批中', value: '审批中' },
|
||||
{ label: '已完成', value: '已完成' },
|
||||
{ label: '已驳回', value: '已驳回' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '申请人',
|
||||
prop: 'tCreateUser',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '申请时间',
|
||||
prop: 'tArrivalTime',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
label: '当前节点',
|
||||
prop: 'currentApprovalNode',
|
||||
width: 140,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadProcessTypes();
|
||||
},
|
||||
methods: {
|
||||
loadProcessTypes() {
|
||||
getProcessTypes().then(res => {
|
||||
const data = res.data.data;
|
||||
this.processTypes = data.map(item => ({
|
||||
label: item.processName,
|
||||
value: item.processId,
|
||||
}));
|
||||
});
|
||||
},
|
||||
searchReset() {
|
||||
this.query = {};
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
searchChange(params, done) {
|
||||
this.query = params;
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page, params);
|
||||
done();
|
||||
},
|
||||
currentChange(currentPage) {
|
||||
this.page.currentPage = currentPage;
|
||||
},
|
||||
sizeChange(pageSize) {
|
||||
this.page.pageSize = pageSize;
|
||||
},
|
||||
refreshChange() {
|
||||
this.onLoad(this.page, this.query);
|
||||
},
|
||||
onLoad(page, params = {}) {
|
||||
this.loading = true;
|
||||
const query = {
|
||||
...this.query,
|
||||
...params,
|
||||
};
|
||||
getMyList(page.currentPage, page.pageSize, query).then(res => {
|
||||
const data = res.data.data;
|
||||
this.page.total = data.total;
|
||||
this.data = data.records;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 发起新流程
|
||||
handleStart() {
|
||||
this.startDialogVisible = true;
|
||||
},
|
||||
// 选择流程类型
|
||||
selectProcessType(item) {
|
||||
this.startDialogVisible = false;
|
||||
this.$message.success(`选择了流程类型: ${item.label}`);
|
||||
// TODO: 后续接入流程发起表单页面
|
||||
},
|
||||
// 查看详情
|
||||
handleView(row) {
|
||||
this.$message.info(`查看流程详情: ${row.processName}`);
|
||||
// TODO: 后续接入流程详情页面
|
||||
},
|
||||
// 编辑(仅待提交状态)
|
||||
handleEdit(row) {
|
||||
this.$message.info(`编辑流程: ${row.processName}`);
|
||||
// TODO: 后续接入编辑表单页面
|
||||
},
|
||||
// 删除(仅待提交状态)
|
||||
handleDelete(row) {
|
||||
this.$confirm(`确认删除流程 "${row.processName}" 吗?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
// 从列表中移除
|
||||
const index = this.data.findIndex(item => item.id === row.id);
|
||||
if (index !== -1) {
|
||||
this.data.splice(index, 1);
|
||||
this.page.total -= 1;
|
||||
}
|
||||
this.$message.success('删除成功');
|
||||
}).catch(() => {});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.workflow-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.workflow-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<basic-container>
|
||||
<div class="my-process">
|
||||
<!-- 页面标题 -->
|
||||
<div class="page-header">
|
||||
<h3 class="page-title">我的流程</h3>
|
||||
<el-tag type="info" class="process-count">共 {{ processList.length }} 个流程</el-tag>
|
||||
</div>
|
||||
|
||||
<!-- 流程卡片网格 -->
|
||||
<div class="process-grid">
|
||||
<div
|
||||
v-for="process in processList"
|
||||
:key="process.id"
|
||||
class="process-card"
|
||||
:style="{ '--process-color': process.processColor }"
|
||||
@click="handleStartProcess(process)"
|
||||
>
|
||||
<div class="process-content">
|
||||
<div
|
||||
class="process-icon"
|
||||
:style="{ backgroundColor: process.iconColor }"
|
||||
>
|
||||
<el-icon :size="36"><component :is="process.icon" /></el-icon>
|
||||
</div>
|
||||
<div class="process-info">
|
||||
<div class="process-name">{{ process.name }}</div>
|
||||
<div class="process-category">{{ process.category }}</div>
|
||||
<el-tag
|
||||
:type="process.status === 'active' ? 'success' : 'info'"
|
||||
size="small"
|
||||
class="process-status"
|
||||
>
|
||||
{{ process.status === 'active' ? '启用' : '停用' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getProcessTypes } from '@/api/workflow';
|
||||
import { Document, OfficeBuilding, ShoppingCart, Connection } from '@element-plus/icons-vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
processList: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadProcessTypes();
|
||||
},
|
||||
methods: {
|
||||
loadProcessTypes() {
|
||||
this.loading = true;
|
||||
getProcessTypes().then(res => {
|
||||
const data = res.data.data;
|
||||
// 将接口返回的 {processName, processId} 映射为页面需要的结构
|
||||
const iconMap = [
|
||||
{ icon: Document, iconColor: '#67c23a', processColor: '#67c23a', category: '非经营性商品管理' },
|
||||
{ icon: OfficeBuilding, iconColor: '#409eff', processColor: '#409eff', category: '招标管理' },
|
||||
{ icon: Document, iconColor: '#e6a23c', processColor: '#e6a23c', category: '招标管理' },
|
||||
{ icon: Connection, iconColor: '#909399', processColor: '#909399', category: '订单管理' },
|
||||
{ icon: ShoppingCart, iconColor: '#f56c6c', processColor: '#f56c6c', category: '询比价管理' },
|
||||
];
|
||||
this.processList = data.map((item, index) => {
|
||||
const style = iconMap[index % iconMap.length];
|
||||
return {
|
||||
id: item.processId,
|
||||
code: item.processId,
|
||||
name: item.processName,
|
||||
category: style.category,
|
||||
status: 'active',
|
||||
version: '1.0',
|
||||
icon: style.icon,
|
||||
iconColor: style.iconColor,
|
||||
processColor: style.processColor,
|
||||
};
|
||||
});
|
||||
this.loading = false;
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleStartProcess(process) {
|
||||
this.$message.info(`流程"${process.name}"暂未实现`);
|
||||
// TODO: 后续接入流程发起表单页面
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-process {
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 140px);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.process-count {
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.process-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 24px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.process-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 30px 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.process-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--process-color) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
.process-card:hover {
|
||||
border-color: var(--process-color);
|
||||
box-shadow: 0 8px 30px rgba(64, 158, 255, 0.2);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.process-card:hover::before {
|
||||
background: linear-gradient(90deg, var(--process-color) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
.process-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.process-icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
margin-bottom: 20px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.process-card:hover .process-icon {
|
||||
transform: scale(1.1) rotate(5deg);
|
||||
}
|
||||
|
||||
.process-info {
|
||||
text-align: center;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.process-name {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.process-category {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.process-status {
|
||||
margin-top: 4px;
|
||||
height: 24px;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.my-process {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.process-grid {
|
||||
gap: 16px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.process-card {
|
||||
padding: 20px 15px;
|
||||
}
|
||||
|
||||
.process-name {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<basic-container>
|
||||
<!-- 页面标题和待办计数 -->
|
||||
<div class="workflow-header">
|
||||
<h3 class="workflow-title">我的待办</h3>
|
||||
<el-tag type="danger" size="large">待处理 {{ todoCount }} 项</el-tag>
|
||||
</div>
|
||||
|
||||
<avue-crud
|
||||
:option="option"
|
||||
:table-loading="loading"
|
||||
:data="data"
|
||||
:page="page"
|
||||
ref="crud"
|
||||
v-model="form"
|
||||
@search-change="searchChange"
|
||||
@search-reset="searchReset"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@refresh-change="refreshChange"
|
||||
@on-load="onLoad"
|
||||
>
|
||||
<!-- 自定义阅知状态列 -->
|
||||
<template #pendingSubStatus="scope">
|
||||
<el-tag
|
||||
:type="scope.row.pendingSubStatus === '待阅' ? 'warning' : 'success'"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.pendingSubStatus || '待办' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<!-- 自定义操作列 -->
|
||||
<template #menu="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleApprove(scope.row)"
|
||||
>审批</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click.stop="handleView(scope.row)"
|
||||
>查看</el-button>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<!-- 统一审批弹窗(同意/驳回) -->
|
||||
<el-dialog
|
||||
title="审批处理"
|
||||
v-model="approveDialogVisible"
|
||||
width="500px"
|
||||
append-to-body
|
||||
>
|
||||
<el-form :model="approveForm" label-width="80px">
|
||||
<el-form-item label="流程名称">
|
||||
<el-input v-model="approveForm.processName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="申请人">
|
||||
<el-input v-model="approveForm.applicantName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="处理结果" required>
|
||||
<el-radio-group v-model="approveForm.result">
|
||||
<el-radio label="同意">同意</el-radio>
|
||||
<el-radio label="驳回">驳回</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="approveForm.result === '驳回' ? '驳回原因' : '审批意见'">
|
||||
<el-input
|
||||
v-model="approveForm.comment"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
:placeholder="approveForm.result === '驳回' ? '请输入驳回原因' : '请输入审批意见(选填)'"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="approveDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmApprove">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTodoList, approve, reject, getTodoCount } from '@/api/workflow';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
loading: true,
|
||||
todoCount: 0,
|
||||
page: {
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0,
|
||||
},
|
||||
query: {},
|
||||
data: [],
|
||||
// 审批弹窗
|
||||
approveDialogVisible: false,
|
||||
approveForm: {
|
||||
id: '',
|
||||
processName: '',
|
||||
applicantName: '',
|
||||
result: '同意',
|
||||
comment: '',
|
||||
},
|
||||
// Avue 表格配置
|
||||
option: {
|
||||
height: 'auto',
|
||||
calcHeight: 32,
|
||||
tip: false,
|
||||
searchShow: true,
|
||||
searchMenuSpan: 6,
|
||||
border: true,
|
||||
index: true,
|
||||
selection: false,
|
||||
editBtn: false,
|
||||
addBtn: false,
|
||||
viewBtn: false,
|
||||
delBtn: false,
|
||||
menuWidth: 140,
|
||||
dialogClickModal: false,
|
||||
column: [
|
||||
{
|
||||
label: '流程名称',
|
||||
prop: 'processName',
|
||||
overHidden: true,
|
||||
},
|
||||
{
|
||||
label: '申请人',
|
||||
prop: 'tCreateUser',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
label: '到达时间',
|
||||
prop: 'tArrivalTime',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
label: '提交时间',
|
||||
prop: 'tSubmitTime',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
label: '当前节点',
|
||||
prop: 'currentApprovalNode',
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
label: '阅知状态',
|
||||
prop: 'pendingSubStatus',
|
||||
slot: true,
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
searchReset() {
|
||||
this.query = {};
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
searchChange(params, done) {
|
||||
this.query = params;
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page, params);
|
||||
done();
|
||||
},
|
||||
currentChange(currentPage) {
|
||||
this.page.currentPage = currentPage;
|
||||
},
|
||||
sizeChange(pageSize) {
|
||||
this.page.pageSize = pageSize;
|
||||
},
|
||||
refreshChange() {
|
||||
this.onLoad(this.page, this.query);
|
||||
},
|
||||
onLoad(page, params = {}) {
|
||||
this.loading = true;
|
||||
const query = {
|
||||
...this.query,
|
||||
...params,
|
||||
};
|
||||
getTodoList(page.currentPage, page.pageSize, query).then(res => {
|
||||
const data = res.data.data;
|
||||
this.page.total = data.total;
|
||||
this.data = data.records;
|
||||
this.loading = false;
|
||||
});
|
||||
// 获取待办数量
|
||||
getTodoCount().then(res => {
|
||||
this.todoCount = res.data.data;
|
||||
});
|
||||
},
|
||||
// 审批操作(统一弹窗)
|
||||
handleApprove(row) {
|
||||
this.approveForm = {
|
||||
id: row.id,
|
||||
taskId: row.taskId,
|
||||
instanceCode: row.instanceCode,
|
||||
processName: row.processName,
|
||||
applicantName: row.tCreateUser,
|
||||
result: '同意',
|
||||
comment: '',
|
||||
};
|
||||
this.approveDialogVisible = true;
|
||||
},
|
||||
confirmApprove() {
|
||||
if (this.approveForm.result === '驳回' && !this.approveForm.comment) {
|
||||
this.$message.warning('请输入驳回原因');
|
||||
return;
|
||||
}
|
||||
const api = this.approveForm.result === '同意' ? approve : reject;
|
||||
api(this.approveForm).then(res => {
|
||||
if (res.data.code === 200) {
|
||||
this.$message.success(this.approveForm.result === '同意' ? '审批成功' : '驳回成功');
|
||||
this.approveDialogVisible = false;
|
||||
this.refreshChange();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 查看详情
|
||||
handleView(row) {
|
||||
this.$message.info(`查看流程详情: ${row.processName}`);
|
||||
// TODO: 后续接入流程详情页面
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.workflow-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
.workflow-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user