Kaynağa Gözat

提交代码

zlwu 1 yıl önce
ebeveyn
işleme
f1c498f1c7

+ 434 - 0
mobile/src/pages/bak/taskCopyList-bak.vue

@@ -0,0 +1,434 @@
+<template>
+    <view class="task-copy-container">
+        <!-- 头部标题和操作 -->
+        <view class="header">
+            <text class="title">我的抄送</text>
+            <view class="header-actions">
+                <u-icon name="search" size="20" color="#666" @click="toggleSearch"></u-icon>
+            </view>
+        </view>
+
+        <!-- 搜索栏 -->
+        <view v-if="showSearch" class="search-section">
+            <view class="search-input">
+                <u-input
+                    v-model="queryParams.nodeName"
+                    placeholder="请输入任务名称"
+                    border="bottom"
+                    clearable
+                    @confirm="handleQuery"
+                ></u-input>
+            </view>
+            <view class="search-input">
+                <u-input
+                    v-model="queryParams.flowName"
+                    placeholder="请输入流程定义名称"
+                    border="bottom"
+                    clearable
+                    @confirm="handleQuery"
+                ></u-input>
+            </view>
+            <view class="search-input">
+                <u-input
+                    v-model="queryParams.flowCode"
+                    placeholder="请输入流程定义编码"
+                    border="bottom"
+                    clearable
+                    @confirm="handleQuery"
+                ></u-input>
+            </view>
+            <view class="search-actions">
+                <u-button type="primary" size="small" @click="handleQuery">搜索</u-button>
+                <u-button size="small" @click="resetQuery">重置</u-button>
+            </view>
+        </view>
+
+        <!-- 内容区域 -->
+        <view class="content">
+            <!-- 加载状态 -->
+            <view v-if="loading" class="loading">
+                <u-loading-icon></u-loading-icon>
+                <text class="loading-text">加载中...</text>
+            </view>
+
+            <!-- 空数据 -->
+            <view v-else-if="taskList.length === 0" class="empty">
+                <view class="empty-content">
+                    <u-icon name="file-text" size="80" color="#ddd"></u-icon>
+                    <text class="empty-text">暂无数据</text>
+                </view>
+            </view>
+
+            <!-- 任务列表 -->
+            <view v-else class="task-list">
+                <view
+                    v-for="item in taskList"
+                    :key="item.id"
+                    class="task-item"
+                    @click="handleView(item)"
+                >
+                    <!-- 任务信息 -->
+                    <view class="task-header">
+                        <view class="task-title-row">
+                            <text class="task-name">{{ item.flowName }}</text>
+                            <view
+                                class="task-status"
+                                :style="{
+                                    backgroundColor: getStatusStyle(item.flowStatus).color,
+                                    color: 'white',
+                                }"
+                            >
+                                <text class="status-text">
+                                    {{ getStatusText(item.flowStatus) }}
+                                </text>
+                            </view>
+                        </view>
+                        <view class="task-info">
+                            <text class="task-code">{{ item.flowCode }}</text>
+                            <text class="task-category">{{ item.categoryName }}</text>
+                        </view>
+                        <text class="task-version">版本:v{{ item.version }}.0</text>
+                        <text class="task-node-name">任务:{{ item.nodeName }}</text>
+
+                        <!-- 抄送标识 -->
+                        <view class="copy-info">
+                            <u-icon name="email" size="16" color="#ff9500"></u-icon>
+                            <text class="copy-label">抄送任务</text>
+                        </view>
+
+                        <text class="task-time">{{ formatTime(item.createTime) }}</text>
+                    </view>
+
+                    <!-- 操作按钮 -->
+                    <view class="task-actions" @click.stop>
+                        <u-button type="info" size="mini" @click="handleView(item)">查看</u-button>
+                    </view>
+                </view>
+            </view>
+
+            <!-- 分页加载 -->
+            <view v-if="taskList.length > 0" class="pagination">
+                <u-loadmore v-if="hasMore" status="loading" @loadmore="loadMore">
+                    <text>正在加载更多...</text>
+                </u-loadmore>
+                <view v-else class="load-end">
+                    <text>已加载全部数据</text>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+import { workflowApi, getStatusStyle, formatTime, routerJump } from '@/common/workflow-api.js';
+
+export default {
+    data() {
+        return {
+            loading: false,
+            showSearch: false,
+            taskList: [],
+            total: 0,
+            hasMore: true,
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                nodeName: '',
+                flowName: '',
+                flowCode: '',
+            },
+        };
+    },
+    onLoad() {
+        this.getTaskCopyList();
+    },
+    onReachBottom() {
+        if (this.hasMore && !this.loading) {
+            this.loadMore();
+        }
+    },
+    onPullDownRefresh() {
+        this.refreshData();
+    },
+    methods: {
+        async getTaskCopyList() {
+            if (this.loading) return;
+
+            this.loading = true;
+            try {
+                const res = await workflowApi.pageByTaskCopy(this.queryParams);
+                if (res.code === 200) {
+                    if (this.queryParams.pageNum === 1) {
+                        this.taskList = res.rows || [];
+                    } else {
+                        this.taskList.push(...(res.rows || []));
+                    }
+                    this.total = res.total;
+                    this.hasMore = this.taskList.length < this.total;
+                } else {
+                    uni.showToast({ title: res.msg || '加载失败', icon: 'error' });
+                }
+            } catch (e) {
+                console.error('加载抄送任务失败:', e);
+                uni.showToast({ title: '网络错误', icon: 'error' });
+            } finally {
+                this.loading = false;
+                uni.stopPullDownRefresh();
+            }
+        },
+
+        async loadMore() {
+            if (!this.hasMore || this.loading) return;
+
+            this.queryParams.pageNum++;
+            await this.getTaskCopyList();
+        },
+
+        async refreshData() {
+            this.queryParams.pageNum = 1;
+            this.hasMore = true;
+            await this.getTaskCopyList();
+        },
+
+        toggleSearch() {
+            this.showSearch = !this.showSearch;
+        },
+
+        handleQuery() {
+            this.queryParams.pageNum = 1;
+            this.hasMore = true;
+            this.refreshData();
+        },
+
+        resetQuery() {
+            this.queryParams = {
+                pageNum: 1,
+                pageSize: 10,
+                nodeName: '',
+                flowName: '',
+                flowCode: '',
+            };
+            this.hasMore = true;
+            this.refreshData();
+        },
+
+        handleView(item) {
+            this.routerJump({
+                businessId: item.businessId,
+                taskId: item.id,
+                type: 'view',
+                formCustom: item.formCustom,
+                formPath: item.formPath,
+            });
+        },
+
+        getStatusText(status) {
+            const statusMap = {
+                draft: '草稿',
+                waiting: '待审批',
+                complete: '已完成',
+                cancel: '已取消',
+                back: '已退回',
+                suspend: '挂起',
+                terminate: '终止',
+            };
+            return statusMap[status] || '未知';
+        },
+
+        getStatusStyle(status) {
+            return getStatusStyle(status);
+        },
+
+        formatTime(timeStr) {
+            return formatTime(timeStr);
+        },
+
+        routerJump(params) {
+            routerJump(params);
+        },
+    },
+};
+</script>
+
+<style scoped>
+.task-copy-container {
+    background: #f5f5f5;
+    min-height: 100vh;
+    padding-bottom: 20px;
+}
+
+.header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 16px 20px;
+    background: #fff;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+}
+
+.title {
+    font-size: 20px;
+    font-weight: bold;
+    color: #333;
+}
+
+.header-actions {
+    display: flex;
+    align-items: center;
+}
+
+.search-section {
+    background: #fff;
+    padding: 16px 20px;
+    border-bottom: 1px solid #eee;
+}
+
+.search-input {
+    margin-bottom: 12px;
+}
+
+.search-actions {
+    display: flex;
+    gap: 12px;
+}
+
+.content {
+    flex: 1;
+}
+
+.loading {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 40px;
+}
+
+.loading-text {
+    margin-top: 8px;
+    color: #999;
+    font-size: 14px;
+}
+
+.empty {
+    padding: 40px 20px;
+}
+
+.empty-content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+}
+
+.empty-text {
+    font-size: 14px;
+    color: #999;
+    margin-top: 12px;
+}
+
+.task-list {
+    padding: 16px 20px;
+}
+
+.task-item {
+    background: #fff;
+    border-radius: 12px;
+    padding: 16px;
+    margin-bottom: 12px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
+    transition: box-shadow 0.2s;
+    /* 抄送任务特殊样式 */
+    border-left: 4px solid #ff9500;
+}
+
+.task-item:active {
+    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
+}
+
+.task-header {
+    margin-bottom: 12px;
+}
+
+.task-title-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+    margin-bottom: 8px;
+}
+
+.task-name {
+    font-size: 16px;
+    font-weight: 500;
+    color: #333;
+    flex: 1;
+    margin-right: 12px;
+}
+
+.task-status {
+    padding: 4px 8px;
+    border-radius: 12px;
+    font-size: 12px;
+    font-weight: 500;
+    white-space: nowrap;
+}
+
+.task-info {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 6px;
+}
+
+.task-code {
+    font-size: 13px;
+    color: #666;
+}
+
+.task-category {
+    font-size: 13px;
+    color: #666;
+}
+
+.task-version,
+.task-node-name {
+    font-size: 13px;
+    color: #666;
+    margin-bottom: 4px;
+}
+
+.copy-info {
+    display: flex;
+    align-items: center;
+    margin-bottom: 4px;
+}
+
+.copy-label {
+    font-size: 13px;
+    color: #ff9500;
+    font-weight: 500;
+    margin-left: 4px;
+}
+
+.task-time {
+    font-size: 12px;
+    color: #999;
+}
+
+.task-actions {
+    border-top: 1px solid #f0f0f0;
+    padding-top: 12px;
+}
+
+.pagination {
+    padding: 16px 20px;
+}
+
+.load-end {
+    text-align: center;
+    padding: 16px;
+}
+
+.load-end text {
+    font-size: 14px;
+    color: #999;
+}
+</style>

