243 lines
5.2 KiB
Vue
243 lines
5.2 KiB
Vue
<template>
|
|
<view class="verify-page">
|
|
<view class="tabs-wrapper">
|
|
<uv-tabs :list="tabs" :current="currentTab" @click="onTabClick"></uv-tabs>
|
|
</view>
|
|
|
|
<scroll-view class="list-scroll" scroll-y @scrolltolower="loadMore">
|
|
<view class="card" v-for="item in displayList" :key="item.id" @click="goDetail(item)">
|
|
<view class="card-header">
|
|
<view class="left">
|
|
<text class="badge">申请延期</text>
|
|
<text class="sub">所属项目 · {{ item.projectName || '—' }}</text>
|
|
</view>
|
|
<view class="right">
|
|
<uv-tags :text="statusText(item.status)" :type="statusType(item.status)" size="mini"></uv-tags>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="card-body">
|
|
<text class="remark" v-if="item.createRemark">{{ item.createRemark }}</text>
|
|
<view class="row">
|
|
<text class="label">截止时间:</text>
|
|
<text class="value">{{ item.expireTime || '—' }}</text>
|
|
</view>
|
|
<view class="row">
|
|
<text class="label">申请人:</text>
|
|
<text class="value">{{ item.createName || '—' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="card-footer">
|
|
<uv-button
|
|
v-if="item.status === '3'"
|
|
type="primary"
|
|
size="small"
|
|
text="去处理"
|
|
@click.stop="goHandle(item)"
|
|
/>
|
|
<uv-button
|
|
v-else
|
|
type="info"
|
|
size="small"
|
|
:text="statusText(item.status)"
|
|
:plain="true"
|
|
:disabled="true"
|
|
/>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="empty" v-if="!loading && displayList.length === 0">
|
|
<text>暂无数据</text>
|
|
</view>
|
|
<view class="loading" v-if="loading">
|
|
<text>加载中...</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import { getVerifyList } from '@/api';
|
|
|
|
const tabs = [
|
|
{ name: '待我处理', value: 'pending' },
|
|
{ name: '我已处理', value: 'done' }
|
|
];
|
|
const currentTab = ref(0);
|
|
|
|
const pageNum = ref(1);
|
|
const pageSize = ref(20);
|
|
const total = ref(0);
|
|
const rawList = ref([]);
|
|
const loading = ref(false);
|
|
const bstType = ref('UPDATE_TASK');
|
|
|
|
function statusText(s) {
|
|
if (s === '1') return '已通过';
|
|
if (s === '2') return '已驳回';
|
|
return '待处理';
|
|
}
|
|
function statusType(s) {
|
|
if (s === '1') return 'success';
|
|
if (s === '2') return 'error';
|
|
return 'warning';
|
|
}
|
|
|
|
const displayList = computed(() => {
|
|
if (currentTab.value === 0) {
|
|
return rawList.value.filter(i => String(i.status) === '3');
|
|
}
|
|
return rawList.value.filter(i => String(i.status) !== '3');
|
|
});
|
|
|
|
const safeParseExpire = (dataField) => {
|
|
if (!dataField) return '';
|
|
try {
|
|
if (typeof dataField === 'string') {
|
|
return JSON.parse(dataField)?.expireTime || '';
|
|
}
|
|
return dataField.expireTime || '';
|
|
} catch (e) {
|
|
return '';
|
|
}
|
|
};
|
|
|
|
const fetchList = async () => {
|
|
if (loading.value) return;
|
|
loading.value = true;
|
|
try {
|
|
const res = await getVerifyList({
|
|
pageNum: pageNum.value,
|
|
pageSize: pageSize.value,
|
|
orderByColumn: 'createTime',
|
|
isAsc: 'descending',
|
|
bstType: bstType.value
|
|
});
|
|
const rows = res?.rows || [];
|
|
total.value = res?.total || 0;
|
|
const mapped = rows.map(r => ({
|
|
...r,
|
|
expireTime: safeParseExpire(r.data)
|
|
}));
|
|
if (pageNum.value === 1) {
|
|
rawList.value = mapped;
|
|
} else {
|
|
rawList.value = rawList.value.concat(mapped);
|
|
}
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
const loadMore = () => {
|
|
if (rawList.value.length >= total.value) return;
|
|
pageNum.value += 1;
|
|
fetchList();
|
|
};
|
|
|
|
const onTabClick = (tab) => {
|
|
currentTab.value = tab.index;
|
|
};
|
|
|
|
const goHandle = (item) => {
|
|
// 预留处理入口
|
|
uni.showToast({ title: '去处理', icon: 'none' });
|
|
};
|
|
|
|
const goDetail = (item) => {
|
|
// 可跳转到任务详情或审批详情
|
|
};
|
|
|
|
onMounted(() => {
|
|
// 读取路由参数
|
|
const pages = getCurrentPages();
|
|
const currentPage = pages[pages.length - 1];
|
|
const options = currentPage?.options || {};
|
|
if (options.bstType) {
|
|
bstType.value = options.bstType;
|
|
}
|
|
fetchList();
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.verify-page {
|
|
|
|
width: 100%;
|
|
|
|
background: #f5f5f5;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.tabs-wrapper {
|
|
background: #fff;
|
|
}
|
|
.list-scroll {
|
|
flex: 1;
|
|
}
|
|
.card {
|
|
background: #fff;
|
|
margin: 12px 12px 0 12px;
|
|
border-radius: 12px;
|
|
padding: 12px;
|
|
}
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 6px;
|
|
}
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
.badge {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
.sub {
|
|
font-size: 12px;
|
|
color: #999;
|
|
}
|
|
.card-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
margin-top: 4px;
|
|
}
|
|
.remark {
|
|
font-size: 13px;
|
|
color: #333;
|
|
line-height: 1.6;
|
|
}
|
|
.row {
|
|
display: flex;
|
|
font-size: 12px;
|
|
color: #666;
|
|
}
|
|
.label {
|
|
width: 70px;
|
|
flex-shrink: 0;
|
|
}
|
|
.value {
|
|
color: #333;
|
|
}
|
|
.card-footer {
|
|
margin-top: 10px;
|
|
display: flex;
|
|
justify-content: flex-start;
|
|
}
|
|
.empty, .loading {
|
|
text-align: center;
|
|
color: #999;
|
|
font-size: 12px;
|
|
padding: 16px 0;
|
|
}
|
|
</style>
|
|
|
|
|