国庆稳定版

This commit is contained in:
vben
2026-09-30 21:32:51 +08:00
parent ea7d5ae459
commit 5950f08d9f
134 changed files with 1078 additions and 4437 deletions
+2 -2
View File
@@ -12,7 +12,7 @@ VITE_ROUTER_HISTORY=hash
# 后台请求路径 具体在vite.config.mts配置代理
VITE_GLOB_API_URL=/api
#VITE_GLOB_API_URL=http://8.153.168.178:8080
#VITE_GLOB_API_URL=http://localhost:8080
# 全局加密开关(即开启了加解密功能才会生效 不是全部接口加密 需要和后端对应)
VITE_GLOB_ENABLE_ENCRYPT=true
@@ -24,7 +24,7 @@ VITE_GLOB_RSA_PRIVATE_KEY=MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuP
VITE_GLOB_APP_CLIENT_ID=e5cd7e4891bf95d1d19206ce24a7b32e
# 开启SSE 具体消息逻辑: apps/web-ele/src/store/notify.ts
VITE_GLOB_SSE_ENABLE=true
VITE_GLOB_SSE_ENABLE=false
# 开启websocket 具体消息逻辑: apps/web-ele/src/store/notify.ts
VITE_GLOB_WEBSOCKET_ENABLE=false
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -5
View File
@@ -11,7 +11,7 @@ import type {RouteRecordStringComponent} from "@vben-core/typings";
export interface MenuMeta {
icon: string;
link?: string;
noCache: boolean;
catag: boolean;
title: string;
}
@@ -29,12 +29,12 @@ export interface MenuMeta {
export interface Menu {
alwaysShow?: boolean;
children: Menu[];
component: string;
hidden: boolean;
comp: string;
shtag: boolean;
meta: MenuMeta;
name: string;
path: string;
query?: string;
param?: string;
redirect?: string;
}
@@ -42,6 +42,7 @@ export interface Menu {
* 获取用户所有菜单
*/
export async function getAllMenusApi() {
return requestClient.get<Menu[]>('/system/menu/getRouters');
return requestClient.get<Menu[]>('/pub/menus');
// return requestClient.get<Menu[]>('/system/menu/getRouters');
// return requestClient.get<RouteRecordStringComponent[]>('/menu/all');
}
+1 -1
View File
@@ -35,7 +35,7 @@ export function uploadApi(
) {
const { onUploadProgress, signal, otherData = {} } = options ?? {};
return requestClient.upload<UploadResult>(
'/resource/oss/upload',
'/tool/oss/upload',
{ file, ...otherData },
{ onUploadProgress, signal, timeout: 60_000 },
);
+16 -15
View File
@@ -13,26 +13,26 @@ export interface Role {
export interface User {
avatar: string;
createTime: string;
deptId: number;
deptName: string;
crtim: string;
orgid: number;
orgna: string;
email: string;
loginDate: string;
loginIp: string;
nickName: string;
phonenumber: string;
remark: string;
lotim: string;
loip: string;
nicna: string;
monum: string;
notes: string;
roles: Role[];
gender: string;
status: string;
tenantId: string;
userId: number;
userName: string;
userType: string;
avtag: string;
tenid: string;
useid: number;
usena: string;
usety: string;
}
export interface UserInfoResp {
permissions: string[];
perms: string[];
roles: string[];
user: User;
}
@@ -42,6 +42,7 @@ export interface UserInfoResp {
* 存在返回null的情况(401) 不会抛出异常 需要手动抛异常
*/
export async function getUserInfoApi() {
return requestClient.get<null | UserInfoResp>('/system/user/getInfo');
return requestClient.get<null | UserInfoResp>('/pub/user');
// return requestClient.get<null | UserInfoResp>('/system/user/getInfo');
// return requestClient.get<null | UserInfoResp>('/user/info');
}
-24
View File
@@ -1,24 +0,0 @@
import { requestClient } from '#/api/request';
export interface CommandStats {
name: string;
value: string;
}
export interface RedisInfo {
[key: string]: string;
}
export interface CacheInfo {
commandStats: CommandStats[];
dbSize: number;
info: RedisInfo;
}
/**
*
* @returns redis信息
*/
export function redisCacheInfo() {
return requestClient.get<CacheInfo>('/monitor/cache');
}
@@ -1,60 +0,0 @@
import type { LoginLog } from './model';
import type { IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
loginInfoClean = '/monitor/logininfor/clean',
loginInfoExport = '/monitor/logininfor/export',
loginInfoList = '/monitor/logininfor/list',
root = '/monitor/logininfor',
userUnlock = '/monitor/logininfor/unlock',
}
/**
* 登录日志列表
* @param params 查询参数
* @returns list[]
*/
export function loginInfoList(params?: PageQuery) {
return requestClient.get<PageResult<LoginLog>>(Api.loginInfoList, { params });
}
/**
* 导出登录日志
* @param data 表单参数
* @returns excel
*/
export function loginInfoExport(data: any) {
return commonExport(Api.loginInfoExport, data);
}
/**
* 移除登录日志
* @param infoIds 登录日志id数组
* @returns void
*/
export function loginInfoRemove(infoIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${infoIds}`);
}
/**
* 账号解锁
* @param username 用户名(账号)
* @returns void
*/
export function userUnlock(username: string) {
return requestClient.get<void>(`${Api.userUnlock}/${username}`, {
successMessageMode: 'message',
});
}
/**
* 清空全部登录日志
* @returns void
*/
export function loginInfoClean() {
return requestClient.deleteWithMsg<void>(Api.loginInfoClean);
}
-13
View File
@@ -1,13 +0,0 @@
export interface LoginLog {
infoId: string;
tenantId: string;
userName: string;
status: string;
ipaddr: string;
loginLocation: string;
browser: string;
os: string;
msg: string;
loginTime: string;
clientKey: string;
}
@@ -1,45 +0,0 @@
import type { OnlineUser } from './model';
import type { PageQuery, PageResult } from '#/api/common';
import { requestClient } from '#/api/request';
enum Api {
onlineList = '/monitor/online/list',
root = '/monitor/online',
}
/**
* 当前账号的在线设备 个人中心使用
* @returns OnlineUser[]
*/
export function onlineDeviceList() {
return requestClient.get<PageResult<OnlineUser>>(Api.root);
}
/**
* 这里的分页参数无效 返回的是全部的分页
* @param params 请求参数
* @returns 结果
*/
export function onlineList(params?: PageQuery) {
return requestClient.get<PageResult<OnlineUser>>(Api.onlineList, { params });
}
/**
* 强制下线
* @param tokenId 用户token
* @returns void
*/
export function forceLogout(tokenId: string) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${tokenId}`);
}
/**
* 个人中心用的 跟上面的不同是用的Post
* @param tokenId 用户token
* @returns void
*/
export function forceLogout2(tokenId: string) {
return requestClient.deleteWithMsg<void>(`${Api.root}/myself/${tokenId}`);
}
-11
View File
@@ -1,11 +0,0 @@
export interface OnlineUser {
tokenId: string;
deptName: string;
userName: string;
ipaddr: string;
loginLocation: string;
browser: string;
os: string;
loginTime: number;
deviceType: string;
}
@@ -1,47 +0,0 @@
import type { OperationLog } from './model';
import type { IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
operLogClean = '/monitor/operlog/clean',
operLogExport = '/monitor/operlog/export',
operLogList = '/monitor/operlog/list',
root = '/monitor/operlog',
}
/**
* 操作日志分页
* @param params 查询参数
* @returns 分页结果
*/
export function operLogList(params?: PageQuery) {
return requestClient.get<PageResult<OperationLog>>(Api.operLogList, {
params,
});
}
/**
* 删除操作日志
* @param operIds id/ids
*/
export function operLogDelete(operIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${operIds}`);
}
/**
* 清空全部分页日志
*/
export function operLogClean() {
return requestClient.deleteWithMsg<void>(Api.operLogClean);
}
/**
* 导出操作日志
* @param data 查询参数
*/
export function operLogExport(data: Partial<OperationLog>) {
return commonExport(Api.operLogExport, data);
}
-21
View File
@@ -1,21 +0,0 @@
export interface OperationLog {
operId: string;
tenantId: string;
title: string;
businessType: string;
businessTypes?: any;
method: string;
requestMethod: string;
operatorType: number;
operName: string;
deptName: string;
operUrl: string;
operIp: string;
operLocation: string;
operParam: string;
jsonResult: string;
status: string;
errorMsg: string;
operTime: string;
costTime: number;
}
@@ -1,75 +0,0 @@
import type { Client } from './model';
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
clientChangeStatus = '/system/client/changeStatus',
clientExport = '/system/client/export',
clientList = '/system/client/list',
root = '/system/client',
}
/**
* 查询客户端分页列表
* @param params 请求参数
* @returns 列表
*/
export function clientList(params?: PageQuery) {
return requestClient.get<PageResult<Client>>(Api.clientList, { params });
}
/**
* 导出客户端excel
* @param data 请求参数
*/
export function clientExport(data: Partial<Client>) {
return commonExport(Api.clientExport, data);
}
/**
* 客户端详情
* @param id id
* @returns 详情
*/
export function clientInfo(id: ID) {
return requestClient.get<Client>(`${Api.root}/${id}`);
}
/**
* 客户端新增
* @param data 参数
*/
export function clientAdd(data: Partial<Client>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 客户端修改
* @param data 参数
*/
export function clientUpdate(data: Partial<Client>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 客户端状态修改
* @param data 状态
*/
export function clientChangeStatus(data: any) {
const requestData = {
clientId: data.clientId,
status: data.status,
};
return requestClient.putWithMsg<void>(Api.clientChangeStatus, requestData);
}
/**
* 客户端删除
* @param ids id集合
*/
export function clientRemove(ids: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${ids}`);
}
-12
View File
@@ -1,12 +0,0 @@
export interface Client {
id: number;
clientId: string;
clientKey: string;
clientSecret: string;
grantTypeList: string[];
grantType: string;
deviceType: string;
activeTimeout: number;
timeout: number;
status: string;
}
@@ -1,76 +0,0 @@
import type { SysConfig } from './model';
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
configExport = '/system/config/export',
configInfoByKey = '/system/config/configKey',
configList = '/system/config/list',
configRefreshCache = '/system/config/refreshCache',
root = '/system/config',
}
/**
* 系统参数分页列表
* @param params 请求参数
* @returns 列表
*/
export function configList(params?: PageQuery) {
return requestClient.get<PageResult<SysConfig>>(Api.configList, { params });
}
export function configInfo(configId: ID) {
return requestClient.get<SysConfig>(`${Api.root}/${configId}`);
}
/**
* 导出
* @param data 参数
*/
export function configExport(data: Partial<SysConfig>) {
return commonExport(Api.configExport, data);
}
/**
* 刷新缓存
* @returns void
*/
export function configRefreshCache() {
return requestClient.deleteWithMsg<void>(Api.configRefreshCache);
}
/**
* 更新系统配置
* @param data 参数
*/
export function configUpdate(data: Partial<SysConfig>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 新增系统配置
* @param data 参数
*/
export function configAdd(data: Partial<SysConfig>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 删除配置
* @param configIds ids
*/
export function configRemove(configIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${configIds}`);
}
/**
* 获取配置信息
* @param configKey configKey
* @returns value
*/
export function configInfoByKey(configKey: string) {
return requestClient.get<string>(`${Api.configInfoByKey}/${configKey}`);
}
-9
View File
@@ -1,9 +0,0 @@
export interface SysConfig {
configId: number;
configName: string;
configKey: string;
configValue: string;
configType: string;
remark: string;
createTime: string;
}
-62
View File
@@ -1,62 +0,0 @@
import type { Dept } from './model';
import type { ID } from '#/api/common';
import { requestClient } from '#/api/request';
enum Api {
deptList = '/system/dept/list',
deptNodeInfo = '/system/dept/list/exclude',
root = '/system/dept',
}
/**
* 部门列表
* @returns list
*/
export function deptList(params?: { deptName?: string; status?: string }) {
return requestClient.get<Dept[]>(Api.deptList, { params });
}
/**
* 查询部门列表(排除节点)
* @param deptId 部门ID
* @returns void
*/
export function deptNodeList(deptId: ID) {
return requestClient.get<Dept[]>(`${Api.deptNodeInfo}/${deptId}`);
}
/**
* 部门详情
* @param deptId 部门id
* @returns 部门信息
*/
export function deptInfo(deptId: ID) {
return requestClient.get<Dept>(`${Api.root}/${deptId}`);
}
/**
* 部门新增
* @param data 参数
*/
export function deptAdd(data: Partial<Dept>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 部门更新
* @param data 参数
*/
export function deptUpdate(data: Partial<Dept>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 注意这里只允许单删除
* @param deptId ID
* @returns void
*/
export function deptRemove(deptId: ID) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${deptId}`);
}
-19
View File
@@ -1,19 +0,0 @@
export interface Dept {
createBy: string;
createTime: string;
updateBy?: string;
updateTime?: string;
remark?: string;
deptId: number;
parentId: number;
ancestors: string;
deptName: string;
orderNum: number;
leader: string;
phone: string;
email: string;
status: string;
delFlag: string;
parentName?: string;
children?: Dept[];
}
-17
View File
@@ -1,17 +0,0 @@
export interface DictData {
createBy: string;
createTime: string;
cssClass: string;
default: boolean;
dictCode: number;
dictLabel: string;
dictSort: number;
dictType: string;
dictValue: string;
isDefault: string;
listClass: string;
remark: string;
status: string;
updateBy?: any;
updateTime?: any;
}
@@ -1,75 +0,0 @@
import type { DictData } from './dict-data-model';
import type { ID, IDS, PageQuery } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
dictDataExport = '/system/dict/data/export',
dictDataList = '/system/dict/data/list',
root = '/system/dict/data',
}
/**
* 主要是DictTag组件使用
* @param dictType 字典类型
* @returns 字典数据
*/
export function dictDataInfo(dictType: string) {
return requestClient.get<DictData[]>(`${Api.root}/type/${dictType}`);
}
/**
* 字典数据
* @param params 查询参数
* @returns 字典数据列表
*/
export function dictDataList(params?: PageQuery) {
return requestClient.get<DictData[]>(Api.dictDataList, { params });
}
/**
* 导出字典数据
* @param data 表单参数
* @returns blob
*/
export function dictDataExport(data: Partial<DictData>) {
return commonExport(Api.dictDataExport, data);
}
/**
* 删除
* @param dictIds 字典ID Array
* @returns void
*/
export function dictDataRemove(dictIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${dictIds}`);
}
/**
* 新增
* @param data 表单参数
* @returns void
*/
export function dictDataAdd(data: Partial<DictData>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 修改
* @param data 表单参数
* @returns void
*/
export function dictDataUpdate(data: Partial<DictData>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 查询字典数据详细
* @param dictCode 字典编码
* @returns 字典数据
*/
export function dictDetailInfo(dictCode: ID) {
return requestClient.get<DictData>(`${Api.root}/${dictCode}`);
}
-8
View File
@@ -1,8 +0,0 @@
export interface DictType {
createTime: string;
dictId: number;
dictName: string;
dictType: string;
remark: string;
status: string;
}
@@ -1,85 +0,0 @@
import type { DictType } from './dict-type-model';
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
dictOptionSelectList = '/system/dict/type/optionselect',
dictTypeExport = '/system/dict/type/export',
dictTypeList = '/system/dict/type/list',
dictTypeRefreshCache = '/system/dict/type/refreshCache',
root = '/system/dict/type',
}
/**
* 获取字典类型列表
* @param params 请求参数
* @returns list
*/
export function dictTypeList(params?: PageQuery) {
return requestClient.get<PageResult<DictType>>(Api.dictTypeList, { params });
}
/**
* 导出字典类型列表
* @param data 表单参数
* @returns blob
*/
export function dictTypeExport(data: Partial<DictType>) {
return commonExport(Api.dictTypeExport, data);
}
/**
* 删除字典类型
* @param dictIds 字典类型id数组
* @returns void
*/
export function dictTypeRemove(dictIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${dictIds}`);
}
/**
* 刷新字典缓存
* @returns void
*/
export function refreshDictTypeCache() {
return requestClient.deleteWithMsg<void>(Api.dictTypeRefreshCache);
}
/**
* 新增
* @param data 表单参数
* @returns void
*/
export function dictTypeAdd(data: Partial<DictType>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 修改
* @param data 表单参数
* @returns void
*/
export function dictTypeUpdate(data: Partial<DictType>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 查询详情
* @param dictId 字典类型id
* @returns 信息
*/
export function dictTypeInfo(dictId: ID) {
return requestClient.get<DictType>(`${Api.root}/${dictId}`);
}
/**
* 这个在ele用到 v5用不上
* 下拉框 返回值和list一样
* @returns options
*/
export function dictOptionSelectList() {
return requestClient.get<DictType[]>(Api.dictOptionSelectList);
}
-92
View File
@@ -1,92 +0,0 @@
import type { Menu, MenuOption, MenuQuery, MenuResp } from './model';
import type { ID, IDS } from '#/api/common';
import { requestClient } from '#/api/request';
enum Api {
menuList = '/system/menu/list',
menuTreeSelect = '/system/menu/treeselect',
roleMenuTree = '/system/menu/roleMenuTreeselect',
root = '/system/menu',
tenantPackageMenuTreeselect = '/system/menu/tenantPackageMenuTreeselect',
}
/**
* 菜单列表
* @param params 参数
* @returns 列表
*/
export function menuList(params?: MenuQuery) {
return requestClient.get<Menu[]>(Api.menuList, { params });
}
/**
* 菜单详情
* @param menuId 菜单id
* @returns 菜单详情
*/
export function menuInfo(menuId: ID) {
return requestClient.get<Menu>(`${Api.root}/${menuId}`);
}
/**
* 菜单新增
* @param data 参数
*/
export function menuAdd(data: Partial<Menu>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 菜单更新
* @param data 参数
*/
export function menuUpdate(data: Partial<Menu>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 菜单删除
* @param menuIds ids
*/
export function menuRemove(menuIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${menuIds}`);
}
/**
* 返回对应角色的菜单
* @param roleId id
* @returns resp
*/
export function roleMenuTreeSelect(roleId: ID) {
return requestClient.get<MenuResp>(`${Api.roleMenuTree}/${roleId}`);
}
/**
* 下拉框使用 返回所有的菜单
* @returns []
*/
export function menuTreeSelect() {
return requestClient.get<MenuOption[]>(Api.menuTreeSelect);
}
/**
* 租户套餐使用
* @param packageId packageId
* @returns resp
*/
export function tenantPackageMenuTreeSelect(packageId: ID) {
return requestClient.get<MenuResp>(
`${Api.tenantPackageMenuTreeselect}/${packageId}`,
);
}
/**
* 批量删除菜单
* @param menuIds 菜单ids
* @returns void
*/
export function menuCascadeRemove(menuIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/cascade/${menuIds}`);
}
-57
View File
@@ -1,57 +0,0 @@
export interface Menu {
createBy?: any;
createTime: string;
updateBy?: any;
updateTime?: any;
remark?: any;
menuId: number;
menuName: string;
parentName?: string;
parentId: number;
orderNum: number;
path: string;
component?: string;
query: string;
isFrame: string;
isCache: string;
menuType: string;
visible: string;
status: string;
perms: string;
icon: string;
children: Menu[];
}
/**
* @description 菜单信息
* @param label 菜单名称
*/
export interface MenuOption {
id: number;
parentId: number;
label: string;
weight: number;
children: MenuOption[];
key: string; // 实际上不存在 ide报错
menuType: string;
icon: string;
}
/**
* @description 菜单返回
* @param checkedKeys 选中的菜单id
* @param menus 菜单信息
*/
export interface MenuResp {
checkedKeys: number[];
menus: MenuOption[];
}
/**
* 菜单表单查询
*/
export interface MenuQuery {
menuName?: string;
visible?: string;
status?: string;
}
@@ -1,52 +0,0 @@
import type { Notice } from './model';
import type { ID, IDS, PageQuery } from '#/api/common';
import { requestClient } from '#/api/request';
enum Api {
noticeList = '/system/notice/list',
root = '/system/notice',
}
/**
* 通知公告分页
* @param params 分页参数
* @returns 分页结果
*/
export function noticeList(params?: PageQuery) {
return requestClient.get<Notice[]>(Api.noticeList, { params });
}
/**
* 通知公告详情
* @param noticeId id
* @returns 详情
*/
export function noticeInfo(noticeId: ID) {
return requestClient.get<Notice>(`${Api.root}/${noticeId}`);
}
/**
* 通知公告新增
* @param data 参数
*/
export function noticeAdd(data: Partial<Notice>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 通知公告更新
* @param data 参数
*/
export function noticeUpdate(data: any) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 通知公告删除
* @param noticeIds ids
*/
export function noticeRemove(noticeIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${noticeIds}`);
}
-11
View File
@@ -1,11 +0,0 @@
export interface Notice {
noticeId: number;
noticeTitle: string;
noticeType: string;
noticeContent: string;
status: string;
remark: string;
createBy: number;
createByName: string;
createTime: string;
}
+1 -1
View File
@@ -57,7 +57,7 @@ export function ossDownload(
ossId: ID,
onDownloadProgress?: AxiosRequestConfig['onDownloadProgress'],
) {
return requestClient.get<Blob>(`/tool/oss/main/show?id=${ossId}`, {
return requestClient.get<Blob>(`/tool/oss/show?id=${ossId}`, {
responseType: 'blob',
timeout: 30 * 1000,
isTransformResponse: false,
-85
View File
@@ -1,85 +0,0 @@
import type { DeptTree } from '../user/model';
import type { Post } from './model';
import type { ID, IDS, PageQuery } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
postExport = '/system/post/export',
postList = '/system/post/list',
postSelect = '/system/post/optionselect',
root = '/system/post',
}
/**
* 获取岗位列表
* @param params 参数
* @returns Post[]
*/
export function postList(params?: PageQuery) {
return requestClient.get<Post[]>(Api.postList, { params });
}
/**
* 导出岗位信息
* @param data 请求参数
* @returns blob
*/
export function postExport(data: Partial<Post>) {
return commonExport(Api.postExport, data);
}
/**
* 查询岗位信息
* @param postId id
* @returns 岗位信息
*/
export function postInfo(postId: ID) {
return requestClient.get<Post>(`${Api.root}/${postId}`);
}
/**
* 岗位新增
* @param data 参数
* @returns void
*/
export function postAdd(data: Partial<Post>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 岗位更新
* @param data 参数
* @returns void
*/
export function postUpdate(data: Partial<Post>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 岗位删除
* @param postIds ids
* @returns void
*/
export function postRemove(postIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${postIds}`);
}
/**
* 根据部门id获取岗位下拉列表
* @param deptId 部门id
* @returns 岗位
*/
export function postOptionSelect(deptId: ID) {
return requestClient.get<Post[]>(Api.postSelect, { params: { deptId } });
}
/**
* 岗位专用 - 获取部门树
* @returns 部门树
*/
export function postDeptTreeSelect() {
return requestClient.get<DeptTree[]>('/system/post/deptTree');
}
-12
View File
@@ -1,12 +0,0 @@
/**
* @description: Post interface
*/
export interface Post {
postId: number;
postCode: string;
postName: string;
postSort: number;
status: string;
remark: string;
createTime: string;
}
+3 -3
View File
@@ -5,9 +5,9 @@ import { buildUUID } from '@vben/utils';
import { requestClient } from '#/api/request';
enum Api {
root = '/system/user/profile',
updateAvatar = '/system/user/profile/avatar',
updatePassword = '/system/user/profile/updatePwd',
root = '/pub/profile',
updateAvatar = '/pub/profile/avatar',
updatePassword = '/pub/profile/updatePwd',
}
/**
-166
View File
@@ -1,166 +0,0 @@
import type { User } from '../user/model';
import type { DeptResp, Role } from './model';
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
roleAllocatedList = '/system/role/authUser/allocatedList',
roleAuthCancel = '/system/role/authUser/cancel',
roleAuthCancelAll = '/system/role/authUser/cancelAll',
roleAuthSelectAll = '/system/role/authUser/selectAll',
roleChangeStatus = '/system/role/changeStatus',
roleDataScope = '/system/role/dataScope',
roleDeptTree = '/system/role/deptTree',
roleExport = '/system/role/export',
roleList = '/system/role/list',
roleOptionSelect = '/system/role/optionselect',
roleUnallocatedList = '/system/role/authUser/unallocatedList',
root = '/system/role',
}
/**
* 查询角色分页列表
* @param params 搜索条件
* @returns 分页列表
*/
export function roleList(params?: PageQuery) {
return requestClient.get<PageResult<Role>>(Api.roleList, { params });
}
/**
* 导出角色信息
* @param data 查询参数
* @returns blob
*/
export function roleExport(data: Partial<Role>) {
return commonExport(Api.roleExport, data);
}
/**
* 查询角色信息
* @param roleId 角色id
* @returns 角色信息
*/
export function roleInfo(roleId: ID) {
return requestClient.get<Role>(`${Api.root}/${roleId}`);
}
/**
* 角色新增
* @param data 参数
* @returns void
*/
export function roleAdd(data: Partial<Role>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 角色更新
* @param data 参数
* @returns void
*/
export function roleUpdate(data: Partial<Role>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 修改角色状态
* @param data 参数
* @returns void
*/
export function roleChangeStatus(data: Partial<Role>) {
const requestData = {
roleId: data.roleId,
status: data.status,
};
return requestClient.putWithMsg<void>(Api.roleChangeStatus, requestData);
}
/**
* 角色删除
* @param roleIds ids
* @returns void
*/
export function roleRemove(roleIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${roleIds}`);
}
/**
* 更新数据权限
* @param data
* @returns void
*/
export function roleDataScope(data: any) {
return requestClient.putWithMsg<void>(Api.roleDataScope, data);
}
/**
* @deprecated 全局并没有用到这个方法
*/
export function roleOptionSelect(params?: any) {
return requestClient.get(Api.roleOptionSelect, { params });
}
/**
* 已分配角色的用户分页
* @param params 请求参数
* @returns 分页
*/
export function roleAllocatedList(params?: PageQuery) {
return requestClient.get<PageResult<User>>(Api.roleAllocatedList, { params });
}
/**
* 未授权的用户
* @param params
* @returns void
*/
export function roleUnallocatedList(params: any) {
return requestClient.get<PageResult<User>>(Api.roleUnallocatedList, {
params,
});
}
/**
* 取消用户角色授权
* @returns void
*/
export function roleAuthCancel(data: { roleId: ID; userId: ID }) {
return requestClient.putWithMsg<void>(Api.roleAuthCancel, data);
}
/**
* 批量取消授权
* @param roleId 角色ID
* @param userIds 用户ID集合
* @returns void
*/
export function roleAuthCancelAll(roleId: ID, userIds: IDS) {
return requestClient.putWithMsg<void>(
`${Api.roleAuthCancelAll}?roleId=${roleId}&userIds=${userIds.join(',')}`,
);
}
/**
* 批量授权用户
* @param roleId 角色ID
* @param userIds 用户ID集合
* @returns void
*/
export function roleSelectAll(roleId: ID, userIds: IDS) {
return requestClient.putWithMsg<void>(
`${Api.roleAuthSelectAll}?roleId=${roleId}&userIds=${userIds.join(',')}`,
);
}
/**
* 根据角色id获取部门树
* @param roleId 角色id
* @returns DeptResp
*/
export function roleDeptTree(roleId: ID) {
return requestClient.get<DeptResp>(`${Api.roleDeptTree}/${roleId}`);
}
-29
View File
@@ -1,29 +0,0 @@
export interface Role {
roleId: number;
roleName: string;
roleKey: string;
roleSort: number;
dataScope: string;
menuCheckStrictly: boolean;
deptCheckStrictly: boolean;
status: string;
remark: string;
createTime: string;
// 用户是否存在此角色标识 默认不存在
flag: boolean;
superAdmin: boolean;
}
export interface DeptOption {
id: number;
parentId: number;
label: string;
weight: number;
children: DeptOption[];
key: string; // 实际上不存在 ide报错
}
export interface DeptResp {
checkedKeys: number[];
depts: DeptOption[];
}
@@ -1,91 +0,0 @@
import type { TenantPackage } from './model';
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
packageChangeStatus = '/system/tenant/package/changeStatus',
packageExport = '/system/tenant/package/export',
packageList = '/system/tenant/package/list',
packageSelectList = '/system/tenant/package/selectList',
root = '/system/tenant/package',
}
/**
* 租户套餐分页列表
* @param params 请求参数
* @returns 分页列表
*/
export function packageList(params?: PageQuery) {
return requestClient.get<PageResult<TenantPackage>>(Api.packageList, {
params,
});
}
/**
* 租户套餐下拉框
* @returns 下拉框
*/
export function packageSelectList() {
return requestClient.get<TenantPackage[]>(Api.packageSelectList);
}
/**
* 租户套餐导出
* @param data 参数
* @returns blob
*/
export function packageExport(data: Partial<TenantPackage>) {
return commonExport(Api.packageExport, data);
}
/**
* 租户套餐信息
* @param id id
* @returns 信息
*/
export function packageInfo(id: ID) {
return requestClient.get<TenantPackage>(`${Api.root}/${id}`);
}
/**
* 租户套餐新增
* @param data data
* @returns void
*/
export function packageAdd(data: Partial<TenantPackage>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 租户套餐更新
* @param data data
* @returns void
*/
export function packageUpdate(data: Partial<TenantPackage>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 租户套餐状态变更
* @param data data
* @returns void
*/
export function packageChangeStatus(data: Partial<TenantPackage>) {
const packageId = {
packageId: data.packageId,
status: data.status,
};
return requestClient.putWithMsg<void>(Api.packageChangeStatus, packageId);
}
/**
* 租户套餐移除
* @param ids ids
* @returns void
*/
export function packageRemove(ids: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${ids}`);
}
-17
View File
@@ -1,17 +0,0 @@
/**
* @description 租户套餐
* @param packageId id
* @param packageName 名称
* @param menuIds 菜单id 格式为[1,2,3] 返回为string 提交为数组
* @param remark 备注
* @param menuCheckStrictly 是否关联父节点
* @param status 状态
*/
export interface TenantPackage {
packageId: string;
packageName: string;
menuIds: number[] | string;
remark: string;
menuCheckStrictly: boolean;
status: string;
}
-127
View File
@@ -1,127 +0,0 @@
import type { Tenant } from './model';
import type { ID, IDS, PageQuery } from '#/api/common';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
dictSync = '/system/tenant/syncTenantDict',
root = '/system/tenant',
tenantDynamic = '/system/tenant/dynamic',
tenantDynamicClear = '/system/tenant/dynamic/clear',
tenantExport = '/system/tenant/export',
tenantList = '/system/tenant/list',
tenantStatus = '/system/tenant/changeStatus',
tenantSyncPackage = '/system/tenant/syncTenantPackage',
}
/**
* 查询租户分页列表
* @param params 参数
* @returns 分页
*/
export function tenantList(params?: PageQuery) {
return requestClient.get<Tenant[]>(Api.tenantList, { params });
}
/**
* 租户导出
* @param data data
* @returns void
*/
export function tenantExport(data: Partial<Tenant>) {
return commonExport(Api.tenantExport, data);
}
/**
* 查询租户信息
* @param id id
* @returns 租户信息
*/
export function tenantInfo(id: ID) {
return requestClient.get<Tenant>(`${Api.root}/${id}`);
}
/**
* 新增租户 必须开启加密
* @param data data
* @returns void
*/
export function tenantAdd(data: Partial<Tenant>) {
return requestClient.postWithMsg<void>(Api.root, data, { encrypt: true });
}
/**
* 租户更新
* @param data data
* @returns void
*/
export function tenantUpdate(data: Partial<Tenant>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 租户状态更新
* @param data data
* @returns void
*/
export function tenantStatusChange(data: Partial<Tenant>) {
const requestData = {
id: data.id,
tenantId: data.tenantId,
status: data.status,
};
return requestClient.putWithMsg(Api.tenantStatus, requestData);
}
/**
* 租户删除
* @param ids ids
* @returns void
*/
export function tenantRemove(ids: IDS) {
return requestClient.deleteWithMsg(`${Api.root}/${ids}`);
}
/**
* 动态切换租户
* @param tenantId 租户ID
* @returns void
*/
export function tenantDynamicToggle(tenantId: string) {
return requestClient.get<void>(`${Api.tenantDynamic}/${tenantId}`);
}
/**
* 清除 动态切换租户
* @returns void
*/
export function tenantDynamicClear() {
return requestClient.get<void>(Api.tenantDynamicClear);
}
/**
* 租户套餐同步
* @param tenantId 租户id
* @param packageId 套餐id
* @returns void
*/
export function tenantSyncPackage(tenantId: string, packageId: string) {
return requestClient.get<void>(Api.tenantSyncPackage, {
params: { packageId, tenantId },
successMessageMode: 'message',
});
}
/**
* 同步租户字典
* @param tenantId 租户ID
* @returns void
*/
export function dictSyncTenant(tenantId?: string) {
return requestClient.get<void>(Api.dictSync, {
params: { tenantId },
successMessageMode: 'message',
});
}
-16
View File
@@ -1,16 +0,0 @@
export interface Tenant {
accountCount: number;
address?: string;
companyName: string;
contactPhone: string;
contactUserName: string;
domain?: string;
expireTime?: string;
id: number;
intro: string;
licenseNumber?: any;
packageId: string;
remark?: string;
status: string;
tenantId: string;
}
-171
View File
@@ -1,171 +0,0 @@
import type {
DeptTree,
ResetPwdParam,
User,
UserImportParam,
UserInfoResponse,
} from './model';
import type { ID, IDS, PageQuery, PageResult } from '#/api/common';
import { commonExport, ContentTypeEnum } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
deptTree = '/system/user/deptTree',
listDeptUsers = '/system/user/list/dept',
root = '/system/user',
userAuthRole = '/system/user/authRole',
userExport = '/system/user/export',
userImport = '/system/user/importData',
userImportTemplate = '/system/user/importTemplate',
userList = '/system/user/list',
userResetPassword = '/system/user/resetPwd',
userStatusChange = '/system/user/changeStatus',
}
/**
* 获取用户列表
* @param params
* @returns User
*/
export function userList(params?: PageQuery) {
return requestClient.get<PageResult<User>>(Api.userList, { params });
}
/**
* 导出excel
* @param data data
* @returns blob
*/
export function userExport(data: Partial<User>) {
return commonExport(Api.userExport, data);
}
/**
* 从excel导入用户
* @param data
* @returns void
*/
export function userImportData(data: UserImportParam) {
return requestClient.post<{ code: number; msg: string }>(
Api.userImport,
data,
{
headers: {
'Content-Type': ContentTypeEnum.FORM_DATA,
},
isTransformResponse: false,
},
);
}
/**
* 下载用户导入模板
* @returns blob
*/
export function downloadImportTemplate() {
return requestClient.post<Blob>(
Api.userImportTemplate,
{},
{
isTransformResponse: false,
responseType: 'blob',
},
);
}
/**
* 可以不传ID 返回部门和角色options 需要获得原始数据
* 不传ID时一定要带最后的/
* @param userId 用户ID
* @returns 用户信息
*/
export function findUserInfo(userId?: ID) {
const url = userId ? `${Api.root}/${userId}` : `${Api.root}/`;
return requestClient.get<UserInfoResponse>(url);
}
/**
* 新增用户
* @param data data
* @returns void
*/
export function userAdd(data: Partial<User>) {
return requestClient.postWithMsg<void>(Api.root, data);
}
/**
* 更新用户
* @param data data
* @returns void
*/
export function userUpdate(data: Partial<User>) {
return requestClient.putWithMsg<void>(Api.root, data);
}
/**
* 更新用户状态
* @param data data
* @returns void
*/
export function userStatusChange(data: Partial<User>) {
const requestData = {
userId: data.userId,
status: data.status,
};
return requestClient.putWithMsg<void>(Api.userStatusChange, requestData);
}
/**
* 删除用户
* @param userIds 用户ID数组
* @returns void
*/
export function userRemove(userIds: IDS) {
return requestClient.deleteWithMsg<void>(`${Api.root}/${userIds}`);
}
/**
* 重置用户密码 需要加密
* @param data
* @returns void
*/
export function userResetPassword(data: ResetPwdParam) {
return requestClient.putWithMsg<void>(Api.userResetPassword, data, {
encrypt: true,
});
}
/**
* 这个方法未调用过
* @param userId
* @returns void
*/
export function getUserAuthRole(userId: ID) {
return requestClient.get(`${Api.userAuthRole}/${userId}`);
}
/**
* 这个方法未调用过
* @param userId
* @returns void
*/
export function userAuthRoleUpdate(userId: ID, roleIds: number[]) {
return requestClient.putWithMsg(Api.userAuthRole, { roleIds, userId });
}
/**
* 获取部门树
* @returns 部门树数组
*/
export function getDeptTree() {
return requestClient.get<DeptTree[]>(Api.deptTree);
}
/**
* 获取部门下的所有用户信息
*/
export function listUserByDeptId(deptId: ID) {
return requestClient.get<User[]>(`${Api.listDeptUsers}/${deptId}`);
}
-117
View File
@@ -1,117 +0,0 @@
/**
* @description: 用户导入
* @param updateSupport 是否覆盖数据
* @param file excel文件
*/
export interface UserImportParam {
updateSupport: boolean;
file: Blob | File;
}
/**
* @description: 重置密码
*/
export interface ResetPwdParam {
userId: string;
password: string;
}
export interface Dept {
deptId: number;
parentId: number;
parentName?: string;
ancestors: string;
deptName: string;
orderNum: number;
leader: string;
phone?: string;
email?: string;
status: string;
createTime?: string;
}
export interface Role {
roleId: string;
roleName: string;
roleKey: string;
roleSort: number;
dataScope: string;
menuCheckStrictly?: boolean;
deptCheckStrictly?: boolean;
status: string;
remark: string;
createTime?: string;
flag: boolean;
superAdmin: boolean;
}
export interface User {
userId: string;
tenantId: string;
deptId: number;
userName: string;
nickName: string;
userType: string;
email: string;
phonenumber: string;
gender: string;
avatar?: string;
status: string;
loginIp: string;
loginDate: string;
remark: string;
createTime: string;
dept: Dept;
roles: Role[];
roleIds?: string[];
postIds?: number[];
roleId: string;
deptName: string;
}
export interface Post {
postId: number;
postCode: string;
postName: string;
postSort: number;
status: string;
remark: string;
createTime: string;
}
/**
* @description 用户信息
* @param user 用户个人信息
* @param roleIds 角色IDS 不传id为空
* @param roles 所有的角色
* @param postIds 岗位IDS 不传id为空
* @param posts 所有的岗位
*/
export interface UserInfoResponse {
user?: User;
roleIds?: string[];
roles: Role[];
postIds?: number[];
posts?: Post[];
}
/**
* @description: 部门树
*/
export interface DeptTree {
id: number;
/**
* antd组件必须要这个属性 实际是没有这个属性的
*/
key: string;
parentId: number;
label: string;
weight: number;
children?: DeptTree[];
}
export interface DeptTreeData {
id: number;
label: string;
children?: DeptTreeData[];
}
+4
View File
@@ -47,6 +47,10 @@
padding: 8px !important;
}
.chat-card .el-card__body {
padding: 0 !important;
}
.nopadding .el-card__body {
padding: 0 !important;
}
@@ -24,7 +24,7 @@ const emit = defineEmits(['update:modelValue']);
const number = ref(0);
const uploadList = ref<any[]>([]);
const uploadFileUrl = ref(import.meta.env.VITE_GLOB_API_URL + '/tool/oss/main/upload'); // 上传文件服务器地址
const uploadFileUrl = ref(import.meta.env.VITE_GLOB_API_URL + '/tool/oss/upload'); // 上传文件服务器地址
const headers = ref(globalHeaders());
@@ -39,7 +39,7 @@ const dialogImageUrl = ref('');
const dialogVisible = ref(false);
const baseUrl = import.meta.env.VITE_GLOB_API_URL;
const uploadImgUrl = ref(baseUrl + '/tool/oss/main/upload'); // 上传的图片服务器地址
const uploadImgUrl = ref(baseUrl + '/tool/oss/upload'); // 上传的图片服务器地址
const headers = ref(globalHeaders());
const fileList = ref<any[]>([]);
@@ -46,7 +46,7 @@ export default function CustomRenderer(eventBus, styles, textRenderer) {
// or customConfig[type]
console.log('重构');
let data = {};
data.tabna = 'sys_org [组织架构汇总表]';
data.tabna = 'sys_actor [系统参与者]';
data.fields = [
{ name: 'id', comet: '主键' },
{ name: 'name', comet: '名称' },
+10 -10
View File
@@ -4,7 +4,7 @@ import { computed, defineExpose, reactive, ref, toRaw, toRefs } from 'vue';
import { buildUUID } from '@vben/utils';
import { requestClient } from '#/api/request';
import OrgModal from '#/components/sys/OrgModal.vue';
import ActorModal from '#/components/sys/ActorModal.vue';
import FuncModal from './func.vue';
@@ -146,8 +146,8 @@ const closeModal = () => {
};
const cdata = reactive({}) as any;
// region -----组织架构逻辑-----
const orgModal = ref();
// region -----成员逻辑-----
const actorModal = ref();
const funcModal = ref();
const hatypChange = () => {
@@ -155,20 +155,20 @@ const hatypChange = () => {
};
const hamenModal = () => {
if (state.form.hatyp === '1') {
orgModal.value.open({
actorModal.value.open({
opener: 'hamen',
orgType: 6,
actorType: 6,
selectMode: 2,
orgs: toRaw(form.value.hamen),
actors: toRaw(form.value.hamen),
});
} else if (state.form.hatyp === '2') {
funcModal.value.open({});
}
};
const closeOrgModal = (data: any) => {
const closeActorModal = (data: any) => {
if (data.opener === 'hamen') {
form.value.hamen = data.orgs && data.orgs.length > 0 ? data.orgs : null;
form.value.hamen = data.actors && data.actors.length > 0 ? data.actors : null;
if (form.value.name === '审批节点' || form.value.name === '') {
let names = '';
if (form.value.hamen && form.value.hamen.length > 0) {
@@ -302,7 +302,7 @@ const addEvent = () => {
<template>
<div>
<OrgModal ref="orgModal" @close="closeOrgModal" />
<ActorModal ref="actorModal" @close="closeActorModal" />
<FuncModal ref="funcModal" @close="closeFuncModal" />
<el-dialog v-model="state.isShow" :title="state.title" width="600px" draggable>
<div style="height: 500px">
@@ -314,7 +314,7 @@ const addEvent = () => {
</el-form-item>
<el-form-item label="审批人类型:" v-show="cdata.show1 || cdata.show2">
<el-radio-group v-model="form.hatyp" @change="hatypChange">
<el-radio label="1">从组织架构选择</el-radio>
<el-radio label="1">从系统成员选择</el-radio>
<el-radio label="2">使用公式定义器</el-radio>
</el-radio-group>
</el-form-item>
@@ -71,7 +71,7 @@ const closeModal = () => {
state.isShow = false;
};
//region a 左侧部门树点击
//region a 左侧组织树点击
const nodeClick = async (node: any) => {
if(node){
state.tabna = node.name;
+16 -16
View File
@@ -417,43 +417,43 @@ const refChange = (id: any) => {
}
};
// region -----组织架构逻辑-----
const orgModal = ref();
// region -----系统参与者逻辑-----
const actorModal = ref();
const cdata = reactive({}) as any;
const tumanModal = () => {
orgModal.value.open({
actorModal.value.open({
opener: 'tuman',
orgType: 6,
actorType: 6,
selectMode: 1,
});
};
const comenModal = () => {
orgModal.value.open({
actorModal.value.open({
opener: 'comen',
orgType: 6,
actorType: 6,
selectMode: 2,
orgs: toRaw(form.value.comen),
actors: toRaw(form.value.comen),
});
};
const closeOrgModal = (data: any) => {
const closeActorModal = (data: any) => {
if (data.opener === 'tuman') {
if (data.orgs && data.orgs.length > 0) {
if (data.actors && data.actors.length > 0) {
form.value.tuman = {};
form.value.tuman = { id: data.orgs[0].id, name: data.orgs[0].name };
form.value.tuuid = data.orgs[0].id;
form.value.tuman = { id: data.actors[0].id, name: data.actors[0].name };
form.value.tuuid = data.actors[0].id;
} else {
form.value.tuman = null;
form.value.tuuid = null;
}
} else if (data.opener === 'comen') {
if (data.orgs && data.orgs.length > 0) {
form.value.comen = data.orgs;
if (data.actors && data.actors.length > 0) {
form.value.comen = data.actors;
form.value.coids = '';
for (const org of data.orgs) {
form.value.coids += `${org.id};`;
for (const actor of data.actors) {
form.value.coids += `${actor.id};`;
}
if (form.value.coids !== '') {
form.value.coids = form.value.coids.slice(0, Math.max(0, form.value.coids.length - 1));
@@ -699,7 +699,7 @@ const nodeModalRef = ref();
<div class="canvas" ref="canvasRef"></div>
</div>
</div>
<OrgModal ref="orgModal" @close="closeOrgModal" />
<ActorModal ref="actorModal" @close="closeActorModal" />
<!-- <Pmodal ref="pmodal" @close="closePmodal" />-->
</el-form>
</template>
+2 -2
View File
@@ -1,6 +1,6 @@
<template>
<div>
<OrgModal ref="orgModal" @close="closeOrgModal" />
<ActorModal ref="actorModal" @close="closeActorModal" />
<el-dialog v-model="state.isShow" :title="state.title" width="600px" draggable>
<div style="height: 500px">
<el-form ref="formRef" :model="form" label-width="140px">
@@ -28,7 +28,7 @@
<script lang="ts" setup>
import { defineExpose, reactive, toRefs } from 'vue';
import OrgModal from '/@/comps/sys/OrgModal.vue';
import ActorModal from '/@/comps/sys/ActorModal.vue';
const state = reactive({
isShow: false,
@@ -72,6 +72,7 @@ function handleBeforeUpload(file: File) {
});
return false;
}
const fileList = ref([]);
function handleCropend({ imgBase64 }: CropendResult) {
previewSource.value = imgBase64;
@@ -117,40 +118,17 @@ async function handleOk() {
}
</script>
<template>
<BasicModal
v-bind="$attrs"
:confirm-text="t('component.cropper.okText')"
:fullscreen-button="false"
:title="t('component.cropper.modalTitle')"
class="w-[800px]"
>
<BasicModal v-bind="$attrs" :confirm-text="t('component.cropper.okText')" :fullscreen-button="false" :title="t('component.cropper.modalTitle')" class="w-[800px]">
<div :class="prefixCls">
<div :class="`${prefixCls}-left`" class="w-full">
<div :class="`${prefixCls}-cropper`">
<CropperImage
v-if="src"
:circled="circled"
:src="src"
crossorigin="anonymous"
height="300px"
@cropend="handleCropend"
@ready="handleReady"
@ready-error="handleReadyError"
/>
<CropperImage v-if="src" :circled="circled" :src="src" crossorigin="anonymous" height="300px" @cropend="handleCropend" @ready="handleReady" @ready-error="handleReadyError" />
</div>
<div :class="`${prefixCls}-toolbar`">
<el-upload
:before-upload="handleBeforeUpload"
:file-list="[]"
accept="image/*"
style="height: 24px"
>
<el-tooltip
:content="t('component.cropper.selectImage')"
placement="bottom"
>
<el-button size="small" type="primary" style="width:26px">
<el-upload :before-upload="handleBeforeUpload" v-model:file-list="fileList" accept="image/*" style="height: 24px">
<el-tooltip :content="t('component.cropper.selectImage')" placement="bottom">
<el-button size="small" type="primary" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -163,7 +141,7 @@ async function handleOk() {
</el-upload>
<el-space>
<el-tooltip :content="t('component.cropper.btn_reset')" placement="bottom">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('reset')" style="width:26px">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('reset')" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -175,7 +153,7 @@ async function handleOk() {
</el-tooltip>
<el-tooltip :content="t('component.cropper.btn_rotate_left')" placement="bottom">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('rotate', -45)" style="width:26px">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('rotate', -45)" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -187,7 +165,7 @@ async function handleOk() {
</el-tooltip>
<el-tooltip :content="t('component.cropper.btn_rotate_right')" placement="bottom">
<el-button :disabled="!src" pre-icon="ep:d-arrow-right" size="small" type="primary" @click="handlerToolbar('rotate', 45)" style="width:26px">
<el-button :disabled="!src" pre-icon="ep:d-arrow-right" size="small" type="primary" @click="handlerToolbar('rotate', 45)" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -199,7 +177,7 @@ async function handleOk() {
</el-tooltip>
<el-tooltip :content="t('component.cropper.btn_scale_x')" placement="bottom">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('scaleX')" style="width:26px">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('scaleX')" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -211,7 +189,7 @@ async function handleOk() {
</el-tooltip>
<el-tooltip :content="t('component.cropper.btn_scale_y')" placement="bottom">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('scaleY')" style="width:26px">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('scaleY')" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -223,7 +201,7 @@ async function handleOk() {
</el-tooltip>
<el-tooltip :content="t('component.cropper.btn_zoom_in')" placement="bottom">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('zoom', 0.1)" style="width:26px">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('zoom', 0.1)" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -235,7 +213,7 @@ async function handleOk() {
</el-tooltip>
<el-tooltip :content="t('component.cropper.btn_zoom_out')" placement="bottom">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('zoom', -0.1)" style="width:26px">
<el-button :disabled="!src" size="small" type="primary" @click="handlerToolbar('zoom', -0.1)" style="width: 26px">
<template #icon>
<div class="flex items-center justify-center">
<el-icon>
@@ -250,11 +228,7 @@ async function handleOk() {
</div>
<div :class="`${prefixCls}-right`">
<div :class="`${prefixCls}-preview`">
<img
v-if="previewSource"
:alt="t('component.cropper.preview')"
:src="previewSource"
/>
<img v-if="previewSource" :alt="t('component.cropper.preview')" :src="previewSource" />
</div>
<template v-if="previewSource">
<div :class="`${prefixCls}-group`">
@@ -290,20 +264,7 @@ async function handleOk() {
height: 300px;
background: #eee;
background-image:
linear-gradient(
45deg,
rgb(0 0 0 / 25%) 25%,
transparent 0,
transparent 75%,
rgb(0 0 0 / 25%) 0
),
linear-gradient(
45deg,
rgb(0 0 0 / 25%) 25%,
transparent 0,
transparent 75%,
rgb(0 0 0 / 25%) 0
);
linear-gradient(45deg, rgb(0 0 0 / 25%) 25%, transparent 0, transparent 75%, rgb(0 0 0 / 25%) 0), linear-gradient(45deg, rgb(0 0 0 / 25%) 25%, transparent 0, transparent 75%, rgb(0 0 0 / 25%) 0);
background-position:
0 0,
12px 12px;
@@ -8,20 +8,20 @@ const emits = defineEmits(['close']);
let p_tab_key = 'k1';
let p_select_mode = 1; // 1单选,2多选
let p_opener = null as any; // 弹框打开者标记
let p_dept_init_flag = false; // 层级架构页签初始化标记
let p_org_init_flag = false; // 层级架构页签初始化标记
let p_role_init_flag = false; // 审批角色页签初始化标记
let p_group_init_flag = false; // 常用群组页签初始化标记
let p_coop_init_flag = false; // 外部协同页签初始化标记
const deptTreeRef = ref();
const orgTreeRef = ref();
const roleTreeRef = ref();
const groupTreeRef = ref();
const coopTreeRef = ref();
const state = reactive({
isShow: false,
p_org_type: -1, // 0为综合,1为机构,2为部门,4为岗位,8为用户,16为常用群组,32为角色线
p_coop_type: -1, // 0为综合,1为协调分类,2为协调公司,4为协同部门
p_actor_type: -1,
p_coop_type: -1,
receSearch: '' as string,
receItems: [] as any,
tierItems: [] as any,
@@ -57,9 +57,9 @@ async function tabChange(tab: any) {
break;
}
case 'k2': {
if (!p_dept_init_flag) {
await deptTreeRef.value.init();
p_dept_init_flag = true;
if (!p_org_init_flag) {
await orgTreeRef.value.init();
p_org_init_flag = true;
}
for (const tItem of tierItems.value) {
let flag = false;
@@ -149,7 +149,7 @@ async function tabChange(tab: any) {
// region x.1 最近使用
async function onSearch() {
receItems.value = await requestClient.get(`/pub/org?type=${state.p_org_type}&name=${state.receSearch}`);
receItems.value = await requestClient.get(`/pub/actor?type=${state.p_actor_type}&name=${state.receSearch}`);
for (const rItem of receItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
@@ -166,7 +166,7 @@ async function onSearch() {
}
const receInit = async () => {
receItems.value = await requestClient.get(`/pub/org/rece?type=${state.p_org_type}`);
receItems.value = await requestClient.get(`/pub/rece?type=${state.p_actor_type}`);
};
function receItemClick(item: any) {
@@ -182,7 +182,7 @@ function receItemClick(item: any) {
receItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -213,8 +213,8 @@ function receItemClick(item: any) {
async function nodeClick(node: any) {
if (node && node.id) {
//tierItems.value = await requestClient.get(`/system/user/list?type=${state.p_org_type}&depid=${node.id}`);
tierItems.value = await requestClient.get(`/pub/org?type=${state.p_org_type}&depid=${node.id}`);
//tierItems.value = await requestClient.get(`/system/user/list?type=${state.p_actor_type}&orgid=${node.id}`);
tierItems.value = await requestClient.get(`/pub/actor?type=${state.p_actor_type}&orgid=${node.id}`);
for (const tItem of tierItems.value) {
for (const sItem of seldItems.value) {
@@ -240,7 +240,7 @@ function tierItemClick(item: any) {
tierItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -270,7 +270,7 @@ function tierItemClick(item: any) {
// region x.3 常用群组
async function groupNodeClick(node: any) {
if (node && node.id) {
groupItems.value = await requestClient.get(`/pub/org/group/list?pid=${node.id}&type=${node.type}`);
groupItems.value = await requestClient.get(`/pub/group/list?pid=${node.id}&type=${node.type}`);
for (const gItem of groupItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === gItem.id) {
@@ -295,7 +295,7 @@ function groupItemClick(item: any) {
groupItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -326,7 +326,7 @@ function groupItemClick(item: any) {
async function roleNodeClick(node: any) {
if (node && node.id) {
roleItems.value = await requestClient.get(`/pub/org/role/list?treid=${node.id}`);
roleItems.value = await requestClient.get(`/pub/actor/role/list?treid=${node.id}`);
for (const rItem of roleItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
@@ -351,7 +351,7 @@ function roleItemClick(item: any) {
roleItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -407,7 +407,7 @@ function coopItemClick(item: any) {
coopItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -467,14 +467,14 @@ function selectedItemClick(item: any) {
// region 与父组件的交互逻辑
const open = async (data: any) => {
if (!data.orgType) {
data.orgType = 2;
if (!data.actorType) {
data.actorType = 2;
}
if (!data.selectMode) {
data.selectMode = 1;
}
if (state.p_org_type !== data.orgType) {
state.p_org_type = data.orgType;
if (state.p_actor_type !== data.actorType) {
state.p_actor_type = data.actorType;
await receInit();
tierItems.value.splice(0);
}
@@ -484,7 +484,7 @@ const open = async (data: any) => {
p_select_mode = data.selectMode;
p_opener = data.opener;
// 1.初始化
seldItems.value = data.orgs ? data.orgs : [];
seldItems.value = data.actors ? data.actors : [];
// //2.设置最近使用与层级架构里item的check状态
if (p_tab_key === 'k1') {
for (const rItem of receItems.value) {
@@ -523,22 +523,22 @@ defineExpose({ open });
const closeModal = async () => {
const rawSeldItems = toRaw(seldItems.value);
if (rawSeldItems && rawSeldItems.length > 0) {
// 更新后台数据库最近使用的ORGS
await requestClient.post('/pub/org/rece', rawSeldItems);
// 更新后台数据库最近使用的ACTORS
await requestClient.post('/pub/rece', rawSeldItems);
}
emits('close', { opener: p_opener, orgs: toRaw(rawSeldItems) });
emits('close', { opener: p_opener, actors: toRaw(rawSeldItems) });
state.isShow = false;
};
const clearAndcloseModal = () => {
emits('close', { opener: p_opener, orgs: null });
emits('close', { opener: p_opener, actors: null });
state.isShow = false;
};
// endregion
</script>
<template>
<el-dialog v-model="state.isShow" title="组织架构选择" width="1000px" draggable>
<el-dialog v-model="state.isShow" title="成员选择" width="1000px" draggable>
<div style="height: 440px">
<el-row>
<el-col :span="16">
@@ -549,12 +549,12 @@ const clearAndcloseModal = () => {
<el-button type="primary" style="margin-left: 10px" @click="onSearch">查询 </el-button>
</div>
<div style="margin-top: 5px; overflow: auto; height: 353px; border: 1px solid #ccc">
<ul class="z-org-search" id="zOrgSearch" style="padding: 2px">
<ul class="z-actor-search" id="zActorSearch" style="padding: 2px">
<li v-for="item in receItems" :key="item.id" class="f-user" @click="receItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="item.avatar ?? avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
<span class="layui-elip f-user-org">{{ item.org }}</span>
</li>
</ul>
</div>
@@ -563,33 +563,33 @@ const clearAndcloseModal = () => {
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/sys/dept/tree" @node-click="nodeClick" :ma-init="true" ref="deptTreeRef" tip="部门名称" />
<SelectTree url="/pub/org/tree" @node-click="nodeClick" :ma-init="true" ref="orgTreeRef" tip="组织名称" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<ul class="z-actor-tree">
<li v-for="item in tierItems" :key="item.id" class="f-user" title=" " @click="tierItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="item.avatar ?? avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
<span class="layui-elip f-user-org">{{ item.org }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="常用群组" name="k3" v-if="(state.p_org_type & 8) !== 0">
<el-tab-pane label="常用群组" name="k3" v-if="(state.p_actor_type & 8) !== 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/pub/org/group/tree" @node-click="groupNodeClick" :ma-init="true" ref="groupTreeRef" tip="群组分类/群组" />
<SelectTree url="/pub/group/tree" @node-click="groupNodeClick" :ma-init="true" ref="groupTreeRef" tip="群组分类/群组" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<ul class="z-actor-tree">
<li v-for="item in groupItems" :key="item.id" class="f-user" title=" " @click="groupItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="item.avatar ?? avatar" />
@@ -600,16 +600,16 @@ const clearAndcloseModal = () => {
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="审批角色" name="k4" v-if="(state.p_org_type & 16) !== 0">
<el-tab-pane label="审批角色" name="k4" v-if="(state.p_actor_type & 16) !== 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/pub/org/role/tree" @node-click="roleNodeClick" :ma-init="true" ref="roleTreeRef" />
<SelectTree url="/pub/actor/role/tree" @node-click="roleNodeClick" :ma-init="true" ref="roleTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<ul class="z-actor-tree">
<li v-for="item in roleItems" :key="item.id" class="f-user" title=" " @click="roleItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="item.avatar ?? avatar" />
@@ -629,7 +629,7 @@ const clearAndcloseModal = () => {
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<ul class="z-actor-tree">
<li v-for="item in coopItems" :key="item.id" class="f-user" title=" " @click="coopItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="item.avatar ?? avatar" />
@@ -649,7 +649,7 @@ const clearAndcloseModal = () => {
<div style="margin-top: 20px">已 选</div>
</div>
<div style="border: 1px solid #ccc; height: 390px; overflow: auto">
<ul class="z-org-selected" style="position: relative">
<ul class="z-actor-selected" style="position: relative">
<li v-for="item in seldItems" :key="item.id" class="f-user" style="overflow: hidden">
<el-icon @click="selectedItemClick(item)">
<CircleClose />
@@ -710,7 +710,7 @@ const clearAndcloseModal = () => {
}
.f-user .f-user-name,
.f-user .f-user-dept {
.f-user .f-user-org {
display: block;
}
@@ -718,12 +718,12 @@ const clearAndcloseModal = () => {
margin-top: 6px;
}
.f-user .f-user-dept {
.f-user .f-user-org {
color: #a599b2;
}
/*最近*/
/*.z-org-recently li {*/
/*.z-actor-recently li {*/
/* width: 33%;*/
/* float: left;*/
/* cursor: pointer;*/
@@ -731,12 +731,12 @@ const clearAndcloseModal = () => {
/* list-style-type: none;*/
/*}*/
/*.z-org-recently li:hover {*/
/*.z-actor-recently li:hover {*/
/* background-color: #f7efec;*/
/*}*/
/*搜索查询*/
.z-org-search li {
.z-actor-search li {
/*width: 280px;*/
width: 50%;
float: left;
@@ -746,47 +746,46 @@ const clearAndcloseModal = () => {
/*margin: 3px;*/
}
.z-org-search li:hover {
.z-actor-search li:hover {
background-color: #f7efec;
}
.dark .z-org-search li:hover {
.dark .z-actor-search li:hover {
background-color: #1f1f1f;
}
/*!*组织架构树*!*/
.z-org-tree li {
.z-actor-tree li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-tree li:hover {
.z-actor-tree li:hover {
background-color: #f7efec;
}
.dark .z-org-tree li:hover {
.dark .z-actor-tree li:hover {
background-color: #1f1f1f;
}
/*已选的*/
.z-org-selected li {
.z-actor-selected li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-selected li:hover {
.z-actor-selected li:hover {
background-color: #f7efec;
}
.dark .z-org-selected li:hover {
.dark .z-actor-selected li:hover {
background-color: #1f1f1f;
}
.z-org-selected .f-user .el-icon {
.z-actor-selected .f-user .el-icon {
/*float: left;*/
/*position:relative;*/
position: absolute;
@@ -797,16 +796,16 @@ const clearAndcloseModal = () => {
margin-left: 42px;
}
.z-org-selected li:hover .el-icon {
.z-actor-selected li:hover .el-icon {
display: inline;
}
.z-org-selected .f-user img {
.z-actor-selected .f-user img {
display: inline;
/*float: none;*/
}
.z-org-selected .f-user-name2 {
.z-actor-selected .f-user-name2 {
display: block;
margin-top: 14px;
}
@@ -1,812 +0,0 @@
<script lang="ts" setup>
import { requestClient } from '#/api/request';
import SelectTree from '#/components/tree/ViewTree.vue';
import avatar from './avatar.png';
const emits = defineEmits(['close']);
let p_tab_key = 'k1';
let p_select_mode = 1; // 1单选,2多选
let p_opener = null as any; // 弹框打开者标记
let p_dept_init_flag = false; // 层级架构页签初始化标记
let p_role_init_flag = false; // 审批角色页签初始化标记
let p_group_init_flag = false; // 常用群组页签初始化标记
let p_coop_init_flag = false; // 外部协同页签初始化标记
const deptTreeRef = ref();
const roleTreeRef = ref();
const groupTreeRef = ref();
const coopTreeRef = ref();
const state = reactive({
isShow: false,
p_org_type: -1, // 0为综合,1为机构,2为部门,4为岗位,8为用户,16为常用群组,32为角色线
p_coop_type: -1, // 0为综合,1为协调分类,2为协调公司,4为协同部门
receSearch: '' as string,
receItems: [] as any,
tierItems: [] as any,
seldItems: [] as any,
roleItems: [] as any,
groupItems: [] as any,
coopItems: [] as any,
});
const { receItems, tierItems, seldItems, roleItems, groupItems, coopItems } = toRefs(state);
const activeName = ref('k1');
// region z Tab切换
async function tabChange(tab: any) {
p_tab_key = tab.paneName;
switch (p_tab_key) {
case 'k1': {
for (const rItem of receItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
break;
}
case 'k2': {
if (!p_dept_init_flag) {
await deptTreeRef.value.init();
p_dept_init_flag = true;
}
for (const tItem of tierItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === tItem.id) {
tItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
tItem.checked = false;
}
}
break;
}
case 'k3': {
if (!p_group_init_flag) {
await groupTreeRef.value.init();
p_group_init_flag = true;
}
for (const gItem of groupItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === gItem.id) {
gItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
gItem.checked = false;
}
}
break;
}
case 'k4': {
if (!p_role_init_flag) {
await roleTreeRef.value.init();
p_role_init_flag = true;
}
for (const rItem of roleItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
break;
}
case 'k5': {
if (!p_coop_init_flag) {
await coopTreeRef.value.init();
p_coop_init_flag = true;
}
for (const rItem of coopItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id == rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
break;
}
// No default
}
}
// endregion
// region x.1 最近使用
async function onSearch() {
receItems.value = await requestClient.get(`/gen/org/main?type=${state.p_org_type}&name=${state.receSearch}`);
for (const rItem of receItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
}
const receInit = async () => {
receItems.value = await requestClient.get(`/gen/org/rece?type=${state.p_org_type}`);
};
function receItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < receItems.value.length; i++) {
if (receItems.value[i].id !== item.id) {
receItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.2 层级架构
async function nodeClick(node: any) {
if (node && node.id) {
tierItems.value = await requestClient.get(`/system/user/list?type=${state.p_org_type}&depid=${node.id}`);
for (const tItem of tierItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === tItem.id) {
tItem.checked = true;
break;
}
}
}
}
}
function tierItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < tierItems.value.length; i++) {
if (tierItems.value[i].id !== item.id) {
tierItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.3 常用群组
async function groupNodeClick(node: any) {
if (node && node.id) {
groupItems.value = await requestClient.get(`/gen/org/group/list?pid=${node.id}&type=${node.type}`);
for (const gItem of groupItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === gItem.id) {
gItem.checked = true;
break;
}
}
}
}
}
function groupItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < groupItems.value.length; i++) {
if (groupItems.value[i].id !== item.id) {
groupItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.4 审批角色
async function roleNodeClick(node: any) {
if (node && node.id) {
roleItems.value = await requestClient.get(`/gen/org/role/list?treid=${node.id}`);
for (const rItem of roleItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
break;
}
}
}
}
}
function roleItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < roleItems.value.length; i++) {
if (roleItems.value[i].id !== item.id) {
roleItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.5 外部协同
async function coopNodeClick(node: any) {
if (node) {
coopItems.value = await requestClient.get(`/gen/coop/list?pid=${node.id}&type=${state.p_coop_type}`);
for (const rItem of coopItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
break;
}
}
}
}
}
function coopItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < coopItems.value.length; i++) {
if (coopItems.value[i].id !== item.id) {
coopItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.6 我的收藏
// endregion
// region c.1 已选逻辑
function selectedItemClick(item: any) {
if (p_tab_key === 'k1') {
for (let i = 0; i < receItems.value.length; i++) {
if (receItems.value[i].id === item.id) {
receItems.value[i].checked = false;
break;
}
}
} else if (p_tab_key === 'k2') {
for (let i = 0; i < tierItems.value.length; i++) {
if (tierItems.value[i].id === item.id) {
tierItems.value[i].checked = false;
break;
}
}
}
for (let j = 0; j < seldItems.value.length; j++) {
if (seldItems.value[j].id === item.id) {
seldItems.value.splice(j, 1);
break;
}
}
}
// endregion
// region 与父组件的交互逻辑
const open = async (data: any) => {
if (!data.orgType) {
data.orgType = 8;
}
if (!data.selectMode) {
data.selectMode = 1;
}
if (state.p_org_type !== data.orgType) {
state.p_org_type = data.orgType;
await receInit();
tierItems.value.splice(0);
}
if (data.coopType && state.p_coop_type !== data.coopType) {
state.p_coop_type = data.coopType;
}
p_select_mode = data.selectMode;
p_opener = data.opener;
// 1.初始化
seldItems.value = data.orgs ? data.orgs : [];
// //2.设置最近使用与层级架构里item的check状态
if (p_tab_key === 'k1') {
for (const rItem of receItems.value) {
for (const sItem of seldItems.value) {
let flag = false;
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
if (!flag) {
rItem.checked = false;
}
}
}
} else if (p_tab_key === 'k2') {
for (const tItem of tierItems.value) {
for (const sItem of seldItems.value) {
let flag = false;
if (sItem.id === tItem.id) {
tItem.checked = true;
flag = true;
break;
}
if (!flag) {
tItem.checked = false;
}
}
}
}
state.isShow = true;
};
defineExpose({ open });
const closeModal = async () => {
const rawSeldItems = toRaw(seldItems.value);
if (rawSeldItems && rawSeldItems.length > 0) {
// 更新后台数据库最近使用的ORGS
await requestClient.post('/gen/org/rece', rawSeldItems);
}
emits('close', { opener: p_opener, orgs: toRaw(rawSeldItems) });
state.isShow = false;
};
const clearAndcloseModal = () => {
emits('close', { opener: p_opener, orgs: null });
state.isShow = false;
};
// endregion
</script>
<template>
<el-dialog v-model="state.isShow" title="组织架构选择" width="1000px" draggable>
<div style="height: 440px">
<el-row>
<el-col :span="16">
<el-tabs v-model="activeName" type="card" @tab-click="tabChange">
<el-tab-pane label="快捷选择" name="k1">
<div>
<el-input v-model="state.receSearch" placeholder="请输入关键字查询" style="width: 200px" @keyup.enter="onSearch" />
<el-button type="primary" style="margin-left: 10px" @click="onSearch">查询 </el-button>
</div>
<div style="margin-top: 5px; overflow: auto; height: 353px; border: 1px solid #ccc">
<ul class="z-org-search" id="zOrgSearch" style="padding: 2px">
<li v-for="item in receItems" :key="item.id" class="f-user" @click="receItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
</li>
</ul>
</div>
</el-tab-pane>
<el-tab-pane label="层级架构" name="k2">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/system/user/deptTree" @node-click="nodeClick" :ma-init="true" ref="deptTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in tierItems" :key="item.id" class="f-user" title=" " @click="tierItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="常用群组" name="k3" v-if="(state.p_org_type & 16) !== 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/gen/org/group/tree" @node-click="groupNodeClick" :ma-init="true" ref="groupTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in groupItems" :key="item.id" class="f-user" title=" " @click="groupItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="审批角色" name="k4" v-if="(state.p_org_type & 32) !== 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/gen/org/role/tree" @node-click="roleNodeClick" :ma-init="true" ref="roleTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in roleItems" :key="item.id" class="f-user" title=" " @click="roleItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="外部协同" name="k5" v-if="state.p_coop_type >= 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/gen/coop/tree?type=user" @node-click="coopNodeClick" :ma-init="true" ref="coopTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in coopItems" :key="item.id" class="f-user" title=" " @click="coopItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="我的收藏" name="k9">这个也暂不支持,待开发</el-tab-pane>
</el-tabs>
</el-col>
<el-col :span="8">
<div style="margin-left: 5px">
<div style="height: 36px">
<div style="margin-top: 20px">已 选</div>
</div>
<div style="border: 1px solid #ccc; height: 390px; overflow: auto">
<ul class="z-org-selected" style="position: relative">
<li v-for="item in seldItems" :key="item.id" class="f-user" style="overflow: hidden">
<el-icon @click="selectedItemClick(item)">
<CircleClose />
</el-icon>
<img :src="avatar" />
<span class="layui-elip f-user-name2">{{ item.name }}</span>
</li>
</ul>
</div>
</div>
</el-col>
</el-row>
</div>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="closeModal">确认</el-button>
<el-button @click="state.isShow = false">取消</el-button>
<el-button @click="clearAndcloseModal" style="margin-left: 20px">清空选择</el-button>
</span>
</template>
</el-dialog>
</template>
<style scoped>
.dialog-footer button:first-child {
margin-right: 10px;
}
.layui-elip {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.f-user:before,
.f-user:after {
content: ' ';
display: table;
}
.f-user:after {
clear: both;
}
.f-user input,
.f-user label {
float: left;
margin-top: 10px;
margin-right: 8px;
}
.f-user img {
width: 50px;
height: 50px;
float: left;
border-radius: 100%;
margin-right: 8px;
}
.f-user .f-user-name,
.f-user .f-user-dept {
display: block;
}
.f-user .f-user-name {
margin-top: 6px;
}
.f-user .f-user-dept {
color: #a599b2;
}
/*最近*/
/*.z-org-recently li {*/
/* width: 33%;*/
/* float: left;*/
/* cursor: pointer;*/
/* padding: 5px;*/
/* list-style-type: none;*/
/*}*/
/*.z-org-recently li:hover {*/
/* background-color: #f7efec;*/
/*}*/
/*搜索查询*/
.z-org-search li {
/*width: 280px;*/
width: 50%;
float: left;
cursor: pointer;
padding: 2px;
list-style-type: none;
/*margin: 3px;*/
}
.z-org-search li:hover {
background-color: #f7efec;
}
.dark .z-org-search li:hover {
background-color: #1f1f1f;
}
/*!*组织架构树*!*/
.z-org-tree li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-tree li:hover {
background-color: #f7efec;
}
.dark .z-org-tree li:hover {
background-color: #1f1f1f;
}
/*已选的*/
.z-org-selected li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-selected li:hover {
background-color: #f7efec;
}
.dark .z-org-selected li:hover {
background-color: #1f1f1f;
}
.z-org-selected .f-user .el-icon {
/*float: left;*/
/*position:relative;*/
position: absolute;
/*position:fixed;*/
color: #f26b96;
font-size: 20px;
display: none;
margin-left: 42px;
}
.z-org-selected li:hover .el-icon {
display: inline;
}
.z-org-selected .f-user img {
display: inline;
/*float: none;*/
}
.z-org-selected .f-user-name2 {
display: block;
margin-top: 14px;
}
</style>
@@ -1,813 +0,0 @@
<script lang="ts" setup>
import { requestClient } from '#/api/request';
import SelectTree from '#/components/tree/ViewTree.vue';
import avatar from './avatar.png';
const emits = defineEmits(['close']);
let p_tab_key = 'k1';
let p_select_mode = 1; // 1单选,2多选
let p_opener = null as any; // 弹框打开者标记
let p_dept_init_flag = false; // 层级架构页签初始化标记
let p_role_init_flag = false; // 审批角色页签初始化标记
let p_group_init_flag = false; // 常用群组页签初始化标记
let p_coop_init_flag = false; // 外部协同页签初始化标记
const deptTreeRef = ref();
const roleTreeRef = ref();
const groupTreeRef = ref();
const coopTreeRef = ref();
const state = reactive({
isShow: false,
p_org_type: -1, // 0为综合,1为机构,2为部门,4为岗位,8为用户,16为常用群组,32为角色线
p_coop_type: -1, // 0为综合,1为协调分类,2为协调公司,4为协同部门
receSearch: '' as string,
receItems: [] as any,
tierItems: [] as any,
seldItems: [] as any,
roleItems: [] as any,
groupItems: [] as any,
coopItems: [] as any,
});
const { receItems, tierItems, seldItems, roleItems, groupItems, coopItems } = toRefs(state);
const activeName = ref('k1');
// region z Tab切换
async function tabChange(tab: any) {
p_tab_key = tab.paneName;
switch (p_tab_key) {
case 'k1': {
for (const rItem of receItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
break;
}
case 'k2': {
if (!p_dept_init_flag) {
await deptTreeRef.value.init();
p_dept_init_flag = true;
}
for (const tItem of tierItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === tItem.id) {
tItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
tItem.checked = false;
}
}
break;
}
case 'k3': {
if (!p_group_init_flag) {
await groupTreeRef.value.init();
p_group_init_flag = true;
}
for (const gItem of groupItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === gItem.id) {
gItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
gItem.checked = false;
}
}
break;
}
case 'k4': {
if (!p_role_init_flag) {
await roleTreeRef.value.init();
p_role_init_flag = true;
}
for (const rItem of roleItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
break;
}
case 'k5': {
if (!p_coop_init_flag) {
await coopTreeRef.value.init();
p_coop_init_flag = true;
}
for (const rItem of coopItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id == rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
break;
}
// No default
}
}
// endregion
// region x.1 最近使用
async function onSearch() {
receItems.value = await requestClient.get(`/pub/org/main?type=${state.p_org_type}&name=${state.receSearch}`);
for (const rItem of receItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
}
if (!flag) {
rItem.checked = false;
}
}
}
const receInit = async () => {
receItems.value = await requestClient.get(`/gen/org/rece?type=${state.p_org_type}`);
};
function receItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < receItems.value.length; i++) {
if (receItems.value[i].id !== item.id) {
receItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.2 层级架构
async function nodeClick(node: any) {
if (node && node.id) {
//tierItems.value = await requestClient.get(`/system/user/list?type=${state.p_org_type}&depid=${node.id}`);
tierItems.value = await requestClient.get(`/pub/org/main?type=${state.p_org_type}&depid=${node.id}`);
for (const tItem of tierItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === tItem.id) {
tItem.checked = true;
break;
}
}
}
}
}
function tierItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < tierItems.value.length; i++) {
if (tierItems.value[i].id !== item.id) {
tierItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.3 常用群组
async function groupNodeClick(node: any) {
if (node && node.id) {
groupItems.value = await requestClient.get(`/gen/org/group/list?pid=${node.id}&type=${node.type}`);
for (const gItem of groupItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === gItem.id) {
gItem.checked = true;
break;
}
}
}
}
}
function groupItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < groupItems.value.length; i++) {
if (groupItems.value[i].id !== item.id) {
groupItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.4 审批角色
async function roleNodeClick(node: any) {
if (node && node.id) {
roleItems.value = await requestClient.get(`/pub/org/role/list?treid=${node.id}`);
for (const rItem of roleItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
break;
}
}
}
}
}
function roleItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < roleItems.value.length; i++) {
if (roleItems.value[i].id !== item.id) {
roleItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.5 外部协同
async function coopNodeClick(node: any) {
if (node) {
coopItems.value = await requestClient.get(`/gen/coop/list?pid=${node.id}&type=${state.p_coop_type}`);
for (const rItem of coopItems.value) {
for (const sItem of seldItems.value) {
if (sItem.id === rItem.id) {
rItem.checked = true;
break;
}
}
}
}
}
function coopItemClick(item: any) {
item.checked = !item.checked;
if (p_select_mode === 1) {
// 单选
if (seldItems.value.length > 0) {
seldItems.value.splice(0, 1);
}
seldItems.value.push(item);
for (let i = 0; i < coopItems.value.length; i++) {
if (coopItems.value[i].id !== item.id) {
coopItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
} else {
// 多选
if (item.checked) {
let flag = false;
for (const sItem of seldItems.value) {
if (sItem.id === item.id) {
flag = true;
break;
}
}
if (!flag) {
seldItems.value.push(item);
}
} else {
for (let i = 0; i < seldItems.value.length; i++) {
if (seldItems.value[i].id === item.id) {
seldItems.value.splice(i, 1);
break;
}
}
}
}
}
// endregion
// region x.6 我的收藏
// endregion
// region c.1 已选逻辑
function selectedItemClick(item: any) {
if (p_tab_key === 'k1') {
for (let i = 0; i < receItems.value.length; i++) {
if (receItems.value[i].id === item.id) {
receItems.value[i].checked = false;
break;
}
}
} else if (p_tab_key === 'k2') {
for (let i = 0; i < tierItems.value.length; i++) {
if (tierItems.value[i].id === item.id) {
tierItems.value[i].checked = false;
break;
}
}
}
for (let j = 0; j < seldItems.value.length; j++) {
if (seldItems.value[j].id === item.id) {
seldItems.value.splice(j, 1);
break;
}
}
}
// endregion
// region 与父组件的交互逻辑
const open = async (data: any) => {
if (!data.orgType) {
data.orgType = 8;
}
if (!data.selectMode) {
data.selectMode = 1;
}
if (state.p_org_type !== data.orgType) {
state.p_org_type = data.orgType;
//await receInit();
tierItems.value.splice(0);
}
if (data.coopType && state.p_coop_type !== data.coopType) {
state.p_coop_type = data.coopType;
}
p_select_mode = data.selectMode;
p_opener = data.opener;
// 1.初始化
seldItems.value = data.orgs ? data.orgs : [];
// //2.设置最近使用与层级架构里item的check状态
if (p_tab_key === 'k1') {
for (const rItem of receItems.value) {
for (const sItem of seldItems.value) {
let flag = false;
if (sItem.id === rItem.id) {
rItem.checked = true;
flag = true;
break;
}
if (!flag) {
rItem.checked = false;
}
}
}
} else if (p_tab_key === 'k2') {
for (const tItem of tierItems.value) {
for (const sItem of seldItems.value) {
let flag = false;
if (sItem.id === tItem.id) {
tItem.checked = true;
flag = true;
break;
}
if (!flag) {
tItem.checked = false;
}
}
}
}
state.isShow = true;
};
defineExpose({ open });
const closeModal = async () => {
const rawSeldItems = toRaw(seldItems.value);
if (rawSeldItems && rawSeldItems.length > 0) {
// 更新后台数据库最近使用的ORGS
//await requestClient.post('/gen/org/rece', rawSeldItems);
}
emits('close', { opener: p_opener, orgs: toRaw(rawSeldItems) });
state.isShow = false;
};
const clearAndcloseModal = () => {
emits('close', { opener: p_opener, orgs: null });
state.isShow = false;
};
// endregion
</script>
<template>
<el-dialog v-model="state.isShow" title="组织架构选择" width="1000px" draggable>
<div style="height: 440px">
<el-row>
<el-col :span="16">
<el-tabs v-model="activeName" type="card" @tab-click="tabChange">
<el-tab-pane label="快捷选择" name="k1">
<div>
<el-input v-model="state.receSearch" placeholder="请输入关键字查询" style="width: 200px" @keyup.enter="onSearch" />
<el-button type="primary" style="margin-left: 10px" @click="onSearch">查询 </el-button>
</div>
<div style="margin-top: 5px; overflow: auto; height: 353px; border: 1px solid #ccc">
<ul class="z-org-search" id="zOrgSearch" style="padding: 2px">
<li v-for="item in receItems" :key="item.id" class="f-user" @click="receItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
</li>
</ul>
</div>
</el-tab-pane>
<el-tab-pane label="层级架构" name="k2">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/system/user/deptTree" @node-click="nodeClick" :ma-init="true" ref="deptTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in tierItems" :key="item.id" class="f-user" title=" " @click="tierItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="常用群组" name="k3" v-if="(state.p_org_type & 16) !== 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/gen/org/group/tree" @node-click="groupNodeClick" :ma-init="true" ref="groupTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in groupItems" :key="item.id" class="f-user" title=" " @click="groupItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="审批角色" name="k4" v-if="(state.p_org_type & 32) !== 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/gen/org/role/tree" @node-click="roleNodeClick" :ma-init="true" ref="roleTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in roleItems" :key="item.id" class="f-user" title=" " @click="roleItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="外部协同" name="k5" v-if="state.p_coop_type >= 0">
<el-row>
<el-col :span="12">
<div style="height: 390px">
<SelectTree url="/gen/coop/tree?type=user" @node-click="coopNodeClick" :ma-init="true" ref="coopTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<li v-for="item in coopItems" :key="item.id" class="f-user" title=" " @click="coopItemClick(item)">
<el-checkbox v-model="item.checked" />
<img :src="avatar" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="我的收藏" name="k9">这个也暂不支持,待开发</el-tab-pane>
</el-tabs>
</el-col>
<el-col :span="8">
<div style="margin-left: 5px">
<div style="height: 36px">
<div style="margin-top: 20px">已 选</div>
</div>
<div style="border: 1px solid #ccc; height: 390px; overflow: auto">
<ul class="z-org-selected" style="position: relative">
<li v-for="item in seldItems" :key="item.id" class="f-user" style="overflow: hidden">
<el-icon @click="selectedItemClick(item)">
<CircleClose />
</el-icon>
<img :src="avatar" />
<span class="layui-elip f-user-name2">{{ item.name }}</span>
</li>
</ul>
</div>
</div>
</el-col>
</el-row>
</div>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="closeModal">确认</el-button>
<el-button @click="state.isShow = false">取消</el-button>
<el-button @click="clearAndcloseModal" style="margin-left: 20px">清空选择</el-button>
</span>
</template>
</el-dialog>
</template>
<style scoped>
.dialog-footer button:first-child {
margin-right: 10px;
}
.layui-elip {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.f-user:before,
.f-user:after {
content: ' ';
display: table;
}
.f-user:after {
clear: both;
}
.f-user input,
.f-user label {
float: left;
margin-top: 10px;
margin-right: 8px;
}
.f-user img {
width: 50px;
height: 50px;
float: left;
border-radius: 100%;
margin-right: 8px;
}
.f-user .f-user-name,
.f-user .f-user-dept {
display: block;
}
.f-user .f-user-name {
margin-top: 6px;
}
.f-user .f-user-dept {
color: #a599b2;
}
/*最近*/
/*.z-org-recently li {*/
/* width: 33%;*/
/* float: left;*/
/* cursor: pointer;*/
/* padding: 5px;*/
/* list-style-type: none;*/
/*}*/
/*.z-org-recently li:hover {*/
/* background-color: #f7efec;*/
/*}*/
/*搜索查询*/
.z-org-search li {
/*width: 280px;*/
width: 50%;
float: left;
cursor: pointer;
padding: 2px;
list-style-type: none;
/*margin: 3px;*/
}
.z-org-search li:hover {
background-color: #f7efec;
}
.dark .z-org-search li:hover {
background-color: #1f1f1f;
}
/*!*组织架构树*!*/
.z-org-tree li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-tree li:hover {
background-color: #f7efec;
}
.dark .z-org-tree li:hover {
background-color: #1f1f1f;
}
/*已选的*/
.z-org-selected li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-selected li:hover {
background-color: #f7efec;
}
.dark .z-org-selected li:hover {
background-color: #1f1f1f;
}
.z-org-selected .f-user .el-icon {
/*float: left;*/
/*position:relative;*/
position: absolute;
/*position:fixed;*/
color: #f26b96;
font-size: 20px;
display: none;
margin-left: 42px;
}
.z-org-selected li:hover .el-icon {
display: inline;
}
.z-org-selected .f-user img {
display: inline;
/*float: none;*/
}
.z-org-selected .f-user-name2 {
display: block;
margin-top: 14px;
}
</style>
@@ -27,7 +27,7 @@ const open = async (url: string) => {
// eslint-disable-next-line unicorn/prefer-string-slice
state.uploadUrl = url.startsWith('/') ? `${import.meta.env.VITE_GLOB_API_URL}${url.substring(1, url.length - 1)}` : `${import.meta.env.VITE_GLOB_API_URL}${url}`;
} else {
state.uploadUrl = `${import.meta.env.VITE_GLOB_API_URL}/tool/oss/main/upload`;
state.uploadUrl = `${import.meta.env.VITE_GLOB_API_URL}/tool/oss/upload`;
}
dialogVisible.value = true;
};
@@ -5,7 +5,7 @@
"user": "用户管理",
"role": "角色管理",
"menu": "菜单管理",
"dept": "部门管理",
"dept": "组织管理",
"post": "岗位管理",
"dict": "字典管理",
"config": "参数设置",
-1
View File
@@ -12,7 +12,6 @@ export const overridesPreferences = defineOverridesPreferences({
* 不要动这里 后端路由模式
*/
// accessMode: 'frontend',
// defaultHomePath: '/bpm/bus/main',
accessMode: 'backend',
/**
* 不需要refresh token 由后端处理
+13 -13
View File
@@ -74,7 +74,7 @@ function backMenuToVbenMenu(
// 需要处理根目录为内嵌的情况 不会带InnerLink
if (/^https?:\/\//.test(menu.children[0].path)) {
menu.children[0].component = 'InnerLink';
menu.children[0].comp = 'InnerLink';
menu.children[0].path = menu.children[0].path
.replaceAll(/^https?:\/\//g, '')
.replaceAll('/#/', '')
@@ -88,7 +88,7 @@ function backMenuToVbenMenu(
menu.meta = menu.children[0].meta;
// 由于在一级路由 父级路径需要加上/
menu.path = `/${path}`;
menu.component = 'RootMenu';
menu.comp = 'RootMenu';
// 将子路径设置为''
menu.children[0].path = '';
}
@@ -97,14 +97,14 @@ function backMenuToVbenMenu(
// 正则判断是否为http://或者https://开头
if (
/^https?:\/\//.test(menu.path) &&
(menu.component === 'Layout' || menu.component === 'ParentView')
(menu.comp === 'Layout' || menu.comp === 'ParentView')
) {
menu.component = 'Link';
menu.comp = 'Link';
}
// 内嵌iframe 组件为InnerLink
if (menu.meta?.link && menu.component === 'InnerLink') {
menu.component = 'IFrameView';
if (menu.meta?.link && menu.comp === 'InnerLink') {
menu.comp = 'IFrameView';
}
/**
@@ -117,13 +117,13 @@ function backMenuToVbenMenu(
// 创建vben路由对象
const vbenRoute: RouteRecordStringComponent = {
component: menu.component,
component: menu.comp,
meta: {
// 当前路由不在菜单显示 但是可以通过链接访问
// 不可访问的路由由后端控制隐藏(不返回对应路由)
hideInMenu: menu.hidden,
hideInMenu: !menu.shtag,
icon: menu.meta?.icon,
keepAlive: !menu.meta?.noCache,
keepAlive: menu.meta?.catag,
title: menu.meta?.title,
},
name: menu.name,
@@ -142,9 +142,9 @@ function backMenuToVbenMenu(
}
// 添加路由参数信息
if (menu.query) {
if (menu.param) {
try {
const query = JSON.parse(menu.query);
const query = JSON.parse(menu.param);
vbenRoute.meta && (vbenRoute.meta.query = query);
} catch {
console.error('错误的路由参数类型, 必须为[json]格式');
@@ -154,7 +154,7 @@ function backMenuToVbenMenu(
/**
* 处理不同组件
*/
switch (menu.component) {
switch (menu.comp) {
/**
* iframe内嵌
*/
@@ -213,7 +213,7 @@ function backMenuToVbenMenu(
* 其他自定义组件 如system/user/index 拼接/
*/
default: {
vbenRoute.component = `/${menu.component}`;
vbenRoute.component = `/${menu.comp}`;
break;
}
}
+22 -22
View File
@@ -12,20 +12,12 @@ const routes: RouteRecordRaw[] = [
path: '/sys',
children: [
{
name: 'SysCorp',
path: '/sys/corp',
component: () => import('#/views/sys/corp/index.vue'),
meta: {
title: '公司管理',
},
},
{
name: 'SysDept',
path: '/sys/dept',
component: () => import('#/views/sys/dept/index.vue'),
name: 'SysOrg',
path: '/sys/org',
component: () => import('#/views/sys/org/index.vue'),
meta: {
// affixTab: true,
title: '部门管理',
title: '组织管理',
},
},
{
@@ -126,6 +118,14 @@ const routes: RouteRecordRaw[] = [
title: '通知公告',
},
},
{
name: 'SysTenant',
path: '/sys/tenant',
component: () => import('#/views/sys/tenant/index.vue'),
meta: {
title: '租户管理',
},
},
],
},
{
@@ -137,24 +137,24 @@ const routes: RouteRecordRaw[] = [
path: '/mon',
children: [
{
name: 'MonOnlineUser',
path: '/mon/online/user',
name: 'MonOnline',
path: '/mon/online',
component: () => import('#/views/mon/online/user/index.vue'),
meta: {
title: '在线用户',
},
},
{
name: 'MonLoginLog',
path: '/mon/login/log',
name: 'MonLogin',
path: '/mon/login',
component: () => import('#/views/mon/login/log/index.vue'),
meta: {
title: '登录日志',
},
},
{
name: 'MonOperLog',
path: '/mon/oper/log',
name: 'MonOper',
path: '/mon/oper',
component: () => import('#/views/mon/oper/log/index.vue'),
meta: {
title: '操作日志',
@@ -177,16 +177,16 @@ const routes: RouteRecordRaw[] = [
},
},
{
name: 'MonJobMain',
path: '/mon/job/main',
name: 'MonJob',
path: '/mon/job',
component: () => import('#/views/mon/job/main/index.vue'),
meta: {
title: '定时任务',
},
},
{
name: 'MonJobLog',
path: '/mon/job/log',
name: 'MonJobl',
path: '/mon/jobl',
component: () => import('#/views/mon/job/log/index.vue'),
meta: {
title: '任务日志',
+25 -25
View File
@@ -11,34 +11,34 @@ const routes: RouteRecordRaw[] = [
children: [
{
name: 'BpmBusCate',
path: '/bpm/bus/cate',
path: '/bpm/busc',
component: () => import('#/views/bpm/bus/cate/index.vue'),
meta: {
title: '流程分类',
},
},
{
name: 'BpmBusTmpl',
path: '/bpm/bus/tmpl',
name: 'BpmBust',
path: '/bpm/bust',
component: () => import('#/views/bpm/bus/tmpl/index.vue'),
meta: {
title: '流程模板',
},
},
{
name: 'BpmBusTmplEdit',
path: '/bpm/bus/tmpl/edit',
name: 'BpmBustEdit',
path: '/bpm/bust/edit',
component: () => import('#/views/bpm/bus/tmpl/edit.vue'),
meta: {
title: '流程模板编辑',
hideInMenu: true,
keepAlive: true,
activePath: '/bpm/bus/tmpl',
activePath: '/bpm/bust',
},
},
{
name: 'BpmBusMain',
path: '/bpm/bus/main',
name: 'BpmBus',
path: '/bpm/bus',
component: () => import('#/views/bpm/bus/main/index.vue'),
meta: {
title: '流程清单',
@@ -46,25 +46,25 @@ const routes: RouteRecordRaw[] = [
},
},
{
name: 'BpmBusMainEdit',
path: '/bpm/bus/main/edit',
name: 'BpmBusEdit',
path: '/bpm/bus/edit',
component: () => import('#/views/bpm/bus/main/edit.vue'),
meta: {
title: '流程编辑',
hideInMenu: true,
keepAlive: true,
activePath: '/bpm/bus/main',
activePath: '/bpm/bus',
},
},
{
name: 'BpmBusMainView',
path: '/bpm/bus/main/view',
name: 'BpmBusView',
path: '/bpm/bus/view',
component: () => import('#/views/bpm/bus/main/view.vue'),
meta: {
title: '流程查看',
hideInMenu: true,
keepAlive: true,
activePath: '/bpm/bus/main',
activePath: '/bpm/bus',
},
},
{
@@ -76,27 +76,27 @@ const routes: RouteRecordRaw[] = [
},
},
{
name: 'BpmOrgTree',
path: '/bpm/org/tree',
component: () => import('#/views/bpm/org/tree/index.vue'),
name: 'BpmRoleTree',
path: '/bpm/role',
component: () => import('#/views/bpm/role/tree/index.vue'),
meta: {
title: '流程组织',
title: '流程角色',
},
},
{
name: 'BpmOrgNode',
path: '/bpm/org/node',
component: () => import('#/views/bpm/org/node/index.vue'),
name: 'BpmRoleNode',
path: '/bpm/role/node',
component: () => import('#/views/bpm/role/node/index.vue'),
meta: {
title: '组织节点',
title: '流程角色节点',
hideInMenu: true,
keepAlive: true,
activePath: '/bpm/org/node',
activePath: '/bpm/role/node',
},
},
{
name: 'BpmOrgTree2',
path: '/bpm/org/tree2',
name: 'BpmRoleTree2',
path: '/bpm/role/tree2',
component: () => import('#/views/bpm/todo/index2.vue'),
meta: {
title: '待办测试',
+18 -2
View File
@@ -10,8 +10,8 @@ const routes: RouteRecordRaw[] = [
path: '/demo',
children: [
{
name: 'DemoSingleMain',
path: '/demo/single/main',
name: 'DemoSingle',
path: '/demo/single',
component: () => import('#/views/demo/single/main/index.vue'),
meta: {
title: '单一主表案例',
@@ -33,6 +33,22 @@ const routes: RouteRecordRaw[] = [
title: '关联主分子案例',
},
},
{
name: 'DemoPerm1',
path: '/demo/perm1',
component: () => import('#/views/demo/perm/way1/index.vue'),
meta: {
title: '数据权限案例1',
},
},
{
name: 'DemoPerm2',
path: '/demo/perm2',
component: () => import('#/views/demo/perm/way2/index.vue'),
meta: {
title: '数据权限案例2',
},
},
{
name: 'DemoGiteeVote',
path: '/demo/gitee/vote',
+7 -5
View File
@@ -120,17 +120,19 @@ export const useAuthStore = defineStore('auth', () => {
if (!backUserInfo) {
throw new Error('获取用户信息失败.');
}
const { permissions = [], roles = [], user } = backUserInfo;
const { perms = [], roles = [], user } = backUserInfo;
/**
* 从后台user -> vben user转换
*/
const userInfo: UserInfo = {
avatar: user.avatar ?? '',
permissions,
realName: user.nickName,
permissions: perms,
realName: user.nicna,
roles,
userId: user.userId,
username: user.userName,
userId: user.useid,
username: user.usena,
orgid: user.orgid,
orgna: user.orgna,
email: user.email ?? '',
};
userStore.setUserInfo(userInfo);
+1 -1
View File
@@ -15,7 +15,7 @@ export const useDict = (...args: string[]): { [key: string]: DictDataOption[] }
if (dicts) {
res.value[dictType] = dicts;
} else {
const backData = await requestClient.get(`/tool/dict/main/data?code=${dictType}`);
const backData = await requestClient.get(`/tool/dict/data?code=${dictType}`);
res.value[dictType] = backData.map((p: any): DictDataOption => ({ label: p.label, value: p.value, elTagType: p.shsty, elTagClass: p.shsty }));
console.log(res.value[dictType]);
useDictStore().setDict(dictType, res.value[dictType]);
@@ -44,7 +44,7 @@ const submit = () => {
userRef.value?.validate(async (valid: boolean) => {
if (valid) {
// await userProfileUpdate(state.form);
await requestClient.putWithMsg<void>('/system/user/profile', state.form);
await requestClient.putWithMsg<void>('/pub/profile', state.form);
}
});
};
@@ -9,7 +9,7 @@ async function handleForceOffline(row: any) {
cancelButtonText: '取消',
})
.then(async () => {
await requestClient.deleteWithMsg<void>(`/mon/online/user/kick/${row.tokenId}`);
await requestClient.deleteWithMsg<void>(`/mon/online/kick/${row.tokenId}`);
await listQuery();
})
.catch(() => {});
@@ -25,7 +25,7 @@ onMounted(async () => {
const listQuery = async () => {
// const res = await onlineDeviceList();
state.list = await requestClient.get('/mon/online/user/list');
state.list = await requestClient.get('/mon/online/list');
// state.list = res.rows;
};
</script>
@@ -45,8 +45,8 @@ const poetrySrc = computed(() => {
<el-descriptions-item label="账号:">{{ profile.user.userName }}</el-descriptions-item>
<el-descriptions-item label="手机号码:">{{ profile.user.phonenumber || '未绑定手机号' }} </el-descriptions-item>
<el-descriptions-item label="邮箱:">{{ profile.user.email || '未绑定邮箱' }} </el-descriptions-item>
<el-descriptions-item label="部门:">
<el-tag style="margin-right: 10px">{{ profile.user.deptName ?? '未分配部门' }}</el-tag>
<el-descriptions-item label="组织:">
<el-tag style="margin-right: 10px">{{ profile.user.orgna ?? '未分配组织' }}</el-tag>
<el-tag v-if="profile.postGroup">{{ profile.postGroup }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="上次登录:"> {{ profile.user.loginDate }} </el-descriptions-item>
+1 -1
View File
@@ -6,7 +6,7 @@ const emits = defineEmits(['close']);
const formRef = ref();
const state = reactive({
url: '/bpm/bus/cate',
url: '/bpm/busc',
show: false,
form: {} as any,
});
@@ -6,7 +6,7 @@ import { treeItemDelete, treeQuery } from '#/utils/page/tree';
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/bpm/bus/cate',
url: '/bpm/busc',
list: [] as any,
form: { name: '' } as any,
});
+2 -2
View File
@@ -23,7 +23,7 @@ const formComp = shallowRef(null as any);
// const ComponentA = () => import('./ComponentA.vue');
const state = reactive({
url: '/bpm/bus/main',
url: '/bpm/bus',
form: { prxml: '' } as any,
});
@@ -39,7 +39,7 @@ onMounted(async () => {
state.form.tmpid = useRoute().query?.tmpid;
state.form.tmpna = useRoute().query?.tmpna;
}
tmplData.value = await requestClient.get(`bpm/bus/tmpl/info/${state.form.tmpid}`);
tmplData.value = await requestClient.get(`bpm/bust/info/${state.form.tmpid}`);
rule.value = JSON.parse(tmplData.value.frule);
state.form.prdid = tmplData.value.prdid;
if (tmplData.value.ftype === 1) {
@@ -8,7 +8,7 @@ import TmplModal from '#/views/bpm/bus/tmpl/select.vue';
import { emitter } from './mitt';
const state = reactive({
url: '/bpm/bus/main',
url: '/bpm/bus',
loading: false,
ids: [],
form: {
@@ -88,7 +88,7 @@ const closeFlowTmplModal = (item: any) => {
<Page auto-content-height>
<div class="flex h-full gap-[8px]">
<div class="w-[260px]">
<CateTree @node-click="nodeClick" url="/bpm/bus/tmpl/tree" tip="模板名称" />
<CateTree @node-click="nodeClick" url="/bpm/bust/tree" tip="模板名称" />
</div>
<el-card style="height: 100%" body-style="height: 100%" class="box-card flex-1 overflow-hidden">
<template #header>
+2 -2
View File
@@ -20,7 +20,7 @@ const formComp = shallowRef(null as any);
const formRef = ref();
const state = reactive({
url: '/bpm/bus/main',
url: '/bpm/bus',
form: {} as any,
});
@@ -33,7 +33,7 @@ console.log("modules2", modules);
onMounted(async () => {
const id = useRoute().query?.id;
state.form = await requestClient.get(`${state.url}/info/${id}`);
tmplData.value = await requestClient.get(`bpm/bus/tmpl/info/${state.form.tmpid}`);
tmplData.value = await requestClient.get(`bpm/bust/info/${state.form.tmpid}`);
rule.value = JSON.parse(tmplData.value.frule);
console.log(state.form);
initTag.value = true;
+15 -15
View File
@@ -7,7 +7,7 @@ import { useTabs } from '@vben/hooks';
import FcDesigner from '@form-create/designer';
import { requestClient } from '#/api/request';
import OrgModal from '#/components/sys/OrgModal.vue';
import ActorModal from '#/components/sys/ActorModal.vue';
import WfDefEdit from '#/components/bpm/def/dedit.vue';
import { tabSave } from '#/utils/page/edit';
@@ -16,7 +16,7 @@ import { emitter } from './mitt';
const formRef = ref();
const state = reactive({
url: '/bpm/bus/tmpl',
url: '/bpm/bust',
form: { prxml: '' } as any,
});
@@ -31,7 +31,7 @@ onMounted(async () => {
state.form.catid = catid;
}
}
cateOptions.value = await requestClient.get('/bpm/bus/cate/tree');
cateOptions.value = await requestClient.get('/bpm/busc/tree');
wfShowTag.value = true;
formRef?.value?.clearValidate();
if (id) {
@@ -67,33 +67,33 @@ const cateOptions = ref([]);
const wfShowTag = ref(false);
const wfDefEditRef = ref();
// region -----组织架构逻辑-----
const orgModal = ref();
// region -----成员逻辑-----
const actorModal = ref();
const cdata = reactive({}) as any;
const openUsmenModal = () => {
orgModal.value.open({
actorModal.value.open({
opener: 'usmen',
orgType: 15,
actorType: 15,
selectMode: 2,
orgs: toRaw(form.value.usmen),
actors: toRaw(form.value.usmen),
});
};
const openDvmenModal = () => {
orgModal.value.open({
actorModal.value.open({
opener: 'dvmen',
orgType: 15,
actorType: 15,
selectMode: 2,
orgs: toRaw(form.value.dvmen),
actors: toRaw(form.value.dvmen),
});
};
const closeOrgModal = (data: any) => {
const closeActorModal = (data: any) => {
if (data.opener === 'usmen') {
form.value.usmen = data.orgs && data.orgs.length > 0 ? data.orgs : null;
form.value.usmen = data.actors && data.actors.length > 0 ? data.actors : null;
} else if (data.opener === 'dvmen') {
form.value.dvmen = data.orgs && data.orgs.length > 0 ? data.orgs : null;
form.value.dvmen = data.actors && data.actors.length > 0 ? data.actors : null;
}
};
@@ -184,6 +184,6 @@ const config = {
</el-form>
</div>
</el-card>
<OrgModal ref="orgModal" @close="closeOrgModal" />
<ActorModal ref="actorModal" @close="closeActorModal" />
</Page>
</template>
@@ -7,7 +7,7 @@ import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/
import { emitter } from './mitt';
const state = reactive({
url: '/bpm/bus/tmpl',
url: '/bpm/bust',
loading: false,
ids: [],
form: {
@@ -64,7 +64,7 @@ function handleEdit(row: any) {
<Page auto-content-height>
<div class="flex h-full gap-[8px]">
<div class="w-[260px]">
<CateTree @node-click="nodeClick" url="/bpm/bus/cate/tree" />
<CateTree @node-click="nodeClick" url="/bpm/busc/tree" />
</div>
<el-card style="height: 100%" body-style="height: 100%" class="box-card flex-1 overflow-hidden">
<template #header>
+13 -14
View File
@@ -19,11 +19,11 @@ const activeName = ref('k1');
// region x.1 最近使用
async function onSearch() {
receItems.value = await requestClient.get(`/gen/org/main?name=${state.receSearch}`);
receItems.value = await requestClient.get(`/gen/actor/main?name=${state.receSearch}`);
}
const receInit = async () => {
const res = await requestClient.get(`/bpm/bus/tmpl/list`);
const res = await requestClient.get(`/bpm/bust/list`);
receItems.value = res.rows;
};
@@ -38,7 +38,7 @@ function receItemClick(item: any) {
async function nodeClick(node: any) {
if (node && node.id) {
tierItems.value = await requestClient.get(`/bpm/bus/tmpl/list?catid=${node.id}`);
tierItems.value = await requestClient.get(`/bpm/bust/list?catid=${node.id}`);
}
}
@@ -55,7 +55,7 @@ function tierItemClick(item: any) {
// region 与父组件的交互逻辑
const openModal = async (data: any) => {
state.show = true;
tierItems.value = await requestClient.get(`/bpm/bus/tmpl/list`);
tierItems.value = await requestClient.get(`/bpm/bust/list`);
};
defineExpose({ openModal });
@@ -86,12 +86,12 @@ onMounted(async () => {
<el-row>
<el-col :span="12">
<div style="height: 390px">
<CateTree @node-click="nodeClick" url="/bpm/bus/cate/tree" />
<CateTree @node-click="nodeClick" url="/bpm/busc/tree" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<ul class="z-actor-tree">
<li v-for="item in tierItems" :key="item.id" title=" " @click="tierItemClick(item)" style="display: flex">
<el-checkbox v-model="item.checked" />
<el-text truncated style="margin-left: 5px">{{ item.name }}</el-text>
@@ -107,7 +107,7 @@ onMounted(async () => {
<el-button type="primary" style="margin-left: 10px" @click="onSearch">查询</el-button>
</div>
<div style="margin-top: 5px; overflow: auto; height: 353px; border: 1px solid #ccc">
<ul class="z-org-search" id="zOrgSearch" style="padding: 2px">
<ul class="z-actor-search" id="zActorSearch" style="padding: 2px">
<li v-for="item in receItems" :key="item.id" title=" " @click="receItemClick(item)" style="display: flex">
<el-checkbox v-model="item.checked" />
<el-text truncated style="margin-left: 5px">{{ item.name }}</el-text>
@@ -134,7 +134,7 @@ onMounted(async () => {
}
/*搜索查询*/
.z-org-search li {
.z-actor-search li {
/*width: 280px;*/
width: 50%;
float: left;
@@ -144,27 +144,26 @@ onMounted(async () => {
/*margin: 3px;*/
}
.z-org-search li:hover {
.z-actor-search li:hover {
background-color: #f7efec;
}
.dark .z-org-search li:hover {
.dark .z-actor-search li:hover {
background-color: #1f1f1f;
}
/*!*组织架构树*!*/
.z-org-tree li {
.z-actor-tree li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-tree li:hover {
.z-actor-tree li:hover {
background-color: #f7efec;
}
.dark .z-org-tree li:hover {
.dark .z-actor-tree li:hover {
background-color: #1f1f1f;
}
</style>
+32 -33
View File
@@ -71,7 +71,7 @@ async function tabChange(tab: any) {
// region x.1 最近使用
async function onSearch() {
receItems.value = await requestClient.get(`/gen/org/main?name=${state.receSearch}`);
receItems.value = await requestClient.get(`/gen/actor/main?name=${state.receSearch}`);
for (const rItem of receItems.value) {
let flag = false;
for (const sItem of seldItems.value) {
@@ -88,7 +88,7 @@ async function onSearch() {
}
const receInit = async () => {
receItems.value = await requestClient.get(`/gen/org/rece`);
receItems.value = await requestClient.get(`/gen/actor/rece`);
};
function receItemClick(item: any) {
@@ -104,7 +104,7 @@ function receItemClick(item: any) {
receItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -135,7 +135,7 @@ function receItemClick(item: any) {
async function nodeClick(node: any) {
if (node && node.id) {
const res = await requestClient.get(`/bpm/bus/tmpl/list?cateId=${node.id}`);
const res = await requestClient.get(`/bpm/bust/list?cateId=${node.id}`);
tierItems.value = res.rows;
for (const tItem of tierItems.value) {
for (const sItem of seldItems.value) {
@@ -161,7 +161,7 @@ function tierItemClick(item: any) {
tierItems.value[i].checked = false;
}
}
// closeOrgModal();改成不自动关
// closeActorModal();改成不自动关
} else {
// 多选
if (item.checked) {
@@ -227,7 +227,7 @@ const openModal = async (data: any) => {
p_select_mode = data.selectMode;
p_opener = data.opener;
// 1.初始化
seldItems.value = data.orgs ? data.orgs : [];
seldItems.value = data.actors ? data.actors : [];
// //2.设置最近使用与层级架构里item的check状态
if (p_tab_key === 'k1') {
for (const rItem of receItems.value) {
@@ -266,15 +266,15 @@ defineExpose({ openModal });
const closeModal = async () => {
const rawSeldItems = toRaw(seldItems.value);
if (rawSeldItems && rawSeldItems.length > 0) {
// 更新后台数据库最近使用的ORGS
await requestClient.post('/gen/org/rece', rawSeldItems);
// 更新后台数据库最近使用的ACTORS
await requestClient.post('/gen/actor/rece', rawSeldItems);
}
emits('close', { opener: p_opener, orgs: toRaw(rawSeldItems) });
emits('close', { opener: p_opener, actors: toRaw(rawSeldItems) });
state.show = false;
};
const clearAndcloseModal = () => {
emits('close', { opener: p_opener, orgs: null });
emits('close', { opener: p_opener, actors: null });
state.show = false;
};
// endregion
@@ -292,11 +292,11 @@ const clearAndcloseModal = () => {
<el-button type="primary" style="margin-left: 10px" @click="onSearch">查询 </el-button>
</div>
<div style="margin-top: 5px; overflow: auto; height: 353px; border: 1px solid #ccc">
<ul class="z-org-search" id="zOrgSearch" style="padding: 2px">
<ul class="z-actor-search" id="zActorSearch" style="padding: 2px">
<li v-for="item in receItems" :key="item.id" class="f-user" @click="receItemClick(item)">
<el-checkbox v-model="item.checked" />
<span class="layui-elip f-user-name">{{ item.name }}</span>
<span class="layui-elip f-user-dept">{{ item.dept }}</span>
<span class="layui-elip f-user-org">{{ item.org }}</span>
</li>
</ul>
</div>
@@ -305,12 +305,12 @@ const clearAndcloseModal = () => {
<el-row>
<el-col :span="12">
<div style="height: 390px">
<CateTree @node-click="nodeClick" url="/bpm/bus/cate" ref="cateTreeRef" />
<CateTree @node-click="nodeClick" url="/bpm/busc" ref="cateTreeRef" />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; height: 390px; margin-left: 5px; overflow: auto">
<ul class="z-org-tree">
<ul class="z-actor-tree">
<li v-for="item in tierItems" :key="item.id" class="f-user" title=" " @click="tierItemClick(item)">
<el-checkbox v-model="item.checked" />
<span>{{ item.name }}</span>
@@ -329,7 +329,7 @@ const clearAndcloseModal = () => {
<div style="margin-top: 20px">已 选</div>
</div>
<div style="border: 1px solid #ccc; height: 390px; overflow: auto">
<ul class="z-org-selected" style="position: relative">
<ul class="z-actor-selected" style="position: relative">
<li v-for="item in seldItems" :key="item.id" class="f-user" style="overflow: hidden">
<el-icon @click="selectedItemClick(item)">
<CircleClose />
@@ -389,7 +389,7 @@ const clearAndcloseModal = () => {
}
.f-user .f-user-name,
.f-user .f-user-dept {
.f-user .f-user-org {
display: block;
}
@@ -397,12 +397,12 @@ const clearAndcloseModal = () => {
margin-top: 6px;
}
.f-user .f-user-dept {
.f-user .f-user-org {
color: #a599b2;
}
/*最近*/
/*.z-org-recently li {*/
/*.z-actor-recently li {*/
/* width: 33%;*/
/* float: left;*/
/* cursor: pointer;*/
@@ -410,12 +410,12 @@ const clearAndcloseModal = () => {
/* list-style-type: none;*/
/*}*/
/*.z-org-recently li:hover {*/
/*.z-actor-recently li:hover {*/
/* background-color: #f7efec;*/
/*}*/
/*搜索查询*/
.z-org-search li {
.z-actor-search li {
/*width: 280px;*/
width: 50%;
float: left;
@@ -425,47 +425,46 @@ const clearAndcloseModal = () => {
/*margin: 3px;*/
}
.z-org-search li:hover {
.z-actor-search li:hover {
background-color: #f7efec;
}
.dark .z-org-search li:hover {
.dark .z-actor-search li:hover {
background-color: #1f1f1f;
}
/*!*组织架构树*!*/
.z-org-tree li {
.z-actor-tree li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-tree li:hover {
.z-actor-tree li:hover {
background-color: #f7efec;
}
.dark .z-org-tree li:hover {
.dark .z-actor-tree li:hover {
background-color: #1f1f1f;
}
/*已选的*/
.z-org-selected li {
.z-actor-selected li {
margin: 3px;
cursor: pointer;
padding: 3px;
list-style-type: none;
}
.z-org-selected li:hover {
.z-actor-selected li:hover {
background-color: #f7efec;
}
.dark .z-org-selected li:hover {
.dark .z-actor-selected li:hover {
background-color: #1f1f1f;
}
.z-org-selected .f-user .el-icon {
.z-actor-selected .f-user .el-icon {
/*float: left;*/
/*position:relative;*/
position: absolute;
@@ -476,16 +475,16 @@ const clearAndcloseModal = () => {
margin-left: 42px;
}
.z-org-selected li:hover .el-icon {
.z-actor-selected li:hover .el-icon {
display: inline;
}
.z-org-selected .f-user img {
.z-actor-selected .f-user img {
display: inline;
/*float: none;*/
}
.z-org-selected .f-user-name2 {
.z-actor-selected .f-user-name2 {
display: block;
margin-top: 14px;
}
@@ -1,12 +1,12 @@
<script lang="ts" setup>
import { requestClient } from '#/api/request';
import OrgModal from '#/components/sys/OrgModal.vue';
import ActorModal from '#/components/sys/ActorModal.vue';
import { modalSave, reset } from '#/utils/page/edit';
const emits = defineEmits(['close']);
const state = reactive({
url: '/bpm/org/node',
url: '/bpm/role/node',
show: false,
form: {} as any,
});
@@ -27,20 +27,20 @@ const save = async () => {
};
// region a 包含成员逻辑
const orgModal = ref();
const actorModal = ref();
const openOrgModal = () => {
orgModal.value.open({
orgType: 15,
const openActorModal = () => {
actorModal.value.open({
actorType: 15,
selectMode: 1,
orgs: form.value.memid ? toRaw([{ id: form.value.memid, name: form.value.memna }]) : [],
actors: form.value.memid ? toRaw([{ id: form.value.memid, name: form.value.memna }]) : [],
});
};
const closeOrgModal = (data: any) => {
if (data.orgs && data.orgs.length > 0) {
form.value.memid = data.orgs[0].id;
form.value.memna = data.orgs[0].name;
const closeActorModal = (data: any) => {
if (data.actors && data.actors.length > 0) {
form.value.memid = data.actors[0].id;
form.value.memna = data.actors[0].name;
} else {
form.value.memid = '';
form.value.memna = '';
@@ -53,8 +53,8 @@ const closeOrgModal = (data: any) => {
<template>
<el-drawer v-model="state.show" size="46%">
<template #header>
<h4>组织节点</h4>
<OrgModal ref="orgModal" @close="closeOrgModal" />
<h4>流程角色节点</h4>
<ActorModal ref="actorModal" @close="closeActorModal" />
</template>
<template #default>
<el-form ref="formRef" :model="form" label-width="140px" class="zform">
@@ -68,7 +68,7 @@ const closeOrgModal = (data: any) => {
<el-input-number v-model="form.ornum" controls-position="right" />
</el-form-item>
<el-form-item label="对应成员">
<el-input v-model="form.memna" readonly @click="openOrgModal" />
<el-input v-model="form.memna" readonly @click="openActorModal" />
</el-form-item>
<el-form-item label="备注" prop="notes">
<el-input v-model="form.notes" :rows="2" type="textarea" />
@@ -8,7 +8,7 @@ import { treeDelete, treeItemDelete, treeQuery, treeSelect } from '#/utils/page/
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/bpm/org/node',
url: '/bpm/role/node',
loading: false,
ids: [],
form: {} as any,
@@ -43,7 +43,7 @@ const editClose = async () => {
<div class="flex justify-between">
<el-space>
{{ state.form.trena }}
<el-input style="width: 180px" v-model="state.form.name" placeholder="组织节点名称" clearable @keyup.enter="treeQuery(state)" />
<el-input style="width: 180px" v-model="state.form.name" placeholder="流程角色节点名称" clearable @keyup.enter="treeQuery(state)" />
<el-button type="primary" @click="treeQuery(state)" icon="Search"> 查询</el-button>
</el-space>
<el-space>
@@ -11,7 +11,7 @@ const emits = defineEmits(['close']);
const formRef = ref();
const state = reactive({
url: '/bpm/org/tree',
url: '/bpm/role/tree',
show: false,
form: {} as any,
});
@@ -28,7 +28,7 @@ const open = async (data: any) => {
state.form.catid = data.catid;
}
}
rdata.cates = await requestClient.get(`/bpm/org/treec/tree`);
rdata.cates = await requestClient.get(`/bpm/role/cate/tree`);
state.show = true;
formRef?.value?.clearValidate();
};
@@ -62,14 +62,14 @@ const addItem = () => {
<template>
<el-drawer v-model="state.show" size="46%">
<template #header>
<h4>流程组织树</h4>
<h4>流程角色树</h4>
</template>
<template #default>
<el-form ref="formRef" :model="form" label-width="140px" class="zform">
<el-form-item label="所属分类" prop="catid">
<el-tree-select v-model="form.catid" :data="rdata.cates" :props="{ value: 'id', label: 'name', children: 'children' } as any" value-key="catid" placeholder="选择所属分类" check-strictly />
</el-form-item>
<el-form-item label="组织树名称" prop="name" :rules="[{ required: true, message: '组织树名称不能为空' }]">
<el-form-item label="角色树名称" prop="name" :rules="[{ required: true, message: '角色树名称不能为空' }]">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="排序号" prop="ornum" :rules="[{ required: true, message: '排序号不能为空' }]" style="width: 50%">
@@ -7,7 +7,7 @@ import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/bpm/org/tree',
url: '/bpm/role/tree',
loading: false,
ids: [],
form: {
@@ -36,7 +36,7 @@ const editClose = async () => {
const router = useRouter();
const toNode = (data: any) => {
router.push({ path: '/bpm/org/node', query: data });
router.push({ path: '/bpm/role/node', query: data });
};
</script>
@@ -44,13 +44,13 @@ const toNode = (data: any) => {
<Page auto-content-height>
<div class="flex h-full gap-[8px]">
<div class="w-[260px]">
<EditTree @node-click="nodeClick" url="/bpm/org/treec" tip="组织树分类" :type="0" />
<EditTree @node-click="nodeClick" url="/bpm/role/cate" tip="流程角色分类" :type="0" />
</div>
<el-card style="height: 100%" body-style="height: 100%" class="box-card flex-1 overflow-hidden">
<template #header>
<div class="flex justify-between">
<el-space>
<el-input style="width: 180px" v-model="state.form.name" placeholder="流程组织树" clearable @keyup.enter="listQuery(state)" />
<el-input style="width: 180px" v-model="state.form.name" placeholder="流程角色树" clearable @keyup.enter="listQuery(state)" />
<el-button type="primary" @click="listQuery(state)" icon="Search"> 查询</el-button>
</el-space>
<el-space>
@@ -72,7 +72,7 @@ const toNode = (data: any) => {
>
<el-table-column type="selection" width="44" align="center" />
<el-table-column label="#" type="index" width="50" align="center" />
<el-table-column label="组织树名称" align="center" prop="name" width="180">
<el-table-column label="角色树名称" align="center" prop="name" width="180">
<template #default="scope">
<span class="link_span" @click="toNode({ treid: scope.row.id,trena: scope.row.name })">{{ scope.row.name }}</span>
</template>
@@ -16,7 +16,7 @@ import { VbenAvatar } from '@vben/common-ui';
<div class="text-nowrap opacity-50">
<el-tooltip placement="top" title="更新时间">
<div class="flex items-center gap-1">
<span class="icon-[mdi--clock-outline] size-[16px]"></span>
<!-- <span class="icon-[mdi&#45;&#45;clock-outline] size-[16px]"></span>-->
<span>前更新</span>
</div>
</el-tooltip>
+1 -1
View File
@@ -8,7 +8,7 @@ import { tabSave } from '#/utils/page/edit';
const formRef = ref();
const state = reactive({
url: '/bpm/todo/main',
url: '/bpm/todo',
show: true,
form: { avtag: true } as any,
});
+3 -3
View File
@@ -4,7 +4,7 @@ import { Page } from '@vben/common-ui';
import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/list';
const state = reactive({
url: '/bpm/todo/main',
url: '/bpm/todo',
loading: false,
ids: [],
form: {
@@ -19,11 +19,11 @@ const state = reactive({
const router = useRouter();
function handleAdd() {
router.push('/bpm/todo/main/edit');
router.push('/bpm/todo/edit');
}
function handleEdit(row: any) {
router.push({ path: '/bpm/todo/main/edit', query: { id: row.id } });
router.push({ path: '/bpm/todo/edit', query: { id: row.id } });
}
onMounted(async () => {
+2 -2
View File
@@ -6,7 +6,7 @@ import { debounce } from 'lodash-es';
import AppvCard from './approval-card.vue';
const state = reactive({
url: '/bpm/org/tree',
url: '/bpm/role/tree',
loading: false,
ids: [],
form: {
@@ -93,7 +93,7 @@ const handleScroll = debounce(async (e: Event) => {
<template #header>
<div class="flex justify-between">
<el-space>
<el-input style="width: 180px" v-model="state.form.name" placeholder="流程组织树" clearable @keyup.enter="listQuery(state)" />
<el-input style="width: 180px" v-model="state.form.name" placeholder="流程角色树" clearable @keyup.enter="listQuery(state)" />
<el-button type="primary" @click="listQuery(state)" icon="Search"> 查询</el-button>
</el-space>
<el-space>
@@ -60,8 +60,8 @@ const MemberSelectRule: DragRule = {
},
{
type: 'input',
title: t?.('MemberSelect.deptId') || '部门id',
field: 'deptId',
title: t?.('MemberSelect.orgid') || '组织id',
field: 'orgid',
},
];
},
@@ -54,8 +54,8 @@ const MemberSelectDragRule: DragRule = {
},
{
type: 'input',
title: t?.('deptId') || '部门ID',
field: 'deptId',
title: t?.('orgid') || '组织ID',
field: 'orgid',
},
];
},
+16 -16
View File
@@ -4,7 +4,7 @@ import { ref } from 'vue';
import { buildUUID } from '@vben/utils';
import { requestClient } from '#/api/request';
import OrgModal from '#/components/sys/OrgModal.vue';
import ActorModal from '#/components/sys/ActorModal.vue';
import { drawerSave } from '#/utils/page/edit';
const emits = defineEmits(['close']);
@@ -12,7 +12,7 @@ const emits = defineEmits(['close']);
const formRef = ref();
const state = reactive({
url: '/demo/link/main',
url: '/demo/link',
show: false,
form: {} as any,
});
@@ -22,7 +22,7 @@ const { form } = toRefs(state);
// 暴露open方法给父组件调用
const open = async (data: any) => {
state.form = data && data.id ? await requestClient.get(`${state.url}/info/${data.id}`) : { avtag: true, items: [], catid: data.catid };
rdata.cates = await requestClient.get(`/demo/link/cate/tree`);
rdata.cates = await requestClient.get(`/demo/linkc/tree`);
if (state.form.catid === 0 || state.form.catid === '0' || state.form.catid === undefined) {
delete state.form.catid;
}
@@ -58,25 +58,25 @@ const addItem = () => {
// endregion
// region a 包含成员逻辑
const orgModal = ref();
const actorModal = ref();
const openOrgsModal = () => {
orgModal.value.open({
orgType: 15,
const openActorsModal = () => {
actorModal.value.open({
actorType: 15,
selectMode: 2,
orgs: toRaw(form.value.orgs),
actors: toRaw(form.value.actors),
});
};
const closeOrgModal = (data: any) => {
form.value.orgs = data.orgs;
const closeActorModal = (data: any) => {
form.value.actors = data.actors;
};
const orgsName = computed(() => {
const actorsName = computed(() => {
let names = '';
if (form.value.orgs && form.value.orgs.length > 0) {
for (const org of form.value.orgs) {
names += `${org.name};`;
if (form.value.actors && form.value.actors.length > 0) {
for (const actor of form.value.actors) {
names += `${actor.name};`;
}
}
return names;
@@ -88,7 +88,7 @@ const orgsName = computed(() => {
<el-drawer v-model="state.show" size="40%">
<template #header>
<h4>XX信息维护</h4>
<OrgModal ref="orgModal" @close="closeOrgModal" />
<ActorModal ref="actorModal" @close="closeActorModal" />
</template>
<template #default>
<el-form ref="formRef" :model="form" label-width="140px" class="zform">
@@ -130,7 +130,7 @@ const orgsName = computed(() => {
</el-table>
</el-form-item>
<el-form-item label="包含成员">
<el-input type="textarea" placeholder="中间表测试" :rows="3" v-model="orgsName" readonly @click="openOrgsModal" />
<el-input type="textarea" placeholder="中间表测试" :rows="3" v-model="actorsName" readonly @click="openActorsModal" />
</el-form-item>
<el-form-item label="XX备注" prop="notes">
<el-input v-model="form.notes" :rows="3" type="textarea" />
+2 -2
View File
@@ -7,7 +7,7 @@ import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/demo/link/main',
url: '/demo/link',
loading: false,
ids: [],
form: {
@@ -42,7 +42,7 @@ const editClose = async () => {
<Page auto-content-height>
<div class="flex h-full gap-[8px]">
<div class="w-[260px]">
<EditTree @node-click="nodeClick" url="/demo/link/cate" tip="XX分类" />
<EditTree @node-click="nodeClick" url="/demo/linkc" tip="XX分类" />
</div>
<el-card style="height: 100%" body-style="height: 100%" class="box-card flex-1 overflow-hidden">
<template #header>
@@ -0,0 +1,128 @@
<script lang="ts" setup>
import { useUserStore } from '@vben/stores';
import { requestClient } from '#/api/request';
import ActorModal from '#/components/sys/ActorModal.vue';
import { drawerSave, reset } from '#/utils/page/edit';
const emits = defineEmits(['close']);
const state = reactive({
url: '/demo/perm1',
show: false,
form: {} as any,
});
const formRef = ref();
const { form } = toRefs(state);
const userStore = useUserStore();
const open = async (data: any) => {
state.form =
data && data.id
? await requestClient.get(`${state.url}/info/${data.id}`)
: { avtag: true, blman: { id: userStore.userInfo?.userId, name: userStore.userInfo?.realName }, blorg: { id: userStore.userInfo?.orgid, name: userStore.userInfo?.orgna } };
await reset({ formRef: formRef.value, state });
};
defineExpose({ open });
const save = async () => {
await drawerSave({ formRef: formRef.value, state });
emits('close');
};
// region a 可查看者与可编辑者逻辑
const actorModal = ref();
const openBlmanModal = () => {
actorModal.value.open({
opener: 'blman',
actorType: 2,
selectMode: 1,
actors: toRaw([form.value.blman]),
});
};
const openBlorgModal = () => {
actorModal.value.open({
opener: 'blorg',
actorType: 1,
selectMode: 1,
actors: toRaw([form.value.blorg]),
});
};
const closeActorModal = (data: any) => {
if (data.opener === 'blman') {
form.value.blman = data.actors[0];
} else if (data.opener === 'blorg') {
form.value.blorg = data.actors[0];
}
};
const bluna = computed(() => {
let name = '';
if (form.value.blman) {
name = form.value.blman.name;
}
return name;
});
const blona = computed(() => {
let name = '';
if (form.value.blorg) {
name = form.value.blorg.name;
}
return name;
});
// endregion
</script>
<template>
<el-drawer v-model="state.show" size="46%">
<template #header>
<h4>XX信息维护</h4>
<ActorModal ref="actorModal" @close="closeActorModal" />
</template>
<template #default>
<el-form ref="formRef" :model="form" label-width="140px" class="zform">
<el-form-item label="XX名称" prop="name" :rules="[{ required: true, message: 'XX名称不能为空' }]">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="归属用户" prop="blman" :rules="[{ required: true, message: '归属用户不能为空' }]">
<el-input v-model="bluna" readonly @click="openBlmanModal" />
</el-form-item>
<el-form-item label="归属组织" prop="blorg" :rules="[{ required: true, message: '归属组织不能为空' }]">
<el-input v-model="blona" readonly @click="openBlorgModal" />
</el-form-item>
<!-- <el-form-item label="可查看者">-->
<!-- <el-input type="textarea" placeholder="可查看者" :rows="3" v-model="vimenNames" readonly @click="openVimenModal" />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="可编辑者">-->
<!-- <el-input type="textarea" placeholder="可编辑者" :rows="3" v-model="edmenNames" readonly @click="openEdmenModal" />-->
<!-- </el-form-item>-->
<el-form-item label="备注" prop="notes">
<el-input v-model="form.notes" :rows="3" type="textarea" />
</el-form-item>
<template v-if="form.crtim">
<el-form-item label="创建人" style="width: 50%">
<div>{{ form.cruna }}</div>
</el-form-item>
<el-form-item label="创建时间" style="width: 50%">
<div>{{ form.crtim }}</div>
</el-form-item>
<el-form-item label="更新人" style="width: 50%">
<div>{{ form.upuna }}</div>
</el-form-item>
<el-form-item label="更新时间" style="width: 50%">
<div>{{ form.uptim }}</div>
</el-form-item>
</template>
</el-form>
</template>
<template #footer>
<div style="flex: auto; margin: 20px">
<el-button type="primary" @click="save">保 存</el-button>
<el-button @click="state.show = false">关 闭</el-button>
</div>
</template>
</el-drawer>
</template>
@@ -0,0 +1,97 @@
<script setup lang="ts">
import { Page } from '@vben/common-ui';
import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/list';
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/demo/perm1',
loading: false,
ids: [],
form: {
pageSize: 10,
} as any,
single: true,
multiple: true,
rows: [],
total: 0,
});
const editRef = ref() as any;
const editClose = async () => {
await listQuery(state);
};
onMounted(async () => {
await listQuery(state);
});
</script>
<template>
<Page auto-content-height>
<el-card class="box-card" style="height: 100%" body-style="height: 100%">
<template #header>
<div class="flex justify-between">
<el-space>
<el-input style="width: 180px" v-model="state.form.name" placeholder="输入名称回车查询" clearable @keyup.enter="listQuery(state)" />
<el-button type="primary" @click="listQuery(state)" icon="Search"> 查询</el-button>
</el-space>
<el-space>
<el-button icon="Plus" type="success" plain @click="editRef.open()">新增</el-button>
<el-button icon="Delete" type="danger" plain @click="listDelete(state)" :disabled="state.multiple">删除</el-button>
</el-space>
</div>
</template>
<el-table
@selection-change="listSelect($event, state)"
style="height: calc(100% - 90px)"
:cell-style="{ padding: '2px' }"
:row-style="{ height: '36px' }"
v-loading="state.loading"
:data="state.rows"
border
stripe
>
<el-table-column type="selection" width="44" align="center" />
<el-table-column label="#" type="index" width="50" align="center" />
<el-table-column label="XX名称">
<template #default="scope">
<span class="link_span" @click="editRef.open({ id: scope.row.id })">{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="创建人" prop="cruna" width="86" align="center" />
<el-table-column label="更新人" prop="upuna" width="86" align="center" />
<el-table-column label="归属人" prop="bluna" width="86" align="center" />
<el-table-column label="归属组织" prop="blona" width="200" align="center" />
<el-table-column label="XX备注" prop="notes" />
<el-table-column label="操作" align="center" width="86" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="editRef.open({ id: scope.row.id })" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="listItemDelete(state, scope.row.id)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
<el-pagination
style="margin-top: 10px"
@size-change="listQuery(state)"
@current-change="listQuery(state)"
:pager-count="5"
:page-sizes="[10, 20, 30]"
background
:total="state.total"
v-model:current-page="state.form.pageNum"
v-model:page-size="state.form.pageSize"
layout="total, sizes, prev, pager, next, jumper"
/>
</el-card>
<DrawerEdit ref="editRef" @close="editClose" />
</Page>
</template>
@@ -0,0 +1,134 @@
<script lang="ts" setup>
import { useUserStore } from '@vben/stores';
import { requestClient } from '#/api/request';
import ActorModal from '#/components/sys/ActorModal.vue';
import { drawerSave, reset } from '#/utils/page/edit';
const emits = defineEmits(['close']);
const state = reactive({
url: '/demo/perm2',
show: false,
form: {} as any,
});
const formRef = ref();
const { form } = toRefs(state);
const userStore = useUserStore();
const open = async (data: any) => {
if (data && data.id) {
state.form = await requestClient.get(`${state.url}/info/${data.id}`);
} else {
state.form = {
avtag: true,
vimen: [
{ id: userStore.userInfo?.userId, name: userStore.userInfo?.realName },
{ id: userStore.userInfo?.orgid, name: userStore.userInfo?.orgna },
],
edmen: [{ id: userStore.userInfo?.userId, name: userStore.userInfo?.realName }],
};
}
await reset({ formRef: formRef.value, state });
};
defineExpose({ open });
const save = async () => {
await drawerSave({ formRef: formRef.value, state });
emits('close');
};
// region a 可查看者与可编辑者逻辑
const actorModal = ref();
const openVimenModal = () => {
actorModal.value.open({
opener: 'vimen',
actorType: 15,
selectMode: 2,
actors: toRaw(form.value.vimen),
});
};
const openEdmenModal = () => {
actorModal.value.open({
opener: 'edmen',
actorType: 15,
selectMode: 2,
actors: toRaw(form.value.edmen),
});
};
const closeActorModal = (data: any) => {
if (data.opener === 'vimen') {
form.value.vimen = data.actors;
} else if (data.opener === 'edmen') {
form.value.edmen = data.actors;
}
};
const vimenNames = computed(() => {
let names = '';
if (form.value.vimen && form.value.vimen.length > 0) {
for (const actor of form.value.vimen) {
names += `${actor.name};`;
}
}
return names;
});
const edmenNames = computed(() => {
let names = '';
if (form.value.edmen && form.value.edmen.length > 0) {
for (const actor of form.value.edmen) {
names += `${actor.name};`;
}
}
return names;
});
// endregion
</script>
<template>
<el-drawer v-model="state.show" size="46%">
<template #header>
<h4>XX信息维护</h4>
<ActorModal ref="actorModal" @close="closeActorModal" />
</template>
<template #default>
<el-form ref="formRef" :model="form" label-width="140px" class="zform">
<el-form-item label="XX名称" prop="name" :rules="[{ required: true, message: 'XX名称不能为空' }]">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="可查看者">
<el-input type="textarea" placeholder="可查看者" :rows="3" v-model="vimenNames" readonly @click="openVimenModal" />
</el-form-item>
<el-form-item label="可编辑者">
<el-input type="textarea" placeholder="可编辑者" :rows="3" v-model="edmenNames" readonly @click="openEdmenModal" />
</el-form-item>
<el-form-item label="备注" prop="notes">
<el-input v-model="form.notes" :rows="3" type="textarea" />
</el-form-item>
<template v-if="form.crtim">
<el-form-item label="创建人" style="width: 50%">
<div>{{ form.cruna }}</div>
</el-form-item>
<el-form-item label="创建时间" style="width: 50%">
<div>{{ form.crtim }}</div>
</el-form-item>
<el-form-item label="更新人" style="width: 50%">
<div>{{ form.upuna }}</div>
</el-form-item>
<el-form-item label="更新时间" style="width: 50%">
<div>{{ form.uptim }}</div>
</el-form-item>
</template>
</el-form>
</template>
<template #footer>
<div style="flex: auto; margin: 20px">
<el-button type="primary" @click="save">保 存</el-button>
<el-button @click="state.show = false">关 闭</el-button>
</div>
</template>
</el-drawer>
</template>
@@ -0,0 +1,97 @@
<script setup lang="ts">
import { Page } from '@vben/common-ui';
import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/list';
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/demo/perm2',
loading: false,
ids: [],
form: {
pageSize: 10,
} as any,
single: true,
multiple: true,
rows: [],
total: 0,
});
const editRef = ref() as any;
const editClose = async () => {
await listQuery(state);
};
onMounted(async () => {
await listQuery(state);
});
</script>
<template>
<Page auto-content-height>
<el-card class="box-card" style="height: 100%" body-style="height: 100%">
<template #header>
<div class="flex justify-between">
<el-space>
<el-input style="width: 180px" v-model="state.form.name" placeholder="输入名称回车查询" clearable @keyup.enter="listQuery(state)" />
<el-button type="primary" @click="listQuery(state)" icon="Search"> 查询</el-button>
</el-space>
<el-space>
<el-button icon="Plus" type="success" plain @click="editRef.open()">新增</el-button>
<el-button icon="Delete" type="danger" plain @click="listDelete(state)" :disabled="state.multiple">删除</el-button>
</el-space>
</div>
</template>
<el-table
@selection-change="listSelect($event, state)"
style="height: calc(100% - 90px)"
:cell-style="{ padding: '2px' }"
:row-style="{ height: '36px' }"
v-loading="state.loading"
:data="state.rows"
border
stripe
>
<el-table-column type="selection" width="44" align="center" />
<el-table-column label="#" type="index" width="50" align="center" />
<el-table-column label="XX名称">
<template #default="scope">
<span class="link_span" @click="editRef.open({ id: scope.row.id })">{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="crtim" width="164" />
<el-table-column label="创建人" prop="cruna" width="86" align="center" />
<el-table-column label="更新时间" prop="uptim" width="164" />
<el-table-column label="更新人" prop="upuna" width="86" align="center" />
<el-table-column label="XX备注" prop="notes" />
<el-table-column label="操作" align="center" width="86" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="editRef.open({ id: scope.row.id })" />
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="listItemDelete(state, scope.row.id)" />
</el-tooltip>
</template>
</el-table-column>
</el-table>
<el-pagination
style="margin-top: 10px"
@size-change="listQuery(state)"
@current-change="listQuery(state)"
:pager-count="5"
:page-sizes="[10, 20, 30]"
background
:total="state.total"
v-model:current-page="state.form.pageNum"
v-model:page-size="state.form.pageSize"
layout="total, sizes, prev, pager, next, jumper"
/>
</el-card>
<DrawerEdit ref="editRef" @close="editClose" />
</Page>
</template>
@@ -6,7 +6,7 @@ const emits = defineEmits(['close']);
const formRef = ref();
const state = reactive({
url: '/demo/single/cate',
url: '/demo/singlec',
show: false,
form: {} as any,
});
@@ -6,7 +6,7 @@ import { treeItemDelete, treeQuery } from '#/utils/page/tree';
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/demo/single/cate',
url: '/demo/singlec',
list: [] as any,
form: { name: '' } as any,
});
@@ -4,7 +4,7 @@ import { drawerSave, reset } from '#/utils/page/edit';
const emits = defineEmits(['close']);
const state = reactive({
url: '/demo/single/main',
url: '/demo/single',
show: false,
form: {} as any,
});
@@ -33,9 +33,6 @@ const save = async () => {
<el-form-item label="XX名称" prop="name" :rules="[{ required: true, message: 'XX名称不能为空' }]">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="XX时间" prop="aaa">
<el-date-picker v-model="form.aaa" type="date" value-format="YYYY-MM-DD HH:mm:ss" />
</el-form-item>
<el-form-item label="备注" prop="notes">
<el-input v-model="form.notes" :rows="3" type="textarea" />
</el-form-item>
@@ -6,7 +6,7 @@ import { listDelete, listItemDelete, listQuery, listSelect } from '#/utils/page/
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/demo/single/main',
url: '/demo/single',
loading: false,
ids: [],
form: {
+1 -1
View File
@@ -6,7 +6,7 @@ import { listDelete, listQuery, listSelect } from '#/utils/page/list';
import DrawerView from './view.vue';
const state = reactive({
url: '/mon/job/log',
url: '/mon/jobl',
loading: false,
ids: [],
form: {
+1 -1
View File
@@ -3,7 +3,7 @@ import { requestClient } from '#/api/request';
import { renderJsonPreview } from '#/utils/render';
const state = reactive({
url: '/mon/job/log',
url: '/mon/jobl',
show: false,
form: { avtag: true } as any,
});
+1 -1
View File
@@ -4,7 +4,7 @@ import { drawerSave, reset } from '#/utils/page/edit';
const emits = defineEmits(['close']);
const state = reactive({
url: '/mon/job/main',
url: '/mon/job',
show: false,
form: {} as any,
});
@@ -7,7 +7,7 @@ import { listDelete, listQuery, listSelect } from '#/utils/page/list';
import DrawerEdit from './edit.vue';
const state = reactive({
url: '/mon/job/main',
url: '/mon/job',
loading: false,
ids: [],
form: {
@@ -80,7 +80,7 @@ const doOnce = async (id: string) => {
const router = useRouter();
function openLog() {
router.push('/mon/job/log');
router.push('/mon/jobl');
}
</script>
@@ -7,7 +7,7 @@ import { renderBrowserIcon, renderOsIcon } from '#/utils/render';
import DrawerView from './view.vue';
const state = reactive({
url: '/mon/login/log',
url: '/mon/login',
loading: false,
ids: [],
form: {
@@ -3,7 +3,7 @@ import { requestClient } from '#/api/request';
import { renderBrowserIcon, renderOsIcon } from '#/utils/render';
const state = reactive({
url: '/mon/login/log',
url: '/mon/login',
show: false,
form: { avtag: true } as any,
});
@@ -7,7 +7,7 @@ import { requestClient } from '#/api/request';
import { renderBrowserIcon, renderOsIcon } from '#/utils/render';
const state = reactive({
url: '/mon/online/user',
url: '/mon/online',
loading: true,
ids: [],
form: {
@@ -76,7 +76,7 @@ const kick = async (row: any) => {
<el-table-column label="#" type="index" width="50" align="center" />
<el-table-column label="用户账号" prop="usena" width="110" min-width="110" />
<el-table-column label="登录平台" prop="detyp" width="86">PC</el-table-column>
<el-table-column label="部门名称" prop="depna" width="150" min-width="150" />
<el-table-column label="组织名称" prop="orgna" width="150" min-width="150" />
<el-table-column label="IP地址" prop="ip" />
<el-table-column label="IP地点" prop="loginLocation" />
<el-table-column label="系统" prop="os" width="150">

Some files were not shown because too many files have changed in this diff Show More