+ 431 - 309
mobile/src/pages/task/taskCopyList.vue

@@ -1,434 +1,556 @@
 <template>
-    <view class="task-copy-container">
-        <!-- 头部标题和操作 -->
-        <view class="header">
-            <text class="title">我的抄送</text>
-            <view class="header-actions">
-                <u-icon name="search" size="20" color="#666" @click="toggleSearch"></u-icon>
+    <view class="task-copy-list-container">
+        <!-- 顶部导航 -->
+        <u-navbar title="我的抄送" :border-bottom="false" bg-color="#3c9cff" title-color="#fff">
+            <view slot="left" @click="goBack">
+                <u-icon name="arrow-left" color="#fff" size="22"></u-icon>
             </view>
+        </u-navbar>
+
+        <!-- 搜索区域 -->
+        <view class="search-container">
+            <u-search
+                v-model="queryParams.flowName"
+                placeholder="请输入流程定义名称"
+                :show-action="true"
+                action-text="搜索"
+                :animation="true"
+                @search="handleQuery"
+                @custom="handleQuery"
+            ></u-search>
         </view>
 
-        <!-- 搜索栏 -->
-        <view v-if="showSearch" class="search-section">
-            <view class="search-input">
-                <u-input
-                    v-model="queryParams.nodeName"
-                    placeholder="请输入任务名称"
-                    border="bottom"
-                    clearable
-                    @confirm="handleQuery"
-                ></u-input>
-            </view>
-            <view class="search-input">
-                <u-input
-                    v-model="queryParams.flowName"
-                    placeholder="请输入流程定义名称"
-                    border="bottom"
-                    clearable
-                    @confirm="handleQuery"
-                ></u-input>
-            </view>
-            <view class="search-input">
-                <u-input
-                    v-model="queryParams.flowCode"
-                    placeholder="请输入流程定义编码"
-                    border="bottom"
-                    clearable
-                    @confirm="handleQuery"
-                ></u-input>
-            </view>
-            <view class="search-actions">
-                <u-button type="primary" size="small" @click="handleQuery">搜索</u-button>
-                <u-button size="small" @click="resetQuery">重置</u-button>
-            </view>
-        </view>
+        <!-- 加载状态 -->
+        <u-loading-page :loading="loading && !refreshing" loading-text="加载中..."></u-loading-page>
 
