Merge remote-tracking branch 'origin/feature_职代会UI优化' into release_20260831

This commit is contained in:
2026-08-30 14:39:27 +08:00
38 changed files with 2484 additions and 188 deletions
@@ -111,6 +111,13 @@ public class CongressH5ServiceImpl implements CongressH5Service {
cm.file_type AS fileType, cm.file_type AS fileType,
cm.file_size AS fileSize, cm.file_size AS fileSize,
cm.create_time AS uploadTime, cm.create_time AS uploadTime,
CASE
WHEN cvi.id IS NULL THEN NULL
WHEN cvr.id IS NOT NULL THEN 'voted'
WHEN cvi.voting_start_time IS NOT NULL AND cvi.voting_start_time > NOW() THEN 'upcoming'
WHEN cvi.voting_end_time IS NOT NULL AND cvi.voting_end_time < NOW() THEN 'ended'
ELSE 'pending'
END AS voteStatus,
CASE CASE
WHEN cvi.id IS NULL THEN NULL WHEN cvi.id IS NULL THEN NULL
WHEN cvr.id IS NOT NULL THEN true WHEN cvr.id IS NOT NULL THEN true
@@ -132,8 +139,7 @@ public class CongressH5ServiceImpl implements CongressH5Service {
WHERE COALESCE(cm.deleted, 0) = 0 WHERE COALESCE(cm.deleted, 0) = 0
AND cm.type_id = @typeId AND cm.type_id = @typeId
AND (cm.session_id = @sessionId OR cm.time_id = @sessionId) AND (cm.session_id = @sessionId OR cm.time_id = @sessionId)
AND (@searchKeyword = '' OR cm.name LIKE CONCAT('%%', @searchKeyword, '%%') AND (@searchKeyword = '' OR cm.name LIKE CONCAT('%%', @searchKeyword, '%%'))
OR cm.file_name LIKE CONCAT('%%', @searchKeyword, '%%'))
AND (@fileType = '' OR FIND_IN_SET(LOWER(REPLACE(cm.file_type, '.', '')), @fileType) > 0 AND (@fileType = '' OR FIND_IN_SET(LOWER(REPLACE(cm.file_type, '.', '')), @fileType) > 0
OR FIND_IN_SET(LOWER(SUBSTRING_INDEX(cm.file_name, '.', -1)), @fileType) > 0) OR FIND_IN_SET(LOWER(SUBSTRING_INDEX(cm.file_name, '.', -1)), @fileType) > 0)
ORDER BY cm.create_time %s, cm.id DESC ORDER BY cm.create_time %s, cm.id DESC
@@ -349,6 +355,11 @@ public class CongressH5ServiceImpl implements CongressH5Service {
i.voting_type AS votingType, i.voting_type AS votingType,
i.voting_start_time AS votingStartTime, i.voting_start_time AS votingStartTime,
i.voting_end_time AS votingEndTime, i.voting_end_time AS votingEndTime,
CASE
WHEN i.voting_start_time IS NOT NULL AND i.voting_start_time > NOW() THEN 'upcoming'
WHEN i.voting_end_time IS NOT NULL AND i.voting_end_time < NOW() THEN 'ended'
ELSE 'ongoing'
END AS votingStatus,
i.voting_content AS votingContent, i.voting_content AS votingContent,
i.voting_content_item_header AS votingContentItemHeader, i.voting_content_item_header AS votingContentItemHeader,
i.voting_content_option_header AS votingContentOptionHeader, i.voting_content_option_header AS votingContentOptionHeader,
@@ -385,7 +396,14 @@ public class CongressH5ServiceImpl implements CongressH5Service {
return Result.error("投票参数不完整"); return Result.error("投票参数不完整");
} }
NutMap issue = fetchMap(""" NutMap issue = fetchMap("""
SELECT id, session_id AS sessionId, COALESCE(time_id, session_id) AS timeId SELECT id,
session_id AS sessionId,
COALESCE(time_id, session_id) AS timeId,
CASE
WHEN voting_start_time IS NOT NULL AND voting_start_time > NOW() THEN 'upcoming'
WHEN voting_end_time IS NOT NULL AND voting_end_time < NOW() THEN 'ended'
ELSE 'ongoing'
END AS votingStatus
FROM congress_voting_issue FROM congress_voting_issue
WHERE id = @issueId WHERE id = @issueId
AND session_id = @sessionId AND session_id = @sessionId
@@ -395,6 +413,12 @@ public class CongressH5ServiceImpl implements CongressH5Service {
if (issue == null) { if (issue == null) {
return Result.error("投票议题不存在"); return Result.error("投票议题不存在");
} }
if ("upcoming".equals(issue.getString("votingStatus"))) {
return Result.error("投票尚未开始");
}
if ("ended".equals(issue.getString("votingStatus"))) {
return Result.error("投票已结束,无法继续投票");
}
NutMap rep = fetchMap(""" NutMap rep = fetchMap("""
SELECT id, userId, loginName, userName, delegationId SELECT id, userId, loginName, userName, delegationId
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

@@ -6,15 +6,29 @@ layout("/layouts/platform_h5.html"){
<van-nav-bar title="职代会" left-text="返回" left-arrow @click-left="returnH5Home('apps')" placeholder fixed></van-nav-bar> <van-nav-bar title="职代会" left-text="返回" left-arrow @click-left="returnH5Home('apps')" placeholder fixed></van-nav-bar>
<div class="congress-page"> <div class="congress-page">
<div class="empty-box" v-if="!loading && timesList.length === 0"> <div v-if="loading" class="congress-skeleton">
<div class="congress-skeleton__hero">
<van-skeleton title :row="2"></van-skeleton>
</div>
<div class="congress-skeleton__list">
<div v-for="index in 5" :key="'congress-skeleton-' + index" class="congress-skeleton__card">
<van-skeleton avatar avatar-size="56px" title :row="1"></van-skeleton>
</div>
</div>
</div>
<div class="empty-box" v-else-if="timesList.length === 0">
<van-icon name="notes-o" class="empty-icon"></van-icon> <van-icon name="notes-o" class="empty-icon"></van-icon>
<p class="empty-text">暂无参与届次信息</p> <p class="empty-text">暂无参与届次信息</p>
</div> </div>
<template v-else> <template v-else>
<div class="page-header"> <div class="page-header">
<img class="page-header__bg" src="${base!}/images/congress/home/congress-hero-v8.png" alt="">
<div class="page-header__color-layer" aria-hidden="true"></div>
<div class="session-info-card"> <div class="session-info-card">
<h2 class="session-title">{{ selectedSessionName }}</h2> <h2 class="session-title">{{ selectedTimeText || selectedSessionName }}</h2>
<p class="session-subtitle">凝聚共识 · 共谋发展</p>
<button v-if="timesList.length > 1" type="button" class="header-switch-btn" @click="showTimePicker = true"> <button v-if="timesList.length > 1" type="button" class="header-switch-btn" @click="showTimePicker = true">
<span>切换届次</span> <span>切换届次</span>
<van-icon name="arrow-down" size="12"></van-icon> <van-icon name="arrow-down" size="12"></van-icon>
@@ -31,9 +45,10 @@ layout("/layouts/platform_h5.html"){
:class="resolveTheme(module.name)" :class="resolveTheme(module.name)"
@click="handleModuleClick(module)" @click="handleModuleClick(module)"
> >
<img class="module-card__bg" :src="module.background" alt="">
<div class="module-header"> <div class="module-header">
<div class="icon-wrapper"> <div class="icon-wrapper">
<van-icon :name="module.icon" size="36"></van-icon> <img :src="module.image" :alt="module.name">
</div> </div>
<div class="module-info"> <div class="module-info">
<h4 class="module-title">{{ module.name }}</h4> <h4 class="module-title">{{ module.name }}</h4>
@@ -85,7 +100,6 @@ layout("/layouts/platform_h5.html"){
}, },
methods: { methods: {
async initPage() { async initPage() {
const loading = this.$toast.loading({message: "加载中...", forbidClick: true, duration: 0})
try { try {
await this.fetchRepTimes() await this.fetchRepTimes()
if (this.timesList.length > 0) { if (this.timesList.length > 0) {
@@ -95,7 +109,6 @@ layout("/layouts/platform_h5.html"){
} }
} finally { } finally {
this.loading = false this.loading = false
loading.close()
} }
}, },
loginName() { loginName() {
@@ -121,14 +134,16 @@ layout("/layouts/platform_h5.html"){
const modules = (res.data || []).map((item) => ({ const modules = (res.data || []).map((item) => ({
id: item.id, id: item.id,
name: item.name, name: item.name,
icon: this.resolveIcon(item.name), image: this.resolveImage(item.name),
background: this.resolveBackground(item.name),
desc: this.resolveDesc(item.name) desc: this.resolveDesc(item.name)
})) }))
const hasSignin = modules.some((item) => item.name && item.name.indexOf("会议签到") > -1) const hasSignin = modules.some((item) => item.name && item.name.indexOf("会议签到") > -1)
this.moduleList = hasSignin ? modules : [{ this.moduleList = hasSignin ? modules : [{
id: "signin", id: "signin",
name: "会议签到", name: "会议签到",
icon: "completed", image: this.resolveImage("会议签到"),
background: this.resolveBackground("会议签到"),
desc: "点击进行会议签到" desc: "点击进行会议签到"
}].concat(modules) }].concat(modules)
}, },
@@ -184,15 +199,23 @@ layout("/layouts/platform_h5.html"){
"&timeId=" + encodeURIComponent(this.selectedTimeId) + "&timeId=" + encodeURIComponent(this.selectedTimeId) +
"&sessionId=" + encodeURIComponent(this.selectedSessionId)) "&sessionId=" + encodeURIComponent(this.selectedSessionId))
}, },
resolveIcon(name) { resolveImage(name) {
if (!name) return "orders-o" const imageRoot = "${base!}/images/congress/home/"
if (name.indexOf("会议签到") > -1) return "completed" if (!name) return imageRoot + "file-notice-v4.png"
if (name.indexOf("评议") > -1) return "star" if (name.indexOf("会议签到") > -1) return imageRoot + "meeting-sign-v4.png"
if (name.indexOf("议") > -1) return "todo-list" if (name.indexOf("议") > -1) return imageRoot + "evaluation-vote-v4.png"
if (name.indexOf("资料") > -1) return "notes" if (name.indexOf("议题") > -1) return imageRoot + "topic-vote-v4.png"
if (name.indexOf("公告") > -1 || name.indexOf("结果") > -1) return "bell" if (name.indexOf("表决公告") > -1 || name.indexOf("结果") > -1) return imageRoot + "vote-notice-v4.png"
if (name.indexOf("文件") > -1) return "description" return imageRoot + "file-notice-v4.png"
return "orders" },
resolveBackground(name) {
const imageRoot = "${base!}/images/congress/home/"
if (!name) return imageRoot + "file-notice-bg-v1.png"
if (name.indexOf("会议签到") > -1) return imageRoot + "meeting-sign-bg-v1.png"
if (name.indexOf("评议") > -1) return imageRoot + "evaluation-vote-bg-v1.png"
if (name.indexOf("议题") > -1) return imageRoot + "topic-vote-bg-v1.png"
if (name.indexOf("表决公告") > -1 || name.indexOf("结果") > -1) return imageRoot + "vote-notice-bg-v1.png"
return imageRoot + "file-notice-bg-v1.png"
}, },
resolveDesc(name) { resolveDesc(name) {
if (!name) return "" if (!name) return ""
@@ -223,18 +246,74 @@ layout("/layouts/platform_h5.html"){
<style id="style-congress-h5"> <style id="style-congress-h5">
.congress-page { .congress-page {
height: calc(100vh - 46px); height: calc(100vh - 46px);
background: #f4f8ff; background: #f3f7fd;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.congress-skeleton {
flex: 1;
min-height: 0;
overflow: hidden;
background: #f3f7fd;
}
.congress-skeleton__hero {
height: 220px;
padding: 0 24px;
display: flex;
align-items: center;
box-sizing: border-box;
background: #e8eef7;
}
.congress-skeleton__hero .van-skeleton {
width: 52%;
padding: 0;
}
.congress-skeleton__list {
padding: 12px;
display: grid;
gap: 12px;
box-sizing: border-box;
}
.congress-skeleton__card {
min-height: 104px;
padding: 18px 16px;
display: flex;
align-items: center;
box-sizing: border-box;
border: 1px solid #e5edf8;
border-radius: 12px;
background: #fff;
box-shadow: 0 7px 20px rgba(55, 85, 126, 0.06);
}
.congress-skeleton__card .van-skeleton {
width: 100%;
padding: 0;
}
#app > .van-nav-bar .van-nav-bar__title {
color: #1f2937;
font-size: 16px;
font-weight: 600;
}
#app > .van-nav-bar .van-icon,
#app > .van-nav-bar .van-nav-bar__text {
color: #1989fa;
}
.page-header { .page-header {
min-height: 192px; min-height: 220px;
background: #1686ff url("${base!}/images/congress/h5-congress-header.png") center center / cover no-repeat; background-color: #1458ad;
padding: 0px 15px 50px; padding: 18px 24px 24px;
box-sizing: border-box;
color: #fff; color: #fff;
box-shadow: 0 12px 28px rgba(25, 137, 250, 0.18);
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
@@ -243,6 +322,30 @@ layout("/layouts/platform_h5.html"){
flex-shrink: 0; flex-shrink: 0;
} }
.page-header__bg {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: 88% center;
display: block;
}
.page-header__color-layer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 64%;
z-index: 1;
pointer-events: none;
background: linear-gradient(90deg,
rgba(22, 112, 232, 0.98) 0%,
rgba(22, 112, 232, 0.88) 52%,
rgba(22, 112, 232, 0) 100%);
}
.session-info-card { .session-info-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -250,34 +353,41 @@ layout("/layouts/platform_h5.html"){
text-align: left; text-align: left;
position: relative; position: relative;
z-index: 3; z-index: 3;
max-width: 50%; max-width: 52%;
} }
.session-title { .session-title {
font-size: 25px; font-size: 25px;
font-weight: 700; font-weight: 700;
line-height: 1.25; line-height: 1.32;
color: #fff; color: #fff;
margin: 0 0 10px; margin: 0;
text-shadow: 0 4px 12px rgba(3, 77, 168, 0.18); text-shadow: 0 3px 10px rgba(3, 77, 168, 0.2);
}
.session-subtitle {
margin: 8px 0 0;
font-size: 14px;
line-height: 1.4;
color: rgba(255, 255, 255, 0.88);
white-space: nowrap;
} }
.header-switch-btn { .header-switch-btn {
margin-top: 6px; margin-top: 15px;
height: 34px; height: 36px;
padding: 0 14px; padding: 0 15px;
border: 0; border: 1px solid rgba(255, 255, 255, 0.56);
border-radius: 18px; border-radius: 20px;
background: rgba(255, 255, 255, 0.18); background: rgba(255, 255, 255, 0.12);
color: #fff; color: #fff;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
font-size: 14px; font-size: 13px;
font-weight: 600;
line-height: 1; line-height: 1;
cursor: pointer; cursor: pointer;
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.36), 0 8px 18px rgba(0, 66, 160, 0.12); box-shadow: 0 8px 18px rgba(0, 66, 160, 0.12);
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
} }
@@ -291,9 +401,9 @@ layout("/layouts/platform_h5.html"){
z-index: 2; z-index: 2;
flex: 1; flex: 1;
min-height: 0; min-height: 0;
margin: -72px 0 0; margin: 0;
padding: 18px 16px 24px; padding: 12px 12px 24px;
background: #fff; background: #f3f7fd;
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
@@ -305,14 +415,18 @@ layout("/layouts/platform_h5.html"){
} }
.module-card { .module-card {
min-height: 98px; --module-color: #1989fa;
background: linear-gradient(135deg, #f8fbff 0%, #fff 100%); --module-bg: #fff;
border-radius: 14px; --module-icon-bg: #edf5ff;
box-shadow: 0 8px 18px rgba(27, 56, 105, 0.06); --module-border: #e5edf8;
min-height: 104px;
background: var(--module-bg);
border-radius: 12px;
box-shadow: 0 7px 20px rgba(55, 85, 126, 0.08);
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid rgba(237, 242, 250, 0.88); border: 1px solid var(--module-border);
position: relative; position: relative;
} }
@@ -325,25 +439,49 @@ layout("/layouts/platform_h5.html"){
box-shadow: 0 4px 16px rgba(25, 137, 250, 0.08); box-shadow: 0 4px 16px rgba(25, 137, 250, 0.08);
} }
.module-card__bg {
position: absolute;
top: 50%;
right: 38px;
z-index: 0;
width: 42%;
height: 88%;
display: block;
object-fit: contain;
object-position: right center;
opacity: 1;
pointer-events: none;
transform: translateY(-50%);
}
.module-header { .module-header {
min-height: 60px; min-height: 72px;
padding: 14px; padding: 16px 15px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 14px;
position: relative;
z-index: 2;
} }
.icon-wrapper { .icon-wrapper {
width: 54px; width: 58px;
height: 54px; height: 58px;
border-radius: 16px; border-radius: 14px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: #eef5ff;
flex-shrink: 0; flex-shrink: 0;
box-shadow: 0 8px 18px rgba(25, 137, 250, 0.1); overflow: hidden;
color: #1989fa; background: #eef3fb;
box-shadow: 0 4px 12px rgba(42, 74, 117, 0.1);
}
.icon-wrapper img {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
} }
.module-info { .module-info {
@@ -352,9 +490,9 @@ layout("/layouts/platform_h5.html"){
} }
.module-title { .module-title {
font-size: 16px; font-size: 17px;
font-weight: 700; font-weight: 600;
color: #111a3a; color: #23344a;
margin: 0 0 6px; margin: 0 0 6px;
line-height: 1.4; line-height: 1.4;
overflow: hidden; overflow: hidden;
@@ -363,7 +501,7 @@ layout("/layouts/platform_h5.html"){
} }
.module-desc { .module-desc {
font-size: 12px; font-size: 13px;
color: #7d89a6; color: #7d89a6;
margin: 0; margin: 0;
line-height: 1.5; line-height: 1.5;
@@ -373,62 +511,38 @@ layout("/layouts/platform_h5.html"){
} }
.arrow-icon { .arrow-icon {
width: 26px; width: 16px;
height: 26px; min-width: 16px;
border-radius: 50%; height: 16px;
display: flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 16px;
color: #1989fa;
background: rgba(25, 137, 250, 0.1);
flex-shrink: 0; flex-shrink: 0;
transition: all 0.3s ease; color: #aab6c5;
background: transparent;
font-size: 16px;
line-height: 16px;
} }
.theme-green { .theme-green {
background: linear-gradient(135deg, #f3fff9 0%, #fff 100%); --module-color: #3d9182;
} --module-bg: #fff;
--module-icon-bg: #edf6f3;
.theme-green .icon-wrapper { --module-border: #e4eee9;
color: #17c979;
background: #eafbf2;
box-shadow: 0 8px 18px rgba(23, 201, 121, 0.12);
}
.theme-green .arrow-icon {
color: #17b977;
background: rgba(23, 201, 121, 0.12);
} }
.theme-purple { .theme-purple {
background: linear-gradient(135deg, #fbf7ff 0%, #fff 100%); --module-color: #6c6fa3;
} --module-bg: #fff;
--module-icon-bg: #f0f0f7;
.theme-purple .icon-wrapper { --module-border: #e9e7f1;
color: #8756e9;
background: #f1eaff;
box-shadow: 0 8px 18px rgba(135, 86, 233, 0.12);
}
.theme-purple .arrow-icon {
color: #8756e9;
background: rgba(135, 86, 233, 0.12);
} }
.theme-orange { .theme-orange {
background: linear-gradient(135deg, #fff8ed 0%, #fff 100%); --module-color: #a78345;
} --module-bg: #fff;
--module-icon-bg: #f7f2e9;
.theme-orange .icon-wrapper { --module-border: #eee9df;
color: #ff9f1a;
background: #fff2df;
box-shadow: 0 8px 18px rgba(255, 159, 26, 0.12);
}
.theme-orange .arrow-icon {
color: #d9a05b;
background: rgba(255, 159, 26, 0.12);
} }
.empty-box { .empty-box {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -16,7 +16,7 @@ layout("/layouts/platform_h5.html"){
</div> </div>
<div v-if="voteInfo" class="footer-bar"> <div v-if="voteInfo" class="footer-bar">
<van-button type="primary" block @click="handleVoteClick">{{ isVoted(voteInfo.voted) ? '查看投票' : '投票' }}</van-button> <van-button type="primary" block :disabled="voteDisabled" @click="handleVoteClick">{{ voteButtonText }}</van-button>
</div> </div>
</div> </div>
</div> </div>
@@ -45,6 +45,20 @@ layout("/layouts/platform_h5.html"){
const source = name.indexOf(".") > -1 ? name : url const source = name.indexOf(".") > -1 ? name : url
const index = source.lastIndexOf(".") const index = source.lastIndexOf(".")
return index > -1 ? source.substring(index + 1).toLowerCase() : "" return index > -1 ? source.substring(index + 1).toLowerCase() : ""
},
voteState() {
if (!this.voteInfo) return ""
if (this.isVoted(this.voteInfo.voted)) return "voted"
return this.voteInfo.votingStatus || "ongoing"
},
voteDisabled() {
return this.voteState === "upcoming" || this.voteState === "ended"
},
voteButtonText() {
if (this.voteState === "voted") return "查看投票"
if (this.voteState === "upcoming") return "投票未开始"
if (this.voteState === "ended") return "投票已结束"
return "投票"
} }
}, },
methods: { methods: {
@@ -159,6 +173,14 @@ layout("/layouts/platform_h5.html"){
this.$toast("投票信息未加载") this.$toast("投票信息未加载")
return return
} }
if (this.voteState === "upcoming") {
this.$toast("投票尚未开始")
return
}
if (this.voteState === "ended") {
this.$toast("投票已结束,无法继续投票")
return
}
window.localStorage.setItem("voteInfo", JSON.stringify(this.voteInfo)) window.localStorage.setItem("voteInfo", JSON.stringify(this.voteInfo))
this.$pjaxReplace(this.isVoted(this.voteInfo.voted) ? "/platform/h5/congress/voted" : "/platform/h5/congress/vote") this.$pjaxReplace(this.isVoted(this.voteInfo.voted) ? "/platform/h5/congress/voted" : "/platform/h5/congress/vote")
}, },
@@ -247,6 +269,13 @@ layout("/layouts/platform_h5.html"){
font-weight: 600; font-weight: 600;
box-shadow: 0 4px 12px rgba(25, 137, 250, 0.3); box-shadow: 0 4px 12px rgba(25, 137, 250, 0.3);
} }
.footer-bar .van-button.van-button--disabled {
color: #fff;
background: #b8c1cc;
box-shadow: none;
opacity: 1;
}
</style> </style>
<!--# <!--#
@@ -157,6 +157,14 @@ layout("/layouts/platform_h5.html"){
return Math.ceil(item.options.length / 2) return Math.ceil(item.options.length / 2)
}, },
submitVote() { submitVote() {
if (this.voteInfo.votingStatus === "upcoming") {
this.$toast("投票尚未开始")
return
}
if (this.voteInfo.votingStatus === "ended") {
this.$toast("投票已结束,无法继续投票")
return
}
const missing = this.voteItems.filter((_, index) => !this.selectedVotes[index]) const missing = this.voteItems.filter((_, index) => !this.selectedVotes[index])
if (missing.length > 0) { if (missing.length > 0) {
this.$toast("请完成所有投票项的选择") this.$toast("请完成所有投票项的选择")