Compare commits

...

18 Commits

Author SHA1 Message Date
herenshan112 15c7fd2421 Merge branch 'qin_26' into power_master 2 days ago
herenshan112 019fe5b30d 便跟菜单 2 days ago
herenshan112 c9f5619730 Merge branch 'qin_26' into power_master 4 days ago
herenshan112 78064dca8e 增加全选 4 days ago
herenshan112 c7c0489187 Merge branch 'qin_26' into power_master 5 days ago
herenshan112 b83b554e7e 授权完成 5 days ago
herenshan112 07d089ec25 修改修正变更 1 week ago
herenshan112 b7e53ff199 Merge branch 'qin_26' into power_master 1 week ago
herenshan112 ba70244b96 新权限设计完毕 2 weeks ago
herenshan112 170b9d6692 上传写入数据库 2 weeks ago
herenshan112 57d391670e Merge branch 'qin_26' into power_master 3 weeks ago
herenshan112 7a2b48374b 提交权限配置 3 weeks ago
herenshan112 f347cda044 新增页面 3 weeks ago
herenshan112 7ec5ad5e2d 合并 3 weeks ago
herenshan112 401762d554 Merge branch 'qin_26' into power_master 3 weeks ago
herenshan112 ef4f7e263b 员工权限 3 weeks ago
herenshan112 e565863d14 修改权限及流程 3 weeks ago
herenshan112 a9e4d032eb 修改权限设置 1 month ago
  1. 103
      src/api/system/roleapi/postrole.ts
  2. 61
      src/api/system/roleapi/power.ts
  3. 49
      src/api/system/roleapi/types.ts
  4. 2
      src/api/user/types.ts
  5. 1
      src/assets/icons/xiala.svg
  6. 1
      src/assets/icons/xiala1.svg
  7. 41
      src/components/DesignForm/app/index.vue
  8. 35
      src/components/DesignForm/tableListPage/index.vue
  9. 2
      src/components/workflow/dialog/errorDialog.vue
  10. 1
      src/components/workflow/drwer/approverDrawer.vue
  11. 5
      src/directive/index.ts
  12. 186
      src/directive/permission/button.ts
  13. 97
      src/layout/components/myconst/editmypassword.vue
  14. 7
      src/permission.ts
  15. 1
      src/store/modules/knowledge.ts
  16. 3
      src/store/modules/permission.ts
  17. 7
      src/store/modules/user.ts
  18. 307
      src/utils/CheckPassword.ts
  19. 52
      src/utils/workflow/const.ts
  20. 34
      src/utils/workflow/index.ts
  21. 5
      src/views/hr/archives/archivescont.vue
  22. 1609
      src/views/hr/archives/index.vue
  23. 200
      src/views/hr/archives/index_20251202.vue
  24. 1465
      src/views/hr/archives/index_251128.vue
  25. 274
      src/views/hr/archives/unitpage/addUserPage.vue
  26. 235
      src/views/hr/archives/unitpage/batchImport.vue
  27. 96
      src/views/hr/archives/unitpage/lockInfo.vue
  28. 222
      src/views/hr/archives/unitpage/uploadTemplate.vue
  29. 12
      src/views/nested/.editorconfig
  30. 4
      src/views/opk/yui/new/lzq.vue
  31. 4
      src/views/opk/yui/new/xy.vue
  32. 3
      src/views/powermanage/rolepower/setuprole/setuprolepower.vue
  33. 865
      src/views/system/monitor/online/index copy 4.vue
  34. 777
      src/views/system/monitor/online/index.vue
  35. 903
      src/views/system/monitor/online/index123.vue
  36. 819
      src/views/system/monitor/online/index2.vue
  37. 0
      src/views/system/monitor/online/index_20251112.vue
  38. 1189
      src/views/system/monitor/online/index_20251217.vue
  39. 283
      src/views/system/monitor/online/page.vue
  40. 444
      src/views/system/monitor/online/powerPage/appTabsPower.vue
  41. 249
      src/views/system/monitor/online/powerPage/apptablepower.vue
  42. 338
      src/views/system/monitor/online/roleConfig/setRolePeople.vue
  43. 3
      src/views/sysworkflow/lowCodeTasks/index.vue
  44. 11
      src/views/sysworkflow/lowcodepage/appCardPage.vue
  45. 28
      src/views/sysworkflow/lowcodepage/appListPage.vue
  46. 23
      src/views/sysworkflow/lowcodepage/appPage/appMenus.vue
  47. 20
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/openAppFormPage.vue
  48. 1
      src/views/sysworkflow/lowcodepage/appPage/appSetUp/setup.vue
  49. 18
      src/views/sysworkflow/lowcodepage/appPage/createAppFormPage.vue
  50. 28
      src/views/sysworkflow/lowcodepage/index.vue
  51. 20
      src/views/sysworkflow/lowcodepage/newLowCode/appLayoutEdit/appContainerPage.vue
  52. 3
      src/views/sysworkflow/lowcodepage/pageFlow/appTableFlow.vue
  53. 2
      src/views/sysworkflow/lowcodepage/runApp/regularPage.vue
  54. 4
      src/views/sysworkflow/lowcodepage/runApp/runAppForm.vue
  55. 3
      src/views/taskplatform/taskmanagement/flowStep.vue
  56. 4
      src/views/taskplatform/taskmanagement/lookAndOperateLogInfo.vue
  57. 4
      src/views/taskplatform/taskmanagement/taskcustomerform.vue
  58. 4
      src/views/taskplatform/taskmanagement/tasklist.vue
  59. 215
      vite.config.ts.timestamp-1762732876054-97f8b5f7ef739.mjs
  60. 215
      vite.config.ts.timestamp-1763685117626-b9e83b063ec3.mjs

103
src/api/system/roleapi/postrole.ts