-        <!-- 内容区域 -->
-        <view class="content">
-            <!-- 加载状态 -->
-            <view v-if="loading" class="loading">
-                <u-loading-icon></u-loading-icon>
-                <text class="loading-text">加载中...</text>
+        <!-- 任务列表 -->
+        <view v-if="!loading || refreshing" class="content-wrapper">
+            <!-- 空状态 -->
+            <view v-if="taskList.length === 0 && !loading" class="empty-container">
+                <u-empty text="暂无抄送任务" mode="data"></u-empty>
             </view>
 
-            <!-- 空数据 -->
-            <view v-else-if="taskList.length === 0" class="empty">
-                <view class="empty-content">
-                    <u-icon name="file-text" size="80" color="#ddd"></u-icon>
-                    <text class="empty-text">暂无数据</text>
-                </view>
-            </view>
+            <!-- 任务卡片列表 -->
+            <scroll-view
+                v-else
+                scroll-y
+                class="task-list"
+                @scrolltolower="loadMore"
+                :refresher-enabled="true"
+                :refresher-triggered="refreshing"
+                @refresherrefresh="onRefresh"
+            >
+                <view v-for="(item, index) in taskList" :key="item.id || index" class="task-card">
+                    <!-- 卡片头部 -->
+                    <view class="card-header">
+                        <view class="flow-name">{{ item.flowName || '-' }}</view>
+                        <view class="flow-status">
+                            <u-tag
+                                :text="getFlowStatusText(item.flowStatus)"
+                                :type="getFlowStatusType(item.flowStatus)"
+                                size="mini"
+                            ></u-tag>
+                        </view>
+                    </view>
 
