Compare commits

...

23 Commits

Author SHA1 Message Date
48c25b9d71 拿掉测试提示 2026-01-29 19:30:41 +08:00
chenli
3a92479126 feat; 优化加载数据 2026-01-29 16:39:59 +08:00
chenli
a4cd5c3f14 feat: 优化申请单位 2026-01-29 16:27:15 +08:00
chenli
87ce9403e5 feat: 修改时间问题 2026-01-29 15:32:10 +08:00
chenli
949e49ab1b feat: 修改提交时间传值问题 2026-01-29 14:28:28 +08:00
chenli
ebb46dc1b3 feat: 优化跳转地址栏带参数 2026-01-29 11:53:50 +08:00
chenli
112a036dd5 feat: 修改图片显示问题 2026-01-29 11:43:02 +08:00
chenli
82ea0103b6 feat: 优化流程详情审批记录显示效果 2026-01-28 17:32:24 +08:00
chenli
b38961ac53 feat: 登录添加弹框显示地址 2026-01-28 15:56:11 +08:00
chenli
33ae09849c feat: 打印 2026-01-28 10:33:09 +08:00
caijun
16cf3fc750 feat: 修改点击登录逻辑 2026-01-28 10:25:53 +08:00
ae5e5dc08a 修改认证参数为110 2026-01-27 18:51:44 +08:00
caijun
ed2be2a938 feat: 优化代码 2026-01-27 15:42:20 +08:00
caijun
22d656889a feat: 修改已知问题 2026-01-27 09:00:58 +08:00
caijun
46c351151b feat: 端点登录 2026-01-26 10:44:20 +08:00
caijun
f43f2ff3c2 feat: 端点登录 2026-01-25 20:22:58 +08:00
caijun
f9e1a0cc18 feat: 更改环境 2026-01-23 15:16:31 +08:00
caijun
5b3c7512a2 feat: 解决问题 2026-01-23 11:12:57 +08:00
caijun
686bf339ae feat: 蓝星登录 2026-01-23 11:09:28 +08:00
caijun
2195b230ed feat: 优化页面显示 2026-01-22 11:23:09 +08:00
caijun
8e66789811 feat: 新增需求 2026-01-22 11:01:19 +08:00
caijun
4243e1213f feat: 新增需求 2026-01-20 18:07:35 +08:00
caijun
9f5b2a92c4 feat: 新增需求 2026-01-19 17:34:15 +08:00
99 changed files with 11424 additions and 1613 deletions

View File

@@ -47,7 +47,7 @@
const token = uni.getStorageSync("token"); const token = uni.getStorageSync("token");
if (!token) return if (!token) return
chat.initSocket() // chat.initSocket()
const userStore = useUserStore() const userStore = useUserStore()
userStore.getCurrentUser().then(res => { userStore.getCurrentUser().then(res => {
const { const {

View File

@@ -1,4 +1,57 @@
import request from '@/utils/request' import request from '@/utils/request'
export function getDesForm(modelId,data) {
return request({
url: `/admin-api/MobileMenu/desform/${modelId}`,
method: 'POST',
data,
options: {
load: false
}
})
}
// 获取表单id
export function getProcessBusinessInfo(id) {
return request({
url: `/admin-api/MobileProcess/getProcessBusinessInfo?processInstanceId=${id}`,
method: 'GET'
})
}
// 获取流程表单
export function getdbformlist(dbFormId) {
return request({
url: `/admin-api/bpm/process-definition/dbformlist?dbFormId=${dbFormId}`,
method: 'GET'
})
}
// 获取审批节点
export function getAssignList(id) {
return request({
url: `/admin-api/bpm/task-assign-rule/list?processDefinitionId=${id}`,
method: 'GET'
})
}
// 发起流程
export function getListCreate(data,id) {
return request({
url: `/admin-api/MobileMenu/addMobileProcessLog/${id}`,
method: 'POST',
data,
options: {
load: false
}
})
}
// 获取审批记录数据
export function getByProcess(id) {
return request({
url: `/admin-api/bpm/task/list-by-process-instance-id?processInstanceId=${id}`,
method: 'GET'
})
}
// 获取列表表单配置JSON // 获取列表表单配置JSON
export function getConfigData(modelId, menuId) { export function getConfigData(modelId, menuId) {
return request({ return request({
@@ -25,10 +78,33 @@ export function getModelList(modelId, data, options) {
} }
}) })
} }
// 获取数据列表
export function getModelDataList(id, data, options) {
return request({
url: `/admin-api/MobileMenu/list/${id}`,
method: 'POST',
data,
options: {
load: false
}
})
}
// 获取申请单位下拉选项
export function getDbfromList(id, data={}, options) {
return request({
url: `/admin-api/jeelowcode/dbform-data/list/${id}`,
method: 'POST',
data,
options: {
load: false
}
})
}
// 添加数据 // 添加数据
export function createModel(modelId, data) { export function createModel(modelId, data) {
return request({ return request({
url: `/api/visualdev/OnlineDev/${modelId}?menuId=${data.menuId}`, url: `/admin-api/MobileMenu/addMobileOperateLog/${modelId}`,
method: 'POST', method: 'POST',
data data
}) })
@@ -42,10 +118,10 @@ export function updateModel(modelId, data) {
}) })
} }
// 获取数据信息 // 获取数据信息
export function getModelInfo(modelId, id, menuId) { export function getModelInfo(modelId, id) {
return request({ return request({
url: `/api/visualdev/OnlineDev/${modelId}/${id}?menuId=${menuId}`, url: `/admin-api/jeelowcode/dbform-data/detail/${modelId}/${id}`,
method: 'GET' method: 'POST'
}) })
} }
// 删除数据 // 删除数据

View File

@@ -72,13 +72,41 @@ export function getOrganizeSelector(data) {
parentId: '0' parentId: '0'
}; };
return request({ return request({
url: '/api/permission/Organize/Selector', url: '/admin-api/jeelowcode/adapter/dept/list',
options: { options: {
load: false load: false
}, },
data data
}) })
} }
// 获取人员选项
export function getAdapterUserList(data, options) {
return request({
url: `/admin-api/jeelowcode/adapter/user/list`,
method: 'POST',
data,
options: {
load: true
}
})
}
// 社交授权的跳转
export function socialAuthRedirect(type, redirectUri) {
return request({
url: '/admin-api/system/auth/social-auth-redirect?type=' + type + '&redirectUri=' + redirectUri,
method: 'GET'
})
}
// 获取人员角色
export function getAdapterRoleList() {
return request({
url: '/admin-api/jeelowcode/adapter/role/list',
method: 'GET'
})
}
// 获取组织和岗位下拉框列表 // 获取组织和岗位下拉框列表
export function getOrgAndPosSelector(data) { export function getOrgAndPosSelector(data) {
if (!data) data = { if (!data) data = {
@@ -203,11 +231,35 @@ export function getDataInterfaceRes(id, data) {
// 用户登录 // 用户登录
export function login(data) { export function login(data) {
return request({ return request({
url: '/api/oauth/Login', url: '/admin-api/system/auth/login',
method: 'post', method: 'post',
data, data,
header: { header: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/json',
}
})
}
// 获取用户角色
export function getPermissionInfo() {
return request({
url: '/admin-api/system/auth/get-permission-info',
method: 'GET'
})
}
// 获取token
export function socialLogin(type, code, state) {
console.log(type,code,state,'data数据---')
return request({
url: '/admin-api/system/auth/social-login',
method: 'post',
data: {
type,
code,
state
},
header: {
'Content-Type': 'application/json',
} }
}) })
} }
@@ -349,6 +401,16 @@ export function getConfig(account) {
} }
}) })
} }
// 获取配置信息
export function getByName(name) {
return request({
url: `/admin-api/system/tenant/get-id-by-name?name=${name}`,
method: 'get',
options: {
load: false
}
})
}
// 获取行政区划下拉框数据 // 获取行政区划下拉框数据
export function getProvinceSelector(id) { export function getProvinceSelector(id) {
return request({ return request({
@@ -390,6 +452,21 @@ export function getUserPositions(data) {
data data
}) })
} }
// 获取个人资料
export function getUserProfile() {
return request({
url: '/admin-api/system/user/profile/get',
method: 'GET'
})
}
// 退出登录
export function getLogout() {
return request({
url: '/admin-api/system/auth/logout',
method: 'POST'
})
}
// 获取当前用户个人资料 // 获取当前用户个人资料
export function UserSettingInfo() { export function UserSettingInfo() {
return request({ return request({
@@ -405,6 +482,15 @@ export function UpdateUser(data) {
data data
}) })
} }
// 更新当前用户个人资料
export function profileUpdate(data) {
return request({
url: '/admin-api/system/user/profile/update',
method: 'PUT',
data
})
}
// 更新当前用户头像 // 更新当前用户头像
export function UpdateAvatar(name) { export function UpdateAvatar(name) {
return request({ return request({

View File

@@ -8,3 +8,24 @@ export function getHomeData(id) {
} }
}) })
} }
export function getMenuData(id) {
return request({
url: `/admin-api/MobileMenu/getMenu`,
method: 'get',
options: {
load: true
}
})
}
export function getDonePage(data) {
return request({
url: `/admin-api/bpm/task/todo-page`,
method: 'get',
data,
options: {
load: true
}
})
}

View File

@@ -30,6 +30,54 @@ export function getOperatorList(data) {
}) })
} }
// 获取我的流程
export function getMyPage(data) {
return request({
url: `/admin-api/bpm/process-instance/my-page`,
method: 'get',
data,
options: {
load: false
}
})
}
// 获取待办流程
export function getTodoPage(data) {
return request({
url: `/admin-api/bpm/task/todo-page`,
method: 'get',
data,
options: {
load: false
}
})
}
// 获取已办流程
export function getDonePage(data) {
return request({
url: `/admin-api/bpm/task/done-page`,
method: 'get',
data,
options: {
load: false
}
})
}
// 获取抄送流程
export function getCcMyPage(data) {
return request({
url: `/admin-api/bpm/process-instance/cc/my-page`,
method: 'get',
data,
options: {
load: false
}
})
}
// 获取流程发起列表 // 获取流程发起列表

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

View File

