Merge remote-tracking branch 'origin/master_develop' into master_develop
This commit is contained in:
commit
ee9a519d57
@ -10,10 +10,12 @@ import com.lesingle.common.result.PageResult;
|
||||
import com.lesingle.modules.biz.contest.entity.BizContest;
|
||||
import com.lesingle.modules.biz.contest.entity.BizContestAttachment;
|
||||
import com.lesingle.modules.biz.contest.entity.BizContestNotice;
|
||||
import com.lesingle.modules.biz.contest.entity.BizContestNoticeAttachment;
|
||||
import com.lesingle.modules.biz.contest.entity.BizContestRegistration;
|
||||
import com.lesingle.modules.biz.contest.entity.BizContestWork;
|
||||
import com.lesingle.modules.biz.contest.mapper.ContestAttachmentMapper;
|
||||
import com.lesingle.modules.biz.contest.mapper.ContestMapper;
|
||||
import com.lesingle.modules.biz.contest.mapper.ContestNoticeAttachmentMapper;
|
||||
import com.lesingle.modules.biz.contest.mapper.ContestNoticeMapper;
|
||||
import com.lesingle.modules.biz.contest.mapper.ContestRegistrationMapper;
|
||||
import com.lesingle.modules.biz.contest.mapper.ContestWorkMapper;
|
||||
@ -50,6 +52,7 @@ public class PublicActivityService {
|
||||
private final UgcWorkMapper ugcWorkMapper;
|
||||
private final UgcWorkPageMapper ugcWorkPageMapper;
|
||||
private final ContestNoticeMapper contestNoticeMapper;
|
||||
private final ContestNoticeAttachmentMapper contestNoticeAttachmentMapper;
|
||||
private final ContestAttachmentMapper contestAttachmentMapper;
|
||||
private final SysUserMapper sysUserMapper;
|
||||
|
||||
@ -163,6 +166,31 @@ public class PublicActivityService {
|
||||
m.put("createTime", n.getCreateTime());
|
||||
list.add(m);
|
||||
}
|
||||
if (!rows.isEmpty()) {
|
||||
List<Long> noticeIds = rows.stream().map(BizContestNotice::getId).filter(Objects::nonNull).toList();
|
||||
LambdaQueryWrapper<BizContestNoticeAttachment> attw = new LambdaQueryWrapper<>();
|
||||
attw.in(BizContestNoticeAttachment::getNoticeId, noticeIds);
|
||||
attw.orderByAsc(BizContestNoticeAttachment::getCreateTime);
|
||||
List<BizContestNoticeAttachment> attRows = contestNoticeAttachmentMapper.selectList(attw);
|
||||
Map<Long, List<BizContestNoticeAttachment>> byNotice = attRows.stream()
|
||||
.collect(Collectors.groupingBy(BizContestNoticeAttachment::getNoticeId));
|
||||
for (Map<String, Object> m : list) {
|
||||
Long nid = (Long) m.get("id");
|
||||
List<BizContestNoticeAttachment> nas = byNotice.getOrDefault(nid, Collections.emptyList());
|
||||
List<Map<String, Object>> attList = new ArrayList<>();
|
||||
for (BizContestNoticeAttachment a : nas) {
|
||||
Map<String, Object> am = new LinkedHashMap<>();
|
||||
am.put("id", a.getId());
|
||||
am.put("fileName", a.getFileName());
|
||||
am.put("fileUrl", a.getFileUrl());
|
||||
am.put("fileType", a.getFileType());
|
||||
am.put("format", a.getFormat());
|
||||
am.put("size", a.getSize());
|
||||
attList.add(am);
|
||||
}
|
||||
m.put("attachments", attList);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@ -289,6 +289,15 @@ export interface PublicActivity {
|
||||
workRequirement: string;
|
||||
}
|
||||
|
||||
export interface PublicActivityAttachment {
|
||||
id: number;
|
||||
fileName: string;
|
||||
fileUrl: string;
|
||||
fileType?: string;
|
||||
format?: string;
|
||||
size?: string;
|
||||
}
|
||||
|
||||
/** 公众端活动详情(含公告、附件等扩展字段) */
|
||||
export interface PublicActivityNotice {
|
||||
id: number;
|
||||
@ -297,15 +306,8 @@ export interface PublicActivityNotice {
|
||||
noticeType?: string;
|
||||
publishTime?: string;
|
||||
createTime?: string;
|
||||
}
|
||||
|
||||
export interface PublicActivityAttachment {
|
||||
id: number;
|
||||
fileName: string;
|
||||
fileUrl: string;
|
||||
fileType?: string;
|
||||
format?: string;
|
||||
size?: string;
|
||||
/** 公告附件(公众活动详情接口填充,与活动附件字段一致) */
|
||||
attachments?: PublicActivityAttachment[];
|
||||
}
|
||||
|
||||
export interface PublicActivityDetail extends PublicActivity {
|
||||
|
||||
@ -4,15 +4,12 @@
|
||||
<!-- 顶部海报区域 -->
|
||||
<div class="hero-section">
|
||||
<!-- 背景图 -->
|
||||
<div
|
||||
class="hero-bg"
|
||||
:style="{
|
||||
backgroundImage:
|
||||
contest?.posterUrl || contest?.coverUrl
|
||||
? `url(${contest.posterUrl || contest.coverUrl})`
|
||||
: undefined,
|
||||
}"
|
||||
>
|
||||
<div class="hero-bg" :style="{
|
||||
backgroundImage:
|
||||
contest?.posterUrl || contest?.coverUrl
|
||||
? `url(${contest.posterUrl || contest.coverUrl})`
|
||||
: undefined,
|
||||
}">
|
||||
<div class="hero-overlay"></div>
|
||||
</div>
|
||||
|
||||
@ -46,43 +43,29 @@
|
||||
<div class="hero-meta">
|
||||
<div class="meta-item">
|
||||
<CalendarOutlined />
|
||||
<span
|
||||
>活动时间:{{ formatDate(contest?.startTime) }} ~
|
||||
{{ formatDate(contest?.endTime) }}</span
|
||||
>
|
||||
<span>活动时间:{{ formatDate(contest?.startTime) }} ~
|
||||
{{ formatDate(contest?.endTime) }}</span>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<ClockCircleOutlined />
|
||||
<span
|
||||
>报名时间:{{ formatDate(contest?.registerStartTime) }} ~
|
||||
{{ formatDate(contest?.registerEndTime) }}</span
|
||||
>
|
||||
<span>报名时间:{{ formatDate(contest?.registerStartTime) }} ~
|
||||
{{ formatDate(contest?.registerEndTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 报名按钮 -->
|
||||
<div class="hero-actions">
|
||||
<button
|
||||
v-if="isTeacher && isRegistering && !hasRegistered"
|
||||
class="action-btn primary"
|
||||
@click="handleRegister"
|
||||
>
|
||||
<button v-if="isTeacher && isRegistering && !hasRegistered" class="action-btn primary"
|
||||
@click="handleRegister">
|
||||
<FormOutlined />
|
||||
立即报名
|
||||
</button>
|
||||
<button
|
||||
v-else-if="isTeacher && hasRegistered && canViewRegistration"
|
||||
class="action-btn secondary"
|
||||
@click="handleViewRegistration"
|
||||
>
|
||||
<button v-else-if="isTeacher && hasRegistered && canViewRegistration" class="action-btn secondary"
|
||||
@click="handleViewRegistration">
|
||||
<EyeOutlined />
|
||||
查看报名
|
||||
</button>
|
||||
<button
|
||||
v-else-if="isTeacher"
|
||||
class="action-btn disabled"
|
||||
disabled
|
||||
>
|
||||
<button v-else-if="isTeacher" class="action-btn disabled" disabled>
|
||||
<FormOutlined />
|
||||
{{ isRegistering ? "立即报名" : "报名已截止" }}
|
||||
</button>
|
||||
@ -98,30 +81,18 @@
|
||||
<div class="tab-section">
|
||||
<div class="tab-container">
|
||||
<div class="custom-tabs">
|
||||
<div
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === 'info' }"
|
||||
@click="handleTabChange('info')"
|
||||
>
|
||||
<div class="tab-item" :class="{ active: activeTab === 'info' }" @click="handleTabChange('info')">
|
||||
<FileTextOutlined />
|
||||
<span>活动信息</span>
|
||||
</div>
|
||||
<div
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === 'notices' }"
|
||||
@click="handleTabChange('notices')"
|
||||
>
|
||||
<div class="tab-item" :class="{ active: activeTab === 'notices' }" @click="handleTabChange('notices')">
|
||||
<BellOutlined />
|
||||
<span>通知公告</span>
|
||||
<span v-if="notices.length > 0" class="badge">{{
|
||||
notices.length
|
||||
}}</span>
|
||||
</div>
|
||||
<div
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === 'results' }"
|
||||
@click="handleTabChange('results')"
|
||||
>
|
||||
<div class="tab-item" :class="{ active: activeTab === 'results' }" @click="handleTabChange('results')">
|
||||
<TrophyOutlined />
|
||||
<span>活动结果</span>
|
||||
</div>
|
||||
@ -144,11 +115,7 @@
|
||||
<h2>竞赛详情</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div
|
||||
v-if="contest.content"
|
||||
class="rich-content"
|
||||
v-html="contest.content"
|
||||
></div>
|
||||
<div v-if="contest.content" class="rich-content" v-html="contest.content"></div>
|
||||
<a-empty v-else description="暂无详情内容" />
|
||||
</div>
|
||||
</div>
|
||||
@ -165,18 +132,11 @@
|
||||
<div v-if="noticesLoading" class="loading-placeholder">
|
||||
<a-spin />
|
||||
</div>
|
||||
<div
|
||||
v-else-if="notices.length === 0"
|
||||
class="empty-placeholder"
|
||||
>
|
||||
<div v-else-if="notices.length === 0" class="empty-placeholder">
|
||||
<a-empty description="暂无公告" />
|
||||
</div>
|
||||
<div v-else class="notice-list">
|
||||
<div
|
||||
v-for="item in notices"
|
||||
:key="item.id"
|
||||
class="notice-item"
|
||||
>
|
||||
<div v-for="item in notices" :key="item.id" class="notice-item">
|
||||
<div class="notice-header">
|
||||
<span class="notice-title">{{ item.title }}</span>
|
||||
<span class="notice-type" :class="item.noticeType">
|
||||
@ -184,6 +144,15 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="notice-content">{{ item.content }}</div>
|
||||
<div v-if="item.attachments?.length" class="notice-attachments-block">
|
||||
<div class="notice-attachments-title">公告附件</div>
|
||||
<div v-for="na in item.attachments" :key="na.id" class="notice-att-link">
|
||||
<a :href="na.fileUrl" target="_blank" rel="noopener noreferrer">
|
||||
<PaperClipOutlined />
|
||||
{{ na.fileName }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-time">
|
||||
<ClockCircleOutlined />
|
||||
{{ formatDateTime(item.publishTime) }}
|
||||
@ -204,19 +173,11 @@
|
||||
<div class="card-body">
|
||||
<div v-if="contest.resultState === 'published'">
|
||||
<a-spin :spinning="resultsLoading">
|
||||
<a-table
|
||||
:columns="resultColumns"
|
||||
:data-source="results"
|
||||
:pagination="resultsPagination"
|
||||
row-key="id"
|
||||
@change="handleResultsTableChange"
|
||||
>
|
||||
<a-table :columns="resultColumns" :data-source="results" :pagination="resultsPagination"
|
||||
row-key="id" @change="handleResultsTableChange">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'rank'">
|
||||
<div
|
||||
class="rank-badge"
|
||||
:class="getRankClass(record.rank)"
|
||||
>
|
||||
<div class="rank-badge" :class="getRankClass(record.rank)">
|
||||
{{ record.rank || "-" }}
|
||||
</div>
|
||||
</template>
|
||||
@ -228,11 +189,7 @@
|
||||
}}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'award'">
|
||||
<span
|
||||
v-if="record.awardName"
|
||||
class="award-tag"
|
||||
:class="getAwardClass(record.awardName)"
|
||||
>
|
||||
<span v-if="record.awardName" class="award-tag" :class="getAwardClass(record.awardName)">
|
||||
{{ record.awardName }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
@ -265,20 +222,14 @@
|
||||
{{ getVisibilityText(contest?.visibility) }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="contest?.visibility === 'designated' && contest?.contestTenantInfos?.length"
|
||||
class="sidebar-item"
|
||||
>
|
||||
<div v-if="contest?.visibility === 'designated' && contest?.contestTenantInfos?.length"
|
||||
class="sidebar-item">
|
||||
<div class="item-label">
|
||||
<TeamOutlined />
|
||||
开放机构
|
||||
</div>
|
||||
<div class="item-value">
|
||||
<div
|
||||
v-for="tenant in contest.contestTenantInfos"
|
||||
:key="tenant.id"
|
||||
class="org-name"
|
||||
>
|
||||
<div v-for="tenant in contest.contestTenantInfos" :key="tenant.id" class="org-name">
|
||||
{{ tenant.name }}({{ tenant.code }})
|
||||
</div>
|
||||
</div>
|
||||
@ -301,6 +252,20 @@
|
||||
{{ formatDateTime(contest?.createTime) }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="contest.attachments?.length" class="sidebar-item">
|
||||
<div class="item-label">
|
||||
<PaperClipOutlined />
|
||||
活动附件
|
||||
</div>
|
||||
<div class="item-value">
|
||||
<div v-for="att in contest.attachments" :key="att.id" class="contest-attachment-link">
|
||||
<a :href="att.fileUrl" target="_blank" rel="noopener noreferrer">
|
||||
<PaperClipOutlined />
|
||||
{{ att.fileName }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -318,11 +283,7 @@
|
||||
<div class="item-value">
|
||||
<template v-if="contest.organizers">
|
||||
<template v-if="Array.isArray(contest.organizers)">
|
||||
<div
|
||||
v-for="org in contest.organizers"
|
||||
:key="org"
|
||||
class="org-name"
|
||||
>
|
||||
<div v-for="org in contest.organizers" :key="org" class="org-name">
|
||||
{{ org }}
|
||||
</div>
|
||||
</template>
|
||||
@ -342,11 +303,7 @@
|
||||
<div class="item-value">
|
||||
<template v-if="contest.coOrganizers">
|
||||
<template v-if="Array.isArray(contest.coOrganizers)">
|
||||
<div
|
||||
v-for="org in contest.coOrganizers"
|
||||
:key="org"
|
||||
class="org-name"
|
||||
>
|
||||
<div v-for="org in contest.coOrganizers" :key="org" class="org-name">
|
||||
{{ org }}
|
||||
</div>
|
||||
</template>
|
||||
@ -366,11 +323,7 @@
|
||||
<div class="item-value">
|
||||
<template v-if="contest.sponsors">
|
||||
<template v-if="Array.isArray(contest.sponsors)">
|
||||
<div
|
||||
v-for="sp in contest.sponsors"
|
||||
:key="sp"
|
||||
class="org-name"
|
||||
>
|
||||
<div v-for="sp in contest.sponsors" :key="sp" class="org-name">
|
||||
{{ sp }}
|
||||
</div>
|
||||
</template>
|
||||
@ -381,14 +334,12 @@
|
||||
<span v-else class="empty-text">暂无</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 联系方式 -->
|
||||
<div
|
||||
v-if="contest.contactName || contest.contactPhone"
|
||||
class="sidebar-card"
|
||||
>
|
||||
<div v-if="contest.contactName || contest.contactPhone" class="sidebar-card">
|
||||
<div class="sidebar-header">
|
||||
<PhoneOutlined />
|
||||
<span>联系方式</span>
|
||||
@ -415,11 +366,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-empty
|
||||
v-else-if="!loading"
|
||||
description="活动不存在"
|
||||
style="padding: 100px 0"
|
||||
/>
|
||||
<a-empty v-else-if="!loading" description="活动不存在" style="padding: 100px 0" />
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
@ -445,6 +392,7 @@ import {
|
||||
UserOutlined,
|
||||
GlobalOutlined,
|
||||
InfoCircleOutlined,
|
||||
PaperClipOutlined,
|
||||
} from "@ant-design/icons-vue"
|
||||
import dayjs from "dayjs"
|
||||
import { useAuthStore } from "@/stores/auth"
|
||||
@ -731,11 +679,9 @@ $primary-dark: #0958d9;
|
||||
.hero-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0.3) 0%,
|
||||
rgba(0, 0, 0, 0.6) 100%
|
||||
);
|
||||
background: linear-gradient(180deg,
|
||||
rgba(0, 0, 0, 0.3) 0%,
|
||||
rgba(0, 0, 0, 0.6) 100%);
|
||||
}
|
||||
|
||||
.hero-nav {
|
||||
@ -800,12 +746,15 @@ $primary-dark: #0958d9;
|
||||
.tag-registering {
|
||||
background: linear-gradient(135deg, #52c41a, #73d13d);
|
||||
}
|
||||
|
||||
.tag-submitting {
|
||||
background: linear-gradient(135deg, #1890ff, #40a9ff);
|
||||
}
|
||||
|
||||
.tag-reviewing {
|
||||
background: linear-gradient(135deg, #faad14, #ffc53d);
|
||||
}
|
||||
|
||||
.tag-finished {
|
||||
background: linear-gradient(135deg, #8c8c8c, #bfbfbf);
|
||||
}
|
||||
@ -1018,6 +967,7 @@ $primary-dark: #0958d9;
|
||||
|
||||
:deep(p) {
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@ -1033,6 +983,7 @@ $primary-dark: #0958d9;
|
||||
font-weight: 600;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
@ -1083,6 +1034,7 @@ $primary-dark: #0958d9;
|
||||
:deep(a) {
|
||||
color: $primary;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@ -1123,6 +1075,7 @@ $primary-dark: #0958d9;
|
||||
background: #fff2f0;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.system {
|
||||
background: #e6f7ff;
|
||||
color: #1890ff;
|
||||
@ -1137,6 +1090,28 @@ $primary-dark: #0958d9;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.notice-attachments-block {
|
||||
margin-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
|
||||
.notice-attachments-title {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.notice-att-link a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
color: $primary;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-time {
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
@ -1164,10 +1139,12 @@ $primary-dark: #0958d9;
|
||||
background: linear-gradient(135deg, #ffd700, #ffb800);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.rank-2 {
|
||||
background: linear-gradient(135deg, #c0c0c0, #a0a0a0);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.rank-3 {
|
||||
background: linear-gradient(135deg, #cd7f32, #b8860b);
|
||||
color: #fff;
|
||||
@ -1185,10 +1162,12 @@ $primary-dark: #0958d9;
|
||||
background: #fffbe6;
|
||||
color: #d48806;
|
||||
}
|
||||
|
||||
&.award-silver {
|
||||
background: #f5f5f5;
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
&.award-bronze {
|
||||
background: #fff7e6;
|
||||
color: #d46b08;
|
||||
@ -1212,11 +1191,9 @@ $primary-dark: #0958d9;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 16px 20px;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba($primary, 0.05),
|
||||
rgba($primary-dark, 0.08)
|
||||
);
|
||||
background: linear-gradient(135deg,
|
||||
rgba($primary, 0.05),
|
||||
rgba($primary-dark, 0.08));
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
@ -1269,6 +1246,15 @@ $primary-dark: #0958d9;
|
||||
.empty-text {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.contest-attachment-link a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: $primary;
|
||||
font-size: 13px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1299,10 +1285,12 @@ $primary-dark: #0958d9;
|
||||
.hero-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@ -147,6 +147,14 @@
|
||||
<div v-for="notice in activity.notices" :key="notice.id" class="notice-item">
|
||||
<h4>{{ notice.title }}</h4>
|
||||
<div class="notice-content" v-html="sanitizeNoticeContent(notice.content)"></div>
|
||||
<div v-if="notice.attachments?.length" class="notice-attachments">
|
||||
<div class="notice-attachments-title">公告附件</div>
|
||||
<div v-for="att in notice.attachments" :key="att.id" class="att-item">
|
||||
<a :href="att.fileUrl" target="_blank" rel="noopener noreferrer">
|
||||
<paper-clip-outlined /> {{ att.fileName }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<span class="notice-time">{{ formatNoticeTime(notice) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -262,7 +270,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 报名弹窗 -->
|
||||
<a-modal v-model:open="showRegisterModal" title="活动报名" :footer="null" :width="420">
|
||||
<a-modal v-model:open="showRegisterModal" title="活动报名" :footer="null" :width="420" centered>
|
||||
<div class="register-modal">
|
||||
<template v-if="isChildUser">
|
||||
<p class="modal-desc">将使用当前账号报名,确认参加本活动吗?</p>
|
||||
@ -1201,6 +1209,28 @@ $primary: #6366f1;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.notice-attachments {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
|
||||
.notice-attachments-title {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #6b7280;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.att-item a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
color: $primary;
|
||||
padding: 4px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-time {
|
||||
font-size: 12px;
|
||||
color: #9ca3af;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
:open="open"
|
||||
title="从作品库选择作品"
|
||||
:width="600"
|
||||
centered
|
||||
@cancel="$emit('update:open', false)"
|
||||
@ok="handleConfirm"
|
||||
:ok-button-props="{ disabled: !selectedWork }"
|
||||
|
||||
@ -68,6 +68,7 @@
|
||||
title="创建子女账号"
|
||||
:footer="null"
|
||||
:width="440"
|
||||
centered
|
||||
>
|
||||
<a-form :model="createForm" layout="vertical" @finish="handleCreate" class="child-form">
|
||||
<a-form-item label="用户名" name="username" :rules="[{ required: true, message: '请输入用户名' }, { min: 4, message: '至少4个字符' }]">
|
||||
@ -109,6 +110,7 @@
|
||||
title="编辑子女账号"
|
||||
:footer="null"
|
||||
:width="440"
|
||||
centered
|
||||
>
|
||||
<a-form :model="editForm" layout="vertical" @finish="handleEdit" class="child-form">
|
||||
<a-form-item label="昵称" name="nickname">
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 编辑个人信息弹窗 -->
|
||||
<a-modal v-model:open="showEditModal" title="编辑个人信息" :footer="null" :width="400">
|
||||
<a-modal v-model:open="showEditModal" title="编辑个人信息" :footer="null" :width="400" centered>
|
||||
<a-form layout="vertical" @finish="handleSaveProfile" style="margin-top: 16px;">
|
||||
<a-form-item label="昵称" :rules="[{ required: true, message: '请输入昵称' }]">
|
||||
<a-input v-model:value="editForm.nickname" placeholder="你的昵称" :maxlength="20" />
|
||||
|
||||
@ -158,7 +158,7 @@
|
||||
</a-spin>
|
||||
|
||||
<!-- 二次确认弹窗 -->
|
||||
<a-modal v-model:open="confirmVisible" :title="confirmTitle" :ok-text="confirmOkText" cancel-text="取消"
|
||||
<a-modal v-model:open="confirmVisible" :title="confirmTitle" :ok-text="confirmOkText" cancel-text="取消" centered
|
||||
:confirm-loading="actionLoading" @ok="handleConfirmOk" @cancel="handleConfirmCancel">
|
||||
<p>{{ confirmContent }}</p>
|
||||
</a-modal>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user