-            <!-- 任务列表 -->
-            <view v-else class="task-list">
-                <view
-                    v-for="item in taskList"
-                    :key="item.id"
-                    class="task-item"
-                    @click="handleView(item)"
-                >
-                    <!-- 任务信息 -->
-                    <view class="task-header">
-                        <view class="task-title-row">
-                            <text class="task-name">{{ item.flowName }}</text>
-                            <view
-                                class="task-status"
-                                :style="{
-                                    backgroundColor: getStatusStyle(item.flowStatus).color,
-                                    color: 'white',
-                                }"
-                            >
-                                <text class="status-text">
-                                    {{ getStatusText(item.flowStatus) }}
-                                </text>
-                            </view>
+                    <!-- 卡片内容 -->
+                    <view class="card-content">
+                        <view class="info-item">
+                            <text class="label">流程名称:</text>
+                            <text class="value">{{ item.flowName || '-' }}</text>
                         </view>
-                        <view class="task-info">
-                            <text class="task-code">{{ item.flowCode }}</text>
-                            <text class="task-category">{{ item.categoryName }}</text>
+                        <view class="info-item">
+                            <text class="label">流程分类:</text>
+                            <text class="value">{{ item.categoryName || '-' }}</text>
                         </view>
-                        <text class="task-version">版本:v{{ item.version }}.0</text>
-                        <text class="task-node-name">任务:{{ item.nodeName }}</text>
-
-                        <!-- 抄送标识 -->
-                        <view class="copy-info">
-                            <u-icon name="email" size="16" color="#ff9500"></u-icon>
-                            <text class="copy-label">抄送任务</text>
+                        <view class="info-item">
+                            <text class="label">版本号:</text>
+                            <text class="value">v{{ item.version || '1' }}.0</text>
+                        </view>
+                        <view class="info-item">
+                            <text class="label">任务名称:</text>
+                            <text class="value">{{ item.nodeName || '-' }}</text>
+                        </view>
+                        <view v-if="item.createTime" class="info-item">
+                            <text class="label">创建时间:</text>
+                            <text class="value">{{ formatTime(item.createTime) }}</text>
                         </view>
-
-                        <text class="task-time">{{ formatTime(item.createTime) }}</text>
                     </view>
 
                     <!-- 操作按钮 -->
-                    <view class="task-actions" @click.stop>
-                        <u-button type="info" size="mini" @click="handleView(item)">查看</u-button>
+                    <view class="card-actions">
+                        <view class="action-btn info-btn" @click="handleView(item)">
+                            <u-icon name="eye" size="16" color="#3c9cff"></u-icon>
+                            <text class="btn-text">查看</text>
+                        </view>
                     </view>
                 </view>
-            </view>
 
-            <!-- 分页加载 -->
-            <view v-if="taskList.length > 0" class="pagination">
-                <u-loadmore v-if="hasMore" status="loading" @loadmore="loadMore">
-                    <text>正在加载更多...</text>
-                </u-loadmore>
-                <view v-else class="load-end">
-                    <text>已加载全部数据</text>
+                <!-- 加载更多提示 -->
+                <view v-if="hasMore && taskList.length > 0" class="load-more">
+                    <u-loading-icon v-if="loadingMore"></u-loading-icon>
+                    <text class="load-more-text">
+                        {{ loadingMore ? '正在加载...' : '上拉加载更多' }}
+                    </text>
                 </view>
