feat:系统UI优化初版
This commit is contained in:
+5
-1
@@ -84,7 +84,7 @@ public class LearningCourseDisplayController {
|
|||||||
/**
|
/**
|
||||||
* 查询课程展示列表。
|
* 查询课程展示列表。
|
||||||
* pageForm 传分页页码和每页条数;keyword、courseTypeId、recommendFlag 分别用于关键词、分类和推荐标识筛选;
|
* pageForm 传分页页码和每页条数;keyword、courseTypeId、recommendFlag 分别用于关键词、分类和推荐标识筛选;
|
||||||
* sortType 支持 default(综合排序)和 view_count(观看次数倒序)。返回值为 Pagination,list 中包含课程基础字段、课节数、总时长和观看次数。
|
* sortType 支持 default(综合排序)和 view_count(观看次数倒序)。返回值为 Pagination,list 中包含课程基础字段、课节数、总时长、观看次数和当前用户学习进度。
|
||||||
*/
|
*/
|
||||||
public Result pageData(PageForm pageForm, String keyword, String courseTypeId, String recommendFlag, String sortType) {
|
public Result pageData(PageForm pageForm, String keyword, String courseTypeId, String recommendFlag, String sortType) {
|
||||||
Cnd cnd = Cnd.where("c.status", "=", "published");
|
Cnd cnd = Cnd.where("c.status", "=", "published");
|
||||||
@@ -112,6 +112,9 @@ public class LearningCourseDisplayController {
|
|||||||
SELECT c.id, c.courseName, c.courseIntro, c.startTime, c.endTime, c.openType, c.cover,
|
SELECT c.id, c.courseName, c.courseIntro, c.startTime, c.endTime, c.openType, c.cover,
|
||||||
c.recommendFlags, c.courseTypeId, c.lecturerName, c.sortNum,
|
c.recommendFlags, c.courseTypeId, c.lecturerName, c.sortNum,
|
||||||
COALESCE(c.viewCount, 0) AS viewCount, t.typeName AS courseTypeName,
|
COALESCE(c.viewCount, 0) AS viewCount, t.typeName AS courseTypeName,
|
||||||
|
COALESCE((SELECT ROUND(AVG(IFNULL(sr.progressPercent, 0)))
|
||||||
|
FROM learning_study_record sr
|
||||||
|
WHERE sr.courseId = c.id AND sr.userId = @userId), 0) AS progressPercent,
|
||||||
(SELECT COUNT(1) FROM learning_outline_resource r
|
(SELECT COUNT(1) FROM learning_outline_resource r
|
||||||
WHERE r.courseId = c.id AND r.status = 'enabled') AS resourceCount,
|
WHERE r.courseId = c.id AND r.status = 'enabled') AS resourceCount,
|
||||||
COALESCE((SELECT SUM(r.durationSeconds) FROM learning_outline_resource r
|
COALESCE((SELECT SUM(r.durationSeconds) FROM learning_outline_resource r
|
||||||
@@ -122,6 +125,7 @@ public class LearningCourseDisplayController {
|
|||||||
ORDER BY $orderBy
|
ORDER BY $orderBy
|
||||||
""");
|
""");
|
||||||
listSql.setCondition(cnd);
|
listSql.setCondition(cnd);
|
||||||
|
listSql.params().set("userId", SecurityUtil.getUserId());
|
||||||
// 排序字段由固定选项映射,禁止将前端参数直接拼接进SQL。
|
// 排序字段由固定选项映射,禁止将前端参数直接拼接进SQL。
|
||||||
listSql.setVar("orderBy", "view_count".equals(sortType)
|
listSql.setVar("orderBy", "view_count".equals(sortType)
|
||||||
? "COALESCE(c.viewCount, 0) DESC, c.sortNum ASC, c.createdAt DESC"
|
? "COALESCE(c.viewCount, 0) DESC, c.sortNum ASC, c.createdAt DESC"
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.budwk.app.zhgh.spread.h5controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import com.budwk.app.base.param.PageForm;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.zhgh.spread.service.SpreadCategoryService;
|
||||||
|
import com.budwk.app.zhgh.spread.service.SpreadContentService;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 风采墙 H5 展示控制器,提供栏目、列表和内容详情预览。
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/h5/spread")
|
||||||
|
public class H5SpreadDisplayController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SpreadCategoryService categoryService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SpreadContentService contentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开风采墙 H5 预览页面。
|
||||||
|
*/
|
||||||
|
@At("")
|
||||||
|
@Ok("beetl:/platform/zhghh5/spread/display/index.html")
|
||||||
|
@SaCheckLogin
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 H5 端可见栏目树。
|
||||||
|
*
|
||||||
|
* @return 按层级组织的可见栏目
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("H5可见栏目树")
|
||||||
|
public Result categoryTree() {
|
||||||
|
return Result.success(categoryService.categoryTree(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询指定栏目及其子栏目的已发布内容。
|
||||||
|
*
|
||||||
|
* @param pageForm 分页参数
|
||||||
|
* @param categoryId 栏目 ID
|
||||||
|
* @param title 标题模糊查询条件
|
||||||
|
* @return 已发布内容分页数据
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("H5已发布内容分页")
|
||||||
|
public Result pageData(PageForm pageForm, String categoryId, String title) {
|
||||||
|
return Result.success(contentService.pagePublished(pageForm, categoryId, title));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 H5 内容详情。
|
||||||
|
*
|
||||||
|
* @param id 内容 ID
|
||||||
|
* @return 内容详情
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("H5内容详情")
|
||||||
|
public Result detailData(String id) {
|
||||||
|
try {
|
||||||
|
return Result.success(contentService.getContent(id));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登记 H5 内容浏览量。
|
||||||
|
*
|
||||||
|
* @param id 内容 ID
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@SaCheckLogin
|
||||||
|
@ApiOperation("H5增加浏览量")
|
||||||
|
public Result addView(String id) {
|
||||||
|
try {
|
||||||
|
contentService.addViewCount(id);
|
||||||
|
return Result.success();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,16 @@ public interface SpreadContentService extends BaseService<SpreadContent> {
|
|||||||
|
|
||||||
Pagination<NutMap> pagePublished(PageForm pageForm, String categoryId);
|
Pagination<NutMap> pagePublished(PageForm pageForm, String categoryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询指定栏目中标题匹配的已发布内容。
|
||||||
|
*
|
||||||
|
* @param pageForm 分页参数
|
||||||
|
* @param categoryId 栏目 ID,查询时包含该栏目的直接子栏目
|
||||||
|
* @param title 标题模糊查询条件
|
||||||
|
* @return 已发布内容分页数据
|
||||||
|
*/
|
||||||
|
Pagination<NutMap> pagePublished(PageForm pageForm, String categoryId, String title);
|
||||||
|
|
||||||
SpreadContent getContent(String id);
|
SpreadContent getContent(String id);
|
||||||
|
|
||||||
void saveContent(SpreadContent content);
|
void saveContent(SpreadContent content);
|
||||||
|
|||||||
@@ -62,8 +62,22 @@ public class SpreadContentServiceImpl extends BaseServiceImpl<SpreadContent> imp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pagination<NutMap> pagePublished(PageForm pageForm, String categoryId) {
|
public Pagination<NutMap> pagePublished(PageForm pageForm, String categoryId) {
|
||||||
|
return pagePublished(pageForm, categoryId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询指定栏目中标题匹配的已发布内容。
|
||||||
|
*
|
||||||
|
* @param pageForm 分页参数
|
||||||
|
* @param categoryId 栏目 ID,查询时包含该栏目的直接子栏目
|
||||||
|
* @param title 标题模糊查询条件
|
||||||
|
* @return 已发布内容分页数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Pagination<NutMap> pagePublished(PageForm pageForm, String categoryId, String title) {
|
||||||
SpreadContentQuery query = new SpreadContentQuery();
|
SpreadContentQuery query = new SpreadContentQuery();
|
||||||
query.setCategoryId(categoryId);
|
query.setCategoryId(categoryId);
|
||||||
|
query.setTitle(title);
|
||||||
query.setIsPublished(1);
|
query.setIsPublished(1);
|
||||||
Cnd cnd = buildCondition(query);
|
Cnd cnd = buildCondition(query);
|
||||||
Sql countSql = Sqls.create("SELECT COUNT(1) FROM spread_content c $condition");
|
Sql countSql = Sqls.create("SELECT COUNT(1) FROM spread_content c $condition");
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 2.0 MiB |
@@ -124,11 +124,44 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.custom-list-loading {
|
.custom-list-loading {
|
||||||
background-color: unset;
|
min-width: 72px;
|
||||||
|
padding: 10px 12px 9px;
|
||||||
|
border-radius: 12px;
|
||||||
|
color: #7890a8;
|
||||||
|
background-color: rgba(255, 255, 255, 0.94);
|
||||||
|
box-shadow: 0 5px 18px rgba(52, 91, 128, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-list-loading .van-icon {
|
.custom-list-loading .van-icon {
|
||||||
font-size: 108px;
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 48px;
|
||||||
|
transform-origin: center;
|
||||||
|
animation: smart-union-loading-breathe 1.15s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-list-loading .van-icon__image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes smart-union-loading-breathe {
|
||||||
|
0%, 100% {
|
||||||
|
opacity: 0.58;
|
||||||
|
transform: scale(0.92);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.03);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-list-loading .van-toast__text {
|
||||||
|
margin-top: 5px;
|
||||||
|
color: #7890a8;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-card {
|
.list-card {
|
||||||
|
|||||||
@@ -149,9 +149,10 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function createListLoading(icon = "https://preview.qiantucdn.com/58pic/35/39/61/62K58PICb88i68HEwVnm5_PIC2018.gif!qt480") {
|
function createListLoading(icon = "/assets/mobile/img/common/smart-union-loading.png") {
|
||||||
return vant.Toast.loading({
|
return vant.Toast.loading({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
|
message: "加载中...",
|
||||||
forbidClick: true,
|
forbidClick: true,
|
||||||
loadingType: "spinner",
|
loadingType: "spinner",
|
||||||
duration: 0,
|
duration: 0,
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform_h5.html"){
|
||||||
|
#-->
|
||||||
|
<style>
|
||||||
|
body { background: #f5f7fa; }
|
||||||
|
.spread-h5 { min-height: 100vh; color: #202124; background: #f5f7fa; }
|
||||||
|
.spread-h5__toolbar { position: sticky; top: 46px; z-index: 15; background: #fff; box-shadow: 0 3px 10px rgba(31,72,122,.06); }
|
||||||
|
.spread-h5__search { padding: 8px 12px 2px; background: #fff; }
|
||||||
|
.spread-h5__search .van-search { padding: 0; }
|
||||||
|
.spread-h5__categories { padding: 2px 12px 10px; background: #fff; }
|
||||||
|
.spread-h5__tabs { height: 36px; padding: 0; display: flex; gap: 0; overflow-x: auto; overflow-y: hidden; border-bottom: 1px solid #edf1f6; border-radius: 0; background: transparent; box-sizing: border-box; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
|
||||||
|
.spread-h5__tabs::-webkit-scrollbar { display: none; }
|
||||||
|
.spread-h5__tab { position: relative; min-width: 92px; height: 30px; padding: 0 8px; flex: 1 0 calc((100% - 8px) / 3); display: flex; align-items: center; justify-content: center; color: #7d8797; font-size: 13px; white-space: nowrap; border-radius: 6px; box-sizing: border-box; }
|
||||||
|
.spread-h5__tab--active { color: #087af4; font-weight: 600; background: transparent; box-shadow: none; }
|
||||||
|
.spread-h5__tabs:not(.spread-h5__tabs--secondary) .spread-h5__tab--active::after { content: ""; position: absolute; left: 50%; bottom: -1px; width: 26px; height: 2px; border-radius: 2px; background: #087af4; transform: translateX(-50%); }
|
||||||
|
.spread-h5__tabs--secondary { height: 30px; margin-top: 7px; padding: 1px 0; gap: 6px; border-bottom: 0; border-radius: 0; background: transparent; }
|
||||||
|
.spread-h5__tabs--secondary .spread-h5__tab { min-width: 84px; height: 26px; padding: 0 10px; flex: 1 0 calc((100% - 12px) / 3); color: #969daa; font-size: 11px; border: 1px solid #e7ecf3; border-radius: 999px; background: #fafbfd; box-shadow: none; }
|
||||||
|
.spread-h5__tabs--secondary .spread-h5__tab--active { color: #087af4; border-color: #b9d8ff; background: #edf6ff; }
|
||||||
|
.spread-h5__list { margin: 10px 12px 20px; padding: 0 12px; border-radius: 10px; background: #fff; }
|
||||||
|
.spread-h5__item { min-height: 82px; padding: 11px 0; display: flex; align-items: center; box-sizing: border-box; }
|
||||||
|
.spread-h5__item + .spread-h5__item { border-top: 1px solid #f0f2f5; }
|
||||||
|
.spread-h5__cover { width: 96px; height: 60px; margin-right: 11px; flex-shrink: 0; border-radius: 5px; object-fit: cover; }
|
||||||
|
.spread-h5__item-content { min-width: 0; flex: 1; }
|
||||||
|
.spread-h5__item-title { overflow: hidden; color: #202124; font-size: 14px; line-height: 20px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
|
.spread-h5__item-summary { margin-top: 4px; overflow: hidden; color: #7d8797; font-size: 11px; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
|
.spread-h5__item-meta { margin-top: 6px; display: flex; align-items: center; justify-content: space-between; color: #9aa2af; font-size: 10px; line-height: 14px; }
|
||||||
|
.spread-h5__views { display: inline-flex; align-items: center; }
|
||||||
|
.spread-h5__views .van-icon { margin-right: 3px; }
|
||||||
|
.spread-h5__loading { padding: 35px 0; text-align: center; }
|
||||||
|
.spread-h5__finished { padding: 10px 0 18px; color: #b0b6c0; font-size: 11px; line-height: 16px; text-align: center; }
|
||||||
|
.spread-h5__empty { padding: 36px 0; color: #9aa2af; font-size: 13px; line-height: 20px; text-align: center; }
|
||||||
|
.spread-h5__detail { margin: 10px 12px 24px; padding: 18px 15px 24px; border-radius: 10px; background: #fff; }
|
||||||
|
.spread-h5__detail-title { margin: 0; color: #202124; font-size: 20px; line-height: 29px; text-align: center; word-break: break-word; }
|
||||||
|
.spread-h5__detail-meta { margin-top: 10px; padding-bottom: 14px; color: #9aa2af; font-size: 11px; line-height: 17px; text-align: center; border-bottom: 1px solid #edf1f6; }
|
||||||
|
.spread-h5__detail-summary { margin: 15px 0 0; padding: 10px 12px; color: #697386; font-size: 14px; line-height: 22px; border-radius: 6px; background: #f7f9fc; }
|
||||||
|
.spread-h5__detail-cover { width: 100%; max-height: 240px; margin: 16px 0 0; display: block; border-radius: 6px; object-fit: contain; }
|
||||||
|
.spread-h5__slider { height: 220px; margin-top: 16px; overflow: hidden; border-radius: 6px; background: #eef2f7; }
|
||||||
|
.spread-h5__slide { position: relative; height: 220px; }
|
||||||
|
.spread-h5__slide img { width: 100%; height: 100%; display: block; object-fit: contain; }
|
||||||
|
.spread-h5__slide-caption { position: absolute; left: 0; right: 0; bottom: 0; padding: 24px 12px 10px; overflow: hidden; color: #fff; font-size: 12px; line-height: 18px; text-overflow: ellipsis; white-space: nowrap; background: linear-gradient(to top, rgba(15,23,42,.72), transparent); box-sizing: border-box; }
|
||||||
|
.spread-h5__detail-body { margin-top: 16px; overflow: hidden; color: #323233; font-size: 15px; line-height: 1.8; word-break: break-word; }
|
||||||
|
.spread-h5__detail-body img, .spread-h5__detail-body video { max-width: 100% !important; height: auto !important; }
|
||||||
|
.spread-h5__detail-body table { max-width: 100% !important; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" class="spread-h5" v-cloak>
|
||||||
|
<van-nav-bar :title="detail ? '动态详情' : '工会动态'" left-arrow left-text="返回" fixed placeholder :z-index="20" @click-left="handleBack"></van-nav-bar>
|
||||||
|
|
||||||
|
<template v-if="!detail">
|
||||||
|
<div class="spread-h5__toolbar">
|
||||||
|
<div class="spread-h5__search">
|
||||||
|
<van-search v-model.trim="keyword"
|
||||||
|
shape="round"
|
||||||
|
placeholder="搜索动态标题"
|
||||||
|
@search="doSearch"
|
||||||
|
@clear="doSearch"></van-search>
|
||||||
|
</div>
|
||||||
|
<div class="spread-h5__categories" v-if="categories.length">
|
||||||
|
<div class="spread-h5__tabs">
|
||||||
|
<div class="spread-h5__tab"
|
||||||
|
v-for="category in categories"
|
||||||
|
:key="category.id"
|
||||||
|
:class="{'spread-h5__tab--active': parentId === category.id}"
|
||||||
|
@click="selectParent(category)">{{category.name}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="spread-h5__tabs spread-h5__tabs--secondary" v-if="currentChildren.length">
|
||||||
|
<div class="spread-h5__tab"
|
||||||
|
v-for="category in currentChildren"
|
||||||
|
:key="category.id"
|
||||||
|
:class="{'spread-h5__tab--active': categoryId === category.id}"
|
||||||
|
@click="selectCategory(category)">{{category.name}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="pageData.list.length" class="spread-h5__list">
|
||||||
|
<div class="spread-h5__item" v-for="item in pageData.list" :key="item.id" @click="openDetail(item)">
|
||||||
|
<img v-if="getCoverUrl(item.thumbUrl)" class="spread-h5__cover" :src="getCoverUrl(item.thumbUrl)" :alt="item.title">
|
||||||
|
<div class="spread-h5__item-content">
|
||||||
|
<div class="spread-h5__item-title">{{item.title}}</div>
|
||||||
|
<div v-if="item.summary || item.subTitle" class="spread-h5__item-summary">{{item.summary || item.subTitle}}</div>
|
||||||
|
<div class="spread-h5__item-meta">
|
||||||
|
<span>{{formatDate(item.publishedAt || item.createdAt)}}</span>
|
||||||
|
<span class="spread-h5__views"><van-icon name="eye-o"></van-icon>{{item.viewCount || 0}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="loading" class="spread-h5__loading"><van-loading size="22px">加载中...</van-loading></div>
|
||||||
|
<div v-if="!loading && finished && pageData.list.length" class="spread-h5__finished">没有更多了</div>
|
||||||
|
<div v-if="!loading && finished && !pageData.list.length" class="spread-h5__empty">暂无动态</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<article v-else class="spread-h5__detail">
|
||||||
|
<h1 class="spread-h5__detail-title">{{detail.title}}</h1>
|
||||||
|
<div class="spread-h5__detail-meta">
|
||||||
|
{{formatDate(detail.publishedAt || detail.createdAt)}} {{detail.categoryName}}
|
||||||
|
<van-icon name="eye-o"></van-icon> {{detail.viewCount || 0}}
|
||||||
|
</div>
|
||||||
|
<img v-if="getCoverUrl(detail.thumbUrl)" class="spread-h5__detail-cover" :src="getCoverUrl(detail.thumbUrl)" :alt="detail.title">
|
||||||
|
<div v-if="detail.summary" class="spread-h5__detail-summary">{{detail.summary}}</div>
|
||||||
|
<van-swipe v-if="detailSlides.length"
|
||||||
|
class="spread-h5__slider"
|
||||||
|
:autoplay="3000"
|
||||||
|
:show-indicators="detailSlides.length > 1"
|
||||||
|
indicator-color="#1989fa">
|
||||||
|
<van-swipe-item v-for="(slide, index) in detailSlides" :key="slide.src + '-' + index">
|
||||||
|
<div class="spread-h5__slide">
|
||||||
|
<img :src="slide.src" :alt="slide.title || detail.title">
|
||||||
|
<div v-if="slide.title" class="spread-h5__slide-caption">{{slide.title}}</div>
|
||||||
|
</div>
|
||||||
|
</van-swipe-item>
|
||||||
|
</van-swipe>
|
||||||
|
<div class="spread-h5__detail-body" v-html="detail.contentBody"></div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script nonce="${cspNonce!}">
|
||||||
|
new Vue({
|
||||||
|
el: "#app",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
apiBase: "/platform/h5/spread",
|
||||||
|
categories: [],
|
||||||
|
parentId: "",
|
||||||
|
categoryId: "",
|
||||||
|
keyword: "",
|
||||||
|
loading: false,
|
||||||
|
finished: false,
|
||||||
|
scrollContainer: null,
|
||||||
|
requestSeq: 0,
|
||||||
|
detail: null,
|
||||||
|
pageData: {pageNumber: 1, pageSize: 10, totalCount: 0, list: []}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentChildren() {
|
||||||
|
const parent = this.categories.find(item => item.id === this.parentId)
|
||||||
|
return parent && parent.children ? parent.children : []
|
||||||
|
},
|
||||||
|
detailSlides() {
|
||||||
|
return this.getSliderEntries(this.detail && this.detail.sliderImages)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadCategories() {
|
||||||
|
return this.$axios.post(this.apiBase + "/categoryTree").then(resp => {
|
||||||
|
if (resp.code !== 0) return
|
||||||
|
this.categories = resp.data || []
|
||||||
|
const firstParent = this.categories[0]
|
||||||
|
if (!firstParent) return
|
||||||
|
this.parentId = firstParent.id
|
||||||
|
const children = firstParent.children || []
|
||||||
|
this.categoryId = children.length ? children[0].id : firstParent.id
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadPage() {
|
||||||
|
if (!this.categoryId || this.loading || this.finished) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loading = true
|
||||||
|
const requestSeq = ++this.requestSeq
|
||||||
|
this.$axios.post(this.apiBase + "/pageData", {
|
||||||
|
categoryId: this.categoryId,
|
||||||
|
title: this.keyword,
|
||||||
|
pageNumber: this.pageData.pageNumber,
|
||||||
|
pageSize: this.pageData.pageSize
|
||||||
|
}).then(resp => {
|
||||||
|
if (requestSeq !== this.requestSeq) return
|
||||||
|
if (resp.code === 0) {
|
||||||
|
const data = resp.data || {}
|
||||||
|
const rows = data.list || []
|
||||||
|
this.pageData.list = this.pageData.list.concat(rows)
|
||||||
|
this.pageData.totalCount = data.totalCount || 0
|
||||||
|
this.pageData.pageNumber += 1
|
||||||
|
this.finished = this.pageData.list.length >= this.pageData.totalCount || rows.length < this.pageData.pageSize
|
||||||
|
} else {
|
||||||
|
this.finished = true
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
if (requestSeq === this.requestSeq) this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
resetPage() {
|
||||||
|
this.requestSeq += 1
|
||||||
|
this.loading = false
|
||||||
|
this.finished = false
|
||||||
|
this.pageData = {pageNumber: 1, pageSize: 10, totalCount: 0, list: []}
|
||||||
|
this.$nextTick(() => this.loadPage())
|
||||||
|
},
|
||||||
|
handlePageScroll() {
|
||||||
|
if (!this.scrollContainer || this.loading || this.finished || this.detail) return
|
||||||
|
const remaining = this.scrollContainer.scrollHeight
|
||||||
|
- this.scrollContainer.scrollTop
|
||||||
|
- this.scrollContainer.clientHeight
|
||||||
|
if (remaining <= 80) this.loadPage()
|
||||||
|
},
|
||||||
|
doSearch() {
|
||||||
|
this.resetPage()
|
||||||
|
},
|
||||||
|
selectParent(category) {
|
||||||
|
if (this.parentId === category.id) return
|
||||||
|
this.parentId = category.id
|
||||||
|
const children = category.children || []
|
||||||
|
this.categoryId = children.length ? children[0].id : category.id
|
||||||
|
this.resetPage()
|
||||||
|
},
|
||||||
|
selectCategory(category) {
|
||||||
|
if (this.categoryId === category.id) return
|
||||||
|
this.categoryId = category.id
|
||||||
|
this.resetPage()
|
||||||
|
},
|
||||||
|
openDetail(item) {
|
||||||
|
this.loading = true
|
||||||
|
Promise.all([
|
||||||
|
this.$axios.post(this.apiBase + "/detailData", {id: item.id}),
|
||||||
|
this.$axios.post(this.apiBase + "/addView", {id: item.id})
|
||||||
|
]).then(values => {
|
||||||
|
if (values[0].code === 0) {
|
||||||
|
this.detail = values[0].data
|
||||||
|
this.detail.viewCount = Number(this.detail.viewCount || 0) + 1
|
||||||
|
}
|
||||||
|
}).finally(() => this.loading = false)
|
||||||
|
},
|
||||||
|
loadRequestedDetail() {
|
||||||
|
const id = new URLSearchParams(window.location.search).get("id")
|
||||||
|
if (!id) return false
|
||||||
|
this.openDetail({id: id})
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
handleBack() {
|
||||||
|
if (this.detail) {
|
||||||
|
this.detail = null
|
||||||
|
if (!this.pageData.list.length) this.resetPage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$pjaxReplace("/platform/h5/home")
|
||||||
|
},
|
||||||
|
getCoverUrl(value) {
|
||||||
|
if (!value) return ""
|
||||||
|
let files = value
|
||||||
|
if (typeof value === "string" && value.trim().startsWith("[")) {
|
||||||
|
try {
|
||||||
|
files = JSON.parse(value)
|
||||||
|
} catch (e) {
|
||||||
|
files = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Array.isArray(files)) files = String(files).split(",")
|
||||||
|
const first = files[0]
|
||||||
|
if (typeof first === "string") return first.trim()
|
||||||
|
return first && (first.src || first.url || first.data || (first.response && first.response.data)) || ""
|
||||||
|
},
|
||||||
|
getSliderEntries(value) {
|
||||||
|
if (!value) return []
|
||||||
|
let items = value
|
||||||
|
if (!Array.isArray(items)) {
|
||||||
|
try {
|
||||||
|
items = JSON.parse(value)
|
||||||
|
} catch (e) {
|
||||||
|
items = String(value).split(",").filter(Boolean)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Array.isArray(items)) return []
|
||||||
|
return items.map(item => {
|
||||||
|
if (typeof item === "string") return {src: item.trim(), title: ""}
|
||||||
|
return {
|
||||||
|
src: item.src || item.url || item.data || (item.response && item.response.data) || "",
|
||||||
|
title: item.title || item.description || ""
|
||||||
|
}
|
||||||
|
}).filter(item => item.src)
|
||||||
|
},
|
||||||
|
formatDate(value) {
|
||||||
|
return value ? this.$moment(Number(value)).format("YYYY-MM-DD") : ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadCategories().then(() => {
|
||||||
|
if (!this.loadRequestedDetail()) this.resetPage()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.scrollContainer = document.querySelector("body > .main-page .page-wrapper")
|
||||||
|
if (this.scrollContainer) {
|
||||||
|
this.scrollContainer.addEventListener("scroll", this.handlePageScroll, {passive: true})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.scrollContainer) {
|
||||||
|
this.scrollContainer.removeEventListener("scroll", this.handlePageScroll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
+38
-2
@@ -1,6 +1,29 @@
|
|||||||
const MOBILE_MEMBER_INFO = {
|
const MOBILE_MEMBER_INFO = {
|
||||||
template: /*language=HTML*/ `
|
template: /*language=HTML*/ `
|
||||||
<div class="detail-container">
|
<div v-if="profileMode" class="mine-profile-details">
|
||||||
|
<section class="mine-detail-card">
|
||||||
|
<h2>基本信息</h2>
|
||||||
|
<div class="mine-detail-row"><span>姓名</span><strong>{{ viewData.username || '-' }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>性别</span><strong>{{ viewData.sex || '-' }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>民族</span><strong>{{ viewData.nation || '-' }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>出生日期</span><strong>{{ formatBirthday(viewData.birthday) }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>政治面貌</span><strong>{{ viewData.political || '-' }}</strong></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="mine-detail-card">
|
||||||
|
<h2>组织信息</h2>
|
||||||
|
<div class="mine-detail-row"><span>工作单位</span><strong>{{ viewData.unitName || '-' }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>所属工会</span><strong>{{ viewData.unionName || '-' }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>人员类型</span><strong>{{ viewData.personType || '-' }}</strong></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="mine-detail-card">
|
||||||
|
<h2>联系方式</h2>
|
||||||
|
<div class="mine-detail-row"><span>联系电话</span><strong>{{ maskMobile(viewData.mobile) }}</strong></div>
|
||||||
|
<div class="mine-detail-row"><span>电子邮箱</span><strong>{{ viewData.email || '-' }}</strong></div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div v-else class="detail-container">
|
||||||
<van-cell-group title="基本信息">
|
<van-cell-group title="基本信息">
|
||||||
<van-cell title="工号">{{ viewData.loginname }}</van-cell>
|
<van-cell title="工号">{{ viewData.loginname }}</van-cell>
|
||||||
<van-cell title="姓名">{{ viewData.username }}</van-cell>
|
<van-cell title="姓名">{{ viewData.username }}</van-cell>
|
||||||
@@ -61,7 +84,8 @@
|
|||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
props: {
|
props: {
|
||||||
userId: { type: String, required: true }
|
userId: { type: String, required: true },
|
||||||
|
profileMode: { type: Boolean, default: false }
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -77,6 +101,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formatBirthday(birthday) {
|
||||||
|
if (!birthday) {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
return this.$moment(birthday).format("YYYY-MM-DD")
|
||||||
|
},
|
||||||
|
maskMobile(mobile) {
|
||||||
|
if (!mobile) {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
return mobile.replace(/^(\d{3})\d+(\d{4})$/, "$1****$2")
|
||||||
|
},
|
||||||
findUserInfoByUserId() {
|
findUserInfoByUserId() {
|
||||||
if (!this.userId) {
|
if (!this.userId) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -6,13 +6,19 @@ const apps = {
|
|||||||
<van-sticky offset-top="46px">
|
<van-sticky offset-top="46px">
|
||||||
<van-search
|
<van-search
|
||||||
v-model="searchKeyword"
|
v-model="searchKeyword"
|
||||||
placeholder="搜索应用"
|
placeholder="搜索应用或服务名称"
|
||||||
show-action
|
|
||||||
@search="onSearch"
|
@search="onSearch"
|
||||||
@cancel="onCancel"
|
@cancel="onCancel"
|
||||||
></van-search>
|
></van-search>
|
||||||
</van-sticky>
|
</van-sticky>
|
||||||
|
|
||||||
|
<div class="apps-guide-banner">
|
||||||
|
<div class="apps-guide-copy">
|
||||||
|
<div class="apps-guide-title">工会服务,一站直达</div>
|
||||||
|
<div class="apps-guide-desc">常用应用与业务办理便捷入口</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="custom-tree-select">
|
<div class="custom-tree-select">
|
||||||
<!-- 左侧导航 -->
|
<!-- 左侧导航 -->
|
||||||
<div class="tree-nav">
|
<div class="tree-nav">
|
||||||
@@ -22,24 +28,20 @@ const apps = {
|
|||||||
:class="['nav-item', { active: activeTab === index }]"
|
:class="['nav-item', { active: activeTab === index }]"
|
||||||
@click="onClickNav(index)"
|
@click="onClickNav(index)"
|
||||||
>
|
>
|
||||||
<div class="nav-icon">
|
|
||||||
<!--<i v-if="category.icon" :class="category.icon"></i>
|
|
||||||
<i v-else class="fa fa-book"></i>-->
|
|
||||||
<img v-if="category.picIcon" :src="category.picIcon" :alt="category.name || ''" style="width: 18px"/>
|
|
||||||
<i v-else :class="category.icon || 'fa fa-th-large'"></i>
|
|
||||||
</div>
|
|
||||||
<div class="nav-text">{{ category.name }}</div>
|
<div class="nav-text">{{ category.name }}</div>
|
||||||
<div class="nav-indicator" v-if="activeTab === index"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 右侧内容 -->
|
<!-- 右侧内容 -->
|
||||||
<div class="tree-content">
|
<div class="tree-content">
|
||||||
|
<div class="tree-content-title">
|
||||||
|
{{ allCategories[activeTab] ? allCategories[activeTab].name : '全部应用' }}
|
||||||
|
</div>
|
||||||
<div v-if="loading" class="module-loading">
|
<div v-if="loading" class="module-loading">
|
||||||
<van-loading size="24px">加载中...</van-loading>
|
<van-loading size="24px">加载中...</van-loading>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="['app-grid', { 'app-grid-single': applications.length === 1 }]"
|
<div class="app-grid"
|
||||||
v-else-if="isFixedCategory && applications.length > 0">
|
v-else-if="isFixedCategory && applications.length > 0">
|
||||||
<div v-for="app in applications"
|
<div v-for="app in applications"
|
||||||
:key="app.id"
|
:key="app.id"
|
||||||
@@ -47,21 +49,26 @@ const apps = {
|
|||||||
:class="{ 'is-favorite': app.isFavorite }"
|
:class="{ 'is-favorite': app.isFavorite }"
|
||||||
@click="openApp(app)"
|
@click="openApp(app)"
|
||||||
@touchstart="onTouchStart(app)"
|
@touchstart="onTouchStart(app)"
|
||||||
@touchend="onTouchEnd"
|
@touchend="onTouchEnd"
|
||||||
@touchmove="onTouchMove">
|
@touchmove="onTouchMove">
|
||||||
<div class="app-grid-icon">
|
<div class="app-grid-icon">
|
||||||
<van-icon v-if="app.picIcon" :name="app.picIcon" size="45"></van-icon>
|
<img v-if="app.picIcon" :src="app.picIcon" :alt="app.name || ''"/>
|
||||||
<van-icon v-else-if="app.icon" :name="app.icon" size="28"></van-icon>
|
<van-icon v-else-if="app.icon" :name="app.icon" size="28"></van-icon>
|
||||||
<van-icon v-else name="apps-o" size="28"></van-icon>
|
<van-icon v-else name="apps-o" size="28"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-grid-name">{{ app.name }}</div>
|
<div class="app-grid-info">
|
||||||
|
<div class="app-grid-name">{{ app.name }}</div>
|
||||||
|
<div v-if="app.aliasName || app.note" class="app-grid-desc">{{ app.aliasName || app.note }}</div>
|
||||||
|
</div>
|
||||||
|
<van-icon v-if="app.isFavorite" name="star" class="app-grid-favorite"></van-icon>
|
||||||
|
<van-icon name="arrow" class="app-grid-arrow"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="!isFixedCategory && moduleSections.length > 0" class="module-sections">
|
<div v-else-if="!isFixedCategory && moduleSections.length > 0" class="module-sections">
|
||||||
<div v-for="section in moduleSections" :key="section.id" class="module-section">
|
<div v-for="section in moduleSections" :key="section.id" class="module-section">
|
||||||
<div class="module-title">{{ section.name }}</div>
|
<div class="module-title">{{ section.name }}</div>
|
||||||
<div :class="['module-grid', { 'module-grid-single': section.menus.length === 1 }]">
|
<div class="module-grid">
|
||||||
<div
|
<div
|
||||||
v-for="menu in section.menus"
|
v-for="menu in section.menus"
|
||||||
:key="menu.id"
|
:key="menu.id"
|
||||||
@@ -72,7 +79,11 @@ const apps = {
|
|||||||
<div v-else class="module-feature-icon">
|
<div v-else class="module-feature-icon">
|
||||||
<van-icon :name="menu.icon || 'apps-o'" size="24"></van-icon>
|
<van-icon :name="menu.icon || 'apps-o'" size="24"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="module-feature-name">{{ menu.name }}</div>
|
<div class="module-feature-info">
|
||||||
|
<div class="module-feature-name">{{ menu.name }}</div>
|
||||||
|
<div v-if="menu.aliasName || menu.note" class="module-feature-desc">{{ menu.aliasName || menu.note }}</div>
|
||||||
|
</div>
|
||||||
|
<van-icon name="arrow" class="module-feature-arrow"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +96,7 @@ const apps = {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 应用菜单弹框 -->
|
<!-- 应用菜单弹框 -->
|
||||||
<van-popup v-model="showMenuPopup" position="bottom" :style="{ width: '100%', maxHeight: '60%' }" round>
|
<van-popup v-model="showMenuPopup" position="bottom" :style="{ width: '100%', height: '62%' }" round>
|
||||||
<div class="menu-popup">
|
<div class="menu-popup">
|
||||||
<div class="popup-header">
|
<div class="popup-header">
|
||||||
<div class="popup-title">{{ currentApp.name }}</div>
|
<div class="popup-title">{{ currentApp.name }}</div>
|
||||||
@@ -98,12 +109,17 @@ const apps = {
|
|||||||
class="grid-item"
|
class="grid-item"
|
||||||
@click="navigateToMenu(menu)"
|
@click="navigateToMenu(menu)"
|
||||||
>
|
>
|
||||||
<img v-if="menu.picIcon" :src="menu.picIcon" :alt="menu.name || ''" style="width: 48px" class="grid-img"/>
|
<div v-if="menu.picIcon" class="grid-img-wrap">
|
||||||
|
<img :src="menu.picIcon" :alt="menu.name || ''" class="grid-img"/>
|
||||||
|
</div>
|
||||||
<div v-else class="grid-icon">
|
<div v-else class="grid-icon">
|
||||||
<van-icon :name="menu.icon || 'apps-o'" size="24"></van-icon>
|
<van-icon :name="menu.icon || 'apps-o'" size="24"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-name">{{ menu.name }}</div>
|
<div class="grid-info">
|
||||||
<div class="grid-desc" v-if="menu.aliasName">{{ menu.aliasName }}</div>
|
<div class="grid-name">{{ menu.name }}</div>
|
||||||
|
<div class="grid-desc" v-if="menu.aliasName || menu.note">{{ menu.aliasName || menu.note }}</div>
|
||||||
|
</div>
|
||||||
|
<van-icon name="arrow" class="grid-arrow"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -432,6 +448,65 @@ const apps = {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: calc(100vh - 50px);
|
height: calc(100vh - 50px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-container .van-search {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-container .van-search__content {
|
||||||
|
border-radius: 18px;
|
||||||
|
background: #f3f5f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-guide-banner {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 132px;
|
||||||
|
margin: 0 12px 10px;
|
||||||
|
border-radius: 9px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #168cff url('/assets/mobile/img/home/v4/apps-guide-banner.png') right top / cover no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-guide-copy {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
width: 58%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 0 0 16px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-guide-title {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 1.35;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-guide-desc {
|
||||||
|
margin-top: 7px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
opacity: 0.94;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-content-title {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 38px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 16px;
|
||||||
|
border-bottom: 1px solid #eef1f5;
|
||||||
|
color: #1677ff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自定义树形选择组件样式 */
|
/* 自定义树形选择组件样式 */
|
||||||
@@ -439,7 +514,6 @@ const apps = {
|
|||||||
display: flex;
|
display: flex;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: calc(100vh - 150px);
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,12 +532,12 @@ const apps = {
|
|||||||
|
|
||||||
.nav-item {
|
.nav-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 12px 8px;
|
min-height: 54px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
border-bottom: 1px solid #ebedf0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
@@ -487,30 +561,17 @@ const apps = {
|
|||||||
background: #1989fa;
|
background: #1989fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-icon {
|
|
||||||
font-size: 18px;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-text {
|
.nav-text {
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
font-weight: 500;
|
font-weight: 400;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.2;
|
line-height: 1.35;
|
||||||
word-break: break-all;
|
color: #64748b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-indicator {
|
.nav-item.active .nav-text {
|
||||||
position: absolute;
|
color: #1677ff;
|
||||||
right: 0;
|
font-weight: 600;
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 6px solid #1989fa;
|
|
||||||
border-top: 6px solid transparent;
|
|
||||||
border-bottom: 6px solid transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-content {
|
.tree-content {
|
||||||
@@ -530,57 +591,43 @@ const apps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.module-sections {
|
.module-sections {
|
||||||
padding: 12px 12px 18px;
|
padding: 0 12px 18px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-section {
|
.module-section {
|
||||||
padding: 0 0 18px;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-section + .module-section {
|
.module-section + .module-section {
|
||||||
border-top: 1px solid #f1f3f6;
|
padding-top: 8px;
|
||||||
padding-top: 14px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-title {
|
.module-title {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 10px;
|
padding: 12px 0 8px;
|
||||||
margin-bottom: 10px;
|
|
||||||
color: #202733;
|
color: #202733;
|
||||||
font-size: 15px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: 600;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-title::before {
|
.module-title::before {
|
||||||
content: '';
|
display: none;
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 4px;
|
|
||||||
width: 3px;
|
|
||||||
height: 14px;
|
|
||||||
border-radius: 2px;
|
|
||||||
background: #1989fa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-grid {
|
.module-grid {
|
||||||
display: grid;
|
display: block;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
||||||
gap: 10px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.module-grid-single {
|
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-feature {
|
.module-feature {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 8px 2px;
|
min-height: 68px;
|
||||||
border-radius: 8px;
|
padding: 9px 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1px solid #edf1f5;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,67 +636,74 @@ const apps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.module-feature-img {
|
.module-feature-img {
|
||||||
|
flex: 0 0 42px;
|
||||||
width: 42px;
|
width: 42px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
margin-bottom: 6px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-feature-icon {
|
.module-feature-icon {
|
||||||
|
flex: 0 0 42px;
|
||||||
width: 42px;
|
width: 42px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 6px;
|
margin-right: 10px;
|
||||||
color: #ffffff;
|
color: #168cff;
|
||||||
background: linear-gradient(135deg, #2f8af5 0%, #49c3dc 100%);
|
background: #eef6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-feature-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module-feature-name {
|
.module-feature-name {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: #323233;
|
color: #172033;
|
||||||
font-size: 13px;
|
font-size: 14px;
|
||||||
line-height: 1.25;
|
line-height: 1.4;
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module-feature-desc {
|
||||||
|
margin-top: 3px;
|
||||||
|
color: #8a94a6;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.35;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-feature-arrow,
|
||||||
|
.app-grid-arrow {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #9eb0c8;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
.app-grid {
|
.app-grid {
|
||||||
display: grid;
|
display: block;
|
||||||
/* 改为自适应列数:每格最小 80px,自动换行 */
|
padding: 0 12px 18px;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
|
|
||||||
|
|
||||||
justify-items: center; /* 子项内容居中(图标和文字) */
|
|
||||||
justify-content: start; /* 整体网格靠左对齐,避免居中 */
|
|
||||||
|
|
||||||
gap: 12px;
|
|
||||||
padding: 12px;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-grid-single {
|
|
||||||
display: flex;
|
|
||||||
justify-content: start;
|
|
||||||
padding: 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-grid-single .app-grid-item {
|
|
||||||
max-width: 80px;
|
|
||||||
margin: 0 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-grid-item {
|
.app-grid-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12px 4px;
|
min-height: 68px;
|
||||||
border-radius: 8px;
|
padding: 9px 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1px solid #edf1f5;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
@@ -665,27 +719,49 @@ const apps = {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 6px;
|
margin-right: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
/*border: 2px solid transparent;*/
|
/*border: 2px solid transparent;*/
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-grid-icon img {
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-grid-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.app-grid-name {
|
.app-grid-name {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #323233;
|
line-height: 1.4;
|
||||||
text-align: center;
|
color: #172033;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-grid-item.is-favorite .app-grid-icon,
|
.app-grid-desc {
|
||||||
.app-grid-icon.is-favorite {
|
margin-top: 3px;
|
||||||
border-color: #ff9800;
|
color: #8a94a6;
|
||||||
box-shadow: 0 0 0 2px rgba(255, 152, 0, 0.2);
|
font-size: 11px;
|
||||||
|
line-height: 1.35;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-grid-favorite {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #ffb020;
|
||||||
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -722,15 +798,17 @@ const apps = {
|
|||||||
/deep/ .menu-grid {
|
/deep/ .menu-grid {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
display: grid;
|
display: block;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
padding: 0 16px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .grid-item {
|
/deep/ .grid-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 20px 12px;
|
min-height: 70px;
|
||||||
|
padding: 10px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1px solid #edf1f5;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
@@ -738,7 +816,6 @@ const apps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .grid-item:active {
|
/deep/ .grid-item:active {
|
||||||
transform: scale(0.95);
|
|
||||||
background: #f2f3f5;
|
background: #f2f3f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,28 +827,40 @@ const apps = {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 12px;
|
margin-right: 12px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/deep/ .grid-img-wrap {
|
||||||
|
flex: 0 0 56px;
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
padding: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
/deep/ .grid-img {
|
/deep/ .grid-img {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
border-radius: 12px;
|
display: block;
|
||||||
display: flex;
|
object-fit: contain;
|
||||||
align-items: center;
|
}
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 12px;
|
/deep/ .grid-info {
|
||||||
color: #fff;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .grid-name {
|
/deep/ .grid-name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
color: #323233;
|
color: #172033;
|
||||||
text-align: center;
|
line-height: 1.4;
|
||||||
margin-bottom: 4px;
|
|
||||||
line-height: 1.2;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -780,10 +869,20 @@ const apps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .grid-desc {
|
/deep/ .grid-desc {
|
||||||
|
margin-top: 3px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #969799;
|
color: #969799;
|
||||||
text-align: center;
|
line-height: 1.35;
|
||||||
line-height: 1.2;
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .grid-arrow {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #9eb0c8;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .menu-name {
|
/deep/ .menu-name {
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
const home = {
|
const home = {
|
||||||
template: /*language=HTML*/ `
|
template: /*language=HTML*/ `
|
||||||
<div class="home-page">
|
<div class="home-page">
|
||||||
<div class="home-hero">
|
<div class="home-summary-bar" :class="{'home-summary-bar--visible': showHomeSummary}">
|
||||||
|
<img class="home-summary-bar__logo"
|
||||||
|
src="/assets/mobile/img/home/v4/中国地质大学-logo.png"
|
||||||
|
alt="中国地质大学">
|
||||||
|
<span class="home-summary-bar__divider"></span>
|
||||||
|
<span class="home-summary-bar__title">智慧工会</span>
|
||||||
|
</div>
|
||||||
|
<div ref="homeHero" class="home-hero">
|
||||||
<img class="home-hero__bg" src="/assets/mobile/img/home/v4/hero-campus.png" alt="">
|
<img class="home-hero__bg" src="/assets/mobile/img/home/v4/hero-campus.png" alt="">
|
||||||
|
<div class="home-hero__color-layer" aria-hidden="true"></div>
|
||||||
<div class="home-hero__content">
|
<div class="home-hero__content">
|
||||||
<div class="home-hero__topbar">
|
<div class="home-hero__topbar">
|
||||||
<img class="home-hero__brand-logo"
|
<img class="home-hero__brand-logo"
|
||||||
@@ -59,16 +67,92 @@ const home = {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="classroom-panel" @click="enterClassroom">
|
<div class="classroom-section">
|
||||||
<div class="entry-panel__heading">
|
<div class="classroom-section__head">
|
||||||
<span class="entry-panel__icon entry-panel__icon--classroom"><van-icon name="notes-o"></van-icon></span>
|
<div class="classroom-section__title">我的课堂</div>
|
||||||
<span class="classroom-panel__title">我的课堂</span>
|
<div class="classroom-section__more" @click="enterClassroom">
|
||||||
|
<span>全部课程</span>
|
||||||
|
<van-icon name="arrow"></van-icon>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="classroom-panel__course">{{ currentClassroomCourseName }}</div>
|
<div v-if="classroomCourses.length" class="classroom-course-scroll">
|
||||||
<div class="classroom-panel__action">
|
<div class="classroom-course-card"
|
||||||
<span>个人学习</span>
|
v-for="course in classroomCourses"
|
||||||
<van-icon name="arrow"></van-icon>
|
:key="course.id"
|
||||||
|
@click="enterCourse(course)">
|
||||||
|
<div class="classroom-course-cover">
|
||||||
|
<img v-if="getCourseCover(course.cover)" :src="getCourseCover(course.cover)" :alt="course.courseName">
|
||||||
|
<div v-else class="classroom-course-cover__empty">{{ course.courseTypeName || '课程' }}</div>
|
||||||
|
<span v-if="getCourseRecommendName(course.recommendFlags)" class="classroom-course-recommend">
|
||||||
|
{{ getCourseRecommendName(course.recommendFlags) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="classroom-course-content">
|
||||||
|
<div class="classroom-course-name">{{ course.courseName || '未命名课程' }}</div>
|
||||||
|
<div class="classroom-course-tags">
|
||||||
|
<span v-if="course.courseTypeName" class="classroom-course-tag">{{ course.courseTypeName }}</span>
|
||||||
|
<span v-if="course.lecturerName" class="classroom-course-lecturer">讲师:{{ course.lecturerName }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="classroom-course-stats">
|
||||||
|
<span><van-icon name="eye-o"></van-icon>{{ course.viewCount || 0 }}次观看</span>
|
||||||
|
<span>我的进度 {{ course.progressPercent || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<div class="classroom-course-progress">
|
||||||
|
<span :style="{width: Math.min(Number(course.progressPercent || 0), 100) + '%'}"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="classroom-empty">暂无课程</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="union-news-panel">
|
||||||
|
<div class="union-news-panel__head">
|
||||||
|
<div class="union-news-panel__title">工会动态</div>
|
||||||
|
<div class="union-news-panel__more" @click="enterSpreadList">
|
||||||
|
<span>全部动态</span>
|
||||||
|
<van-icon name="arrow"></van-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="union-news-tabs union-news-tabs--primary">
|
||||||
|
<div class="union-news-tab"
|
||||||
|
v-for="category in spreadCategories"
|
||||||
|
:key="category.id"
|
||||||
|
:class="{'union-news-tab--active': spreadParentId === category.id}"
|
||||||
|
@click="changeSpreadParent(category)">{{ category.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="union-news-tabs union-news-tabs--secondary" v-if="spreadChildren.length">
|
||||||
|
<div class="union-news-tab union-news-tab--secondary"
|
||||||
|
v-for="category in spreadChildren"
|
||||||
|
:key="category.id"
|
||||||
|
:class="{'union-news-tab--active': spreadCategoryId === category.id}"
|
||||||
|
@click="changeSpreadCategory(category)">{{ category.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="union-news-list" v-if="spreadDynamics.length">
|
||||||
|
<div class="union-news-item"
|
||||||
|
v-for="item in spreadDynamics"
|
||||||
|
:key="item.id"
|
||||||
|
@click="enterSpreadDetail(item)">
|
||||||
|
<img v-if="getSpreadCover(item.thumbUrl)"
|
||||||
|
class="union-news-item__cover"
|
||||||
|
:src="getSpreadCover(item.thumbUrl)"
|
||||||
|
:alt="item.title">
|
||||||
|
<div class="union-news-item__content">
|
||||||
|
<div class="union-news-item__title">{{ item.title }}</div>
|
||||||
|
<div v-if="item.summary || item.subTitle" class="union-news-item__summary">
|
||||||
|
{{ item.summary || item.subTitle }}
|
||||||
|
</div>
|
||||||
|
<div class="union-news-item__meta">
|
||||||
|
<span>{{ formatSpreadDate(item.publishedAt || item.createdAt) }}</span>
|
||||||
|
<span class="union-news-item__views">
|
||||||
|
<van-icon name="eye-o"></van-icon>
|
||||||
|
{{ item.viewCount || 0 }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="!spreadLoading" class="union-news-empty">暂无动态</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="policy-panel">
|
<div class="policy-panel">
|
||||||
@@ -121,18 +205,16 @@ const home = {
|
|||||||
return {
|
return {
|
||||||
activityOptions: [],
|
activityOptions: [],
|
||||||
quickEntries: [],
|
quickEntries: [],
|
||||||
quickEntryIcons: {
|
|
||||||
"撰写提案": "/assets/mobile/img/home/v4/recommend/撰写提案.png",
|
|
||||||
"会员入会": "/assets/mobile/img/home/v4/recommend/会员入会.png",
|
|
||||||
"帮扶申请": "/assets/mobile/img/home/v4/recommend/帮扶申请.png",
|
|
||||||
"疗休养报名": "/assets/mobile/img/home/v4/recommend/疗休养报名.png",
|
|
||||||
"社团入会": "/assets/mobile/img/home/v4/recommend/社团入会.png",
|
|
||||||
"慰问申请": "/assets/mobile/img/home/v4/recommend/慰问申请.png",
|
|
||||||
"问卷调查": "/assets/mobile/img/home/v4/recommend/问卷调查.png"
|
|
||||||
},
|
|
||||||
classroomCourses: [],
|
classroomCourses: [],
|
||||||
classroomCourseIndex: 0,
|
classroomRecommendOptions: [],
|
||||||
classroomCourseTimer: null,
|
showHomeSummary: false,
|
||||||
|
homeScrollContainer: null,
|
||||||
|
spreadCategories: [],
|
||||||
|
spreadParentId: "",
|
||||||
|
spreadCategoryId: "",
|
||||||
|
spreadDynamics: [],
|
||||||
|
spreadLoading: false,
|
||||||
|
spreadLoadSeq: 0,
|
||||||
showLatestActivity: false,
|
showLatestActivity: false,
|
||||||
featuredEntries: [
|
featuredEntries: [
|
||||||
{
|
{
|
||||||
@@ -197,9 +279,9 @@ const home = {
|
|||||||
currentBanner() {
|
currentBanner() {
|
||||||
return this.bannerList[this.activeBannerIndex] || this.bannerList[0] || {}
|
return this.bannerList[this.activeBannerIndex] || this.bannerList[0] || {}
|
||||||
},
|
},
|
||||||
currentClassroomCourseName() {
|
spreadChildren() {
|
||||||
const course = this.classroomCourses[this.classroomCourseIndex]
|
const parent = this.spreadCategories.find(item => item.id === this.spreadParentId)
|
||||||
return course && course.courseName ? course.courseName : "二十大精神"
|
return parent && parent.children ? parent.children : []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -353,8 +435,6 @@ const home = {
|
|||||||
const cached = this.readHomeCache("classroom")
|
const cached = this.readHomeCache("classroom")
|
||||||
if (cached && cached.length) {
|
if (cached && cached.length) {
|
||||||
this.classroomCourses = cached
|
this.classroomCourses = cached
|
||||||
this.classroomCourseIndex = 0
|
|
||||||
this.startClassroomCourseTimer()
|
|
||||||
}
|
}
|
||||||
this.$axios.post("/platform/learning/course/display/pageData", {
|
this.$axios.post("/platform/learning/course/display/pageData", {
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
@@ -363,34 +443,140 @@ const home = {
|
|||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
const data = res.data || {}
|
const data = res.data || {}
|
||||||
this.classroomCourses = data.list || []
|
this.classroomCourses = data.list || []
|
||||||
this.classroomCourseIndex = 0
|
|
||||||
this.writeHomeCache("classroom", this.classroomCourses, this.homeCacheTtl.classroom)
|
this.writeHomeCache("classroom", this.classroomCourses, this.homeCacheTtl.classroom)
|
||||||
this.startClassroomCourseTimer()
|
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
this.classroomCourses = []
|
this.classroomCourses = []
|
||||||
this.classroomCourseIndex = 0
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
startClassroomCourseTimer() {
|
listClassroomRecommendOptions() {
|
||||||
if (this.classroomCourseTimer) {
|
this.$axios.post("/platform/learning/course/display/recommendOptions").then((res) => {
|
||||||
clearInterval(this.classroomCourseTimer)
|
if (res.code === 0) {
|
||||||
this.classroomCourseTimer = null
|
this.classroomRecommendOptions = res.data || []
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.classroomRecommendOptions = []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getCourseCover(cover) {
|
||||||
|
if (!cover) return ""
|
||||||
|
if (Array.isArray(cover)) {
|
||||||
|
const first = cover[0]
|
||||||
|
return first && (first.url || first.data || (first.response && first.response.data)) || ""
|
||||||
}
|
}
|
||||||
if (this.classroomCourses.length <= 1) {
|
if (typeof cover !== "string") return ""
|
||||||
|
const text = cover.trim()
|
||||||
|
if (!text) return ""
|
||||||
|
if (!text.startsWith("[")) return text
|
||||||
|
try {
|
||||||
|
const files = JSON.parse(text)
|
||||||
|
const first = files[0]
|
||||||
|
return first && (first.url || first.data || (first.response && first.response.data)) || ""
|
||||||
|
} catch (e) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCourseRecommendName(flags) {
|
||||||
|
const code = flags ? flags.split(",").filter(Boolean)[0] : ""
|
||||||
|
if (!code) return ""
|
||||||
|
const option = this.classroomRecommendOptions.find(item => item.code === code)
|
||||||
|
return option ? option.name : code
|
||||||
|
},
|
||||||
|
listSpreadCategories() {
|
||||||
|
this.$axios.post("/platform/h5/spread/categoryTree").then((res) => {
|
||||||
|
if (res.code !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.spreadCategories = res.data || []
|
||||||
|
const firstParent = this.spreadCategories[0]
|
||||||
|
if (!firstParent) {
|
||||||
|
this.spreadDynamics = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.spreadParentId = firstParent.id
|
||||||
|
const children = firstParent.children || []
|
||||||
|
this.spreadCategoryId = children.length ? children[0].id : firstParent.id
|
||||||
|
this.listSpreadHomeContent(this.spreadCategoryId)
|
||||||
|
}).catch(() => {
|
||||||
|
this.spreadCategories = []
|
||||||
|
this.spreadDynamics = []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
listSpreadHomeContent(categoryId) {
|
||||||
|
const loadSeq = ++this.spreadLoadSeq
|
||||||
|
this.spreadLoading = true
|
||||||
|
this.$axios.post("/platform/h5/spread/pageData", {
|
||||||
|
categoryId: categoryId,
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 5
|
||||||
|
}).then((res) => {
|
||||||
|
if (loadSeq === this.spreadLoadSeq && res.code === 0) {
|
||||||
|
const data = res.data || {}
|
||||||
|
this.spreadDynamics = data.list || []
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
if (loadSeq === this.spreadLoadSeq) {
|
||||||
|
this.spreadDynamics = []
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
if (loadSeq === this.spreadLoadSeq) {
|
||||||
|
this.spreadLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
changeSpreadParent(category) {
|
||||||
|
if (this.spreadParentId === category.id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.classroomCourseTimer = setInterval(() => {
|
this.spreadParentId = category.id
|
||||||
this.classroomCourseIndex = (this.classroomCourseIndex + 1) % this.classroomCourses.length
|
const children = category.children || []
|
||||||
}, 3000)
|
this.spreadCategoryId = children.length ? children[0].id : category.id
|
||||||
|
this.listSpreadHomeContent(this.spreadCategoryId)
|
||||||
|
},
|
||||||
|
changeSpreadCategory(category) {
|
||||||
|
if (this.spreadCategoryId === category.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.spreadCategoryId = category.id
|
||||||
|
this.listSpreadHomeContent(category.id)
|
||||||
|
},
|
||||||
|
getSpreadCover(value) {
|
||||||
|
if (!value) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
let files = value
|
||||||
|
if (typeof value === "string" && value.trim().startsWith("[")) {
|
||||||
|
try {
|
||||||
|
files = JSON.parse(value)
|
||||||
|
} catch (e) {
|
||||||
|
files = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Array.isArray(files)) {
|
||||||
|
files = String(files).split(",")
|
||||||
|
}
|
||||||
|
const first = files[0]
|
||||||
|
if (typeof first === "string") {
|
||||||
|
return first.trim()
|
||||||
|
}
|
||||||
|
return first && (first.src || first.url || first.data || (first.response && first.response.data)) || ""
|
||||||
|
},
|
||||||
|
formatSpreadDate(value) {
|
||||||
|
return value ? this.$moment(Number(value)).format("YYYY-MM-DD") : ""
|
||||||
|
},
|
||||||
|
enterSpreadDetail(item) {
|
||||||
|
this.$pjaxReplace("/platform/h5/spread?id=" + encodeURIComponent(item.id))
|
||||||
|
},
|
||||||
|
enterSpreadList() {
|
||||||
|
this.$pjaxReplace("/platform/h5/spread")
|
||||||
},
|
},
|
||||||
menuClick(item) {
|
menuClick(item) {
|
||||||
this.$pjaxReplace(item.href)
|
this.$pjaxReplace(item.href)
|
||||||
},
|
},
|
||||||
getQuickEntryIcon(item) {
|
getQuickEntryIcon(item) {
|
||||||
return this.quickEntryIcons[item.name] || item.picIcon || ""
|
return item.picIcon || ""
|
||||||
},
|
},
|
||||||
featureClick(item) {
|
featureClick(item) {
|
||||||
if (item.href) {
|
if (item.href) {
|
||||||
@@ -400,6 +586,16 @@ const home = {
|
|||||||
enterClassroom() {
|
enterClassroom() {
|
||||||
this.$pjaxReplace("/platform/learning/course/h5")
|
this.$pjaxReplace("/platform/learning/course/h5")
|
||||||
},
|
},
|
||||||
|
enterCourse(course) {
|
||||||
|
if (course && course.id) {
|
||||||
|
this.$pjaxReplace("/platform/learning/course/h5/study?id=" + encodeURIComponent(course.id))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleHomeScroll() {
|
||||||
|
if (!this.homeScrollContainer) return
|
||||||
|
const heroHeight = this.$refs.homeHero ? this.$refs.homeHero.offsetHeight : 200
|
||||||
|
this.showHomeSummary = this.homeScrollContainer.scrollTop >= Math.max(heroHeight - 48, 0)
|
||||||
|
},
|
||||||
bannerChange(index) {
|
bannerChange(index) {
|
||||||
this.activeBannerIndex = index
|
this.activeBannerIndex = index
|
||||||
},
|
},
|
||||||
@@ -416,43 +612,129 @@ const home = {
|
|||||||
this.listHomeBrand()
|
this.listHomeBrand()
|
||||||
this.listRecommendApp()
|
this.listRecommendApp()
|
||||||
this.listClassroomCourses()
|
this.listClassroomCourses()
|
||||||
|
this.listClassroomRecommendOptions()
|
||||||
|
this.listSpreadCategories()
|
||||||
if (this.showLatestActivity) {
|
if (this.showLatestActivity) {
|
||||||
this.listActivity()
|
this.listActivity()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.homeScrollContainer = document.querySelector("body > .main-page .page-wrapper")
|
||||||
|
if (this.homeScrollContainer) {
|
||||||
|
this.homeScrollContainer.addEventListener("scroll", this.handleHomeScroll, {passive: true})
|
||||||
|
this.handleHomeScroll()
|
||||||
|
}
|
||||||
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.classroomCourseTimer) {
|
if (this.homeScrollContainer) {
|
||||||
clearInterval(this.classroomCourseTimer)
|
this.homeScrollContainer.removeEventListener("scroll", this.handleHomeScroll)
|
||||||
this.classroomCourseTimer = null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style: /*language=CSS*/ `
|
style: /*language=CSS*/ `
|
||||||
|
.home-page {
|
||||||
|
padding-bottom: 65px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-summary-bar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 30;
|
||||||
|
height: 48px;
|
||||||
|
padding: 0 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
color: #202124;
|
||||||
|
background-color: rgba(255, 255, 255, .96);
|
||||||
|
border-bottom: 1px solid rgba(224, 230, 238, .9);
|
||||||
|
box-shadow: 0 3px 12px rgba(31, 72, 122, .08);
|
||||||
|
box-sizing: border-box;
|
||||||
|
transform: translateY(-100%);
|
||||||
|
transition: opacity .2s ease, transform .2s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-summary-bar--visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-summary-bar__logo {
|
||||||
|
width: 118px;
|
||||||
|
height: 28px;
|
||||||
|
display: block;
|
||||||
|
object-fit: contain;
|
||||||
|
object-position: left center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-summary-bar__divider {
|
||||||
|
width: 1px;
|
||||||
|
height: 18px;
|
||||||
|
margin: 0 10px;
|
||||||
|
background-color: #dce3ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-summary-bar__title {
|
||||||
|
color: #202124;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-weight: 600;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.home-hero {
|
.home-hero {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #0878f7;
|
background: #0878f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-hero__color-layer {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
background: linear-gradient(111deg,
|
||||||
|
#0561e9 0%,
|
||||||
|
#0873f0 45%,
|
||||||
|
rgba(9, 132, 244, .96) 51%,
|
||||||
|
rgba(10, 150, 247, .72) 58%,
|
||||||
|
rgba(10, 158, 247, .4) 65%,
|
||||||
|
rgba(10, 158, 247, .14) 71%,
|
||||||
|
rgba(10, 158, 247, 0) 75%);
|
||||||
|
-webkit-clip-path: polygon(0 0, 90% 0, 70% 100%, 0 100%);
|
||||||
|
clip-path: polygon(0 0, 90% 0, 70% 100%, 0 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-hero__bg {
|
.home-hero__bg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: center;
|
object-position: 90% center;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-hero__content {
|
.home-hero__content {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 2;
|
||||||
|
width: 60%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 15px 20px 12px;
|
padding: 15px 0 12px 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,7 +746,9 @@ const home = {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-hero__brand-logo {
|
.home-hero__brand-logo {
|
||||||
|
transform: scale(1.15);
|
||||||
|
transform-origin: left center;
|
||||||
display: block;
|
display: block;
|
||||||
width: 160px;
|
width: 160px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
@@ -712,20 +996,192 @@ const home = {
|
|||||||
color: #087af4;
|
color: #087af4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.classroom-panel {
|
.classroom-section {
|
||||||
height: 48px;
|
margin: 10px 12px 7px;
|
||||||
margin: 15px 12px 7px;
|
padding: 13px 0 12px;
|
||||||
padding: 0 12px;
|
overflow: hidden;
|
||||||
display: flex;
|
border-radius: 10px;
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.classroom-panel:active {
|
.classroom-section__head {
|
||||||
transform: scale(.99);
|
padding: 0 12px 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-section__title {
|
||||||
|
color: #202124;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 21px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-section__more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #969799;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-section__more .van-icon {
|
||||||
|
margin-left: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-scroll {
|
||||||
|
padding: 0 12px 4px;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
scrollbar-width: none;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-scroll::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-card {
|
||||||
|
width: 238px;
|
||||||
|
flex: 0 0 238px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #edf1f6;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 3px 10px rgba(34, 76, 122, .07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-card:active {
|
||||||
|
transform: scale(.985);
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-cover {
|
||||||
|
position: relative;
|
||||||
|
height: 104px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #eaf2fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-cover img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-cover__empty {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #6b87a8;
|
||||||
|
font-size: 13px;
|
||||||
|
background: linear-gradient(135deg, #e8f2ff, #f3f8ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-recommend {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 8px;
|
||||||
|
max-width: 90px;
|
||||||
|
padding: 2px 7px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: rgba(255, 116, 52, .92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-content {
|
||||||
|
padding: 9px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-name {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #202124;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-tags {
|
||||||
|
height: 22px;
|
||||||
|
margin-top: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-tag {
|
||||||
|
max-width: 82px;
|
||||||
|
padding: 1px 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #287ff0;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #edf6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-lecturer {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #7d8797;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-stats {
|
||||||
|
margin-top: 7px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: #969daa;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-stats .van-icon {
|
||||||
|
margin-right: 3px;
|
||||||
|
vertical-align: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-progress {
|
||||||
|
height: 3px;
|
||||||
|
margin-top: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #edf1f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-course-progress span {
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
border-radius: inherit;
|
||||||
|
background-color: #287ff0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-empty {
|
||||||
|
padding: 18px 0 12px;
|
||||||
|
color: #9aa2af;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry-panel__heading {
|
.entry-panel__heading {
|
||||||
@@ -746,55 +1202,13 @@ const home = {
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry-panel__icon--classroom {
|
|
||||||
background: linear-gradient(145deg, #0c70f5, #278fff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry-panel__icon--policy {
|
.entry-panel__icon--policy {
|
||||||
background: linear-gradient(145deg, #ff424d, #ff6c73);
|
background: linear-gradient(145deg, #ff424d, #ff6c73);
|
||||||
}
|
}
|
||||||
|
|
||||||
.classroom-panel__title {
|
|
||||||
flex-shrink: 0;
|
|
||||||
color: #202124;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.classroom-panel__course {
|
|
||||||
min-width: 0;
|
|
||||||
flex: 1;
|
|
||||||
margin: 0 8px;
|
|
||||||
color: #087af4;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 17px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.classroom-panel__action {
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
color: #969799;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 17px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.classroom-panel__action .van-icon {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.policy-panel {
|
.policy-panel {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
margin: 0 12px 65px;
|
margin: 0 12px 7px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -825,6 +1239,205 @@ const home = {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.union-news-panel {
|
||||||
|
margin: 15px 12px 7px;
|
||||||
|
padding: 13px 12px 8px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-panel__head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-panel__title {
|
||||||
|
color: #202124;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 21px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-panel__more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #969799;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-panel__more .van-icon {
|
||||||
|
margin-left: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tabs {
|
||||||
|
height: 38px;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
gap: 0;
|
||||||
|
border-bottom: 1px solid #edf1f6;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
box-sizing: border-box;
|
||||||
|
scrollbar-width: none;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tabs::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tabs--secondary {
|
||||||
|
height: 32px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 0;
|
||||||
|
gap: 6px;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tab {
|
||||||
|
position: relative;
|
||||||
|
min-width: 96px;
|
||||||
|
padding: 0 8px;
|
||||||
|
flex: 1 0 calc((100% - 6px) / 3);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #7d8797;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: 7px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tab--secondary {
|
||||||
|
min-width: 88px;
|
||||||
|
height: 28px;
|
||||||
|
padding: 0 12px;
|
||||||
|
flex: 1 0 calc((100% - 12px) / 3);
|
||||||
|
color: #969daa;
|
||||||
|
font-size: 11px;
|
||||||
|
border: 1px solid #e7ecf3;
|
||||||
|
border-radius: 999px;
|
||||||
|
background-color: #fafbfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tab--active {
|
||||||
|
color: #087af4;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tabs--primary .union-news-tab--active {
|
||||||
|
color: #087af4;
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: linear-gradient(#087af4, #087af4);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center bottom;
|
||||||
|
background-size: 24px 2px;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tabs--primary .union-news-tab--active::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-tabs--secondary .union-news-tab--active {
|
||||||
|
color: #087af4;
|
||||||
|
border-color: #b9d8ff;
|
||||||
|
background-color: #edf6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-list {
|
||||||
|
margin-top: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item {
|
||||||
|
min-height: 58px;
|
||||||
|
padding: 8px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item + .union-news-item {
|
||||||
|
border-top: 1px solid #f2f4f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item:active {
|
||||||
|
background-color: #f7faff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__cover {
|
||||||
|
width: 80px;
|
||||||
|
height: 48px;
|
||||||
|
margin-right: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__content {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__title {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #202124;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 19px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__summary {
|
||||||
|
margin-top: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #7d8797;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 15px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__meta {
|
||||||
|
margin-top: 3px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: #9aa2af;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__views {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-item__views .van-icon {
|
||||||
|
margin-right: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.union-news-empty {
|
||||||
|
padding: 18px 0 14px;
|
||||||
|
color: #9aa2af;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.act-list {
|
.act-list {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<home v-if="homeTabbarActive === 'home'" @module-click="moduleClick"></home>
|
<home v-if="homeTabbarActive === 'home'" @module-click="moduleClick"></home>
|
||||||
<todo v-if="homeTabbarActive === 'todo'"></todo>
|
<todo v-if="homeTabbarActive === 'todo'"></todo>
|
||||||
<work v-if="homeTabbarActive === 'work'"></work>
|
<work v-if="homeTabbarActive === 'work'"></work>
|
||||||
<mine v-if="homeTabbarActive === 'mine'"></mine>
|
<mine v-if="homeTabbarActive === 'mine'" @switch-tab="switchHomeTab"></mine>
|
||||||
<apps v-if="homeTabbarActive === 'apps'"></apps>
|
<apps v-if="homeTabbarActive === 'apps'"></apps>
|
||||||
<msg v-if="homeTabbarActive === 'msg'"></msg>
|
<msg v-if="homeTabbarActive === 'msg'"></msg>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,6 +60,10 @@ layout("/layouts/platform_h5.html"){
|
|||||||
homeTabbarChange(val) {
|
homeTabbarChange(val) {
|
||||||
this.$store.commit("setActiveTarBar", val)
|
this.$store.commit("setActiveTarBar", val)
|
||||||
},
|
},
|
||||||
|
switchHomeTab(val) {
|
||||||
|
this.homeTabbarActive = val
|
||||||
|
this.$store.commit("setActiveTarBar", val)
|
||||||
|
},
|
||||||
moduleClick(val) {
|
moduleClick(val) {
|
||||||
this.homeTabbarActive = "apps"
|
this.homeTabbarActive = "apps"
|
||||||
this.$store.commit("setActiveTarBar", "apps")
|
this.$store.commit("setActiveTarBar", "apps")
|
||||||
|
|||||||
@@ -1,102 +1,148 @@
|
|||||||
const mine = {
|
const mine = {
|
||||||
template: /*language=HTML*/ `
|
template: /*language=HTML*/ `
|
||||||
<div class="home-mine">
|
<div class="home-mine">
|
||||||
<van-nav-bar title="个人中心" class="nav-bar"></van-nav-bar>
|
<van-nav-bar title="我的" class="mine-nav" placeholder fixed :border="false"></van-nav-bar>
|
||||||
|
<section class="mine-hero">
|
||||||
<div class="profile-card">
|
<div class="mine-user-summary">
|
||||||
<div class="profile-header">
|
<div class="mine-avatar-wrap">
|
||||||
<div class="avatar-section">
|
<van-image :src="avatar" round width="58" height="58" class="mine-avatar">
|
||||||
<div class="avatar-wrapper">
|
<van-loading slot="loading" type="spinner" size="18"></van-loading>
|
||||||
<van-image :src="avatar" round width="80" height="80" class="avatar">
|
</van-image>
|
||||||
<van-loading slot="loading" type="spinner" size="20"></van-loading>
|
<i class="mine-online-dot"></i>
|
||||||
</van-image>
|
|
||||||
<div class="status-badge">
|
|
||||||
<div class="status-dot"></div>
|
|
||||||
<span>{{ $store.state.user.userState }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mine-user-text">
|
||||||
<div class="basic-info">
|
<strong>{{ user.username || '-' }}</strong>
|
||||||
<div class="name-row">
|
<span>工号:{{ user.loginname || '-' }}</span>
|
||||||
<h2 class="username">{{ $store.state.user.username }}</h2>
|
<span>性别:{{ user.sex || '-' }}</span>
|
||||||
<div class="gender-tag">
|
|
||||||
<van-icon name="friends-o" class="gender-icon"></van-icon>
|
|
||||||
<span>{{ $store.state.user.sex }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="employee-id">
|
|
||||||
工号:
|
|
||||||
<span class="id-value">{{ $store.state.user.loginname }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-list">
|
<div class="mine-status-card">
|
||||||
<!-- <div class="info-item">
|
<div class="mine-status-item">
|
||||||
<van-icon name="user-o"></van-icon>
|
<span>在职状态</span>
|
||||||
<span class="item-label">人员类型</span>
|
<strong :class="employmentStatusClass">{{ user.userState || '-' }}</strong>
|
||||||
<span class="info-value">{{ $store.state.user.personType }}</span>
|
|
||||||
</div>-->
|
|
||||||
<div class="info-item">
|
|
||||||
<van-icon name="user-o"></van-icon>
|
|
||||||
<span class="item-label">在职状态</span>
|
|
||||||
<span class="info-value">{{ $store.state.user.userState }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="mine-status-item">
|
||||||
<van-icon name="wap-home-o"></van-icon>
|
<span>所属单位</span>
|
||||||
<span class="item-label">所属单位</span>
|
<strong>{{ unitName }}</strong>
|
||||||
<span class="info-value">{{ $store.state.user.unit.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="mine-status-item">
|
||||||
<van-icon name="wap-home-o"></van-icon>
|
<span>所属工会</span>
|
||||||
<span class="item-label">所属工会</span>
|
<strong>{{ unionName }}</strong>
|
||||||
<span class="info-value">{{ $store.state.user.union.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<div class="action-cards">
|
<main class="mine-content">
|
||||||
<van-cell-group>
|
<section class="mine-panel mine-business-panel">
|
||||||
<van-cell is-link @click="$pjaxReplace('/platform/h5/indexMine/userInfo')" class="action-cell">
|
<div class="mine-panel-heading">
|
||||||
<span class="cell-title" slot="title">
|
<h2>我的业务</h2>
|
||||||
<van-icon name="user-o" class="cell-icon"></van-icon>
|
<button type="button" class="mine-panel-link" @click="switchTab('apps')">
|
||||||
个人信息
|
全部业务 <van-icon name="arrow"></van-icon>
|
||||||
</span>
|
</button>
|
||||||
</van-cell>
|
</div>
|
||||||
|
<div class="mine-grid mine-business-grid">
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('todo')">
|
||||||
|
<van-icon name="orders-o"></van-icon>
|
||||||
|
<span>待办事项</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="edit"></van-icon>
|
||||||
|
<span>我的申请</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="$pjaxReplace('/platform/learning/course/h5')">
|
||||||
|
<van-icon name="notes-o"></van-icon>
|
||||||
|
<span>我的课程</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('msg')">
|
||||||
|
<van-icon name="envelop-o"></van-icon>
|
||||||
|
<span>我的消息</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<van-cell is-link @click="$pjaxReplace('/platform/signature/h5')" class="action-cell">
|
<section class="mine-panel mine-tools-panel">
|
||||||
<span class="cell-title" slot="title">
|
<div class="mine-panel-heading">
|
||||||
<van-icon name="edit" class="cell-icon"></van-icon>
|
<h2>我的工具</h2>
|
||||||
我的签名
|
</div>
|
||||||
</span>
|
<div class="mine-grid mine-tools-grid">
|
||||||
</van-cell>
|
<button type="button" class="mine-grid-item" @click="$pjaxReplace('/platform/h5/indexMine/userInfo')">
|
||||||
|
<van-icon name="user-circle-o"></van-icon>
|
||||||
|
<span>个人信息</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="$pjaxReplace('/platform/signature/h5')">
|
||||||
|
<van-icon name="edit"></van-icon>
|
||||||
|
<span>我的签名</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="star-o"></van-icon>
|
||||||
|
<span>我的收藏</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="gift-o"></van-icon>
|
||||||
|
<span>福利中心</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="calendar-o"></van-icon>
|
||||||
|
<span>活动报名</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="completed-o"></van-icon>
|
||||||
|
<span>问卷调查</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="setting-o"></van-icon>
|
||||||
|
<span>设置中心</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="mine-grid-item" @click="switchTab('apps')">
|
||||||
|
<van-icon name="question-o"></van-icon>
|
||||||
|
<span>帮助中心</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- <van-cell :value="$store.state.user.totalIntegral" is-link @click="$pjaxReplace('/platform/integral/records/h5')" class="action-cell">-->
|
<div class="mine-logout-wrap">
|
||||||
<!-- <span class="cell-title" slot="title">-->
|
<van-button round block plain color="#bdcbe0" @click="logout" class="mine-logout-btn">退出登录</van-button>
|
||||||
<!-- <van-icon name="points" class="cell-icon"></van-icon>-->
|
</div>
|
||||||
<!-- 我的积分-->
|
</main>
|
||||||
<!-- </span>-->
|
|
||||||
<!-- </van-cell>-->
|
|
||||||
</van-cell-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="logout-wrapper">
|
|
||||||
<van-button round block color="#ee0a24" @click="logout" class="logout-btn">退出登录</van-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
computed: {
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.$store.state.user || {}
|
||||||
|
},
|
||||||
|
unitName() {
|
||||||
|
return (this.user.unit && this.user.unit.name) || "-"
|
||||||
|
},
|
||||||
|
unionName() {
|
||||||
|
return (this.user.union && this.user.union.name) || "-"
|
||||||
|
},
|
||||||
|
employmentStatusClass() {
|
||||||
|
const status = this.user.userState || ""
|
||||||
|
if (/离职|不在职|停职|辞退/.test(status)) {
|
||||||
|
return "mine-employment-status--inactive"
|
||||||
|
}
|
||||||
|
if (/退休|离休/.test(status)) {
|
||||||
|
return "mine-employment-status--retired"
|
||||||
|
}
|
||||||
|
if (/在职/.test(status)) {
|
||||||
|
return "mine-employment-status--active"
|
||||||
|
}
|
||||||
|
return "mine-employment-status--default"
|
||||||
|
},
|
||||||
avatar() {
|
avatar() {
|
||||||
const sex = this.$store.state.user.sex
|
const sex = this.user.sex
|
||||||
if (sex === "男" || !sex) {
|
if (sex === "男" || !sex) {
|
||||||
return "/assets/platform/img/home/avatar_boy.png"
|
return "/assets/platform/img/home/avatar_boy.png"
|
||||||
} else {
|
|
||||||
return "/assets/platform/img/home/avatar_girl.png"
|
|
||||||
}
|
}
|
||||||
|
return "/assets/platform/img/home/avatar_girl.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
switchTab(tab) {
|
||||||
|
this.$store.commit("setActiveTarBar", tab)
|
||||||
|
this.$emit("switch-tab", tab)
|
||||||
|
},
|
||||||
logout() {
|
logout() {
|
||||||
this.$dialog
|
this.$dialog
|
||||||
.confirm({
|
.confirm({
|
||||||
@@ -112,261 +158,258 @@ const mine = {
|
|||||||
style() {
|
style() {
|
||||||
return /*language=CSS*/ `
|
return /*language=CSS*/ `
|
||||||
.home-mine {
|
.home-mine {
|
||||||
background: #f7f8fa;
|
min-height: 100vh;
|
||||||
|
padding-bottom: 76px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #f3f6fa;
|
||||||
|
color: #15243a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-card {
|
.mine-hero {
|
||||||
margin: 10px;
|
|
||||||
padding: 20px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
|
||||||
animation: slideIn 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-header {
|
|
||||||
display: flex;
|
|
||||||
gap: 16px;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
animation: slideIn 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar-section {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar-wrapper {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 80px;
|
height: 154px;
|
||||||
height: 80px;
|
box-sizing: border-box;
|
||||||
|
padding: 0 26px;
|
||||||
|
background: linear-gradient(90deg, #0878f9 0%, #35aff6 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
/deep/ .mine-nav,
|
||||||
border: 2px solid #f5f5f5;
|
/deep/ .mine-nav .van-nav-bar {
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
background: linear-gradient(90deg, #0878f9 0%, #35aff6 100%) !important;
|
||||||
transition: transform 0.3s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-badge {
|
/deep/ .mine-nav .van-nav-bar__title {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-user-summary {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-avatar-wrap {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 58px;
|
||||||
|
width: 58px;
|
||||||
|
height: 58px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-avatar {
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.96);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-online-dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -2px;
|
right: -1px;
|
||||||
right: -2px;
|
bottom: 2px;
|
||||||
background: rgba(255, 255, 255, 0.9);
|
width: 11px;
|
||||||
color: #34c759;
|
height: 11px;
|
||||||
padding: 2px 8px;
|
border: 2px solid #fff;
|
||||||
border-radius: 10px;
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
z-index: 1;
|
|
||||||
animation: fadeInScale 0.3s ease-out 0.2s backwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-dot {
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
background: #34c759;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
background: #3dd0a0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.basic-info {
|
.mine-user-text {
|
||||||
flex: 1;
|
|
||||||
padding-top: 4px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
color: #fff;
|
||||||
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name-row {
|
.mine-user-text strong {
|
||||||
display: flex;
|
overflow: hidden;
|
||||||
align-items: center;
|
max-width: 240px;
|
||||||
gap: 12px;
|
margin-bottom: 1px;
|
||||||
animation: slideLeft 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.username {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
color: #333;
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gender-tag {
|
.mine-user-text span {
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.96;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-card {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
right: 12px;
|
||||||
|
bottom: -102px;
|
||||||
|
left: 12px;
|
||||||
|
display: grid;
|
||||||
|
min-height: 112px;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.82);
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 12px 30px rgba(35, 82, 130, 0.13);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item + .mine-status-item::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 1px;
|
||||||
|
background: #e3ebf5;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item strong {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 18px;
|
||||||
|
color: #18263a;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 24px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item span {
|
||||||
|
color: #75849b;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item .mine-employment-status--active {
|
||||||
|
color: #28b985;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item .mine-employment-status--retired {
|
||||||
|
color: #f2a33a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item .mine-employment-status--inactive {
|
||||||
|
color: #e46a6a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-status-item .mine-employment-status--default {
|
||||||
|
color: #718198;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-content {
|
||||||
|
padding: 124px 12px 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-panel {
|
||||||
|
margin-bottom: 13px;
|
||||||
|
padding: 14px 10px 13px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.82);
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 12px 30px rgba(35, 82, 130, 0.13);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-panel-heading {
|
||||||
|
display: flex;
|
||||||
|
height: 28px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 1px solid #e3ebf5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-panel-heading h2 {
|
||||||
|
margin: 0;
|
||||||
|
color: #18263a;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-panel-link {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
padding: 0;
|
||||||
background: #f5f5f5;
|
border: 0;
|
||||||
padding: 2px 10px;
|
outline: 0;
|
||||||
border-radius: 20px;
|
background: transparent;
|
||||||
|
color: #75849b;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #666;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.employee-id {
|
.mine-panel-link .van-icon {
|
||||||
color: #666;
|
margin-left: 5px;
|
||||||
font-size: 15px;
|
color: #a8b6c8;
|
||||||
animation: slideLeft 0.3s ease-out 0.1s backwards;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.id-value {
|
.mine-grid {
|
||||||
color: #333;
|
display: grid;
|
||||||
font-weight: 500;
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
font-size: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-list {
|
.mine-business-grid {
|
||||||
margin-top: 20px;
|
padding-top: 19px;
|
||||||
padding-top: 20px;
|
}
|
||||||
border-top: 1px solid #f5f5f5;
|
|
||||||
|
.mine-tools-grid {
|
||||||
|
padding-top: 18px;
|
||||||
|
row-gap: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-grid-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
padding: 0 2px;
|
||||||
font-size: 14px;
|
border: 0;
|
||||||
animation: slideLeft 0.3s ease-out;
|
outline: 0;
|
||||||
transition: background-color 0.3s;
|
background: transparent;
|
||||||
padding: 8px;
|
color: #173d68;
|
||||||
border-radius: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-item:active {
|
.mine-grid-item:active {
|
||||||
background-color: #f5f5f5;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-label {
|
.mine-grid-item .van-icon {
|
||||||
color: #999;
|
height: 26px;
|
||||||
width: 70px;
|
font-size: 25px;
|
||||||
|
line-height: 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-value {
|
.mine-grid-item span {
|
||||||
color: #333;
|
overflow: hidden;
|
||||||
flex: 1;
|
width: 100%;
|
||||||
|
margin-top: 9px;
|
||||||
|
color: #1c2b41;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
text-align: center;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-item .van-icon {
|
.mine-logout-wrap {
|
||||||
font-size: 16px;
|
padding-top: 4px;
|
||||||
color: #666;
|
|
||||||
width: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-cards {
|
.mine-logout-btn {
|
||||||
margin: 10px;
|
|
||||||
animation: slideUp 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-cell {
|
|
||||||
padding: 16px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-size: 15px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-icon {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logout-wrapper {
|
|
||||||
padding: 16px;
|
|
||||||
margin-top: 20px;
|
|
||||||
animation: fadeIn 0.3s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logout-btn {
|
|
||||||
height: 44px;
|
height: 44px;
|
||||||
font-size: 16px;
|
border-color: #bdcbe0 !important;
|
||||||
transition: opacity 0.3s;
|
background: rgba(255, 255, 255, 0.82) !important;
|
||||||
}
|
color: #718198 !important;
|
||||||
|
font-size: 15px;
|
||||||
.logout-btn:active {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 动画定义 */
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-20px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideLeft {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(20px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateX(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideUp {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(20px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeInScale {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.8);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 为每个列表项添加延迟动画 */
|
|
||||||
.info-item:nth-child(1) {
|
|
||||||
animation-delay: 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item:nth-child(2) {
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item:nth-child(3) {
|
|
||||||
animation-delay: 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item:nth-child(4) {
|
|
||||||
animation-delay: 0.4s;
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,37 @@
|
|||||||
const todo = {
|
const todo = {
|
||||||
template: /*language=HTML*/ `
|
template: /*language=HTML*/ `
|
||||||
<div class="task-center">
|
<div class="task-center">
|
||||||
<van-nav-bar title="待办中心" placeholder fixed></van-nav-bar>
|
<van-nav-bar class="task-nav" placeholder fixed :border="false" style="background-color: #0879f9;">
|
||||||
|
<template #title><span class="task-nav-title">待办中心</span></template>
|
||||||
|
</van-nav-bar>
|
||||||
|
<div class="task-hero">
|
||||||
|
<div class="task-statistics">
|
||||||
|
<div class="statistic-item">
|
||||||
|
<div class="statistic-icon statistic-icon-todo">
|
||||||
|
<van-icon name="description"></van-icon>
|
||||||
|
</div>
|
||||||
|
<div class="statistic-count">{{ todoCount }}</div>
|
||||||
|
<div class="statistic-label">待办事项</div>
|
||||||
|
</div>
|
||||||
|
<div class="statistic-item">
|
||||||
|
<div class="statistic-icon statistic-icon-done">
|
||||||
|
<van-icon name="underway-o"></van-icon>
|
||||||
|
</div>
|
||||||
|
<div class="statistic-count">{{ doneCount }}</div>
|
||||||
|
<div class="statistic-label">已办事项</div>
|
||||||
|
</div>
|
||||||
|
<div class="statistic-item">
|
||||||
|
<div class="statistic-icon statistic-icon-started">
|
||||||
|
<van-icon name="guide-o"></van-icon>
|
||||||
|
</div>
|
||||||
|
<div class="statistic-count">{{ startedCount }}</div>
|
||||||
|
<div class="statistic-label">我发起的</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- 标签页 -->
|
<!-- 标签页 -->
|
||||||
<van-sticky offset-top="46px">
|
<van-sticky offset-top="46px">
|
||||||
<van-tabs v-model="activeTab" @change="handleTabChange" animated swipeable>
|
<van-tabs v-model="activeTab" class="task-tabs" @change="handleTabChange" animated swipeable>
|
||||||
<van-tab :title="'待办(' + todoCount + ')'" name="todo"></van-tab>
|
<van-tab :title="'待办(' + todoCount + ')'" name="todo"></van-tab>
|
||||||
<van-tab :title="'已办(' + doneCount + ')'" name="done"></van-tab>
|
<van-tab :title="'已办(' + doneCount + ')'" name="done"></van-tab>
|
||||||
<van-tab :title="'发起(' + startedCount + ')'" name="started"></van-tab>
|
<van-tab :title="'发起(' + startedCount + ')'" name="started"></van-tab>
|
||||||
@@ -44,6 +71,15 @@ const todo = {
|
|||||||
ref="tableListRef"
|
ref="tableListRef"
|
||||||
@ready="doSearch"
|
@ready="doSearch"
|
||||||
title="variable.instanceName">
|
title="variable.instanceName">
|
||||||
|
<template #header="{row}">
|
||||||
|
<div class="todo-item-header">
|
||||||
|
<div class="todo-item-title">
|
||||||
|
<span class="todo-title-icon"><van-icon name="description"></van-icon></span>
|
||||||
|
<span class="todo-title-text">{{ row.variable?.instanceName || '' }}</span>
|
||||||
|
</div>
|
||||||
|
<span class="todo-status">{{ getTaskStatus(row) }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template v-slot="{index,row}">
|
<template v-slot="{index,row}">
|
||||||
<table-column label="任务节点">{{row.taskName}}</table-column>
|
<table-column label="任务节点">{{row.taskName}}</table-column>
|
||||||
<table-column label="流程分类">{{row.categoryName}}</table-column>
|
<table-column label="流程分类">{{row.categoryName}}</table-column>
|
||||||
@@ -183,6 +219,13 @@ const todo = {
|
|||||||
this.$pjaxReplace(h5FormKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey+ "&tab=" + this.activeTab)
|
this.$pjaxReplace(h5FormKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey+ "&tab=" + this.activeTab)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 根据当前列表类型统一展示流程状态,发起列表保留流程实例的实际状态。
|
||||||
|
getTaskStatus(task) {
|
||||||
|
if (this.activeTab === "todo") return "进行中";
|
||||||
|
if (this.activeTab === "done") return "已完成";
|
||||||
|
return this.processStatusMap[task.state]?.text || "未知状态";
|
||||||
|
},
|
||||||
|
|
||||||
// 获取空状态文本
|
// 获取空状态文本
|
||||||
getEmptyText() {
|
getEmptyText() {
|
||||||
switch (this.activeTab) {
|
switch (this.activeTab) {
|
||||||
@@ -198,6 +241,98 @@ const todo = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
style: /*language=CSS*/ `
|
style: /*language=CSS*/ `
|
||||||
|
.task-center {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding-bottom: 72px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #f5f7fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .task-nav .van-nav-bar {
|
||||||
|
background-color: #0879f9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .task-nav .van-nav-bar::after {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .task-nav .van-nav-bar__title {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-nav-title {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-hero {
|
||||||
|
position: relative;
|
||||||
|
height: 92px;
|
||||||
|
background-color: #0879f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-statistics {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 12px;
|
||||||
|
left: 12px;
|
||||||
|
display: flex;
|
||||||
|
height: 78px;
|
||||||
|
padding: 10px 6px 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 6px 18px rgba(45, 91, 145, 0.14);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-item {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-icon {
|
||||||
|
display: flex;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-icon-todo {
|
||||||
|
background: #4d8ff7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-icon-done {
|
||||||
|
background: #ffad3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-icon-started {
|
||||||
|
background: #5dce91;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-count {
|
||||||
|
margin-top: 3px;
|
||||||
|
color: #26364d;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic-label {
|
||||||
|
color: #8d97a7;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 标签页样式优化 */
|
/* 标签页样式优化 */
|
||||||
/deep/ .van-tabs__nav {
|
/deep/ .van-tabs__nav {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
@@ -213,6 +348,9 @@ const todo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .van-tabs__line {
|
/deep/ .van-tabs__line {
|
||||||
|
width: 30px;
|
||||||
|
height: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
background-color: var(--color-primary, #1989fa);
|
background-color: var(--color-primary, #1989fa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,14 +360,26 @@ const todo = {
|
|||||||
|
|
||||||
.search-form {
|
.search-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
background: #fff;
|
padding: 8px 12px 4px;
|
||||||
padding: 12px 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
background: #f5f7fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-form .van-search{
|
.search-form .van-search{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .search-form .van-search__content {
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .van-sticky--fixed {
|
||||||
|
background: #f5f7fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
@@ -289,5 +439,96 @@ const todo = {
|
|||||||
.category-select {
|
.category-select {
|
||||||
margin: 0 12px 12px 0;
|
margin: 0 12px 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/deep/ .table-list-container {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .table-list-container .table-list-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 9px;
|
||||||
|
box-shadow: 0 2px 10px rgba(31, 68, 113, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .todo-item-header {
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .todo-item-title {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .todo-title-icon {
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 24px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #438df5;
|
||||||
|
font-size: 15px;
|
||||||
|
background: #edf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .todo-title-text {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #26364d;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 22px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .todo-status {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding: 3px 7px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #4b92f2;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
background: #edf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .table-column {
|
||||||
|
padding: 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .table-column .label,
|
||||||
|
/deep/ .table-column .value {
|
||||||
|
color: #637083;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .table-list-container .table-list-item .item-actions {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding-top: 7px;
|
||||||
|
border-top-color: #edf1f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .table-list-container .table-list-item .action-btn {
|
||||||
|
padding: 0;
|
||||||
|
color: #2783ef;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .table-list-container .table-list-item .action-btn i {
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,39 +3,301 @@ layout("/layouts/platform_h5.html"){
|
|||||||
#-->
|
#-->
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.bgcolor-white {
|
body {
|
||||||
background: #ffffff;
|
background: #f3f6fa;
|
||||||
}
|
}
|
||||||
.van-status__figure {
|
|
||||||
text-align: center;
|
.signature-page {
|
||||||
line-height: 1.5;
|
min-height: 100vh;
|
||||||
|
background: #f3f6fa;
|
||||||
|
color: #15243a;
|
||||||
}
|
}
|
||||||
.van-status__figure img {
|
|
||||||
width: 130px;
|
.signature-hero {
|
||||||
|
position: relative;
|
||||||
|
height: 154px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 26px;
|
||||||
|
background: linear-gradient(90deg, #0878f9 0%, #35aff6 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-nav,
|
||||||
|
.signature-nav .van-nav-bar {
|
||||||
|
background: linear-gradient(90deg, #0878f9 0%, #35aff6 100%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-nav .van-nav-bar__title,
|
||||||
|
.signature-nav .van-icon {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-user {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-avatar-wrap {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 58px;
|
||||||
|
width: 58px;
|
||||||
|
height: 58px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-avatar {
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.96);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-online {
|
||||||
|
position: absolute;
|
||||||
|
right: -1px;
|
||||||
|
bottom: 2px;
|
||||||
|
width: 11px;
|
||||||
|
height: 11px;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #3dd0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-user-text {
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-user-text strong {
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 240px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-body {
|
||||||
|
position: relative;
|
||||||
|
min-height: calc(100vh - 184px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: -16px;
|
||||||
|
padding: 24px 16px 40px;
|
||||||
|
border-radius: 18px 18px 0 0;
|
||||||
|
background: #f3f6fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-card {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
padding: 17px 16px 19px;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 8px 22px rgba(31, 72, 113, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-card-heading {
|
||||||
|
display: flex;
|
||||||
|
height: 32px;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 1px solid #e3ebf5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-card-heading h2 {
|
||||||
|
margin: 0;
|
||||||
|
color: #18263a;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-state-tag {
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: #eaf8f3;
|
||||||
|
color: #30bc8c;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-state-tag.unset {
|
||||||
|
background: #eef3f9;
|
||||||
|
color: #8292a8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-description {
|
||||||
|
margin: 20px 0 12px;
|
||||||
|
color: #718198;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-preview {
|
||||||
|
display: flex;
|
||||||
height: 130px;
|
height: 130px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #bdcbe0;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #f7f9fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-preview .van-image,
|
||||||
|
.signature-preview .van-image__img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-empty {
|
||||||
|
color: #95a4b8;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-meta {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #718198;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-health {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-health .van-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
color: #42ca99;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-action {
|
||||||
|
height: 42px;
|
||||||
|
margin-top: 15px;
|
||||||
|
border: 0;
|
||||||
|
background: #087cf4;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-instructions {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-steps {
|
||||||
|
margin: 17px 0 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-steps li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
color: #718198;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-steps li:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-step-number {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
flex: 0 0 20px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #e7f1ff;
|
||||||
|
color: #087cf4;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-editor-card {
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 8px 22px rgba(31, 72, 113, 0.06);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div id="app" v-cloak>
|
<div id="app" v-cloak>
|
||||||
<van-nav-bar title="我的签名" @click-left="historyBack" left-arrow left-text="返回" placeholder fixed></van-nav-bar>
|
<div class="signature-page">
|
||||||
|
<van-nav-bar title="我的签名" class="signature-nav" left-arrow @click-left="historyBack"
|
||||||
<div class="bgcolor-white">
|
placeholder fixed :border="false"></van-nav-bar>
|
||||||
<div v-if="!showSignature" class="p10">
|
<header class="signature-hero">
|
||||||
<van-image width="100%" height="200" :src="userSignatureUrl" v-if="userSignatureUrl" style="border: 1px dashed #000">
|
<div class="signature-user">
|
||||||
<template slot="error">获取签名失败</template>
|
<div class="signature-avatar-wrap">
|
||||||
</van-image>
|
<van-image :src="avatar" round width="58" height="58" class="signature-avatar">
|
||||||
<div v-else class="van-status__figure">
|
<van-loading slot="loading" type="spinner" size="18"></van-loading>
|
||||||
<img src="/assets/platform/plugins/vant-green/images/figure/fail.png" class="" />
|
</van-image>
|
||||||
<div class="text-center pt10 pb10">暂无签名</div>
|
<i class="signature-online"></i>
|
||||||
|
</div>
|
||||||
|
<div class="signature-user-text">
|
||||||
|
<strong>{{ user.username || '-' }}</strong>
|
||||||
|
<span>工号:{{ user.loginname || '-' }}</span>
|
||||||
|
<span>性别:{{ user.sex || '-' }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <van-status orient="vertical" :figure="14" title="暂无签名" v-else></van-status>-->
|
</header>
|
||||||
|
|
||||||
<div class="margin-top10">
|
<main class="signature-body">
|
||||||
<van-button v-if="!userSignatureUrl" block type="primary" @click="openSignature">去签名</van-button>
|
<template v-if="!showSignature">
|
||||||
<van-button v-else block type="primary" @click="openSignature">修改签名</van-button>
|
<section class="signature-card">
|
||||||
|
<div class="signature-card-heading">
|
||||||
|
<h2>当前签名</h2>
|
||||||
|
<span class="signature-state-tag" :class="{ unset: !userSignatureUrl }">
|
||||||
|
{{ userSignatureUrl ? '已设置' : '未设置' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p class="signature-description">用于工会业务审批和材料签署</p>
|
||||||
|
<div class="signature-preview">
|
||||||
|
<van-image v-if="userSignatureUrl" :src="userSignatureUrl">
|
||||||
|
<template slot="error">获取签名失败</template>
|
||||||
|
</van-image>
|
||||||
|
<span v-else class="signature-empty">暂无签名</span>
|
||||||
|
</div>
|
||||||
|
<div class="signature-meta">
|
||||||
|
<div>最近更新:{{ signatureUpdatedAt }}</div>
|
||||||
|
<div class="signature-health">
|
||||||
|
<van-icon name="checked"></van-icon>
|
||||||
|
<span>{{ userSignatureUrl ? '签名状态正常,可用于业务办理' : '请先设置签名后办理相关业务' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<van-button round block type="primary" class="signature-action" @click="openSignature">
|
||||||
|
{{ userSignatureUrl ? '重新签名' : '立即签名' }}
|
||||||
|
</van-button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="signature-card signature-instructions">
|
||||||
|
<div class="signature-card-heading">
|
||||||
|
<h2>使用说明</h2>
|
||||||
|
</div>
|
||||||
|
<ol class="signature-steps">
|
||||||
|
<li><span class="signature-step-number">1</span><span>在签名区域内完成本人签名</span></li>
|
||||||
|
<li><span class="signature-step-number">2</span><span>确认清晰完整后保存</span></li>
|
||||||
|
<li><span class="signature-step-number">3</span><span>签名变更后自动更新业务调用</span></li>
|
||||||
|
</ol>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<div v-else class="signature-editor-card">
|
||||||
|
<signature @save="saveSignature"></signature>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
<signature v-if="showSignature" @save="saveSignature"></signature>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -49,14 +311,34 @@ layout("/layouts/platform_h5.html"){
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showSignature: false,
|
showSignature: false,
|
||||||
userSignatureUrl: null
|
userSignatureUrl: null,
|
||||||
|
signatureUpdatedTime: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.$store.state.user || {}
|
||||||
|
},
|
||||||
|
avatar() {
|
||||||
|
if (this.user.sex === "男" || !this.user.sex) {
|
||||||
|
return "/assets/platform/img/home/avatar_boy.png"
|
||||||
|
}
|
||||||
|
return "/assets/platform/img/home/avatar_girl.png"
|
||||||
|
},
|
||||||
|
signatureUpdatedAt() {
|
||||||
|
if (!this.signatureUpdatedTime) {
|
||||||
|
return "--"
|
||||||
|
}
|
||||||
|
return this.$moment(this.signatureUpdatedTime).format("YYYY-MM-DD HH:mm")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getUserSignature() {
|
getUserSignature() {
|
||||||
this.$axios.post("/platform/signature/get").then((res) => {
|
this.$axios.post("/platform/signature/get").then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.userSignatureUrl = res.data.signature
|
const signatureData = res.data || {}
|
||||||
|
this.userSignatureUrl = signatureData.signature || null
|
||||||
|
this.signatureUpdatedTime = signatureData.updatedAt || signatureData.createdAt || null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -64,7 +346,6 @@ layout("/layouts/platform_h5.html"){
|
|||||||
this.showSignature = true
|
this.showSignature = true
|
||||||
},
|
},
|
||||||
saveSignature(signature) {
|
saveSignature(signature) {
|
||||||
console.log(signature)
|
|
||||||
const file = base64ToFile(signature, "signature.png")
|
const file = base64ToFile(signature, "signature.png")
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append("file", file)
|
formData.append("file", file)
|
||||||
|
|||||||
@@ -2,9 +2,169 @@
|
|||||||
layout("/layouts/platform_h5.html"){
|
layout("/layouts/platform_h5.html"){
|
||||||
#-->
|
#-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f3f6fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f3f6fa;
|
||||||
|
color: #15243a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-hero {
|
||||||
|
position: relative;
|
||||||
|
height: 154px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 26px;
|
||||||
|
background: linear-gradient(90deg, #0878f9 0%, #35aff6 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-nav,
|
||||||
|
.profile-detail-nav .van-nav-bar {
|
||||||
|
background: linear-gradient(90deg, #0878f9 0%, #35aff6 100%) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-nav .van-nav-bar__title,
|
||||||
|
.profile-detail-nav .van-icon {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-user {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-avatar-wrap {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 58px;
|
||||||
|
width: 58px;
|
||||||
|
height: 58px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-avatar {
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.96);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-online {
|
||||||
|
position: absolute;
|
||||||
|
right: -1px;
|
||||||
|
bottom: 2px;
|
||||||
|
width: 11px;
|
||||||
|
height: 11px;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #3dd0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-user-text {
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: column;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-user-text strong {
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 240px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-detail-body {
|
||||||
|
position: relative;
|
||||||
|
min-height: calc(100vh - 184px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: -16px;
|
||||||
|
padding: 24px 16px 40px;
|
||||||
|
border-radius: 18px 18px 0 0;
|
||||||
|
background: #f3f6fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-profile-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-detail-card {
|
||||||
|
padding: 15px 16px 3px;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 8px 22px rgba(31, 72, 113, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-detail-card h2 {
|
||||||
|
height: 29px;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid #e3ebf5;
|
||||||
|
color: #18263a;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-detail-row {
|
||||||
|
display: flex;
|
||||||
|
min-height: 42px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 1px solid #e3ebf5;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-detail-row:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-detail-row span {
|
||||||
|
flex: 0 0 82px;
|
||||||
|
color: #718198;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mine-detail-row strong {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
color: #1c2b41;
|
||||||
|
font-weight: 400;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<div id="app" v-cloak>
|
<div id="app" v-cloak>
|
||||||
<van-nav-bar title="个人信息" @click-left="historyBack" left-arrow left-text="返回" placeholder fixed></van-nav-bar>
|
<div class="profile-detail-page">
|
||||||
<member-info :user-id="userId" ref="memberInfoRef"></member-info>
|
<van-nav-bar title="个人信息" class="profile-detail-nav" left-arrow @click-left="historyBack"
|
||||||
|
placeholder fixed :border="false"></van-nav-bar>
|
||||||
|
<header class="profile-detail-hero">
|
||||||
|
<div class="profile-detail-user">
|
||||||
|
<div class="profile-detail-avatar-wrap">
|
||||||
|
<van-image :src="avatar" round width="58" height="58" class="profile-detail-avatar">
|
||||||
|
<van-loading slot="loading" type="spinner" size="18"></van-loading>
|
||||||
|
</van-image>
|
||||||
|
<i class="profile-detail-online"></i>
|
||||||
|
</div>
|
||||||
|
<div class="profile-detail-user-text">
|
||||||
|
<strong>{{ user.username || '-' }}</strong>
|
||||||
|
<span>工号:{{ user.loginname || '-' }}</span>
|
||||||
|
<span>性别:{{ user.sex || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main class="profile-detail-body">
|
||||||
|
<member-info :user-id="userId" :profile-mode="true" ref="memberInfoRef"></member-info>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script nonce="${cspNonce!}">
|
<script nonce="${cspNonce!}">
|
||||||
<!--#include("/platform/zhghh5/staffmanage/member/common/mobileMemberInfo.js"){}#-->
|
<!--#include("/platform/zhghh5/staffmanage/member/common/mobileMemberInfo.js"){}#-->
|
||||||
@@ -16,12 +176,23 @@ layout("/layouts/platform_h5.html"){
|
|||||||
userId: ""
|
userId: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.$store.state.user || {}
|
||||||
|
},
|
||||||
|
avatar() {
|
||||||
|
if (this.user.sex === "男" || !this.user.sex) {
|
||||||
|
return "/assets/platform/img/home/avatar_boy.png"
|
||||||
|
}
|
||||||
|
return "/assets/platform/img/home/avatar_girl.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
"member-info": MOBILE_MEMBER_INFO
|
"member-info": MOBILE_MEMBER_INFO
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
viewInfo() {
|
viewInfo() {
|
||||||
this.userId = this.$store.state.user.id
|
this.userId = this.user.id
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
Reference in New Issue
Block a user