first commit
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
<template>
|
||||
<view class="main-data-page">
|
||||
<!-- 使用子头部组件 -->
|
||||
<sub-header
|
||||
title="业务审批"
|
||||
@goBack="goBack"
|
||||
@showMoreOptions="showMoreOptions"
|
||||
/>
|
||||
<view class="main-container">
|
||||
<!-- 审批状态tabs -->
|
||||
<view class="approval-tabs">
|
||||
<view
|
||||
v-for="tab in approvalTabs"
|
||||
:key="tab.key"
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === tab.key }"
|
||||
@click="switchTab(tab.key)"
|
||||
>
|
||||
{{ tab.label }}
|
||||
<view v-if="(tab.key === 'pending' || tab.key === 'all') && tab.count > 0" class="tab-badge">{{ tab.count }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审批列表 -->
|
||||
<view class="approval-list">
|
||||
<view
|
||||
v-for="item in filteredApprovalList"
|
||||
:key="item.id"
|
||||
class="approval-item"
|
||||
@click="viewDetail(item)"
|
||||
>
|
||||
<view class="item-header">
|
||||
<view class="item-title">{{ item.title }}</view>
|
||||
<view class="item-status" :class="item.status">
|
||||
{{ getStatusText(item.status) }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-content">
|
||||
<view class="item-info">
|
||||
<text class="info-label">申请人:</text>
|
||||
<text class="info-value">{{ item.applicant }}</text>
|
||||
</view>
|
||||
<view class="item-info">
|
||||
<text class="info-label">申请时间:</text>
|
||||
<text class="info-value">{{ item.applyTime }}</text>
|
||||
</view>
|
||||
<view class="item-info">
|
||||
<text class="info-label">业务类型:</text>
|
||||
<text class="info-value">{{ item.businessType }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-footer">
|
||||
<view class="priority" :class="item.priority">
|
||||
{{ getPriorityText(item.priority) }}
|
||||
</view>
|
||||
<view class="item-amount" v-if="item.amount">
|
||||
金额:{{ item.amount }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="filteredApprovalList.length === 0" class="empty-state">
|
||||
<view class="empty-icon">📋</view>
|
||||
<view class="empty-text">暂无{{ getCurrentTabLabel() }}审批</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import SubHeader from "../components/subHeader.vue";
|
||||
|
||||
// 响应式数据
|
||||
const activeTab = ref('all'); // 当前激活的tab
|
||||
|
||||
// 审批状态tabs配置
|
||||
const approvalTabs = ref([
|
||||
{ key: 'all', label: '全部', count: 0 },
|
||||
{ key: 'pending', label: '待审批', count: 0 },
|
||||
{ key: 'approved', label: '已通过', count: 0 },
|
||||
{ key: 'rejected', label: '已拒绝', count: 0 }
|
||||
]);
|
||||
|
||||
// 审批列表数据
|
||||
const approvalList = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: '港口作业申请',
|
||||
status: 'pending',
|
||||
applicant: '张三',
|
||||
applyTime: '2024-01-15 09:30',
|
||||
businessType: '港口作业',
|
||||
priority: 'high',
|
||||
amount: '¥50,000'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '设备维修申请',
|
||||
status: 'approved',
|
||||
applicant: '李四',
|
||||
applyTime: '2024-01-14 14:20',
|
||||
businessType: '设备维护',
|
||||
priority: 'medium',
|
||||
amount: '¥15,000'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '人员调动申请',
|
||||
status: 'rejected',
|
||||
applicant: '王五',
|
||||
applyTime: '2024-01-13 16:45',
|
||||
businessType: '人事管理',
|
||||
priority: 'low',
|
||||
amount: null
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '采购申请',
|
||||
status: 'pending',
|
||||
applicant: '赵六',
|
||||
applyTime: '2024-01-12 11:15',
|
||||
businessType: '采购管理',
|
||||
priority: 'high',
|
||||
amount: '¥80,000'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '安全培训申请',
|
||||
status: 'approved',
|
||||
applicant: '钱七',
|
||||
applyTime: '2024-01-11 08:30',
|
||||
businessType: '培训管理',
|
||||
priority: 'medium',
|
||||
amount: '¥5,000'
|
||||
}
|
||||
]);
|
||||
|
||||
// 计算属性:根据当前tab过滤列表
|
||||
const filteredApprovalList = computed(() => {
|
||||
let filteredList = [];
|
||||
|
||||
if (activeTab.value === 'all') {
|
||||
filteredList = approvalList.value;
|
||||
} else {
|
||||
filteredList = approvalList.value.filter(item => item.status === activeTab.value);
|
||||
}
|
||||
|
||||
// 按照状态排序:待审批、已拒绝、已通过
|
||||
const statusOrder = ['pending', 'rejected', 'approved'];
|
||||
return filteredList.sort((a, b) => {
|
||||
const aIndex = statusOrder.indexOf(a.status);
|
||||
const bIndex = statusOrder.indexOf(b.status);
|
||||
return aIndex - bIndex;
|
||||
});
|
||||
});
|
||||
|
||||
// 更新tabs计数
|
||||
const updateTabCounts = () => {
|
||||
approvalTabs.value.forEach(tab => {
|
||||
if (tab.key === 'all') {
|
||||
tab.count = approvalList.value.length;
|
||||
} else {
|
||||
tab.count = approvalList.value.filter(item => item.status === tab.key).length;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 切换tab
|
||||
const switchTab = (tabKey) => {
|
||||
activeTab.value = tabKey;
|
||||
};
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
pending: '待审批',
|
||||
approved: '已通过',
|
||||
rejected: '已拒绝'
|
||||
};
|
||||
return statusMap[status] || status;
|
||||
};
|
||||
|
||||
// 获取优先级文本
|
||||
const getPriorityText = (priority) => {
|
||||
const priorityMap = {
|
||||
high: '高',
|
||||
medium: '中',
|
||||
low: '低'
|
||||
};
|
||||
return priorityMap[priority] || priority;
|
||||
};
|
||||
|
||||
// 获取当前tab标签
|
||||
const getCurrentTabLabel = () => {
|
||||
const currentTab = approvalTabs.value.find(tab => tab.key === activeTab.value);
|
||||
return currentTab ? currentTab.label : '';
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const viewDetail = (item) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/tasks/approvalDetail?id=${item.id}&title=${encodeURIComponent(item.title)}&status=${item.status}&applicant=${encodeURIComponent(item.applicant)}&applyTime=${encodeURIComponent(item.applyTime)}&businessType=${encodeURIComponent(item.businessType)}&priority=${item.priority}&amount=${item.amount ? encodeURIComponent(item.amount) : ''}`
|
||||
});
|
||||
};
|
||||
|
||||
// 头部相关方法
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
const showMoreOptions = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ["刷新", "返回首页"],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex) {
|
||||
case 0:
|
||||
// 刷新数据
|
||||
updateTabCounts();
|
||||
uni.showToast({ title: "数据已刷新", icon: "success" });
|
||||
break;
|
||||
case 1:
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index",
|
||||
});
|
||||
uni.showToast({ title: "已返回工作台", icon: "success" });
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 页面加载时处理URL参数
|
||||
onMounted(() => {
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const options = currentPage.options;
|
||||
|
||||
// 如果URL中有activeTab参数,则设置为对应的tab
|
||||
if (options.activeTab) {
|
||||
activeTab.value = options.activeTab;
|
||||
}
|
||||
|
||||
// 初始化计数
|
||||
updateTabCounts();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
// 变量定义
|
||||
$border-radius: 16rpx;
|
||||
$border-radius-small: 12rpx;
|
||||
$border-radius-badge: 20rpx;
|
||||
$spacing-small: 12rpx;
|
||||
$spacing-medium: 20rpx;
|
||||
$spacing-large: 30rpx;
|
||||
$transition: all 0.3s ease;
|
||||
|
||||
.main-data-page {
|
||||
background: var(--background);
|
||||
min-height: 100vh;
|
||||
padding-top: calc(var(--status-bar-height) + 88rpx);
|
||||
padding-bottom: 40rpx;
|
||||
|
||||
.main-container {
|
||||
padding: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 审批状态tabs
|
||||
.approval-tabs {
|
||||
display: flex;
|
||||
background: var(--surface);
|
||||
border-radius: $border-radius;
|
||||
margin-bottom: $spacing-large;
|
||||
box-shadow: var(--shadow-md);
|
||||
border: 1rpx solid var(--border-light);
|
||||
overflow: hidden;
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24rpx 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
background: var(--surface);
|
||||
transition: $transition;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
background: var(--primary-color);
|
||||
color: var(--white);
|
||||
font-weight: 600;
|
||||
|
||||
.tab-badge {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.tab-badge {
|
||||
background: var(--error);
|
||||
color: var(--white);
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: $border-radius-badge;
|
||||
margin-left: 8rpx;
|
||||
min-width: 32rpx;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 审批列表
|
||||
.approval-list {
|
||||
.approval-item {
|
||||
background: var(--surface);
|
||||
border-radius: $border-radius;
|
||||
margin-bottom: $spacing-medium;
|
||||
padding: $spacing-large;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1rpx solid var(--border-light);
|
||||
transition: $transition;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: var(--shadow-md);
|
||||
background: var(--surface-hover);
|
||||
}
|
||||
|
||||
.item-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: $spacing-medium;
|
||||
|
||||
.item-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--title-color);
|
||||
flex: 1;
|
||||
margin-right: $spacing-medium;
|
||||
}
|
||||
|
||||
.item-status {
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: $border-radius-badge;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
|
||||
&.pending {
|
||||
background: var(--warning-light);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
&.approved {
|
||||
background: var(--success-light);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
&.rejected {
|
||||
background: var(--error-light);
|
||||
color: var(--error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-content {
|
||||
margin-bottom: $spacing-medium;
|
||||
|
||||
.item-info {
|
||||
display: flex;
|
||||
margin-bottom: $spacing-small;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-muted);
|
||||
width: 140rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.priority {
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: $border-radius-small;
|
||||
font-size: 22rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.high {
|
||||
background: var(--error-light);
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
&.medium {
|
||||
background: var(--warning-light);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
&.low {
|
||||
background: var(--success-light);
|
||||
color: var(--success);
|
||||
}
|
||||
}
|
||||
|
||||
.item-amount {
|
||||
font-size: 26rpx;
|
||||
color: var(--orange);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 120rpx 60rpx;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 120rpx;
|
||||
margin-bottom: $spacing-large;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
}
|
||||
|
||||
// 支持安全区域的设备
|
||||
@supports (padding: max(0px)) {
|
||||
.main-data-page {
|
||||
padding-top: calc(
|
||||
var(--status-bar-height) + 88rpx + env(safe-area-inset-top)
|
||||
);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,484 @@
|
||||
<template>
|
||||
<view class="main-data-page">
|
||||
<!-- 使用子头部组件 -->
|
||||
<sub-header
|
||||
title="审批详情"
|
||||
@goBack="goBack"
|
||||
@showMoreOptions="showMoreOptions"
|
||||
/>
|
||||
<view class="main-container">
|
||||
<!-- 审批详情卡片 -->
|
||||
<view class="detail-card">
|
||||
<!-- 标题和状态 -->
|
||||
<view class="detail-header">
|
||||
<view class="detail-title">{{ approvalDetail.title }}</view>
|
||||
<view class="detail-status" :class="approvalDetail.status">
|
||||
{{ getStatusText(approvalDetail.status) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<view class="detail-section">
|
||||
<view class="section-title">基本信息</view>
|
||||
<view class="info-list">
|
||||
<view class="info-item">
|
||||
<text class="info-label">申请人:</text>
|
||||
<text class="info-value">{{ approvalDetail.applicant }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">申请时间:</text>
|
||||
<text class="info-value">{{ approvalDetail.applyTime }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">业务类型:</text>
|
||||
<text class="info-value">{{ approvalDetail.businessType }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">优先级:</text>
|
||||
<view class="priority-tag" :class="approvalDetail.priority">
|
||||
{{ getPriorityText(approvalDetail.priority) }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-item" v-if="approvalDetail.amount">
|
||||
<text class="info-label">申请金额:</text>
|
||||
<text class="info-value amount">{{ approvalDetail.amount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审批信息 -->
|
||||
<view class="detail-section">
|
||||
<view class="section-title">审批信息</view>
|
||||
<view class="info-list">
|
||||
<view class="info-item">
|
||||
<text class="info-label">审批人:</text>
|
||||
<text class="info-value">{{ approvalDetail.approver || '待分配' }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">审批时间:</text>
|
||||
<text class="info-value">{{ approvalDetail.approveTime || '待审批' }}</text>
|
||||
</view>
|
||||
<view class="info-item" v-if="approvalDetail.remark">
|
||||
<text class="info-label">审批意见:</text>
|
||||
<text class="info-value">{{ approvalDetail.remark }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-buttons" v-if="approvalDetail.status === 'pending'">
|
||||
<button class="action-btn reject-btn" @click="handleApproval('rejected')">
|
||||
拒绝
|
||||
</button>
|
||||
<button class="action-btn approve-btn" @click="handleApproval('approved')">
|
||||
通过
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 理由输入弹窗 -->
|
||||
<view v-if="showReasonDialog" class="reason-mask" @click.self="closeReasonDialog">
|
||||
<view class="reason-modal">
|
||||
<view class="reason-title">{{ actionType === 'approved' ? '通过理由' : '拒绝理由' }}</view>
|
||||
<textarea class="reason-textarea" v-model="reasonText" placeholder="请输入审批理由(必填)" auto-height :maxlength="200" />
|
||||
<view class="reason-tip">最多200字,需填写后才能提交</view>
|
||||
<view class="reason-actions">
|
||||
<button class="reason-btn cancel" @click="closeReasonDialog">取消</button>
|
||||
<button class="reason-btn confirm" @click="submitApproval">提交</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import SubHeader from "../components/subHeader.vue";
|
||||
|
||||
// 审批详情数据
|
||||
const approvalDetail = ref({
|
||||
id: '',
|
||||
title: '',
|
||||
status: '',
|
||||
applicant: '',
|
||||
applyTime: '',
|
||||
businessType: '',
|
||||
priority: '',
|
||||
amount: '',
|
||||
approver: '',
|
||||
approveTime: '',
|
||||
remark: ''
|
||||
});
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
pending: '待审批',
|
||||
approved: '已通过',
|
||||
rejected: '已拒绝'
|
||||
};
|
||||
return statusMap[status] || status;
|
||||
};
|
||||
|
||||
// 获取优先级文本
|
||||
const getPriorityText = (priority) => {
|
||||
const priorityMap = {
|
||||
high: '高',
|
||||
medium: '中',
|
||||
low: '低'
|
||||
};
|
||||
return priorityMap[priority] || priority;
|
||||
};
|
||||
|
||||
// 理由弹框状态
|
||||
const showReasonDialog = ref(false);
|
||||
const actionType = ref('approved'); // 'approved' | 'rejected'
|
||||
const reasonText = ref('');
|
||||
|
||||
// 处理审批操作(先弹出理由框)
|
||||
const handleApproval = (action) => {
|
||||
actionType.value = action;
|
||||
reasonText.value = '';
|
||||
showReasonDialog.value = true;
|
||||
};
|
||||
|
||||
const closeReasonDialog = () => {
|
||||
showReasonDialog.value = false;
|
||||
};
|
||||
|
||||
const submitApproval = () => {
|
||||
const text = reasonText.value.trim();
|
||||
if (!text) {
|
||||
uni.showToast({ title: '请先填写理由', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
const action = actionType.value;
|
||||
const actionText = action === 'approved' ? '通过' : '拒绝';
|
||||
|
||||
// 这里可以调用API提交备注与状态
|
||||
approvalDetail.value.status = action;
|
||||
approvalDetail.value.approveTime = new Date().toLocaleString('zh-CN');
|
||||
approvalDetail.value.approver = '当前用户'; // 实际应为当前登录用户
|
||||
approvalDetail.value.remark = text;
|
||||
|
||||
showReasonDialog.value = false;
|
||||
uni.showToast({ title: `已${actionText}`, icon: 'success' });
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1200);
|
||||
};
|
||||
|
||||
// 头部相关方法
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
const showMoreOptions = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ["刷新", "返回首页"],
|
||||
success: (res) => {
|
||||
switch (res.tapIndex) {
|
||||
case 0:
|
||||
// 刷新数据
|
||||
uni.showToast({ title: "数据已刷新", icon: "success" });
|
||||
break;
|
||||
case 1:
|
||||
uni.reLaunch({
|
||||
url: "/pages/index/index",
|
||||
});
|
||||
uni.showToast({ title: "已返回工作台", icon: "success" });
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 页面加载时获取参数
|
||||
onMounted(() => {
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const options = currentPage.options;
|
||||
|
||||
// 从URL参数中获取数据
|
||||
approvalDetail.value = {
|
||||
id: options.id || '',
|
||||
title: decodeURIComponent(options.title || ''),
|
||||
status: options.status || '',
|
||||
applicant: decodeURIComponent(options.applicant || ''),
|
||||
applyTime: decodeURIComponent(options.applyTime || ''),
|
||||
businessType: decodeURIComponent(options.businessType || ''),
|
||||
priority: options.priority || '',
|
||||
amount: options.amount ? decodeURIComponent(options.amount) : '',
|
||||
approver: '待分配',
|
||||
approveTime: '',
|
||||
remark: ''
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../static/css/style.scss";
|
||||
|
||||
// 变量定义
|
||||
$border-radius: 16rpx;
|
||||
$border-radius-small: 12rpx;
|
||||
$spacing-small: 12rpx;
|
||||
$spacing-medium: 20rpx;
|
||||
$spacing-large: 30rpx;
|
||||
$transition: all 0.3s ease;
|
||||
|
||||
.main-data-page {
|
||||
background: var(--background);
|
||||
min-height: 100vh;
|
||||
padding-top: calc(var(--status-bar-height) + 88rpx);
|
||||
padding-bottom: 40rpx;
|
||||
|
||||
.main-container {
|
||||
padding: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 详情卡片
|
||||
.detail-card {
|
||||
background: var(--surface);
|
||||
border-radius: $border-radius;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1rpx solid var(--border-light);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 详情头部
|
||||
.detail-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding: $spacing-large;
|
||||
border-bottom: 1rpx solid var(--border-light);
|
||||
|
||||
.detail-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--title-color);
|
||||
flex: 1;
|
||||
margin-right: $spacing-medium;
|
||||
}
|
||||
|
||||
.detail-status {
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
|
||||
&.pending {
|
||||
background: var(--warning-light);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
&.approved {
|
||||
background: var(--success-light);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
&.rejected {
|
||||
background: var(--error-light);
|
||||
color: var(--error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 详情区域
|
||||
.detail-section {
|
||||
padding: $spacing-large;
|
||||
border-bottom: 1rpx solid var(--border-light);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: var(--title-color);
|
||||
margin-bottom: $spacing-medium;
|
||||
}
|
||||
}
|
||||
|
||||
// 信息列表
|
||||
.info-list {
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $spacing-small;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-muted);
|
||||
width: 140rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
|
||||
&.amount {
|
||||
color: var(--orange);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.priority-tag {
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: $border-radius-small;
|
||||
font-size: 22rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.high {
|
||||
background: var(--error-light);
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
&.medium {
|
||||
background: var(--warning-light);
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
&.low {
|
||||
background: var(--success-light);
|
||||
color: var(--success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: $spacing-medium;
|
||||
padding: $spacing-large;
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border-radius: $border-radius;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
transition: $transition;
|
||||
|
||||
&.reject-btn {
|
||||
background: var(--error-light);
|
||||
color: var(--error);
|
||||
border: 1rpx solid var(--error);
|
||||
|
||||
&:active {
|
||||
background: var(--error);
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
|
||||
&.approve-btn {
|
||||
background: var(--success-light);
|
||||
color: var(--success);
|
||||
border: 1rpx solid var(--success);
|
||||
|
||||
&:active {
|
||||
background: var(--success);
|
||||
color: var(--white);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 支持安全区域的设备
|
||||
@supports (padding: max(0px)) {
|
||||
.main-data-page {
|
||||
padding-top: calc(
|
||||
var(--status-bar-height) + 88rpx + env(safe-area-inset-top)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 理由弹窗样式
|
||||
.reason-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.reason-modal {
|
||||
width: 86%;
|
||||
background: var(--surface);
|
||||
border-radius: $border-radius;
|
||||
box-shadow: var(--shadow-lg);
|
||||
border: 1rpx solid var(--border-light);
|
||||
padding: $spacing-large;
|
||||
}
|
||||
|
||||
.reason-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: var(--title-color);
|
||||
margin-bottom: $spacing-medium;
|
||||
}
|
||||
|
||||
.reason-textarea {
|
||||
width: 100%;
|
||||
min-height: 160rpx;
|
||||
background: var(--surface-hover);
|
||||
border: 1rpx solid var(--border-light);
|
||||
border-radius: $border-radius-small;
|
||||
padding: $spacing-medium;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-color);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.reason-tip {
|
||||
margin-top: $spacing-small;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.reason-actions {
|
||||
margin-top: $spacing-large;
|
||||
display: flex;
|
||||
gap: $spacing-medium;
|
||||
}
|
||||
|
||||
.reason-btn {
|
||||
flex: 1;
|
||||
height: 76rpx;
|
||||
border-radius: $border-radius;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.reason-btn.cancel {
|
||||
background: var(--button-secondary);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.reason-btn.confirm {
|
||||
background: var(--primary-color);
|
||||
color: var(--white);
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user