-            </view>
+                <view v-else-if="taskList.length > 0" class="load-more">
+                    <text class="load-more-text">没有更多数据了</text>
+                </view>
+            </scroll-view>
         </view>
     </view>
 </template>
 
 <script>
-import { workflowApi, getStatusStyle, formatTime, routerJump } from '@/common/workflow-api.js';
+import { request } from '@/common/request.js';
+import { useDict, getDictLabel, getDictTagType } from '@/common/dict.js';
 
 export default {
+    name: 'TaskCopyList',
     data() {
         return {
             loading: false,
-            showSearch: false,
+            refreshing: false,
+            loadingMore: false,
             taskList: [],
             total: 0,
             hasMore: true,
+
+            // 查询参数
             queryParams: {
                 pageNum: 1,
                 pageSize: 10,
-                nodeName: '',
                 flowName: '',
-                flowCode: '',
+                nodeName: undefined,
+                flowCode: undefined,
             },
+
+            // 字典数据
+            wfBusinessStatusDict: [],
         };
     },
-    onLoad() {
-        this.getTaskCopyList();
-    },
-    onReachBottom() {
-        if (this.hasMore && !this.loading) {
-            this.loadMore();
-        }
-    },
-    onPullDownRefresh() {
-        this.refreshData();
+
+    async created() {
+        await this.initDict();
+        await this.getTaskCopyList();
     },
+
     methods: {
-        async getTaskCopyList() {
-            if (this.loading) return;
+        // 返回上一页
+        goBack() {
+            uni.navigateBack();
+        },
 
-            this.loading = true;
+        // 初始化字典
+        async initDict() {
             try {
-                const res = await workflowApi.pageByTaskCopy(this.queryParams);
-                if (res.code === 200) {
-                    if (this.queryParams.pageNum === 1) {
-                        this.taskList = res.rows || [];
-                    } else {
-                        this.taskList.push(...(res.rows || []));
+                const dictResult = useDict('wf_business_status');
+
+                // 设置响应式更新回调
+                dictResult.setUpdateCallback((dictType, data) => {
+                    if (dictType === 'wf_business_status') {
+                        this.wfBusinessStatusDict = data;
+                        console.log('✅ 工作流业务状态字典加载完成:', this.wfBusinessStatusDict);
                     }
-                    this.total = res.total;
-                    this.hasMore = this.taskList.length < this.total;
-                } else {
-                    uni.showToast({ title: res.msg || '加载失败', icon: 'error' });
-                }
-            } catch (e) {
-                console.error('加载抄送任务失败:', e);
-                uni.showToast({ title: '网络错误', icon: 'error' });
-            } finally {
-                this.loading = false;
-                uni.stopPullDownRefresh();
+                });
+
+                // 获取初始数据
+                this.wfBusinessStatusDict = dictResult.data.wf_business_status || [];
+            } catch (error) {
+                console.error('❌ 初始化字典失败:', error);
+                this.wfBusinessStatusDict = [];
             }
         },
 
-        async loadMore() {
-            if (!this.hasMore || this.loading) return;
+        // 获取流程状态文本
+        getFlowStatusText(status) {
+            const label = getDictLabel(this.wfBusinessStatusDict, status);
+            return label || this.getDefaultStatusText(status);
+        },
 
-            this.queryParams.pageNum++;
-            await this.getTaskCopyList();
+        // 获取流程状态类型
+        getFlowStatusType(status) {
+            const fallbackMap = {
+                draft: 'info', // 草稿
+                waiting: 'warning', // 待审批
+                complete: 'success', // 已完成
+                reject: 'error', // 已拒绝
+                cancel: 'info', // 已取消
+                suspend: 'warning', // 已挂起
+                back: 'warning', // 已退回
+            };
+            return getDictTagType(this.wfBusinessStatusDict, status, fallbackMap);
         },
 
-        async refreshData() {
-            this.queryParams.pageNum = 1;
-            this.hasMore = true;
-            await this.getTaskCopyList();
+        // 默认状态文本(当字典未加载时使用)
+        getDefaultStatusText(status) {
+            const defaultMap = {
+                draft: '草稿',
+                waiting: '待审批',
+                complete: '已完成',
+                reject: '已拒绝',
+                cancel: '已取消',
+                suspend: '已挂起',
+                back: '已退回',
+            };
+            return defaultMap[status] || status || '未知';
         },
 
-        toggleSearch() {
-            this.showSearch = !this.showSearch;
+        // 获取任务抄送列表
+        async getTaskCopyList(isRefresh = false) {
+            if (isRefresh) {
+                this.refreshing = true;
+                this.queryParams.pageNum = 1;
+                this.hasMore = true;
+            } else if (this.queryParams.pageNum === 1) {
+                this.loading = true;
+            } else {
+                this.loadingMore = true;
+            }
+
+            try {
+                const res = await request({
+                    url: '/workflow/task/pageByTaskCopy',
+                    method: 'GET',
+                    params: {
+                        pageNum: this.queryParams.pageNum,
+                        pageSize: this.queryParams.pageSize,
+                        flowName: this.queryParams.flowName || undefined,
+                        nodeName: this.queryParams.nodeName,
+                        flowCode: this.queryParams.flowCode,
+                    },
+                });
+
+                if (res && res.code === 200) {
+                    const data = res.rows || [];
+                    const total = res.total || 0;
+
+                    if (isRefresh || this.queryParams.pageNum === 1) {
+                        this.taskList = data;
+                    } else {
+                        this.taskList = [...this.taskList, ...data];
+                    }
+
+                    this.total = total;
+                    this.hasMore = this.taskList.length < total;
+
+                    console.log('✅ 获取任务抄送列表成功:', {
+                        当前页: this.queryParams.pageNum,
+                        页面大小: this.queryParams.pageSize,
+                        当前数据量: this.taskList.length,
+                        总数据量: total,
+                        是否有更多: this.hasMore,
+                    });
+                } else {
+                    if (isRefresh || this.queryParams.pageNum === 1) {
+                        this.taskList = [];
+                    }
+                    this.total = 0;
+                    this.hasMore = false;
+
+                    if (res.code !== 404) {
+                        uni.showToast({
+                            title: res?.msg || '获取数据失败',
+                            icon: 'none',
+                        });
+                    }
+                }
+            } catch (error) {
+                console.error('❌ 获取任务抄送列表失败:', error);
+                if (isRefresh || this.queryParams.pageNum === 1) {
+                    this.taskList = [];
+                }
+                this.total = 0;
+                this.hasMore = false;
+
+                uni.showToast({
+                    title: '获取数据失败',
+                    icon: 'none',
+                });
+            } finally {
+                this.loading = false;
+                this.refreshing = false;
+                this.loadingMore = false;
+            }
         },
 
+        // 搜索操作
         handleQuery() {
             this.queryParams.pageNum = 1;
-            this.hasMore = true;
-            this.refreshData();
+            this.getTaskCopyList();
         },
 
-        resetQuery() {
-            this.queryParams = {
-                pageNum: 1,
-                pageSize: 10,
-                nodeName: '',
-                flowName: '',
-                flowCode: '',
-            };
-            this.hasMore = true;
-            this.refreshData();
+        // 下拉刷新
+        onRefresh() {
+            console.log('🔄 下拉刷新');
+            this.getTaskCopyList(true);
         },
 
-        handleView(item) {
-            this.routerJump({
-                businessId: item.businessId,
-                taskId: item.id,
-                type: 'view',
-                formCustom: item.formCustom,
-                formPath: item.formPath,
-            });
+        // 加载更多
+        loadMore() {
+            if (this.hasMore && !this.loadingMore && !this.loading && !this.refreshing) {
+                console.log('📖 加载更多数据');
+                this.queryParams.pageNum += 1;
+                this.getTaskCopyList();
+            }
         },
 
-        getStatusText(status) {
-            const statusMap = {
-                draft: '草稿',
-                waiting: '待审批',
-                complete: '已完成',
-                cancel: '已取消',
-                back: '已退回',
-                suspend: '挂起',
-                terminate: '终止',
-            };
-            return statusMap[status] || '未知';
+        // 格式化时间
+        formatTime(timeStr) {
+            if (!timeStr) return '-';
+            try {
+                const date = new Date(timeStr);
+                if (isNaN(date.getTime())) return timeStr;
+
+                const year = date.getFullYear();
+                const month = String(date.getMonth() + 1).padStart(2, '0');
+                const day = String(date.getDate()).padStart(2, '0');
+                const hours = String(date.getHours()).padStart(2, '0');
+                const minutes = String(date.getMinutes()).padStart(2, '0');
+                const seconds = String(date.getSeconds()).padStart(2, '0');
+
+                return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+            } catch (error) {
+                console.error('时间格式化失败:', error);
+                return timeStr;
+            }
         },
 
-        getStatusStyle(status) {
-            return getStatusStyle(status);
-        },
+        // 查看按钮操作
+        handleView(row) {
+            console.log('查看任务抄送详情:', row);
 
-        formatTime(timeStr) {
-            return formatTime(timeStr);
+            // 动态跳转到formPath对应的路径,携带参数
+            if (row.formPath) {
+                // 确保路径以pages开头
+                let fullPath = row.formPath;
+
+                // 统一处理路径:去掉开头的/,然后添加pages前缀
+                if (!fullPath.startsWith('pages/')) {
+                    // 如果以/开头,先去掉/
+                    if (fullPath.startsWith('/')) {
+                        fullPath = fullPath.substring(1);
+                    }
+                    // 添加pages前缀
+                    fullPath = `pages/${fullPath}`;
+                }
+
+                // 构建URL参数,保持现有的参数结构
+                const params = new URLSearchParams({
+                    id: row.businessId || '',
+                    taskId: row.id || '',
+                    type: 'view',
+                    formCustom: row.formCustom || '',
+                });
+
+                const url = `/${fullPath}?${params.toString()}`;
+
+                // 添加调试信息
+                console.log('查看页面 - 原始formPath:', row.formPath);
+                console.log('查看页面 - 处理后的fullPath:', fullPath);
+                console.log('查看页面 - 最终跳转URL:', url);
+
+                // 使用navigateTo进行跳转
+                uni.navigateTo({
+                    url: url,
+                    fail: (err) => {
+                        console.error('查看页面跳转失败:', err);
+                        // 如果跳转失败,使用原有的通用详情页作为备选
+                        this.showWorkflowDetail({
+                            businessId: row.businessId,
+                            taskId: row.id,
+                            type: 'view',
+                            formCustom: row.formCustom,
+                            formPath: row.formPath,
+                        });
+                    },
+                });
+            } else {
+                // 如果没有formPath,使用原有的通用详情页作为备选
+                this.showWorkflowDetail({
+                    businessId: row.businessId,
+                    taskId: row.id,
+                    type: 'view',
+                    formCustom: row.formCustom,
+                    formPath: row.formPath,
+                });
+            }
         },
 
-        routerJump(params) {
-            routerJump(params);
+        // 显示工作流详情(通用页面)
+        showWorkflowDetail(routerJumpVo) {
+            // 跳转到通用的工作流详情页面
+            const params = new URLSearchParams({
+                businessId: routerJumpVo.businessId || '',
+                taskId: routerJumpVo.taskId || '',
+                type: routerJumpVo.type || 'view',
+                formCustom: routerJumpVo.formCustom || '',
+                formPath: routerJumpVo.formPath || '',
+            });
+
+            uni.navigateTo({
+                url: `/pages/workflow/common/detail?${params.toString()}`,
+                fail: (error) => {
+                    console.error('跳转到工作流详情页失败:', error);
+                    uni.showToast({
+                        title: '页面跳转失败',
+                        icon: 'none',
+                    });
+                },
+            });
         },
     },
 };
 </script>
 
-<style scoped>
-.task-copy-container {
-    background: #f5f5f5;
+<style lang="scss" scoped>
+.task-copy-list-container {
+    background-color: #f5f6fa;
     min-height: 100vh;
-    padding-bottom: 20px;
 }
 
-.header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    padding: 16px 20px;
-    background: #fff;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
-}
-
-.title {
-    font-size: 20px;
-    font-weight: bold;
-    color: #333;
-}
-
-.header-actions {
-    display: flex;
-    align-items: center;
-}
-
-.search-section {
-    background: #fff;
-    padding: 16px 20px;
-    border-bottom: 1px solid #eee;
-}
-
-.search-input {
-    margin-bottom: 12px;
+.search-container {
+    padding: 20rpx;
+    background-color: #fff;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
 }
 
-.search-actions {
-    display: flex;
-    gap: 12px;
+.content-wrapper {
+    height: calc(100vh - 176rpx); // 减去导航栏和搜索栏的高度
+    padding: 20rpx;
 }
 
-.content {
-    flex: 1;
+.empty-container {
+    padding: 100rpx 20rpx;
 }
 
-.loading {
+.task-list {
+    height: 100%;
     display: flex;
     flex-direction: column;
-    align-items: center;
-    padding: 40px;
-}
-
-.loading-text {
-    margin-top: 8px;
-    color: #999;
-    font-size: 14px;
+    gap: 20rpx;
 }
 
-.empty {
-    padding: 40px 20px;
+.task-card {
+    background-color: #fff;
+    border-radius: 16rpx;
+    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
+    overflow: hidden;
+    margin-bottom: 20rpx;
 }
 
-.empty-content {
+.card-header {
     display: flex;
-    flex-direction: column;
+    justify-content: space-between;
     align-items: center;
-    justify-content: center;
+    padding: 24rpx;
+    border-bottom: 1px solid #f0f0f0;
 }
 
-.empty-text {
-    font-size: 14px;
-    color: #999;
-    margin-top: 12px;
+.flow-name {
+    font-size: 32rpx;
+    font-weight: bold;
+    color: #303133;
+    flex: 1;
+    margin-right: 16rpx;
+    word-break: break-all;
 }
 
-.task-list {
-    padding: 16px 20px;
+.flow-status {
+    flex-shrink: 0;
 }
 
-.task-item {
-    background: #fff;
-    border-radius: 12px;
-    padding: 16px;
-    margin-bottom: 12px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
-    transition: box-shadow 0.2s;
-    /* 抄送任务特殊样式 */
-    border-left: 4px solid #ff9500;
+.card-content {
+    padding: 24rpx;
 }
 
-.task-item:active {
-    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
-}
+.info-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 16rpx;
 
-.task-header {
-    margin-bottom: 12px;
+    &:last-child {
+        margin-bottom: 0;
+    }
 }
 
-.task-title-row {
-    display: flex;
-    justify-content: space-between;
-    align-items: flex-start;
-    margin-bottom: 8px;
+.label {
+    font-size: 28rpx;
+    color: #606266;
+    min-width: 140rpx;
+    margin-right: 16rpx;
+    flex-shrink: 0;
 }
 
-.task-name {
-    font-size: 16px;
-    font-weight: 500;
-    color: #333;
+.value {
+    font-size: 28rpx;
+    color: #303133;
     flex: 1;
-    margin-right: 12px;
-}
-
-.task-status {
-    padding: 4px 8px;
-    border-radius: 12px;
-    font-size: 12px;
-    font-weight: 500;
-    white-space: nowrap;
+    word-break: break-all;
 }
 
-.task-info {
+.card-actions {
     display: flex;
-    justify-content: space-between;
-    margin-bottom: 6px;
+    justify-content: flex-end;
+    padding: 20rpx;
+    border-top: 1px solid #f0f0f0;
 }
 
-.task-code {
-    font-size: 13px;
-    color: #666;
+.action-btn {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 16rpx 20rpx;
+    border-radius: 12rpx;
+    background-color: rgba(60, 156, 255, 0);
+    min-width: 120rpx;
+    transition: all 0.3s ease;
+
+    &:active {
+        transform: scale(0.95);
+        opacity: 0.8;
+    }
 }
 
-.task-category {
-    font-size: 13px;
-    color: #666;
+.btn-text {
+    font-size: 24rpx;
+    margin-top: 8rpx;
+    color: #3c9cff;
+    font-weight: 500;
 }
 
-.task-version,
-.task-node-name {
-    font-size: 13px;
-    color: #666;
-    margin-bottom: 4px;
+.info-btn {
+    .btn-text {
+        color: #3c9cff;
+    }
 }
 
-.copy-info {
+.load-more {
     display: flex;
+    justify-content: center;
     align-items: center;
-    margin-bottom: 4px;
-}
-
-.copy-label {
-    font-size: 13px;
-    color: #ff9500;
-    font-weight: 500;
-    margin-left: 4px;
-}
-
-.task-time {
-    font-size: 12px;
-    color: #999;
+    padding: 30rpx 0;
+    margin-top: 20rpx;
 }
 
-.task-actions {
-    border-top: 1px solid #f0f0f0;
-    padding-top: 12px;
+.load-more-text {
+    font-size: 26rpx;
+    color: #909399;
+    margin-left: 16rpx;
 }
 
-.pagination {
-    padding: 16px 20px;
+// uview组件样式调整
+::v-deep .u-search {
+    background-color: #f5f6fa;
 }
 
-.load-end {
-    text-align: center;
-    padding: 16px;
+::v-deep .u-tag {
+    margin: 0;
 }
 
-.load-end text {
-    font-size: 14px;
-    color: #999;
+::v-deep .u-loading-icon {
+    width: 32rpx;
+    height: 32rpx;
 }
 </style>