This commit is contained in:
Paidax
2025-11-08 10:09:41 +08:00
parent 42ca668f6e
commit 51a417ea20
2 changed files with 395 additions and 194 deletions
+71 -32
View File
@@ -4,41 +4,51 @@ const act = {
<div class="section-wrapper">
<div class="section-act">
<!-- Swiper容器 -->
<div class="activity-swiper-container">
<!-- 活动数据 - Swiper -->
<div class="swiper activity-swiper">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(activity, index) in actList" :key="activity.id">
<div class="item" @click="go(activity)">
<div class="img-box">
<img :src="activity.cover || 'https://www.ncu.edu.cn/__local/8/52/2C/644986B4C9A030F7B65300178A6_8679CB08_18467.jpg'"
alt="">
<span class="status">
<div v-if="actList && actList.length > 0" class="activity-swiper-container">
<div class="activity-swiper-container">
<!-- 活动数据 - Swiper -->
<div class="swiper activity-swiper">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(activity, index) in actList" :key="activity.id">
<div class="item" @click="go(activity)">
<div class="img-box">
<img :src="activity.cover || 'https://www.ncu.edu.cn/__local/8/52/2C/644986B4C9A030F7B65300178A6_8679CB08_18467.jpg'"
alt="">
<span class="status">
{{getStatusText(activity)}}
</span>
</div>
<h4 class="title">
{{ activity.name}}
</h4>
<!--报名时间-->
<div class="time">
<p>
<i class="fa fa-clock-o"></i>
时间:{{ activity.startDate }}至{{ activity.endDate }}
</p>
</div>
</div>
</div>
</div>
</div>
<!-- 导航按钮 -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
<!-- 进度条 -->
<div class="swiper-pagination"></div>
</div>
<h4 class="title">
{{ activity.name}}
</h4>
<!--报名时间-->
<div class="time">
<p>
<i class="fa fa-clock-o"></i>
时间:{{ activity.startDate }}至{{ activity.endDate }}
</p>
</div>
</div>
</div>
</div>
</div>
<!-- 导航按钮 -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
<!-- 进度条 -->
<div class="swiper-pagination"></div>
</div>
</div>
<div v-else class="no-activity-placeholder">
<div class="icon">📅</div>
<p>暂无近期活动</p>
<p class="subtext">敬请关注后续通知</p>
</div>
</div>
</div>
`,
@@ -287,5 +297,34 @@ const act = {
margin-right: 5px;
color: var(--color-primary);
}
/* 无活动占位提示 */
.no-activity-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 20px;
color: #94a3b8;
text-align: center;
}
.no-activity-placeholder .icon {
font-size: 48px;
margin-bottom: 12px;
opacity: 0.6;
}
.no-activity-placeholder p {
margin: 4px 0 0;
font-size: 16px;
font-weight: 500;
}
.no-activity-placeholder .subtext {
font-size: 13px;
opacity: 0.8;
}
`
};
+324 -162
View File
@@ -1,106 +1,116 @@
const user = {
template: /*language=HTML*/ `
<div class="user-wrapper">
<!-- 用户容器:左右布局 -->
<div class="user-container">
<!-- 左侧:用户信息卡片 -->
<div class="user-info-card">
<div v-if="weatherData">
<div class="weather-tq"><span>{{weatherData.name}}</span></div>
<div class="weather-tq">
<span>
{{ getWeatherEmoji(weatherData.icon) }} {{ weatherData.temp }}°C {{ weatherData.text }}
</span>
<div class="user-wrapper">
<!-- 用户容器:左右布局 -->
<div class="user-container">
<!-- 左侧:用户信息卡片 -->
<div class="user-info-card">
<div class="user-details">
<div class="user-name">${@auth.getPrincipalProperty('username')}</div>
<div class="user-meta-grid">
<div class="meta-row">
<span class="meta-icon">🆔</span>
<div>
<span class="meta-label">工号</span>
<span class="meta-value">${@auth.getPrincipalProperty('loginname')}</span>
</div>
</div>
<div class="meta-row">
<span class="meta-icon">🏢</span>
<div>
<span class="meta-label">单位信息</span>
<span class="meta-value">
<!--#if(!isEmpty(@auth.getPrincipalProperty('unit'))){#-->
${@auth.getPrincipalProperty('unit').getName()}
<!--#}#-->
(
<!--#if(!isEmpty(@auth.getPrincipalProperty('union'))){#-->
${@auth.getPrincipalProperty('union').getName()}
<!--#}#-->
)
</span>
</div>
</div>
<div class="meta-row">
<span class="meta-icon">🎭</span>
<div>
<span class="meta-label">角色</span>
<span class="meta-value">{{ roleNames || '—' }}</span>
</div>
</div>
</div>
</div>
<!-- 天气区域 -->
<div v-if="weatherData" class="weather-section" :class="weatherData.bgClass">
<div style="display: flex; justify-content: space-around">
<div class="weather-header">
<span class="weather-location">{{ weatherData.name }}</span>
<span class="weather-text">{{ weatherData.text }}</span>
</div>
<div class="weather-main">
<span class="weather-emoji">{{ weatherData.emoji }}</span>
<span class="weather-temp">{{ weatherData.temp }}°</span>
</div>
</div>
</div>
<div class="meta-item" v-else-if="weatherError">
<span class="meta-value" style="color:#999">天气加载失败</span>
</div>
<div class="user-details">
<div class="user-name">${@auth.getPrincipalProperty('username')}</div>
<div class="user-meta">
<div class="meta-item">
<span class="meta-label">工号:</span>
<span class="meta-value">${@auth.getPrincipalProperty('loginname')}</span>
</div>
<div class="meta-item">
<span class="meta-label">单位:</span>
<span class="meta-value">
<!--#if(!isEmpty(@auth.getPrincipalProperty('unit'))){#-->
${@auth.getPrincipalProperty('unit').getName()}
<!--#}#-->
</span>
</div>
<div class="meta-item">
<span class="meta-label">分工会:</span>
<span class="meta-value">
<!--#if(!isEmpty(@auth.getPrincipalProperty('union'))){#-->
${@auth.getPrincipalProperty('union').getName()}
<!--#}#-->
</span>
</div>
<div class="meta-item">
<span class="meta-label">角色:</span>
<span class="meta-value">
{{roleNames}}
</span>
</div>
</div>
</div>
</div>
<!-- 右侧:待办中心 -->
<div class="todo-center">
<!-- 标题和标签 -->
<div class="header">
<h3>待办中心</h3>
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
<el-tab-pane label="待办事宜" name="todo"></el-tab-pane>
<el-tab-pane label="已办事宜" name="done"></el-tab-pane>
<el-tab-pane label="我的发起" name="started"></el-tab-pane>
<el-tab-pane label="办结事务" name="completed"></el-tab-pane>
</el-tabs>
</div>
<!-- 表格 -->
<el-table
:data="todoList"
style="width: 100%"
border
stripe
v-loading="loading"
:cell-style="{ padding: '8px' }"
:header-cell-style="{ background: '#f8f9fa', color: '#444', fontWeight: '500' }"
>
<el-table-column label="序号" type="index" :index="indexMethod" width="100px"></el-table-column>
<el-table-column prop="categoryName" label="流程分类" width="100"></el-table-column>
<el-table-column prop="title" label="流程名称" min-width="300">
<template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.instanceName" placement="top">
<span class="table-title">{{ scope.row.instanceName }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="sender" label="申请人" width="120">
<template slot-scope="{row}">{{row.variable.initiatorName}}</template>
</el-table-column>
<el-table-column prop="date" label="发起日期" width="120">
<template slot-scope="{row}">
{{$moment(row.createdAt).format('YYYY-MM-DD')}}
</template>
</el-table-column>
<el-table-column label="操作" width="100px" fixed="right">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="openView(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<div class="weather-tip">{{ weatherData.tip }}</div>
</div>
<div v-else-if="weatherError" class="weather-error">
🌤️ 天气服务暂时不可用
</div>
</div>
<!-- 右侧:待办中心 -->
<div class="todo-center">
<!-- 标题和标签 -->
<div class="header">
<h3>待办中心</h3>
<el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
<el-tab-pane label="待办事宜" name="todo"></el-tab-pane>
<el-tab-pane label="已办事宜" name="done"></el-tab-pane>
<el-tab-pane label="我的发起" name="started"></el-tab-pane>
<el-tab-pane label="办结事务" name="completed"></el-tab-pane>
</el-tabs>
</div>
<!-- 表格 -->
<el-table
:data="todoList"
style="width: 100%"
border
stripe
v-loading="loading"
:cell-style="{ padding: '8px' }"
:header-cell-style="{ background: '#f8f9fa', color: '#444', fontWeight: '500' }"
>
<el-table-column label="序号" type="index" :index="indexMethod" width="100px"></el-table-column>
<el-table-column prop="categoryName" label="流程分类" width="100"></el-table-column>
<el-table-column prop="title" label="流程名称" min-width="300">
<template slot-scope="scope">
<el-tooltip effect="dark" :content="scope.row.instanceName" placement="top">
<span class="table-title">{{ scope.row.instanceName }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="sender" label="申请人" width="120">
<template slot-scope="{row}">{{row.variable.initiatorName}}</template>
</el-table-column>
<el-table-column prop="date" label="发起日期" width="120">
<template slot-scope="{row}">
{{$moment(row.createdAt).format('YYYY-MM-DD')}}
</template>
</el-table-column>
<el-table-column label="操作" width="100px" fixed="right">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="openView(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
`,
mixins: [initTableMixins],
data() {
@@ -184,6 +194,54 @@ const user = {
};
return WEATHER_ICON_EMOJI[iconCode] || '🌤️';
},
getWeatherInfo(iconCode, temp) {
const info = {
emoji: '🌤️',
tip: '今日天气宜人,心情也该放晴啦!',
bgClass: 'weather-sunny' // 用于 CSS 类
};
const tempNum = parseFloat(temp);
const isCold = tempNum < 10;
const isHot = tempNum > 28;
// 按照和风天气 iconCode 分类
if (['100'].includes(iconCode)) {
info.emoji = '☀️';
info.tip = isHot ? '高温预警!注意防暑降温,多喝水~' : '阳光灿烂,适合外出走走!';
info.bgClass = 'weather-sunny';
} else if (['101', '102', '103', '104'].includes(iconCode)) {
info.emoji = ['101', '103'].includes(iconCode) ? '⛅' : '☁️';
info.tip = isCold ? '天凉加衣,别让感冒找上门!' : '云层温柔,适合静心工作。';
info.bgClass = 'weather-cloudy';
} else if (['300', '301', '302', '305', '306', '399'].some(code => code === iconCode)) {
info.emoji = '🌧️';
info.tip = '🌧️ 下雨啦!记得带伞,小心路滑~';
info.bgClass = 'weather-rainy';
} else if (['307', '308', '309', '310'].includes(iconCode)) {
info.emoji = '⛈️';
info.tip = '⛈️ 雷雨天气,请减少外出,注意安全!';
info.bgClass = 'weather-storm';
} else if (['400', '401', '402', '403'].includes(iconCode)) {
info.emoji = '❄️';
info.tip = '❄️ 天寒地冻,保暖最重要!';
info.bgClass = 'weather-snowy';
} else if (['404', '405', '406', '407', '408', '409', '410'].includes(iconCode)) {
info.emoji = '🌫️';
info.tip = '🌫️ 能见度较低,出行请注意安全。';
info.bgClass = 'weather-foggy';
} else if (['500', '501', '502', '504'].includes(iconCode)) {
info.emoji = '🌀';
info.tip = '🌀 极端天气预警!请关注官方通知。';
info.bgClass = 'weather-extreme';
} else {
info.emoji = '🌤️';
info.tip = '今日天气未知,但愿你心情晴朗!';
info.bgClass = 'weather-default';
}
return info;
},
async getConfigKey(key) {
const resp = await this.$axios.post("/open/common/getConfigKey", { key })
return resp.data
@@ -191,8 +249,10 @@ const user = {
// 🔆 获取天气
async fetchWeather() {
try {
const AppMapCenterPointX = await this.getConfigKey("AppMapCenterPointX")
const AppMapCenterPointY = await this.getConfigKey("AppMapCenterPointY")
// 存localStorage 112.13,32.01 广州 113.27,23.14
const AppMapCenterPointX = '113.27'
const AppMapCenterPointY = '23.14'
// 1. 先通过城市名获取 locationId
this.$axios.get("https://mx5rk62kvj.re.qweatherapi.com/geo/v2/city/lookup?location=" + AppMapCenterPointX + "," + AppMapCenterPointY + "&key=" + this.QWEATHER_KEY).then((geoRes) => {
if (geoRes.code !== '200' || !geoRes.location?.[0]) {
@@ -205,10 +265,11 @@ const user = {
if (weatherRes.code !== '200') {
console.warn('天气数据异常:', weatherRes);
}
const weatherInfo = this.getWeatherInfo(weatherRes.now.icon, weatherRes.now.temp);
this.weatherData = {
...weatherInfo,
temp: weatherRes.now.temp,
text: weatherRes.now.text,
icon: weatherRes.now.icon,
name: geoRes.location[0].name
};
this.weatherError = false;
@@ -270,8 +331,7 @@ const user = {
this.getRoleNames()
},
mounted() {
// 🔆 组件挂载后加载天气
this.fetchWeather();
// this.fetchWeather();
},
style: /*language=CSS*/ `
.user-wrapper {
@@ -283,89 +343,191 @@ const user = {
width: 80%;
margin: 20px auto;
display: grid;
grid-template-columns: 0.5fr 2.5fr;
grid-template-columns: 0.7fr 2.3fr;
gap: 24px;
align-items: stretch;
row-gap: 24px;
}
/* 左侧用户卡片 */
.user-info-card {
/*display: flex;*/
align-items: center;
min-width: 320px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
padding: 16px;
transition: transform 0.2s, box-shadow 0.2s;
border-radius: 16px;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
padding: 24px;
display: flex;
flex-direction: column;
gap: 20px;
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.user-info-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
/* 天气值放大样式 */
.weather-tq {
font-size: 30px;
font-weight: 600;
color: #2c3e50;
display: flex;
justify-content: center;
gap: 4px;
}
.user-avatar {
width: 60px;
height: 60px;
background: linear-gradient(135deg, #1890ff, #0056b3);
color: white;
/* 头像占位符 */
.user-avatar-placeholder {
width: 64px;
height: 64px;
border-radius: 50%;
background: linear-gradient(135deg, #409eff, #1877f2);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: bold;
margin-right: 16px;
flex-shrink: 0;
font-size: 24px;
font-weight: 600;
margin: 0 auto;
box-shadow: 0 4px 10px rgba(24, 127, 255, 0.3);
}
.user-details {
/* 用户名 */
.user-name {
font-size: 20px;
font-weight: 700;
color: #1f2937;
text-align: center;
margin: 8px 0 0;
}
/* 元信息网格 */
.user-meta-grid {
display: flex;
flex-direction: column;
gap: 14px;
margin-top: 8px;
}
.meta-row {
display: flex;
align-items: flex-start;
gap: 12px;
}
.meta-icon {
font-size: 18px;
min-width: 24px;
text-align: center;
color: #409eff;
margin-top: 2px;
}
.meta-row > div {
flex: 1;
}
.user-name {
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
margin: 0 0 8px 0;
}
.user-meta {
display: flex;
flex-direction: column;
gap: 4px;
font-size: 14px;
}
.meta-item {
display: flex;
/*align-items: center;*/
line-height: 25px;
}
.meta-label {
color: #666;
min-width: 50px;
flex-shrink: 0;
font-size: 12px;
color: #6b7280;
font-weight: 500;
display: block;
margin-bottom: 2px;
}
.meta-value {
font-size: 15px;
color: #1f2937;
font-weight: 600;
word-break: break-word;
}
/* === 天气卡片 - 情感化设计 === */
.weather-section {
border-radius: 16px;
padding: 20px;
text-align: center;
color: white;
background: linear-gradient(135deg, #a8edea, #fed6e3); /* 默认柔和渐变 */
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
/* 不同天气的背景主题 */
.weather-sunny {
background: linear-gradient(135deg, #FFD700, #FFA500);
color: #2c3e50;
}
.weather-cloudy {
background: linear-gradient(135deg, #B0C4DE, #708090);
color: white;
}
.weather-rainy {
background: linear-gradient(135deg, #4A6FA5, #1E3F66);
color: white;
}
.weather-storm {
background: linear-gradient(135deg, #2F2F2F, #0D0D0D);
color: #FFD700;
}
.weather-snowy {
background: linear-gradient(135deg, #E0F7FA, #B3E5FC);
color: #01579B;
}
.weather-foggy {
background: linear-gradient(135deg, #D7CCC8, #A1887F);
color: white;
}
.weather-extreme {
background: linear-gradient(135deg, #FF5252, #B71C1C);
color: white;
}
.weather-default {
background: linear-gradient(135deg, #E0E0E0, #90A4AE);
color: #333;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
}
/* 天气头部:城市 + 描述 */
.weather-header {
margin-bottom: 12px;
}
.weather-location {
font-weight: 700;
font-size: 16px;
display: block;
}
.weather-text {
font-size: 13px;
opacity: 0.9;
display: block;
margin-top: 4px;
}
/* 主体:图标 + 温度 */
.weather-main {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
position: relative;
bottom: 8px;
}
.weather-emoji {
font-size: 36px;
filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2));
}
.weather-temp {
font-size: 28px;
font-weight: 800;
}
/* 贴心提示语 */
.weather-tip {
font-size: 14px;
line-height: 1.5;
opacity: 0.95;
margin-top: 8px;
padding: 0 8px;
}
/* 错误状态 */
.weather-error {
text-align: center;
color: #94a3b8;
font-size: 14px;
padding: 16px;
background: #f8fafc;
border-radius: 12px;
border: 1px dashed #cbd5e1;
}
/* 右侧待办中心 */