|
|
<template>
|
|
|
<view class="page-container">
|
|
|
<scroll-view scroll-y class="main-scroll" @scroll="onScroll">
|
|
|
<view class="banner-section">
|
|
|
<view class="banner-bg">
|
|
|
<view class="banner-content">
|
|
|
<text class="banner-title">欢迎您使用</text>
|
|
|
<text class="banner-subtitle">必硕数字化智能中控平台</text>
|
|
|
</view>
|
|
|
<view class="banner-decoration">
|
|
|
<view class="deco-line"></view>
|
|
|
<view class="deco-dot"></view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="bell-wrapper" @click="showTodoList">
|
|
|
<text class="bell-icon">
|
|
|
<el-badge :value="todoCount" :hidden="todoCount === 0" class="item">
|
|
|
<image src="/static/logo/bell.png" mode="aspectFit" style="width: 48rpx; height: 48rpx;" />
|
|
|
</el-badge>
|
|
|
</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="content-section">
|
|
|
<view class="nav-section">
|
|
|
<view class="section-title">功能导航</view>
|
|
|
<view class="nav-grid">
|
|
|
<view v-for="(item, index) in navList" :key="index" class="nav-item" @click="handleNavClick(item)">
|
|
|
<view class="nav-icon" :style="{ backgroundColor: item.bgColor }">
|
|
|
<text class="nav-icon-text">{{ item.icon }}</text>
|
|
|
</view>
|
|
|
<text class="nav-text">{{ item.name }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="stats-section">
|
|
|
<view class="section-title">生产整体概况</view>
|
|
|
<view class="stats-grid">
|
|
|
<view v-for="(stat, index) in statsData" :key="index" class="stat-card" :class="'stat-' + stat.type">
|
|
|
<text class="stat-value">{{ stat.value }}</text>
|
|
|
<text class="stat-label">{{ stat.label }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view class="plan-section">
|
|
|
<view class="section-header">
|
|
|
<text class="section-title">生产计划</text>
|
|
|
<text class="section-more" @click="viewMorePlans">查看更多 ›</text>
|
|
|
</view>
|
|
|
<view class="plan-list">
|
|
|
<view v-for="(plan, index) in planList" :key="index" class="plan-card" @click="handlePlanClick(plan)">
|
|
|
<view class="plan-header">
|
|
|
<text class="plan-code">{{ plan.code }}</text>
|
|
|
<view class="plan-status" :class="'status-' + plan.statusType">
|
|
|
<text>{{ plan.status }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="plan-body">
|
|
|
<view class="plan-row">
|
|
|
<text class="plan-label">产品名称</text>
|
|
|
<text class="plan-value">{{ plan.productName }}</text>
|
|
|
</view>
|
|
|
<view class="plan-row">
|
|
|
<text class="plan-label">生产线</text>
|
|
|
<text class="plan-value">{{ plan.feedingPipelineName }}</text>
|
|
|
</view>
|
|
|
<view class="plan-row">
|
|
|
<text class="plan-label">计划数量</text>
|
|
|
<text class="plan-value plan-num">{{ plan.planNumber }}</text>
|
|
|
</view>
|
|
|
<view class="plan-row">
|
|
|
<text class="plan-label">计划开始</text>
|
|
|
<text class="plan-value">{{ plan.planStartTimeText }}</text>
|
|
|
</view>
|
|
|
<view class="plan-row">
|
|
|
<text class="plan-label">计划结束</text>
|
|
|
<text class="plan-value">{{ plan.planEndTimeText }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</scroll-view>
|
|
|
|
|
|
<uni-popup ref="todoPopup" type="right" background-color="#fff">
|
|
|
<view class="todo-popup">
|
|
|
<view class="todo-header">
|
|
|
<view class="todo-back" @click="closeTodoList">
|
|
|
<text class="back-icon">‹</text>
|
|
|
<text class="back-text">返回</text>
|
|
|
</view>
|
|
|
<text class="todo-title">待办任务</text>
|
|
|
</view>
|
|
|
<scroll-view scroll-y class="todo-scroll">
|
|
|
<view v-if="todoList.length === 0" class="todo-empty">
|
|
|
<text class="empty-text">暂无待办任务</text>
|
|
|
</view>
|
|
|
<view v-else>
|
|
|
<view v-for="(item, index) in todoList" :key="index" class="todo-item">
|
|
|
<view class="todo-dot"></view>
|
|
|
<view class="todo-content">
|
|
|
<view class="todo-title" style="text-align: left;margin-right: 0;">{{ item.name }}</view>
|
|
|
<view class="todo-sub">任务编号:{{ item.code }}</view>
|
|
|
<view class="todo-sub">任务类型:{{ item.type }}</view>
|
|
|
<view class="todo-sub">目标:{{ item.deviceName }}</view>
|
|
|
<view class="todo-sub">创建时间:{{ formatDate(item.createTime) }}</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</scroll-view>
|
|
|
</view>
|
|
|
</uni-popup>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { onMounted, ref, reactive } from 'vue';
|
|
|
import request from '@/utils/request'
|
|
|
|
|
|
const todoPopup = ref(null);
|
|
|
const todoCount = ref(0);
|
|
|
|
|
|
const navList = reactive([
|
|
|
{ name: '模具', icon: '🔧', bgColor: '#1a3a5c', path: '/pages_function/mold' },
|
|
|
{ name: '设备', icon: '⚙️', bgColor: '#2d5a87', path: '/pages_function/equipment' },
|
|
|
{ name: '关键件', icon: '🔩', bgColor: '#3d7ab5', path: '/pages_function/keypart' },
|
|
|
{ name: '备件', icon: '📦', bgColor: '#4a90c2', path: '/pages_function/spare' },
|
|
|
{ name: '出入库', icon: '📊', bgColor: '#5aa0d2', path: '/pages_function/warehouse' }
|
|
|
]);
|
|
|
|
|
|
const statsData = reactive([
|
|
|
{ label: '总数', type: 'total' },
|
|
|
{ label: '未开工', type: 'pending' },
|
|
|
{ label: '生产中', type: 'running' },
|
|
|
{ label: '完工', type: 'finished' }
|
|
|
]);
|
|
|
|
|
|
const planList = reactive([]);
|
|
|
|
|
|
const todoList = reactive([]);
|
|
|
|
|
|
function showTodoList() {
|
|
|
todoPopup.value.open();
|
|
|
}
|
|
|
|
|
|
function closeTodoList() {
|
|
|
todoPopup.value.close();
|
|
|
}
|
|
|
|
|
|
function handleNavClick(item) {
|
|
|
const navMap = {
|
|
|
'模具': '/pages_function/pages/mold/index',
|
|
|
'设备': '/pages_function/pages/equipment/index',
|
|
|
'备件': '/pages_function/pages/spare/index',
|
|
|
'关键件': '/pages_function/pages/keypart/index'
|
|
|
};
|
|
|
|
|
|
const url = navMap[item.name];
|
|
|
if (url) {
|
|
|
uni.navigateTo({ url });
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
title: `进入${item.name}模块`,
|
|
|
icon: 'none'
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function handlePlanClick(plan) {
|
|
|
uni.showToast({
|
|
|
title: `查看计划: ${plan.code}`,
|
|
|
icon: 'none'
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function viewMorePlans() {
|
|
|
uni.showToast({
|
|
|
title: '查看更多计划',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function onScroll(e) {
|
|
|
}
|
|
|
|
|
|
function formatDate(ms) {
|
|
|
if (!ms) return '-'
|
|
|
const date = new Date(ms)
|
|
|
if (Number.isNaN(date.getTime())) return '-'
|
|
|
const pad2 = (n) => String(n).padStart(2, '0')
|
|
|
const y = date.getFullYear()
|
|
|
const m = pad2(date.getMonth() + 1)
|
|
|
const d = pad2(date.getDate())
|
|
|
return `${y}-${m}-${d}`
|
|
|
}
|
|
|
|
|
|
const getPlanStatusLabel = (value) => {
|
|
|
const v = value === '' || value === null || value === undefined ? undefined : String(value)
|
|
|
if (v == '1') return '已排产'
|
|
|
if (v == '6') return '试产'
|
|
|
if (v == '2') return '量产'
|
|
|
if (v == '3') return '暂停'
|
|
|
if (v == '4') return '待入库'
|
|
|
return '-'
|
|
|
}
|
|
|
|
|
|
function mapPlanStatus(status) {
|
|
|
const v = status === '' || status === null || status === undefined ? undefined : String(status)
|
|
|
if (v == '1') return { status: getPlanStatusLabel(v), statusType: 'pending' }
|
|
|
if (v == '6') return { status: getPlanStatusLabel(v), statusType: 'running' }
|
|
|
if (v == '2') return { status: getPlanStatusLabel(v), statusType: 'running' }
|
|
|
if (v == '3') return { status: getPlanStatusLabel(v), statusType: 'pending' }
|
|
|
if (v == '4') return { status: getPlanStatusLabel(v), statusType: 'finished' }
|
|
|
return { status: getPlanStatusLabel(v), statusType: 'pending' }
|
|
|
}
|
|
|
|
|
|
async function loadProductionStats() {
|
|
|
const res = await request({ url: '/admin-api/mes/dashboard/getProduction', method: 'get' })
|
|
|
const taskItems = (res?.data?.taskItems || []).map((i) => ({
|
|
|
key: String(i.key),
|
|
|
value: Number(i.value ?? 0)
|
|
|
}))
|
|
|
const byKey = taskItems.reduce((acc, cur) => {
|
|
|
acc[cur.key] = cur.value
|
|
|
return acc
|
|
|
}, {})
|
|
|
const keyOrder = ['1', '2', '3', '4']
|
|
|
statsData.forEach((stat, index) => {
|
|
|
const k = keyOrder[index]
|
|
|
stat.value = byKey[k] ?? 0
|
|
|
})
|
|
|
}
|
|
|
|
|
|
async function loadPlanList() {
|
|
|
const res = await request({ url: '/admin-api/mes/dashboard/getPlan', method: 'get' })
|
|
|
const raw = Array.isArray(res?.data) ? res.data : (res?.data ? [res.data] : [])
|
|
|
const mapped = raw.map((p) => {
|
|
|
const statusInfo = mapPlanStatus(p?.status)
|
|
|
return {
|
|
|
id: p?.id,
|
|
|
code: p?.code ?? '-',
|
|
|
status: statusInfo.status,
|
|
|
statusType: statusInfo.statusType,
|
|
|
productName: p?.productName ?? '-',
|
|
|
feedingPipelineName: p?.feedingPipelineName ?? '-',
|
|
|
planNumber: p?.planNumber ?? 0,
|
|
|
planStartTimeText: formatDate(p?.planStartTime),
|
|
|
planEndTimeText: formatDate(p?.planEndTime),
|
|
|
}
|
|
|
})
|
|
|
if (mapped.length) {
|
|
|
planList.splice(0, planList.length, ...mapped)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
async function loadTodoList() {
|
|
|
const res = await request({ url: '/admin-api/mes/dashboard/getTodoList', method: 'get' })
|
|
|
const data = res?.data || []
|
|
|
todoList.splice(0, todoList.length, ...data)
|
|
|
todoCount.value = data.length
|
|
|
}
|
|
|
|
|
|
async function loadDashboard() {
|
|
|
await Promise.allSettled([loadProductionStats(), loadPlanList(), loadTodoList()])
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
loadDashboard()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.page-container {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
height: 100vh;
|
|
|
background-color: #f0f2f5;
|
|
|
}
|
|
|
|
|
|
.main-scroll {
|
|
|
flex: 1;
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
|
.banner-section {
|
|
|
position: relative;
|
|
|
height: 320rpx;
|
|
|
}
|
|
|
|
|
|
.banner-bg {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
background: linear-gradient(135deg, #1a3a5c 0%, #2d5a87 50%, #3d7ab5 100%);
|
|
|
position: relative;
|
|
|
overflow: visible;
|
|
|
|
|
|
&::before {
|
|
|
content: '';
|
|
|
position: absolute;
|
|
|
top: -50%;
|
|
|
right: -20%;
|
|
|
width: 300rpx;
|
|
|
height: 300rpx;
|
|
|
background: rgba(255, 255, 255, 0.1);
|
|
|
border-radius: 50%;
|
|
|
}
|
|
|
|
|
|
&::after {
|
|
|
content: '';
|
|
|
position: absolute;
|
|
|
bottom: -30%;
|
|
|
left: 10%;
|
|
|
width: 200rpx;
|
|
|
height: 200rpx;
|
|
|
background: rgba(255, 255, 255, 0.05);
|
|
|
border-radius: 50%;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.banner-content {
|
|
|
position: relative;
|
|
|
z-index: 2;
|
|
|
padding: 60rpx 40rpx;
|
|
|
|
|
|
.banner-title {
|
|
|
display: block;
|
|
|
font-size: 28rpx;
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
margin-bottom: 16rpx;
|
|
|
}
|
|
|
|
|
|
.banner-subtitle {
|
|
|
display: block;
|
|
|
font-size: 40rpx;
|
|
|
font-weight: bold;
|
|
|
color: #ffffff;
|
|
|
line-height: 1.4;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.banner-decoration {
|
|
|
position: absolute;
|
|
|
bottom: 40rpx;
|
|
|
left: 40rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
.deco-line {
|
|
|
width: 60rpx;
|
|
|
height: 4rpx;
|
|
|
background: #ff8c00;
|
|
|
border-radius: 2rpx;
|
|
|
}
|
|
|
|
|
|
.deco-dot {
|
|
|
width: 12rpx;
|
|
|
height: 12rpx;
|
|
|
background: #ff8c00;
|
|
|
border-radius: 50%;
|
|
|
margin-left: 16rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.bell-wrapper {
|
|
|
position: absolute;
|
|
|
top: 30rpx;
|
|
|
right: 30rpx;
|
|
|
width: 80rpx;
|
|
|
height: 80rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
z-index: 100;
|
|
|
}
|
|
|
|
|
|
.bell-icon {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
|
|
|
|
.content-section {
|
|
|
padding: 0 24rpx 24rpx;
|
|
|
margin-top: -40rpx;
|
|
|
position: relative;
|
|
|
z-index: 5;
|
|
|
}
|
|
|
|
|
|
.section-title {
|
|
|
font-size: 32rpx;
|
|
|
font-weight: 600;
|
|
|
color: #1a3a5c;
|
|
|
margin-bottom: 24rpx;
|
|
|
}
|
|
|
|
|
|
.section-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
|
.section-more {
|
|
|
font-size: 26rpx;
|
|
|
color: #666666;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.nav-section {
|
|
|
background: #ffffff;
|
|
|
border-radius: 20rpx;
|
|
|
padding: 28rpx;
|
|
|
margin-bottom: 24rpx;
|
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
|
|
}
|
|
|
|
|
|
.nav-grid {
|
|
|
display: flex;
|
|
|
justify-content: space-around;
|
|
|
}
|
|
|
|
|
|
.nav-item {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
|
|
|
&:active {
|
|
|
opacity: 0.7;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.nav-icon {
|
|
|
width: 96rpx;
|
|
|
height: 96rpx;
|
|
|
border-radius: 24rpx;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
margin-bottom: 16rpx;
|
|
|
|
|
|
.nav-icon-text {
|
|
|
font-size: 44rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.nav-text {
|
|
|
font-size: 26rpx;
|
|
|
color: #333333;
|
|
|
}
|
|
|
|
|
|
.stats-section {
|
|
|
margin-bottom: 24rpx;
|
|
|
}
|
|
|
|
|
|
.stats-grid {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
|
|
|
.stat-card {
|
|
|
flex: 1;
|
|
|
background: #ffffff;
|
|
|
border-radius: 16rpx;
|
|
|
padding: 28rpx 16rpx;
|
|
|
margin: 0 8rpx;
|
|
|
text-align: center;
|
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
|
|
|
|
|
&:first-child {
|
|
|
margin-left: 0;
|
|
|
}
|
|
|
|
|
|
&:last-child {
|
|
|
margin-right: 0;
|
|
|
}
|
|
|
|
|
|
&:active {
|
|
|
transform: scale(0.98);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.stat-value {
|
|
|
display: block;
|
|
|
font-size: 48rpx;
|
|
|
font-weight: bold;
|
|
|
margin-bottom: 8rpx;
|
|
|
}
|
|
|
|
|
|
.stat-label {
|
|
|
display: block;
|
|
|
font-size: 24rpx;
|
|
|
color: #666666;
|
|
|
}
|
|
|
|
|
|
.stat-total {
|
|
|
border-left: 6rpx solid #1a3a5c;
|
|
|
|
|
|
.stat-value {
|
|
|
color: #1a3a5c;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.stat-pending {
|
|
|
border-left: 6rpx solid #ff8c00;
|
|
|
|
|
|
.stat-value {
|
|
|
color: #ff8c00;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.stat-running {
|
|
|
border-left: 6rpx solid #18bc37;
|
|
|
|
|
|
.stat-value {
|
|
|
color: #18bc37;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.stat-finished {
|
|
|
border-left: 6rpx solid #4a90c2;
|
|
|
|
|
|
.stat-value {
|
|
|
color: #4a90c2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.plan-section {
|
|
|
background: #ffffff;
|
|
|
border-radius: 20rpx;
|
|
|
padding: 28rpx;
|
|
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
|
|
}
|
|
|
|
|
|
.plan-list {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
|
|
|
.plan-card {
|
|
|
background: #f8fafc;
|
|
|
border-radius: 16rpx;
|
|
|
padding: 24rpx;
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
&:last-child {
|
|
|
margin-bottom: 0;
|
|
|
}
|
|
|
|
|
|
&:active {
|
|
|
background: #e8f4ff;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.plan-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
margin-bottom: 20rpx;
|
|
|
}
|
|
|
|
|
|
.plan-code {
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 600;
|
|
|
color: #1a3a5c;
|
|
|
}
|
|
|
|
|
|
.plan-status {
|
|
|
padding: 8rpx 20rpx;
|
|
|
border-radius: 20rpx;
|
|
|
font-size: 22rpx;
|
|
|
}
|
|
|
|
|
|
.status-pending {
|
|
|
background: rgba(255, 140, 0, 0.15);
|
|
|
color: #ff8c00;
|
|
|
}
|
|
|
|
|
|
.status-running {
|
|
|
background: rgba(24, 188, 55, 0.15);
|
|
|
color: #18bc37;
|
|
|
}
|
|
|
|
|
|
.status-finished {
|
|
|
background: rgba(74, 144, 194, 0.15);
|
|
|
color: #4a90c2;
|
|
|
}
|
|
|
|
|
|
.plan-body {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
}
|
|
|
|
|
|
.plan-row {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
margin-bottom: 12rpx;
|
|
|
|
|
|
&:last-child {
|
|
|
margin-bottom: 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.plan-label {
|
|
|
font-size: 26rpx;
|
|
|
color: #999999;
|
|
|
}
|
|
|
|
|
|
.plan-value {
|
|
|
font-size: 26rpx;
|
|
|
color: #333333;
|
|
|
}
|
|
|
|
|
|
.plan-num {
|
|
|
font-weight: 600;
|
|
|
color: #1a3a5c;
|
|
|
}
|
|
|
|
|
|
.todo-popup {
|
|
|
width: 600rpx;
|
|
|
height: 100vh;
|
|
|
background: #ffffff;
|
|
|
}
|
|
|
|
|
|
.todo-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
padding: 40rpx 30rpx;
|
|
|
background: linear-gradient(135deg, #1a3a5c 0%, #2d5a87 100%);
|
|
|
}
|
|
|
|
|
|
.todo-back {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
&:active {
|
|
|
opacity: 0.7;
|
|
|
}
|
|
|
|
|
|
.back-icon {
|
|
|
font-size: 48rpx;
|
|
|
color: #ffffff;
|
|
|
margin-right: 8rpx;
|
|
|
}
|
|
|
|
|
|
.back-text {
|
|
|
font-size: 28rpx;
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.todo-title {
|
|
|
flex: 1;
|
|
|
text-align: center;
|
|
|
font-size: 34rpx;
|
|
|
font-weight: 600;
|
|
|
color: #ffffff;
|
|
|
margin-right: 80rpx;
|
|
|
}
|
|
|
|
|
|
.todo-scroll {
|
|
|
height: calc(100vh - 140rpx);
|
|
|
background: #f5f7fa;
|
|
|
}
|
|
|
|
|
|
.todo-empty {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
height: 400rpx;
|
|
|
|
|
|
.empty-text {
|
|
|
font-size: 28rpx;
|
|
|
color: #999999;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.todo-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
background: #ffffff;
|
|
|
padding: 28rpx 30rpx;
|
|
|
margin-bottom: 2rpx;
|
|
|
|
|
|
&:active {
|
|
|
background: #f5f7fa;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.todo-dot {
|
|
|
width: 16rpx;
|
|
|
height: 16rpx;
|
|
|
border-radius: 50%;
|
|
|
background: #1a3a5c;
|
|
|
margin-right: 20rpx;
|
|
|
}
|
|
|
|
|
|
.todo-content {
|
|
|
flex: 1;
|
|
|
|
|
|
.todo-title {
|
|
|
display: block;
|
|
|
font-size: 28rpx;
|
|
|
color: #333333;
|
|
|
font-weight: bold;
|
|
|
margin-bottom: 12rpx;
|
|
|
}
|
|
|
|
|
|
.todo-sub {
|
|
|
display: block;
|
|
|
font-size: 24rpx;
|
|
|
color: #666666;
|
|
|
margin-bottom: 6rpx;
|
|
|
line-height: 1.4;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.todo-priority {
|
|
|
padding: 8rpx 16rpx;
|
|
|
border-radius: 8rpx;
|
|
|
font-size: 22rpx;
|
|
|
}
|
|
|
|
|
|
.priority-high {
|
|
|
background: rgba(255, 77, 79, 0.1);
|
|
|
color: #ff4d4f;
|
|
|
}
|
|
|
|
|
|
.priority-medium {
|
|
|
background: rgba(255, 140, 0, 0.1);
|
|
|
color: #ff8c00;
|
|
|
}
|
|
|
|
|
|
.priority-low {
|
|
|
background: rgba(24, 188, 55, 0.1);
|
|
|
color: #18bc37;
|
|
|
}
|
|
|
</style>
|