<template>
|
<view class="content">
|
|
<view class="hero-card">
|
<view class="hero-left">
|
<view class="hero-avatar">{{ initials }}</view>
|
<view class="hero-texts">
|
<text class="hero-title">{{ greeting }}</text>
|
<view>
|
<text class="hero-sub">{{ today }}</text>
|
</view>
|
</view>
|
</view>
|
<view class="hero-actions">
|
<view class="hero-chip" @click="goFunctions">
|
<uni-icons type="list" color="#fff" size="24"></uni-icons>
|
<text class="chip-text">功能中心</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 数据统计概览 -->
|
<view class="stats-card">
|
<view class="stats-item">
|
<text class="stats-num">{{ count.total }}</text>
|
<text class="stats-label">项目总数</text>
|
</view>
|
<view class="stats-item">
|
<text class="stats-num text-blue">{{ count.green }}</text>
|
<text class="stats-label">进行中</text>
|
</view>
|
<view class="stats-item">
|
<text class="stats-num text-green">{{ count.yellow }}</text>
|
<text class="stats-label">有风险</text>
|
</view>
|
<view class="stats-item">
|
<text class="stats-num text-orange">{{ count.red }}</text>
|
<text class="stats-label">已过期</text>
|
</view>
|
</view>
|
<!-- 项目进度柱状图 -->
|
<view class="filter-card">
|
<view class="filter-header">
|
<text class="filter-title">筛选项目</text>
|
<view class="filter-actions">
|
<view class="filter-chip" @click="filterVisible = !filterVisible">
|
<uni-icons :type="filterVisible ? 'top' : 'down'" color="#1E88E5" size="22"></uni-icons>
|
<text class="filter-chip-text">{{ filterVisible ? '收起' : '展开' }}</text>
|
</view>
|
<button class="filter-btn apply" @click="applyFilter">应用</button>
|
<button class="filter-btn clear" @click="clearFilter">清空</button>
|
</view>
|
</view>
|
<view class="filter-grid" v-if="filterVisible">
|
<view class="filter-controls">
|
<input class="filter-input" v-model="searchQuery" placeholder="搜索项目名称" />
|
</view>
|
<view class="filter-tag" v-for="p in filteredList.slice(0, displayLimit)" :key="p.id"
|
:class="{ selected: selectedIds.includes(p.id) }" @click="toggleId(p.id)">
|
<text class="ft-label">{{ p.name }}</text>
|
<uni-icons v-if="selectedIds.includes(p.id)" type="checkmarkempty" color="#fff" size="20"></uni-icons>
|
</view>
|
<view class="more-btn" v-if="filteredList.length > displayLimit" @click="increaseLimit">
|
<uni-icons type="down" color="#1E88E5" size="22"></uni-icons>
|
<text class="more-text">加载更多</text>
|
</view>
|
</view>
|
</view>
|
<view class="chart-card">
|
<text class="chart-title">项目材料进度统计</text>
|
<!-- 图表容器 -->
|
<view class="chart-box">
|
<qiun-data-charts type="bar" :opts="opts" :chartData="chartData" :tooltipShow="false" />
|
</view>
|
</view>
|
<!-- 项目阶段折线图 -->
|
<view class="chart-card">
|
<text class="chart-title">项目阶段趋势图</text>
|
<view class="chart-box">
|
<qiun-data-charts type="line" :opts="optsPhase" :chartData="chartDataPhase" />
|
</view>
|
</view>
|
|
<view class="quick-card">
|
<view class="quick-header">
|
<text class="quick-title">快捷入口</text>
|
</view>
|
|
<view class="quick-grid">
|
<view class="quick-item" @click="goPending">
|
<view class="quick-icon quick-blue">
|
<uni-icons type="calendar" color="#fff" size="36"></uni-icons>
|
</view>
|
<text class="quick-label">待处理</text>
|
</view>
|
<view class="quick-item" @click="goReport">
|
<view class="quick-icon quick-green">
|
<uni-icons type="compose" color="#fff" size="36"></uni-icons>
|
</view>
|
<text class="quick-label">上报</text>
|
</view>
|
<view class="quick-item" @click="goProgress">
|
<view class="quick-icon quick-orange">
|
<uni-icons type="flag" color="#fff" size="36"></uni-icons>
|
</view>
|
<text class="quick-label">进度</text>
|
</view>
|
<view class="quick-item" @click="goSchedule">
|
<view class="quick-icon quick-purple">
|
<uni-icons type="folder" color="#fff" size="36"></uni-icons>
|
</view>
|
<text class="quick-label">日程</text>
|
</view>
|
</view>
|
</view>
|
|
<view class="list-card">
|
<view class="list-header">
|
<text class="list-title">通知公告</text>
|
<view class="filter-chip" @click="noticeLimited = !noticeLimited">
|
<uni-icons :type="noticeLimited ? 'top' : 'down'" color="#1E88E5" size="22"></uni-icons>
|
<text class="filter-chip-text">{{ noticeLimited ? '取消展开' : '展开' }}</text>
|
</view>
|
</view>
|
<scroll-view v-if="noticeLimited" class="notice-container limited" scroll-y :lower-threshold="50"
|
@scrolltolower="loadMoreAuditHistory">
|
<view class="notice-row" v-for="(n, idx) in auditHistory" :key="idx">
|
<view class="notice-left">
|
<text class="notice-title">{{ n.title || n.projectName || n.name || '通知' }}</text>
|
<text class="notice-sub">{{ (n.time || n.auditTime || n.createTime) }} · {{ n.source || n.auditor || ''
|
}}</text>
|
</view>
|
<view class="notice-right">
|
<text class="badge badge-blue">公告</text>
|
</view>
|
</view>
|
</scroll-view>
|
<view v-else class="notice-container">
|
<view class="notice-row" v-for="(n, idx) in auditHistory" :key="idx">
|
<view class="notice-left">
|
<text class="notice-title">{{ n.projectName || '通知' }}</text>
|
<span class="log-action">{{ getAuditTypeText(n.auditType) }}</span>
|
<span class="log-detail">{{ n.content }}</span>
|
</view>
|
<view class="notice-right">
|
<text class="badge badge-blue">公告</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="list-card" style="margin-bottom: 50rpx;">
|
<text class="list-title">今日待办</text>
|
<scroll-view class="todo-container limited" scroll-y :lower-threshold="50" @scrolltolower="loadMoreWaitTask">
|
<view v-if="todos.length === 0" class="empty">暂无待办</view>
|
<view v-else class="todo-row" v-for="t in todos" :key="t.id" @click="openTodo(t)">
|
<view class="todo-left">
|
<text class="todo-title">{{ t.taskName }}</text>
|
|
</view>
|
<view class="todo-right">
|
<text class="status" :class="statusClass(t.taskType)">{{ t.taskType }}</text>
|
</view>
|
</view>
|
</scroll-view>
|
|
|
</view>
|
|
<!-- 底部导航栏 -->
|
<BottomTabBar active="home" />
|
</view>
|
</template>
|
|
<script>
|
import BottomTabBar from '@/components/BottomTabBar.vue'
|
import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
|
import { getCodingCount, getProjectSelectList, getTaskStatus, getStageCount } from '@/api/index/index.js'
|
import { getCurrentMonth } from '@/utils/util.js'
|
import { auditHistoryPage, getWaitTaskList,getTaskIsAuditing } from '@/api/workStationSchedule/workStationSchedule.js'
|
export default {
|
name: 'Index',
|
components: { BottomTabBar, qiunDataCharts },
|
data() {
|
return {
|
// 用户信息展示
|
userName: '',
|
initials: '',
|
greeting: '',
|
today: '',
|
filterVisible: false, // 筛选器是否可见
|
selectedIds: [], // 选中的项目ID列表
|
searchQuery: '', // 搜索查询字符串
|
inintLimit: 5, // 初始显示项目数量
|
displayLimit: 5, // 显示项目数量 初始值与initLimit相同
|
loadMoreStep: 5, // 每次加载更多项目数量
|
selectedMonth: getCurrentMonth(),
|
count: { // 统计对象
|
total: 0,
|
red: 0,
|
yellow: 0,
|
green: 0,
|
},
|
projectSelectList: [], // 项目选择列表
|
projectList: [], // 柱状图数据
|
chartData: {},
|
opts: {
|
color: ["#73C0DE", "#91CB74", "#EE6666"],
|
padding: [15, 30, 0, 10],
|
enableScroll: true,
|
legend: {},
|
xAxis: { boundaryGap: "justify", disableGrid: false, min: 0, axisLine: false },
|
yAxis: { data: [{ type: 'categories', disabled: false, fontSize: 10, formatter: (val) => val.length > 6 ? (val.substring(0, 6) + '...') : val }] },
|
extra: {
|
bar: { type: "stack", width: 32, categoryGap: 2, dataLabel: true, labelPosition: "right", labelWidth: 40 },
|
|
}
|
},
|
// 项目阶段折线图数据与配置
|
chartDataPhase: {},
|
optsPhase: {
|
color: ["#1890FF"],
|
padding: [30, 20, 20, 20], // 增大顶部留白,避免顶部点被裁切
|
legend: {},
|
xAxis: { disableGrid: false },
|
yAxis: { data: [{ min: 0, max: 105 }] }, // 给顶部留5%的空间,防止100%被遮蔽
|
extra: { line: { type: 'straight', width: 2, dataLabel: true } }
|
},
|
//待做任务
|
todoTotal: 0,
|
todoPageSzie: 5,
|
todoCurrentPage: 1,
|
todoLoading: false,
|
todos: [],
|
//项目日志
|
auditHistory: [],
|
auditHistoryTotal: 0,
|
auditHistoryPageSize: 5,
|
auditHistoryCurrentPage: 1,
|
auditHistoryLoading: false,
|
noticeLimited: true,
|
|
|
}
|
},
|
onLoad() {
|
|
this.initUser();
|
this.initMeta();
|
this.loadData();
|
},
|
onReachBottom() {
|
this.loadMoreAuditHistory()
|
},
|
methods: {
|
|
async initWaitTask() {
|
let params = {
|
pageSize: 10,
|
currentPage: this.todoCurrentPage,
|
id:"all"
|
}
|
|
const res = await getWaitTaskList(params)
|
if (res.statusCode === 200) {
|
const list = res.data.data ? res.data.data: []
|
if(this.todoCurrentPage === 1){
|
this.todos = list
|
}else{
|
this.todos = this.todos.concat(list)
|
}
|
this.todoTotal = res.data.total
|
}
|
},
|
async loadData() {
|
//统计数据
|
const res = await getCodingCount();
|
if (res.statusCode === 200) {
|
this.count = res.data.data;
|
}
|
await this.initSelectList(); // 下拉框数据
|
await this.initTaskStatus(); // 柱状图数据
|
this.selectedIds = this.projectSelectList.slice(0, this.inintLimit).map(p => p.id);
|
this.buildChartData();
|
this.buildPhaseChart();
|
this.initAuditHistory();
|
this.initWaitTask();
|
},
|
async initAuditHistory() {
|
let form = {
|
pageSize: this.auditHistoryPageSize,
|
currentPage: this.auditHistoryCurrentPage,
|
projectId: "all"
|
}
|
const res = await auditHistoryPage(form);
|
if (res.statusCode === 200) {
|
const list = Array.isArray(res.data.data) ? res.data.data : []
|
if (this.auditHistoryCurrentPage === 1) {
|
this.auditHistory = list
|
} else {
|
this.auditHistory = this.auditHistory.concat(list)
|
}
|
this.auditHistoryTotal = res.data.total || this.auditHistoryTotal
|
}
|
},
|
loadMoreWaitTask() {
|
if (this.todoLoading) return
|
if (this.todos.length >= this.todoTotal) return
|
this.todoLoading = true
|
this.todoCurrentPage += 1
|
this.initWaitTask().finally(() => { this.todoLoading = false })
|
},
|
loadMoreAuditHistory() {
|
if (this.auditHistoryLoading) return
|
if (this.auditHistory.length >= this.auditHistoryTotal) return
|
this.auditHistoryLoading = true
|
this.auditHistoryCurrentPage += 1
|
this.initAuditHistory().finally(() => { this.auditHistoryLoading = false })
|
},
|
async initTaskStatus() {
|
const form = {
|
startTime: this.selectedMonth
|
}
|
const res = await getTaskStatus(form)
|
if (res.statusCode === 200) {
|
this.projectList = res.data.data
|
}
|
},
|
async initSelectList() {
|
const res = await getProjectSelectList()
|
if (res.statusCode === 200) {
|
this.projectSelectList = this.normalizeSelectList(res.data.data)
|
}
|
},
|
// 转换格式为 [{ id: 1, name: '项目1' }, ...]
|
normalizeSelectList(raw) {
|
if (!raw) return []
|
if (Array.isArray(raw)) {
|
return raw.map(it => {
|
if (it && typeof it === 'object') {
|
const id = it.id != null ? it.id : (it.key != null ? it.key : it.value)
|
const name = it.name != null ? it.name : (it.label != null ? it.label : it.text)
|
if (id != null && name != null) return { id: typeof id === 'string' ? Number(id) : id, name: String(name) }
|
}
|
return null
|
}).filter(Boolean)
|
}
|
if (typeof raw === 'object') {
|
return Object.keys(raw).map(k => ({ id: Number(k), name: String(raw[k]) }))
|
}
|
return []
|
},
|
toggleId(id) {
|
const q = (this.searchQuery || '').trim()
|
if (q) {
|
// 排除未在查询范围的项目id
|
const filteredIds = this.filteredList.map(p => p.id)
|
this.selectedIds = this.selectedIds.filter(x => filteredIds.includes(x))
|
}
|
const i = this.selectedIds.indexOf(id)
|
// 如果已选中则去除 未选中则添加
|
if (i >= 0) { this.selectedIds.splice(i, 1) } else { this.selectedIds.push(id) }
|
},
|
// 增加显示项目数量
|
increaseLimit() { this.displayLimit += this.loadMoreStep },
|
// 应用筛选器
|
applyFilter() {
|
this.buildChartData()
|
},
|
// 清空赛选器
|
clearFilter() {
|
this.searchQuery = '';
|
this.displayLimit = this.inintLimit;
|
this.selectedIds = this.projectSelectList.slice(0, this.inintLimit).map(p => p.id);
|
this.buildChartData()
|
},
|
initUser() {
|
const storageUser = uni.getStorageSync('userInfo') || {}
|
const name = storageUser.user && storageUser.user.userName ? storageUser.user.userName : '用户'
|
this.userName = name
|
const n = name || ''
|
this.initials = n.length >= 2 ? n.slice(-2) : n
|
},
|
// 初始化时间相关数据
|
initMeta() {
|
const now = new Date()
|
const h = now.getHours()
|
this.greeting = h < 12 ? '上午好,' + this.userName : (h < 18 ? '下午好,' + this.userName : '晚上好,' + this.userName)
|
const y = now.getFullYear()
|
const m = String(now.getMonth() + 1).padStart(2, '0')
|
const d = String(now.getDate()).padStart(2, '0')
|
this.today = `${y}-${m}-${d}`
|
},
|
getAuditTypeText(auditType) {
|
// 映射关系:后端值 → 前端汉字
|
const typeMap = {
|
Submit: '提交',
|
Review: '审核',
|
Reject: '驳回',
|
Forward: '转交'
|
};
|
// 兜底:未知值返回“未知操作”
|
return typeMap[auditType] || '未知操作';
|
},
|
statusClass(s) {
|
if (s === '待完成') return 'status-green'
|
return 'status-blue'
|
},
|
|
openTodo(row) {
|
console.log(row)
|
// this.queryParams.projectId = row.checkPointInfo.id +"";
|
// this.queryParams.processDefId = row.checkPointInfo.processDefinitionId;
|
// this.queryParams.processInsId = row.checkPointInfo.processInstanceId;
|
// this.queryParams.deployId = row.checkPointInfo.deployId;
|
// this.queryParams.processName = row.checkPointInfo.processName;
|
|
// console.log(this.queryParams)
|
|
if (row.taskType === '容缺') {
|
uni.navigateTo({
|
url: '/subpackage/flowable/task-process' + this.formatQueryParams({
|
deployId: row.checkPointInfo.deployId,
|
procDefId: row.checkPointInfo.processDefinitionId,
|
procInsId: row.checkPointInfo.processInstanceId,
|
processName: row.taskName,
|
flowName: row.checkPointInfo.processName,
|
projectName: row.checkPointInfo.projectName,
|
taskId: row.id,
|
showAuditing: false,
|
projectId: row.checkPointInfo.id,
|
isWait: true,
|
// goBackParams: this.queryParams
|
})
|
});
|
} else {
|
// 查询该任务是否配置了需要审批
|
let params = {
|
processDefId: row.checkPointInfo.processDefinitionId,
|
taskId: row.id
|
}
|
getTaskIsAuditing(params).then(res => {
|
const q = {
|
deployId: row.checkPointInfo.deployId,
|
procDefId: row.checkPointInfo.processDefinitionId,
|
procInsId: row.checkPointInfo.processInstanceId,
|
processName: row.taskName,
|
flowName: row.checkPointInfo.processName,
|
projectName: row.checkPointInfo.projectName,
|
taskId: row.id,
|
showAuditing: res.data,
|
projectId: row.checkPointInfo.id,
|
isWait: false
|
}
|
uni.navigateTo({ url: '/subpackage/flowable/task-process' + this.formatQueryParams(q) })
|
})
|
}
|
},
|
formatQueryParams(obj) {
|
const entries = Object.entries(obj || {}).filter(([k, v]) => v !== undefined && v !== null)
|
if (!entries.length) return ''
|
return '?' + entries.map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)).join('&')
|
},
|
|
goFunctions() { uni.navigateTo({ url: '/subpackage/user/functions' }) },
|
goProgress() { uni.navigateTo({ url: '/subpackage/manager/progress' }) },
|
goPending() { uni.navigateTo({ url: '/subpackage/user/pending' }) },
|
goReport() { uni.navigateTo({ url: '/subpackage/manager/report' }) },
|
goSchedule() { uni.navigateTo({ url: '/subpackage/manager/schedule' }) },
|
|
// 将柱状图数据改为:已处理/待处理/未处理 百分比
|
buildChartData() {
|
console.log(this.selectedIds)
|
console.log(this.projectList)
|
const base = this.selectedIds.length ? this.projectList.filter(p => this.selectedIds.includes(Number(p.id))) : this.projectList
|
console.log("筛选后:{}", base)
|
const categories = base.map(p => p.projectName)
|
const completed = base.map(p => p.co)
|
const inProgress = base.map(p => p.co2)
|
const notStarted = base.map(p => p.co3)
|
this.chartData = {
|
categories,
|
series: [
|
{ name: '已处理', data: completed },
|
{ name: '待处理', data: inProgress },
|
{ name: '未处理', data: notStarted }
|
]
|
};
|
},
|
// 项目阶段折线图:x轴为 在库、前期、实施、竣工,模拟百分比趋势
|
async buildPhaseChart() {
|
let categories = ['在库', '前期', '实施', '竣工'];
|
let data = [0, 0, 0, 0];
|
try {
|
const res = await getStageCount()
|
if (res.statusCode === 200) {
|
categories = res.data.data.xData;
|
data = res.data.data.yData;
|
}
|
} catch (error) {
|
console.log(error)
|
|
}
|
this.chartDataPhase = { categories, series: [{ name: '数量', data }] };
|
}
|
},
|
computed: {
|
filteredList() {
|
let list = this.projectSelectList
|
const q = (this.searchQuery || '').trim().toLowerCase()
|
if (q) {
|
list = list.filter(p => (p.name || '').toLowerCase().includes(q))
|
}
|
return list
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
/* 全局容器与顶部导航 */
|
.content {
|
width: 100%;
|
min-height: 100vh;
|
background-color: #f5f7fa;
|
padding-bottom: 120rpx;
|
/* 给底部导航留空间,避免遮挡内容 */
|
}
|
|
/* 数据统计卡片 */
|
.stats-card {
|
display: flex;
|
justify-content: space-around;
|
padding: 30rpx 0;
|
background-color: #fff;
|
margin: 20rpx;
|
border-radius: 16rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.stats-item {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
}
|
|
.stats-num {
|
font-size: 40rpx;
|
font-weight: 700;
|
margin-bottom: 8rpx;
|
}
|
|
.stats-label {
|
font-size: 24rpx;
|
color: #666;
|
}
|
|
.text-blue {
|
color: #1E88E5;
|
}
|
|
.text-green {
|
color: #26A69A;
|
}
|
|
.text-orange {
|
color: #FF9800;
|
}
|
|
/* 图表卡片样式(保留并完善) */
|
.chart-card {
|
background-color: #fff;
|
margin: 20rpx;
|
border-radius: 16rpx;
|
padding: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.chart-title {
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #333;
|
margin-bottom: 16rpx;
|
}
|
|
.chart-box {
|
width: 100%;
|
height: 650rpx;
|
}
|
|
.hero-card {
|
height: 200rpx;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin: 20rpx;
|
padding: 24rpx;
|
border-radius: 20rpx;
|
background: linear-gradient(135deg, #1E88E5 0%, #26A69A 100%);
|
box-shadow: 0 8rpx 20rpx rgba(30, 136, 229, 0.25);
|
color: #fff;
|
}
|
|
.hero-left {
|
display: flex;
|
align-items: center;
|
}
|
|
.hero-avatar {
|
width: 100rpx;
|
height: 100rpx;
|
border-radius: 50rpx;
|
background-color: rgba(255, 255, 255, 0.25);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 36rpx;
|
font-weight: 700;
|
margin-right: 20rpx;
|
}
|
|
.hero-title {
|
font-size: 36rpx;
|
font-weight: 700;
|
}
|
|
.hero-sub {
|
font-size: 24rpx;
|
opacity: 0.9;
|
margin: 6rpx 0 0 6rpx;
|
}
|
|
.hero-actions {
|
display: flex;
|
}
|
|
.hero-chip {
|
display: flex;
|
align-items: center;
|
/* gap: 10rpx; */
|
padding: 12rpx 18rpx;
|
background-color: rgba(255, 255, 255, 0.22);
|
border-radius: 999rpx;
|
margin-left: 16rpx;
|
}
|
|
.chip-text {
|
color: #fff;
|
font-size: 26rpx;
|
}
|
|
.quick-card {
|
background-color: #fff;
|
margin: 20rpx;
|
border-radius: 16rpx;
|
padding: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.quick-header {
|
display: flex;
|
/* justify-content: space-between; */
|
/* align-items: center; */
|
}
|
|
.quick-title {
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #333;
|
margin-bottom: 16rpx;
|
}
|
|
.quick-grid {
|
display: flex;
|
justify-content: space-between;
|
}
|
|
.quick-item {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
width: 22%;
|
}
|
|
.quick-icon {
|
width: 120rpx;
|
height: 120rpx;
|
border-radius: 16rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-bottom: 10rpx;
|
}
|
|
.quick-blue {
|
background-color: #1E88E5;
|
box-shadow: 0 6rpx 14rpx rgba(30, 136, 229, 0.25);
|
}
|
|
.quick-green {
|
background-color: #26A69A;
|
box-shadow: 0 6rpx 14rpx rgba(38, 166, 154, 0.25);
|
}
|
|
.quick-orange {
|
background-color: #FF9800;
|
box-shadow: 0 6rpx 14rpx rgba(255, 152, 0, 0.25);
|
}
|
|
.quick-purple {
|
background-color: #7E57C2;
|
box-shadow: 0 6rpx 14rpx rgba(126, 87, 194, 0.25);
|
}
|
|
.quick-label {
|
font-size: 26rpx;
|
color: #333;
|
}
|
|
.list-card {
|
background-color: #fff;
|
margin: 20rpx;
|
border-radius: 16rpx;
|
padding: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.list-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 10rpx;
|
}
|
|
.list-title {
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #333;
|
margin-bottom: 10rpx;
|
}
|
.todo-container {
|
width: 100%;
|
}
|
.todo-container.limited{
|
height: 420rpx;
|
}
|
|
.notice-container {
|
width: 100%;
|
}
|
|
.notice-container.limited {
|
height: 420rpx;
|
}
|
|
.notice-row,
|
.todo-row {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 16rpx 0;
|
border-bottom: 1rpx solid #f0f0f0;
|
}
|
|
.notice-row:last-child,
|
.todo-row:last-child {
|
border-bottom: none;
|
}
|
|
.notice-left,
|
.todo-left {
|
display: flex;
|
flex-direction: column;
|
width: 80%;
|
}
|
|
.notice-title,
|
.todo-title {
|
font-size: 28rpx;
|
color: #333;
|
font-weight: 600;
|
}
|
|
.log-action {
|
font-size: 25rpx;
|
color: #ff9800;
|
}
|
|
.log-detail {
|
font-size: 25rpx;
|
color: #999;
|
margin-right: 10px;
|
}
|
|
.notice-sub,
|
.todo-sub {
|
font-size: 24rpx;
|
color: #999;
|
margin-top: 6rpx;
|
}
|
|
.notice-right,
|
.todo-right {
|
display: flex;
|
align-items: center;
|
}
|
|
.badge {
|
padding: 6rpx 14rpx;
|
border-radius: 999rpx;
|
font-size: 22rpx;
|
color: #fff;
|
}
|
|
.badge-red {
|
background-color: #EE6666;
|
}
|
|
.badge-orange {
|
background-color: #FF9800;
|
}
|
|
.badge-blue {
|
background-color: #1E88E5;
|
}
|
|
.status {
|
padding: 6rpx 14rpx;
|
border-radius: 999rpx;
|
font-size: 22rpx;
|
color: #fff;
|
}
|
|
.status-red {
|
background-color: #EE6666;
|
}
|
|
.status-green {
|
background-color: #26A69A;
|
}
|
|
.status-blue {
|
background-color: #1E88E5;
|
}
|
|
.empty {
|
font-size: 26rpx;
|
color: #999;
|
padding: 10rpx 0;
|
text-align: center;
|
}
|
|
.filter-card {
|
background-color: #fff;
|
margin: 20rpx;
|
border-radius: 16rpx;
|
padding: 20rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.filter-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 12rpx;
|
}
|
|
.filter-title {
|
font-size: 30rpx;
|
font-weight: 600;
|
color: #333;
|
}
|
|
.filter-actions {
|
display: flex;
|
align-items: center;
|
}
|
|
.filter-chip {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
margin-right: 12rpx;
|
padding: 8rpx 12rpx;
|
background-color: #E3F2FD;
|
border-radius: 999rpx;
|
}
|
|
.filter-chip-text {
|
font-size: 24rpx;
|
color: #1E88E5;
|
}
|
|
.filter-btn {
|
height: 64rpx;
|
line-height: 64rpx;
|
font-size: 26rpx;
|
border: none;
|
border-radius: 10rpx;
|
padding: 0 24rpx;
|
margin-left: 8rpx;
|
}
|
|
.filter-btn.apply {
|
background-color: #1E88E5;
|
color: #fff;
|
}
|
|
.filter-btn.clear {
|
background-color: #EEEEEE;
|
color: #333;
|
}
|
|
.filter-grid {
|
display: flex;
|
flex-wrap: wrap;
|
margin-top: 8rpx;
|
}
|
|
.filter-controls {
|
width: 100%;
|
margin-bottom: 12rpx;
|
}
|
|
.filter-input {
|
width: 100%;
|
height: 72rpx;
|
border: 1rpx solid #e8e8e8;
|
border-radius: 12rpx;
|
padding: 0 20rpx;
|
font-size: 26rpx;
|
background-color: #fff;
|
}
|
|
.more-btn {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
padding: 8rpx 12rpx;
|
background-color: #E3F2FD;
|
border-radius: 999rpx;
|
margin: 8rpx;
|
}
|
|
.more-text {
|
font-size: 24rpx;
|
color: #1E88E5;
|
}
|
|
.filter-tag {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 12rpx 16rpx;
|
border: 1rpx solid #e8e8e8;
|
border-radius: 999rpx;
|
margin: 8rpx;
|
background-color: #fafafa;
|
min-width: 200rpx;
|
}
|
|
.filter-tag.selected {
|
background-color: #1E88E5;
|
border-color: #1E88E5;
|
color: #fff;
|
}
|
|
.ft-label {
|
font-size: 24rpx;
|
}
|
</style>
|