@@ -0,0 +1,216 @@
<template>
<view class="card">
<view class="card-content">
<view class="card-tabs u-flex">
<view class="u-flex card-left">
<view class="card-title">{{title}}</view>
</view>
<view @click="openPage" class="morebtn">更多<u-icon name="arrow-right" class="u-p-r-10"
color="#666"></u-icon></view>
</view>
<view class="card-item">
<!-- 遍历渲染业务图标 -->
<view class="item u-flex-col" v-for="(item,index) in cardData" :key="index" @click="clickItem(item)">
<view class="item-icon" :style="{ background: item.iconBackground || '#008cff' }">
<image class="item-img" :src="`/static/image/${item.name}.png`"></image>
<!-- 使用 iconify-icon 渲染 ep 系列图标 -->
<!-- <iconify-icon
:icon="item.icon"
color="#ffffff"
width="24"
height="24"
></iconify-icon> -->
</view>
<view class="item-title u-m-t-8">{{item.name}}</view>
</view>
<view v-if="showAdd" class="item u-flex-col u-col-center" @click="add">
<text class="u-font-40 item-icon more">+</text>
<text class="u-m-t-8 item-title">添加</text>
</view>
</view>
<JnpfEmpty v-if="!cardData.length && type != 'collect' "></JnpfEmpty>
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: "我的收藏"
},
menuList: {
type: Array,
default: () => []
},
flowList: {
type: Array,
default: () => []
},
showAdd: {
type: Boolean,
default: false
},
type: {
type: String,
default: "collect"
},
flowEnabled: {
type: Boolean,
default: false
}
},
data() {
return {
tabList: [{
name: '应用功能',
type: 'menu'
}],
current: 0,
cardData: [],
userInfo: {}
}
},
computed: {
tabType() {
return this.tabList[this.current].type
}
},
watch: {
menuList: {
handler(val) {
if (this.current != 0) this.cardData = this.flowList
},
immediate: true
},
flowList: {
handler(val) {
if (this.current == 0) this.cardData = this.menuList
},
immediate: true
}
},
created() {
this.userInfo = uni.getStorageSync('userInfo') || {}
this.handleTabList()
},
methods: {
handleTabList() {
if (this.flowEnabled) {
this.tabList.push({
name: '发起审批',
type: 'flow'
})
}
},
tabChange(index) {
this.current = index;
if (this.tabType === 'menu') this.cardData = this.menuList
if (this.tabType === 'flow') this.cardData = this.flowList
},
clickItem(item) {
this.$emit('launch', {
...item,
tabType: this.tabType
})
},
openPage() {
this.$emit('openPage', '/pages/apply/menu/index')
},
add() {
let url = this.tabType === 'menu' ? '/pages/apply/allAppApply/index' :
'/pages/workFlow/allAppWorkFlow/index'
this.$emit('addApp', url)
}
}
}
</script>
<style lang="scss">
.card {
margin-top: 20rpx;
&-title {
padding: 0 20rpx;
color: #303133;
font-size: 36rpx;
margin-bottom: 10rpx;
font-weight: 500;
}
&-content {
width: 100%;
height: 100%;
background-color: #fff;
padding-top: 15rpx;
.card-tabs {
width: 100%;
justify-content: space-between;
.card-left {}
.morebtn {
color: #666;
}
}
.card-item {
width: 100%;
display: flex;
flex-wrap: wrap;
flex-direction: row;
.item {
width: 33.33%;
padding: 10px;
justify-content: center;
align-items: center;
padding: 30rpx 0;
.item-icon {
width: 50px;
height: 50px;
/* 关键:改为 flex 布局,让图标居中 */
display: flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: 18px;
font-size: 24px;
background-color: #f0f2f6;
/* 移除原有伪类样式,避免干扰 */
&:before {
margin: 0;
}
}
.item-img {
width: 60%;
height: 60%;
}
.more {
background: #ececec;
color: #666;
font-size: 1.5625rem;
/* 保持添加按钮的居中 */
display: flex;
align-items: center;
justify-content: center;
}
.item-title {
width: 92px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
font-size: 24rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,500 @@
<template>
<u-popup class="jnpf-tree-select-popup" mode="right" v-model="showPopup" width="100%" @close="close">
<view class="jnpf-tree-select-body">
<view class="jnpf-tree-select-title">
<text class="icon-ym icon-ym-report-icon-preview-pagePre backIcon" @tap="close()"></text>
<view class="title">选择用户</view>
</view>
<view class="jnpf-tree-select-search">
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72"
:show-action="false" @change="handleSearch" bg-color="#f0f2f6" shape="square">
</u-search>
</view>
<view class="jnpf-tree-selected">
<view class="jnpf-tree-selected-head">
<view>{{$t('component.jnpf.common.selected')}}({{selectedList.length||0}})</view>
<view v-if="multiple" class="clear-btn" @click="setCheckAll">
{{$t('component.jnpf.common.clearAll')}}
</view>
</view>
<view class="jnpf-tree-selected-box">
<scroll-view scroll-y="true" class="select-list">
<u-tag closeable @close="delSelect(index)" v-for="(item,index) in selectedList" :key="index"
:text="item.nickName" class="u-selectTag" />
</scroll-view>
</view>
</view>
<view class="jnpf-tree-selected-line"></view>
<view class="jnpf-tree-selected-tabs">
<view class="tab-item" :class="{'tab-item-active':activeKey==='user'}" @click="toggloActive('user')">
用户
</view>
<block v-if="selectType === 'all'">
<!-- <view class="tab-item" :class="{'tab-item-active':activeKey==='position'}"
@click="toggloActive('position')">
组织岗位
</view> -->
<view class="tab-item" :class="{'tab-item-active':activeKey==='role'}"
@click="toggloActive('role')">
角色
</view>
<!-- <view class="tab-item" :class="{'tab-item-active':activeKey==='current'}"
@click="toggloActive('current')">
当前用户
</view> -->
</block>
</view>
<view class="jnpf-tree-selected-breadcrumb" v-if="selectType === 'all' && activeKey!=='current'">
<view class="breadcrumb-item" :class="{'breadcrumb-item-active':!currStep}" @click="handleToFirst()"
v-if="activeKey==='user'">
用户组
</view>
<view class="breadcrumb-item" :class="{'breadcrumb-item-active':!currStep}" @click="handleToFirst()"
v-if="activeKey==='position'">
组织岗位
</view>
<view class="breadcrumb-item" :class="{'breadcrumb-item-active':!currStep}" @click="handleToFirst()"
v-if="activeKey==='role'">
角色
</view>
<view class="icon-ym icon-ym-caret-right breadcrumb-item" v-if="currStep"></view>
<view class="breadcrumb-item" :class="{'breadcrumb-item-active':currStep}" v-if="currStep">
用户列表
</view>
</view>
<view class="jnpf-tree-select-tree">
<scroll-view :scroll-y="true" style="height: 100%" :scroll-top="scrollTop" @scroll="handleScroll"
v-show="(!hasPage && !currStep) && selectType === 'all' && activeKey!=='current'">
<ly-tree v-show="activeKey == 'user'" ref="tree" :props="realProps" :node-key="realProps.value"
:load="loadNode" lazy :tree-data="lazyOptions" show-node-icon :defaultExpandAll='false'
@node-click="handleTreeNodeClick" :show-checkbox="multiple" :show-radio="!multiple"
:expandOnClickNode="false" :checkOnClickNode="true" :expandOnCheckNode="false" checkStrictly />
<block v-if="activeKey == 'role'">
<view class="jnpf-selcet-list" v-if="list.length">
<view class="jnpf-selcet-cell" v-for="item in list" :key="item.id"
@click.stop="handleNodeClick(item)">
<view class="jnpf-selcet-cell-icon" :class='item.icon'></view>
<view class="jnpf-selcet-cell-name">
{{item.deptName}}
</view>
</view>
</view>
<Empty class="h-full" v-else />
</block>
</scroll-view>
<scroll-view :scroll-y="true" style="height: 100%" :refresher-enabled="false" :refresher-threshold="100"
:scroll-with-animation='true' :refresher-triggered="triggered" @scrolltolower="handleScrollToLower"
v-if="hasPage||currStep||activeKey==='current'">
<view class="jnpf-selcet-list" v-if="userList.length">
<view class="jnpf-selcet-cell" v-for="item in userList" :key="item.userId"
@click.stop="handleUserNodeClick(item)">
<view class="jnpf-selcet-cell-action">
<lyCheckbox :type="multiple ? 'checkbox' : 'radio'"
:checked="selectedIds.includes(item.userId)" />
</view>
<u-avatar class="jnpf-selcet-cell-avatar" :src="baseURL+item.headIcon" mode="circle"
size="44"></u-avatar>
<view class="jnpf-selcet-cell-name">
{{item.nickName}}
</view>
</view>
</view>
<Empty class="h-full" v-else />
</scroll-view>
</view>
<!-- 底部按钮 -->
<view class="jnpf-tree-select-actions">
<u-button class="buttom-btn" @click="close()">{{$t('common.cancelText')}}</u-button>
<u-button class="buttom-btn" type="primary"
@click.stop="handleConfirm()">{{$t('common.okText')}}</u-button>
</view>
</view>
</u-popup>
</template>
<script>
import {
getOrgAndPosSelector,
getUserList,
getSelectedUserList,
getOrganizeSelector,
getAdapterUserList,
getAdapterRoleList
} from '@/api/common'
import lyCheckbox from '@/components/ly-tree/components/ly-checkbox.vue';
import {
useBaseStore
} from '@/store/modules/base'
import Empty from '../Empty/index.vue'
const baseStore = useBaseStore()
const defaultProps = {
label: 'deptName',
value: 'deptId',
icon: 'icon',
children: 'children'
}
const defaultUserQuery = {
enabledMark: 1,
groupId: '',
organizeId: '',
positionId: '',
roleId: '',
};
export default {
props: {
selectedData: {
type: Array,
default: () => []
},
ableIds: {
type: Array,
default: () => []
},
selectType: {
type: String,
default: 'all'
},
// 通过双向绑定控制组件的弹出与收起
modelValue: {
type: Boolean,
default: false
},
// 弹出的z-index值
zIndex: {
type: [String, Number],
default: 0
},
props: {
type: Object,
default: () => ({
label: 'deptName',
value: 'deptId',
icon: 'icon',
children: 'children',
isLeaf: 'isLeaf'
})
},
multiple: {
type: Boolean,
default: false
}
},
components: {
lyCheckbox,
Empty
},
data() {
return {
moving: false,
selectedList: [],
selectedIds: [],
keyword: '',
showPopup: false,
lazyOptions: [{}],
activeKey: 'user',
hasPage: false,
pagination: {
hasPage: 1,
currentPage: 1,
pageSize: 20
},
triggered: false,
finish: false,
list: [],
userList: [],
scrollTop: 0,
currStep: 0,
userQuery: {},
};
},
watch: {
// 在select弹起的时候重新初始化所有数据
modelValue: {
handler(val) {
this.showPopup = val
if (val) setTimeout(() => this.init(), 10);
},
immediate: true
},
selectedList: {
handler(val) {
this.selectedIds = val.map((o) => o.userId);
this.$refs.tree && this.$refs.tree.setCheckedKeys(this.selectedIds)
},
deep: true
},
},
computed: {
baseURL() {
return this.define.baseURL
},
uZIndex() {
// 如果用户有传递z-index值优先使用
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
},
realProps() {
return {
...defaultProps,
...this.props
}
},
getCurrList() {
const userInfo = uni.getStorageSync('userInfo') || {}
const current = {
fullName: `${userInfo.userName}/${userInfo.userAccount}`,
headIcon: userInfo.headIcon,
id: userInfo.userId,
realName: userInfo.userName,
};
return [current];
}
},
methods: {
init() {
this.keyword = ""
this.hasPage = 0
this.currStep = 0
this.activeKey = 'user'
this.resetQuery()
this.$nextTick(() => {
this.triggered = true
})
this.getGroupList()
// this.selectedList = JSON.parse(JSON.stringify(this.selectedData))
// if (this.selectType === 'all') {
// this.getGroupList()
// } else {
// this.hasPage = 1
// this.getConditionOptions()
// }
},
handleToFirst() {
if (!this.currStep) return
this.currStep = 0
this.hasPage = false
this.keyword = ''
this.resetQuery()
},
resetQuery() {
this.userList = []
this.finish = false
this.pagination.currentPage = 1
},
getConditionOptions() {
if (!this.ableIds.length) return
const query = {
nickName: this.keyword,
ids: this.ableIds,
...this.pagination
}
getSelectedUserList(query).then(res => {
const list = res.data.list || []
if (list.length < this.pagination.pageSize) this.finish = true;
this.userList = this.userList.concat(list);
this.pagination.currentPage++
})
},
loadNode(node, resolve) {
const parentId = node.key || '0'
const level = node.level || 0
// 如果是根节点level为0直接使用已经构建好的options
// if (level === 0 && this.options.length > 0) {
// resolve(this.options)
// return
// }
getOrganizeSelector(this.selectType).then(res => {
const list = res.data || []
// 将返回的扁平数据转换为树形节点
const treeData = this.buildTree(list, 'deptId', 'deptPid', parentId)
console.log(treeData,'-treeData')
// 设置节点的isLeaf属性根据是否有子节点判断
treeData.forEach(item => {
// 判断该节点是否还有子节点(根据实际情况调整)
// 如果知道接口返回是否有子节点的字段,可以替换这个判断
item.isLeaf = !item.children || item.children.length === 0
})
console.log(`加载父节点 ${parentId} 的子节点:`, treeData)
resolve(treeData)
}).catch(() => {
resolve([]) // 异常时返回空数组,避免组件报错
})
},
handleScroll(e) {
this.scrollTop = e.detail.scrollTop
},
goTop() {
this.scrollTop = 0
},
handleScrollToLower() {
if (this.finish || this.activeKey === 'current') return
this.getUserData()
},
getUserData() {
this.selectType == 'all' ? this.getUserList() : this.getConditionOptions()
},
getUserList() {
let data = {
nickName: this.keyword,
// ...this.pagination,
...this.userQuery
}
getAdapterUserList(data).then(res => {
const list = res.data.records || []
if (list.length < this.pagination.pageSize) this.finish = true;
this.userList = this.userList.concat(list);
this.pagination.currentPage++
})
},
handleTreeNodeClick(item) {
const data = item.data
this.handleNodeClick(data)
},
handleNodeClick(data) {
const key = this.activeKey == 'user' ? 'deptId' : 'roleId'
this.hasPage = 1
this.userQuery = {
[key]: data[key],
fieldList: ["userId","nickName","sex","post","deptName"],
pageNo: this.hasPage,
pageSize: 10
};
this.currStep = 1
this.keyword = ''
this.resetQuery()
this.getUserList()
},
handleUserNodeClick(data) {
const index = this.selectedList.findIndex((o) => o.userId === data.userId);
if (index !== -1) return this.selectedList.splice(index, 1);
this.multiple ? this.selectedList.push(data) : (this.selectedList = [data]);
},
delSelect(index) {
this.selectedList.splice(index, 1);
},
setCheckAll() {
this.selectedIds = []
this.selectedList = []
},
handleConfirm() {
this.$emit('confirm', this.selectedList, this.selectedIds);
this.close();
},
close() {
this.$emit('close', false);
},
toggloActive(key) {
if (this.activeKey === key) return
this.currStep = 0
this.hasPage = false
this.keyword = ''
this.resetQuery()
this.$nextTick(async () => {
this.activeKey = key
this.goTop()
if (this.activeKey === 'user') return this.getGroupList()
if (this.activeKey === 'role') return this.getRoleList()
if (this.activeKey === 'current') this.userList = this.getCurrList
})
},
async getGroupList() {
const res = await getOrganizeSelector(this.selectType)
const list = res.data || []
const treeData = this.buildTree(list, 'deptId', 'deptPid', '0')
treeData.forEach(item => {
item.isLeaf = !item.children || item.children.length === 0
})
// this.list = treeData
this.lazyOptions = treeData
console.log(this.list,'list---')
// const list = this.formatDeptData(res.data) || []
// this.list = [{
// deptName: '全部用户',
// icon: 'icon-ym icon-ym-generator-group1',
// id: ''
// }, ...list]
},
async getRoleList() {
const res = await getAdapterRoleList()
const list = this.formatDeptData(res.data) || []
this.list = list
},
buildTree(data, idKey, pidKey, rootPid) {
const result = []
const map = {}
// 先构建ID映射
data.forEach(item => {
map[item[idKey]] = { ...item, children: [] }
})
// 组装父子关系
data.forEach(item => {
const parent = map[item[pidKey]]
if (item[pidKey] === rootPid) {
result.push(map[item[idKey]])
} else if (parent) {
parent.children.push(map[item[idKey]])
}
})
return result
},
formatDeptData(data) {
const result = [];
const formatItem = (item) => {
// 优先使用 deptId 字段(根据打印结果)
let deptId = item.deptId || item.roleId;
let deptName = item.deptName || item.roleName;
// 确保ID是字符串
deptId = String(deptId || '');
return {
...item,
deptId: deptId,
deptName: deptName ,
depthd: item.depthd,
depthName: item.depthName,
id: item.id
};
};
// 遍历数据
if (Array.isArray(data)) {
data.forEach(item => {
const formatted = formatItem(item);
if (formatted.deptId) {
result.push(formatted);
}
// 如果有子部门,递归处理
if (item.children && Array.isArray(item.children)) {
const children = this.formatDeptData(item.children);
result.push(...children);
}
});
}
return result;
},
handleSearch(val) {
this.keyword = val
this.hasPage = this.selectType !== 'all' || !!val
this.currStep = val ? 1 : 0
this.goTop()
if (this.activeKey != 'user') this.activeKey = 'user'
this.$nextTick(() => {
if (this.keyword || this.selectType !== 'all') {
this.userQuery = {
...defaultUserQuery
};
this.getGroupList()
this.resetQuery()
this.$u.debounce(this.getUserData, 300)
}
})
},
}
};
</script>

View File

@@ -0,0 +1,116 @@
<template>
<view class="jnpf-user-select w-full">
<selectBox v-model="innerValue" :placeholder="placeholder" @openSelect="openSelect"
:select-open="selectShow" :disabled="disabled" v-if="isInput" />
<SelectPopup v-model="selectShow" :multiple="multiple" :selectedData="selectedData" @close="handleClose"
@confirm="handleConfirm" :selectType="selectType" :ableIds="realAbleIds" />
</view>
</template>
<script>
import SelectPopup from './SelectPopup';
import selectBox from '@/components/selectBox'
import {
getUserInfoList
} from '@/api/common'
export default {
name: 'jnpf-user-select',
components: {
SelectPopup,
selectBox
},
props: {
modelValue: {
default: ''
},
isInput: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
selectType: {
type: String,
default: 'all'
},
ableIds: {
type: Array,
default: () => []
},
ableRelationIds: {
type: [Array, String],
default: () => []
},
},
data() {
return {
selectShow: false,
innerValue: '',
selectedData: [],
realAbleIds: []
}
},
watch: {
// modelValue: {
// handler() {
// this.setDefault()
// },
// immediate: true
// },
},
methods: {
// setDefault() {
// if (!this.modelValue || !this.modelValue.length) return this.setNullValue();
// const ids = this.multiple ? this.modelValue : [this.modelValue];
// getUserInfoList(ids).then((res) => {
// if (!this.modelValue || !this.modelValue.length) return this.setNullValue();
// const selectedData = res.data.list || []
// this.selectedData = selectedData
// this.innerValue = this.selectedData.map(o => o.fullName).join();
// });
// },
setNullValue() {
this.innerValue = '';
this.selectedData = [];
},
openSelect() {
if (this.disabled) return
if (this.selectType === 'custom') {
this.realAbleIds = this.ableIds
} else if (this.selectType != 'all') {
const suffix = '--' + this.selectType;
let ableIds = !this.ableRelationIds ? [] : Array.isArray(this.ableRelationIds) ? this
.ableRelationIds : [this.ableRelationIds];
this.realAbleIds = ableIds.map(o => o + suffix)
} else {
this.realAbleIds = []
}
this.selectShow = true
},
handleConfirm(selectedData, selectedIds) {
this.selectedData = selectedData;
this.innerValue = selectedData.map(o => o.nickName).join();
if (!this.multiple) {
this.$emit('update:modelValue', selectedIds[0])
this.$emit('change', selectedIds[0], selectedData[0])
} else {
this.$emit('update:modelValue', selectedIds)
this.$emit('change', selectedIds, selectedData)
}
},
handleClose() {
this.selectShow = false
}
}
}
</script>

View File

@@ -3,7 +3,7 @@
<view class="jnpf-tree-select-body"> <view class="jnpf-tree-select-body">
<view class="jnpf-tree-select-title"> <view class="jnpf-tree-select-title">
<text class="icon-ym icon-ym-report-icon-preview-pagePre backIcon" @tap="close()"></text> <text class="icon-ym icon-ym-report-icon-preview-pagePre backIcon" @tap="close()"></text>
<view class="title">组织选择</view> <view class="title">选择申请人单位</view>
</view> </view>
<view class="jnpf-tree-select-search"> <view class="jnpf-tree-select-search">
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72" <u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72"
@@ -20,20 +20,20 @@
<view class="jnpf-tree-selected-box"> <view class="jnpf-tree-selected-box">
<scroll-view scroll-y="true" class="select-list"> <scroll-view scroll-y="true" class="select-list">
<u-tag closeable @close="delSelect(index)" v-for="(item,index) in selectedList" :key="index" <u-tag closeable @close="delSelect(index)" v-for="(item,index) in selectedList" :key="index"
:text="item.orgNameTree" class="u-selectTag" /> :text="item.deptName" class="u-selectTag" />
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
<view class="jnpf-tree-selected-line"></view> <view class="jnpf-tree-selected-line"></view>
<view class="jnpf-tree-selected-tabs"> <!-- <view class="jnpf-tree-selected-tabs">
<view class="tab-item" :class="{'tab-item-active':activeKey==='1'}" @click="toggloActive('1')">组织构架 <view class="tab-item" :class="{'tab-item-active':activeKey==='1'}" @click="toggloActive('1')">组织构架</view>
</view>
<view class="tab-item" :class="{'tab-item-active':activeKey==='2'}" @click="toggloActive('2')" <view class="tab-item" :class="{'tab-item-active':activeKey==='2'}" @click="toggloActive('2')"
v-if="selectType === 'all'"> v-if="selectType === 'all'">
当前组织 当前组织
</view> </view>
</view> </view> -->
<view class="jnpf-tree-select-tree"> <view class="jnpf-tree-select-tree">
<!-- 树形结构区域 -->
<scroll-view :scroll-y="true" style="height: 100%" v-if="activeKey==='1' && !hasPage"> <scroll-view :scroll-y="true" style="height: 100%" v-if="activeKey==='1' && !hasPage">
<ly-tree v-if="selectType !== 'all'" :tree-data="options" :node-key="realProps.value" <ly-tree v-if="selectType !== 'all'" :tree-data="options" :node-key="realProps.value"
default-expand-all :props="realProps" :filter-node-method="filterNode" default-expand-all :props="realProps" :filter-node-method="filterNode"
@@ -46,18 +46,19 @@
@node-click="handleTreeNodeClick" :show-checkbox="multiple" :show-radio="!multiple" @node-click="handleTreeNodeClick" :show-checkbox="multiple" :show-radio="!multiple"
:expandOnClickNode="false" :checkOnClickNode="true" :expandOnCheckNode="false" checkStrictly /> :expandOnClickNode="false" :checkOnClickNode="true" :expandOnCheckNode="false" checkStrictly />
</scroll-view> </scroll-view>
<!-- 列表/搜索结果区域 -->
<scroll-view :scroll-y="true" style="height: 100%" :refresher-enabled="false" :refresher-threshold="100" <scroll-view :scroll-y="true" style="height: 100%" :refresher-enabled="false" :refresher-threshold="100"
:scroll-with-animation='true' :refresher-triggered="triggered" @scrolltolower="handleScrollToLower" :scroll-with-animation='true' :refresher-triggered="triggered" @scrolltolower="handleScrollToLower"
v-if="activeKey==='2'|| (activeKey==='1' && hasPage)"> v-if="activeKey==='2'|| (activeKey==='1' && hasPage)">
<view class="jnpf-selcet-list" v-if="list.length"> <view class="jnpf-selcet-list" v-if="list.length">
<view class="jnpf-selcet-cell" v-for="item in list" :key="item.id" <view class="jnpf-selcet-cell" v-for="item in list" :key="item.deptId"
@click.stop="handleNodeClick(item)"> @click.stop="handleNodeClick(item)">
<view class="jnpf-selcet-cell-action"> <view class="jnpf-selcet-cell-action">
<lyCheckbox :type="multiple ? 'checkbox' : 'radio'" <lyCheckbox :type="multiple ? 'checkbox' : 'radio'"
:checked="selectedIds.includes(item.id)" /> :checked="selectedIds.includes(item.deptId)" />
</view> </view>
<view class="jnpf-selcet-cell-name"> <view class="jnpf-selcet-cell-name">
{{item.orgNameTree}} {{item.deptName}}
</view> </view>
</view> </view>
</view> </view>
@@ -73,6 +74,7 @@
</view> </view>
</u-popup> </u-popup>
</template> </template>
<script> <script>
import { import {
getOrgByOrganizeCondition, getOrgByOrganizeCondition,
@@ -81,12 +83,15 @@
import lyCheckbox from '@/components/ly-tree/components/ly-checkbox.vue'; import lyCheckbox from '@/components/ly-tree/components/ly-checkbox.vue';
import Empty from '../Empty/index.vue' import Empty from '../Empty/index.vue'
// 适配接口返回的字段
const defaultProps = { const defaultProps = {
label: 'fullName', label: 'deptName', // 对应接口的deptName
value: 'id', value: 'deptId', // 对应接口的deptId
icon: 'icon', icon: 'icon',
children: 'children' children: 'children',// 子节点字段
isLeaf: 'isLeaf' // 叶子节点标识
} }
export default { export default {
props: { props: {
selectedData: { selectedData: {
@@ -101,25 +106,21 @@
type: String, type: String,
default: 'all' default: 'all'
}, },
// 通过双向绑定控制组件的弹出与收起 type: {
type: String,
default: 'all'
},
modelValue: { modelValue: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// 弹出的z-index值
zIndex: { zIndex: {
type: [String, Number], type: [String, Number],
default: 0 default: 0
}, },
props: { props: {
type: Object, type: Object,
default: () => ({ default: () => ({})
label: 'fullName',
value: 'id',
icon: 'icon',
children: 'children',
isLeaf: 'isLeaf'
})
}, },
multiple: { multiple: {
type: Boolean, type: Boolean,
@@ -138,7 +139,7 @@
keyword: '', keyword: '',
showPopup: false, showPopup: false,
options: [], options: [],
lazyOptions: [], lazyOptions: [{}], // 懒加载根节点占位
activeKey: '1', activeKey: '1',
hasPage: false, hasPage: false,
pagination: { pagination: {
@@ -152,7 +153,6 @@
}; };
}, },
watch: { watch: {
// 在select弹起的时候重新初始化所有数据
modelValue: { modelValue: {
handler(val) { handler(val) {
this.showPopup = val this.showPopup = val
@@ -163,7 +163,8 @@
}, },
selectedList: { selectedList: {
handler(val) { handler(val) {
this.selectedIds = val.map((o) => o.id); // 适配deptId字段
this.selectedIds = val.map((o) => o.deptId);
this.$refs.tree && this.$refs.tree.setCheckedKeys(this.selectedIds) this.$refs.tree && this.$refs.tree.setCheckedKeys(this.selectedIds)
}, },
deep: true deep: true
@@ -171,7 +172,6 @@
}, },
computed: { computed: {
uZIndex() { uZIndex() {
// 如果用户有传递z-index值优先使用
return this.zIndex ? this.zIndex : this.$u.zIndex.popup; return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
}, },
realProps() { realProps() {
@@ -184,7 +184,8 @@
const userInfo = uni.getStorageSync('userInfo') || {} const userInfo = uni.getStorageSync('userInfo') || {}
const list = (userInfo.organizeList || []).map((o) => ({ const list = (userInfo.organizeList || []).map((o) => ({
...o, ...o,
orgNameTree: o.treeName deptName: o.treeName || o.deptName,
deptId: o.id || o.deptId
})) }))
return list return list
} }
@@ -197,10 +198,41 @@
this.finish = false this.finish = false
this.pagination.currentPage = 1 this.pagination.currentPage = 1
this.$nextTick(() => { this.$nextTick(() => {
this.triggered = true this.triggered = false
})
// 深拷贝选中数据
this.selectedList = JSON.parse(JSON.stringify(this.selectedData)).map(item => ({
deptId: item.id || item.deptId,
deptName: item.orgNameTree || item.deptName || item.fullName,
...item
}))
// 如果是全量选择,预加载根节点
if (this.selectType === 'all') {
this.preloadRootNodes()
} else {
this.getConditionOptions()
}
},
preloadRootNodes() {
const data = {
type: this.type,
}
getOrganizeSelector(data).then(res => {
const list = res.data || []
// 构建根节点树
this.options = this.buildTree(list, 'deptId', 'deptPid', '0')
console.log('预加载的根节点:', this.options)
// 设置初始选中状态
this.$nextTick(() => {
if (this.$refs.tree && this.selectedIds.length > 0) {
this.$refs.tree.setCheckedKeys(this.selectedIds)
}
})
}) })
this.selectedList = JSON.parse(JSON.stringify(this.selectedData))
if (this.selectType !== 'all') this.getConditionOptions()
}, },
getConditionOptions() { getConditionOptions() {
if (!this.ableIds.length) return if (!this.ableIds.length) return
@@ -208,90 +240,263 @@
ids: this.ableIds ids: this.ableIds
} }
getOrgByOrganizeCondition(query).then(res => { getOrgByOrganizeCondition(query).then(res => {
this.options = res.data.list || [] // 适配接口返回的扁平数据为树形结构
this.options = this.buildTree(res.data.list || [], 'deptId', 'deptPid', '0')
this.$refs.tree && this.$refs.tree.setCheckedKeys(this.selectedIds) this.$refs.tree && this.$refs.tree.setCheckedKeys(this.selectedIds)
}) })
}, },
// 扁平数组转树形结构
buildTree(data, idKey, pidKey, rootPid) {
const result = []
const map = {}
// 先构建ID映射
data.forEach(item => {
map[item[idKey]] = { ...item, children: [] }
})
// 组装父子关系
data.forEach(item => {
const parent = map[item[pidKey]]
if (item[pidKey] === rootPid) {
result.push(map[item[idKey]])
} else if (parent) {
parent.children.push(map[item[idKey]])
}
})
return result
},
// 树形节点过滤
filterNode(value, data) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
return data[this.realProps.label].indexOf(value) !== -1; return data.deptName && data.deptName.indexOf(value) !== -1;
}, },
// 懒加载节点
loadNode(node, resolve) { loadNode(node, resolve) {
const id = node.key || '0' const parentId = node.key || '0'
const data = {
keyword: '', // 获取该节点的深度信息
parentId: id const level = node.level || 0
console.log('加载节点:', { parentId, level, node })
// 如果是根节点level为0直接使用已经构建好的options
if (level === 0 && this.options.length > 0) {
resolve(this.options)
return
} }
const data = {
type: this.type,
}
getOrganizeSelector(data).then(res => { getOrganizeSelector(data).then(res => {
resolve(res.data?.list) const list = res.data || []
this.$refs.tree && this.$refs.tree.setCheckedKeys(this.selectedIds)
// 将返回的扁平数据转换为树形节点
const treeData = this.buildTree(list, 'deptId', 'deptPid', parentId)
// 设置节点的isLeaf属性根据是否有子节点判断
treeData.forEach(item => {
// 判断该节点是否还有子节点(根据实际情况调整)
// 如果知道接口返回是否有子节点的字段,可以替换这个判断
item.isLeaf = !item.children || item.children.length === 0
})
console.log(`加载父节点 ${parentId} 的子节点:`, treeData)
resolve(treeData)
}).catch(() => {
resolve([]) // 异常时返回空数组,避免组件报错
}) })
}, },
// 滚动加载(仅搜索列表使用)
handleScrollToLower() { handleScrollToLower() {
if (this.finish || this.activeKey === '2') return if (this.finish || this.activeKey === '2' || !this.keyword) return
this.getTreeData() this.getTreeData()
}, },
// 获取搜索列表数据
getTreeData() { getTreeData() {
let data = { const data = {
keyword: this.keyword, type: this.type,
parentId: '0', // keyword: this.keyword,
...this.pagination // parentId: '0',
// ...this.pagination
} }
getOrganizeSelector(data).then(res => { getOrganizeSelector(data).then(res => {
const list = res.data.list || [] const list = res.data || []
if (list.length < this.pagination.pageSize) this.finish = true; if (list.length < this.pagination.pageSize) this.finish = true;
this.list = this.list.concat(list); this.list = this.list.concat(list);
this.pagination.currentPage++ this.pagination.currentPage++
}) })
}, },
onTreeCheck(item) { // 树形节点点击
this.handleTreeNodeClick(item);
},
handleTreeNodeClick(item) { handleTreeNodeClick(item) {
const data = item.data const data = item.data || item
this.handleNodeClick(data) this.handleNodeClick(data)
}, },
// 列表节点点击
handleNodeClick(data) { handleNodeClick(data) {
const index = this.selectedList.findIndex((o) => o.id === data.id); // 适配deptId字段
if (index !== -1) return this.selectedList.splice(index, 1); const index = this.selectedList.findIndex((o) => o.deptId === data.deptId);
if (index !== -1) {
this.selectedList.splice(index, 1);
} else {
this.multiple ? this.selectedList.push(data) : (this.selectedList = [data]); this.multiple ? this.selectedList.push(data) : (this.selectedList = [data]);
}
}, },
// 删除选中项
delSelect(index) { delSelect(index) {
this.selectedList.splice(index, 1); this.selectedList.splice(index, 1);
}, },
// 清空选中
setCheckAll() { setCheckAll() {
this.selectedIds = [] this.selectedIds = []
this.selectedList = [] this.selectedList = []
}, },
// 确认选择
handleConfirm() { handleConfirm() {
this.$emit('confirm', this.selectedList, this.selectedIds); // 转换回原始字段格式,兼容父组件
const resultList = this.selectedList.map(item => ({
id: item.deptId,
orgNameTree: item.deptName,
...item
}))
const resultIds = resultList.map(item => item.id)
console.log(resultIds,resultList,'数据')
this.$emit('confirm', resultList, resultIds);
this.close(); this.close();
}, },
// 关闭弹窗
close() { close() {
this.$emit('update:modelValue', false); // 双向绑定规范
this.$emit('close', false); this.$emit('close', false);
}, },
// 切换标签
toggloActive(key) { toggloActive(key) {
if (this.activeKey === key) return if (this.activeKey === key) return
this.keyword = '' this.keyword = ''
this.$nextTick(() => { this.$nextTick(() => {
this.activeKey = key this.activeKey = key
if (this.activeKey === '2') this.list = this.getCurrOrgList if (this.activeKey === '2') {
}) this.list = this.getCurrOrgList
}, } else {
handleSearch(val) {
this.keyword = val
if (this.selectType !== 'all') return this.$refs.tree && this.$refs.tree.filter(val)
this.hasPage = !!val
this.list = [] this.list = []
if (this.activeKey != '1') this.activeKey = '1'
this.$nextTick(() => {
if (this.keyword) {
this.pagination.currentPage = 1
this.finish = false
this.$u.debounce(this.getTreeData, 300)
} }
}) })
}, },
// 搜索处理
handleSearch(val) {
this.keyword = val.trim()
// 非全量选择时,使用树形过滤
if (this.selectType !== 'all') {
this.$refs.tree && this.$refs.tree.filter(this.keyword)
return
}
// 有搜索关键词时,切换为列表展示
this.hasPage = !!this.keyword
this.list = []
this.finish = false
this.pagination.currentPage = 1
this.activeKey = '1'
if (this.keyword) {
this.$u.debounce(this.getTreeData, 300)() // 执行防抖函数
}
},
} }
}; };
</script> </script>
<style scoped>
/* 保留原有样式,如需补充可添加 */
.jnpf-tree-select-body {
height: 100vh;
display: flex;
flex-direction: column;
background: #fff;
}
.jnpf-tree-select-title {
display: flex;
align-items: center;
padding: 16rpx;
border-bottom: 1rpx solid #eee;
}
.backIcon {
font-size: 32rpx;
margin-right: 16rpx;
}
.title {
font-size: 32rpx;
font-weight: 500;
}
.jnpf-tree-select-search {
padding: 16rpx;
}
.jnpf-tree-selected {
padding: 0 16rpx;
}
.jnpf-tree-selected-head {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12rpx 0;
}
.clear-btn {
color: #007aff;
font-size: 28rpx;
}
.select-list {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
padding: 8rpx 0;
max-height: 200rpx;
}
.u-selectTag {
margin-bottom: 8rpx;
}
.jnpf-tree-selected-line {
height: 1rpx;
background: #eee;
margin: 8rpx 0;
}
.jnpf-tree-selected-tabs {
display: flex;
}
.tab-item {
flex: 1;
text-align: center;
padding: 16rpx;
font-size: 28rpx;
}
.tab-item-active {
color: #007aff;
border-bottom: 2rpx solid #007aff;
}
.jnpf-tree-select-tree {
flex: 1;
padding: 16rpx;
}
.jnpf-selcet-cell {
display: flex;
align-items: center;
padding: 16rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
.jnpf-selcet-cell-action {
margin-right: 16rpx;
}
.jnpf-tree-select-actions {
display: flex;
padding: 16rpx;
gap: 16rpx;
}
.buttom-btn {
flex: 1;
height: 88rpx;
line-height: 88rpx;
}
.h-full {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@@ -3,16 +3,16 @@
<selectBox v-model="innerValue" :placeholder="placeholder" @openSelect="openSelect" :select-open="selectShow" <selectBox v-model="innerValue" :placeholder="placeholder" @openSelect="openSelect" :select-open="selectShow"
:disabled="disabled" /> :disabled="disabled" />
<SelectPopup v-model="selectShow" :multiple="multiple" :selectedData="selectedData" @close="handleClose" <SelectPopup v-model="selectShow" :multiple="multiple" :selectedData="selectedData" @close="handleClose"
@confirm="handleConfirm" :selectType="selectType" :ableIds="ableIds" /> @confirm="handleConfirm" :selectType="selectType" :type="type" :ableIds="ableIds" />
</view> </view>
</template> </template>
<script> <script>
import SelectPopup from './SelectPopup'; import SelectPopup from './SelectPopup';
import selectBox from '@/components/selectBox' import selectBox from '@/components/selectBox'
import { // 移除接口导入:不再需要 getOrgSelectedList
getOrgSelectedList // import { getOrgSelectedList } from '@/api/common'
} from '@/api/common'
export default { export default {
name: 'jnpf-organize-select', name: 'jnpf-organize-select',
components: { components: {
@@ -39,9 +39,17 @@
type: String, type: String,
default: 'all' default: 'all'
}, },
type: {
type: String,
default: 'all'
},
ableIds: { ableIds: {
type: Array, type: Array,
default: () => [] default: () => []
},
innerSelectedData: {
type: Array,
default: () => []
} }
}, },
data() { data() {
@@ -53,24 +61,40 @@
}, },
watch: { watch: {
modelValue: { modelValue: {
handler() { handler(val) {
this.setDefault() this.setDefault(val) // 传入modelValue直接处理赋值
}, },
immediate: true immediate: true
}, },
innerSelectedData: {
handler(val) {
if(val.length){
const data = val[0]
this.selectedData = val
this.setDefault(data['id'])
}
},
immediate: true,
deep: true
},
}, },
methods: { methods: {
setDefault() { // 重构setDefault:不再调用接口,直接处理赋值
if (!this.modelValue || !this.modelValue.length) return this.setNullValue(); setDefault(val) {
const ids = this.multiple ? this.modelValue : [this.modelValue]; if (!val || !val.length) {
getOrgSelectedList({ return this.setNullValue();
ids }
}).then((res) => { // 场景1父组件传入初始值modelValue直接匹配已选数据赋值
if (!this.modelValue || !this.modelValue.length) return this.setNullValue(); // 如果没有初始选中数据innerValue为空即可无需请求接口
const selectedData = res.data.list || [] // 重点这里不再调用getOrgSelectedList直接用已有的selectedData或空值
this.selectedData = selectedData
this.innerValue = this.selectedData.map(o => o.orgNameTree).join(); if (this.selectedData.length > 0) {
}); // 有已选数据时,直接拼接名称
this.innerValue = this.selectedData.map(o => o.deptName || o.orgNameTree).join();
} else {
// 无已选数据时若modelValue是ID暂时显示空或根据需要处理
this.innerValue = '';
}
}, },
setNullValue() { setNullValue() {
this.innerValue = ''; this.innerValue = '';
@@ -80,7 +104,16 @@
if (this.disabled) return if (this.disabled) return
this.selectShow = true this.selectShow = true
}, },
// 核心修改:确认选择时,直接用弹窗返回的原始数据赋值
handleConfirm(selectedData, selectedIds) { handleConfirm(selectedData, selectedIds) {
// 1. 保存选中的原始数据
this.selectedData = selectedData;
// 2. 直接拼接名称到显示框innerValue无需接口
this.innerValue = selectedData.map(o => o.deptName || o.orgNameTree).join();
// 3. 向父组件传递选中值(保持原有逻辑)
console.log(this.multiple,'this.multiple')
console.log(selectedData[0],'selectedData[0]')
console.log(selectedIds[0],'selectedIds[0]')
if (!this.multiple) { if (!this.multiple) {
this.$emit('update:modelValue', selectedIds[0]) this.$emit('update:modelValue', selectedIds[0])
this.$emit('change', selectedIds[0], selectedData[0]) this.$emit('change', selectedIds[0], selectedData[0])
@@ -88,6 +121,8 @@
this.$emit('update:modelValue', selectedIds) this.$emit('update:modelValue', selectedIds)
this.$emit('change', selectedIds, selectedData) this.$emit('change', selectedIds, selectedData)
} }
// 4. 关闭弹窗
this.selectShow = false;
}, },
handleClose() { handleClose() {
this.selectShow = false this.selectShow = false

View File

@@ -156,7 +156,7 @@
:relationField="item.relationField" :formData="formData" /> :relationField="item.relationField" :formData="formData" />
<JnpfOrganizeSelect v-if="config.jnpfKey=='organizeSelect'" v-model="value" :multiple="item.multiple" <JnpfOrganizeSelect v-if="config.jnpfKey=='organizeSelect'" v-model="value" :multiple="item.multiple"
:placeholder="item.placeholder" :disabled="item.disabled" :ableIds="item.ableIds" :placeholder="item.placeholder" :disabled="item.disabled" :ableIds="item.ableIds"
:selectType="item.selectType" @change="onChange" /> :selectType="item.selectType" :type="item.type" :innerSelectedData="item.innerSelectedData" @change="onChange" />
<JnpfPosSelect v-if="config.jnpfKey=='posSelect'" v-model="value" :multiple="item.multiple" <JnpfPosSelect v-if="config.jnpfKey=='posSelect'" v-model="value" :multiple="item.multiple"
:placeholder="item.placeholder" :disabled="item.disabled" :ableIds="item.ableIds" :placeholder="item.placeholder" :disabled="item.disabled" :ableIds="item.ableIds"
:selectType="item.selectType" @change="onChange" /> :selectType="item.selectType" @change="onChange" />

View File

@@ -15,9 +15,10 @@
</view> </view>
<u-button size="mini" v-if="disabled" class="jnpf-file-disabled">{{buttonText}}</u-button> <u-button size="mini" v-if="disabled" class="jnpf-file-disabled">{{buttonText}}</u-button>
<view v-for='(item,index) in fileList' :key="index" class="jnpf-file-item u-type-primary u-flex u-line-1" <view v-for='(item,index) in fileList' :key="index" class="jnpf-file-item u-type-primary u-flex u-line-1"
@tap='downLoad(item)'> @click.stop='downLoad(item)'>
<view class="jnpf-file-item-txt u-line-1" v-if="item.fileSize"> <view class="jnpf-file-item-txt u-line-1" v-if="item.fileSize">
{{item.name+''+`${jnpf.toFileSize(item.fileSize)}`+' '}} <!-- {{item.name+''+`${jnpf.toFileSize(item.fileSize)}`+' '}} -->
{{item.name}}
</view> </view>
<view class="jnpf-file-item-txt u-line-1" v-else>{{item.name}}</view> <view class="jnpf-file-item-txt u-line-1" v-else>{{item.name}}</view>
<view class="closeBox u-flex-col" @click.stop="delFile(index)" v-if="!detailed && !disabled"> <view class="closeBox u-flex-col" @click.stop="delFile(index)" v-if="!detailed && !disabled">
@@ -149,7 +150,7 @@
created() { created() {
const token = uni.getStorageSync('token') const token = uni.getStorageSync('token')
this.option = { this.option = {
url: this.baseURL + '/api/file/Uploader/annex', url: this.baseURL + '/admin-api/infra/file/jeelowcode/upload',
name: 'file', name: 'file',
header: { header: {
'Authorization': token, 'Authorization': token,
@@ -163,7 +164,22 @@
watch: { watch: {
modelValue: { modelValue: {
handler(val) { handler(val) {
this.fileList = JSON.parse(JSON.stringify(val)); if(Array.isArray(val)){
this.fileList = val
return
}
if (!val || typeof val !== 'string') {
this.fileList = [];
return;
}
const urlList = val.split(',').filter(item => item.trim());
this.fileList = urlList.map(url => {
const fileName = url.substring(url.lastIndexOf('/') + 1) || '未知文件';
return {
fileUrl: url,
name: fileName
};
});
}, },
immediate: true immediate: true
} }
@@ -174,13 +190,17 @@
if (item['responseText']) { if (item['responseText']) {
let response = JSON.parse(item.responseText) let response = JSON.parse(item.responseText)
if (this.fileList.length >= this.limit) return this.$u.toast('已达最大上传数量') if (this.fileList.length >= this.limit) return this.$u.toast('已达最大上传数量')
if (response.code != 200) return this.$u.toast(response.msg) if (response.code != 0) return this.$u.toast(response.msg)
console.log(this.fileList,'fileList---')
this.fileList.push({ this.fileList.push({
fileName: item.name,
name: item.name, name: item.name,
fileId: response.data.name, fileId: response.data.name,
url: response.data.url, fileUrl: response.data.url,
fileExtension: response.data.fileExtension, fileExtension: response.data.fileExtension,
fileSize: response.data.fileSize fileSize: response.data.size,
fileType: response.data.type,
filePath: response.data.path,
}) })
this.$emit('update:modelValue', this.fileList) this.$emit('update:modelValue', this.fileList)
this.$emit('change', this.fileList) this.$emit('change', this.fileList)
@@ -188,20 +208,23 @@
this.$forceUpdate(); this.$forceUpdate();
}, },
downLoad(item) { downLoad(item) {
if (item.fileExtension && imgTypeList.includes(item.fileExtension)) return this.previewImage(item) const {fileUrl} = item
window.location.href = fileUrl
// if (item.fileExtension && imgTypeList.includes(item.fileExtension)) return this.previewImage(item)
// #ifdef MP // #ifdef MP
this.previewFile(item) // this.previewFile(item)
// #endif // #endif
// #ifndef MP // #ifndef MP
getDownloadUrl('annex', item.fileId).then(res => { // getDownloadUrl('annex', item.fileId).then(res => {
const fileUrl = this.baseURL + res.data.url + '&name=' + item.name; // const fileUrl = this.baseURL + res.data.url + '&name=' + item.name;
// #ifdef H5 // #ifdef H5
window.location.href = fileUrl; // window.location.href = fileUrl;
// #endif // #endif
// #ifdef APP-PLUS // #ifdef APP-PLUS
this.downloadFile(res.data.url); // this.downloadFile(res.data.url);
// #endif // #endif
}) // })
// #endif // #endif
}, },
// 移除某个文件 // 移除某个文件

View File

@@ -256,13 +256,13 @@
this.$nextTick(() => { this.$nextTick(() => {
this.triggered = true this.triggered = true
}) })
this.selectedList = JSON.parse(JSON.stringify(this.selectedData)) // this.selectedList = JSON.parse(JSON.stringify(this.selectedData))
if (this.selectType === 'all') { // if (this.selectType === 'all') {
this.getGroupList() // this.getGroupList()
} else { // } else {
this.hasPage = 1 // this.hasPage = 1
this.getConditionOptions() // this.getConditionOptions()
} // }
}, },
handleToFirst() { handleToFirst() {

View File

@@ -189,7 +189,7 @@ const Socket = {
}, },
//重连 //重连
reConnect() { reConnect() {
Socket.initSocket() // Socket.initSocket()
}, },
close() { close() {
socketTask.close({ socketTask.close({

View File

@@ -650,8 +650,10 @@
"views.dynamicModel.showMore": "加载更多", "views.dynamicModel.showMore": "加载更多",
"views.dynamicModel.hideSome": "隐藏部分", "views.dynamicModel.hideSome": "隐藏部分",
"app.tabBar.home": "工作台", "app.tabBar.home": "工作台",
"app.tabBar.home1": "工作台1",
"app.tabBar.dashboard": "仪表盘", "app.tabBar.dashboard": "仪表盘",
"app.tabBar.message": "消息", "app.tabBar.message": "消息",
"app.tabBar.task": "待办任务",
"app.tabBar.my": "我的", "app.tabBar.my": "我的",
"app.tabBar.menu": "应用功能", "app.tabBar.menu": "应用功能",
"app.tabBar.workFlow": "发起审批", "app.tabBar.workFlow": "发起审批",

View File

@@ -650,8 +650,10 @@
"views.dynamicModel.showMore": "加載更多", "views.dynamicModel.showMore": "加載更多",
"views.dynamicModel.hideSome": "隱藏部分", "views.dynamicModel.hideSome": "隱藏部分",
"app.tabBar.home": "工作台", "app.tabBar.home": "工作台",
"app.tabBar.home1": "工作台1",
"app.tabBar.dashboard": "仪表盘", "app.tabBar.dashboard": "仪表盘",
"app.tabBar.message": "消息", "app.tabBar.message": "消息",
"app.tabBar.task": "待办任务",
"app.tabBar.my": "我的", "app.tabBar.my": "我的",
"app.tabBar.menu": "應用功能", "app.tabBar.menu": "應用功能",
"app.tabBar.workFlow": "發起審批", "app.tabBar.workFlow": "發起審批",

View File

@@ -1,6 +1,6 @@
{ {
"name" : "jnpf java vue3版", "name" : "jnpf java vue3版",
"appid": "__UNI__663111E", "appid" : "__UNI__55507A7",
"description" : "专注信息化平台、软件开发、app开发", "description" : "专注信息化平台、软件开发、app开发",
"versionName" : "1.0.0", "versionName" : "1.0.0",
"versionCode" : "100", "versionCode" : "100",
@@ -202,7 +202,7 @@
"vueVersion" : "3", "vueVersion" : "3",
"h5" : { "h5" : {
"devServer" : { "devServer" : {
"port": 3800 "port" : 5001
}, },
"title" : "jnpf java vue3版", "title" : "jnpf java vue3版",
"router" : { "router" : {
@@ -235,3 +235,4 @@
} }
} }
/* 5+App */ /* 5+App */

View File

@@ -6,27 +6,27 @@
"^jnpf-(.*)": "@/components/Jnpf/$1/index.vue" "^jnpf-(.*)": "@/components/Jnpf/$1/index.vue"
} }
}, },
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages "pages": [
// #ifdef APP // #ifdef APP
{ {
"path": "pages/launch/index", "path": "pages/launch/index",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
{ {
"path": "pages/launch/policy", "path": "pages/launch/policy",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
{ {
"path": "pages/launch/guide", "path": "pages/launch/guide",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
// #endif // #endif
@@ -34,14 +34,14 @@
"path": "pages/login/index", "path": "pages/login/index",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
{ {
"path": "pages/login/sso-redirect", "path": "pages/login/sso-redirect",
"style": { "style": {
"navigationStyle": "custom", // 隐藏系统导航栏 "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
{ {
@@ -62,7 +62,18 @@
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "JNPF快速开发平台", "navigationBarTitleText": "JNPF快速开发平台",
"app-plus": { "app-plus": {
"bounce": "none" // 取消APP端iOS回弹,避免与下拉刷新冲突 (可统一配在 'globalStyle') "bounce": "none"
}
}
},
{
"path": "pages/index/indexWork",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "综合监控系统",
"app-plus": {
"bounce": "none"
} }
} }
}, },
@@ -73,11 +84,14 @@
"navigationBarTitleText": "%app.tabBar.dashboard%" "navigationBarTitleText": "%app.tabBar.dashboard%"
} }
}, },
// 核心修改将审批中心页面移到根pages数组删除分包里的同名配置
{ {
"path": "pages/index/message", "path": "pages/workFlow/flowTodo/index",
"style": { "style": {
"navigationStyle": "custom", "navigationBarTitleText": "审批中心", // 审批中心标题
"navigationBarTitleText": "%app.tabBar.message%" "app-plus": {
"bounce": "none"
}
} }
}, },
// #ifndef MP // #ifndef MP
@@ -112,15 +126,16 @@
} }
} }
], ],
"subPackages": [{ "subPackages": [
{
"root": "pages/portal", "root": "pages/portal",
"pages": [ "pages": [
// #ifndef MP // #ifndef MP
{ {
"path": "applyPortal/index", "path": "applyPortal/index",
"style": { "style": {
"navigationStyle": "custom", // 隐藏系统导航栏 "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
// #endif // #endif
@@ -128,8 +143,8 @@
{ {
"path": "mpPortal/index", "path": "mpPortal/index",
"style": { "style": {
"navigationStyle": "custom", // 隐藏系统导航栏 "navigationStyle": "custom",
"navigationBarTextStyle": "black" // 状态栏字体为白色 "navigationBarTextStyle": "black"
} }
}, },
// #endif // #endif
@@ -143,7 +158,8 @@
}, },
{ {
"root": "pages/message", "root": "pages/message",
"pages": [{ "pages": [
{
"path": "messageDetail/index", "path": "messageDetail/index",
"style": { "style": {
"navigationBarTitleText": "详情" "navigationBarTitleText": "详情"
@@ -165,7 +181,8 @@
}, },
{ {
"root": "pages/workFlow", "root": "pages/workFlow",
"pages": [{ "pages": [
{
"path": "flowBefore/index", "path": "flowBefore/index",
"style": { "style": {
"navigationBarTitleText": "" "navigationBarTitleText": ""
@@ -216,7 +233,7 @@
{ {
"path": "schedule/detail", "path": "schedule/detail",
"style": { "style": {
"navigationStyle": "custom", // 隐藏系统导航栏 "navigationStyle": "custom",
"navigationBarTitleText": "详情", "navigationBarTitleText": "详情",
"app-plus": { "app-plus": {
"titleNView": false, "titleNView": false,
@@ -252,12 +269,7 @@
} }
} }
}, },
{ // 注意删除分包里的flowTodo/index配置已移到根pages
"path": "flowTodo/index",
"style": {
"navigationBarTitleText": "审批中心"
}
},
// #ifdef MP // #ifdef MP
{ {
"path": "filePreview/index", "path": "filePreview/index",
@@ -316,16 +328,19 @@
}, },
{ {
"root": "pages/commonPage", "root": "pages/commonPage",
"pages": [{ "pages": [
{
"path": "morePage/index", "path": "morePage/index",
"style": { "style": {
"navigationBarTitleText": "常用菜单" "navigationBarTitleText": "常用菜单"
} }
}] }
]
}, },
{ {
"root": "pages/apply", "root": "pages/apply",
"pages": [{ "pages": [
{
"path": "menu/index", "path": "menu/index",
"style": { "style": {
"navigationBarTitleText": "应用功能" "navigationBarTitleText": "应用功能"
@@ -346,7 +361,7 @@
{ {
"path": "catalog/index", "path": "catalog/index",
"style": { "style": {
"navigationStyle": "custom" // 隐藏系统导航栏 "navigationStyle": "custom"
} }
}, },
{ {
@@ -392,6 +407,30 @@
"navigationBarTitleText": "" "navigationBarTitleText": ""
} }
}, },
{
"path": "dynamicModelList/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "dynamicModelList/form",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "dynamicModelList/detail",
"style": {
"navigationBarTitleText": "详情"
}
},
{
"path": "dynamicModelList/scanForm",
"style": {
"navigationBarTitleText": ""
}
},
{ {
"path": "tableLinkage/index", "path": "tableLinkage/index",
"style": { "style": {
@@ -428,7 +467,8 @@
}, },
{ {
"root": "pages/my", "root": "pages/my",
"pages": [{ "pages": [
{
"path": "contacts/index", "path": "contacts/index",
"style": { "style": {
"navigationBarTitleText": "%app.my.contacts%" "navigationBarTitleText": "%app.my.contacts%"
@@ -447,7 +487,8 @@
"style": { "style": {
"navigationBarTitleText": "用户列表" "navigationBarTitleText": "用户列表"
} }
}, { },
{
"path": "settings/index", "path": "settings/index",
"style": { "style": {
"navigationBarTitleText": "%app.my.setting%", "navigationBarTitleText": "%app.my.setting%",
@@ -510,7 +551,7 @@
{ {
"path": "personalData/index", "path": "personalData/index",
"style": { "style": {
"navigationBarTitleText": "%layout.header.profile%", "navigationBarTitleText": "",
"app-plus": { "app-plus": {
"bounce": "none" "bounce": "none"
} }
@@ -552,36 +593,33 @@
"preloadRule": { "preloadRule": {
"pages/index/message": { "pages/index/message": {
"network": "all", "network": "all",
"packages": [ "packages": ["pages/message"]
"pages/message"
]
}, },
"pages/index/my": { "pages/index/my": {
"network": "all", "network": "all",
"packages": [ "packages": ["pages/my"]
"pages/my"
]
} }
}, },
"tabBar": { "tabBar": {
"color": "#303133", "color": "#303133",
"selectedColor": "#2979FF", "selectedColor": "#2979FF",
"backgroundColor": "#ffffff", "backgroundColor": "#ffffff",
"list": [{ "list": [
"pagePath": "pages/index/index", {
"pagePath": "pages/index/indexWork",
"text": "%app.tabBar.home%", "text": "%app.tabBar.home%",
"iconPath": "static/image/tabbar/home.png", "iconPath": "static/image/tabbar/home.png",
"selectedIconPath": "static/image/tabbar/homeHL.png" "selectedIconPath": "static/image/tabbar/homeHL.png"
}, },
// {
// "pagePath": "pages/index/index",
// "text": "%app.tabBar.home%",
// "iconPath": "static/image/tabbar/home.png",
// "selectedIconPath": "static/image/tabbar/homeHL.png"
// },
{ {
"pagePath": "pages/index/dashboard", "pagePath": "pages/workFlow/flowTodo/index",
"text": "%app.tabBar.dashboard%", "text": "%app.tabBar.task%",
"iconPath": "static/image/tabbar/workFlow.png",
"selectedIconPath": "static/image/tabbar/workFlowHL.png"
},
{
"pagePath": "pages/index/message",
"text": "%app.tabBar.message%",
"iconPath": "static/image/tabbar/message.png", "iconPath": "static/image/tabbar/message.png",
"selectedIconPath": "static/image/tabbar/messageHL.png" "selectedIconPath": "static/image/tabbar/messageHL.png"
}, },

View File

@@ -81,10 +81,8 @@
</view> </view>
<view v-if="!showTop"> <view v-if="!showTop">
<!-- 新增按钮 --> <!-- 新增按钮 -->
<view v-if="config.webType !=4"> <view>
<view class="com-addBtn" <view class="com-addBtn" @click="addPage()">
v-if="isPreview||(permission.btnPermission && permission.btnPermission.includes('btn_add'))"
@click="addPage()">
<u-icon name="plus" size="48" color="#fff" /> <u-icon name="plus" size="48" color="#fff" />
</view> </view>
</view> </view>
@@ -114,10 +112,9 @@
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import { import { useBaseStore } from '@/store/modules/base'
useBaseStore
} from '@/store/modules/base'
const baseStore = useBaseStore() const baseStore = useBaseStore()
import list from './list.vue' import list from './list.vue'
import resources from '@/libs/resources.js' import resources from '@/libs/resources.js'
@@ -126,18 +123,16 @@
import jnpf from "@/utils/jnpf"; import jnpf from "@/utils/jnpf";
import Parser from '../parser/index.vue' import Parser from '../parser/index.vue'
import { import {
getModelList, getModelDataList,
getDbfromList,
deteleModel, deteleModel,
getModelInfo, getModelInfo,
launchFlow launchFlow
} from '@/api/apply/visualDev' } from '@/api/apply/visualDev'
import { import { getDataInterfaceRes } from '@/api/common'
getDataInterfaceRes
} from '@/api/common'
import deepClone from '../../../../../uni_modules/vk-uview-ui/libs/function/deepClone'; import deepClone from '../../../../../uni_modules/vk-uview-ui/libs/function/deepClone';
import { import { useDefineSetting } from '@/utils/useDefineSetting';
useDefineSetting
} from '@/utils/useDefineSetting';
export default { export default {
mixins: [MescrollMixin, bulkOperationMixin], mixins: [MescrollMixin, bulkOperationMixin],
props: ['config', 'modelId', 'isPreview', 'title', 'menuId'], props: ['config', 'modelId', 'isPreview', 'title', 'menuId'],
@@ -147,6 +142,7 @@
}, },
data() { data() {
return { return {
selectedSort: {},
tabActiveKey: 0, tabActiveKey: 0,
tabList: [], tabList: [],
tabQueryJson: {}, tabQueryJson: {},
@@ -172,16 +168,17 @@
list: [], list: [],
listQuery: { listQuery: {
sidx: '', sidx: '',
keyword: '', asc: '', // 升序
queryJson: '' desc: '', // 降序
queryJson: {}
}, },
actionOptions: [], actionOptions: [],
showParser: false, showParser: true, // 强制显示筛选面板
columnData: {}, columnData: {},
columnList: [], columnList: [],
sortList: [], sortList: [],
sortOptions: [], sortOptions: [],
searchList: [], searchList: [], // 初始化空数组
searchFormConf: [], searchFormConf: [],
permission: {}, permission: {},
selectListIndex: 0, selectListIndex: 0,
@@ -196,23 +193,29 @@
selectItems: [], selectItems: [],
listInnerBtn: [], listInnerBtn: [],
listTopBtn: [], listTopBtn: [],
useDefine: useDefineSetting() useDefine: useDefineSetting(),
departmentList: [] // 新增:存储接口返回的部门列表
} }
}, },
created() { async created() {
// 1. 先加载部门数据await 确保接口完成后再执行init
await this.loadDepartmentList()
// 2. 强制执行初始化
this.init() this.init()
// 3. 强制触发列表加载,确保页面初始化完成
this.$nextTick(() => {
this.mescrollInit()
this.mescroll.resetUpScroll()
})
},
mounted() {
// 兜底mounted阶段再次强制设置mock数据
this.forceSetMockData()
}, },
computed: { computed: {
showBatchOperate() {
return this.list.length && (this.isBatchRemove || this.listTopBtn.length)
},
isBatchRemove() {
return this.columnData.btnsList.find(item => item.value === "batchRemove" && item.show)
},
showTabs() { showTabs() {
return this.columnData?.tabConfig?.on && this.tabList.length return this.columnData?.tabConfig?.on && this.tabList.length
}, },
/* 底部自定义按钮 */
bottomCustomBtnsList() { bottomCustomBtnsList() {
if (this.listTopBtn.length <= 3) return [this.listTopBtn, []]; if (this.listTopBtn.length <= 3) return [this.listTopBtn, []];
const firstArray = this.listTopBtn.slice(0, 3); const firstArray = this.listTopBtn.slice(0, 3);
@@ -231,36 +234,208 @@
}, },
customBtnsList() { customBtnsList() {
return this.columnData?.customBtnsList?.some(item => item.event?.btnType === 1); return this.columnData?.customBtnsList?.some(item => item.event?.btnType === 1);
},
isBatchRemove() {
return this.columnData?.btnsList?.find(item => item.value === "batchRemove" && item.show)
} }
}, },
methods: { methods: {
/**
* 加载部门列表改为async/await确保异步逻辑等待完成
*/
async loadDepartmentList() {
console.log(this.modelId,'modelId------')
try {
// 用await等待接口返回解决异步时序问题
const res = await getDbfromList('1964207990401785857');
console.log(res,'res---------111')
if(res.code == 0 && res.data?.records?.length){
this.departmentList = res.data.records.map(item => ({
label: item.full_name,
value: item.id // 如需用名称作为value可改为 item.full_name
}));
}
console.log(this.departmentList,'departmentList----')
// 关键:接口返回后更新筛选配置的部门选项
this.mockSearchListForDepartment();
this.handleSearchList();
} catch (error) {
console.error('加载部门列表失败:', error);
// 接口失败时的兜底数据
this.departmentList = [
{ label: '技术部', value: '技术部' },
{ label: '财务部', value: '财务部' },
{ label: '行政部', value: '行政部' },
{ label: '销售部', value: '销售部' }
];
// 兜底数据也要更新筛选配置
this.mockSearchListForDepartment();
this.handleSearchList();
}
},
/**
* 专门生成带部门列表的筛选配置(只更新申请单位项,不影响其他筛选项)
*/
mockSearchListForDepartment() {
// 先检查是否已有申请单位的筛选项有则更新options无则新增
const depItemIndex = this.searchList.findIndex(item => item.id === 'applyDepId');
if (depItemIndex > -1) {
// 已有则更新options
this.searchList[depItemIndex].options = this.departmentList;
} else {
// 没有则新增申请单位筛选项
this.searchList.push({
id: 'applyDepId',
prop: '$applyDepId',
label: '申请单位',
placeholder: '请选择申请单位',
jnpfKey: 'select',
value: '',
options: this.departmentList,
__config__: {
jnpfKey: 'select',
label: '申请单位',
isFromParam: false
},
noShow: false
});
}
// 同时更新forceSetMockData里的申请单位options兜底
this.forceSetMockData();
},
filterEmpty(arr) { filterEmpty(arr) {
return arr.filter(item => { return arr.filter(item => {
// 处理数组情况
if (Array.isArray(item)) return item.length > 0; if (Array.isArray(item)) return item.length > 0;
// 处理对象情况
if (typeof item === 'object' && item !== null) return Object.keys(item).length > 0; if (typeof item === 'object' && item !== null) return Object.keys(item).length > 0;
// 其他情况保留
return true; return true;
}); });
}, },
selectCheckbox(data) { selectCheckbox(data) {
this.selectItems = data this.selectItems = data
}, },
// 新增强制设置mock数据兜底逻辑
forceSetMockData() {
// 强制设置排序选项
if (!this.sortOptions.length) {
this.sortOptions = [
{ label: '创建时间 升序', value: 'create_time_asc', field: 'create_time', type: 'asc' },
{ label: '创建时间 降序', value: 'create_time_desc', field: 'create_time', type: 'desc' },
];
}
// 强制设置筛选配置(只在无数据时初始化,避免覆盖接口返回的配置)
if (!this.searchFormConf.length) {
this.searchFormConf = [
{
id: 'applyDepId',
prop: '$applyDepId',
label: '申请单位',
placeholder: '请选择申请单位',
jnpfKey: 'select',
value: '',
options: this.departmentList, // 动态绑定最新部门列表
__config__: {
jnpfKey: 'select',
label: '申请单位',
isFromParam: false
},
noShow: false
},
{
id: 'applyUser',
prop: 'applyUser',
label: '申请人',
placeholder: '请输入申请人员',
jnpfKey: 'input',
clearable: true,
isKeyword: true,
value: '',
__config__: {
jnpfKey: 'input',
label: '申请人',
isFromParam: false
},
noShow: false
},
{
id: 'operationDepName',
prop: 'operationDepName',
label: '作业单位',
placeholder: '请输入作业单位',
jnpfKey: 'input',
clearable: true,
isKeyword: true,
value: '',
__config__: {
jnpfKey: 'input',
label: '作业单位',
isFromParam: false
},
noShow: false
},
];
this.searchList = [...this.searchFormConf]
} else {
// 如果已有筛选配置只更新申请单位的options
const depConfIndex = this.searchFormConf.findIndex(item => item.id === 'applyDepId');
if (depConfIndex > -1) {
this.searchFormConf[depConfIndex].options = this.departmentList;
}
}
},
init() { init() {
this.userInfo = uni.getStorageSync('userInfo') || {}; this.userInfo = uni.getStorageSync('userInfo') || {};
this.properties = this.config.flowTemplateJson ? JSON.parse(this.config.flowTemplateJson).properties : {}; this.properties = this.config.flowTemplateJson ? JSON.parse(this.config.flowTemplateJson).properties : {};
let columnDataStr = this.config?.appColumnData || '[]'; let columnDataStr = this.config?.appColumnData || '{}'; // 改为空对象,避免解析报错
try { try {
this.columnData = JSON.parse(columnDataStr); this.columnData = JSON.parse(columnDataStr);
} catch (e) { } catch (e) {
this.columnData = []; this.columnData = {};
} }
this.permission = this.$permission.getPermission(this.columnData, this.menuId, this.jnpf.getScriptFunc); this.permission = this.$permission.getPermission(this.columnData, this.menuId, this.jnpf.getScriptFunc);
this.enableFunc = this.permission.enableFunc; this.enableFunc = this.permission.enableFunc;
this.upOption.page.size = this.columnData.hasPage ? this.columnData.pageSize : 1000000; this.upOption.page.size = this.columnData.hasPage ? this.columnData.pageSize : 1000000;
this.setDefaultQuery(); this.setDefaultQuery();
this.columnList = this.permission.columnPermission || [];
// ========== 强制设置列数据(优先级最高) ==========
this.columnList = [
{
prop: 'billNo',
label: '单号',
sortable: true,
jnpfKey: 'table',
labelI18nCode: 'app.apply.billNo'
},
{
prop: 'applyDepName',
label: '申请单位',
sortable: false,
jnpfKey: 'table',
labelI18nCode: 'app.apply.applyDepName'
},
{
prop: 'applyUser',
label: '申请人员',
sortable: true,
jnpfKey: 'table',
labelI18nCode: 'app.apply.applyUser'
},
{
prop: 'create_time',
label: '创建时间',
sortable: true,
jnpfKey: 'table',
labelI18nCode: 'app.apply.createTime'
},
{
prop: 'approveStatusName',
label: '审批状态',
sortable: false,
jnpfKey: 'table',
labelI18nCode: 'app.apply.approveStatus'
}
];
this.columnData.customBtnsList = this.permission.customBtnsPermission || []; this.columnData.customBtnsList = this.permission.customBtnsPermission || [];
this.columnData.customBtnsList.map((o) => { this.columnData.customBtnsList.map((o) => {
if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode) if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode)
@@ -269,14 +444,21 @@
this.columnList = this.transformColumnList(this.columnList) this.columnList = this.transformColumnList(this.columnList)
this.columnList.map((o) => { this.columnList.map((o) => {
if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode) if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode)
// if (o.jnpfKey != 'table' && o.label.length > 4) o.label = o.label.substring(0, 4) });
})
this.sortList = this.columnList.filter(o => o.sortable) // ========== 强制设置排序数据 ==========
this.sortList = this.columnList.filter(o => o.sortable);
// this.handleSortList(); // 立即生成排序选项
// ========== 强制设置筛选数据 ==========
this.handleSearchList(); // 处理筛选配置
this.getTabList(); this.getTabList();
this.handleSearchList()
this.handleSortList()
this.handleDeleteBtn() this.handleDeleteBtn()
this.key = +new Date() this.key = +new Date()
// 兜底强制触发mock数据生效
this.forceSetMockData()
}, },
setBtns() { setBtns() {
const buttons = { const buttons = {
@@ -292,14 +474,17 @@
}, },
upCallback(page) { upCallback(page) {
if (this.isPreview == '1') return this.mescroll.endSuccess(0, false); if (this.isPreview == '1') return this.mescroll.endSuccess(0, false);
const { asc, desc, queryJson = {} } = this.listQuery
const query = { const query = {
currentPage: page.num, pageNo: page.num,
pageSize: page.size, pageSize: page.size,
menuId: this.menuId, menuId: this.menuId,
modelId: this.modelId, modelId: this.modelId,
...this.listQuery asc,
desc,
...queryJson
} }
getModelList(this.modelId, query, { getDbfromList(this.modelId, query, {
load: page.num == 1 load: page.num == 1
}).then(res => { }).then(res => {
this.selectItems = [] this.selectItems = []
@@ -308,13 +493,14 @@
}) })
this.showParser = true this.showParser = true
if (page.num == 1) this.list = []; if (page.num == 1) this.list = [];
this.mescroll.endSuccess(res.data.list.length); this.mescroll.endSuccess(res.data.records.length);
const list = res.data.list.map((o, i) => ({ const list = res.data.records.map((o, i) => ({
checked: false, checked: false,
index: i, index: i,
...o ...o
})); }));
this.list = this.list.concat(list); this.list = this.list.concat(list);
console.log(this.list, 'list----')
this.$nextTick(() => { this.$nextTick(() => {
if (this.columnData.funcs && this.columnData.funcs.afterOnload) this if (this.columnData.funcs && this.columnData.funcs.afterOnload) this
.setTableLoadFunc() .setTableLoadFunc()
@@ -325,7 +511,6 @@
this.mescroll.endErr(); this.mescroll.endErr();
}) })
}, },
//获取标签面板数据、设置标签面板默认值
async getTabList() { async getTabList() {
this.tabList = []; this.tabList = [];
if (!this.columnData.tabConfig) return; if (!this.columnData.tabConfig) return;
@@ -356,13 +541,11 @@
relationField relationField
} = this.columnData.tabConfig; } = this.columnData.tabConfig;
const currentTab = this.tabList[val]; const currentTab = this.tabList[val];
// 合并条件判断
const shouldSetRelation = !hasAllTab || val !== 0; const shouldSetRelation = !hasAllTab || val !== 0;
this.tabActiveKey = val; this.tabActiveKey = val;
this.tabQueryJson = shouldSetRelation ? { this.tabQueryJson = shouldSetRelation ? {
[relationField]: currentTab.id [relationField]: currentTab.id
} : {}; } : {};
// 使用可选链操作符和空对象兜底
const search = this.$refs.searchForm?.allCondition() || {}; const search = this.$refs.searchForm?.allCondition() || {};
this.listQuery.queryJson = JSON.stringify({ this.listQuery.queryJson = JSON.stringify({
...search, ...search,
@@ -389,26 +572,14 @@
return newData return newData
}, },
sumbitSearchForm(data) { sumbitSearchForm(data) {
let queryJson = data || {}
this.searchFormData = data this.searchFormData = data
// 标签面板查询 this.listQuery.queryJson = data
if (this.columnData.tabConfig && this.columnData.tabConfig.on) {
this.tabQueryJson = {
[this.columnData.tabConfig.relationField]: this.tabList[this.tabActiveKey]?.id
};
queryJson = {
...queryJson,
...this.tabQueryJson
}
}
this.listQuery.queryJson = JSON.stringify(queryJson) !== '{}' ? JSON.stringify(queryJson) : ''
this.$refs.uDropdown.close(); this.$refs.uDropdown.close();
this.$nextTick(() => { this.$nextTick(() => {
this.list = []; this.list = [];
this.mescroll.resetUpScroll(); this.mescroll.resetUpScroll();
}) })
}, },
// 处理启用规则
customEnableRule(data, funcName) { customEnableRule(data, funcName) {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
return true return true
@@ -441,7 +612,8 @@
})) }))
}, },
handleSearchList() { handleSearchList() {
this.searchList = (this.$u.deepClone(this.columnData.searchList) || []).filter(o => !o.noShow) // 保留mock数据不被原有逻辑覆盖
this.searchList = this.searchList.filter(o => !o.noShow)
for (let i = 0; i < this.searchList.length; i++) { for (let i = 0; i < this.searchList.length; i++) {
const item = this.searchList[i] const item = this.searchList[i]
if (item.labelI18nCode) { if (item.labelI18nCode) {
@@ -457,59 +629,8 @@
if (this.config.webType == 4) config.label = item.label if (this.config.webType == 4) config.label = item.label
} }
if (Object.keys(this.searchFormData).length) this.listQuery.queryJson = JSON.stringify(this.searchFormData) if (Object.keys(this.searchFormData).length) this.listQuery.queryJson = JSON.stringify(this.searchFormData)
if (this.searchList.some(o => o.isKeyword)) {
const keywordItem = {
id: 'jnpfKeyword',
fullName: '关键词',
prop: 'jnpfKeyword',
label: this.$t('common.keyword'),
jnpfKey: 'input',
clearable: true,
placeholder: '请输入',
value: undefined,
__config__: {
jnpfKey: 'input'
},
};
this.searchList.unshift(keywordItem);
}
if (this.config.enableFlow && this.searchList.length) {
const flowStateItem = {
id: 'jnpfFlowState',
fullName: '状态',
prop: 'jnpfFlowState',
label: '状态',
jnpfKey: 'select',
placeholder: '请选择状态',
value: undefined,
options: this.useDefine.flowStatusList,
__config__: {
jnpfKey: 'select',
},
};
this.searchList.push(flowStateItem);
}
this.searchFormConf = this.$u.deepClone(this.searchList) this.searchFormConf = this.$u.deepClone(this.searchList)
}, },
handleSortList() {
this.sortOptions = [];
const sortList = this.sortList
for (let i = 0; i < sortList.length; i++) {
let ascItem = {
label: sortList[i].label + ' ' + this.$t('app.apply.ascendingOrder'),
value: sortList[i].prop,
sidx: sortList[i].prop,
sort: 'asc'
}
let descItem = {
label: sortList[i].label + ' ' + this.$t('app.apply.descendingOrder'),
value: '-' + sortList[i].prop,
sidx: sortList[i].prop,
sort: 'desc'
}
this.sortOptions.push(ascItem, descItem)
}
},
transformColumnList(columnList) { transformColumnList(columnList) {
let list = [] let list = []
for (let i = 0; i < columnList.length; i++) { for (let i = 0; i < columnList.length; i++) {
@@ -547,9 +668,8 @@
return list return list
}, },
setDefaultQuery() { setDefaultQuery() {
const defaultSortConfig = (this.columnData.defaultSortConfig || []).map(o => this.listQuery.desc = 'create_time';
(o.sort === 'desc' ? '-' : '') + o.field); this.listQuery.asc = '';
this.listQuery.sidx = defaultSortConfig.join(',')
}, },
setTableLoadFunc() { setTableLoadFunc() {
const JNPFTable = this.$refs.tableRef const JNPFTable = this.$refs.tableRef
@@ -562,7 +682,6 @@
if (!func) return if (!func) return
func.call(this, parameter) func.call(this, parameter)
}, },
//删除操作
handleClick(index) { handleClick(index) {
const item = this.list[index] const item = this.list[index]
if (!this.permission.btnPermission.includes('btn_remove')) return this.$u.toast("未开启删除权限") if (!this.permission.btnPermission.includes('btn_remove')) return this.$u.toast("未开启删除权限")
@@ -591,16 +710,13 @@
} }
}) })
}, },
//底部更多按钮
handleBottomMoreClick(type) { handleBottomMoreClick(type) {
this.showBottomMoreBtn = true this.showBottomMoreBtn = true
}, },
//更多按钮弹窗
handleMoreClick(index) { handleMoreClick(index) {
this.selectListIndex = index this.selectListIndex = index
this.showMoreBtn = true this.showMoreBtn = true
}, },
//底部按钮操作
bottomBtnConfirm(e) { bottomBtnConfirm(e) {
if (Array.isArray(e) && e.length) { if (Array.isArray(e) && e.length) {
const index = this.bottomCustomBtnsList[1].findIndex(item => item.value === e[0].value); const index = this.bottomCustomBtnsList[1].findIndex(item => item.value === e[0].value);
@@ -615,13 +731,11 @@
if (!this.selectItems.length && e.event.dataRequired) { if (!this.selectItems.length && e.event.dataRequired) {
return this.$u.toast('请选择一条数据') return this.$u.toast('请选择一条数据')
} }
// 当e是一个对象且包含event属性时
if (e.event.btnType == 2) this.handleScriptFunc(e.event, this.selectItems) if (e.event.btnType == 2) this.handleScriptFunc(e.event, this.selectItems)
if (e.event.btnType === 3) this.handleBottomBtnInterface(e.event); if (e.event.btnType === 3) this.handleBottomBtnInterface(e.event);
if (e.event.btnType == 4) this.handleLaunchFlow(e, this.selectItems) if (e.event.btnType == 4) this.handleLaunchFlow(e, this.selectItems)
} }
}, },
//底部自定义按钮接口操作
handleBottomBtnInterface(item) { handleBottomBtnInterface(item) {
const selectedItemsCopy = [...this.selectItems]; const selectedItemsCopy = [...this.selectItems];
const webType = this.config.webType; const webType = this.config.webType;
@@ -653,7 +767,6 @@
} }
}); });
}, },
// 自定义按钮事件
selectBtnconfirm(e) { selectBtnconfirm(e) {
var i = this.columnData.customBtnsList.findIndex((item) => { var i = this.columnData.customBtnsList.findIndex((item) => {
return item.value == e[0].value return item.value == e[0].value
@@ -661,14 +774,12 @@
const item = this.columnData.customBtnsList[i] const item = this.columnData.customBtnsList[i]
const row = this.list[this.selectListIndex] const row = this.list[this.selectListIndex]
const index = this.selectListIndex const index = this.selectListIndex
// 自定义启用规则判断
if (!this.customEnableRule(row, item.value)) return this.$u.toast('没有' + item.label + '权限') if (!this.customEnableRule(row, item.value)) return this.$u.toast('没有' + item.label + '权限')
if (item.event.btnType == 1) this.handlePopup(item.event, row) if (item.event.btnType == 1) this.handlePopup(item.event, row)
if (item.event.btnType == 2) this.handleScriptFunc(item.event, row, index) if (item.event.btnType == 2) this.handleScriptFunc(item.event, row, index)
if (item.event.btnType == 3) this.handleInterface(item.event, row) if (item.event.btnType == 3) this.handleInterface(item.event, row)
if (item.event.btnType == 4) this.handleLaunchFlow(item, [row]) if (item.event.btnType == 4) this.handleLaunchFlow(item, [row])
}, },
//自定义按钮发起流程
handleLaunchFlow(item, records) { handleLaunchFlow(item, records) {
const data = deepClone(item.event.launchFlow) const data = deepClone(item.event.launchFlow)
let dataList = []; let dataList = [];
@@ -688,7 +799,6 @@
this.$u.toast(res.msg) this.$u.toast(res.msg)
}); });
}, },
//自定义按钮弹窗操作
handlePopup(item, row) { handlePopup(item, row) {
this.handleListen() this.handleListen()
let data = { let data = {
@@ -703,7 +813,6 @@
url: '/pages/apply/customBtn/index?data=' + data url: '/pages/apply/customBtn/index?data=' + data
}) })
}, },
//自定义按钮JS操作
handleScriptFunc(item, row, index) { handleScriptFunc(item, row, index) {
const parameter = { const parameter = {
data: row, data: row,
@@ -715,7 +824,6 @@
if (!func) return if (!func) return
func.call(this, parameter) func.call(this, parameter)
}, },
//自定义按钮接口操作
handleInterface(item, row) { handleInterface(item, row) {
const handlerData = () => { const handlerData = () => {
getModelInfo(this.modelId, row[this.getModelInfo]).then(res => { getModelInfo(this.modelId, row[this.getModelInfo]).then(res => {
@@ -778,7 +886,7 @@
}, },
addPage() { addPage() {
this.handleListen() this.handleListen()
this.jumPage({}, '') this.jumPage({}, 'btn_add')
}, },
jumPage(item, btnType) { jumPage(item, btnType) {
if (!item.id && !item.flowState) btnType = 'btn_add' if (!item.id && !item.flowState) btnType = 'btn_add'
@@ -807,18 +915,11 @@
} else { } else {
const type = btnType == 'btn_detail' ? 'detail' : 'form' const type = btnType == 'btn_detail' ? 'detail' : 'form'
const currentMenu = encodeURIComponent(JSON.stringify(this.permission.formPermission)) const currentMenu = encodeURIComponent(JSON.stringify(this.permission.formPermission))
let btnType_ = this.permission.btnPermission.includes('btn_edit') ? 'btn_edit' : 'btn_add'
let enableEdit = this.customEnableRule(item, 'edit') let enableEdit = this.customEnableRule(item, 'edit')
let labelS = {} let labelS = {}
for (let i = 0; i < this.columnData.columnBtnsList.length; i++) {
const item = this.columnData.columnBtnsList[i]
if (item.value == 'edit') {
labelS[btnType_] = item.labelI18nCode ? this.$t(item.labelI18nCode) : item.label
}
}
const config = { const config = {
currentMenu, currentMenu,
btnType: btnType_, btnType,
list: this.list, list: this.list,
modelId: this.modelId, modelId: this.modelId,
menuId: this.menuId, menuId: this.menuId,
@@ -826,9 +927,11 @@
id: item.id || '', id: item.id || '',
index: item.index, index: item.index,
enableEdit, enableEdit,
labelS labelS,
name: this.config.name,
billNoPrefix: this.config.billNoPrefix
} }
const url = '/pages/apply/dynamicModel/' + type + '?config=' + const url = '/pages/apply/dynamicModelList/' + type + '?config=' +
this.jnpf.base64.encode(JSON.stringify(config)) this.jnpf.base64.encode(JSON.stringify(config))
uni.navigateTo({ uni.navigateTo({
url: url url: url
@@ -836,8 +939,8 @@
} }
}, },
goDetail(item) { goDetail(item) {
if (this.config.webType == 4) return
this.handleListen() this.handleListen()
return this.jumPage(item, 'btn_edit')
let hasDetail = this.permission.btnPermission.includes('btn_detail') let hasDetail = this.permission.btnPermission.includes('btn_detail')
let hasEdit = this.permission.btnPermission.includes('btn_edit') let hasEdit = this.permission.btnPermission.includes('btn_edit')
if (!hasDetail && !hasEdit) return if (!hasDetail && !hasEdit) return
@@ -856,14 +959,11 @@
}, },
cellClick(item) { cellClick(item) {
if (this.isPreview == '1') return this.$u.toast('功能预览不支持排序') if (this.isPreview == '1') return this.$u.toast('功能预览不支持排序')
const findIndex = this.sortValue.findIndex(o => o === item.value); this.sortValue = [item.value];
if (findIndex < 0) { this.selectedSort = {
const findLikeIndex = this.sortValue.findIndex(o => o.indexOf(item.sidx) > -1); field: item.field,
if (findLikeIndex > -1) this.sortValue.splice(findLikeIndex, 1) type: item.type
this.sortValue.push(item.value) };
} else {
this.sortValue.splice(findIndex, 1)
}
}, },
handleReset() { handleReset() {
this.searchFormData = {} this.searchFormData = {}
@@ -902,19 +1002,32 @@
}, },
handleSortReset() { handleSortReset() {
this.sortValue = [] this.sortValue = []
this.selectedSort = {};
this.listQuery.asc = '';
this.listQuery.desc = '';
}, },
handleSortSearch() { handleSortSearch() {
if (this.sortValue.length) { this.listQuery.asc = '';
this.listQuery.sidx = this.sortValue.join(',') this.listQuery.desc = '';
if (Object.keys(this.selectedSort).length > 0) {
const sortItem = this.selectedSort;
if (sortItem.type === 'asc') {
this.listQuery.asc = sortItem.field;
this.listQuery.desc = '';
} else { } else {
this.setDefaultQuery() this.listQuery.desc = sortItem.field;
this.listQuery.asc = '';
} }
} else {
this.setDefaultQuery();
}
console.log(this.listQuery, 'listQuery')
this.$refs.uDropdown.close(); this.$refs.uDropdown.close();
this.$nextTick(() => { this.$nextTick(() => {
this.list = []; this.list = [];
this.mescroll.resetUpScroll(); this.mescroll.resetUpScroll();
}) })
} },
} }
} }
</script> </script>
@@ -930,6 +1043,7 @@
width: 100%; width: 100%;
/* #endif */ /* #endif */
} }
:deep(.u-cell) { :deep(.u-cell) {
padding: 0rpx; padding: 0rpx;
height: 112rpx; height: 112rpx;

View File

@@ -3,69 +3,58 @@
<view class="list-box"> <view class="list-box">
<SwipeItem :list="list" :buttons="options" @action="actionClick" ref="swipeItem" :marginB="20"> <SwipeItem :list="list" :buttons="options" @action="actionClick" ref="swipeItem" :marginB="20">
<template v-slot="{ item }"> <template v-slot="{ item }">
<view class="item" @tap.stop="goDetail(item)" style="border: 1px solid #fff;"> <view class="item" @tap.stop="goDetail(item)">
<view class="u-m-b-10 checkbox_box" v-if="showCheckbox"> <view class="item-content">
<u-checkbox @change="checkboxChange($event,item)" v-model="item.checked" class="checkbox" <!-- 左侧信息区 -->
@tap.stop shape="circle"></u-checkbox> <view class="item-left">
<!-- 单号 + 普通标签核心修改区域 -->
<view class="item-row item-header">
<!-- 新增普通标签 -->
<view class="flow-tag">单号</view>
<text class="content unit-name">{{ item.billNo }}</text>
</view> </view>
<view class="item-cell" v-for="(column,i) in columnList" :key="i"> <view class="item-row">
<template v-if="column.jnpfKey != 'table'"> <text class="label">申请单位:</text>
<text class="item-cell-label">{{column.label}}:</text> <text class="content unit-name">{{ item.applyDepName }}</text>
<text class="item-cell-content"
v-if="['calculate','inputNumber'].includes(column.jnpfKey)">
{{toThousands(item[column.prop],column)}}
</text>
<text class="item-cell-content text-primary"
v-else-if="column.jnpfKey == 'relationForm'"
@click.stop="relationFormClick(item,column)">
{{item[column.prop]}}
</text>
<view class="item-cell-content" v-else-if="column.jnpfKey == 'sign'">
<JnpfSign v-model="item[column.prop]" align="left" detailed />
</view> </view>
<view class="item-cell-content" v-else-if="column.jnpfKey == 'signature'"> <view class="item-row">
<JnpfSignature v-model="item[column.prop]" align="left" detailed /> <text class="label">申请人员:</text>
<text class="content">{{ item.applyUser}}</text>
</view> </view>
<view class="item-cell-content" v-else-if="column.jnpfKey == 'uploadImg'" @click.stop> <view class="item-row">
<JnpfUploadImg v-model="item[column.prop]" detailed simple <text class="label">创建时间:</text>
v-if="item[column.prop]&&item[column.prop].length" /> <text class="content">{{ formatTime(item.create_time) }}</text>
</view> </view>
<!-- #ifndef APP-HARMONY -->
<view class="item-cell-content" v-else-if="column.jnpfKey == 'uploadFile'" @click.stop>
<JnpfUploadFile v-model="item[column.prop]" detailed
v-if="item[column.prop]&&item[column.prop].length" align="left" />
</view> </view>
<!-- #endif -->
<!-- #ifdef APP-HARMONY --> <!-- 右侧状态图 -->
<view class="item-cell-content" v-else-if="column.jnpfKey == 'uploadFile'" @click.stop> <view class="item-right">
<JnpfUploadFileH v-model="item[column.prop]" detailed <image
v-if="item[column.prop]&&item[column.prop].length" align="left" /> v-if="item.approveStatusName == '未审核'"
src="../../img/UNAPPROVED.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '审批中'"
src="../../img/APPROVING.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '已审批'"
src="../../img/APPROVED.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '已驳回'"
src="../../img/REJECTED.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '已作废'"
src="../../img/INVALID.png"
mode="widthFix"
class="status-img" />
</view> </view>
<!-- #endif -->
<view class="item-cell-content" v-else-if="column.jnpfKey == 'rate'">
<JnpfRate v-model="item[column.prop]" :max="column.count"
:allowHalf="column.allowHalf" disabled />
</view>
<view class="item-cell-content item-cell-slider" v-else-if="column.jnpfKey == 'slider'">
<JnpfSlider v-model="item[column.prop]" :min="column.min" :max="column.max"
:step="column.step" disabled />
</view>
<view class="item-cell-content" v-else-if="column.jnpfKey == 'input'">
<JnpfInput v-model="item[column.prop]" detailed showOverflow
:useMask="column.useMask" :maskConfig="column.maskConfig" align='left' />
</view>
<text class="item-cell-content" v-else>{{item[column.prop]}}</text>
</template>
<tableCell v-else @click.stop class="tableCell" ref="tableCell" :label="column.label"
:childList="item[column.prop]" :children="column.children" :pageLen="3"
@cRelationForm="relationFormClick" :key="item.id+i">
</tableCell>
</view>
<view class="item-cell" v-if="config.enableFlow==1">
<text class="item-cell-label">审批状态:</text>
<text :style="{color:useDefine.getFlowStatusColor(item.flowState)}">
{{useDefine.getFlowStatusContent(item.flowState)}}
</text>
</view> </view>
</view> </view>
</template> </template>
@@ -75,9 +64,8 @@
</template> </template>
<script> <script>
import { // 脚本部分无需修改,保持原逻辑
useDefineSetting import { useDefineSetting } from '@/utils/useDefineSetting';
} from '@/utils/useDefineSetting';
import tableCell from '../tableCell.vue' import tableCell from '../tableCell.vue'
import SwipeItem from "@/components/SwipeItem/index" import SwipeItem from "@/components/SwipeItem/index"
export default { export default {
@@ -86,7 +74,14 @@
tableCell, tableCell,
SwipeItem SwipeItem
}, },
props: ['config', 'list', 'columnList', 'actionOptions', 'showSelect', 'checkedAll', 'modelValue', 'isMoreBtn', props: [
'config',
'list',
'actionOptions',
'showSelect',
'checkedAll',
'modelValue',
'isMoreBtn',
'customBtnsList' 'customBtnsList'
], ],
data() { data() {
@@ -121,28 +116,41 @@
} }
}, },
methods: { methods: {
/* 关联表单操作 */ formatTime(timestamp) {
if (!timestamp) return '-';
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
getStatusClass(statusName) {
switch (statusName) {
case '已审批':
return 'status-approved';
case '未审核':
return 'status-unchecked';
default:
return 'status-other';
}
},
relationFormClick(item, column) { relationFormClick(item, column) {
this.$emit('relationFormClick', item, column) this.$emit('relationFormClick', item, column)
}, },
/* 跳转详情 */
goDetail(item) { goDetail(item) {
this.$emit('goDetail', item) this.$emit('goDetail', item)
}, },
actionClick(data) { actionClick(data) {
const { const { index, value } = data
index,
value
} = data
if (value === 'remove') return this.$emit('handleClick', index) if (value === 'remove') return this.$emit('handleClick', index)
if (value === 'more') return this.$emit('handleMoreClick', index) if (value === 'more') return this.$emit('handleMoreClick', index)
}, },
/* 列表选择框 */
checkboxChange(e, item) { checkboxChange(e, item) {
const isSelected = e.value; const isSelected = e.value;
const selectedItemsSet = new Set(this.selectData.map(selectedItem => { const selectedItemsSet = new Set(this.selectData.map(selectedItem => selectedItem.id));
return selectedItem.id;
}));
if (isSelected) { if (isSelected) {
selectedItemsSet.add(item.id); selectedItemsSet.add(item.id);
} else { } else {
@@ -153,67 +161,113 @@
}); });
this.$emit('selectCheckbox', this.selectData); this.$emit('selectCheckbox', this.selectData);
}, },
/* 全部选中 */
handleCheckAll() { handleCheckAll() {
this.selectData = [] this.selectData = []
if (this.checkedAll) this.selectData = this.list.filter(o => o.checked) if (this.checkedAll) this.selectData = this.list.filter(o => o.checked)
this.$emit('selectCheckbox', this.selectData) this.$emit('selectCheckbox', this.selectData);
},
/* 千分位操作 */
toThousands(val, column) {
if (val) {
let valList = val.toString().split('.')
let num = Number(valList[0])
let newVal = column.thousands ? num.toLocaleString() : num
return valList[1] ? newVal + '.' + valList[1] : newVal
} else {
return val
}
} }
} }
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.list { .list {
.list_box { background-color: #f0f2f6;
.list-box {
.item { .item {
padding: 0; background: #fff;
border-radius: 12rpx;
.checkbox_box { margin-bottom: 20rpx;
width: 60rpx; padding: 20rpx;
height: 46rpx; box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
position: relative; position: relative;
.checkbox { .item-content {
position: absolute;
top: 6rpx;
left: 8rpx;
z-index: 9999;
}
}
}
}
}
.right-option-box {
display: flex; display: flex;
width: max-content; align-items: flex-start; /* 改为顶部对齐,避免标签错位 */
justify-content: space-between;
}
.right-option { .item-left {
width: 144rpx; flex: 1;
height: 100%; }
font-size: 16px;
.item-row {
display: flex;
align-items: center;
margin-bottom: 8rpx; /* 调整行间距 */
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 26rpx;
color: #909399;
min-width: 140rpx;
margin-right: 8rpx;
}
.content {
font-size: 28rpx;
color: #303133;
}
}
// 单号+标签的布局样式(核心新增)
.item-header {
align-items: center;
gap: 10rpx; // 标签、单号、单号值之间的间距
// 普通标签样式
.flow-tag {
font-size: 22rpx;
color: #1677ff;
background: #e8f3ff;
padding: 2rpx 8rpx;
border-radius: 4rpx;
font-weight: 500;
}
// 单号文本样式
.bill-label {
font-size: 26rpx;
color: #303133;
}
}
// 流程名称样式(对应图中的“管理员的动火审批流程”)
.flow-name {
font-size: 28rpx;
color: #1E293B;
font-weight: 500;
}
.status-tag {
padding: 4rpx 16rpx;
border-radius: 20rpx;
font-size: 26rpx;
color: #fff; color: #fff;
background-color: #dd524d; &.status-approved {
background-color: #67c23a;
}
&.status-unchecked {
background-color: #e6a23c;
}
&.status-other {
background-color: #909399;
}
}
// 右侧状态图样式
.item-right {
width: 100rpx;
height: 160rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.status-img {
width: 100%;
height: auto;
object-fit: contain;
}
}
} }
.more-option {
background-color: #1890ff;
} }
} }
</style> </style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<u-form :model="formData" ref="dataForm" :errorType="['toast']" label-position="left" label-width="150"> <u-form :model="formData" ref="dataForm" :errorType="['toast']" label-position="left" label-width="150">
<u-form-item :label="item.label" :prop="item.id" v-for="(item, i) in formConfCopy" :key="i"> <u-form-item :label="item.label" :prop="item.id" v-for="(item, i) in formConfCopy" :key="`${item.id}-${i}`">
<JnpfInput v-if="useInputList.includes(item.__config__.jnpfKey)" input-align='right' <JnpfInput v-if="useInputList.includes(item.__config__.jnpfKey)" input-align='right'
v-model="formData[item.id]" :placeholder="textPrefix+item.label" clearable /> v-model="formData[item.id]" :placeholder="textPrefix+item.label" clearable />
<template v-if="['inputNumber','calculate'].includes(item.__config__.jnpfKey)"> <template v-if="['inputNumber','calculate'].includes(item.__config__.jnpfKey)">
@@ -12,11 +12,19 @@
<template v-if="['rate', 'slider'].includes(item.__config__.jnpfKey)"> <template v-if="['rate', 'slider'].includes(item.__config__.jnpfKey)">
<JnpfNumberRange v-model="formData[item.id]" :precision="item.allowHalf ? 1 : 0" /> <JnpfNumberRange v-model="formData[item.id]" :precision="item.allowHalf ? 1 : 0" />
</template> </template>
<JnpfSelect v-if="useSelectList.includes(item.__config__.jnpfKey)" v-model="formData[item.id]" <JnpfSelect
:placeholder="selectPrefix+item.label" :options="item.options" :props="item.props" v-if="useSelectList.includes(item.__config__.jnpfKey)"
:multiple="item.searchMultiple" :key="key" filterable /> v-model="formData[item.id]"
:placeholder="selectPrefix+item.label"
:options="item.options || []"
:props="item.props || { label: 'label', value: 'value' }"
:multiple="!!item.searchMultiple"
:key="`select-${item.id}-${key}`"
filterable
/>
<JnpfCascader v-if="item.__config__.jnpfKey==='cascader'" v-model="formData[item.id]" <JnpfCascader v-if="item.__config__.jnpfKey==='cascader'" v-model="formData[item.id]"
:placeholder="selectPrefix+item.label" :options="item.options" :props="item.props" filterable :placeholder="selectPrefix+item.label" :options="item.options || []" :props="item.props" filterable
:showAllLevels="item.showAllLevels" :multiple="item.searchMultiple" /> :showAllLevels="item.showAllLevels" :multiple="item.searchMultiple" />
<JnpfAutoComplete v-if="item.__config__.jnpfKey==='autoComplete'" v-model="formData[item.id]" <JnpfAutoComplete v-if="item.__config__.jnpfKey==='autoComplete'" v-model="formData[item.id]"
:interfaceName="item.interfaceName" :placeholder="selectPrefix+item.label" :interfaceName="item.interfaceName" :placeholder="selectPrefix+item.label"
@@ -44,10 +52,12 @@
<JnpfUsersSelect v-if="item.__config__.jnpfKey==='usersSelect'" v-model="formData[item.id]" <JnpfUsersSelect v-if="item.__config__.jnpfKey==='usersSelect'" v-model="formData[item.id]"
:placeholder="selectPrefix+item.label" :clearable="item.clearable" /> :placeholder="selectPrefix+item.label" :clearable="item.clearable" />
<JnpfTreeSelect v-if="item.__config__.jnpfKey==='treeSelect'" v-model="formData[item.id]" <JnpfTreeSelect v-if="item.__config__.jnpfKey==='treeSelect'" v-model="formData[item.id]"
:options="item.options" :props="item.props" :placeholder="selectPrefix+item.label" filterable :options="item.options || []" :props="item.props" :placeholder="selectPrefix+item.label" filterable
:multiple="item.searchMultiple" /> :multiple="item.searchMultiple" />
<JnpfAreaSelect v-if="item.__config__.jnpfKey==='areaSelect'" v-model="formData[item.id]" <JnpfAreaSelect v-if="item.__config__.jnpfKey==='areaSelect'" v-model="formData[item.id]"
:placeholder="selectPrefix+item.label" :level="item.level" :multiple="item.searchMultiple" /> :placeholder="selectPrefix+item.label" :level="item.level" :multiple="item.searchMultiple" />
<!-- 日期/时间选择 -->
<template v-if="useDateList.includes(item.__config__.jnpfKey)"> <template v-if="useDateList.includes(item.__config__.jnpfKey)">
<JnpfDatePicker v-model="formData[item.id]" :format='item.format' v-if="item.__config__.isFromParam" /> <JnpfDatePicker v-model="formData[item.id]" :format='item.format' v-if="item.__config__.isFromParam" />
<JnpfDateRange v-model="formData[item.id]" :format='item.format' v-else /> <JnpfDateRange v-model="formData[item.id]" :format='item.format' v-else />
@@ -58,41 +68,71 @@
</u-form> </u-form>
</template> </template>
<script> <script>
import {
getDictionaryDataSelector,
getDataInterfaceRes
} from '@/api/common'
const dyOptionsList = ['radio', 'checkbox', 'select', 'cascader', 'treeSelect']; const dyOptionsList = ['radio', 'checkbox', 'select', 'cascader', 'treeSelect'];
const useSelectList = ['radio', 'checkbox', 'select']; const useSelectList = ['radio', 'checkbox', 'select'];
const useInputList = ['input', 'textarea', 'text', 'link', 'billRule', 'location']; const useInputList = ['input', 'textarea', 'text', 'link', 'billRule', 'location'];
const useDateList = ['createTime', 'modifyTime', 'datePicker', 'dateCalculate']; const useDateList = ['createTime', 'modifyTime', 'datePicker', 'dateCalculate'];
const useArrList = ['cascader', 'address', 'numInput', 'calculate', ...useDateList] const useArrList = ['cascader', 'address', 'numInput', 'calculate', ...useDateList]
export default { export default {
props: ['formConf', 'webType', 'searchFormData'], props: ['formConf', 'webType', 'searchFormData'],
data() { data() {
const data = { return {
useInputList, useInputList,
useDateList, useDateList,
useSelectList, useSelectList,
formConfCopy: this.$u.deepClone(this.formConf), formConfCopy: [], // 初始化为空,避免提前克隆
formData: this.$u.deepClone(this.searchFormData), formData: {},
key: +new Date(), key: +new Date(),
textPrefix: this.$t('common.inputTextPrefix') + ' ', textPrefix: this.$t('common.inputTextPrefix') + ' ',
selectPrefix: this.$t('common.chooseTextPrefix') + ' ', selectPrefix: this.$t('common.chooseTextPrefix') + ' ',
} }
this.initRelationForm(data.formConfCopy)
this.initFormData(data.formConfCopy, data.formData)
return data
}, },
// 核心深度监听formConf变化确保数据同步
watch: { watch: {
searchFormData(val) { // 监听父组件传递的formConf深度+立即执行)
this.formData = val formConf: {
deep: true,
immediate: true,
handler(newVal) {
if (!newVal) return;
// 重新克隆最新的配置
this.formConfCopy = this.$u.deepClone(newVal);
// 延迟初始化确保DOM更新
this.$nextTick(() => {
this.initRelationForm(this.formConfCopy);
// 初始化时彻底跳过接口请求
this.initFormData(this.formConfCopy, this.formData);
});
}
},
// 监听搜索数据变化
searchFormData: {
deep: true,
immediate: true,
handler(newVal) {
this.formData = this.$u.deepClone(newVal);
}
} }
}, },
methods: { methods: {
/**
* 初始化表单数据(彻底跳过接口请求)
*/
initFormData(componentList, formData) { initFormData(componentList, formData) {
console.log('Parser接收的配置:', componentList);
if (!componentList || !Array.isArray(componentList)) return;
componentList.forEach(cur => { componentList.forEach(cur => {
const config = cur.__config__ const config = cur.__config__ || {};
if (cur.id && formData[cur.id] === undefined) {
// 初始化表单默认值
formData[cur.id] = cur.value || (cur.searchMultiple ? [] : '');
}
// 原接口逻辑全部注释,彻底跳过
/*
if (dyOptionsList.indexOf(config.jnpfKey) > -1) { if (dyOptionsList.indexOf(config.jnpfKey) > -1) {
if (config.dataType === 'dictionary' && config.dictionaryType) { if (config.dataType === 'dictionary' && config.dictionaryType) {
getDictionaryDataSelector(config.dictionaryType).then(res => { getDictionaryDataSelector(config.dictionaryType).then(res => {
@@ -113,51 +153,71 @@
}) })
} }
} }
}) */
});
// 更新key强制刷新组件
this.key = +new Date();
}, },
/**
* 初始化关联表单配置
*/
initRelationForm(componentList) { initRelationForm(componentList) {
if (!componentList) return;
componentList.forEach(cur => { componentList.forEach(cur => {
const config = cur.__config__ const config = cur.__config__ || {};
if (config.jnpfKey == 'relationFormAttr' || config.jnpfKey == 'popupAttr') { if (config.jnpfKey == 'relationFormAttr' || config.jnpfKey == 'popupAttr') {
const relationKey = cur.relationField.split("_jnpfTable_")[0] const relationKey = cur.relationField?.split("_jnpfTable_")[0];
if (!relationKey) return;
componentList.forEach(item => { componentList.forEach(item => {
const noVisibility = Array.isArray(item.__config__.visibility) && !item const noVisibility = Array.isArray(item.__config__?.visibility) && !item.__config__.visibility.includes('app');
.__config__.visibility.includes('app') if ((relationKey == item.id) && (noVisibility || !!item.__config__?.noShow)) {
if ((relationKey == item.id) && (noVisibility || !!item.__config__ cur.__config__.noShow = true;
.noShow)) {
cur.__config__.noShow = true
} }
}) });
} }
if (cur.__config__.children && cur.__config__.children.length) this.initRelationForm(cur if (cur.__config__?.children && cur.__config__.children.length) {
.__config__.children) this.initRelationForm(cur.__config__.children);
}) }
});
}, },
/**
* 获取表单数据(空值处理)
*/
allCondition() { allCondition() {
for (let key in this.formData) { const result = {...this.formData};
if (this.formData[key] !== 0 && !this.formData[key]) this.formData[key] = undefined; for (let key in result) {
if (this.formData[key] && Array.isArray(this.formData[key]) && !this.formData[key] if (result[key] === 0) continue;
.length) { if (!result[key] || (Array.isArray(result[key]) && result[key].length === 0)) {
this.formData[key] = undefined delete result[key];
} }
} }
return this.formData return result;
}, },
/**
* 提交表单
*/
submitForm() { submitForm() {
if (!this.$refs.dataForm) {
this.$emit('submit', this.allCondition());
return;
}
this.$refs.dataForm.validate(valid => { this.$refs.dataForm.validate(valid => {
if (!valid) return if (!valid) return;
for (let key in this.formData) { this.$emit('submit', this.allCondition());
if (this.formData[key] !== 0 && !this.formData[key]) this.formData[key] = undefined; });
if (this.formData[key] && Array.isArray(this.formData[key]) && !this.formData[key]
.length) {
this.formData[key] = undefined
}
}
this.$emit('submit', this.formData)
})
}, },
/**
* 重置表单
*/
resetForm() { resetForm() {
this.$refs.dataForm.resetFields() if (this.$refs.dataForm) {
this.$refs.dataForm.resetFields();
}
} }
} }
} }

View File

@@ -240,6 +240,7 @@
}, },
getConfigData() { getConfigData() {
this.loading = true; this.loading = true;
console.log(this.modelId,'modelId-------')
getConfigData(this.modelId).then((res) => { getConfigData(this.modelId).then((res) => {
if (res.code !== 200 || !res.data) { if (res.code !== 200 || !res.data) {
uni.showToast({ uni.showToast({

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="dynamicModel-v"> <view class="dynamicModel-v">
<Form v-if="webType == 1" :config="config" :modelId="modelId" :isPreview="isPreview" /> <!-- <Form :config="config" :modelId="modelId" :isPreview="isPreview" /> -->
<List v-if="webType == 2 || webType == 4" :config="config" :modelId="modelId" :isPreview="isPreview" <List :config="config" :modelId="modelId" :isPreview="isPreview"
:title="title" :menuId="menuId" ref="List" /> :title="title" :menuId="menuId" ref="List" />
</view> </view>
</template> </template>
@@ -18,6 +18,7 @@
import { import {
useBaseStore useBaseStore
} from '@/store/modules/base' } from '@/store/modules/base'
import { computed } from "vue";
const baseStore = useBaseStore() const baseStore = useBaseStore()
export default { export default {
@@ -41,18 +42,18 @@
}; };
}, },
onLoad(obj) { onLoad(obj) {
baseStore.getDictionaryDataAll() // baseStore.getDictionaryDataAll()
this.config = JSON.parse(this.jnpf.base64.decode(obj.config)) || {}; this.config = JSON.parse(this.jnpf.base64.decode(obj.config)) || {};
this.isPreview = this.config.isPreview || false; this.isPreview = this.config.isPreview || false;
this.enableFlow = this.config.type === 9 ? 1 : 0; this.enableFlow = this.config.type === 9 ? 1 : 0;
this.title = this.config.fullName || ""; this.title = this.config.name || "";
this.menuId = this.config.id || ""; this.modelId = this.config.id || "";
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: this.title, title: this.title,
}); });
if (!this.enableFlow) return this.getConfigData(); // if (!this.enableFlow) return this.getConfigData();
this.flowId = this.config.moduleId this.flowId = this.config.moduleId
this.getModelId() // this.getModelId()
}, },
methods: { methods: {
// 获取流程版本ID和发起节点表单ID // 获取流程版本ID和发起节点表单ID
@@ -60,7 +61,7 @@
getFlowStartFormId(this.flowId).then(res => { getFlowStartFormId(this.flowId).then(res => {
if (!res.data || !res.data.formId) return; if (!res.data || !res.data.formId) return;
this.config.moduleId = res.data.formId this.config.moduleId = res.data.formId
this.getConfigData(); // this.getConfigData();
}) })
}, },
getConfigData() { getConfigData() {

View File

@@ -0,0 +1,75 @@
import {
deteleModel
} from '@/api/apply/visualDev'
export default {
data() {
return {
slide: '',
slide2: '',
checkedAll: false,
ids: [],
showTop: false,
}
},
methods: {
/* 批量删除 */
batchDelete() {
if (!this.selectItems.length) {
return this.$u.toast('请选择一条数据')
}
uni.showModal({
title: '提示',
content: '删除后数据无法恢复',
success: (res) => {
if (res.confirm) {
const uniqueIds = new Set();
this.selectItems.forEach(item => {
uniqueIds.add(item.id);
});
const ids = [...uniqueIds];
let data = {
flowId: this.config.flowId,
ids
};
deteleModel(data, this.modelId).then(res => {
this.selectItems = [];
this.$u.toast(res.msg)
this.mescroll.resetUpScroll()
})
}
}
})
},
openBatchOperate() {
this.showTop = !this.showTop
if (this.showTop) {
this.slide = 'slide-up'
this.slide2 = 'slide-up2'
}
},
checkAll() {
this.checkedAll = !this.checkedAll
this.list = this.list.map(o => ({
...o,
checked: false
}))
if (this.checkedAll) {
this.list = this.list.map(o => ({
...o,
checked: true
}))
}
},
cancel() {
this.list = this.list.map(o => ({
...o,
checked: false
}))
this.showTop = false
this.checkedAll = false
this.$nextTick(() => {
this.$refs.list.handleCheckAll()
})
}
}
}

View File

@@ -0,0 +1,596 @@
<template>
<view :class="{'item-card':config.jnpfKey==='card'}"
v-if="!config.noShow && (!config.visibility || (Array.isArray(config.visibility) && config.visibility.includes('app')))">
<template v-if="config.layout==='colFormItem'">
<JnpfText v-if="config.jnpfKey=='text'" :content="item.content" :textStyle="item.textStyle" />
<JnpfDivider v-else-if="config.jnpfKey==='divider'" :content="item.content" />
<JnpfGroupTitle v-else-if="config.jnpfKey=='groupTitle'" :content="item.content"
:content-position="item.contentPosition" :helpMessage="item.helpMessage" @groupIcon="clickIcon(item)" />
<u-form-item v-else-if="config.jnpfKey==='popupSelect' || config.jnpfKey==='relationForm'"
:label="realLabel" :prop="item.__vModel__" class="popup-select" :label-width="labelWidth"
:left-icon="leftIcon" :left-icon-style="{'color':'#a8aaaf'}" @clickIcon="clickIcon(item)">
<view class="detail-text-box" v-if="config.jnpfKey==='popupSelect'">
<view class="jnpf-detail-text">
{{formData[item.__vModel__]}}
</view>
<DisplayList v-if="Object.keys(extraObj).length" :extraObj="extraObj"
:extraOptions="item.extraOptions">
</DisplayList>
</view>
<view class="detail-text-box" @click.native="toDetail(item)" v-if="config.jnpfKey==='relationForm'">
<view class="jnpf-detail-text" style="color:rgb(41, 121, 255)">
{{formData[item.__vModel__]}}
</view>
<DisplayList v-if="Object.keys(extraObj).length" :extraObj="extraObj"
:extraOptions="item.extraOptions">
</DisplayList>
</view>
</u-form-item>
<u-form-item v-else :label="realLabel" :prop="item.__vModel__" :label-width="labelWidth"
:left-icon="leftIcon" :left-icon-style="{'color':'#a8aaaf'}" @clickIcon="clickIcon(item)">
<JnpfUploadImg v-if="config.jnpfKey==='uploadImg'" v-model="config.defaultValue" detailed />
<!-- #ifndef APP-HARMONY -->
<JnpfUploadFile v-else-if="config.jnpfKey=='uploadFile'" v-model="config.defaultValue" detailed />
<!-- #endif -->
<!-- #ifdef APP-HARMONY -->
<JnpfUploadFileH v-else-if="config.jnpfKey=='uploadFile'" v-model="config.defaultValue" detailed />
<!-- #endif -->
<JnpfColorPicker v-else-if="config.jnpfKey==='colorPicker'" v-model="config.defaultValue"
:colorFormat="item.colorFormat" disabled />
<JnpfRate v-else-if="config.jnpfKey==='rate'" v-model="config.defaultValue" :max="item.count"
:allowHalf="item.allowHalf" disabled />
<JnpfEditor v-else-if="config.jnpfKey==='editor'" v-model="config.defaultValue" detailed />
<JnpfBarcode v-else-if="config.jnpfKey=='barcode'" :staticText="item.staticText" :width="item.width"
:height="item.height" :format="item.format" :dataType="item.dataType" :lineColor="item.lineColor"
:background="item.background" :relationField="item.relationField+'_id'" :formData="formData" />
<JnpfQrcode v-else-if="config.jnpfKey=='qrcode'" :staticText="item.staticText" :width="item.width"
:dataType="item.dataType" :colorDark="item.colorDark" :colorLight="item.colorLight"
:relationField="item.relationField+'_id'" :formData="formData" />
<JnpfInputNumber v-else-if="config.jnpfKey=='inputNumber'" v-model="config.defaultValue"
:step='item.step' :max='item.max||999999999999999' :min='item.min||-999999999999999'
:disabled="item.disabled" :placeholder="item.placeholder" :isAmountChinese="item.isAmountChinese"
:thousands="item.thousands" :addonAfter="item.addonAfter" :addonBefore="item.addonBefore"
:controls="item.controls" :precision="item.precision" detailed />
<JnpfCalculate v-else-if="config.jnpfKey==='calculate'" :expression='item.expression'
:vModel='item.__vModel__' :config='config' :formData='formData' v-model="config.defaultValue"
:precision="item.precision" :isAmountChinese="item.isAmountChinese" :thousands="item.thousands"
:roundType="item.roundType" :dateCalConfig="item.dateCalConfig" :type="item.type" />
<JnpfDateCalculate v-else-if="config.jnpfKey==='dateCalculate'" :expression='item.expression'
:vModel='item.__vModel__' :config='config' :formData='formData' v-model="config.defaultValue"
:startRelationField="item.startRelationField" :startTimeType="item.startTimeType"
:startTimeValue="item.startTimeValue" :format="item.format" />
<JnpfLink v-else-if="config.jnpfKey=='link'" :content="item.content" :href="item.href"
:target='item.target' :textStyle="item.textStyle" />
<JnpfAlert v-else-if="config.jnpfKey=='alert'" :type="item.type" :title="item.title"
:tagIcon='item.tagIcon' :showIcon="item.showIcon" :closable="item.closable"
:description="item.description" :closeText="item.closeText" />
<JnpfButton v-else-if="config.jnpfKey=='button'" :buttonText="item.buttonText" :align="item.align"
:type="item.type" :disabled="item.disabled" />
<JnpfSlider v-else-if="config.jnpfKey=='slider'" v-model="config.defaultValue" :step="item.step"
:min="item.min||0" :max="item.max||100" disabled />
<JnpfSign v-else-if="config.jnpfKey=='sign'" v-model="config.defaultValue" detailed />
<JnpfSignature v-else-if="config.jnpfKey=='signature'" v-model="config.defaultValue" detailed />
<JnpfLocation v-else-if="config.jnpfKey=='location'" v-model="config.defaultValue"
:enableLocationScope="item.enableLocationScope" detailed />
<!--end labelwidth=0-->
<template v-else>
<JnpfInput v-if="config.jnpfKey=='input'" v-model="config.defaultValue" detailed
:useMask="item.useMask" :maskConfig="item.maskConfig" :addonBefore="item.addonBefore"
:addonAfter="item.addonAfter" />
<view class="jnpf-detail-text" v-else>{{ getValue(item) }}</view>
</template>
</u-form-item>
</template>
<template v-else>
<view class="jnpf-card" v-if="config.jnpfKey==='card'||config.jnpfKey==='row'">
<view class="jnpf-card-cap u-line-1 u-flex" v-if="item.header" @click="clickIcon(item)">
{{item.header}}
<u-icon :name="config.tipLabel? 'question-circle-fill':''" class="u-m-l-10" color="#a0acb7" />
</view>
<Item v-for="(child, index) in config.children" :key="config.renderKey+index" :itemData="child"
:formConf="formConf" :formData="formData" @toDetail="toDetail" @clickIcon='clickIcon' />
</view>
<template v-if="config.jnpfKey==='table'">
<view class="jnpf-table">
<view class="jnpf-table-title u-line-1" @click="clickIcon(item)">
{{config.label}}
<u-icon v-if="config.tipLabel" :name="'question-circle-fill'" class="u-m-l-10"
color="#a0acb7" />
</view>
<view v-for="(column,columnIndex) in config.defaultValue" :key="columnIndex">
<view class="jnpf-table-item-title">
<view class="jnpf-table-item-title-num">({{columnIndex+1}})</view>
</view>
<view class="form-item-box" v-for="(childItem,cIndex) in config.children" :key="cIndex">
<u-form-item :label="childItem.__config__.showLabel?childItem.__config__.label:''"
:label-width="childItem.__config__.labelWidth ? childItem.__config__.labelWidth * 1.5 : undefined"
@clickIcon="clickIcon(childItem)"
:left-icon='childItem.__config__.tipLabel &&childItem.__config__.showLabel&& childItem.__config__.label? "question-circle-fill":""'
:left-icon-style="{'color':'#a0acb7'}"
v-if="!childItem.__config__.noShow&&(!childItem.__config__.visibility|| (Array.isArray(childItem.__config__.visibility) && childItem.__config__.visibility.includes('app')))">
<template
v-if="['relationFormAttr','popupAttr'].includes(childItem.__config__.jnpfKey)">
<view class="jnpf-detail-text" v-if="!childItem.__vModel__">
{{ column[childItem.relationField.split('_jnpfTable_')[0]+'_'+childItem.showField] }}
</view>
<view class="jnpf-detail-text" v-else>
{{column[childItem.__vModel__]}}
</view>
</template>
<view v-else-if="childItem.__config__.jnpfKey==='relationForm'" class="jnpf-detail-text"
style="color:rgb(41, 121, 255)"
@click.native="toTableDetail(childItem,column[childItem.__vModel__+'_id'])">
{{column[childItem.__vModel__]}}
</view>
<JnpfSign v-else-if="childItem.__config__.jnpfKey=='sign'"
v-model="column[childItem.__vModel__]" detailed />
<JnpfSignature v-else-if="childItem.__config__.jnpfKey=='signature'"
v-model="column[childItem.__vModel__]" detailed />
<JnpfLocation v-else-if="childItem.__config__.jnpfKey=='location'"
v-model="column[childItem.__vModel__]"
:enableLocationScope="item.enableLocationScope" detailed />
<!-- #ifndef APP-HARMONY -->
<JnpfUploadFile v-else-if="childItem.__config__.jnpfKey==='uploadFile'"
v-model="column[childItem.__vModel__]" detailed />
<!-- #endif -->
<!-- #ifdef APP-HARMONY -->
<JnpfUploadFileH v-else-if="childItem.__config__.jnpfKey==='uploadFile'"
v-model="column[childItem.__vModel__]" detailed />
<!-- #endif -->
<JnpfUploadImg v-else-if="childItem.__config__.jnpfKey==='uploadImg'"
v-model="column[childItem.__vModel__]" detailed />
<JnpfInputNumber v-else-if="childItem.__config__.jnpfKey=='inputNumber'"
v-model="column[childItem.__vModel__]" :step='childItem.step' :max='childItem.max'
:min='childItem.min' :disabled="childItem.disabled"
:placeholder="childItem.placeholder" :isAmountChinese="childItem.isAmountChinese"
:thousands="childItem.thousands" :addonAfter="childItem.addonAfter"
:addonBefore="childItem.addonBefore" :controls="childItem.controls"
:precision="childItem.precision" detailed />
<JnpfCalculate v-else-if="childItem.__config__.jnpfKey==='calculate'"
:expression='childItem.expression' :vModel='childItem.__vModel__'
:config='childItem.__config__' :formData='formData' :roundType="childItem.roundType"
:dateCalConfig="childItem.dateCalConfig" :type="childItem.type"
v-model="column[childItem.__vModel__]" :precision="childItem.precision"
:isAmountChinese="childItem.isAmountChinese" :thousands="childItem.thousands"
:rowIndex="columnIndex" />
<JnpfDateCalculate v-else-if="childItem.__config__.jnpfKey==='dateCalculate'"
:expression='childItem.expression' :vModel='childItem.__vModel__'
:config='childItem.__config__' :formData='formData'
v-model="column[childItem.__vModel__]"
:startRelationField="childItem.startRelationField"
:startTimeType="childItem.startTimeType" :startTimeValue="childItem.startTimeValue"
:format="childItem.format" :rowIndex="columnIndex" />
<JnpfRate v-else-if="childItem.__config__.jnpfKey==='rate'" :max="childItem.count"
v-model="column[childItem.__vModel__]" :allowHalf="childItem.allowHalf" disabled />
<JnpfSlider v-else-if="childItem.__config__.jnpfKey=='slider'"
v-model="column[childItem.__vModel__]" :step="childItem.step"
:min="childItem.min||0" :max="childItem.max||100" disabled />
<template v-else>
<JnpfInput v-if="childItem.__config__.jnpfKey=='input'"
v-model="column[childItem.__vModel__]" detailed :useMask="childItem.useMask"
:maskConfig="childItem.maskConfig" :addonBefore="childItem.addonBefore"
:addonAfter="childItem.addonAfter" />
<view class="jnpf-detail-text" v-else>{{column[childItem.__vModel__]}}</view>
</template>
</u-form-item>
</view>
</view>
<view class="jnpf-table-item" v-if="item.showSummary && summaryField.length">
<view class="jnpf-table-item-title u-flex u-row-between">
<text class="jnpf-table-item-title-num">{{item.__config__.label}}合计</text>
</view>
<view class=" u-p-l-20 u-p-r-20 form-item-box">
<u-form-item v-for="(item,index) in summaryField" :label="item.__config__.label"
:key="item.__vModel__">
<u-input input-align='right' v-model="item.value" disabled />
</u-form-item>
</view>
</view>
</view>
</template>
<view v-else-if="config.jnpfKey==='steps'" style="background-color: #fff;padding:15px 0">
<view class="step-container">
<u-steps :list="config.children" name="title" :mode="item.simple ? 'dot' :'number'"
@change="onStepChange($event,item)" :current="stepCurrent">
</u-steps>
</view>
<view v-for="(itemSub,i) in config.children" :key='i'>
<view v-if="i === stepCurrent">
<Item v-for="(childItem, childIndex) in itemSub.__config__.children" :key="childIndex"
:itemData="childItem" :formConf="formConf" :formData="formData" @toDetail="toDetail"
@clickIcon='clickIcon' />
</view>
</view>
</view>
<view class="jnpf-tab" v-if="config.jnpfKey==='tab'">
<u-tabs is-scroll :list="config.children" name="title" v-model="tabCurrent" @change="onTabChange" />
<view v-for="(pane,i) in config.children" :key='i'>
<view v-show="i == tabCurrent">
<Item v-for="(childItem, childIndex) in pane.__config__.children" :key="childIndex"
:itemData="childItem" :formConf="formConf" :formData="formData" @toDetail="toDetail"
@clickIcon='clickIcon' />
</view>
</view>
</view>
<template v-if="config.jnpfKey==='collapse'">
<u-collapse :head-style="{'padding-left':'20rpx'}" :accordion="item.accordion" ref="collapseRef">
<u-collapse-item :title="pane.title" v-for="(pane, i) in config.children" :key="i"
:open="config.active && config.active.indexOf(pane.name)>-1">
<Item v-for="(child, j) in pane.__config__.children" :key="child.__config__.renderKey"
:itemData="child" :formConf="formConf" :formData="formData" @toDetail="toDetail"
@clickIcon='clickIcon' />
</u-collapse-item>
</u-collapse>
</template>
</template>
</view>
</template>
<script>
import {
getRelationFormDetail,
getDataInterfaceDataInfoByIds
} from '@/api/common.js'
// #ifdef MP
import Item from './Item.vue' //兼容小程序
// #endif
import DisplayList from '@/components/displayList'
const specialList = ['link', 'editor', 'button', 'alert']
export default {
name: 'Item',
components: {
// #ifdef MP
Item,
// #endif
DisplayList
},
props: {
itemData: {
type: Object,
required: true
},
formConf: {
type: Object,
required: true
},
formData: {
type: Object,
},
},
computed: {
item() {
const item = uni.$u.deepClone(this.itemData)
this.initI18n(item)
return item
},
config() {
return this.item.__config__
},
labelWidth() {
if (specialList.indexOf(this.config.jnpfKey) > -1) return 0
return this.config.labelWidth ? this.config.labelWidth * 1.5 : undefined
},
label() {
return this.config.showLabel && specialList.indexOf(this.config.jnpfKey) < 0 ? this.config.label : ''
},
realLabel() {
return this.label ? (this.label + (this.formConf.labelSuffix || '')) : ''
},
leftIcon() {
return this.config.tipLabel && this.label && this.config.showLabel ? "question-circle-fill" : ""
}
},
data() {
return {
tabCurrent: 0,
tableData: [],
summaryField: [],
stepCurrent: 0,
extraObj: {}
}
},
created() {
this.handleSummary()
this.handleTab()
},
mounted() {
if (this.config.jnpfKey === 'collapse') {
this.$refs.collapseRef && this.$refs.collapseRef.init()
}
uni.$on('initCollapse', () => {
this.$refs.collapseRef && this.$refs.collapseRef.init()
})
this.getDataChange()
this.getDataInterfaceDataInfoByIds()
},
methods: {
onStepChange(index, item) {
if (this.stepCurrent === index) return
item.__config__.active = index
this.stepCurrent = index
this.$nextTick(() => {
uni.$emit('updateCode')
uni.$emit('initCollapse')
})
},
initI18n(item) {
const config = item.__config__
if (item.placeholderI18nCode) {
//#ifdef MP-WEIXIN
item.placeholder = this.$t(item.placeholderI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.placeholder = this.$t(item.placeholderI18nCode, item.placeholder);
//#endif
}
if (item.__config__.label && item.__config__.labelI18nCode) {
//#ifdef MP-WEIXIN
item.__config__.label = this.$t(item.__config__.labelI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.__config__.label = this.$t(item.__config__.labelI18nCode, item.__config__.label);
//#endif
}
if (item.__config__.tipLabel && item.__config__.tipLabelI18nCode) {
//#ifdef MP-WEIXIN
item.__config__.tipLabel = this.$t(item.__config__.tipLabelI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.__config__.tipLabel = this.$t(item.__config__.tipLabelI18nCode, item.__config__.tipLabel);
//#endif
}
if (['groupTitle', 'divider', 'link', 'text'].includes(config.jnpfKey)) {
if (item.contentI18nCode) {
//#ifdef MP-WEIXIN
item.content = this.$t(item.contentI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.content = this.$t(item.contentI18nCode, item.content);
//#endif
}
if (item.helpMessageI18nCode) {
//#ifdef MP-WEIXIN
item.helpMessage = this.$t(item.helpMessageI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.helpMessage = this.$t(item.helpMessageI18nCode, item.helpMessage);
//#endif
}
}
if (config.jnpfKey === 'button') {
if (item.buttonTextI18nCode) {
//#ifdef MP-WEIXIN
item.buttonText = this.$t(item.buttonTextI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.buttonText = this.$t(item.buttonTextI18nCode.item.buttonText);
//#endif
}
}
if (config.jnpfKey === 'alert') {
if (item.titleI18nCode) {
//#ifdef MP-WEIXIN
item.title = this.$t(item.titleI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.title = this.$t(item.titleI18nCode, item.title);
//#endif
}
if (item.descriptionI18nCode) {
//#ifdef MP-WEIXIN
item.description = this.$t(item.descriptionI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.description = this.$t(item.descriptionI18nCode, item.description);
//#endif
}
if (item.closeTextI18nCode) {
//#ifdef MP-WEIXIN
item.closeText = this.$t(item.closeTextI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.closeText = this.$t(item.closeTextI18nCode, item.closeText);
//#endif
}
}
if (config.jnpfKey === 'card') {
if (item.headerI18nCode) {
//#ifdef MP-WEIXIN
item.header = this.$t(item.headerI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.header = this.$t(item.headerI18nCode, item.header);
//#endif
}
}
if (['tab', 'collapse', 'steps'].includes(config.jnpfKey)) {
if (config.children && config.children.length) {
for (let i = 0; i < config.children.length; i++) {
if (config.children[i].titleI18nCode) {
//#ifdef MP-WEIXIN
config.children[i].title =
this.$t(config.children[i].titleI18nCode);
//#endif
//#ifndef MP-WEIXIN
config.children[i].title =
this.$t(config.children[i].titleI18nCode, config.children[i].title);
//#endif
}
}
}
if (item.headerI18nCode) {
//#ifdef MP-WEIXIN
item.header = this.$t(item.headerI18nCode);
//#endif
//#ifndef MP-WEIXIN
item.header = this.$t(item.headerI18nCode, item.header);
//#endif
}
}
if (config.jnpfKey === 'table') {
if (config.children && config.children.length) {
for (let i = 0; i < config.children.length; i++) {
this.initI18n(config.children[i])
}
}
}
},
handleTab() {
if (this.config.jnpfKey === 'steps') return this.stepCurrent = this.config.active
if (this.config.jnpfKey !== 'tab') return
for (var i = 0; i < this.config.children.length; i++) {
if (this.config.active == this.config.children[i].name) {
this.tabCurrent = i
break
}
}
},
getDataChange() {
if (this.config.jnpfKey === 'relationForm' && this.config.defaultValue) {
let query = {
id: this.formData[this.item.__vModel__ + '_id'],
};
if (this.item.propsValue) query = {
...query,
propsValue: this.item.propsValue
};
getRelationFormDetail(this.item.modelId, query).then(res => {
if ((!res.data || !res.data.data) || res.data.data === "undefined") return
let data = JSON.parse(res.data?.data)
this.extraObj = data
})
}
},
getDataInterfaceDataInfoByIds() {
if (this.config.jnpfKey === 'popupSelect' && this.config.defaultValue) {
let query = {
ids: [this.config.defaultValue],
interfaceId: this.item.interfaceId,
propsValue: this.item.propsValue,
relationField: this.item.relationField,
paramList: this.getParamList()
}
getDataInterfaceDataInfoByIds(this.item.interfaceId, query).then(res => {
const data = res.data && res.data.length ? res.data[0] : {};
this.extraObj = data
})
}
},
getParamList() {
let templateJson = this.item.templateJson
if (!this.formData) return templateJson
for (let i = 0; i < templateJson.length; i++) {
if (templateJson[i].relationField && templateJson[i].sourceType == 1) {
if (templateJson[i].relationField.includes('-')) {
let tableVModel = templateJson[i].relationField.split('-')[0]
let childVModel = templateJson[i].relationField.split('-')[1]
templateJson[i].defaultValue = this.formData[tableVModel] && this.formData[tableVModel][this
.rowIndex
] && this.formData[tableVModel][this.rowIndex][childVModel] || ''
} else {
templateJson[i].defaultValue = this.formData[templateJson[i].relationField] || ''
}
}
}
return templateJson
},
handleSummary() {
if (this.item.__config__.jnpfKey !== 'table') return
const val = this.item.__config__.defaultValue
let summaryField = this.item.summaryField || []
this.summaryField = []
this.tableData = this.item.__config__.children || []
for (let i = 0; i < summaryField.length; i++) {
for (let o = 0; o < this.tableData.length; o++) {
const item = this.tableData[o]
if (this.tableData[o].__vModel__ === summaryField[i] && !item.__config__.noShow) {
this.summaryField.push({
value: '',
...item
})
}
}
}
this.$nextTick(() => this.getTableSummaries(val, this.item))
},
toThousands(val, column) {
if (val) {
let valList = val.toString().split('.')
let num = Number(valList[0])
let newVal = column.thousands ? num.toLocaleString() : num
return valList[1] ? newVal + '.' + valList[1] : newVal
} else {
return val
}
},
getTableSummaries(newVal, config) {
for (let i = 0; i < this.summaryField.length; i++) {
let val = 0
for (let j = 0; j < newVal.length; j++) {
if (newVal[j][this.summaryField[i].__vModel__]) {
let data = isNaN(newVal[j][this.summaryField[i].__vModel__]) ? 0 :
Number(newVal[j][this.summaryField[i].__vModel__])
val += data
}
}
let realVal = val && !Number.isInteger(val) ? Number(val).toFixed(2) : val;
if (this.summaryField[i].thousands) realVal = Number(realVal).toLocaleString('zh')
this.summaryField[i].value = realVal
}
},
clickIcon(e) {
this.$emit('clickIcon', e)
},
onTabChange(index) {
if (this.tabCurrent === index) return
this.tabCurrent = index;
this.$emit('tab-change', this.item, index)
this.$nextTick(() => {
uni.$emit('initCollapse')
uni.$emit('updateCode')
})
},
doPreviewImage(current, imageList) {
const images = imageList.map(item => this.define.baseURL + item.url);
uni.previewImage({
urls: images,
current: current,
success: () => {},
fail: () => {
uni.showToast({
title: '预览图片失败',
icon: 'none'
});
}
});
},
toDetail(item) {
const data = {
...item,
...(item.__config__.jnpfKey === 'relationForm' ? {
sourceRelationForm: true,
propsValue: item.propsValue
} : {})
};
this.$emit('toDetail', data)
},
toTableDetail(item, value) {
item.__config__.defaultValue = value
this.$emit('toDetail', item)
},
getValue(item) {
if (Array.isArray(item.__config__.defaultValue)) {
if (['timeRange', 'dateRange'].includes(item.__config__.jnpfKey)) {
return item.__config__.defaultValue.join('')
}
return item.__config__.defaultValue.join()
}
return item.__config__.defaultValue
},
}
}
</script>
<style lang="scss">
.detail-text-box {
width: 100%;
}
</style>

View File

@@ -0,0 +1,68 @@
<template>
<u-form class="jnpf-wrap-form" :model="formData" ref="dataForm"
:label-position="formConf.labelPosition==='top'?'top':'left'"
:label-align="formConf.labelPosition==='right'?'right':'left'"
:label-width="formConf.labelWidth?formConf.labelWidth*1.5:150" :class='formConf.className'>
<template v-for="(item, index) in formConf.fields" :key="item.__config__.renderKey">
<Item :itemData="item" :formConf="formConf" :class="item.__config__.className" :formData="formData"
:ref="item.__vModel__?item.__vModel__: undefined" @toDetail="toDetail" @clickIcon='clickIcon' />
</template>
<u-modal v-model="show" :content="content" width='70%' border-radius="16" :content-style="contentStyle"
:titleStyle="titleStyle" :confirm-style="confirmStyle" :title="title" :confirm-text="$t('common.okText')">
</u-modal>
</u-form>
</template>
<script>
import Item from './Item'
export default {
components: {
Item
},
props: {
formConf: {
type: Object,
required: true
},
formData: {
type: Object,
},
loading: {
type: Boolean,
default: false
}
},
data() {
return {
show: false,
content: '',
contentStyle: {
fontSize: '28rpx',
padding: '20rpx',
lineHeight: '44rpx',
textAlign: 'left'
},
titleStyle: {
padding: '20rpx'
},
confirmStyle: {
height: '80rpx',
lineHeight: '80rpx',
},
title: this.$t('common.tipTitle'),
}
},
methods: {
clickIcon(e) {
if (!e.__config__.tipLabel && !e.helpMessage) return
this.content = e.helpMessage || e.__config__.tipLabel
this.title = e.__config__.label
if (e.__config__.jnpfKey === 'card') this.title = e.header
if (e.__config__.jnpfKey === 'groupTitle') this.title = e.content
this.show = true
},
toDetail(item) {
this.$emit('toDetail', item)
}
}
}
</script>

View File

@@ -0,0 +1,179 @@
<template>
<view class="jnpf-wrap jnpf-wrap-form">
<JnpfParser v-if="!loading" ref="dynamicForm" :formConf="formConf" :key="key" @submit="sumbitForm" />
<view class="buttom-actions" v-if="origin !='scan'">
<u-button class="buttom-btn" @click.stop="resetForm">{{$t('common.resetText')}}</u-button>
<u-button class="buttom-btn" type="primary" @click.stop="submit" :loading="btnLoading">
{{getOkText}}
</u-button>
</view>
</view>
</template>
<script>
import {
createModel,
getModelInfo
} from '@/api/apply/visualDev'
export default {
props: ['config', 'modelId', 'isPreview', 'origin', 'id'],
data() {
return {
dataForm: {
data: ''
},
formConf: {},
key: +new Date(),
btnLoading: false,
loading: true,
isAdd: false,
userInfo: {}
}
},
computed: {
getOkText() {
const text = this.formConf.confirmButtonTextI18nCode ?
this.$t(this.formConf.confirmButtonTextI18nCode, this.formConf.confirmButtonText) :
this.formConf.confirmButtonText;
return text || this.$t('common.okText');
},
},
created() {
this.init()
},
methods: {
init() {
this.userInfo = uni.getStorageSync('userInfo') || {}
this.formConf = JSON.parse(this.config.formData)
this.loading = true
this.initData()
},
initData() {
this.$nextTick(() => {
if (this.origin === 'scan') {
let extra = {
modelId: this.modelId,
id: this.id,
type: 2
}
uni.setStorageSync('dynamicModelExtra', extra)
getModelInfo(this.modelId, this.id).then(res => {
this.dataForm = res.data
if (!this.dataForm.data) return
this.formData = JSON.parse(this.dataForm.data)
this.fillFormData(this.formConf, this.formData)
this.$nextTick(() => {
this.loading = false
})
})
} else {
this.formData = {}
this.loading = false
this.isAdd = true
this.fillFormData(this.formConf, this.formData)
}
this.key = +new Date()
})
},
fillFormData(form, data) {
const loop = list => {
for (let i = 0; i < list.length; i++) {
let item = list[i]
let vModel = item.__vModel__
let config = item.__config__
if (vModel) {
let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
if (!config.isSubTable) config.defaultValue = val
if (this.isAdd || config.isSubTable) { //新增时候,默认当前
if (config.defaultCurrent) {
if (config.jnpfKey === 'datePicker') {
if (!data.hasOwnProperty(vModel)) {
let format = this.jnpf.handelFormat(item.format)
let dateStr = this.jnpf.toDate(new Date().getTime(), format)
let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
'-01 00:00:00' : format === 'yyyy-MM-dd' ?
' 00:00:00' : ''
val = new Date(dateStr + time).getTime()
config.defaultValue = val
}
}
if (config.jnpfKey === 'timePicker') {
if (!data.hasOwnProperty(vModel)) {
config.defaultValue = this.jnpf.toDate(new Date(), item.format)
}
}
if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
config.defaultValue = item.multiple ? this.userInfo.organizeIds :
this.userInfo.organizeId
}
if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
config.defaultValue = item.multiple ? this.userInfo.positionIds :
this.userInfo.positionId
}
const userId = this.userInfo.userId
if (config.jnpfKey === 'userSelect' && userId) {
config.defaultValue = item.multiple ? [userId] : userId;
}
if (config.jnpfKey === 'usersSelect' && userId) {
config.defaultValue = [userId + '--user'];
}
if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
config.defaultValue = this.userInfo.signImg
}
}
}
if (this.origin === 'scan') this.$set(item, 'disabled', true)
let noShow = !config.noShow ? false : config.noShow
let isVisibility = false
if (!config.visibility || (Array.isArray(config.visibility) && config.visibility.includes(
'app'))) isVisibility = true
this.$set(config, 'isVisibility', isVisibility)
this.$set(config, 'noShow', noShow)
} else {
let noShow = false,
isVisibility = false
if (!config.visibility || (Array.isArray(config.visibility) && config.visibility.includes(
'app'))) isVisibility = true
this.$set(config, 'isVisibility', isVisibility)
this.$set(config, 'noShow', noShow)
}
if (config && config.children && Array.isArray(config.children)) loop(config.children)
}
}
loop(form.fields)
},
sumbitForm(data, callback) {
if (!data) return
this.btnLoading = true
this.dataForm.data = JSON.stringify(data)
if (callback && typeof callback === "function") callback()
createModel(this.modelId, this.dataForm).then(res => {
uni.showToast({
title: res.msg,
complete: () => {
setTimeout(() => {
this.btnLoading = false
uni.navigateBack()
}, 1500)
}
})
}).catch(() => {
this.btnLoading = false
})
},
submit() {
if (this.isPreview) return this.$u.toast('功能预览不支持数据保存')
this.$refs.dynamicForm && this.$refs.dynamicForm.submitForm()
},
resetForm() {
this.loading = true
this.$nextTick(() => {
this.loading = false
this.$refs.dynamicForm && this.$refs.dynamicForm.resetForm()
this.init()
this.key = +new Date()
})
}
}
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,273 @@
<template>
<view class="list u-p-b-20 u-p-l-20 u-p-r-20" ref="tableRef">
<view class="list-box">
<SwipeItem :list="list" :buttons="options" @action="actionClick" ref="swipeItem" :marginB="20">
<template v-slot="{ item }">
<view class="item" @tap.stop="goDetail(item)">
<view class="item-content">
<!-- 左侧信息区 -->
<view class="item-left">
<!-- 单号 + 普通标签核心修改区域 -->
<view class="item-row item-header">
<!-- 新增普通标签 -->
<view class="flow-tag">单号</view>
<text class="content unit-name">{{ item.billNo }}</text>
</view>
<view class="item-row">
<text class="label">申请单位:</text>
<text class="content unit-name">{{ item.applyDepName }}</text>
</view>
<view class="item-row">
<text class="label">申请人员:</text>
<text class="content">{{ item.applyUser}}</text>
</view>
<view class="item-row">
<text class="label">创建时间:</text>
<text class="content">{{ formatTime(item.create_time) }}</text>
</view>
</view>
<!-- 右侧状态图 -->
<view class="item-right">
<image
v-if="item.approveStatusName == '未审核'"
src="../../img/UNAPPROVED.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '审批中'"
src="../../img/APPROVING.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '已审批'"
src="../../img/APPROVED.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '已驳回'"
src="../../img/REJECTED.png"
mode="widthFix"
class="status-img" />
<image
v-if="item.approveStatusName == '已作废'"
src="../../img/INVALID.png"
mode="widthFix"
class="status-img" />
</view>
</view>
</view>
</template>
</SwipeItem>
</view>
</view>
</template>
<script>
// 脚本部分无需修改,保持原逻辑
import { useDefineSetting } from '@/utils/useDefineSetting';
import tableCell from '../tableCell.vue'
import SwipeItem from "@/components/SwipeItem/index"
export default {
emits: ['selectCheckbox', 'handleClick', 'handleMoreClick', 'goDetail', 'relationFormClick', 'update:modelValue'],
components: {
tableCell,
SwipeItem
},
props: [
'config',
'list',
'actionOptions',
'showSelect',
'checkedAll',
'modelValue',
'isMoreBtn',
'customBtnsList'
],
data() {
return {
selectData: [],
useDefine: useDefineSetting()
}
},
watch: {
checkedAll: {
handler(val) {
this.handleCheckAll()
},
immediate: true
}
},
computed: {
options() {
if (!this.customBtnsList?.length) return this.actionOptions;
return [{
text: this.$t('common.moreText'),
value: 'more',
style: {
backgroundColor: '#007aff'
}
},
...this.actionOptions,
];
},
showCheckbox() {
return this.showSelect
}
},
methods: {
formatTime(timestamp) {
if (!timestamp) return '-';
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
getStatusClass(statusName) {
switch (statusName) {
case '已审批':
return 'status-approved';
case '未审核':
return 'status-unchecked';
default:
return 'status-other';
}
},
relationFormClick(item, column) {
this.$emit('relationFormClick', item, column)
},
goDetail(item) {
this.$emit('goDetail', item)
},
actionClick(data) {
const { index, value } = data
if (value === 'remove') return this.$emit('handleClick', index)
if (value === 'more') return this.$emit('handleMoreClick', index)
},
checkboxChange(e, item) {
const isSelected = e.value;
const selectedItemsSet = new Set(this.selectData.map(selectedItem => selectedItem.id));
if (isSelected) {
selectedItemsSet.add(item.id);
} else {
selectedItemsSet.delete(item.id);
}
this.selectData = [...selectedItemsSet.values()].map(id => {
return this.list.find(listItem => listItem.id === id);
});
this.$emit('selectCheckbox', this.selectData);
},
handleCheckAll() {
this.selectData = []
if (this.checkedAll) this.selectData = this.list.filter(o => o.checked)
this.$emit('selectCheckbox', this.selectData);
}
}
}
</script>
<style lang="scss" scoped>
.list {
background-color: #f0f2f6;
.list-box {
.item {
background: #fff;
border-radius: 12rpx;
margin-bottom: 20rpx;
padding: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
position: relative;
.item-content {
display: flex;
align-items: flex-start; /* 改为顶部对齐,避免标签错位 */
justify-content: space-between;
}
.item-left {
flex: 1;
}
.item-row {
display: flex;
align-items: center;
margin-bottom: 8rpx; /* 调整行间距 */
&:last-child {
margin-bottom: 0;
}
.label {
font-size: 26rpx;
color: #909399;
min-width: 140rpx;
margin-right: 8rpx;
}
.content {
font-size: 28rpx;
color: #303133;
}
}
// 单号+标签的布局样式(核心新增)
.item-header {
align-items: center;
gap: 10rpx; // 标签、单号、单号值之间的间距
// 普通标签样式
.flow-tag {
font-size: 22rpx;
color: #1677ff;
background: #e8f3ff;
padding: 2rpx 8rpx;
border-radius: 4rpx;
font-weight: 500;
}
// 单号文本样式
.bill-label {
font-size: 26rpx;
color: #303133;
}
}
// 流程名称样式(对应图中的“管理员的动火审批流程”)
.flow-name {
font-size: 28rpx;
color: #1E293B;
font-weight: 500;
}
.status-tag {
padding: 4rpx 16rpx;
border-radius: 20rpx;
font-size: 26rpx;
color: #fff;
&.status-approved {
background-color: #67c23a;
}
&.status-unchecked {
background-color: #e6a23c;
}
&.status-other {
background-color: #909399;
}
}
// 右侧状态图样式
.item-right {
width: 100rpx;
height: 160rpx;
display: flex;
align-items: center;
justify-content: center;
.status-img {
width: 100%;
height: auto;
object-fit: contain;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,224 @@
<template>
<u-form :model="formData" ref="dataForm" :errorType="['toast']" label-position="left" label-width="150">
<u-form-item :label="item.label" :prop="item.id" v-for="(item, i) in formConfCopy" :key="`${item.id}-${i}`">
<JnpfInput v-if="useInputList.includes(item.__config__.jnpfKey)" input-align='right'
v-model="formData[item.id]" :placeholder="textPrefix+item.label" clearable />
<template v-if="['inputNumber','calculate'].includes(item.__config__.jnpfKey)">
<JnpfInputNumber v-model="formData[item.id]" :precision="item.precision"
:placeholder="textPrefix+item.__config__.label" v-if="item.__config__.isFromParam" />
<JnpfNumberRange v-model="formData[item.id]"
:precision="!item.precision && item.__config__.jnpfKey=='calculate'?0:item.precision" v-else />
</template>
<template v-if="['rate', 'slider'].includes(item.__config__.jnpfKey)">
<JnpfNumberRange v-model="formData[item.id]" :precision="item.allowHalf ? 1 : 0" />
</template>
<JnpfSelect
v-if="useSelectList.includes(item.__config__.jnpfKey)"
v-model="formData[item.id]"
:placeholder="selectPrefix+item.label"
:options="item.options || []"
:props="item.props || { label: 'label', value: 'value' }"
:multiple="!!item.searchMultiple"
:key="`select-${item.id}-${key}`"
filterable
/>
<JnpfCascader v-if="item.__config__.jnpfKey==='cascader'" v-model="formData[item.id]"
:placeholder="selectPrefix+item.label" :options="item.options || []" :props="item.props" filterable
:showAllLevels="item.showAllLevels" :multiple="item.searchMultiple" />
<JnpfAutoComplete v-if="item.__config__.jnpfKey==='autoComplete'" v-model="formData[item.id]"
:interfaceName="item.interfaceName" :placeholder="selectPrefix+item.label"
:interfaceId="item.interfaceId" :total="item.total" :templateJson="item.templateJson"
:formData='formData' :relationField="item.relationField" :propsValue="item.propsValue"
:clearable='item.clearable' />
<JnpfGroupSelect v-if="item.__config__.jnpfKey==='groupSelect'" v-model="formData[item.id]"
:vModel='item.id' :multiple="item.searchMultiple" :disabled="item.disabled"
:placeholder="selectPrefix+item.label" :ableIds="item.ableIds" :selectType="item.selectType" />
<JnpfRoleSelect v-if="item.__config__.jnpfKey==='roleSelect'" v-model="formData[item.id]"
:multiple="item.searchMultiple" :disabled="item.disabled" :placeholder="selectPrefix+item.label"
:ableIds="item.ableIds" :selectType="item.selectType" />
<JnpfOrganizeSelect v-if="['organizeSelect','currOrganize'].includes(item.__config__.jnpfKey)"
v-model="formData[item.id]" :placeholder="selectPrefix+item.label"
:multiple="item.__config__.jnpfKey === 'currOrganize' ? true : item.searchMultiple"
:ableIds="item.ableIds" :selectType="item.selectType" />
<JnpfPosSelect v-if="['posSelect','currPosition'].includes(item.__config__.jnpfKey)"
v-model="formData[item.id]" :placeholder="selectPrefix+item.label" :ableIds="item.ableIds"
:selectType="item.selectType"
:multiple="item.__config__.jnpfKey === 'currPosition' ? true : item.searchMultiple" />
<JnpfUserSelect v-if="['userSelect','createUser', 'modifyUser'].includes(item.__config__.jnpfKey)"
v-model="formData[item.id]" :placeholder="selectPrefix+item.label" :ableDepIds="item.ableDepIds"
:ableIds="item.ableIds" :selectType="item.selectType!='custom'?'all':'custom'"
:multiple="item.searchMultiple" />
<JnpfUsersSelect v-if="item.__config__.jnpfKey==='usersSelect'" v-model="formData[item.id]"
:placeholder="selectPrefix+item.label" :clearable="item.clearable" />
<JnpfTreeSelect v-if="item.__config__.jnpfKey==='treeSelect'" v-model="formData[item.id]"
:options="item.options || []" :props="item.props" :placeholder="selectPrefix+item.label" filterable
:multiple="item.searchMultiple" />
<JnpfAreaSelect v-if="item.__config__.jnpfKey==='areaSelect'" v-model="formData[item.id]"
:placeholder="selectPrefix+item.label" :level="item.level" :multiple="item.searchMultiple" />
<!-- 日期/时间选择 -->
<template v-if="useDateList.includes(item.__config__.jnpfKey)">
<JnpfDatePicker v-model="formData[item.id]" :format='item.format' v-if="item.__config__.isFromParam" />
<JnpfDateRange v-model="formData[item.id]" :format='item.format' v-else />
</template>
<JnpfTimeRange v-if="item.__config__.jnpfKey==='timePicker'" v-model="formData[item.id]"
:format='item.format' />
</u-form-item>
</u-form>
</template>
<script>
const dyOptionsList = ['radio', 'checkbox', 'select', 'cascader', 'treeSelect'];
const useSelectList = ['radio', 'checkbox', 'select'];
const useInputList = ['input', 'textarea', 'text', 'link', 'billRule', 'location'];
const useDateList = ['createTime', 'modifyTime', 'datePicker', 'dateCalculate'];
const useArrList = ['cascader', 'address', 'numInput', 'calculate', ...useDateList]
export default {
props: ['formConf', 'webType', 'searchFormData'],
data() {
return {
useInputList,
useDateList,
useSelectList,
formConfCopy: [], // 初始化为空,避免提前克隆
formData: {},
key: +new Date(),
textPrefix: this.$t('common.inputTextPrefix') + ' ',
selectPrefix: this.$t('common.chooseTextPrefix') + ' ',
}
},
// 核心深度监听formConf变化确保数据同步
watch: {
// 监听父组件传递的formConf深度+立即执行)
formConf: {
deep: true,
immediate: true,
handler(newVal) {
if (!newVal) return;
// 重新克隆最新的配置
this.formConfCopy = this.$u.deepClone(newVal);
// 延迟初始化确保DOM更新
this.$nextTick(() => {
this.initRelationForm(this.formConfCopy);
// 初始化时彻底跳过接口请求
this.initFormData(this.formConfCopy, this.formData);
});
}
},
// 监听搜索数据变化
searchFormData: {
deep: true,
immediate: true,
handler(newVal) {
this.formData = this.$u.deepClone(newVal);
}
}
},
methods: {
/**
* 初始化表单数据(彻底跳过接口请求)
*/
initFormData(componentList, formData) {
console.log('Parser接收的配置:', componentList);
if (!componentList || !Array.isArray(componentList)) return;
componentList.forEach(cur => {
const config = cur.__config__ || {};
if (cur.id && formData[cur.id] === undefined) {
// 初始化表单默认值
formData[cur.id] = cur.value || (cur.searchMultiple ? [] : '');
}
// 原接口逻辑全部注释,彻底跳过
/*
if (dyOptionsList.indexOf(config.jnpfKey) > -1) {
if (config.dataType === 'dictionary' && config.dictionaryType) {
getDictionaryDataSelector(config.dictionaryType).then(res => {
cur.options = res.data.list || []
this.key = +new Date()
this.resetForm()
})
}
if (config.dataType === 'dynamic' && config.propsUrl) {
const query = {
paramList: this.jnpf.getParamList(config.templateJson) || []
};
getDataInterfaceRes(config.propsUrl, query).then(res => {
let list = res.data || []
cur.options = Array.isArray(list) ? list : [];
this.key = +new Date()
this.resetForm()
})
}
}
*/
});
// 更新key强制刷新组件
this.key = +new Date();
},
/**
* 初始化关联表单配置
*/
initRelationForm(componentList) {
if (!componentList) return;
componentList.forEach(cur => {
const config = cur.__config__ || {};
if (config.jnpfKey == 'relationFormAttr' || config.jnpfKey == 'popupAttr') {
const relationKey = cur.relationField?.split("_jnpfTable_")[0];
if (!relationKey) return;
componentList.forEach(item => {
const noVisibility = Array.isArray(item.__config__?.visibility) && !item.__config__.visibility.includes('app');
if ((relationKey == item.id) && (noVisibility || !!item.__config__?.noShow)) {
cur.__config__.noShow = true;
}
});
}
if (cur.__config__?.children && cur.__config__.children.length) {
this.initRelationForm(cur.__config__.children);
}
});
},
/**
* 获取表单数据(空值处理)
*/
allCondition() {
const result = {...this.formData};
for (let key in result) {
if (result[key] === 0) continue;
if (!result[key] || (Array.isArray(result[key]) && result[key].length === 0)) {
delete result[key];
}
}
return result;
},
/**
* 提交表单
*/
submitForm() {
if (!this.$refs.dataForm) {
this.$emit('submit', this.allCondition());
return;
}
this.$refs.dataForm.validate(valid => {
if (!valid) return;
this.$emit('submit', this.allCondition());
});
},
/**
* 重置表单
*/
resetForm() {
if (this.$refs.dataForm) {
this.$refs.dataForm.resetFields();
}
}
}
}
</script>

View File

@@ -0,0 +1,125 @@
<template>
<uni-collapse class='collapse' accordion ref="collapse" @change="collapseChange" @click.stop>
<uni-collapse-item :key="key">
<template v-slot:title>
<view class="u-font-24 u-flex">
<view style="width: 124rpx;text-align: right;">
<text>{{label+':'}}</text>
</view>
<text style="color: #606266;" class="u-m-l-28">{{$t('app.apply.expandData')}}</text>
</view>
</template>
<view class="collapse-item" v-for="(item,d) in dataList" :key="d">
<view v-if="d<allPageLen" class="item-cell-children">
<view class="item-cell" v-for="(cld,c) in children" :key="c">
<text
class="item-cell-label">{{cld.labelI18nCode ? $t(cld.labelI18nCode, cld.label) : cld.label}}:</text>
<text class="item-cell-content"
v-if="['calculate','inputNumber'].includes(cld.__config__.jnpfKey)">
{{toThousands(item[cld.vModel],cld) }}
</text>
<text class="item-cell-content text-primary"
v-else-if="cld.__config__.jnpfKey === 'relationForm'"
@click.stop="relationFormClick(item,cld)">
{{item[cld.vModel]}}
</text>
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'sign'">
<JnpfSign v-model="item[cld.vModel]" align="left" detailed />
</view>
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'signature'">
<JnpfSignature v-model="item[cld.vModel]" align="left" detailed />
</view>
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'uploadImg'" @click.stop>
<JnpfUploadImg v-model="item[cld.vModel]" detailed simple
v-if="item[cld.vModel]&&item[cld.vModel].length" />
</view>
<!-- #ifndef APP-HARMONY -->
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'uploadFile'" @click.stop>
<JnpfUploadFile v-model="item[cld.vModel]" detailed
v-if="item[cld.vModel]&&item[cld.vModel].length" align="left" />
</view>
<!-- #endif -->
<!-- #ifdef APP-HARMONY -->
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'uploadFile'" @click.stop>
<JnpfUploadFileH v-model="item[cld.vModel]" detailed
v-if="item[cld.vModel]&&item[cld.vModel].length" align="left" />
</view>
<!-- #endif -->
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'rate'">
<JnpfRate v-model="item[cld.vModel]" :max="cld.count" :allowHalf="cld.allowHalf" disabled />
</view>
<view class="item-cell-content item-cell-slider" v-else-if="cld.jnpfKey == 'slider'">
<JnpfSlider v-model="item[cld.vModel]" :min="cld.min" :max="cld.max" :step="cld.step"
disabled />
</view>
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'input'">
<JnpfInput v-model="item[cld.vModel]" detailed showOverflow :useMask="cld.useMask"
:maskConfig="cld.maskConfig" align='left' />
</view>
<text class="item-cell-content" v-else>{{item[cld.vModel]}}</text>
</view>
</view>
</view>
<view class="loadMore" @click.stop="loadMore" v-if="!isAllData&&this.dataList.length>allPageLen">
加载更多
</view>
</uni-collapse-item>
</uni-collapse>
</template>
<script>
export default {
props: ['childList', 'label', 'children', 'pageLen', 'thousands', 'thousandsField'],
data() {
return {
dataList: [],
isAllData: false,
key: +new Date(),
allPageLen: 3
}
},
watch: {
childList: {
handler(val) {
this.dataList = val || []
this.allPageLen = this.pageLen
this.children.map(o => {
if (o.childLabel.length > 4) o.childLabel = o.childLabel.substring(0, 4)
})
},
immediate: true,
}
},
methods: {
toThousands(val, column) {
if (val) {
let valList = val.toString().split('.')
let num = Number(valList[0])
let newVal = column.thousands ? num.toLocaleString() : num
return valList[1] ? newVal + '.' + valList[1] : newVal
}
},
relationFormClick(item, cld) {
this.$emit('cRelationForm', item, cld)
},
loadMore() {
this.allPageLen = this.childList.length
this.isAllData = true
this.resizeCollapse()
},
collapseChange(e) {
if (!e) {
this.isAllData = false
setTimeout(() => {
this.allPageLen = this.pageLen
}, 500)
}
this.resizeCollapse()
},
resizeCollapse() {
setTimeout(() => {
this.$refs.collapse && this.$refs.collapse.resize()
}, 50)
}
}
}
</script>

View File

@@ -0,0 +1,450 @@
<template>
<view class="dynamicModel-form-v jnpf-wrap jnpf-wrap-form" v-if="showPage">
<Parser :formConf="formConf" :formData="formData" ref="dynamicForm" v-if="!loading" :key="key"
@toDetail="toDetail" />
<view class="u-m-t-20 dataLog-box u-flex-col u-m-b-20" v-if="formConf.dataLog && !setting.noDataLog">
<view class="title u-flex">
<u-icon name=" icon-ym-generator-menu" custom-prefix="icon-ym"></u-icon>
<text class="u-m-l-10">修改记录</text>
</view>
<view class="dataLog-v" v-if="dataLogList.length">
<dataLog :dataLogList="dataLogList"></dataLog>
</view>
<JnpfEmpty v-else />
</view>
<view class="buttom-actions">
<CustomButton class="u-flex buttom-btn-left-inner" v-if="showMoreBtn" btnText="更多" btnType="more"
iconName="more-dot-fill" size="28" @handleBtn="showAction = $event" :btnLoading="loading" />
<template v-if="showEditBtn">
<CustomButton class="u-flex buttom-btn-left-inner" :btnText="$t('common.cancelText')"
btnIcon="icon-ym icon-ym-add-cancel" customIcon :btnLoading="loading" />
<u-button class="buttom-btn" type="primary" @click.stop="handleEdit" :loading="loading">
{{labelS.btn_edit}}
</u-button>
</template>
<u-button class="cancel" @click.stop="jnpf.goBack()"
v-if="!showEditBtn && !showMoreBtn">{{$t('common.cancelText')}}</u-button>
</view>
<u-select :list="actionList" v-model="showAction" @confirm="selectBtnconfirm" />
</view>
</template>
<script>
import CustomButton from '@/components/CustomButton'
import {
getConfigData,
getOnlineLog,
getModelInfo,
getDataChange,
launchFlow
} from "@/api/apply/visualDev";
import {
getRelationFormDetail,
getDataInterfaceRes
} from "@/api/common.js";
import Parser from "./components/detail/Parser";
import dataLog from '@/components/dataLog'
import deepClone from '../../../uni_modules/vk-uview-ui/libs/function/deepClone';
export default {
components: {
Parser,
dataLog,
CustomButton
},
data() {
return {
dataLogList: [],
actionList: [],
showAction: false,
showPage: false,
loading: true,
isPreview: "0",
modelId: "",
formConf: {},
formData: {},
dataForm: {
id: "",
data: "",
},
btnType: "",
formPermissionList: {},
formList: [],
labelS: {}
};
},
onLoad(option) {
this.init(option)
},
computed: {
showMoreBtn() {
if (this.actionList.length && !this.setting?.noShowBtn || 0 && this.setting?.noDataLog) return true
return false
},
showEditBtn() {
if (this.btnType === 'btn_edit' && !this.setting.noShowBtn && this.setting.enableEdit) return true
return false
}
},
onShow() {
setTimeout(() => {
uni.$emit('initCollapse')
}, 100)
},
onUnload() {
uni.$off("refresh");
},
methods: {
init(option) {
// 提取公共解析方法
const parseConfig = (rawConfig) => {
try {
return JSON.parse(this.jnpf.base64.decode(rawConfig)) || {}
} catch (error) {
return {}
}
}
// 使用解构赋值提取配置
const config = parseConfig(option.config)
const {
currentMenu,
btnType = "",
labelS: rawLabelS = {},
modelId,
isPreview = "0",
id = ""
} = config
// 缓存解析结果
const formPermissionList = currentMenu ? JSON.parse(decodeURIComponent(currentMenu)) : [];
// 批量属性赋值
Object.assign(this, {
formPermissionList,
formList: formPermissionList.formList || [],
btnType,
labelS: {
btn_edit: this.$t('common.editText'),
...rawLabelS
},
modelId,
isPreview,
dataForm: {
id
},
setting: config
})
// 设置导航栏标题
uni.setNavigationBarTitle({
title: this.$t('common.detailText')
})
this.getConfigData();
uni.$on("refresh", () => {
this.getConfigData();
});
},
// 自定义按钮事件
selectBtnconfirm(e) {
var i = this.actionList.findIndex((item) => {
return item.value == e[0].value
})
const item = this.actionList[i].actionConfig
const row = this.formData
// 自定义启用规则判断
if (item.btnType == 1) this.handlePopup(item, row)
if (item.btnType == 2) this.handleScriptFunc(item, row)
if (item.btnType == 3) this.handleInterface(item, row)
if (item.btnType == 4) this.handleLaunchFlow(item, [row])
},
//自定义按钮发起流程
handleLaunchFlow(item, records) {
const data = deepClone(item.launchFlow)
let dataList = [];
for (let i = 0; i < records.length; i++) {
dataList.push(this.jnpf.getLaunchFlowParamList(data.transferList, records[i], this.getRowKey));
}
const query = {
template: data.flowId,
btnCode: item.value,
currentUser: data.currentUser,
customUser: data.customUser,
initiator: data.initiator,
hasPermission: data.hasPermission,
dataList
};
launchFlow(query, this.modelId).then(res => {
this.$u.toast(res.msg)
});
},
//自定义按钮弹窗操作
handlePopup(item, row) {
let data = {
config: item,
modelId: this.modelId,
id: row.id,
row,
}
data = encodeURIComponent(JSON.stringify(data))
uni.navigateTo({
url: '/pages/apply/customBtn/index?data=' + data
})
},
//自定义按钮JS操作
handleScriptFunc(item, row) {
const parameter = {
data: row,
refresh: this.initData,
onlineUtils: this.jnpf.onlineUtils,
}
const func = this.jnpf.getScriptFunc.call(this, item.func)
if (!func) return
func.call(this, parameter)
},
//自定义按钮接口操作
handleInterface(item, row, index) {
const handlerData = () => {
getModelInfo(this.modelId, row.id).then(res => {
const dataForm = res.data || {};
if (!dataForm.data) return;
const data = {
...JSON.parse(dataForm.data),
id: row.id
};
handlerInterface(data);
})
}
const handlerInterface = (data) => {
let query = {
paramList: this.jnpf.getParamList(item.templateJson, data) || [],
}
getDataInterfaceRes(item.interfaceId, query).then(res => {
uni.showToast({
title: res.msg,
icon: 'none'
})
if (item.isRefresh) this.initData();
})
}
const handleFun = () => {
handlerData();
};
if (!item.useConfirm) return handleFun()
uni.showModal({
title: '提示',
content: item.confirmTitle || '确认执行此操作',
success: (res) => {
if (!res.cancel) handleFun()
}
})
},
getOnlineLog() {
getOnlineLog(this.setting.modelId, this.setting.id).then(res => {
this.dataLogList = res.data.list || []
})
},
getConfigData() {
this.loading = true;
console.log(this.modelId,'modelId-------')
getConfigData(this.modelId).then((res) => {
if (res.code !== 200 || !res.data) {
uni.showToast({
title: "暂无此页面",
icon: "none",
complete: () => {
setTimeout(() => {
uni.navigateBack();
}, 1500);
},
});
return;
}
this.formConf = res.data.formData ? JSON.parse(res.data.formData) : {};
this.actionList = this.formConf?.appCustomBtns || []
this.actionList.map((o) => {
if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode, o.label)
})
this.beforeInit(this.formConf.fields || []);
this.showPage = true;
this.key = +new Date();
this.initData();
});
},
beforeInit(fields) {
const loop = (list) => {
for (var index = 0; index < list.length; index++) {
const config = list[index].__config__;
if (config.children && config.children.length) loop(config.children);
if (config.jnpfKey == "tableGrid") {
let newList = [];
for (var i = 0; i < config.children.length; i++) {
let element = config.children[i];
for (var j = 0; j < element.__config__.children.length; j++) {
let item = element.__config__.children[j];
newList.push(...item.__config__.children);
}
}
list.splice(index, 1, ...newList);
}
}
};
loop(fields);
},
initData() {
this.$nextTick(() => {
if (this.dataForm.id) {
let extra = {
modelId: this.modelId,
id: this.dataForm.id,
type: 2,
};
uni.setStorageSync('dynamicModelExtra', extra)
this.getRelationFormDetail()
} else {
this.loading = false;
}
this.$nextTick(() => {
this.getOnlineLog()
})
this.key = +new Date();
});
},
getRelationFormDetail() {
const processResponse = (res) => {
this.dataForm = res.data;
this.loading = false;
if (!this.dataForm.data) return;
this.formData = {
...JSON.parse(this.dataForm.data),
id: this.dataForm.id,
};
this.fillFormData(this.formConf, this.formData);
this.initRelationForm(this.formConf.fields);
};
let requestParams = {
id: this.dataForm.id,
menuId: this.setting.menuId
};
if (this.setting?.sourceRelationForm) {
if (this.setting.propsValue) requestParams.propsValue = this.setting.propsValue;
}
getDataChange(requestParams, this.modelId).then(res => {
processResponse(res)
}).catch(err => {
this.loading = false;
})
},
fillFormData(form, data) {
const loop = (list, parent) => {
for (let i = 0; i < list.length; i++) {
let item = list[i];
if (item.__vModel__) {
if (
item.__config__.jnpfKey === "relationForm" ||
item.__config__.jnpfKey === "popupSelect"
) {
item.__config__.defaultValue = data[item.__vModel__ + "_id"];
this.$set(item, "name", item.__config__.defaultValue || "");
} else {
let val = data.hasOwnProperty(item.__vModel__) ?
data[item.__vModel__] :
item.__config__.defaultValue;
item.__config__.defaultValue = val;
}
if (this.formPermissionList.useFormPermission) {
let id = item.__config__.isSubTable ?
parent.__vModel__ + "-" + item.__vModel__ :
item.__vModel__;
let noShow = true;
if (this.formList && this.formList.length) {
noShow = !this.formList.some((o) => o.enCode === id);
}
noShow = item.__config__.noShow ? item.__config__.noShow : noShow;
this.$set(item.__config__, "noShow", noShow);
}
} else {
if (['relationFormAttr', 'popupAttr'].includes(item.__config__.jnpfKey)) {
item.__config__.defaultValue =
data[item.relationField.split('_jnpfTable_')[0] + '_' + item.showField];
}
}
if (
item.__config__ &&
item.__config__.children &&
Array.isArray(item.__config__.children)
) {
loop(item.__config__.children, item);
}
}
};
loop(form.fields);
this.loading = false;
},
initRelationForm(componentList) {
componentList.forEach((cur) => {
const config = cur.__config__;
if (
config.jnpfKey == "relationFormAttr" ||
config.jnpfKey == "popupAttr"
) {
const relationKey = cur.relationField.split("_jnpfTable_")[0];
componentList.forEach((item) => {
const noVisibility =
Array.isArray(item.__config__.visibility) &&
!item.__config__.visibility.includes("app");
if (
relationKey == item.__vModel__ &&
(noVisibility || !!item.__config__.noShow) && !cur.__vModel__
) {
cur.__config__.noShow = true;
}
});
}
if (cur.__config__.children && cur.__config__.children.length)
this.initRelationForm(cur.__config__.children);
});
},
toDetail(item) {
const id = item.__config__.defaultValue;
if (!id) return;
let config = {
modelId: item.modelId,
id: id,
formTitle: "详情",
noShowBtn: 1,
noDataLog: 1,
sourceRelationForm: item?.sourceRelationForm || false,
propsValue: item?.propsValue || ''
};
this.$nextTick(() => {
const url =
"/pages/apply/dynamicModel/detail?config=" +
this.jnpf.base64.encode(JSON.stringify(config));
uni.navigateTo({
url: url,
});
});
},
handleEdit() {
if (this.setting.disableEdit) return;
const currentMenu = encodeURIComponent(JSON.stringify(this.formPermissionList));
let config = {
modelId: this.modelId,
isPreview: this.isPreview,
id: this.setting.id,
btnType: "btn_edit",
currentMenu,
list: this.setting.list,
index: this.setting.index,
menuId: this.setting.menuId
};
const url =
"/pages/apply/dynamicModel/form?config=" +
this.jnpf.base64.encode(JSON.stringify(config));
uni.navigateTo({
url: url,
});
},
},
};
</script>
<style lang="scss" scoped>
page {
background-color: #f0f2f6;
}
</style>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

View File

@@ -0,0 +1,121 @@
<template>
<view class="dynamicModel-v">
<!-- <Form :config="config" :modelId="modelId" :isPreview="isPreview" /> -->
<List :config="config" :modelId="modelId" :isPreview="isPreview"
:title="title" :menuId="menuId" ref="List" />
</view>
</template>
<script>
import Form from "./components/form/index.vue";
import List from "./components/list/index.vue";
import {
getFlowStartFormId
} from "@/api/workFlow/flowEngine";
import {
getConfigData
} from "@/api/apply/visualDev";
import {
useBaseStore
} from '@/store/modules/base'
import { computed } from "vue";
const baseStore = useBaseStore()
export default {
name: "dynamicModel",
components: {
Form,
List,
},
data() {
return {
webType: "",
showPage: false,
isPreview: false,
modelId: "",
menuId: "",
title: "",
config: {},
preview: false,
flowId: '',
enableFlow: 0,
};
},
onLoad(obj) {
// baseStore.getDictionaryDataAll()
this.config = JSON.parse(obj.config) || {};
this.isPreview = this.config.isPreview || false;
this.enableFlow = this.config.type === 9 ? 1 : 0;
this.title = this.config.tableTitle || "";
this.modelId = this.config.id || "";
uni.setNavigationBarTitle({
title: this.title,
});
// if (!this.enableFlow) return this.getConfigData();
this.flowId = this.config.moduleId
// this.getModelId()
},
methods: {
// 获取流程版本ID和发起节点表单ID
getModelId() {
getFlowStartFormId(this.flowId).then(res => {
if (!res.data || !res.data.formId) return;
this.config.moduleId = res.data.formId
// this.getConfigData();
})
},
getConfigData() {
getConfigData(this.config.moduleId, this.menuId).then((res) => {
if (res.code !== 200 || !res.data) return this.handleError('暂无此页面')
if (this.enableFlow && res.data.webType == 1) return this.jump();
this.config = {
...res.data,
...this.config,
enableFlow: this.enableFlow,
flowId: this.flowId
};
this.showPage = true;
this.isPreview = !!this.config.isPreview;
this.modelId = this.config.moduleId;
this.menuId = this.config.id || "";
this.webType = this.config.webType || 2;
this.title = this.config.fullName || "";
uni.setNavigationBarTitle({
title: this.title
});
});
},
jump() {
const config = {
id: "",
flowId: this.flowId,
opType: "-1",
hideCancelBtn: true,
hideSaveBtn: true
};
uni.redirectTo({
url: "/pages/workFlow/flowBefore/index?config=" +
this.jnpf.base64.encode(JSON.stringify(config)),
fail: () => {
this.$u.toast("暂无此页面");
},
});
},
handleError(msg) {
this.$u.toast(msg);
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
},
};
</script>
<style lang="scss">
page {
background-color: #f0f2f6;
}
.dynamicModel-v {
height: 100%;
}
</style>

View File

@@ -0,0 +1,180 @@
<template>
<view class="dynamicModel-v">
<template v-if="showPage">
<view class="jnpf-wrap jnpf-wrap-form" v-if="config.mt == 2">
<JnpfParser :formConf="formConf" ref="dynamicForm" @submit="sumbitForm" :key="key" />
</view>
<template v-else>
<FlowForm ref="flowForm" />
</template>
</template>
</view>
</template>
<script>
import FlowForm from '@/pages/workFlow/flowBefore/flowForm'
import {
getConfigData,
getModelInfo
} from '@/api/apply/visualDev'
export default {
name: 'scanForm',
components: {
FlowForm
},
data() {
return {
webType: '',
showPage: false,
origin: '',
id: '',
config: {},
formConf: {},
key: +new Date(),
isAdd: false,
userInfo: {}
}
},
onLoad(option) {
this.userInfo = uni.getStorageSync('userInfo') || {}
this.config = JSON.parse(option.config)
this.initData()
},
methods: {
initData() {
this.showPage = false
if (this.config.mt == 2) {
this.getConfigData()
} else {
this.isAdd = true
let data = {
flowId: this.config.fid,
id: this.config.pid,
formType: 2,
opType: this.config.opt,
taskId: this.config.ftid
}
this.showPage = true
this.$nextTick(() => {
this.$refs.flowForm.init(data)
})
}
},
getConfigData() {
getConfigData(this.config.mid).then(res => {
if (res.code !== 200 || !res.data) {
uni.showToast({
title: '暂无此页面',
icon: 'none',
complete: () => {
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
})
return
}
this.formConf = JSON.parse(res.data.formData)
uni.setNavigationBarTitle({
title: res.data.fullName
})
let extra = {
modelId: this.config.mid,
id: this.config.id,
type: this.config.mt
}
uni.setStorageSync('dynamicModelExtra', extra)
getModelInfo(this.config.mid, this.config.id).then(res => {
if (!res.data.data) return
let formData = JSON.parse(res.data.data)
this.fillFormData(this.formConf, formData)
this.$nextTick(() => {
this.showPage = true
this.key = +new Date()
})
})
})
},
fillFormData(form, data) {
const loop = list => {
for (let i = 0; i < list.length; i++) {
let item = list[i]
let vModel = item.__vModel__
let config = item.__config__
if (vModel) {
let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
if (!config.isSubTable) config.defaultValue = val
if (this.isAdd || config.isSubTable) { //新增时候,默认当前
if (config.defaultCurrent) {
if (config.jnpfKey === 'datePicker') {
if (!data.hasOwnProperty(vModel)) {
let format = this.jnpf.handelFormat(item.format)
let dateStr = this.jnpf.toDate(new Date().getTime(), format)
let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
'-01 00:00:00' : format === 'yyyy-MM-dd' ?
' 00:00:00' : ''
val = new Date(dateStr + time).getTime()
config.defaultValue = val
}
}
if (config.jnpfKey === 'timePicker') {
if (!data.hasOwnProperty(vModel)) {
config.defaultValue = this.jnpf.toDate(new Date(), item.format)
}
}
if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
config.defaultValue = item.multiple ? this.userInfo.organizeIds :
this.userInfo.organizeId
}
if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
config.defaultValue = item.multiple ? this.userInfo.positionIds :
this.userInfo.positionId
}
const userId = this.userInfo.userId
if (config.jnpfKey === 'userSelect' && userId) {
config.defaultValue = item.multiple ? [userId] : userId;
}
if (config.jnpfKey === 'usersSelect' && userId) {
config.defaultValue = [userId + '--user'];
}
if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
config.defaultValue = this.userInfo.signImg
}
}
}
this.$set(item, 'disabled', true)
let noShow = !item.__config__.noShow ? false : item.__config__.noShow
let isVisibility = false
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
.__config__.visibility.includes('app'))) isVisibility = true
this.$set(item.__config__, 'isVisibility', isVisibility)
this.$set(item.__config__, 'noShow', noShow)
} else {
let noShow = false,
isVisibility = false
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
.__config__.visibility.includes('app'))) isVisibility = true
this.$set(item.__config__, 'isVisibility', isVisibility)
this.$set(item.__config__, 'noShow', noShow)
}
if (item.__config__ && item.__config__.jnpfKey !== 'table' && item.__config__.children && Array
.isArray(item.__config__.children)) {
loop(item.__config__.children)
}
}
}
loop(form.fields)
},
}
}
</script>
<style lang="scss">
page {
background-color: #f0f2f6;
}
.dynamicModel-v {
height: 100%;
}
</style>

View File

@@ -1,24 +1,32 @@
<template> <template>
<view class="menu-v"> <view class="menu-v">
<view class="search-box u-m-b-20"> <!-- <view class="search-box u-m-b-20">
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72" :show-action="false" <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%;"> @change="search" bg-color="#f0f2f6" shape="square" style="width: 100%;">
</u-search> </u-search>
</view> </view> -->
<mescroll-body ref="mescrollRef" @down="downCallback" :down="downOption" :sticky="false" @up="upCallback" <mescroll-body ref="mescrollRef" @down="downCallback" :down="downOption" :sticky="false" @up="upCallback"
:up="upOption" :bottombar="false" @init="mescrollInit" :top="mescrollTop"> :up="upOption" :bottombar="false" @init="mescrollInit" :top="mescrollTop">
<view class="workFlow-list"> <view class="workFlow-list">
<view class="part" v-for="(item, i) in menuList" :key="i"> <view class="caption u-line-1">业务表单</view>
<view class="caption u-line-1" v-if="item?.children?.length"> <view class="u-flex u-flex-wrap item-container">
{{ item.fullName }} <view class="item u-flex-col u-col-center"
</view> v-for="(item, i) in menuList"
<view class="u-flex u-flex-wrap"> :key="item.id"
<view class="item u-flex-col u-col-center" v-for="(child, ii) in item.children" :key="ii" @click="handelClick(item)">
@click="handelClick(child)"> <!-- 渲染图标 -->
<text class="u-font-40 item-icon" :class="child.icon" <view class="item-icon" :style="{ background: item.iconBackground || '#008cff' }">
:style="{ background: child.iconBackground || '#008cff' }" /> <image class="item-img" :src="`/static/image/${item.name}.png`"></image>
<text class="u-font-24 u-line-1 item-text">{{child.fullName}}</text> <!-- 使用 iconify-icon 渲染 ep 系列图标 -->
<!-- <iconify-icon
:icon="item.icon"
color="#ffffff"
width="24"
height="24"
></iconify-icon> -->
</view> </view>
<!-- 渲染名称 -->
<text class="u-font-24 u-line-1 item-text">{{item.name}}</text>
</view> </view>
</view> </view>
</view> </view>
@@ -27,9 +35,11 @@
</template> </template>
<script> <script>
import { import {
getMenuList,
getChildList getChildList
} from "@/api/apply/apply.js"; } from "@/api/apply/apply.js";
import {
getMenuData
} from "@/api/index/index";
import resources from "@/libs/resources.js"; import resources from "@/libs/resources.js";
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
import { import {
@@ -91,84 +101,13 @@
}, },
methods: { methods: {
handelClick(item) { handelClick(item) {
if (item.type == 1) { const config = {
getChildList(item.id).then(res => { billNoPrefix: item.billNoPrefix,
this.listChild = res.data || [] id: item.id,
this.handleProperty(this.listChild) name: item.name,
this.$nextTick(() => { tableTitle: item.tableTitle,
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 = '' let url = "/pages/apply/dynamicModelList/index?config=" + JSON.stringify(config)
// 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({ uni.navigateTo({
url, url,
fail: () => { fail: () => {
@@ -184,13 +123,13 @@
title: '正在加载', title: '正在加载',
mask: true mask: true
}) })
getMenuList(query) getMenuData()
.then((res) => { .then((res) => {
let list = res.data.list || []; let list =res?.data || [];
this.mescroll.endSuccess(list.length); this.mescroll.endSuccess(list.length);
this.list = list.filter(o => o.children && o.children.length) this.menuList = list;
this.menuList = this.list; console.log(this.menuList,'menuList---')
this.handleProperty(this.list) // this.handleProperty(this.list)
uni.hideLoading() uni.hideLoading()
this.key = +new Date(); this.key = +new Date();
this.mescroll.endSuccess(this.menuList.length, false); this.mescroll.endSuccess(this.menuList.length, false);
@@ -338,4 +277,58 @@
} }
} }
} }
.menu-v {
.workFlow-list {
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
// 分类标题样式
.caption {
font-size: 32rpx;
font-weight: bold;
color: #333;
padding: 0 20rpx 20rpx;
border-bottom: 1px solid #f5f5f5;
}
// 项容器(让项横向排列)
.item-container {
padding: 20rpx;
}
// 单个项的样式
.item {
width: 25%; // 一行显示4个可根据需求调整
margin-bottom: 30rpx;
align-items: center;
// 图标样式
.item-icon {
width: 88rpx;
height: 88rpx;
border-radius: 20rpx; // 圆角更美观
color: #fff;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10rpx;
}
.item-img {
width: 60%;
height: 60%;
}
// 文字样式
.item-text {
font-size: 24rpx;
color: #333;
text-align: center;
}
}
}
}
</style> </style>

BIN
pages/index/img/dun.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 KiB

View File

@@ -86,7 +86,7 @@
}, },
onLoad() { onLoad() {
const chatStore = useChatStore() const chatStore = useChatStore()
if (!chatStore.getSocket) chat && chat.initSocket() // if (!chatStore.getSocket) chat && chat.initSocket()
const userStore = useUserStore() const userStore = useUserStore()
userStore.getCurrentUser().then(() => { userStore.getCurrentUser().then(() => {
this.getSystemName() this.getSystemName()

744
pages/index/indexWork.vue Normal file
View File

@@ -0,0 +1,744 @@
<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>
<view v-if="todoList.length > 2" class="todo-more" @click="openToDoPage">
更多
<u-icon name="arrow-down" class="u-p-r-10"color="#666"></u-icon>
</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-------')
const config = {
billNoPrefix: item.billNoPrefix,
id: item.id,
name: item.name,
tableTitle: item.tableTitle,
}
if (item.tabType == 'flow') return this.JumpFlow(config)
if (item.tabType == 'menu') return this.JumpApply(config)
},
JumpApply(item) {
let url = "/pages/apply/dynamicModelList/index?config=" + 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: 2000
}
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.slice(0,3) || []
}
})
},
//更多按钮
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', 1);
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=' +
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: 780rpx !important;
::-webkit-scrollbar {
width: 4rpx;
}
::-webkit-scrollbar-thumb {
background-color: #e5e5e5;
border-radius: 2rpx;
}
}
.todo-more {
text-align: center;
color: #666;
font-size: 28rpx;
margin-top: 5rpx;
}
.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: 28rpx;
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>

View File

@@ -4,8 +4,8 @@
<view class="u-m-r-10"> <view class="u-m-r-10">
<u-avatar size="127" @click='chooseAvatar' :src='avatarSrc'></u-avatar> <u-avatar size="127" @click='chooseAvatar' :src='avatarSrc'></u-avatar>
</view> </view>
<view class="u-flex-1 f-right" @click="personalPage('/pages/my/personalData/index')"> <view class="u-flex-1 f-right" @click="personalPage('/pages/my/personalData/index','个人中心')">
<view class="u-font-36 u-m-l-16">{{baseInfo.realName}}</view> <view class="u-font-36 u-m-l-16">{{baseInfo.nickname}}</view>
<view class="u-m-l-10 u-p-10"> <view class="u-m-l-10 u-p-10">
<u-icon name="arrow-right" color="#969799" size="28"></u-icon> <u-icon name="arrow-right" color="#969799" size="28"></u-icon>
</view> </view>
@@ -15,7 +15,7 @@
<view class="my-group-box-inner"> <view class="my-group-box-inner">
<u-cell-group :border="false" class="cell-group"> <u-cell-group :border="false" class="cell-group">
<view v-for="(item, idx) in group.items" :key="idx"> <view v-for="(item, idx) in group.items" :key="idx">
<u-cell-item :title="$t(item.title)" @click="openPage(item.page, item.param)" <u-cell-item :title="$t(item.title)" @click="personalPage(item.page,item.name)"
:title-style="titleStyle" :border-bottom="item.borderBottom" :title-style="titleStyle" :border-bottom="item.borderBottom"
v-if="item.title!='app.my.scanCode'"> v-if="item.title!='app.my.scanCode'">
<template #icon> <template #icon>
@@ -46,7 +46,8 @@
import { import {
UpdateAvatar, UpdateAvatar,
UserSettingInfo, UserSettingInfo,
setMajor setMajor,
getUserProfile,
} from '@/api/common' } from '@/api/common'
import chat from '@/libs/chat.js' import chat from '@/libs/chat.js'
import { import {
@@ -67,61 +68,63 @@
avatarSrc: '', avatarSrc: '',
baseInfo: {}, baseInfo: {},
loading: false, loading: false,
cellGroups: [{ cellGroups: [
items: [{ // {
title: 'app.my.organization', // items: [{
page: '/pages/my/organization/index', // title: 'app.my.organization',
param: 'position', // page: '/pages/my/organization/index',
icon: 'icon-ym-zuzhi', // param: 'position',
color: '#6071F5', // icon: 'icon-ym-zuzhi',
borderBottom: true // color: '#6071F5',
}, // borderBottom: true
{ // },
title: 'app.my.switchIdentity', // {
page: '/pages/my/identity/index', // title: 'app.my.switchIdentity',
param: 'standing', // page: '/pages/my/identity/index',
icon: 'icon-ym-position1', // param: 'standing',
color: '#F4A02F', // icon: 'icon-ym-position1',
borderBottom: true // color: '#F4A02F',
}, // borderBottom: true
{ // },
title: 'app.my.changeSystem', // {
page: '/pages/my/changeSystem/index', // title: 'app.my.changeSystem',
icon: 'icon-ym-header-sys-toggle', // page: '/pages/my/changeSystem/index',
color: '#3686F2', // icon: 'icon-ym-header-sys-toggle',
borderBottom: false // color: '#3686F2',
}, // borderBottom: false
], // },
}, // ],
// },
{ {
items: [{ items: [{
title: 'app.my.personalSetting', title: 'app.my.personalSetting',
page: '/pages/my/personalSetting/index', page: '/pages/my/personalData/index',
icon: 'icon-ym-shezhi', icon: 'icon-ym-shezhi',
color: '#F46E1B', color: '#F46E1B',
name: '个人设置',
borderBottom: true borderBottom: true
}, },
{ // {
title: 'app.my.accountSecurity', // title: 'app.my.accountSecurity',
page: '/pages/my/accountSecurity/index', // page: '/pages/my/accountSecurity/index',
icon: 'icon-ym-secure', // icon: 'icon-ym-secure',
color: '#26C6A1', // color: '#26C6A1',
borderBottom: true // borderBottom: true
}, // },
{ // {
title: 'app.my.contacts', // title: 'app.my.contacts',
page: '/pages/my/contacts/index', // page: '/pages/my/contacts/index',
icon: 'icon-ym-contacts', // icon: 'icon-ym-contacts',
color: '#6071F5', // color: '#6071F5',
borderBottom: true // borderBottom: true
}, // },
{ // {
title: 'app.my.chat', // title: 'app.my.chat',
page: '/pages/message/chat/index', // page: '/pages/message/chat/index',
icon: 'icon-ym-chat', // icon: 'icon-ym-chat',
color: '#4CBF2A', // color: '#4CBF2A',
borderBottom: false // borderBottom: false
}, // },
], ],
}, },
{ {
@@ -132,13 +135,13 @@
color: '#F7AA41', color: '#F7AA41',
borderBottom: true borderBottom: true
}, },
{ // {
title: 'app.my.setting', // title: 'app.my.setting',
page: '/pages/my/settings/index', // page: '/pages/my/settings/index',
icon: 'icon-ym-route-appMenu', // icon: 'icon-ym-route-appMenu',
color: '#5944FC', // color: '#5944FC',
borderBottom: false // borderBottom: false
}, // },
], ],
}, },
], ],
@@ -161,12 +164,18 @@
}, },
onLoad() { onLoad() {
const chatStore = useChatStore() const chatStore = useChatStore()
if (!chatStore.getSocket) chat.initSocket() // if (!chatStore.getSocket) chat.initSocket()
}, },
onShow() { onShow() {
UserSettingInfo().then(res => { // UserSettingInfo().then(res => {
// this.baseInfo = res.data || {}
// this.avatarSrc = this.baseURL2 + this.baseInfo.avatar
// this.loading = true
// })
getUserProfile().then(res=>{
if(res.code == 0) {
this.baseInfo = res.data || {} this.baseInfo = res.data || {}
this.avatarSrc = this.baseURL2 + this.baseInfo.avatar }
this.loading = true this.loading = true
}) })
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
@@ -184,8 +193,9 @@
if (!isAccept) return this.$u.toast(`请上传图片`) if (!isAccept) return this.$u.toast(`请上传图片`)
// #endif // #endif
let tempFilePaths = res.tempFilePaths[0] let tempFilePaths = res.tempFilePaths[0]
console.log(this.baseURL,'baseURL---')
uni.uploadFile({ uni.uploadFile({
url: this.baseURL + 'userAvatar', url: this.baseURL + '/admin-api/infra/file/jeelowcode/upload',
filePath: tempFilePaths, filePath: tempFilePaths,
name: 'file', name: 'file',
header: { header: {
@@ -193,14 +203,18 @@
}, },
success: (uploadFileRes) => { success: (uploadFileRes) => {
let data = JSON.parse(uploadFileRes.data) let data = JSON.parse(uploadFileRes.data)
if (data.code === 200) { console.log(data,'data-----')
UpdateAvatar(data.data.name).then(res => { this.avatarSrc =data.data.fileUrl
console.log(this.avatarSrc,'-this.avatarSrc')
this.$u.toast('头像更换成功') this.$u.toast('头像更换成功')
this.avatarSrc = this.baseURL2 + data.data.url // if (data.code === 0) {
}) // UpdateAvatar(data.data.name).then(res => {
} else { // this.$u.toast('头像更换成功')
this.$u.toast(data.msg) // this.avatarSrc = this.baseURL2 + data.data.url
} // })
// } else {
// this.$u.toast(data.msg)
// }
}, },
fail: (err) => { fail: (err) => {
this.$u.toast('头像更换失败') this.$u.toast('头像更换失败')
@@ -216,19 +230,17 @@
url: url url: url
}) })
}, },
personalPage(path) { personalPage(path,name) {
if (!path) return; if (!path) return;
const neededFields = [ const neededFields = [
'realName', 'nation', 'gender', 'nativePlace', 'certificatesType', 'realName', 'nation', 'gender', 'nativePlace', 'certificatesType',
'certificatesNumber', 'education', 'birthday', 'telePhone', 'landline', 'certificatesNumber', 'education', 'birthday', 'telePhone', 'landline',
'urgentContacts', 'urgentTelePhone', 'postalAddress', 'signature' 'urgentContacts', 'urgentTelePhone', 'postalAddress', 'signature'
]; ];
const baseInfo = neededFields.reduce((obj, key) => { const baseInfo = {
if (this.baseInfo[key] !== undefined) { ...this.baseInfo,
obj[key] = this.baseInfo[key]; title:name,
} }
return obj;
}, {});
uni.navigateTo({ uni.navigateTo({
url: `${path}?baseInfo=${JSON.stringify(baseInfo)}` url: `${path}?baseInfo=${JSON.stringify(baseInfo)}`
}); });
@@ -255,7 +267,7 @@
userStore.logout().then(() => { userStore.logout().then(() => {
uni.closeSocket() uni.closeSocket()
uni.reLaunch({ uni.reLaunch({
url: '/pages/login/index' url: '/pages/login/index?socialLogin=true'
}) })
}) })
this.removeAccount() this.removeAccount()

View File

@@ -6,7 +6,7 @@
<view class="launch-img"> <view class="launch-img">
<image :src="startup" mode="widthFix"></image> <image :src="startup" mode="widthFix"></image>
</view> </view>
<view class="copyright">Copyright © 2025 引迈信息技术有限公司出品</view> <view class="copyright">Copyright © 2025 CSCN技术有限公司出品</view>
</view> </view>
</view> </view>
</template> </template>

View File

@@ -3,24 +3,30 @@
<view class="login-bg"> <view class="login-bg">
<image src="../../static/image/login-bg.jpg" mode="widthFix"></image> <image src="../../static/image/login-bg.jpg" mode="widthFix"></image>
<view class="logoImg"> <view class="logoImg">
<u-image :src="appIcon" mode="widthFix" :border-radius="20" width="160" height="160"> <image src="../../static/image/logoT.png" mode="widthFix"></image>
<!-- <u-image src="../../static/image/logo.png" mode="widthFix" :border-radius="20" width="160" height="160">
<template #error> <template #error>
<u-image :src="logoImg" mode="widthFix" width="160" height="160"> <u-image :src="logoImg" mode="widthFix" width="160" height="160">
</u-image> </u-image>
</template> </template>
</u-image> </u-image> -->
</view> </view>
<view class="login-version"> <!-- <view class="login-version">
<view class="login-version-text">{{sysConfigInfo.sysVersion || define.sysVersion}}</view> <view class="login-version-text">{{sysConfigInfo.sysVersion || define.sysVersion}}</view>
</view> </view> -->
</view> </view>
<view class="logo-hd u-flex-col"> <view class="logo-hd u-flex-col">
<view class="loginSwitch u-flex-col"> <view class="loginSwitch u-flex-col">
<view class="loginInputBox u-flex-col" v-show="!isSso && !ssoLoading"> <view class="loginInputBox u-flex-col" v-show=" true || !isSso && !ssoLoading">
<u-form :model="formData" :rules="rules" ref="dataForm" :errorType="['toast']" label-position="left" <u-form :model="formData" :rules="rules" ref="dataForm" :errorType="['toast']" label-position="left"
label-width="150" label-align="left"> label-width="150" label-align="left">
<u-form-item prop="account" :borderBottom="false"> <u-form-item v-show="false" prop="account" :borderBottom="false">
<u-input input-align='left' v-model="formData.account" placeholder="请输入帐号" @focus="onFocus" <u-input input-align='left' v-model="formData.tenantName" placeholder="请输入租户名称" @focus="onFocus"
@blur="onBlur" border border-color="#F0F1F3" placeholder-style="#9D9D9D">
</u-input>
</u-form-item>
<u-form-item prop="username" :borderBottom="false">
<u-input input-align='left' v-model="formData.username" placeholder="请输入帐号" @focus="onFocus"
@blur="onBlur" border border-color="#F0F1F3" placeholder-style="#9D9D9D"> @blur="onBlur" border border-color="#F0F1F3" placeholder-style="#9D9D9D">
</u-input> </u-input>
</u-form-item> </u-form-item>
@@ -43,6 +49,9 @@
<view class="remember-wrap"> <view class="remember-wrap">
<u-checkbox v-model="remember"><span class="remember-text">记住账号密码</span></u-checkbox> <u-checkbox v-model="remember"><span class="remember-text">记住账号密码</span></u-checkbox>
</view> </view>
<!-- <view class="remember-wrap">
<u-checkbox v-model="isCertify"><span class="remember-text">是否认证</span></u-checkbox>
</view> -->
<view class="loginBtnBox"> <view class="loginBtnBox">
<u-button @click="login" type="primary" :loading="loading">{{ loading ? "登录中...":"登录"}} <u-button @click="login" type="primary" :loading="loading">{{ loading ? "登录中...":"登录"}}
</u-button> </u-button>
@@ -107,19 +116,22 @@
</view> </view>
</view> </view>
</u-popup> </u-popup>
<view class="copyright" v-if="isKeyUp">{{copyright}}</view> <view class="copyright">{{copyright}}</view>
</view> </view>
</template> </template>
<script> <script>
import { import {
login, login,
getConfig, socialLogin,
getPermissionInfo,
getByName,
getCallback, getCallback,
otherlogin, otherlogin,
getLoginConfig, getLoginConfig,
getSocialsUserList, getSocialsUserList,
socialsLogin, socialsLogin,
getTicket getTicket,
socialAuthRedirect
} from '@/api/common.js' } from '@/api/common.js'
import md5Libs from "@/uni_modules/vk-uview-ui/libs/function/md5"; import md5Libs from "@/uni_modules/vk-uview-ui/libs/function/md5";
import resources from '@/libs/resources' import resources from '@/libs/resources'
@@ -127,15 +139,18 @@
useUserStore useUserStore
} from '@/store/modules/user' } from '@/store/modules/user'
import logoImg from '@/static/logo.png' import logoImg from '@/static/logo.png'
let unique = 0
export default { export default {
data() { data() {
return { return {
remember: false, remember: false,
isCertify: false,
logoImg, logoImg,
imgUrl: '', imgUrl: '',
loading: false, loading: false,
formData: { formData: {
account: "", tenantName: "000000",
username: "",
password: "", password: "",
code: "", code: "",
origin: 'password' origin: 'password'
@@ -144,7 +159,7 @@
codeLength: 4, codeLength: 4,
isCode: false, isCode: false,
rules: { rules: {
account: [{ username: [{
required: true, required: true,
message: '请输入账号', message: '请输入账号',
trigger: 'blur', trigger: 'blur',
@@ -157,8 +172,8 @@
}, },
sysConfigInfo: {}, sysConfigInfo: {},
appIcon: '', appIcon: '',
sysName: '', sysName: '综合监控系统',
copyright: '', copyright: '综合监控系统',
socialsList: [], socialsList: [],
show: false, show: false,
tenantUserInfo: [], tenantUserInfo: [],
@@ -169,7 +184,9 @@
preUrl: '', preUrl: '',
ticketParams: "", ticketParams: "",
loginCode: '', loginCode: '',
isKeyUp: true isKeyUp: true,
ssoOptions: {}, // 端点登录参数
currentUrl: '', // 地址
} }
}, },
watch: { watch: {
@@ -195,39 +212,60 @@
this.$refs.dataForm.setRules(this.rules); this.$refs.dataForm.setRules(this.rules);
}, },
onLoad(options) { onLoad(options) {
if (options?.JNPF_TICKET) { this.currentUrl = window.location.href
this.ssoTicket = options.JNPF_TICKET this.ssoOptions = options
uni.navigateTo({ if(options.code){
url: `/pages/login/otherLogin?ssoTicket=${this.ssoTicket}` this.exchangeToken(options)
}) }else if(options.socialLogin){
this.getLogin('creat')
} }
this.ssoTicket = uni.getStorageSync('ssoTicket') else{
this.sysConfigInfo = uni.getStorageSync('sysConfigInfo') this.certifyLogin()
this.appIcon = !!this.sysConfigInfo.appIcon ? this.baseURL + this.sysConfigInfo.appIcon : }
logoImg
this.sysName = !!this.sysConfigInfo.companyName ? this.sysConfigInfo.sysName : // if(JSON.stringify(options) == '{}'){
'JNPF快速开发平台' // // 端点登录
this.copyright = !!this.sysConfigInfo.copyright ? this.sysConfigInfo.copyright : // this.certifyLogin()
this.define.copyright // }else {
// this.getLogin()
// }
// if (options?.JNPF_TICKET) {
// this.ssoTicket = options.JNPF_TICKET
// uni.navigateTo({
// url: `/pages/login/otherLogin?ssoTicket=${this.ssoTicket}`
// })
// }
// this.ssoTicket = uni.getStorageSync('ssoTicket')
// this.sysConfigInfo = uni.getStorageSync('sysConfigInfo')
// console.log(this.define,'define-------------')
// this.appIcon = !!this.sysConfigInfo.appIcon ? this.baseURL + this.sysConfigInfo.appIcon :
// logoImg
// this.sysName = !!this.sysConfigInfo.companyName ? this.sysConfigInfo.sysName :
// '综合监控系统'
// // this.copyright = !!this.sysConfigInfo.copyright ? this.sysConfigInfo.copyright :
// // this.define.copyright
// // this.copyright = !!this.sysConfigInfo.copyright && this.sysConfigInfo.copyright
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: this.sysName title: this.sysName
}) })
let needCode = uni.getStorageSync('app_loginNeedCode') // let needCode = uni.getStorageSync('app_loginNeedCode')
this.isCode = needCode // this.isCode = needCode
this.changeCode() // this.changeCode()
this.getLoginConfig() // this.getLoginConfig()
this.formData.password = ''; // this.formData.password = '';
if (options.data) { // if (options.data) {
this.tenantUserInfo = JSON.parse(options.data) // this.tenantUserInfo = JSON.parse(options.data)
if (this.tenantUserInfo) this.show = true // // if (this.tenantUserInfo) this.show = true
} // }
this.initAccount() // this.initAccount()
// #ifndef H5 // // #ifndef H5
uni.onKeyboardHeightChange(res => { // uni.onKeyboardHeightChange(res => {
this.isKeyUp = res.height == 0 ? true : false // this.isKeyUp = res.height == 0 ? true : false
return this.isKeyUp // return this.isKeyUp
}) // })
// #endif // // #endif
// this.initLoginConfig()
}, },
methods: { methods: {
initAccount() { initAccount() {
@@ -279,7 +317,7 @@
if (this.tenantUserInfo.length == 1) { if (this.tenantUserInfo.length == 1) {
this.loginHandel() this.loginHandel()
} else { } else {
this.show = true // this.show = true
} }
} else { } else {
this.show = false this.show = false
@@ -442,14 +480,37 @@
this.ssoLoading = false this.ssoLoading = false
}) })
}, },
getCodeConfig(val) {
if (!val) return initLoginConfig() {
getConfig(val).then(res => { // 1. 强制关闭SSO登录显示账号密码登录
this.needCode = !!res.data.enableVerificationCode this.isSso = false
if (this.needCode) { // 2. 关闭SSO加载状态让页面正常显示
this.codeLength = res.data.verificationCodeNumber || 4 this.ssoLoading = false
this.changeCode() // 3. 可选:配置第三方登录列表(如果需要显示微信/QQ登录
} // 如需显示第三方登录,取消下面注释并调整配置;不需要则留空数组
this.socialsList = [
// 示例微信登录配置根据实际项目的icon/class调整
// {
// enname: 'wechat_open',
// name: '微信登录',
// icon: 'icon-ym icon-ym-wechat' // 替换成项目真实的微信图标类名
// },
// 示例QQ登录配置
// {
// enname: 'qq',
// name: 'QQ登录',
// icon: 'icon-ym icon-ym-qq' // 替换成项目真实的QQ图标类名
// }
]
// 4. 可选SSO相关配置用不到可以不赋值
this.preUrl = ''
this.ticketParams = ''
},
getCodeConfig() {
const userStore = useUserStore()
getByName(this.formData.tenantName).then(res => {
const data = res.data
userStore.setTenantId(data)
}) })
}, },
changeCode() { changeCode() {
@@ -458,20 +519,25 @@
this.imgUrl = `/api/oauth/ImageCode/${this.codeLength || 4}/${timestamp}` this.imgUrl = `/api/oauth/ImageCode/${this.codeLength || 4}/${timestamp}`
}, },
login() { login() {
const userStore = useUserStore()
this.$refs.dataForm.validate(valid => { this.$refs.dataForm.validate(valid => {
if (valid) { if (valid) {
this.loading = true this.loading = true
const password = md5Libs.md5(this.formData.password); const password = md5Libs.md5(this.formData.password);
const encryptPassword = this.jnpf.aesEncryption.encrypt(password); const encryptPassword = this.jnpf.aesEncryption.encrypt(password);
this.getLogin('click')
}
});
// this.certifyLogin()
},
// 普通登录
getLogin(type){
if(type !== 'click') return
const userStore = useUserStore()
let query = { let query = {
account: this.formData.account, tenantName: this.formData.tenantName,
password: encryptPassword, username: this.formData.username,
timestamp: this.timestamp, password: this.formData.password,
code: this.formData.code, rememberMe : false
origin: this.formData.origin,
jnpf_ticket: this.ssoTicket,
grant_type: 'password',
} }
// #ifdef APP-PLUS // #ifdef APP-PLUS
const clientId = plus.push.getClientInfo().clientid; const clientId = plus.push.getClientInfo().clientid;
@@ -480,19 +546,31 @@
// query.Client_Id = uni.getStorageSync('cid') // query.Client_Id = uni.getStorageSync('cid')
// #endif // #endif
login(query).then(res => { login(query).then(res => {
let token = res.data.token const {accessToken,refreshToken} = res.data
userStore.setToken(token) userStore.setToken(accessToken)
userStore.setRefreshToken(refreshToken)
this.rememberAccount() this.rememberAccount()
setTimeout(()=>{ if(res.code == 0){
userStore.getCurrentUser().then(res => { getPermissionInfo().then(res=>{
this.loading = false if(res.code == 0){
userStore.setUserInfo(res.data)
uni.switchTab({ uni.switchTab({
url: '/pages/index/index' url: '/pages/index/indexWork'
}); });
}).catch(() => { }
this.loading = false
}) })
},1000) }
// setTimeout(()=>{
// userStore.getCurrentUser().then(res => {
// this.loading = false
// uni.switchTab({
// url: '/pages/index/index'
// });
// }).catch(() => {
// this.loading = false
// })
// },1000)
// getPermissionInfo
}).catch((err) => { }).catch((err) => {
uni.showToast({ uni.showToast({
title: err, title: err,
@@ -503,8 +581,44 @@
this.changeCode() this.changeCode()
this.loading = false this.loading = false
}) })
} },
// 认证登录
async certifyLogin(){
let type = '110'
let redirectUri = location.origin + '/pages/login/index?' + encodeURIComponent(`type=${type}&redirect=/`)
const res = await socialAuthRedirect(type,encodeURIComponent(redirectUri))
console.log(res,'res-------')
window.location.href = res.data
},
async exchangeToken(options) {
try {
const type = '110'
const code = options?.code
const state =options?.state || this.uuid()
const res = await socialLogin(type, code, state)
const {accessToken,refreshToken} = res.data
const userStore = useUserStore()
// 存储Token和用户信息
userStore.setToken(accessToken)
userStore.setRefreshToken(refreshToken)
uni.switchTab({
url: '/pages/index/indexWork'
}); });
} catch (err) {
console.error('换取Token失败', err)
uni.showToast({
title: '登录失败,请重试',
icon: 'none'
})
} finally {
this.loading = false
}
},
uuid() {
const time = Date.now()
const random = Math.floor(Math.random() * 1000000000)
unique++
return 'qrcode_' + random + unique + String(time)
}, },
ssoLogin() { ssoLogin() {
getTicket().then(res => { getTicket().then(res => {
@@ -571,8 +685,8 @@
} }
.logoImg { .logoImg {
width: 160rpx; width: 260rpx;
height: 160rpx; height: 260rpx;
margin: 0 auto; margin: 0 auto;
position: absolute; position: absolute;
/* #ifdef APP-PLUS */ /* #ifdef APP-PLUS */
@@ -787,4 +901,47 @@
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.url-modal {
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
text-align: left;
.modal-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #333;
text-align: center;
}
.modal-content {
margin-bottom: 40rpx;
max-height: 300rpx;
overflow-y: auto;
padding: 20rpx;
background: #f5f7fa;
border-radius: 8rpx;
.url-text {
font-size: 26rpx;
color: #666;
line-height: 40rpx;
word-break: break-all;
}
}
.modal-btns {
display: flex;
justify-content: space-between;
gap: 20rpx;
.u-button {
flex: 1;
height: 80rpx;
line-height: 80rpx;
}
}
}
</style> </style>

View File

@@ -10,9 +10,7 @@
</view> </view>
<view class="content u-p-l-32 u-p-r-32 u-p-t-30 u-font-28"> <view class="content u-p-l-32 u-p-r-32 u-p-t-30 u-font-28">
<text>引迈信息技术有限公司是一家做快速开发平台的企业针对软件传统开发遇到招人难留人难用人成本高技术更新换代快等一系列问题只需要一套JNPF平台您遇到的一系列问题就依然而解 <text>软通动力</text>
JNPF采用主流的两大技术Java/.Net开发是一套低代码开发平台可视化开发环境有拖拽式的代码生成器灵活的权限配置SaaS服务强大的接口对接随心可变的工作流引擎一站式开发多端使用WebAndroidIOS微信小程序并且有以构建业务流程逻辑和数据模型等所需的功能为企业项目节省80%的重回工作让开发者将重心放在业务逻辑不必烦恼底层架构设计可短时间开发出如ERPOACRMHRMIS以及电信银行政府企业等各行业的企业应用系统
引迈信息技术有限公司以诚信为根本服务为基础理念通过持续不断地研发技术创新强化平台质量和颜值为企业保驾护航</text>
</view> </view>
<view class="copyright">{{copyright}}</view> <view class="copyright">{{copyright}}</view>
</view> </view>

View File

@@ -31,11 +31,11 @@
onShow() { onShow() {
if (this.needRefresh) { if (this.needRefresh) {
this.needRefresh = false; this.needRefresh = false;
this.init(); // this.init();
} }
}, },
onLoad() { onLoad() {
this.init() // this.init()
}, },
methods: { methods: {
init() { init() {

View File

@@ -62,7 +62,7 @@
bcg: 'u-type-primary-bg' bcg: 'u-type-primary-bg'
} }
], ],
copyright: 'Copyright © 2024 引迈信息技术有限公司出品', copyright: 'Copyright © 2024 CSCN技术有限公司出品',
show: false show: false
} }
}, },

View File

@@ -3,37 +3,52 @@
<view style="background-color: #fff;" class="u-p-l-20 u-p-r-20"> <view style="background-color: #fff;" class="u-p-l-20 u-p-r-20">
<u-form :model="dataForm" :errorType="['toast']" label-position="left" label-width="150" label-align="right" <u-form :model="dataForm" :errorType="['toast']" label-position="left" label-width="150" label-align="right"
ref="dataForm"> ref="dataForm">
<u-form-item label="姓名" prop='realName' required> <u-form-item label="姓名" prop='nickname' required>
<u-input input-align='right' v-model="dataForm.realName" placeholder="请输入"></u-input> <u-input input-align='right' v-model="dataForm.nickname" :disabled="isDisabled" placeholder="请输入"></u-input>
</u-form-item> </u-form-item>
<u-form-item label="民族"> <!-- <u-form-item label="民族">
<JnpfSelect v-model="dataForm.nation" placeholder="请选择" :options='nationOptions' /> <JnpfSelect v-model="dataForm.nation" placeholder="请选择" :options='nationOptions' />
</u-form-item> </u-form-item>
<u-form-item label="性别"> <u-form-item label="性别">
<JnpfSelect v-model="dataForm.gender" placeholder="请选择" :options='genderOptions' :props='props' /> <JnpfSelect v-model="dataForm.gender" placeholder="请选择" :options='genderOptions' :props='props' />
</u-form-item> </u-form-item> -->
<u-form-item label="籍贯"> <!-- <u-form-item label="籍贯">
<u-input input-align='right' v-model="dataForm.nativePlace" placeholder="请输入"></u-input> <u-input input-align='right' v-model="dataForm.nativePlace" placeholder="请输入"></u-input>
</u-form-item> </u-form-item> -->
<u-form-item label="证件类型"> <!-- <u-form-item label="证件类型">
<JnpfSelect v-model="dataForm.certificatesType" placeholder="请选择" <JnpfSelect v-model="dataForm.certificatesType" placeholder="请选择"
:options='certificatesTypeOptions' /> :options='certificatesTypeOptions' />
</u-form-item> </u-form-item> -->
<u-form-item label="证件号码"> <!-- <u-form-item label="证件号码">
<u-input input-align='right' v-model="dataForm.certificatesNumber" placeholder="请输入"> <u-input input-align='right' v-model="dataForm.certificatesNumber" placeholder="请输入">
</u-input> </u-input>
</u-form-item> </u-form-item> -->
<u-form-item label="文化程度"> <!-- <u-form-item label="文化程度">
<JnpfSelect v-model="dataForm.education" placeholder="请选择" :options='educationOptions' /> <JnpfSelect v-model="dataForm.education" placeholder="请选择" :options='educationOptions' />
</u-form-item> </u-form-item> -->
<u-form-item label="出生年月"> <!-- <u-form-item label="出生年月">
<JnpfDatePicker v-model="dataForm.birthday" placeholder="请选择" /> <JnpfDatePicker v-model="dataForm.birthday" placeholder="请选择" />
</u-form-item> -->
<u-form-item label="性别">
<JnpfSelect v-model="dataForm.sex" placeholder="请选择" :disabled="isDisabled" :options='genderOptions' :props='props' />
</u-form-item> </u-form-item>
<u-form-item label="办公电话"> <u-form-item label="手机号">
<u-input input-align='right' v-model="dataForm.telePhone" placeholder="请输入"> <u-input input-align='right' v-model="dataForm.mobile" :disabled="isDisabled" placeholder="请输入">
</u-input> </u-input>
</u-form-item> </u-form-item>
<u-form-item label="办公座机"> <u-form-item label="邮箱">
<u-input input-align='right' v-model="dataForm.email" :disabled="isDisabled" placeholder="请输入">
</u-input>
</u-form-item>
<u-form-item v-if="isDisabled" label="所属部门">
<u-input input-align='right' v-model="dataForm.deptInfoList[0].deptName" disabled placeholder="请输入">
</u-input>
</u-form-item>
<u-form-item v-if="isDisabled" label="创建时间">
<u-input input-align='right' v-model="dataForm.loginDate" disabled placeholder="请输入">
</u-input>
</u-form-item>
<!-- <u-form-item label="办公座机">
<u-input input-align='right' v-model="dataForm.landline" placeholder="请输入"> <u-input input-align='right' v-model="dataForm.landline" placeholder="请输入">
</u-input> </u-input>
</u-form-item> </u-form-item>
@@ -51,10 +66,10 @@
</u-form-item> </u-form-item>
<u-form-item label="自我介绍"> <u-form-item label="自我介绍">
<u-input input-align='right' v-model="dataForm.signature" placeholder="请输入" type="textarea" /> <u-input input-align='right' v-model="dataForm.signature" placeholder="请输入" type="textarea" />
</u-form-item> </u-form-item> -->
</u-form> </u-form>
</view> </view>
<view class="flowBefore-actions"> <view v-if="!isDisabled" class="flowBefore-actions">
<u-button class="buttom-btn" type="primary" @click='submit'>保存</u-button> <u-button class="buttom-btn" type="primary" @click='submit'>保存</u-button>
</view> </view>
</view> </view>
@@ -62,7 +77,7 @@
<script> <script>
import { import {
UpdateUser profileUpdate
} from '@/api/common' } from '@/api/common'
import { import {
useBaseStore useBaseStore
@@ -94,19 +109,32 @@
nation: "", nation: "",
nativePlace: "", nativePlace: "",
postalAddress: "", postalAddress: "",
realName: "", nickname: "",
signature: null, signature: null,
telePhone: "", mobile: "",
email: '',
sex: null,
deptInfoList: [],
loginDate: '',
urgentContacts: "", urgentContacts: "",
urgentTelePhone: "", urgentTelePhone: "",
id: null id: null
}, },
nationOptions: [], nationOptions: [],
genderOptions: [], genderOptions: [
{
fullName: '男',
enCode: 1
},
{
fullName: '女',
enCode: 2
}
],
certificatesTypeOptions: [], certificatesTypeOptions: [],
educationOptions: [], educationOptions: [],
rules: { rules: {
realName: [{ nickname: [{
required: true, required: true,
message: '请输入姓名', message: '请输入姓名',
trigger: ['change', 'blur'], trigger: ['change', 'blur'],
@@ -118,6 +146,11 @@
computed: { computed: {
baseURL() { baseURL() {
return this.define.baseURL return this.define.baseURL
},
isDisabled() {
const config = JSON.parse(JSON.stringify(this.personalData))
const {title} = config
return title == '个人中心'
} }
}, },
watch: { watch: {
@@ -135,14 +168,15 @@
methods: { methods: {
init() { init() {
let initData = JSON.parse(JSON.stringify(this.personalData)) let initData = JSON.parse(JSON.stringify(this.personalData))
for (let key in initData) { // for (let key in initData) {
for (let k in this.dataForm) { // for (let k in this.dataForm) {
if (key === k) { // if (key === k) {
this.dataForm[key] = initData[key] // this.dataForm[key] = initData[key]
} // }
} // }
} // }
this.getOptions() this.dataForm = initData
this.dataForm.loginDate = this.formatTime(initData.loginDate)
}, },
getOptions() { getOptions() {
baseStore.getDictionaryData({ baseStore.getDictionaryData({
@@ -170,7 +204,8 @@
submit() { submit() {
this.$refs.dataForm.validate(valid => { this.$refs.dataForm.validate(valid => {
if (valid) { if (valid) {
UpdateUser(this.dataForm).then(res => { profileUpdate(this.dataForm).then(res => {
if(res.code == 0) {
uni.showToast({ uni.showToast({
title: '保存成功', title: '保存成功',
duration: 800, duration: 800,
@@ -179,10 +214,19 @@
setTimeout(() => { setTimeout(() => {
uni.navigateBack() uni.navigateBack()
}, 1000) }, 1000)
}
}) })
} }
}); });
} },
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');
},
} }
} }
</script> </script>

View File

@@ -17,17 +17,23 @@
}; };
}, },
onLoad(e) { onLoad(e) {
// this.baseInfo = JSON.parse(e.baseInfo) this.baseInfo = JSON.parse(e.baseInfo)
// #ifdef MP-WEIXIN || APP-HARMONY // #ifdef MP-WEIXIN || APP-HARMONY
this.baseInfo = JSON.parse(decodeURIComponent(e.baseInfo)) // this.baseInfo = JSON.parse(decodeURIComponent(e.baseInfo))
// #endif // #endif
// #ifndef MP-WEIXIN || APP-HARMONY // #ifndef MP-WEIXIN || APP-HARMONY
this.baseInfo = JSON.parse(decodeURIComponent(this.jnpf.encodeContent(e.baseInfo))) // this.baseInfo = JSON.parse(decodeURIComponent(this.jnpf.encodeContent(e.baseInfo)))
// #endif // #endif
},
onShow() {
console.log(this.baseInfo,'baseInfo------')
uni.setNavigationBarTitle({
title: this.baseInfo.title
})
}, },
methods: {} methods: {}
} }

View File

@@ -157,7 +157,7 @@
this.getPortalList() this.getPortalList()
}) })
const chatStore = useChatStore() const chatStore = useChatStore()
if (!chatStore.getSocket) chat && chat.initSocket() // if (!chatStore.getSocket) chat && chat.initSocket()
uni.$on('refresh', () => { uni.$on('refresh', () => {
this.formData = []; this.formData = [];
this.mescroll.resetUpScroll(); this.mescroll.resetUpScroll();

View File

@@ -121,6 +121,7 @@
watch: { watch: {
option(v) { option(v) {
// #ifdef APP-PLUS // #ifdef APP-PLUS
console.log(v,'v--------')
this.lsjFile && this.show(); this.lsjFile && this.show();
// #endif // #endif
} }

View File

@@ -1,9 +1,9 @@
<template> <template>
<view> <view>
<template v-if="config.formType == 1"> <template >
<dynamicForm ref="form" @eventReceiver="eventReceiver" @setBtnLoad="setBtnLoad" :config="config" /> <dynamicForm ref="form" @eventReceiver="eventReceiver" @setBtnLoad="setBtnLoad" :config="config" />
</template> </template>
<template v-if="config.formType == 2"> <!-- <template v-if="config.formType == 2">
<crmOrder ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='crmOrder'" <crmOrder ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='crmOrder'"
:config="config" /> :config="config" />
<leaveApply ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='leaveApply'" <leaveApply ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='leaveApply'"
@@ -12,7 +12,7 @@
:config="config" /> :config="config" />
<revokeApply ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='revoke'" <revokeApply ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='revoke'"
:config="config" /> :config="config" />
</template> </template> -->
</view> </view>
</template> </template>
@@ -36,6 +36,15 @@
default: () => {} default: () => {}
}, },
}, },
watch:{
config:{
handler(val){
console.log(val,'val1233')
},
deep:true,
immediate: true
}
},
methods: { methods: {
eventReceiver(formData, eventType) { eventReceiver(formData, eventType) {
this.$emit('eventReceiver', formData, eventType) this.$emit('eventReceiver', formData, eventType)

View File

@@ -99,7 +99,9 @@
import { import {
createModel, createModel,
updateModel, updateModel,
getOnlineLog getOnlineLog,
getDesForm,
getProcessBusinessInfo
} from '@/api/apply/visualDev' } from '@/api/apply/visualDev'
import { import {
createComment createComment
@@ -127,6 +129,8 @@
}, },
data() { data() {
return { return {
formConf: {},
processBusinessInfo: {},
dataLogList: [], dataLogList: [],
dataLog: false, dataLog: false,
childFormKey: +new Date(), childFormKey: +new Date(),
@@ -207,6 +211,7 @@
onLoad(option) { onLoad(option) {
if (!option.config) return this.jnpf.goBack() if (!option.config) return this.jnpf.goBack()
this.config = JSON.parse(this.jnpf.base64.decode(option.config)) this.config = JSON.parse(this.jnpf.base64.decode(option.config))
uni.$on('operate', (data) => { uni.$on('operate', (data) => {
this.btnLoading = true this.btnLoading = true
this[data.eventType + 'Handle'](data) this[data.eventType + 'Handle'](data)
@@ -450,7 +455,7 @@
}) })
}) })
}, },
init() { async init() {
this.processId = this.config.id this.processId = this.config.id
if (this.config.id) { if (this.config.id) {
let extra = { let extra = {
@@ -464,6 +469,10 @@
} }
uni.setStorageSync('dynamicModelExtra', extra) uni.setStorageSync('dynamicModelExtra', extra)
} }
// 先获取id
const res = await getProcessBusinessInfo(this.config.processInstance.id)
console.log(res,'res----------')
this.processBusinessInfo = res.data || {}
/** /**
* opType * opType
* -1 - 我发起的新建/编辑 * -1 - 我发起的新建/编辑
@@ -484,100 +493,110 @@
}; };
if (config.isFlow) query.isFlow = config.isFlow if (config.isFlow) query.isFlow = config.isFlow
if (config.opType != "-1" && config.opType != '0') query.operatorId = config.operatorId; if (config.opType != "-1" && config.opType != '0') query.operatorId = config.operatorId;
FlowTask(config?.taskId || config?.id || 0, query).then((res) => { getDesForm(this.processBusinessInfo.dbformId).then((res) => {
this.flowInfo = res.data.flowInfo || {}; // this.flowInfo = res.data.flowInfo || {};
this.properties = res.data.nodeProperties || {}; // this.properties = res.data.nodeProperties || {};
this.auxiliaryInfo = this.properties.auxiliaryInfo // this.auxiliaryInfo = this.properties.auxiliaryInfo
this.$nextTick(() => { // this.$nextTick(() => {
this.initApprovalField() // this.initApprovalField()
}) // })
this.formInfo = res.data.formInfo || {}; const data = res.data ? JSON.parse(res.data) : {};
this.taskInfo = res.data.taskInfo || {}; console.log(data,'data---11')
this.btnInfo = res.data.btnInfo || []; // this.formConf = JSON.parse(data.formData)
this.progressList = res.data.progressList || []; this.config = {
config.formOperates = res.data.formOperates || []; ...data,
config.formType = this.formInfo.type formConf: data.formData
const fullName =
config.opType == "-1" ?
this.flowInfo.fullName :
this.taskInfo.fullName;
config.fullName = fullName;
this.title = this.flowInfo.fullName;
this.thisStep = this.taskInfo.thisStep || "";
if (config.status !== 0 && config.status !== 3) {
this.title = this.thisStep ?
config.fullName + "/" + this.thisStep :
config.fullName;
} }
config.type = this.flowInfo.type; console.log(this.config,'config--')
config.draftData = res.data.draftData || null; // this.$refs.child.$refs.form.init(this.formConf)
config.formData = res.data.formData || {}; // console.log(JSON.parse(data.formData),'判断---')
let dataId = config.formData.id // this.formInfo = res.data.formInfo || {};
config.formEnCode = this.formInfo.enCode; // this.taskInfo = res.data.taskInfo || {};
this.nodeList = res.data.nodeList || []; // this.btnInfo = res.data.btnInfo || [];
this.recordList = (res.data.recordList || []).reverse(); // this.progressList = res.data.progressList || [];
config.formConf = this.formInfo.formData; // config.formOperates = res.data.formOperates || [];
if (config.formConf) { // config.formType = this.formInfo.type
this.dataLog = JSON.parse(config.formConf).dataLog // const fullName =
if (this.dataLog) this.getOnlineLog(dataId) // config.opType == "-1" ?
} // this.flowInfo.fullName :
this.hasComment = this.flowInfo.flowNodes.global.hasComment; // this.taskInfo.fullName;
// config.fullName = fullName;
// // this.title = this.flowInfo.fullName;
// this.thisStep = this.taskInfo.thisStep || "";
// if (config.status !== 0 && config.status !== 3) {
// this.title = this.thisStep ?
// config.fullName + "/" + this.thisStep :
// config.fullName;
// }
// config.type = this.flowInfo.type;
// config.draftData = res.data.draftData || null;
// config.formData = res.data.formData || {};
// let dataId = config.formData.id
// config.formEnCode = this.formInfo.enCode;
// this.nodeList = res.data.nodeList || [];
// this.recordList = (res.data.recordList || []).reverse();
// config.formConf = this.formInfo.formData;
// if (config.formConf) {
// this.dataLog = JSON.parse(config.formConf).dataLog
// if (this.dataLog) this.getOnlineLog(dataId)
// }
// this.hasComment = this.flowInfo.flowNodes.global.hasComment;
this.loading = false; this.loading = false;
this.formLoding = true; // this.formLoding = true;
uni.setNavigationBarTitle({ // uni.setNavigationBarTitle({
title: this.config.formEnCode === "revoke" ? `${this.flowInfo.fullName}撤销申请` : this // title: this.config.formEnCode === "revoke" ? `${this.flowInfo.fullName}撤销申请` : this
.flowInfo.fullName, // .flowInfo.fullName,
}); // });
if (config.formRecords && config.title) { // if (config.formRecords && config.title) {
uni.setNavigationBarTitle({ // uni.setNavigationBarTitle({
title: config.title, // title: config.title,
}); // });
} // }
this.flowUrgent = this.taskInfo.flowUrgent || 1; // this.flowUrgent = this.taskInfo.flowUrgent || 1;
const getSelectInfo = () => { // const getSelectInfo = () => {
var obj = { // var obj = {
value: this.flowUrgent, // value: this.flowUrgent,
extra: "0", // extra: "0",
label: "普通", // label: "普通",
}; // };
this.flowUrgentList.forEach((e, i) => { // this.flowUrgentList.forEach((e, i) => {
if (e.value == this.flowUrgent) { // if (e.value == this.flowUrgent) {
obj.extra = i; // obj.extra = i;
obj.label = e.label; // obj.label = e.label;
} // }
}); // });
return obj; // return obj;
}; // };
this.selectflowUrgent = getSelectInfo(); // this.selectflowUrgent = getSelectInfo();
this.initRightBtnList(); // this.initRightBtnList();
if (config.opType != "-1" && config.opType != "3") config.readonly = // if (config.opType != "-1" && config.opType != "3") config.readonly =
true; // true;
config.formOperates = []; // config.formOperates = [];
if (config.opType == 0) { // if (config.opType == 0) {
if (this.properties && this.properties && this.properties.formOperates) config // if (this.properties && this.properties && this.properties.formOperates) config
.formOperates = this.properties.formOperates || []; // .formOperates = this.properties.formOperates || [];
} else { // } else {
config.formOperates = res.data.formOperates || []; // config.formOperates = res.data.formOperates || [];
} // }
this.getFlowStatus() // this.getFlowStatus()
setTimeout(() => { // setTimeout(() => {
this.$nextTick(() => { // this.$nextTick(() => {
if (!this.$refs.child || !this.$refs.child.$refs.form) { // if (!this.$refs.child || !this.$refs.child.$refs.form) {
uni.showToast({ // uni.showToast({
title: "暂无此流程表单", // title: "暂无此流程表单",
icon: "none", // icon: "none",
complete: () => { // complete: () => {
setTimeout(() => { // setTimeout(() => {
uni.navigateBack(); // uni.navigateBack();
}, 1500); // }, 1500);
}, // },
}); // });
return; // return;
} // }
this.$refs.child.$refs.form.init(config) // this.$refs.child.$refs.form.init(config)
}); // });
}, 100); // }, 100);
this.config = config; // this.config = config;
}); });
}, },
//获取修改记录 //获取修改记录

View File

@@ -103,30 +103,35 @@ const statusMap = {
import { import {
getOperatorList, getOperatorList,
getFlowLaunchList getFlowLaunchList,
getMyPage,
getTodoPage,
getDonePage,
getCcMyPage
} from '@/api/workFlow/template' } from '@/api/workFlow/template'
export default { export default {
data() { data() {
return { return {
mescrollTop: 206, mescrollTop: 206,
statusList: [], statusList: [],
tabsList: [{ tabsList: [{
fullName: '在办', fullName: '我的消息',
category: '1',
key: 3,
enCode: "workFlow.flowLaunch"
},{
fullName: '待办任务',
category: '2', category: '2',
key: 2, key: 2,
enCode: "workFlow.flowDoing" enCode: "workFlow.flowDoing"
}, { }, {
fullName: '发起', fullName: '已办任务',
category: null,
key: 3,
enCode: "workFlow.flowLaunch"
}, {
fullName: '已办',
category: '3', category: '3',
key: 4, key: 4,
enCode: "workFlow.flowDone" enCode: "workFlow.flowDone"
}, { }, {
fullName: '抄送', fullName: '抄送任务',
category: '4', category: '4',
key: 5, key: 5,
enCode: "workFlow.flowCirculate" enCode: "workFlow.flowCirculate"
@@ -147,7 +152,7 @@ export default {
return return
} }
this.statusList = statusMap[this.tabsList[val].key] this.statusList = statusMap[this.tabsList[val].key]
this.mescrollTop = 322 / 2 this.mescrollTop = 220 / 2
this.category = this.tabsList[this.current].category this.category = this.tabsList[this.current].category
}, },
immediate: true, immediate: true,
@@ -182,9 +187,9 @@ export default {
} }
} }
]; ];
configToCheck.forEach(config => { // configToCheck.forEach(config => {
if (this.sysConfigInfo[config.key] === 1) return this.tabsList.unshift(config.tab); // if (this.sysConfigInfo[config.key] === 1) return this.tabsList.unshift(config.tab);
}); // });
this.menuList = uni.getStorageSync("menuList"); this.menuList = uni.getStorageSync("menuList");
let workFlowList = this.menuList.filter(o => o.enCode === 'workFlow') let workFlowList = this.menuList.filter(o => o.enCode === 'workFlow')
if (!workFlowList.length) return if (!workFlowList.length) return
@@ -203,6 +208,8 @@ export default {
/* tab1 */ /* tab1 */
change(index) { change(index) {
let item = this.tabsList[index] let item = this.tabsList[index]
console.log(item,'item------------')
console.log(index,'index------------')
this.current = index; this.current = index;
this.status = '' this.status = ''
this.keyword = '' this.keyword = ''
@@ -225,13 +232,13 @@ export default {
}, },
/* 列表数据 */ /* 列表数据 */
upCallback(page) { upCallback(page) {
let methods = this.category ? getOperatorList : getFlowLaunchList; let methods = this.getList(this.category)
let query = { let query = {
currentPage: page.num, pageNo: page.num,
pageSize: page.size, pageSize: page.size,
keyword: this.keyword, keyword: this.keyword,
category: this.tabsList[this.current].category, // category: this.tabsList[this.current].category,
status: this.status // status: this.status
} }
methods(query, { methods(query, {
load: page.num == 1 load: page.num == 1
@@ -245,11 +252,32 @@ export default {
'swipeAction': this.swipeAction(o.status), 'swipeAction': this.swipeAction(o.status),
...o ...o
})) }))
console.log(list,'list---')
this.list = this.list.concat(list); this.list = this.list.concat(list);
}).catch(() => { }).catch(() => {
this.mescroll.endErr(); this.mescroll.endErr();
}) })
}, },
// 流程列表接口
getList(category){
let methods = ''
console.log(category,'category---')
switch(category){
case '1':
methods = getMyPage
break;
case '2':
methods = getTodoPage
break;
case '3':
methods = getDonePage
break;
case '4':
methods = getCcMyPage
break;
}
return methods
},
swipeAction(status) { swipeAction(status) {
let swipeAction = true let swipeAction = true
if (this.tabsList[this.current].key === 3 && !this.category && (status == '0' || status == '9')) if (this.tabsList[this.current].key === 3 && !this.category && (status == '0' || status == '9'))

View File

@@ -11,20 +11,27 @@
<view class='common-lable-entrust' v-if="item.delegateUser"> <view class='common-lable-entrust' v-if="item.delegateUser">
{{!category ? '委托' : '代理' }} {{!category ? '委托' : '代理' }}
</view> </view>
<view class='common-lable' <view class='common-lable'>
:class="{'urgent-lable':item.flowUrgent==2,'important-lable':item.flowUrgent==3}"> 单号
{{getLableValue(item.flowUrgent)}}
</view> </view>
<text class="title u-font-28 u-line-1">{{item.fullName}}</text> <text class="title u-font-28 u-line-1">{{item.businessInfo && item.businessInfo.billNo}}</text>
</view> </view>
<text class="title u-line-1 u-font-24">审批节点{{item.currentNodeName}}<text <text class="title u-line-1 u-font-24">单据类型{{item.name || item.processInstanceName}}<text
class="titInner">{{item.thisStep ? item.thisStep : ''}}</text></text> class="titInner">{{item.thisStep ? item.thisStep : ''}}</text></text>
<text class="time title u-font-24">发起时间<text <text class="time title u-font-24">发起时间<text
class="titInner">{{item.startTime?$u.timeFormat(item.startTime, 'yyyy-mm-dd hh:MM:ss'):''}}</text></text> class="titInner">{{item.createTime?$u.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss'):''}}</text></text>
</view> </view>
<view class="item-right"> <view v-if="category == 2" class="item-right">
<image :src="item.flowStatus" mode="widthFix" class="item-right-img"> <image v-if="item.suspensionState == 1" src="./img/jihuo.png" mode="widthFix" class="item-right-img" />
</image> <image v-else src="./img/wanc.png" mode="widthFix" class="item-right-img" />
</view>
<view v-else class="item-right">
<image v-if="item.result == 1" src="./img/doing.png" mode="widthFix" class="item-right-img" />
<image v-if="item.result == 2" src="./img/togo.png" mode="widthFix" class="item-right-img" />
<image v-if="item.result == 3" src="./img/pass.png" mode="widthFix" class="item-right-img" />
<image v-if="item.result == 4" src="./img/quxiao.png" mode="widthFix" class="item-right-img" />
<image v-if="item.result == 5" src="./img/REJECTED.png" mode="widthFix" class="item-right-img" />
<image v-if="item.result == 6" src="./img/weipai.png" mode="widthFix" class="item-right-img" />
</view> </view>
</view> </view>
</template> </template>
@@ -34,6 +41,9 @@
</view> </view>
</template> </template>
<script> <script>
import {
getProcessBusinessInfo
} from '@/api/apply/visualDev'
import { import {
delFlowLaunch delFlowLaunch
} from '@/api/workFlow/template' } from '@/api/workFlow/template'
@@ -79,15 +89,24 @@
}) })
}, },
goDetail(item) { goDetail(item) {
const {processInstance,processDefinitionId,processInstanceId,processInstanceName} = item
const id = this.category == 4 ? processInstanceId :(!!processDefinitionId ? item.id :processInstance.id)
const name = this.category == 4 ? processInstanceName : !!processDefinitionId ? item.name : processInstance.name
getProcessBusinessInfo(id).then(res=>{
if(res.code == 0){
const {dbformId,businessId} = res.data
const config = { const config = {
opType: item.opType, modelId: dbformId,
operatorId: item.id, id: businessId,
category: this.category, name: name,
...item btnType: 'btn_process',
current: this.category
} }
uni.navigateTo({ uni.navigateTo({
url: '/pages/workFlow/flowBefore/index?config=' + url: '/pages/apply/dynamicModelList/form?config=' +
this.jnpf.base64.encode(JSON.stringify(config)) JSON.stringify(config)
})
}
}) })
}, },
handleClick(data) { handleClick(data) {
@@ -105,24 +124,6 @@
this.list.splice(index, 1) this.list.splice(index, 1)
}) })
}, },
getLableValue(value) {
var lableValue = ''
switch (value) {
case 1:
lableValue = '普通'
break;
case 2:
lableValue = '重要'
break;
case 3:
lableValue = '紧急'
break;
default:
lableValue = '普通'
break;
}
return lableValue
}
} }
}; };
</script> </script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -10,11 +10,11 @@
<u-tabs ref="tabs" :list="tabsList" active-color="#0177FF" inactive-color="#303133" font-size="30" <u-tabs ref="tabs" :list="tabsList" active-color="#0177FF" inactive-color="#303133" font-size="30"
v-model="current" name="fullName" @change="change" height="80" :is-scroll="false"></u-tabs> v-model="current" name="fullName" @change="change" height="80" :is-scroll="false"></u-tabs>
</view> </view>
<view class="flow-status-tabs" v-if="statusList.length"> <!-- <view class="flow-status-tabs" v-if="statusList.length">
<u-subsection :list="statusList" :current="subsectionIndex" name="name" active-color="#2979FF" <u-subsection :list="statusList" :current="subsectionIndex" name="name" active-color="#2979FF"
inactive-color="#999999" bg-color="#F2F3F7" font-size="24" :bold="false" inactive-color="#999999" bg-color="#F2F3F7" font-size="24" :bold="false"
@change="subsection"></u-subsection> @change="subsection"></u-subsection>
</view> </view> -->
</view> </view>
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption"
:up="upOption" :top="mescrollTop"> :up="upOption" :top="mescrollTop">
@@ -28,6 +28,9 @@
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
import FlowMixin from "./FlowMixin.js"; import FlowMixin from "./FlowMixin.js";
import flowlist from './flowList.vue' import flowlist from './flowList.vue'
import {
useUserStore
} from '@/store/modules/user'
export default { export default {
components: { components: {
flowlist flowlist
@@ -62,7 +65,24 @@
}, },
} }
}, },
watch:{
current:{
handler(val){
uni.setStorageSync('fromNonTabBar', val);
},
immediate: true
}
},
onShow() { onShow() {
const fromNonTabBar = uni.getStorageSync('fromNonTabBar');
console.log(fromNonTabBar,'fromNonTabBar---')
this.current = fromNonTabBar && Number(fromNonTabBar)
// if(!fromNonTabBar){
// this.current = 1
// }else {
// this.current = 0
// }
uni.removeStorageSync('fromNonTabBar');
uni.$off('operate') uni.$off('operate')
uni.$on('refresh', () => { uni.$on('refresh', () => {
this.list = []; this.list = [];

View File

@@ -37,6 +37,8 @@
this.userInfo = uni.getStorageSync('userInfo') || {} this.userInfo = uni.getStorageSync('userInfo') || {}
this.setting = data this.setting = data
this.formConf = data.formConf ? JSON.parse(data.formConf) : {} this.formConf = data.formConf ? JSON.parse(data.formConf) : {}
console.log(this.formConf,'formConf112')
console.log(data,'data112')
this.dataForm.id = data.id || null; this.dataForm.id = data.id || null;
this.dataForm.flowId = data.flowId; this.dataForm.flowId = data.flowId;
this.loading = true; this.loading = true;
@@ -74,91 +76,91 @@
}, },
fillFormData(form, data) { fillFormData(form, data) {
form.disabled = this.setting.readonly form.disabled = this.setting.readonly
const loop = (list, parent) => { // const loop = (list, parent) => {
for (let i = 0; i < list.length; i++) { // for (let i = 0; i < list?.length; i++) {
let item = list[i] // let item = list[i]
let vModel = item.__vModel__ // let vModel = item.__vModel__
let config = item.__config__ // let config = item.__config__
if (vModel) { // if (vModel) {
let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue // let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
if (!config.isSubTable) config.defaultValue = val // if (!config.isSubTable) config.defaultValue = val
if (this.isAdd || config.isSubTable) { //新增时候,默认当前 // if (this.isAdd || config.isSubTable) { //新增时候,默认当前
if (config.defaultCurrent) { // if (config.defaultCurrent) {
if (config.jnpfKey === 'datePicker') { // if (config.jnpfKey === 'datePicker') {
if (!data.hasOwnProperty(vModel)) { // if (!data.hasOwnProperty(vModel)) {
let format = this.jnpf.handelFormat(item.format) // let format = this.jnpf.handelFormat(item.format)
let dateStr = this.jnpf.toDate(new Date().getTime(), format) // let dateStr = this.jnpf.toDate(new Date().getTime(), format)
let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ? // let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
'-01 00:00:00' : format === 'yyyy-MM-dd' ? // '-01 00:00:00' : format === 'yyyy-MM-dd' ?
' 00:00:00' : '' // ' 00:00:00' : ''
val = new Date(dateStr + time).getTime() // val = new Date(dateStr + time).getTime()
config.defaultValue = val // config.defaultValue = val
} // }
} // }
if (config.jnpfKey === 'timePicker') { // if (config.jnpfKey === 'timePicker') {
if (!data.hasOwnProperty(vModel)) { // if (!data.hasOwnProperty(vModel)) {
config.defaultValue = this.jnpf.toDate(new Date(), item.format) // config.defaultValue = this.jnpf.toDate(new Date(), item.format)
} // }
} // }
if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) { // if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
config.defaultValue = item.multiple ? this.userInfo.organizeIds : // config.defaultValue = item.multiple ? this.userInfo.organizeIds :
this.userInfo.organizeId // this.userInfo.organizeId
} // }
if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) { // if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
config.defaultValue = item.multiple ? this.userInfo.positionIds : // config.defaultValue = item.multiple ? this.userInfo.positionIds :
this.userInfo.positionId // this.userInfo.positionId
} // }
const userId = this.userInfo.userId // const userId = this.userInfo.userId
if (config.jnpfKey === 'userSelect' && userId) { // if (config.jnpfKey === 'userSelect' && userId) {
config.defaultValue = item.multiple ? [userId] : userId; // config.defaultValue = item.multiple ? [userId] : userId;
} // }
if (config.jnpfKey === 'usersSelect' && userId) { // if (config.jnpfKey === 'usersSelect' && userId) {
config.defaultValue = [userId + '--user']; // config.defaultValue = [userId + '--user'];
} // }
if (config.jnpfKey === 'sign' && this.userInfo.signImg) { // if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
config.defaultValue = this.userInfo.signImg // config.defaultValue = this.userInfo.signImg
} // }
} // }
} // }
let noShow = item.__config__.noShow || false, // let noShow = item.__config__.noShow || false,
isDisabled = item.disabled || false, // isDisabled = item.disabled || false,
required = item.__config__.required || false, // required = item.__config__.required || false,
isVisibility = false // isVisibility = false
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item // if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
.__config__.visibility.includes('app'))) isVisibility = true // .__config__.visibility.includes('app'))) isVisibility = true
if (this.setting.formOperates && this.setting.formOperates.length) { // if (this.setting.formOperates && this.setting.formOperates.length) {
let id = item.__config__.isSubTable ? parent?.__vModel__ + '-' + item?.__vModel__ : // let id = item.__config__.isSubTable ? parent?.__vModel__ + '-' + item?.__vModel__ :
item // item
.__vModel__ // .__vModel__
let arr = this.setting.formOperates.filter(o => o.id === id) || [] // let arr = this.setting.formOperates.filter(o => o.id === id) || []
if (arr.length) { // if (arr.length) {
let obj = arr[0] // let obj = arr[0]
noShow = !obj.read // noShow = !obj.read
isDisabled = !obj.write // isDisabled = !obj.write
required = obj.required ? obj.required : item.__config__.required // required = obj.required ? obj.required : item.__config__.required
} // }
} // }
isDisabled = item.readonly ? item.readonly : isDisabled; // isDisabled = item.readonly ? item.readonly : isDisabled;
if (this.setting.readonly || config.disabled) isDisabled = true // if (this.setting.readonly || config.disabled) isDisabled = true
if (this.setting.origin === 'scan') isDisabled = true // if (this.setting.origin === 'scan') isDisabled = true
this.$set(item, 'disabled', isDisabled) // this.$set(item, 'disabled', isDisabled)
this.$set(item.__config__, 'noShow', noShow) // this.$set(item.__config__, 'noShow', noShow)
this.$set(item.__config__, 'required', required) // this.$set(item.__config__, 'required', required)
this.$set(item.__config__, 'isVisibility', isVisibility) // this.$set(item.__config__, 'isVisibility', isVisibility)
} else { // } else {
let noShow = item.__config__.noShow ? item.__config__.noShow : false, // let noShow = item.__config__.noShow ? item.__config__.noShow : false,
isVisibility = false // isVisibility = false
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item // if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
.__config__.visibility.includes('app'))) isVisibility = true // .__config__.visibility.includes('app'))) isVisibility = true
this.$set(item.__config__, 'isVisibility', isVisibility) // this.$set(item.__config__, 'isVisibility', isVisibility)
this.$set(item.__config__, 'noShow', noShow) // this.$set(item.__config__, 'noShow', noShow)
} // }
if (item.__config__ && item.__config__.children && Array.isArray(item.__config__.children)) { // if (item.__config__ && item.__config__.children && Array.isArray(item.__config__.children)) {
loop(item.__config__.children, item) // loop(item.__config__.children, item)
} // }
} // }
} // }
loop(form.fields) // loop(form.fields)
form.formData = data form.formData = data
}, },
sumbitForm(data, callback) { sumbitForm(data, callback) {

BIN
static/image/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
static/image/logoT.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
static/image/logoT.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

View File

@@ -2,7 +2,7 @@ import {
defineStore defineStore
} from 'pinia'; } from 'pinia';
import { import {
logout, getLogout,
getCurrentUser getCurrentUser
} from '@/api/common' } from '@/api/common'
import store from '../index' import store from '../index'
@@ -12,19 +12,37 @@ export const useUserStore = defineStore({
id: 'user', id: 'user',
state: () => ({ state: () => ({
token: "", token: "",
refreshToken: "",
userInfo: {}, userInfo: {},
menuList: [], menuList: [],
tenantId: '',
current: 0,
}), }),
getters: { getters: {
getToken() { getToken() {
return this.token return this.token
}, },
getCurrent() {
return this.current
},
}, },
actions: { actions: {
setCurrent(current) {
this.current = current
uni.setStorageSync('current', current)
},
setTenantId(tenantId) {
this.tenantId = tenantId
uni.setStorageSync('tenantId', tenantId)
},
setToken(token) { setToken(token) {
this.token = token this.token = token
uni.setStorageSync('token', token) uni.setStorageSync('token', token)
}, },
setRefreshToken(refreshToken) {
this.refreshToken = refreshToken
uni.setStorageSync('refreshToken', refreshToken)
},
setCid(cid) { setCid(cid) {
this.cid = cid this.cid = cid
uni.setStorageSync('cid', cid) uni.setStorageSync('cid', cid)
@@ -61,8 +79,9 @@ export const useUserStore = defineStore({
}, },
logout() { logout() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout().then(() => { getLogout().then(() => {
this.setToken('') this.setToken('')
this.setTenantId('')
this.setCid('') this.setCid('')
this.setUserInfo({}) this.setUserInfo({})
this.resetToken() this.resetToken()

View File

@@ -342,7 +342,7 @@ export class LsjFile {
} }
form.append(name, item.file); form.append(name, item.file);
let xmlRequest = new XMLHttpRequest(); let xmlRequest = new XMLHttpRequest();
xmlRequest.open(method, `${url}?parentId=${parentId}`, true); xmlRequest.open(method, `${url}`, true);
for (let keys in header) { for (let keys in header) {
xmlRequest.setRequestHeader(keys, header[keys]) xmlRequest.setRequestHeader(keys, header[keys])
} }

View File

@@ -126,6 +126,7 @@
watch: { watch: {
option(v) { option(v) {
// #ifdef APP-PLUS // #ifdef APP-PLUS
console.log(v,'v22222222222')
this.lsjFile && this.show(); this.lsjFile && this.show();
// #endif // #endif
} }

View File

@@ -163,7 +163,7 @@ export default {
.u-radio-group { .u-radio-group {
/* #ifndef MP || APP-NVUE */ /* #ifndef MP || APP-NVUE */
display: inline-flex; // display: inline-flex;
flex-wrap: wrap; flex-wrap: wrap;
/* #endif */ /* #endif */
} }

View File

@@ -1,13 +1,13 @@
{ {
"hash": "76a9be6d", "hash": "546c637a",
"configHash": "13b242e7", "configHash": "9b3d750a",
"lockfileHash": "e3b0c442", "lockfileHash": "e3b0c442",
"browserHash": "305fc28d", "browserHash": "68bd3506",
"optimized": { "optimized": {
"crypto-js": { "crypto-js": {
"src": "../../../../../node_modules/crypto-js/index.js", "src": "../../../../../node_modules/crypto-js/index.js",
"file": "crypto-js.js", "file": "crypto-js.js",
"fileHash": "cf97db96", "fileHash": "209eb0b3",
"needsInterop": true "needsInterop": true
} }
}, },

View File

@@ -23,9 +23,9 @@ var require_crypto = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/core.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/core.js
var require_core = __commonJS({ var require_core = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/core.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/core.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(); module.exports = exports = factory();
@@ -631,9 +631,9 @@ var require_core = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/x64-core.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/x64-core.js
var require_x64_core = __commonJS({ var require_x64_core = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/x64-core.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/x64-core.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -888,9 +888,9 @@ var require_x64_core = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/lib-typedarrays.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/lib-typedarrays.js
var require_lib_typedarrays = __commonJS({ var require_lib_typedarrays = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/lib-typedarrays.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/lib-typedarrays.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -933,9 +933,9 @@ var require_lib_typedarrays = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/enc-utf16.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/enc-utf16.js
var require_enc_utf16 = __commonJS({ var require_enc_utf16 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/enc-utf16.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/enc-utf16.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -1051,9 +1051,9 @@ var require_enc_utf16 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/enc-base64.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/enc-base64.js
var require_enc_base64 = __commonJS({ var require_enc_base64 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/enc-base64.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/enc-base64.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -1159,9 +1159,9 @@ var require_enc_base64 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/enc-base64url.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/enc-base64url.js
var require_enc_base64url = __commonJS({ var require_enc_base64url = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/enc-base64url.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/enc-base64url.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -1272,9 +1272,9 @@ var require_enc_base64url = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/md5.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/md5.js
var require_md5 = __commonJS({ var require_md5 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/md5.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/md5.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -1451,9 +1451,9 @@ var require_md5 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha1.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha1.js
var require_sha1 = __commonJS({ var require_sha1 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha1.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha1.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -1542,9 +1542,9 @@ var require_sha1 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha256.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha256.js
var require_sha256 = __commonJS({ var require_sha256 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha256.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha256.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -1663,9 +1663,9 @@ var require_sha256 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha224.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha224.js
var require_sha224 = __commonJS({ var require_sha224 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha224.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha224.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_sha256()); module.exports = exports = factory(require_core(), require_sha256());
@@ -1708,9 +1708,9 @@ var require_sha224 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha512.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha512.js
var require_sha512 = __commonJS({ var require_sha512 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha512.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha512.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_x64_core()); module.exports = exports = factory(require_core(), require_x64_core());
@@ -1990,9 +1990,9 @@ var require_sha512 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha384.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha384.js
var require_sha384 = __commonJS({ var require_sha384 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha384.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha384.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_x64_core(), require_sha512()); module.exports = exports = factory(require_core(), require_x64_core(), require_sha512());
@@ -2036,9 +2036,9 @@ var require_sha384 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha3.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha3.js
var require_sha3 = __commonJS({ var require_sha3 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/sha3.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/sha3.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_x64_core()); module.exports = exports = factory(require_core(), require_x64_core());
@@ -2238,9 +2238,9 @@ var require_sha3 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/ripemd160.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/ripemd160.js
var require_ripemd160 = __commonJS({ var require_ripemd160 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/ripemd160.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/ripemd160.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -2709,9 +2709,9 @@ var require_ripemd160 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/hmac.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/hmac.js
var require_hmac = __commonJS({ var require_hmac = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/hmac.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/hmac.js"(exports, module) {
(function(root, factory) { (function(root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core()); module.exports = exports = factory(require_core());
@@ -2816,9 +2816,9 @@ var require_hmac = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pbkdf2.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/pbkdf2.js
var require_pbkdf2 = __commonJS({ var require_pbkdf2 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pbkdf2.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/pbkdf2.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_sha1(), require_hmac()); module.exports = exports = factory(require_core(), require_sha1(), require_hmac());
@@ -2914,9 +2914,9 @@ var require_pbkdf2 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/evpkdf.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/evpkdf.js
var require_evpkdf = __commonJS({ var require_evpkdf = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/evpkdf.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/evpkdf.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_sha1(), require_hmac()); module.exports = exports = factory(require_core(), require_sha1(), require_hmac());
@@ -3005,9 +3005,9 @@ var require_evpkdf = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/cipher-core.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/cipher-core.js
var require_cipher_core = __commonJS({ var require_cipher_core = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/cipher-core.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/cipher-core.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_evpkdf()); module.exports = exports = factory(require_core(), require_evpkdf());
@@ -3645,9 +3645,9 @@ var require_cipher_core = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-cfb.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-cfb.js
var require_mode_cfb = __commonJS({ var require_mode_cfb = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-cfb.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-cfb.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3697,9 +3697,9 @@ var require_mode_cfb = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ctr.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ctr.js
var require_mode_ctr = __commonJS({ var require_mode_ctr = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ctr.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ctr.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3737,9 +3737,9 @@ var require_mode_ctr = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ctr-gladman.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ctr-gladman.js
var require_mode_ctr_gladman = __commonJS({ var require_mode_ctr_gladman = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ctr-gladman.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ctr-gladman.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3812,9 +3812,9 @@ var require_mode_ctr_gladman = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ofb.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ofb.js
var require_mode_ofb = __commonJS({ var require_mode_ofb = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ofb.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ofb.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3850,9 +3850,9 @@ var require_mode_ofb = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ecb.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ecb.js
var require_mode_ecb = __commonJS({ var require_mode_ecb = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/mode-ecb.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/mode-ecb.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3881,9 +3881,9 @@ var require_mode_ecb = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-ansix923.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-ansix923.js
var require_pad_ansix923 = __commonJS({ var require_pad_ansix923 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-ansix923.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-ansix923.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3913,9 +3913,9 @@ var require_pad_ansix923 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-iso10126.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-iso10126.js
var require_pad_iso10126 = __commonJS({ var require_pad_iso10126 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-iso10126.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-iso10126.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3941,9 +3941,9 @@ var require_pad_iso10126 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-iso97971.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-iso97971.js
var require_pad_iso97971 = __commonJS({ var require_pad_iso97971 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-iso97971.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-iso97971.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -3968,9 +3968,9 @@ var require_pad_iso97971 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-zeropadding.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-zeropadding.js
var require_pad_zeropadding = __commonJS({ var require_pad_zeropadding = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-zeropadding.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-zeropadding.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -4002,9 +4002,9 @@ var require_pad_zeropadding = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-nopadding.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-nopadding.js
var require_pad_nopadding = __commonJS({ var require_pad_nopadding = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/pad-nopadding.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/pad-nopadding.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -4025,9 +4025,9 @@ var require_pad_nopadding = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/format-hex.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/format-hex.js
var require_format_hex = __commonJS({ var require_format_hex = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/format-hex.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/format-hex.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_cipher_core()); module.exports = exports = factory(require_core(), require_cipher_core());
@@ -4085,9 +4085,9 @@ var require_format_hex = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/aes.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/aes.js
var require_aes = __commonJS({ var require_aes = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/aes.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/aes.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core()); module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core());
@@ -4239,9 +4239,9 @@ var require_aes = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/tripledes.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/tripledes.js
var require_tripledes = __commonJS({ var require_tripledes = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/tripledes.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/tripledes.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core()); module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core());
@@ -5020,9 +5020,9 @@ var require_tripledes = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/rc4.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/rc4.js
var require_rc4 = __commonJS({ var require_rc4 = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/rc4.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/rc4.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core()); module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core());
@@ -5103,9 +5103,9 @@ var require_rc4 = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/rabbit.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/rabbit.js
var require_rabbit = __commonJS({ var require_rabbit = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/rabbit.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/rabbit.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core()); module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core());
@@ -5232,9 +5232,9 @@ var require_rabbit = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/rabbit-legacy.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/rabbit-legacy.js
var require_rabbit_legacy = __commonJS({ var require_rabbit_legacy = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/rabbit-legacy.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/rabbit-legacy.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core()); module.exports = exports = factory(require_core(), require_enc_base64(), require_md5(), require_evpkdf(), require_cipher_core());
@@ -5358,9 +5358,9 @@ var require_rabbit_legacy = __commonJS({
} }
}); });
// ../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/index.js // E:/web/ruantong/jnpf_app/node_modules/crypto-js/index.js
var require_crypto_js = __commonJS({ var require_crypto_js = __commonJS({
"../../../../SourceCode/jnpf6.0/jnpf/jnpf-app-vue3-v6x/node_modules/crypto-js/index.js"(exports, module) { "E:/web/ruantong/jnpf_app/node_modules/crypto-js/index.js"(exports, module) {
(function(root, factory, undef) { (function(root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
module.exports = exports = factory(require_core(), require_x64_core(), require_lib_typedarrays(), require_enc_utf16(), require_enc_base64(), require_enc_base64url(), require_md5(), require_sha1(), require_sha256(), require_sha224(), require_sha512(), require_sha384(), require_sha3(), require_ripemd160(), require_hmac(), require_pbkdf2(), require_evpkdf(), require_cipher_core(), require_mode_cfb(), require_mode_ctr(), require_mode_ctr_gladman(), require_mode_ofb(), require_mode_ecb(), require_pad_ansix923(), require_pad_iso10126(), require_pad_iso97971(), require_pad_zeropadding(), require_pad_nopadding(), require_format_hex(), require_aes(), require_tripledes(), require_rc4(), require_rabbit(), require_rabbit_legacy()); module.exports = exports = factory(require_core(), require_x64_core(), require_lib_typedarrays(), require_enc_utf16(), require_enc_base64(), require_enc_base64url(), require_md5(), require_sha1(), require_sha256(), require_sha224(), require_sha512(), require_sha384(), require_sha3(), require_ripemd160(), require_hmac(), require_pbkdf2(), require_evpkdf(), require_cipher_core(), require_mode_cfb(), require_mode_ctr(), require_mode_ctr_gladman(), require_mode_ofb(), require_mode_ecb(), require_pad_ansix923(), require_pad_iso10126(), require_pad_iso97971(), require_pad_zeropadding(), require_pad_nopadding(), require_format_hex(), require_aes(), require_tripledes(), require_rc4(), require_rabbit(), require_rabbit_legacy());

View File

@@ -1,27 +1,27 @@
/* process.env.NODE_ENV设置生产环境模式 */ /* process.env.NODE_ENV设置生产环境模式 */
// #ifndef MP // #ifndef MP
const baseURL = process.env.NODE_ENV === "production" ? "https://app.java.jnpfsoft.com" : "http://localhost:30000" const baseURL = process.env.NODE_ENV === "production" ? "http://10.0.64.25:48080" : "http://10.0.64.25:48080"
const webSocketUrl = process.env.NODE_ENV === "production" ? "wss://app.java.jnpfsoft.com/websocket" : const webSocketUrl = process.env.NODE_ENV === "production" ? "http://10.0.64.25:48080" :
"ws://localhost:30000/api/message/websocket" "ws://10.0.64.25:48080/api/message/websocket"
const report = process.env.NODE_ENV === 'production' ? 'https://java.jnpfsoft.com/Report' : 'http://localhost:8200' const report = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080' : 'http://10.0.64.25:48080'
const pcURL = process.env.NODE_ENV === 'production' ? 'https://java.jnpfsoft.com' : 'http://localhost:3000' const pcURL = process.env.NODE_ENV === 'production' ? 'http://10.0.64.25:48080' : 'http://10.0.64.25:48080'
// #endif // #endif
// #ifdef MP // #ifdef MP
const baseURL = "http://localhost:30000" // const baseURL = "http://10.28.117.48:30000"
const webSocketUrl = "ws://localhost:30000/api/message/websocket" // const webSocketUrl = "ws://10.28.117.183:30000/api/message/websocket"
const report = 'http://localhost:8200' // const report = 'http://10.28.117.183:8200'
const pcURL = 'http://localhost:3000' // const pcURL = 'http://10.28.117.183:3000'
// #endif // #endif
console.log(process.env.NODE_ENV === "production",'判断环境----------')
const define = { const define = {
copyright: "Copyright @ 2025 引迈信息技术有限公司版权所有", copyright: "Copyright @ 2026 软通动力",
sysVersion: "V6.0", sysVersion: "V6.0",
baseURL, // 接口前缀 baseURL, // 接口前缀
report, report,
pcURL, pcURL,
webSocketUrl, webSocketUrl,
comUploadUrl: baseURL + '/api/file/Uploader/', comUploadUrl: baseURL,
timeout: 1000000, timeout: 1000000,
aMapWebKey: '', aMapWebKey: '',
cipherKey: 'EY8WePvjM5GGwQzn', // 加密key cipherKey: 'EY8WePvjM5GGwQzn', // 加密key

View File

@@ -1,64 +1,120 @@
import define from './define' import define from './define'
import { import { useLocale } from '@/locale/useLocale';
useLocale
} from '@/locale/useLocale';
const { const { getBackLocale } = useLocale();
getBackLocale let host = define.baseURL
} = useLocale(); const defaultOpt = { load: true }
const host = define.baseURL
const defaultOpt = {
load: true
}
// 示例 // ------------- token刷新核心配置 -------------
// async xxxx(code) { const whiteList = ['/login', '/system/auth/refresh-token']
// var res = await this.request({ let requestQueue = []
// url: '/api/System/DictionaryData/All', let isRefreshingToken = false
// method: 'GET', const isRelogin = { show: false }
// data,
// options: {
// load: false
// }
// })
// if (!res) return
// console.log(res)
// }
// ------------- 核心request方法 -------------
function request(config) { function request(config) {
config.options = Object.assign(defaultOpt, config.options) config.options = Object.assign(defaultOpt, config.options)
const token = uni.getStorageSync('token') || '' const token = uni.getStorageSync('token') || ''
const refreshToken = uni.getStorageSync('refreshToken') || ''
const tenantId = '1' || uni.getStorageSync('tenantId')
const systemCode = uni.getStorageSync('systemCode') || '' const systemCode = uni.getStorageSync('systemCode') || ''
const locale = getBackLocale() const locale = getBackLocale()
// 构建请求头
let header = { let header = {
"accept": 'application/json, text/plain, */*',
"App-Code": systemCode, "App-Code": systemCode,
"Content-Type": "application/json;charset=UTF-8", "Content-Type": "application/json;charset=UTF-8",
"Jnpf-Origin": "app", "Jnpf-Origin": "app",
"Vue-Version": "3", "Vue-Version": "3",
"Accept-Language": locale, "Accept-Language": locale,
"tenant-id": tenantId,
...config.header ...config.header
} }
header['App-Code'] = encodeURIComponent(header['App-Code']) header['App-Code'] = encodeURIComponent(header['App-Code'])
if (token) header['Authorization'] = token if (token) header['Authorization'] = token
let url = config.url.indexOf('http') > -1 ? config.url : host + config.url // let url = config.url.indexOf('http') > -1 ? config.url : host + config.url
let url = host + config.url
console.log(url,'url---')
// 3. 显示加载中
if (config.options.load) { if (config.options.load) {
uni.showLoading({ uni.showLoading({ title: config.options.loadText || '正在加载' })
title: config.options.loadText || '正在加载'
})
} }
// 4. 返回Promise核心改造逻辑
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 封装核心请求逻辑
const coreRequest = () => {
uni.request({ uni.request({
url: url, url: url,
data: config.data || {}, data: config.data || {},
method: config.method || 'GET', method: config.method || 'GET',
header: header, header: header,
timeout: define.timeout, timeout: define.timeout,
success: res => { success: async (res) => {
uni.hideLoading();
if (res.statusCode === 200) { if (res.statusCode === 200) {
if (res.data.code == 200) { if (res.data.code == 200 || res.data.code == 0) {
resolve(res.data) resolve(res.data)
} else if ([401, 600, 601, 602].includes(res.data.code)) {
// 白名单接口不处理
const isWhiteList = whiteList.some(v => config.url.includes(v))
if (isWhiteList) {
ajaxError(res.data)
reject(res.data.msg)
return
}
// ------------- 刷新token请求改为问号拼接参数 -------------
if (!refreshToken) {
await handleAuthorized()
reject(res.data.msg)
return
}
if (isRefreshingToken) {
requestQueue.push(() => coreRequest())
return
}
isRefreshingToken = true
try {
// 拼接URL参数
const refreshUrl = `${host}/admin-api/system/auth/refresh-token?refreshToken=${encodeURIComponent(refreshToken)}`
// 调用刷新token接口POST方法 + URL参数无请求体
const refreshRes = await uni.request({
url: refreshUrl, // 带参数的URL
method: 'POST', // 保持POST方法
header: {
'tenant-id': tenantId, // 携带租户ID
'Content-Type': 'application/json'
},
data: {} // 无请求体参数全在URL上
})
// 刷新成功处理
if (refreshRes.data.code == 0) {
const newTokenData = refreshRes.data.data
// 存储新token
uni.setStorageSync('token', newTokenData.accessToken)
uni.setStorageSync('refreshToken', newTokenData.refreshToken)
// 更新请求头
header['Authorization'] = newTokenData.accessToken
// 重试当前请求
coreRequest()
// 执行队列请求
requestQueue.forEach(cb => cb())
requestQueue = []
} else {
await handleAuthorized()
reject('刷新token失败' + (refreshRes.data?.msg || '接口返回异常'))
}
} catch (err) {
await handleAuthorized()
reject('刷新token异常' + err.errMsg)
} finally {
isRefreshingToken = false
requestQueue = []
}
} else { } else {
ajaxError(res.data) ajaxError(res.data)
reject(res.data.msg) reject(res.data.msg)
@@ -67,42 +123,54 @@ function request(config) {
ajaxError(res.data) ajaxError(res.data)
reject(res.errMsg) reject(res.errMsg)
} }
uni.hideLoading();
}, },
fail: err => { fail: (err) => {
uni.showToast({
title: '连接服务器失败',
icon: 'none',
})
setTimeout(function () {
uni.hideLoading(); uni.hideLoading();
}, 2000); uni.showToast({ title: '连接服务器失败', icon: 'none' })
reject(err) reject(err)
} }
}) })
}
coreRequest()
}) })
} }
// ------------- 辅助函数 -------------
function ajaxError(data) { function ajaxError(data) {
uni.showToast({ uni.showToast({
title: data.msg || '请求出错,请重试', title: data.msg || '请求出错,请重试',
icon: 'none', icon: 'none',
complete() { complete() {
if (data.code === 600 || data.code === 601 || data.code === 602) { if ([600, 601, 602, 401].includes(data.code) && !isRefreshingToken) {
setTimeout(() => { setTimeout(() => handleAuthorized(), 1500)
uni.removeStorageSync('token')
uni.removeStorageSync('cid')
uni.removeStorageSync('userInfo')
uni.removeStorageSync('permissionList')
uni.removeStorageSync('sysVersion')
uni.removeStorageSync('dynamicModelExtra')
uni.reLaunch({
url: '/pages/login/index'
})
}, 1500)
} }
} }
}) })
} }
async function handleAuthorized() {
if (!isRelogin.show) {
isRelogin.show = true
const res = await uni.showModal({
title: '登录过期',
content: '您的登录已过期,请重新登录',
showCancelButton: false,
confirmText: '重新登录'
})
if (res.confirm) {
// 清除缓存建议用项目封装的removeToken方法
uni.removeStorageSync('token')
uni.removeStorageSync('refreshToken')
uni.removeStorageSync('cid')
uni.removeStorageSync('userInfo')
uni.removeStorageSync('permissionList')
uni.removeStorageSync('sysVersion')
uni.removeStorageSync('dynamicModelExtra')
uni.reLaunch({ url: '/pages/login/index' })
}
isRelogin.show = false
}
}
export default request export default request