You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.1 KiB
239 lines
7.1 KiB
<!--合同列表页面-->
|
|
<template>
|
|
<view class="contract-list" style="background-color: #181A20; min-height: 100vh;">
|
|
<!-- 顶部统计 -->
|
|
<view class="stats-section" style="background-color: #181A20; padding: 20rpx;">
|
|
<view class="stats-card" style="background-color: #2A2A2A; border-radius: 12rpx; padding: 30rpx;">
|
|
<view class="stats-row">
|
|
<view class="stats-item">
|
|
<text class="stats-number" style="color: rgb(41, 211, 180); font-size: 36rpx; font-weight: bold;">{{ stats.total }}</text>
|
|
<text class="stats-label" style="color: #fff; font-size: 24rpx;">总合同</text>
|
|
</view>
|
|
<view class="stats-item">
|
|
<text class="stats-number" style="color: rgb(41, 211, 180); font-size: 36rpx; font-weight: bold;">{{ stats.pending }}</text>
|
|
<text class="stats-label" style="color: #fff; font-size: 24rpx;">待签署</text>
|
|
</view>
|
|
<view class="stats-item">
|
|
<text class="stats-number" style="color: rgb(41, 211, 180); font-size: 36rpx; font-weight: bold;">{{ stats.completed }}</text>
|
|
<text class="stats-label" style="color: #fff; font-size: 24rpx;">已完成</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 合同列表 -->
|
|
<view class="contract-section" style="padding: 20rpx;">
|
|
<view class="section-title" style="color: #fff; font-size: 32rpx; margin-bottom: 20rpx;">
|
|
我的合同
|
|
</view>
|
|
|
|
<view
|
|
v-for="contract in contractList"
|
|
:key="contract.id"
|
|
class="contract-item"
|
|
style="background-color: #2A2A2A; border-radius: 12rpx; margin-bottom: 20rpx; padding: 30rpx;"
|
|
@click="goToDetail(contract)"
|
|
>
|
|
<view class="contract-header">
|
|
<text class="contract-name" style="color: #fff; font-size: 30rpx; font-weight: bold;">
|
|
{{ contract.contract_name }}
|
|
</text>
|
|
<view
|
|
class="contract-status"
|
|
:style="{
|
|
backgroundColor: getStatusColor(contract.status),
|
|
color: '#fff',
|
|
padding: '8rpx 16rpx',
|
|
borderRadius: '20rpx',
|
|
fontSize: '22rpx'
|
|
}"
|
|
>
|
|
{{ getStatusText(contract.status) }}
|
|
</view>
|
|
</view>
|
|
|
|
<view class="contract-info" style="margin-top: 20rpx;">
|
|
<view class="info-row">
|
|
<text class="info-label" style="color: #999; font-size: 24rpx;">合同类型:</text>
|
|
<text class="info-value" style="color: #fff; font-size: 24rpx;">{{ contract.contract_type_text }}</text>
|
|
</view>
|
|
<view class="info-row" style="margin-top: 10rpx;">
|
|
<text class="info-label" style="color: #999; font-size: 24rpx;">分发时间:</text>
|
|
<text class="info-value" style="color: #fff; font-size: 24rpx;">{{ formatTime(contract.created_at) }}</text>
|
|
</view>
|
|
<view v-if="contract.sign_time" class="info-row" style="margin-top: 10rpx;">
|
|
<text class="info-label" style="color: #999; font-size: 24rpx;">签署时间:</text>
|
|
<text class="info-value" style="color: #fff; font-size: 24rpx;">{{ formatTime(contract.sign_time) }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="contract-actions" style="margin-top: 30rpx; text-align: right;">
|
|
<button
|
|
v-if="contract.status === 'pending'"
|
|
class="action-btn primary"
|
|
style="background-color: rgb(41, 211, 180); color: #fff; border: none; border-radius: 20rpx; padding: 12rpx 30rpx; font-size: 24rpx;"
|
|
>
|
|
立即签署
|
|
</button>
|
|
<button
|
|
v-else-if="contract.status === 'completed'"
|
|
class="action-btn secondary"
|
|
style="background-color: transparent; color: rgb(41, 211, 180); border: 2rpx solid rgb(41, 211, 180); border-radius: 20rpx; padding: 12rpx 30rpx; font-size: 24rpx;"
|
|
>
|
|
查看详情
|
|
</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 加载更多 -->
|
|
<view v-if="hasMore" class="load-more" style="text-align: center; padding: 40rpx; color: #999;">
|
|
<text @click="loadMore">加载更多</text>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view v-if="contractList.length === 0 && !loading" class="empty-state" style="text-align: center; padding: 100rpx; color: #999;">
|
|
<text>暂无合同</text>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import apiRoute from '@/api/apiRoute.js'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
hasMore: true,
|
|
page: 1,
|
|
stats: {
|
|
total: 0,
|
|
pending: 0,
|
|
completed: 0
|
|
},
|
|
contractList: []
|
|
}
|
|
},
|
|
|
|
onLoad() {
|
|
this.getContractList()
|
|
this.getStats()
|
|
},
|
|
|
|
onPullDownRefresh() {
|
|
this.page = 1
|
|
this.contractList = []
|
|
this.getContractList()
|
|
this.getStats()
|
|
},
|
|
|
|
onReachBottom() {
|
|
if (this.hasMore) {
|
|
this.loadMore()
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
async getContractList() {
|
|
if (this.loading) return
|
|
|
|
this.loading = true
|
|
try {
|
|
const res = await apiRoute.getMyContracts({
|
|
page: this.page,
|
|
limit: 10
|
|
})
|
|
|
|
if (this.page === 1) {
|
|
this.contractList = res.data.data
|
|
} else {
|
|
this.contractList.push(...res.data.data)
|
|
}
|
|
|
|
this.hasMore = res.data.data.length >= 10
|
|
uni.stopPullDownRefresh()
|
|
} catch (error) {
|
|
uni.showToast({
|
|
title: '获取数据失败',
|
|
icon: 'none'
|
|
})
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async getStats() {
|
|
try {
|
|
const res = await apiRoute.getContractStats()
|
|
this.stats = res.data
|
|
} catch (error) {
|
|
console.error('获取统计数据失败', error)
|
|
}
|
|
},
|
|
|
|
loadMore() {
|
|
this.page++
|
|
this.getContractList()
|
|
},
|
|
|
|
goToDetail(contract) {
|
|
uni.navigateTo({
|
|
url: `/pages-common/contract/detail?id=${contract.id}`
|
|
})
|
|
},
|
|
|
|
getStatusColor(status) {
|
|
const colorMap = {
|
|
'pending': '#f39c12',
|
|
'completed': 'rgb(41, 211, 180)',
|
|
'rejected': '#e74c3c'
|
|
}
|
|
return colorMap[status] || '#999'
|
|
},
|
|
|
|
getStatusText(status) {
|
|
const textMap = {
|
|
'pending': '待签署',
|
|
'completed': '已完成',
|
|
'rejected': '已拒绝'
|
|
}
|
|
return textMap[status] || '未知'
|
|
},
|
|
|
|
formatTime(timestamp) {
|
|
if (!timestamp) return ''
|
|
const date = new Date(timestamp * 1000)
|
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.stats-row {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
.stats-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.contract-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
}
|
|
|
|
.contract-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
</style>
|
|
|