834 lines
20 KiB
Vue
834 lines
20 KiB
Vue
<template>
|
||
<a-modal
|
||
v-model:open="visible"
|
||
:width="680"
|
||
:closable="true"
|
||
:maskClosable="false"
|
||
:keyboard="true"
|
||
:footer="null"
|
||
centered
|
||
class="daily-progress-modal"
|
||
@cancel="handleClose"
|
||
>
|
||
<!-- 自定义标题 -->
|
||
<template #title>
|
||
<div class="modal-title">
|
||
<span class="title-icon">📋</span>
|
||
<span class="title-text">每日任务进度更新</span>
|
||
<a-button type="text" class="skip-btn" @click="handleSkip">
|
||
稍后提醒
|
||
</a-button>
|
||
</div>
|
||
</template>
|
||
|
||
<div class="daily-progress-reminder">
|
||
<!-- 提示信息 -->
|
||
<div class="reminder-banner">
|
||
<div class="banner-icon">
|
||
<Icon name="alert-circle" size="md" color="#F59E0B" />
|
||
</div>
|
||
<div class="banner-content">
|
||
<div class="banner-title">请更新您今天的任务进度</div>
|
||
<div class="banner-desc">每日 17:30 后首次登录需要更新进行中的任务进度</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 加载状态 -->
|
||
<div v-if="loading" class="loading-container">
|
||
<a-spin size="large" />
|
||
<p class="loading-text">正在加载任务列表...</p>
|
||
</div>
|
||
|
||
<!-- 无任务状态 -->
|
||
<div v-else-if="tasks.length === 0" class="no-tasks">
|
||
<div class="no-tasks-icon">
|
||
<Icon name="check-circle" size="xl" color="#31f08b" />
|
||
</div>
|
||
<div class="no-tasks-title">太棒了!</div>
|
||
<div class="no-tasks-desc">您目前没有进行中的任务</div>
|
||
<a-button type="primary" size="large" @click="handleNoTasksConfirm">
|
||
<Icon name="check" size="sm" style="margin-right: 6px;" />
|
||
确认并关闭
|
||
</a-button>
|
||
</div>
|
||
|
||
<!-- 任务列表 -->
|
||
<div v-else class="tasks-container">
|
||
<div class="tasks-list">
|
||
<div v-for="(task, index) in tasks" :key="task.id" class="task-card">
|
||
<!-- 任务序号标签 -->
|
||
<div class="task-index">{{ index + 1 }}</div>
|
||
|
||
<!-- 任务信息 -->
|
||
<div class="task-info">
|
||
<div class="task-header">
|
||
<div class="task-title">{{ task.title }}</div>
|
||
<div class="task-no">{{ task.taskNo }}</div>
|
||
</div>
|
||
|
||
<div class="task-time">
|
||
<div class="time-item">
|
||
<Icon name="calendar" size="xs" />
|
||
<span class="time-label">开始:</span>
|
||
<span class="time-value">{{ formatDate(task.startTime) }}</span>
|
||
</div>
|
||
<div class="time-item deadline">
|
||
<Icon name="clock" size="xs" />
|
||
<span class="time-label">截止:</span>
|
||
<span class="time-value">{{ formatDate(task.deadline) }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 进度更新区域 -->
|
||
<div class="progress-section">
|
||
<div class="progress-header">
|
||
<span class="progress-title">更新进度</span>
|
||
<span class="progress-hint">当前: {{ task.progress || 0 }}%</span>
|
||
</div>
|
||
|
||
<div class="progress-control">
|
||
<div class="slider-wrapper">
|
||
<a-slider
|
||
v-model:value="task.newProgress"
|
||
:min="0"
|
||
:max="100"
|
||
:step="5"
|
||
:tooltip="{ formatter: (value: number) => `${value}%` }"
|
||
/>
|
||
<div class="slider-labels">
|
||
<span class="label-start">0%</span>
|
||
<span class="label-current" :style="{ left: `${task.progress || 0}%` }">
|
||
上次 {{ task.progress || 0 }}%
|
||
</span>
|
||
<span class="label-end">100%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="input-wrapper">
|
||
<a-input-number
|
||
v-model:value="task.newProgress"
|
||
:min="0"
|
||
:max="100"
|
||
:precision="0"
|
||
:controls="true"
|
||
/>
|
||
<span class="input-suffix">%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 备注输入 -->
|
||
<div class="remark-section">
|
||
<a-textarea
|
||
v-model:value="task.progressRemark"
|
||
placeholder="简要说明今日进展(选填)"
|
||
:rows="2"
|
||
:maxlength="200"
|
||
show-count
|
||
/>
|
||
</div>
|
||
|
||
<!-- 错误提示 -->
|
||
<div v-if="task.error" class="error-tip">
|
||
<Icon name="alert-circle" size="xs" />
|
||
{{ task.error }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 提交按钮 -->
|
||
<div class="submit-section">
|
||
<a-button
|
||
type="primary"
|
||
size="large"
|
||
block
|
||
:loading="submitting"
|
||
@click="handleSubmit"
|
||
>
|
||
<template #icon>
|
||
<Icon name="check" size="sm" />
|
||
</template>
|
||
提交所有任务进度
|
||
</a-button>
|
||
<div class="submit-tip">* 必须更新所有任务进度才能关闭此弹窗</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</a-modal>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref } from 'vue'
|
||
import { message } from 'ant-design-vue'
|
||
import Icon from '@/components/Icon.vue'
|
||
import * as taskApi from '@/api/task'
|
||
import dayjs from 'dayjs'
|
||
|
||
interface TaskProgress {
|
||
id: number
|
||
taskNo: string
|
||
title: string
|
||
startTime?: string
|
||
deadline?: string
|
||
progress?: number
|
||
newProgress: number
|
||
progressRemark?: string
|
||
error?: string
|
||
}
|
||
|
||
const visible = ref(false)
|
||
const loading = ref(false)
|
||
const submitting = ref(false)
|
||
const tasks = ref<TaskProgress[]>([])
|
||
|
||
// 检查是否需要显示提醒
|
||
const checkAndShow = async () => {
|
||
// 检查今天是否已填写
|
||
const today = dayjs().format('YYYY-MM-DD')
|
||
const lastUpdateDate = localStorage.getItem('lastProgressUpdateDate')
|
||
|
||
if (lastUpdateDate === today) {
|
||
return // 今天已填写,不再提醒
|
||
}
|
||
|
||
// 检查当前时间是否在17:30之后
|
||
const currentTime = dayjs()
|
||
const currentHour = currentTime.hour()
|
||
const currentMinute = currentTime.minute()
|
||
|
||
// 判断是否在17:30之后
|
||
if (currentHour < 17 || (currentHour === 17 && currentMinute < 30)) {
|
||
return // 还未到17:30,不提醒
|
||
}
|
||
|
||
// 加载进行中的任务
|
||
await loadInProgressTasks()
|
||
}
|
||
|
||
// 加载进行中的任务
|
||
const loadInProgressTasks = async () => {
|
||
loading.value = true
|
||
visible.value = true
|
||
|
||
try {
|
||
const response = await taskApi.getMyInProgressTasks()
|
||
if (response.code === 200) {
|
||
const taskList = response.data || []
|
||
tasks.value = taskList.map((task: any) => ({
|
||
...task,
|
||
newProgress: task.progress || 0,
|
||
progressRemark: ''
|
||
}))
|
||
}
|
||
} catch (error) {
|
||
console.error('加载任务失败:', error)
|
||
message.error('加载任务列表失败')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 格式化日期
|
||
const formatDate = (date: string | undefined) => {
|
||
if (!date) return '--'
|
||
return dayjs(date).format('YYYY-MM-DD HH:mm')
|
||
}
|
||
|
||
// 处理无任务的确认
|
||
const handleNoTasksConfirm = () => {
|
||
const today = dayjs().format('YYYY-MM-DD')
|
||
localStorage.setItem('lastProgressUpdateDate', today)
|
||
visible.value = false
|
||
message.success('确认成功')
|
||
}
|
||
|
||
// 关闭弹窗
|
||
const handleClose = () => {
|
||
visible.value = false
|
||
}
|
||
|
||
// 稍后提醒(跳过本次)
|
||
const handleSkip = () => {
|
||
visible.value = false
|
||
message.info('已跳过,下次登录时将再次提醒')
|
||
}
|
||
|
||
// 提交所有任务进度
|
||
const handleSubmit = async () => {
|
||
// 验证:新进度不能小于当前进度
|
||
const hasError = tasks.value.some(task => {
|
||
if (task.newProgress < (task.progress || 0)) {
|
||
task.error = '新进度不能小于当前进度'
|
||
return true
|
||
}
|
||
task.error = ''
|
||
return false
|
||
})
|
||
|
||
if (hasError) {
|
||
message.warning('请检查所有任务进度')
|
||
return
|
||
}
|
||
|
||
// 过滤出有更新的任务
|
||
const updatedTasks = tasks.value.filter(task => task.newProgress !== task.progress)
|
||
|
||
submitting.value = true
|
||
|
||
try {
|
||
// 批量更新进度(只更新有变化的任务)
|
||
const updates = updatedTasks.map(task => ({
|
||
taskId: task.id,
|
||
progress: task.newProgress,
|
||
remark: task.progressRemark
|
||
}))
|
||
|
||
// 如果没有任何更新,直接关闭
|
||
if (updates.length === 0) {
|
||
const today = dayjs().format('YYYY-MM-DD')
|
||
localStorage.setItem('lastProgressUpdateDate', today)
|
||
message.success('已确认今日进度')
|
||
visible.value = false
|
||
return
|
||
}
|
||
|
||
const response = await taskApi.batchUpdateProgress(updates)
|
||
|
||
if (response.code === 200) {
|
||
// 记录今天已填写
|
||
const today = dayjs().format('YYYY-MM-DD')
|
||
localStorage.setItem('lastProgressUpdateDate', today)
|
||
|
||
message.success('进度更新成功!')
|
||
visible.value = false
|
||
}
|
||
} catch (error: any) {
|
||
console.error('更新进度失败:', error)
|
||
message.error(error.message || '更新进度失败')
|
||
} finally {
|
||
submitting.value = false
|
||
}
|
||
}
|
||
|
||
// 暴露方法供外部调用
|
||
defineExpose({
|
||
checkAndShow
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import '@/styles/variables.scss';
|
||
|
||
// 模态框标题
|
||
.modal-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
width: 100%;
|
||
|
||
.title-icon {
|
||
font-size: 20px;
|
||
}
|
||
|
||
.title-text {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: $text-primary;
|
||
flex: 1;
|
||
}
|
||
|
||
.skip-btn {
|
||
color: $text-tertiary;
|
||
font-size: 13px;
|
||
height: auto;
|
||
padding: 4px 12px;
|
||
|
||
&:hover {
|
||
color: $text-secondary;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
}
|
||
}
|
||
}
|
||
|
||
.daily-progress-reminder {
|
||
// 提示横幅
|
||
.reminder-banner {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
padding: 16px 20px;
|
||
background: linear-gradient(135deg, rgba(245, 158, 11, 0.12) 0%, rgba(245, 158, 11, 0.06) 100%);
|
||
border: 1px solid rgba(245, 158, 11, 0.25);
|
||
border-radius: 12px;
|
||
margin-bottom: 24px;
|
||
|
||
.banner-icon {
|
||
width: 40px;
|
||
height: 40px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(245, 158, 11, 0.15);
|
||
border-radius: 10px;
|
||
}
|
||
|
||
.banner-content {
|
||
flex: 1;
|
||
|
||
.banner-title {
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
color: $text-primary;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.banner-desc {
|
||
font-size: 13px;
|
||
color: $text-secondary;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 加载状态
|
||
.loading-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 60px 20px;
|
||
|
||
.loading-text {
|
||
margin-top: 16px;
|
||
color: $text-secondary;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
// 无任务状态
|
||
.no-tasks {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 50px 20px;
|
||
|
||
.no-tasks-icon {
|
||
width: 72px;
|
||
height: 72px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(49, 240, 139, 0.1);
|
||
border-radius: 50%;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.no-tasks-title {
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
color: $text-primary;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.no-tasks-desc {
|
||
font-size: 14px;
|
||
color: $text-secondary;
|
||
margin-bottom: 24px;
|
||
}
|
||
}
|
||
|
||
// 任务容器
|
||
.tasks-container {
|
||
max-height: 55vh;
|
||
overflow-y: auto;
|
||
padding-right: 4px;
|
||
|
||
&::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
|
||
&::-webkit-scrollbar-track {
|
||
background: rgba(255, 255, 255, 0.05);
|
||
border-radius: 3px;
|
||
}
|
||
|
||
&::-webkit-scrollbar-thumb {
|
||
background: rgba(255, 255, 255, 0.15);
|
||
border-radius: 3px;
|
||
|
||
&:hover {
|
||
background: rgba(255, 255, 255, 0.25);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 任务列表
|
||
.tasks-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
// 任务卡片
|
||
.task-card {
|
||
position: relative;
|
||
background: linear-gradient(145deg, $bg-card 0%, rgba($bg-card, 0.8) 100%);
|
||
border: 1px solid $border-primary;
|
||
border-radius: 14px;
|
||
padding: 20px 20px 20px 56px;
|
||
transition: all 0.2s ease;
|
||
|
||
&:hover {
|
||
border-color: rgba($brand-primary, 0.3);
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
// 任务序号
|
||
.task-index {
|
||
position: absolute;
|
||
left: 16px;
|
||
top: 20px;
|
||
width: 28px;
|
||
height: 28px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg, $brand-primary 0%, darken($brand-primary, 10%) 100%);
|
||
border-radius: 8px;
|
||
font-size: 13px;
|
||
font-weight: 700;
|
||
color: #000;
|
||
}
|
||
|
||
// 任务信息
|
||
.task-info {
|
||
margin-bottom: 16px;
|
||
|
||
.task-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
margin-bottom: 10px;
|
||
|
||
.task-title {
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
color: $text-primary;
|
||
line-height: 1.4;
|
||
flex: 1;
|
||
}
|
||
|
||
.task-no {
|
||
font-size: 11px;
|
||
color: $text-tertiary;
|
||
background: rgba(255, 255, 255, 0.06);
|
||
padding: 3px 8px;
|
||
border-radius: 4px;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
|
||
.task-time {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 16px;
|
||
|
||
.time-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 12px;
|
||
color: $text-tertiary;
|
||
|
||
.time-label {
|
||
color: $text-tertiary;
|
||
}
|
||
|
||
.time-value {
|
||
color: $text-secondary;
|
||
}
|
||
|
||
&.deadline {
|
||
.time-value {
|
||
color: #F59E0B;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 进度区域
|
||
.progress-section {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border-radius: 10px;
|
||
padding: 16px;
|
||
|
||
.progress-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
|
||
.progress-title {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: $text-primary;
|
||
}
|
||
|
||
.progress-hint {
|
||
font-size: 12px;
|
||
color: $brand-primary;
|
||
background: rgba($brand-primary, 0.1);
|
||
padding: 2px 10px;
|
||
border-radius: 10px;
|
||
}
|
||
}
|
||
|
||
.progress-control {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 16px;
|
||
|
||
.slider-wrapper {
|
||
flex: 1;
|
||
position: relative;
|
||
padding-bottom: 24px;
|
||
|
||
.slider-labels {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-size: 11px;
|
||
color: $text-tertiary;
|
||
|
||
.label-current {
|
||
position: absolute;
|
||
transform: translateX(-50%);
|
||
color: rgba($brand-primary, 0.8);
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
}
|
||
|
||
.input-wrapper {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
|
||
.input-suffix {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: $text-secondary;
|
||
}
|
||
}
|
||
}
|
||
|
||
.remark-section {
|
||
margin-top: 14px;
|
||
}
|
||
|
||
.error-tip {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
margin-top: 12px;
|
||
padding: 10px 14px;
|
||
background: rgba(239, 68, 68, 0.1);
|
||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||
border-radius: 8px;
|
||
font-size: 13px;
|
||
color: #EF4444;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 提交区域
|
||
.submit-section {
|
||
padding-top: 20px;
|
||
border-top: 1px solid $border-primary;
|
||
|
||
.submit-tip {
|
||
margin-top: 10px;
|
||
text-align: center;
|
||
font-size: 12px;
|
||
color: $text-tertiary;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 深度样式覆盖
|
||
:deep(.ant-slider) {
|
||
.ant-slider-rail {
|
||
background: rgba(255, 255, 255, 0.1);
|
||
height: 8px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.ant-slider-track {
|
||
background: linear-gradient(90deg, $brand-primary 0%, lighten($brand-primary, 10%) 100%);
|
||
height: 8px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.ant-slider-handle {
|
||
width: 20px;
|
||
height: 20px;
|
||
margin-top: -6px;
|
||
background: $brand-primary;
|
||
border: 3px solid #fff;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||
|
||
&:hover, &:focus {
|
||
border-color: #fff;
|
||
box-shadow: 0 2px 12px rgba($brand-primary, 0.5);
|
||
}
|
||
}
|
||
|
||
.ant-slider-dot {
|
||
display: none;
|
||
}
|
||
|
||
.ant-slider-mark {
|
||
display: none;
|
||
}
|
||
}
|
||
|
||
:deep(.ant-input-number) {
|
||
width: 72px;
|
||
background: rgba(255, 255, 255, 0.06);
|
||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||
border-radius: 8px;
|
||
|
||
.ant-input-number-input {
|
||
color: $text-primary;
|
||
font-weight: 600;
|
||
font-size: 15px;
|
||
text-align: center;
|
||
}
|
||
|
||
.ant-input-number-handler-wrap {
|
||
background: rgba(255, 255, 255, 0.06);
|
||
border-left: 1px solid rgba(255, 255, 255, 0.1);
|
||
|
||
.ant-input-number-handler {
|
||
border-color: rgba(255, 255, 255, 0.1);
|
||
|
||
.ant-input-number-handler-up-inner,
|
||
.ant-input-number-handler-down-inner {
|
||
color: $text-secondary;
|
||
}
|
||
|
||
&:hover {
|
||
.ant-input-number-handler-up-inner,
|
||
.ant-input-number-handler-down-inner {
|
||
color: $brand-primary;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
&:hover, &:focus {
|
||
border-color: rgba($brand-primary, 0.5);
|
||
}
|
||
}
|
||
|
||
:deep(.ant-input) {
|
||
background: rgba(255, 255, 255, 0.04);
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
border-radius: 8px;
|
||
color: $text-primary;
|
||
|
||
&::placeholder {
|
||
color: $text-tertiary;
|
||
}
|
||
|
||
&:hover {
|
||
border-color: rgba(255, 255, 255, 0.2);
|
||
}
|
||
|
||
&:focus {
|
||
border-color: rgba($brand-primary, 0.5);
|
||
box-shadow: 0 0 0 2px rgba($brand-primary, 0.1);
|
||
}
|
||
}
|
||
|
||
:deep(.ant-input-textarea) {
|
||
.ant-input {
|
||
background: rgba(255, 255, 255, 0.04);
|
||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
border-radius: 8px;
|
||
color: $text-primary;
|
||
resize: none;
|
||
|
||
&::placeholder {
|
||
color: $text-tertiary;
|
||
}
|
||
|
||
&:hover {
|
||
border-color: rgba(255, 255, 255, 0.2);
|
||
}
|
||
|
||
&:focus {
|
||
border-color: rgba($brand-primary, 0.5);
|
||
box-shadow: 0 0 0 2px rgba($brand-primary, 0.1);
|
||
}
|
||
}
|
||
|
||
.ant-input-data-count {
|
||
color: $text-tertiary;
|
||
font-size: 11px;
|
||
}
|
||
}
|
||
|
||
:deep(.ant-spin) {
|
||
.ant-spin-dot-item {
|
||
background-color: $brand-primary;
|
||
}
|
||
}
|
||
|
||
:deep(.ant-btn-primary) {
|
||
height: 48px;
|
||
font-size: 15px;
|
||
font-weight: 600;
|
||
border-radius: 10px;
|
||
background: linear-gradient(135deg, $brand-primary 0%, darken($brand-primary, 8%) 100%);
|
||
border: none;
|
||
|
||
&:hover {
|
||
background: linear-gradient(135deg, lighten($brand-primary, 5%) 0%, $brand-primary 100%);
|
||
}
|
||
}
|
||
</style>
|
||
|
||
<style lang="scss">
|
||
// 全局模态框样式
|
||
.daily-progress-modal {
|
||
.ant-modal-content {
|
||
background: #1a1a1a;
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 16px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.ant-modal-header {
|
||
background: transparent;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||
padding: 20px 24px;
|
||
}
|
||
|
||
.ant-modal-title {
|
||
color: #fff;
|
||
}
|
||
|
||
.ant-modal-body {
|
||
padding: 24px;
|
||
}
|
||
}
|
||
</style>
|