..
This commit is contained in:
@@ -112,6 +112,7 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
|
||||
.content-body {
|
||||
min-height: 400px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@@ -137,7 +138,8 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
</div>
|
||||
|
||||
<el-scrollbar>
|
||||
<el-menu unique-opened :default-active="activeMenuIndex" :default-openeds="openedMenus" @select="menuSelect">
|
||||
<el-menu unique-opened :default-active="activeMenuIndex" :default-openeds="openedMenus"
|
||||
@select="menuSelect">
|
||||
<menu-list :menus="leftMenus" :depth="0"></menu-list>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
@@ -145,11 +147,6 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
|
||||
<!-- 右侧主体区域 -->
|
||||
<main class="sub-app-container-main-content" id="sub-app-container-main-content">
|
||||
<!-- <header class="content-header">-->
|
||||
<!-- <h1 class="content-title"></h1>-->
|
||||
<!-- <!– <p class="content-subtitle"></p>–>-->
|
||||
<!-- </header>-->
|
||||
|
||||
<div class="content-body" id="sub-app-container-main-content-body">${layoutContent!}</div>
|
||||
</main>
|
||||
|
||||
@@ -169,7 +166,7 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
})
|
||||
|
||||
$(document).on("pjax:send", function () {
|
||||
NProgress.configure({ parent: ".sub-app-container-main-content" })
|
||||
NProgress.configure({parent: ".sub-app-container-main-content"})
|
||||
NProgress.start()
|
||||
$("#sub-app-container-main-content").hide()
|
||||
})
|
||||
@@ -190,7 +187,8 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
try {
|
||||
const app = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
|
||||
$("#sub-app-container #sidebar-menu .menu-header .menu-title").text(app?.name)
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
@@ -209,36 +207,41 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
"menu-list": {
|
||||
name: "menu-list",
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<div>
|
||||
<template v-for="(item, index) in menus">
|
||||
<el-submenu :index="item.id" v-if="item.children && item.children.length > 0">
|
||||
<template #title>
|
||||
<i :class="item.icon" v-if="item.icon" :size="18"></i>
|
||||
<i v-else class="el-icon-paperclip"></i>
|
||||
<span>{{ item.name }}</span>
|
||||
</template>
|
||||
<menu-list :menus="item.children" :depth="depth + 1" />
|
||||
</el-submenu>
|
||||
<el-menu-item :index="item.id" v-else>
|
||||
<a :href="item.href" data-pjax>
|
||||
<i :class="item.icon" v-if="item.icon" :size="18"></i>
|
||||
<i v-else :class="item.icon ? item.icon : 'el-icon-menu'"></i>
|
||||
<span>{{ item.name }}</span>
|
||||
</a>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</div>
|
||||
`,
|
||||
/*language=HTML*/
|
||||
`
|
||||
<div>
|
||||
<template v-for="(item, index) in menus">
|
||||
<el-submenu :index="item.id" v-if="item.children && item.children.length > 0">
|
||||
<template #title>
|
||||
<i :class="item.icon" v-if="item.icon" :size="18"></i>
|
||||
<i v-else class="el-icon-paperclip"></i>
|
||||
<span>{{ item.name }}</span>
|
||||
</template>
|
||||
<menu-list :menus="item.children" :depth="depth + 1"/>
|
||||
</el-submenu>
|
||||
<el-menu-item :index="item.id" v-else>
|
||||
<a :href="item.href" data-pjax>
|
||||
<i :class="item.icon" v-if="item.icon" :size="18"></i>
|
||||
<i v-else :class="item.icon ? item.icon : 'el-icon-menu'"></i>
|
||||
<span>{{ item.name }}</span>
|
||||
</a>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</div>
|
||||
`,
|
||||
props: ["menus", "depth"]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 菜单数据
|
||||
menus: [],
|
||||
// 当前激活的菜单索引
|
||||
activeMenuIndex: null,
|
||||
openedMenus: []
|
||||
// 当前打开的菜单索引
|
||||
openedMenus: [],
|
||||
// 默认选中菜单是否加载中
|
||||
defaultSelectLoading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -260,12 +263,13 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
const app = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
|
||||
window.sessionStorage.setItem("zhgh_sub_app_left_menu_active_index-" + app.id, index)
|
||||
window.sessionStorage.setItem("zhgh_sub_app_left_menu_opens-" + app.id, JSON.stringify(indexPath))
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
}
|
||||
},
|
||||
// 获取菜单
|
||||
getMenus(appId) {
|
||||
if (!appId) return
|
||||
$.get("/platform/sys/user/subAppMenus", { appId }).then((res) => {
|
||||
this.$axios.post("/platform/sys/user/subAppMenus", {appId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.menus = res.data
|
||||
window.sessionStorage.setItem("zhgh_sub_app_menus", JSON.stringify(res.data))
|
||||
@@ -276,6 +280,7 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
})
|
||||
},
|
||||
|
||||
// 设置应用信息
|
||||
setAppInfo(app) {
|
||||
if (app) {
|
||||
// 储存到缓存
|
||||
@@ -294,26 +299,73 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
this.openedMenus = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app_left_menu_opens-" + app.id)) || []
|
||||
console.log(this.openedMenus)
|
||||
console.log(this.activeMenuIndex)
|
||||
} catch (e) {}
|
||||
|
||||
if (!this.activeMenuIndex) {
|
||||
this.defaultSelect()
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
},
|
||||
|
||||
// 默认选中
|
||||
defaultSelect() {
|
||||
// 查找第一个有href的子菜单
|
||||
function findFirstChildWithHref(menus) {
|
||||
for (const menu of menus) {
|
||||
// 如果当前菜单有href,返回它
|
||||
if (menu.href) {
|
||||
return {
|
||||
menu: menu,
|
||||
parentIds: [menu.parentId]
|
||||
};
|
||||
}
|
||||
|
||||
// 如果有子菜单,递归查找
|
||||
if (menu.children && menu.children.length > 0) {
|
||||
const result = findFirstChildWithHref(menu.children);
|
||||
if (result) {
|
||||
// 添加当前菜单的ID到父ID集合
|
||||
result.parentIds.push(menu.id);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const result = findFirstChildWithHref(this.menus)
|
||||
if (result) {
|
||||
this.activeMenuIndex = result.menu.id
|
||||
this.openedMenus = result.parentIds
|
||||
this.$nextTick(() => {
|
||||
this.menuSelect(this.activeMenuIndex, this.openedMenus)
|
||||
// 使用pjax跳转
|
||||
commonUtil.pjaxPush(result.menu.href)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
// 页面加载时获取到正确的菜单
|
||||
const pathname = window.location.pathname
|
||||
if (!pathname.startsWith("/platform/v4/subApp")) {
|
||||
this.$axios.post("/platform/sys/user/rootMenuByPath", {pathname}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.setAppInfo(res.data)
|
||||
this.getMenus(res.data?.id)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const appId = GetQueryString("appId")
|
||||
if (!appId) return
|
||||
this.getMenus(appId)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// 页面加载时获取到正确的菜单
|
||||
const pathname = window.location.pathname
|
||||
if (!pathname.startsWith("/platform/v4/subApp")) {
|
||||
$.get("/platform/sys/user/rootMenuByPath", { pathname }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.setAppInfo(res.data)
|
||||
this.getMenus(res.data?.id)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const appId = GetQueryString("appId")
|
||||
if (!appId) {
|
||||
return
|
||||
}
|
||||
this.getMenus(appId)
|
||||
}
|
||||
this.init()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -165,12 +165,12 @@
|
||||
} else {
|
||||
window.location.href = "/platform/h5/home"
|
||||
}
|
||||
func && func()
|
||||
func && typeof func === "function" && func()
|
||||
}
|
||||
|
||||
Vue.mixin({
|
||||
methods: {
|
||||
historyBack: function(func) {
|
||||
historyBack: function(func = ()=>{}) {
|
||||
historyBack(func);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
<script src="${base!}/assets/platform/plugins/jquery/jquery.js"></script>
|
||||
<!-- pjax是异步加载html片段的工具,模拟前端路由机制 -->
|
||||
<script src="${base!}/assets/platform/plugins/pjax/jquery.pjax.js"></script>
|
||||
<!--nprogress 配合pjax使用-->
|
||||
<link ref="stylesheet" href="${base!}/assets/platform/plugins/nprogress/nprogress.css"/>
|
||||
<!-- nprogress 配合pjax使用 -->
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/nprogress/nprogress.css" />
|
||||
<script src="${base!}/assets/platform/plugins/nprogress/nprogress.js"></script>
|
||||
|
||||
<!-- 农历插件 -->
|
||||
@@ -97,6 +97,8 @@
|
||||
ELEMENT.Dialog.props.closeOnClickModal.default = false
|
||||
ELEMENT.Dialog.props.top.default = "50px"
|
||||
ELEMENT.Table.props.border.default = true
|
||||
ELEMENT.TableColumn.props.headerAlign.default = 'center'
|
||||
ELEMENT.TableColumn.props.align.default = 'center'
|
||||
ELEMENT.TableColumn.props.showOverflowTooltip = { type: Boolean, default: true }
|
||||
Vue.use(ELEMENT, {
|
||||
zIndex: 20000
|
||||
@@ -603,7 +605,7 @@
|
||||
</div>
|
||||
|
||||
<nav class="v4-nav">
|
||||
<a href="/platform/v4/home2" data-pjax class="v4-nav-item">
|
||||
<a href="/platform/v4/home" data-pjax class="v4-nav-item">
|
||||
<i class="fa fa-home"></i>
|
||||
首页
|
||||
</a>
|
||||
@@ -615,10 +617,14 @@
|
||||
<i class="fa fa-th-large"></i>
|
||||
服务中心
|
||||
</a>
|
||||
<a href="/flow/todoCenter" data-pjax class="v4-nav-item">
|
||||
<a href="/platform/v4/todo" data-pjax class="v4-nav-item">
|
||||
<i class="fa fa-th-large"></i>
|
||||
待办中心
|
||||
</a>
|
||||
<a href="/platform/v4/msg" data-pjax class="v4-nav-item">
|
||||
<i class="fa fa-th-large"></i>
|
||||
消息中心
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -663,7 +669,7 @@
|
||||
var currentPath = window.location.pathname
|
||||
var footer = $("#v4-footer")
|
||||
|
||||
if (currentPath === "/platform/v4/home2") {
|
||||
if (currentPath === "/platform/v4/home") {
|
||||
footer.show()
|
||||
} else {
|
||||
footer.hide()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,936 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/v4/baseLayout.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
/* 主容器 */
|
||||
.oa-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 主要内容区域 */
|
||||
.oa-main-content {
|
||||
margin: 0 auto;
|
||||
padding-bottom: 20px;
|
||||
background: url(/assets/platform/img/v4/home-bg.png);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
/* 背景图和搜索统计区域容器 */
|
||||
.oa-hero-section {
|
||||
position: relative;
|
||||
height: 350px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oa-background-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.oa-background-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* 搜索和统计区域 */
|
||||
.oa-search-stats-section {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 500px;
|
||||
gap: 40px;
|
||||
align-items: center;
|
||||
width: 1500px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 搜索区域 */
|
||||
.oa-search-section {
|
||||
text-align: left;
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.oa-search-container {
|
||||
display: flex;
|
||||
max-width: 600px;
|
||||
background: white;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.oa-search-input {
|
||||
flex: 1;
|
||||
padding: 15px 25px;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 16px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.oa-search-btn {
|
||||
background: #ff6b35;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 15px 30px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
.oa-search-btn:hover {
|
||||
background: #e55a2b;
|
||||
}
|
||||
|
||||
/* 数字提醒区域 */
|
||||
.oa-stats-section {
|
||||
background: rgba(0, 109, 185, 0.7);
|
||||
padding: 20px 25px;
|
||||
}
|
||||
|
||||
.oa-stats-title {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 15px 0;
|
||||
text-align: left;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.oa-stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.oa-stat-card {
|
||||
background: #ffffff;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.8);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oa-stat-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, #4a90e2, #357abd);
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-stat-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oa-stat-card:hover::before {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
.oa-stat-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.oa-stat-icon {
|
||||
font-size: 28px;
|
||||
color: #4a90e2;
|
||||
flex-shrink: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-stat-card:hover .oa-stat-icon {
|
||||
transform: scale(1.1);
|
||||
color: #357abd;
|
||||
}
|
||||
|
||||
.oa-stat-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.oa-stat-number {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #2c3e50;
|
||||
line-height: 1;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-stat-card:hover .oa-stat-number {
|
||||
color: #4a90e2;
|
||||
}
|
||||
|
||||
.oa-stat-label {
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* 活动中心 */
|
||||
.oa-box-1-section {
|
||||
display: grid;
|
||||
grid-template-columns: 400px 1fr;
|
||||
gap: 30px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
width: 1500px;
|
||||
margin: 20px auto 0;
|
||||
}
|
||||
|
||||
/* 左侧用户信息 */
|
||||
.oa-user-panel {
|
||||
background: rgba(0, 109, 185, 0.9);
|
||||
color: white;
|
||||
padding: 25px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
max-height: 410px;
|
||||
}
|
||||
|
||||
.oa-user-panel::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.oa-user-panel > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.oa-user-avatar {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36px;
|
||||
margin-bottom: 15px;
|
||||
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-user-avatar:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.oa-user-name {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.oa-user-info {
|
||||
line-height: 1.6;
|
||||
margin-bottom: 20px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.oa-user-info .info-item {
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1.6;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.oa-user-panel .info-label {
|
||||
font-weight: 600;
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0;
|
||||
min-width: 50px;
|
||||
max-width: 60px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.oa-user-panel .info-value {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.oa-user-homepage-btn {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
padding: 10px 20px;
|
||||
border-radius: 25px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.oa-user-homepage-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-color: rgba(255, 255, 255, 0.5);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 右侧活动列表 */
|
||||
.oa-activity-content {
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
max-height: 410px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0; /* 允许flex子项收缩 */
|
||||
overflow: hidden; /* 防止内容溢出 */
|
||||
}
|
||||
|
||||
.oa-activity-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 15px;
|
||||
flex-shrink: 0; /* 防止头部被压缩 */
|
||||
}
|
||||
|
||||
.oa-activity-tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.oa-activity-tab {
|
||||
padding: 10px 0;
|
||||
font-size: 20px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
position: relative;
|
||||
background: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.oa-activity-tab:hover {
|
||||
color: #4a90e2;
|
||||
}
|
||||
|
||||
.oa-activity-tab.active {
|
||||
color: #4a90e2;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.oa-activity-tab.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: #4a90e2;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
|
||||
/* 活动轮播样式 */
|
||||
.oa-activity-carousel {
|
||||
flex: 1;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.oa-activity-carousel .el-carousel,.oa-activity-carousel .el-carousel .el-carousel__container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.oa-activity-carousel .el-carousel__item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.oa-activity-card {
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oa-activity-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.oa-activity-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-activity-card:hover .oa-activity-image img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 图片上的文字叠加层 */
|
||||
.oa-activity-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
|
||||
padding: 40px 20px 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.oa-activity-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.oa-activity-meta {
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
margin-bottom: 15px;
|
||||
line-height: 1.5;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* 无活动时的提示区域 */
|
||||
.oa-no-activity {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
background: #f8f9fa;
|
||||
border-radius: 12px;
|
||||
color: #6c757d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.oa-no-activity-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
color: #dee2e6;
|
||||
}
|
||||
|
||||
.oa-no-activity-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.oa-no-activity-desc {
|
||||
font-size: 14px;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
/* box2 - 系统通知公告 */
|
||||
.oa-box-2-section {
|
||||
width: 1500px;
|
||||
margin: 30px auto 0;
|
||||
background: #ffffff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oa-notice-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.oa-notice-header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.oa-notice-header-content::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.oa-notice-header-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.oa-notice-header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.oa-notice-header-more {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.oa-header-more-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-header-more-btn:hover {
|
||||
background: #f5f5f5;
|
||||
color: #4a90e2;
|
||||
}
|
||||
|
||||
.oa-header-more-btn i {
|
||||
font-size: 12px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.oa-header-more-btn:hover i {
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
|
||||
.oa-notice-content {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.oa-notice-list {
|
||||
display: grid;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.oa-notice-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 15px 20px;
|
||||
background: #ffffff;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.oa-notice-item:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.oa-notice-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.oa-notice-item-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #666;
|
||||
margin-right: 12px;
|
||||
margin-top: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.oa-notice-item-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.oa-notice-item-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oa-notice-item-desc {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oa-notice-item-date {
|
||||
margin-left: 15px;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="oa-container" id="v4-home-app">
|
||||
<!-- 顶部导航 -->
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div class="oa-main-content">
|
||||
<!-- 背景图和搜索统计区域容器 -->
|
||||
<div class="oa-hero-section">
|
||||
<!-- 背景图 -->
|
||||
<div class="oa-background-image">
|
||||
<img
|
||||
src="https://i.cpu.edu.cn/mnews/_upload/article/images/ed/dc/eff0e4b84ee6b2d7e770ed1de071/0f515087-45e3-4dbf-acf4-e7096d6cbdc0.jpg"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 搜索和统计区域 -->
|
||||
<div class="oa-search-stats-section">
|
||||
<!-- 搜索区域 -->
|
||||
<div class="oa-search-section">
|
||||
<!-- <h1 class="oa-search-title">精业济群</h1>-->
|
||||
<div class="oa-search-container">
|
||||
<input type="text" class="oa-search-input" placeholder="请输入您要查询的关键字"
|
||||
v-model="searchQuery" />
|
||||
<button class="oa-search-btn" @click="performSearch">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数字提醒 -->
|
||||
<div class="oa-stats-section">
|
||||
<h3 class="oa-stats-title">提醒</h3>
|
||||
<div class="oa-stats-grid">
|
||||
<div class="oa-stat-card" @click="handleStatClick('todo')">
|
||||
<div class="oa-stat-top">
|
||||
<div class="oa-stat-icon">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</div>
|
||||
<div class="oa-stat-number">{{ stats.todo }}</div>
|
||||
</div>
|
||||
<div class="oa-stat-label">待办</div>
|
||||
</div>
|
||||
<div class="oa-stat-card" @click="handleStatClick('done')">
|
||||
<div class="oa-stat-top">
|
||||
<div class="oa-stat-icon">
|
||||
<i class="fa fa-check-circle"></i>
|
||||
</div>
|
||||
<div class="oa-stat-number">{{ stats.done }}</div>
|
||||
</div>
|
||||
<div class="oa-stat-label">已办</div>
|
||||
</div>
|
||||
<div class="oa-stat-card" @click="handleStatClick('notification')">
|
||||
<div class="oa-stat-top">
|
||||
<div class="oa-stat-icon">
|
||||
<i class="fa fa-bell"></i>
|
||||
</div>
|
||||
<div class="oa-stat-number">{{ stats.notifications }}</div>
|
||||
</div>
|
||||
<div class="oa-stat-label">消息</div>
|
||||
</div>
|
||||
<div class="oa-stat-card" @click="handleStatClick('started')">
|
||||
<div class="oa-stat-top">
|
||||
<div class="oa-stat-icon">
|
||||
<i class="fa fa-file-text"></i>
|
||||
</div>
|
||||
<div class="oa-stat-number">{{ stats.started }}</div>
|
||||
</div>
|
||||
<div class="oa-stat-label">申请</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- box1 -->
|
||||
<div class="oa-box-1-section">
|
||||
<!-- 左侧用户信息 -->
|
||||
<div class="oa-user-panel">
|
||||
<div class="oa-user-avatar">
|
||||
<i class="fa fa-user"></i>
|
||||
</div>
|
||||
<div class="oa-user-name">${@auth.getPrincipalProperty('username')}</div>
|
||||
<div class="oa-user-info">
|
||||
<div class="info-item">
|
||||
<span class="info-label">工号:</span>
|
||||
<span class="info-value">${@auth.getPrincipalProperty('loginname')}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">性别:</span>
|
||||
<span class="info-value">${@auth.getPrincipalProperty('sex')}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">单位:</span>
|
||||
<span class="info-value">
|
||||
<!--#if(!isEmpty(@auth.getPrincipalProperty('unit'))){#-->
|
||||
${@auth.getPrincipalProperty('unit').getName()}
|
||||
<!--#}#-->
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">工会:</span>
|
||||
<span class="info-value">
|
||||
<!--#if(!isEmpty(@auth.getPrincipalProperty('union'))){#-->
|
||||
${@auth.getPrincipalProperty('union').getName()}
|
||||
<!--#}#-->
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/platform/v4/personCenter" class="oa-user-homepage-btn" target="_blank">
|
||||
<i class="fa fa-home"></i>
|
||||
个人主页
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- 右侧活动列表 -->
|
||||
<div class="oa-activity-content">
|
||||
<div class="oa-activity-header">
|
||||
<div class="oa-activity-tabs">
|
||||
<div class="oa-activity-tab" :class="{active: activeTab === 'recent'}"
|
||||
@click="setActiveTab('recent')">最新活动
|
||||
</div>
|
||||
<div class="oa-activity-tab" :class="{active: activeTab === 'history'}"
|
||||
@click="setActiveTab('history')">历史活动
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oa-activity-carousel">
|
||||
<div v-if="currentActivityList.length === 0" class="oa-no-activity">
|
||||
<div class="oa-no-activity-icon">
|
||||
<i class="fa fa-calendar-o"></i>
|
||||
</div>
|
||||
<div class="oa-no-activity-title">暂无活动信息</div>
|
||||
<div class="oa-no-activity-desc">{{ activeTab === 'recent' ? '当前没有最新活动' : '当前没有历史活动'
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<el-carousel v-else :autoplay="true" arrow="always" indicator-position="none">
|
||||
<el-carousel-item v-for="activity in currentActivityList" :key="activity.id">
|
||||
<div class="oa-activity-card">
|
||||
<div class="oa-activity-image">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?w=800&auto=format&fit=crop"
|
||||
:alt="activity.name" />
|
||||
<div class="oa-activity-overlay">
|
||||
<div class="oa-activity-title">{{ activity.name }}</div>
|
||||
<div class="oa-activity-meta">{{ activity.startDate }} ~ {{ activity.endDate
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- box2 - 系统通知公告 -->
|
||||
<div class="oa-box-2-section">
|
||||
<div class="oa-notice-header">
|
||||
<div class="oa-notice-header-content">
|
||||
<div class="oa-notice-header-icon">
|
||||
<i class="fa fa-bullhorn"></i>
|
||||
</div>
|
||||
<h2 class="oa-notice-header-title">系统通知公告</h2>
|
||||
</div>
|
||||
<div class="oa-notice-header-more">
|
||||
<button class="oa-header-more-btn">
|
||||
更多
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oa-notice-content">
|
||||
<div class="oa-notice-list">
|
||||
<div v-for="notice in noticeList" :key="notice.id" class="oa-notice-item" @click="viewNotice(notice)">
|
||||
<div class="oa-notice-item-icon">
|
||||
<i class="fa fa-bullhorn"></i>
|
||||
</div>
|
||||
<div class="oa-notice-item-content">
|
||||
<div class="oa-notice-item-title">{{ notice.title }}</div>
|
||||
<div class="oa-notice-item-desc">{{ notice.content }}</div>
|
||||
</div>
|
||||
<div class="oa-notice-item-date">{{ notice.publishDate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
const vue = new Vue({
|
||||
el: "#v4-home-app",
|
||||
data() {
|
||||
return {
|
||||
searchQuery: "",
|
||||
activeTab: "recent",
|
||||
noticeTab: "system",
|
||||
currentIndex: 0,
|
||||
stats: {
|
||||
todo: 3,
|
||||
done: 0,
|
||||
notifications: 7,
|
||||
started: 9
|
||||
},
|
||||
activityList: [],
|
||||
noticeList: [
|
||||
{
|
||||
id: 1,
|
||||
type: 'system',
|
||||
title: '系统维护通知',
|
||||
content: '系统将于本周六晚上22:00-24:00进行例行维护,期间可能影响正常使用,请提前做好相关准备。',
|
||||
publishDate: '2024-01-15',
|
||||
isRead: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
type: 'announcement',
|
||||
title: '新功能上线公告',
|
||||
content: '移动端应用已正式上线,支持手机端办公审批,欢迎大家下载使用。',
|
||||
publishDate: '2024-01-14',
|
||||
isRead: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
type: 'urgent',
|
||||
title: '紧急安全提醒',
|
||||
content: '近期发现钓鱼邮件攻击,请勿点击可疑链接,如有疑问请联系IT部门。',
|
||||
publishDate: '2024-01-13',
|
||||
isRead: false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
recentActivities() {
|
||||
const now = new Date()
|
||||
return this.activityList
|
||||
.filter(activity => new Date(activity.endDate) >= now)
|
||||
.sort((a, b) => new Date(b.startDate) - new Date(a.startDate))
|
||||
},
|
||||
historyActivities() {
|
||||
const now = new Date()
|
||||
return this.activityList
|
||||
.filter(activity => new Date(activity.endDate) < now)
|
||||
.sort((a, b) => new Date(b.startDate) - new Date(a.startDate))
|
||||
},
|
||||
currentActivityList() {
|
||||
return this.activeTab === "recent" ? this.recentActivities : this.historyActivities
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化数据
|
||||
this.getActivity()
|
||||
this.getStatistics()
|
||||
},
|
||||
methods: {
|
||||
performSearch() {
|
||||
if (this.searchQuery.trim()) {
|
||||
console.log("搜索:", this.searchQuery)
|
||||
// 实现搜索逻辑
|
||||
}
|
||||
},
|
||||
setActiveTab(tab) {
|
||||
this.activeTab = tab
|
||||
this.currentIndex = 0 // 切换标签时重置索引
|
||||
},
|
||||
getActivity() {
|
||||
$.get("/platform/home/listHomeActivity").then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.activityList = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
viewNotice(notice) {
|
||||
console.log('查看通知:', notice.title)
|
||||
// 标记为已读
|
||||
notice.isRead = true
|
||||
// 这里可以添加查看详情的逻辑
|
||||
},
|
||||
|
||||
handleStatClick(val){
|
||||
if(['todo', 'done', 'application']){
|
||||
window.open('/flow/todoCenter?status=' + val)
|
||||
}
|
||||
},
|
||||
async getStatistics() {
|
||||
try {
|
||||
const res = await $.post("/flow/todoCenter/statistics")
|
||||
if (res.code === 0) {
|
||||
const { todoCount, doneCount, startedCount } = res.data
|
||||
this.stats.todo = todoCount
|
||||
this.stats.done = doneCount
|
||||
this.stats.started = startedCount
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error("获取统计数据失败")
|
||||
console.error("获取统计数据失败:", error)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#}#-->
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
<!--#
|
||||
layout("/layouts/v4/baseLayout.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.message-center {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.statistics-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border: none;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.stat-card .el-card__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.all-icon {
|
||||
background-color: rgba(64, 158, 255, 0.1);
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.unread-icon {
|
||||
background-color: rgba(245, 108, 108, 0.1);
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.read-icon {
|
||||
background-color: rgba(103, 194, 58, 0.1);
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 搜索区域样式 */
|
||||
.filter-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.filter-section .el-card__body {
|
||||
padding: 15px 20px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.search-form .el-form-item {
|
||||
margin-bottom: 0;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
/* 消息列表区域样式 */
|
||||
.message-section .el-card__header {
|
||||
padding: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 优化后的 tabs 样式 */
|
||||
.message-header .el-tabs__header {
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.message-header .el-tabs__nav-wrap::after {
|
||||
height: 1px;
|
||||
background-color: #ebeef5;
|
||||
}
|
||||
|
||||
.message-header .el-tabs__item {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 15px;
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.message-header .el-tabs__item.is-active {
|
||||
color: var(--color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.message-header .el-tabs__active-bar {
|
||||
height: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.message-title {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<div class="message-center">
|
||||
<!-- 统计数据区域 -->
|
||||
<el-row :gutter="20" class="statistics-section">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="never" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon all-icon">
|
||||
<i class="el-icon-message"></i>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{stats.total}}</div>
|
||||
<div class="stat-label">全部消息</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="never" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon unread-icon">
|
||||
<i class="el-icon-bell"></i>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{stats.unread}}</div>
|
||||
<div class="stat-label">未读消息</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="never" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon read-icon">
|
||||
<i class="el-icon-finished"></i>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{stats.read}}</div>
|
||||
<div class="stat-label">已读消息</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 搜索筛选区域 -->
|
||||
<el-card shadow="never" class="filter-section">
|
||||
<el-form :inline="true" :model="filters" class="search-form">
|
||||
<el-form-item>
|
||||
<el-select v-model="filters.type" placeholder="消息类型" clearable @change="loadMessages"
|
||||
style="width: 150px;">
|
||||
<el-option label="全部类型" value=""></el-option>
|
||||
<el-option label="系统公告" value="1"></el-option>
|
||||
<el-option label="消息通知" value="2"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="pageForm.isRead == 0">
|
||||
<el-button size="medium" type="primary" @click="markAllAsRead" :loading="loading">
|
||||
<i class="el-icon-check"></i> 全部标记已读
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 消息列表区域 -->
|
||||
<el-card shadow="never" class="message-section">
|
||||
<div slot="header" class="message-header">
|
||||
<el-tabs v-model="pageForm.isRead" @tab-click="handleTabClick">
|
||||
<el-tab-pane label="全部消息" name="-1">
|
||||
<span slot="label">
|
||||
<i class="el-icon-message"></i>
|
||||
全部消息
|
||||
</span>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="未读消息" name="0">
|
||||
<span slot="label">
|
||||
<i class="el-icon-bell"></i>
|
||||
未读消息
|
||||
</span>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="已读消息" name="1">
|
||||
<span slot="label">
|
||||
<i class="el-icon-finished"></i>
|
||||
已读消息
|
||||
</span>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 表格展示 -->
|
||||
<el-table v-loading="loading" :data="messages" style="width: 100%" :key="currentTab"
|
||||
empty-text="暂无消息"
|
||||
:header-cell-style="{backgroundColor: '#f5f7fa'}">
|
||||
<el-table-column prop="type" label="消息类型" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="mini" :type="scope.row.type === 1 ? 'danger' : 'primary'">
|
||||
{{getMessageTypeName(scope.row.type)}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="title" label="标题" min-width="200" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
<span class="message-title">{{scope.row.title}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="content" label="内容预览" min-width="250" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
{{getContentPreview(scope.row.content)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="接收时间" width="180">
|
||||
<template slot-scope="scope">
|
||||
{{formatTime(scope.row.createdAt)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isRead" label="状态" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="mini" :type="scope.row.isRead ? 'success' : 'warning'">
|
||||
{{scope.row.isRead ? '已读' : '未读'}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini" @click="viewMessage(scope.row)">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container" v-if="messages.length > 0">
|
||||
<el-pagination
|
||||
background
|
||||
@current-change="handlePageChange"
|
||||
:current-page="pageForm.pageNumber"
|
||||
:page-size="pageForm.pageSize"
|
||||
layout="prev, pager, next, jumper"
|
||||
:total="pageForm.totalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 消息详情弹窗 -->
|
||||
<el-dialog
|
||||
:visible.sync="detailVisible"
|
||||
:title="currentMessage?.globalMessage?.title"
|
||||
width="60%"
|
||||
class="message-detail-dialog"
|
||||
>
|
||||
<div v-if="currentMessage.id">
|
||||
<div style="text-align: center; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid #eee;">
|
||||
<div style="font-size: 18px; font-weight: 500; margin-bottom: 8px;">{{currentMessage.title}}</div>
|
||||
<div style="font-size: 14px; color: #666;">
|
||||
<span>{{getMessageTypeName(currentMessage?.globalMessage?.type)}}</span>
|
||||
<span style="margin: 0 8px;">•</span>
|
||||
<span>{{formatTime(currentMessage.createdAt)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="line-height: 1.8; font-size: 15px;" v-html="currentMessage?.globalMessage?.content"></div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailVisible = false">关闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return {
|
||||
currentTab: 'all',
|
||||
loading: false,
|
||||
messages: [],
|
||||
stats: {
|
||||
total: 0,
|
||||
unread: 0,
|
||||
read: 0
|
||||
},
|
||||
filters: {
|
||||
type: ''
|
||||
},
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0
|
||||
},
|
||||
detailVisible: false,
|
||||
currentMessage: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadStats() {
|
||||
try {
|
||||
const resp = await this.$axios.get('/platform/v4/msg/stats')
|
||||
if (resp.code === 0) {
|
||||
this.stats = resp.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载统计数据失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
async loadMessages() {
|
||||
this.loading = true
|
||||
try {
|
||||
const resp = await this.$axios.post('/platform/v4/msg/pageData', this.pageForm)
|
||||
if (resp.code === 0) {
|
||||
this.messages = resp.data.list
|
||||
this.pageForm.totalCount = resp.data.totalCount
|
||||
} else {
|
||||
this.$message.error(resp.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('加载消息失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async viewMessage(message) {
|
||||
this.$axios.post(`/platform/v4/msg/detail/` + message.id).then(async res => {
|
||||
if (res.code === 0) {
|
||||
this.currentMessage = res.data
|
||||
this.detailVisible = true
|
||||
// 如果是未读消息,标记为已读
|
||||
if (!message.isRead) {
|
||||
await this.markAsRead(message.id)
|
||||
this.loadStats()
|
||||
this.loadMessages()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async markAsRead(messageId) {
|
||||
try {
|
||||
await this.$axios.post(`/platform/v4/msg/read/` + messageId)
|
||||
} catch (error) {
|
||||
console.error('标记已读失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
async markAllAsRead() {
|
||||
this.$confirm('确定要将所有未读消息标记为已读吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
this.loading = true
|
||||
try {
|
||||
const resp = await this.$axios.post('/platform/v4/msg/read/all')
|
||||
if (resp.code === 0) {
|
||||
this.$message.success('操作成功')
|
||||
this.loadMessages()
|
||||
this.loadStats()
|
||||
} else {
|
||||
this.$message.error(resp.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error('操作失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleTabClick(tab) {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.loadMessages()
|
||||
},
|
||||
|
||||
handlePageChange(pageNumber) {
|
||||
this.pageForm.pageNumber = pageNumber
|
||||
this.loadMessages()
|
||||
},
|
||||
|
||||
getMessageTypeName(type) {
|
||||
return type === 1 ? '系统公告' : '消息通知'
|
||||
},
|
||||
|
||||
getContentPreview(content) {
|
||||
if (!content) return ''
|
||||
// 移除HTML标签
|
||||
const text = content.replace(/<[^>]*>/g, '')
|
||||
return text.length > 50 ? text.substring(0, 50) + '...' : text
|
||||
},
|
||||
|
||||
formatTime(timestamp) {
|
||||
return this.$moment(timestamp).format('YYYY-MM-DD HH:mm')
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.loadStats()
|
||||
this.loadMessages()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,448 @@
|
||||
<!--#
|
||||
layout("/layouts/v4/baseLayout.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.task-todo-center {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.statistics-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.stat-card .el-card__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.todo-icon {
|
||||
background-color: rgba(64, 158, 255, 0.1);
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.done-icon {
|
||||
background-color: rgba(103, 194, 58, 0.1);
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.started-icon {
|
||||
background-color: rgba(230, 162, 60, 0.1);
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 搜索区域样式 */
|
||||
.filter-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.filter-section .el-card__body {
|
||||
padding: 15px 20px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.search-form .el-form-item {
|
||||
margin-bottom: 0;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
/* 任务列表区域样式 */
|
||||
.task-section .el-card__header {
|
||||
padding: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 优化后的 tabs 样式 */
|
||||
.task-header .el-tabs__header {
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.task-header .el-tabs__nav-wrap::after {
|
||||
height: 1px;
|
||||
background-color: #ebeef5;
|
||||
}
|
||||
|
||||
.task-header .el-tabs__item {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 15px;
|
||||
color: #606266;
|
||||
padding: 0 20px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.task-header .el-tabs__item.is-active {
|
||||
color: #409eff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.task-header .el-tabs__active-bar {
|
||||
height: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/* 表格行样式 */
|
||||
.el-table .hover-row {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<div class="task-todo-center">
|
||||
<!-- 统计数据区域 -->
|
||||
<el-row :gutter="20" class="statistics-section">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon todo-icon">
|
||||
<i class="el-icon-s-claim"></i>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{todoCount}}</div>
|
||||
<div class="stat-label">待办任务</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon done-icon">
|
||||
<i class="el-icon-finished"></i>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{doneCount}}</div>
|
||||
<div class="stat-label">已办任务</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon started-icon">
|
||||
<i class="el-icon-s-promotion"></i>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{startedCount}}</div>
|
||||
<div class="stat-label">我发起的</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 搜索筛选区域 -->
|
||||
<el-card shadow="never" class="filter-section">
|
||||
<el-form :inline="true" :model="pageForm" class="search-form">
|
||||
<el-form-item>
|
||||
<el-input v-model="pageForm.searchKeyword" placeholder="请输入关键词搜索"
|
||||
prefix-icon="el-icon-search"
|
||||
clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="pageForm.category" placeholder="所有流程分类" clearable>
|
||||
<el-option v-for="type in categoryOptions" :key="type.id" :label="type.name"
|
||||
:value="type.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="search">搜索</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 任务列表区域 -->
|
||||
<el-card shadow="never" class="task-section">
|
||||
<div slot="header" class="task-header">
|
||||
<el-tabs v-model="activeTab" @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-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 表格展示 -->
|
||||
<el-table v-loading="loading" :data="tasks" style="width: 100%" :key="activeTab"
|
||||
:header-cell-style="{backgroundColor: '#f5f7fa'}">
|
||||
<el-table-column prop="processInstanceName" label="流程名称" min-width="180" show-overflow-tooltip>
|
||||
<template slot-scope="scope">
|
||||
<span class="task-title">{{scope.row.variable?.instanceName}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="taskName" label="任务节点" min-width="150"
|
||||
show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="categoryName" label="流程分类" min-width="150" show-overflow-tooltip>
|
||||
<template slot-scope="{row}">{{categoryOptions.find(item => item.id === row.category)?.name}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="initiatorName" label="申请人" min-width="120">
|
||||
<template slot-scope="{row}">{{row.variable.initiatorName}}</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="时间" min-width="180">-->
|
||||
<!-- <template slot-scope="scope">-->
|
||||
<!-- <div v-if="activeTab === 'todo'">-->
|
||||
<!-- <i class="el-icon-time"></i>-->
|
||||
<!-- {{scope.row.createdAt}}-->
|
||||
<!-- </div>-->
|
||||
<!-- <div v-else-if="activeTab === 'done'">-->
|
||||
<!-- <i class="el-icon-check"></i>-->
|
||||
<!-- {{scope.row.finishTime}}-->
|
||||
<!-- </div>-->
|
||||
<!-- <div v-else-if="activeTab === 'started'">-->
|
||||
<!-- <i class="el-icon-s-promotion"></i>-->
|
||||
<!-- {{scope.row.createdAt}}-->
|
||||
<!-- </div>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column v-if="activeTab === 'started'" label="状态" width="100">
|
||||
<template slot-scope="{row}">{{processStatusMap[row.state]?.text}}</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>
|
||||
|
||||
<!-- 空状态展示 -->
|
||||
<el-empty v-if="tasks.length === 0" :description="getEmptyText()"></el-empty>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container" v-if="tasks.length > 0">
|
||||
<el-pagination
|
||||
background
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="pageForm.pageNumber"
|
||||
:page-size="pageForm.pageSize"
|
||||
layout="prev, pager, next, jumper"
|
||||
:total="pageForm.totalCount"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
// 统计数据
|
||||
todoCount: 0,
|
||||
doneCount: 0,
|
||||
startedCount: 0,
|
||||
|
||||
// 查询表单
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
todoCount: 0,
|
||||
keyword: "",
|
||||
category: ""
|
||||
},
|
||||
|
||||
|
||||
// 流程类型选项
|
||||
categoryOptions: [],
|
||||
|
||||
// 任务列表
|
||||
tasks: [],
|
||||
loading: false,
|
||||
|
||||
// 标签页
|
||||
activeTab: "todo",
|
||||
|
||||
// 当前任务
|
||||
currentTask: null,
|
||||
dialogVisible: false,
|
||||
|
||||
processStatusMap: {
|
||||
10: {text: "进行中", class: "doing"},
|
||||
20: {text: "已完成", class: "finished"},
|
||||
30: {text: "已撤回", class: "withdraw"},
|
||||
40: {text: "强行终止", class: "interrupt"},
|
||||
45: {text: "已拒绝", class: "reject"},
|
||||
50: {text: "挂起", class: "pending"},
|
||||
99: {text: "已废弃", class: "abandon"}
|
||||
},
|
||||
|
||||
// 任务状态枚举
|
||||
taskStateEnum: {
|
||||
DOING: 10,
|
||||
FINISHED: 20,
|
||||
WITHDRAW: 30,
|
||||
INTERRUPT: 40,
|
||||
PENDING: 50,
|
||||
ABANDON: 99
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.initData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 初始化数据
|
||||
async initData() {
|
||||
await Promise.all([this.getStatistics(), this.listCategory(), this.getTasks()])
|
||||
},
|
||||
|
||||
// 获取统计数据
|
||||
async getStatistics() {
|
||||
try {
|
||||
const res = await $.post("/flow/todoCenter/statistics")
|
||||
if (res.code === 0) {
|
||||
const {todoCount, doneCount, startedCount} = res.data
|
||||
this.todoCount = todoCount
|
||||
this.doneCount = doneCount
|
||||
this.startedCount = startedCount
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error("获取统计数据失败")
|
||||
console.error("获取统计数据失败:", error)
|
||||
}
|
||||
},
|
||||
|
||||
// 获取流程类型
|
||||
async listCategory() {
|
||||
this.$axios.post("/flow/category/list").then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.categoryOptions = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 获取任务列表
|
||||
async getTasks() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await $.post("/flow/todoCenter/" + this.activeTab, this.pageForm)
|
||||
if (res.code === 0) {
|
||||
this.tasks = res.data.list
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
this.dialogVisible = false
|
||||
}
|
||||
} catch (error) {
|
||||
this.$message.error("获取任务列表失败")
|
||||
console.error("获取任务列表失败:", error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 处理标签页点击
|
||||
handleTabClick(tab) {
|
||||
this.activeTab = tab.name
|
||||
this.pageForm.pageNumber = 1
|
||||
this.getTasks()
|
||||
},
|
||||
|
||||
// 搜索
|
||||
search() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.getTasks()
|
||||
this.getStatistics()
|
||||
},
|
||||
|
||||
// 重置搜索
|
||||
reset() {
|
||||
this.pageForm.searchKeyword = ""
|
||||
this.pageForm.category = ""
|
||||
this.search()
|
||||
},
|
||||
|
||||
// 处理页码变化
|
||||
handleCurrentChange(val) {
|
||||
this.pageForm.pageNumber = val
|
||||
this.getTasks()
|
||||
},
|
||||
|
||||
// 处理任务
|
||||
async openView(task) {
|
||||
console.log(task)
|
||||
const {taskId, taskKey, taskState, instanceId, businessNo, formKey} = task
|
||||
if (!formKey) {
|
||||
this.$message.warning("当前流程没有配置地址")
|
||||
return
|
||||
}
|
||||
window.open(formKey + "?taskId=" + taskId + "bizId=" + businessNo + "taskKey=" + taskKey)
|
||||
},
|
||||
|
||||
// 获取空状态文本
|
||||
getEmptyText() {
|
||||
switch (this.activeTab) {
|
||||
case "todo":
|
||||
return "您当前没有需要办理的任务,辛苦了"
|
||||
case "done":
|
||||
return "您当前没有已办理的任务记录"
|
||||
case "started":
|
||||
return "您当前没有发起的流程"
|
||||
default:
|
||||
return "暂无数据"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user