Files
jnpf_app/pages/apply/menu/index.vue

341 lines
7.8 KiB
Vue
Raw Permalink Normal View History

2026-01-04 11:09:06 +08:00
<template>
<view class="menu-v">
<view class="search-box u-m-b-20">
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72" :show-action="false"
@change="search" bg-color="#f0f2f6" shape="square" style="width: 100%;">
</u-search>
</view>
<mescroll-body ref="mescrollRef" @down="downCallback" :down="downOption" :sticky="false" @up="upCallback"
:up="upOption" :bottombar="false" @init="mescrollInit" :top="mescrollTop">
<view class="workFlow-list">
<view class="part" v-for="(item, i) in menuList" :key="i">
<view class="caption u-line-1" v-if="item?.children?.length">
{{ item.fullName }}
</view>
<view class="u-flex u-flex-wrap">
<view class="item u-flex-col u-col-center" v-for="(child, ii) in item.children" :key="ii"
@click="handelClick(child)">
<text class="u-font-40 item-icon" :class="child.icon"
:style="{ background: child.iconBackground || '#008cff' }" />
<text class="u-font-24 u-line-1 item-text">{{child.fullName}}</text>
</view>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import {
getMenuList,
getChildList
} from "@/api/apply/apply.js";
import resources from "@/libs/resources.js";
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
import {
useUserStore
} from '@/store/modules/user'
export default {
mixins: [MescrollMixin],
data() {
return {
mescrollTop: 0,
menuList: [],
downOption: {
use: true,
auto: true,
},
upOption: {
page: {
num: 0,
size: 50,
time: null,
},
empty: {
use: true,
icon: resources.message.nodata,
tip: this.$t('common.noData'),
fixed: false,
top: "560rpx",
},
textNoMore: this.$t('app.apply.noMoreData'),
},
keyword: "",
fullName: "",
key: +new Date(),
listChild: [],
};
},
computed: {
token() {
return uni.getStorageSync('token')
},
report() {
return this.define.report;
},
pcURL() {
return this.define.pcURL;
},
},
onShow() {
this.keyword = "";
uni.$on('refresh', () => {
this.menuList = [];
this.$nextTick(() => {
this.mescroll.resetUpScroll();
})
});
},
onUnload() {
uni.$off("updateUsualList");
},
methods: {
handelClick(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("暂无此页面");
},
});
},
upCallback(keyword) {
let query = {
keyword: this.keyword,
};
uni.showLoading({
title: '正在加载',
mask: true
})
getMenuList(query)
.then((res) => {
let list = res.data.list || [];
this.mescroll.endSuccess(list.length);
this.list = list.filter(o => o.children && o.children.length)
this.menuList = this.list;
this.handleProperty(this.list)
uni.hideLoading()
this.key = +new Date();
this.mescroll.endSuccess(this.menuList.length, false);
}).catch(() => {
this.mescroll.endSuccess(0);
this.mescroll.endErr();
});
},
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)
},
search() {
this.searchTimer && clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.list = [];
this.menuList = [];
this.mescroll.resetUpScroll();
}, 300);
}
},
};
</script>
<style lang="scss">
page {
background-color: #f0f2f6;
}
.menu-v {
.search-box {
height: 120rpx;
padding: 0rpx 20rpx;
display: flex;
align-items: center;
background-color: #fff;
}
.common-block {
background-color: #fff;
margin: 20rpx 0;
.caption {
padding: 0 32rpx;
line-height: 100rpx;
justify-content: space-between;
.caption-left {
font-size: 36rpx;
font-weight: bold;
}
.caption-right {}
}
.item {
margin-bottom: 32rpx;
width: 25%;
.item-icon {
width: 88rpx;
height: 88rpx;
margin-bottom: 8rpx;
line-height: 82rpx;
text-align: center;
border-radius: 30rpx;
color: #fff;
font-size: 40rpx;
&.more {
background: #ececec;
color: #666666;
font-size: 50rpx;
}
}
.item-text {
width: 100%;
text-align: center;
padding: 0 16rpx;
}
}
}
.select-box {
max-height: 600rpx;
:deep(.u-drawer-content) {
height: 100% !important;
}
}
.popupItem {
height: 400rpx;
overflow-y: scroll;
/* #ifdef APP-HARMONY || MP */
padding-top: 40rpx;
/* #endif */
}
.item {
.currentItem {
color: #2979ff;
}
.select-item {
height: 100rpx;
display: flex;
align-items: center;
padding: 0 20rpx;
font-size: 30rpx;
color: #303133;
text-align: left;
position: relative;
&::after {
content: " ";
position: absolute;
left: 2%;
top: 0;
box-sizing: border-box;
width: 96%;
height: 1px;
transform: scale(1, 0.3);
border: 0 solid #e4e7ed;
z-index: 2;
border-bottom-width: 1px;
}
.sysName {
flex: 1;
overflow: auto;
min-width: 0;
}
}
}
}
</style>