Files
jnpf_app/pages/index/indexWork.vue
2026-01-23 15:16:31 +08:00

728 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="custom-nav-bar">
<!-- 左侧图标 + 标题 -->
<view class="nav-left">
<image class="nav-icon" src="./img/dun.png" mode="widthFix"></image>
<text class="nav-title">{{'综合监控系统'}}</text>
</view>
<!-- <view class="nav-right">
<image class="nav-avatar" :src="userInfo.avatar || '/static/image/avatar-default.png'" mode="widthFix"></image>
<text class="nav-dot" v-if="count > 0"></text>
</view> -->
</view>
<view class="index_v">
<!-- <u-sticky>
<view class="head-tabs u-flex">
<view class="head-tabs-item" @click="openPage('/pages/workFlow/flowTodo/index','approve')">
<text class="icon-ym icon-ym-flowTodo-app u-m-r-4 icon-style" />
<text class="u-font-24 head-tabs-name">审批中心</text>
<u-badge type="error" :count="count" :absolute="true" :offset="offset" />
</view>
<view class="head-tabs-item" @click="openPage('/pages/workFlow/entrustAgent/index','entrust')">
<text class="icon-ym icon-ym-flowDone-app u-m-r-4 icon-style" />
<text class="u-font-24 head-tabs-name">委托代理</text>
</view>
<view class="head-tabs-item" @click="openPage('/pages/workFlow/schedule/index','schedule')">
<text class="icon-ym icon-ym-flowDone-app u-m-r-4 icon-style" />
<text class="u-font-24 head-tabs-name">日程</text>
</view>
<view class="head-tabs-item" @click="openPage('/pages/workFlow/document/index','document')">
<text class="icon-ym icon-ym-flowCopy-app u-m-r-4 icon-style" />
<text class="u-font-24 head-tabs-name">文档</text>
</view>
</view>
</u-sticky> -->
<!-- <CommonPane :flowList="homeData.favoritesFlowList || []" :menuList="homeData.favoritesMenuList || []"
type="collect" @launch="launch" v-if="homeData.favoritesEnable" @openPage="openPage" @addApp="addApp"
:showAdd="true" :flowEnabled="homeData.flowEnabled" />
<CommonPane title="最近使用" :flowList="homeData.latelyUseFlowList || []" type="use"
:menuList="homeData.latelyUseMenuList || []" @launch="launch" v-if="homeData.latelyUseEnable"
@openPage="openPage" :flowEnabled="homeData.flowEnabled" />
<CommonPane title="最近常用" :flowList="homeData.commonUseFlowList || []" type="common"
:menuList="homeData.commonUseMenuList || []" @launch="launch" v-if="homeData.commonUseEnable"
@openPage="openPage" :flowEnabled="homeData.flowEnabled" /> -->
<CommonPaneSys title="应用功能" :flowList="[]" type="common"
:menuList="homeData || []" @launch="launch" v-if="homeData"
@openPage="openPage" />
<view class="todo-list-wrap">
<view class="todo-title">
<view class="title-left">
<view >待处理事项</view>
<!-- <u-badge type="error" :count="count" :absolute="true" :offset="offset" /> -->
</view>
<view class="title-right" @click="openToDoPage">
工作信息
<u-icon name="arrow-right" class="u-p-r-10"color="#666"></u-icon>
</view>
</view >
<scroll-view
v-if="todoList.length > 0"
class="todo-scroll-container"
scroll-y
show-scrollbar="true"
:style="{height: todoList.length > 3 ? '350rpx' : 'auto'}"
>
<view
class="todo-item"
v-for="(item, index) in todoList"
:key="index"
@click="goDetail(item)"
>
<!-- 顶部单号栏 -->
<view class="todo-header">
<view class="todo-code">
<text class="code-label">单号</text>
<text class="code-value">{{item.businessInfo && item.businessInfo.billNo}}</text>
</view>
</view>
<!-- 信息列表 -->
<view class="todo-info-list">
<view class="todo-info-row">
<text class="info-label">单据类型</text>
<text class="info-value">{{item.processInstance.name}}</text>
</view>
<view class="todo-info-row">
<text class="info-label">发起人</text>
<text class="info-value">{{item.processInstance.startUserNickname}}</text>
</view>
<view class="todo-info-row">
<text class="info-label">创建时间</text>
<text class="info-value">{{formatTime(item.createTime) || '2026-01-15 14:16:36'}}</text>
</view>
</view>
</view>
</scroll-view>
<view class="empty-container" v-else>
<view>
<image
class="empty-icon"
src="https://app.cdn.jnpfsoft.com/image/message/nodata.png"
mode="widthFix"
/></view>
<text class="empty-tip">暂无数据</text>
</view>
</view>
<PasswordPopup @submit="dataFormSubmit" :passwordShow="passwordShow" :formData="baseForm"></PasswordPopup>
</view>
</template>
<script>
import {
getFlowTodoCount
} from "@/api/workFlow/flowEngine";
import {
getMenuData,
getDonePage
} from "@/api/index/index";
import {
useUserStore
} from '@/store/modules/user'
import {
useChatStore
} from '@/store/modules/chat'
import {
updatePassword,
updatePasswordMessage
} from '@/api/common.js'
import {
getProcessBusinessInfo
} from '@/api/apply/visualDev'
import chat from '@/libs/chat'
import CommonPane from '@/components/CommonPane'
import CommonPaneSys from '@/components/CommonPane/indexSystem'
import PasswordPopup from './components/PasswordPopup'
import {
useLocale
} from '@/locale/useLocale';
const chatStore = useChatStore()
export default {
components: {
CommonPane,
CommonPaneSys,
PasswordPopup
},
data() {
return {
homeData: [],
count: 0,
offset: [430, 525],
menuList: [],
passwordShow: false,
baseForm: {
passwordStrengthLimit: 0,
passwordLengthMin: false,
passwordLengthMinNumber: 0,
containsNumbers: false,
includeLowercaseLetters: false,
includeUppercaseLetters: false,
containsCharacters: false,
mandatoryModificationOfInitialPassword: 0,
},
userInfo: {},
todoList: []
};
},
// onLoad() {
// const chatStore = useChatStore()
// if (!chatStore.getSocket) chat && chat.initSocket()
// const userStore = useUserStore()
// userStore.getCurrentUser().then(() => {
// this.getSystemName()
// }).catch(() => {
// setTimeout(() => {
// userStore.resetToken()
// setTimeout(() => {
// uni.reLaunch({
// url: '/pages/login/index'
// })
// }, 500)
// }, 1000)
// })
// const {
// changeLocale
// } = useLocale();
// changeLocale(uni.getLocale())
// },
onShow(e) {
this.init()
},
computed: {
baseURL() {
return this.define.baseURL;
},
token() {
return uni.getStorageSync('token')
},
report() {
return this.define.report;
},
pcURL() {
return this.define.pcURL;
}
},
methods: {
// 时间格式化
formatTime(timestamp) {
if (!timestamp) return '-';
const date = new Date(timestamp);
return `${date.getFullYear()}-${this.padZero(date.getMonth() + 1)}-${this.padZero(date.getDate())} ${this.padZero(date.getHours())}:${this.padZero(date.getMinutes())}:${this.padZero(date.getSeconds())}`;
},
padZero(num) {
return num.toString().padStart(2, '0');
},
init() {
this.getMenuData()
this.getDonePage()
// this.getFlowCount()
// this.getSystemConfig()
},
// 获取系统配置
getSystemConfig() {
updatePasswordMessage();
this.userInfo = uni.getStorageSync('userInfo') || {}
const config = uni.getStorageSync('sysConfigInfo') || {};
this.$nextTick(() => {
this.baseForm.passwordStrengthLimit = config.passwordStrengthLimit
this.baseForm.passwordLengthMin = config.passwordLengthMin
this.baseForm.passwordLengthMinNumber = config.passwordLengthMinNumber
this.baseForm.containsNumbers = config.containsNumbers
this.baseForm.includeLowercaseLetters = config.includeLowercaseLetters
this.baseForm.containsCharacters = config.containsCharacters
this.baseForm.mandatoryModificationOfInitialPassword = config
.mandatoryModificationOfInitialPassword
if (this.userInfo.changePasswordDate == null && config
.mandatoryModificationOfInitialPassword == 1)
this.passwordShow = true;
})
},
dataFormSubmit(query) {
updatePassword(query).then((res) => {
const userStore = useUserStore()
// userStore.logout().then(() => {
// uni.reLaunch({
// url: "/pages/login/index",
// });
// });
})
},
//获取并设置应用名称
getSystemName() {
const userInfo = uni.getStorageSync("userInfo");
this.menuList = uni.getStorageSync("menuList");
uni.setNavigationBarTitle({
title: userInfo.systemName
})
},
launch(item) {
console.log(item,'item-------')
if (item.tabType == 'flow') return this.JumpFlow(item)
if (item.tabType == 'menu') return this.JumpApply(item)
},
JumpApply(item) {
let url = "/pages/apply/dynamicModelList/index?config=" + this.jnpf.base64.encode(JSON.stringify(item))
// if (item.type == 1) {
// getChildList(item.id).then(res => {
// this.listChild = res.data || []
// this.handleProperty(this.listChild)
// this.$nextTick(() => {
// uni.navigateTo({
// url: "/pages/apply/catalog/index?config=" +
// this.jnpf.base64.encode(JSON.stringify(this.listChild[0])),
// fail: (err) => {
// this.$u.toast("暂无此页面");
// },
// });
// })
// })
// return;
// }
// let url = ''
// // 2-页面 11-回传表单
// if (item.type == 2 || item.type == 11) {
// if (!item.pageAddress) {
// this.$u.toast("暂无此页面");
// return;
// }
// url = item.pageAddress + "?menuId=" + item.id + "&fullName=" + item.fullName
// }
// // 3-在线表单 9-流程
// if (item.type == 3 || item.type == 9) {
// if (!item.moduleId) {
// this.$u.toast("暂无此页面");
// return;
// }
// url = "/pages/apply/dynamicModel/index?config=" + this.jnpf.base64.encode(JSON.stringify(item))
// }
// // 外链
// if (item.type == 7) {
// if (!item.pageAddress) {
// this.$u.toast("暂无此页面");
// return;
// }
// url = "/pages/apply/externalLink/index?url=" + encodeURIComponent(item.pageAddress) + "&fullName=" +
// item.fullName + "&type=" + item.type
// }
// // 报表(原)
// if (item.type == 5) {
// if (!item.moduleId) {
// this.$u.toast("暂无此页面");
// return;
// }
// userInfo = uni.getStorageSync('userInfo') || {}
// const appCode = userInfo.systemCode
// const urlPre = encodeURIComponent(
// `${this.report}/preview.html?id=${item.moduleId}&token=${this.token}&appCode=${appCode}&page=1&from=menu`
// )
// url = "/pages/apply/externalLink/index?url=" + urlPre + "&fullName=" + item.fullName + "&type=" +
// item.type
// }
// // 报表
// if (item.type == 10) {
// if (!item.moduleId) {
// this.$u.toast("暂无此页面");
// return;
// }
// const urlPre = encodeURIComponent(
// `${this.pcURL}/reportPreview?id=${item.moduleId}&token=${this.token}&from=app`
// );
// url = "/pages/apply/externalLink/index?url=" + urlPre + "&fullName=" + item.fullName + "&type=" +
// item.type
// }
// // 门户
// if (item.type == 8) {
// if (!item.moduleId) {
// this.$u.toast("暂无此页面");
// return;
// }
// url = "/pages/portal/scanPortal/index?id=" + item.moduleId + "&portalType=1&fullName=" +
// item.fullName
// }
if (!url) return;
uni.navigateTo({
url,
fail: () => {
this.$u.toast("暂无此页面");
},
});
},
handleProperty(list) {
const loop = (par) => {
par.map(o => {
if (o?.propertyJson) {
let propertyJson = JSON.parse(o.propertyJson);
this.$set(o, "iconBackground", propertyJson.iconBackgroundColor || "");
this.$set(o, "moduleId", propertyJson.moduleId || "");
}
if (o?.children && o?.children?.length) loop(o.children)
})
}
loop(list)
},
JumpFlow(item) {
const config = {
id: "",
flowId: item.id,
opType: "-1",
isFlow: 1
};
uni.navigateTo({
url: "/pages/workFlow/flowBefore/index?config=" +
this.jnpf.base64.encode(JSON.stringify(config))
});
},
//获取审批中心待办条数
getFlowCount() {
getFlowTodoCount().then((res) => {
this.count = res.data.flowTodo || 0;
})
},
getMenuData() {
getMenuData().then((res) => {
const list = res?.data
this.homeData = list
}).catch(() => {
const userStore = useUserStore()
setTimeout(() => {
userStore.resetToken()
setTimeout(() => {
uni.reLaunch({
url: '/pages/login/index'
})
}, 500)
}, 1000)
});
},
// 获取待办信息
getDonePage() {
const params = {
pageNo:1,
pageSize: 3
}
getDonePage(params).then(res=>{
const {code,data} = res
if(code == 0){
this.count = data.total
uni.setTabBarBadge({
index: 1, // 待办任务的tab索引
text: res.data.total.toString() // 角标数字
});
this.todoList = data.list || []
}
})
},
//更多按钮
openPage(path, type) {
if (type === 'approve') {
let workFlowList = this.menuList.filter(o => o.enCode === 'workFlow')
console.log(this.menuList,'menuList---------')
if (!workFlowList[0]?.children?.length) return this.$u.toast('暂无权限')
}
if (!path) return;
uni.navigateTo({
url: path,
});
},
// 跳转待办
openToDoPage() {
uni.setStorageSync('fromNonTabBar', true);
uni.switchTab({
url: '/pages/workFlow/flowTodo/index',
});
},
//添加按钮
addApp(path) {
if (!path) return;
uni.navigateTo({
url: path,
});
},
// 待处理事项跳转详情
goDetail(item) {
const {processInstance} = item
getProcessBusinessInfo(processInstance.id).then(res=>{
if(res.code == 0){
const {dbformId,businessId} = res.data
// this.processBusinessInfo = res.data || {}
const config = {
modelId: dbformId,
id: businessId,
name: processInstance.name,
btnType: 'btn_process',
current: 2
}
uni.navigateTo({
url: '/pages/apply/dynamicModelList/form?config=' +
this.jnpf.base64.encode(JSON.stringify(config))
})
}
})
const config = {
opType: item.opType,
operatorId: item.id,
category: '1',
...item
}
// /pages/apply/dynamicModelList/form
// uni.navigateTo({
// url: '/pages/workFlow/flowBefore/index?config=' +
// this.jnpf.base64.encode(JSON.stringify(config))
// })
}
}
}
</script>
<style lang="scss">
page {
background-color: #f0f2f6;
padding-bottom: 20rpx;
}
.custom-nav-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
height: 44px;
background: #fff;
border-bottom: 1px solid #f0f2f6;
display: flex;
align-items: center;
padding: 0 20rpx;
box-sizing: border-box;
.nav-left {
display: flex;
align-items: center; // 图标和标题垂直居中
}
.nav-icon {
width: 20px;
height: 20px;
margin-right: 8rpx;
}
.nav-title {
font-size: 16px;
font-weight: 500;
color: #303133;
// 标题左对齐flex布局默认左排列
}
.nav-right {
margin-left: auto; // 右侧元素靠右
display: flex;
align-items: center;
position: relative;
}
.nav-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
}
.nav-dot {
position: absolute;
top: -2px;
right: -2px;
color: #f56c6c;
font-size: 12px;
}
}
.index_v {
padding-top: 65rpx;
.head-tabs {
background-color: #fff;
width: 100%;
height: 120rpx;
justify-content: space-between;
padding: 0 20rpx;
.head-tabs-item {
display: flex;
justify-content: center;
font-size: 28rpx;
color: #303133;
flex-shrink: 0;
position: relative;
align-items: center;
height: 120rpx;
.icon-style {
font-size: 42rpx;
color: #666666;
}
.head-tabs-name {
color: #303133;
font-family: PingFang SC;
margin-left: 6rpx;
}
}
}
}
.todo-list-wrap {
background: #fff;
margin: 20rpx 0;
border-radius: 10rpx;
padding: 20rpx;
}
.todo-title {
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
}
.title-left {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
/* 滚动容器样式 */
.todo-scroll-container {
width: 100%;
max-height: 680rpx !important;
::-webkit-scrollbar {
width: 4rpx;
}
::-webkit-scrollbar-thumb {
background-color: #e5e5e5;
border-radius: 2rpx;
}
}
.todo-item {
// display: flex;
align-items: flex-start;
padding: 15rpx 0;
border-bottom: 1px solid #f5f5f5;
/* 最后一项去掉下划线 */
&:last-child {
border-bottom: none;
}
}
.todo-dot {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
margin-right: 15rpx;
margin-top: 8rpx;
}
.todo-content {
flex: 1;
}
.todo-code {
font-size: 26rpx;
color: #666;
margin-right: 10rpx;
}
.todo-name {
font-size: 28rpx;
color: #333;
}
.todo-meta {
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
display: flex;
// justify-content: space-between;
}
.todo-time {
margin-left: 30rpx;
}
.todo-list-wrap {
background: #fff;
margin: 20rpx 0;
border-radius: 10rpx;
padding: 20rpx;
}
.todo-title {
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
}
.title-left {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.title-right {
align-items: center;
font-size: 24rpx;
color: #666;
}
/* 滚动容器 */
.todo-scroll-container {
width: 100%;
max-height: 350rpx;
::-webkit-scrollbar {
width: 4rpx;
}
::-webkit-scrollbar-thumb {
background-color: #e5e5e5;
border-radius: 2rpx;
}
}
/* 每个待办项容器 */
.todo-item {
background: #f9f9f9;
border-radius: 8rpx;
padding: 15rpx;
margin-bottom: 15rpx;
}
/* 单号栏 */
.todo-header {
font-size: 26rpx;
color: #333;
margin-bottom: 10rpx;
font-weight: 500;
}
.todo-header .code-label{
font-size: 22rpx;
color: #1677ff;
background: #e8f3ff;
padding: 2rpx 8rpx;
border-radius: 4rpx;
font-weight: 500;
margin-right: 15rpx;
}
.todo-code {
display: flex;
}
/* 信息列表 */
.todo-info-list {
font-size: 24rpx;
}
/* 每一行信息 */
.todo-info-row {
display: flex;
margin-bottom: 8rpx;
color: #666;
}
.info-label {
width: 120rpx; /* 固定宽度,对齐更整齐 */
color: #999;
}
.info-value {
flex: 1;
color: #333;
}
// 暂无数据样式
.empty-container {
text-align: center;
}
.empty-icon {
width: 260rpx;
height: auto;
margin-bottom: 20rpx;
// opacity: 0.5;
}
.empty-tip {
font-size: 28rpx;
color: #c0c4cc;
}
</style>