2025-11-13 17:18:37 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view class="verify-page">
|
2025-11-14 10:01:12 +08:00
|
|
|
|
<!-- 筛选条件 -->
|
|
|
|
|
|
<view class="filter-wrapper">
|
|
|
|
|
|
<view class="filter-item">
|
|
|
|
|
|
<text class="filter-label">业务类型:</text>
|
|
|
|
|
|
<view class="filter-buttons">
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: bstType === '' }"
|
|
|
|
|
|
@click="onBstTypeChange('')"
|
|
|
|
|
|
>
|
|
|
|
|
|
全部
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: bstType === 'TASK' }"
|
|
|
|
|
|
@click="onBstTypeChange('TASK')"
|
|
|
|
|
|
>
|
|
|
|
|
|
任务
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: bstType === 'UPDATE_TASK' }"
|
|
|
|
|
|
@click="onBstTypeChange('UPDATE_TASK')"
|
|
|
|
|
|
>
|
|
|
|
|
|
延期审核
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="filter-item">
|
|
|
|
|
|
<text class="filter-label">审核状态:</text>
|
|
|
|
|
|
<view class="filter-buttons">
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: filterStatus === '' }"
|
|
|
|
|
|
@click="onStatusChange('')"
|
|
|
|
|
|
>
|
|
|
|
|
|
全部
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: filterStatus === '1' }"
|
|
|
|
|
|
@click="onStatusChange('1')"
|
|
|
|
|
|
>
|
|
|
|
|
|
已通过
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: filterStatus === '2' }"
|
|
|
|
|
|
@click="onStatusChange('2')"
|
|
|
|
|
|
>
|
|
|
|
|
|
已驳回
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn"
|
|
|
|
|
|
:class="{ active: filterStatus === '3' }"
|
|
|
|
|
|
@click="onStatusChange('3')"
|
|
|
|
|
|
>
|
|
|
|
|
|
待审核
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="filter-item">
|
|
|
|
|
|
<text class="filter-label">时间范围:</text>
|
|
|
|
|
|
<view class="filter-buttons">
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="filter-btn date-btn"
|
|
|
|
|
|
@click="openDatePicker"
|
|
|
|
|
|
>
|
|
|
|
|
|
<text>{{ dateRangeText }}</text>
|
|
|
|
|
|
<text class="date-icon">📅</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-if="dateRange.length > 0"
|
|
|
|
|
|
class="filter-btn clear-btn"
|
|
|
|
|
|
@click="clearDateRange"
|
|
|
|
|
|
>
|
|
|
|
|
|
清除
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2025-11-13 17:18:37 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
|
2025-11-14 10:24:25 +08:00
|
|
|
|
<scroll-view class="list-scroll" >
|
2025-11-13 17:18:37 +08:00
|
|
|
|
<view class="card" v-for="item in displayList" :key="item.id" @click="goDetail(item)">
|
|
|
|
|
|
<view class="card-header">
|
|
|
|
|
|
<view class="left">
|
2025-11-14 10:01:12 +08:00
|
|
|
|
<text class="badge">{{ getBstTypeText(item.bstType) }}</text>
|
2025-11-13 17:18:37 +08:00
|
|
|
|
<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">
|
2025-11-14 10:24:25 +08:00
|
|
|
|
<text class="remark" v-if="item.createRemark">备注:{{ item.createRemark }}</text>
|
2025-11-13 17:18:37 +08:00
|
|
|
|
<view class="row">
|
2025-11-14 10:01:12 +08:00
|
|
|
|
<text class="label">创建时间:</text>
|
|
|
|
|
|
<text class="value">{{ item.createTime || '—' }}</text>
|
2025-11-13 17:18:37 +08:00
|
|
|
|
</view>
|
2025-11-14 10:24:25 +08:00
|
|
|
|
<!-- <view class="row">-->
|
|
|
|
|
|
<!-- <text class="label">申请人:</text>-->
|
|
|
|
|
|
<!-- <text class="value">{{ item.createName || '—' }}</text>-->
|
|
|
|
|
|
<!-- </view>-->
|
2025-11-13 17:18:37 +08:00
|
|
|
|
</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>
|
|
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
<view class="empty" v-if="isEmpty && !loading">
|
2025-11-13 17:18:37 +08:00
|
|
|
|
<text>暂无数据</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="loading" v-if="loading">
|
|
|
|
|
|
<text>加载中...</text>
|
|
|
|
|
|
</view>
|
2025-11-14 10:01:12 +08:00
|
|
|
|
<view class="load-more" v-if="list.length > 0">
|
|
|
|
|
|
<text v-if="loading">加载中...</text>
|
|
|
|
|
|
<text v-else-if="noMore">没有更多数据了</text>
|
|
|
|
|
|
<text v-else>上拉加载更多</text>
|
|
|
|
|
|
</view>
|
2025-11-13 17:18:37 +08:00
|
|
|
|
</scroll-view>
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 日期范围选择弹窗 -->
|
|
|
|
|
|
<view v-if="showDatePicker" class="modal-mask" @click="closeDatePicker">
|
|
|
|
|
|
<view class="modal-content date-modal" @click.stop>
|
|
|
|
|
|
<view class="modal-title">选择日期范围</view>
|
|
|
|
|
|
<view class="date-picker-content">
|
|
|
|
|
|
<view class="date-section">
|
|
|
|
|
|
<text class="section-label">开始日期</text>
|
|
|
|
|
|
<picker
|
|
|
|
|
|
mode="date"
|
|
|
|
|
|
:value="startDate"
|
|
|
|
|
|
:start="'2020-01-01'"
|
|
|
|
|
|
:end="endDate || '2099-12-31'"
|
|
|
|
|
|
@change="handleStartDateChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view class="picker-display">
|
|
|
|
|
|
{{ startDate || '请选择开始日期' }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</picker>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="date-section">
|
|
|
|
|
|
<text class="section-label">结束日期</text>
|
|
|
|
|
|
<picker
|
|
|
|
|
|
mode="date"
|
|
|
|
|
|
:value="endDate"
|
|
|
|
|
|
:start="startDate || '2020-01-01'"
|
|
|
|
|
|
:end="'2099-12-31'"
|
|
|
|
|
|
@change="handleEndDateChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view class="picker-display">
|
|
|
|
|
|
{{ endDate || '请选择结束日期' }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</picker>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="modal-buttons">
|
|
|
|
|
|
<button class="modal-btn" @click="closeDatePicker">取消</button>
|
|
|
|
|
|
<button class="modal-btn primary" @click="confirmDateRange">确定</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2025-11-13 17:18:37 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-11-14 14:44:01 +08:00
|
|
|
|
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
2025-11-13 17:18:37 +08:00
|
|
|
|
import { getVerifyList } from '@/api';
|
2025-11-14 10:01:12 +08:00
|
|
|
|
import { usePagination } from '@/composables';
|
2025-11-14 10:24:25 +08:00
|
|
|
|
import { onReachBottom } from '@dcloudio/uni-app'
|
2025-11-14 10:01:12 +08:00
|
|
|
|
const bstType = ref('');
|
|
|
|
|
|
const filterStatus = ref('');
|
|
|
|
|
|
const dateRange = ref([]); // [startDate, endDate] 格式: yyyy-MM-dd
|
|
|
|
|
|
const showDatePicker = ref(false);
|
|
|
|
|
|
const startDate = ref('');
|
|
|
|
|
|
const endDate = ref('');
|
|
|
|
|
|
|
|
|
|
|
|
// 使用分页组合式函数
|
|
|
|
|
|
const {
|
|
|
|
|
|
list,
|
|
|
|
|
|
loading,
|
|
|
|
|
|
noMore,
|
|
|
|
|
|
isEmpty,
|
|
|
|
|
|
getList,
|
|
|
|
|
|
loadMore,
|
|
|
|
|
|
updateParams,
|
|
|
|
|
|
queryParams
|
|
|
|
|
|
} = usePagination({
|
|
|
|
|
|
fetchData: async (params) => {
|
|
|
|
|
|
// 构建请求参数
|
|
|
|
|
|
const requestParams = {
|
|
|
|
|
|
...params,
|
|
|
|
|
|
orderByColumn: 'createTime',
|
|
|
|
|
|
isAsc: 'descending'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 添加业务类型筛选
|
|
|
|
|
|
if (bstType.value) {
|
|
|
|
|
|
requestParams.bstType = bstType.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加审核状态筛选
|
|
|
|
|
|
if (filterStatus.value) {
|
|
|
|
|
|
requestParams.status = filterStatus.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加时间范围筛选
|
|
|
|
|
|
if (dateRange.value.length === 2) {
|
|
|
|
|
|
requestParams.createTimeList = dateRange.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = await getVerifyList(requestParams);
|
|
|
|
|
|
// 处理数据,添加 expireTime 字段
|
|
|
|
|
|
if (res?.rows) {
|
|
|
|
|
|
res.rows = res.rows.map(r => ({
|
|
|
|
|
|
...r,
|
|
|
|
|
|
expireTime: safeParseExpire(r.data)
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
return res;
|
|
|
|
|
|
},
|
|
|
|
|
|
mode: 'loadMore',
|
|
|
|
|
|
pageSize: 20,
|
|
|
|
|
|
defaultParams: {}
|
|
|
|
|
|
});
|
2025-11-13 17:18:37 +08:00
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
// 日期范围显示文本
|
|
|
|
|
|
const dateRangeText = computed(() => {
|
|
|
|
|
|
if (dateRange.value.length === 2) {
|
|
|
|
|
|
return `${dateRange.value[0]} 至 ${dateRange.value[1]}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
return '选择日期范围';
|
|
|
|
|
|
});
|
2025-11-13 17:18:37 +08:00
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
// 获取业务类型文本
|
|
|
|
|
|
const getBstTypeText = (type) => {
|
|
|
|
|
|
if (type === 'TASK') return '任务审核';
|
|
|
|
|
|
if (type === 'UPDATE_TASK') return '延期审核';
|
|
|
|
|
|
return '审核';
|
|
|
|
|
|
};
|
2025-11-13 17:18:37 +08:00
|
|
|
|
|
|
|
|
|
|
function statusText(s) {
|
|
|
|
|
|
if (s === '1') return '已通过';
|
|
|
|
|
|
if (s === '2') return '已驳回';
|
|
|
|
|
|
return '待处理';
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
function statusType(s) {
|
|
|
|
|
|
if (s === '1') return 'success';
|
|
|
|
|
|
if (s === '2') return 'error';
|
|
|
|
|
|
return 'warning';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const safeParseExpire = (dataField) => {
|
|
|
|
|
|
if (!dataField) return '';
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (typeof dataField === 'string') {
|
|
|
|
|
|
return JSON.parse(dataField)?.expireTime || '';
|
|
|
|
|
|
}
|
|
|
|
|
|
return dataField.expireTime || '';
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
// 显示列表(直接使用分页的 list)
|
|
|
|
|
|
const displayList = computed(() => list.value);
|
|
|
|
|
|
|
|
|
|
|
|
// 打开日期选择器
|
|
|
|
|
|
const openDatePicker = () => {
|
|
|
|
|
|
if (dateRange.value.length === 2) {
|
|
|
|
|
|
startDate.value = dateRange.value[0];
|
|
|
|
|
|
endDate.value = dateRange.value[1];
|
|
|
|
|
|
} else {
|
|
|
|
|
|
startDate.value = '';
|
|
|
|
|
|
endDate.value = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
showDatePicker.value = true;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭日期选择器
|
|
|
|
|
|
const closeDatePicker = () => {
|
|
|
|
|
|
showDatePicker.value = false;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 开始日期改变
|
|
|
|
|
|
const handleStartDateChange = (e) => {
|
|
|
|
|
|
startDate.value = e.detail.value;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 结束日期改变
|
|
|
|
|
|
const handleEndDateChange = (e) => {
|
|
|
|
|
|
endDate.value = e.detail.value;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 确认日期范围
|
|
|
|
|
|
const confirmDateRange = () => {
|
|
|
|
|
|
if (startDate.value && endDate.value) {
|
|
|
|
|
|
// 确保开始日期 <= 结束日期
|
|
|
|
|
|
if (startDate.value > endDate.value) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '开始日期不能大于结束日期',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
2025-11-13 17:18:37 +08:00
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
dateRange.value = [startDate.value, endDate.value];
|
|
|
|
|
|
closeDatePicker();
|
|
|
|
|
|
refreshList();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '请选择完整的日期范围',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
});
|
2025-11-13 17:18:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
// 清除日期范围
|
|
|
|
|
|
const clearDateRange = () => {
|
|
|
|
|
|
dateRange.value = [];
|
|
|
|
|
|
startDate.value = '';
|
|
|
|
|
|
endDate.value = '';
|
|
|
|
|
|
refreshList();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 业务类型改变
|
|
|
|
|
|
const onBstTypeChange = (value) => {
|
|
|
|
|
|
bstType.value = value;
|
|
|
|
|
|
refreshList();
|
2025-11-13 17:18:37 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
// 审核状态改变
|
|
|
|
|
|
const onStatusChange = (value) => {
|
|
|
|
|
|
filterStatus.value = value;
|
|
|
|
|
|
refreshList();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新列表
|
|
|
|
|
|
const refreshList = () => {
|
|
|
|
|
|
updateParams({});
|
2025-11-13 17:18:37 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const goHandle = (item) => {
|
2025-11-14 14:02:47 +08:00
|
|
|
|
// 跳转到审核详情页进行处理
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/verify/detail/index?id=${item.id}`
|
|
|
|
|
|
})
|
2025-11-13 17:18:37 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const goDetail = (item) => {
|
2025-11-14 14:02:47 +08:00
|
|
|
|
// 跳转到审核详情页
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/verify/detail/index?id=${item.id}`
|
|
|
|
|
|
})
|
2025-11-13 17:18:37 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
// 读取路由参数
|
|
|
|
|
|
const pages = getCurrentPages();
|
|
|
|
|
|
const currentPage = pages[pages.length - 1];
|
|
|
|
|
|
const options = currentPage?.options || {};
|
|
|
|
|
|
if (options.bstType) {
|
|
|
|
|
|
bstType.value = options.bstType;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
if (options.status) {
|
|
|
|
|
|
filterStatus.value = options.status;
|
|
|
|
|
|
}
|
|
|
|
|
|
getList(true);
|
2025-11-14 14:44:01 +08:00
|
|
|
|
|
|
|
|
|
|
// 监听审核列表刷新事件
|
|
|
|
|
|
uni.$on('verifyListRefresh', refreshList);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
// 取消监听审核列表刷新事件
|
|
|
|
|
|
uni.$off('verifyListRefresh', refreshList);
|
2025-11-13 17:18:37 +08:00
|
|
|
|
});
|
2025-11-14 10:24:25 +08:00
|
|
|
|
|
|
|
|
|
|
onReachBottom(()=>{
|
|
|
|
|
|
loadMore();
|
|
|
|
|
|
});
|
2025-11-13 17:18:37 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.verify-page {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
|
|
|
|
|
.filter-wrapper {
|
2025-11-13 17:18:37 +08:00
|
|
|
|
background: #fff;
|
2025-11-14 10:01:12 +08:00
|
|
|
|
padding: 12px;
|
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.filter-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
&:last-child {
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.filter-label {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
width: 70px;
|
|
|
|
|
|
flex-shrink: 0;
|
2025-11-13 17:18:37 +08:00
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
|
|
|
|
|
.filter-buttons {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.filter-btn {
|
|
|
|
|
|
padding: 6px 12px;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
|
border: 1px solid #e0e0e0;
|
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
&.active {
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
background: #2979ff;
|
|
|
|
|
|
border-color: #2979ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
&.date-btn {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
&.clear-btn {
|
|
|
|
|
|
background: #ffebee;
|
|
|
|
|
|
color: #f44336;
|
|
|
|
|
|
border-color: #f44336;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.date-icon {
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.list-scroll {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.card {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
margin: 12px 12px 0 12px;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.card-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 6px;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.left {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.badge {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.sub {
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.card-body {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.remark {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.label {
|
|
|
|
|
|
width: 70px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.value {
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
2025-11-13 17:18:37 +08:00
|
|
|
|
.card-footer {
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
}
|
2025-11-14 10:01:12 +08:00
|
|
|
|
|
|
|
|
|
|
.empty, .loading, .load-more {
|
2025-11-13 17:18:37 +08:00
|
|
|
|
text-align: center;
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
padding: 16px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
// 日期选择弹窗样式
|
|
|
|
|
|
.modal-mask {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
background: rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
z-index: 999;
|
|
|
|
|
|
}
|
2025-11-13 17:18:37 +08:00
|
|
|
|
|
2025-11-14 10:01:12 +08:00
|
|
|
|
.modal-content {
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
width: 90%;
|
|
|
|
|
|
max-width: 500px;
|
|
|
|
|
|
max-height: 80vh;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-title {
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.date-picker-content {
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.date-section {
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
&:last-child {
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-label {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.picker-display {
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
border: 1px solid #e0e0e0;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-buttons {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
border-top: 1px solid #f0f0f0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-btn {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-right: 1px solid #f0f0f0;
|
|
|
|
|
|
&:last-child {
|
|
|
|
|
|
border-right: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
&.primary {
|
|
|
|
|
|
color: #2979ff;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|