feat:职代会h5端UI优化调整
This commit is contained in:
+34
-4
@@ -37,6 +37,12 @@ public class CongressH5Controller {
|
||||
public void meetingListPage() {
|
||||
}
|
||||
|
||||
@At("/meeting/remark")
|
||||
@Ok("beetl:/platform/zhghh5/democratic/congress/meeting/remark.html")
|
||||
@SaCheckLogin
|
||||
public void meetingRemarkPage() {
|
||||
}
|
||||
|
||||
@At("/pdf")
|
||||
@Ok("beetl:/platform/zhghh5/democratic/congress/pdf.html")
|
||||
@SaCheckLogin
|
||||
@@ -69,14 +75,38 @@ public class CongressH5Controller {
|
||||
|
||||
@At("/materialsList")
|
||||
@SaCheckLogin
|
||||
public Result materialsList(@Param("typeId") String typeId, @Param("timeId") String timeId, @Param("emplid") String emplid) {
|
||||
return Result.success(congressH5Service.materialsList(typeId, timeId, emplid));
|
||||
public Result materialsList(@Param("typeId") String typeId,
|
||||
@Param("timeId") String timeId,
|
||||
@Param("emplid") String emplid,
|
||||
@Param("searchKeyword") String searchKeyword,
|
||||
@Param("fileType") String fileType,
|
||||
@Param("uploadTimeOrder") String uploadTimeOrder,
|
||||
@Param("pageNumber") Integer pageNumber,
|
||||
@Param("pageSize") Integer pageSize) {
|
||||
return Result.success(congressH5Service.materialsList(typeId, timeId, emplid, searchKeyword,
|
||||
fileType, uploadTimeOrder, pageNumber, pageSize));
|
||||
}
|
||||
|
||||
@At("/user/meetingList")
|
||||
@SaCheckLogin
|
||||
public Result userMeetingList(@Param("timeId") String timeId, @Param("emplid") String emplid) {
|
||||
return Result.success(congressH5Service.userMeetingList(timeId, emplid));
|
||||
public Result userMeetingList(@Param("timeId") String timeId,
|
||||
@Param("emplid") String emplid,
|
||||
@Param("searchKeyword") String searchKeyword,
|
||||
@Param("signTimeStatus") String signTimeStatus,
|
||||
@Param("signInCountStatus") String signInCountStatus,
|
||||
@Param("signStatus") String signStatus,
|
||||
@Param("pageNumber") Integer pageNumber,
|
||||
@Param("pageSize") Integer pageSize) {
|
||||
return Result.success(congressH5Service.userMeetingList(timeId, emplid, searchKeyword,
|
||||
signTimeStatus, signInCountStatus, signStatus, pageNumber, pageSize));
|
||||
}
|
||||
|
||||
@At("/user/meetingRemark")
|
||||
@SaCheckLogin
|
||||
public Result meetingRemark(@Param("meetingId") String meetingId,
|
||||
@Param("timeId") String timeId,
|
||||
@Param("emplid") String emplid) {
|
||||
return Result.success(congressH5Service.meetingRemark(meetingId, timeId, emplid));
|
||||
}
|
||||
|
||||
@At("/signin")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.democratic.congress.service;
|
||||
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
@@ -11,9 +12,14 @@ public interface CongressH5Service {
|
||||
|
||||
List<NutMap> materialsTypeList();
|
||||
|
||||
List<NutMap> materialsList(String typeId, String sessionId, String emplid);
|
||||
Pagination<NutMap> materialsList(String typeId, String sessionId, String emplid, String searchKeyword,
|
||||
String fileType, String uploadTimeOrder, Integer pageNumber, Integer pageSize);
|
||||
|
||||
List<NutMap> userMeetingList(String sessionId, String emplid);
|
||||
Pagination<NutMap> userMeetingList(String sessionId, String emplid, String searchKeyword,
|
||||
String signTimeStatus, String signInCountStatus, String signStatus,
|
||||
Integer pageNumber, Integer pageSize);
|
||||
|
||||
NutMap meetingRemark(String meetingId, String sessionId, String emplid);
|
||||
|
||||
Result signin(String repId, String sessionId, String timeId, String meetingId);
|
||||
|
||||
|
||||
+124
-7
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.democratic.congress.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.democratic.congress.service.CongressH5Service;
|
||||
@@ -44,6 +45,7 @@ public class CongressH5ServiceImpl implements CongressH5Service {
|
||||
AND COALESCE(dg.delFlag, 0) = 0
|
||||
WHERE d.loginName = @emplid
|
||||
AND COALESCE(d.delFlag, 0) = 0
|
||||
AND COALESCE(s.enable, 0) = 1
|
||||
ORDER BY s.startDate DESC, s.createdAt DESC, s.id DESC
|
||||
""");
|
||||
sql.setParam("emplid", loginName);
|
||||
@@ -90,9 +92,13 @@ public class CongressH5ServiceImpl implements CongressH5Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> materialsList(String typeId, String sessionId, String emplid) {
|
||||
public Pagination<NutMap> materialsList(String typeId, String sessionId, String emplid, String searchKeyword,
|
||||
String fileType, String uploadTimeOrder, Integer pageNumber, Integer pageSize) {
|
||||
String loginName = loginName(emplid);
|
||||
Sql sql = Sqls.create("""
|
||||
int currentPage = pageNumber == null || pageNumber < 1 ? 1 : pageNumber;
|
||||
int currentSize = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 50);
|
||||
String orderBy = "asc".equalsIgnoreCase(uploadTimeOrder) ? "ASC" : "DESC";
|
||||
Sql sql = Sqls.create(("""
|
||||
SELECT
|
||||
cm.id,
|
||||
cm.session_id AS sessionId,
|
||||
@@ -126,19 +132,50 @@ public class CongressH5ServiceImpl implements CongressH5Service {
|
||||
WHERE COALESCE(cm.deleted, 0) = 0
|
||||
AND cm.type_id = @typeId
|
||||
AND (cm.session_id = @sessionId OR cm.time_id = @sessionId)
|
||||
ORDER BY cm.sort_no ASC, cm.create_time DESC
|
||||
""");
|
||||
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
|
||||
OR FIND_IN_SET(LOWER(SUBSTRING_INDEX(cm.file_name, '.', -1)), @fileType) > 0)
|
||||
ORDER BY cm.create_time %s, cm.id DESC
|
||||
""").formatted(orderBy));
|
||||
sql.setParam("typeId", typeId);
|
||||
sql.setParam("sessionId", sessionId);
|
||||
sql.setParam("emplid", loginName);
|
||||
sql.setParam("searchKeyword", StrUtil.blankToDefault(searchKeyword, ""));
|
||||
sql.setParam("fileType", StrUtil.blankToDefault(fileType, ""));
|
||||
sql.setPager(dao.createPager(currentPage, currentSize));
|
||||
sql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(sql);
|
||||
return sql.getList(NutMap.class);
|
||||
|
||||
int totalCount = count("""
|
||||
SELECT COUNT(DISTINCT cm.id)
|
||||
FROM congress_materials cm
|
||||
INNER JOIN teacher_congress_delegate d ON d.sessionId = cm.session_id
|
||||
AND d.loginName = @emplid
|
||||
AND COALESCE(d.delFlag, 0) = 0
|
||||
WHERE COALESCE(cm.deleted, 0) = 0
|
||||
AND cm.type_id = @typeId
|
||||
AND (cm.session_id = @sessionId OR cm.time_id = @sessionId)
|
||||
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
|
||||
OR FIND_IN_SET(LOWER(SUBSTRING_INDEX(cm.file_name, '.', -1)), @fileType) > 0)
|
||||
""", NutMap.NEW()
|
||||
.addv("typeId", typeId)
|
||||
.addv("sessionId", sessionId)
|
||||
.addv("emplid", loginName)
|
||||
.addv("searchKeyword", StrUtil.blankToDefault(searchKeyword, ""))
|
||||
.addv("fileType", StrUtil.blankToDefault(fileType, "")));
|
||||
return new Pagination<>(currentPage, currentSize, totalCount, sql.getList(NutMap.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> userMeetingList(String sessionId, String emplid) {
|
||||
public Pagination<NutMap> userMeetingList(String sessionId, String emplid, String searchKeyword,
|
||||
String signTimeStatus, String signInCountStatus, String signStatus,
|
||||
Integer pageNumber, Integer pageSize) {
|
||||
String loginName = loginName(emplid);
|
||||
int currentPage = pageNumber == null || pageNumber < 1 ? 1 : pageNumber;
|
||||
int currentSize = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 50);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
m.id,
|
||||
@@ -166,13 +203,93 @@ public class CongressH5ServiceImpl implements CongressH5Service {
|
||||
AND si.rep_id = d.id
|
||||
WHERE COALESCE(m.deleted, 0) = 0
|
||||
AND (m.session_id = @sessionId OR m.time_id = @sessionId)
|
||||
AND (@searchKeyword = '' OR m.meeting_name LIKE CONCAT('%', @searchKeyword, '%'))
|
||||
AND (@signTimeStatus = ''
|
||||
OR (@signTimeStatus = 'upcoming' AND m.sign_in_start_time > NOW())
|
||||
OR (@signTimeStatus = 'ongoing' AND m.sign_in_start_time <= NOW() AND m.sign_in_end_time >= NOW())
|
||||
OR (@signTimeStatus = 'ended' AND m.sign_in_end_time < NOW()))
|
||||
AND (@signInCountStatus = ''
|
||||
OR (@signInCountStatus = 'has' AND EXISTS (
|
||||
SELECT 1 FROM congress_sign_in count_si
|
||||
WHERE count_si.meeting_id = m.id AND COALESCE(count_si.deleted, 0) = 0))
|
||||
OR (@signInCountStatus = 'none' AND NOT EXISTS (
|
||||
SELECT 1 FROM congress_sign_in count_si
|
||||
WHERE count_si.meeting_id = m.id AND COALESCE(count_si.deleted, 0) = 0)))
|
||||
AND (@signStatus = ''
|
||||
OR (@signStatus = 'signed' AND si.id IS NOT NULL)
|
||||
OR (@signStatus = 'unsigned' AND si.id IS NULL))
|
||||
ORDER BY m.sign_in_start_time DESC, m.create_time DESC
|
||||
""");
|
||||
sql.setParam("sessionId", sessionId);
|
||||
sql.setParam("emplid", loginName);
|
||||
sql.setParam("searchKeyword", StrUtil.blankToDefault(searchKeyword, ""));
|
||||
sql.setParam("signTimeStatus", StrUtil.blankToDefault(signTimeStatus, ""));
|
||||
sql.setParam("signInCountStatus", StrUtil.blankToDefault(signInCountStatus, ""));
|
||||
sql.setParam("signStatus", StrUtil.blankToDefault(signStatus, ""));
|
||||
sql.setPager(dao.createPager(currentPage, currentSize));
|
||||
sql.setCallback(Sqls.callback.maps());
|
||||
dao.execute(sql);
|
||||
return sql.getList(NutMap.class);
|
||||
|
||||
int totalCount = count("""
|
||||
SELECT COUNT(DISTINCT m.id)
|
||||
FROM congress_sign_in_meeting m
|
||||
INNER JOIN teacher_congress_delegate d ON d.sessionId = m.session_id
|
||||
AND d.loginName = @emplid
|
||||
AND COALESCE(d.delFlag, 0) = 0
|
||||
LEFT JOIN congress_sign_in si ON m.id = si.meeting_id
|
||||
AND COALESCE(si.deleted, 0) = 0
|
||||
AND si.rep_id = d.id
|
||||
WHERE COALESCE(m.deleted, 0) = 0
|
||||
AND (m.session_id = @sessionId OR m.time_id = @sessionId)
|
||||
AND (@searchKeyword = '' OR m.meeting_name LIKE CONCAT('%', @searchKeyword, '%'))
|
||||
AND (@signTimeStatus = ''
|
||||
OR (@signTimeStatus = 'upcoming' AND m.sign_in_start_time > NOW())
|
||||
OR (@signTimeStatus = 'ongoing' AND m.sign_in_start_time <= NOW() AND m.sign_in_end_time >= NOW())
|
||||
OR (@signTimeStatus = 'ended' AND m.sign_in_end_time < NOW()))
|
||||
AND (@signInCountStatus = ''
|
||||
OR (@signInCountStatus = 'has' AND EXISTS (
|
||||
SELECT 1 FROM congress_sign_in count_si
|
||||
WHERE count_si.meeting_id = m.id AND COALESCE(count_si.deleted, 0) = 0))
|
||||
OR (@signInCountStatus = 'none' AND NOT EXISTS (
|
||||
SELECT 1 FROM congress_sign_in count_si
|
||||
WHERE count_si.meeting_id = m.id AND COALESCE(count_si.deleted, 0) = 0)))
|
||||
AND (@signStatus = ''
|
||||
OR (@signStatus = 'signed' AND si.id IS NOT NULL)
|
||||
OR (@signStatus = 'unsigned' AND si.id IS NULL))
|
||||
""", NutMap.NEW()
|
||||
.addv("sessionId", sessionId)
|
||||
.addv("emplid", loginName)
|
||||
.addv("searchKeyword", StrUtil.blankToDefault(searchKeyword, ""))
|
||||
.addv("signTimeStatus", StrUtil.blankToDefault(signTimeStatus, ""))
|
||||
.addv("signInCountStatus", StrUtil.blankToDefault(signInCountStatus, ""))
|
||||
.addv("signStatus", StrUtil.blankToDefault(signStatus, "")));
|
||||
return new Pagination<>(currentPage, currentSize, totalCount, sql.getList(NutMap.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap meetingRemark(String meetingId, String sessionId, String emplid) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
m.id,
|
||||
m.meeting_name AS meetingName,
|
||||
m.remark,
|
||||
m.session_id AS sessionId,
|
||||
COALESCE(m.time_id, m.session_id) AS timeId
|
||||
FROM congress_sign_in_meeting m
|
||||
INNER JOIN teacher_congress_delegate d ON d.sessionId = m.session_id
|
||||
AND d.loginName = @emplid
|
||||
AND COALESCE(d.delFlag, 0) = 0
|
||||
WHERE m.id = @meetingId
|
||||
AND COALESCE(m.deleted, 0) = 0
|
||||
AND (m.session_id = @sessionId OR m.time_id = @sessionId)
|
||||
LIMIT 1
|
||||
""");
|
||||
sql.setParam("meetingId", meetingId);
|
||||
sql.setParam("sessionId", sessionId);
|
||||
sql.setParam("emplid", loginName(emplid));
|
||||
sql.setCallback(Sqls.callback.map());
|
||||
dao.execute(sql);
|
||||
return sql.getObject(NutMap.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@@ -15,12 +15,11 @@ layout("/layouts/platform_h5.html"){
|
||||
<div class="page-header">
|
||||
<div class="session-info-card">
|
||||
<h2 class="session-title">{{ selectedSessionName }}</h2>
|
||||
<!-- <p class="session-subtitle">{{ selectedTimeText }}</p>-->
|
||||
<button v-if="timesList.length > 1" type="button" class="header-switch-btn" @click="showTimePicker = true">
|
||||
<span>切换届次</span>
|
||||
<van-icon name="arrow-down" size="12"></van-icon>
|
||||
</button>
|
||||
</div>
|
||||
<button v-if="timesList.length > 1" type="button" class="header-switch-btn" @click="showTimePicker = true">
|
||||
<span>切换届次</span>
|
||||
<van-icon name="arrow-down" size="12"></van-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="module-list-container">
|
||||
@@ -29,6 +28,7 @@ layout("/layouts/platform_h5.html"){
|
||||
v-for="module in moduleList"
|
||||
:key="module.id"
|
||||
class="module-card"
|
||||
:class="resolveTheme(module.name)"
|
||||
@click="handleModuleClick(module)"
|
||||
>
|
||||
<div class="module-header">
|
||||
@@ -47,7 +47,7 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
</template>
|
||||
|
||||
<van-popup v-model="showTimePicker" position="bottom">
|
||||
<van-popup v-model="showTimePicker" position="bottom" :z-index="3000">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="formattedTimeColumns"
|
||||
@@ -128,7 +128,7 @@ layout("/layouts/platform_h5.html"){
|
||||
this.moduleList = hasSignin ? modules : [{
|
||||
id: "signin",
|
||||
name: "会议签到",
|
||||
icon: "calendar-o",
|
||||
icon: "completed",
|
||||
desc: "点击进行会议签到"
|
||||
}].concat(modules)
|
||||
},
|
||||
@@ -186,13 +186,13 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
resolveIcon(name) {
|
||||
if (!name) return "orders-o"
|
||||
if (name.indexOf("会议签到") > -1) return "calendar-o"
|
||||
if (name.indexOf("会议签到") > -1) return "completed"
|
||||
if (name.indexOf("评议") > -1) return "star"
|
||||
if (name.indexOf("议题") > -1) return "todo-list-o"
|
||||
if (name.indexOf("资料") > -1) return "notes-o"
|
||||
if (name.indexOf("公告") > -1 || name.indexOf("结果") > -1) return "bullhorn-o"
|
||||
if (name.indexOf("议题") > -1) return "todo-list"
|
||||
if (name.indexOf("资料") > -1) return "notes"
|
||||
if (name.indexOf("公告") > -1 || name.indexOf("结果") > -1) return "bell"
|
||||
if (name.indexOf("文件") > -1) return "description"
|
||||
return "orders-o"
|
||||
return "orders"
|
||||
},
|
||||
resolveDesc(name) {
|
||||
if (!name) return ""
|
||||
@@ -203,6 +203,15 @@ layout("/layouts/platform_h5.html"){
|
||||
if (name.indexOf("表决公告") > -1) return "查看表决结果公告"
|
||||
if (name.indexOf("资料") > -1) return "查看会议准备资料"
|
||||
return ""
|
||||
},
|
||||
resolveTheme(name) {
|
||||
if (!name) return "theme-blue"
|
||||
if (name.indexOf("会议签到") > -1) return "theme-blue"
|
||||
if (name.indexOf("文件") > -1) return "theme-blue"
|
||||
if (name.indexOf("表决公告") > -1) return "theme-green"
|
||||
if (name.indexOf("议题") > -1) return "theme-purple"
|
||||
if (name.indexOf("评议") > -1) return "theme-orange module-card-wide"
|
||||
return "theme-blue"
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -213,60 +222,62 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
<style id="style-congress-h5">
|
||||
.congress-page {
|
||||
min-height: calc(100vh - 46px);
|
||||
background: #f5f7fa;
|
||||
height: calc(100vh - 46px);
|
||||
background: #f4f8ff;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background: linear-gradient(135deg, #1989fa 0%, #0d6efd 100%);
|
||||
padding: 34px 16px 28px;
|
||||
min-height: 192px;
|
||||
background: #1686ff url("${base!}/images/congress/h5-congress-header.png") center center / cover no-repeat;
|
||||
padding: 0px 15px 50px;
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 16px rgba(25, 137, 250, 0.15);
|
||||
box-shadow: 0 12px 28px rgba(25, 137, 250, 0.18);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.session-info-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.session-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
font-size: 25px;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
color: #fff;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.session-subtitle {
|
||||
font-size: 15px;
|
||||
line-height: 1.3;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
margin: 0 0 10px;
|
||||
text-shadow: 0 4px 12px rgba(3, 77, 168, 0.18);
|
||||
}
|
||||
|
||||
.header-switch-btn {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 12px;
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
margin-top: 6px;
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 0;
|
||||
border-radius: 14px;
|
||||
border-radius: 18px;
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
color: #fff;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
gap: 6px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
|
||||
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.36), 0 8px 18px rgba(0, 66, 160, 0.12);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
@@ -276,70 +287,62 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
|
||||
.module-list-container {
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
margin: -72px 0 0;
|
||||
padding: 18px 16px 24px;
|
||||
background: #fff;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.modules-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.module-card {
|
||||
background: #fff;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
min-height: 98px;
|
||||
background: linear-gradient(135deg, #f8fbff 0%, #fff 100%);
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 8px 18px rgba(27, 56, 105, 0.06);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.03);
|
||||
border: 1px solid rgba(237, 242, 250, 0.88);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.module-card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
background: linear-gradient(180deg, #1989fa 0%, #0d6efd 100%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.module-card:hover {
|
||||
box-shadow: 0 8px 24px rgba(25, 137, 250, 0.12);
|
||||
transform: translateY(-3px);
|
||||
border-color: rgba(25, 137, 250, 0.1);
|
||||
}
|
||||
|
||||
.module-card:hover::before {
|
||||
opacity: 1;
|
||||
.module-card-wide {
|
||||
grid-column: auto;
|
||||
}
|
||||
|
||||
.module-card:active {
|
||||
transform: translateY(-1px) scale(0.99);
|
||||
transform: scale(0.99);
|
||||
box-shadow: 0 4px 16px rgba(25, 137, 250, 0.08);
|
||||
}
|
||||
|
||||
.module-header {
|
||||
padding: 16px 18px;
|
||||
min-height: 60px;
|
||||
padding: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 14px;
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #e6f0ff 0%, #f0f5ff 100%);
|
||||
background: #eef5ff;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 2px 8px rgba(25, 137, 250, 0.12);
|
||||
box-shadow: 0 8px 18px rgba(25, 137, 250, 0.1);
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
@@ -349,9 +352,9 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
|
||||
.module-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
color: #4a4a4a;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #111a3a;
|
||||
margin: 0 0 6px;
|
||||
line-height: 1.4;
|
||||
overflow: hidden;
|
||||
@@ -360,8 +363,8 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
|
||||
.module-desc {
|
||||
font-size: 13px;
|
||||
color: #969799;
|
||||
font-size: 12px;
|
||||
color: #7d89a6;
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
overflow: hidden;
|
||||
@@ -370,15 +373,62 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 18px;
|
||||
color: #c8c9cc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
color: #1989fa;
|
||||
background: rgba(25, 137, 250, 0.1);
|
||||
flex-shrink: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.module-card:hover .arrow-icon {
|
||||
color: #1989fa;
|
||||
transform: translateX(4px);
|
||||
.theme-green {
|
||||
background: linear-gradient(135deg, #f3fff9 0%, #fff 100%);
|
||||
}
|
||||
|
||||
.theme-green .icon-wrapper {
|
||||
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 {
|
||||
background: linear-gradient(135deg, #fbf7ff 0%, #fff 100%);
|
||||
}
|
||||
|
||||
.theme-purple .icon-wrapper {
|
||||
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 {
|
||||
background: linear-gradient(135deg, #fff8ed 0%, #fff 100%);
|
||||
}
|
||||
|
||||
.theme-orange .icon-wrapper {
|
||||
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 {
|
||||
|
||||
@@ -6,14 +6,18 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-nav-bar :title="pageTitle" left-text="返回" left-arrow @click-left="backToCongress" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="file-list-page">
|
||||
<van-sticky :offset-top="46">
|
||||
<div class="file-filter-bar">
|
||||
<van-search v-model="keyword" placeholder="搜索文件名" shape="round" class="file-search" @input="onKeywordChange"></van-search>
|
||||
<van-dropdown-menu class="file-filter-menu">
|
||||
<van-dropdown-item v-model="selectedFileType" :options="fileTypeOptions" @change="resetList"></van-dropdown-item>
|
||||
<van-dropdown-item v-model="uploadTimeOrder" :options="uploadTimeSortOptions" @change="resetList"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</div>
|
||||
</van-sticky>
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list v-model="loading" :finished="finished" :finished-text="fileList.length > 0 ? '没有更多了' : ''" @load="onLoad">
|
||||
<div v-for="item in fileList" :key="item.id" class="file-card" @click="handleFileClick(item)">
|
||||
<div v-if="item.hasVoted !== null && item.hasVoted !== undefined" class="vote-badge">
|
||||
<span v-if="isVoted(item.hasVoted)" class="badge voted">已投票</span>
|
||||
<span v-else class="badge pending">待投票</span>
|
||||
</div>
|
||||
|
||||
<div class="card-left">
|
||||
<div class="icon-wrapper">
|
||||
<img :src="getFileIconUrl(item)" :alt="resolveFileSuffix(item) || 'file'" class="file-type-icon">
|
||||
@@ -22,17 +26,27 @@ layout("/layouts/platform_h5.html"){
|
||||
<div class="card-content">
|
||||
<div class="card-header">
|
||||
<span class="file-name">{{ formatFileName(item.name || item.fileName) }}</span>
|
||||
<van-icon name="arrow" class="arrow-icon"></van-icon>
|
||||
<div class="card-actions">
|
||||
<span v-if="item.hasVoted !== null && item.hasVoted !== undefined" class="vote-status" :class="isVoted(item.hasVoted) ? 'voted' : 'pending'">
|
||||
<van-icon :name="isVoted(item.hasVoted) ? 'checked' : 'clock-o'" size="12"></van-icon>
|
||||
{{ isVoted(item.hasVoted) ? '已投票' : '待投票' }}
|
||||
</span>
|
||||
<van-icon name="arrow" class="arrow-icon"></van-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.uploadTime" class="file-info">
|
||||
<div class="file-info">
|
||||
<div class="info-row">
|
||||
<van-icon name="clock-o" size="14" color="#969799"></van-icon>
|
||||
<van-icon name="description" size="14"></van-icon>
|
||||
<span class="info-text">文件类型:<span class="info-value">{{ fileTypeText(item) }}</span></span>
|
||||
</div>
|
||||
<div v-if="item.uploadTime" class="info-row">
|
||||
<van-icon name="clock-o" size="14"></van-icon>
|
||||
<span class="info-text">上传时间:<span class="info-value">{{ formatTime(item.uploadTime) }}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<van-empty v-if="!loading && fileList.length === 0" description="暂无文件"></van-empty>
|
||||
<van-empty v-if="!loading && fileList.length === 0" :description="hasFilter ? '未找到匹配文件' : '暂无文件'"></van-empty>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</div>
|
||||
@@ -52,7 +66,39 @@ layout("/layouts/platform_h5.html"){
|
||||
loadedOnce: false,
|
||||
typeId: "",
|
||||
timeId: "",
|
||||
sessionId: ""
|
||||
sessionId: "",
|
||||
keyword: "",
|
||||
selectedFileType: "",
|
||||
uploadTimeOrder: "desc",
|
||||
searchTimer: null,
|
||||
queryVersion: 0,
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
fileTypeOptions() {
|
||||
return [
|
||||
{text: "全部类型", value: ""},
|
||||
{text: "PDF", value: "pdf"},
|
||||
{text: "Word", value: "doc,docx"},
|
||||
{text: "Excel", value: "xls,xlsx"},
|
||||
{text: "PPT", value: "ppt,pptx"},
|
||||
{text: "图片", value: "jpg,jpeg,png,gif,bmp,webp"},
|
||||
{text: "压缩包", value: "zip,rar"}
|
||||
]
|
||||
},
|
||||
uploadTimeSortOptions() {
|
||||
return [
|
||||
{text: "上传时间:最新", value: "desc"},
|
||||
{text: "上传时间:最早", value: "asc"}
|
||||
]
|
||||
},
|
||||
hasFilter() {
|
||||
return !!(this.keyword || this.selectedFileType)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -72,33 +118,61 @@ layout("/layouts/platform_h5.html"){
|
||||
return user.loginname || user.loginName || ""
|
||||
},
|
||||
onRefresh() {
|
||||
this.resetList()
|
||||
},
|
||||
onLoad() {
|
||||
if (!this.finished) {
|
||||
this.fetchFileList()
|
||||
}
|
||||
},
|
||||
onKeywordChange() {
|
||||
clearTimeout(this.searchTimer)
|
||||
this.searchTimer = setTimeout(() => this.resetList(), 300)
|
||||
},
|
||||
resetList() {
|
||||
this.queryVersion++
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.fileList = []
|
||||
this.finished = false
|
||||
this.loadedOnce = false
|
||||
this.fetchFileList()
|
||||
},
|
||||
onLoad() {
|
||||
if (!this.loadedOnce) {
|
||||
this.fetchFileList()
|
||||
}
|
||||
},
|
||||
fetchFileList() {
|
||||
const queryVersion = this.queryVersion
|
||||
this.loading = true
|
||||
this.$axios.get("/platform/h5/congress/materialsList", {
|
||||
params: {
|
||||
typeId: this.typeId,
|
||||
timeId: this.timeId,
|
||||
emplid: this.loginName()
|
||||
emplid: this.loginName(),
|
||||
searchKeyword: this.keyword,
|
||||
fileType: this.selectedFileType,
|
||||
uploadTimeOrder: this.uploadTimeOrder,
|
||||
pageNumber: this.pageForm.pageNumber,
|
||||
pageSize: this.pageForm.pageSize
|
||||
}
|
||||
}).then((res) => {
|
||||
if (queryVersion !== this.queryVersion) return
|
||||
if (res.code === 0) {
|
||||
this.fileList = res.data || []
|
||||
const pageData = res.data || {}
|
||||
const records = pageData.list || []
|
||||
this.fileList = this.fileList.concat(records)
|
||||
this.pageForm.totalCount = pageData.totalCount || 0
|
||||
if (this.fileList.length >= this.pageForm.totalCount) {
|
||||
this.finished = true
|
||||
} else {
|
||||
this.pageForm.pageNumber++
|
||||
}
|
||||
} else {
|
||||
this.finished = true
|
||||
}
|
||||
this.finished = true
|
||||
this.loadedOnce = true
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
if (queryVersion === this.queryVersion) {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
}
|
||||
})
|
||||
},
|
||||
getFileIconUrl(item) {
|
||||
@@ -135,6 +209,10 @@ layout("/layouts/platform_h5.html"){
|
||||
isKnownSuffix(suffix) {
|
||||
return ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "zip", "rar", "jpg", "jpeg", "png", "gif", "bmp", "webp", "mp4", "avi", "wmv", "rmvb", "flv", "mkv", "mp3", "wav", "wma", "flac", "ape"].indexOf(suffix) > -1
|
||||
},
|
||||
fileTypeText(item) {
|
||||
const suffix = this.resolveFileSuffix(item)
|
||||
return suffix ? suffix.toUpperCase() : "未知类型"
|
||||
},
|
||||
formatTime(time) {
|
||||
if (!time) return ""
|
||||
const date = new Date(time)
|
||||
@@ -193,6 +271,27 @@ layout("/layouts/platform_h5.html"){
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.file-filter-bar {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 8px rgba(30, 48, 80, 0.04);
|
||||
}
|
||||
|
||||
.file-search {
|
||||
padding: 10px 16px 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.file-filter-menu {
|
||||
height: 42px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.file-filter-menu .van-dropdown-menu__bar {
|
||||
height: 42px;
|
||||
box-shadow: none;
|
||||
border-top: 1px solid #f2f3f5;
|
||||
}
|
||||
|
||||
.file-card {
|
||||
background: #fff;
|
||||
margin: 12px 16px;
|
||||
@@ -220,48 +319,43 @@ layout("/layouts/platform_h5.html"){
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.file-card:hover {
|
||||
box-shadow: 0 8px 24px rgba(25, 137, 250, 0.12);
|
||||
transform: translateY(-3px);
|
||||
border-color: rgba(25, 137, 250, 0.1);
|
||||
}
|
||||
|
||||
.file-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.file-card:active {
|
||||
transform: translateY(-1px) scale(0.99);
|
||||
transform: scale(0.99);
|
||||
box-shadow: 0 4px 16px rgba(25, 137, 250, 0.08);
|
||||
}
|
||||
|
||||
.vote-badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
.card-actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 6px 14px;
|
||||
.vote-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
padding: 4px 7px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border-bottom-right-radius: 12px;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.badge.voted {
|
||||
background: linear-gradient(135deg, #52c41a 0%, #389e0d 100%);
|
||||
.vote-status.voted {
|
||||
color: #17a65b;
|
||||
background: #edf9f1;
|
||||
}
|
||||
|
||||
.badge.pending {
|
||||
background: linear-gradient(135deg, #faad14 0%, #d48806 100%);
|
||||
.vote-status.pending {
|
||||
color: #d98a00;
|
||||
background: #fff6e5;
|
||||
}
|
||||
|
||||
.card-left {
|
||||
flex-shrink: 0;
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
@@ -316,6 +410,15 @@ layout("/layouts/platform_h5.html"){
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
color: #969799;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.info-row + .info-row {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.info-row .van-icon {
|
||||
color: #969799;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
|
||||
@@ -6,27 +6,42 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-nav-bar title="会议签到" left-text="返回" left-arrow @click-left="backToCongress" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="meeting-list-page">
|
||||
<van-sticky :offset-top="46">
|
||||
<div class="meeting-filter-bar">
|
||||
<van-search v-model="keyword" placeholder="搜索会议名称" shape="round" class="meeting-search" @input="onKeywordChange"></van-search>
|
||||
<van-dropdown-menu class="meeting-filter-menu">
|
||||
<van-dropdown-item v-model="signTimeStatus" :options="signTimeOptions" @change="resetList"></van-dropdown-item>
|
||||
<van-dropdown-item v-model="signInCountStatus" :options="signInCountOptions" @change="resetList"></van-dropdown-item>
|
||||
<van-dropdown-item v-model="signStatus" :options="signStatusOptions" @change="resetList"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</div>
|
||||
</van-sticky>
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list v-model="loading" :finished="finished" :finished-text="meetingList.length > 0 ? '没有更多了' : ''" @load="onLoad">
|
||||
<div v-for="item in meetingList" :key="item.id" class="meeting-card">
|
||||
<div class="card-left">
|
||||
<div class="icon-wrapper" :class="{'signed-icon': item.signInId}">
|
||||
<van-icon name="calendar-o" size="26"></van-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="item in meetingList" :key="item.id" class="meeting-card" :class="{'meeting-card-disabled': !item.signInId && !canSignIn(item)}">
|
||||
<div class="card-content">
|
||||
<div class="card-header">
|
||||
<div class="card-left">
|
||||
<div class="icon-wrapper" :class="{'signed-icon': item.signInId}">
|
||||
<van-icon name="completed" size="26"></van-icon>
|
||||
</div>
|
||||
</div>
|
||||
<span class="meeting-name">{{ item.meetingName }}</span>
|
||||
<button v-if="item.remark" type="button" class="remark-link" @click.stop="openRemark(item)">
|
||||
<van-icon name="notes-o" size="14"></van-icon>
|
||||
<span>备注</span>
|
||||
<van-icon name="arrow" size="12"></van-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="info-list">
|
||||
<div v-if="item.signInStartTime" class="info-row">
|
||||
<van-icon name="clock-o" size="14" color="#969799"></van-icon>
|
||||
<span class="info-text">签到时间:<span class="info-value">{{ formatTimeRange(item.signInStartTime, item.signInEndTime) }}</span></span>
|
||||
<span class="info-text">签到开始:<span class="info-value">{{ formatTime(item.signInStartTime) }}</span></span>
|
||||
</div>
|
||||
<div v-if="item.userSignInTime" class="info-row signed">
|
||||
<van-icon name="checked" size="14" color="#07c160"></van-icon>
|
||||
<span class="info-text">已签到:<span class="info-value">{{ formatTime(item.userSignInTime) }}</span></span>
|
||||
<div v-if="item.signInEndTime" class="info-row">
|
||||
<van-icon name="clock-o" size="14" color="#969799"></van-icon>
|
||||
<span class="info-text">签到结束:<span class="info-value">{{ formatTime(item.signInEndTime) }}</span></span>
|
||||
</div>
|
||||
<div class="info-row count">
|
||||
<van-icon name="friends-o" size="14" color="#1989fa"></van-icon>
|
||||
@@ -34,11 +49,15 @@ layout("/layouts/platform_h5.html"){
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!item.signInId" class="action-section">
|
||||
<van-button v-if="!canSignIn(item)" disabled type="default" class="signin-btn disabled">
|
||||
<div v-if="item.userSignInTime" class="action-section signin-status signed-status">
|
||||
<van-icon name="checked" size="16"></van-icon>
|
||||
<span>已签到:{{ formatTime(item.userSignInTime) }}</span>
|
||||
</div>
|
||||
<div v-else class="action-section">
|
||||
<div v-if="!canSignIn(item)" class="signin-status disabled-status">
|
||||
<van-icon name="clock-o" size="16"></van-icon>
|
||||
{{ getSignInButtonText(item) }}
|
||||
</van-button>
|
||||
</div>
|
||||
<van-button v-else type="primary" class="signin-btn" @click.stop="handleSignInClick(item)">
|
||||
<van-icon name="checked" size="16"></van-icon>
|
||||
立即签到
|
||||
@@ -46,7 +65,7 @@ layout("/layouts/platform_h5.html"){
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<van-empty v-if="!loading && meetingList.length === 0" description="暂无会议"></van-empty>
|
||||
<van-empty v-if="!loading && meetingList.length === 0" :description="hasFilter ? '未找到匹配会议' : '暂无会议'"></van-empty>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</div>
|
||||
@@ -64,7 +83,45 @@ layout("/layouts/platform_h5.html"){
|
||||
refreshing: false,
|
||||
loadedOnce: false,
|
||||
timeId: "",
|
||||
sessionId: ""
|
||||
sessionId: "",
|
||||
keyword: "",
|
||||
signTimeStatus: "",
|
||||
signInCountStatus: "",
|
||||
signStatus: "",
|
||||
searchTimer: null,
|
||||
queryVersion: 0,
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
signTimeOptions() {
|
||||
return [
|
||||
{text: "签到时间", value: ""},
|
||||
{text: "未开始", value: "upcoming"},
|
||||
{text: "进行中", value: "ongoing"},
|
||||
{text: "已结束", value: "ended"}
|
||||
]
|
||||
},
|
||||
signInCountOptions() {
|
||||
return [
|
||||
{text: "签到人数", value: ""},
|
||||
{text: "有人签到", value: "has"},
|
||||
{text: "无人签到", value: "none"}
|
||||
]
|
||||
},
|
||||
signStatusOptions() {
|
||||
return [
|
||||
{text: "签到状态", value: ""},
|
||||
{text: "已签到", value: "signed"},
|
||||
{text: "未签到", value: "unsigned"}
|
||||
]
|
||||
},
|
||||
hasFilter() {
|
||||
return !!(this.keyword || this.signTimeStatus || this.signInCountStatus || this.signStatus)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -82,31 +139,68 @@ layout("/layouts/platform_h5.html"){
|
||||
return user.loginname || user.loginName || ""
|
||||
},
|
||||
onRefresh() {
|
||||
this.resetList()
|
||||
},
|
||||
onLoad() {
|
||||
if (!this.finished) {
|
||||
this.fetchMeetingList()
|
||||
}
|
||||
},
|
||||
onKeywordChange() {
|
||||
clearTimeout(this.searchTimer)
|
||||
this.searchTimer = setTimeout(() => this.resetList(), 300)
|
||||
},
|
||||
resetList() {
|
||||
this.queryVersion++
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.meetingList = []
|
||||
this.finished = false
|
||||
this.loadedOnce = false
|
||||
this.fetchMeetingList()
|
||||
},
|
||||
onLoad() {
|
||||
if (!this.loadedOnce) {
|
||||
this.fetchMeetingList()
|
||||
}
|
||||
},
|
||||
fetchMeetingList() {
|
||||
const queryVersion = this.queryVersion
|
||||
this.loading = true
|
||||
this.$axios.get("/platform/h5/congress/user/meetingList", {
|
||||
params: {timeId: this.timeId, emplid: this.loginName()}
|
||||
params: {
|
||||
timeId: this.timeId,
|
||||
emplid: this.loginName(),
|
||||
searchKeyword: this.keyword,
|
||||
signTimeStatus: this.signTimeStatus,
|
||||
signInCountStatus: this.signInCountStatus,
|
||||
signStatus: this.signStatus,
|
||||
pageNumber: this.pageForm.pageNumber,
|
||||
pageSize: this.pageForm.pageSize
|
||||
}
|
||||
}).then((res) => {
|
||||
if (queryVersion !== this.queryVersion) return
|
||||
if (res.code === 0) {
|
||||
this.meetingList = res.data || []
|
||||
const pageData = res.data || {}
|
||||
const records = pageData.list || []
|
||||
this.meetingList = this.meetingList.concat(records)
|
||||
this.pageForm.totalCount = pageData.totalCount || 0
|
||||
if (this.meetingList.length >= this.pageForm.totalCount) {
|
||||
this.finished = true
|
||||
} else {
|
||||
this.pageForm.pageNumber++
|
||||
}
|
||||
} else {
|
||||
this.finished = true
|
||||
}
|
||||
this.finished = true
|
||||
this.loadedOnce = true
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
if (queryVersion === this.queryVersion) {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
}
|
||||
})
|
||||
},
|
||||
openRemark(item) {
|
||||
this.$pjaxReplace("/platform/h5/congress/meeting/remark?meetingId=" + encodeURIComponent(item.id) +
|
||||
"&timeId=" + encodeURIComponent(item.timeId || this.timeId) +
|
||||
"&sessionId=" + encodeURIComponent(item.sessionId || this.sessionId))
|
||||
},
|
||||
handleSignInClick(item) {
|
||||
if (item.signInId) {
|
||||
this.$toast.success("您已签到,无需重复签到")
|
||||
@@ -153,7 +247,7 @@ layout("/layouts/platform_h5.html"){
|
||||
const end = new Date(item.signInEndTime).getTime()
|
||||
if (Number.isNaN(start) || Number.isNaN(end)) return "立即签到"
|
||||
if (now < start) return "未到签到时间"
|
||||
if (now > end) return "已超过签到时间"
|
||||
if (now > end) return "已过签到时间"
|
||||
return "立即签到"
|
||||
},
|
||||
formatTimeRange(startTime, endTime) {
|
||||
@@ -183,16 +277,38 @@ layout("/layouts/platform_h5.html"){
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.meeting-filter-bar {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 8px rgba(30, 48, 80, 0.04);
|
||||
}
|
||||
|
||||
.meeting-search {
|
||||
padding: 10px 16px 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.meeting-filter-menu {
|
||||
height: 42px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.meeting-filter-menu .van-dropdown-menu__bar {
|
||||
height: 42px;
|
||||
box-shadow: none;
|
||||
border-top: 1px solid #f2f3f5;
|
||||
}
|
||||
|
||||
.meeting-card {
|
||||
background: #fff;
|
||||
margin: 16px;
|
||||
height: 220px;
|
||||
padding: 24px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 2px 16px rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 18px;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(0, 0, 0, 0.03);
|
||||
@@ -210,19 +326,9 @@ layout("/layouts/platform_h5.html"){
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.meeting-card:hover {
|
||||
box-shadow: 0 8px 24px rgba(25, 137, 250, 0.12);
|
||||
transform: translateY(-3px);
|
||||
border-color: rgba(25, 137, 250, 0.1);
|
||||
}
|
||||
|
||||
.meeting-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card-left {
|
||||
flex-shrink: 0;
|
||||
padding-top: 2px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
@@ -242,13 +348,24 @@ layout("/layouts/platform_h5.html"){
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.meeting-card-disabled .icon-wrapper {
|
||||
background: #f4f4f5;
|
||||
color: #c8c9cc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.meeting-name {
|
||||
@@ -256,14 +373,32 @@ layout("/layouts/platform_h5.html"){
|
||||
color: #323233;
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.remark-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-left: 8px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #969799;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
gap: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
@@ -280,12 +415,36 @@ layout("/layouts/platform_h5.html"){
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.info-row.signed .info-text {
|
||||
.info-row.count .info-text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.meeting-card-disabled .info-row.count .van-icon {
|
||||
color: #c8c9cc !important;
|
||||
}
|
||||
|
||||
.meeting-card-disabled .info-row.count .info-text {
|
||||
color: #c8c9cc;
|
||||
}
|
||||
|
||||
.action-section {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.signin-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.signed-status {
|
||||
color: #07c160;
|
||||
}
|
||||
|
||||
.info-row.count .info-text {
|
||||
color: #1989fa;
|
||||
.disabled-status {
|
||||
color: #c8c9cc;
|
||||
}
|
||||
|
||||
.signin-btn {
|
||||
@@ -297,14 +456,9 @@ layout("/layouts/platform_h5.html"){
|
||||
background: linear-gradient(135deg, #1989fa 0%, #0d6efd 100%);
|
||||
border: none;
|
||||
box-shadow: 0 3px 10px rgba(25, 137, 250, 0.3);
|
||||
transform: translateY(4px);
|
||||
}
|
||||
|
||||
.signin-btn.disabled {
|
||||
background: linear-gradient(135deg, rgba(25, 137, 250, 0.3) 0%, rgba(13, 110, 253, 0.3) 100%);
|
||||
color: #fff;
|
||||
border: 1px solid rgba(25, 137, 250, 0.4);
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--#
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="会议备注" left-text="返回" left-arrow @click-left="backToMeeting" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="meeting-remark-page">
|
||||
<div v-if="remarkData" class="remark-content-card">
|
||||
<h2 class="remark-title">{{ remarkData.meetingName }}</h2>
|
||||
<div class="remark-divider"></div>
|
||||
<div class="remark-content">{{ remarkData.remark || "暂无备注" }}</div>
|
||||
</div>
|
||||
<van-empty v-else-if="!loading" description="暂无备注"></van-empty>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
meetingId: "",
|
||||
timeId: "",
|
||||
sessionId: "",
|
||||
remarkData: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initQuery() {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
this.meetingId = params.get("meetingId") || ""
|
||||
this.timeId = params.get("timeId") || ""
|
||||
this.sessionId = params.get("sessionId") || this.timeId
|
||||
},
|
||||
backToMeeting() {
|
||||
this.$pjaxReplace("/platform/h5/congress/meeting/list?timeId=" + encodeURIComponent(this.timeId) +
|
||||
"&sessionId=" + encodeURIComponent(this.sessionId))
|
||||
},
|
||||
loginName() {
|
||||
const user = (this.$store.state && this.$store.state.user) || JSON.parse(window.sessionStorage.getItem("user") || "{}")
|
||||
return user.loginname || user.loginName || ""
|
||||
},
|
||||
fetchRemark() {
|
||||
this.$axios.get("/platform/h5/congress/user/meetingRemark", {
|
||||
params: {meetingId: this.meetingId, timeId: this.timeId, emplid: this.loginName()}
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.remarkData = res.data || null
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initQuery()
|
||||
this.fetchRemark()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style id="style-congress-meeting-remark-h5">
|
||||
.meeting-remark-page {
|
||||
min-height: calc(100vh - 46px);
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.remark-content-card {
|
||||
padding: 20px;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.remark-title {
|
||||
margin: 0;
|
||||
color: #323233;
|
||||
font-size: 17px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.remark-divider {
|
||||
height: 1px;
|
||||
margin: 16px 0;
|
||||
background: #ebedf0;
|
||||
}
|
||||
|
||||
.remark-content {
|
||||
color: #646566;
|
||||
font-size: 15px;
|
||||
line-height: 1.8;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -3,7 +3,7 @@ layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar :title="voteInfo.name || '投票'" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||
<van-nav-bar title="进行投票" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="vote-page">
|
||||
<div class="vote-content">
|
||||
@@ -12,10 +12,10 @@ layout("/layouts/platform_h5.html"){
|
||||
<div v-if="voteTicketName" class="vote-type-text">{{ voteTicketName }}</div>
|
||||
<div class="vote-meta">
|
||||
<div class="meta-item">
|
||||
<van-icon name="calendar-o" size="14"></van-icon>
|
||||
<van-icon name="completed" size="14"></van-icon>
|
||||
<span>{{ sessionName }}</span>
|
||||
</div>
|
||||
<div class="meta-divider"></div>
|
||||
<!-- <div class="meta-divider"></div>-->
|
||||
<!-- <div class="meta-item">-->
|
||||
<!-- <van-icon name="clock-o" size="14"></van-icon>-->
|
||||
<!-- <span>{{ timeName }}</span>-->
|
||||
@@ -245,6 +245,7 @@ layout("/layouts/platform_h5.html"){
|
||||
.vote-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid #ebedf0;
|
||||
@@ -372,7 +373,6 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
.vote-description {
|
||||
padding: 20px;
|
||||
border-left: 4px solid #1989fa;
|
||||
}
|
||||
|
||||
.description-header {
|
||||
@@ -412,6 +412,32 @@ layout("/layouts/platform_h5.html"){
|
||||
border: 0;
|
||||
box-shadow: 0 4px 12px rgba(25, 137, 250, 0.3);
|
||||
}
|
||||
.vote-table-container {
|
||||
border-color: #dfe5ee;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(30, 48, 80, 0.04);
|
||||
}
|
||||
|
||||
.vote-table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.vote-table th,
|
||||
.vote-table td {
|
||||
border: 0;
|
||||
border-right: 1px solid #dfe5ee;
|
||||
border-bottom: 1px solid #dfe5ee;
|
||||
}
|
||||
|
||||
.vote-table tr > :last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.vote-table tbody tr:last-child td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--#
|
||||
|
||||
@@ -3,7 +3,7 @@ layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar :title="voteInfo.name || '查看投票'" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||
<van-nav-bar title="查看投票" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="vote-page">
|
||||
<div class="vote-content">
|
||||
@@ -12,10 +12,10 @@ layout("/layouts/platform_h5.html"){
|
||||
<div v-if="voteTicketName" class="vote-type-text">{{ voteTicketName }}</div>
|
||||
<div class="vote-meta">
|
||||
<div class="meta-item">
|
||||
<van-icon name="calendar-o" size="14"></van-icon>
|
||||
<van-icon name="completed" size="14"></van-icon>
|
||||
<span>{{ sessionName }}</span>
|
||||
</div>
|
||||
<div class="meta-divider"></div>
|
||||
<!-- <div class="meta-divider"></div>-->
|
||||
<!-- <div class="meta-item">-->
|
||||
<!-- <van-icon name="clock-o" size="14"></van-icon>-->
|
||||
<!-- <span>{{ timeName }}</span>-->
|
||||
@@ -229,6 +229,7 @@ layout("/layouts/platform_h5.html"){
|
||||
.vote-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid #ebedf0;
|
||||
@@ -357,7 +358,6 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
.vote-description {
|
||||
padding: 20px;
|
||||
border-left: 4px solid #1989fa;
|
||||
}
|
||||
|
||||
.description-header {
|
||||
@@ -402,6 +402,32 @@ layout("/layouts/platform_h5.html"){
|
||||
border: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.vote-table-container {
|
||||
border-color: #dfe5ee;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(30, 48, 80, 0.04);
|
||||
}
|
||||
|
||||
.vote-table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.vote-table th,
|
||||
.vote-table td {
|
||||
border: 0;
|
||||
border-right: 1px solid #dfe5ee;
|
||||
border-bottom: 1px solid #dfe5ee;
|
||||
}
|
||||
|
||||
.vote-table tr > :last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.vote-table tbody tr:last-child td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--#
|
||||
|
||||
Reference in New Issue
Block a user