@ -103,6 +103,13 @@ export function gainAppTableList(data?: any){
data:data
});
}
export function gainAppTableListNew(data?: any){
return request({
url: '/systemapi/grant/gainAppTableListNew',
method: 'post',
data:data
});
}
/**
*
*/
@ -113,3 +120,99 @@ export function setpAppTableForms(data?: any){
data:data
});
}
/**
*
*/
export function getMyPeoplceAndSunOrg(data?: any){
return request({
url: '/systemapi/authorize/getMyPeoplceAndSunOrg',
method: 'post',
data:data
});
}
/**
*
*/
export function getMyPeopleAndSunOrgPost(data?: any){
return request({
url: '/systemapi/authorize/getMyPeopleAndSunOrgPost',
method: 'post',
data:data
});
}
/**
*
*/
export function getPowerPageUser(data?: any){
return request({
url: '/systemapi/authorize/getPowerPageUser',
method: 'post',
data:data
});
}
/**
*
*/
export function systemAppAuthorization(data?: any){
return request({
url: '/systemapi/authorize/systemAppAuthorization',
method: 'post',
data:data
});
}
/**
* 使
*/
export function getRolePeople(data?: any){
return request({
url: '/systemapi/authorize/getRolePeople',
method: 'post',
data:data
});
}
/**
* 使
*/
export function savePickRoleMan(data?: any){
return request({
url: '/systemapi/authorize/savePickRoleMan',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-12-11 14:23:55
@ :
*/
export function gainAppEmpowerPower(data?: any){
return request({
url: '/systemapi/grant/gainAppEmpowerPower',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-12-11 14:23:55
@ 功能: 初始化应用授权选项
*/
export function appInitAuthorization(data?: any){
return request({
url: '/systemapi/grant/appInitAuthorization',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-12-11 14:23:55
@ 功能: 初始化应用授权选项
*/
export function tabsAuthorizationMode(data?: any){
return request({
url: '/systemapi/grant/tabsAuthorizationMode',
method: 'post',
data:data
});
}

61
src/api/system/roleapi/power.ts

@ -0,0 +1,61 @@
import request from "@/utils/request";
import { getSystemPower } from "./types";
/**
*
*/
export function appPowerUnit(data: getSystemPower){
return request({
url: '/systemapi/authorize/appPowerUnit',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-11-28 10:24:09
@ 功能: 授权行政组织书
*/
export function authorizeOrgTree(data?: getSystemPower){
return request({
url: '/systemapi/hr/authorizeOrgTree',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-11-28 10:24:09
@ 功能: 根据权限获取数据
*/
export function authorizePeopleList(data?: getSystemPower){
return request({
url: '/systemapi/hr/authorizePeopleList',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-11-28 10:24:09
@ 功能: 新增人员
*/
export function addNewPeople(data?: getSystemPower){
return request({
url: '/systemapi/hr/addNewPeople',
method: 'post',
data:data
});
}
/**
@ 作者: 秦东
@ 时间: 2025-11-28 10:24:09
@ 功能: 编辑自己登陆密码
*/
export function editMyPwd(data?: getSystemPower){
return request({
url: '/systemapi/hr/editMyPwd',
method: 'post',
data:data
});
}

49
src/api/system/roleapi/types.ts

@ -57,6 +57,11 @@ export interface systemCont{
sort?:number; //排序
state?:number; //状态
time?:number; //编辑时间
isPick?:boolean; //是否选中
icon?:string; //图标
name?:string; //名称
code?:string; //编码
org?:string; //组织
}
//菜单列表
@ -285,3 +290,47 @@ export interface custerAppTablePower extends custerAppInfo{
attribute:number[]
};
}
//获取平台授权项目
export interface getSystemPower{
powerType:string;
appId:string;
appType:string;
appSystem:string;
roleId:string;
isPick?:boolean;
}
// 平台授权结构体
export interface AppPowerInfo {
id :number;
name :string; //菜单名称
types :number;
perm :number;
sort :number;
parentId :number;
isTrue :boolean;
}
// 分流
export interface AppMenuBut extends AppPowerInfo {
buttenPower:AppPowerInfo[]
}
// 平台授权结构树
export interface AppPowerTree extends AppMenuBut {
children:AppPowerTree[]
visible :number;
visibleRange:VisibleRangeInfo[]; //当可见范围为自定义范围时。此辅助选项生效
}
export interface VisibleRangeInfo {
types:number;
val:string;
}
//搜索
export interface searchUser extends setupPage{
name?:string;
}

2
src/api/user/types.ts

@ -6,6 +6,8 @@ export interface UserInfo {
avatar: string;
roles: string[];
perms: string[];
allPowerConfig: any;
userInfoCont: any;
}
/**

1
src/assets/icons/xiala.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1765935600369" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1814" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512.5 952.8c-9.1 0-17.8-3.7-24.1-10.2L110.8 552c-12.9-13.3-12.5-34.5 0.8-47.4 13.3-12.9 34.5-12.5 47.4 0.8l353.5 365.7L866 505.4c12.9-13.3 34.1-13.7 47.4-0.8 13.3 12.9 13.7 34.1 0.8 47.4L536.6 942.6c-6.3 6.5-15 10.2-24.1 10.2z" fill="#231815" p-id="1815"></path><path d="M512.5 545.2c-9.1 0-17.8-3.7-24.1-10.2L110.8 144.4c-12.9-13.3-12.5-34.5 0.8-47.4 13.3-12.9 34.5-12.5 47.4 0.8l353.5 365.7L866 97.8c12.9-13.3 34.1-13.7 47.4-0.8 13.3 12.9 13.7 34.1 0.8 47.4L536.6 535c-6.3 6.6-15 10.2-24.1 10.2z" fill="#231815" p-id="1816"></path></svg>

After

Width:  |  Height:  |  Size: 873 B

1
src/assets/icons/xiala1.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1765935956258" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1976" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M57.3 248.7c27.1-29 71.1-29 98.4 0l393.3 421c27.1 29 27.1 76.1 0 105.2-27.1 29-71.1 29-98.4 0l-393.3-421c-27.1-28.9-27.1-76 0-105.2z m0 0" p-id="1977"></path><path d="M966.3 248.7c27.1 29 27.1 76.1 0 105.2L572.9 775c-27.1 29-71.1 29-98.4 0-27.2-29-27.2-76.1 0-105.2l393.3-421c27.2-29.1 71.2-29.1 98.5-0.1z m0 0" p-id="1978"></path></svg>

After

Width:  |  Height:  |  Size: 670 B

41
src/components/DesignForm/app/index.vue

@ -43,10 +43,9 @@ import {
} from "@/api/taskapi/management";
import { formatNumber } from "@/api/DesignForm/utils";
import printHtmlRender from '../printHtmlRender.vue'
import {fieldTree,PageConfig} from '../printHtmlRender.vue'
import {printElement} from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js"
import {getPrintTemplate} from '@/api/DesignForm/requestapi'
import { formHasPower } from "@/directive/permission/button";
//
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
import TableFlow from "@/views/sysworkflow/lowcodepage/pageFlow/appTableFlow.vue";
@ -72,8 +71,9 @@ const props = withDefaults(
data: FormPageList;
searchData?: attrButton[];
config?: FormPageConfig|any;
formId?: string;
appKey?: string;
formId?: string;
signCode?: string;
beforeRequest?: (params: any, rout: any) => any;
afterResponse?: (result: any) => any | string;
beforeDelete?: (params: any, route: any) => any;
@ -87,8 +87,6 @@ const props = withDefaults(
delKey?: string; //
lookPageIsShow?: boolean;
versionid?: string;
formKey?:string;
signCode?: string;
pickAppMenu?: any;
versiontitle?: string;
viewPage?: viewPageType|any;
@ -111,9 +109,15 @@ const props = withDefaults(
dict: () => {
return {};
},
appKey: () => {
return "";
},
formId: () => {
return "";
},
signCode: () => {
return "";
},
versionid: () => {
return "";
},
@ -2095,14 +2099,18 @@ const isObject = (obj: any) => {
<el-text v-if="data.controlBtn.length === 0" class="mx-1 tipBox" type="info"
>操作按钮区域</el-text
>
<el-button
v-for="item in data.controlBtn"
v-bind="item"
:key="item.type"
@click="setUpClick(item)"
>
{{ item.label }}
</el-button>
<template v-for="item in data.controlBtn" :key="item.type">
<el-button
v-bind="item"
v-if="formHasPower(props.pickAppMenu.appkey,props.signCode,item.key,0)"
@click="setUpClick(item)"
>
{{ item.label }}
</el-button>
</template>
</div>
<div>
<el-button-group class="ml-4">
@ -2349,6 +2357,7 @@ const isObject = (obj: any) => {
type="info"
size="small"
class="fa fa-edit"
v-if="formHasPower(props.pickAppMenu.appkey,props.signCode,'bj',0)"
/>
</el-tooltip>
@ -2377,7 +2386,7 @@ const isObject = (obj: any) => {
@cancel="cancelEvent(scope.row)"
>
<template #reference>
<el-button type="danger" size="small" class="fa fa-trash-o" />
<el-button type="danger" size="small" class="fa fa-trash-o" v-if="formHasPower(props.pickAppMenu.appkey,props.signCode,'sc',0)" />
</template>
</el-popconfirm>

35
src/components/DesignForm/tableListPage/index.vue

@ -38,10 +38,7 @@ import { ElLoading, ElMessage, ElNotification } from "element-plus";
import { softDeletion, retractRunWorkFlow, recalSendMsg } from "@/api/taskapi/management";
import { echatsViews } from "@/api/DesignForm/types";
import { formatNumber } from "@/api/DesignForm/utils";
import { Ref } from "vue";
import printHtmlRender from '../printHtmlRender.vue'
import {fieldTree,PageConfig} from '../printHtmlRender.vue'
import {printElement} from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/printHtmlDom.js"
import { formHasPower } from "@/directive/permission/button";
//
import FormPageCont from "@/components/DesignForm/tableListPage/formPageCont.vue";
import TableFlow from "@/views/sysworkflow/lowcodepage/pageFlow/tableFlow.vue";
@ -61,8 +58,9 @@ const props = withDefaults(
data: FormPageList;
searchData?: attrButton[];
config: FormPageConfig;
formId?: string;
appKey?: string;
formId?: string;
signCode?: string;
beforeRequest?: (params: any, rout: any) => any;
afterResponse?: (result: any) => any | string;
beforeDelete?: (params: any, route: any) => any;
@ -98,9 +96,15 @@ const props = withDefaults(
dict: () => {
return {};
},
appKey: () => {
return "";
},
formId: () => {
return "";
},
signCode: () => {
return "";
},
versionid: () => {
return "";
},
@ -1888,14 +1892,17 @@ const isObject = (obj: any) => {
<el-text v-if="data.controlBtn.length === 0" class="mx-1 tipBox" type="info"
>操作按钮区域</el-text
>
<el-button
v-for="item in data.controlBtn"
v-bind="item"
:key="item.type"
@click="setUpClick(item)"
>
{{ item.label }}
<template v-for="item in data.controlBtn" :key="item.type">
<el-button
v-bind="item"
v-if="formHasPower(props.appKey,props.signCode,item.key,0)"
@click="setUpClick(item)"
>
{{ item.label }}
</el-button>
</template>
</div>
<div>
<el-button-group class="ml-4">
@ -2124,6 +2131,7 @@ const isObject = (obj: any) => {
size="small"
class="fa fa-mail-reply-all"
color="rgb(250, 181.5, 181.5)"
/>
</template>
</el-popconfirm>
@ -2154,6 +2162,7 @@ const isObject = (obj: any) => {
type="info"
size="small"
class="fa fa-edit"
v-if="formHasPower(props.appKey,props.signCode,'bj',0)"
/>
</el-tooltip>
<el-popconfirm
@ -2167,7 +2176,7 @@ const isObject = (obj: any) => {
@cancel="cancelEvent(scope.row)"
>
<template #reference>
<el-button type="danger" size="small" class="fa fa-trash-o" />
<el-button v-if="formHasPower(props.appKey,props.signCode,'sc',0)" type="danger" size="small" class="fa fa-trash-o" />
</template>
</el-popconfirm>

2
src/components/workflow/dialog/errorDialog.vue

@ -32,7 +32,7 @@ let visibleDialog = computed({
<div class="ant-confirm-content">
<div>
<p class="error-modal-desc">以下内容不完善需进行修改</p>
<div class="error-modal-list">
<div class="error-modal-list">{{list}}
<div v-for="(item,index) in list" :key="index" class="error-modal-item">
<div class="error-modal-item-label">流程设计</div>
<div class="error-modal-item-content">{{item.name}} 未选择{{item.type}}</div>

1
src/components/workflow/drwer/approverDrawer.vue

@ -309,6 +309,7 @@ const saveApprover = () => {
formData: JSON.stringify(formData.value),
formPower: JSON.stringify(formData.value.purview),
};
console.log("sendInfo----------------->", sendInfo);
// console.log("sendInfo", sendInfo);
setFlowFormKeyPower(sendInfo);
closeDrawer();

5
src/directive/index.ts

@ -1,9 +1,14 @@
import type { App } from 'vue';
import { hasPerm } from './permission';
import { hasButton,hasApp,hasAppGroup,hasGroupApp,hasCustomAppGroup } from './permission/button';
// 全局注册 directive
export function setupDirective(app: App<Element>) {
// 使 v-hasPerm 在所有组件中都可用
app.directive('hasPerm', hasPerm);
app.directive('hasButton', hasButton);
app.directive('hasApp', hasApp);
app.directive('hasAppGroup', hasAppGroup);
app.directive('hasGroupApp', hasGroupApp);
}

186
src/directive/permission/button.ts

@ -0,0 +1,186 @@
import { Directive, DirectiveBinding } from 'vue';
import { useUserStore } from "@/store/modules/user";
/**
*
*/
export const hasButton: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const userStore = useUserStore();
const { value } = binding;
// console.log("按钮权限",el,"-->",binding,"-->",value,"-->",userStore.myPower.menuButIdAry,"-->",userStore.myPower);
if (value) {
const requiredPerms = value; // DOM绑定需要的按钮权限标识
const hasPerm = userStore.myPower.menuButIdAry.some((perm: any) => {
return requiredPerms.includes(perm);
});
if (!hasPerm) {
el.parentNode?.removeChild(el);
}
}
}
}
/**
* app权限
*/
export const hasApp: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const userStore = useUserStore();
const { value } = binding;
// console.log("app权限",el,"-->",binding,"-->",value,"-->",userStore.myPower.appKeyAry,"-->",userStore.myPower);
// console.log("我的App--->",userStore.myPower)
if (value) {
const requiredPerms = value; // DOM绑定需要的app权限标识
const hasPerm = userStore.myPower.appKeyAry.some((perm: any) => {
return requiredPerms.includes(perm);
});
if (!hasPerm) {
el.parentNode?.removeChild(el);
}
}
}
}
export const hasAppList = (signCode:string) => {
const userStore = useUserStore();
return userStore.myPower.appKeyAry.some((perm: any) => {
return perm.includes(signCode);
});
}
/**
@ 作者: 秦东
@ 时间: 2025-12-11 16:30:08
@ 功能: 自定义App分组指令授权
*/
export const hasAppGroup: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const userStore = useUserStore();
const { value } = binding;
// console.log("app权限",el,"-->",binding,"-->",value,"-->",userStore.myPower.appGroupPower,"-->",userStore.myPower);
// console.log("我的App--->",userStore.myPower)
if (value) {
const requiredPerms = value; // DOM绑定需要的app权限标识
const hasPerm = userStore.myPower.appGroupPower.some((perm: any) => {
return requiredPerms.includes(perm);
});
if (!hasPerm) {
el.parentNode?.removeChild(el);
}
}
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-11 16:39:01
@ 功能: 判断应用级权限
*/
export const appHasPower = (signCode:string,buttonKey:string) => {
const userStore = useUserStore();
return userStore.myPower.appSystemPower.some((perm: any) => {
// console.log("判断应用级权限--->",buttonKey)
if(perm.AppId == signCode){
// console.log("判断应用级权限-1111-->",perm.AppId,buttonKey)
// console.log("判断应用级权限-222-->",perm.butPower && Array.isArray(perm.butPower))
if(perm.butPower && Array.isArray(perm.butPower)){
// console.log("判断应用级权限--->",perm.AppId,buttonKey)
return perm.butPower.includes(buttonKey)
}
}
});
}
/**
@ 作者: 秦东
@ 时间: 2025-12-12 09:33:21
@ 功能: 判断表单级权限
*/
export const formHasPower = (signCode:string,tormCode:string,buttonKey:string,classType:number) => {
const userStore = useUserStore();
// console.log("判断表单级权限-1111-->",signCode,userStore.myPower.appSystemPower)
if(userStore.myPower.appSystemPower && Array.isArray(userStore.myPower.appSystemPower)){
return userStore.myPower.appSystemPower.some((perm: any) => {
if(perm.AppId == signCode){
// console.log("判断表单级权限-1112-->",signCode)
// console.log("判断表单级权限-1113-->",tormCode)
// console.log("判断表单级权限-1114-->",perm.formPower)
// console.log("判断表单级权限-1115-->",buttonKey)
if(perm.formPower && Array.isArray(perm.formPower)){
return perm.formPower.some((formPerm: any) => {
switch(classType){
case 1:
return formPerm.AppId == tormCode && formPerm.tablePower.includes(buttonKey);
break;
case 2:
return formPerm.AppId == tormCode && formPerm.PagePower.includes(buttonKey);
break;
default:
return formPerm.AppId == tormCode && formPerm.listPower.includes(buttonKey);
break;
}
});
}
}
});
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-12 13:42:40
@ 功能: 判断自定义App菜单
*/
export const hasCustomAppMenu = (appKey:string,menuKey:string) => {
// console.log("判断自定义App菜单--->",appKey,menuKey)
const userStore = useUserStore();
if(userStore.myPower.appSystemPower && Array.isArray(userStore.myPower.appSystemPower)){
return userStore.myPower.appSystemPower.some((perm: any) => {
if(perm.AppId == appKey){
if(perm.formTrue && Array.isArray(perm.formTrue)){
return perm.formTrue.includes(menuKey);
}
}
});
}
return false;
}
//自定义App分组
export const hasGroupApp: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const userStore = useUserStore();
const { value } = binding;
// console.log("app权限appGroupMenu",el,"-->",binding,"-->",value,"-->",userStore.myPower.appGroupMenu,"-->",userStore.myPower);
// console.log("我的App--->",userStore.myPower)
if (value) {
const requiredPerms = value; // DOM绑定需要的app权限标识
const hasPerm = userStore.myPower.appGroupMenu.some((perm: any) => {
// console.log("我的App-判断值-->",requiredPerms.includes(perm))
return requiredPerms.includes(perm);
});
if (!hasPerm) {
el.parentNode?.removeChild(el);
}
}
}
}
export const hasCustomAppGroup = (appKey:string) => {
const userStore = useUserStore();
if(userStore.myPower.appGroupMenu && Array.isArray(userStore.myPower.appGroupMenu)){
return userStore.myPower.appGroupMenu.some((perm: any) => {
// console.log("--->",perm,appKey)
if (perm == appKey){
return true
}
});
}
return false;
}

97
src/layout/components/myconst/editmypassword.vue

@ -4,14 +4,64 @@
@ 备注: 修改密码
-->
<script lang='ts' setup>
import { editMyPwd } from '@/api/system/roleapi/power'
import { checkPwdRule,level } from '@/utils/CheckPassword'
const props = defineProps({
editPasswordIsShow:{
type:Boolean,
default:false
}
});
const rulePowwerFormRef = ref()
const emits = defineEmits(["update:editPasswordIsShow"]); //
const addLoading = ref(false)
const saveData = ref({
oldPassword:"",
newPassword:"",
confirmPassword:""
})
const rules = ref<any>({
oldPassword: [{ required: true, message: '请输入旧密码', trigger: 'blur' }],
newPassword: [{required: true,
validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(new Error('请确认密码'));
return;
}
const result: string = checkPwdRule(value);
if(result !== "校验通过"){
callback(new Error(result));
return;
}
callback();
// const res: string = level(value);
// callback('success');
// console.log("",rule)
},
trigger: ['blur']
}],
confirmPassword: [{required: true,
validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(new Error('请确认密码'));
return;
}
const result: string = checkPwdRule(value);
if(result !== "校验通过"){
callback(new Error(result));
return;
}
if (value !== saveData.value.newPassword) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
},
trigger: ['blur']
}],
});
/**
* 弹窗显示控制
*/
@ -42,6 +92,35 @@ const addLoading = ref(false)
*/
const submitEditPwdForm = ()=>{
addLoading.value = true
rulePowwerFormRef.value.validate((valid: any) => {
if (valid) {
//
// console.log(':', saveData.value);
//
editMyPwd(saveData.value).then(( data:any ) =>{
// console.log(':',data);
if(data.code == 0){
//
//
editMyPwdBoxClose()
//
ElMessage.success('密码修改成功');
}else{
//
//
ElMessage.error(data.msg);
}
addLoading.value = false
}).finally(() => {
addLoading.value = false
})
} else {
//
console.log('表单验证不通过');
addLoading.value = false
}
});
}
/**
* 初始化数据
@ -58,6 +137,24 @@ function initData(){
custom-class="dialog_box"
:before-close="editMyPwdBoxClose"
>
<el-form
ref="rulePowwerFormRef"
style="width: 100%"
:model="saveData"
:rules="rules"
label-width="auto"
>
<el-form-item label="原始密码" prop="oldPassword">
<el-input v-model="saveData.oldPassword" type="password" autocomplete="off" placeholder="请输入原始密码" clearable show-password />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="saveData.newPassword" type="password" autocomplete="off" placeholder="请输入新密码" clearable show-password />
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="saveData.confirmPassword" type="password" autocomplete="off" placeholder="请确认新密码" clearable show-password />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" :loading="addLoading" @click="submitEditPwdForm" > </el-button>

7
src/permission.ts

@ -42,9 +42,10 @@ router.beforeEach(async (to:any, from:any, next:any) => {
} else {
try {
// const { roles } = await userStore.getInfo();
const { perms } = await userStore.getInfo();
// console.log("路由权限---》",perms);
const accessRoutes = await permissionStore.generateRoutes(perms);
const { perms,allPowerConfig } = await userStore.getInfo();
console.log("路由权限---》",perms,allPowerConfig);
// const accessRoutes = await permissionStore.generateRoutes(perms);
const accessRoutes = await permissionStore.generateRoutes(allPowerConfig.menuIdAry);
// console.log("路由权限--perms--》",accessRoutes);
accessRoutes.forEach((route:any) => {
// console.log("路由权限--addRoutecessRoutes",route);

1
src/store/modules/knowledge.ts

@ -1,4 +1,5 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { ShowTitle } from '@/api/knowledge/types';
// 第一个参数是应用程序中 store 的唯一 id
export const useKnowledgeStore = defineStore('knowledge', {

3
src/store/modules/permission.ts

@ -104,7 +104,8 @@ export const usePermissionStore = defineStore("permission", () => {
listRoutes()
.then(({ data: asyncRoutes }) => {
// 根据角色获取有访问权限的路由
// console.log("获取到的路由---->",asyncRoutes);
console.log("获取到的路由---->",asyncRoutes);
console.log("获取到的路由--roles-->",roles);
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
// console.log("获取到的路由--1-->",accessedRoutes);

7
src/store/modules/user.ts

@ -22,6 +22,7 @@ export const useUserStore = defineStore("user", () => {
const perms = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限
const userKey = useStorage("userKey", "");
const userToken = useStorage("userToken", "");
const myPower = ref<any>("");
const userInfoCont = ref<any>("");
/**
@ -95,7 +96,7 @@ export const useUserStore = defineStore("user", () => {
// });
getUserInfoIng()
.then(({data})=>{
// console.log("获取用户信息:角色必须是非null数组!",data);
// console.log("获取用户信息:角色必须是非null数组!",data);
// debugger;
if (!data) {
return reject("验证失败,请重新登录。");
@ -108,6 +109,8 @@ export const useUserStore = defineStore("user", () => {
roles.value = data.roles;
perms.value = data.perms;
userInfoCont.value = data
myPower.value = data.allPowerConfig
console.log("myPower.value",myPower.value);
resolve(data);
})
.catch((error:any) => {
@ -139,6 +142,7 @@ export const useUserStore = defineStore("user", () => {
userKey.value = "";
userToken.value = "";
userInfoCont.value = ""
myPower.value = ""
avatar.value = "";
roles.value = [];
perms.value = [];
@ -152,6 +156,7 @@ export const useUserStore = defineStore("user", () => {
avatar,
roles,
perms,
myPower,
login,
getInfo,
logout,

307
src/utils/CheckPassword.ts

@ -0,0 +1,307 @@
/**
*
*/
const REG_NUMBER:string = ".*\\d+.*";
/**
*
*/
const REG_UPPERCASE:string = ".*[A-Z]+.*";
/**
*
*/
const REG_LOWERCASE:string = ".*[a-z]+.*";
/**
* (~!@#$%^&*()_+|<>,.?/:;'[]{}\)
*/
const REG_SYMBOL:string = ".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*";
/**
* ()
* shift键盘字符表
*/
const CHAR_TABLE1:string[][] = [
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\0'],
['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\\'],
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '\0', '\0'],
['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', '\0', '\0']];
/**
* shift键盘的字符表
*/
const CHAR_TABLE2:string[][] = [
['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\0'],
['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '{', '}', '|'],
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ':', '"', '\0', '\0'],
['z', 'x', 'c', 'v', 'b', 'n', 'm', '<', '>', '?', '\0', '\0', '\0']];
/**
*
* @param password
* @param username
*/
export const checkPasswordRule = (password:string,username:string) => {
if (password === '' || password.length < 8 || password.length > 32) {
// console.log("长度小于8,或大于32");
return "密码长度应大于8小于32";
} if (password.indexOf(username) !== -1) {
// console.log("包含用户名");
return "请勿包含用户名";
}
if (isContinuousChar(password)) {
// console.log("包含3个及以上相同或字典连续字符");
return "请勿包含3个及以上相同或连续的字符";
}
if (isKeyBoardContinuousChar(password)) {
// console.log("包含3个及以上键盘连续字符");
return "请勿包含3个及以上键盘连续字符";
}
let i:number = 0;
if (password.match(REG_NUMBER)) i++;
if (password.match(REG_LOWERCASE)) i++;
if (password.match(REG_UPPERCASE)) i++;
if (password.match(REG_SYMBOL)) i++;
if (i < 2) {
// console.log(("数字、小写字母、大写字母、特殊字符,至少包含两种"));
return "数字、小写字母、大写字母、特殊字符,至少包含两种";
}
// console.log(i);
return "校验通过";
}
/**
* 3
*/
const isContinuousChar = (password:string) => {
let chars: string[] = password.split('')
let charCode: number[] = [];
for (let i = 0; i < chars.length - 2; i++) {
charCode[i] = chars[i].charCodeAt(0)
}
for (let i = 0; i < charCode.length - 2; i++) {
let n1 = charCode[i];
let n2 = charCode[i + 1];
let n3 = charCode[i + 2];
// 判断重复字符
if (n1 == n2 && n1 == n3) {
return true;
}
// 判断连续字符: 正序 + 倒序
if ((n1 + 1 == n2 && n1 + 2 == n3) || (n1 - 1 == n2 && n1 - 2 == n3)) {
return true;
}
}
return false;
}
/**
* 3
* @param password
*/
const isKeyBoardContinuousChar = (password:string) => {
if (password === '') {
return false;
}
//考虑大小写,都转换成小写字母
let lpStrChars: string[] = password.toLowerCase().split('')
// 获取字符串长度
let nStrLen: number = lpStrChars.length;
// 定义位置数组:row - 行,col - column 列
const pRowCharPos:number[] = new Array(nStrLen).fill('')
const pColCharPos: number[] = new Array(nStrLen).fill('')
for (let i = 0; i < nStrLen; i++) {
let chLower: string = lpStrChars[i];
pColCharPos[i] = -1;
// 检索在表1中的位置,构建位置数组
for (let nRowTable1Idx = 0; nRowTable1Idx < 4; nRowTable1Idx++) {
for (let nColTable1Idx = 0; nColTable1Idx < 13; nColTable1Idx++) {
if (chLower == CHAR_TABLE1[nRowTable1Idx][nColTable1Idx]) {
pRowCharPos[i] = nRowTable1Idx;
pColCharPos[i] = nColTable1Idx;
}
}
}
// 在表1中没找到,到表二中去找,找到则continue
if (pColCharPos[i] >= 0) {
continue;
}
// 检索在表2中的位置,构建位置数组
for (let nRowTable2Idx = 0; nRowTable2Idx < 4; nRowTable2Idx++) {
for (let nColTable2Idx = 0; nColTable2Idx < 13; nColTable2Idx++) {
if (chLower == CHAR_TABLE2[nRowTable2Idx][nColTable2Idx]) {
pRowCharPos[i] = nRowTable2Idx;
pColCharPos[i] = nColTable2Idx;
}
}
}
}
// 匹配坐标连线
for (let j = 1; j <= nStrLen - 2; j++) {
//同一行
if (pRowCharPos[j - 1] == pRowCharPos[j] && pRowCharPos[j] == pRowCharPos[j + 1]) {
// 键盘行正向连续(asd)或者键盘行反向连续(dsa)
if ((pColCharPos[j - 1] + 1 == pColCharPos[j] && pColCharPos[j] + 1 == pColCharPos[j + 1]) ||
(pColCharPos[j + 1] + 1 == pColCharPos[j] && pColCharPos[j] + 1 == pColCharPos[j - 1])) {
return true;
}
}
//同一列
if (pColCharPos[j - 1] == pColCharPos[j] && pColCharPos[j] == pColCharPos[j + 1]) {
//键盘列连续(qaz)或者键盘列反向连续(zaq)
if ((pRowCharPos[j - 1] + 1 == pRowCharPos[j] && pRowCharPos[j] + 1 == pRowCharPos[j + 1]) ||
(pRowCharPos[j - 1] - 1 == pRowCharPos[j] && pRowCharPos[j] - 1 == pRowCharPos[j + 1])) {
return true;
}
}
}
return false;
}
/**
*
*/
/**
*
* @param str
*/
const length = (str:string) => {
if(str.length<5){
return 5;
}else if(str.length<8){
return 10;
}else{
return 25;
}
}
/**
*
* @param str
*/
const letters = (str: string) => {
let count1=0,count2=0;
for(let i=0;i<str.length;i++){
if(str.charAt(i)>='a'&&str.charAt(i)<='z'){
count1++;
}
if(str.charAt(i)>='A'&&str.charAt(i)<='Z'){
count2++;
}
}
if(count1==0 && count2==0){
return 0;
}
if(count1!=0 && count2!=0){
return 20;
}
return 10;
}
/**
*
* @param str
*/
const numbers = (str: string) => {
let count=0;
for(let i=0;i<str.length;i++){
if(str.charAt(i)>='0'&&str.charAt(i)<='9'){
count++;
}
}
if(count==0){
return 0;
}
if(count==1){
return 10;
}
return 20;
}
/**
*
* @param str
*/
const symbols = (str: string) => {
let count=0;
for(let i=0;i<str.length;i++){
if(str.charCodeAt(i)>=0x21 && str.charCodeAt(i)<=0x2F ||
str.charCodeAt(i)>=0x3A && str.charCodeAt(i)<=0x40 ||
str.charCodeAt(i)>=0x5B && str.charCodeAt(i)<=0x60 ||
str.charCodeAt(i)>=0x7B && str.charCodeAt(i)<=0x7E ){
count++;
}
}
if(count==0){
return 0;
}
if(count==1){
return 10;
}
return 25;
}
/**
*
* @param str
*/
const rewards = (str: string) => {
let letter=letters(str);//字母
let number=numbers(str);//数字
let symbol=symbols(str);//符号
if(letter>0 && number>0 && symbol==0){//字母和数字
return 2;
}
if(letter==10 && number>0 && symbol>0){//字母、数字和符号
return 3;
}
if(letter==20 && number>0 && symbol>0){//大小写字母、数字和符号
return 5;
}
return 0;
}
/**
*
* @param str
*/
export const level = (str: string) => {
let lengths=length(str);//长度
let letter=letters(str);//字母
let number=numbers(str);//数字
let symbol=symbols(str);//符号
let reward=rewards(str);//奖励
let sum=lengths+letter+number+symbol+reward;
console.log(sum);
if(sum>=80){
return "非常强";//非常安全
}else if(sum>=60){
return "强";//非常强
}else if(sum>=40){
return "一般";//一般
}else if(sum>=25){
return "弱";//弱
}else{
return "非常弱";//非常弱
}
}
export const checkPwdRule = (password:string) => {
if (password === '' || password.length < 8 || password.length > 32) {
// console.log("长度小于8,或大于32");
return "密码长度应大于8小于32";
}
if (isContinuousChar(password)) {
// console.log("包含3个及以上相同或字典连续字符");
return "请勿包含3个及以上相同或连续的字符";
}
if (isKeyBoardContinuousChar(password)) {
// console.log("包含3个及以上键盘连续字符");
return "请勿包含3个及以上键盘连续字符";
}
let i:number = 0;
if (password.match(REG_NUMBER)) i++;
if (password.match(REG_LOWERCASE)) i++;
if (password.match(REG_UPPERCASE)) i++;
if (password.match(REG_SYMBOL)) i++;
if (i < 2) {
// console.log(("数字、小写字母、大写字母、特殊字符,至少包含两种"));
return "数字、小写字母、大写字母、特殊字符,至少包含两种";
}
// console.log(i);
return "校验通过";
}

52
src/utils/workflow/const.ts

@ -406,10 +406,54 @@ export let appTableBut = [
@ 功能: 列表按钮
*/
export let appListBut = [
{ label: '新增',value: 'xz',key:1},
{ label: '导入',value: 'dr',key:2},
{ label: '导出 ',value: 'dc',key:3},
{ label: '新增',value: 'newAdd',key:1},
{ label: '导入',value: 'import',key:2},
{ label: '导出 ',value: 'export',key:3},
{ label: '删除',value: 'sc',key:4},
{ label: '打印',value: 'dy',key:5},
{ label: '打印二维码',value: 'dyewm',key:6}
{ label: '打印二维码',value: 'showQrCode',key:6},
{ label: '批量删除',value: 'del',key:7},
{ label: '编辑',value: 'bj',key:8},
]
/**
@ 作者: 秦东
@ 时间: 2025-05-15 08:06:57
@ 功能: 自定义App详情按钮
*/
export let appDetailBut = [
{ label: '编辑App',value: 'bjapp',key:1},
{ label: '删除App',value: 'scapp',key:2},
{ label: '新增表单分组',value: 'xzfg',key:3},
{ label: '删除表单分组',value: 'scfg',key:4},
{ label: '移动表单分组',value: 'yzfg',key:5},
{ label: '新增表单',value: 'xz',key:6},
{ label: '编辑表单',value: 'bj',key:7},
{ label: '删除表单',value: 'sc',key:8},
{ label: '移动表单',value: 'yz',key:9},
{ label: '集成&自动化',value: 'jczdh',key:10},
{ label: '应用设置',value: 'yysz',key:11},
{ label: '应用发布',value: 'yyfb',key:12},
]
/**
@ 作者: 秦东
@ 时间: 2025-12-10 14:09:42
@ 功能: 表单基础功能
*/
export let formBaseBut = [
{ label: '流程设计',value: 'lc',key:1},
{ label: '列表设计',value: 'lb',key:2},
{ label: '数据看板',value: 'sj',key:3},
{ label: '打印设计',value: 'dy',key:4},
{ label: '内容呈现设计',value: 'nc',key:5},
]
/**
@ 作者: 秦东
@ 时间: 2025-12-10 14:11:25
@ 功能: 自定义App分组级权限
*/
export let appGroupBut = [
{ label: '新增分组',value: 'xz',key:1},
{ label: '删除分组',value: 'dl',key:2},
{ label: '编辑分组',value: 'bj',key:3},
{ label: '新增App',value: 'xzapp',key:4},
]

34
src/utils/workflow/index.ts

@ -62,10 +62,10 @@ All.prototype = {
console.log("setApproverStr---签字解析--->",nodeConfig);
if (nodeConfig.settype == 1) {
if (nodeConfig.nodeUserList.length == 1) {
nodeConfig.error=false
nodeConfig.error = false;
return nodeConfig.nodeUserList[0].name
} else if (nodeConfig.nodeUserList.length > 1) {
nodeConfig.error=false
nodeConfig.error = false;
if (nodeConfig.examineMode == 1) {
return this.arrToStr(nodeConfig.nodeUserList)
} else if (nodeConfig.examineMode == 2) {
@ -77,18 +77,21 @@ All.prototype = {
// return "指定成员"
}
} else if (nodeConfig.settype == 2) {
nodeConfig.error=false
let level = nodeConfig.directorLevel == 1 ? '直接主管' : '第' + nodeConfig.directorLevel + '级主管'
if (nodeConfig.examineMode == 1) {
nodeConfig.error = false;
return level
} else if (nodeConfig.examineMode == 2) {
nodeConfig.error = false;
return level + "会签"
}else if (nodeConfig.examineMode == 3) {
nodeConfig.error = false;
return level + + "或签"
}
} else if (nodeConfig.settype == 3) {
nodeConfig.error=false
// console.log("nodeConfig==会签==>",nodeConfig)
nodeConfig.error = false;
if (nodeConfig.nodeUserList.length == 1) {
return nodeConfig.nodeUserList[0].name
}else{
@ -97,11 +100,11 @@ All.prototype = {
} else if (nodeConfig.settype == 4) {
// console.log("nodeConfig.selectRange",nodeConfig.selectRange,nodeConfig.nodeUserList);
if (nodeConfig.selectRange == 1) {
nodeConfig.error=false
nodeConfig.error = false;
return "发起人自选"
} else {
if (nodeConfig.nodeUserList.length > 0) {
nodeConfig.error=false
nodeConfig.error = false;
if (nodeConfig.selectRange == 2) {
return "发起人从指定成员中自选"
} else {
@ -112,20 +115,19 @@ All.prototype = {
}
}
} else if (nodeConfig.settype == 5) {
nodeConfig.error=false
nodeConfig.error = false;
return "发起人自己"
} else if (nodeConfig.settype == 6) {
nodeConfig.error=false
nodeConfig.error = false;
// console.log("nodeConfig==直接主管==>",nodeConfig)
return '从直接主管到通讯录中级别最高的第' + nodeConfig.examineEndDirectorLevel + '个层级主管'
}else if (nodeConfig.settype == 7){
nodeConfig.error=false
nodeConfig.error = false;
return "指定前置审批为本节点设置审批人"
}else if (nodeConfig.settype == 8){
// console.log("checkedFormList--1111->",nodeConfig)
if(nodeConfig.nodeUserList.length > 0){
nodeConfig.error=false
nodeConfig.error = false;
if (nodeConfig.examineMode == 1) {
return nodeConfig.nodeUserList[0].name + "依次审批"
} else if (nodeConfig.examineMode == 2) {
@ -139,7 +141,7 @@ All.prototype = {
console.log("setApproverStr---签字解析--9->",nodeConfig.matrix.list);
if(nodeConfig.matrix && nodeConfig.matrix.list){
let strVal = ""
nodeConfig.error=false
if(nodeConfig.matrix.list.length > 0){
nodeConfig.matrix.list.forEach((item:any,inx:number)=>{
if (inx > 0) {
@ -148,7 +150,7 @@ All.prototype = {
strVal += item.outcomeName;
})
}
nodeConfig.error = false;
if (nodeConfig.examineMode == 1) {
return strVal + "依次审批"
} else if (nodeConfig.examineMode == 2) {
@ -156,9 +158,10 @@ All.prototype = {
}else if (nodeConfig.examineMode == 3) {
return strVal + "或签"
}
}else{
if(nodeConfig.matrix && nodeConfig.matrix.outcomeName){
nodeConfig.error=false
nodeConfig.error = false;
let strVal = nodeConfig.matrix.outcomeName
if (nodeConfig.examineMode == 1) {
return strVal + "依次审批"
@ -167,12 +170,13 @@ All.prototype = {
}else if (nodeConfig.examineMode == 3) {
return strVal + "或签"
}
}
}
}else if (nodeConfig.settype == 10){
nodeConfig.error=false
nodeConfig.error = false;
return "指定部门负责人"
}
},

5
src/views/hr/archives/archivescont.vue

@ -57,7 +57,7 @@ const userIcon = ref<string>(); //人员头像
const boxTitle = ref<string>(); //
const userConting = ref<any>(""); //
const rowLoading = ref(false);
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API + "/api/upordown"; //
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API+"/setupFile/uploads/oneFileUpload";//
const editMyOrgCont = ref(false); //
const editMyCont = ref(false); //
/**
@ -134,11 +134,14 @@ const handleAvatarSuccess: UploadProps["onSuccess"] = (
uploadFiles
) => {
userIcon.value = URL.createObjectURL(uploadFile.raw!);
// console.log("-------------------->", uploadFile);
// console.log("-------------------->", props.archivesdata.id);
//
editMyInfoIcon({
id: props.archivesdata.id,
iconpath: response.data.url,
}).then((data) => {
fileUploadIng.value = false;
ElMessage.success("编辑成功");
emits("getarchivespageclick");
});

1609
src/views/hr/archives/index.vue

File diff suppressed because it is too large

200
src/views/hr/archives/index_20251202.vue

@ -0,0 +1,200 @@
<!--
@ 作者: 秦东
@ 时间: 2025-11-28 10:11:16
@ 备注: 人员列表
-->
<script lang='ts' setup>
import { emptypeOptions } from "@/api/hr/people/datacont";
import { orgInfo } from "@/api/hr/org/type";
import { authorizeOrgTree } from '@/api/system/roleapi/power'
import {
teamcontlist
} from "@/api/hr/org/index";
const orgTreeRef = ref(ElTree); //
const orgTreeLoading = ref(false); //
const orgTreeList = ref<orgInfo[]>(); //
const tiemList = ref([]); //
const orgTreeProps = {
children: "child",
label: "name",
}; //
const searchInfo = reactive({
orgId:"",
name:"",
employ:"",
team:"",
joinTime:""
})
const getOrgPowerTrue = () => {
orgTreeLoading.value = true
let sendInfo = {
menuId:"50"
}
authorizeOrgTree(sendInfo).then((res) => {
console.log(res)
orgTreeList.value = res.data
orgTreeLoading.value = false
}).finally(() => {
orgTreeLoading.value = false
})
}
/**
@ 作者: 秦东
@ 时间: 2025-01-14 10:27:12
@ 功能: 获取班组列表
*/
const gainTimeList = () => {
let searchMap = {
page: 1,
pagesize: 2000,
name: "",
};
teamcontlist(searchMap).then((data) => {
tiemList.value = data.data.list;
});
};
const resetChecked = () => {
orgTreeRef.value.setCheckedKeys([])
}
/**
* 选中行政组织树节点
*/
const handleOrgTreeNodeClick = (data: orgInfo) => {
// console.log(data)
searchInfo.orgId = data.id;
// getArchivesPage();
};
onMounted(() => {
getOrgPowerTrue();
gainTimeList();
})
</script>
<template>
<div class="app-content">
<el-container>
<el-aside width="300px" style="padding: 10px 10px">
<el-card :body-style="{ height: 'calc(100vh - 190px)', padding: '0px 5px' }">
<el-button
type="primary"
style="width: 100%; margin: 10px 0"
@click="resetChecked"
>
查看全部
</el-button>
<el-tree-v2
style="max-width: 100%"
:data="orgTreeList"
:props="orgTreeProps"
v-loading="orgTreeLoading"
node-key="id"
:expand-on-click-node="false"
:check-on-click-node="true"
:check-strictly="true"
:default-expand-all="false"
:height="1200"
@node-click="handleOrgTreeNodeClick"
/>
</el-card>
</el-aside>
<el-main style="padding: 10px 10px 0 0">
<el-card :body-style="{ height: 'calc(100vh - 190px)', padding: '0px 15px' }">
<el-form ref="searchForm" :model="searchInfo" :inline="true" style="width: 100%; margin-top: 10px;">
<el-form-item label="工号 / 姓名 / 手机号" prop="keywords">
<el-input
v-model="searchInfo.name"
placeholder="请输入工号/姓名/手机号"
clearable
/>
</el-form-item>
<el-form-item label="用工关系" prop="number">
<el-select
v-model="searchInfo.employ"
multiple
clearable
collapse-tags
placeholder="用工关系"
style="width: 200px"
>
<el-option
v-for="item in emptypeOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="班组" prop="number">
<el-select
v-model="searchInfo.team"
clearable
collapse-tags
placeholder="员工班组"
style="width: 240px"
>
<el-option
v-for="item in tiemList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="入职日期" prop="number">
<el-date-picker
v-model="searchInfo.joinTime"
type="date"
placeholder="入职日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item label="" prop="number">
<el-button type="primary" @click="getArchivesPage">
<template #icon><i-ep-search /></template>
搜索
</el-button>
<el-button @click="resetArcFormQuery">
<template #icon><i-ep-refresh /></template>
重置
</el-button>
</el-form-item>
</el-form>
<div class="func-but">
<el-button v-hasButton="[215437071358111744]" type="primary" @click="handleAddArchives">
<template #icon><i-ep-plus /></template>
新增
</el-button>
<el-button
v-hasPerm="['215437153071542272']"
plain
type="primary"
@click="openPiliangBox"
>
<el-icon><MessageBox /></el-icon>
批量导入数据
</el-button>
</div>
</el-card>
</el-main>
</el-container>
</div>
</template>
<style lang='scss' scoped>
.app-content {
height: calc(100vh - 170px);
background-color: aqua;
:deep .el-drawer__body {
padding: 0 10px;
}
}
.common-layout {
}
</style>

1465
src/views/hr/archives/index_251128.vue

File diff suppressed because it is too large

274
src/views/hr/archives/unitpage/addUserPage.vue

@ -0,0 +1,274 @@
<!--
@ 作者: 秦东
@ 时间: 2025-12-03 14:22:19
@ 备注: 添加人员
-->
<script lang='ts' setup>
import { addNewPeople } from "@/api/system/roleapi/power";
import defaultImg from "@/assets/images/1.png";
const props = defineProps({
show: {
type: Boolean,
default: false
},
orgTree: {
type: Array as PropType<orgInfo[]>,
default: () => []
}
})
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API+"/setupFile/uploads/oneFileUpload";//
const emit = defineEmits(['update:show','updateInfo'])
const ubLockPage = computed(() => props.show)
const orgTreeList = computed(() => props.orgTree) //
const butLoading = ref(false)
const fileUploadIng = ref(false);
const systemMenuTreeProps = {
children: "child",
label: "name",
value:"id"
} //
const formRef = ref<any>();
const rules = ref<any>({
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
code: [{ required: true, message: '请输入工号', trigger: 'blur' }],
orgId: [{ required: true, message: '请选择行政组织', trigger: 'change' }],
employment: [{ required: true, message: '请输入用工关系', trigger: 'blur' }],
mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
});
const userInfo = ref({
name: "",
code: "",
mobile: "",
nation: "",
sex: "1",
age: "",
oldName: "",
icon: defaultImg,
orgId:"",
employment:"",
address:""
})
/**
@ 作者: 秦东
@ 时间: 2025-12-03 14:26:25
@ 功能: 关闭
*/
const closeLock = () => {
emit('update:show', false)
emit('updateInfo')
userInfo.value.icon = defaultImg
butLoading.value = false
formRef.value.resetFields();
}
/**
@ 作者: 秦东
@ 时间: 2025-12-03 15:40:14
@ 功能: 提交数据
*/
const onSubmit = () => {
butLoading.value = true
formRef.value.validate((valid) => {
if (valid) {
//
addNewPeople(userInfo.value).then((res) => {
if (res.code == 0) {
ElMessage.success("新增成功");
closeLock();
} else {
ElMessage.error(res.msg);
}
butLoading.value = false
})
} else {
butLoading.value = false
}
});
}
/**
@ 作者: 秦东
@ 时间: 2024-08-31 14:35:18
@ 功能: 上传前判断类型
*/
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
fileUploadIng.value = true;
if (!/\.(png|jpg|gif|jpeg|svg|bmp)$/.test(rawFile.name)) {
ElMessage.warning("您上传的图片不符合要求!");
fileUploadIng.value = false;
return false;
}
};
/**
@ 作者: 秦东
@ 时间: 2024-08-31 14:40:31
@ 功能: 上传成功
*/
const handleAvatarSuccess: UploadProps["onSuccess"] = (
response,
uploadFile,
uploadFiles
) => {
userInfo.value.icon = URL.createObjectURL(uploadFile.raw!);
// console.log("-------------------->", uploadFile);
// console.log("-------------------->", props.archivesdata.id);
fileUploadIng.value = false;
ElMessage.success("上传成功");
};
</script>
<template>
<el-dialog
v-model="ubLockPage"
title="新增人员信息"
width="650"
draggable
:destroy-on-close="true"
:before-close="closeLock"
>
<el-form :model="userInfo" :rules="rules" ref="formRef" label-width="80px">
<table>
<tr>
<td>
<el-form-item label="姓名" prop="name">
<el-input v-model="userInfo.name" placeholder="请输入姓名" />
</el-form-item>
</td>
<td>
<el-form-item label="曾用名" prop="oldName">
<el-input v-model="userInfo.oldName" placeholder="请输入曾用名" />
</el-form-item>
</td>
</tr>
<tr>
<td>
<el-form-item label="工号" prop="code">
<el-input v-model="userInfo.code" placeholder="请输入工号" />
</el-form-item>
</td>
<td rowspan="3" align="center">
<el-upload
class="avatar-uploader"
:action="imgUploadApiUrl"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
v-loading="fileUploadIng"
>
<el-avatar shape="square" :size="180" :src="userInfo.icon" class="bianKuang" />
</el-upload>
</td>
</tr>
<tr>
<td>
<el-form-item label="民族" prop="nation">
<el-input v-model="userInfo.nation" placeholder="请输入民族" />
</el-form-item>
</td>
</tr>
<tr>
<td>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="userInfo.sex">
<el-radio label="1"></el-radio>
<el-radio label="2"></el-radio>
</el-radio-group>
</el-form-item>
</td>
</tr>
<tr>
<td colspan="2">
<el-form-item label="归属部门" prop="orgId">
<el-tree-select
v-model="userInfo.orgId"
:data="orgTreeList"
check-strictly
:render-after-expand="false"
:props="systemMenuTreeProps"
style="width: 100%"
clearable
/>
</el-form-item>
</td>
</tr>
<tr>
<td>
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="userInfo.mobile" placeholder="请输入联系电话" />
</el-form-item>
</td>
<td>
<el-form-item label="用工关系" prop="employment">
<el-select v-model="userInfo.employment" placeholder="请选择用工关系" style="width: 100%">
<el-option label="临时工" value="1" />
<el-option label="编外人员" value="2" />
<el-option label="实习&实习生" value="3" />
<el-option label="试用员工" value="4" />
<el-option label="待分配" value="5" />
<el-option label="待岗" value="6" />
<el-option label="临时调入" value="7" />
<el-option label="正式员工" value="8" />
<el-option label="长期病假" value="9" />
<el-option label="停薪留职" value="10" />
<el-option label="退休" value="11" />
<el-option label="辞职" value="12" />
<el-option label="辞退" value="13" />
<el-option label="离职" value="14" />
</el-select>
</el-form-item>
</td>
</tr>
<tr>
<td>
<el-form-item label="出生日期" prop="age">
<el-date-picker
v-model="userInfo.age"
type="date"
placeholder="请选择出生日期"
format="YYYY/MM/DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</td>
<td>
<el-form-item label="联系地址" prop="address">
<el-input v-model="userInfo.address" placeholder="请输入联系地址" />
</el-form-item>
</td>
</tr>
<tr>
<td>
<el-form-item label="身体状况" prop="bodyStatus">
<el-select v-model="userInfo.bodyStatus" placeholder="请选择身体状况" style="width: 100%">
<el-option label="良好" value="1" />
<el-option label="一般" value="2" />
<el-option label="较弱" value="3" />
<el-option label="有生理缺陷" value="4" />
<el-option label="有生理缺陷" value="4" />
</el-select>
</el-form-item>
</td>
<td>
<el-form-item label="婚姻状况" prop="marriageStatus">
<el-select v-model="userInfo.marriageStatus" placeholder="请选择婚姻状况" style="width: 100%">
<el-option label="未婚" value="1" />
<el-option label="已婚" value="2" />
<el-option label="离异" value="4" />
<el-option label="丧偶" value="3" />
</el-select>
</el-form-item>
</td>
</tr>
</table>
<div class="flex justify-center">
<el-button type="primary" :loading="butLoading" @click="onSubmit">提交</el-button>
<el-button @click="closeLock">取消</el-button>
</div>
</el-form>
</el-dialog>
</template>
<style lang='scss' scoped>
.bianKuang {
border: 1px solid #ccc;
}
</style>

235
src/views/hr/archives/unitpage/batchImport.vue

@ -0,0 +1,235 @@
<!--
@ 作者: 秦东
@ 时间: 2025-12-02 16:17:37
@ 备注: 批量导入
-->
<script lang='ts' setup>
import { orgInfo } from "@/api/hr/org/type";
import {
analysisRedisOrgExelect,
} from "@/api/hr/people/index";
import { ElScrollbar as ElScrollbarType } from "element-plus";
const uploadFFurl = import.meta.env.VITE_APP_BASE_API + "/hrapi/staff/uploadUserFilesRedis";
const props = defineProps({
show: {
type: Boolean,
default: false
},
orgTree: {
type: Array as PropType<orgInfo[]>,
default: () => []
}
})
const ubLockPage = computed(() => props.show)
const emit = defineEmits(['update:show','updateInfo'])
const closeUploadTemp = () => {
emit('update:show', false)
emit('updateInfo')
tempForm.orgId = ""
excelLoading.value = false;
excelJiexi.value = false;
}
const orgTreeList = computed(() => props.orgTree) //
const excelLoading = ref(false);
const excelJiexi = ref(false);
const tempForm = reactive({
orgId: "",
});
const systemMenuTreeProps = {
children: "child",
label: "name",
value:"id"
}
const excelUpload = ref<any>();
let peopleListAry = new Array(); //
const peopleMsg = ref<string[]>([]);
let jiBuQiVal = 0;
const progressSize = ref(0);
const meritsYearIng = ref<any>();
const rewPunYearsIng = ref<any>();
const redisListKey = ref<string>();
const totalNum = ref<number>();
const innerRef = ref<HTMLDivElement>();
const scrollbarRef = ref<InstanceType<typeof ElScrollbarType>>();
/**
@ 作者: 秦东
@ 时间: 2025-12-02 16:53:45
@ 功能: 上传前检查
*/
function handleExcelChangeTemp(file: UploadFile) {
excelLoading.value = true;
if (tempForm.orgId == 0 || tempForm.orgId == "") {
ElMessage.warning("对不起!你没有选定上传的是哪个行政组织得人员信息!");
excelLoading.value = false;
return false;
}
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
ElMessage.warning("上传Excel只能为xlsx、xls格式");
excelLoading.value = false;
return false;
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-02 16:55:17
@ 功能: 上传失败
*/
const uploadError = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
excelLoading.value = true;
// console.log("1response",response);
// console.log("1uploadFile",uploadFile);
// console.log("1uploadFiles",uploadFiles);
let msgAry = new Array();
msgAry.push(
"响应时间过长,系统自动转为后台静默处理,可先关闭窗口!完成时间大约90分钟。请于90分钟后刷新信息"
);
// errorMsg = ["9090"]
peopleListAry.value = msgAry;
};
/**
@ 作者: 秦东
@ 时间: 2025-12-02 16:56:39
@ 功能: 上传成功
*/
const uploadTrue = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
excelLoading.value = false;
// console.log("response", response);
// console.log("uploadFile",uploadFile);
// console.log("uploadFiles",uploadFiles);
peopleListAry.push("文件上传成功!开始解析数据并写入数据库!");
peopleMsg.value.push("文件上传成功!开始解析数据并写入数据库!");
// peopleListAry.value.push("")
// console.log("",response.code)
if (response.code == 0) {
jiBuQiVal = 0;
progressSize.value = 0;
excelJiexi.value = true;
meritsYearIng.value = response.data.meritsYearIng;
rewPunYearsIng.value = response.data.rewPunYearsIng;
redisListKey.value = response.data.redisListKey;
totalNum.value = response.data.totalNum;
// console.log("===>", staffChengji);
insetPeopleCont();
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-02 17:01:05
@ 功能: 写入数据库
*/
const insetPeopleCont = () => {
console.log("启动数据写入数据库===============》", jiBuQiVal, totalNum.value,jiBuQiVal < totalNum.value);
if (jiBuQiVal < totalNum.value) {
let sendData = {
meritsYearIng: meritsYearIng.value,
rewPunYearsIng: rewPunYearsIng.value,
redisListKey: redisListKey.value,
number: jiBuQiVal,
orgId: tempForm.orgId.toString(),
};
console.log("启动数据写入数据库", sendData);
analysisRedisOrgExelect(sendData).then((data: any) => {
console.log("启动数据写入11111数据库",data,data.data.msgStr)
peopleMsg.value.push(data.data.msgStr);
jiBuQiVal++;
// if (jibuq+ 1 >= totalNum.value){
// }
progressSize.value = Math.round((jiBuQiVal / totalNum.value) * 10000) / 100;
insetPeopleCont();
nextTick(() => {
handleClick();
});
});
} else {
excelJiexi.value = false;
progressSize.value = 100;
excelUpload.value.clearFiles();
}
};
const handleClick = () => {
nextTick(() => {
// console.log("",innerRef.value!.clientHeight)
if (innerRef.value!.clientHeight > 300) {
scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight);
}
});
};
</script>
<template>
<el-dialog
v-model="ubLockPage"
title="批量导入人员信息"
width="800"
draggable
:destroy-on-close="true"
:before-close="closeUploadTemp"
>
<el-row v-loading="excelLoading" element-loading-text="文档上传中,请稍候..." style="width: 100%">
<el-col :span="24">
<el-form :model="tempForm" label-width="auto" style="width: 100%">
<el-form-item label="请选择上传那个公司的人员信息">
<el-tree-select
v-model="tempForm.orgId"
:data="orgTreeList"
check-strictly
:render-after-expand="false"
:props="systemMenuTreeProps"
style="width: 100%"
clearable
/>
</el-form-item>
</el-form>
</el-col>
<el-col
:span="24"
v-loading="excelJiexi"
element-loading-text="文档解析中,请稍候..."
>
<el-upload
ref="excelUpload"
class="upload-demo"
drag
:action="uploadFFurl"
:data="{ orgId: tempForm.orgId.toString() }"
:before-upload="handleExcelChangeTemp"
:on-success="uploadTrue"
:on-error="uploadError"
:show-file-list="false"
multiple
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将电子表格拖到此处或 <em>单击上载</em></div>
</el-upload>
</el-col>
</el-row>
<el-row style="width: 100%;">
<el-col :span="24">
<el-progress
:text-inside="true"
:stroke-width="20"
:percentage="progressSize"
>
<span>已完成{{ progressSize }}%</span>
</el-progress>
</el-col>
</el-row>
<el-scrollbar height="300px" ref="scrollbarRef" always style="padding:10px 20px;">
<div ref="innerRef">
<p
v-for="(item, index) in peopleMsg"
:key="index"
class="scrollbar-demo-item"
>
{{ item }}
</p>
</div>
</el-scrollbar>
</el-dialog>
</template>
<style lang='scss' scoped>
.app-content {
}
</style>

96
src/views/hr/archives/unitpage/lockInfo.vue

@ -0,0 +1,96 @@
<!--
@ 作者: 秦东
@ 时间: 2025-12-02 15:50:46
@ 备注: 解除人员信息锁
-->
<script lang='ts' setup>
import {
jiechuUserLock,
} from "@/api/hr/org/index";
const props = defineProps({
show: {
type: Boolean,
default: false
}
})
const ubLockPage = computed(() => props.show)
const emit = defineEmits(['update:show','updateInfo'])
const unLockForm = reactive({
numText: "",
});
/**
@ 作者: 秦东
@ 时间: 2025-12-02 15:53:20
@ 功能: 关闭解锁弹窗
*/
const closeLock = () => {
emit('update:show', false)
emit('updateInfo')
}
const ruleFormRefLock = ref(null);
var butLoad = ref(false);
//
const picksubus = () => {
butLoad.value = true;
ruleFormRefLock.value.validate((isValid: boolean) => {
if (isValid) {
jiechuUserLock({ userId: unLockForm.numText })
.then((res: any) => {
butLoad.value = false;
closeLock()
})
.finally(() => {
butLoad.value = false;
});
} else {
butLoad.value = false;
}
});
};
const resetForm = () => {
closeLock();
ruleFormRefLock.value.resetFields();
};
</script>
<template>
<el-dialog
v-model="ubLockPage"
title="清除锁定人员信息锁"
width="500"
draggable
:destroy-on-close="true"
:before-close="closeLock"
>
<el-form
ref="ruleFormRefLock"
:model="unLockForm"
:rules="editTitleRules"
label-width="80"
style="width: 100%"
>
<el-form-item label="工号" prop="numText">
<el-text>请输入工号以英文逗号隔开(,)</el-text>
<el-input
v-model="unLockForm.numText"
type="textarea"
placeholder="请输入工号;以英文逗号隔开(,)"
clearable
:autosize="{ minRows: 4, maxRows: 10 }"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" v-loading="butLoad" @click="picksubus">
确定
</el-button>
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<style lang='scss' scoped>
.app-content {
}
</style>

222
src/views/hr/archives/unitpage/uploadTemplate.vue

@ -0,0 +1,222 @@
<!-- eslint-disable vue/no-side-effects-in-computed-properties -->
<!--
@ 作者: 秦东
@ 时间: 2025-12-03 10:44:56
@ 备注: 上传模版
-->
<script lang='ts' setup>
import { orgInfo } from "@/api/hr/org/type";
import {
uploadUserTemplate
} from "@/api/hr/org/index";
import { uploadUrl } from "@/api/DesignForm";
const props = defineProps({
show: {
type: Boolean,
default: false
},
orgTree: {
type: Array as PropType<orgInfo[]>,
default: () => []
},
ruleForm: {
type: Object as PropType<typeof ruleForm>,
default: () => ({})
}
})
const addTemLoading = ref(false);
let peopleListAry = new Array();
const excelLoading = ref(false);
const excelUploadUs = ref();
const emits = defineEmits(['update:show'])
const ruleFormRef = ref<any>();
const ruleFormIng = ref({
id: "",
orgId: "",
fileName: "",
filePath: "",
fileUrl: "",
});
const orgTreePropsBut = {
children: "child",
value: "id",
label: "name",
}; //
const orgTreeList = computed(() => props.orgTree) //
const ubLockPage = computed({
get: () =>{
if(props.show){
ruleFormIng.value.id = props.ruleForm.id
ruleFormIng.value.orgId = props.ruleForm.orgId
ruleFormIng.value.fileName = props.ruleForm.fileName
ruleFormIng.value.filePath = props.ruleForm.filePath
ruleFormIng.value.fileUrl = props.ruleForm.fileUrl
}
return props.show
},
set: (val) => {
emits("update:show", val);
},
})
/**
@ 作者: 秦东
@ 时间: 2024-04-19 13:13:18
@ 功能: 表单验证规则
*/
const dataFormRules = reactive({
orgId: [{ required: true, message: "请选择行政组织", trigger: "blur" }],
fileName: [{ required: true, message: "请上传模版文件", trigger: "blur" }],
});
//
const tempOpenClose = () => {
emits('update:show', false)
ruleFormIng.value.id = ""
ruleFormIng.value.orgId = 0
ruleFormIng.value.fileName = ""
ruleFormIng.value.filePath = ""
ruleFormIng.value.fileUrl = ""
}
//
const handleExcelChange = (file: UploadFile) => {
excelLoading.value = true;
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
ElMessage.warning("上传Excel只能为xlsx、xls格式");
excelLoading.value = false;
return false;
}
}
/**
@ 作者: 秦东
@ 时间: 2024-08-24 14:46:32
@ 功能: 文件上传成功
*/
const uploadTrueUs = (
response: any,
uploadFile: UploadFile,
uploadFiles: UploadFiles
) => {
// console.log("response",response);
// console.log("uploadFile",uploadFile);
// console.log("uploadFiles",uploadFiles);
excelLoading.value = false;
ruleFormIng.value.fileName = uploadFile.name;
ruleFormIng.value.filePath = response.data.physicspath;
ruleFormIng.value.fileUrl = response.data.url;
};
/**
@ 作者: 秦东
@ 时间: 2025-12-03 11:02:30
@ 功能: 文件上传失败
*/
const uploadError = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
excelLoading.value = true;
// console.log("1response",response);
// console.log("1uploadFile",uploadFile);
// console.log("1uploadFiles",uploadFiles);
let msgAry = new Array();
msgAry.push(
"响应时间过长,系统自动转为后台静默处理,可先关闭窗口!完成时间大约90分钟。请于90分钟后刷新信息"
);
// errorMsg = ["9090"]
peopleListAry.value = msgAry;
};
/**
@ 作者: 秦东
@ 时间: 2025-12-03 11:05:57
@ 功能: 提交上传数据
*/
const saveTemp = () => {
addTemLoading.value = true;
ruleFormRef.value.validate((valid: any) => {
if (valid) {
ruleFormIng.value.orgId = ruleFormIng.value.orgId.toString();
// console.log("--->", ruleForm);
if (ruleFormIng.value.id == 0 || ruleFormIng.value.id == "") {
uploadUserTemplate(ruleForm)
.then((data: any) => {
console.log("上传传输信息-1-->", data);
tempOpenClose();
})
.finally(() => {
addTemLoading.value = false;
});
} else {
editUserTemplateInfo(ruleForm)
.then((data: any) => {
console.log("上传传输信息-2-->", data);
tempOpenClose();
})
.finally(() => {
addTemLoading.value = false;
});
}
} else {
addTemLoading.value = false;
}
});
};
</script>
<template>
<el-dialog
v-model="ubLockPage"
title="上传导入模版"
width="400"
:before-close="tempOpenClose"
>
<el-form
ref="ruleFormRef"
style="max-width: 600px"
:model="ruleForm"
:rules="dataFormRules"
label-width="auto"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<el-form-item label="归属行政组织" prop="orgId">
<el-tree-select
v-model="ruleFormIng.orgId"
:data="orgTreeList"
:props="orgTreePropsBut"
:render-after-expand="false"
:expand-on-click-node="false"
:check-on-click-node="true"
:check-strictly="true"
:default-expand-all="false"
style="width: 240px"
/>
</el-form-item>
<el-form-item label="信息模版" prop="fileName">
<el-input v-model="ruleFormIng.fileName" />
<el-upload
ref="excelUploadUs"
class="upload-demo"
drag
v-loading="excelLoading"
:action="uploadUrl"
:limit="1"
:before-upload="handleExcelChange"
:on-success="uploadTrueUs"
:on-error="uploadError"
:show-file-list="false"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将电子表格拖到此处或 <em>单击上载</em></div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" v-loading="addTemLoading" @click="saveTemp()">
确定上传
</el-button>
<el-button @click="tempOpenClose()">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<style lang='scss' scoped>
.app-content {
}
</style>

12
src/views/nested/.editorconfig

@ -0,0 +1,12 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

4
src/views/opk/yui/new/lzq.vue

@ -58,13 +58,13 @@
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import { reactive, ref } from "vue";
import {get_target_details} from '@/api/opk/news/api'
import { addPostCont,getgroupuser } from '@/api/opk/api'
import { getonedetailedtarget,getcompany,edit_detail } from '@/api/opk/opk/api'
const isshow = ref(false)
const num = (1)
const num = ref(1)
const props= defineProps( {
title: {
type: String,

4
src/views/opk/yui/new/xy.vue

@ -68,13 +68,13 @@
</el-dialog>
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import { reactive, ref } from "vue";
import { getdetailscont,getnew_target,edit_post,get_organdpost } from '@/api/opk/opk/api'
import {getgroupuser} from '@/api/opk/api'
const isshow = ref(false)
const num = (1)
const num = ref(1)
const props= defineProps( {
title: {
type: String,

3
src/views/powermanage/rolepower/setuprole/setuprolepower.vue

@ -385,6 +385,7 @@ const pickOrgIdClick = () => {
v-for="itemes in appList"
:class="itemes.signCode == activeAppId ? 'active' : ''"
@click="pickAppList(itemes)"
:key="itemes.id"
>
{{ itemes.name }}
</li>
@ -406,6 +407,7 @@ const pickOrgIdClick = () => {
v-for="itemes in appList"
:class="itemes.signCode == activeAppId ? 'active' : ''"
@click="pickAppList(itemes)"
:key="itemes.id"
>
{{ itemes.name }}
</li>
@ -590,4 +592,5 @@ const pickOrgIdClick = () => {
background-color: #a0cfff;
}
}
</style>

865
src/views/system/monitor/online/index copy 4.vue

@ -0,0 +1,865 @@
<!--
@ 作者: 秦东
@ 时间: 2025-10-21 10:06:51
@ 备注: 在线人数
-->
<script lang='ts' setup>
import { giveRoleTree,editRoleStatus,getOrgPostTree } from '@/api/role/index'
import type {RoleListTree,RoleFormInfo,orgAndPostisListTree} from '@/api/role/types'
import type { TreeNode,TreeInstance } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { orgInfo } from "@/api/hr/org/type";
import { getOrgTreeList } from "@/api/hr/org/index";
import { appPowerUnit } from "@/api/system/roleapi/power";
import type { getSystemPower,AppPowerTree } from "@/api/system/roleapi/types";
import { appTableBut, appListBut } from "@/utils/workflow/const";
import {
gainAppList,
gainAppTableListNew
} from "@/api/system/roleapi/postrole";
import {
custerAppInfo
} from "@/api/system/roleapi/types";
import AddRoleGroup from '@/views/system/monitor/online/roleConfig/addRoleGroup.vue'
import EditRoleGroup from '@/views/system/monitor/online/roleConfig/editRoleGroup.vue'
const squareUrl = ref<string>(
"https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png"
);
const orgTree = ref<orgInfo[]>([])
const roleGroupOrInfo = ref(1)
const searchQuery = ref('')
const orgWorkRole = ref("org")
const appSysPick = ref("system")
const treeRef = ref<TreeInstance>()
const treeRefOrg = ref<TreeInstance>()
const roleListdata = ref<RoleListTree[]>([])
const orgPostisListdata = ref<orgAndPostisListTree[]>([])
const treeBoxHeight = ref(300)
const treeBoxHeightOrg = ref(300)
const roleLeft = ref()
const systemPowerTree = ref<AppPowerTree[]>([])
const ownerPeople = ref<any>([])
const props = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
const propsOrg = {
value: 'id',
label: 'name',
disabled:'status',
children: 'child',
}
const propsOrgPost = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
const systemPower = ref<getSystemPower>({
powerType:"org",
appType:"appsystem",
appSystem:"system",
roleId:"",
})
const roleLoading = ref(false)
const openRoleGroup = ref(false)
const orgLoading = ref(false)
const orgPostLoading = ref(false)
const appList = ref<custerAppInfo[]>([]);
//
const onQueryChanged = (query: string) => {
treeRef.value!.filter(query)
}
//
const onQueryChangedOrg = (query: string) => {
treeRefOrg.value!.filter(query)
}
const filterMethod = (query: string, node: any) => node.label!.includes(query)
const filterMethodOrg = (query: string, node: any) => node.name!.includes(query)
//
watch(()=>systemPower.value.powerType,(val:string)=>{
console.log("监测赋权组",val)
getSystemPowerSub();
switch(val){
case "org":
getOrgTreeAry();
break;
case "job":
getOrgPostisTree()
break;
case "role":
getRoleTree();
break;
default:
}
if(systemPower.value.appSystem=="app"){
getAppList();
}else{
getSystemPowerSub();
}
},{
deep:true
})
//
const pickRoleTree = (data:any) => {
if(data.status && data.types==1){
console.log("监测赋权组------->",data)
}
}
//
const pickOrgTree = (data:any) => {
console.log("监测赋权组------->",data)
}
//
const getRoleTree = () => {
roleLoading.value = true
giveRoleTree().then(({data})=>{
console.log("监测赋权组------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id
}
roleListdata.value=data;
roleLoading.value = false;
}).finally(()=>{roleLoading.value = false})
}
const editRoleCont = ref<RoleFormInfo>()
const openEditRoleGroup = ref(false)
//
const editMyInfoIcon = (data:RoleListTree,types:number) => {
console.log("编辑角色信息------->",data)
console.log("编辑角色信息---types---->",types)
switch(types){
case 1:
editRoleStatusBut(data.id,2)
break;
case 2:
editRoleStatusBut(data.id,1)
break;
case 3:
editRoleCont.value = {
id:data.id,
name:data.label,
type:data.types,
superior:data.superior,
sort:data.sort
}
openEditRoleGroup.value = true
break;
case 4:
ElMessageBox.confirm(
"您确定要删除此信息吗?一经删除!数据将不可恢复!请慎重操作!",
"警告",
{
confirmButtonText: '确定删除',
cancelButtonText: '取消删除',
type: 'warning',
}
).then(()=>{
editRoleStatusBut(data.id,3)
})
break;
default:
break;
}
}
//
const editRoleStatusBut = (id:string|number,types:number) => {
// console.log("--->",id)
editRoleStatus({id:id.toString(),status:types}).then((data:any)=>{
if(data.code==0){
ElMessage({
message: data.msg,
type: 'success',
})
getRoleTree()
}else{
ElMessage({
message: data.msg,
type: 'success',
})
}
})
}
//
const addRoleGroup = (types:number) => {
roleGroupOrInfo.value = types
openRoleGroup.value = true
}
//
const getOrgTreeAry = () => {
roleLoading.value = true
if(!Array.isArray(orgTree.value) || orgTree.value.length<=0){
getOrgTreeList({ orgid: 0 })
.then(({ data }) => {
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id
}
orgTree.value = data
roleLoading.value = false
}).finally(()=>{roleLoading.value = false})
}else{
roleLoading.value = false
}
}
//
const getOrgPostisTree = () => {
orgPostLoading.value=true
if(!Array.isArray(orgPostisListdata.value) || orgPostisListdata.value.length<=0){
getOrgPostTree({id:"313"}).then(({data})=>{
console.log("获取行政组织及岗位--------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id
}
orgPostisListdata.value = data
orgPostLoading.value=false
}).finally(()=>{orgPostLoading.value=false})
}else{
orgPostLoading.value=true
}
}
//
const getSystemPowerSub = () => {
appPowerUnit(systemPower.value).then(({data})=>{
console.log("获取平台授权项目------->",data)
systemPowerTree.value = data
})
}
const activeAppId = ref<string>("");
const appTableList = ref<custerAppTablePower[]>([]);
/**
@ 作者: 秦东
@ 时间: 2025-05-13 14:20:47
@ 功能: 获取自定义App
*/
const getAppList = () => {
gainAppList().then((data: any) => {
console.log("获取自定义App", data);
appList.value = data.data;
if (data.data && data.data.length > 0) {
if (data.data[0] && data.data[0].signCode) {
activeAppId.value = data.data[0].signCode;
getAppTableList();
}
}
console.log("获取自定义App", activeAppId.value);
});
};
/**
@ 作者: 秦东
@ 时间: 2025-05-13 16:00:19
@ 功能: 获取对应App下边的表单
*/
const getAppTableList = () => {
systemPower.value.roleId = activeAppId.value
gainAppTableListNew({id:activeAppId.value,appType:systemPower.value.appType,powerType:systemPower.value.powerType,roleId:systemPower.value.roleId}).then(
(data: any) => {
console.log("获取对应App下边的表单", data);
if (Array.isArray(data.data)) {
appTableList.value = data.data;
} else {
appTableList.value = [];
}
}
);
};
watch(()=>systemPower.value.appSystem,(val:string)=>{
if(val=="app"){
getAppList();
}
},{
immediate:true
})
onMounted(()=>{
getOrgTreeAry();
getSystemPowerSub();
console.log("高度-----1---->",roleLeft.value?.offsetHeight)
nextTick(()=>{
treeBoxHeight.value = roleLeft.value?.offsetHeight - 140
treeBoxHeightOrg.value = roleLeft.value?.offsetHeight - 100
})
})
watch(
() => activeAppId.value,
(val) => {
getAppTableList();
},
{
immediate:true
}
);
/**
@ 作者: 秦东
@ 时间: 2025-05-14 15:01:26
@ 功能: 选择App数据
*/
const pickAppList = (val: custerAppInfo) => {
activeAppId.value = val.signCode;
};
const systemMenuTreePropsing = {
children: "child",
label: "name",
value: "id",
};
</script>
<template>
<div class="roleBox">
<div ref="roleLeft" class="roleLeft">
<el-tabs v-model="systemPower.powerType" class="demo-tabs">
<el-tab-pane label="组织" name="org">
<template #label>
<el-text class="tabsTitle">组织</el-text>
</template>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQueryChangedOrg"/>
</div>
<el-tree-v2
ref="treeRefOrg"
style="max-width: 350px;"
:data="orgTree"
:props="propsOrg"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@node-click="pickOrgTree"
>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="岗位" name="job">
<template #label>
<el-text class="tabsTitle">岗位</el-text>
</template>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQueryChangedOrg"/>
</div>
<el-tree-v2
ref="treeRefOrg"
style="max-width: 350px;"
:data="orgPostisListdata"
:props="propsOrgPost"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
v-loading="orgPostLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@node-click="pickOrgTree"
>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="角色" name="role">
<template #label>
<el-text class="tabsTitle">角色</el-text>
</template>
<div class="butBox">
<el-button type="primary" @click="addRoleGroup(1)">新建角色组</el-button>
<el-button type="primary" @click="addRoleGroup(2)">新建角色</el-button>
</div>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的角色" :suffix-icon="Search" @input="onQueryChanged"/>
</div>
<el-tree-v2
ref="treeRef"
style="max-width: 350px;"
:data="roleListdata"
:props="props"
:filter-method="filterMethod"
:height="treeBoxHeight"
v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@node-click="pickRoleTree"
>
<template #default="{ node }" >
<div class="treeRoleBox">
<span>{{ node.label }}</span>
<div class="spanButBox">
<el-text v-if="node.disabled" type="warning" size="small" @click.stop="editMyInfoIcon(node.data,1)">禁用</el-text>
<el-text v-else type="success" size="small" @click.stop="editMyInfoIcon(node.data,2)">启用</el-text>
<el-text type="primary" size="small" @click.stop="editMyInfoIcon(node.data,3)">编辑</el-text>
<el-text type="danger" size="small" @click.stop="editMyInfoIcon(node.data,4)">删除</el-text>
</div>
</div>
</template>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="个人" name="person">
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的人" :suffix-icon="Search" @input="onQueryChangedOrg"/>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="roleright">
<el-tabs v-model="systemPower.appSystem" class="demo-tabs">
<el-tab-pane label="平台" name="system">
<template #label>
<el-text class="tabsTitleCont">平台</el-text>
</template>
<el-container v-if="systemPower.powerType == 'role'">
<el-main>
<el-table
:data="systemPowerTree"
style="width: 100%; height: calc(100vh - 277px)"
:cell-style="{ padding: '10px 0' }"
:header-cell-style="{ background: '#F5F7FA', color: '#909399' }"
border
row-key="id"
>
<el-table-column fixed prop="name" label="目录/菜单" width="380">
<template #default="scope">
<span class="tree_sapn">{{ scope.row.name }}</span>
<el-tag v-if="scope.row.types === 2" type="warning" size="small">目录</el-tag>
<el-tag v-if="scope.row.types === 1" type="success" size="small">菜单</el-tag>
<el-tag v-if="scope.row.types === 4" type="danger" size="small">按钮</el-tag>
<el-tag v-if="scope.row.types === 3" type="info" size="small">外链</el-tag>
</template>
</el-table-column>
<el-table-column prop="isTrue" label="授权" width="80" align="center" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" label="" />
</template>
</el-table-column>
<el-table-column prop="buttenPower" label="操作按钮" >
<template #header>
<div class="pickButBox">
<el-text >操作按钮</el-text>
<el-button type="primary" size="small">确定授权</el-button>
</div>
</template>
<template #default="scope">
<el-checkbox v-for="item in scope.row.buttenPower" :key="item" v-model="scope.row.isTrue" :label="item.name" />
</template>
</el-table-column>
</el-table>
</el-main>
<el-aside width="200px">
<div class="userTitleBox">
<el-text type="info" >使用人员</el-text>
<el-button type="primary" size="small">添加使用人</el-button>
</div>
<el-scrollbar class="scrollBox">
<div class="userBox" v-for="item in ownerPeople" :key="item.id">
<el-avatar shape="square" :size="size" :src="item.icon?item.icon:squareUrl" />
<div>
<el-text type="primary" >{{item.name}}{{ '('+item.code+')' }}</el-text>
<el-text type="primary" >{{item.orgName}}</el-text>
</div>
</div>
</el-scrollbar>
</el-aside>
</el-container>
<el-table
v-else
:data="systemPowerTree"
style="width: 100%; height: calc(100vh - 277px)"
:cell-style="{ padding: '10px 0' }"
:header-cell-style="{ background: '#F5F7FA', color: '#909399' }"
border
row-key="id"
>
<el-table-column fixed prop="name" label="目录/菜单" width="380" >
<template #default="scope">
<span class="tree_sapn">{{ scope.row.name }}</span>
<el-tag v-if="scope.row.types === 2" type="warning" size="small">目录</el-tag>
<el-tag v-if="scope.row.types === 1" type="success" size="small">菜单</el-tag>
<el-tag v-if="scope.row.types === 4" type="danger" size="small">按钮</el-tag>
<el-tag v-if="scope.row.types === 3" type="info" size="small">外链</el-tag>
</template>
</el-table-column>
<el-table-column prop="isTrue" label="授权" width="80" align="center" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" label="" />
</template>
</el-table-column>
<el-table-column prop="buttenPower" label="操作按钮" >
<template #header>
<div class="pickButBox">
<el-text >操作按钮</el-text>
<el-button type="primary" size="small">确定授权</el-button>
</div>
</template>
<template #default="scope">
<el-checkbox v-for="item in scope.row.buttenPower" :key="item" v-model="scope.row.isTrue" :label="item.name" />
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="应用" name="app">
<template #label>
<el-text class="tabsTitleCont">应用</el-text>
</template>
<table class="table_body">
<thead>
<tr v-if="systemPower.powerType == 'role'">
<td align="center" width="20%">应用</td>
<td align="center" width="50%">应用详情</td>
<td align="center" width="30%">
<div class="userTitleBoxes">
<el-text type="info" >使用人员</el-text>
<el-button type="primary" size="small">添加使用人</el-button>
</div>
</td>
</tr>
<tr v-else>
<td align="center" width="20%">应用</td>
<td width="80%">
<div class="appPickPower">
应用详情
<el-button type="primary" size="small">确定授权</el-button>
</div>
</td>
</tr>
</thead>
<tbody>
<tr >
<td valign="top">
<el-scrollbar class="tab_pane_box">
<ul class="appListBox">
<li v-for="item in appList" :key="item" @click="pickAppList(item)">{{ item.name }}</li>
</ul>
</el-scrollbar>
</td>
<td valign="top">
<el-row class="row_head">
<el-col class="roe_col_head left_line" :span="6">
页面
</el-col>
<el-col class="roe_col_head left_line" :span="6">
表单权力
</el-col>
<el-col class="roe_col_head left_line" :span="6">
列表权限
</el-col>
<el-col class="roe_col_head" :span="6">
数据权限
</el-col>
</el-row>
<el-scrollbar class="tab_pane_body">
<el-row class="left_right" v-for="item in appTableList" :key="item.id">
<el-col class="roe_col_head left_line" :span="6">
{{ item.name }}
</el-col>
<el-col class="roe_col_head left_line" :span="6">
<el-checkbox-group v-model="item.tablePower">
<el-checkbox
v-for="city in appTableBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col class="roe_col_head left_line" :span="6">
<el-checkbox-group v-if="item.istIsTrue" v-model="item.listPower">
<el-checkbox
v-for="city in appListBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col class="roe_col_head" :span="6">
<el-radio-group
v-model="item.datePower.types"
@change="pickAppDataPower(item.datePower)"
>
<el-row>
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
<el-col :span="24">
<el-radio :value="5">指定行政组织</el-radio>
<el-tree-select
v-if="item.datePower.types == 5"
v-model="item.datePower.attribute"
:data="orgTree"
style="width: 100%"
node-key="id"
:props="systemMenuTreePropsing"
clearable
multiple
:render-after-expand="false"
show-checkbox
collapse-tags
collapse-tags-tooltip
/>
</el-col>
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
</el-row>
</el-radio-group>
</el-col>
</el-row>
</el-scrollbar>
</td>
<td v-if="systemPower.powerType == 'role'" valign="top">
<el-scrollbar class="tab_pane_bodyes">
<div class="userBox" v-for="item in 30" :key="item.id">
<el-avatar shape="square" :size="size" :src="item.icon?item.icon:squareUrl" />
<div>
<el-text type="primary" >{{item.name}}{{ '('+item.code+')' }}</el-text>
<el-text type="primary" >{{item.orgName}}</el-text>
</div>
</div>
</el-scrollbar>
</td>
</tr>
</tbody>
</table>
</el-tab-pane>
</el-tabs>
</div>
<AddRoleGroup v-if="openRoleGroup" v-model:show="openRoleGroup" :group-info="roleGroupOrInfo" @resthandel="getRoleTree" />
<EditRoleGroup v-if="openEditRoleGroup" v-model:show="openEditRoleGroup" :group-info="roleGroupOrInfo" :data="editRoleCont" @resthandel="getRoleTree" />
</div>
</template>
<style lang='scss' scoped>
.roleBox{
display: flex;
width: 100%;
height: calc(100vh - 170px);
padding: 15px 20px 0 20px;
justify-content: space-between;
.roleLeft{
width: 350px;
height: calc(100vh - 185px);
background-color: #FFFFFF;
.butBox{
display: flex;
justify-content: space-between;
padding: 0 10px 10px 10px;
}
.searchBox{
padding: 0 10px 10px 10px;
}
.treeBox{
height: calc(100vh - 330px);
}
}
.roleright{
width: calc(100% - 370px);
height: calc(100vh - 185px);
background-color: #FFFFFF;
overflow: hidden;
:deep .el-tabs__content{
padding: 15px 15px 15px 0px;
}
:deep .el-main{
padding: 0 15px;
}
.userTitleBox{
display: flex;
justify-content: space-between;
padding: 0px 0px 15px 0px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2);
}
.userTitleBoxes{
display: flex;
justify-content: space-between;
}
.pickButBox{
display: flex;
align-items: center;
justify-content: space-between;
}
.scrollBox{
margin-top: 5px;
height: calc(100vh - 320px);
}
.userBox{
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-items: space-between;
border-bottom: 1px dashed rgba($color: #000000, $alpha: 0.2);
div{
span{
display: flex;
width: 100%;
padding: 0 5px;
color:rgba($color: #000000, $alpha: 0.6);
}
}
}
}
.tabsTitle{
padding: 0 15px;
}
.tabsTitleCont{
padding: 0 35px;
}
.treeRoleBox{
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
}
.spanButBox{
span{
padding: 0 5px;
}
}
}
.tree_sapn {
padding: 0 10px 0 0;
}
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
.appListBox {
width: 100%;
li {
padding: 10px 2px;
border-bottom: 1px solid #ececec;
cursor: pointer;
}
li.active {
background-color: #a0cfff;
}
}
.tab_pane_box {
height: calc(100vh - 310px);
overflow: hidden;
overflow-y: auto;
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
}
.row_head{
background-color: #f5f7fa;
color: #000000;
text-align: center;
border: 1px solid #E4E7ED;
}
.roe_col_head{
padding: 5px 5px;
}
.left_right{
border-left: 1px solid #E4E7ED;
border-right: 1px solid #E4E7ED;
border-bottom: 1px solid #E4E7ED;
}
.left_line{
border-right: 1px solid #E4E7ED;
}
.tab_pane_body {
height: calc(100vh - 340px);
overflow: hidden;
overflow-y: auto;
}
.tab_pane_bodyes {
height: calc(100vh - 320px);
overflow: hidden;
overflow-y: auto;
}
.appPickPower{
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

777
src/views/system/monitor/online/index.vue

@ -1,41 +1,82 @@
<!--
@ 作者: 秦东
@ 时间: 2025-10-21 10:06:51
@ 备注: 在线人数
@ 时间: 2025-12-17 13:24:58
@ 备注: 设置系统权限
-->
<script lang='ts' setup>
import { getOrgTreeList } from "@/api/hr/org/index";
import { appInitAuthorization,gainAppTableListNew,getPowerPageUser,systemAppAuthorization,gainAppEmpowerPower } from "@/api/system/roleapi/postrole";
import { appPowerUnit } from "@/api/system/roleapi/power";
import { giveRoleTree,editRoleStatus,getOrgPostTree } from '@/api/role/index'
import type { getSystemPower,AppPowerTree,systemList,custerAppInfo, custerAppTablePower, searchUser } from "@/api/system/roleapi/types";
import type { TreeInstance } from 'element-plus'
import type {RoleListTree,RoleFormInfo,orgAndPostisListTree} from '@/api/role/types'
import type { TreeNode,TreeInstance } from 'element-plus'
import { appTableBut, appListBut,appDetailBut,formBaseBut,appGroupBut } from "@/utils/workflow/const";
import { Search } from '@element-plus/icons-vue'
import { orgInfo } from "@/api/hr/org/type";
import { getOrgTreeList } from "@/api/hr/org/index";
import SvgIcon from "@/components/SvgIcon/index.vue";
import SetRolePeople from '@/views/system/monitor/online/roleConfig/setRolePeople.vue'
import AddRoleGroup from '@/views/system/monitor/online/roleConfig/addRoleGroup.vue'
import EditRoleGroup from '@/views/system/monitor/online/roleConfig/editRoleGroup.vue'
import { orgInfo } from '@/api/displayboardapi/types';
const squareUrl = ref<string>(
"https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png"
);
import AppTablePower from '@/views/system/monitor/online/powerPage/apptablepower.vue'
import AppTabsPower from '@/views/system/monitor/online/powerPage/appTabsPower.vue'
const orgTree = ref<orgInfo[]>([])
const appTabsPowerPage = ref()
const appLoading = ref(false)
const setRolePople = ref(false)
const orgTree = ref<orgInfo[]>([]) //
const setRoleManInfo = ref<RoleListTree>()
const roleGroupOrInfo = ref(1)
const searchQuery = ref('')
const orgWorkRole = ref("org")
const appSysPick = ref("system")
const treeRef = ref<TreeInstance>()
const roleLeft = ref() //
const searchQuery = ref('') //
const treeRefOrg = ref<TreeInstance>()
const roleListdata = ref<RoleListTree[]>([])
const orgPostisListdata = ref<orgAndPostisListTree[]>([])
const treeRefOrgPost = ref<TreeInstance>() //
const roleListdata = ref<RoleListTree[]>([]) //
const editRoleCont = ref<RoleFormInfo>()
const appList = ref<custerAppInfo[]>([]);
const openEditRoleGroup = ref(false)
const roleLoading = ref(false)
const orgPostLoading = ref(false)
const openRoleGroup = ref(false)
const treeBoxHeight = ref(300)
const treeBoxHeightOrg = ref(300)
const roleLeft = ref()
const systemPowerTree = ref<AppPowerTree[]>([])
const orgPostisListdata = ref<orgAndPostisListTree[]>([]) ///
const userPowerList = ref<systemList>({}) //
const activeAppId = ref<string>("");
const appTableList = ref<custerAppTablePower[]>([]);
const myAppTableLoad = ref(false)
const treeRef = ref()
const appSystemConfig = ref<any[]>([])
const appFormButConfig = ref<any[]>([])
const grouTabsLoading = ref(false)
const props = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
//
const systemPower = ref<getSystemPower>({
powerType: "org",
appId: "",
appSystem: "system",
roleId: "",
isPick: false,
appType: ""
})
//
const propsOrg = {
value: 'id',
label: 'name',
disabled:'status',
// disabled:'status',
children: 'child',
}
const propsOrgPost = {
@ -44,64 +85,105 @@ const propsOrgPost = {
disabled:'status',
children: 'children',
}
const roleLoading = ref(false)
const openRoleGroup = ref(false)
const orgLoading = ref(false)
const orgPostLoading = ref(false)
//
const onQueryChanged = (query: string) => {
treeRef.value!.filter(query)
const systemMenuTreePropsing = {
children: "child",
label: "name",
value: "id",
};
//
const searchUserQuery =reactive<searchUser>({
page:1,
pagesize:20,
name:"",
}); //
const filterMethod = (query: string, node: any) => node.label!.includes(query)
const filterMethodOrg = (query: string, node: any) => {
return node.name!.includes(query)
}
//
const onQueryChangedOrg = (query: string) => {
treeRefOrg.value!.filter(query)
}
const filterMethod = (query: string, node: any) => node.label!.includes(query)
const filterMethodOrg = (query: string, node: any) => node.name!.includes(query)
//
watch(()=>orgWorkRole.value,(val:string)=>{
console.log("监测赋权组",val)
switch(val){
case "org":
getOrgTreeAry();
break;
case "job":
getOrgPostisTree()
break;
case "role":
getRoleTree();
break;
default:
}
},{
deep:true
})
//
const pickRoleTree = (data:any) => {
if(data.status && data.types==1){
console.log("监测赋权组------->",data)
}
//
const onQuedOrg = (query: string) => {
treeRefOrgPost.value!.filter(query)
}
//
const pickOrgTree = (data:any) => {
console.log("监测赋权组------->",data)
//
const onQueryChanged = (query: string) => {
treeRef.value!.filter(query)
}
//
/**
@ 作者: 秦东
@ 时间: 2025-11-26 10:09:42
@ 功能: 编辑角色人员
*/
const editRolePeopel = (item:RoleListTree) =>{
console.log("编辑角色人员--111111->",item)
setRoleManInfo.value = item
setRolePople.value = true
}
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:32:54
@ 功能: 获取角色树
*/
const getRoleTree = () => {
roleLoading.value = true
giveRoleTree().then(({data})=>{
console.log("监测赋权组------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id.toString()
}
roleListdata.value=data;
roleLoading.value = false;
}).finally(()=>{roleLoading.value = false})
}).finally(()=>{
roleLoading.value = false
grouTabsLoading.value=false
})
}
const editRoleCont = ref<RoleFormInfo>()
const openEditRoleGroup = ref(false)
//
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:37:28
@ 功能: 添加角色组
*/
const addRoleGroup = (types:number) => {
roleGroupOrInfo.value = types
openRoleGroup.value = true
}
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:40:53
@ 功能: 获取平台授权项目
*/
const getSystemPowerSub = () => {
appPowerUnit(systemPower.value).then(({data})=>{
console.log("获取平台授权项目------->",data)
systemPowerTree.value = data
grouTabsLoading.value=false
})
}
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:40:01
@ 功能: 选中角色
*/
const pickRoleTree = (data:any) => {
console.log("监测赋权组------->",data)
if(data.status && data.types==1){
console.log("监测赋权组------->",data)
systemPower.value.appId=""
systemPower.value.appSystem="system"
systemPower.value.roleId=""
systemPower.value.roleId=data.id.toString()
getSystemPowerSub();
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:47:01
@ 功能: 编辑角色信息
*/
const editMyInfoIcon = (data:RoleListTree,types:number) => {
console.log("编辑角色信息------->",data)
console.log("编辑角色信息---types---->",types)
switch(types){
case 1:
editRoleStatusBut(data.id,2)
@ -136,7 +218,11 @@ const editMyInfoIcon = (data:RoleListTree,types:number) => {
break;
}
}
//
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:47:30
@ 功能: 编辑角色状态
*/
const editRoleStatusBut = (id:string|number,types:number) => {
// console.log("--->",id)
editRoleStatus({id:id.toString(),status:types}).then((data:any)=>{
@ -154,43 +240,270 @@ const editRoleStatusBut = (id:string|number,types:number) => {
}
})
}
//
const addRoleGroup = (types:number) => {
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:52:17
@ 功能: 获取行政组织
*/
const pickOrgTree = (data:any) => {
console.log("监测赋权组----2222--->",systemPower.value.powerType,"---------->",data)
if((systemPower.value.powerType=="job" && data.types == "9") || systemPower.value.powerType!="job"){
systemPower.value.appId=""
systemPower.value.appSystem="system"
systemPower.value.roleId=""
systemPower.value.roleId=data.id.toString()
getSystemPowerSub();
}
roleGroupOrInfo.value = types
openRoleGroup.value = true
}
//
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:55:39
@ 功能: 获取平台授权项目用户
*/
const getPowerPageUserSub = () => {
console.log("获取平台授权项目用户---searchUserQuery---->",searchUserQuery)
getPowerPageUser(searchUserQuery).then(({data})=>{
console.log("获取平台授权项目用户------->",data)
userPowerList.value = data
grouTabsLoading.value=false
})
}
/**
@ 作者: 秦东
@ 时间: 2025-12-17 13:55:02
@ 功能: 查询用户
*/
const onQueryChangedOrgUser = (query: string) => {
console.log("获取平台授权项目用户---查询--->",query)
searchUserQuery.page=1
searchUserQuery.name = query
getPowerPageUserSub()
}
/**
@ 作者: 秦东
@ 时间: 2025-11-18 17:00:46
@ 功能: 选择用户陪权
*/
const pickUser = (item:any) =>{
console.log("选择用户陪权--111111->",item)
item.isPick = true
systemPower.value.roleId = item.id.toString()
// systemPower.value.powerType="user"
console.log("选择用户陪权--2222->",userPowerList)
if(userPowerList.value.list && Array.isArray(userPowerList.value.list)){
userPowerList.value.list.forEach((items:any)=>{
// console.log("--111111->",items.id)
if(items.id!=item.id){
items.isPick = false
}
})
}
getSystemPowerSub()
}
/**
@ 作者: 秦东
@ 时间: 2025-12-17 14:07:34
@ 功能: 获取行政组织树
*/
const getOrgTreeAry = () => {
roleLoading.value = true
if(!Array.isArray(orgTree.value) || orgTree.value.length<=0){
getOrgTreeList({ orgid: 0 })
.then(({ data }) => {
orgTree.value = data
.then(( data:any ) => {
if(Array.isArray(data.data) && data.data.length>0){
systemPower.value.roleId=data.data[0].id.toString()
}
orgTree.value = data.data
roleLoading.value = false
getSystemPowerSub();
}).finally(()=>{
roleLoading.value = false
}).finally(()=>{roleLoading.value = false})
grouTabsLoading.value=false
})
}else{
roleLoading.value = false
}
}
//
/**
@ 作者: 秦东
@ 时间: 2025-12-17 14:12:36
@ 功能: 获取行政组织及岗位
*/
const getOrgPostisTree = () => {
orgPostLoading.value=true
if(!Array.isArray(orgPostisListdata.value) || orgPostisListdata.value.length<=0){
getOrgPostTree({id:"313"}).then(({data})=>{
console.log("获取行政组织及岗位--------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id.toString()
}
orgPostisListdata.value = data
orgPostLoading.value=false
}).finally(()=>{orgPostLoading.value=false})
}).finally(()=>{
orgPostLoading.value=false
grouTabsLoading.value=false
})
}else{
orgPostLoading.value=true
}
}
/**
@ 作者: 秦东
@ 时间: 2025-05-13 14:20:47
@ 功能: 获取自定义App
*/
const appGroupButAry = ref<string[]>([])
const appPowerArt = ref<any>([])
const getAppList = () => {
appLoading.value=true
appInitAuthorization({appType:systemPower.value.appSystem,powerType:systemPower.value.powerType,roleId:systemPower.value.roleId}).then((data: any) => {
console.log("获取自定义App", data);
// appList.value = data.data;
appPowerArt.value = data.data.appList
appGroupButAry.value = data.data.groupButton
// if (data.data && data.data.length > 0) {
// if (data.data[0] && data.data[0].signCode) {
// activeAppId.value = data.data[0].signCode;
// }
// }
// console.log("App", activeAppId.value);
grouTabsLoading.value=false
}).finally(()=>{
appLoading.value=false
})
};
/**
@ 作者: 秦东
@ 时间: 2025-12-17 14:11:19
@ 功能: 检测赋权组
*/
watch(()=>systemPower.value.powerType,(val:string)=>{
systemPower.value.appId=""
systemPower.value.appSystem="system"
systemPower.value.roleId=""
grouTabsLoading.value=true
switch(val){
case "org":
getOrgTreeAry();
break;
case "job":
getOrgPostisTree()
break;
case "role":
getRoleTree();
break;
case "person":
getPowerPageUserSub()
break;
default:
}
if(systemPower.value.appSystem=="app"){
appTabsPowerPage.value.getAppList();
}else{
getSystemPowerSub();
}
},{
immediate:true
})
/**
@ 作者: 秦东
@ 时间: 2025-12-17 14:44:08
@ 功能: 监听系统选择
*/
watch(()=>systemPower.value.appSystem,(val:string)=>{
console.log("监听系统选择--111111->",val)
if(val=="app"){
// getAppList();
appTabsPowerPage.value.getAppList()
}else{
getSystemPowerSub()
}
systemPower.value.isPick = false
},{
immediate:true
})
/**
@ 作者: 秦东
@ 时间: 2025-11-19 08:25:41
@ 功能: 选择系统菜单授权
*/
const pickSystemMenuInfo = (item:AppPowerTree) =>{
console.log("选择系统菜单授权--111111->",item)
if(item.isTrue){
if(item.buttenPower && Array.isArray(item.buttenPower)){
item.buttenPower.forEach((child:any)=>{
child.isTrue = false
})
}
childPickSystemMenuInfo(item.children,false)
}else{
if(item.buttenPower && Array.isArray(item.buttenPower)){
item.buttenPower.forEach((child:any)=>{
child.isTrue = true
})
}
childPickSystemMenuInfo(item.children,true)
}
}
const childPickSystemMenuInfo = (menuList:AppPowerTree[],isTrue:boolean) =>{
if(menuList && Array.isArray(menuList)){
menuList.forEach((item:AppPowerTree)=>{
item.isTrue = isTrue
if(item.buttenPower && Array.isArray(item.buttenPower)){
item.buttenPower.forEach((child:any)=>{
child.isTrue = isTrue
})
}
childPickSystemMenuInfo(item.children,isTrue)
})
}
}
/**
@ 作者: 秦东
@ 时间: 2025-11-18 08:38:06
@ 功能: 提交应用授权
*/
const savePowerUserSub = () => {
console.log("提交应用授权---1---->",systemPower.value)
console.log("提交应用授权---2---->",systemPowerTree.value)
let sendInfo = {
powerType: systemPower.value.powerType,
appId: systemPower.value.appId,
appSystem: systemPower.value.appSystem,
roleId: systemPower.value.roleId,
isPick: systemPower.value.isPick,
sysstemPowerInfo: systemPowerTree.value,
CustomizeApp:appTableList.value
}
console.log("提交应用授权---3---->",sendInfo)
systemAppAuthorization(sendInfo).then((data:any)=>{
console.log("提交应用授权-data--3---->",data)
if(data.code==0){
ElMessage({
message: "提交成功",
type: "success",
})
}else{
ElMessage({
message: "提交失败",
type: "error",
})
}
})
}
//
onMounted(()=>{
getOrgTreeAry();
console.log("高度-----1---->",roleLeft.value?.offsetHeight)
nextTick(()=>{
treeBoxHeight.value = roleLeft.value?.offsetHeight - 140
@ -200,12 +513,12 @@ onMounted(()=>{
})
</script>
<template>
<div class="roleBox">
<div class="app-content">
<div ref="roleLeft" class="roleLeft">
<el-tabs v-model="orgWorkRole" class="demo-tabs">
<el-tab-pane label="行政组织" name="org">
<el-tabs v-model="systemPower.powerType" class="demo-tabs">
<el-tab-pane label="组织" name="org">
<template #label>
<el-text class="tabsTitle">行政组织</el-text>
<el-text class="tabsTitle">组织</el-text>
</template>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQueryChangedOrg"/>
@ -217,7 +530,7 @@ onMounted(()=>{
:props="propsOrg"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
v-loading="roleLoading"
:v-loading="roleLoading||grouTabsLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@ -230,16 +543,16 @@ onMounted(()=>{
<el-text class="tabsTitle">岗位</el-text>
</template>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQueryChangedOrg"/>
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQuedOrg"/>
</div>
<el-tree-v2
ref="treeRefOrg"
ref="treeRefOrgPost"
style="max-width: 350px;"
:data="orgPostisListdata"
:props="propsOrgPost"
:filter-method="filterMethodOrg"
:filter-method="filterMethod"
:height="treeBoxHeightOrg"
v-loading="orgPostLoading"
:v-loading="orgPostLoading||grouTabsLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@ -258,6 +571,7 @@ onMounted(()=>{
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的角色" :suffix-icon="Search" @input="onQueryChanged"/>
</div>
<div class="treeBoxClass">
<el-tree-v2
ref="treeRef"
style="max-width: 350px;"
@ -265,47 +579,176 @@ onMounted(()=>{
:props="props"
:filter-method="filterMethod"
:height="treeBoxHeight"
v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:v-loading="roleLoading||grouTabsLoading"
:expand-on-click-node="false"
:highlight-current="true"
class="treebox"
@node-click="pickRoleTree"
>
<template #default="{ node }" >
<div class="treeRoleBox">
<span>{{ node.label }}</span>
<div class="spanButBox">
<el-text v-if="node.disabled" type="warning" size="small" @click.stop="editMyInfoIcon(node.data,1)">禁用</el-text>
<el-text v-else type="success" size="small" @click.stop="editMyInfoIcon(node.data,2)">启用</el-text>
<el-text type="primary" size="small" @click.stop="editMyInfoIcon(node.data,3)">编辑</el-text>
<el-text type="danger" size="small" @click.stop="editMyInfoIcon(node.data,4)">删除</el-text>
<el-dropdown trigger="click">
<svg-icon icon-class="xiala1" style="margin-right: 20px;" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="node.data.types == 1">
<el-text size="small" @click.stop="editRolePeopel(node.data)">人员</el-text>
</el-dropdown-item>
<el-dropdown-item v-if="node.disabled">
<el-text size="small" @click.stop="editMyInfoIcon(node.data,1)">禁用</el-text>
</el-dropdown-item>
<el-dropdown-item v-else>
<el-text size="small" @click.stop="editMyInfoIcon(node.data,2)">启用</el-text>
</el-dropdown-item>
<el-dropdown-item>
<el-text size="small" @click.stop="editMyInfoIcon(node.data,3)">编辑</el-text>
</el-dropdown-item >
<el-dropdown-item divided>
<el-text type="danger" size="small" @click.stop="editMyInfoIcon(node.data,4)">删除</el-text>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
</el-tree-v2>
</div>
</el-tab-pane>
<el-tab-pane label="用户" name="person">
<div class="searchBox">
<el-input v-model="searchUserQuery.name" placeholder="请输入要查找的人" :suffix-icon="Search" @input="onQueryChangedOrgUser" clearable />
</div>
<el-scrollbar class="tab_pane_bodyes" :v-loading="grouTabsLoading">
<div v-for="item in userPowerList.list" :key="item.id" :class="item.isPick?'userBox active':'userBox'" @click="pickUser(item)">
<el-avatar shape="square" :src="item.icon?item.icon:squareUrl" />
<div>
<el-text type="primary" >{{item.name}}{{ '('+item.code+')' }}</el-text>
<el-text type="primary" >{{item.org}}</el-text>
</div>
</div>
</el-scrollbar>
<div style="width: 100%; display: flex; justify-content: center; margin-top: 5px;">
<el-pagination
v-model:current-page="searchUserQuery.page"
:page-size="searchUserQuery.pagesize"
:pager-count="7"
layout="prev, pager, next"
:total="userPowerList.total"
@change="getPowerPageUserSub"
/>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="roleright">
<el-tabs v-model="appSysPick" class="demo-tabs">
<el-tabs v-model="systemPower.appSystem" class="demo-tabs">
<el-tab-pane label="平台" name="system">
<template #label>
<el-text class="tabsTitleCont">平台</el-text>
</template>
<el-table
:data="systemPowerTree"
style="width: 100%; height: calc(100vh - 277px)"
:cell-style="{ padding: '10px 0' }"
:header-cell-style="{ background: '#F5F7FA', color: '#909399' }"
border
row-key="id"
>
<el-table-column fixed prop="name" label="目录/菜单" min-width="300" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" label="" @click.stop="pickSystemMenuInfo(scope.row)" />
<span class="tree_sapn">{{ scope.row.name }}</span>
<el-tag v-if="scope.row.types === 2" type="warning" size="small">目录</el-tag>
<el-tag v-if="scope.row.types === 1" type="success" size="small">菜单</el-tag>
<el-tag v-if="scope.row.types === 4" type="danger" size="small">按钮</el-tag>
<el-tag v-if="scope.row.types === 3" type="info" size="small">外链</el-tag>
</template>
</el-table-column>
<!-- <el-table-column prop="isTrue" label="授权" width="80" align="center" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" label="" @click.stop="pickSystemMenuInfo(scope.row)" />
</template>
</el-table-column> -->
<el-table-column prop="isTrue" label="操作按钮" min-width="380" align="center" >
<template #default="scope">
<template v-for="item in scope.row.buttenPower" :key="item.id" >
<el-checkbox v-model="item.isTrue" :label="item.name" :value="item.isTrue" />
</template>
</template>
</el-table-column>
<el-table-column fixed="right" prop="buttenPower" label="操作按钮" min-width="220" >
<template #header>
<div class="pickButBox">
<el-text >数据权限</el-text>
<el-button type="primary" size="small" @click="savePowerUserSub">确定授权</el-button>
</div>
</template>
<template #default="scope">
<el-radio-group
v-model="scope.row.visibleRange.typrs"
>
<el-row>
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
<el-col :span="24">
<el-radio :value="5">指定行政组织</el-radio>
<el-tree-select
v-if="scope.row.visibleRange.typrs == 5"
v-model="scope.row.visibleRange.val"
:data="orgTree"
style="width: 100%"
node-key="id"
:props="systemMenuTreePropsing"
clearable
multiple
:render-after-expand="false"
show-checkbox
collapse-tags
collapse-tags-tooltip
/>
</el-col>
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
</el-row>
</el-radio-group>
</template>
</el-table-column>
</el-table>
<!--appPowerArt.value = data.data.appList
appGroupBut.value = data.data.groupButton-->
</el-tab-pane>
<el-tab-pane label="应用" name="app">
<template #label>
<el-text class="tabsTitleCont">应用</el-text>
</template>
<AppTabsPower ref="appTabsPowerPage" :app-type="systemPower.appSystem" :power-type="systemPower.powerType" :role-id="systemPower.roleId" :org-tree="orgTree" />
<!--AppTablePower :app-type="systemPower.appSystem" :power-type="systemPower.powerType" :role-id="systemPower.roleId" /-->
</el-tab-pane>
</el-tabs>
</div>
<AddRoleGroup v-if="openRoleGroup" v-model:show="openRoleGroup" :group-info="roleGroupOrInfo" @resthandel="getRoleTree" />
<SetRolePeople v-model:show="setRolePople" :org="orgTree" :role-info="setRoleManInfo" />
<EditRoleGroup v-if="openEditRoleGroup" v-model:show="openEditRoleGroup" :group-info="roleGroupOrInfo" :data="editRoleCont" @resthandel="getRoleTree" />
</div>
</template>
<style lang='scss' scoped>
.roleBox{
.app-content{
display: flex;
width: 100%;
height: calc(100vh - 170px);
@ -315,23 +758,66 @@ onMounted(()=>{
width: 350px;
height: calc(100vh - 185px);
background-color: #FFFFFF;
.butBox{
display: flex;
justify-content: space-between;
padding: 0 10px 10px 10px;
}
.searchBox{
padding: 0 10px 10px 10px;
padding: 0 10px 5px 10px;
}
.treeBox{
height: calc(100vh - 330px);
}
.el-tree{
--el-color-primary-light-9:#6eb3f8;
--el-tree-node-hover-bg-color:#a1c7ee;
--el-tree-node-content-height:43px;
--el-tree-expand-icon-color:#4c4c4e;
.el-tree-node__content{
height: 43px;
}
}
.el-tree-node__content {
height: 40px; /* 设置选项高度 */
}
}
.roleright{
width: calc(100% - 370px);
height: calc(100vh - 185px);
background-color: #FFFFFF;
overflow: hidden;
:deep .el-tabs__content{
padding: 15px 15px 15px 15px;
}
:deep .el-main{
padding: 0 15px;
}
.userTitleBox{
display: flex;
justify-content: space-between;
padding: 0px 0px 15px 0px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2);
}
.userTitleBoxes{
display: flex;
justify-content: space-between;
}
.pickButBox{
display: flex;
align-items: center;
justify-content: space-between;
}
.scrollBox{
margin-top: 5px;
height: calc(100vh - 320px);
}
}
.tabsTitle{
padding: 0 15px;
@ -344,12 +830,123 @@ onMounted(()=>{
justify-content: space-between;
width: 100%;
align-items: center;
svg{
display: none;
margin: 0 5px 0 auto;
}
}
.spanButBox{
span{
padding: 0 5px;
.treeRoleBox:hover svg{
display: block;
}
}
.tree_sapn {
padding: 0 10px 0 0;
}
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
min-width: 100px;
td,
th {
min-width: 100px;
// border: 0px solid #cccccc;
border-bottom: 1px solid #cccccc;
padding: 5px;
}
}
}
}
.appListBox {
width: 100%;
li {
padding: 10px 2px;
border-bottom: 1px solid #ececec;
cursor: pointer;
}
li.active {
background-color: #a0cfff;
}
}
.tab_pane_box {
height: calc(100vh - 310px);
overflow: hidden;
overflow-y: auto;
}
.row_head{
background-color: #f5f7fa;
color: #000000;
text-align: center;
border: 1px solid #E4E7ED;
}
.roe_col_head{
padding: 5px 5px;
}
.left_right{
border-left: 1px solid #E4E7ED;
border-right: 1px solid #E4E7ED;
border-bottom: 1px solid #E4E7ED;
}
.left_line{
border-right: 1px solid #E4E7ED;
}
.tab_pane_body {
height: calc(100vh - 340px);
overflow: hidden;
overflow-y: auto;
}
.tab_pane_bodyes {
height: calc(100vh - 320px);
overflow: hidden;
overflow-y: auto;
}
.appPickPower{
display: flex;
justify-content: space-between;
align-items: center;
}
.userBox{
width: 100%;
display: flex;
align-items: center;
justify-items: space-between;
padding: 5px 10px;
border-bottom: 1px dashed rgba($color: #000000, $alpha: 0.2);
cursor: pointer;
div{
span{
display: flex;
width: 100%;
padding: 0 5px;
color:rgba($color: #000000, $alpha: 0.6);
}
}
}
.userBox.active {
background-color: #a0cfff;
}
.tableScrollbar{
width: 100%;
height: calc(100vh - 260px);
overflow: hidden;
overflow-y: auto;
}
</style>

903
src/views/system/monitor/online/index123.vue

@ -0,0 +1,903 @@
<!--
@ 作者: 秦东
@ 时间: 2025-10-21 10:06:51
@ 备注: 在线人数
-->
<script lang='ts' setup>
import { giveRoleTree,editRoleStatus,getOrgPostTree } from '@/api/role/index'
import type {RoleListTree,RoleFormInfo,orgAndPostisListTree} from '@/api/role/types'
import type { TreeNode,TreeInstance } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { orgInfo } from "@/api/hr/org/type";
import { getOrgTreeList } from "@/api/hr/org/index";
import { appPowerUnit } from "@/api/system/roleapi/power";
import type { getSystemPower,AppPowerTree } from "@/api/system/roleapi/types";
import { appTableBut, appListBut } from "@/utils/workflow/const";
import {
gainAppList,
gainAppTableListNew,
getMyPeoplceAndSunOrg,
getMyPeopleAndSunOrgPost,
getPowerPageUser
} from "@/api/system/roleapi/postrole";
import {
custerAppInfo
} from "@/api/system/roleapi/types";
import type { LoadFunction } from 'element-plus'
import AddRoleGroup from '@/views/system/monitor/online/roleConfig/addRoleGroup.vue'
import EditRoleGroup from '@/views/system/monitor/online/roleConfig/editRoleGroup.vue'
const squareUrl = ref<string>(
"https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png"
);
const orgTree = ref<orgInfo[]>([])
const roleGroupOrInfo = ref(1)
const searchQuery = ref('')
const orgWorkRole = ref("org")
const appSysPick = ref("system")
const treeRef = ref<TreeInstance>()
const treeRefOrg = ref<TreeInstance>()
const roleListdata = ref<RoleListTree[]>([])
const orgPostisListdata = ref<orgAndPostisListTree[]>([])
const treeBoxHeight = ref(300)
const treeBoxHeightOrg = ref(300)
const roleLeft = ref()
const systemPowerTree = ref<AppPowerTree[]>([])
const ownerPeople = ref<any>([])
const props = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
const propsOrg = {
value: 'id',
label: 'name',
disabled:'status',
children: 'child',
}
const propsOrgPost = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
const searchUser = reactive({
page:1,
pageSize:19,
name:"",
total:0,
});
const systemPower = ref<getSystemPower>({
powerType:"org",
appType:"appsystem",
appSystem:"system",
roleId:"",
})
const roleLoading = ref(false)
const openRoleGroup = ref(false)
const orgLoading = ref(false)
const orgPostLoading = ref(false)
const appList = ref<custerAppInfo[]>([]);
//
const onQueryChanged = (query: string) => {
treeRef.value!.filter(query)
}
//
const onQueryChangedOrg = (query: string) => {
// treeRefOrg.value!.filter(query)
searchUser.page = 1
searchUser.total = 0
fpickUserTabs()
}
const filterMethod = (query: string, node: any) => node.label!.includes(query)
const filterMethodOrg = (query: string, node: any) => node.name!.includes(query)
//
watch(()=>systemPower.value.powerType,(val:string)=>{
console.log("监测赋权组",val)
getSystemPowerSub();
switch(val){
case "org":
getOrgTreeAry();
break;
case "job":
getOrgPostisTree()
break;
case "role":
getRoleTree();
break;
case "person":
fpickUserTabs();
break;
default:
}
if(systemPower.value.appSystem=="app"){
getAppList();
}else{
getSystemPowerSub();
}
},{
deep:true
})
//
const pickRoleTree = (data:any) => {
if(data.status && data.types==1){
console.log("监测赋权组------->",data)
}
}
//
const pickOrgTree = (data:any) => {
console.log("监测赋权组------->",data)
}
//
const getRoleTree = () => {
roleLoading.value = true
giveRoleTree().then(({data})=>{
console.log("监测赋权组------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id
}
roleListdata.value=data;
roleLoading.value = false;
}).finally(()=>{roleLoading.value = false})
}
const editRoleCont = ref<RoleFormInfo>()
const openEditRoleGroup = ref(false)
//
const editMyInfoIcon = (data:RoleListTree,types:number) => {
console.log("编辑角色信息------->",data)
console.log("编辑角色信息---types---->",types)
switch(types){
case 1:
editRoleStatusBut(data.id,2)
break;
case 2:
editRoleStatusBut(data.id,1)
break;
case 3:
editRoleCont.value = {
id:data.id,
name:data.label,
type:data.types,
superior:data.superior,
sort:data.sort
}
openEditRoleGroup.value = true
break;
case 4:
ElMessageBox.confirm(
"您确定要删除此信息吗?一经删除!数据将不可恢复!请慎重操作!",
"警告",
{
confirmButtonText: '确定删除',
cancelButtonText: '取消删除',
type: 'warning',
}
).then(()=>{
editRoleStatusBut(data.id,3)
})
break;
default:
break;
}
}
//
const editRoleStatusBut = (id:string|number,types:number) => {
// console.log("--->",id)
editRoleStatus({id:id.toString(),status:types}).then((data:any)=>{
if(data.code==0){
ElMessage({
message: data.msg,
type: 'success',
})
getRoleTree()
}else{
ElMessage({
message: data.msg,
type: 'success',
})
}
})
}
//
const addRoleGroup = (types:number) => {
roleGroupOrInfo.value = types
openRoleGroup.value = true
}
//
const getOrgTreeAry = () => {
roleLoading.value = true
if(!Array.isArray(orgTree.value) || orgTree.value.length<=0){
getOrgTreeList({ orgid: 0 })
.then(({ data }) => {
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id
}
orgTree.value = data
roleLoading.value = false
}).finally(()=>{roleLoading.value = false})
}else{
roleLoading.value = false
}
}
//
const getOrgPostisTree = () => {
orgPostLoading.value=true
if(!Array.isArray(orgPostisListdata.value) || orgPostisListdata.value.length<=0){
getOrgPostTree({id:"313"}).then(({data})=>{
console.log("获取行政组织及岗位--------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id
}
orgPostisListdata.value = data
orgPostLoading.value=false
}).finally(()=>{orgPostLoading.value=false})
}else{
orgPostLoading.value=true
}
}
//
const getSystemPowerSub = () => {
appPowerUnit(systemPower.value).then(({data})=>{
console.log("获取平台授权项目------->",data)
systemPowerTree.value = data
})
}
const activeAppId = ref<string>("");
const appTableList = ref<custerAppTablePower[]>([]);
/**
@ 作者: 秦东
@ 时间: 2025-05-13 14:20:47
@ 功能: 获取自定义App
*/
const getAppList = () => {
gainAppList().then((data: any) => {
console.log("获取自定义App", data);
appList.value = data.data;
if (data.data && data.data.length > 0) {
if (data.data[0] && data.data[0].signCode) {
activeAppId.value = data.data[0].signCode;
getAppTableList();
}
}
console.log("获取自定义App", activeAppId.value);
});
};
/**
@ 作者: 秦东
@ 时间: 2025-05-13 16:00:19
@ 功能: 获取对应App下边的表单
*/
const getAppTableList = () => {
systemPower.value.roleId = activeAppId.value
gainAppTableListNew({id:activeAppId.value,appType:systemPower.value.appType,powerType:systemPower.value.powerType,roleId:systemPower.value.roleId}).then(
(data: any) => {
console.log("获取对应App下边的表单", data);
if (Array.isArray(data.data)) {
appTableList.value = data.data;
} else {
appTableList.value = [];
}
}
);
};
watch(()=>systemPower.value.appSystem,(val:string)=>{
if(val=="app"){
getAppList();
}
},{
immediate:true
})
onMounted(()=>{
// getOrgTreeAry();
getSystemPowerSub();
console.log("高度-----1---->",roleLeft.value?.offsetHeight)
nextTick(()=>{
treeBoxHeight.value = roleLeft.value?.offsetHeight - 140
treeBoxHeightOrg.value = roleLeft.value?.offsetHeight - 100
})
})
watch(
() => activeAppId.value,
(val) => {
getAppTableList();
},
{
immediate:true
}
);
/**
@ 作者: 秦东
@ 时间: 2025-05-14 15:01:26
@ 功能: 选择App数据
*/
const pickAppList = (val: custerAppInfo) => {
activeAppId.value = val.signCode;
};
const systemMenuTreePropsing = {
children: "child",
label: "name",
value: "id",
};
interface Tree {
name: string
leaf?: boolean
}
const propsLoading = {
label: 'name',
children: 'zones',
isLeaf: 'isLeaf',
}
const loadNode: LoadFunction<Tree> = (node, resolve, reject) => {
console.log("node============>",node)
console.log("resolve===>",resolve)
if (node.level === 0) {
getMyPeoplceAndSunOrg({id:"313",level:node.level}).then((res) => {
console.log("res================>",res)
resolve(res.data)
})
}
if (node.level > 0){
getMyPeoplceAndSunOrg({id:node.data.id.toString(),level:1}).then((res) => {
console.log("res=========1=======>",res.data)
if(res.data && Array.isArray(res.data) && res.data.length > 0){
resolve(res.data)
}else{
resolve([])
}
}).catch(() => {
return reject()
})
}
}
const loadNodePost: LoadFunction<Tree> = (node, resolve, reject) => {
console.log("node============>",node)
console.log("resolve===>",resolve)
if (node.level === 0) {
getMyPeopleAndSunOrgPost({id:"313",level:node.level,types:node.data.types}).then((res) => {
console.log("res================>",res)
resolve(res.data)
})
}
if (node.level > 0){
getMyPeopleAndSunOrgPost({id:node.data.id.toString(),level:1,types:node.data.types}).then((res) => {
console.log("res=========1=======>",res.data)
if(res.data && Array.isArray(res.data) && res.data.length > 0){
resolve(res.data)
}else{
resolve([])
}
}).catch(() => {
return reject()
})
}
}
//
const fpickUserTabs = () => {
getPowerPageUser(searchUser).then((res) => {
console.log("res================>",res)
ownerPeople.value = res.data.list
searchUser.total = res.data.total
})
}
//
const pageCurrentChange = (val:number) => {
searchUser.page = val
fpickUserTabs()
}
</script>
<template>
<div class="roleBox">
<div ref="roleLeft" class="roleLeft">
<el-tabs v-model="systemPower.powerType" class="demo-tabs">
<el-tab-pane label="组织" name="org">
<template #label>
<el-text class="tabsTitle">组织</el-text>
</template>
<el-scrollbar class="tab_pane_bodyLoading">
<el-tree
ref="treeRefOrg"
style="max-width: 350px;"
:props="propsLoading"
:load="loadNode"
:highlight-current="true"
:expand-on-click-node="false"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
node-key="id"
lazy
show-checkbox
@node-click="pickOrgTree"
/>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane label="岗位" name="job">
<template #label>
<el-text class="tabsTitle">岗位</el-text>
</template>
<el-scrollbar class="tab_pane_bodyLoading">
<el-tree
ref="treeRefOrg"
style="max-width: 350px;"
:props="propsLoading"
:load="loadNodePost"
:highlight-current="true"
:expand-on-click-node="false"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
node-key="id"
lazy
show-checkbox
@node-click="pickOrgTree"
/>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane label="角色" name="role">
<template #label>
<el-text class="tabsTitle">角色</el-text>
</template>
<div class="butBox">
<el-button type="primary" @click="addRoleGroup(1)">新建角色组</el-button>
<el-button type="primary" @click="addRoleGroup(2)">新建角色</el-button>
</div>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的角色" :suffix-icon="Search" @input="onQueryChanged"/>
</div>
<el-tree-v2
ref="treeRef"
style="max-width: 350px;"
:data="roleListdata"
:props="props"
:filter-method="filterMethod"
:height="treeBoxHeight"
v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@node-click="pickRoleTree"
>
<template #default="{ node }" >
<div class="treeRoleBox">
<span>{{ node.label }}</span>
<div class="spanButBox">
<el-text v-if="node.disabled" type="warning" size="small" @click.stop="editMyInfoIcon(node.data,1)">禁用</el-text>
<el-text v-else type="success" size="small" @click.stop="editMyInfoIcon(node.data,2)">启用</el-text>
<el-text type="primary" size="small" @click.stop="editMyInfoIcon(node.data,3)">编辑</el-text>
<el-text type="danger" size="small" @click.stop="editMyInfoIcon(node.data,4)">删除</el-text>
</div>
</div>
</template>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="个人" name="person">
<div class="searchBox">
<el-input v-model="searchUser.name" placeholder="请输入要查找的人" :suffix-icon="Search" @input="onQueryChangedOrg"/>
</div>
<el-scrollbar class="tab_pane_bodyes">
<div class="userBox" v-for="item in ownerPeople" :key="item.id">
<el-avatar shape="square" :size="size" :src="item.icon?item.icon:squareUrl" />
<div>
<el-text type="primary" >{{item.name}}{{ '('+item.code+')' }}</el-text>
<el-text type="primary" >{{item.org}}</el-text>
</div>
</div>
</el-scrollbar>
<div style="width: 100%; display: flex; justify-content: center; margin-top: 5px;">
<el-pagination
:page-size="searchUser.pageSize"
:pager-count="7"
layout="prev, pager, next"
:total="searchUser.total"
@current-change="pageCurrentChange"
/>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="roleright">
<el-tabs v-model="systemPower.appSystem" class="demo-tabs">
<el-tab-pane label="平台" name="system">
<template #label>
<el-text class="tabsTitleCont">平台</el-text>
</template>
<el-table
:data="systemPowerTree"
style="width: 100%; height: calc(100vh - 277px)"
:cell-style="{ padding: '10px 0' }"
:header-cell-style="{ background: '#F5F7FA', color: '#909399' }"
border
row-key="id"
>
<el-table-column fixed prop="name" label="目录/菜单" width="380" >
<template #default="scope">
<span class="tree_sapn">{{ scope.row.name }}</span>
<el-tag v-if="scope.row.types === 2" type="warning" size="small">目录</el-tag>
<el-tag v-if="scope.row.types === 1" type="success" size="small">菜单</el-tag>
<el-tag v-if="scope.row.types === 4" type="danger" size="small">按钮</el-tag>
<el-tag v-if="scope.row.types === 3" type="info" size="small">外链</el-tag>
</template>
</el-table-column>
<el-table-column prop="isTrue" label="授权" width="80" align="center" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" label="" />
</template>
</el-table-column>
<el-table-column prop="buttenPower" label="操作按钮" min-width="380" >
<template #header>
<div class="pickButBox">
<el-text >操作按钮</el-text>
<el-button type="primary" size="small">确定授权</el-button>
</div>
</template>
<template #default="scope">
<el-checkbox v-for="item in scope.row.buttenPower" :key="item" v-model="scope.row.isTrue" :label="item.name" />
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="应用" name="app">
<template #label>
<el-text class="tabsTitleCont">应用</el-text>
</template>
<table class="table_body">
<thead>
<tr v-if="systemPower.powerType == 'role'">
<td align="center" width="20%">应用</td>
<td align="center" width="50%">应用详情</td>
</tr>
<tr v-else>
<td align="center" width="20%">应用</td>
<td width="80%">
<div class="appPickPower">
应用详情
<el-button type="primary" size="small">确定授权</el-button>
</div>
</td>
</tr>
</thead>
<tbody>
<tr >
<td valign="top">
<el-scrollbar class="tab_pane_box">
<ul class="appListBox">
<li v-for="item in appList" :key="item" @click="pickAppList(item)">{{ item.name }}</li>
</ul>
</el-scrollbar>
</td>
<td valign="top">
<el-row class="row_head">
<el-col class="roe_col_head left_line" :span="6">
页面
</el-col>
<el-col class="roe_col_head left_line" :span="6">
表单权力
</el-col>
<el-col class="roe_col_head left_line" :span="6">
列表权限
</el-col>
<el-col class="roe_col_head" :span="6">
数据权限
</el-col>
</el-row>
<el-scrollbar class="tab_pane_body">
<el-row class="left_right" v-for="item in appTableList" :key="item.id">
<el-col class="roe_col_head left_line" :span="6">
{{ item.name }}
</el-col>
<el-col class="roe_col_head left_line" :span="6">
<el-checkbox-group v-model="item.tablePower">
<el-checkbox
v-for="city in appTableBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col class="roe_col_head left_line" :span="6">
<el-checkbox-group v-if="item.istIsTrue" v-model="item.listPower">
<el-checkbox
v-for="city in appListBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col class="roe_col_head" :span="6">
<el-radio-group
v-model="item.datePower.types"
@change="pickAppDataPower(item.datePower)"
>
<el-row>
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
<el-col :span="24">
<el-radio :value="5">指定行政组织</el-radio>
<el-tree-select
v-if="item.datePower.types == 5"
v-model="item.datePower.attribute"
:data="orgTree"
style="width: 100%"
node-key="id"
:props="systemMenuTreePropsing"
clearable
multiple
:render-after-expand="false"
show-checkbox
collapse-tags
collapse-tags-tooltip
/>
</el-col>
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
</el-row>
</el-radio-group>
</el-col>
</el-row>
</el-scrollbar>
</td>
</tr>
</tbody>
</table>
</el-tab-pane>
</el-tabs>
</div>
<AddRoleGroup v-if="openRoleGroup" v-model:show="openRoleGroup" :group-info="roleGroupOrInfo" @resthandel="getRoleTree" />
<EditRoleGroup v-if="openEditRoleGroup" v-model:show="openEditRoleGroup" :group-info="roleGroupOrInfo" :data="editRoleCont" @resthandel="getRoleTree" />
</div>
</template>
<style lang='scss' scoped>
.roleBox{
display: flex;
width: 100%;
height: calc(100vh - 170px);
padding: 15px 20px 0 20px;
justify-content: space-between;
.roleLeft{
width: 350px;
height: calc(100vh - 185px);
background-color: #FFFFFF;
.butBox{
display: flex;
justify-content: space-between;
padding: 0 10px 10px 10px;
}
.searchBox{
padding: 0 10px 5px 10px;
}
.treeBox{
height: calc(100vh - 330px);
}
}
.roleright{
width: calc(100% - 370px);
height: calc(100vh - 185px);
background-color: #FFFFFF;
overflow: hidden;
:deep .el-tabs__content{
padding: 15px 15px 15px 0px;
}
:deep .el-main{
padding: 0 15px;
}
.userTitleBox{
display: flex;
justify-content: space-between;
padding: 0px 0px 15px 0px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2);
}
.userTitleBoxes{
display: flex;
justify-content: space-between;
}
.pickButBox{
display: flex;
align-items: center;
justify-content: space-between;
}
.scrollBox{
margin-top: 5px;
height: calc(100vh - 320px);
}
}
.tabsTitle{
padding: 0 15px;
}
.tabsTitleCont{
padding: 0 35px;
}
.treeRoleBox{
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
}
.spanButBox{
span{
padding: 0 5px;
}
}
}
.tree_sapn {
padding: 0 10px 0 0;
}
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
.appListBox {
width: 100%;
li {
padding: 10px 2px;
border-bottom: 1px solid #ececec;
cursor: pointer;
}
li.active {
background-color: #a0cfff;
}
}
.tab_pane_box {
height: calc(100vh - 310px);
overflow: hidden;
overflow-y: auto;
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
}
.row_head{
background-color: #f5f7fa;
color: #000000;
text-align: center;
border: 1px solid #E4E7ED;
}
.roe_col_head{
padding: 5px 5px;
}
.left_right{
border-left: 1px solid #E4E7ED;
border-right: 1px solid #E4E7ED;
border-bottom: 1px solid #E4E7ED;
}
.left_line{
border-right: 1px solid #E4E7ED;
}
.tab_pane_body {
height: calc(100vh - 340px);
overflow: hidden;
overflow-y: auto;
}
.tab_pane_bodyes {
height: calc(100vh - 320px);
overflow: hidden;
overflow-y: auto;
}
.tab_pane_bodyLoading {
height: calc(100vh - 250px);
overflow: hidden;
overflow-y: auto;
}
.appPickPower{
display: flex;
justify-content: space-between;
align-items: center;
}
.userBox{
width: 100%;
min-height: 50px;
display: flex;
align-items: center;
justify-items: space-between;
padding: 0 10px;
border-bottom: 1px dashed rgba($color: #000000, $alpha: 0.2);
div{
span{
display: flex;
width: 100%;
padding: 0 5px;
color:rgba($color: #000000, $alpha: 0.6);
}
}
}
</style>

819
src/views/system/monitor/online/index2.vue

@ -0,0 +1,819 @@
<!--
@ 作者: 秦东
@ 时间: 2025-10-21 10:06:51
@ 备注: 在线人数
-->
<script lang='ts' setup>
import { giveRoleTree,editRoleStatus,getOrgPostTree } from '@/api/role/index'
import type {RoleListTree,RoleFormInfo,orgAndPostisListTree} from '@/api/role/types'
import type { TreeNode,TreeInstance } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { orgInfo } from "@/api/hr/org/type";
import { getOrgTreeList } from "@/api/hr/org/index";
import { appPowerUnit } from "@/api/system/roleapi/power";
import type { getSystemPower,AppPowerTree } from "@/api/system/roleapi/types";
import { appTableBut, appListBut } from "@/utils/workflow/const";
import {
gainAppList,
gainAppTableListNew,
getMyPeoplceAndSunOrg,
getMyPeopleAndSunOrgPost,
getPowerPageUser
} from "@/api/system/roleapi/postrole";
import {
custerAppInfo
} from "@/api/system/roleapi/types";
import AddRoleGroup from '@/views/system/monitor/online/roleConfig/addRoleGroup.vue'
import EditRoleGroup from '@/views/system/monitor/online/roleConfig/editRoleGroup.vue'
const squareUrl = ref<string>(
"https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png"
);
const orgTree = ref<orgInfo[]>([])
const roleGroupOrInfo = ref(1)
const searchQuery = ref('')
const orgWorkRole = ref("org")
const appSysPick = ref("system")
const treeRef = ref<TreeInstance>()
const treeRefOrg = ref<TreeInstance>()
const treeRefOrgPost = ref<TreeInstance>()
const roleListdata = ref<RoleListTree[]>([])
const orgPostisListdata = ref<orgAndPostisListTree[]>([])
const treeBoxHeight = ref(300)
const treeBoxHeightOrg = ref(300)
const roleLeft = ref()
const systemPowerTree = ref<AppPowerTree[]>([])
const ownerPeople = ref<any>([])
const props = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
const propsOrg = {
value: 'id',
label: 'name',
// disabled:'status',
children: 'child',
}
const propsOrgPost = {
value: 'id',
label: 'label',
disabled:'status',
children: 'children',
}
const systemPower = ref<getSystemPower>({
powerType:"org",
appType:"appsystem",
appSystem:"system",
roleId:"",
})
const roleLoading = ref(false)
const openRoleGroup = ref(false)
const orgLoading = ref(false)
const orgPostLoading = ref(false)
const appList = ref<custerAppInfo[]>([]);
//
const onQueryChanged = (query: string) => {
treeRef.value!.filter(query)
}
//
const onQueryChangedOrg = (query: string) => {
treeRefOrg.value!.filter(query)
}
const filterMethod = (query: string, node: any) => node.label!.includes(query)
const filterMethodOrg = (query: string, node: any) => node.label!.includes(query)
//
watch(()=>systemPower.value.powerType,(val:string)=>{
console.log("监测赋权组",val)
getSystemPowerSub();
switch(val){
case "org":
getOrgTreeAry();
break;
case "job":
getOrgPostisTree()
break;
case "role":
getRoleTree();
break;
default:
}
if(systemPower.value.appSystem=="app"){
getAppList();
}else{
getSystemPowerSub();
}
},{
deep:true
})
//
const pickRoleTree = (data:any) => {
if(data.status && data.types==1){
console.log("监测赋权组------->",data)
}
}
//
const pickOrgTree = (data:any) => {
console.log("监测赋权组------->",data)
}
//
const getRoleTree = () => {
roleLoading.value = true
giveRoleTree().then(({data})=>{
console.log("监测赋权组------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id.toString()
}
roleListdata.value=data;
roleLoading.value = false;
}).finally(()=>{roleLoading.value = false})
}
const editRoleCont = ref<RoleFormInfo>()
const openEditRoleGroup = ref(false)
//
const editMyInfoIcon = (data:RoleListTree,types:number) => {
console.log("编辑角色信息------->",data)
console.log("编辑角色信息---types---->",types)
switch(types){
case 1:
editRoleStatusBut(data.id,2)
break;
case 2:
editRoleStatusBut(data.id,1)
break;
case 3:
editRoleCont.value = {
id:data.id,
name:data.label,
type:data.types,
superior:data.superior,
sort:data.sort
}
openEditRoleGroup.value = true
break;
case 4:
ElMessageBox.confirm(
"您确定要删除此信息吗?一经删除!数据将不可恢复!请慎重操作!",
"警告",
{
confirmButtonText: '确定删除',
cancelButtonText: '取消删除',
type: 'warning',
}
).then(()=>{
editRoleStatusBut(data.id,3)
})
break;
default:
break;
}
}
//
const editRoleStatusBut = (id:string|number,types:number) => {
// console.log("--->",id)
editRoleStatus({id:id.toString(),status:types}).then((data:any)=>{
if(data.code==0){
ElMessage({
message: data.msg,
type: 'success',
})
getRoleTree()
}else{
ElMessage({
message: data.msg,
type: 'success',
})
}
})
}
//
const addRoleGroup = (types:number) => {
roleGroupOrInfo.value = types
openRoleGroup.value = true
}
//
const getOrgTreeAry = () => {
roleLoading.value = true
if(!Array.isArray(orgTree.value) || orgTree.value.length<=0){
getOrgTreeList({ orgid: 0 })
.then(({ data }) => {
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id.toString()
}
orgTree.value = data
roleLoading.value = false
}).finally(()=>{roleLoading.value = false})
}else{
roleLoading.value = false
}
}
//
const getOrgPostisTree = () => {
orgPostLoading.value=true
if(!Array.isArray(orgPostisListdata.value) || orgPostisListdata.value.length<=0){
getOrgPostTree({id:"313"}).then(({data})=>{
console.log("获取行政组织及岗位--------->",data)
if(Array.isArray(data) && data.length>0){
systemPower.value.roleId=data[0].id.toString()
}
orgPostisListdata.value = data
orgPostLoading.value=false
}).finally(()=>{orgPostLoading.value=false})
}else{
orgPostLoading.value=true
}
}
//
const getSystemPowerSub = () => {
appPowerUnit(systemPower.value).then(({data})=>{
console.log("获取平台授权项目------->",data)
systemPowerTree.value = data
})
}
const activeAppId = ref<string>("");
const appTableList = ref<custerAppTablePower[]>([]);
/**
@ 作者: 秦东
@ 时间: 2025-05-13 14:20:47
@ 功能: 获取自定义App
*/
const getAppList = () => {
gainAppList().then((datassssssssssssssssssssssssssssssssssssssssssssssssssssss: any) => {
console.log("获取自定义App", data);
appList.value = data.data;
if (data.data && data.data.length > 0) {
if (data.data[0] && data.data[0].signCode) {
activeAppId.value = data.data[0].signCode;
getAppTableList();
}
}
console.log("获取自定义App", activeAppId.value);
});
};
/**
@ 作者: 秦东
@ 时间: 2025-05-13 16:00:19
@ 功能: 获取对应App下边的表单
*/
const getAppTableList = () => {
systemPower.value.roleId = activeAppId.value.toString()
gainAppTableListNew({id:activeAppId.value,appType:systemPower.value.appType,powerType:systemPower.value.powerType,roleId:systemPower.value.roleId}).then(
(data: any) => {
console.log("获取对应App下边的表单", data);
if (Array.isArray(data.data)) {
appTableList.value = data.data;
} else {
appTableList.value = [];
}
}
);
};
watch(()=>systemPower.value.appSystem,(val:string)=>{
if(val=="app"){
getAppList();
}
},{
immediate:true
})
onMounted(()=>{
getOrgTreeAry();
getSystemPowerSub();
console.log("高度-----1---->",roleLeft.value?.offsetHeight)
nextTick(()=>{
treeBoxHeight.value = roleLeft.value?.offsetHeight - 140
treeBoxHeightOrg.value = roleLeft.value?.offsetHeight - 100
})
})
watch(
() => activeAppId.value,
(val) => {
getAppTableList();
},
{
immediate:true
}
);
/**
@ 作者: 秦东
@ 时间: 2025-05-14 15:01:26
@ 功能: 选择App数据
*/
const pickAppList = (val: custerAppInfo) => {
activeAppId.value = val.signCode;
};
const systemMenuTreePropsing = {
children: "child",
label: "name",
value: "id",
};
//
const onQuedOrg = (query: string) => {
treeRefOrgPost.value!.filter(query)
}
</script>
<template>
<div class="roleBox">
<div ref="roleLeft" class="roleLeft">
<el-tabs v-model="systemPower.powerType" class="demo-tabs">
<el-tab-pane label="组织" name="org">
<template #label>
<el-text class="tabsTitle">组织</el-text>
</template>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQueryChangedOrg"/>
</div>
<el-tree-v2
ref="treeRefOrg"
style="max-width: 350px;"
:data="orgTree"
:props="propsOrg"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
show-checkbox
@node-click="pickOrgTree"
>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="岗位" name="job">
<template #label>
<el-text class="tabsTitle">岗位</el-text>
</template>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :suffix-icon="Search" @input="onQuedOrg"/>
</div>
<el-tree-v2
ref="treeRefOrgPost"
style="max-width: 350px;"
:data="orgPostisListdata"
:props="propsOrgPost"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
show-checkbox
@node-click="pickOrgTree"
>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="角色" name="role">
<template #label>
<el-text class="tabsTitle">角色</el-text>
</template>
<div class="butBox">
<el-button type="primary" @click="addRoleGroup(1)">新建角色组</el-button>
<el-button type="primary" @click="addRoleGroup(2)">新建角色</el-button>
</div>
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的角色" :suffix-icon="Search" @input="onQueryChanged"/>
</div>
<el-tree-v2
ref="treeRef"
style="max-width: 350px;"
:data="roleListdata"
:props="props"
:filter-method="filterMethod"
:height="treeBoxHeight"
v-loading="roleLoading"
show-checkbox
@node-click="pickRoleTree"
>
<template #default="{ node }" >
<div class="treeRoleBox">
<span>{{ node.label }}</span>
<div class="spanButBox">
<el-text v-if="node.disabled" type="warning" size="small" @click.stop="editMyInfoIcon(node.data,1)">禁用</el-text>
<el-text v-else type="success" size="small" @click.stop="editMyInfoIcon(node.data,2)">启用</el-text>
<el-text type="primary" size="small" @click.stop="editMyInfoIcon(node.data,3)">编辑</el-text>
<el-text type="danger" size="small" @click.stop="editMyInfoIcon(node.data,4)">删除</el-text>
</div>
</div>
</template>
</el-tree-v2>
</el-tab-pane>
<el-tab-pane label="个人" name="person">
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的人" :suffix-icon="Search" @input="onQueryChangedOrg"/>
</div>
<el-scrollbar class="tab_pane_bodyes">
<div class="userBox" v-for="item in 30" :key="item.id">
<el-avatar shape="square" :size="size" :src="item.icon?item.icon:squareUrl" />
<div>
<el-text type="primary" >{{item.name}}{{ '('+item.code+')' }}</el-text>
<el-text type="primary" >{{item.orgName}}</el-text>
</div>
</div>
</el-scrollbar>
<div style="width: 100%; display: flex; justify-content: center; margin-top: 5px;">
<el-pagination
:page-size="19"
:pager-count="7"
layout="prev, pager, next"
:total="2"
/>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="roleright">
<el-tabs v-model="systemPower.appSystem" class="demo-tabs">
<el-tab-pane label="平台" name="system">
<template #label>
<el-text class="tabsTitleCont">平台</el-text>
</template>
<el-table
:data="systemPowerTree"
style="width: 100%; height: calc(100vh - 277px)"
:cell-style="{ padding: '10px 0' }"
:header-cell-style="{ background: '#F5F7FA', color: '#909399' }"
border
row-key="id"
>
<el-table-column fixed prop="name" label="目录/菜单" width="380" >
<template #default="scope">
<span class="tree_sapn">{{ scope.row.name }}</span>
<el-tag v-if="scope.row.types === 2" type="warning" size="small">目录</el-tag>
<el-tag v-if="scope.row.types === 1" type="success" size="small">菜单</el-tag>
<el-tag v-if="scope.row.types === 4" type="danger" size="small">按钮</el-tag>
<el-tag v-if="scope.row.types === 3" type="info" size="small">外链</el-tag>
</template>
</el-table-column>
<el-table-column prop="isTrue" label="授权" width="80" align="center" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" label="" />
</template>
</el-table-column>
<el-table-column prop="buttenPower" label="操作按钮" min-width="380" >
<template #header>
<div class="pickButBox">
<el-text >操作按钮</el-text>
<el-button type="primary" size="small">确定授权</el-button>
</div>
</template>
<template #default="scope">
<el-checkbox v-for="item in scope.row.buttenPower" :key="item" v-model="scope.row.isTrue" :label="item.name" />
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="应用" name="app">
<template #label>
<el-text class="tabsTitleCont">应用</el-text>
</template>
<table class="table_body">
<thead>
<tr>
<td align="center" width="20%">应用</td>
<td width="80%">
<div class="appPickPower">
应用详情
<el-button type="primary" size="small">确定授权</el-button>
</div>
</td>
</tr>
</thead>
<tbody>
<tr >
<td valign="top">
<el-scrollbar class="tab_pane_box">
<ul class="appListBox">
<li v-for="item in appList" :key="item" @click="pickAppList(item)">{{ item.name }}</li>
</ul>
</el-scrollbar>
</td>
<td valign="top">
<el-row class="row_head">
<el-col class="roe_col_head left_line" :span="6">
页面
</el-col>
<el-col class="roe_col_head left_line" :span="6">
表单权力
</el-col>
<el-col class="roe_col_head left_line" :span="6">
列表权限
</el-col>
<el-col class="roe_col_head" :span="6">
数据权限
</el-col>
</el-row>
<el-scrollbar class="tab_pane_body">
<el-row class="left_right" v-for="item in appTableList" :key="item.id">
<el-col class="roe_col_head left_line" :span="6">
{{ item.name }}
</el-col>
<el-col class="roe_col_head left_line" :span="6">
<el-checkbox-group v-model="item.tablePower">
<el-checkbox
v-for="city in appTableBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col class="roe_col_head left_line" :span="6">
<el-checkbox-group v-if="item.istIsTrue" v-model="item.listPower">
<el-checkbox
v-for="city in appListBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</el-col>
<el-col class="roe_col_head" :span="6">
<el-radio-group
v-model="item.datePower.types"
@change="pickAppDataPower(item.datePower)"
>
<el-row>
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
<el-col :span="24">
<el-radio :value="5">指定行政组织</el-radio>
<el-tree-select
v-if="item.datePower.types == 5"
v-model="item.datePower.attribute"
:data="orgTree"
style="width: 100%"
node-key="id"
:props="systemMenuTreePropsing"
clearable
multiple
:render-after-expand="false"
show-checkbox
collapse-tags
collapse-tags-tooltip
/>
</el-col>
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
</el-row>
</el-radio-group>
</el-col>
</el-row>
</el-scrollbar>
</td>
</tr>
</tbody>
</table>
</el-tab-pane>
</el-tabs>
</div>
<AddRoleGroup v-if="openRoleGroup" v-model:show="openRoleGroup" :group-info="roleGroupOrInfo" @resthandel="getRoleTree" />
<EditRoleGroup v-if="openEditRoleGroup" v-model:show="openEditRoleGroup" :group-info="roleGroupOrInfo" :data="editRoleCont" @resthandel="getRoleTree" />
</div>
</template>
<style lang='scss' scoped>
.roleBox{
display: flex;
width: 100%;
height: calc(100vh - 170px);
padding: 15px 20px 0 20px;
justify-content: space-between;
.roleLeft{
width: 350px;
height: calc(100vh - 185px);
background-color: #FFFFFF;
.butBox{
display: flex;
justify-content: space-between;
padding: 0 10px 10px 10px;
}
.searchBox{
padding: 0 10px 5px 10px;
}
.treeBox{
height: calc(100vh - 330px);
}
}
.roleright{
width: calc(100% - 370px);
height: calc(100vh - 185px);
background-color: #FFFFFF;
overflow: hidden;
:deep .el-tabs__content{
padding: 15px 15px 15px 0px;
}
:deep .el-main{
padding: 0 15px;
}
.userTitleBox{
display: flex;
justify-content: space-between;
padding: 0px 0px 15px 0px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2);
}
.userTitleBoxes{
display: flex;
justify-content: space-between;
}
.pickButBox{
display: flex;
align-items: center;
justify-content: space-between;
}
.scrollBox{
margin-top: 5px;
height: calc(100vh - 320px);
}
}
.tabsTitle{
padding: 0 15px;
}
.tabsTitleCont{
padding: 0 35px;
}
.treeRoleBox{
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
}
.spanButBox{
span{
padding: 0 5px;
}
}
}
.tree_sapn {
padding: 0 10px 0 0;
}
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
.appListBox {
width: 100%;
li {
padding: 10px 2px;
border-bottom: 1px solid #ececec;
cursor: pointer;
}
li.active {
background-color: #a0cfff;
}
}
.tab_pane_box {
height: calc(100vh - 310px);
overflow: hidden;
overflow-y: auto;
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
}
.row_head{
background-color: #f5f7fa;
color: #000000;
text-align: center;
border: 1px solid #E4E7ED;
}
.roe_col_head{
padding: 5px 5px;
}
.left_right{
border-left: 1px solid #E4E7ED;
border-right: 1px solid #E4E7ED;
border-bottom: 1px solid #E4E7ED;
}
.left_line{
border-right: 1px solid #E4E7ED;
}
.tab_pane_body {
height: calc(100vh - 340px);
overflow: hidden;
overflow-y: auto;
}
.tab_pane_bodyes {
height: calc(100vh - 320px);
overflow: hidden;
overflow-y: auto;
}
.appPickPower{
display: flex;
justify-content: space-between;
align-items: center;
}
.userBox{
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-items: space-between;
padding: 0 10px;
border-bottom: 1px dashed rgba($color: #000000, $alpha: 0.2);
div{
span{
display: flex;
width: 100%;
padding: 0 5px;
color:rgba($color: #000000, $alpha: 0.6);
}
}
}
</style>

0
src/views/system/monitor/online/index copy.vue → src/views/system/monitor/online/index_20251112.vue

1189
src/views/system/monitor/online/index_20251217.vue

File diff suppressed because it is too large

283
src/views/system/monitor/online/page.vue

@ -0,0 +1,283 @@
<!--
@ 作者: 秦东
@ 时间: 2025-10-21 10:06:51
@ 备注: 在线人数
-->
<script lang='ts' setup>
import {
getMyPeoplceAndSunOrg
} from "@/api/system/roleapi/postrole";
import type { LoadFunction } from 'element-plus'
interface Tree {
name: string
leaf?: boolean
}
const props = {
label: 'name',
children: 'zones',
isLeaf: 'isLeaf',
}
let time = 0
const loadNode: LoadFunction<Tree> = (node, resolve, reject) => {
console.log("node============>",node)
console.log("resolve===>",resolve)
if (node.level === 0) {
getMyPeoplceAndSunOrg({id:"313",level:node.level}).then((res) => {
console.log("res================>",res)
resolve(res.data)
})
}
if (node.level > 0){
getMyPeoplceAndSunOrg({id:node.data.id.toString(),level:1}).then((res) => {
console.log("res=========1=======>",res.data)
if(res.data && Array.isArray(res.data) && res.data.length > 0){
resolve(res.data)
}else{
resolve([])
}
}).catch(() => {
return reject()
})
}
// time++
// if (node.level > 0){
// setTimeout(() => {
// if (time > 3) {
// console.log("node.id============>",node.id)
// console.log("node.level============>",node.level)
// getMyPeoplceAndSunOrg({id:node.data.id.toString(),level:1}).then((res) => {
// console.log("res=========1=======>",res.data)
// // resolve(res.data.data?.map((item: any) => ({
// // name: item.orgName,
// // id: item.orgId,
// // isLeaf: item.isLeaf,
// // zones: []
// // })) || [])
// if(res.data && Array.isArray(res.data) && res.data.length > 0){
// resolve(res.data)
// }else{
// resolve([])
// }
// })
// }else{
// return reject()
// }
// }, 3000)
// }
}
//
const pickOrgTree = (data:any) => {
console.log("监测赋权组------->",data)
}
</script>
<template>
<div class="roleBox">
<el-tree
style="max-width: 100%"
:props="props"
:load="loadNode"
:highlight-current="true"
:expand-on-click-node="false"
node-key="id"
lazy
@node-click="pickOrgTree"
/>
</div>
</template>
<style lang='scss' scoped>
.roleBox{
display: flex;
width: 100%;
height: calc(100vh - 170px);
padding: 15px 20px 0 20px;
justify-content: space-between;
.roleLeft{
width: 350px;
height: calc(100vh - 185px);
background-color: #FFFFFF;
.butBox{
display: flex;
justify-content: space-between;
padding: 0 10px 10px 10px;
}
.searchBox{
padding: 0 10px 5px 10px;
}
.treeBox{
height: calc(100vh - 330px);
}
}
.roleright{
width: calc(100% - 370px);
height: calc(100vh - 185px);
background-color: #FFFFFF;
overflow: hidden;
:deep .el-tabs__content{
padding: 15px 15px 15px 0px;
}
:deep .el-main{
padding: 0 15px;
}
.userTitleBox{
display: flex;
justify-content: space-between;
padding: 0px 0px 15px 0px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2);
}
.userTitleBoxes{
display: flex;
justify-content: space-between;
}
.pickButBox{
display: flex;
align-items: center;
justify-content: space-between;
}
.scrollBox{
margin-top: 5px;
height: calc(100vh - 320px);
}
}
.tabsTitle{
padding: 0 15px;
}
.tabsTitleCont{
padding: 0 35px;
}
.treeRoleBox{
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
}
.spanButBox{
span{
padding: 0 5px;
}
}
}
.tree_sapn {
padding: 0 10px 0 0;
}
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
.appListBox {
width: 100%;
li {
padding: 10px 2px;
border-bottom: 1px solid #ececec;
cursor: pointer;
}
li.active {
background-color: #a0cfff;
}
}
.tab_pane_box {
height: calc(100vh - 310px);
overflow: hidden;
overflow-y: auto;
.table_body {
background-color: #ffffff;
width: 100%;
border-collapse: collapse;
/*
* 设置边框
*/
td,
th {
border: 1px solid #cccccc;
padding: 5px;
table {
width: 100%;
td,
th {
border: 0px solid #cccccc;
padding: 0px;
}
}
}
}
}
.row_head{
background-color: #f5f7fa;
color: #000000;
text-align: center;
border: 1px solid #E4E7ED;
}
.roe_col_head{
padding: 5px 5px;
}
.left_right{
border-left: 1px solid #E4E7ED;
border-right: 1px solid #E4E7ED;
border-bottom: 1px solid #E4E7ED;
}
.left_line{
border-right: 1px solid #E4E7ED;
}
.tab_pane_body {
height: calc(100vh - 340px);
overflow: hidden;
overflow-y: auto;
}
.tab_pane_bodyes {
height: calc(100vh - 320px);
overflow: hidden;
overflow-y: auto;
}
.appPickPower{
display: flex;
justify-content: space-between;
align-items: center;
}
.userBox{
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-items: space-between;
padding: 0 10px;
border-bottom: 1px dashed rgba($color: #000000, $alpha: 0.2);
div{
span{
display: flex;
width: 100%;
padding: 0 5px;
color:rgba($color: #000000, $alpha: 0.6);
}
}
}
</style>

444
src/views/system/monitor/online/powerPage/appTabsPower.vue

@ -0,0 +1,444 @@
<!--
@ 作者: 秦东
@ 时间: 2025-12-17 16:53:07
@ 备注:
-->
<script lang='ts' setup>
import { appTableBut, appListBut,appDetailBut,formBaseBut,appGroupBut } from "@/utils/workflow/const";
import { orgInfo } from '@/api/displayboardapi/types';
import { appInitAuthorization,tabsAuthorizationMode } from "@/api/system/roleapi/postrole";
import type { TabsPaneContext } from 'element-plus'
const props = defineProps({
appType: {
type: String,
default: "app"
},
powerType: {
type: String,
default: ""
},
roleId: {
type: String,
default: ""
},
orgTree: {
type: Array as PropType<orgInfo[]>,
default: () => []
}
})
const appLoading = ref(false)
const submitLoading = ref(false)
const appPowerArt = ref<any>([])
const appGroupButAry = ref<string[]>([])
const powerActiveName = reactive({
group:"",
app:""
})
const systemMenuTreePropsing = {
children: "child",
label: "name",
value: "id",
};
/**
@ 作者: 秦东
@ 时间: 2025-05-13 14:20:47
@ 功能: 获取自定义App
*/
const getAppList = () => {
appLoading.value=true
appPowerArt.value = []
appGroupButAry.value = []
appInitAuthorization({appType:"app",powerType:props.powerType,roleId:props.roleId}).then((data: any) => {
console.log("获取自定义App", data);
// appList.value = data.data;
appPowerArt.value = data.data.appList
appGroupButAry.value = data.data.groupButPower
appLoading.value=false
if(data.data.appList && Array.isArray(data.data.appList)){
powerActiveName.group = data.data.appList[0].id
if(data.data.appList[0].appList && Array.isArray(data.data.appList[0].appList)){
powerActiveName.app = data.data.appList[0].appList[0].id
}
}
}).finally(()=>{
appLoading.value=false
submitLoading.value = false
})
};
/**
@ 作者: 秦东
@ 时间: 2025-12-18 10:17:07
@ 功能: 标签被选择
*/
const handleTabClick = (val:any) => {
if(appPowerArt.value && Array.isArray(appPowerArt.value)){
appPowerArt.value.find((item:any) => {
if(item.id === powerActiveName.group){
powerActiveName.app = item.appList[0].id
}
})
// powerActiveName.app = appPowerArt.value.find((item:any) => item.id === powerActiveName.group)?.appList[0].id
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-18 11:14:56
@ 功能: 选择分组
*/
const handleGroupChange = (item:any) => {
console.log("-------------------------->",item)
// if(item.isTrue){
if(item.appList && Array.isArray(item.appList)){
item.appList.find((app:any) => {
app.isTrue = item.isTrue
if(item.isTrue){
app.operationButton = ["bjapp","scapp","xzfg","scfg","yzfg","xz","bj","sc","yz","jczdh","yysz","yyfb"]
}else{
app.operationButton = []
}
if(app.appMenuTree && Array.isArray(app.appMenuTree)){
app.appMenuTree = handleAppChange(app.appMenuTree,item.isTrue)
}
})
}
// }
}
/**
@ 作者: 秦东
@ 时间: 2025-12-18 11:23:40
@ 功能: 循环递归联动赋值
*/
const handleAppChange = (item:any,isTrue:boolean) => {
// console.log("-------------------------->",item)
if(item && Array.isArray(item)){
item.forEach((menu:any) => {
menu.isTrue = isTrue
if(isTrue){
menu.formPower = [ "zc", "tj", "dy", "sc", "fz"]
menu.listPower = [ "newAdd", "import", "export", "sc", "dy", "showQrCode","del","bj"]
}else{
menu.formPower = []
menu.listPower = []
}
if(menu.children && Array.isArray(menu.children)){
menu.children = handleAppChange(menu.children,isTrue)
}
})
}
return item
}
/**
@ 作者: 秦东
@ 时间: 2025-12-18 13:48:26
@ 功能: 选择App
*/
const handleAppPowerChange = (item:any) => {
console.log("----------------选择App---------->",item)
if(item.isTrue){
item.operationButton = ["bjapp","scapp","xzfg","scfg","yzfg","xz","bj","sc","yz","jczdh","yysz","yyfb"]
}else{
item.operationButton = []
}
if(item.appMenuTree && Array.isArray(item.appMenuTree)){
item.appMenuTree = handleAppChange(item.appMenuTree,item.isTrue)
}
}
/**
@ 作者: 秦东
@ 时间: 2025-12-18 13:58:21
@ 功能: 选择App菜单是选中状态下关联操作按钮
*/
const handleAppMenuChange = (item:any) => {
// console.log("----------------App---------->",item)
if(item.isTrue){
item.formPower = [ "zc", "tj", "dy", "sc", "fz"]
item.listPower = [ "newAdd", "import", "export", "sc", "dy", "showQrCode","del","bj"]
}else{
item.formPower = []
item.listPower = []
}
if(item.children && Array.isArray(item.children)){
item.children = handleAppChange(item.children,item.isTrue)
}
}
onMounted(()=>{
// getAppList()
})
defineExpose({
getAppList
})
/**
@ 作者: 秦东
@ 时间: 2025-12-18 14:16:49
@ 功能: 提交授权
*/
const submitPower = () => {
submitLoading.value = true
let sendData:any = {
appType:"app",
powerType:props.powerType,
roleId:props.roleId,
listPower:appPowerArt.value,
groupPower:appGroupButAry.value
}
if(!props.roleId || props.roleId === ""){
ElMessage.error("具体授权属性!")
submitLoading.value = false
return
}
console.log("----------------提交授权---------->",sendData)
// submitLoading.value = true
tabsAuthorizationMode(sendData).then((data: any) => {
if(data.code === 0){
ElMessage.success("授权成功!")
submitLoading.value = false
}else{
ElMessage.error(data.msg)
}
}).catch((err: any) => {
ElMessage.error(err.message)
submitLoading.value = false
})
}
/**
@ 作者: 秦东
@ 时间: 2025-12-20 15:33:37
@ 功能: 全选
*/
const pickAllBut = (item:any,types:number) => {
console.log("--全选------------------------>",item,types)
// item.isTrue = !item.isTrue
switch(types){
case 1:
// item.pagePowerIsAll = item.isTrue
item.pagePower = item.pagePowerIsAll ? ["lc","lb","sj","dy","nc"] : []
break
case 2:
// item.formPowerIsAll = item.isTrue
item.formPower = item.formPowerIsAll ? ["zc", "tj", "dy", "sc", "fz"] : []
break
case 3:
// item.listPowerIsAll = item.isTrue
item.listPower = item.listPowerIsAll ? ["newAdd", "import", "export", "sc", "dy", "showQrCode","del","bj"] : []
break
case 4:
// item.isTrue = item.isTrue
item.operationButton = item.isPick ? ["bjapp","scapp","xzfg","scfg","yzfg","xz","bj","sc","yz","jczdh","yysz","yyfb"] : []
break
}
}
</script>
<template>
<div class="app-tabs-content" v-loading="appLoading">
<el-checkbox-group v-model="appGroupButAry">
<el-checkbox
v-for="city in appGroupBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
<el-tabs v-model="powerActiveName.group" @tab-change="handleTabClick" class="demo-tabs " >
<el-tab-pane v-for="item in appPowerArt" :label="item.name" :key="item.id" :name="item.id" class="center-content">
<template #label>
<div class="app-tabs-checkbox">
<el-checkbox v-model="item.isTrue" @change="handleGroupChange(item)" /><span>{{item.name}}</span>
</div>
</template>
<!--应用-->
<el-tabs v-model="powerActiveName.app" class="demo-tabs left_hight" tab-position="left">
<el-tab-pane v-for="app in item.appList" :label="app.name" :key="app.id" :name="app.id" class="center-content">
<template #label>
<div class="app-tabs-checkbox">
<el-checkbox v-model="app.isTrue" @change="handleAppPowerChange(app)" /><span>{{app.name}}</span>
</div>
</template>
<div >
<div style="width:100%">
<el-checkbox label="全选" v-model="app.isPick" @change="pickAllBut(app,4)" />
</div>
<div class="app-form-checkbox">
<el-checkbox-group v-model="app.operationButton">
<el-checkbox
v-for="city in appDetailBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<el-table
:data="app.appMenuTree"
style="width: 100%;"
class="tableScrollbar"
row-key="id"
border
default-expand-all
>
<el-table-column prop="name" label="栏目名称" >
<template #default="scope">
<el-checkbox v-model="scope.row.isTrue" :value="scope.row.isTrue" @change="handleAppMenuChange(scope.row)" ></el-checkbox>
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column prop="pagePower" label="页面权力" >
<template #header>
<el-text>页面权限</el-text>
</template>
<template #default="scope">
<el-checkbox label="全选" v-model="scope.row.pagePowerIsAll" @change="pickAllBut(scope.row,1)" />
<el-checkbox-group v-model="scope.row.pagePower">
<el-checkbox
v-for="city in formBaseBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.value }} {{ city.label }}
</el-checkbox>
</el-checkbox-group>
</template>
</el-table-column>
<el-table-column prop="formPower" label="表单权限" >
<template #header>
<el-text>表单权限</el-text>
</template>
<template #default="scope">
<el-checkbox label="全选" v-model="scope.row.formPowerIsAll" @change="pickAllBut(scope.row,2)" />
<el-checkbox-group v-model="scope.row.formPower">
<el-checkbox
v-for="city in appTableBut"
:key="city.value"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</template>
</el-table-column>
<el-table-column prop="listPower" label="listPower" >
<template #header>
<el-text>列表权限</el-text>
</template>
<template #default="scope">
<el-checkbox label="全选" v-model="scope.row.listPowerIsAll" @change="pickAllBut(scope.row,3)" />
<el-checkbox-group v-model="scope.row.listPower">
<el-checkbox
v-for="city in appListBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</template>
</el-table-column>
<el-table-column prop="visibleRange" label="数据权限" >
<template #header>
<el-text>数据权限</el-text>
</template>
<template #default="scope">
<el-radio-group
v-model="scope.row.visibleRange.types"
>
<el-row>
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
<el-col :span="24">
<el-radio :value="5">指定行政组织</el-radio>
<el-tree-select
v-if="scope.row.visibleRange.types == 5"
v-model="scope.row.visibleRange.attribute"
:data="orgTree"
style="width: 100%"
node-key="id"
:props="systemMenuTreePropsing"
clearable
multiple
:render-after-expand="false"
show-checkbox
collapse-tags
collapse-tags-tooltip
/>
</el-col>
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
</el-row>
</el-radio-group>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
<el-affix position="bottom" :offset="100" style="margin-left: 250px;">
<el-button v-loading="submitLoading" type="primary" @click="submitPower">确定授权</el-button>
</el-affix>
</el-tabs>
</div>
</template>
<style lang='scss' scoped>
.app-tabs-content {
width: 100%;
:deep .el-tabs__content{
padding: 0;
}
.app-form-checkbox{
width: 200px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 10px;
}
}
.app-tabs-checkbox{
width: 100%;
text-align: left;
padding: 0 10px;
display: flex;
align-items: center;
span{
margin-left: 5px;
}
}
.center-content {
display: flex;
justify-content: space-between;
height: 100%; /* 根据需要设置高度 */
padding: 0px;
}
.tableScrollbar{
width: 100%;
height: calc(100vh - 365px);
overflow: hidden;
overflow-y: auto;
}
.left_hight{
height: calc(100vh - 350px);
}
</style>

249
src/views/system/monitor/online/powerPage/apptablepower.vue

@ -0,0 +1,249 @@
<!--
@ 作者: 秦东
@ 时间: 2025-12-17 16:40:42
@ 备注: app授权布局
-->
<script lang='ts' setup>
import { appTableBut, appListBut,appDetailBut,formBaseBut,appGroupBut } from "@/utils/workflow/const";
import { appInitAuthorization,gainAppTableListNew,getPowerPageUser,systemAppAuthorization,gainAppEmpowerPower } from "@/api/system/roleapi/postrole";
import { orgInfo } from "@/api/displayboardapi/types";
const props = defineProps({
appType: {
type: String,
default: ""
},
powerType: {
type: String,
default: ""
},
roleId: {
type: String,
default: ""
}
})
const orgTree = ref<orgInfo[]>([]) //
const appLoading = ref(false)
const grouTabsLoading = ref(false)
const appSystemConfig = ref<any[]>([])
const appGroupButAry = ref<string[]>([])
const appPowerArt = ref<any>([])
const appFormButConfig = ref<any[]>([])
const systemMenuTreePropsing = {
children: "child",
label: "name",
value: "id",
};
/**
@ 作者: 秦东
@ 时间: 2025-05-13 14:20:47
@ 功能: 获取自定义App
*/
const getAppList = () => {
grouTabsLoading.value=true
appInitAuthorization({appType:props.appType,powerType:props.powerType,roleId:props.roleId}).then((data: any) => {
console.log("获取自定义App", data);
// appList.value = data.data;
appPowerArt.value = data.data.appList
appGroupButAry.value = data.data.groupButton
// if (data.data && data.data.length > 0) {
// if (data.data[0] && data.data[0].signCode) {
// activeAppId.value = data.data[0].signCode;
// }
// }
// console.log("App", activeAppId.value);
grouTabsLoading.value=false
}).finally(()=>{
appLoading.value=false
})
};
const pickAppTableList = (val: any) =>{
}
</script>
<template>
<el-scrollbar class="tableScrollbar" v-loading="appLoading">
<table class="table_body">
<thead>
<tr>
<th align="center" width="10%">分组权限</th>
<th align="center" width="10%">应用分组</th>
</tr>
</thead>
<tbody>
<tr >
<td width="10%" valign="top">
<el-checkbox-group v-model="appSystemConfig">
<el-checkbox
v-for="city in appGroupBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</td>
<td align="center" width="90%" valign="top">
<table class="table_body">
<tbody>
<tr v-for="item in appPowerArt" :key="item.id">
<td align="center" width="10%" valign="top">
<el-checkbox @click.stop="pickAppTableList(item)" v-model="item.isTrue" :value="item.isTrue" ></el-checkbox>
{{ item.name }}
</td>
<td align="center" width="90%" valign="top">
<table class="table_body">
<thead>
<tr>
<th align="center" width="10%">应用</th>
<th align="center" width="10%">应用操作按钮</th>
<th align="center" width="80%">应用栏目</th>
</tr>
</thead>
<tbody>
<tr v-for="itemApp in item.appList" :key="itemApp.id">
<td align="center" width="10%" valign="top">
<el-checkbox @click.stop="pickAppTableList(itemApp)" v-model="itemApp.isTrue" :value="itemApp.isTrue" ></el-checkbox>
{{ itemApp.name }}
</td>
<td align="left" width="10%" valign="top">
<el-checkbox-group v-model="appFormButConfig">
<el-checkbox
v-for="city in appDetailBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</td>
<td align="center" width="80%" valign="top">
<el-table
:data="itemApp.appMenuTree"
style="width: 100%; margin-bottom: 20px"
row-key="id"
border
default-expand-all
>
<el-table-column prop="name" label="栏目名称" >
<template #default="scope">
<el-checkbox @click.stop="pickAppTableList(scope.row)" v-model="scope.row.isTrue" :value="scope.row.isTrue" ></el-checkbox>
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column prop="pagePower" label="页面权力" >
<template #header>
<el-text>页面权力</el-text>
</template>
<template #default="scope">
<el-checkbox-group v-model="scope.pagePower">
<el-checkbox
v-for="city in formBaseBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</template>
</el-table-column>
<el-table-column prop="formPower" label="表单权限" >
<template #header>
<el-text>表单权限</el-text>
</template>
<template #default="scope">
<el-checkbox-group v-model="scope.formPower">
<el-checkbox
v-for="city in formBaseBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</template>
</el-table-column>
<el-table-column prop="listPower" label="listPower" >
<template #header>
<el-text>列表权限</el-text>
</template>
<template #default="scope">
<el-checkbox-group v-model="scope.listPower">
<el-checkbox
v-for="city in formBaseBut"
:key="city.key"
:label="city.label"
:value="city.value"
>
{{ city.label }}
</el-checkbox>
</el-checkbox-group>
</template>
</el-table-column>
<el-table-column prop="visibleRange" label="数据权限" >
<template #header>
<el-text>数据权限</el-text>
</template>
<template #default="scope">
<el-radio-group
v-model="scope.row.visibleRange.types"
>
<el-row>
<el-col :span="24"><el-radio :value="1">本人</el-radio></el-col>
<el-col :span="24"><el-radio :value="2">本岗位</el-radio></el-col>
<el-col :span="24"><el-radio :value="3">本部门</el-radio></el-col>
<el-col :span="24"><el-radio :value="4">本分部</el-radio></el-col>
<el-col :span="24">
<el-radio :value="5">指定行政组织</el-radio>
<el-tree-select
v-if="scope.row.visibleRange.types == 5"
v-model="scope.row.visibleRange.attribute"
:data="orgTree"
style="width: 100%"
node-key="id"
:props="systemMenuTreePropsing"
clearable
multiple
:render-after-expand="false"
show-checkbox
collapse-tags
collapse-tags-tooltip
/>
</el-col>
<el-col :span="24"><el-radio :value="6">所有</el-radio></el-col>
</el-row>
</el-radio-group>
</template>
</el-table-column>
</el-table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</el-scrollbar>
</template>
<style lang='scss' scoped>
.tableScrollbar{
width: 100%;
height: calc(100vh - 260px);
overflow: hidden;
overflow-y: auto;
}
</style>

338
src/views/system/monitor/online/roleConfig/setRolePeople.vue

@ -0,0 +1,338 @@
<!--
@ 作者: 秦东
@ 时间: 2025-11-26 10:13:15
@ 备注: 编辑角色使用人
-->
<script lang='ts' setup>
import type { getSystemPower,AppPowerTree,systemList } from "@/api/system/roleapi/types";
import { savePickRoleMan,getPowerPageUser,getRolePeople } from "@/api/system/roleapi/postrole";
import type { TreeInstance } from 'element-plus'
import type {RoleListTree} from '@/api/role/types'
import { Search } from '@element-plus/icons-vue'
import SvgIcon from "@/components/SvgIcon/index.vue";
const squareUrl = ref<string>(
"https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png"
);
const props = defineProps({
show: {
type: Boolean,
default: false
},
org: {
type: Array as () => orgInfo[],
default: () => []
},
roleInfo: {
type: Object as () => RoleListTree,
default: () => ({})
}
})
const userLoading = ref(false)
const emit = defineEmits(['update:show'])
// const isShowsdf = computed(() => {
// if(props.show){
// getPowerPageUserSub()
// // getPickUser()
// }
// return props.show
// })
const isShowsdf = computed({
get(){
console.log("------------------->",props.show)
return props.show
},
set(val){
emit('update:show', val)
}
})
const roleInfo = computed(() => {
return props.roleInfo
})
const orgTree = computed(() => {
return props.org
})
const treeBoxHeightOrg = ref(400)
const treeRefOrgUser = ref<TreeInstance>()
const propsOrg = {
value: 'id',
label: 'name',
// disabled:'status',
children: 'child',
}
const userPage = reactive({
page: 1,
pageSize: 20,
orgId: '',
name: '',
total: 0
})
const userPowerList = ref<systemList>({}) //
const userPowerListPick = ref<systemList[]>([]) //
const pickUserKey = ref<string[]>([]) //使key
const searchQuery = ref('') //
//
const onQuePeople = (query: string) => {
console.log(query)
treeRefOrgUser.value!.filter(query)
}
const filterMethodOrg = (query: string, node: any) => {
return node.name!.includes(query)
}
/**
@ 作者: 秦东
@ 时间: 2025-11-26 10:19:05
@ 功能: 关闭弹窗
*/
const closeDialog = () => {
emit('update:show', false)
userPowerList.value =
pickUserKey.value=[]
userPowerListPick.value=[]
userPage.page = 1
userPage.name = ''
userPage.orgId = ''
}
/**
@ 作者: 秦东
@ 时间: 2025-11-26 16:32:58
@ 功能: 选择行政组织
*/
const pickOrgTree = (node: any) => {
userPage.page = 1
userPage.name = ''
userPage.orgId = node.id
console.log(userPage)
getPowerPageUserSub()
}
const getPowerPageUserSub = () => {
userLoading.value = true
getPowerPageUser(userPage).then(({data})=>{
console.log("获取平台授权项目用户------->",data)
userPowerList.value = data.list
userPage.total = data.total
userLoading.value = false
})
}
const pickName = ref("")
const getPickUser = () => {
getRolePeople({
roleId: roleInfo.value.id*1,
name: pickName.value
}).then(({data})=>{
console.log("获取角色使用人------->",data)
if(data.list && Array.isArray(data.list)){
userPowerListPick.value = data.list
}else{
userPowerListPick.value = []
}
pickUserKey.value = data.userKey
})
}
const pickUserInfo = (item: any) => {
let isPick = true
if(pickUserKey.value.includes(item.id)){
pickUserKey.value = pickUserKey.value.filter((i) => i !== item.id)
isPick = false
}else{
pickUserKey.value.push(item.id)
isPick = true
}
if(isPick){
userPowerListPick.value.push(item)
}else{
userPowerListPick.value = userPowerListPick.value.filter((i) => i.id !== item.id)
}
}
//
const isPick = (item: any) => {
return pickUserKey.value.includes(item.id)
}
//使
const delUserPick = (item: any) => {
pickUserKey.value = pickUserKey.value.filter((i) => i !== item.id)
userPowerListPick.value = userPowerListPick.value.filter((i) => i.id !== item.id)
}
/**
@ 作者: 秦东
@ 时间: 2025-11-27 10:18:29
@ 功能: 保存人员
*/
const saveRolePeople = () => {
console.log("保存角色使用人------->",roleInfo.value.id*1,pickUserKey.value)
savePickRoleMan({
roleId: roleInfo.value.id*1,
userKey: pickUserKey.value
}).then((data)=>{
console.log("保存角色使用人------->",data)
if(data.code === 0){
ElMessage.success("保存成功")
closeDialog()
}else{
ElMessage.error(data.msg || "保存失败")
}
})
}
watch(() => props.show, (newVal) => {
if(newVal){
getPowerPageUserSub()
getPickUser()
}
},{
immediate: true
})
watch(() => userPage.name, (newVal) => {
getPowerPageUserSub()
},{
immediate: true
})
onMounted(() => {
// getPowerPageUserSub()
// getPickUser()
})
</script>
<template>
<el-dialog
v-model="isShowsdf"
:title="`编辑<<${roleInfo.label}>>角色使用人`"
width="800"
destroy-on-close
:before-close="closeDialog"
>
<el-row class="dialog-row" :gutter="10">
<el-col :span="8">
<div class="quan">
<div class="searchBox">
<el-input v-model="searchQuery" placeholder="请输入要查找的行政组织" :prefix-icon="Search" @input="onQuePeople" clearable />
</div>
<el-tree-v2
ref="treeRefOrgUser"
style="max-width: 100%;"
:data="orgTree"
:props="propsOrg"
:filter-method="filterMethodOrg"
:height="treeBoxHeightOrg"
:v-loading="roleLoading"
:highlight-current="true"
:check-on-click-node="true"
:expand-on-click-node="false"
@node-click="pickOrgTree"
>
</el-tree-v2>
</div>
</el-col>
<el-col :span="9">
<div class="quan">
<div class="searchBox">
<el-input v-model="userPage.name" placeholder="请输入姓名、工号" :prefix-icon="Search" clearable />
</div>
<el-scrollbar v-loading="userLoading" height="370px">
<div v-for="item in userPowerList" :key="item.id" :class="isPick(item)?'userBox active':'userBox'" @click="pickUserInfo(item)">
<el-avatar shape="square" :size="size" :src="item.icon?item.icon:squareUrl" />
<div class="userInfo">
<el-text type="primary" >{{ item.name }}({{ item.code }})</el-text>
<el-text type="primary" >{{ item.org }}</el-text>
</div>
<div style="width: 40px;">
</div>
</div>
</el-scrollbar>
<div class="paginationBox">
<el-pagination
v-model:current-page="userPage.page"
:page-size="userPage.pageSize"
:pager-count="7"
layout="prev, pager, next"
:total="userPage.total"
@change="getPowerPageUserSub"
/>
</div>
</div>
</el-col>
<el-col :span="7">
<div class="quan">
<div class="searchBox">
<!-- <el-input v-model="pickName" placeholder="请输入姓名、工号" :prefix-icon="Search" clearable /> -->
已经选择的使用人
</div>
<el-scrollbar height="415px">
<div v-for="item in userPowerListPick" :key="item.id" class="userBox" >
<el-avatar shape="square" :size="size" :src="item.icon?item.icon:squareUrl" />
<div class="userInfo">
<el-text type="primary" >{{ item.name }}({{ item.code }})</el-text>
<el-text type="primary" >{{ item.org }}</el-text>
</div>
<div>
<svg-icon icon-class="dels" @click="delUserPick(item)" />
</div>
</div>
</el-scrollbar>
</div>
</el-col>
</el-row>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="saveRolePeople">
确认
</el-button>
</div>
</template>
</el-dialog>
</template>
<style lang='scss' scoped>
.dialog-row{
width: 100%;
.quan{
width: 100%;
border: 1px solid #ccc;
overflow: hidden;
}
.searchBox{
padding: 5px 10px 5px 10px;
}
}
.userBox{
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 10px;
border-bottom: 1px dashed rgba($color: #000000, $alpha: 0.2);
.userInfo{
width: 60%;
}
div{
span{
display: flex;
width: 100%;
padding: 0 5px;
color:rgba($color: #000000, $alpha: 0.6);
}
}
svg{
cursor: pointer;
color: #FF0000;
}
}
.userBox.active {
background-color: #a0cfff;
}
.paginationBox{
width: 100%;
display: flex;
justify-content: center;
}
</style>

3
src/views/sysworkflow/lowCodeTasks/index.vue

@ -42,9 +42,8 @@ const stateForm = reactive<any>({
powerstr: {},
},
dict: {},
formId: "1",
id: 0,
formId: 0,
formId: "1",
versionId: 0,
loading: true,
});

11
src/views/sysworkflow/lowcodepage/appCardPage.vue

@ -17,6 +17,7 @@ import {
appJwtPower,
getFieldRecord,
} from "@/api/DesignForm/requestapi";
import { appHasPower } from "@/directive/permission/button";
/**
@ 作者: 秦东
@ -378,7 +379,7 @@ const handleCurrentChange = (val: any) => {
<template>
<div>
<div v-loading="loadingApp" class="content1 flex flex-wrap gap-4">
<el-card v-for="item in contList" :key="item.id" class="cardBox">
<el-card v-for="item in contList" v-hasApp="[item.signCodeStr]" :key="item.id" class="cardBox">
<template #header v-if="item.isEdit">
<el-dropdown v-if="item.classify == 3">
<span class="el-dropdown-link">
@ -386,8 +387,8 @@ const handleCurrentChange = (val: any) => {
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="editForm(item)">编辑</el-dropdown-item>
<el-dropdown-item @click="eidtStatus(item)" divided
<el-dropdown-item v-if="appHasPower(item.signCodeStr,'bjapp')" @click="editForm(item)">编辑</el-dropdown-item>
<el-dropdown-item v-if="appHasPower(item.signCodeStr,'scapp')" @click="eidtStatus(item)" divided
>删除</el-dropdown-item
>
</el-dropdown-menu>
@ -399,9 +400,9 @@ const handleCurrentChange = (val: any) => {
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="editFormApp(item)">编辑</el-dropdown-item>
<el-dropdown-item v-if="appHasPower(item.signCodeStr,'bjapp')" @click="editFormApp(item)">1</el-dropdown-item>
<el-dropdown-item @click="eidtStatus(item)" divided
>删除</el-dropdown-item
v-if="appHasPower(item.signCodeStr,'scapp')">删除</el-dropdown-item
>
</el-dropdown-menu>
</template>

28
src/views/sysworkflow/lowcodepage/appListPage.vue

@ -19,7 +19,8 @@ import {
import AppContainer from '@/views/sysworkflow/lowcodepage/newLowCode/appLayout/appContainer.vue'
import AppContainerPage from '@/views/sysworkflow/lowcodepage/newLowCode/appLayoutEdit/appContainerPage.vue' //
import LowCodeFormPage from "@/views/sysworkflow/lowcodepage/lowCodeFormPage.vue"
import { hasAppList } from "@/directive/permission/button";
import { appHasPower } from "@/directive/permission/button";
const props = defineProps({
searchQuery:{
@ -358,12 +359,21 @@ const handleCurrentChange = (val:any) =>{
props.searchQuery.page = val
getFormAppList(props.searchQuery);
}
/**
@ 作者: 秦东
@ 时间: 2024-08-09 11:28:39
@ 功能: 表格行样式
*/
const tableRowClassName = ({ row, rowIndex }: any) => {
console.log("表格行样式",row,hasAppList(row.signCodeStr))
return hasAppList(row.signCodeStr) ? '' : 'hidden_row';
}
</script>
<template>
<div class="listBody">
<el-table v-loading="loadingApp" :data="contList" border class="tableBox">
<el-table v-loading="loadingApp" :data="contList" border class="tableBox" :row-class-name="tableRowClassName">
<el-table-column fixed label="封面" width="80" align="center">
<template #default="scope">
<template #default="scope" >
<el-image
style="width: 30px; height: 30px"
:src="scope.row.icon?scope.row.icon:'https://docu.hxgk.group/images/2024_04/482167d1bf2b75a5717bcf68e18235f7.png'"
@ -405,20 +415,20 @@ const handleCurrentChange = (val:any) =>{
<el-button-group v-if="scope.row.classify==3" class="ml-4">
<el-button size="small" title="查看" :icon="View" @click="lookAppList(scope.row)" />
<el-button size="small" title="设为常用" :icon="Star" :color="scope.row.isoften?'#FF0000':''" @click="setOften(scope.row)" />
<el-button size="small" title="编辑" type="success" :icon="Edit" @click="editForm(scope.row)" />
<el-button v-if="appHasPower(scope.row.signCodeStr,'bjapp')" size="small" title="编辑" type="success" :icon="Edit" @click="editForm(scope.row)" />
<el-popconfirm title="请问是否真的删除?删除后数据将无法找回!" @confirm="delFormApp(scope.row)">
<template #reference>
<el-button size="small" title="删除" type="danger" :icon="Delete" />
<el-button v-if="appHasPower(scope.row.signCodeStr,'scapp')" size="small" title="删除" type="danger" :icon="Delete" />
</template>
</el-popconfirm>
</el-button-group>
<el-button-group v-else class="ml-4">
<el-button size="small" title="查看" :icon="View" @click="lookFormList(scope.row)" />
<el-button size="small" title="编辑" type="success" :icon="Edit" @click="editFormApp(scope.row)" />
<el-button v-if="appHasPower(scope.row.signCodeStr,'bjapp')" size="small" title="编辑" type="success" :icon="Edit" @click="editFormApp(scope.row)" />
<el-popconfirm title="请问是否真的删除?删除后数据将无法找回!" @confirm="delFormApp(scope.row)">
<template #reference>
<el-button size="small" title="删除" type="danger" :icon="Delete" />
<el-button v-if="appHasPower(scope.row.signCodeStr,'scapp')" size="small" title="删除" type="danger" :icon="Delete" />
</template>
</el-popconfirm>
</el-button-group>
@ -463,9 +473,13 @@ const handleCurrentChange = (val:any) =>{
}
.listBody{
padding: 10px 10px;
:deep .el-table__body .hidden_row {
display: none;
}
}
.tableBox{
width: 100%;
height: calc(100vh - 370px);
}
</style>

23
src/views/sysworkflow/lowcodepage/appPage/appMenus.vue

@ -1,4 +1,4 @@
<!--
<!--
@ 作者: 秦东
@ 时间: 2024-04-22 08:56:40
@ 备注:
@ -16,6 +16,7 @@ import {
delAppMenu,
editAppMenusIcon,
} from "@/api/DesignForm/requestapi";
import { appHasPower,hasCustomAppMenu } from "@/directive/permission/button";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { threeShiyanData } from "@/api/date/type";
@ -308,7 +309,7 @@ const allowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
@ 功能: 打开app表单
*/
const openAppPage = (val: any) => {
// console.log("app------>",val)
console.log("打开app表单------>",val)
if (val.isLock == 1) {
ElMessage({
showClose: true,
@ -343,7 +344,7 @@ const moveMenus = (val: any) => {
@node-drop="handleDrop"
>
<template #default="{ node, data }">
<div class="appMenuTitle">
<div class="appMenuTitle" >
<el-space wrap>
<el-image
v-if="data.icon != ''"
@ -360,22 +361,24 @@ const moveMenus = (val: any) => {
<!-- <el-tooltip :content="node.label" placement="top" effect="dark">
<el-text class="w-120px mb-2" truncated @click="openAppPage(data)">{{node.label}}</el-text>
</el-tooltip> -->
<el-text class="w-120px mb-2" truncated @click="openAppPage(data)">{{
node.label
}}</el-text>
<el-text class="w-120px mb-2" truncated @click="openAppPage(data)">
{{ data.label}}
</el-text>
</el-space>
<el-dropdown>
<svg-icon class="svgBox" prefix="icon" icon-class="set" />
<template #dropdown>
<el-dropdown-item @click="editMenuName(data)">修改名称</el-dropdown-item>
<!-- <el-dropdown-item @click="">复制</el-dropdown-item> -->
<el-dropdown-item @click="moveMenus(data)" divided>移动到</el-dropdown-item>
<el-dropdown-item v-if="data.type == 1" @click="addNewSunMenuGroup(data)"
<el-dropdown-item v-if="appHasPower(props.formKey,'yz')" @click="moveMenus(data)" divided>移动到</el-dropdown-item>
<el-dropdown-item v-if="data.type == 1 && appHasPower(props.formKey,'xzfg')" @click="addNewSunMenuGroup(data)"
>新建子分组</el-dropdown-item
>
<!-- <el-dropdown-item @click="">新建普通表单</el-dropdown-item>
<el-dropdown-item @click="">新建流程表单</el-dropdown-item> -->
<el-dropdown-item v-if="data.type == 1" @click="createNewPage(data.id)"
<el-dropdown-item v-if="data.type == 1 && appHasPower(props.formKey,'xz')" @click="createNewPage(data.id)"
>新建页面</el-dropdown-item
>
<el-dropdown-item @click="showOrHide(data, 1)" divided
@ -386,7 +389,7 @@ const moveMenus = (val: any) => {
><el-text v-if="data.wapIsShow == 1">隐藏移动端</el-text
><el-text v-else>取消-隐藏移动端</el-text></el-dropdown-item
>
<el-dropdown-item @click="editAppMenu(data)" divided>
<el-dropdown-item @click="editAppMenu(data) && appHasPower(props.formKey,'sc')" divided>
<el-text class="mx-1" type="danger">删除</el-text>
</el-dropdown-item>
</template>

20
src/views/sysworkflow/lowcodepage/appPage/appPageForm/openAppFormPage.vue

@ -14,7 +14,7 @@ import request from "@/utils/request";
import { gainAppPageInfo, getFieldRecord } from "@/api/DesignForm/requestapi";
import { Edit, Picture as IconPicture } from "@element-plus/icons-vue";
import { appPageDataInit, appWorkFlow } from "@/api/date/type";
import { appHasPower } from "@/directive/permission/button";
//
import AppFlowSee from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/appFlow/appFlowSee.vue";
import ContainerPath from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/echatesUnit/container.vue";
@ -58,8 +58,8 @@ const stateForm = reactive<any>({
},
dict: {},
formId: "1",
signCode: "",
id: 0,
formId: 0,
versionId: 0,
loading: true,
});
@ -197,8 +197,8 @@ const emits = defineEmits(["editAppInfo"]);
@ 时间: 2024-05-18 14:04:20
@ 功能: 获取App页面预览信息
*/
const editAppPage = (signCode: string) => {
emits("editAppInfo", signCode);
const editAppPage = (signCode: string, appPageKey: string) => {
emits("editAppInfo", signCode, appPageKey);
};
const activePage = ref(0); //
@ -386,9 +386,10 @@ const gainAppFormPageInit = () => {
// console.log("---->", stateList.view);
}
if (data.data.page) {
// console.log("data.data.mastesform", data.data);
console.log("data.data.mastesform", data.data);
stateForm.id = data.data.appForm.version.toString();
stateForm.formId = data.data.appForm.cfid.toString();
stateForm.signCode = data.data.signCode.toString();
stateForm.versionId = data.data.appForm.id.toString();
stateForm.formData = stringToObj(data.data.appForm.mastesform);
// console.log(stateForm.formData);
@ -518,7 +519,7 @@ defineExpose({
<el-row v-if="props.menusInfo">
<el-col :span="24" class="pageBox pageHeader">
<el-text class="wordFont">{{ props.menusInfo.label }}</el-text>
<el-button type="primary" :icon="Edit" @click="editAppPage(stateForm.formId)"
<el-button v-if="appHasPower(props.formKey,'bj')" type="primary" :icon="Edit" @click="editAppPage(stateForm.formId,stateForm.signCode)"
>编辑App页面</el-button
>
</el-col>
@ -533,13 +534,18 @@ defineExpose({
<el-col v-if="activePage != 3" :span="24" class="pageBoxInfo">
<el-card class="tispMsg" shadow="always">
<el-scrollbar class="suojing">
<!-- {{ props.formKey }}
{{ stateForm }} -->
<ak-page-list
v-if="activePage == 1"
:data="stateList.tableData"
:search-data="stateList.searchData"
:config="stateList.config"
:app-key="props.formKey"
:form-id="stateForm.formId"
:app-key="props.menusInfo.appkey"
:sign-code="stateForm.signCode"
:versionid="versionId"
:form-key="props.menusInfo.id"
:versiontitle="versionTitle"

1
src/views/sysworkflow/lowcodepage/appPage/appSetUp/setup.vue

@ -85,6 +85,7 @@ const submitForm = () => {
// console.log("",appSetupCont)
appBasicSettings(appSetupCont)
.then(() => {
// eslint-disable-next-line vue/no-mutating-props
props.appCont.appName = appSetupCont.title;
props.appCont.appSvg = appSetupCont.appSvg;
props.appCont.describe = appSetupCont.appdescribe;

18
src/views/sysworkflow/lowcodepage/appPage/createAppFormPage.vue

@ -9,6 +9,9 @@ import { formStruct } from "@/api/DesignForm/types";
import { customerFormConfig } from "@/api/DesignForm/type";
import { getProductionMarkForm } from "@/api/DesignForm/requestapi";
import { formHasPower } from "@/directive/permission/button";
import PageForm from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/pageForm.vue";
import PageFlow from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/pageFlow.vue";
import PageList from "@/views/sysworkflow/lowcodepage/appPage/appPageForm/pageList.vue";
@ -52,6 +55,10 @@ const props = defineProps({
type: String,
default: "",
},
signCode: {
type: String,
default: "",
},
});
const emits = defineEmits([
"update:isShow",
@ -150,6 +157,7 @@ onBeforeMount(() => {
types: 3,
};
if (props.isNew) {
// eslint-disable-next-line vue/no-mutating-props
props.appPageKey = "";
state.formData.list = [];
formVersion.value = "";
@ -229,11 +237,11 @@ onBeforeMount(() => {
class="tabsMain"
>
<el-tab-pane label="① 页面管理" :name="1"> </el-tab-pane>
<el-tab-pane label="② 流程设计" :name="2"> </el-tab-pane>
<el-tab-pane label="③ 列表设计" :name="3"> </el-tab-pane>
<el-tab-pane label="④ 数据看板" :name="4"> </el-tab-pane>
<el-tab-pane label="⑤ 模板设计" :name="5"> </el-tab-pane>
<!-- <el-tab-pane label="⑥ 内容呈现设计" :name="6"> </el-tab-pane> -->
<el-tab-pane v-if="formHasPower(props.formKey,props.signCode,'lc',2)" label="② 流程设计" :name="2"> </el-tab-pane>
<el-tab-pane v-if="formHasPower(props.formKey,props.signCode,'lb',2)" label="③ 列表设计" :name="3"> </el-tab-pane>
<el-tab-pane v-if="formHasPower(props.formKey,props.signCode,'sjc',2)" label="④ 数据看板" :name="4"> </el-tab-pane>
<el-tab-pane v-if="formHasPower(props.formKey,props.signCode,'dy',2)" label="⑤ 打印设计" :name="5"> </el-tab-pane>
<el-tab-pane v-if="formHasPower(props.formKey,props.signCode,'nc',2)" label="⑥ 内容呈现设计" :name="6"> </el-tab-pane>
</el-tabs>
</div>
<div class="headRight">

28
src/views/sysworkflow/lowcodepage/index.vue

@ -12,6 +12,8 @@ import {
gainAppEditPsge,
} from "@/api/DesignForm/requestapi";
import { hasCustomAppGroup } from "@/directive/permission/button";
import { Search } from "@element-plus/icons-vue";
//
@ -21,6 +23,10 @@ import LowCodeFormPage from "@/views/sysworkflow/lowcodepage/lowCodeFormPage.vue
import LowCodeFormGroupPage from "@/views/sysworkflow/lowcodepage/lowCodeFormGroupPage.vue";
import DesignAPPpage from "@/views/sysworkflow/lowcodepage/appPage/index.vue"; //
import { useUserStore } from "@/store/modules/user";
const userStore = useUserStore();
const contbody = ref(); //
const carPage = ref();
const appListPage = ref();
@ -234,11 +240,13 @@ const eidtGroupStatus = (id: string, state: number) => {
class="demo-tabs"
@tab-click="handleClick"
>
<el-tab-pane
v-for="item in groupFormList"
:label="item.title"
:name="item.idStr"
></el-tab-pane>
<template v-for="item in groupFormList" :key="item.idStr">
<el-tab-pane
:label="item.title"
:name="item.idStr"
v-if="hasCustomAppGroup(item.idStr)"
></el-tab-pane>
</template>
</el-tabs>
<div class="appSubButton">
@ -268,7 +276,9 @@ const eidtGroupStatus = (id: string, state: number) => {
<el-dropdown>
<el-button class="fa fa-reorder leftLink" />
<template #dropdown>
<el-dropdown-item @click="handleCommand('addFormGroup', appGroup)"
<el-dropdown-item
v-hasAppGroup="['xz']"
@click="handleCommand('addFormGroup', appGroup)"
>新增分组</el-dropdown-item
>
<el-dropdown-item
@ -276,13 +286,13 @@ const eidtGroupStatus = (id: string, state: number) => {
style="display: none"
>添加表单</el-dropdown-item
>
<el-dropdown-item @click="handleCommand('addFormApp', appGroup)"
<el-dropdown-item v-hasAppGroup="['xzapp']" @click="handleCommand('addFormApp', appGroup)"
>添加应用</el-dropdown-item
>
<el-dropdown-item @click="editFormGroup(appGroup)" divided
<el-dropdown-item v-hasAppGroup="['bj']" @click="editFormGroup(appGroup)" divided
>编辑</el-dropdown-item
>
<el-dropdown-item @click="eidtGroupStatus(appGroup, 3)"
<el-dropdown-item v-hasAppGroup="['dl']" @click="eidtGroupStatus(appGroup, 3)"
>删除</el-dropdown-item
>
</template>

20
src/views/sysworkflow/lowcodepage/newLowCode/appLayoutEdit/appContainerPage.vue

@ -7,6 +7,8 @@
import { appMenuTreeInfo, appSetInfo } from "@/api/date/type";
import { gainAppEditPsge } from "@/api/DesignForm/requestapi";
import { appHasPower } from "@/directive/permission/button";
import SvgIcon from "@/components/SvgIcon/index.vue";
import AppMenus from "@/views/sysworkflow/lowcodepage/appPage/appMenus.vue";
import AppMenuGroup from "@/views/sysworkflow/lowcodepage/appPage/appMenuGroup.vue";
@ -46,6 +48,7 @@ const tabsActive = ref(1);
const menusTree = ref<appMenuTreeInfo[]>([]); //
const checkedMenu = ref<appMenuTreeInfo>("");
const appPageKey = ref<string>(""); //AppId
const pageSignCode = ref<string>(""); //AppId
const isNew = ref(false);
const saveAppFormIsShow = ref(false);
const menuParentKey = ref<string>("");
@ -98,6 +101,7 @@ const closeAppDraw = () => {
tabsActive.value = 1;
checkedMenu.value = "";
appPageKey.value = "";
pageSignCode.value = "";
checkedMenu.appkey = "";
isNew.value = false;
};
@ -115,8 +119,9 @@ const openAppPageForm = (val: appMenuTreeInfo) => {
@ 时间: 2024-05-20 13:27:37
@ 功能: 编辑app页面
*/
const editAppInfo = (id: string) => {
const editAppInfo = (id: string,signCode: string) => {
appPageKey.value = id;
pageSignCode.value = signCode;
saveAppFormIsShow.value = true;
isNew.value = false;
};
@ -183,9 +188,9 @@ const updataPageInit = () => {
class="tabsMain"
>
<el-tab-pane label="① 页面管理" :name="1"> </el-tab-pane>
<el-tab-pane label="② 集成&自动化" :name="2"> </el-tab-pane>
<el-tab-pane label="③ 应用设置" :name="3"> </el-tab-pane>
<el-tab-pane label="④ 应用发布" :name="4"> </el-tab-pane>
<el-tab-pane v-if="appHasPower(props.pickAppInfo.signCodeStr,'jczdh')" label="② 集成&自动化" :name="2"> </el-tab-pane>
<el-tab-pane v-if="appHasPower(props.pickAppInfo.signCodeStr,'yysz')" label="③ 应用设置" :name="3"> </el-tab-pane>
<el-tab-pane v-if="appHasPower(props.pickAppInfo.signCodeStr,'yyfb')" label="④ 应用发布" :name="4"> </el-tab-pane>
</el-tabs>
</div>
<div>
@ -221,7 +226,7 @@ const updataPageInit = () => {
<el-button type="primary" class="fa fa-plus" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="addAppPageForm">
<el-dropdown-item v-if="appHasPower(props.pickAppInfo.signCodeStr,'xz')" @click="addAppPageForm">
<el-row>
<el-col :span="24">
<el-space wrap>
@ -238,7 +243,7 @@ const updataPageInit = () => {
</el-col>
</el-row>
</el-dropdown-item>
<el-dropdown-item divided @click="addMenu">
<el-dropdown-item v-if="appHasPower(props.pickAppInfo.signCodeStr,'xzfg')" divided @click="addMenu">
<el-row>
<el-col :span="24">
<el-space wrap>
@ -265,6 +270,7 @@ const updataPageInit = () => {
:form-Key="appCont.uuid"
v-model:menus-tree="menusTree"
v-model:app-page-key="appPageKey"
:sign-code="pageSignCode"
:group-key="props.groupKey"
:app-cont="appCont"
:drawer-with="props.drawerWith"
@ -280,6 +286,7 @@ const updataPageInit = () => {
:app-cont="appCont"
:group-key="props.groupKey"
:menu-id="appCont.uuid"
:sign-code="pageSignCode"
v-model:app-page-key="appPageKey"
@gainSunAppContent="gainAppContent"
@updateInit="updataPageInit"
@ -293,6 +300,7 @@ const updataPageInit = () => {
:form-Key="checkedMenu.appkey"
:group-key="props.groupKey"
:app-cont="appCont"
:sign-code="pageSignCode"
:drawer-with="props.drawerWith"
:menus-info="checkedMenu"
@editAppInfo="editAppInfo"

3
src/views/sysworkflow/lowcodepage/pageFlow/appTableFlow.vue

@ -489,9 +489,8 @@ const stateForm = reactive<any>({
powerstr: {},
},
dict: {},
formId: "1",
id: 0,
formId: 0,
formId: "1",
versionId: 0,
loading: true,
});

2
src/views/sysworkflow/lowcodepage/runApp/regularPage.vue

@ -51,7 +51,7 @@ const resetQueryTd = () => {
};
</script>
<template>
<el-scrollbar class="scroBox">
<el-scrollbar class="scroBox">{{props.pickAppMenu.isMain}}
<MyToDoPage
v-if="props.pickAppMenu.isMain == 1"
:pick-app-menu="pickAppMenu"

4
src/views/sysworkflow/lowcodepage/runApp/runAppForm.vue

@ -48,9 +48,8 @@ const stateForm = reactive<any>({
powerstr: {},
},
dict: {},
formId: "1",
id: 0,
formId: 0,
formId: "1",
versionId: 0,
loading: true,
});
@ -438,6 +437,7 @@ function optionsValue3Get3(data: any, fieldName: string) {
:mastesformjson="mastesformjson"
:flowkey="appInitData.flowkey"
:groupid="appInitData.groupid"
:app-key="props.appkey"
:sign-code="appInitData.signCode"
:version-id="appInitData.versionId"
add-url="addData"

3
src/views/taskplatform/taskmanagement/flowStep.vue

@ -141,7 +141,6 @@ const updateNode = (val:any) =>{
</el-tooltip>
</template>
<template #description>
<table>
<tr v-for="items in item.operator" :key="items.id">
<td valign="top" align="center" width="50">
@ -187,7 +186,7 @@ const updateNode = (val:any) =>{
</template>
</el-step>
</el-steps>
{{ openOrClose }}======={{ openclosebox }}
<OrgUserPage v-if="openOrClose" v-model:openclose="openOrClose" :preset-personnel="presetPersonnel" :selected-people="selectedPeople" @update-node="updateNode" />
<OrgAllUserPage v-if="openclosebox" v-model:openclosebox="openclosebox" :selected-people="selectedPeople" @update-node="updateNode" />
</div>

4
src/views/taskplatform/taskmanagement/lookAndOperateLogInfo.vue

@ -178,7 +178,7 @@ const closeAppSubmit = () => {}
</style>
<style lang='scss'>
.drawerClass ::v-deep.el-drawer__header {
.drawerClass :deep(.el-drawer__header) {
font-size: 22px;
text-align: center;
margin-bottom: 0px;
@ -188,7 +188,7 @@ const closeAppSubmit = () => {}
color: white;
}
}
::v-deep .el-drawer__body {
:deep(.el-drawer__body) {
padding: 0px;
}
.details {

4
src/views/taskplatform/taskmanagement/taskcustomerform.vue

@ -435,7 +435,7 @@ watch(()=>flowMap,(val:any)=>{
</template>
<style lang='scss'>
.drawerClass ::v-deep.el-drawer__header {
.drawerClass :deep(.el-drawer__header) {
font-size: 22px;
text-align: center;
margin-bottom: 0px;
@ -445,7 +445,7 @@ watch(()=>flowMap,(val:any)=>{
color: white;
}
}
::v-deep .el-drawer__body {
:deep(.el-drawer__body) {
padding: 0px;
}
.details {

4
src/views/taskplatform/taskmanagement/tasklist.vue

@ -10,7 +10,7 @@ import { appFormdataLog,delCustomerFormData } from '@/api/taskapi/management'
//
import TaskEntry from '@/views/taskplatform/taskmanagement/taskentry.vue'
import TaskCustomerForm from '@/views/taskplatform/taskmanagement/taskcustomerformnew.vue'
import EditTaskCustomerForm from '@/views/taskplatform/taskmanagement/edittaskcustomerform.vue'
const loading = ref(false)
const searckFormRef = ref(ElForm);
@ -180,7 +180,7 @@ const openCustomerForm = (id:string,title:string) =>{
</el-card>
<TaskEntry v-model:isshow="openTaskDialog" @opencustomerform="openCustomerForm" />
<TaskCustomerForm v-model:isopen="openTaskDrawer" :versionid="versionId" :versiontitle="versionTitle" :drawerwith="drawerWith" @searchquery="searchQuery" />
<EditTaskCustomerForm v-model:iseditopen="openEditTaskDrawer" :versionid="versionId" :versiontitle="versionTitle" :masterskey="mastersKey" infoid="2" :drawerwith="drawerWith" @searchquery="searchQuery" />
<TaskCustomerForm v-model:isopen="openEditTaskDrawer" :versionid="versionId" :versiontitle="versionTitle" infoid="2" :drawerwith="drawerWith" @searchquery="searchQuery" />
</div>
</div>
</template>

215
vite.config.ts.timestamp-1762732876054-97f8b5f7ef739.mjs

File diff suppressed because one or more lines are too long

215
vite.config.ts.timestamp-1763685117626-b9e83b063ec3.mjs

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save