Compare commits
25 Commits
f4747be3bc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 883416417f | |||
| cd8347d3d1 | |||
| 9fa073546b | |||
| 836bcf196c | |||
| a1e247c2e3 | |||
| a2a7335536 | |||
| dbc6ecf62d | |||
| cf455216f9 | |||
| e4a044944d | |||
| ebdd319f9f | |||
| 92c1f0be41 | |||
| c4cc33bee3 | |||
| 96e97de237 | |||
| 5bb7ca0515 | |||
| 00c9f1e07f | |||
| 76df2bc42c | |||
| aa1af80bdf | |||
| 0020d383bf | |||
| 571e149313 | |||
| 6b563f728f | |||
| 52095b5fb9 | |||
| f31be82805 | |||
| 35c6849b43 | |||
| baa818153f | |||
| 70ed05c67a |
@ -1 +1 @@
|
||||
src/
|
||||
# 取消忽略 src 目录,让 ESLint 正常检查源代码
|
||||
94
check_unused_dicts.js
Normal file
94
check_unused_dicts.js
Normal file
@ -0,0 +1,94 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const baseDir = path.join(__dirname, 'src/views/backOfficeSystem');
|
||||
|
||||
// Find all .vue files with proxy.$dict
|
||||
function findVueFiles(dir) {
|
||||
let results = [];
|
||||
const files = fs.readdirSync(dir);
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
results = results.concat(findVueFiles(filePath));
|
||||
} else if (file.endsWith('.vue')) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
if (content.includes('proxy.$dict')) {
|
||||
results.push(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// Parse dict variables and their usage
|
||||
function analyzeFile(filePath) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
// Find the dict destructuring pattern
|
||||
// Pattern: const { VAR1, VAR2, ... } = proxy.$dict("KEY1", "KEY2", ...)
|
||||
|
||||
// Extract the destructured variable names
|
||||
const destructMatch = content.match(/const\s*\{([^}]+)\}\s*=\s*proxy\.\$dict\s*\(/);
|
||||
if (!destructMatch) return null;
|
||||
|
||||
const varsStr = destructMatch[1];
|
||||
const dictVars = varsStr.split(',').map(v => v.trim().replace(/\/\/.*$/, '').trim()).filter(v => v && !v.startsWith('//'));
|
||||
|
||||
// Extract the dict keys
|
||||
const dictCallMatch = content.match(/proxy\.\$dict\s*\(([^)]+)\)/s);
|
||||
if (!dictCallMatch) return null;
|
||||
|
||||
const dictKeysStr = dictCallMatch[1];
|
||||
const dictKeys = dictKeysStr.split(',').map(k => k.trim().replace(/['"]/g, '').replace(/\/\/.*$/, '').trim()).filter(k => k && !k.startsWith('//'));
|
||||
|
||||
// Now check which dict vars are actually used in the file
|
||||
// Remove the dict declaration part first
|
||||
const scriptContent = content.replace(/const\s*\{[^}]+\}\s*=\s*proxy\.\$dict\s*\([^)]+\)[^;\n]*;?/s, '');
|
||||
|
||||
const unusedVars = [];
|
||||
const usedVars = [];
|
||||
|
||||
for (const varName of dictVars) {
|
||||
if (!varName) continue;
|
||||
// Check if the variable name appears elsewhere in the file (outside the dict declaration)
|
||||
// Look for: varName in template, searchConfiger, getMultiDictVal, DictTag :options, :dict= etc.
|
||||
const regex = new RegExp('\\b' + varName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\b');
|
||||
const matches = scriptContent.match(regex);
|
||||
if (matches && matches.length > 0) {
|
||||
usedVars.push(varName);
|
||||
} else {
|
||||
unusedVars.push(varName);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
filePath,
|
||||
dictVars,
|
||||
dictKeys,
|
||||
unusedVars,
|
||||
usedVars
|
||||
};
|
||||
}
|
||||
|
||||
const vueFiles = findVueFiles(baseDir);
|
||||
console.log(`Found ${vueFiles.length} files with proxy.$dict\n`);
|
||||
|
||||
let totalUnused = 0;
|
||||
const filesWithUnused = [];
|
||||
|
||||
for (const filePath of vueFiles) {
|
||||
const result = analyzeFile(filePath);
|
||||
if (result && result.unusedVars.length > 0) {
|
||||
const relPath = path.relative(__dirname, filePath).replace(/\\/g, '/');
|
||||
console.log(`\n${relPath}:`);
|
||||
console.log(` Unused: ${result.unusedVars.join(', ')}`);
|
||||
filesWithUnused.push(result);
|
||||
totalUnused += result.unusedVars.length;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n\n=== Summary ===`);
|
||||
console.log(`Total files with unused dicts: ${filesWithUnused.length}`);
|
||||
console.log(`Total unused dict variables: ${totalUnused}`);
|
||||
129
docs/navigation-issue-solution.md
Normal file
129
docs/navigation-issue-solution.md
Normal file
@ -0,0 +1,129 @@
|
||||
# 首页导航跳转问题分析与解决方案
|
||||
|
||||
## 问题现象
|
||||
|
||||
接口请求完成之前,首页的导航菜单无法跳转;接口请求完成后,导航跳转正常。
|
||||
|
||||
---
|
||||
|
||||
## 问题根源
|
||||
|
||||
### 核心问题:SideBarMenu.vue 的页面刷新逻辑
|
||||
|
||||
```javascript
|
||||
// 问题代码(已修复)
|
||||
if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
|
||||
setTimeout(() => {
|
||||
router.go(0); // 触发页面刷新!
|
||||
}, 200);
|
||||
}
|
||||
```
|
||||
|
||||
当动态路由还没添加完成时,这个条件会触发页面不断刷新,导致导航不可用。
|
||||
|
||||
---
|
||||
|
||||
## 已完成的修复
|
||||
|
||||
### 1. 修改 `src/store/modules/permission.js`
|
||||
|
||||
**修改内容**:优化 `routeReady` 状态管理(0: 未开始 → 1: 进行中 → 2: 完成)
|
||||
|
||||
```javascript
|
||||
actions: {
|
||||
filterRoutes(context, menus) {
|
||||
// 开始处理,标记为进行中
|
||||
context.commit('setRouteReady', 1);
|
||||
|
||||
let routes = [];
|
||||
if (menus && menus.length > 0) {
|
||||
routes = filter(privateRoutes, menus);
|
||||
}
|
||||
routes.push({ path: '/:catchAll(.*)', redirect: '/404' });
|
||||
|
||||
context.commit('setRoutes', routes);
|
||||
// 处理完成,标记为已完成
|
||||
context.commit('setRouteReady', 2); // ← 新增:完成时设为 2
|
||||
|
||||
return routes;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 修改 `src/permission.js`
|
||||
|
||||
**修改内容**:移除了在路由守卫开始时设置 `setRouteReady(1)` 的代码,让 `filterRoutes` action 统一管理状态。
|
||||
|
||||
### 3. 修改 `src/layout/components/SideBar/SideBarMenu.vue`
|
||||
|
||||
**修改内容**:移除自动刷新页面的逻辑,改为监听路由加载状态
|
||||
|
||||
```javascript
|
||||
// 原代码(已移除):
|
||||
// if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
|
||||
// store.commit("user/setIsReady", {});
|
||||
// setTimeout(() => {
|
||||
// router.go(0);
|
||||
// }, 200);
|
||||
// }
|
||||
|
||||
// 新代码:监听路由加载完成状态
|
||||
if (store.state.permission.routeReady !== 2) {
|
||||
const unwatch = watch(
|
||||
() => store.state.permission.routeReady,
|
||||
(val) => {
|
||||
if (val === 2) {
|
||||
unwatch();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 修改 `src/utils/route.js`
|
||||
|
||||
**修改内容**:添加空值安全检查,避免 `deptId` 或 `roleList` 为空时报错
|
||||
|
||||
```javascript
|
||||
// 原代码(可能报错):
|
||||
// const { deptBizType, deptLevel } = getItem('deptId')[0]
|
||||
|
||||
// 新代码(安全):
|
||||
const deptIdData = getItem('deptId');
|
||||
const deptInfo = deptIdData && deptIdData.length > 0 ? deptIdData[0] : {};
|
||||
const deptBizType = deptInfo.deptBizType || '';
|
||||
const deptLevel = deptInfo.deptLevel || '';
|
||||
const roleListData = getItem('roleList') || [];
|
||||
const roleList = roleListData.filter(item => item.roleCode == 'JS_666666').length > 0;
|
||||
const xjLsit = roleListData.filter(item => item.roleCode == 'JS_999999').length > 0;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 修复后的流程
|
||||
|
||||
```
|
||||
登录成功 → window.location.href = '/' → 页面加载
|
||||
↓
|
||||
permission.js 路由守卫执行
|
||||
↓
|
||||
filterRoutes 开始执行 → routeReady = 1(进行中)
|
||||
↓
|
||||
动态路由添加完成 → routeReady = 2(完成)
|
||||
↓
|
||||
SideBarMenu.vue 监听到 routeReady === 2
|
||||
↓
|
||||
导航菜单正常渲染,可以跳转
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 修复文件列表
|
||||
|
||||
| 文件路径 | 修改内容 |
|
||||
|---------|---------|
|
||||
| `src/store/modules/permission.js` | 优化 routeReady 状态管理(0→1→2) |
|
||||
| `src/permission.js` | 移除重复的 setRouteReady 调用 |
|
||||
| `src/layout/components/SideBar/SideBarMenu.vue` | 移除自动刷新逻辑,改为监听状态 |
|
||||
| `src/utils/route.js` | 添加空值安全检查 |
|
||||
463
docs/菜单权限逻辑文档.md
Normal file
463
docs/菜单权限逻辑文档.md
Normal file
@ -0,0 +1,463 @@
|
||||
# 菜单权限逻辑文档
|
||||
|
||||
## 概述
|
||||
|
||||
本项目采用**动态路由注册**方案实现权限控制。用户登录后,系统根据后端返回的菜单权限码动态注册路由,无权限的路由**根本不会注册**到 Vue Router,从根本上杜绝了越权访问的可能。
|
||||
|
||||
---
|
||||
|
||||
## 整体流程图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 用户登录 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 调用登录接口 │
|
||||
│ 返回:jwtToken、menuList、menuCodeSet、deptList 等 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 存储权限数据 │
|
||||
│ - localStorage.menusPermission = menuCodeSet(菜单权限码集合) │
|
||||
│ - Vuex: user.userInfo.permission.menus = menuCodeSet │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 路由守卫(permission.js) │
|
||||
│ 首次进入时:获取 menusPermission → 调用 filterRoutes 动态注册路由 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Vuex: permission/filterRoutes │
|
||||
│ 1. 根据 menusPermission 过滤 privateRoutes │
|
||||
│ 2. 通过 router.addRoute() 动态注册有权限的路由 │
|
||||
│ 3. 最后注册 404 兜底路由 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ SideBarMenu.vue 组件 │
|
||||
│ 从已注册的路由中筛选并渲染侧边栏菜单 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心文件说明
|
||||
|
||||
| 文件路径 | 作用 |
|
||||
|---------|------|
|
||||
| `src/router/index.js` | 路由配置,定义 `publicRoutes`(公开路由)和 `privateRoutes`(私有路由) |
|
||||
| `src/store/modules/permission.js` | 权限模块,处理路由过滤和动态注册逻辑 |
|
||||
| `src/store/modules/user.js` | 用户模块,处理登录和退出登录 |
|
||||
| `src/permission.js` | 路由守卫,控制路由初始化时机 |
|
||||
| `src/utils/route.js` | 路由工具函数,处理菜单生成 |
|
||||
| `src/layout/components/SideBar/SideBarMenu.vue` | 侧边栏菜单组件,渲染权限菜单 |
|
||||
| `src/views/error/404.vue` | 无权限/页面不存在页面 |
|
||||
| `src/directives/permission.js` | 按钮级权限指令 |
|
||||
|
||||
---
|
||||
|
||||
## 路由分类
|
||||
|
||||
### 公开路由(publicRoutes)
|
||||
|
||||
应用启动时静态注册,所有用户都能访问:
|
||||
|
||||
| 路由路径 | 说明 |
|
||||
|---------|------|
|
||||
| `/login` | 登录页 |
|
||||
| `/oatuh_login` | OAuth 登录页 |
|
||||
| `/zeroTrust_login` | 零信任登录页 |
|
||||
| `/` | 首页 |
|
||||
| `/401` | 无权限页(保留) |
|
||||
| `/404` | 页面不存在/无权限页 |
|
||||
| `/mapNavigation` | 地图导航 |
|
||||
| `/KeyPopulations` | 重点人详情 |
|
||||
| `/deploymentApproval` | 布控审核 |
|
||||
| `/clueVerification` | 线索核实 |
|
||||
| 其他特殊路由... | 无需菜单权限校验的业务路由 |
|
||||
|
||||
### 私有路由(privateRoutes)
|
||||
|
||||
登录后根据权限动态注册,包含所有业务功能页面。
|
||||
|
||||
---
|
||||
|
||||
## 详细逻辑分析
|
||||
|
||||
### 1. 登录阶段 - 获取并存储权限
|
||||
|
||||
**文件**: `src/store/modules/user.js`
|
||||
|
||||
```javascript
|
||||
// 登录成功后存储权限数据
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setMenuList", data.menuList);
|
||||
setItem("menusPermission", data.menuCodeSet); // 核心:菜单权限码集合
|
||||
|
||||
this.commit("user/setUserInfo", {
|
||||
token: data.jwtToken,
|
||||
permission: {
|
||||
buttonPermission: ["removeTest", "viewTest"],
|
||||
menus: data.menuCodeSet
|
||||
},
|
||||
menuList: data.menuList,
|
||||
deptList: data.deptList
|
||||
});
|
||||
```
|
||||
|
||||
**权限码示例**:
|
||||
```javascript
|
||||
["FourColorWarning", "YjData", "IntelligentControl", "userList", "departmentList", ...]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. 路由守卫 - 控制初始化
|
||||
|
||||
**文件**: `src/permission.js`
|
||||
|
||||
```javascript
|
||||
const whiteList = ['/login', '/oatuh_login', '/404', '/401', '/zeroTrust_login',
|
||||
'/focusExploration', '/clueVerification', '/deploymentApproval'];
|
||||
|
||||
let routesInitialized = false;
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
if (store.getters.token) {
|
||||
if (!routesInitialized) {
|
||||
// ★ 首次进入:动态注册路由
|
||||
routesInitialized = true;
|
||||
const afterMenuList = getItem('menusPermission');
|
||||
|
||||
// 根据权限动态注册路由
|
||||
await store.dispatch('permission/filterRoutes', afterMenuList);
|
||||
|
||||
// 重新导航,确保刚注册的路由能正确匹配
|
||||
next({ ...to, replace: true });
|
||||
return;
|
||||
}
|
||||
next();
|
||||
} else {
|
||||
// 未登录:白名单放行,否则跳转登录
|
||||
if (whiteList.indexOf(to.path) > -1) {
|
||||
next();
|
||||
} else {
|
||||
// 跳转登录逻辑...
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 权限过滤与动态注册
|
||||
|
||||
**文件**: `src/store/modules/permission.js`
|
||||
|
||||
```javascript
|
||||
import router from '@/router'
|
||||
import { publicRoutes, privateRoutes } from '@/router'
|
||||
|
||||
/**
|
||||
* 递归过滤路由(保留 component 引用)
|
||||
* 规则:
|
||||
* 1. 路由有 name 且在权限列表中 → 保留
|
||||
* 2. 路由无 name 但有子路由 → 检查子路由权限,有权限子路由则保留父路由
|
||||
*/
|
||||
function filter(data, menus) {
|
||||
const result = []
|
||||
|
||||
data.forEach(route => {
|
||||
const newRoute = { ...route } // 浅拷贝,保留 component 引用
|
||||
|
||||
if (route.name && menus?.includes(route.name)) {
|
||||
// 有权限:递归处理子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
newRoute.children = filter(route.children, menus)
|
||||
}
|
||||
result.push(newRoute)
|
||||
} else if (!route.name && route.children && route.children.length > 0) {
|
||||
// 父路由无 name:检查子路由
|
||||
const filteredChildren = filter(route.children, menus)
|
||||
if (filteredChildren.length > 0) {
|
||||
newRoute.children = filteredChildren
|
||||
result.push(newRoute)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
actions: {
|
||||
filterRoutes(context, menus) {
|
||||
let routes = []
|
||||
|
||||
if (menus && menus.length > 0) {
|
||||
routes = filter(privateRoutes, menus)
|
||||
}
|
||||
|
||||
// ★★★ 关键:动态添加路由到 Vue Router ★★★
|
||||
routes.forEach(route => {
|
||||
router.addRoute(route)
|
||||
})
|
||||
|
||||
// 404 兜底路由必须最后添加
|
||||
router.addRoute({
|
||||
path: '/:catchAll(.*)',
|
||||
redirect: '/404'
|
||||
})
|
||||
|
||||
context.commit('setRoutes', routes)
|
||||
return routes
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**重要说明**:
|
||||
- 不能使用 `JSON.parse(JSON.stringify())` 深拷贝,会丢失 `component` 函数引用导致页面空白
|
||||
- 使用 `{ ...route }` 浅拷贝保留 `component` 引用
|
||||
|
||||
---
|
||||
|
||||
### 4. 侧边栏菜单渲染
|
||||
|
||||
**文件**: `src/layout/components/SideBar/SideBarMenu.vue`
|
||||
|
||||
```javascript
|
||||
// 从已注册的路由中获取并过滤
|
||||
const routes = computed(() => {
|
||||
const fRoutes = filterRoutes(router.getRoutes());
|
||||
const data = fRoutes.filter((item) => !EXCLUDE_NAMES.includes(item.name));
|
||||
|
||||
const menusPermission = getItem("menusPermission");
|
||||
|
||||
if (menusPermission === null || menusPermission === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const menusSet = new Set(menusPermission.map((item) => `${item}`));
|
||||
|
||||
const permissionFiltered = menusSet.size
|
||||
? filterRoutesByMenusPermission(data, menusSet)
|
||||
: [];
|
||||
|
||||
return generateMenus(permissionFiltered);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 404 无权限页面
|
||||
|
||||
**文件**: `src/views/error/404.vue`
|
||||
|
||||
无权限访问时统一跳转此页面,显示提示信息和操作按钮:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="error-page">
|
||||
<div class="error-content">
|
||||
<h1>404</h1>
|
||||
<h2>无权限访问</h2>
|
||||
<p>您没有权限访问此页面,请联系上级部门添加相关权限。</p>
|
||||
<el-button type="primary" @click="goHome">返回首页</el-button>
|
||||
<el-button @click="logout">退出登录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const logout = () => {
|
||||
window.opener = null;
|
||||
window.open('', '_self');
|
||||
window.close();
|
||||
store.commit("app/clearTag", null, { immediate: true });
|
||||
store.commit("permission/deleteRouter", { immediate: true });
|
||||
store.commit("user/deleteKeepLiiveRoute", "home");
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. 退出登录
|
||||
|
||||
**文件**: `src/store/modules/user.js`
|
||||
|
||||
```javascript
|
||||
async logout(ctx) {
|
||||
const res = await loginOut();
|
||||
if (res) {
|
||||
// 重置动态路由
|
||||
resetRouter();
|
||||
// 重置路由守卫初始化标记
|
||||
resetRoutesInit();
|
||||
// 清除权限模块状态
|
||||
ctx.dispatch("permission/resetRoutes");
|
||||
// 清除用户状态
|
||||
ctx.commit("user/setToken", "");
|
||||
ctx.commit("user/setUserName", "admin");
|
||||
ctx.commit("user/setUserInfo", {});
|
||||
// 清除本地存储
|
||||
removeAllItem();
|
||||
// 跳转统一门户
|
||||
window.location.href = `https://tyyy.lz.dsj.xz/portal/home`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 权限判断核心
|
||||
|
||||
### 匹配公式
|
||||
|
||||
```
|
||||
用户权限码:menusPermission = ["FourColorWarning", "YjData", "userList", ...]
|
||||
|
||||
路由配置:
|
||||
{
|
||||
path: "/FourColorWarning",
|
||||
name: "FourColorWarning", // ← 必须与权限码一致
|
||||
meta: { title: "预警中心", icon: "article-ranking" },
|
||||
children: [...]
|
||||
}
|
||||
|
||||
判断逻辑:
|
||||
menusPermission.includes(route.name) ? 有权限 : 无权限
|
||||
```
|
||||
|
||||
### 关键点
|
||||
|
||||
| 要素 | 说明 |
|
||||
|-----|------|
|
||||
| **权限来源** | 后端登录接口返回的 `menuCodeSet` |
|
||||
| **存储位置** | `localStorage.menusPermission` |
|
||||
| **匹配字段** | 路由的 `name` 属性 |
|
||||
| **匹配方式** | 数组 `includes` 检查 |
|
||||
| **父路由处理** | 无 `name` 时检查子路由,有权限子路由则保留父路由 |
|
||||
|
||||
---
|
||||
|
||||
## 权限控制层级
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 权限控制层级 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第一层:路由守卫 │
|
||||
│ - 控制登录状态 │
|
||||
│ - 未登录跳转登录页 │
|
||||
│ - 白名单路由直接放行 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第二层:动态路由注册 │
|
||||
│ - 根据权限码筛选路由 │
|
||||
│ - 无权限路由不注册 → 用户输入 URL 直接 404 │
|
||||
│ - 只在登录时计算一次,性能最优 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第三层:侧边栏菜单过滤 │
|
||||
│ - 从已注册路由中筛选 │
|
||||
│ - 只显示有权限的菜单项 │
|
||||
│ - 支持特殊部门/角色的额外过滤 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第四层:按钮级权限 │
|
||||
│ - 使用 v-permission 指令控制按钮显示 │
|
||||
│ - 根据用户的功能权限动态移除无权限元素 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 安全特性
|
||||
|
||||
### 动态路由方案的安全优势
|
||||
|
||||
| 特性 | 说明 |
|
||||
|-----|------|
|
||||
| **路由不存在** | 无权限路由不会注册到 Vue Router,从根本上杜绝越权访问 |
|
||||
| **URL 直接访问** | 用户输入无权限 URL 直接跳转 404 |
|
||||
| **性能最优** | 只在登录时计算一次,后续跳转无需校验 |
|
||||
| **业界标准** | Vue 官方推荐的权限控制方案 |
|
||||
|
||||
### 无权限访问流程
|
||||
|
||||
```
|
||||
用户访问无权限 URL(如 /user/userList)
|
||||
│
|
||||
▼
|
||||
路由是否已注册?
|
||||
│
|
||||
┌─────┴─────┐
|
||||
│ 否 │ 是
|
||||
▼ ▼
|
||||
跳转 404 正常访问(但不会发生,因为无权限路由不会注册)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 特殊权限处理
|
||||
|
||||
### 部门类型 + 角色组合
|
||||
|
||||
系统根据部门类型(`deptBizType`)和角色(`roleList`)进行特殊路由控制:
|
||||
|
||||
| 条件 | 排除的路由 |
|
||||
|-----|----------|
|
||||
| `deptBizType == '23'` 且有 `JS_666666` 角色 | 不排除任何路由 |
|
||||
| `deptBizType == '23'` 且有 `JS_999999` 角色 | 排除 `/internalAuditor` |
|
||||
| 其他情况 | 排除 `/internalAuditor` 和 `/auditList` |
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 页面空白?
|
||||
|
||||
检查项:
|
||||
1. 是否使用了 `JSON.parse(JSON.stringify())` 深拷贝路由(会丢失 component)
|
||||
2. 路由的 `name` 是否与权限码一致
|
||||
3. 控制台是否有报错
|
||||
|
||||
### Q2: 菜单不显示?
|
||||
|
||||
检查项:
|
||||
1. `localStorage.menusPermission` 是否存在
|
||||
2. 路由是否包含 `meta.title` 和 `meta.icon`
|
||||
3. 路由是否在 `EXCLUDE_NAMES` 列表中
|
||||
|
||||
### Q3: 刷新后 404?
|
||||
|
||||
检查项:
|
||||
1. `localStorage.menusPermission` 是否存在
|
||||
2. 路由守卫是否正确重新初始化
|
||||
|
||||
### Q4: 退出登录后无法重新登录?
|
||||
|
||||
检查项:
|
||||
1. 是否正确调用了 `resetRoutesInit()` 重置初始化标记
|
||||
2. 是否正确清除了 localStorage
|
||||
|
||||
---
|
||||
|
||||
## 相关文件索引
|
||||
|
||||
| 文件 | 说明 |
|
||||
|-----|------|
|
||||
| `src/router/index.js` | 路由配置(publicRoutes / privateRoutes) |
|
||||
| `src/store/modules/permission.js` | 权限路由模块(过滤 + 动态注册) |
|
||||
| `src/store/modules/user.js` | 用户模块(登录/退出) |
|
||||
| `src/permission.js` | 路由守卫 |
|
||||
| `src/utils/route.js` | 路由工具函数 |
|
||||
| `src/layout/components/SideBar/SideBarMenu.vue` | 侧边栏菜单 |
|
||||
| `src/layout/components/NavBar.vue` | 导航栏(退出登录) |
|
||||
| `src/views/error/404.vue` | 无权限/404 页面 |
|
||||
| `src/directives/permission.js` | 按钮级权限指令 |
|
||||
209
docs/麒麟系统文件下载兼容性修复方案.md
Normal file
209
docs/麒麟系统文件下载兼容性修复方案.md
Normal file
@ -0,0 +1,209 @@
|
||||
# 麒麟系统浏览器文件下载兼容性修复方案
|
||||
|
||||
## 一、问题现象
|
||||
|
||||
**下载成功,但文件打不开**。文件已保存到本地,但用对应软件打开时提示损坏或格式错误。
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 可能原因 1:`URL.revokeObjectURL` 释放过早(文件内容损坏)
|
||||
|
||||
当前代码(第300-313行):
|
||||
|
||||
```javascript
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const link = document.createElement("a");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href); // 同步释放,可能过早
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
`link.click()` 在麒麟浏览器中是异步的,同步调用 `revokeObjectURL` 会在 Blob 数据写入磁盘前就销毁它,导致文件内容不完整。
|
||||
|
||||
---
|
||||
|
||||
### 可能原因 2:文件名无后缀 / 后缀被篡改
|
||||
|
||||
分析文件名传递链路:
|
||||
|
||||
**上传时**,`handlerSuccess` 保存的是 `{ id, name }`,`name` 来自浏览器原始文件名(带后缀),这部分没问题。
|
||||
|
||||
**但回显时**,watch 中第183-188行存在一个关键问题:
|
||||
|
||||
```javascript
|
||||
// 当 modelValue 元素是字符串(非对象)时:
|
||||
} else {
|
||||
return {
|
||||
url: String(`/mosty-api/mosty-base/minio/image/download/` + el || ""),
|
||||
id: el
|
||||
// ← 没有 name 属性!
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
此时 `file.name` 为 `undefined`,传入 `downloadFile(file.url, file.name)`:
|
||||
|
||||
```javascript
|
||||
link.download = undefined; // 文件名丢失
|
||||
```
|
||||
|
||||
**麒麟浏览器的行为**:当 `download` 属性为空或 `undefined` 时,浏览器会:
|
||||
- 从 URL 路径提取文件名(如 `/minio/image/download/abc123` → 文件名变成 `abc123`,**无后缀**)
|
||||
- 或根据 Blob 的 `type` 自动添加后缀(如服务端返回的 Content-Type 是 `application/json` → 强制加 `.json` 后缀)
|
||||
|
||||
**结果**:一个 `.docx` 文件下载后变成了 `.json` 或无后缀文件,自然打不开。
|
||||
|
||||
**验证方法**:在麒麟系统上下载一个文件,查看下载后的文件名是否和原始文件名一致(包括后缀)。
|
||||
|
||||
---
|
||||
|
||||
### 可能原因 3:麒麟系统安全机制拦截
|
||||
|
||||
麒麟系统(基于 Linux)自带安全中心,可能触发以下行为:
|
||||
|
||||
| 安全机制 | 行为 | 结果 |
|
||||
|----------|------|------|
|
||||
| 文件隔离 | 将下载的文件标记为不可信,移到隔离区 | 文件存在但被锁,其他程序无法读取 |
|
||||
| 执行权限 | 给文件添加可执行标记,或删除可执行标记 | 程序拒绝打开带危险标记的文件 |
|
||||
| 杀毒扫描 | 实时扫描下载文件,误报则隔离 | 文件被移动或内容被修改 |
|
||||
| WINE 兼容层 | 试图用 WINE 打开 Windows 格式文件 | 文件关联错误,打开方式不对 |
|
||||
|
||||
**验证方法**:
|
||||
1. 在麒麟系统终端执行 `ls -la` 查看下载文件是否有特殊权限标记
|
||||
2. 检查 `/tmp` 或隔离区目录是否有被拦截的文件
|
||||
3. 暂时关闭麒麟安全中心,重新下载测试
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案 A:综合修复(推荐)
|
||||
|
||||
同时解决原因1和原因2,并在下载失败时给出明确提示:
|
||||
|
||||
```javascript
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
// 补全文件名后缀
|
||||
function ensureFilename(file) {
|
||||
if (file.name) return file.name
|
||||
// name 丢失时,从 URL 中尝试提取,或使用默认名
|
||||
const urlId = file.url?.split('/').pop()
|
||||
return urlId ? `文件_${urlId}` : '未命名文件'
|
||||
}
|
||||
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载失败: ${response.status}`)
|
||||
}
|
||||
return response.blob()
|
||||
})
|
||||
.then((blob) => {
|
||||
// saveAs 内部处理了 Blob 释放时序,不会过早 revoke
|
||||
saveAs(blob, filename)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('下载失败:', error)
|
||||
ElMessage.error('文件下载失败,请重试')
|
||||
})
|
||||
}
|
||||
|
||||
const handleDownload = (file) => {
|
||||
if (file?.response?.data) {
|
||||
window.open(file.response.data)
|
||||
} else if (file?.url) {
|
||||
const filename = ensureFilename(file)
|
||||
downloadFile(file.url, filename)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**改动内容**:
|
||||
1. 引入 `file-saver`(项目已有依赖)→ 解决 Blob 释放过早
|
||||
2. `ensureFilename` 补全文件名 → 解决后缀丢失
|
||||
3. 响应状态校验 → 发现服务端错误时提示用户
|
||||
|
||||
---
|
||||
|
||||
### 方案 B:仅修复 Blob 释放时序(最小改动)
|
||||
|
||||
```javascript
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = blobUrl;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
// 延迟释放,确保浏览器完成 Blob 数据拷贝
|
||||
setTimeout(() => URL.revokeObjectURL(blobUrl), 3000);
|
||||
})
|
||||
.catch((error) => console.error("下载失败:", error));
|
||||
}
|
||||
```
|
||||
|
||||
**改动量**:1 行。但未修复文件名丢失问题。
|
||||
|
||||
---
|
||||
|
||||
### 方案 C:window.open 直接下载
|
||||
|
||||
```javascript
|
||||
const handleDownload = (file) => {
|
||||
if (file?.url) {
|
||||
window.open(file.url, "_blank");
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**前提**:后端接口需设置 `Content-Disposition: attachment; filename="xxx.docx"` 响应头,浏览器才能正确处理文件名和下载行为。
|
||||
|
||||
---
|
||||
|
||||
## 四、排查步骤
|
||||
|
||||
建议按以下顺序验证,定位到底是哪个原因:
|
||||
|
||||
1. **检查文件名**:在麒麟系统下载后,文件名是否带正确后缀(如 `.docx`、`.pdf`)?
|
||||
- 后缀丢失/被改 → **原因2(文件名问题)**
|
||||
- 后缀正确 → 排除原因2
|
||||
|
||||
2. **检查文件大小**:下载的文件大小是否和服务端一致?
|
||||
- 文件明显偏小或0字节 → **原因1(Blob 释放过早)**
|
||||
- 大小一致 → 排除原因1
|
||||
|
||||
3. **关闭安全中心测试**:暂时关闭麒麟安全中心,重新下载
|
||||
- 能正常打开 → **原因3(安全拦截)**
|
||||
- 仍打不开 → 排除原因3
|
||||
|
||||
---
|
||||
|
||||
## 五、方案对比
|
||||
|
||||
| | 方案 A 综合修复 | 方案 B 延迟释放 | 方案 C window.open |
|
||||
|---|---|---|---|
|
||||
| 修复原因1(Blob释放) | ✅ | ✅ | 不涉及 |
|
||||
| 修复原因2(文件名后缀) | ✅ | ❌ | 取决于后端 |
|
||||
| 处理原因3(安全拦截) | ❌ 需系统配置 | ❌ | ❌ |
|
||||
| 改动量 | ~15行 | 1行 | 最小 |
|
||||
|
||||
**建议**:先执行排查步骤确认根因,再选择对应方案。如果原因1和2同时存在,直接用方案A。
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v3.0
|
||||
**创建日期**: 2026-04-24
|
||||
@ -83,14 +83,5 @@
|
||||
"sass-loader": "^8.0.2",
|
||||
"svg-sprite-loader": "^6.0.9",
|
||||
"vue-cli-plugin-element-plus": "0.0.13"
|
||||
},
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,vue}": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,6 @@ onMounted(() => {
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*@Descripttion:图片页面初始化
|
||||
*@Author: PengShuai
|
||||
|
||||
@ -75,6 +75,14 @@ export const xxcjSelectCzlcList = (params) => {
|
||||
})
|
||||
}
|
||||
// 情报采集指令更新
|
||||
export const xxcjPlsb = (data) => {
|
||||
return request({
|
||||
url: api + `/xxcj/plsb`,
|
||||
method: "post",
|
||||
data
|
||||
})
|
||||
}
|
||||
// 情报采集指令更新
|
||||
export const xxcjUpdateCzlc = (data) => {
|
||||
return request({
|
||||
url: api + `/xxcj/updateCzlc`,
|
||||
|
||||
@ -88,7 +88,11 @@
|
||||
import { qcckGet } from "@/api/qcckApi.js";
|
||||
import { defineProps, ref, getCurrentInstance, watch } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_BQ_DJ, D_GS_SSYJ,D_GS_BQ_LB,D_GS_BQ_LX } = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ","D_GS_BQ_LB","D_GS_BQ_LX"); //获取字典数据
|
||||
const { D_GS_BQ_DJ, D_GS_SSYJ,
|
||||
// D_GS_BQ_LB, D_GS_BQ_LX
|
||||
} = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ"
|
||||
// ,"D_GS_BQ_LB","D_GS_BQ_LX"
|
||||
); //获取字典数据
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
|
||||
@ -67,13 +67,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getItem } from "@/utils/storage";
|
||||
import { timeValidate } from '@/utils/tools'
|
||||
import { ref,defineEmits, onMounted } from 'vue'
|
||||
const props = defineProps({
|
||||
modelValue:Boolean,
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue','save'])
|
||||
const baseInfo = localStorage.getItem('rhInfo') ? JSON.parse(localStorage.getItem('rhInfo')) : {};
|
||||
const baseInfo = getItem('rhInfo') || {};
|
||||
const formData = ref({
|
||||
alarm:1,
|
||||
duration:'30',
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getItem } from "@/utils/storage";
|
||||
import useCallModule from '@/components/Consultation/sdk/call';
|
||||
import useRecorder from '@/components/Consultation/hooks/recorder';
|
||||
import DraggableResizableVue from "draggable-resizable-vue3";
|
||||
@ -43,7 +44,7 @@ const props = defineProps({
|
||||
modelValue:Boolean,
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const baseInfo = localStorage.getItem('rhInfo') ? JSON.parse(localStorage.getItem('rhInfo')) : {};
|
||||
const baseInfo = getItem('rhInfo') || {};
|
||||
let waveContainer;
|
||||
let audioWave = SiriWave || undefined;
|
||||
const element = ref({
|
||||
|
||||
@ -24,7 +24,7 @@ const modleType = ref('')
|
||||
const store = useStore();
|
||||
const inDustRialId = getItem('inDustRialId'); // 当前用户的警号
|
||||
const sdkBDModule = useBaseDataModule();
|
||||
const baseInfo = localStorage.getItem('rhInfo') ? JSON.parse(localStorage.getItem('rhInfo')) : {};
|
||||
const baseInfo = ref(getItem('rhInfo') || {});
|
||||
const showVideo = ref(false)//拖动视频
|
||||
const showDailog = ref(false)//showDailog
|
||||
const openMeeting = ref(false) //打开会议
|
||||
@ -97,8 +97,8 @@ const handleTime = (n=10) =>{
|
||||
|
||||
// 创建会议
|
||||
const conferenceActionSDK = async (record ) => {
|
||||
const createRes = await lemon.conference.createConference({
|
||||
subject: record.glxsmc, //主题
|
||||
let data = {
|
||||
subject: record.hsbt, //主题
|
||||
type: 1, //会议类型 0=即时会议,1=预约会议
|
||||
emergency_flag: 0, //会议紧急标识 0 = 非紧急会议,1 = 紧急会议
|
||||
duration: 60, //预计时长 (分钟)
|
||||
@ -107,14 +107,14 @@ const conferenceActionSDK = async (record ) => {
|
||||
appointment: handleTime(), // start_date 和 start_time 对应的 UTC 时间
|
||||
members:[
|
||||
{
|
||||
alias:baseInfo.dispatcher_name,
|
||||
basedata_id:baseInfo.basedata_id,
|
||||
guid:baseInfo.user_guid,
|
||||
number:baseInfo.user_id,
|
||||
alias:baseInfo.value.dispatcher_name,
|
||||
basedata_id:baseInfo.value.basedata_id,
|
||||
guid:baseInfo.value.user_guid,
|
||||
number:baseInfo.value.user_id,
|
||||
}
|
||||
],//当前创建人
|
||||
});
|
||||
console.log(createRes,'===========创建的会议');
|
||||
}
|
||||
const createRes = await lemon.conference.createConference(data);
|
||||
if (createRes.result === 0) {
|
||||
ElMessage.success(jsonData.value['data']['conference.book.result.ok']);
|
||||
record.number = createRes.meeting.number;
|
||||
@ -137,7 +137,7 @@ const enterConferenceByNumber = (it) =>{
|
||||
"camera_status": 1
|
||||
}
|
||||
lemon.conference.enterConferenceByNumber(params).then(res=> {
|
||||
console.log(res,'加入会议......');
|
||||
console.log(res,'=======加入会议=======');
|
||||
}).catch(err=> {
|
||||
console.log(err,' 加入会议失败......');
|
||||
})
|
||||
@ -147,7 +147,6 @@ const enterConferenceByNumber = (it) =>{
|
||||
// 获取会议
|
||||
const fetchConferences = (it) =>{
|
||||
lemon.conference.fetchConferences().then(res=> {
|
||||
console.log(res.conferenceList,'获取会议');
|
||||
meetList.value = res.conferenceList;
|
||||
let obj = meetList.value.find(v=>v.number == it.number);
|
||||
// 会议存在 ? 进入会议 : 创建会议 ;
|
||||
@ -155,10 +154,55 @@ const fetchConferences = (it) =>{
|
||||
}).catch(err=> {})
|
||||
}
|
||||
|
||||
// 初始化后需要监听的方法
|
||||
const listenerEvents = () =>{
|
||||
getLoginAccountInfo() //前账号的登录信息
|
||||
useConfernceEvent()// 注册会议管理相关事件
|
||||
// 无人机对讲机的监听时事件
|
||||
window.lemon.call.addMediaStream((call_id, stream, type) => {
|
||||
// console.log(call_id, stream, type,'=======无人机对讲机的监听时事件==');
|
||||
});
|
||||
}
|
||||
|
||||
const getLoginAccountInfo =() =>{
|
||||
lemon.login.getLoginAccountInfo().then(res => {
|
||||
let info = JSON.stringify(res.account_info)
|
||||
baseInfo.value = res.account_info;
|
||||
window.localStorage.setItem("rhInfo",info);
|
||||
window.localStorage.setItem("user_basedata_id",res.account_info.basedata_id);
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 加入会议
|
||||
const openInit = (it,type) =>{
|
||||
modleType.value = type;
|
||||
if(type == '会议'){
|
||||
//判断是否有会议号
|
||||
let into = it.number ? '确定开始会议?' : '没有找到会议,是否创建会议?'
|
||||
ElMessageBox.confirm(into,'提示',{
|
||||
confirmButtonText:'确定',
|
||||
cancelButtonText:'取消',
|
||||
type:'warning',
|
||||
}).then(res=>{
|
||||
// 会议号存在 ? 获取会议列表里面是否包含该条会议 : 创建会议 ;
|
||||
it.number ? fetchConferences(it) : conferenceActionSDK(it);
|
||||
}).catch(()=>{ })
|
||||
}
|
||||
|
||||
if(['对讲机','无人机'].includes(type)){
|
||||
showVideo.value = true;
|
||||
nextTick(()=>{
|
||||
RefEqripment.value.handleBtn(type)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Init = () => {
|
||||
let token = window.localStorage.getItem("rhToken");
|
||||
if (!token) {
|
||||
if (!token || 'undefined' == token || token == 'null') {
|
||||
let userInfo = {
|
||||
username: inDustRialId, //用户名
|
||||
password: "123456",
|
||||
@ -169,7 +213,7 @@ const Init = () => {
|
||||
token = esacpe.token;
|
||||
window.localStorage.setItem("rhToken", esacpe.token);
|
||||
listenerEvents()
|
||||
});
|
||||
})
|
||||
} else {
|
||||
ConnectWebsocket(token);
|
||||
}
|
||||
@ -194,52 +238,6 @@ const ConnectWebsocket = (token) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化后需要监听的方法
|
||||
const listenerEvents = () =>{
|
||||
getLoginAccountInfo() //前账号的登录信息
|
||||
useConfernceEvent()// 注册会议管理相关事件
|
||||
// 无人机对讲机的监听时事件
|
||||
window.lemon.call.addMediaStream((call_id, stream, type) => {
|
||||
console.log(call_id, stream, type,'=======无人机对讲机的监听时事件==');
|
||||
});
|
||||
}
|
||||
|
||||
const getLoginAccountInfo =() =>{
|
||||
lemon.login.getLoginAccountInfo().then(res => {
|
||||
let info = JSON.stringify(res.account_info)
|
||||
window.localStorage.setItem("rhInfo",info);
|
||||
window.localStorage.setItem("user_basedata_id",res.account_info.basedata_id);
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 加入会议
|
||||
const openInit = (it,type) =>{
|
||||
modleType.value = type;
|
||||
if(type == '会议'){
|
||||
//判断是否有会议号
|
||||
let into = it.number ? '确定开始会议?' : '没有找到会议,是否创建会议?'
|
||||
ElMessageBox.confirm(into,'提示',{
|
||||
confirmButtonText:'确定',
|
||||
cancelButtonText:'取消',
|
||||
type:'warning',
|
||||
}).then(res=>{
|
||||
// 会议号存在 ? 获取会议列表里面是否包含该条会议 : 创建会议 ;
|
||||
it.number ? fetchConferences(it) : conferenceActionSDK(it);
|
||||
}).catch(()=>{ })
|
||||
|
||||
}
|
||||
|
||||
if(['对讲机','无人机'].includes(type)){
|
||||
showVideo.value = true;
|
||||
nextTick(()=>{
|
||||
RefEqripment.value.handleBtn(type)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
jsonData.value = require('./components/zh_CN.json');
|
||||
nextTick(()=>{
|
||||
@ -252,7 +250,7 @@ onUnmounted(()=>{
|
||||
lemon.login.removeLoginStatusChangeListener(loginStatusCallbackId.value);
|
||||
})
|
||||
|
||||
defineExpose({openInit});
|
||||
defineExpose({openInit,Init});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -4,14 +4,47 @@
|
||||
:class="props.showBtn ? 'showBtn-upload' : ''"
|
||||
:style="{ width: width }"
|
||||
>
|
||||
<!-- 列表模式:按钮在上,文件列表在下 -->
|
||||
<div v-if="props.showBtn" class="upload-wrapper">
|
||||
<el-upload
|
||||
v-bind="$attrs"
|
||||
:headers="headers"
|
||||
:multiple="false"
|
||||
class="avatar-uploader upload-btn-only"
|
||||
:limit="props.limit"
|
||||
:action="actionUrl"
|
||||
:file-list="fileList"
|
||||
:show-file-list="false"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handlerSuccess"
|
||||
:before-upload="beforeImgUpload"
|
||||
>
|
||||
<el-button size="small" type="primary">上传文件</el-button>
|
||||
</el-upload>
|
||||
<!-- 文件列表 -->
|
||||
<div v-if="showFileList" class="upload-file-list">
|
||||
<div v-for="(file, index) in fileList" :key="file.id || index" class="upload-list-item">
|
||||
<span class="upload-list-item__name" @click="handleDownload(file)">
|
||||
<el-icon class="upload-list-item__icon"><Document /></el-icon>
|
||||
{{ file.name }}
|
||||
</span>
|
||||
<span class="upload-list-item__actions">
|
||||
<el-icon class="upload-list-item__download" @click="handleDownload(file)"><Download /></el-icon>
|
||||
<el-icon v-if="!disabled" class="upload-list-item__delete" @click="handleRemove(file, fileList)"><Close /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 卡片模式 -->
|
||||
<el-upload
|
||||
v-else
|
||||
v-bind="$attrs"
|
||||
:headers="headers"
|
||||
:multiple="false"
|
||||
class="avatar-uploader"
|
||||
:limit="props.limit"
|
||||
:action="actionUrl"
|
||||
:list-type="props.showBtn ? '' : 'picture-card'"
|
||||
list-type="picture-card"
|
||||
:file-list="fileList"
|
||||
:show-file-list="showFileList"
|
||||
:before-remove="beforeRemove"
|
||||
@ -20,12 +53,10 @@
|
||||
:before-upload="beforeImgUpload"
|
||||
>
|
||||
<template #default>
|
||||
<el-button v-if="props.showBtn" size="small" type="primary"
|
||||
>上传文件</el-button
|
||||
>
|
||||
<el-icon v-else><Plus /></el-icon>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</template>
|
||||
<template #file="{ file }" v-if="!props.showBtn">
|
||||
<template #file="{ file }">
|
||||
<!-- 图片卡片模式 -->
|
||||
<div v-if="props.isImg">
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
@ -48,6 +79,7 @@
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 文件卡片模式 -->
|
||||
<div v-else>
|
||||
<div class="file-wrap">
|
||||
<span><svg-icon :icon="getSuffix(file.name)" /></span>
|
||||
@ -90,6 +122,7 @@ import {
|
||||
onUnmounted
|
||||
} from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { saveAs } from "file-saver";
|
||||
import { useStore } from "vuex";
|
||||
const props = defineProps({
|
||||
//获取组件传值
|
||||
@ -151,7 +184,8 @@ watch(
|
||||
} else {
|
||||
return {
|
||||
url: String(`/mosty-api/mosty-base/minio/image/download/` + el || ""),
|
||||
id: el
|
||||
id: el,
|
||||
name: el
|
||||
};
|
||||
}
|
||||
});
|
||||
@ -265,25 +299,35 @@ const handlePictureCardPreview = (file) => {
|
||||
dialogImageUrl.value = file.url || "";
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const link = document.createElement("a");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href);
|
||||
})
|
||||
.catch((error) => console.error("下载失败:", error));
|
||||
// 补全文件名:确保文件名有效且有后缀
|
||||
const ensureFilename = (file) => {
|
||||
if (file.name) return file.name;
|
||||
// name 丢失时,从 URL 或 ID 提取
|
||||
const urlId = file.url?.split('/').pop() || file.id;
|
||||
return urlId ? `文件_${urlId}` : '未命名文件';
|
||||
};
|
||||
|
||||
async function downloadFile(url, filename) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载失败: ${response.status}`);
|
||||
}
|
||||
const blob = await response.blob();
|
||||
// 使用 file-saver 处理下载,内部处理了 Blob 释放时序,兼容各系统
|
||||
saveAs(blob, filename);
|
||||
} catch (error) {
|
||||
console.error("下载失败:", error);
|
||||
ElMessage.error("文件下载失败,请重试");
|
||||
}
|
||||
}
|
||||
|
||||
const handleDownload = (file) => {
|
||||
if (file?.response?.data) {
|
||||
window.open(file.response.data);
|
||||
} else if (file?.url) {
|
||||
downloadFile(file.url, file.name);
|
||||
const filename = ensureFilename(file);
|
||||
downloadFile(file.url, filename);
|
||||
}
|
||||
};
|
||||
// const handleDownload = (file) => {
|
||||
@ -361,4 +405,90 @@ const handleRemove = (file) => {
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* 列表模式容器 */
|
||||
.upload-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
.upload-btn-only {
|
||||
:deep(.el-upload-list) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 文件列表 */
|
||||
.upload-file-list {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 列表模式样式 */
|
||||
.upload-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 8px 12px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 8px;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: #e9ecf0;
|
||||
|
||||
.upload-list-item__actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-list-item__name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
cursor: pointer;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-list-item__icon {
|
||||
margin-right: 8px;
|
||||
font-size: 18px;
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.upload-list-item__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
.el-icon {
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin-left: 12px;
|
||||
color: #606266;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-list-item__delete:hover {
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<el-select v-if="item.showType === 'select'" v-model="searchObj[item.prop]" :multiple="item.multiple"
|
||||
:clearable="item.clearable" :filterable="item.filterable" :placeholder="item.placeholder" collapse-tags
|
||||
collapse-tags-tooltip class="control-select">
|
||||
<el-option v-for="obj in getOptions[item.prop]" :key="obj.value" :label="obj.label || obj.lable"
|
||||
<el-option v-for="obj in (getOptions[item.prop] || [])" :key="obj.value" :label="obj.label || obj.lable"
|
||||
:value="obj.value" />
|
||||
</el-select>
|
||||
<!-- input -->
|
||||
@ -412,12 +412,12 @@ const cascaderLazyProps = reactive({
|
||||
}
|
||||
});
|
||||
// 获取到传过来的参数
|
||||
let getArr = reactive([]);
|
||||
let getArr = ref([]);
|
||||
const submit = () => {
|
||||
emit("submit", searchObj);
|
||||
};
|
||||
const reset = () => {
|
||||
getArr.forEach((item) => {
|
||||
getArr.value.forEach((item) => {
|
||||
searchObj[item.prop] = item.defaultVal;
|
||||
});
|
||||
emit("reset", true);
|
||||
@ -430,63 +430,63 @@ defineExpose({
|
||||
submit,
|
||||
reset
|
||||
});
|
||||
// 优化 watchEffect 为 watch,避免因 reactive 内部状态变化导致频繁重新执行
|
||||
// 监听 searchArr 变化,同时监听内部 options 的异步更新
|
||||
watch(() => props.searchArr, (newArr) => {
|
||||
loadingPage.value = true;
|
||||
// 使用 try-catch 防止解析失败导致崩溃
|
||||
try {
|
||||
let arr = JSON.parse(JSON.stringify(newArr));
|
||||
getArr = arr.map((item) => {
|
||||
switch (item.showType) {
|
||||
// 不再深拷贝,保留响应式引用
|
||||
getArr.value = newArr.map((item) => {
|
||||
const itemCopy = { ...item }; // 浅拷贝即可
|
||||
switch (itemCopy.showType) {
|
||||
case "select":
|
||||
item = { ...selectDefault, ...item };
|
||||
item.options = reactive(item.options);
|
||||
getOptions[item.prop] = item.options;
|
||||
Object.assign(itemCopy, { ...selectDefault, ...itemCopy });
|
||||
// 直接引用原 options,保持响应式
|
||||
getOptions[itemCopy.prop] = itemCopy.options || [];
|
||||
break;
|
||||
case "input":
|
||||
item = { ...inputDefault, ...item };
|
||||
Object.assign(itemCopy, { ...inputDefault, ...itemCopy });
|
||||
break;
|
||||
case "daterange":
|
||||
item = { ...daterangeDefault, ...item };
|
||||
if (item.defaultShortcuts) item.shortcuts = shortcuts;
|
||||
Object.assign(itemCopy, { ...daterangeDefault, ...itemCopy });
|
||||
if (itemCopy.defaultShortcuts) itemCopy.shortcuts = shortcuts;
|
||||
break;
|
||||
case "date":
|
||||
item = { ...defaultDate, ...item };
|
||||
if (item.defaultShortcuts) {
|
||||
item.shortcuts = dateShortcuts;
|
||||
Object.assign(itemCopy, { ...defaultDate, ...itemCopy });
|
||||
if (itemCopy.defaultShortcuts) {
|
||||
itemCopy.shortcuts = dateShortcuts;
|
||||
}
|
||||
break;
|
||||
case "checkbox":
|
||||
item = reactive({ ...defaultCheckbox, ...item });
|
||||
item.checkboxValueArr = item.options.map((obj) => {
|
||||
Object.assign(itemCopy, { ...defaultCheckbox, ...itemCopy });
|
||||
itemCopy.checkboxValueArr = (itemCopy.options || []).map((obj) => {
|
||||
return obj.value;
|
||||
});
|
||||
break;
|
||||
case "cascader":
|
||||
item = { ...defaultCascader, ...item };
|
||||
if (item.lazy) {
|
||||
cascaderLazyProps.checkStrictly = item.checkStrictly;
|
||||
item.props = { ...cascaderLazyProps, ...(item.props || {}) };
|
||||
delete item.options;
|
||||
Object.assign(itemCopy, { ...defaultCascader, ...itemCopy });
|
||||
if (itemCopy.lazy) {
|
||||
cascaderLazyProps.checkStrictly = itemCopy.checkStrictly;
|
||||
itemCopy.props = { ...cascaderLazyProps, ...(itemCopy.props || {}) };
|
||||
delete itemCopy.options;
|
||||
} else {
|
||||
item.props = {
|
||||
itemCopy.props = {
|
||||
...defaultCascader.props,
|
||||
...(item.props || {}),
|
||||
...{ checkStrictly: item.checkStrictly }
|
||||
...(itemCopy.props || {}),
|
||||
...{ checkStrictly: itemCopy.checkStrictly }
|
||||
};
|
||||
getOptions[item.prop] = reactive(item.options);
|
||||
getOptions[itemCopy.prop] = itemCopy.options || [];
|
||||
}
|
||||
break;
|
||||
}
|
||||
loadingPage.value = false;
|
||||
searchObj[item.prop] = item.defaultVal;
|
||||
return item;
|
||||
searchObj[itemCopy.prop] = itemCopy.defaultVal;
|
||||
return itemCopy;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Search组件初始化失败:', e);
|
||||
console.error('Search组件解析searchArr失败:', e);
|
||||
} finally {
|
||||
loadingPage.value = false;
|
||||
}
|
||||
}, { immediate: true, deep: false });
|
||||
}, { immediate: true, deep: true }); // 开启深度监听,检测 options 变化
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -82,6 +82,7 @@ const playAudioByType = (val) => {
|
||||
switch (val.yjlb) {
|
||||
case "01":
|
||||
case "02":
|
||||
if (val.sfQs == '1') return
|
||||
if (val.yjJb == "01") {
|
||||
getAudioPlayer("18")?.play();
|
||||
getAudioPlayer("17")?.play();
|
||||
@ -89,8 +90,6 @@ const playAudioByType = (val) => {
|
||||
getAudioPlayer("19")?.play();
|
||||
}
|
||||
break;
|
||||
case "03":
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "02": //信息汇聚
|
||||
@ -123,7 +122,7 @@ const playAudioByType = (val) => {
|
||||
break;
|
||||
case "11":
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("16")?.play();
|
||||
getAudioPlayer("19")?.play();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -159,13 +158,14 @@ const checkNews = ref(null);
|
||||
const checkNewsInterval = 15000; // 15秒
|
||||
const idEntityCard = ref(getItem("idEntityCard"));
|
||||
|
||||
onMounted(async () => {
|
||||
await initAudioPlayers();
|
||||
|
||||
// 音频预加载完成后再启动轮询,避免定时器先触发但播放器还未就绪
|
||||
onMounted(() => {
|
||||
// 音频初始化在后台进行,不阻塞组件渲染
|
||||
initAudioPlayers().then(() => {
|
||||
// 音频预加载完成后再启动轮询
|
||||
checkNews.value = setInterval(() => {
|
||||
dataModel();
|
||||
}, checkNewsInterval);
|
||||
});
|
||||
|
||||
// 注册事件监听(需在 onUnmounted 中精确解绑)
|
||||
emitter.on("webSocketMessage", handleWebSocketMessage);
|
||||
@ -272,6 +272,7 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
|
||||
@ -75,10 +75,10 @@ const handleClick = () => {
|
||||
xxlx: ""
|
||||
}
|
||||
queryWdxxPageList({ ...promes, xxlx: 100 }).then((res) => {
|
||||
xxListData.xtxxNumber = res.total
|
||||
xxListData.xtxxNumber = res?.total || 0
|
||||
});
|
||||
queryWdxxPageList({ ...promes, xxlx: 200 }).then((res) => {
|
||||
xxListData.tztgNumber = res.total
|
||||
xxListData.tztgNumber = res?.total || 0
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
<template>
|
||||
<el-dropdown class="avatar-container" trigger="click">
|
||||
<div class="avatar-wrapper">
|
||||
<el-avatar
|
||||
shape="circle"
|
||||
:size="28"
|
||||
:src="require('@/assets/images/ly-person-icon.png')"
|
||||
></el-avatar>
|
||||
<el-avatar shape="circle" :size="28" :src="require('@/assets/images/ly-person-icon.png')"></el-avatar>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="user-dropdown">
|
||||
@ -28,12 +24,7 @@ const updatePwd = () => {
|
||||
const store = useStore();
|
||||
|
||||
const logout = () => {
|
||||
window.opener = null;
|
||||
window.open('', '_self');
|
||||
window.close();
|
||||
store.commit("app/clearTag", null, { immediate: true });
|
||||
store.commit("permission/deleteRouter", { immediate: true });
|
||||
store.commit("user/deleteKeepLiiveRoute", "home");
|
||||
store.dispatch("user/logout");
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -52,6 +43,7 @@ const logout = () => {
|
||||
cursor: pointer;
|
||||
// hover 动画
|
||||
transition: background 0.5s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@ -86,9 +78,11 @@ const logout = () => {
|
||||
|
||||
::v-deep .avatar-container {
|
||||
cursor: pointer;
|
||||
|
||||
.avatar-wrapper {
|
||||
margin-top: 5px;
|
||||
position: relative;
|
||||
|
||||
.el-avatar {
|
||||
--el-avatar-background-color: none;
|
||||
margin-right: 12px;
|
||||
|
||||
@ -18,12 +18,13 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { computed, watch } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { useStore } from "vuex";
|
||||
import { filterRoutes, generateMenus } from "@/utils/route";
|
||||
import { getItem } from "@/utils/storage";
|
||||
import SideBarItem from "./SideBarItem.vue";
|
||||
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
const EXCLUDE_NAMES = [
|
||||
@ -35,6 +36,7 @@ const EXCLUDE_NAMES = [
|
||||
"mpvPeos",
|
||||
"myControls"
|
||||
];
|
||||
|
||||
const filterRoutesByMenusPermission = (routes, menusSet) => {
|
||||
return routes.reduce((result, route) => {
|
||||
const children = Array.isArray(route.children)
|
||||
@ -50,43 +52,57 @@ const filterRoutesByMenusPermission = (routes, menusSet) => {
|
||||
};
|
||||
const routes = computed(() => {
|
||||
const fRoutes = filterRoutes(router.getRoutes());
|
||||
const data = fRoutes.filter((item) => !EXCLUDE_NAMES.includes(item.name));
|
||||
const menusPermission = getItem("menusPermission");
|
||||
console.log(JSON.parse(localStorage.getItem("menusPermission")));
|
||||
console.log(
|
||||
router.getRoutes().map((r) => ({ name: r.name, path: r.path })),
|
||||
"xxx"
|
||||
// 排除不需要显示的菜单,包括 forumPost(单独处理)
|
||||
const data = fRoutes.filter((item) =>
|
||||
!EXCLUDE_NAMES.includes(item.name) && item.name !== 'forumPost'
|
||||
);
|
||||
// menusPermission 里存的 name
|
||||
router
|
||||
.getRoutes()
|
||||
.filter((r) => r.path === "/")
|
||||
.map((r) => ({
|
||||
name: r.name,
|
||||
path: r.path,
|
||||
children: r.children?.map((c) => ({ name: c.name, path: c.path }))
|
||||
}));
|
||||
console.log(JSON.parse(localStorage.getItem("menusPermission")));
|
||||
const menusPermission = getItem("menusPermission");
|
||||
|
||||
// 情报论坛菜单(所有人可见,始终显示在最后)
|
||||
const forumMenu = {
|
||||
path: '/forumPost',
|
||||
meta: { title: '情报论坛', icon: 'article-ranking' },
|
||||
children: []
|
||||
};
|
||||
|
||||
// 如果 menusPermission 为 null 或 undefined,只显示情报论坛菜单
|
||||
if (menusPermission === null || menusPermission === undefined) {
|
||||
return [forumMenu];
|
||||
}
|
||||
|
||||
const menusSet = new Set(
|
||||
Array.isArray(menusPermission)
|
||||
? menusPermission.map((item) => `${item}`)
|
||||
: []
|
||||
);
|
||||
console.log(menusSet);
|
||||
|
||||
const permissionFiltered = menusSet.size
|
||||
// 先按权限过滤
|
||||
let permissionFiltered = menusSet.size
|
||||
? filterRoutesByMenusPermission(data, menusSet)
|
||||
: data;
|
||||
return generateMenus(permissionFiltered);
|
||||
: [];
|
||||
|
||||
// 生成菜单
|
||||
const menus = generateMenus(permissionFiltered);
|
||||
|
||||
// 最后添加情报论坛菜单(所有人可见,放到最后)
|
||||
menus.push(forumMenu);
|
||||
|
||||
return menus;
|
||||
});
|
||||
if (!store.getters.token) {
|
||||
router.push("/login");
|
||||
}
|
||||
if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
|
||||
store.commit("user/setIsReady", {});
|
||||
setTimeout(() => {
|
||||
router.go(0);
|
||||
}, 200);
|
||||
// 路由未完成加载时,等待加载完成,不再刷新页面
|
||||
if (store.state.permission.routeReady !== 2) {
|
||||
const unwatch = watch(
|
||||
() => store.state.permission.routeReady,
|
||||
(val) => {
|
||||
if (val === 2) {
|
||||
unwatch();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
}
|
||||
//默认激活项
|
||||
const route = useRoute();
|
||||
|
||||
@ -9,62 +9,55 @@ import {
|
||||
import {
|
||||
getCookie
|
||||
} from "@/utils/cookie";
|
||||
// 白名单
|
||||
|
||||
// 白名单路由(无需登录即可访问)
|
||||
const whiteList = ['/login', '/oatuh_login', '/404', '/401', '/zeroTrust_login', '/focusExploration', '/clueVerification', '/deploymentApproval']
|
||||
|
||||
// 标记路由是否已初始化
|
||||
let routesInitialized = false;
|
||||
|
||||
/**
|
||||
* 路由前置守卫
|
||||
* to 去哪里
|
||||
* from 来自哪
|
||||
* next 往下走
|
||||
*/
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// 存在 token ,进入主页
|
||||
// if (store.state.user.token) {
|
||||
// 快捷访问
|
||||
// console.log(store.getters.token);
|
||||
console.log('[permission.js] 路由守卫触发:', from.path, '->', to.path, '时间:', Date.now());
|
||||
|
||||
if (store.getters.token) {
|
||||
// console.log("路由1");
|
||||
|
||||
// 判断用户资料是否获取
|
||||
// 若不存在用户信息,则需要获取用户信息
|
||||
// 触发获取用户信息的 action,并获取用户当前权限
|
||||
store.commit('permission/setRouteReady', 1)
|
||||
// 添加完动态路由之后,需要在进行一次主动跳转
|
||||
// 已登录
|
||||
if (!routesInitialized) {
|
||||
// 首次进入:根据权限动态注册路由
|
||||
console.log('[permission.js] 首次初始化路由...');
|
||||
routesInitialized = true;
|
||||
const afterMenuList = getItem('menusPermission');
|
||||
// 处理用户权限,筛选出需要添加的权限
|
||||
// console.log(store.state.permission.routes);
|
||||
console.log('[permission.js] menusPermission:', afterMenuList?.length);
|
||||
|
||||
if (store.state.permission.routes.length === 0) {
|
||||
const filterRoutes = await store.dispatch('permission/filterRoutes', afterMenuList)
|
||||
filterRoutes.forEach(item => {
|
||||
router.addRoute(item)
|
||||
})
|
||||
// console.log("已添加动态路由");
|
||||
next({
|
||||
...to,
|
||||
replace: true
|
||||
})
|
||||
} else {
|
||||
// console.log('已存在路由');
|
||||
next()
|
||||
// 动态注册有权限的路由
|
||||
await store.dispatch('permission/filterRoutes', afterMenuList);
|
||||
console.log('[permission.js] 路由初始化完成');
|
||||
|
||||
// 重新导航到目标路由,确保刚注册的路由能正确匹配
|
||||
next({ ...to, replace: true });
|
||||
return;
|
||||
}
|
||||
// 利用 addRoute 循环添加
|
||||
|
||||
// 处理 keep-alive 缓存(使用组件名称,而非路由名称)
|
||||
if (to.meta.keepAlive && to.meta.componentName) {
|
||||
store.commit('user/setKeepLiiveRoute', to.meta.componentName);
|
||||
}
|
||||
|
||||
console.log('[permission.js] 放行跳转');
|
||||
next();
|
||||
} else {
|
||||
// 没有token的情况下,可以进入白名单
|
||||
// 未登录:白名单放行,否则跳转登录
|
||||
if (whiteList.indexOf(to.path) > -1) {
|
||||
// console.log("路由2");
|
||||
next()
|
||||
} else {
|
||||
const cookie = getCookie("clientKey");
|
||||
if (cookie) {
|
||||
// console.log("路由3");
|
||||
next(`/zeroTrust_login`)
|
||||
} else {
|
||||
// console.log("路由4");
|
||||
const isOatuh = getItem('isOatuh')
|
||||
// 没有token的情况下,可以进入白名单
|
||||
if (isOatuh) {
|
||||
// console.log("路由5");
|
||||
const idEntityCard = getItem('idEntityCard')
|
||||
next(`/oatuh_login?token=${Base64.encode(idEntityCard)}`)
|
||||
} else {
|
||||
@ -74,3 +67,15 @@ router.beforeEach(async (to, from, next) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 添加路由后置守卫,确认路由变化
|
||||
router.afterEach((to, from) => {
|
||||
console.log('[permission.js] 路由跳转完成:', from.path, '->', to.path, '时间:', Date.now());
|
||||
})
|
||||
|
||||
/**
|
||||
* 重置路由初始化状态(退出登录时调用)
|
||||
*/
|
||||
export function resetRoutesInit() {
|
||||
routesInitialized = false;
|
||||
}
|
||||
|
||||
@ -1,26 +1,24 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import layout from "@/layout/index"; //layout直接引用 其他使用路由懒加载
|
||||
import layout from "@/layout/index";
|
||||
import store from "@/store";
|
||||
|
||||
// import Home from '../views/Home.vue'
|
||||
/**
|
||||
* 关于路由配置描述
|
||||
* 1.meta && meta.title && meta.icon 则在菜单栏显示
|
||||
* 2.如果存在children , 则以el-sub-menu子菜单显示
|
||||
* 否则不在menu菜单显示
|
||||
* 如果只展示单级别菜单 需要像developer这样配置
|
||||
* 路由配置说明
|
||||
*
|
||||
* 1. publicRoutes(公开路由)- 所有用户都能访问,应用启动时静态注册
|
||||
* 包括:登录页、首页、错误页等
|
||||
*
|
||||
* 2. privateRoutes(私有路由)- 需要权限才能访问,登录后动态注册
|
||||
* 包括:所有业务功能路由
|
||||
*
|
||||
* 3. 路由的 name 属性必须与后端返回的菜单权限码(menuCodeSet)一致
|
||||
*/
|
||||
|
||||
/**
|
||||
* 私有路由表
|
||||
*/
|
||||
|
||||
export const privateRoutes = [];
|
||||
|
||||
/**
|
||||
* 公开路由表
|
||||
* 公开路由表 - 所有人都能访问
|
||||
*/
|
||||
export const publicRoutes = [
|
||||
// 登录相关路由
|
||||
{
|
||||
path: "/oatuh_login",
|
||||
name: "oatuh_login",
|
||||
@ -36,44 +34,57 @@ export const publicRoutes = [
|
||||
name: "zeroTrust_login",
|
||||
component: () => import("@/views/login/zeroTrust_login")
|
||||
},
|
||||
// 错误页面
|
||||
{
|
||||
path: "/401",
|
||||
name: "401",
|
||||
component: () => import("@/views/error/401.vue")
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "404",
|
||||
component: () => import("@/views/error/404.vue")
|
||||
},
|
||||
// 首页(所有登录用户都可访问)
|
||||
{
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: () => import("@/views/home/index") //系统登录
|
||||
component: () => import("@/views/home/index"),
|
||||
meta: { keepAlive: true, componentName: 'HomePage' }
|
||||
},
|
||||
// 公共访问页面(无需权限校验)
|
||||
{
|
||||
path: "/mapNavigation",
|
||||
name: "mapNavigation",
|
||||
component: () => import("@/views/home/model/mapNavigation.vue") //系统登录
|
||||
component: () => import("@/views/home/model/mapNavigation.vue")
|
||||
},
|
||||
{
|
||||
path: "/KeyPopulations",
|
||||
name: "KeyPopulations",
|
||||
component: () => import("@/views/KeyPopulations/index") //系统登录
|
||||
component: () => import("@/views/KeyPopulations/index")
|
||||
},
|
||||
// 布控审核信息
|
||||
// 以下路由虽然在白名单中,但仍需要登录才能访问
|
||||
// 它们是特殊业务路由,登录后所有人都能访问(不依赖菜单权限)
|
||||
{
|
||||
path: "/deploymentApproval",
|
||||
name: "deploymentApproval",
|
||||
component: () => import("@/views/backOfficeSystem/ApprovalInformation/deploycontrol/deploymentApproval.vue"),
|
||||
},
|
||||
// 标签布控审核
|
||||
{
|
||||
path: "/shym",
|
||||
name: "shym",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/marksControl/components/shym.vue"),
|
||||
},
|
||||
// 布控审核信息
|
||||
{
|
||||
path: "/information",
|
||||
name: "information",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/internalAuditor/information.vue"),
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/Spdloyment",
|
||||
name: "Spdloyment",
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/auditList/components/spdloyment.vue"),
|
||||
},
|
||||
// 线索
|
||||
{
|
||||
path: "/clueVerification",
|
||||
name: "clueVerification",
|
||||
@ -84,13 +95,40 @@ export const publicRoutes = [
|
||||
name: "ReviewListSH",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/ReviewList/detail.vue"),
|
||||
},
|
||||
// 重点人发掘
|
||||
{
|
||||
path: "/focusExploration",
|
||||
name: "focusExploration",
|
||||
component: () => import("@/views/backOfficeSystem/ApprovalInformation/FocusExploration/index.vue"),
|
||||
},
|
||||
//开放到派出所路由
|
||||
// 情报论坛(所有登录用户都可访问)
|
||||
{
|
||||
path: "/forumPost",
|
||||
name: "forumPost",
|
||||
component: layout,
|
||||
meta: {
|
||||
title: "情报论坛",
|
||||
icon: "article-ranking"
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "forumPostPage",
|
||||
component: () => import("@/views/backOfficeSystem/luntan/index.vue"),
|
||||
meta: {
|
||||
title: "情报论坛",
|
||||
icon: "article-ranking"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 私有路由表 - 需要权限才能访问
|
||||
* 登录后根据用户的 menuCodeSet 动态注册
|
||||
*/
|
||||
export const privateRoutes = [
|
||||
// 派出所开放路由(特殊权限,不在菜单显示)
|
||||
{
|
||||
path: "/warningLists",
|
||||
name: "warningLists",
|
||||
@ -100,7 +138,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/behaviorWarnings",
|
||||
name: "behaviorWarnings",
|
||||
@ -127,7 +164,8 @@ export const publicRoutes = [
|
||||
title: "重点人管理",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/myControls",
|
||||
name: "myControls",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/myControl/index"),
|
||||
@ -135,7 +173,8 @@ export const publicRoutes = [
|
||||
title: "我的布控",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/DeploymentAreas",
|
||||
name: "DeploymentAreas",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/DeploymentArea/index"),
|
||||
@ -144,8 +183,9 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// 主业务路由(带 layout)
|
||||
{
|
||||
path: "/editPassword", // 注意:带有路径“/”的记录中的组件“默认”是一个不返回 Promise 的函数
|
||||
path: "/editPassword",
|
||||
redirect: "/IdentityManage",
|
||||
component: layout,
|
||||
children: [
|
||||
@ -154,18 +194,6 @@ export const publicRoutes = [
|
||||
name: "FourColorWarning",
|
||||
meta: { title: "预警中心", icon: "article-ranking" },
|
||||
children: [
|
||||
// {
|
||||
// path: "/centerHome",
|
||||
// name: "centerHome",
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/index"),
|
||||
// meta: { title: "预警中心大屏", icon: "article-create" },
|
||||
// },
|
||||
// {
|
||||
// path: "/warningBk",
|
||||
// name: "warningBk",
|
||||
// meta: { title: "布控预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/warningBk/index"),
|
||||
// },
|
||||
{
|
||||
path: "/YjData",
|
||||
name: "YjData",
|
||||
@ -185,7 +213,8 @@ export const publicRoutes = [
|
||||
title: "警情信息",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/policeSituations",
|
||||
name: "policeSituations",
|
||||
component: () => import("@/views/backOfficeSystem/PoliceIncidentMonitoring/index.vue"),
|
||||
@ -196,107 +225,20 @@ export const publicRoutes = [
|
||||
},
|
||||
]
|
||||
},
|
||||
// {
|
||||
// path: "/fouColorWarning",
|
||||
// name: "fouColorWarning",
|
||||
// meta: { title: "预警数据整合", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/fouColorWarning/index"),
|
||||
// },
|
||||
// {
|
||||
// path: "/sevenWarning",
|
||||
// name: "sevenWarning",
|
||||
// meta: { title: "七类重点人员", icon: "article" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/sevenWarning/index.vue"),
|
||||
// },
|
||||
// {
|
||||
// path: "/identityWarning",
|
||||
// name: "identityWarning",
|
||||
// meta: { title: "身份预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/identityWarning/index"),
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: "/behaviorWarning",
|
||||
// name: "behaviorWarning",
|
||||
// meta: { title: "行为预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/behaviorWarning/index"),
|
||||
// },
|
||||
// {
|
||||
// path: "/combinedWarning",
|
||||
// name: "combinedWarning",
|
||||
// meta: { title: "组合预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/combinedWarning/index"),
|
||||
// },
|
||||
// {
|
||||
// path: "/warningList",
|
||||
// name: "warningList",
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningList/index"),
|
||||
// meta: {
|
||||
// title: "布控预警",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/portraitWarning",
|
||||
// name: "portraitWarning",
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningList/portraitWarning/index"),
|
||||
// meta: {
|
||||
// title: "人像预警",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: "/vehicleWarning",
|
||||
// name: "vehicleWarning",
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningList/vehicleWarning/index"),
|
||||
// meta: {
|
||||
// title: "车辆预警",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/controlWarning",
|
||||
// name: "controlWarning",
|
||||
// meta: { title: "布控预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/controlWarning/index"),
|
||||
// },
|
||||
// {
|
||||
// path: "/regionalControl",
|
||||
// name: "regionalControl",
|
||||
// meta: { title: "区域布控预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/regionalControl/index"),
|
||||
// },
|
||||
// {
|
||||
// path: "/fouColorWarning",
|
||||
// name: "fouColorWarning",
|
||||
// meta: { title: "四色预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/fouColorWarning/index"),
|
||||
// },
|
||||
{
|
||||
path: "/scoreRanking",
|
||||
name: "scoreRanking",
|
||||
meta: { title: "积分排名", icon: "article-create" },
|
||||
component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/scoreRanking/index"),
|
||||
},
|
||||
|
||||
{
|
||||
path: "/sevenWarningFail",
|
||||
name: "sevenWarningFail",
|
||||
meta: { title: "报错列表", icon: "article" },
|
||||
component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/sevenWarningFail/index.vue"),
|
||||
},
|
||||
// {
|
||||
// path: "/modelWarning",
|
||||
// name: "modelWarning",
|
||||
// meta: { title: "模型预警", icon: "article-create" },
|
||||
// component: () => import("@/views/backOfficeSystem/fourColorManage/warningControl/modelWarning/index"),
|
||||
// },
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: "/IntelligentControl",
|
||||
name: "IntelligentControl",
|
||||
@ -329,7 +271,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/marksControl",
|
||||
name: "marksControl",
|
||||
@ -339,7 +280,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/ReviewListControl",
|
||||
name: "ReviewListControl",
|
||||
@ -349,26 +289,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// {
|
||||
// path: "/DeploymentAudit",
|
||||
// name: "DeploymentAudit",
|
||||
// component: () => import("@/views/backOfficeSystem/IntelligentControl/DeploymentAudit/index"),
|
||||
// meta: {
|
||||
// title: "我的审核",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/ControlApproval",
|
||||
// name: "ControlApproval",
|
||||
// component: () => import("@/views/backOfficeSystem/IntelligentControl/ControlApproval/index"),
|
||||
// meta: {
|
||||
// title: "我的审批",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// }
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -393,29 +313,13 @@ export const publicRoutes = [
|
||||
name: "openSourceList",
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/listView/index"),
|
||||
meta: { title: "共享列表", icon: "article-create", qbjbList: '01' },
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/auditList",
|
||||
name: "auditList",
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/auditList/index"),
|
||||
meta: { title: "审批列表", icon: "article-create" },
|
||||
},
|
||||
// {
|
||||
// path: "/socialInformationCrculated",
|
||||
// name: "changeTheClue",
|
||||
// component: () => import("@/views/backOfficeSystem/HumanIntelligence/FollowLeads/index"),
|
||||
// meta: { title: "转线索列表", icon: "article-create" },
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: "/CollectPoints",
|
||||
// name: "CollectPoints",
|
||||
// component: () => import("@/views/backOfficeSystem/HumanIntelligence/CollectPoints/index"),
|
||||
// meta: {
|
||||
// title: "采集积分",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
|
||||
{
|
||||
path: "/supplementReportList",
|
||||
name: "supplementReportList",
|
||||
@ -434,24 +338,15 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/InformationReporting",
|
||||
// name: "InformationReporting",
|
||||
// component: () => import("@/views/backOfficeSystem/InformationReporting/index.vue"),
|
||||
// meta: {
|
||||
// title: "蜂群信息",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/MakeAcomment",
|
||||
// name: "MakeAcomment",
|
||||
// component: () => import("@/views/backOfficeSystem/MakeAcomment/index"),
|
||||
// meta: {
|
||||
// title: "情报评一评",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// }
|
||||
{
|
||||
path: "/InformationReporting",
|
||||
name: "InformationReporting",
|
||||
component: () => import("@/views/backOfficeSystem/InformationReporting/index.vue"),
|
||||
meta: {
|
||||
title: "蜂群信息",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -471,19 +366,6 @@ export const publicRoutes = [
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/lamXs/index"),
|
||||
meta: { title: "林安码线索", icon: "article" },
|
||||
},
|
||||
|
||||
|
||||
// 暂时不要
|
||||
// {
|
||||
// path: "/MoralAnalysis",
|
||||
// name: "MoralAnalysis",
|
||||
// component: () => import("@/views/backOfficeSystem/ResearchJudgment/MoralAnalysis/index"),
|
||||
// meta: {
|
||||
// title: "情报语义分析",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
|
||||
{
|
||||
path: "/InstructionInformation",
|
||||
name: "InstructionInformation",
|
||||
@ -493,21 +375,8 @@ export const publicRoutes = [
|
||||
icon: "article"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/InformationFlows",
|
||||
// name: "InformationFlows",
|
||||
// meta: { title: "情报流转", icon: "article-create" },
|
||||
// // redirect: "/InformationFlow",
|
||||
// // children: [
|
||||
|
||||
|
||||
// // ]
|
||||
// },
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: "/JudgmentHome",
|
||||
name: "JudgmentHome",
|
||||
@ -517,7 +386,6 @@ export const publicRoutes = [
|
||||
icon: "article-ranking"
|
||||
},
|
||||
children: [
|
||||
|
||||
{
|
||||
path: "/policeManagement",
|
||||
name: "policeManagement",
|
||||
@ -545,16 +413,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/situationHome",
|
||||
// name: "situationHome",
|
||||
// component: () => import("@/views/backOfficeSystem/JudgmentHome/situationHome/index"),
|
||||
// meta: {
|
||||
// title: "战略研判",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// 后面写的研判
|
||||
{
|
||||
path: "/strategicResearchs",
|
||||
name: "strategicResearchs",
|
||||
@ -591,15 +449,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/analysisReport",
|
||||
// name: "AnalysisReport",
|
||||
// component: () => import("@/views/backOfficeSystem/AnalysisReport/index"),
|
||||
// meta: {
|
||||
// title: "研判报告",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
{
|
||||
path: "/MeetingRoom",
|
||||
name: "MeetingRoom",
|
||||
@ -647,7 +496,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/mpvGroup",
|
||||
name: "mpvGroup",
|
||||
@ -657,7 +505,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/mpvCar",
|
||||
name: "mpvCar",
|
||||
@ -676,24 +523,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/mpvPeoSh",
|
||||
// name: "mpvPeoSh",
|
||||
// component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvPeoSh/index"),
|
||||
// meta: {
|
||||
// title: "重点人审批",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/mpvGroupSh",
|
||||
// name: "mpvGroupSh",
|
||||
// component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvGroupSh/index"),
|
||||
// meta: {
|
||||
// title: "重点群体审核",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -714,7 +543,8 @@ export const publicRoutes = [
|
||||
name: "goingJob",
|
||||
meta: { title: "工作情况", icon: "article-ranking" },
|
||||
component: () => import("@/views/backOfficeSystem/goingJob/index.vue")
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/workLogInfo",
|
||||
name: "workLogInfo",
|
||||
meta: { title: "值班信息", icon: "article-ranking" },
|
||||
@ -722,80 +552,15 @@ export const publicRoutes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: "/Cspz",
|
||||
name: "Cspz",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/fourColorManage/Cspz/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/fourColorManage/Cspz/index"),
|
||||
meta: {
|
||||
title: "参数配置",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
// {
|
||||
// path: "/IntegralCoefficient",
|
||||
// name: "IntegralCoefficient",
|
||||
// component: () =>
|
||||
// import(
|
||||
// "@/views/backOfficeSystem/fourColorManage/IntegralCoefficient/index"
|
||||
// ),
|
||||
// meta: {
|
||||
// title: "积分系数配置",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: "/IdentityManage",
|
||||
// name: "IdentityManage",
|
||||
// component: () =>
|
||||
// import(
|
||||
// "@/views/backOfficeSystem/fourColorManage/IdentityManage/index"
|
||||
// ),
|
||||
// meta: {
|
||||
// title: "身份标签管理",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/BehaviorLabels",
|
||||
// name: "BehaviorLabels",
|
||||
// component: () =>
|
||||
// import(
|
||||
// "@/views/backOfficeSystem/fourColorManage/BehaviorLabels/index"
|
||||
// ),
|
||||
// meta: {
|
||||
// title: "行为标签管理",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/tagManage",
|
||||
// name: "tagManage",
|
||||
// component: () =>
|
||||
// import(
|
||||
// "@/views/backOfficeSystem/fourColorManage/tagManage/index"
|
||||
// ),
|
||||
// meta: {
|
||||
// title: "标签组合管理",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/tsypHome",
|
||||
// name: "tsypHome",
|
||||
// component: () => import("@/views/backOfficeSystem/JudgmentHome/tsypHome/index"),
|
||||
// meta: {
|
||||
// title: "模型管理",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
|
||||
{
|
||||
path: "/permissionApply",
|
||||
name: "permissionApply",
|
||||
@ -814,7 +579,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/FileData",
|
||||
name: "FileData",
|
||||
@ -824,24 +588,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/fileTransfer",
|
||||
// name: "fileTransfer",
|
||||
// component: () => import("@/views/backOfficeSystem/HumanIntelligence/fileTransfer/index"),
|
||||
// meta: {
|
||||
// title: "文件中转",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/fileOrientation",
|
||||
// name: "fileOrientation",
|
||||
// component: () => import("@/views/backOfficeSystem/HumanIntelligence/fileOrientation/index"),
|
||||
// meta: {
|
||||
// title: "点对点",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
{
|
||||
path: "/ssemanticAnalysis",
|
||||
name: "semanticAnalysis",
|
||||
@ -868,7 +614,8 @@ export const publicRoutes = [
|
||||
title: "操作记录",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/dataMonitor",
|
||||
name: "dataMonitor",
|
||||
meta: { title: "数据监控", icon: "article-ranking" },
|
||||
@ -895,66 +642,9 @@ export const publicRoutes = [
|
||||
},
|
||||
]
|
||||
},
|
||||
// {
|
||||
// path: "/BasicManagement",
|
||||
// name: "BasicManagement",
|
||||
// meta: {
|
||||
// title: "基础管理",
|
||||
// icon: "article-create"
|
||||
// },
|
||||
// children: [
|
||||
|
||||
// // {
|
||||
// // path: "/surveillanceControl",
|
||||
// // name: "surveillanceControl",
|
||||
// // component: () =>
|
||||
// // import(
|
||||
// // "@/views/backOfficeSystem/BasicManagement/surveillanceControl/index"
|
||||
// // ),
|
||||
// // meta: {
|
||||
// // title: "布控监视",
|
||||
// // icon: "article-create"
|
||||
// // }
|
||||
// // },
|
||||
// // {
|
||||
// // path: "/experienceShare",
|
||||
// // name: "experienceShare",
|
||||
// // component: () =>
|
||||
// // import("@/views/backOfficeSystem/BasicManagement/experienceShare/index"),
|
||||
// // meta: {
|
||||
// // title: "经验分享",
|
||||
// // icon: "article-create"
|
||||
// // }
|
||||
// // },
|
||||
|
||||
|
||||
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// path: "/forumPost2",
|
||||
// name: "forumPost2",
|
||||
// component: () => import("@/views/forumPost/index.vue"),
|
||||
// meta: {
|
||||
// title: "情报论坛",
|
||||
// icon: "article-ranking"
|
||||
// }
|
||||
// },
|
||||
{
|
||||
path: "/forumPost",
|
||||
name: "forumPost",
|
||||
component: () => import("@/views/backOfficeSystem/luntan/index.vue"),
|
||||
meta: {
|
||||
title: "情报论坛",
|
||||
icon: "article-ranking"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/systemConfig",
|
||||
// component: layout,
|
||||
name: "systemConfigModel",
|
||||
// redirect: "/dict/index",
|
||||
meta: {
|
||||
title: "系统管理",
|
||||
icon: "article-ranking"
|
||||
@ -969,12 +659,10 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/user/userList",
|
||||
name: "userList",
|
||||
component: () =>
|
||||
import("@/views/backOfficeSystem/systemConfig/user-list/index"),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/user-list/index"),
|
||||
meta: {
|
||||
title: "用户管理",
|
||||
icon: "article-create"
|
||||
@ -983,8 +671,7 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/user/role",
|
||||
name: "userRoleIndex",
|
||||
component: () =>
|
||||
import("@/views/backOfficeSystem/systemConfig/role-list/index"),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/role-list/index"),
|
||||
meta: {
|
||||
title: "角色列表",
|
||||
icon: "article-create"
|
||||
@ -993,19 +680,16 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/user/menuList",
|
||||
name: "menuList",
|
||||
component: () =>
|
||||
import("@/views/backOfficeSystem/systemConfig/menu-list/index"),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/menu-list/index"),
|
||||
meta: {
|
||||
title: "菜单管理",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/dict/detail",
|
||||
name: "dictDetail",
|
||||
component: () =>
|
||||
import("@/views/backOfficeSystem/systemConfig/dict/detail"),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/dict/detail"),
|
||||
meta: {
|
||||
title: "字典数据"
|
||||
}
|
||||
@ -1013,21 +697,16 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/dict/index",
|
||||
name: "dictIndex",
|
||||
component: () =>
|
||||
import("@/views/backOfficeSystem/systemConfig/dict/index"),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/dict/index"),
|
||||
meta: {
|
||||
title: "字典列表",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/user/deptAllocationUser/:id",
|
||||
name: "deptAllocationUser",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/systemConfig/department-list/deptAllocationUser"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/department-list/deptAllocationUser"),
|
||||
meta: {
|
||||
title: "管理用户"
|
||||
}
|
||||
@ -1035,27 +714,21 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/user/allocationUser/:id",
|
||||
name: "allocationUser",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/systemConfig/role-list/allocationUser"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/role-list/allocationUser"),
|
||||
meta: {
|
||||
title: "分配用户"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/user/systemConfig",
|
||||
name: "systemConfig",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/systemConfig/system-config-list/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/systemConfig/system-config-list/index"),
|
||||
meta: {
|
||||
title: "系统配置",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/calendar",
|
||||
name: "calendar",
|
||||
component: () => import("@/views/backOfficeSystem/calendar/index.vue"),
|
||||
@ -1112,26 +785,20 @@ export const publicRoutes = [
|
||||
name: "CollectCrculate",
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/CollectCrculate/index"),
|
||||
meta: { title: "情报采集", icon: "article-create" },
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/RlStatisticalAnalysis",
|
||||
name: "RlStatisticalAnalysis",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/HumanIntelligence/RlStatisticalAnalysis/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/RlStatisticalAnalysis/index"),
|
||||
meta: {
|
||||
title: "上报统计分析",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/TaskScheduling",
|
||||
name: "TaskScheduling",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/HumanIntelligence/TaskScheduling/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/TaskScheduling/index"),
|
||||
meta: {
|
||||
title: "上报任务调度",
|
||||
icon: "article-create"
|
||||
@ -1140,10 +807,7 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/ConstructionManagement",
|
||||
name: "ConstructionManagement",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/HumanIntelligence/ConstructionManagement/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/ConstructionManagement/index"),
|
||||
meta: {
|
||||
title: "力量建设管理",
|
||||
icon: "article-create"
|
||||
@ -1190,14 +854,10 @@ export const publicRoutes = [
|
||||
name: "ExcavationResearch",
|
||||
meta: { title: "重点人发掘", icon: "article-ranking" },
|
||||
children: [
|
||||
|
||||
{
|
||||
path: "/PreliminaryExcavations",
|
||||
name: "PreliminaryExcavations",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/ExcavationResearch/PreliminaryExcavations/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/ExcavationResearch/PreliminaryExcavations/index"),
|
||||
meta: {
|
||||
title: "重点人员初步发掘",
|
||||
icon: "article-create"
|
||||
@ -1206,10 +866,7 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/ZdryFjyp",
|
||||
name: "ZdryFjyp",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/ExcavationResearch/ZdryFjyp/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/ExcavationResearch/ZdryFjyp/index"),
|
||||
meta: {
|
||||
title: "重点人员深度发掘",
|
||||
icon: "article-create"
|
||||
@ -1218,15 +875,13 @@ export const publicRoutes = [
|
||||
{
|
||||
path: "/LandingAudit",
|
||||
name: "LandingAudit",
|
||||
component: () =>
|
||||
import(
|
||||
"@/views/backOfficeSystem/ExcavationResearch/LandingAudit/index"
|
||||
),
|
||||
component: () => import("@/views/backOfficeSystem/ExcavationResearch/LandingAudit/index"),
|
||||
meta: {
|
||||
title: "重点人员落地审核",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/tacticalResearch",
|
||||
name: "tacticalResearch",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/tacticalResearch/index.vue"),
|
||||
@ -1245,7 +900,8 @@ export const publicRoutes = [
|
||||
}
|
||||
},
|
||||
]
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/tacticalResearch",
|
||||
name: "tacticalResearch",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/tacticalResearch/index.vue"),
|
||||
@ -1254,7 +910,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/strategicResearch",
|
||||
name: "strategicResearch",
|
||||
@ -1273,41 +928,26 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/ResearchHome",
|
||||
// name: "ResearchHome",
|
||||
// component: () => import("@/views/backOfficeSystem/JudgmentHome/ResearchHome/index"),
|
||||
// meta: {
|
||||
// title: "战术研判",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/situationHome",
|
||||
// name: "situationHome",
|
||||
// component: () => import("@/views/backOfficeSystem/JudgmentHome/situationHome/index"),
|
||||
// meta: {
|
||||
// title: "战略研判",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// 创建路由实例,只注册公开路由
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: publicRoutes
|
||||
});
|
||||
//初始化路由表
|
||||
|
||||
// 重置路由(退出登录时调用)
|
||||
export function resetRouter() {
|
||||
if (store.getters?.routeReady && store.getters?.userInfo?.permission?.menus) {
|
||||
const menus = store.getters.userInfo.permission.menus;
|
||||
menus.forEach((menu) => {
|
||||
router.removeRoute(menu);
|
||||
// 移除所有动态添加的路由
|
||||
router.getRoutes().forEach(route => {
|
||||
if (route.name && !publicRoutes.find(r => r.name === route.name)) {
|
||||
router.removeRoute(route.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default router;
|
||||
|
||||
@ -1,23 +1,60 @@
|
||||
// 专门处理权限路由的模块
|
||||
import router from '@/router'
|
||||
import { publicRoutes, privateRoutes } from '@/router'
|
||||
|
||||
/**
|
||||
* 递归过滤路由(保留 component 引用)
|
||||
* 规则:
|
||||
* 1. 如果路由有 name 且在权限列表中,保留
|
||||
* 2. 如果路由没有 name 但有子路由,检查子路由是否有权限
|
||||
* 3. 子路由有权限时保留父路由
|
||||
*
|
||||
* @param {Array} data - 路由数据
|
||||
* @param {Array} menus - 菜单权限码集合
|
||||
* @returns {Array} - 过滤后的路由
|
||||
*/
|
||||
function filter(data, menus) {
|
||||
var newData = data.filter(x => menus?.includes(x.name))
|
||||
newData.forEach(x => x.children && (x.children = filter(x.children, menus)))
|
||||
return newData
|
||||
const result = []
|
||||
|
||||
data.forEach(route => {
|
||||
// 创建新路由对象,保留原有属性(包括 component)
|
||||
const newRoute = { ...route }
|
||||
|
||||
// 如果有 name 且在权限列表中,保留此路由
|
||||
if (route.name && menus?.includes(route.name)) {
|
||||
// 递归处理子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
newRoute.children = filter(route.children, menus)
|
||||
}
|
||||
result.push(newRoute)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果没有 name 但有 children,检查子路由是否有权限
|
||||
if (!route.name && route.children && route.children.length > 0) {
|
||||
const filteredChildren = filter(route.children, menus)
|
||||
// 只要子路由有匹配项,就保留父路由
|
||||
if (filteredChildren.length > 0) {
|
||||
newRoute.children = filteredChildren
|
||||
result.push(newRoute)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
routes: [],// 路由表:初始拥有静态路由权限
|
||||
routeReady: 0
|
||||
routes: [], // 最终路由表:公开路由 + 有权限的私有路由
|
||||
routeReady: 0 // 0: 未开始, 1: 进行中, 2: 完成
|
||||
},
|
||||
mutations: {
|
||||
/**
|
||||
* 增加路由
|
||||
* 设置路由
|
||||
*/
|
||||
setRoutes(state, newRoutes) {
|
||||
// 永远在静态路由的基础上增加新路由
|
||||
state.routes = [...publicRoutes, ...newRoutes]
|
||||
},
|
||||
setRouteReady(state, num) {
|
||||
@ -32,9 +69,14 @@ export default {
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 根据权限筛选路由
|
||||
* 根据权限过滤并动态注册路由
|
||||
* @param {Object} context - Vuex context
|
||||
* @param {Array} menus - 用户菜单权限码集合
|
||||
*/
|
||||
filterRoutes(context, menus) {
|
||||
// 开始处理,标记为进行中
|
||||
context.commit('setRouteReady', 1);
|
||||
|
||||
let routes = []
|
||||
|
||||
/**
|
||||
@ -45,16 +87,36 @@ export default {
|
||||
routes = filter(privateRoutes, menus)
|
||||
}
|
||||
|
||||
// 最后添加 不匹配路由进入 404
|
||||
routes.push({
|
||||
// ★★★ 关键:动态添加路由到 Vue Router ★★★
|
||||
routes.forEach(route => {
|
||||
router.addRoute(route)
|
||||
})
|
||||
|
||||
// 404 兜底路由必须最后添加(否则动态路由会匹配到 404)
|
||||
router.addRoute({
|
||||
path: '/:catchAll(.*)',
|
||||
redirect: '/404'
|
||||
})
|
||||
|
||||
context.commit('setRoutes', routes);
|
||||
context.commit('setRouteReady', 1);
|
||||
// 处理完成,标记为已完成
|
||||
context.commit('setRouteReady', 2);
|
||||
|
||||
return routes
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置路由(退出登录时调用)
|
||||
*/
|
||||
resetRoutes(context) {
|
||||
// 移除所有动态添加的路由
|
||||
router.getRoutes().forEach(route => {
|
||||
if (route.name && !publicRoutes.find(r => r.name === route.name)) {
|
||||
router.removeRoute(route.name);
|
||||
}
|
||||
});
|
||||
context.commit('deleteRouter');
|
||||
context.commit('resetrouteReady');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,27 +5,14 @@ import {
|
||||
refreshToken,
|
||||
loginOut
|
||||
} from "@/api/sys";
|
||||
import {
|
||||
unifiedLogin
|
||||
} from "@/api/user-manage";
|
||||
import { unifiedLogin } from "@/api/user-manage";
|
||||
import Base64 from "base-64";
|
||||
import {
|
||||
setItem,
|
||||
getItem,
|
||||
removeAllItem
|
||||
} from "@/utils/storage";
|
||||
import {
|
||||
TOKEN
|
||||
} from "@/constant";
|
||||
import router, {
|
||||
resetRouter
|
||||
} from "@/router";
|
||||
import {
|
||||
setTimeStamp
|
||||
} from "@/utils/auth";
|
||||
import {
|
||||
TAGS_VIEW
|
||||
} from "@/constant/index.js";
|
||||
import { setItem, getItem, removeAllItem } from "@/utils/storage";
|
||||
import { TOKEN } from "@/constant";
|
||||
import router, { resetRouter } from "@/router";
|
||||
import { setTimeStamp } from "@/utils/auth";
|
||||
import { TAGS_VIEW } from "@/constant/index.js";
|
||||
import { resetRoutesInit } from "@/permission";
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: () => ({
|
||||
@ -37,7 +24,7 @@ export default {
|
||||
isReady: 0,
|
||||
userName: getItem("USERNAME") || "",
|
||||
keepLiiveRoute: [], //需要缓存的路由
|
||||
activeId: '',//警组点击的唯一标识
|
||||
activeId: "" //警组点击的唯一标识
|
||||
}),
|
||||
mutations: {
|
||||
setToken(state, token) {
|
||||
@ -69,14 +56,16 @@ export default {
|
||||
},
|
||||
//保存路由
|
||||
setKeepLiiveRoute(state, val) {
|
||||
// state.keepLiiveRoute.push(val);
|
||||
if (!state.keepLiiveRoute.includes(val)) {
|
||||
state.keepLiiveRoute.push(val);
|
||||
}
|
||||
},
|
||||
//删除缓存路由
|
||||
deleteKeepLiiveRoute(state, val) {
|
||||
// state.keepLiiveRoute = state.keepLiiveRoute.filter((item) => {
|
||||
// return item != val;
|
||||
// });
|
||||
},
|
||||
state.keepLiiveRoute = state.keepLiiveRoute.filter((item) => {
|
||||
return item != val;
|
||||
});
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
/*
|
||||
@ -85,14 +74,20 @@ export default {
|
||||
login(ctx, userInfo) {
|
||||
const { userName, password, kaptcha } = userInfo;
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ userName, password: Base64.encode(password), kaptcha }).then((data) => {
|
||||
login({
|
||||
userName,
|
||||
password: Base64.encode(password),
|
||||
kaptcha,
|
||||
ssxt: "sgxt"
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.deptList.length === 1) {
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setDeptId", data.deptList);
|
||||
this.commit("user/setUserName", data.userName);
|
||||
setItem('isOatuh', 0)
|
||||
setItem('fzUserId', data.fzUserId)
|
||||
setItem('inDustRialId', data.inDustRialId)
|
||||
setItem("isOatuh", 0);
|
||||
setItem("fzUserId", data.fzUserId);
|
||||
setItem("inDustRialId", data.inDustRialId);
|
||||
setItem("USERNAME", data.userName);
|
||||
setItem("roleList", data.sysRole ? data.sysRole : []);
|
||||
setItem("SFRH", data.sfrh);
|
||||
@ -124,22 +119,22 @@ export default {
|
||||
*单点登录
|
||||
*/
|
||||
oatuhLogin(ctx, userInfo) {
|
||||
const { token, systemId, } = userInfo;
|
||||
const { token, systemId } = userInfo;
|
||||
return new Promise((resolve, reject) => {
|
||||
unifiedLogin({ token, systemId }).then((data) => {
|
||||
unifiedLogin({ token, systemId, ssxt: "sgxt" }).then((data) => {
|
||||
if (data.deptList.length === 1) {
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setDeptId", data.deptList);
|
||||
this.commit("user/setUserName", data.userName);
|
||||
setItem("USERNAME", data.userName);
|
||||
setItem('fzUserId', data.fzUserId)
|
||||
setItem('inDustRialId', data.inDustRialId)
|
||||
setItem("fzUserId", data.fzUserId);
|
||||
setItem("inDustRialId", data.inDustRialId);
|
||||
setItem("SFRH", data.sfrh);
|
||||
setItem("USERID", data.userId);
|
||||
setItem("PermissionsInfo", data.permissionsInfo);
|
||||
this.commit("user/setMenuList", data.menuList);
|
||||
setItem("menusPermission", data.menuCodeSet);
|
||||
setItem('isOatuh', 1)
|
||||
setItem("isOatuh", 1);
|
||||
setItem("idEntityCard", data.idEntityCard);
|
||||
this.commit("user/setUserInfo", {
|
||||
token: data.jwtToken,
|
||||
@ -154,8 +149,7 @@ export default {
|
||||
// 保存登录时间
|
||||
setTimeStamp();
|
||||
resolve(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
}).catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
@ -215,20 +209,20 @@ export default {
|
||||
async logout(ctx) {
|
||||
const res = await loginOut();
|
||||
if (res) {
|
||||
// 重置动态路由
|
||||
resetRouter();
|
||||
// 重置路由守卫初始化标记
|
||||
resetRoutesInit();
|
||||
// 清除权限模块状态
|
||||
this.dispatch("permission/resetRoutes");
|
||||
// 清除用户状态
|
||||
this.commit("user/setToken", "");
|
||||
this.commit("user/setUserName", "admin");
|
||||
this.commit("user/setUserInfo", {});
|
||||
this.commit("permission/resetrouteReady", 0);
|
||||
const isOatuh = getItem('isOatuh')
|
||||
this.commit("permission/deleteRouter");
|
||||
// 清除本地存储
|
||||
removeAllItem();
|
||||
// 待补充 清理权限相关的配置
|
||||
// if (isOatuh) {
|
||||
// 跳转到统一门户
|
||||
window.location.href = `https://tyyy.lz.dsj.xz/portal/home`;
|
||||
// } else {
|
||||
// router.push("/login");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,34 +43,50 @@ service.interceptors.response.use(
|
||||
(response) => {
|
||||
const { success, code, msg, message, data, model } = response.data;
|
||||
// 需要判断当前请求是否成功
|
||||
if (success && code === 10000) {
|
||||
return data || [null,0,undefined,''].includes(data) ? data : response.data; // 成功后返回解析后的数据
|
||||
// return data ? data : response.data; // // 成功后返回解析后的数据
|
||||
if (code == 403 || code == 402) {
|
||||
ElMessage({ message: message || msg || '登录已过期,请关闭浏览器,重新登录', grouping: true, type: 'error' });
|
||||
} else if (success && code === 10000) {
|
||||
return data || [null, 0, undefined, ''].includes(data) ? data : response.data;
|
||||
} else if (code === 200 || code == "00000" || code == "10000" || msg == 'success' || model || response.data.success == true) {
|
||||
return data || [null,0,undefined,''].includes(data) ? data : response.data; // 成功后返回解析后的数据
|
||||
// return data ? data : response.data; // // 成功后返回解析后的数据
|
||||
return data || [null, 0, undefined, ''].includes(data) ? data : response.data;
|
||||
} else if (code === 401) {
|
||||
store.dispatch('user/logout');
|
||||
ElMessage.error(message); // 提示错误信息
|
||||
ElMessage({ message: message || msg, grouping: true, type: 'error' })
|
||||
ElMessage({ message: message || msg || '登录已过期,请重新登录', grouping: true, type: 'error' });
|
||||
return Promise.reject(new Error('登录已过期'));
|
||||
} else {
|
||||
// 失败(请求成功,业务失败)弹出消息提示
|
||||
ElMessage({ message: message || msg, grouping: true, type: 'error' })
|
||||
return Promise.reject(new Error(message + '数据格式错误'));
|
||||
ElMessage({ message: message || msg || '请求失败', grouping: true, type: 'error' });
|
||||
return Promise.reject(new Error(message || msg || '数据格式错误'));
|
||||
}
|
||||
},
|
||||
// 请求失败处理
|
||||
// 请求失败处理(网络错误、服务器错误等)
|
||||
(error) => {
|
||||
// token过期
|
||||
if (
|
||||
error.response &&
|
||||
error.response.data &&
|
||||
error.response.data.code === 401
|
||||
) {
|
||||
console.log("Xxxxx");
|
||||
|
||||
if (error.response && error.response.data && error.response.data.code === 401) {
|
||||
store.dispatch('user/logout');
|
||||
ElMessage({ message: '登录已过期,请重新登录', grouping: true, type: 'error' });
|
||||
} else if (error.response) {
|
||||
// 服务器返回了错误响应(500、404、403等)
|
||||
const status = error.response.status;
|
||||
const msg = error.response.data?.message || error.response.data?.msg;
|
||||
if (status === 500) {
|
||||
ElMessage({ message: msg || '服务器内部错误', grouping: true, type: 'error' });
|
||||
} else if (status === 404) {
|
||||
ElMessage({ message: msg || '请求资源不存在', grouping: true, type: 'error' });
|
||||
} else if (status === 403) {
|
||||
ElMessage({ message: msg || '没有权限访问', grouping: true, type: 'error' });
|
||||
} else {
|
||||
ElMessage({ message: msg || `请求错误(${status})`, grouping: true, type: 'error' });
|
||||
}
|
||||
} else if (error.code === 'ECONNABORTED') {
|
||||
// 请求超时
|
||||
ElMessage({ message: '请求超时,请稍后重试', grouping: true, type: 'error' });
|
||||
} else {
|
||||
// 网络错误或其他错误
|
||||
ElMessage({ message: error.message || '网络连接异常', grouping: true, type: 'error' });
|
||||
}
|
||||
// 关键:返回 Promise.reject,让调用方能捕获到错误
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -5,69 +5,40 @@ import { getItem } from '@/utils/storage'
|
||||
*/
|
||||
const getChildrenRoutes = (routes) => {
|
||||
const result = [];
|
||||
const { deptBizType, deptLevel } = getItem('deptId')[0]
|
||||
const roleList = getItem('roleList') ? getItem('roleList').filter(item => item.roleCode == 'JS_666666').length > 0 : false
|
||||
const xjLsit = getItem('roleList') ? getItem('roleList').filter(item => item.roleCode == 'JS_999999').length > 0 : false
|
||||
console.log(roleList, xjLsit);
|
||||
const deptIdData = getItem('deptId');
|
||||
const deptInfo = deptIdData && deptIdData.length > 0 ? deptIdData[0] : {};
|
||||
const deptBizType = deptInfo.deptBizType || '';
|
||||
const deptLevel = deptInfo.deptLevel || '';
|
||||
const roleListData = getItem('roleList') || [];
|
||||
const roleList = roleListData.filter(item => item.roleCode == 'JS_666666').length > 0;
|
||||
const xjLsit = roleListData.filter(item => item.roleCode == 'JS_999999').length > 0;
|
||||
|
||||
// 需要从子路由中排除的路径
|
||||
const excludePaths = ['/internalAuditor', '/auditList'];
|
||||
// deptBizType 为 23 且有特定角色时,不排除 /auditList
|
||||
const excludePathsForBiz23WithRole = ['/internalAuditor'];
|
||||
|
||||
routes.forEach((route) => {
|
||||
if (route.children && route.children.length > 0) {
|
||||
let filteredChildren;
|
||||
|
||||
if (deptBizType == '23') {
|
||||
|
||||
if (roleList) {
|
||||
result.push(...route.children);
|
||||
// 有 JS_666666 角色:不排除任何路由
|
||||
filteredChildren = route.children;
|
||||
} else if (xjLsit) {
|
||||
if (route.path == '/JudgmentHome') {
|
||||
route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
|
||||
result.push(...route.children);
|
||||
// 有 JS_999999 角色:只排除 /internalAuditor
|
||||
filteredChildren = route.children.filter(child => !excludePathsForBiz23WithRole.includes(child.path));
|
||||
} else {
|
||||
result.push(...route.children);
|
||||
// 其他:排除 /internalAuditor 和 /auditList
|
||||
filteredChildren = route.children.filter(child => !excludePaths.includes(child.path));
|
||||
}
|
||||
} else {
|
||||
if (route.path == '/HumanIntelligence') {
|
||||
route.children.splice(route.children.findIndex(item => item.path == '/auditList'), 1)
|
||||
result.push(...route.children);
|
||||
} else {
|
||||
result.push(...route.children);
|
||||
}
|
||||
if (route.path == '/JudgmentHome') {
|
||||
route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
|
||||
result.push(...route.children);
|
||||
} else {
|
||||
result.push(...route.children);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (route.path == '/HumanIntelligence') {
|
||||
route.children.splice(route.children.findIndex(item => item.path == '/auditList'), 1)
|
||||
result.push(...route.children);
|
||||
} else {
|
||||
result.push(...route.children);
|
||||
}
|
||||
if (route.path == '/JudgmentHome') {
|
||||
route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
|
||||
result.push(...route.children);
|
||||
} else {
|
||||
result.push(...route.children);
|
||||
}
|
||||
// 非 23 类型:排除 /internalAuditor 和 /auditList
|
||||
filteredChildren = route.children.filter(child => !excludePaths.includes(child.path));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// if (deptBizType == '23' && (roleList || xjLsit)) {
|
||||
// // 在这个条件分支中也需要过滤掉/internalAuditor路由
|
||||
// result.push(...route.children);
|
||||
// } else {
|
||||
|
||||
|
||||
// if (route.path == '/JudgmentHome' && xjLsit) {
|
||||
// route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
|
||||
// result.push(...route.children);
|
||||
// } else {
|
||||
// result.push(...route.children);
|
||||
// }
|
||||
// }
|
||||
result.push(...filteredChildren);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@ -82,6 +53,8 @@ export const filterRoutes = (routes) => {
|
||||
const childrenRoutes = getChildrenRoutes(routes);
|
||||
const data = routes.filter((route) => {
|
||||
//根据route在childrenRoutes中进行查重,把所有重复路由表 剔除
|
||||
// 但保留 forumPost 路由
|
||||
if (route.name === 'forumPost') return true;
|
||||
return !childrenRoutes.find((childrenRoute) => {
|
||||
return childrenRoute.path === route.path;
|
||||
});
|
||||
@ -135,5 +108,3 @@ export function generateMenus(routes, basePath = "") {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ const btns = ref(['重点人','重点群体'])
|
||||
const active = ref('重点人');
|
||||
const keywords = ref(''); // 搜索关键字
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDQT_ZT,D_BZ_RYBQ,D_GS_ZDQT_FXDJ } = proxy.$dict('D_GS_ZDQT_ZT','D_BZ_RYBQ','D_GS_ZDQT_FXDJ') //获取字典数据
|
||||
const { D_GS_ZDQT_ZT,/* D_BZ_RYBQ, */D_GS_ZDQT_FXDJ } = proxy.$dict('D_GS_ZDQT_ZT',/* 'D_BZ_RYBQ', */'D_GS_ZDQT_FXDJ') //获取字典数据
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
|
||||
@ -49,8 +49,16 @@ import { onMounted, getCurrentInstance, ref, reactive } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { setAddress } from '@/utils/tools'
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||
proxy.$dict("D_BZ_SF", "D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX"); //获取字典数据
|
||||
const {
|
||||
// D_BZ_SF,
|
||||
D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX,
|
||||
// D_GS_XS_QTLX
|
||||
} =
|
||||
proxy.$dict(
|
||||
// "D_BZ_SF",
|
||||
"D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX"
|
||||
// , "D_GS_XS_QTLX"
|
||||
); //获取字典数据
|
||||
|
||||
// 基础信息
|
||||
const basicInformation = ref(
|
||||
|
||||
@ -86,7 +86,22 @@ import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import { qcckGet, qcckPost,qcckDelete } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDQT_ZT,D_GS_ZDR_RYJB, D_BZ_XB,BD_BK_CLYJBQ, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = proxy.$dict("D_GS_ZDQT_ZT","D_GS_ZDR_RYJB","D_BZ_XB","D_BZ_MZ","D_BZ_XZQHDM","D_GS_ZDR_BK_ZT","D_GS_ZDR_CZZT","D_GS_BQ_ZL","D_GS_BQ_LB","D_GS_BQ_LX","D_GS_BK_SSJZ","D_GS_BK_SQLX","D_BZ_SF","D_GS_XS_LY","D_BZ_SSZT","D_GS_XS_LX","D_GS_XS_QTLX","BD_BK_CLYJBQ","D_GS_ZDR_YJDJ");
|
||||
const {
|
||||
D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, BD_BK_CLYJBQ, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ,
|
||||
// D_GS_BK_SQLX,
|
||||
// D_BZ_SF,
|
||||
// D_GS_XS_LY,
|
||||
// D_BZ_SSZT,
|
||||
// D_GS_XS_LX,
|
||||
// D_GS_XS_QTLX
|
||||
} = proxy.$dict("D_GS_ZDQT_ZT","D_GS_ZDR_RYJB","D_BZ_XB","D_BZ_MZ","D_BZ_XZQHDM","D_GS_ZDR_BK_ZT","D_GS_ZDR_CZZT","D_GS_BQ_ZL","D_GS_BQ_LB","D_GS_BQ_LX","D_GS_BK_SSJZ"
|
||||
// ,"D_GS_BK_SQLX"
|
||||
// ,"D_BZ_SF"
|
||||
// ,"D_GS_XS_LY"
|
||||
// ,"D_BZ_SSZT"
|
||||
// ,"D_GS_XS_LX"
|
||||
// ,"D_GS_XS_QTLX"
|
||||
,"BD_BK_CLYJBQ","D_GS_ZDR_YJDJ");
|
||||
const obj = ref({});
|
||||
const showzxs = ref(false);
|
||||
const zxsDilof = ref();
|
||||
|
||||
@ -65,7 +65,26 @@ import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import { getItem } from "@/utils/storage.js";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDR_CZZT,D_GS_BK_SQLX, D_GS_ZDQT_FXDJ, D_GS_ZDR_RYJB, D_GS_ZDQT_LB, D_GS_ZDR_BK_ZT, D_GS_BQ_LX, D_GS_ZDQT_ZT, D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = proxy.$dict("D_GS_ZDR_CZZT","D_GS_BK_SQLX", "D_GS_ZDQT_FXDJ", "D_GS_ZDR_RYJB", "D_GS_ZDQT_LB", "D_GS_ZDR_BK_ZT", "D_GS_BQ_LX", "D_GS_ZDQT_ZT", "D_BZ_SF", "D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX"); //获取字典数据
|
||||
const {
|
||||
D_GS_ZDR_CZZT,
|
||||
// D_GS_BK_SQLX,
|
||||
D_GS_ZDQT_FXDJ, D_GS_ZDR_RYJB, D_GS_ZDQT_LB, D_GS_ZDR_BK_ZT, D_GS_BQ_LX, D_GS_ZDQT_ZT,
|
||||
// D_BZ_SF,
|
||||
D_BZ_XB,
|
||||
// D_GS_XS_LY,
|
||||
// D_BZ_SSZT,
|
||||
// D_GS_XS_LX,
|
||||
// D_GS_XS_QTLX
|
||||
} = proxy.$dict("D_GS_ZDR_CZZT"
|
||||
// ,"D_GS_BK_SQLX"
|
||||
, "D_GS_ZDQT_FXDJ", "D_GS_ZDR_RYJB", "D_GS_ZDQT_LB", "D_GS_ZDR_BK_ZT", "D_GS_BQ_LX", "D_GS_ZDQT_ZT"
|
||||
// , "D_BZ_SF"
|
||||
, "D_BZ_XB"
|
||||
// , "D_GS_XS_LY"
|
||||
// , "D_BZ_SSZT"
|
||||
// , "D_GS_XS_LX"
|
||||
// , "D_GS_XS_QTLX"
|
||||
); //获取字典数据
|
||||
const showzxs = ref(false);
|
||||
const queryFrom = ref({});
|
||||
const ids = ref([]);
|
||||
|
||||
@ -74,8 +74,23 @@ import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
|
||||
import { getItem } from "@/utils/storage.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||
proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
||||
const {
|
||||
D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ,
|
||||
// D_GS_BK_SQLX,
|
||||
// D_BZ_SF,
|
||||
// D_GS_XS_LY,
|
||||
// D_BZ_SSZT,
|
||||
// D_GS_XS_LX,
|
||||
// D_GS_XS_QTLX
|
||||
} =
|
||||
proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ"
|
||||
// , "D_GS_BK_SQLX"
|
||||
// , "D_BZ_SF"
|
||||
// , "D_GS_XS_LY"
|
||||
// , "D_BZ_SSZT"
|
||||
// , "D_GS_XS_LX"
|
||||
// , "D_GS_XS_QTLX"
|
||||
);
|
||||
const obj = ref({});
|
||||
const show = ref(false);
|
||||
const addFormDiloag = ref();
|
||||
|
||||
@ -19,7 +19,7 @@ import { generateRandom10Digits } from '@/utils/tools'
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_ZFNR_MBLX } = proxy.$dict("D_ZFNR_MBLX")
|
||||
// const { D_ZFNR_MBLX } = proxy.$dict("D_ZFNR_MBLX") // 未使用,已注释
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
:class="activeSection === 'character-section' ? 'active' : ''">背景信息</li>
|
||||
<li @click="scrollToSection('controlInfo-section')"
|
||||
:class="activeSection === 'controlInfo-section' ? 'active' : ''" v-if="!butShow">管控信息</li>
|
||||
<li @click="scrollToSection('featinfo-section')"
|
||||
:class="activeSection === 'featinfo-section' ? 'active' : ''" v-if="!butShow">全要素布控</li>
|
||||
<li @click="scrollToSection('featinfo-section')" :class="activeSection === 'featinfo-section' ? 'active' : ''"
|
||||
v-if="!butShow">全要素布控</li>
|
||||
<li @click="scrollToSection('demandsInfo-section')"
|
||||
:class="activeSection === 'demandsInfo-section' ? 'active' : ''" v-if="!butShow">密切联系人</li>
|
||||
<li @click="scrollToSection('requestInfo-section')"
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
}"></Pages>
|
||||
</div>
|
||||
<!-- 详情 -->
|
||||
<AddForm ref="addFormDiloag" @updateDate="getList"
|
||||
<AddForm ref="addFormDiloag" @updateDate="getList" rylx="03"
|
||||
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
|
||||
<!-- 选择用户 -->
|
||||
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
|
||||
@ -87,15 +87,17 @@ import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import WarnDataTable from "@/views/backOfficeSystem/ces/components/WarnDataTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import AddForm from "./components/addForm.vue";
|
||||
// import AddForm from "./components/addForm.vue";
|
||||
import AddForm from "@/views/backOfficeSystem/DeploymentDisposal/mpvPeo/components/addForm.vue";
|
||||
// src\views\backOfficeSystem\DeploymentDisposal\mpvPeo\components\addForm.vue
|
||||
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_ZDRGK_GKZT, D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||
proxy.$dict('D_ZDRGK_GKZT', "D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
||||
const { D_ZDRGK_GKZT, D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||
proxy.$dict('D_ZDRGK_GKZT', "D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
||||
const obj = ref({});
|
||||
const showzxs = ref(false);
|
||||
const zxsDilof = ref();
|
||||
@ -160,7 +162,7 @@ const pageData = reactive({
|
||||
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true, slotName: "zdrBkZt", width: 100 },
|
||||
{ label: "审核状态", prop: "zdrZt", slotName: "zdrZt", width: 100 },
|
||||
{ label: "入库时间", prop: "zdrRkkssj", },
|
||||
{ label: "操作", prop: "controls", slotName: "controls", width: 280 },
|
||||
{ label: "操作", prop: "controls", slotName: "controls", width: 300 },
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ import { ref, getCurrentInstance, onMounted } from 'vue'
|
||||
import GdMap from "@/components/GdMap/index.vue";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_ZJLX } = proxy.$dict("D_BZ_ZJLX")
|
||||
// const { D_BZ_ZJLX } = proxy.$dict("D_BZ_ZJLX") // 未使用,已注释
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = ref({
|
||||
|
||||
@ -25,7 +25,7 @@ import CaseLodig from "../component/caseLodig.vue";
|
||||
import { tbGsxtZdryAjxxSaveOrUpdateAjxx, tbGsxtZdryAjxx, tbGsxtZdryAjxxselectAjxx } from '@/api/zdr.js'
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); //获取字典数据
|
||||
// const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); // 未使用,已注释
|
||||
const chooseMarksVisible = ref(false)
|
||||
const props = defineProps({
|
||||
dataList: {
|
||||
|
||||
@ -76,37 +76,37 @@ const chooseMarksVisible = ref(false); // 控制标签选择弹窗显示
|
||||
const roleIds = ref([]); // 已选择的标签ID
|
||||
const formData = ref([
|
||||
{ label: "人员照片", prop: "ryzp", type: "slot", width: "100%" },
|
||||
{ label: "姓名", prop: "ryXm", type: "input" },
|
||||
{ label: "性别", prop: "ryXb", type: "select", options: D_BZ_XB },
|
||||
{ label: "身份证号", prop: "rySfzh", type: "input" },
|
||||
{ label: "籍贯", prop: "ryJg", type: "select", options: D_BZ_XZQHDM },
|
||||
{ label: "曾用名", prop: "cym", type: "input" },
|
||||
{ label: "文化程度", prop: "whcdBm", type: "select", options: D_BZ_WHCD },
|
||||
{ label: "民族", prop: "ryMz", type: "select", options: D_BZ_MZ },
|
||||
{ label: "政治面貌", prop: "zzmm", type: "select", options: D_BZ_ZZMM },
|
||||
{ label: "职业", prop: "zyBm", type: "select", options: D_ZDRY_ZYLB },
|
||||
{ label: "人员级别", prop: "zdrRyjb", type: "select", options: D_GS_ZDR_RYJB },
|
||||
{ label: "预警等级", prop: "zdrYjdj", type: "select", options: D_GS_ZDR_YJDJ },
|
||||
{ label: "出生日期", prop: "ryCsrq", type: "date" },
|
||||
{ label: "户籍地区划", prop: "hjdQh", type: "select", options: D_BZ_XZQHDM },
|
||||
{ label: "户籍地详址", prop: "hjdXz", type: "input" },
|
||||
{ label: "户籍地派出所", prop: "hjdPcsdm",depMc:"hjdPcsmc" ,type: "department" },
|
||||
{ label: "现住地区划", prop: "xzdQh", type: "select", options: D_BZ_XZQHDM },
|
||||
{ label: "现住地详址", prop: "xzdXz", type: "input" },
|
||||
{ label: "现住地派出所", prop: "xzdPcsdm",depMc:"xzdPcsmc" ,type: "department" },
|
||||
{ label: "管辖单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department" },
|
||||
{ label: "诉求单位", prop: "sqSsbmdm", depMc: 'sqSsbmmc', type: "department" },
|
||||
{ label: "责任单位", prop: "zrSsbmdm", depMc: 'zrSsbmmc', type: "department" },
|
||||
{ label: "所属警种", prop: "zdrSsjz", type: "select", options: D_GS_BK_SSJZ },
|
||||
{ label: "涉及警种", prop: "zdrSjjz", type: "select", options: D_GS_BK_SSJZ, multiple: true },
|
||||
{ label: "婚姻状态", prop: "hyzk", type: "select", options: D_BZ_HYZK },
|
||||
{ label: "姓名", prop: "ryXm", type: "input", width: "30%" },
|
||||
{ label: "性别", prop: "ryXb", type: "select", options: D_BZ_XB, width: "30%" },
|
||||
{ label: "身份证号", prop: "rySfzh", type: "input", width: "30%" },
|
||||
{ label: "籍贯", prop: "ryJg", type: "select", options: D_BZ_XZQHDM, width: "30%" },
|
||||
{ label: "曾用名", prop: "cym", type: "input", width: "30%" },
|
||||
{ label: "文化程度", prop: "whcdBm", type: "select", options: D_BZ_WHCD, width: "30%" },
|
||||
{ label: "民族", prop: "ryMz", type: "select", options: D_BZ_MZ, width: "30%" },
|
||||
{ label: "政治面貌", prop: "zzmm", type: "select", options: D_BZ_ZZMM, width: "30%" },
|
||||
{ label: "职业", prop: "zyBm", type: "select", options: D_ZDRY_ZYLB, width: "30%" },
|
||||
{ label: "人员级别", prop: "zdrRyjb", type: "select", options: D_GS_ZDR_RYJB, width: "30%" },
|
||||
{ label: "预警等级", prop: "zdrYjdj", type: "select", options: D_GS_ZDR_YJDJ, width: "30%" },
|
||||
{ label: "出生日期", prop: "ryCsrq", type: "date", width: "30%" },
|
||||
{ label: "户籍地区划", prop: "hjdQh", type: "select", options: D_BZ_XZQHDM, width: "30%" },
|
||||
{ label: "户籍地详址", prop: "hjdXz", type: "input", width: "30%" },
|
||||
{ label: "户籍地派出所", prop: "hjdPcsdm", depMc: "hjdPcsmc", type: "department", width: "30%" },
|
||||
{ label: "现住地区划", prop: "xzdQh", type: "select", options: D_BZ_XZQHDM, width: "30%" },
|
||||
{ label: "现住地详址", prop: "xzdXz", type: "input", width: "30%" },
|
||||
{ label: "现住地派出所", prop: "xzdPcsdm", depMc: "xzdPcsmc", type: "department", width: "30%" },
|
||||
{ label: "管辖单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department", width: "30%" },
|
||||
{ label: "诉求单位", prop: "sqSsbmdm", depMc: 'sqSsbmmc', type: "department", width: "30%" },
|
||||
{ label: "责任单位", prop: "zrSsbmdm", depMc: 'zrSsbmmc', type: "department", width: "30%" },
|
||||
{ label: "所属警种", prop: "zdrSsjz", type: "select", options: D_GS_BK_SSJZ, width: "30%" },
|
||||
{ label: "涉及警种", prop: "zdrSjjz", type: "select", options: D_GS_BK_SSJZ, multiple: true, width: "30%" },
|
||||
{ label: "婚姻状态", prop: "hyzk", type: "select", options: D_BZ_HYZK, width: "30%" },
|
||||
// { label: "处置状态", prop: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT },
|
||||
// { label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT },
|
||||
// { label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
|
||||
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime" },
|
||||
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime" },
|
||||
{ label: "Mac地址", prop: "macDz", type: "input" },
|
||||
{ label: "联系电话", prop: "ryLxdh", type: "slot", width: "100%" },
|
||||
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime", width: "30%" },
|
||||
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime", width: "30%" },
|
||||
{ label: "Mac地址", prop: "macDz", type: "input", width: "30%" },
|
||||
{ label: "联系电话", prop: "ryLxdh", type: "slot", width: "30%" },
|
||||
// { label: "标签选择", prop: "tags", type: "slot", width: "100%" },
|
||||
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" },
|
||||
]);
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
<div class="form_cnt">
|
||||
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform"
|
||||
:rules="rules">
|
||||
|
||||
</FormMessage>
|
||||
</div>
|
||||
</div>
|
||||
@ -124,9 +123,9 @@ const getDataById = (id) => {
|
||||
// 提交
|
||||
const submit = () => {
|
||||
elform.value.submit((data) => {
|
||||
data.fjdz = data.fjdz?.join(",");
|
||||
let url = title.value == "新增" ? "/mosty-gsxt/tbGsxtZdcl/add" : "/mosty-gsxt/tbGsxtZdcl/update";
|
||||
let params = { ...data };
|
||||
params.fjdz = data.fjdz?.join(",");
|
||||
loading.value = true;
|
||||
qcckPost(params, url).then(() => {
|
||||
loading.value = false;
|
||||
|
||||
@ -193,8 +193,8 @@ const pageData = reactive({
|
||||
{ label: "车架号", prop: "clCjh" },
|
||||
{ label: "车辆颜色", prop: "clYs", showOverflowTooltip: true },
|
||||
{ label: "车辆所有人", prop: "clSyr" },
|
||||
{ label: "管辖单位", prop: "gxSsbmmc", showSolt: true },
|
||||
{ label: "管控民警姓名", prop: "gkMjXm", showSolt: true },
|
||||
{ label: "管辖单位", prop: "gxSsbmmc"},
|
||||
{ label: "管控民警姓名", prop: "gkMjXm"},
|
||||
// { label: "状态", prop: "xtSjzt", showSolt: true },
|
||||
// { label: "审核状态", prop: "zdrZt", showSolt: true },
|
||||
]
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import { reactive, ref,getCurrentInstance } from 'vue';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_XB } = proxy.$dict("D_BZ_XB"); // 获取字典数据
|
||||
// const { D_BZ_XB } = proxy.$dict("D_BZ_XB"); // 未使用,已注释
|
||||
const elform = ref()
|
||||
const showDialog = ref(false)
|
||||
const emit = defineEmits(['change'])
|
||||
|
||||
@ -70,7 +70,7 @@ import { ElMessage } from "element-plus";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import { getItem } from "@/utils/storage.js";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDR_CZZT, D_GS_BK_SQLX, D_GS_ZDQT_FXDJ, D_GS_ZDR_RYJB, D_GS_ZDQT_LB, D_GS_ZDR_BK_ZT, D_GS_BQ_LX, D_GS_ZDQT_ZT, D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = proxy.$dict("D_GS_ZDR_CZZT", "D_GS_BK_SQLX", "D_GS_ZDQT_FXDJ", "D_GS_ZDR_RYJB", "D_GS_ZDQT_LB", "D_GS_ZDR_BK_ZT", "D_GS_BQ_LX", "D_GS_ZDQT_ZT", "D_BZ_SF", "D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX"); //获取字典数据
|
||||
const { D_GS_ZDR_CZZT, /* D_GS_BK_SQLX, */ D_GS_ZDQT_FXDJ, D_GS_ZDR_RYJB, D_GS_ZDQT_LB, D_GS_ZDR_BK_ZT, D_GS_BQ_LX, D_GS_ZDQT_ZT, D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = proxy.$dict("D_GS_ZDR_CZZT", /* "D_GS_BK_SQLX", */ "D_GS_ZDQT_FXDJ", "D_GS_ZDR_RYJB", "D_GS_ZDQT_LB", "D_GS_ZDR_BK_ZT", "D_GS_BQ_LX", "D_GS_ZDQT_ZT", "D_BZ_SF", "D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX"); //获取字典数据
|
||||
const showzxs = ref(false);
|
||||
const queryFrom = ref({});
|
||||
const ids = ref([]);
|
||||
|
||||
@ -185,7 +185,7 @@ const {
|
||||
D_GS_BQ_LX,
|
||||
D_GS_ZDR_YJDJ,
|
||||
D_GS_BK_SSJZ,
|
||||
D_GS_BK_SQLX,
|
||||
/* D_GS_BK_SQLX, */
|
||||
D_BZ_SF,
|
||||
D_GS_XS_LY,
|
||||
D_BZ_SSZT,
|
||||
@ -205,7 +205,7 @@ const {
|
||||
"D_GS_BQ_LX",
|
||||
"D_GS_ZDR_YJDJ",
|
||||
"D_GS_BK_SSJZ",
|
||||
"D_GS_BK_SQLX",
|
||||
/* "D_GS_BK_SQLX", */
|
||||
"D_BZ_SF",
|
||||
"D_GS_XS_LY",
|
||||
"D_BZ_SSZT",
|
||||
|
||||
@ -65,7 +65,7 @@ import { IdCard } from "@/utils/validate.js";
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
import { ref, reactive, onMounted, getCurrentInstance, watch } from "vue";
|
||||
import { ref, reactive, onMounted, getCurrentInstance, watch, computed } from "vue";
|
||||
import { tbGsxtZdryUpdate } from "@/api/zdr.js";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const {
|
||||
@ -136,7 +136,7 @@ const rules = reactive({
|
||||
const listQuery = ref({}); //表单
|
||||
const chooseMarksVisible = ref(false); // 控制标签选择弹窗显示
|
||||
const roleIds = ref([]); // 已选择的标签ID
|
||||
const formData = ref([
|
||||
const formData = computed(() => [
|
||||
{ label: "人员照片", prop: "ryzp", type: "slot", width: "100%" },
|
||||
{ label: "姓名", prop: "ryXm", type: "input", width: "30%" },
|
||||
{ label: "身份证号", prop: "rySfzh", type: "input", width: "30%" },
|
||||
@ -144,7 +144,7 @@ const formData = ref([
|
||||
label: "性别",
|
||||
prop: "ryXb",
|
||||
type: "select",
|
||||
options: D_BZ_XB,
|
||||
options: D_BZ_XB.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "出生日期", prop: "ryCsrq", type: "date", width: "30%" },
|
||||
@ -152,7 +152,7 @@ const formData = ref([
|
||||
label: "民族",
|
||||
prop: "ryMz",
|
||||
type: "select",
|
||||
options: D_BZ_MZ,
|
||||
options: D_BZ_MZ.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
@ -166,7 +166,7 @@ const formData = ref([
|
||||
label: "预警等级",
|
||||
prop: "zdrYjdj",
|
||||
type: "select",
|
||||
options: D_GS_ZDR_YJDJ,
|
||||
options: D_GS_ZDR_YJDJ.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "管控民警", prop: "gkMjXm", type: "slot", width: "30%" },
|
||||
@ -180,14 +180,14 @@ const formData = ref([
|
||||
label: "文化程度",
|
||||
prop: "whcdBm",
|
||||
type: "select",
|
||||
options: D_BZ_WHCD,
|
||||
options: D_BZ_WHCD.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "政治面貌",
|
||||
prop: "zzmm",
|
||||
type: "select",
|
||||
options: D_BZ_ZZMM,
|
||||
options: D_BZ_ZZMM.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "职业", prop: "zyBm", type: "input", width: "30%" },
|
||||
@ -195,7 +195,7 @@ const formData = ref([
|
||||
label: "人员级别",
|
||||
prop: "zdrRyjb",
|
||||
type: "select",
|
||||
options: D_GS_ZDR_RYJB,
|
||||
options: D_GS_ZDR_RYJB.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "户籍地区划", prop: "hjdQh", type: "input", width: "30%" },
|
||||
@ -218,14 +218,14 @@ const formData = ref([
|
||||
label: "所属警种",
|
||||
prop: "zdrSsjz",
|
||||
type: "select",
|
||||
options: D_GS_BK_SSJZ,
|
||||
options: D_GS_BK_SSJZ.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "涉及警种",
|
||||
prop: "zdrSjjz",
|
||||
type: "select",
|
||||
options: D_GS_BK_SSJZ,
|
||||
options: D_GS_BK_SSJZ.value,
|
||||
multiple: true,
|
||||
width: "30%"
|
||||
},
|
||||
@ -233,21 +233,21 @@ const formData = ref([
|
||||
label: "婚姻状态",
|
||||
prop: "hyzk",
|
||||
type: "select",
|
||||
options: D_BZ_HYZK,
|
||||
options: D_BZ_HYZK.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "处置状态",
|
||||
prop: "zdrCzzt",
|
||||
type: "select",
|
||||
options: D_GS_ZDR_CZZT,
|
||||
options: D_GS_ZDR_CZZT.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "布控状态",
|
||||
prop: "zdrBkZt",
|
||||
type: "select",
|
||||
options: D_BZ_RCBKZT,
|
||||
options: D_BZ_RCBKZT.value,
|
||||
width: "30%"
|
||||
},
|
||||
// { label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
|
||||
|
||||
@ -73,12 +73,16 @@ import Details from './details.vue'
|
||||
import Information from "@/views/home/model/information.vue";
|
||||
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_RCSHZT, D_GS_RQFJ_LX, D_GS_RQFJ_FXDJ, D_BZ_SF, D_GS_RQFJ_FXLB } =
|
||||
const { D_BZ_RCSHZT,
|
||||
// D_GS_RQFJ_LX,
|
||||
D_GS_RQFJ_FXDJ,
|
||||
// D_BZ_SF,
|
||||
D_GS_RQFJ_FXLB } =
|
||||
proxy.$dict(
|
||||
"D_BZ_RCSHZT",
|
||||
"D_GS_RQFJ_LX",
|
||||
// "D_GS_RQFJ_LX",
|
||||
"D_GS_RQFJ_FXDJ",
|
||||
"D_BZ_SF",
|
||||
// "D_BZ_SF",
|
||||
"D_GS_RQFJ_FXLB"
|
||||
);
|
||||
|
||||
|
||||
@ -27,10 +27,12 @@
|
||||
<h3 class="tags-title">审核状态</h3>
|
||||
<div style="display: flex;justify-content:space-between;width: 200%;">
|
||||
<div style="display: flex;">
|
||||
市审核状态:<DictTag v-model:value="listQuery.sldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
市审核状态:
|
||||
<DictTag v-model:value="listQuery.sldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
县审核状态:<DictTag v-model:value="listQuery.xldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
县审核状态:
|
||||
<DictTag v-model:value="listQuery.xldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -236,7 +238,6 @@ const init = (type, row) => {
|
||||
// 根据id查询详情
|
||||
const getDataById = (id) => {
|
||||
xxcjSelectByid({ id }).then((res) => {
|
||||
|
||||
lcList.value = res.czlcList || []
|
||||
listQuery.value = res;
|
||||
listQuery.value.fjdz = res.fjdz ? res.fjdz?.split(",") : []
|
||||
@ -305,9 +306,7 @@ const close = () => {
|
||||
|
||||
const lcList = ref([])
|
||||
const getqbcjPldb = (id) => {
|
||||
xxcjSelectCzlcList({ qbid: id }).then(res => {
|
||||
console.log(res);
|
||||
|
||||
xxcjSelectCzlcList({ id }).then(res => {
|
||||
lcList.value = res || []
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@ -182,7 +182,7 @@ const getDataById = (id) => {
|
||||
|
||||
const lcList = ref([])
|
||||
const getqbcjPldb = (id) => {
|
||||
xxcjSelectCzlcList({ qbid: id }).then(res => {
|
||||
xxcjSelectCzlcList({ id: id }).then(res => {
|
||||
lcList.value = res || []
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
<script setup>
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import { saveAs } from 'file-saver';
|
||||
import { reactive, watch, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const props = defineProps({
|
||||
@ -94,7 +95,6 @@ const deleteFile = (row) => {
|
||||
emit("changeData", data);
|
||||
}
|
||||
const downloadFile = async (item) => {
|
||||
console.log(item);
|
||||
try {
|
||||
const dataList = [item]
|
||||
if (dataList.length === 0) {
|
||||
@ -108,39 +108,15 @@ const downloadFile = async (item) => {
|
||||
|
||||
proxy.$message.info(`开始下载${downloadCount}个文件...`);
|
||||
|
||||
// 并行下载所有文件
|
||||
const downloadPromises = dataList.map(async (fileData, index) => {
|
||||
|
||||
try {
|
||||
// 使用fetch获取文件内容
|
||||
const response = await fetch(fileData.url);
|
||||
if (!response.ok) {
|
||||
throw new Error('文件下载失败');
|
||||
}
|
||||
|
||||
// 将响应转换为Blob对象
|
||||
const blob = await response.blob();
|
||||
|
||||
// 创建下载链接
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = URL.createObjectURL(blob);
|
||||
|
||||
// 设置下载文件的名称,避免冲突
|
||||
const fileName = dataList.length > 1
|
||||
? `${item.wjmc}_${index + 1}`
|
||||
: item.wjmc;
|
||||
downloadLink.download = fileName;
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(downloadLink);
|
||||
downloadLink.click();
|
||||
|
||||
// 清理
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(downloadLink);
|
||||
URL.revokeObjectURL(downloadLink.href);
|
||||
}, 100);
|
||||
|
||||
const fileName = dataList.length > 1 ? `${item.wjmc}_${index + 1}` : item.wjmc;
|
||||
saveAs(blob, fileName);
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
console.error(`文件${index + 1}下载失败:`, error);
|
||||
@ -148,10 +124,8 @@ const downloadFile = async (item) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有下载完成
|
||||
await Promise.all(downloadPromises);
|
||||
|
||||
// 显示下载结果
|
||||
if (failCount === 0) {
|
||||
proxy.$message.success(`成功下载${successCount}个文件`);
|
||||
} else if (successCount === 0) {
|
||||
|
||||
@ -57,9 +57,11 @@ import { useRoute } from 'vue-router'
|
||||
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
|
||||
import { getItem } from '@//utils/storage.js'
|
||||
import { deleteWjZzzAddEntity, getWjZzzAddEntity, selectDxzjList } from '@//api/qbcj.js'
|
||||
import { saveAs } from 'file-saver';
|
||||
import AddForm from "@/views/backOfficeSystem/HumanIntelligence/fileTransfer/components/addForm.vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
// const { D_BZ_CJLX, D_GS_XS_LX } = proxy.$dict("D_BZ_CJLX", "D_GS_XS_LX"); //获取字典数据
|
||||
// 未使用: D_GS_XS_LX
|
||||
const detailDiloag = ref();
|
||||
const searchBox = ref(); //搜索框
|
||||
const ids = ref([])
|
||||
@ -188,27 +190,12 @@ const downloadFile = async (item) => {
|
||||
proxy.$message.info(`开始下载${downloadCount}个文件...`);
|
||||
const downloadPromises = dataList.map(async (fileData, index) => {
|
||||
try {
|
||||
// fileData.url = "http://47.108.232.77:9000/image/2025-01-06/081102a5418e4146beea277d18018e07.jpeg";
|
||||
// 使用fetch获取文件内容
|
||||
const downloadUrl = fileData.url.replace(/^https?:\/\/[^/]+/, '/zyminio');
|
||||
const response = await fetch(downloadUrl);
|
||||
if (!response.ok) throw new Error('文件下载失败');
|
||||
// 将响应转换为Blob对象
|
||||
const blob = await response.blob();
|
||||
// 创建下载链接
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = URL.createObjectURL(blob);
|
||||
// 设置下载文件的名称,避免冲突
|
||||
const fileName = dataList.length > 1 ? `${item.wjmc}_${index + 1}` : item.wjmc;
|
||||
downloadLink.download = fileName;
|
||||
// 触发下载
|
||||
document.body.appendChild(downloadLink);
|
||||
downloadLink.click();
|
||||
// 清理
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(downloadLink);
|
||||
URL.revokeObjectURL(downloadLink.href);
|
||||
}, 100);
|
||||
saveAs(blob, fileName);
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
console.error(`文件${index + 1}下载失败:`, error);
|
||||
@ -216,9 +203,7 @@ const downloadFile = async (item) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有下载完成
|
||||
await Promise.all(downloadPromises);
|
||||
// 显示下载结果
|
||||
if (failCount === 0) {
|
||||
proxy.$message.success(`成功下载${successCount}个文件`);
|
||||
} else if (successCount === 0) {
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form_cnt">
|
||||
|
||||
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
|
||||
<template #wjdz>
|
||||
<FileUploadList @changeData="changeData" :imgMsg="imgMsg" />
|
||||
|
||||
@ -59,6 +59,7 @@ import { useRoute } from 'vue-router'
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
import { getItem } from '@//utils/storage.js'
|
||||
import { deleteWjZzzAddEntity, getWjZzzAddEntity } from '@//api/qbcj.js'
|
||||
import { saveAs } from 'file-saver';
|
||||
import AddForm from "./components/addForm.vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const detailDiloag = ref();
|
||||
@ -180,30 +181,14 @@ const downloadFile = async (item) => {
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
proxy.$message.info(`开始下载${downloadCount}个文件...`);
|
||||
// 并行下载所有文件
|
||||
const downloadPromises = dataList.map(async (fileData, index) => {
|
||||
try {
|
||||
// fileData.url = "http://47.108.232.77:9000/image/2025-01-06/081102a5418e4146beea277d18018e07.jpeg";
|
||||
// 使用fetch获取文件内容
|
||||
const downloadUrl = fileData.url.replace(/^https?:\/\/[^/]+/, '/zyminio');
|
||||
const response = await fetch(downloadUrl);
|
||||
if (!response.ok) throw new Error('文件下载失败');
|
||||
// 将响应转换为Blob对象
|
||||
const blob = await response.blob();
|
||||
// 创建下载链接
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = URL.createObjectURL(blob);
|
||||
// 设置下载文件的名称,避免冲突
|
||||
const fileName = dataList.length > 1 ? `${item.wjmc}_${index + 1}` : item.wjmc;
|
||||
downloadLink.download = fileName;
|
||||
// 触发下载
|
||||
document.body.appendChild(downloadLink);
|
||||
downloadLink.click();
|
||||
// 清理
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(downloadLink);
|
||||
URL.revokeObjectURL(downloadLink.href);
|
||||
}, 100);
|
||||
saveAs(blob, fileName);
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
console.error(`文件${index + 1}下载失败:`, error);
|
||||
@ -211,10 +196,8 @@ const downloadFile = async (item) => {
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有下载完成
|
||||
await Promise.all(downloadPromises);
|
||||
|
||||
// 显示下载结果
|
||||
if (failCount === 0) {
|
||||
proxy.$message.success(`成功下载${successCount}个文件`);
|
||||
} else if (successCount === 0) {
|
||||
|
||||
@ -24,15 +24,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</template> -->
|
||||
<template #scfj>
|
||||
<div style="width: 100%;padding-left: 50px;">
|
||||
<div>上传附件:<span class="f12">(可附电子表格、Word文档、图像、音视频文件)</span> </div>
|
||||
<MOSTY.Upload :showBtn="true" :isAll="true" :isImg="false" :limit="10" v-model="fjdz" />
|
||||
</div>
|
||||
</template>
|
||||
<template #shzt>
|
||||
<div v-if="disabled">
|
||||
<h3 class="tags-title">审核状态</h3>
|
||||
<div style="display: flex;justify-content:space-between;width: 200%;">
|
||||
<div style="display: flex;">
|
||||
市审核状态:<DictTag v-model:value="listQuery.sldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
市审核状态:
|
||||
<DictTag v-model:value="listQuery.sldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
</div>
|
||||
<div style="display: flex;">
|
||||
县审核状态:<DictTag v-model:value="listQuery.xldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
县审核状态:
|
||||
<DictTag v-model:value="listQuery.xldshzt" :options="dict.D_BZ_SSSHZT" :tag="false" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -186,7 +194,7 @@ watch(() => dialogForm.value, (val) => {
|
||||
formData.value = [
|
||||
{ label: "情报标题", prop: "qbmc", type: "input", width: '45%' },
|
||||
{ label: "情报内容", prop: "qbnr", type: "textarea", width: '100%', rows: 100 },
|
||||
{ label: "附件上传", prop: "fjdz", type: "upload", width: '100%', isImg: false },
|
||||
{ prop: "scfj", type: "slot", width: '100%' },
|
||||
{ label: "", prop: "jbxx", type: "slot", width: '100%', },
|
||||
{ label: "", prop: "shzt", type: "slot", width: '100%' },
|
||||
]
|
||||
@ -242,7 +250,14 @@ const getDataById = (id) => {
|
||||
|
||||
lcList.value = res.czlcList || []
|
||||
listQuery.value = res;
|
||||
listQuery.value.fjdz = res.fjdz ? res.fjdz?.split(",") : []
|
||||
// 解析附件:兼容JSON字符串和逗号分隔两种格式
|
||||
try {
|
||||
const parsed = res.fjdz ? JSON.parse(res.fjdz) : []
|
||||
listQuery.value.fjdz = Array.isArray(parsed) ? parsed : []
|
||||
} catch (e) {
|
||||
listQuery.value.fjdz = res.fjdz ? res.fjdz.split(",") : []
|
||||
}
|
||||
fjdz.value = listQuery.value.fjdz
|
||||
});
|
||||
};
|
||||
|
||||
@ -252,11 +267,18 @@ const submitForm = () => {
|
||||
elform.value.submit(valid => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
// 将附件转为JSON字符串
|
||||
let fjdzList = []
|
||||
fjdz.value.forEach(item => {
|
||||
if (Object.prototype.toString.call(item) === '[object Object]') {
|
||||
fjdzList.push({ id: item.id, name: item.name })
|
||||
} else {
|
||||
fjdzList.push({ id: item })
|
||||
}
|
||||
})
|
||||
const promes = {
|
||||
...listQuery.value,
|
||||
fjdz: listQuery.value.fjdz && listQuery.value.fjdz.length > 0 ? listQuery.value.fjdz.map(item => {
|
||||
return item.id
|
||||
}).join(',') : '',
|
||||
fjdz: fjdzList.length > 0 ? JSON.stringify(fjdzList) : '',
|
||||
qbly: 0,
|
||||
}
|
||||
if (title.value == '新增') {
|
||||
@ -308,7 +330,7 @@ const close = () => {
|
||||
|
||||
const lcList = ref([])
|
||||
const getqbcjPldb = (id) => {
|
||||
xxcjSelectCzlcList({ qbid: id }).then(res => {
|
||||
xxcjSelectCzlcList({ id: id }).then(res => {
|
||||
console.log(res);
|
||||
lcList.value = res || []
|
||||
})
|
||||
@ -587,10 +609,12 @@ defineExpose({ init });
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
.timeline-content {
|
||||
width: 100%;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
::v-deep .el-timeline-item__wrapper {
|
||||
padding-left: 21px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--文件导出 -->
|
||||
<template>
|
||||
<el-dialog :model-value="modelValue" :title="title" :width="width" top="5vh" @close="close" append-to-body>
|
||||
<div style="height: 70vh;">
|
||||
<div ref="tableContainer" class="table-container">
|
||||
|
||||
<MyTable ref="tableData" :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn"
|
||||
:tableHeight="pageForm.tableHeight" :key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger"
|
||||
@ -26,7 +26,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import * as XLSX from 'xlsx'
|
||||
import { onMounted, reactive, watch, ref } from 'vue'
|
||||
import { onMounted, reactive, watch, ref, nextTick, onUnmounted } from 'vue'
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import { template } from 'lodash';
|
||||
const props = defineProps({
|
||||
@ -52,12 +52,26 @@ const props = defineProps({
|
||||
default: () => ([])
|
||||
}
|
||||
})
|
||||
const tableContainer = ref(null)
|
||||
const tableData = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
{ { props.dict } }
|
||||
})
|
||||
|
||||
// 计算表格高度
|
||||
const calcTableHeight = () => {
|
||||
nextTick(() => {
|
||||
if (tableContainer.value) {
|
||||
pageForm.tableHeight = tableContainer.value.offsetHeight - 20
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => props.modelValue, (newVal, oldVal) => {
|
||||
if(newVal){
|
||||
pageForm.tableData = props.dataModel
|
||||
calcTableHeight()
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
@ -94,7 +108,6 @@ watch(() => props.modelValue, (newVal) => {
|
||||
const close = () => {
|
||||
emit('update:modelValue', false)
|
||||
}
|
||||
const tableData = ref(null)
|
||||
// 导出当前表格的数据
|
||||
const exportCurrentTable = () => {
|
||||
try {
|
||||
@ -157,3 +170,9 @@ const exportCurrentTable = () => {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.table-container {
|
||||
height: 70vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -0,0 +1,599 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Searchs :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
|
||||
<el-button type="primary" @click="addEdit('add')" size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">新增</span>
|
||||
</el-button>
|
||||
<el-button type="primary" @click="exportFileModel = true;" size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">导出</span>
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'"
|
||||
size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">上报</span>
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="provDepar(ids)" v-if="qxkz.deptLevel == '01'"
|
||||
size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">上报区厅</span>
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="delDictItem(ids)" size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">删除</span>
|
||||
</el-button>
|
||||
<!-- <el-button type="primary" size="small" @click="handleReport">
|
||||
<el-icon class="vertical-middle"><Edit /></el-icon>
|
||||
<span class="vertical-middle">情报信息报告</span>
|
||||
</el-button> -->
|
||||
</Searchs>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="margTop">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData" @handleCellClick="openXxqk">
|
||||
<template #qblx="{ row }">
|
||||
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
|
||||
</template>
|
||||
<template #qbly="{ row }">
|
||||
<DictTag :tag="false" :value="row.qbly" :options="D_BZ_CJLX" />
|
||||
</template>
|
||||
<template #czzt="{ row }">
|
||||
<DictTag :tag="false" :value="row.czzt" :options="D_BZ_QBCZZT" />
|
||||
</template>
|
||||
<template #lczt="{ row }">
|
||||
<DictTag :tag="false" :value="row.lczt" :options="D_BZ_LCZT" />
|
||||
</template>
|
||||
<template #glbqList="{ row }">
|
||||
<div>
|
||||
<el-tag v-for="(item, idx) in row.glbqList" :key="idx">{{ item.bqmc }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<template #cyqk="{ row }">
|
||||
<el-link v-if="isShowBtn('采纳')" size="small" type="danger" @click="cnMsg(row)"
|
||||
:disabled="butcontroll('04', row.lczt)">采纳</el-link>
|
||||
<!-- 只有上报状态才能回退 -->
|
||||
<el-link v-if="isShowBtn('回退')" size="small" type="danger" @click="rollbackNewspapers(row)"
|
||||
:disabled="butcontroll('04', row.lczt)">回退</el-link>
|
||||
</template>
|
||||
<!-- 所有按钮采纳前不能操作,回退后也不能操作 -->
|
||||
<!-- 操作 -->
|
||||
<!-- "市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"], -->
|
||||
<!-- "县情指人员": ["上报", "回退", "修改", "详情", "送审"], -->
|
||||
<template #controls="{ row }">
|
||||
<el-link @click="handleSbqt(row)" size="small" type="primary" v-if="qxkz.deptLevel == '01'"
|
||||
:disabled="row.lczt == '10'">上报区厅</el-link>
|
||||
<el-link v-if="isShowBtn('送审', row) && qxkz.deptLevel == '01' && row.lczt == '04'"
|
||||
:disabled="!(row.lczt == '04') || row.sldshzt != '00'" size="small" type="primary"
|
||||
@click="postXxcjXxcjTjsh(row)">送审</el-link>
|
||||
|
||||
<!-- <el-link
|
||||
v-if="isShowBtn('送审', row) && qxkz.deptLevel == '02'"
|
||||
:disabled="row.xldshzt != '00' "
|
||||
size="small" type="primary"
|
||||
@click="postXxcjXxcjTjsh(row)">
|
||||
送审
|
||||
</el-link> -->
|
||||
|
||||
<!-- (01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商)v-if="qxkz.deptLevel == '01'" -->
|
||||
<el-link v-if="isShowBtn('上报') && qxkz.deptLevel == '03'" size="small" type="primary"
|
||||
@click="appearNewspapers(row)" :disabled="row.lczt != '01'">上报</el-link>
|
||||
<el-link v-else-if="isShowBtn('上报')" size="small" type="primary" @click="appearNewspapers(row)"
|
||||
:disabled="!(row.lczt == '02')">上报</el-link>
|
||||
<!-- && row.lczt != '02' -->
|
||||
<el-link v-if="isShowBtn('分组') && (row.lczt == '04' || row.lczt == '08' || row.lczt == '10')" size="small"
|
||||
type="primary" @click="opneMsg(row)">分组</el-link>
|
||||
<!-- 只有领导有肯定 -->
|
||||
<!-- <el-link v-if="isShowBtn('肯定')" size="small" type="primary" @click="affirm(row)">肯定</el-link> -->
|
||||
<el-link v-if="isShowBtn('删除')" size="small" type="primary" @clic.stopk="delDictItem(row.id)">删除</el-link>
|
||||
<el-link v-if="isShowBtn('修改', row)" size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
|
||||
<el-link v-if="isShowBtn('续报', row) && row.lczt == '04'" size="small" type="primary"
|
||||
@click="addEdit('followUpReport', row)">续报</el-link>
|
||||
|
||||
<el-link v-if="isShowBtn('详情')" size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
|
||||
<!-- 所有状态都能进行转线索 -->
|
||||
<el-link v-if="isShowBtn('转线索') && (row.lczt == '04' || row.lczt == '06')" size="small" type="primary"
|
||||
@click="FollowUpOnLeads(row)" :disabled="row.lczt == '08'">转线索</el-link>
|
||||
<!-- 所有状态都能进行转合成 -->
|
||||
<!-- <el-link v-if="isShowBtn('转合成')" size="small" type="primary" @click="openFkDialogszl(row)" :disabled="butcontroll('01', row.lczt)">转合成</el-link> -->
|
||||
<!-- 所有状态都能进行转会商 -->
|
||||
<!-- <el-link v-if="isShowBtn('转会商')" size="small" type="primary" @click="handleTransferMerchant(row)" :disabled="butcontroll('01', row.lczt)">转会商</el-link> -->
|
||||
|
||||
<el-link v-if="isShowBtn('关注部门') && row.qbjb == '01' && row.lczt == '04'" :disabled="row.sldshzt != '02'"
|
||||
size="small" type="primary" @click="FollowUpOnDept(row)">定向关注</el-link>
|
||||
<!-- 市局能给所有数据创建标签 -->
|
||||
<el-link
|
||||
v-if="isShowBtn('打标签') && (row.lczt == '04' || row.lczt == '06' || row.lczt == '07' || row.lczt == '08' || row.lczt == '09' || row.lczt == '10') && qxkz.deptLevel == '01'"
|
||||
size="small" type="primary" @click="openCustomTag(row)" :disabled="row.sldshzt != '02'">打标签</el-link>
|
||||
<el-link size="small" type="primary" @click="handleAttention(row)">{{ row.sfgz == '1'
|
||||
? '取消关注' : '关注' }}</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></Pages>
|
||||
</div>
|
||||
<!-- 新增 -->
|
||||
<AddForm ref="detailDiloag" @getList="getList" :titleData="titleData" :dict="{ D_BZ_LCZT, D_BZ_SSSHZT }" />
|
||||
</div>
|
||||
|
||||
<ExportFile v-model="exportFileModel" :tableColumn="tableColumn" :dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
|
||||
:dataModel="pageData.tableData" />
|
||||
|
||||
<MakeTag v-model="chooseRow" :dataList="dataList" :dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
|
||||
@getList="getList" />
|
||||
|
||||
<Fszl v-model="fszlShow" path="/xxcj/sendFqzl" :itemData="dataList" />
|
||||
|
||||
<CustomTag v-model="customTagShow" :dataList="dataList" @getList="getList" :dict="{ D_XXCJ_BQLX }" />
|
||||
<Configuration v-model="configurationShow" :dataList="dataList" @getList="getList" />
|
||||
|
||||
<!-- 转会商 -->
|
||||
<transferMerchant v-if="isShowTransferMerchantTc" :row="currRow" title="转会商" @close="isShowTransferMerchantTc = false"
|
||||
@ok="getList" />
|
||||
|
||||
<!-- 情报信息报告 -->
|
||||
<InforReport v-if="inforReportShow" v-model="inforReportShow" :data="tableList" />
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import InforReport from './components/inforReport.vue'
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Searchs from "@/components/aboutTable/Search.vue";
|
||||
import AddForm from "./components/addForm.vue";
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { qbcjSelectQbsbPage, qbcjDeletes, qbcjCzzt, qbcjPlsb } from "@/api/Intelligence.js";
|
||||
import { xxcjSelectXxsbPage, xxcjDeletes, xxcjXxzsx, xxcjUpdateCzlc, xxcjXxqd, xxcjXxcjTjsh, xxcjCare, xxcjReportGat, xxcjPlsb } from '@/api/xxcj.js'
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import MakeTag from '../components/maketag.vue'
|
||||
import ExportFile from './components/exportFile.vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import Fszl from '@/views/backOfficeSystem/HumanIntelligence/components/fszl.vue'
|
||||
import CustomTag from '../components/customTag.vue'
|
||||
import Configuration from '../components/configuration.vue'
|
||||
import transferMerchant from "./components/transferMerchant.vue";
|
||||
import { Edit } from "@element-plus/icons";
|
||||
import { useInfoCollectionPermission, FlowStatus } from './useInfoCollectionPermission.ts'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_SF, D_GS_XS_LY, /* D_BZ_SSSHZT, */ D_GS_XS_LX, D_BZ_BQJB, D_BZ_QBCZZT, D_BZ_CJLX, D_BZ_LCZT, D_XXCJ_BQLX } = proxy.$dict("D_BZ_SF", "D_GS_XS_LY" /*, 'D_BZ_SSSHZT' */, "D_GS_XS_LX", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB", "D_BZ_LCZT", "D_XXCJ_BQLX"); //获取字典数据
|
||||
const route = useRoute()
|
||||
const titleData = ref()
|
||||
const exportFileModel = ref(false)
|
||||
|
||||
// 使用权限管理模块
|
||||
const permission = useInfoCollectionPermission()
|
||||
const { state: qxkz, isCityLevel, canShowBtn, butcontroll, canSubmitAudit, canReport, canTag, canFollowDept, canTransferClue, canFollowUpReport } = permission
|
||||
|
||||
const fszlShow = ref(false)// 发送指令
|
||||
const detailDiloag = ref();
|
||||
const inforReportShow = ref(false) //情报信息报告
|
||||
const customTagShow = ref(false)// 打标签
|
||||
const configurationShow = ref(false)// 配置关注部门
|
||||
const searchBox = ref(); //搜索框
|
||||
const ids = ref([])
|
||||
const tableList = ref([]);
|
||||
const currRow = ref({})
|
||||
const isShowTransferMerchantTc = ref(false)
|
||||
const isShow = ref(false)
|
||||
const searchConfiger = ref([
|
||||
{ label: "录入人", prop: 'xssbr', placeholder: "请输入录入人", showType: "input" },
|
||||
{ label: "录入单位", prop: "ssbmdm", placeholder: "请选择录入单位", showType: "department" },
|
||||
{ label: "编号", prop: 'xsBh', placeholder: "请输入编号", showType: "input" },
|
||||
{ label: "时间", prop: "startTime", placeholder: "请选择时间", showType: "daterange" },
|
||||
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
|
||||
{ label: "标签内容", prop: 'bqdmList', placeholder: "请选择标签内容", showType: "select", options: D_XXCJ_BQLX, multiple: true },
|
||||
{ label: "标签级别", prop: 'qbjb', placeholder: "请选择标签级别", showType: "select", options: D_BZ_BQJB },
|
||||
{ label: "情报处置状态", prop: 'lczt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_LCZT },
|
||||
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
|
||||
{ label: "是否上报区厅", prop: 'sfsbqt', placeholder: "请选择是否上报区厅", showType: "select", options: D_BZ_SF },
|
||||
{ label: "是否关注", prop: 'sfgz', placeholder: "请选择是否关注", showType: "select", options: D_BZ_SF },
|
||||
]);
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "checkBox",
|
||||
loading: false
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 300,
|
||||
tableColumn: [
|
||||
{ label: "情报上报时间", prop: "sxsbsj" },
|
||||
{ label: "情报编号", prop: "xsBh" },
|
||||
{ label: "情报标题", prop: "qbmc" },
|
||||
{ label: "情报来源", prop: "qbly", showSolt: true },
|
||||
{ label: "上报人", prop: "xssbr" },
|
||||
{ label: "上报单位", prop: "ssbm" },
|
||||
{ label: "流程状态", prop: "lczt", showSolt: true },
|
||||
{ label: "采用情况", prop: "cyqk", showSolt: true },
|
||||
{ label: "关联标签", prop: "glbqList", showSolt: true },
|
||||
]
|
||||
});
|
||||
// 导出数据
|
||||
const tableColumn = reactive([
|
||||
{ label: "上报人姓名", prop: "xssbr" },
|
||||
{ label: "情报上报时间", prop: "sxsbsj" },
|
||||
{ label: "情报编号", prop: "xsBh" },
|
||||
{ label: "情报标题", prop: "qbmc" },
|
||||
{ label: "情报来源", prop: "qbly", showSolt: true, zd: 'D_BZ_CJLX' },
|
||||
])
|
||||
const queryFrom = ref({});
|
||||
const chooseRow = ref(false)
|
||||
const dataList = ref()
|
||||
|
||||
const chooseData = (val) => {
|
||||
ids.value = val.map(item => item.id)
|
||||
tableList.value = val
|
||||
}
|
||||
|
||||
// 采纳
|
||||
const cnMsg = (item) => {
|
||||
proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
|
||||
xxcjUpdateCzlc({ id: item.id, lczt: '04' }).then(res => {
|
||||
proxy.$message({ type: "success", message: "采纳成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { });
|
||||
}
|
||||
|
||||
const handleReport = () => {
|
||||
if (tableList.value.length == 0) return proxy.$message({ type: "warning", message: "请选择情报信息" });
|
||||
inforReportShow.value = true
|
||||
}
|
||||
|
||||
// 关注
|
||||
const handleAttention = (val) => {
|
||||
let data = { id: val.id, sfgz: val.sfgz == '1' ? '0' : '1' }
|
||||
xxcjCare(data).then(res => {
|
||||
let text = data.sfgz == '1' ? '关注成功' : '已取消'
|
||||
proxy.$message({ type: "success", message: text });
|
||||
getList();
|
||||
}).catch(() => {
|
||||
let text = data.sfgz == '1' ? '关注失败' : '取消失败'
|
||||
proxy.$message({ type: "error", message: text });
|
||||
})
|
||||
|
||||
}
|
||||
// 回退
|
||||
const rollbackNewspapers = (item) => {
|
||||
// if (item.lczt == '04') {
|
||||
// proxy.$message({
|
||||
// message: '已经采纳的信息无法回退',
|
||||
// type: 'warning',
|
||||
// showClose: true,
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
// if (item.lczt == '03') {
|
||||
// proxy.$message({
|
||||
// message: '无法回退市局上报信息',
|
||||
// type: 'warning',
|
||||
// showClose: true,
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
if (item.qbjb == '00') {
|
||||
ElMessageBox.prompt('请输入回退原因', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
})
|
||||
.then(({ value }) => {
|
||||
xxcjUpdateCzlc({ id: item.id, lczt: '05', czthyy: value }).then(res => {
|
||||
proxy.$message({ type: "success", message: "回退成功" });
|
||||
getList();
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
})
|
||||
} else {
|
||||
proxy.$message({
|
||||
message: '只能回退已上报的情报',
|
||||
type: 'warning',
|
||||
showClose: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
// 上报
|
||||
const appearNewspapers = (item) => {
|
||||
console.log(item);
|
||||
|
||||
if ((item.lczt == '01' || item.lczt == '05' || item.lczt == '02') && item.qbjb == '00' && qxkz.deptLevel != '01') {
|
||||
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
|
||||
let promes = { id: item.id }
|
||||
promes.lczt = qxkz.deptLevel == '02' ? '03' : '02';
|
||||
xxcjUpdateCzlc(promes).then(res => {
|
||||
proxy.$message({ type: "success", message: "上报成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { });
|
||||
} else {
|
||||
proxy.$message({ type: "warning", message: "市局无法进行上报" });
|
||||
}
|
||||
}
|
||||
// 分组
|
||||
const opneMsg = (item) => {
|
||||
chooseRow.value = true
|
||||
dataList.value = [item]
|
||||
}
|
||||
|
||||
const openCustomTag = (item) => {
|
||||
if (qxkz.depBool) {
|
||||
customTagShow.value = true
|
||||
dataList.value = item
|
||||
} else {
|
||||
proxy.$message.warning('暂无权限')
|
||||
}
|
||||
}
|
||||
// 肯定
|
||||
const affirm = (item) => {
|
||||
proxy.$confirm("确定要肯定吗?", "警告", { type: "warning" }).then(() => {
|
||||
xxcjXxqd({ ids: item.id }).then(res => {
|
||||
proxy.$message({ type: "success", message: "肯定成功" });
|
||||
getList();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const FollowUpOnDept = (item) => {
|
||||
if (qxkz.depBool) {
|
||||
configurationShow.value = true
|
||||
dataList.value = item
|
||||
} else {
|
||||
proxy.$message.warning('暂无权限')
|
||||
}
|
||||
}
|
||||
|
||||
// 批量分组
|
||||
// const batchMark = () => {
|
||||
// const listDb = tableList.value.filter(item => item.lczt != '04')
|
||||
// if (listDb.length == 0) {
|
||||
// chooseRow.value = true
|
||||
// dataList.value = tableList.value
|
||||
// } else {
|
||||
// proxy.$message({
|
||||
// message: '还有情报未采纳',
|
||||
// type: 'warning',
|
||||
// showClose: true,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
const handleSumbit = () => {
|
||||
const listDb = tableList.value.filter(item => item.czzt != '01' && item.czzt != '04')
|
||||
if (listDb.length == 0) {
|
||||
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
|
||||
const lczt = qxkz.deptLevel == '02' ? '03' : '02';
|
||||
xxcjPlsb({ ids: ids.value, lczt: lczt }).then(res => {
|
||||
proxy.$message({ type: "success", message: "上报成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { });
|
||||
} else {
|
||||
proxy.$message({ message: '请选择正确数据', type: 'warning', showClose: true })
|
||||
}
|
||||
}
|
||||
// 上报区厅
|
||||
const provDepar = () => {
|
||||
const listDb = tableList.value.filter(item => item.czzt != '10').map(item => item.id)
|
||||
if (listDb.length > 0) {
|
||||
proxy.$confirm("确定要上报区厅吗", "提示", { type: "warning" }).then(() => {
|
||||
xxcjReportGat({ ids: listDb }).then(res => {
|
||||
proxy.$message({ type: "success", message: "上报区厅成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { })
|
||||
|
||||
|
||||
|
||||
// proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
|
||||
// xxcjPlsb({ ids: ids.value, lczt: "10" }).then(res => {
|
||||
// proxy.$message({ type: "success", message: "上报成功" });
|
||||
// getList();
|
||||
// })
|
||||
// }).catch(() => { });
|
||||
} else {
|
||||
proxy.$message({ message: '请选择正确数据', type: 'warning', showClose: true })
|
||||
}
|
||||
}
|
||||
// 按钮状态控制已迁移至 useInfoCollectionPermission
|
||||
|
||||
// 搜索
|
||||
const onSearch = (val) => {
|
||||
const promes = {
|
||||
...pageData.pageConfiger,
|
||||
...val,
|
||||
startTime: val.startTime ? val.startTime[0] : '',
|
||||
endTime: val.endTime ? val.endTime[1] : '',
|
||||
bqdmList: val.bqdmList ? val.bqdmList.join(',') : ""
|
||||
}
|
||||
queryFrom.value = { ...promes }
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList()
|
||||
}
|
||||
|
||||
const changeNo = (val) => {
|
||||
pageData.pageConfiger.pageCurrent = val;
|
||||
getList()
|
||||
}
|
||||
const changeSize = (val) => {
|
||||
pageData.pageConfiger.pageSize = val;
|
||||
getList()
|
||||
}
|
||||
|
||||
// 获取列表
|
||||
const getList = () => {
|
||||
pageData.tableConfiger.loading = true;
|
||||
let data = { ...pageData.pageConfiger, ...queryFrom.value };
|
||||
xxcjSelectXxsbPage(data).then(res => {
|
||||
pageData.tableData = (res.records || []).map(item => {
|
||||
item.glbqList = item.glbqList || [];
|
||||
return item;
|
||||
});
|
||||
pageData.total = res.total;
|
||||
pageData.tableConfiger.loading = false;
|
||||
}).catch(() => { pageData.tableConfiger.loading = false; })
|
||||
}
|
||||
// 删除
|
||||
const delDictItem = (id) => {
|
||||
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
|
||||
xxcjDeletes({ ids: Array.isArray(id) ? id : [id] }).then((res) => {
|
||||
proxy.$message({ type: "success", message: "删除成功" });
|
||||
getList();
|
||||
}).catch(() => {
|
||||
})
|
||||
}).catch(() => { });
|
||||
}
|
||||
|
||||
// 详情
|
||||
const addEdit = (type, row) => {
|
||||
isShow.value = true;
|
||||
setTimeout(() => {
|
||||
detailDiloag.value.init(type, row);
|
||||
}, 500)
|
||||
};
|
||||
const openXxqk = (row) => {
|
||||
if (row.column.property == 'qbmc' || row.column.property == 'xsBh') {
|
||||
isShow.value = true;
|
||||
setTimeout(() => {
|
||||
detailDiloag.value.init('info', row.row);
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
// 转线索
|
||||
const FollowUpOnLeads = (row) => {
|
||||
if (!qxkz.depBool) return proxy.$message({ message: '权限不足', type: 'warning', showClose: true, })
|
||||
proxy.$confirm("确定要转线索吗?", "警告", { type: "warning" }).then(() => {
|
||||
xxcjXxzsx({ ids: Array.isArray(row) ? row.join(',') : row.id }).then(res => {
|
||||
proxy.$message({ type: "success", message: "转线索成功" });
|
||||
getList();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const openFkDialogszl = (row) => {
|
||||
if (!qxkz.depBool) {
|
||||
proxy.$message({
|
||||
message: '权限不足',
|
||||
type: 'warning',
|
||||
showClose: true,
|
||||
})
|
||||
return
|
||||
} else {
|
||||
fszlShow.value = true
|
||||
dataList.value = row
|
||||
}
|
||||
|
||||
}
|
||||
// 权限相关函数已迁移至 useInfoCollectionPermission
|
||||
const handleTransferMerchant = (row) => {
|
||||
currRow.value = row
|
||||
isShowTransferMerchantTc.value = true
|
||||
}
|
||||
// 送审
|
||||
const postXxcjXxcjTjsh = (row) => {
|
||||
proxy.$confirm("确定要送审吗", "提示", { type: "warning" }).then(() => {
|
||||
xxcjXxcjTjsh({ xxid: row.id }).then(res => {
|
||||
proxy.$message({ type: "success", message: "送审成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
// 上报区厅
|
||||
const handleSbqt = (row) => {
|
||||
proxy.$confirm("确定要上报区厅吗", "提示", { type: "warning" }).then(() => {
|
||||
xxcjReportGat({ ids: [row.id] }).then(res => {
|
||||
proxy.$message({ type: "success", message: "上报区厅成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化权限
|
||||
permission.initPermission()
|
||||
|
||||
titleData.value = route.meta.title
|
||||
tabHeightFn()
|
||||
if (route.query.id) {
|
||||
detailDiloag.value.init('edit', { id: route.query.id });
|
||||
}
|
||||
getList()
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.label-pop {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '*';
|
||||
top: 0;
|
||||
left: -7px;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.el-loading-mask {
|
||||
background: rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
:v-deep .el-dialog {
|
||||
width: 90% !important;
|
||||
}
|
||||
|
||||
.zdy-model-dialogs {
|
||||
/* background-color: rgb(50, 148, 214); */
|
||||
background: url("~@/assets/images/bg46.png") no-repeat center center;
|
||||
background-size: 100% 100%;
|
||||
padding: 8px 10px;
|
||||
box-sizing: border-box;
|
||||
pointer-events: auto !important;
|
||||
height: calc(100% - 50px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.vertical-middle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
@ -15,13 +15,19 @@
|
||||
</el-icon>
|
||||
<span class="vertical-middle">导出</span>
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'"
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="!isCityLevel"
|
||||
size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">上报</span>
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="provDepar(ids)" v-if="isCityLevel" size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span class="vertical-middle">上报区厅</span>
|
||||
</el-button>
|
||||
<el-button type="primary" :disabled="ids.length === 0" @click="delDictItem(ids)" size="small">
|
||||
<el-icon class="vertical-middle">
|
||||
<CirclePlus />
|
||||
@ -43,8 +49,8 @@
|
||||
<template #qblx="{ row }">
|
||||
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
|
||||
</template>
|
||||
<template #qbly="{ row }">
|
||||
<DictTag :tag="false" :value="row.qbly" :options="D_BZ_CJLX" />
|
||||
<template #qbjb="{ row }">
|
||||
<DictTag :tag="false" :value="row.qbjb" :options="D_BZ_BQJB" />
|
||||
</template>
|
||||
<template #czzt="{ row }">
|
||||
<DictTag :tag="false" :value="row.czzt" :options="D_BZ_QBCZZT" />
|
||||
@ -58,60 +64,42 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #cyqk="{ row }">
|
||||
<el-link v-if="isShowBtn('采纳')" size="small" type="danger" @click="cnMsg(row)"
|
||||
:disabled="butcontroll('04', row.lczt)">采纳</el-link>
|
||||
<!-- 只有上报状态才能回退 -->
|
||||
<el-link v-if="isShowBtn('回退')" size="small" type="danger" @click="rollbackNewspapers(row)"
|
||||
:disabled="butcontroll('04', row.lczt)">回退</el-link>
|
||||
<template v-if="isCityLevel">
|
||||
<el-link v-if="row.clhtzt == '0' || row.clhtzt == '1'" size="small" type="danger" @click="cnMsg(row)"
|
||||
:disabled="row.clhtzt == '1'">{{ row.clhtzt == '1' ? "已采纳" : "采纳" }}</el-link>
|
||||
<el-link v-if="row.clhtzt == '0' || row.clhtzt == '2'" size="small" type="danger"
|
||||
@click="rollbackNewspapers(row)" :disabled="row.clhtzt == '2'">{{ row.clhtzt == '2' ? "已回退" : "回退"
|
||||
}}</el-link>
|
||||
</template>
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<!-- "市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"], -->
|
||||
<!-- "县情指人员": ["上报", "回退", "修改", "详情", "送审"], -->
|
||||
<template #controls="{ row }">
|
||||
<el-link @click="handleSbqt(row)" size="small" type="primary">上报区厅</el-link>
|
||||
<el-link
|
||||
v-if="isShowBtn('送审', row) && qxkz.deptLevel == '01'"
|
||||
:disabled="!(row.lczt == '04')||row.sldshzt != '00'"
|
||||
size="small" type="primary"
|
||||
@click="postXxcjXxcjTjsh(row)">
|
||||
送审
|
||||
</el-link>
|
||||
<el-link @click="handleSbqt(row)" size="small" type="primary" v-if="isShiQzRole && row.sfsbqt == '0'"
|
||||
:disabled="row.sfsbqt != '0'">上报区厅</el-link>
|
||||
<el-link v-if="canShowBtn('送审', row) && isCityLevel && row.lczt == '04'" :disabled="row.sldshzt != '00'"
|
||||
size="small" type="primary" @click="postXxcjXxcjTjsh(row)">送审</el-link>
|
||||
|
||||
<!-- <el-link
|
||||
v-if="isShowBtn('送审', row) && qxkz.deptLevel == '02'"
|
||||
:disabled="row.xldshzt != '00' "
|
||||
size="small" type="primary"
|
||||
@click="postXxcjXxcjTjsh(row)">
|
||||
送审
|
||||
</el-link> -->
|
||||
<el-link v-if="canShowBtn('上报') && !isCityLevel" size="small" type="primary" @click="appearNewspapers(row)"
|
||||
:disabled="!canReport(row)">上报</el-link>
|
||||
|
||||
<!-- (01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商)v-if="qxkz.deptLevel == '01'" -->
|
||||
<el-link v-if="canShowBtn('分组') && canGroup(row)" size="small" type="primary"
|
||||
@click="opneMsg(row)">分组</el-link>
|
||||
|
||||
<el-link v-if="isShowBtn('上报') && qxkz.deptLevel == '03'" size="small" type="primary" @click="appearNewspapers(row)" :disabled="row.lczt != '01'">上报</el-link>
|
||||
<el-link v-else-if="isShowBtn('上报')" size="small" type="primary" @click="appearNewspapers(row)" :disabled="!(row.xldshzt == '02'&&row.lczt == '02')">上报</el-link>
|
||||
<!-- && row.lczt != '02' -->
|
||||
<el-link v-if="isShowBtn('分组')" size="small" type="primary" @click="opneMsg(row)"
|
||||
:disabled="row.sldshzt != '02'">分组</el-link>
|
||||
<!-- 只有领导有肯定 -->
|
||||
<!-- <el-link v-if="isShowBtn('肯定')" size="small" type="primary" @click="affirm(row)">肯定</el-link> -->
|
||||
<el-link v-if="isShowBtn('删除')" size="small" type="primary" @clic.stopk="delDictItem(row.id)">删除</el-link>
|
||||
<el-link v-if="isShowBtn('修改', row)" size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
|
||||
<el-link v-if="isShowBtn('续报', row)" size="small" type="primary"
|
||||
<el-link v-if="canShowBtn('删除')" size="small" type="primary" @click.stop="delDictItem(row.id)">删除</el-link>
|
||||
<el-link v-if="canShowBtn('修改', row)" size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
|
||||
<el-link v-if="canShowBtn('续报', row) && canFollowUpReport(row)" size="small" type="primary"
|
||||
@click="addEdit('followUpReport', row)">续报</el-link>
|
||||
|
||||
<el-link v-if="isShowBtn('详情')" size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
|
||||
<!-- 所有状态都能进行转线索 -->
|
||||
<el-link v-if="isShowBtn('转线索')" size="small" type="primary" @click="FollowUpOnLeads(row)"
|
||||
:disabled="row.sldshzt != '02'">转线索</el-link>
|
||||
<!-- 所有状态都能进行转合成 -->
|
||||
<!-- <el-link v-if="isShowBtn('转合成')" size="small" type="primary" @click="openFkDialogszl(row)" :disabled="butcontroll('01', row.lczt)">转合成</el-link> -->
|
||||
<!-- 所有状态都能进行转会商 -->
|
||||
<!-- <el-link v-if="isShowBtn('转会商')" size="small" type="primary" @click="handleTransferMerchant(row)" :disabled="butcontroll('01', row.lczt)">转会商</el-link> -->
|
||||
<el-link v-if="canShowBtn('详情')" size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
|
||||
|
||||
<el-link v-if="isShowBtn('关注部门') && row.qbjb=='01'" :disabled="row.sldshzt != '02'" size="small" type="primary" @click="FollowUpOnDept(row)">定向关注</el-link>
|
||||
<!-- 市局能给所有数据创建标签 -->
|
||||
<el-link v-if="isShowBtn('打标签')" size="small" type="primary" @click="openCustomTag(row)" :disabled="row.sldshzt != '02'">打标签</el-link>
|
||||
<el-link size="small" type="primary" @click="handleAttention(row)">{{ row.sfgz == '1' ? '取消关注':'关注'}}</el-link>
|
||||
<el-link v-if="isShiQzRole && row.sfzxs == '0'" size="small" type="primary" @click="FollowUpOnLeads(row)"
|
||||
:disabled="row.sfzxs != '0'">转线索</el-link>
|
||||
|
||||
<el-link v-if="isShiQzRole" size="small" type="primary" @click="FollowUpOnDept(row)">@</el-link>
|
||||
|
||||
<el-link v-if="canShowBtn('打标签') && canTag(row)" size="small" type="primary"
|
||||
@click="openCustomTag(row)">打标签</el-link>
|
||||
<el-link size="small" type="primary" @click="handleAttention(row)">{{ row.sfgz == '1'
|
||||
? '取消关注' : '关注' }}</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
@ -123,46 +111,20 @@
|
||||
<AddForm ref="detailDiloag" @getList="getList" :titleData="titleData" :dict="{ D_BZ_LCZT, D_BZ_SSSHZT }" />
|
||||
</div>
|
||||
|
||||
<ExportFile
|
||||
v-model="exportFileModel"
|
||||
:tableColumn="tableColumn"
|
||||
:dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
|
||||
:dataModel="pageData.tableData"
|
||||
/>
|
||||
<ExportFile v-model="exportFileModel" :tableColumn="tableColumn" :dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
|
||||
:dataModel="pageData.tableData" />
|
||||
|
||||
<MakeTag
|
||||
v-model="chooseRow"
|
||||
:dataList="dataList"
|
||||
:dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
|
||||
@getList="getList"
|
||||
/>
|
||||
<MakeTag v-model="chooseRow" :dataList="dataList" :dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
|
||||
@getList="getList" />
|
||||
|
||||
<Fszl
|
||||
v-model="fszlShow"
|
||||
path="/xxcj/sendFqzl"
|
||||
:itemData="dataList"
|
||||
/>
|
||||
<Fszl v-model="fszlShow" path="/xxcj/sendFqzl" :itemData="dataList" />
|
||||
|
||||
<CustomTag
|
||||
v-model="customTagShow"
|
||||
:dataList="dataList"
|
||||
@getList="getList"
|
||||
:dict="{ D_XXCJ_BQLX }"
|
||||
/>
|
||||
<Configuration
|
||||
v-model="configurationShow"
|
||||
:dataList="dataList"
|
||||
@getList="getList"
|
||||
/>
|
||||
<CustomTag v-model="customTagShow" :dataList="dataList" @getList="getList" :dict="{ D_XXCJ_BQLX }" />
|
||||
<Configuration v-model="configurationShow" :dataList="dataList" @getList="getList" />
|
||||
|
||||
<!-- 转会商 -->
|
||||
<transferMerchant
|
||||
v-if="isShowTransferMerchantTc"
|
||||
:row="currRow"
|
||||
title="转会商"
|
||||
@close="isShowTransferMerchantTc = false"
|
||||
@ok="getList"
|
||||
/>
|
||||
<transferMerchant v-if="isShowTransferMerchantTc" :row="currRow" title="转会商" @close="isShowTransferMerchantTc = false"
|
||||
@ok="getList" />
|
||||
|
||||
<!-- 情报信息报告 -->
|
||||
<InforReport v-if="inforReportShow" v-model="inforReportShow" :data="tableList" />
|
||||
@ -178,28 +140,28 @@ import Searchs from "@/components/aboutTable/Search.vue";
|
||||
import AddForm from "./components/addForm.vue";
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { qbcjSelectQbsbPage, qbcjDeletes, qbcjCzzt, qbcjPlsb } from "@/api/Intelligence.js";
|
||||
import { xxcjSelectXxsbPage, xxcjDeletes, xxcjXxzsx, xxcjUpdateCzlc, xxcjXxqd, xxcjXxcjTjsh ,xxcjCare, xxcjReportGat} from '@/api/xxcj.js'
|
||||
import { xxcjSelectXxsbPage, xxcjDeletes, xxcjXxzsx, xxcjUpdateCzlc, xxcjXxqd, xxcjXxcjTjsh, xxcjCare, xxcjReportGat, xxcjPlsb } from '@/api/xxcj.js'
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import MakeTag from '../components/maketag.vue'
|
||||
import ExportFile from './components/exportFile.vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { getItem } from '@//utils/storage.js'
|
||||
import Fszl from '@/views/backOfficeSystem/HumanIntelligence/components/fszl.vue'
|
||||
import CustomTag from '../components/customTag.vue'
|
||||
import Configuration from '../components/configuration.vue'
|
||||
import transferMerchant from "./components/transferMerchant.vue";
|
||||
import { Edit } from "@element-plus/icons";
|
||||
import { useInfoCollectionPermission } from './useInfoCollectionPermission.js'
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_XS_LY, D_BZ_SSSHZT, D_GS_XS_LX, D_BZ_BQJB,D_BZ_QBCZZT, D_BZ_CJLX, D_BZ_LCZT,D_XXCJ_BQLX } = proxy.$dict( "D_GS_XS_LY", 'D_BZ_SSSHZT',"D_GS_XS_LX", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB", "D_BZ_LCZT", "D_XXCJ_BQLX"); //获取字典数据
|
||||
const { D_BZ_SF, D_GS_XS_LY, /* D_BZ_SSSHZT, */ D_GS_XS_LX, D_BZ_BQJB, D_BZ_QBCZZT, D_BZ_CJLX, D_BZ_LCZT, D_XXCJ_BQLX } = proxy.$dict("D_BZ_SF", "D_GS_XS_LY" /*, 'D_BZ_SSSHZT' */, "D_GS_XS_LX", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB", "D_BZ_LCZT", "D_XXCJ_BQLX"); //获取字典数据
|
||||
const route = useRoute()
|
||||
const titleData = ref()
|
||||
const exportFileModel = ref(false)
|
||||
const qxkz = reactive({
|
||||
deptBizType: '',
|
||||
deptLevel: '',
|
||||
roleCode: false,
|
||||
depBool: false
|
||||
});
|
||||
|
||||
// 使用权限管理模块
|
||||
const permission = useInfoCollectionPermission()
|
||||
const { state: qxkz, isCityLevel, isShiQzRole, canShowBtn, butcontroll, canReport, canTag, canFollowDept, canTransferClue, canGroup, canFollowUpReport, isPostAdopt } = permission
|
||||
|
||||
const fszlShow = ref(false)// 发送指令
|
||||
const detailDiloag = ref();
|
||||
const inforReportShow = ref(false) //情报信息报告
|
||||
@ -221,6 +183,8 @@ const searchConfiger = ref([
|
||||
{ label: "标签级别", prop: 'qbjb', placeholder: "请选择标签级别", showType: "select", options: D_BZ_BQJB },
|
||||
{ label: "情报处置状态", prop: 'lczt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_LCZT },
|
||||
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
|
||||
{ label: "是否上报区厅", prop: 'sfsbqt', placeholder: "请选择是否上报区厅", showType: "select", options: D_BZ_SF },
|
||||
{ label: "是否关注", prop: 'sfgz', placeholder: "请选择是否关注", showType: "select", options: D_BZ_SF },
|
||||
]);
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
@ -240,7 +204,7 @@ const pageData = reactive({
|
||||
{ label: "情报上报时间", prop: "sxsbsj" },
|
||||
{ label: "情报编号", prop: "xsBh" },
|
||||
{ label: "情报标题", prop: "qbmc" },
|
||||
{ label: "情报来源", prop: "qbly", showSolt: true },
|
||||
{ label: "分组状态", prop: "qbjb", showSolt: true },
|
||||
{ label: "上报人", prop: "xssbr" },
|
||||
{ label: "上报单位", prop: "ssbm" },
|
||||
{ label: "流程状态", prop: "lczt", showSolt: true },
|
||||
@ -337,6 +301,8 @@ const rollbackNewspapers = (item) => {
|
||||
}
|
||||
// 上报
|
||||
const appearNewspapers = (item) => {
|
||||
console.log(item);
|
||||
|
||||
if ((item.lczt == '01' || item.lczt == '05' || item.lczt == '02') && item.qbjb == '00' && qxkz.deptLevel != '01') {
|
||||
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
|
||||
let promes = { id: item.id }
|
||||
@ -403,7 +369,8 @@ const handleSumbit = () => {
|
||||
const listDb = tableList.value.filter(item => item.czzt != '01' && item.czzt != '04')
|
||||
if (listDb.length == 0) {
|
||||
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
|
||||
qbcjPlsb({ ids: ids.value, qbjb: '00' }).then(res => {
|
||||
const lczt = qxkz.deptLevel == '02' ? '03' : '02';
|
||||
xxcjPlsb({ ids: ids.value, lczt: lczt }).then(res => {
|
||||
proxy.$message({ type: "success", message: "上报成功" });
|
||||
getList();
|
||||
})
|
||||
@ -412,23 +379,30 @@ const handleSumbit = () => {
|
||||
proxy.$message({ message: '请选择正确数据', type: 'warning', showClose: true })
|
||||
}
|
||||
}
|
||||
// 上报区厅
|
||||
const provDepar = () => {
|
||||
const listDb = tableList.value.filter(item => item.czzt != '10').map(item => item.id)
|
||||
if (listDb.length > 0) {
|
||||
proxy.$confirm("确定要上报区厅吗", "提示", { type: "warning" }).then(() => {
|
||||
xxcjReportGat({ ids: listDb }).then(res => {
|
||||
proxy.$message({ type: "success", message: "上报区厅成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { })
|
||||
|
||||
// <!-- [04、06、07、08、09] -->打标签
|
||||
// <!-- [03、05] -->采纳
|
||||
// <!-- [04] -->回退
|
||||
// <!-- (01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商)v-if="qxkz.deptLevel == '01'" -->
|
||||
const butcontroll = (val, zt) => {
|
||||
switch (val) {
|
||||
case '01':
|
||||
return !(['04', '06', '07', '08', '09'].includes(zt))
|
||||
case '02':
|
||||
return !(['03', '05'].includes(zt))
|
||||
case '03':
|
||||
return !(['02', '03', '04'].includes(zt))
|
||||
case '04':
|
||||
return (['04', '05', '06', '07', '08', '09'].includes(zt))
|
||||
|
||||
|
||||
// proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
|
||||
// xxcjPlsb({ ids: ids.value, lczt: "10" }).then(res => {
|
||||
// proxy.$message({ type: "success", message: "上报成功" });
|
||||
// getList();
|
||||
// })
|
||||
// }).catch(() => { });
|
||||
} else {
|
||||
proxy.$message({ message: '请选择正确数据', type: 'warning', showClose: true })
|
||||
}
|
||||
}
|
||||
// 按钮状态控制已迁移至 useInfoCollectionPermission
|
||||
|
||||
// 搜索
|
||||
const onSearch = (val) => {
|
||||
@ -436,7 +410,7 @@ const onSearch = (val) => {
|
||||
...pageData.pageConfiger,
|
||||
...val,
|
||||
startTime: val.startTime ? val.startTime[0] : '',
|
||||
endTime: val.endTime ? val.endTime[1] : '',
|
||||
endTime: val.startTime ? val.startTime[1] : '',
|
||||
bqdmList: val.bqdmList ? val.bqdmList.join(',') : ""
|
||||
}
|
||||
queryFrom.value = { ...promes }
|
||||
@ -525,42 +499,7 @@ const openFkDialogszl = (row) => {
|
||||
}
|
||||
|
||||
}
|
||||
/** 获取当前角色 */
|
||||
function getRole() {
|
||||
const { deptBizType, deptLevel } = getItem('deptId')[0]
|
||||
/** 是否是市情指领导 */
|
||||
const isShiQzLeader = getItem('roleList').find(item => item.roleCode == 'JS_666666') != undefined
|
||||
if (isShiQzLeader) return '市情指领导'
|
||||
/** 是否是市情指人员 */
|
||||
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
|
||||
if (isShiQz) return '市情指挥人员'
|
||||
/** 是否是县情指人员 */
|
||||
const isXianQz = getItem('roleList').find(item => item.roleCode == 'JS_888888') != undefined
|
||||
if (isXianQz) return '县情指人员'
|
||||
return '部门'
|
||||
}
|
||||
/** 是否展示按钮 */
|
||||
const isShowBtn = (btnName, row = {}) => {
|
||||
/** @type {String} 流程状态(01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 08 转线索) */
|
||||
const lczt = row.lczt
|
||||
/** 按钮权限 */
|
||||
const buttonPermissions = {
|
||||
"市情指领导": ["肯定", "采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门"],
|
||||
"市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"],
|
||||
"县情指人员": ["上报", "回退", "修改", "详情", "送审"],
|
||||
"部门": ["上报", "新增", "修改", "续报", "详情"]
|
||||
};
|
||||
|
||||
const role = getRole(); // 角色
|
||||
const isHadAuth = buttonPermissions[role]?.includes(btnName) // 当前角色所有会显示的按钮
|
||||
if (!isHadAuth) return false
|
||||
// 拦截部分逻辑
|
||||
if (role === '部门') {
|
||||
if (btnName === '续报') return lczt != '01'
|
||||
if (btnName === '修改') return lczt == '01'
|
||||
}
|
||||
return true
|
||||
}
|
||||
// 权限相关函数已迁移至 useInfoCollectionPermission
|
||||
const handleTransferMerchant = (row) => {
|
||||
currRow.value = row
|
||||
isShowTransferMerchantTc.value = true
|
||||
@ -586,18 +525,8 @@ const handleSbqt = (row) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const { deptBizType, deptLevel } = getItem('deptId')[0]
|
||||
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
|
||||
qxkz.roleCode = getItem('roleList').find(item => item.roleCode == 'JS_666666') != undefined
|
||||
qxkz.deptBizType = deptBizType
|
||||
qxkz.deptLevel = Jb
|
||||
if (deptBizType == '23' && Jb == '01') {
|
||||
qxkz.depBool = true
|
||||
} else {
|
||||
qxkz.depBool = false
|
||||
}
|
||||
|
||||
console.log(qxkz,'=======qxkz');
|
||||
// 初始化权限
|
||||
permission.initPermission()
|
||||
|
||||
titleData.value = route.meta.title
|
||||
tabHeightFn()
|
||||
|
||||
@ -0,0 +1,261 @@
|
||||
import { reactive, computed } from 'vue'
|
||||
import { getItem } from '@//utils/storage.js'
|
||||
|
||||
/** 流程状态常量 */
|
||||
export const FlowStatus = {
|
||||
SUBMIT: '01', // 提交
|
||||
REPORT_COUNTY: '02', // 上报县局
|
||||
REPORT_CITY: '03', // 上报市局
|
||||
ADOPT: '04', // 采纳
|
||||
ROLLBACK: '05', // 退回
|
||||
TAG: '06', // 打标签
|
||||
TRANSFER_SYNTHESIS: '07', // 转合成
|
||||
TRANSFER_CLUE: '08', // 转线索
|
||||
TRANSFER_MERCHANT: '09', // 转会商
|
||||
REPORT_PROVINCE: '10' // 上报区厅
|
||||
}
|
||||
|
||||
/** 按钮权限配置 */
|
||||
const BUTTON_PERMISSIONS = {
|
||||
'市情指领导': ['肯定', '采纳', '回退', '分组', '转线索', '转合成', '转会商', '打标签', '修改', '详情', '关注部门'],
|
||||
'市情指挥人员': ['采纳', '回退', '分组', '转线索', '转合成', '转会商', '打标签', '修改', '详情', '关注部门', '送审'],
|
||||
'县情指人员': ['上报', '回退', '修改', '详情', '送审'],
|
||||
'部门': ['上报', '新增', '修改', '续报', '详情']
|
||||
}
|
||||
|
||||
/** 部门级别映射 */
|
||||
const DEPT_LEVEL_MAP = {
|
||||
'2': '01', // 市局
|
||||
'3': '02', // 县局
|
||||
}
|
||||
|
||||
/** 角色代码映射 */
|
||||
const ROLE_CODE_MAP = {
|
||||
'JS_666666': '市情指领导',
|
||||
'JS_777777': '市情指挥人员',
|
||||
'JS_888888': '县情指人员',
|
||||
}
|
||||
|
||||
/** 采纳后的状态(排除回退05) */
|
||||
const POST_ADOPT_STATUS = [FlowStatus.ADOPT, FlowStatus.TAG, FlowStatus.TRANSFER_SYNTHESIS, FlowStatus.TRANSFER_CLUE, FlowStatus.TRANSFER_MERCHANT, FlowStatus.REPORT_PROVINCE]
|
||||
|
||||
/** 按钮可操作的状态配置 */
|
||||
const BTN_STATUS_RULES = {
|
||||
// 转合成/转会商 - 需要已采纳
|
||||
synthesis: [FlowStatus.ADOPT, FlowStatus.TAG, FlowStatus.TRANSFER_SYNTHESIS, FlowStatus.TRANSFER_CLUE, FlowStatus.TRANSFER_MERCHANT],
|
||||
// 采纳 - 需要上报状态
|
||||
adopt: [FlowStatus.REPORT_CITY, FlowStatus.ROLLBACK],
|
||||
// 回退 - 需要上报状态
|
||||
rollback: [FlowStatus.ADOPT, FlowStatus.ROLLBACK, FlowStatus.TAG, FlowStatus.TRANSFER_SYNTHESIS, FlowStatus.TRANSFER_CLUE, FlowStatus.TRANSFER_MERCHANT],
|
||||
// 分组 - 需要已采纳或已转
|
||||
group: [FlowStatus.ADOPT, FlowStatus.TRANSFER_CLUE, FlowStatus.REPORT_PROVINCE],
|
||||
}
|
||||
|
||||
/**
|
||||
* 情报信息采集权限管理 Composable
|
||||
*/
|
||||
export function useInfoCollectionPermission() {
|
||||
/** 权限状态 */
|
||||
const state = reactive({
|
||||
deptBizType: '',
|
||||
deptLevel: '',
|
||||
roleCode: false,
|
||||
depBool: false
|
||||
})
|
||||
|
||||
/** 当前角色 */
|
||||
const currentRole = computed(() => getRole())
|
||||
|
||||
/** 是否为市局 */
|
||||
const isCityLevel = computed(() => state.deptLevel === '01')
|
||||
|
||||
/** 是否为县局 */
|
||||
const isCountyLevel = computed(() => state.deptLevel === '02')
|
||||
|
||||
/** 是否有市情指操作权限(JS_666666 或 JS_777777) */
|
||||
const isShiQzRole = computed(() => {
|
||||
const roleList = getItem('roleList') || []
|
||||
return roleList.some(item => item.roleCode === 'JS_666666' || item.roleCode === 'JS_777777')
|
||||
})
|
||||
|
||||
/** 获取当前角色 */
|
||||
function getRole() {
|
||||
const roleList = getItem('roleList') || []
|
||||
|
||||
for (const role of roleList) {
|
||||
if (ROLE_CODE_MAP[role.roleCode]) {
|
||||
return ROLE_CODE_MAP[role.roleCode]
|
||||
}
|
||||
}
|
||||
return '部门'
|
||||
}
|
||||
|
||||
/** 初始化权限 */
|
||||
function initPermission() {
|
||||
const deptInfo = getItem('deptId')?.[0]
|
||||
if (!deptInfo) return
|
||||
|
||||
const { deptBizType, deptLevel } = deptInfo
|
||||
const levelCode = deptLevel?.[0]
|
||||
|
||||
// 计算部门级别
|
||||
state.deptLevel = DEPT_LEVEL_MAP[levelCode] || levelCode
|
||||
state.deptBizType = deptBizType
|
||||
|
||||
// 是否为市情指领导
|
||||
state.roleCode = getItem('roleList')?.some(item => item.roleCode === 'JS_666666') ?? false
|
||||
|
||||
// 是否有市情指操作权限
|
||||
state.depBool = deptBizType === '23' && state.deptLevel === '01'
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断按钮是否显示
|
||||
* @param {string} btnName 按钮名称
|
||||
* @param {object} row 行数据(可选)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canShowBtn(btnName, row = {}) {
|
||||
const role = currentRole.value
|
||||
const permissions = BUTTON_PERMISSIONS[role] || []
|
||||
|
||||
if (!permissions.includes(btnName)) return false
|
||||
|
||||
// 部门角色特殊逻辑
|
||||
if (role === '部门') {
|
||||
const lczt = row?.lczt
|
||||
if (btnName === '续报') return lczt !== FlowStatus.SUBMIT
|
||||
if (btnName === '修改') return lczt === FlowStatus.SUBMIT
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断按钮是否禁用
|
||||
* @param {string} btnType 按钮类型
|
||||
* @param {string} lczt 流程状态
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isBtnDisabled(btnType, lczt) {
|
||||
const allowedStatus = BTN_STATUS_RULES[btnType]
|
||||
return !allowedStatus?.includes(lczt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断单个按钮是否禁用(兼容旧逻辑)
|
||||
* @param {string} val 类型代码
|
||||
* @param {string} zt 流程状态
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function butcontroll(val, zt) {
|
||||
switch (val) {
|
||||
case '01': // 转合成/转会商
|
||||
return !BTN_STATUS_RULES.synthesis.includes(zt)
|
||||
case '02': // 采纳
|
||||
return !BTN_STATUS_RULES.adopt.includes(zt)
|
||||
case '03': // 提交
|
||||
return ![FlowStatus.REPORT_COUNTY, FlowStatus.REPORT_CITY, FlowStatus.ADOPT].includes(zt)
|
||||
case '04': // 采纳 - 只有01,02,03状态才不禁用
|
||||
return !['01', '02', '03'].includes(zt)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断送审按钮状态
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canSubmitAudit(row) {
|
||||
return isCityLevel.value && row.lczt === FlowStatus.ADOPT && row.sldshzt === '00'
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断上报按钮状态
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canReport(row) {
|
||||
if (isCityLevel.value) {
|
||||
return row.lczt === FlowStatus.SUBMIT
|
||||
}
|
||||
return row.lczt === FlowStatus.REPORT_COUNTY
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为采纳后状态(排除回退)
|
||||
* @param {string} lczt 流程状态
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isPostAdopt(lczt) {
|
||||
return POST_ADOPT_STATUS.includes(lczt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断打标签按钮状态
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canTag(row) {
|
||||
return isPostAdopt(row.lczt) && isCityLevel.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断关注部门按钮状态
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canFollowDept(row) {
|
||||
return row.qbjb === '01' && isPostAdopt(row.lczt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断转线索按钮状态 - 采纳后可转,转过则不再显示
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canTransferClue(row) {
|
||||
// 只允许从采纳状态直接转线索,转过则不再显示
|
||||
return row.lczt === FlowStatus.ADOPT
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断分组按钮状态
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canGroup(row) {
|
||||
return isPostAdopt(row.lczt)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断续报按钮状态
|
||||
* @param {object} row 行数据
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function canFollowUpReport(row) {
|
||||
return row.lczt === FlowStatus.ADOPT
|
||||
}
|
||||
|
||||
return {
|
||||
state,
|
||||
currentRole,
|
||||
isCityLevel,
|
||||
isCountyLevel,
|
||||
isShiQzRole,
|
||||
initPermission,
|
||||
canShowBtn,
|
||||
isBtnDisabled,
|
||||
butcontroll,
|
||||
canSubmitAudit,
|
||||
canReport,
|
||||
canTag,
|
||||
canFollowDept,
|
||||
canTransferClue,
|
||||
canGroup,
|
||||
canFollowUpReport,
|
||||
isPostAdopt,
|
||||
}
|
||||
}
|
||||
@ -94,8 +94,9 @@ const formData = ref([
|
||||
{ label: "线索地点", prop: "zxdz", type: "input" },
|
||||
{ label: "所属专题", prop: "sszt", type: "select", options: props.dic.D_BZ_SSZT },
|
||||
{ prop: "gapline", type: "slot", width: '100%' },
|
||||
{ prop: "scfj", type: "slot", width: '100%' },
|
||||
{ label: "线索内容", prop: "qbnr", type: "textarea", width: '100%' },
|
||||
{ prop: "scfj", type: "slot", width: '100%' },
|
||||
|
||||
]);
|
||||
const fjdz = ref()
|
||||
const listQuery = ref({}); //表单
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
</div>
|
||||
<!-- 新增 -->
|
||||
<AddForm ref="detailDiloag" @change="getList" v-if="isShow"
|
||||
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }" />
|
||||
:dic="{ /* D_BZ_SF, */ D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX /*, D_GS_XS_QTLX */ }" />
|
||||
</div>
|
||||
<SubmissionProcess v-model="showSp" :data="rowData"
|
||||
:userData="{ ajmc: '线索数据采集审批', flowType: 'XSSJCJSP', modelName: '线索' }" :path="fixedValue" @getList="getList" />
|
||||
@ -70,7 +70,7 @@ import { useRoute } from 'vue-router'
|
||||
const router = useRouter();
|
||||
const route = useRoute()
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_XS_XSCZZT, D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_GS_XS_QTLX, D_BZ_XB, D_BZ_XSSHZT } = proxy.$dict("D_GS_XS_XSCZZT", "D_GS_XS_LY", "D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX", "D_BZ_XB", "D_BZ_XSSHZT"); //获取字典数据
|
||||
const { D_GS_XS_XSCZZT, D_GS_XS_LY, D_BZ_SSZT, /* D_BZ_SF, */ D_GS_XS_LX, /* D_GS_XS_QTLX, */ D_BZ_XB, D_BZ_XSSHZT } = proxy.$dict("D_GS_XS_XSCZZT", "D_GS_XS_LY", "D_BZ_SSZT" /*, "D_BZ_SF" */, "D_GS_XS_LX" /*, "D_GS_XS_QTLX" */, "D_BZ_XB", "D_BZ_XSSHZT"); //获取字典数据
|
||||
const detailDiloag = ref(null);
|
||||
const searchBox = ref(); //搜索框
|
||||
const isShow = ref(false)
|
||||
|
||||
@ -14,15 +14,9 @@
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="margTop">
|
||||
<MyTable
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount"
|
||||
:tableConfiger="pageData.tableConfiger"
|
||||
:controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData"
|
||||
>
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<template #qblx="{ row }">
|
||||
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
|
||||
</template>
|
||||
@ -43,7 +37,8 @@
|
||||
<!-- <el-link size="small" type="primary" @click="openCheckProcessXb(row)"> 续报</el-link> -->
|
||||
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
|
||||
<el-link size="small" type="primary" @click="handleCase(row)">
|
||||
<span :style="{'color': row.sfgz == '0' ? 'rgb(242,7,7)' : '#dede17'}">{{ row.sfgz == '0' ? '关注' : '取消关注' }}</span>
|
||||
<span :style="{ 'color': row.sfgz == '0' ? 'rgb(242,7,7)' : '#dede17' }">{{ row.sfgz == '0' ? '关注' : '取消关注'
|
||||
}}</span>
|
||||
</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
@ -191,8 +186,13 @@ const pageData = reactive({
|
||||
{ label: "情报上报时间", prop: "sxsbsj" },
|
||||
{ label: "情报编号", prop: "xsBh" },
|
||||
{ label: "情报标题", prop: "qbmc" },
|
||||
{ label: "情报来源", prop: "qbly", showSolt: true },
|
||||
{ label: "流程状态", prop: "lczt", showSolt: true },
|
||||
{ label: "上报人", prop: "xssbr" },
|
||||
{ label: "所属部门", prop: "ssbm" },
|
||||
{ label: "分组人", prop: "fzrxm" },
|
||||
{ label: "分组时间", prop: "fzsj" },
|
||||
|
||||
// { label: "情报来源", prop: "qbly", showSolt: true },
|
||||
// { label: "流程状态", prop: "lczt", showSolt: true },
|
||||
// { label: "消息状态", prop: "czzt", showSolt: true },
|
||||
]
|
||||
});
|
||||
@ -332,8 +332,10 @@ const openFszl = (item) => {
|
||||
type: 'warning',
|
||||
showClose: true,
|
||||
})
|
||||
} else { fszlShow.value = true
|
||||
dataList.value = item }
|
||||
} else {
|
||||
fszlShow.value = true
|
||||
dataList.value = item
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -70,6 +70,30 @@ const searchConfiger = ref([
|
||||
showType: "select",
|
||||
// options: Object.keys(jflylxTypes).map(key => ({ label: jflylxTypes[key], value: key }))
|
||||
},
|
||||
{
|
||||
label: "编号",
|
||||
prop: "baseNo",
|
||||
placeholder: "请输入编号",
|
||||
showType: "input",
|
||||
},
|
||||
{
|
||||
label: "类型名称",
|
||||
prop: "typeName",
|
||||
placeholder: "请输入类型名称",
|
||||
showType: "input",
|
||||
},
|
||||
{
|
||||
label: "标题",
|
||||
prop: "title",
|
||||
placeholder: "请输入标题",
|
||||
showType: "input",
|
||||
},
|
||||
{
|
||||
label: "上报单位",
|
||||
prop: "reportUnitName",
|
||||
placeholder: "请输入上报单位",
|
||||
showType: "input",
|
||||
},
|
||||
]);
|
||||
const searchBox = ref(); //搜索框
|
||||
const pageData = reactive({
|
||||
|
||||
@ -87,7 +87,7 @@ import Search from "@/components/aboutTable/Search.vue";
|
||||
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_SF,D_GS_BK_BKYS,D_BZ_XB,D_GS_BK_SJLX,D_GS_BK_DJ, D_GS_BK_DX, D_GS_BK_ZT,D_GS_BK_CZYQ,D_GS_BK_CZJSDWLX,D_GS_BK_TJFS } = proxy.$dict("D_BZ_SF","D_GS_BK_BKYS","D_BZ_XB","D_GS_BK_SJLX","D_GS_BK_DJ","D_GS_BK_DX","D_GS_BK_ZT","D_GS_BK_CZYQ","D_GS_BK_CZJSDWLX","D_GS_BK_TJFS"); //获取字典数据
|
||||
const { D_BZ_SF,D_GS_BK_BKYS,D_BZ_XB,/*D_GS_BK_SJLX,*/D_GS_BK_DJ, D_GS_BK_DX, D_GS_BK_ZT,D_GS_BK_CZYQ,D_GS_BK_CZJSDWLX,D_GS_BK_TJFS } = proxy.$dict("D_BZ_SF","D_GS_BK_BKYS","D_BZ_XB"/*,"D_GS_BK_SJLX"*/,"D_GS_BK_DJ","D_GS_BK_DX","D_GS_BK_ZT","D_GS_BK_CZYQ","D_GS_BK_CZJSDWLX","D_GS_BK_TJFS"); //获取字典数据
|
||||
const searchBox = ref();
|
||||
const chooseRow = ref({})
|
||||
const btns = ref();
|
||||
|
||||
@ -87,7 +87,7 @@ import Search from "@/components/aboutTable/Search.vue";
|
||||
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_SF,D_GS_BK_BKYS,D_BZ_XB,D_GS_BK_SJLX,D_GS_BK_DJ, D_GS_BK_DX, D_GS_BK_ZT,D_GS_BK_CZYQ,D_GS_BK_CZJSDWLX,D_GS_BK_TJFS } = proxy.$dict("D_BZ_SF","D_GS_BK_BKYS","D_BZ_XB","D_GS_BK_SJLX","D_GS_BK_DJ","D_GS_BK_DX","D_GS_BK_ZT","D_GS_BK_CZYQ","D_GS_BK_CZJSDWLX","D_GS_BK_TJFS"); //获取字典数据
|
||||
const { D_BZ_SF,D_GS_BK_BKYS,D_BZ_XB,/*D_GS_BK_SJLX,*/D_GS_BK_DJ, D_GS_BK_DX, D_GS_BK_ZT,D_GS_BK_CZYQ,D_GS_BK_CZJSDWLX,D_GS_BK_TJFS } = proxy.$dict("D_BZ_SF","D_GS_BK_BKYS","D_BZ_XB"/*,"D_GS_BK_SJLX"*/,"D_GS_BK_DJ","D_GS_BK_DX","D_GS_BK_ZT","D_GS_BK_CZYQ","D_GS_BK_CZJSDWLX","D_GS_BK_TJFS"); //获取字典数据
|
||||
const searchBox = ref();
|
||||
const chooseRow = ref({})
|
||||
const btns = ref();
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="布控详情"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-dialog v-model="visible" title="布控详情" width="800px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-descriptions :column="2" border v-if="detailData">
|
||||
<el-descriptions-item label="布控对象" :span="2">
|
||||
<span v-if="detailData.bkdxList && detailData.bkdxList.length">
|
||||
@ -32,7 +26,7 @@
|
||||
{{ detailData.bkfqrXm || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="布控状态">
|
||||
<DictTag :value="detailData.bkZt" :tag="false" :options="D_GS_BK_ZT" />
|
||||
<DictTag :value="detailData.bkZt" :tag="false" :options="D_ZDRY_BKZT" />
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="不通过原因">
|
||||
{{ detailData.bkspBtgyy || '-' }}
|
||||
@ -50,11 +44,11 @@ import { ref, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const {
|
||||
D_GS_BK_ZT,
|
||||
D_ZDRY_BKZT,
|
||||
D_GS_SSYJ,
|
||||
D_GS_BK_NEWDX
|
||||
} = proxy.$dict(
|
||||
"D_GS_BK_ZT",
|
||||
"D_ZDRY_BKZT",
|
||||
"D_GS_SSYJ",
|
||||
"D_GS_BK_NEWDX"
|
||||
);
|
||||
|
||||
@ -2,12 +2,7 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10 mb10">
|
||||
<QueryFormPanel
|
||||
v-model="queryFrom"
|
||||
:searchArr="searchConfiger"
|
||||
ref="searchDom"
|
||||
@search="onSearch"
|
||||
>
|
||||
<QueryFormPanel v-model="queryFrom" :searchArr="searchConfiger" ref="searchDom" @search="onSearch">
|
||||
<!-- <template #but>
|
||||
<el-button type="primary" size="small" @click="exportExl"
|
||||
>批量导出</el-button
|
||||
@ -17,18 +12,14 @@
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div style="background-color: #fff">
|
||||
<MyTable
|
||||
:tableConfiger="pageData.tableConfiger"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
:controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="handleChooseData"
|
||||
:key="pageData.keyCount"
|
||||
>
|
||||
|
||||
<MyTable :tableConfiger="pageData.tableConfiger" :tableHeight="pageData.tableHeight"
|
||||
:tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="handleChooseData" :key="pageData.keyCount">
|
||||
<template #bkZt="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkZt" :options="D_GS_BK_ZT" />
|
||||
<DictTag :tag="false" :value="row.bkZt" :options="D_ZDRY_BKZT" />
|
||||
</template>
|
||||
<template #shzt="{ row }">
|
||||
<DictTag :tag="false" :value="row.shzt" :options="D_GS_BK_ZT" />
|
||||
</template>
|
||||
<template #bkDj="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkDj" :options="D_GS_SSYJ" />
|
||||
@ -44,18 +35,13 @@
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" @click="handleDetail(row)">详情</el-link>
|
||||
<el-link type="success" @click="handleApprove(row)" v-if="row.bkZt == '02'">审核</el-link>
|
||||
<el-link type="success" @click="handleApprove(row)" v-if="row.shzt == '02'">审核</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages
|
||||
@changeNo="changeNo"
|
||||
@changeSize="changeSize"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:pageConfiger="{
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"
|
||||
></Pages>
|
||||
}"></Pages>
|
||||
</div>
|
||||
<!-- 详情弹窗 -->
|
||||
<DetailDialog ref="detailDialogRef" />
|
||||
@ -77,7 +63,7 @@ import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const { D_GS_BK_DJ, D_GS_BK_YZ, D_GS_BK_ZT, D_GS_SSYJ, D_GS_BK_NEWDX } = proxy.$dict( "D_GS_BK_DJ", "D_GS_BK_YZ", "D_GS_BK_ZT", "D_GS_SSYJ", "D_GS_BK_NEWDX" );
|
||||
const { D_GS_BK_DJ, D_GS_BK_YZ, D_GS_BK_ZT, D_GS_SSYJ, D_GS_BK_NEWDX, D_ZDRY_BKZT } = proxy.$dict("D_GS_BK_DJ", "D_GS_BK_YZ", "D_GS_BK_ZT", "D_GS_SSYJ", "D_GS_BK_NEWDX", "D_ZDRY_BKZT");
|
||||
|
||||
const searchBox = ref();
|
||||
const searchConfiger = ref([
|
||||
@ -100,6 +86,13 @@ const searchConfiger = ref([
|
||||
prop: "bkZt",
|
||||
placeholder: "请选择布控状态",
|
||||
showType: "select",
|
||||
options: D_ZDRY_BKZT
|
||||
},
|
||||
{
|
||||
label: "审核状态",
|
||||
prop: "shzt",
|
||||
placeholder: "请选择审核状态",
|
||||
showType: "select",
|
||||
options: D_GS_BK_ZT
|
||||
},
|
||||
{
|
||||
@ -142,6 +135,7 @@ const pageData = reactive({
|
||||
{ label: "结束时间", prop: "bkSjJs", showOverflowTooltip: true },
|
||||
{ label: "申请人", prop: "bkfqrXm" },
|
||||
{ label: "布控状态", prop: "bkZt", showSolt: true },
|
||||
{ label: "审核状态", prop: "shzt", showSolt: true },
|
||||
]
|
||||
});
|
||||
|
||||
@ -245,5 +239,4 @@ const tabHeightFn = () => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -2,12 +2,7 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10 mb10">
|
||||
<QueryFormPanel
|
||||
v-model="queryFrom"
|
||||
:fields="searchConfiger"
|
||||
ref="searchDom"
|
||||
@search="onSearch"
|
||||
>
|
||||
<QueryFormPanel v-model="queryFrom" :fields="searchConfiger" ref="searchDom" @search="onSearch">
|
||||
<!-- <template #but>
|
||||
<el-button type="primary" size="small" @click="exportExl"
|
||||
>批量导出</el-button
|
||||
@ -17,37 +12,37 @@
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div style="background-color: #fff">
|
||||
<MyTable
|
||||
:tableConfiger="pageData.tableConfiger"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
:controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="handleChooseData"
|
||||
>
|
||||
<template #bkdj="{ row }">
|
||||
<DictTag :value="row.bkdj" :tag="false" :options="D_GS_BK_DJ" />
|
||||
<MyTable :tableConfiger="pageData.tableConfiger" :tableHeight="pageData.tableHeight"
|
||||
:tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="handleChooseData" :key="pageData.keyCount">
|
||||
|
||||
<template #bkZt="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkZt" :options="D_ZDRY_BKZT" />
|
||||
</template>
|
||||
<template #byz="{ row }">
|
||||
<DictTag :value="row.byz" :tag="false" :options="D_GS_BK_YZ" />
|
||||
<template #shzt="{ row }">
|
||||
<DictTag :tag="false" :value="row.shzt" :options="D_GS_BK_ZT" />
|
||||
</template>
|
||||
<template #qyzt="{ row }">
|
||||
<DictTag :value="row.qyzt" :tag="false" :options="D_GS_BK_ZT" />
|
||||
<template #bkDj="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkDj" :options="D_GS_SSYJ" />
|
||||
</template>
|
||||
<template #bkDx="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkDx" :options="D_GS_BK_NEWDX" />
|
||||
</template>
|
||||
<template #bkdxList="{ row }">
|
||||
<span v-if="row.bkdxList"><span class="nowrap" v-for="(it, idx) in row.bkdxList" :key="idx">
|
||||
{{ it.ryXm ? it.ryXm : it.imei ? it.imei : it.imsi ? it.imsi : it.rySfzh }}
|
||||
<span v-if="idx < row.bkdxList.length - 1">、</span></span></span>
|
||||
<span v-else>暂无</span>
|
||||
</template>
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" @click="handleDetail(row)">详情</el-link>
|
||||
<el-link type="success" @click="handleApprove(row)" v-if="row.bkZt == '02'">审核</el-link>
|
||||
<el-link type="success" @click="handleApprove(row)" v-if="row.shzt == '02'">审核</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages
|
||||
@changeNo="changeNo"
|
||||
@changeSize="changeSize"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:pageConfiger="{
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"
|
||||
></Pages>
|
||||
}"></Pages>
|
||||
</div>
|
||||
<!-- 详情弹窗 -->
|
||||
<DetailDialog ref="detailDialogRef" />
|
||||
@ -73,12 +68,18 @@ const {
|
||||
D_GS_BK_DJ,
|
||||
D_GS_BK_YZ,
|
||||
D_GS_BK_ZT,
|
||||
D_BZ_JQDJ
|
||||
D_BZ_JQDJ,
|
||||
D_GS_BK_NEWDX,
|
||||
D_GS_SSYJ,
|
||||
D_ZDRY_BKZT
|
||||
} = proxy.$dict(
|
||||
"D_GS_BK_DJ",
|
||||
"D_GS_BK_YZ",
|
||||
"D_GS_BK_ZT",
|
||||
'D_BZ_JQDJ'
|
||||
'D_BZ_JQDJ',
|
||||
"D_GS_BK_NEWDX",
|
||||
"D_GS_SSYJ",
|
||||
"D_ZDRY_BKZT"
|
||||
);
|
||||
|
||||
const searchBox = ref();
|
||||
@ -137,10 +138,14 @@ const pageData = reactive({
|
||||
},
|
||||
controlsWidth: 200,
|
||||
tableColumn: [
|
||||
{ prop: "bkbt", label: "布控标题" },
|
||||
{ prop: "bkdj", label: "布控等级", align: "center", showSolt: true },
|
||||
{ prop: "byz", label: "布控要旨", align: "center", showSolt: true },
|
||||
{ prop: "qyzt", label: "布控状态", align: "center", showSolt: true }
|
||||
{ label: "布控对象", prop: "bkdxList", showSolt: true, showOverflowTooltip: true },
|
||||
{ label: "布控类型", prop: "bkDx", showSolt: true, showOverflowTooltip: true },
|
||||
{ label: "布控等级", prop: "bkDj", showSolt: true },
|
||||
{ label: "开始时间", prop: "bkSjKs", showOverflowTooltip: true },
|
||||
{ label: "结束时间", prop: "bkSjJs", showOverflowTooltip: true },
|
||||
{ label: "申请人", prop: "bkfqrXm" },
|
||||
{ label: "布控状态", prop: "bkZt", showSolt: true },
|
||||
{ label: "审核状态", prop: "shzt", showSolt: true },
|
||||
]
|
||||
});
|
||||
|
||||
@ -234,5 +239,4 @@ const tabHeightFn = () => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -83,7 +83,17 @@
|
||||
import { qcckGet } from "@/api/qcckApi.js";
|
||||
import { defineProps, ref, getCurrentInstance, watch } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_BQ_DJ, D_GS_SSYJ,D_GS_BQ_LB,D_GS_BQ_LX } = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ","D_GS_BQ_LB","D_GS_BQ_LX"); //获取字典数据
|
||||
const {
|
||||
D_GS_BQ_DJ,
|
||||
// D_GS_SSYJ,
|
||||
D_GS_BQ_LB,
|
||||
D_GS_BQ_LX
|
||||
} = proxy.$dict(
|
||||
"D_GS_BQ_DJ",
|
||||
// "D_GS_SSYJ",
|
||||
"D_GS_BQ_LB",
|
||||
"D_GS_BQ_LX"
|
||||
); //获取字典数据
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
|
||||
@ -54,7 +54,17 @@
|
||||
import { qcckGet } from "@/api/qcckApi.js";
|
||||
import { defineProps, ref, getCurrentInstance, watch } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_BQ_DJ, D_GS_SSYJ, D_GS_BQ_LB, D_GS_BQ_LX } = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ", "D_GS_BQ_LB", "D_GS_BQ_LX"); //获取字典数据
|
||||
const {
|
||||
D_GS_BQ_DJ,
|
||||
D_GS_SSYJ,
|
||||
// D_GS_BQ_LB,
|
||||
D_GS_BQ_LX
|
||||
} = proxy.$dict(
|
||||
"D_GS_BQ_DJ",
|
||||
"D_GS_SSYJ",
|
||||
// "D_GS_BQ_LB",
|
||||
"D_GS_BQ_LX"
|
||||
); //获取字典数据
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
|
||||
@ -3,49 +3,21 @@
|
||||
<div class="head_box">
|
||||
<span class="title">布控对象</span>
|
||||
<div>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
v-if="!disabled"
|
||||
:loading="loading"
|
||||
@click="submit"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button size="small" type="primary" v-if="!disabled" :loading="loading" @click="submit">保存</el-button>
|
||||
<el-button size="small" @click="close">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<div :class="dataOrge.gzlid ? 'ww80' : 'ww100'">
|
||||
<div class="form_cnt">
|
||||
<el-form
|
||||
:model="listQuery"
|
||||
:rules="rules"
|
||||
:disabled="disabled"
|
||||
ref="elform"
|
||||
inline
|
||||
:label-width="100"
|
||||
label-position="left"
|
||||
>
|
||||
<el-form :model="listQuery" :rules="rules" :disabled="disabled" ref="elform" inline :label-width="100"
|
||||
label-position="left">
|
||||
<div class="flex align-center mb10">
|
||||
<el-radio-group
|
||||
v-model="listQuery.bkDx"
|
||||
size="large"
|
||||
fill="#6cf"
|
||||
@change="shangeDx"
|
||||
>
|
||||
<el-radio-button
|
||||
:label="item.dm"
|
||||
v-for="(item, index) in props.dic.D_GS_BK_NEWDX"
|
||||
:key="index"
|
||||
>{{ item.zdmc }}</el-radio-button
|
||||
>
|
||||
<el-radio-group v-model="listQuery.bkDx" size="large" fill="#6cf" @change="shangeDx">
|
||||
<el-radio-button :label="item.dm" v-for="(item, index) in props.dic.D_GS_BK_NEWDX" :key="index">{{
|
||||
item.zdmc }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAddPeo"
|
||||
v-if="!disabled"
|
||||
class="ml10"
|
||||
>
|
||||
<el-button type="primary" @click="handleAddPeo" v-if="!disabled" class="ml10">
|
||||
<el-icon class="vam">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
@ -53,43 +25,25 @@
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="relative ww100">
|
||||
<MyTable
|
||||
:tableData="listQuery.bkdxList"
|
||||
:tableColumn="tableDate.tableColumn"
|
||||
:tableHeight="tableDate.tableHeight"
|
||||
:key="tableDate.keyCount"
|
||||
:tableConfiger="tableDate.tableConfiger"
|
||||
:controlsWidth="tableDate.controlsWidth"
|
||||
>
|
||||
<MyTable :tableData="listQuery.bkdxList" :tableColumn="tableDate.tableColumn"
|
||||
:tableHeight="tableDate.tableHeight" :key="tableDate.keyCount" :tableConfiger="tableDate.tableConfiger"
|
||||
:controlsWidth="tableDate.controlsWidth">
|
||||
<template #fjZp="{ row }">
|
||||
<el-image :src="setAddress(row.fjZp)"></el-image>
|
||||
</template>
|
||||
<template #yjdj="{ row }">
|
||||
<DictTag
|
||||
:tag="false"
|
||||
:value="row.yjdj"
|
||||
:options="props.dic.D_GS_ZDR_YJDJ"
|
||||
/>
|
||||
<DictTag :tag="false" :value="row.yjdj" :options="props.dic.D_GS_ZDR_YJDJ" />
|
||||
</template>
|
||||
<template #yjbq="{ row }">
|
||||
<DictTag
|
||||
:tag="false"
|
||||
:value="row.yjbq"
|
||||
:options="props.dic.BD_BK_CLYJBQ"
|
||||
/>
|
||||
<DictTag :tag="false" :value="row.yjbq" :options="props.dic.BD_BK_CLYJBQ" />
|
||||
</template>
|
||||
<template #ryXb="{ row }">
|
||||
<DictTag
|
||||
:tag="false"
|
||||
:value="row.ryXb"
|
||||
:options="props.dic.D_BZ_XB"
|
||||
/>
|
||||
<DictTag :tag="false" :value="row.ryXb" :options="props.dic.D_BZ_XB" />
|
||||
</template>
|
||||
<template #bqList="{ row }">
|
||||
<span v-if="row.bqList">
|
||||
<span v-for="(it, idx) in row.bqList" :key="idx">
|
||||
{{ it.bqMc }}、</span
|
||||
>
|
||||
{{ it.bqMc }}、</span>
|
||||
</span>
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
@ -99,109 +53,58 @@
|
||||
</template>
|
||||
</MyTable>
|
||||
</div>
|
||||
<div class="ww100 mt25 mb10">
|
||||
<div class="ww100 mt25 mb10" style="display: flex;justify-content: space-between;">
|
||||
<el-form-item prop="bkSjKs" label="布控开始时间">
|
||||
<MOSTY.Date
|
||||
v-model="listQuery.bkSjKs"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择布控开始时间"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Date v-model="listQuery.bkSjKs" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择布控开始时间" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item prop="bkSjJs" label="布控结束时间">
|
||||
<MOSTY.Date
|
||||
v-model="listQuery.bkSjJs"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择布控结束时间"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Date v-model="listQuery.bkSjJs" type="datetime" format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择布控结束时间" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item prop="czcs" label="处置措施">
|
||||
<MOSTY.Select
|
||||
v-model="listQuery.czcs"
|
||||
:dictEnum="props.dic.D_GS_BK_CZYQ"
|
||||
placeholder="请选择处置措施"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Select v-model="listQuery.czcs" :dictEnum="props.dic.D_GS_BK_CZYQ" placeholder="请选择处置措施"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="ww100 mt10 mb10">
|
||||
<el-form-item prop="czYq" label="处置要求" class="ww100">
|
||||
<MOSTY.Other
|
||||
v-model="listQuery.czYq"
|
||||
placeholder="请输入处置要求"
|
||||
type="textarea"
|
||||
class="ww100"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Other v-model="listQuery.czYq" placeholder="请输入处置要求" type="textarea" class="ww100"
|
||||
style="width: 100%;" clearable />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="ww100 mt10 mb10">
|
||||
<el-form-item prop="bkSy" label="布控原因" class="ww100">
|
||||
<MOSTY.Other
|
||||
v-model="listQuery.bkSy"
|
||||
placeholder="请输入布控原因"
|
||||
type="textarea"
|
||||
class="ww100"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Other v-model="listQuery.bkSy" placeholder="请输入布控原因" type="textarea" style="width: 100%;"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="ww100 mt10 mb10">
|
||||
<el-form-item
|
||||
prop="bkDj"
|
||||
label="布控等级"
|
||||
v-if="props.name == 'myControl'"
|
||||
>
|
||||
<MOSTY.Select
|
||||
v-model="listQuery.bkDj"
|
||||
:dictEnum="props.dic.D_GS_SSYJ"
|
||||
placeholder="请选择布控级别"
|
||||
clearable
|
||||
/>
|
||||
<el-form-item prop="bkDj" label="布控等级" v-if="props.name == 'myControl'">
|
||||
<MOSTY.Select v-model="listQuery.bkDj" :dictEnum="props.dic.D_GS_SSYJ" placeholder="请选择布控级别"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
<el-form-item prop="bkDj" label="布控等级" v-else>
|
||||
<MOSTY.Select
|
||||
v-model="listQuery.bkDj"
|
||||
:dictEnum="props.dic.D_BZ_JQDJ"
|
||||
placeholder="请选择布控级别"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Select v-model="listQuery.bkDj" :dictEnum="props.dic.D_BZ_JQDJ" placeholder="请选择布控级别"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
<el-form-item prop="bklylx" label="布控来源">
|
||||
<MOSTY.Select
|
||||
v-model="listQuery.bklylx"
|
||||
:dictEnum="props.dic.D_BZ_BKLYS"
|
||||
placeholder="请选择布控来源"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Select v-model="listQuery.bklylx" :dictEnum="props.dic.D_BZ_BKLYS" placeholder="请选择布控来源"
|
||||
clearable />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="ww100 mt10 mb10">
|
||||
<el-form-item prop="zfyj" label="执法依据" class="ww100">
|
||||
<MOSTY.Other
|
||||
v-model="listQuery.zfyj"
|
||||
placeholder="请输入执法依据"
|
||||
type="textarea"
|
||||
class="ww100"
|
||||
clearable
|
||||
/>
|
||||
<MOSTY.Other v-model="listQuery.zfyj" placeholder="请输入执法依据" type="textarea" clearable
|
||||
style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="ww100 mt10">
|
||||
<el-form-item prop="bkfj" label="上传附件" class="ww100">
|
||||
<div>
|
||||
<MOSTY.Upload
|
||||
:showBtn="true"
|
||||
:limit="10"
|
||||
:isImg="false"
|
||||
:isAll="true"
|
||||
v-model="listQuery.bkfj"
|
||||
/>
|
||||
<MOSTY.Upload :showBtn="true" :limit="10" :isImg="false" :isAll="true" v-model="listQuery.bkfj" />
|
||||
<div>支持png、jpg、pdf文件上传</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@ -255,36 +158,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 选择布控人员 -->
|
||||
<BkryDialod
|
||||
:modelValue="chooseVisible_RY"
|
||||
@update:modelValue="chooseVisible_RY = $event"
|
||||
@choosed="choosed"
|
||||
@choosedAdd="choosedAdd"
|
||||
:roleIds="roleIds"
|
||||
/>
|
||||
<BkryDialod :modelValue="chooseVisible_RY" @update:modelValue="chooseVisible_RY = $event" @choosed="choosed"
|
||||
@choosedAdd="choosedAdd" :roleIds="roleIds" />
|
||||
<!-- 选择车辆布控 -->
|
||||
<BkclDialod
|
||||
:modelValue="chooseVisible_CL"
|
||||
@update:modelValue="chooseVisible_CL = $event"
|
||||
@choosed="choosed"
|
||||
@choosedAdd="choosedAdd"
|
||||
:roleIds="roleIds"
|
||||
/>
|
||||
<BkclDialod :modelValue="chooseVisible_CL" @update:modelValue="chooseVisible_CL = $event" @choosed="choosed"
|
||||
@choosedAdd="choosedAdd" :roleIds="roleIds" />
|
||||
<!-- 选择布控群体 -->
|
||||
<BkqtDialod
|
||||
:modelValue="chooseVisible_QT"
|
||||
@update:modelValue="chooseVisible_QT = $event"
|
||||
@choosed="choosed"
|
||||
:roleIds="roleIds"
|
||||
/>
|
||||
<BksfzDialod
|
||||
:modelValue="chooseVisible_SFZ"
|
||||
@update:modelValue="chooseVisible_SFZ = $event"
|
||||
@choosed="choosed"
|
||||
:roleIds="roleIds"
|
||||
:bkDx="listQuery.bkDx"
|
||||
@choosedAdd="choosedAdd"
|
||||
/>
|
||||
<BkqtDialod :modelValue="chooseVisible_QT" @update:modelValue="chooseVisible_QT = $event" @choosed="choosed"
|
||||
:roleIds="roleIds" />
|
||||
<BksfzDialod :modelValue="chooseVisible_SFZ" @update:modelValue="chooseVisible_SFZ = $event" @choosed="choosed"
|
||||
:roleIds="roleIds" :bkDx="listQuery.bkDx" @choosedAdd="choosedAdd" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -629,7 +512,7 @@ const submit = () => {
|
||||
bklx = "02";
|
||||
}
|
||||
let params = { ...listQuery.value, bklx: bklx };
|
||||
params.bkfj = params.bkfj ? params.bkfj.join(",") : "";
|
||||
params.bkfj = params.bkfj ? JSON.stringify(params.bkfj) : "";
|
||||
params.bkdxList = params.bkdxList ? params.bkdxList : [];
|
||||
params.bkdxList.forEach((item) => {
|
||||
if (Array.isArray(item.fjZp)) {
|
||||
@ -640,10 +523,7 @@ const submit = () => {
|
||||
});
|
||||
|
||||
loading.value = true;
|
||||
let url =
|
||||
title.value == "新增"
|
||||
? "/mosty-gsxt/tbGsxtBk/save"
|
||||
: "/mosty-gsxt/tbGsxtBk/update";
|
||||
let url = title.value == "新增" ? "/mosty-gsxt/tbGsxtBk/save" : "/mosty-gsxt/tbGsxtBk/update";
|
||||
qcckPost(params, url)
|
||||
.then((res) => {
|
||||
proxy.$message({ type: "success", message: "布控成功" });
|
||||
@ -772,7 +652,18 @@ const changeXzqh = (val) => {
|
||||
// 根据id获取详情
|
||||
const getDataById = (id) => {
|
||||
qcckGet({}, "/mosty-gsxt/tbGsxtBk/selectVoById/" + id).then((res) => {
|
||||
res.bkfj = res.ossList || [];
|
||||
// 兼容处理:优先使用 ossList,为空则解析 bkfj JSON 字符串
|
||||
if (res.ossList && res.ossList.length > 0) {
|
||||
res.bkfj = res.ossList;
|
||||
} else if (res.bkfj) {
|
||||
try {
|
||||
res.bkfj = JSON.parse(res.bkfj);
|
||||
} catch (e) {
|
||||
res.bkfj = [];
|
||||
}
|
||||
} else {
|
||||
res.bkfj = [];
|
||||
}
|
||||
listQuery.value = res || {};
|
||||
dataOrge.value = res;
|
||||
if (res.bkqyList) {
|
||||
@ -924,4 +815,8 @@ defineExpose({ init });
|
||||
::v-deep .el-radio-button__inner {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.form_cnt {
|
||||
width: 80%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -111,7 +111,7 @@ const props = defineProps({
|
||||
})
|
||||
const emits = defineEmits(["update:modelValue", "choosed", "choosedAdd"]);
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_XB, D_GS_ZDR_YJDJ } = proxy.$dict("D_BZ_XB", "D_GS_ZDR_YJDJ"); // 获取字典数据
|
||||
const { D_BZ_XB, /* D_GS_ZDR_YJDJ */ } = proxy.$dict("D_BZ_XB", /* "D_GS_ZDR_YJDJ" */); // 获取字典数据
|
||||
const input = ref('')
|
||||
const value1 = ref('')
|
||||
const value2 = ref('')
|
||||
|
||||
@ -10,17 +10,16 @@
|
||||
<!-- 按钮组 -->
|
||||
<!-- 表格 -->
|
||||
<div class="margTop">
|
||||
<MyTable
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount"
|
||||
:tableConfiger="pageData.tableConfiger"
|
||||
:controlsWidth="pageData.controlsWidth">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
|
||||
|
||||
<template #bkZt="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkZt" :options="D_GS_BK_ZT" />
|
||||
<DictTag :tag="false" :value="row.bkZt" :options="D_ZDRY_BKZT" />
|
||||
</template>
|
||||
<template #shzt="{ row }">
|
||||
<DictTag :tag="false" :value="row.shzt" :options="D_GS_BK_ZT" />
|
||||
</template>
|
||||
|
||||
<template #bkDj="{ row }">
|
||||
<DictTag :tag="false" :value="row.bkDj" :options="D_GS_SSYJ" v-if="route.name == 'myControl'" />
|
||||
<DictTag :tag="false" :value="row.bkDj" :options="D_BZ_JQDJ" v-else />
|
||||
@ -30,10 +29,10 @@
|
||||
</template>
|
||||
<template #bkdxList="{ row }">
|
||||
<span v-if="row.bkdxList"><span class="nowrap" v-for="(it, idx) in row.bkdxList" :key="idx">
|
||||
{{ it.ryXm ? it.ryXm : it.imei ? it.imei : it.imsi ? it.imsi : '' }}
|
||||
<!-- :it.ryXm?it.mac:it.imsi?it.imsi:'xxxx' -->
|
||||
{{ it.ryXm ? it.ryXm : it.imei ? it.imei : it.imsi ? it.imsi : it.rySfzh }}
|
||||
<span v-if="idx < row.bkdxList.length - 1">、</span></span></span>
|
||||
<span v-else>暂无</span>
|
||||
|
||||
</template>
|
||||
<!-- <template #sjrs="{ row }">
|
||||
<span v-if="row.bkdxList"> {{ row.bkdxList.length }} </span>
|
||||
@ -53,9 +52,11 @@
|
||||
@click="createProcess(row)">送审</el-link> -->
|
||||
|
||||
<!-- 不走工作流的送审 -->
|
||||
<el-link type="primary" size="small" v-if="['01', '03', '06'].includes(row.bkZt)" @click="hadleSendSH(row)">送审</el-link>
|
||||
<el-link type="primary" size="small" v-if="['01', '03', '06'].includes(row.bkZt)"
|
||||
@click="hadleSendSH(row)">送审</el-link>
|
||||
|
||||
<el-link type="primary" size="small" @click="tbGsxtBkQuashList(row)" v-if="!!!(['01', '03', '06'].includes(row.bkZt))">撤控</el-link>
|
||||
<el-link type="primary" size="small" @click="tbGsxtBkQuashList(row)"
|
||||
v-if="!!!(['01', '03', '06'].includes(row.bkZt))">撤控</el-link>
|
||||
|
||||
<el-link type="primary" v-if="['01', '03', '06'].includes(row.bkZt)" size="small"
|
||||
@click="handleAdd('edit', row)">编辑</el-link>
|
||||
@ -82,19 +83,10 @@
|
||||
<!-- 预警弹窗 -->
|
||||
<YjDialog ref="warningkdxForm"></YjDialog>
|
||||
|
||||
<SubmissionProcess
|
||||
v-model="showSp"
|
||||
:data="rowData"
|
||||
:userData="{ ajmc: '布控审批', flowType: 'BKSP', modelName: '布控' }"
|
||||
:path="fixedValue"
|
||||
@getList="getList"
|
||||
/>
|
||||
<Hzd
|
||||
v-model="hzdVisible"
|
||||
:dataList="dataList"
|
||||
:dict="{D_GS_BK_NEWDX,D_BZ_BKLYS,D_GS_SSYJ,D_BZ_JQDJ,D_GZL_SHZT,D_GS_BK_CZYQ}"
|
||||
:name="route.name"
|
||||
/>
|
||||
<SubmissionProcess v-model="showSp" :data="rowData" :userData="{ ajmc: '布控审批', flowType: 'BKSP', modelName: '布控' }"
|
||||
:path="fixedValue" @getList="getList" />
|
||||
<Hzd v-model="hzdVisible" :dataList="dataList"
|
||||
:dict="{ D_GS_BK_NEWDX, D_BZ_BKLYS, D_GS_SSYJ, D_BZ_JQDJ, D_GZL_SHZT, D_GS_BK_CZYQ }" :name="route.name" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -114,9 +106,9 @@ const route = useRoute()
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_BK_BKYS, D_BZ_XB, D_GS_BK_SJLX, D_GS_SSYJ, BD_BK_CLYJBQ, D_GS_ZDR_YJDJ,
|
||||
D_GS_BK_NEWDX, D_GS_BK_ZT, D_GS_BK_CZYQ, D_GS_BK_CZJSDWLX, D_GS_BK_TJFS, D_BZ_BKLYS, D_GZL_SHZT,
|
||||
D_BZ_JQDJ, D_BZ_SF } = proxy.$dict("D_GS_ZDR_YJDJ", "D_GS_BK_BKYS", "D_BZ_XB", "D_GS_BK_SJLX",
|
||||
D_BZ_JQDJ, D_BZ_SF, D_ZDRY_BKZT } = proxy.$dict("D_GS_ZDR_YJDJ", "D_GS_BK_BKYS", "D_BZ_XB", "D_GS_BK_SJLX",
|
||||
"D_GS_SSYJ", "D_GS_BK_NEWDX", "D_GS_BK_ZT", "D_GS_BK_CZYQ", "D_GS_BK_CZJSDWLX", "D_GS_BK_TJFS", 'D_GZL_SHZT',
|
||||
'BD_BK_CLYJBQ', 'D_BZ_JQDJ', "D_BZ_BKLYS", "D_BZ_SF"); //获取字典数据
|
||||
'BD_BK_CLYJBQ', 'D_BZ_JQDJ', "D_BZ_BKLYS", "D_BZ_SF", "D_ZDRY_BKZT"); //获取字典数据
|
||||
const addBkdxForm = ref(null); //布控对象组件
|
||||
const warningkdxForm = ref(); //布控对象组件
|
||||
const searchBox = ref(); //搜索框
|
||||
@ -153,6 +145,29 @@ const searchConfiger = ref([
|
||||
placeholder: "请选择布控部门",
|
||||
showType: "department",
|
||||
},
|
||||
{
|
||||
label: "布控对象",
|
||||
prop: "bkBt",
|
||||
placeholder: "请输入身份证号",
|
||||
showType: "input"
|
||||
}, {
|
||||
label: "布控对象身份证号",
|
||||
prop: "bkrsfzh",
|
||||
placeholder: "请输入布控对象身份证号",
|
||||
showType: "input"
|
||||
},
|
||||
{
|
||||
label: "发起人姓名",
|
||||
prop: "bkfqrXm",
|
||||
placeholder: "请输入姓名",
|
||||
showType: "input"
|
||||
},
|
||||
{
|
||||
label: "发起人身份证号",
|
||||
prop: "bkfqrSfzh",
|
||||
placeholder: "请输入身份证号",
|
||||
showType: "input"
|
||||
}
|
||||
]);
|
||||
const queryFrom = ref({});
|
||||
const pageData = reactive({
|
||||
@ -177,7 +192,9 @@ const pageData = reactive({
|
||||
{ label: "开始时间", prop: "bkSjKs", showOverflowTooltip: true },
|
||||
{ label: "结束时间", prop: "bkSjJs", showOverflowTooltip: true },
|
||||
{ label: "申请人", prop: "bkfqrXm" },
|
||||
{ label: "身份证号", prop: "bkfqrSfzh" },
|
||||
{ label: "布控状态", prop: "bkZt", showSolt: true },
|
||||
{ label: "审核状态", prop: "shzt", showSolt: true },
|
||||
]
|
||||
});
|
||||
// 固定值
|
||||
@ -196,6 +213,14 @@ const createProcess = (row) => {
|
||||
onMounted(() => {
|
||||
getList();
|
||||
tabHeightFn();
|
||||
if (route.name == 'PrivateSurveillance') {
|
||||
// 临时布控
|
||||
searchConfiger.value = [
|
||||
...searchConfiger.value,
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// 搜索
|
||||
@ -229,7 +254,7 @@ const getList = () => {
|
||||
};
|
||||
qcckGet(data, "/mosty-gsxt/tbGsxtBk/selectPage").then((res) => {
|
||||
pageData.tableData = res.records || [];
|
||||
pageData.total = res.total;
|
||||
pageData.total = res.total || 0;
|
||||
pageData.tableConfiger.loading = false;
|
||||
}).catch(() => {
|
||||
pageData.tableConfiger.loading = false;
|
||||
@ -302,10 +327,17 @@ const tabHeightFn = () => {
|
||||
};
|
||||
};
|
||||
const tbGsxtBkQuashList = (item) => {
|
||||
proxy.$confirm("确定要进行撤控吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
tbGsxtBkQuash({ id: item.id }).then(res => {
|
||||
proxy.$message({ type: "success", message: "操作成功" });
|
||||
getList();
|
||||
})
|
||||
}).catch(() => { })
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -384,7 +384,7 @@ const submit = () => {
|
||||
bklx = '02'
|
||||
}
|
||||
let params = { ...listQuery.value, bklx: bklx };
|
||||
params.bkfj = params.bkfj ? params.bkfj.join(',') : '';
|
||||
params.bkfj = params.bkfj ? JSON.stringify(params.bkfj) : "";
|
||||
params.bkdxList = params.bkdxList ? params.bkdxList : [];
|
||||
params.bkdxList.forEach(item => {
|
||||
if (Array.isArray(item.fjZp)) {
|
||||
@ -523,7 +523,18 @@ const changeXzqh = (val) => {
|
||||
// 根据id获取详情
|
||||
const getDataById = (id) => {
|
||||
qcckGet({}, '/mosty-gsxt/tbGsxtBk/selectVoById/' + id).then(res => {
|
||||
res.bkfj = res.ossList || [];
|
||||
// 兼容处理:优先使用 ossList,为空则解析 bkfj JSON 字符串
|
||||
if (res.ossList && res.ossList.length > 0) {
|
||||
res.bkfj = res.ossList;
|
||||
} else if (res.bkfj) {
|
||||
try {
|
||||
res.bkfj = JSON.parse(res.bkfj);
|
||||
} catch (e) {
|
||||
res.bkfj = [];
|
||||
}
|
||||
} else {
|
||||
res.bkfj = [];
|
||||
}
|
||||
listQuery.value = res || {}
|
||||
dataOrge.value = res
|
||||
if (res.bkqyList) {
|
||||
|
||||
@ -1,141 +0,0 @@
|
||||
<template>
|
||||
<el-dialog width="1400px" :draggable="true" custom-class="bgData" :model-value="modelValue" append-to-body
|
||||
@close="close" :show-close="false">
|
||||
<template #title>
|
||||
<div class="title">
|
||||
<div class="titleName">测试数据</div>
|
||||
<div>
|
||||
<el-icon :size="25" class="titleIcon">
|
||||
<BottomLeft />
|
||||
</el-icon>
|
||||
<el-icon :size="25" class="titleIcon">
|
||||
<FullScreen />
|
||||
</el-icon>
|
||||
<el-icon @click="close" :size="25" class="titleIcon">
|
||||
<Close />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="statusBar">
|
||||
<div>00:04</div>
|
||||
<div>正在讲话...</div>
|
||||
<div>
|
||||
<el-icon :size="25" class="titleIcon">
|
||||
<InfoFilled />
|
||||
</el-icon>
|
||||
<el-icon :size="25" class="titleIcon">
|
||||
<CircleCheckFilled />
|
||||
</el-icon>
|
||||
<el-icon @click="close" :size="25" class="titleIcon">
|
||||
<Unlock />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="content"></div>
|
||||
<template #footer>
|
||||
<Footer @close="close" />
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, reactive, toRaw, computed, getCurrentInstance } from "vue";
|
||||
import Footer from './footer.vue'
|
||||
// import useCallModule from '../sdk/call.js'
|
||||
const { proxy } = getCurrentInstance();
|
||||
// const Call = useCallModule()
|
||||
try {
|
||||
window.lemon.login.login({
|
||||
username: "linzhigongan1",
|
||||
password: "linzhigongan1",
|
||||
realm: "puc.com",
|
||||
webpucUrl: "https://192.168.0.1:16888",
|
||||
}).then(res => {
|
||||
console.log(res,"登录成功");
|
||||
}).catch(err => {
|
||||
console.log(err,"登录失败");
|
||||
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
console.log('error: ', error);
|
||||
}
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
titleValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const close = () => {
|
||||
emit('update:modelValue', false);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/assets/css/layout.scss";
|
||||
@import "@/assets/css/element-plus.scss";
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
padding: 10px;
|
||||
|
||||
.titleName {
|
||||
font-size: 20px;
|
||||
margin-bottom: 5px;
|
||||
width: 40%;
|
||||
|
||||
}
|
||||
|
||||
.titleIcon {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.statusBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 6px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 10px;
|
||||
height: 60vh;
|
||||
overflow: auto;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.tabBoxRadio .el-checkbox__inner {
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
|
||||
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bgData {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog__body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.bgData .el-dialog__header,
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@ -42,16 +42,16 @@ const handleClick = (tab) => {
|
||||
console.log(tab)
|
||||
}
|
||||
onMounted(() => {
|
||||
try {
|
||||
lemon?.basedata?.fetchSystemOrg({
|
||||
flat: true,
|
||||
key_word: ""
|
||||
}).then(res => {
|
||||
console.log(res);
|
||||
})
|
||||
} catch (error) {
|
||||
console.log('error: ', error);
|
||||
}
|
||||
// try {
|
||||
// lemon?.basedata?.fetchSystemOrg({
|
||||
// flat: true,
|
||||
// key_word: ""
|
||||
// }).then(res => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// } catch (error) {
|
||||
// console.log('error: ', error);
|
||||
// }
|
||||
})
|
||||
|
||||
const getJgList = () => {
|
||||
|
||||
@ -7,6 +7,11 @@
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
|
||||
<el-button size="small" type="primary" @click="handleLogin">
|
||||
<span style="vertical-align: middle">登录</span>
|
||||
</el-button>
|
||||
|
||||
</Search>
|
||||
</div>
|
||||
<div class="tabBox margTop">
|
||||
@ -72,13 +77,11 @@
|
||||
</div>
|
||||
<!-- 详情 -->
|
||||
<DetailForm ref="detailDiloag" @updateDate="getList" />
|
||||
|
||||
<RoomDetail />
|
||||
|
||||
|
||||
<ConferenceRoom v-model="conferenceRoomVisible" titleValue="会议详情" />
|
||||
|
||||
<!-- 音视频会议窗口 -->
|
||||
<MeetingView ref="refMeetingView" :update="updateItem"></MeetingView>
|
||||
<MeetingView ref="refMeetingView" @update="updateItem"></MeetingView>
|
||||
|
||||
<!-- 反馈弹窗 -->
|
||||
<FeedbackForm ref="feedbackFormRef" @success="getList" />
|
||||
@ -87,8 +90,12 @@
|
||||
<ViewFeedback ref="viewFeedbackRef" />
|
||||
|
||||
<Information v-model="showDialog" title="发送指令" @submit="seedFqzl" @close='close'>
|
||||
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="meeting"
|
||||
:tacitly="tacitly" />
|
||||
<SemdFqzl
|
||||
ref="semdFqzlRef"
|
||||
:itemData="itemData"
|
||||
@handleClose="handleClose"
|
||||
identification="meeting"
|
||||
/>
|
||||
</Information>
|
||||
|
||||
</template>
|
||||
@ -107,7 +114,6 @@ import ViewFeedback from "./components/ViewFeedback.vue";
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import ConferenceRoom from "./components/Communications/conferenceRoom.vue";
|
||||
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
|
||||
import Information from "@/views/home/model/information.vue";
|
||||
import { isShiQingZhi } from "@/utils/auth.js"
|
||||
@ -128,9 +134,7 @@ const itemData = ref({})
|
||||
const cityIntelligenceCommand = ref(isShiQingZhi())
|
||||
/** 下发指令 */
|
||||
const showDialog = ref(false)
|
||||
const tacitly = {
|
||||
// title:'ryXm'
|
||||
}
|
||||
|
||||
|
||||
const searchConfiger = ref([
|
||||
{
|
||||
@ -156,12 +160,8 @@ const pageData = reactive({
|
||||
pageCurrent: 1
|
||||
},
|
||||
});
|
||||
const jsonData = ref('')
|
||||
/** 当前行数据 */
|
||||
const currRow = ref({})
|
||||
|
||||
onMounted(() => {
|
||||
jsonData.value = require('@/components/Consultation/components/zh_CN.json');
|
||||
getList();
|
||||
tabHeightFn();
|
||||
});
|
||||
@ -228,6 +228,12 @@ const joinMeeting = (item, type) => {
|
||||
item.number = item.hybh;
|
||||
refMeetingView.value.openInit(item, type)
|
||||
};
|
||||
|
||||
|
||||
const handleLogin = () =>{
|
||||
refMeetingView.value.Init();
|
||||
}
|
||||
|
||||
// 反馈情况
|
||||
const feedBack = (item) => {
|
||||
feedbackFormRef.value.open(item.id);
|
||||
@ -239,6 +245,7 @@ const viewFeedback = (item) => {
|
||||
viewFeedbackRef.value.open(item.fkList || []);
|
||||
};
|
||||
|
||||
|
||||
// 删除
|
||||
const delDictItem = (id) => {
|
||||
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
|
||||
@ -254,6 +261,8 @@ const addEdit = (type, row) => {
|
||||
detailDiloag.value.init(type, row);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 210;
|
||||
@ -262,11 +271,6 @@ const tabHeightFn = () => {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// 会议详情弹窗
|
||||
const conferenceRoomVisible = ref(false);
|
||||
|
||||
|
||||
const seedFqzl = () => {
|
||||
semdFqzlRef.value.getsendFqzl()
|
||||
}
|
||||
|
||||
@ -10,15 +10,30 @@
|
||||
<div class="form_cnt">
|
||||
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
|
||||
</FormMessage>
|
||||
<div class="report-section">
|
||||
<div class="section-title">报告</div>
|
||||
<MyTable :tableData="reportTableData" :tableColumn="reportTableColumn" :tableConfiger="reportTableConfiger"
|
||||
:tableHeight="'400px'" :controlsWidth="120">
|
||||
<template #controls="{ row }">
|
||||
<el-link size="small" type="primary" @click="viewReport(row)">查看</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 报告详情弹窗 -->
|
||||
<ReportDialog ref="reportDialogRef" v-model="reportDialogVisible" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import ReportDialog from "./components/ReportDialog.vue";
|
||||
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch, computed } from "vue";
|
||||
import { addJudgmentCommandList, editJudgmentCommand, getJudgmentCommandDetail } from "@/api/huiShangyp/judgmentCommand.js"
|
||||
|
||||
|
||||
// import { getItem } from '@//utils/storage.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
const emit = defineEmits(["updateDate", "getList"]);
|
||||
@ -44,6 +59,28 @@ const title = ref("");
|
||||
/** 外面行数据 */
|
||||
const outRow = ref({})
|
||||
|
||||
// 报告表格配置
|
||||
const reportTableData = computed(() => Array.isArray(listQuery.value.xfbmList) ? listQuery.value.xfbmList : []);
|
||||
const reportTableColumn = [
|
||||
{ label: "下发部门", prop: "ssbm" },
|
||||
{ label: "操作人", prop: "xtCjr" },
|
||||
];
|
||||
const reportTableConfiger = {
|
||||
showSelectType: "null",
|
||||
showIndex: false,
|
||||
haveControls: true,
|
||||
controls: "操作",
|
||||
loading: false
|
||||
};
|
||||
|
||||
// 报告详情弹窗
|
||||
const reportDialogVisible = ref(false);
|
||||
const reportDialogRef = ref();
|
||||
|
||||
const viewReport = (row) => {
|
||||
reportDialogRef.value.open(row.ypid);
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
zlbt: [{ required: true, message: "请输入标题", trigger: "blur" }],
|
||||
// zlnr: [{ required: true, message: "请输入内容", trigger: "change" }],
|
||||
@ -79,6 +116,7 @@ const getDataById = (id) => {
|
||||
// const xfbmMc = res.xfbmMc
|
||||
});
|
||||
};
|
||||
// http://localhost:9530/mosty-api/mosty-gsxt/gsxtYpbg/0aeb4f6b814b4b05a49f472dd1234935
|
||||
|
||||
|
||||
// 提交
|
||||
@ -149,4 +187,16 @@ defineExpose({ init });
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
// z-index: 1000;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
margin-top: 20px;
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -13,11 +13,7 @@
|
||||
<!-- 研判报告选择 -->
|
||||
<div class="form-item">
|
||||
<label class="form-label">研判报告:</label>
|
||||
<ReportSelectInput
|
||||
v-model="formData.ypmc"
|
||||
:bglx="formData.bglx"
|
||||
@change="handleReportChange"
|
||||
/>
|
||||
<ReportSelectInput v-model="formData.ypmc" :bglx="formData.bglx" @change="handleReportChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="报告详情" width="80%" destroy-on-close @closed="handleClosed">
|
||||
<div v-loading="loading" class="report-content">
|
||||
<div v-if="reportDetail" v-html="reportDetail.bgnr"></div>
|
||||
<el-empty v-else-if="!loading" description="暂无报告内容" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { qcckGet } from '@/api/qcckApi.js';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'closed']);
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
});
|
||||
|
||||
const reportDetail = ref(null);
|
||||
const loading = ref(false);
|
||||
|
||||
const open = (ypbgid) => {
|
||||
visible.value = true;
|
||||
loading.value = true;
|
||||
reportDetail.value = null;
|
||||
qcckGet({}, '/mosty-gsxt/gsxtYpbg/' + ypbgid).then((res) => {
|
||||
reportDetail.value = res || {};
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
const handleClosed = () => {
|
||||
reportDetail.value = null;
|
||||
emit('closed');
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report-content {
|
||||
min-height: 45vh;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -68,7 +68,7 @@ const handleConfirm = () => {
|
||||
return
|
||||
}
|
||||
|
||||
inputValue.value = selectedReport.value.ypyt || selectedReport.value.zlbt || ''
|
||||
inputValue.value = selectedReport.value.bgmc || selectedReport.value.ypyt || selectedReport.value.zlbt || ''
|
||||
emit('update:modelValue', inputValue.value)
|
||||
emit('change', selectedReport.value)
|
||||
showDialog.value = false
|
||||
|
||||
@ -19,10 +19,10 @@
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="研判议题" prop="ypyt" />
|
||||
<el-table-column label="研判要求" prop="ypyq" />
|
||||
<el-table-column label="研判时间" prop="ypsj" />
|
||||
<el-table-column label="研判议题" prop="bgmc" />
|
||||
<el-table-column label="研判时间" prop="scsj" />
|
||||
<el-table-column label="发起部门" prop="ssbm" />
|
||||
<el-table-column label="创建人" prop="cjrxm" />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { tacticalGet } from '@/api/huiShangyp/tacticalApi.js'
|
||||
|
||||
import { qcckGet } from '@/api/qcckApi'
|
||||
const props = defineProps({
|
||||
bglx: {
|
||||
type: String,
|
||||
@ -87,10 +87,14 @@ const loadData = async () => {
|
||||
pageSize: pageSize.value,
|
||||
pageCurrent: currentPage.value
|
||||
}
|
||||
// / gsxtYpbg / getPageList
|
||||
// const res = await tacticalGet(params)
|
||||
|
||||
const res = await tacticalGet(params)
|
||||
qcckGet(params, '/mosty-gsxt/gsxtYpbg/getPageList').then(res => {
|
||||
tableData.value = res.records || []
|
||||
total.value = res.total || 0
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
tableData.value = []
|
||||
total.value = 0
|
||||
|
||||
@ -29,11 +29,11 @@
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link size="small" type="primary" @click="getDataById('edit', row)">修改</el-link>
|
||||
<el-link size="small" type="primary" @click="getDataById('edit', row)" :disabled="!canEdit(row)">修改</el-link>
|
||||
<el-link size="small" type="primary" @click="getDataById('detail', row)">详情</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteFile(row)">删除</el-link>
|
||||
<el-link v-if="showBtn(row) == 'sign'" size="small" type="success" @click="sign(row)">签收</el-link>
|
||||
<el-link v-if="showBtn(row) == 'feedback'" size="small" type="warning" @click="feedback(row)">反馈</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteFile(row)" :disabled="!canDelete(row)">删除</el-link>
|
||||
<el-link v-if="canSign(row)" size="small" type="success" @click="sign(row)">签收</el-link>
|
||||
<el-link v-if="canFeedback(row)" size="small" type="warning" @click="feedback(row)">反馈</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
@ -198,25 +198,46 @@ const handleFeedbackSuccess = () => {
|
||||
|
||||
|
||||
// 权限控制
|
||||
// 显示签收
|
||||
// 获取当前用户在xfbmList中的部门项
|
||||
const getMyDeptItem = (row) => {
|
||||
return row.xfbmList?.find(v => v.ssbmdm == userInfo.value?.deptCode)
|
||||
}
|
||||
|
||||
// 显示签收状态
|
||||
const showSign = (row) => {
|
||||
let item = row.xfbmList.find(v => v.ssbmdm == userInfo.value.deptCode)
|
||||
const item = getMyDeptItem(row)
|
||||
if (item) {
|
||||
return item.zlzt == '01' ? '未签收' : item.zlzt == '02' ? '已签收' : '已反馈'
|
||||
} else {
|
||||
}
|
||||
return row.zlzt == '01' ? '未签收' : row.zlzt == '02' ? '已签收' : '已反馈'
|
||||
}
|
||||
|
||||
// 删除权限:JS_666666/JS_777777可删除所有,其余只能删除自己的
|
||||
const canDelete = (row) => {
|
||||
const roleList = getItem('roleList') || []
|
||||
const roleCodes = roleList.map(r => r.roleCode)
|
||||
|
||||
if (roleCodes.includes('JS_666666') || roleCodes.includes('JS_777777')) return true
|
||||
return row.ssbmdm == userInfo.value?.deptCode
|
||||
}
|
||||
// sign--签收
|
||||
// feedback--反馈
|
||||
// 显示按钮
|
||||
const showBtn = (row) => {
|
||||
let item = row.xfbmList.find(v => v.ssbmdm == userInfo.value.deptCode)
|
||||
if (item) {
|
||||
return item.zlzt == '01' ? 'sign' : item.zlzt == '02' ? 'feedback' : ''
|
||||
} else {
|
||||
return ''
|
||||
|
||||
// 修改权限:只能自己修改,且未签收未反馈
|
||||
const canEdit = (row) => {
|
||||
const item = getMyDeptItem(row)
|
||||
if (!item) return false
|
||||
return item.zlzt == '01'
|
||||
}
|
||||
|
||||
// 签收权限:当前部门在列表中且未签收
|
||||
const canSign = (row) => {
|
||||
const item = getMyDeptItem(row)
|
||||
return item?.zlzt == '01'
|
||||
}
|
||||
|
||||
// 反馈权限:当前部门在列表中且已签收或已反馈(可多次反馈)
|
||||
const canFeedback = (row) => {
|
||||
const item = getMyDeptItem(row)
|
||||
return item && (item.zlzt == '02' || item.zlzt == '03')
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -13,20 +13,11 @@
|
||||
</FormMessage>
|
||||
<div class="cntBox">
|
||||
<!-- 工具栏 -->
|
||||
<Toolbar
|
||||
style="border-bottom: 1px solid #ccc"
|
||||
:editor="editorRef"
|
||||
:defaultConfig="toolbarConfig"
|
||||
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig"
|
||||
:mode="mode" />
|
||||
<!-- 编辑器 -->
|
||||
<Editor
|
||||
:style="`height: 480px; overflow-y: hidden`"
|
||||
v-model="textContent"
|
||||
:defaultConfig="editorConfig"
|
||||
:mode="mode"
|
||||
@onCreated="handleCreated"
|
||||
@onChange="handChange"
|
||||
/>
|
||||
<Editor :style="`height: 480px; overflow-y: hidden`" v-model="textContent" :defaultConfig="editorConfig"
|
||||
:mode="mode" @onCreated="handleCreated" @onChange="handChange" />
|
||||
</div>
|
||||
<div v-if="listQuery.id" style="display: flex; justify-content: center;">
|
||||
<!-- <el-button style="display: block;" type="primary" @click="ConsultationShow = true">网上会商</el-button> -->
|
||||
@ -134,6 +125,7 @@ const init = (type, row) => {
|
||||
const getDataById = (id) => {
|
||||
qcckGet({}, '/mosty-gsxt/gsxtYpbg/' + id).then((res) => {
|
||||
listQuery.value = res || {};
|
||||
textContent.value = res.bgnr
|
||||
// /** @type {Array<JudgmentDept>} 参与研判部门数据数组 */
|
||||
// const cyypList = Array.isArray(res.cyypList) ? res.cyypList : []
|
||||
// listQuery.value.jsdxBmDm = cyypList.map(item => {
|
||||
@ -150,18 +142,18 @@ const getText = (val) => {
|
||||
setEditorTextContent()
|
||||
}
|
||||
|
||||
function stripReportHeader(html) {
|
||||
const source = typeof html === "string" ? html : "";
|
||||
if (!source) return "";
|
||||
const hrMatch = source.match(/<hr\b[^>]*\/?>/i);
|
||||
if (hrMatch && typeof hrMatch.index === "number") {
|
||||
return source.slice(hrMatch.index + hrMatch[0].length).trim();
|
||||
}
|
||||
if (typeof dataBt.value === "string" && source.startsWith(dataBt.value)) {
|
||||
return source.slice(dataBt.value.length).trim();
|
||||
}
|
||||
return source.trim();
|
||||
}
|
||||
// function stripReportHeader(html) {
|
||||
// const source = typeof html === "string" ? html : "";
|
||||
// if (!source) return "";
|
||||
// const hrMatch = source.match(/<hr\b[^>]*\/?>/i);
|
||||
// if (hrMatch && typeof hrMatch.index === "number") {
|
||||
// return source.slice(hrMatch.index + hrMatch[0].length).trim();
|
||||
// }
|
||||
// if (typeof dataBt.value === "string" && source.startsWith(dataBt.value)) {
|
||||
// return source.slice(dataBt.value.length).trim();
|
||||
// }
|
||||
// return source.trim();
|
||||
// }
|
||||
|
||||
function setEditorTextContent() {
|
||||
let html = dataBt.value;
|
||||
@ -176,7 +168,7 @@ const submit = () => {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
...data,
|
||||
bgnr: stripReportHeader(textContent.value)
|
||||
bgnr: textContent.value
|
||||
};
|
||||
const apiFun = !listQuery.value.id ? gsxtYpbgAddEntity : gsxtYpbgEditEntity;
|
||||
if (!listQuery.value.id) delete params.id;
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
</div>
|
||||
<div class="form_cnt">
|
||||
<EarlyWarning v-if="item.mxlx == YJGZ" ref="regulationRef"
|
||||
:dict="{D_BB_AJLB,D_BZ_WPLX}"
|
||||
:dict="{/* D_BB_AJLB, */ D_BZ_WPLX}"
|
||||
:defaultData="defaultData" :disabled="false" />
|
||||
<Regulation v-if="item.mxlx ==SSYJ" ref="regulationRef" :dict="{D_BZ_RYBQ}"
|
||||
:defaultData="defaultData" :disabled="false" />
|
||||
@ -34,7 +34,7 @@ const props = defineProps({
|
||||
|
||||
})
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BB_AJLB,D_BZ_WPLX,D_BZ_RYBQ} = proxy.$dict("D_BB_AJLB","D_BZ_WPLX","D_BZ_RYBQ")
|
||||
const { /* D_BB_AJLB, */ D_BZ_WPLX, D_BZ_RYBQ } = proxy.$dict(/* "D_BB_AJLB", */ "D_BZ_WPLX", "D_BZ_RYBQ")
|
||||
const title = ref("新增")
|
||||
const emit = defineEmits(['getList'])
|
||||
const listQuery = ref()
|
||||
|
||||
@ -46,7 +46,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BB_AJLB,D_BZ_WPLX} = proxy.$dict("D_BB_AJLB","D_BZ_WPLX")
|
||||
const { /* D_BB_AJLB, */ D_BZ_WPLX } = proxy.$dict(/* "D_BB_AJLB", */ "D_BZ_WPLX")
|
||||
const regulation = ref(null)
|
||||
const queryFrom = ref({})
|
||||
const searchBox = ref(); //搜索框
|
||||
|
||||
@ -14,7 +14,7 @@ import WarningList from "./components/AddModel/warningList.vue"
|
||||
const { proxy } = getCurrentInstance();
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import { onMounted, ref, getCurrentInstance } from "vue";
|
||||
const { D_BZ_TPYJLX,D_BZ_YJLX ,D_BZ_JQLY} = proxy.$dict("D_BZ_TPYJLX","D_BZ_YJLX","D_BZ_JQLY")
|
||||
const { /* D_BZ_TPYJLX, */D_BZ_YJLX /* ,D_BZ_JQLY */} = proxy.$dict(/* "D_BZ_TPYJLX", */"D_BZ_YJLX"/* ,"D_BZ_JQLY" */)
|
||||
|
||||
const showModel = ref('研判首页')
|
||||
const itemData = ref({})
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<el-dialog :model-value="modelValue" :title="title" width="80%" @close="closeDialog" destroy-on-close append-to-body
|
||||
:close-on-click-modal="false">
|
||||
<div style="width: 100%;height: 500px;">
|
||||
<div class="table-container">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :key="pageData.keyCount"
|
||||
:tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
|
||||
:tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth" :tableHeight="480">
|
||||
<template #jqdjdm="{ row }">
|
||||
<DictTag :tag="false" :value="row.jqdjdm" :options="dict.D_GS_BQ_DJ" />
|
||||
</template>
|
||||
@ -51,7 +51,9 @@ const pageData = reactive({
|
||||
tableConfiger: {
|
||||
rowHieght: 61,
|
||||
showSelectType: "null", //选择类型
|
||||
loading: false
|
||||
loading: false,
|
||||
haveControls: false,
|
||||
|
||||
},
|
||||
total: 0,
|
||||
pageConfiger: {
|
||||
@ -98,4 +100,10 @@ const submitForm = () => {
|
||||
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.table-container {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -16,7 +16,30 @@
|
||||
<span v-else class="placeholder-text">请选择关联线索</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #fjzd>
|
||||
<div>
|
||||
<MOSTY.Upload :showBtn="true" :limit="10" :isImg="false" :isAll="true" v-model="listQuery.fjzd" />
|
||||
<div class="upload-tip">支持png、jpg、jpeg文件上传</div>
|
||||
</div>
|
||||
</template>
|
||||
</FormMessage>
|
||||
<el-table v-if="title == '详情' && listQuery.czlcList && listQuery.czlcList.length > 0" :data="listQuery.czlcList"
|
||||
border size="small" style="width: 100%;margin-top: 10px;">
|
||||
<el-table-column prop="czrrxm" label="反馈人" min-width="100" />
|
||||
<el-table-column prop="fknr" label="反馈内容" min-width="200" />
|
||||
<el-table-column prop="ssbm" label="所属部门" min-width="150" />
|
||||
<el-table-column label="附件" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="parseFkfj(row.fkfj).length">
|
||||
<el-link v-for="(file, idx) in parseFkfj(row.fkfj)" :key="idx" type="primary" :underline="false"
|
||||
@click="downloadFile(file)" style="margin-right: 10px;">
|
||||
{{ file.name || file.id }}
|
||||
</el-link>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-if="title == '详情'" class="timeline-container">
|
||||
<el-timeline class="timeline-wrapper" v-if="listQuery.czlcLis && listQuery.czlcList.length > 0">
|
||||
@ -49,7 +72,9 @@
|
||||
<script setup>
|
||||
import Xslist from '@/components/ChooseList/ChooseXs/index.vue'
|
||||
import FormMessage from '@/components/aboutTable/FormMessage.vue'
|
||||
import * as MOSTY from '@/components/MyComponents/index'
|
||||
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||
import { saveAs } from 'file-saver';
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ref, defineExpose, reactive, onMounted, defineEmits, getCurrentInstance, nextTick, watch } from "vue";
|
||||
const emit = defineEmits(["updateDate"]);
|
||||
@ -76,10 +101,10 @@ watch(() => props.dic, (newVal) => {
|
||||
{ label: "联系人", prop: "zllxr", type: "input" },
|
||||
{ label: "联系电话", prop: "zllxdh", type: "input" },
|
||||
{ label: "关联线索", prop: "glxsid", type: "slot" },
|
||||
{ label: "主送单位", prop: "zsdw", type: "department" },
|
||||
{ label: "主送单位", prop: "zsdw", type: "department", depMc: "zsdwMc" },
|
||||
{ label: "抄送单位", prop: "csdw", type: "department" },
|
||||
{ label: "指令内容", prop: "zlnr", type: "textarea", width: '100%' },
|
||||
{ label: "附件", prop: "fjzd", type: "upload", width: '100%' },
|
||||
{ label: "附件", prop: "fjzd", type: "slot", width: '100%' },
|
||||
]
|
||||
}
|
||||
}, { deep: true })
|
||||
@ -111,9 +136,17 @@ const init = (type, row,) => {
|
||||
// 根据id查询详情
|
||||
const getDataById = (id) => {
|
||||
qcckGet({ id }, '/mosty-gsxt/zlxx/selectByid').then((res) => {
|
||||
res.fjzd = res.fjzd ? res.fjzd.split(',') : [];
|
||||
// 解析附件:兼容JSON字符串和逗号分隔两种格式
|
||||
let fjzdList = []
|
||||
try {
|
||||
const parsed = res.fjzd ? JSON.parse(res.fjzd) : []
|
||||
fjzdList = Array.isArray(parsed) ? parsed : []
|
||||
} catch (e) {
|
||||
fjzdList = res.fjzd ? res.fjzd.split(',') : []
|
||||
}
|
||||
listQuery.value = {
|
||||
...res,
|
||||
fjzd: fjzdList,
|
||||
czlcList: res.czlcList ? res.czlcList.reverse() : []
|
||||
};
|
||||
});
|
||||
@ -132,7 +165,29 @@ const submit = () => {
|
||||
let url = title.value == "新增" ? '/mosty-gsxt/zlxx/add' : '/mosty-gsxt/zlxx/update';
|
||||
let params = { ...data }
|
||||
loading.value = true;
|
||||
params.fjzd = params.fjzd ? params.fjzd.join(',') : ''
|
||||
// 将附件转为JSON字符串(包含id和name)
|
||||
let fjzdList = []
|
||||
if (Array.isArray(params.fjzd)) {
|
||||
params.fjzd.forEach(item => {
|
||||
if (Object.prototype.toString.call(item) === '[object Object]') {
|
||||
fjzdList.push({ id: item.id, name: item.name })
|
||||
} else {
|
||||
fjzdList.push({ id: item })
|
||||
}
|
||||
})
|
||||
}
|
||||
params.fjzd = fjzdList.length > 0 ? JSON.stringify(fjzdList) : ''
|
||||
// 将主送单位和抄送单位转换为下发部门列表
|
||||
let xfbmList = [];
|
||||
const zsdwArr = Array.isArray(params.zsdw) ? params.zsdw : (params.zsdw ? [params.zsdw] : []);
|
||||
zsdwArr.forEach(code => {
|
||||
xfbmList.push({ ssbmdm: code });
|
||||
});
|
||||
const csdwArr = Array.isArray(params.csdw) ? params.csdw : (params.csdw ? [params.csdw] : []);
|
||||
csdwArr.forEach(code => {
|
||||
xfbmList.push({ ssbmdm: code });
|
||||
});
|
||||
params.xfbmList = xfbmList;
|
||||
qcckPost(params, url).then((res) => {
|
||||
loading.value = false;
|
||||
proxy.$message({ type: "success", message: title.value + "成功" });
|
||||
@ -149,6 +204,34 @@ const close = () => {
|
||||
loading.value = false;
|
||||
router.replace({ path: '/InstructionInformation' })// 移除id 避免刷新一直带参数
|
||||
};
|
||||
|
||||
// 解析附件JSON字符串为数组
|
||||
const parseFkfj = (fkfj) => {
|
||||
if (!fkfj) return []
|
||||
try {
|
||||
const parsed = typeof fkfj === 'string' ? JSON.parse(fkfj) : fkfj
|
||||
return Array.isArray(parsed) ? parsed : []
|
||||
} catch (e) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
const downloadFile = (file) => {
|
||||
const url = `/mosty-api/mosty-base/minio/image/download/${file.id}`
|
||||
const filename = file.name || file.id
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error('下载失败')
|
||||
return response.blob()
|
||||
})
|
||||
.then(blob => {
|
||||
saveAs(blob, filename)
|
||||
})
|
||||
.catch(() => {
|
||||
proxy.$message({ type: 'error', message: '下载失败' })
|
||||
})
|
||||
}
|
||||
defineExpose({ init });
|
||||
</script>
|
||||
|
||||
@ -161,7 +244,6 @@ defineExpose({ init });
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e9e9e9;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
// 新增类样式
|
||||
@ -180,7 +262,11 @@ defineExpose({ init });
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
color: #b8b8b8;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
background: #409eff;
|
||||
}
|
||||
|
||||
.timeline-container {
|
||||
@ -266,4 +352,10 @@ defineExpose({ init });
|
||||
// white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<el-dialog :model-value="modelValue" title="线索反馈" width="50%" @close="closeDialog" destroy-on-close append-to-body>
|
||||
<div style="height: 15vh; overflow: auto;">
|
||||
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" />
|
||||
<div style="height: 50vh; overflow: auto;">
|
||||
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
|
||||
<template #fkfj>
|
||||
<div>
|
||||
<div>上传附件:<span class="f12">(可附电子表格、Word文档、图像、音视频文件)</span> </div>
|
||||
<MOSTY.Upload :showBtn="true" :isAll="true" :isImg="false" :limit="10" v-model="fkfj" />
|
||||
</div>
|
||||
</template>
|
||||
</FormMessage>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@ -13,6 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||
import { ref, reactive, getCurrentInstance, watch } from "vue";
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
@ -32,16 +40,19 @@ const emit = defineEmits(['update:modelValue', 'getList'])
|
||||
const elform = ref(null)
|
||||
const closeDialog = (formEl) => {
|
||||
elform.value.reset()
|
||||
fkfj.value = []
|
||||
emit('update:modelValue', false)
|
||||
}
|
||||
|
||||
const rules = reactive({
|
||||
fknr: [{ required: true, message: '请输入反馈内容', trigger: 'blur' }],
|
||||
})
|
||||
const fkfj = ref([])
|
||||
const listQuery = ref({})
|
||||
const formData = ref(
|
||||
[
|
||||
{ label: "反馈内容", prop: "fknr", type: "textarea", width: '90%' },
|
||||
{ label: "反馈附件", prop: "fkfj", width: '90%', type: "slot" },
|
||||
]
|
||||
)
|
||||
watch(() => props.modelValue, (newVal, oldVal) => {
|
||||
@ -55,8 +66,17 @@ const submitForm = (formEl) => {
|
||||
console.log(listQuery.value);
|
||||
elform.value.submit((valid) => {
|
||||
if (valid) {
|
||||
let fkfjList = [];
|
||||
fkfj.value.forEach(item => {
|
||||
if (Object.prototype.toString.call(item) === '[object Object]') {
|
||||
fkfjList.push({ id: item.id, name: item.name })
|
||||
} else {
|
||||
fkfjList.push({ id: item })
|
||||
}
|
||||
})
|
||||
const params = {
|
||||
...listQuery.value,
|
||||
fkfj: JSON.stringify(fkfjList)
|
||||
}
|
||||
qcckPost(params, '/mosty-gsxt/zlxx/fk').then((res) => {
|
||||
proxy.$message({ type: "success", message: "反馈成功" });
|
||||
|
||||
@ -4,21 +4,17 @@
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch">
|
||||
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
||||
<el-icon style="vertical-align: middle"><CirclePlus /></el-icon>
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</Search>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="margTop">
|
||||
<MyTable
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount"
|
||||
:tableConfiger="pageData.tableConfiger"
|
||||
:controlsWidth="pageData.controlsWidth"
|
||||
>
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
|
||||
|
||||
<template #zllx="{ row }">
|
||||
<DictTag :tag="false" :value="row.zllx" :options="D_GS_XS_ZLLX" />
|
||||
@ -40,18 +36,13 @@
|
||||
<el-link size="small" type="warning" @click="fkRow(row)">反馈</el-link>
|
||||
<el-link size="small" type="primary" @click="addEdit('edit', row)" v-if="showBtn(row)">编辑</el-link>
|
||||
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteRow(row.id)" v-if="showBtn(row)">删除</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteRow(row.id)" :disabled="!canDelete(row)">删除</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages
|
||||
@changeNo="changeNo"
|
||||
@changeSize="changeSize"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:pageConfiger="{
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"
|
||||
></Pages>
|
||||
}"></Pages>
|
||||
</div>
|
||||
<!-- 详情 -->
|
||||
</div>
|
||||
@ -71,7 +62,7 @@ import { useRoute } from "vue-router";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick, watch } from "vue";
|
||||
import { getItem } from '@/utils/storage'
|
||||
const { proxy } = getCurrentInstance();
|
||||
const {D_GS_XS_SJLY,D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ,D_GS_XS_CZZT} = proxy.$dict('D_GS_XS_SJLY','D_GS_XS_ZLLX','D_GS_ZDQT_FXDJ','D_GS_XS_CZZT')
|
||||
const { /*D_GS_XS_SJLY,*/ D_GS_XS_ZLLX, D_GS_ZDQT_FXDJ, D_GS_XS_CZZT } = proxy.$dict(/*'D_GS_XS_SJLY',*/ 'D_GS_XS_ZLLX', 'D_GS_ZDQT_FXDJ', 'D_GS_XS_CZZT')
|
||||
const detailDiloag = ref();
|
||||
const isShow = ref(false);
|
||||
const searchBox = ref(); //搜索框
|
||||
@ -102,6 +93,7 @@ const pageData = reactive({
|
||||
{ label: '指令标题', prop: 'zlbt' },
|
||||
{ label: '指令类型', prop: 'zllx', showSolt: true },
|
||||
{ label: '指令等级', prop: 'zldj', showSolt: true },
|
||||
{ label: '主送单位', prop: 'sfqs', showSolt: true },
|
||||
{ label: '反馈截止时间', prop: 'jssj' },
|
||||
{ label: '处置状态', prop: 'czzt', showSolt: true },
|
||||
{ label: '是否反馈', prop: 'sffk', showSolt: true },
|
||||
@ -205,6 +197,14 @@ const showBtn = (row) => {
|
||||
// // return ''
|
||||
// // }
|
||||
}
|
||||
const canDelete = (row) => {
|
||||
const roleList = getItem('roleList') || []
|
||||
const roleCodes = roleList.map(r => r.roleCode)
|
||||
|
||||
if (roleCodes.includes('JS_666666') || roleCodes.includes('JS_777777')) return true
|
||||
if (roleCodes.includes('JS_888888')) return row.ssbmdm == userInfo.value?.deptCode
|
||||
return false
|
||||
}
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
|
||||
@ -81,7 +81,7 @@ import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
|
||||
import { qcckGet } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const {D_GS_ZDQT_FXDJ,D_GS_XS_ZLLX,D_GS_XS_CZZT,D_GS_XS_LY, D_BZ_SSZT,D_BZ_SF,D_GS_XS_LX ,D_GS_XS_QTLX,D_BZ_XB,D_BZ_XSSHZT} = proxy.$dict("D_GS_ZDQT_FXDJ","D_GS_XS_ZLLX","D_GS_XS_CZZT","D_GS_XS_LY","D_BZ_SSZT","D_BZ_SF","D_GS_XS_LX","D_GS_XS_QTLX","D_BZ_XB","D_BZ_XSSHZT"); //获取字典数据
|
||||
const {D_GS_ZDQT_FXDJ,D_GS_XS_ZLLX,/*D_GS_XS_CZZT,*/D_GS_XS_LY, D_BZ_SSZT,D_BZ_SF,D_GS_XS_LX ,D_GS_XS_QTLX,D_BZ_XB,D_BZ_XSSHZT} = proxy.$dict("D_GS_ZDQT_FXDJ","D_GS_XS_ZLLX",/*"D_GS_XS_CZZT",*/"D_GS_XS_LY","D_BZ_SSZT","D_BZ_SF","D_GS_XS_LX","D_GS_XS_QTLX","D_BZ_XB","D_BZ_XSSHZT"); //获取字典数据
|
||||
const detailDiloag = ref();
|
||||
const searchBox = ref(); //搜索框
|
||||
const isShow = ref(false)
|
||||
|
||||
@ -90,7 +90,7 @@ import Detail from "./components/detail.vue";
|
||||
import { qcckGet, qcckPost, ParsingText } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const {D_GS_ZDQT_FXDJ,D_GS_XS_ZLLX,D_GS_XS_CZZT,D_GS_XS_LY, D_BZ_SSZT,D_BZ_SF,D_GS_XS_LX ,D_GS_XS_QTLX,D_BZ_XB,D_BZ_XSSHZT} = proxy.$dict("D_GS_ZDQT_FXDJ","D_GS_XS_ZLLX","D_GS_XS_CZZT","D_GS_XS_LY","D_BZ_SSZT","D_BZ_SF","D_GS_XS_LX","D_GS_XS_QTLX","D_BZ_XB","D_BZ_XSSHZT"); //获取字典数据
|
||||
const {/*D_GS_ZDQT_FXDJ,*//*D_GS_XS_ZLLX,*//*D_GS_XS_CZZT,*/D_GS_XS_LY, D_BZ_SSZT,D_BZ_SF,D_GS_XS_LX ,D_GS_XS_QTLX,D_BZ_XB/*,D_BZ_XSSHZT*/} = proxy.$dict(/*"D_GS_ZDQT_FXDJ",*//*"D_GS_XS_ZLLX",*//*"D_GS_XS_CZZT",*/"D_GS_XS_LY","D_BZ_SSZT","D_BZ_SF","D_GS_XS_LX","D_GS_XS_QTLX","D_BZ_XB"/*,"D_BZ_XSSHZT"*/); //获取字典数据
|
||||
const detailDiloag = ref();
|
||||
const detailForm = ref();
|
||||
const searchBox = ref(); //搜索框
|
||||
|
||||
@ -1,91 +1,38 @@
|
||||
<template>
|
||||
<section class="query-wrap">
|
||||
<div class="query-title">{{ title }}</div>
|
||||
<div class="query-grid">
|
||||
<div class="query-title" @click="toggleCollapse">
|
||||
<span class="title-text">{{ title }}</span>
|
||||
<el-icon class="collapse-icon" :class="{ 'is-collapsed': isCollapsed }">
|
||||
<ArrowDown />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="query-grid" v-show="!isCollapsed">
|
||||
<div v-for="field in renderFields" :key="field.key" class="query-cell">
|
||||
<div class="cell-label">{{ field.label }}</div>
|
||||
<div
|
||||
class="cell-control"
|
||||
:class="{ 'is-checkbox': field.type === 'checkbox' }"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
v-if="field.type === 'input'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-input"
|
||||
:placeholder="field.placeholder || ''"
|
||||
/>
|
||||
<el-input
|
||||
clearable
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-input"
|
||||
type="number"
|
||||
:placeholder="field.placeholder || ''"
|
||||
/>
|
||||
<el-select
|
||||
clearable
|
||||
v-else-if="field.type === 'select'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-select"
|
||||
:placeholder="field.placeholder || '请选择'"
|
||||
:multiple="field.multiple || false"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
>
|
||||
<el-option
|
||||
v-for="item in field.options || []"
|
||||
:key="item.value ?? item"
|
||||
:label="item.label ?? item"
|
||||
:value="item.value ?? item"
|
||||
/>
|
||||
<div class="cell-control" :class="{ 'is-checkbox': field.type === 'checkbox' }">
|
||||
<el-input clearable v-if="field.type === 'input'" v-model="formState[field.key]" class="control-input"
|
||||
:placeholder="field.placeholder || ''" />
|
||||
<el-input clearable v-else-if="field.type === 'number'" v-model="formState[field.key]" class="control-input"
|
||||
type="number" :placeholder="field.placeholder || ''" />
|
||||
<el-select clearable v-else-if="field.type === 'select'" v-model="formState[field.key]" class="control-select"
|
||||
:placeholder="field.placeholder || '请选择'" :multiple="field.multiple || false" collapse-tags
|
||||
collapse-tags-tooltip>
|
||||
<el-option v-for="item in field.options || []" :key="item.value ?? item" :label="item.label ?? item"
|
||||
:value="item.value ?? item" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-date"
|
||||
type="date"
|
||||
:placeholder="field.placeholder || '请选择日期'"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-else-if="field.type === 'datetime'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-date"
|
||||
type="datetime"
|
||||
:placeholder="field.placeholder || '请选择时间'"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-else-if="field.type === 'daterange'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-date"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-else-if="field.type === 'datetimerange'"
|
||||
v-model="formState[field.key]"
|
||||
class="control-date"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
<el-date-picker clearable v-else-if="field.type === 'date'" v-model="formState[field.key]"
|
||||
class="control-date" type="date" :placeholder="field.placeholder || '请选择日期'" value-format="YYYY-MM-DD" />
|
||||
<el-date-picker clearable v-else-if="field.type === 'datetime'" v-model="formState[field.key]"
|
||||
class="control-date" type="datetime" :placeholder="field.placeholder || '请选择时间'"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" />
|
||||
<el-date-picker clearable v-else-if="field.type === 'daterange'" v-model="formState[field.key]"
|
||||
class="control-date" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD" />
|
||||
<el-date-picker clearable v-else-if="field.type === 'datetimerange'" v-model="formState[field.key]"
|
||||
class="control-date" type="datetimerange" range-separator="至" start-placeholder="开始时间"
|
||||
end-placeholder="结束时间" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||
<template v-else-if="field.type === 'department'">
|
||||
<MOSTY.Department
|
||||
clearable
|
||||
v-model="formState[field.key]"
|
||||
class="control-select"
|
||||
/>
|
||||
<MOSTY.Department clearable v-model="formState[field.key]" class="control-select" />
|
||||
</template>
|
||||
<div v-else-if="field.type === 'checkbox'" class="checkbox-wrap">
|
||||
<el-checkbox v-model="formState[field.key]" />
|
||||
@ -104,8 +51,7 @@
|
||||
<el-button size="small" type="primary" @click="handleSearch">{{
|
||||
searchText
|
||||
}}</el-button>
|
||||
<el-button size="small" type="button" @click="handleReset"
|
||||
>重置
|
||||
<el-button size="small" type="button" @click="handleReset">重置
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -113,7 +59,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, reactive, watch } from "vue";
|
||||
import { computed, reactive, ref, watch } from "vue";
|
||||
import { ArrowDown } from '@element-plus/icons-vue';
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
const props = defineProps({
|
||||
title: {
|
||||
@ -132,11 +79,29 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
defaultCollapsed: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
collapsedHeight: {
|
||||
type: Number,
|
||||
default: 34
|
||||
},
|
||||
expandedHeight: {
|
||||
type: Number,
|
||||
default: 276
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const emit = defineEmits(['update:modelValue',"search", "submit", "reset"]);
|
||||
const emit = defineEmits(['update:modelValue', "search", "submit", "reset", "collapse"]);
|
||||
const formState = reactive({});
|
||||
const isCollapsed = ref(props.defaultCollapsed);
|
||||
|
||||
const toggleCollapse = () => {
|
||||
isCollapsed.value = !isCollapsed.value;
|
||||
emit('collapse', isCollapsed.value);
|
||||
};
|
||||
|
||||
watch(() => formState, val => {
|
||||
emit('update:modelValue', val)
|
||||
@ -236,7 +201,9 @@ watch(
|
||||
defineExpose({
|
||||
formState,
|
||||
handleSearch,
|
||||
handleReset
|
||||
handleReset,
|
||||
isCollapsed,
|
||||
collapsedHeight: props.collapsedHeight
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -244,22 +211,46 @@ defineExpose({
|
||||
.query-wrap {
|
||||
border: 1px solid #b8d3ff;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.query-title {
|
||||
height: 32px;
|
||||
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
|
||||
line-height: 32px;
|
||||
padding-left: 10px;
|
||||
padding: 0 10px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #0d2148;
|
||||
border-bottom: 1px solid #b8d3ff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
.title-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.collapse-icon {
|
||||
font-size: 16px;
|
||||
color: #0d2148;
|
||||
transition: transform 0.3s;
|
||||
|
||||
&.is-collapsed {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.query-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
flex: 1;
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.query-cell {
|
||||
@ -366,6 +357,7 @@ defineExpose({
|
||||
|
||||
.query-action {
|
||||
height: 36px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
// justify-content: flex-end;
|
||||
justify-content: space-between;
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
:align="selectionColumnAlign" />
|
||||
<el-table-column v-for="column in columns" :key="column.prop || column.label || column.type" :prop="column.prop"
|
||||
:type="column.type" :label="column.label" :width="column.width" :min-width="column.minWidth"
|
||||
:align="column.align" :show-overflow-tooltip="true">
|
||||
:align="column.align" :show-overflow-tooltip="isColumnOverflow(column)">
|
||||
<template v-if="column.slotName" #default="scope">
|
||||
<slot v-if="column.slotName" :name="column.slotName" :row="scope.row" :column="column"
|
||||
<slot :name="column.slotName" :row="scope.row" :column="column"
|
||||
:$index="scope.$index">
|
||||
{{ column.prop ? scope.row[column.prop] : '' }}
|
||||
</slot>
|
||||
@ -87,6 +87,15 @@ const onSelectionChange = (selection) => {
|
||||
emit('selection-change', selection)
|
||||
emit('row-change', selection[0] || null)
|
||||
}
|
||||
|
||||
// 判断列是否需要overflow tooltip:只有当列有值时才启用
|
||||
const isColumnOverflow = (column) => {
|
||||
if (!column.prop) return false
|
||||
return props.data.some(row => {
|
||||
const val = row[column.prop]
|
||||
return val !== undefined && val !== null && val !== ''
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="ces-page">
|
||||
<QueryFormPanel :fields="queryFields" @search="handleSearch" />
|
||||
<WarnDataTable :data="tableData" :columns="columns" :selection-mode="selectionMode" :loading="loading">
|
||||
<div ref="queryFormRef">
|
||||
<QueryFormPanel :fields="queryFields" @search="handleSearch" @collapse="handleCollapse" />
|
||||
</div>
|
||||
<WarnDataTable :data="tableData" :columns="columns" :selection-mode="selectionMode" :loading="loading" :tableHeight="tableHeight">
|
||||
<template #status="{ row }">
|
||||
<span class="status" :class="row.statusClass">{{ row.status }}</span>
|
||||
</template>
|
||||
@ -18,14 +20,37 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
import QueryFormPanel from './components/QueryFormPanel.vue'
|
||||
import WarnDataTable from './components/WarnDataTable.vue'
|
||||
|
||||
const queryFormRef = ref()
|
||||
const tableHeight = ref('600px')
|
||||
const selectionMode = ref('multiple')
|
||||
const loading = ref(false)
|
||||
const lastQueryParams = ref({})
|
||||
|
||||
const calcTableHeight = () => {
|
||||
nextTick(() => {
|
||||
const queryEl = queryFormRef.value
|
||||
if (queryEl) {
|
||||
const queryHeight = queryEl.offsetHeight
|
||||
const pageHeight = window.innerHeight
|
||||
const padding = 40
|
||||
tableHeight.value = pageHeight - queryHeight - padding
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleCollapse = () => {
|
||||
setTimeout(calcTableHeight, 350)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
calcTableHeight()
|
||||
window.addEventListener('resize', calcTableHeight)
|
||||
})
|
||||
|
||||
const handleSearch = (params) => {
|
||||
lastQueryParams.value = params
|
||||
}
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<PageTitle
|
||||
:malginLeft="10"
|
||||
:height="35"
|
||||
backgroundColor="#ffff"
|
||||
:marginBottom="5"
|
||||
:marginTop="5"
|
||||
>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<!-- -->
|
||||
<template v-for="(item, index) in butList" :key="index">
|
||||
@ -24,11 +18,7 @@
|
||||
>{{ item }}</el-button
|
||||
>
|
||||
</template>
|
||||
<el-select
|
||||
v-model="value"
|
||||
placeholder="请选择预警类型"
|
||||
@change="qh = value"
|
||||
>
|
||||
<el-select v-model="value" placeholder="请选择预警类型" @change="qh = value">
|
||||
<el-option label="人像预警" value="人像预警" />
|
||||
<el-option label="车辆预警" value="车辆预警" />
|
||||
<el-option label="区域预警" value="区域预警" />
|
||||
@ -59,12 +49,7 @@
|
||||
<el-option label="组合预警" value="组合预警" />
|
||||
</el-select>
|
||||
</el-popover> -->
|
||||
<el-button
|
||||
:type="qh == item ? 'primary' : 'default'"
|
||||
@click="qh = item"
|
||||
size="small"
|
||||
>{{ item }}</el-button
|
||||
>
|
||||
<el-button :type="qh == item ? 'primary' : 'default'" @click="qh = item" size="small">{{ item }}</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</PageTitle>
|
||||
@ -93,7 +78,6 @@ import BehaviorWarning from "@/views/backOfficeSystem/fourColorManage/warningCon
|
||||
import CombinedWarning from "@/views/backOfficeSystem/fourColorManage/warningControl/combinedWarning/index.vue";
|
||||
import PortraitWarning from "@/views/backOfficeSystem/fourColorManage/warningList/portraitWarning/index.vue";
|
||||
import VehicleWarning from "@/views/backOfficeSystem/fourColorManage/warningList/vehicleWarning/index.vue";
|
||||
// import ControlWarning from "@/views/backOfficeSystem/fourColorManage/warningControl/controlWarning/index.vue";
|
||||
import RegionalControl from "@/views/backOfficeSystem/fourColorManage/warningControl/regionalControl/index.vue";
|
||||
import WrjWarning from "@/views/backOfficeSystem/fourColorManage/warningControl/wrjWarning/index.vue";
|
||||
import PoliticalSecurityWarning from "@/views/backOfficeSystem/fourColorManage/warningControl/politicalSecurity/index.vue";
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link type="primary" @click="chooseJfFun(row)">配置系统</el-link>
|
||||
<el-link type="primary" @click="chooseJfFun(row)">配置系数</el-link>
|
||||
<el-link type="primary" @click="addEdit('edit', row)">编辑</el-link>
|
||||
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
|
||||
</template>
|
||||
@ -51,8 +51,8 @@
|
||||
<!-- 编辑详情 -->
|
||||
<EditAddForm v-if="show" ref="detailDiloag" :dic="{ D_GS_BQ_LX, D_GS_BQ_DJ, D_GS_SSYJ, D_GS_BQ_LB }"
|
||||
@updateDate="getList" />
|
||||
<ChooseJf v-model="chooseJfShow" titleValue="选择系数" :Single="false"
|
||||
:chooseJfBh="chooseJfBh" url="/tbGsxtBqzh/sjxspz" :roleIds="roleIds"/>
|
||||
<ChooseJf v-model="chooseJfShow" titleValue="选择系数" :Single="false" :chooseJfBh="chooseJfBh" url="/tbGsxtBqzh/sjxspz"
|
||||
:roleIds="roleIds" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -45,10 +45,11 @@
|
||||
<template #controls="{ row }">
|
||||
<el-link type="warning" @click="pushAssess(row)">全息档案</el-link>
|
||||
<el-link type="primary" @click="handleCzjy(row)" v-if="roleCode">处置建议</el-link>
|
||||
<el-link type="primary" @click="chooseJfFun(row)" >配置系统</el-link>
|
||||
<el-link type="primary" @click="chooseJfFun(row)">配置系数</el-link>
|
||||
<!-- <el-link type="primary" @click="showDetail(row)">转合成</el-link>
|
||||
<el-link type="danger" @click="delDictItem(row.id)">转会商</el-link> -->
|
||||
<el-link type="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01' && permission_sfqs ">签收</el-link>
|
||||
<el-link type="success" @click="handleQsFk(row, '签收')"
|
||||
v-if="row.czzt == '01' && permission_sfqs">签收</el-link>
|
||||
<el-link type="success" @click="handleQsFk(row, '反馈')" v-if="row.czzt == '02' && permission_sfqs">反馈</el-link>
|
||||
<!-- <el-link type="success" @click="handleQsFk(row, '查看反馈')" v-else>查看反馈</el-link> -->
|
||||
<el-link type="primary" @click="openAddModel(row)">详情</el-link>
|
||||
@ -65,11 +66,7 @@
|
||||
<HolographicArchive v-model="assessShow" :dataList="dataList" />
|
||||
<FkDialog @change="getList" lx="02" />
|
||||
<Information v-model="showDialog" title="发送指令" @submit='submit' @close='closeFszl'>
|
||||
<SemdFqzl
|
||||
ref="semdFqzlRef"
|
||||
:itemData="itemData"
|
||||
@handleClose="handleClose"
|
||||
identification="yj"
|
||||
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="yj"
|
||||
:tacitly="tacitly" />
|
||||
</Information>
|
||||
<!-- 详情 -->
|
||||
@ -77,8 +74,8 @@
|
||||
|
||||
<!-- 处置建议 -->
|
||||
<Czjy ref="czjyRef" @okSubmit="getList"></Czjy>
|
||||
<ChooseJf v-model="chooseJfShow" titleValue="选择系数" :Single="false"
|
||||
:chooseJfBh="chooseJfBh" url="/yjzxXwyj/sjxspz" :roleIds="roleIds"/>
|
||||
<ChooseJf v-model="chooseJfShow" titleValue="选择系数" :Single="false" :chooseJfBh="chooseJfBh" url="/yjzxXwyj/sjxspz"
|
||||
:roleIds="roleIds" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -411,5 +408,4 @@ const handleQs = () => {
|
||||
overflow: unset !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<QueryFormPanel v-model="listQuery" :fields="searchConfiger" @search='onSearch'>
|
||||
<QueryFormPanel v-model="listQuery" :fields="searchConfiger" @search='onSearch' @collapse="tabHeightFn">
|
||||
<template #jfd>
|
||||
<div>
|
||||
<el-input v-model="queryFrom.ksfz" type="number" placeholder="开始身份分值" style="width: 130px"></el-input>
|
||||
@ -41,7 +41,7 @@
|
||||
<div style="display: flex;justify-content: space-between;">
|
||||
<span class="warning" @click="pushAssess(row)">全息档案</span>
|
||||
<span class="primary" @click="handleCzjy(row)" v-if="roleCode">处置建议</span>
|
||||
<span class="primary" @click="chooseJfFun(row)">配置系统</span>
|
||||
<span class="primary" @click="chooseJfFun(row)">配置系数</span>
|
||||
<span class="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01' && permission_sfqs">签收</span>
|
||||
<span class="success" @click="handleQsFk(row, '反馈')" v-if="row.czzt == '02' && permission_sfqs">反馈</span>
|
||||
<span class="primary" @click="openAddModel(row)">详情</span>
|
||||
@ -87,7 +87,7 @@ import Information from "@/views/home/model/information.vue";
|
||||
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import AddFrom from './components/addFrom.vue'
|
||||
import { holographicProfileJump } from "@/utils/tools.js"
|
||||
import { getMultiDictVal } from "@/utils/dict.js"
|
||||
@ -194,6 +194,7 @@ const onSearch = (val) => {
|
||||
queryFrom.value.endTime = val.startTime ? val.startTime[1] : ''
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList()
|
||||
nextTick(tabHeightFn);
|
||||
}
|
||||
const reset = () => {
|
||||
delete queryFrom.value.ksfz
|
||||
@ -302,12 +303,12 @@ const chooseJfFun = (val) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
nextTick(() => {
|
||||
if (!searchBox.value) return;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 230;
|
||||
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
});
|
||||
};
|
||||
window.addEventListener('resize', tabHeightFn);
|
||||
|
||||
|
||||
/** 触发选中 */
|
||||
|
||||
@ -1,61 +1,26 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:draggable="true"
|
||||
v-model="showDialog"
|
||||
:append-to-body="true"
|
||||
:destroy-on-close="true"
|
||||
:title="title"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<FormMessage
|
||||
v-model="listQuery"
|
||||
:disabled="title == '反馈' ? false : true"
|
||||
:formList="formData"
|
||||
labelWidth="160px"
|
||||
ref="elform"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-dialog :draggable="true" v-model="showDialog" :append-to-body="true" :destroy-on-close="true" :title="title"
|
||||
:close-on-click-modal="false">
|
||||
<FormMessage v-model="listQuery" :disabled="title == '反馈' ? false : true" :formList="formData" labelWidth="160px"
|
||||
ref="elform" :rules="rules">
|
||||
<template #mbzrmjxm>
|
||||
<MOSTY.Other
|
||||
width="100%"
|
||||
@click="handleChoose('mbzrmjxm')"
|
||||
clearable
|
||||
v-model="listQuery.mbzrmjxm"
|
||||
placeholder="请选择民警"
|
||||
:readonly="true"
|
||||
/>
|
||||
<MOSTY.Other width="100%" @click="handleChoose('mbzrmjxm')" clearable v-model="listQuery.mbzrmjxm"
|
||||
placeholder="请选择民警" :readonly="true" />
|
||||
</template>
|
||||
<template #czzrmj>
|
||||
<MOSTY.Other
|
||||
width="100%"
|
||||
@click="handleChoose('czzrmj')"
|
||||
clearable
|
||||
v-model="listQuery.czzrmj"
|
||||
placeholder="请选择民警"
|
||||
:readonly="true"
|
||||
/>
|
||||
<MOSTY.Other width="100%" @click="handleChoose('czzrmj')" clearable v-model="listQuery.czzrmj"
|
||||
placeholder="请选择民警" :readonly="true" />
|
||||
</template>
|
||||
</FormMessage>
|
||||
<template #footer>
|
||||
<div class="flex just-center">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitForm"
|
||||
:loading="loading"
|
||||
v-if="title == '反馈'"
|
||||
>确认</el-button
|
||||
>
|
||||
<el-button type="primary" @click="submitForm" :loading="loading" v-if="title == '反馈'">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<ChooseUser
|
||||
v-model="chooseUserVisible"
|
||||
v-if="chooseUserVisible"
|
||||
@choosedUsers="handleUserSelected"
|
||||
:roleIds="roleIds"
|
||||
:Single="true"
|
||||
/>
|
||||
<ChooseUser v-model="chooseUserVisible" v-if="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds"
|
||||
:Single="true" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -64,6 +29,7 @@ import * as MOSTY from "@/components/MyComponents/index";
|
||||
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
|
||||
import emitter from "@/utils/eventBus.js";
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import { getItem } from "@/utils/storage";
|
||||
import { onMounted, reactive, ref, getCurrentInstance, onUnmounted, watch } from "vue";
|
||||
const props = defineProps({
|
||||
lx: {
|
||||
@ -88,6 +54,9 @@ const showDialog = ref(false);
|
||||
const loading = ref(false);
|
||||
const choosetype = ref("");
|
||||
const listQuery = ref({});
|
||||
const userIfo = ref('')
|
||||
const idEntityCard = ref()
|
||||
const USERNAME = ref()
|
||||
const formData = ref([
|
||||
{ label: "发现目标状态", prop: "mbzt", type: "select", options: D_BZ_SF },
|
||||
{
|
||||
@ -96,6 +65,7 @@ const formData = ref([
|
||||
type: "select",
|
||||
options: D_YJXX_CKCZJG
|
||||
},
|
||||
{ label: "处置经过描述", prop: "czjgms", type: "textarea", width: "100%" },
|
||||
{
|
||||
label: "发现目标责任单位",
|
||||
prop: "mbzrdwdm",
|
||||
@ -172,7 +142,8 @@ const rules = reactive({
|
||||
// ckczcsxl: [
|
||||
// { required: true, message: "请选择常控处置措施细类", trigger: "change" }
|
||||
// ],
|
||||
ckczjg: [{ required: true, message: "请输入常控处置结果", trigger: "blur" }]
|
||||
ckczjg: [{ required: true, message: "请输入常控处置结果", trigger: "blur" }],
|
||||
czjgms: [{ required: true, message: "请输入常控处置反馈补充信息", trigger: "blur" }]
|
||||
// cklxzcpg: [
|
||||
// { required: true, message: "请输入常控立线侦察评估", trigger: "blur" }
|
||||
// ],
|
||||
@ -186,16 +157,8 @@ const rules = reactive({
|
||||
});
|
||||
|
||||
const title = ref("");
|
||||
onMounted(() => {
|
||||
// 监听 mbzt 变化,动态显示/隐藏常控处置措施字段
|
||||
watch(() => listQuery.value.mbzt, (newVal) => {
|
||||
const ckczcslxField = formData.value.find(item => item.prop === 'ckczcslx');
|
||||
const ckczcsxlField = formData.value.find(item => item.prop === 'ckczcsxl');
|
||||
if (ckczcslxField) ckczcslxField.show = newVal === '1';
|
||||
if (ckczcsxlField) ckczcsxlField.show = newVal === '1';
|
||||
});
|
||||
|
||||
emitter.on("openFkDialog", (val) => {
|
||||
// 事件处理函数引用,用于正确取消监听
|
||||
const handleOpenFkDialog = (val) => {
|
||||
showDialog.value = true;
|
||||
listQuery.value = { yjid: val.id };
|
||||
let url = "";
|
||||
@ -214,6 +177,9 @@ onMounted(() => {
|
||||
case "04":
|
||||
url = "/mosty-gsxt/yjzxZhyj/";
|
||||
break;
|
||||
case "05":
|
||||
url = "/mosty-gsxt/tbYjxx/getInfo/";
|
||||
break;
|
||||
}
|
||||
title.value = val.type;
|
||||
if (val.type == "查看反馈") {
|
||||
@ -222,7 +188,23 @@ onMounted(() => {
|
||||
listQuery.value = list.length > 0 ? list[0] : {};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// watch 应该在 setup 顶层定义,不要放在 onMounted 内部
|
||||
watch(() => listQuery.value.mbzt, (newVal) => {
|
||||
const ckczcslxField = formData.value.find(item => item.prop === 'ckczcslx');
|
||||
const ckczcsxlField = formData.value.find(item => item.prop === 'ckczcsxl');
|
||||
if (ckczcslxField) ckczcslxField.show = newVal === '1';
|
||||
if (ckczcsxlField) ckczcsxlField.show = newVal === '1';
|
||||
});
|
||||
|
||||
// 事件监听应该在 setup 顶层注册,确保组件创建后立即可用
|
||||
emitter.on("openFkDialog", handleOpenFkDialog);
|
||||
|
||||
onMounted(() => {
|
||||
userIfo.value = getItem('deptId') ? getItem('deptId')[0] : {}
|
||||
idEntityCard.value = getItem('idEntityCard')
|
||||
USERNAME.value = getItem('USERNAME')
|
||||
});
|
||||
|
||||
const handleChoose = (type) => {
|
||||
@ -247,7 +229,8 @@ const submitForm = () => {
|
||||
elform.value.submit((val) => {
|
||||
loading.value = true;
|
||||
const prome = {
|
||||
...listQuery.value
|
||||
...listQuery.value,
|
||||
xm: USERNAME.value, sfzh: idEntityCard.value, ssbmdm: userIfo.value.deptCode
|
||||
};
|
||||
let url = "";
|
||||
switch (props.lx) {
|
||||
@ -287,7 +270,8 @@ const close = () => {
|
||||
};
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off("openFkDialog");
|
||||
// 传递具体的处理函数引用,确保正确移除监听器
|
||||
emitter.off("openFkDialog", handleOpenFkDialog);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
<template #controls="{ row }">
|
||||
<el-link type="warning" @click="pushAssess(row)">全息档案</el-link>
|
||||
<el-link type="primary" @click="handleCzjy(row)" v-if="roleCode">处置建议</el-link>
|
||||
<el-link type="primary" @click="chooseJfFun(row)">配置系统</el-link>
|
||||
<el-link type="primary" @click="chooseJfFun(row)">配置系数</el-link>
|
||||
<!-- <el-link type="primary" @click="showDetail(row)">转合成</el-link>
|
||||
<el-link type="danger" @click="delDictItem(row.id)">转会商</el-link> -->
|
||||
<el-link type="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01' && permission_sfqs">签收</el-link>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<QueryFormPanel v-model="listQuery" :fields="searchConfiger" @search='onSearch'>
|
||||
<QueryFormPanel v-model="listQuery" :fields="searchConfiger" @search='onSearch' @collapse="tabHeightFn">
|
||||
<template #jfd>
|
||||
<div>
|
||||
<el-input v-model="queryFrom.ksfz" type="number" placeholder="开始身份分值" style="width: 130px"></el-input>
|
||||
@ -42,7 +42,7 @@
|
||||
<div style="display: flex;justify-content: space-between;">
|
||||
<span class="warning" @click="pushAssess(row)">全息档案</span>
|
||||
<span class="primary" @click="handleCzjy(row)" v-if="roleCode">处置建议</span>
|
||||
<span class="primary" @click="chooseJfFun(row)">配置系统</span>
|
||||
<span class="primary" @click="chooseJfFun(row)">配置系数</span>
|
||||
<span class="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01' && permission_sfqs">签收</span>
|
||||
<span class="success" @click="handleQsFk(row, '反馈')"
|
||||
v-else-if="row.czzt == '02' && permission_sfqs">反馈</span>
|
||||
@ -84,7 +84,7 @@ import Information from "@/views/home/model/information.vue";
|
||||
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
|
||||
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
|
||||
import AddFrom from "./components/addFrom.vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import { qcckPost } from "@/api/qcckApi.js";
|
||||
import Detail from './components/detail.vue'
|
||||
import { exportExlByObj } from "@/utils/exportExcel.js"
|
||||
@ -175,6 +175,7 @@ const onSearch = (val) => {
|
||||
queryFrom.value.endTime = val.startTime ? val.startTime[1] : ''
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList();
|
||||
nextTick(tabHeightFn);
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
@ -305,12 +306,12 @@ const chooseJfFun = (val) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
nextTick(() => {
|
||||
if (!searchBox.value) return;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 230;
|
||||
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
});
|
||||
};
|
||||
window.addEventListener('resize', tabHeightFn);
|
||||
|
||||
|
||||
const handleChooseData = (val) => {
|
||||
|
||||
@ -2,93 +2,43 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<QueryFormPanel
|
||||
v-model="listQuery"
|
||||
:fields="searchConfiger"
|
||||
@search="onSearch"
|
||||
>
|
||||
<QueryFormPanel v-model="listQuery" :fields="searchConfiger" @search="onSearch" @collapse="tabHeightFn">
|
||||
<template #but>
|
||||
<el-button type="primary" @click="exportExl" size="small"
|
||||
>导出</el-button
|
||||
>
|
||||
<el-button type="primary" size="small" @click="handleQs"
|
||||
>签收</el-button
|
||||
>
|
||||
<el-button type="primary" @click="exportExl" size="small">导出</el-button>
|
||||
<el-button type="primary" size="small" @click="handleQs">签收</el-button>
|
||||
</template>
|
||||
</QueryFormPanel>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div
|
||||
class="tabBox_zdy"
|
||||
:style="{ height: pageData.tableHeight + 40 + 'px' }"
|
||||
>
|
||||
<WarnDataTable
|
||||
:loading="pageData.tableConfiger.loading"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:data="pageData.tableData"
|
||||
:columns="pageData.tableColumn"
|
||||
table-class="warn-table"
|
||||
@selectionChange="handleChooseData"
|
||||
>
|
||||
<div class="tabBox_zdy" :style="{ height: pageData.tableHeight + 40 + 'px' }">
|
||||
<WarnDataTable :loading="pageData.tableConfiger.loading" :tableHeight="pageData.tableHeight"
|
||||
:data="pageData.tableData" :columns="pageData.tableColumn" table-class="warn-table"
|
||||
@selectionChange="handleChooseData">
|
||||
<template #yjTp="{ row }">
|
||||
<template v-if="!row.yjTp || row.yjTp.includes('baidu')">
|
||||
<img
|
||||
src="@/assets/images/car.png"
|
||||
width="30"
|
||||
height="30"
|
||||
v-if="row.yjLx == 2"
|
||||
/>
|
||||
<img
|
||||
src="@/assets/images/default_male.png"
|
||||
width="30"
|
||||
height="30"
|
||||
v-else
|
||||
/>
|
||||
<img src="@/assets/images/car.png" width="30" height="30" v-if="row.yjLx == 2" />
|
||||
<img src="@/assets/images/default_male.png" width="30" height="30" v-else />
|
||||
</template>
|
||||
<el-image
|
||||
v-else
|
||||
style="width: 30px; height: 30px"
|
||||
:src="row.yjTp"
|
||||
:preview-src-list="[row.yjTp]"
|
||||
show-progress
|
||||
>
|
||||
<el-image v-else style="width: 30px; height: 30px" :src="row.yjTp" :preview-src-list="[row.yjTp]"
|
||||
show-progress>
|
||||
<template #error>
|
||||
<div class="image-slot error">
|
||||
<img
|
||||
src="@/assets/images/car.png"
|
||||
width="30"
|
||||
height="30"
|
||||
v-if="row.yjLx == 2"
|
||||
/>
|
||||
<img
|
||||
src="@/assets/images/default_male.png"
|
||||
width="30"
|
||||
height="30"
|
||||
v-else
|
||||
/>
|
||||
<img src="@/assets/images/car.png" width="30" height="30" v-if="row.yjLx == 2" />
|
||||
<img src="@/assets/images/default_male.png" width="30" height="30" v-else />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
<template #czzt="{ row }">
|
||||
<DictTag
|
||||
:value="row.czzt"
|
||||
:color="row.czzt === '01' ? '#ff2424' : '#1d72e8'"
|
||||
:tag="false"
|
||||
:options="D_GSXT_YJXX_CZZT"
|
||||
/>
|
||||
<DictTag :value="row.czzt" :color="row.czzt === '01' ? '#ff2424' : '#1d72e8'" :tag="false"
|
||||
:options="D_GSXT_YJXX_CZZT" style="cursor: pointer" @click="openBox(row)" />
|
||||
</template>
|
||||
<template #xbdm="{ row }">
|
||||
<DictTag :value="row.xbdm" :tag="false" :options="D_BZ_XB" />
|
||||
</template>
|
||||
<template #yjJb="{ row }">
|
||||
<div :style="{ 'background-color': bqYs(row.yjJb) }">
|
||||
<DictTag
|
||||
:value="row.yjJb"
|
||||
color="#fff"
|
||||
:tag="false"
|
||||
:options="D_BZ_YJJB"
|
||||
/>
|
||||
<DictTag :value="row.yjJb" color="#fff" :tag="false" :options="D_BZ_YJJB" />
|
||||
</div>
|
||||
</template>
|
||||
<template #bkly="{ row }">
|
||||
@ -107,61 +57,37 @@
|
||||
<template #operation="{ row }">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<span class="warning" @click="pushAssess(row)">全息档案</span>
|
||||
<span class="primary" @click="handleCzjy(row)" v-if="roleCode"
|
||||
>处置建议</span
|
||||
>
|
||||
<span class="primary" @click="handleCzjy(row)" v-if="roleCode">处置建议</span>
|
||||
<!-- <span type="primary" @click="showDetail(row)">转合成</span> -->
|
||||
<!-- <span type="danger" @click="delDictItem(row.id)">转会商</span> -->
|
||||
<span
|
||||
class="success"
|
||||
@click="handleQsFk(row, '签收')"
|
||||
v-if="row.czzt == '01'"
|
||||
>签收</span
|
||||
>
|
||||
<span
|
||||
class="success"
|
||||
@click="handleQsFk(row, '反馈')"
|
||||
v-else-if="row.czzt == '02'"
|
||||
>反馈</span
|
||||
>
|
||||
<span class="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01'">签收</span>
|
||||
<span class="success" @click="handleQsFk(row, '反馈')" v-else-if="row.czzt == '02'">反馈</span>
|
||||
<!-- <span type="success" @click="handleQsFk(row, '查看反馈')" v-else>查看反馈</span> -->
|
||||
<span class="primary" @click="openBox(row)">详情</span>
|
||||
<span class="primary" @click="pushWarning(row)">指派</span>
|
||||
</div>
|
||||
</template>
|
||||
</WarnDataTable>
|
||||
<Pages
|
||||
@changeNo="changeNo"
|
||||
@changeSize="changeSize"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:pageConfiger="{
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"
|
||||
></Pages>
|
||||
}"></Pages>
|
||||
</div>
|
||||
</div>
|
||||
<FkDialog @change="getList" lx="05" />
|
||||
<AddFrom
|
||||
ref="addModelRef"
|
||||
:dict="{ D_GSXT_YJXX_CZZT, D_BZ_YJJB, D_GS_SSYJ }"
|
||||
/>
|
||||
<AddFrom ref="addModelRef" :dict="{ D_GSXT_YJXX_CZZT, D_BZ_YJJB, D_GS_SSYJ }" />
|
||||
<!-- 处置建议 -->
|
||||
<Czjy ref="czjyRef" @okSubmit="getList"></Czjy>
|
||||
<ZpForm v-model="warningShow" :dataList="dataList" />
|
||||
<!-- <Pagination v-model="paginationOpen" /> -->
|
||||
<Pagination
|
||||
v-model="paginationOpen"
|
||||
:dataList="dataPres"
|
||||
:dict="{
|
||||
<Pagination v-model="paginationOpen" :dataList="dataPres" :dict="{
|
||||
D_BZ_XB,
|
||||
D_BZ_YJJB,
|
||||
D_GS_QLZDRLX,
|
||||
D_GS_ZDR_RYJB,
|
||||
D_GS_ZDR_GJLB,
|
||||
D_GS_BK_CZYQ
|
||||
}"
|
||||
/>
|
||||
}" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -187,34 +113,34 @@ const { proxy } = getCurrentInstance();
|
||||
const searchBox = ref();
|
||||
const {
|
||||
D_GS_QLZDRLX,
|
||||
D_BZ_YJLY,
|
||||
// D_BZ_YJLY,
|
||||
D_GSXT_YJXX_CZZT,
|
||||
D_GS_SSYJ,
|
||||
D_BZ_YJJB,
|
||||
D_BZ_BKLYS,
|
||||
// D_BZ_BKLYS,
|
||||
D_BZ_XB,
|
||||
D_BZ_SF,
|
||||
D_GS_CSZT,
|
||||
D_GS_BKZT,
|
||||
D_GS_ZDR_RYJB,
|
||||
D_GS_ZDR_GJLB,
|
||||
D_GS_BK_CZYQ,
|
||||
D_BZ_SJLY
|
||||
D_GS_BK_CZYQ
|
||||
// D_BZ_SJLY
|
||||
} = proxy.$dict(
|
||||
"D_GS_QLZDRLX",
|
||||
"D_BZ_YJLY",
|
||||
// "D_BZ_YJLY",
|
||||
"D_GSXT_YJXX_CZZT",
|
||||
"D_GS_SSYJ",
|
||||
"D_BZ_YJJB",
|
||||
"D_BZ_BKLYS",
|
||||
// "D_BZ_BKLYS",
|
||||
"D_BZ_XB",
|
||||
"D_BZ_SF",
|
||||
"D_GS_CSZT",
|
||||
"D_GS_BKZT",
|
||||
"D_GS_ZDR_RYJB",
|
||||
"D_GS_ZDR_GJLB",
|
||||
"D_GS_BK_CZYQ",
|
||||
"D_BZ_SJLY"
|
||||
"D_GS_BK_CZYQ"
|
||||
// "D_BZ_SJLY"
|
||||
);
|
||||
const dict = reactive({ D_GSXT_YJXX_CZZT, D_GS_SSYJ });
|
||||
// 搜索配置
|
||||
@ -404,7 +330,7 @@ const pageData = reactive({
|
||||
{ label: "相似度", slotName: "xsd", align: "center", width: 50 },
|
||||
{ label: "所属部门", prop: "ssbm", align: "center" },
|
||||
{ label: "数据来源", slotName: "yjLylx", align: "center" },
|
||||
{ label: "操作", width: 180, slotName: "operation" },
|
||||
{ label: "操作", width: 260, slotName: "operation" },
|
||||
{ label: "超时状态", width: 80, align: "center", slotName: "cszt" },
|
||||
{ label: "在控状态", width: 70, align: "center", slotName: "zkzt" }
|
||||
]
|
||||
@ -437,6 +363,7 @@ const onSearch = (val) => {
|
||||
|
||||
pageData.pageConfiger.pageCurrent = 1;
|
||||
getList();
|
||||
nextTick(tabHeightFn);
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
@ -523,13 +450,12 @@ const handleCzjy = (row) => {
|
||||
};
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight =
|
||||
window.innerHeight - searchBox.value.offsetHeight - 230;
|
||||
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
nextTick(() => {
|
||||
if (!searchBox.value) return;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 230;
|
||||
});
|
||||
};
|
||||
window.addEventListener('resize', tabHeightFn);
|
||||
// 指派
|
||||
const dataList = ref(null);
|
||||
const warningShow = ref(false);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user