Compare commits

...

23 Commits

Author SHA1 Message Date
lcw
883416417f lcw 2026-04-29 02:23:59 +08:00
lcw
cd8347d3d1 lcw 2026-04-28 11:26:26 +08:00
lcw
9fa073546b lcw 2026-04-23 09:28:13 +08:00
lcw
836bcf196c Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-04-22 21:07:09 +08:00
lcw
a1e247c2e3 lcw 2026-04-22 21:06:37 +08:00
a2a7335536 更新 2026-04-21 23:20:00 +08:00
dbc6ecf62d 更新 2026-04-21 23:17:28 +08:00
cf455216f9 更新 2026-04-21 20:50:56 +08:00
e4a044944d 更新 2026-04-21 19:42:00 +08:00
lcw
ebdd319f9f Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-04-21 19:23:13 +08:00
lcw
92c1f0be41 lcw 2026-04-21 19:23:00 +08:00
c4cc33bee3 更新 2026-04-21 19:22:56 +08:00
lcw
96e97de237 lcw 2026-04-21 19:22:32 +08:00
5bb7ca0515 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-04-21 19:08:32 +08:00
00c9f1e07f 更新 2026-04-21 19:08:23 +08:00
lcw
76df2bc42c Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-04-21 17:01:37 +08:00
aa1af80bdf 调整 2026-04-21 17:00:48 +08:00
lcw
0020d383bf lcw 2026-04-21 17:00:46 +08:00
571e149313 修改bug 2026-04-20 20:36:59 +08:00
6b563f728f Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-04-20 16:53:32 +08:00
52095b5fb9 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-04-20 16:52:53 +08:00
f31be82805 更新 2026-04-20 16:52:45 +08:00
lcw
35c6849b43 lcw 2026-04-20 16:52:01 +08:00
143 changed files with 9419 additions and 4748 deletions

View File

@ -1 +1 @@
src/
# 取消忽略 src 目录,让 ESLint 正常检查源代码

94
check_unused_dicts.js Normal file
View 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}`);

View 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` | 添加空值安全检查 |

View 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` | 按钮级权限指令 |

View 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 行。但未修复文件名丢失问题。
---
### 方案 Cwindow.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字节 → **原因1Blob 释放过早)**
- 大小一致 → 排除原因1
3. **关闭安全中心测试**:暂时关闭麒麟安全中心,重新下载
- 能正常打开 → **原因3安全拦截**
- 仍打不开 → 排除原因3
---
## 五、方案对比
| | 方案 A 综合修复 | 方案 B 延迟释放 | 方案 C window.open |
|---|---|---|---|
| 修复原因1Blob释放 | ✅ | ✅ | 不涉及 |
| 修复原因2文件名后缀 | ✅ | ❌ | 取决于后端 |
| 处理原因3安全拦截 | ❌ 需系统配置 | ❌ | ❌ |
| 改动量 | ~15行 | 1行 | 最小 |
**建议**先执行排查步骤确认根因再选择对应方案。如果原因1和2同时存在直接用方案A。
---
**文档版本**: v3.0
**创建日期**: 2026-04-24

BIN
gsxt.zip Normal file

Binary file not shown.

View File

@ -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"
]
}
}

View File

@ -45,7 +45,6 @@ onMounted(() => {
/**
*@Descripttion:图片页面初始化
*@Author: PengShuai

View File

@ -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`,

View File

@ -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,

View File

@ -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',

View File

@ -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({

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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;

View File

@ -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
});
}

View File

@ -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">
@ -17,7 +13,7 @@
</template>
<script setup>
import { useRouter, useRoute,onBeforeRouteLeave } from "vue-router";
import { useRouter, useRoute, onBeforeRouteLeave } from "vue-router";
import { ref } from "vue";
import { useStore } from "vuex";
import UpdatePwdDialog from "./UpdatePwdDialog.vue";
@ -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;

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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');
}
}
}

View File

@ -12,6 +12,7 @@ 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: () => ({
@ -55,13 +56,15 @@ 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: {
@ -118,8 +121,7 @@ export default {
oatuhLogin(ctx, userInfo) {
const { token, systemId } = userInfo;
return new Promise((resolve, reject) => {
unifiedLogin({ token, systemId, ssxt: "sgxt" })
.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);
@ -147,8 +149,7 @@ export default {
// 保存登录时间
setTimeStamp();
resolve(data);
})
.catch((err) => {
}).catch((err) => {
reject(err);
});
});
@ -208,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");
// }
}
}
}

View File

@ -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");
// token过期
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);
}
);

View File

@ -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;
}

View File

@ -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,

View File

@ -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(

View File

@ -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();

View File

@ -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([]);

View File

@ -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();

View File

@ -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,

View File

@ -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,13 +69,13 @@
<div id="judgmentRecord-section" v-if="!butShow">
<VisitRecord ref="visitRecord" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="historyAssembly-section" v-if="!butShow" >
<div id="historyAssembly-section" v-if="!butShow">
<CaseInfo ref="caseInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="joblogging-section" v-if="!butShow">
<ActualPerformance ref="actualPerformance" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="joblogging-joblog" v-if="!butShow" >
<div id="joblogging-joblog" v-if="!butShow">
<CzModel ref="czModel" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
</div>
@ -114,7 +114,7 @@ const showBut = ref(false)
const listQuery = ref({});
const butShow = ref(false)
const title = ref('新增')
const showData=ref(false)
const showData = ref(false)
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
@ -207,7 +207,7 @@ const submit = async () => {
info.value.throwData()
// personnelTags.value.throwData(),
]);
tbGsxtZdrySave({...infoData,rylx:'03'}).then(res => {
tbGsxtZdrySave({ ...infoData, rylx: '03' }).then(res => {
proxy.$message({
message: '新增成功',
type: 'success',

View File

@ -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 },
]
});

View File

@ -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({

View File

@ -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: {

View File

@ -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%" },
]);
@ -181,7 +181,7 @@ const gettbGsxtZdryUpdate = () => {
}).finally(() => {
loading.value = false
});
})
})

View File

@ -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;

View File

@ -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 },
]

View File

@ -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'])

View File

@ -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([]);

View File

@ -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",

View File

@ -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 },

View File

@ -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"
);

View File

@ -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>
@ -183,7 +185,7 @@ watch(() => dialogForm.value, (val) => {
{ 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 },
{ label: "", prop: "jbxx", type: "slot", width: '100%',},
{ label: "", prop: "jbxx", type: "slot", width: '100%', },
{ label: "", prop: "shzt", type: "slot", width: '100%' },
]
@ -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(() => {

View File

@ -119,8 +119,8 @@ import { useRoute, useRouter } from 'vue-router'
import * as MOSTY from "@/components/MyComponents/index";
const { proxy } = getCurrentInstance()
const {D_BZ_SSSHZT,D_BZ_LCZT} =proxy.$dict('D_BZ_SSSHZT','D_BZ_LCZT')
const route=useRoute()
const { D_BZ_SSSHZT, D_BZ_LCZT } = proxy.$dict('D_BZ_SSSHZT', 'D_BZ_LCZT')
const route = useRoute()
const emit = defineEmits(["getList"]);
const props = defineProps({
dict: Object,
@ -159,7 +159,7 @@ onMounted(() => {
})
// 初始化数据
const init = () => {
const id= route.query.id
const id = route.query.id
disabled.value = true
fjdz.value = []
getqbcjPldb(id)
@ -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(() => {

View File

@ -22,7 +22,8 @@
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import { reactive, watch,getCurrentInstance } from "vue";
import { saveAs } from 'file-saver';
import { reactive, watch, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
isImg: {
@ -68,7 +69,7 @@ watch(() => listQuery.img, (newVal, oldVal) => {
pageData.tableData = newVal.map(item => {
return {
wjmc: item.name,
wjdx:parseFloat((item.id.fileSize/1024/1024).toFixed(2)),
wjdx: parseFloat((item.id.fileSize / 1024 / 1024).toFixed(2)),
url: item.id.url
}
})
@ -80,10 +81,10 @@ watch(() => props.imgMsg, (newVal, oldVal) => {
...item,
}
})
},{deep:true,immediate:true})
}, { deep: true, immediate: true })
const deleteFile = (row) => {
pageData.tableData = pageData.tableData.filter(item => item.url !== row.url)
const data=pageData.tableData.map(item => {
const data = pageData.tableData.map(item => {
return {
wjmc: item.wjmc,
wjdx: parseFloat(item.wjdx),
@ -91,12 +92,11 @@ const deleteFile = (row) => {
}
})
emit("changeData",data);
emit("changeData", data);
}
const downloadFile = async (item) => {
console.log(item);
try {
const dataList =[item]
const dataList = [item]
if (dataList.length === 0) {
proxy.$message.warning('没有文件可下载');
return;
@ -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) {

View File

@ -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) {

View File

@ -8,10 +8,9 @@
</div>
</div>
<div class="form_cnt">
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<template #wjdz>
<FileUploadList @changeData="changeData" :imgMsg="imgMsg"/>
<FileUploadList @changeData="changeData" :imgMsg="imgMsg" />
<!-- <div style="width: 100%;">
<UploadFile v-model="imgMsg" :limit="1" :isImg="false" :isAll="false" />
</div> -->
@ -33,7 +32,7 @@ import UploadFile from "@/components/MyComponents/Upload/index.vue";
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue"
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch } from "vue";
import { postWjZzzAddEntity, putWjZzzAddEntity, deleteWjZzzAddEntity, getWjZzzAddEntity, getWjZzzAddEntityById } from '@//api/qbcj.js'
const emit = defineEmits(["updateDate","getList"]);
const emit = defineEmits(["updateDate", "getList"]);
const props = defineProps({
dic: Object
});
@ -76,7 +75,7 @@ watch(() => listQuery.value.wjlb, (newVal, oldVal) => {
// }]
// },
{ label: "文件", prop: "wjdz", type: "slot", width: "100%" },
{ label: "文件大小", prop: "wjdx", type: "input", width: "30%", placeholder: "单位MB",disabled: true },
{ label: "文件大小", prop: "wjdx", type: "input", width: "30%", placeholder: "单位MB", disabled: true },
{ label: "文件名称", prop: "wjmc", type: "input", width: "30%" },
// { label: "文件文件类型", prop: "wjlx", type: "input", width: "30%" },
{ label: "接收人", prop: "jsrxm", type: "slot", width: "100%" },
@ -112,7 +111,7 @@ const rules = reactive({
});
// 初始化数据
const init = (type, row,wjlb) => {
const init = (type, row, wjlb) => {
dialogForm.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情";
if (row) { getDataById(row.id) } else {
@ -123,11 +122,11 @@ const init = (type, row,wjlb) => {
const getDataById = (id) => {
getWjZzzAddEntityById(id).then((res) => {
listQuery.value = res;
imgMsg.value =JSON.parse(res.wjdz)
imgMsg.value = JSON.parse(res.wjdz)
listQuery.value.jsbmdm = res.jsdxList.filter(item => item.jsbmdm).map(item => item.jsbmdm)
listQuery.value.jsbmmc=res.jsdxList.filter(item => item.jsbmdm).map(item => item.jsbmmc)
listQuery.value.jsbmmc = res.jsdxList.filter(item => item.jsbmdm).map(item => item.jsbmmc)
userList.value = res.jsdxList.filter(item => {
if ( item.jsrsfzh) {
if (item.jsrsfzh) {
return item
}
}).map(item => {
@ -135,19 +134,19 @@ const getDataById = (id) => {
})
listQuery.value.jsrxm=userList.value.map(item => item.userName).join(',')
listQuery.value.jsrxm = userList.value.map(item => item.userName).join(',')
});
};
const wjList=ref({})
const wjList = ref({})
const changeData = (val) => {
console.log(val);
let wjsize=0
let wjsize = 0
for (let i = 0; i < val.length; i++) {
console.log(val[i].wjdx);
wjsize+= val[i].wjdx
wjsize += val[i].wjdx
}
listQuery.value.wjdx = wjsize
wjList.value.wjdz =val
wjList.value.wjdz = val
};
// 提交
const submit = () => {
@ -160,12 +159,12 @@ const submit = () => {
}) : []
console.log(ryList);
const bmList =listQuery.value.jsbmdm&&listQuery.value.jsbmdm.length>0? listQuery.value.jsbmdm.map((item, index) => ({
const bmList = listQuery.value.jsbmdm && listQuery.value.jsbmdm.length > 0 ? listQuery.value.jsbmdm.map((item, index) => ({
jsbmdm: item,
jsbmmc: listQuery.value.jsbmmc[index],
})):[]
})) : []
const list = [...ryList, ...bmList]
let params = { ...listQuery.value, jsdxList: list,...wjList.value,wjdz:JSON.stringify(wjList.value.wjdz) };
let params = { ...listQuery.value, jsdxList: list, ...wjList.value, wjdz: JSON.stringify(wjList.value.wjdz) };
try {
loading.value = true;
let res
@ -174,7 +173,7 @@ const submit = () => {
} else {
res = await putWjZzzAddEntity(params)
}
if (res&&res >0) {
if (res && res > 0) {
loading.value = false;
imgMsg.value = []
proxy.$message({ type: "success", message: title.value + "成功" });

View File

@ -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) {

View File

@ -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,8 +194,8 @@ 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 },
{ label: "", prop: "jbxx", type: "slot", width: '100%',},
{ 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,11 +609,13 @@ defineExpose({ init });
height: 100%;
overflow: hidden;
overflow-y: auto;
.timeline-content{
.timeline-content {
width: 100%;
padding: 0 10px;
box-sizing: border-box;
::v-deep .el-timeline-item__wrapper{
::v-deep .el-timeline-item__wrapper {
padding-left: 21px;
box-sizing: border-box;
}
@ -743,7 +767,7 @@ defineExpose({ init });
font-style: italic;
}
::v-deep .el-textarea.is-disabled .el-textarea__inner{
::v-deep .el-textarea.is-disabled .el-textarea__inner {
color: #333 !important;
}
</style>

View File

@ -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>

View File

@ -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>

View File

@ -2,7 +2,7 @@
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Searchs :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" >
<Searchs :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
<el-button type="primary" @click="addEdit('add')" size="small">
<el-icon class="vertical-middle">
<CirclePlus />
@ -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 />
@ -36,15 +42,15 @@
</div>
<!-- 表格 -->
<div class="margTop" >
<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 #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" />
@ -54,64 +60,46 @@
</template>
<template #glbqList="{ row }">
<div>
<el-tag v-for="(item,idx) in row.glbqList" :key="idx">{{ item.bqmc }}</el-tag>
<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 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 },
@ -276,19 +240,19 @@ const cnMsg = (item) => {
}
const handleReport = () => {
if(tableList.value.length == 0) return proxy.$message({ type: "warning", message: "请选择情报信息" });
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' ? '关注成功' :'已取消'
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' ? '关注失败' :'取消失败'
}).catch(() => {
let text = data.sfgz == '1' ? '关注失败' : '取消失败'
proxy.$message({ type: "error", message: text });
})
@ -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 }
@ -458,7 +432,7 @@ const getList = () => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
xxcjSelectXxsbPage(data).then(res => {
pageData.tableData = (res.records || []).map(item=>{
pageData.tableData = (res.records || []).map(item => {
item.glbqList = item.glbqList || [];
return item;
});
@ -502,7 +476,7 @@ const tabHeightFn = () => {
};
// 转线索
const FollowUpOnLeads = (row) => {
if (!qxkz.depBool) return proxy.$message({message: '权限不足',type: 'warning',showClose: true, })
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: "转线索成功" });
@ -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()

View File

@ -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,
}
}

View File

@ -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({}); //表单

View File

@ -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)

View File

@ -2,7 +2,7 @@
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" >
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
<el-button type="primary" @click="dologCancel()" size="small">
<el-icon style="vertical-align: middle">
<CirclePlus />
@ -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>
@ -90,7 +85,7 @@ import ExportFile from '@/views/backOfficeSystem/HumanIntelligence/infoCollectio
import pursueContent from "../components/pursueContent.vue";
import Fszl from '../components/fszl.vue'
import { getItem } from '@//utils/storage.js'
import {xxcjSelectPage,xxcjXxzsx} from '@/api/xxcj.js'
import { xxcjSelectPage, xxcjXxzsx } from '@/api/xxcj.js'
import { color } from "echarts";
const { proxy } = getCurrentInstance();
const {
@ -107,7 +102,7 @@ const {
D_BZ_CLLX,
D_BZ_XZQHDM,
D_BZ_QBCZZT,
D_BZ_CJLX ,D_BZ_LCZT } =
D_BZ_CJLX, D_BZ_LCZT } =
proxy.$dict(
"D_BZ_BMJB",
"D_GS_XS_LY",
@ -132,7 +127,7 @@ const tableList = ref([]);
const qxkz = reactive({
deptBizType: "",
deptLevel: "",
userName:''
userName: ''
})
const list = ref()
const searchConfiger = ref();
@ -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 },
]
});
@ -256,7 +256,7 @@ const addEdit = (type, row) => {
const handleCase = (row) => {
let text = row.sfgz == '0' ? '关注' : '取消关注';
proxy.$confirm("确定要" + text + "吗?", "警告", { type: "warning" }).then(() => {
qcckPost({ id: row.id,sfgz: row.sfgz == '0' ? '1' : '0' },'/mosty-gsxt/xxcj/cjgz').then(res => {
qcckPost({ id: row.id, sfgz: row.sfgz == '0' ? '1' : '0' }, '/mosty-gsxt/xxcj/cjgz').then(res => {
proxy.$message({ type: "success", message: text + "成功" });
getList();
})
@ -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>

View File

@ -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({

View File

@ -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();

View File

@ -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();

View File

@ -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"
);

View File

@ -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,21 +12,17 @@
</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"/>
<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" />
@ -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>

View File

@ -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>

View File

@ -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,

View File

@ -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,

View File

@ -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>支持pngjpgpdf文件上传</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>

View File

@ -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('')

View File

@ -2,7 +2,7 @@
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" >
<Search :searchArr="searchConfiger" @submit="onSearch">
<el-button type="primary" size="small" @click="handleAdd('add', null)">发起布控</el-button>
</Search>
</div>
@ -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>
@ -113,10 +105,10 @@ const router = useRouter()
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_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"); //获取字典数据
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, 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", "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,16 +254,16 @@ 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;
});
};
function hadleSendSH (row) {
function hadleSendSH(row) {
proxy.$confirm("确定要送审吗?", "提示", { type: "warning" }).then(() => {
qcckGet({}, '/mosty-gsxt/tbGsxtBk/subExamine/'+row.id).then(res => {
qcckGet({}, '/mosty-gsxt/tbGsxtBk/subExamine/' + row.id).then(res => {
proxy.$message({ type: "success", message: "送审成功" });
getList();
}).catch(() => {
@ -262,9 +287,9 @@ const shFormRules = {
// 提交送审
const submitSh = () => {
try {
shFormRef.value.validate(valida=>{
if(!valida) return;
const params = {...shForm.value }
shFormRef.value.validate(valida => {
if (!valida) return;
const params = { ...shForm.value }
})
} catch (err) {
@ -289,7 +314,7 @@ const handleRow = (id) => {
};
// 回执单
const hzdVisible = ref(false)
const dataList= ref({})
const dataList = ref({})
const openShowHzd = (row) => {
hzdVisible.value = true
dataList.value = row
@ -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>

View File

@ -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) {

View File

@ -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>

View File

@ -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 = () => {

View File

@ -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()
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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' ? '已签收' : '已反馈'
}
}
// 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 ''
}
// 删除权限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
}
// 修改权限:只能自己修改,且未签收未反馈
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>

View File

@ -3,30 +3,21 @@
<div class="head_box">
<span class="title">报告{{ title }} </span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-if="title!='详情'">保存</el-button>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-if="title != '详情'">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage :formList="formData" :disabled="title=='详情'" v-model="listQuery" ref="elform" :rules="rules">
<FormMessage :formList="formData" :disabled="title == '详情'" v-model="listQuery" ref="elform" :rules="rules">
<template #fj><el-button type="primary" @click="showText = true">附件上传</el-button></template>
</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> -->
@ -120,7 +111,7 @@ const title = ref("");
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = type == "add" ? "新增" :type == "edit"? "编辑" : "详情";
title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情";
if (row) {
@ -132,8 +123,9 @@ const init = (type, row) => {
};
// 根据id查询详情
const getDataById = (id) => {
qcckGet({},'/mosty-gsxt/gsxtYpbg/'+id).then((res) => {
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;
@ -172,11 +164,11 @@ function setEditorTextContent() {
// 提交
const submit = () => {
elform.value.submit( async (data) => {
elform.value.submit(async (data) => {
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;

View File

@ -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()

View File

@ -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(); //搜索框

View File

@ -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({})

View File

@ -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>

View File

@ -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">支持pngjpgjpeg文件上传</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,9 +72,11 @@
<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";
import { ref, defineExpose, reactive, onMounted, defineEmits, getCurrentInstance, nextTick, watch } from "vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dic: {
@ -76,13 +101,13 @@ 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})
}, { deep: true })
const listQuery = ref({}); //表单
const loading = ref(false);
@ -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>

View File

@ -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: "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: "反馈成功" });

View File

@ -4,35 +4,31 @@
<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}">
<template #zllx="{ row }">
<DictTag :tag="false" :value="row.zllx" :options="D_GS_XS_ZLLX" />
</template>
<template #zldj="{row}">
<template #zldj="{ row }">
<DictTag :tag="false" :value="row.zldj" :options="D_GS_ZDQT_FXDJ" />
</template>
<template #czzt="{row}">
<template #czzt="{ row }">
<DictTag :tag="false" :value="row.czzt" :options="D_GS_XS_CZZT" />
</template>
<template #sffk="{row}">
<template #sffk="{ row }">
{{ row.sffk == '1' ? '已反馈' : '未反馈' }}
</template>
<template #sfqs="{row}">
<template #sfqs="{ row }">
{{ row.sfqs == '0' ? '未签收' : '已签收' }}
</template>
<template #controls="{ row }">
@ -40,23 +36,18 @@
<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>
<DetailForm ref="detailDiloag" @updateDate="getList" :dic="{D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ}" />
<Fk v-model="isShowFk" :dataList="dataList" @getList="getList"/>
<DetailForm ref="detailDiloag" @updateDate="getList" :dic="{ D_GS_XS_ZLLX, D_GS_ZDQT_FXDJ }" />
<Fk v-model="isShowFk" :dataList="dataList" @getList="getList" />
</template>
<script setup>
@ -71,15 +62,15 @@ 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(); //搜索框
const searchConfiger = ref([
{ label: "指令标题", prop: 'zlbt', placeholder: "请输入指令标题", showType: "input" },
{ label: "指令类型", prop: 'zllx', placeholder: "请选择指令类型", showType: "select",options:D_GS_XS_ZLLX },
{ label: "指令等级", prop: 'zldj', placeholder: "请选择指令等级", showType: "select" ,options:D_GS_ZDQT_FXDJ},
{ label: "处置状态", prop: 'czzt', placeholder: "请选择处置状态", showType: "select" ,options:D_GS_XS_CZZT},
{ label: "指令类型", prop: 'zllx', placeholder: "请选择指令类型", showType: "select", options: D_GS_XS_ZLLX },
{ label: "指令等级", prop: 'zldj', placeholder: "请选择指令等级", showType: "select", options: D_GS_ZDQT_FXDJ },
{ label: "处置状态", prop: 'czzt', placeholder: "请选择处置状态", showType: "select", options: D_GS_XS_CZZT },
{ label: "反馈时间", prop: 'time', placeholder: "请选择反馈时间", showType: "datetimerange" },
]);
@ -100,21 +91,22 @@ const pageData = reactive({
controlsWidth: 240,
tableColumn: [
{ label: '指令标题', prop: 'zlbt' },
{ label: '指令类型', prop: 'zllx',showSolt:true },
{ label: '指令等级', prop: 'zldj',showSolt:true },
{ 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 },
{ label: '是否签收', prop: 'sfqs', showSolt: true },
]
});
const route=useRoute()
const userInfo=ref();
const route = useRoute()
const userInfo = ref();
onMounted(() => {
if (route.query.id) {
addEdit('detail', {id:route.query.id});
addEdit('detail', { id: route.query.id });
}
userInfo.value=getItem('deptId')[0]
userInfo.value = getItem('deptId')[0]
getList()
tabHeightFn();
});
@ -122,89 +114,97 @@ onMounted(() => {
// 搜索
const onSearch = (val) =>{
queryFrom.value = {...val}
queryFrom.value.kssj = val.time ? val.time[0]:'';
queryFrom.value.jssj = val.time ? val.time[1]:'';
const onSearch = (val) => {
queryFrom.value = { ...val }
queryFrom.value.kssj = val.time ? val.time[0] : '';
queryFrom.value.jssj = val.time ? val.time[1] : '';
pageData.pageConfiger.pageCurrent = 1;
getList()
}
const changeNo = (val) =>{
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList()
}
const changeSize = (val) =>{
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList()
}
// 获取列表
const getList = (val) =>{
const getList = (val) => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
delete data.time;
qcckGet(data,'/mosty-gsxt/zlxx/selectPage').then(res=>{
qcckGet(data, '/mosty-gsxt/zlxx/selectPage').then(res => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(()=>{ pageData.tableConfiger.loading = false; })
}).catch(() => { pageData.tableConfiger.loading = false; })
}
const deleteRow = (id) =>{
proxy.$confirm("确定要删除", "警告", {type: "warning"}).then(() => {
qcckPost({id},'/mosty-gsxt/zlxx/delete').then(()=>{
const deleteRow = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
qcckPost({ id }, '/mosty-gsxt/zlxx/delete').then(() => {
proxy.$message({ type: "success", message: "删除成功" });
getList();
})
}).catch(() => {});
}).catch(() => { });
}
// 详情
const addEdit = (type, row) => {
isShow.value = true;
nextTick(()=>{
nextTick(() => {
detailDiloag.value.init(type, row);
})
};
watch(() => route.query.id, (val) => {
if (val) {
addEdit('detail', {id:route.query.id});
addEdit('detail', { id: route.query.id });
}
},{deep:true})
}, { deep: true })
// 签收
const signRow = (row) =>{
proxy.$confirm("确定要签收", "警告", {type: "warning"}).then(() => {
qcckGet({id:row.id},'/mosty-gsxt/zlxx/qs').then(()=>{
const signRow = (row) => {
proxy.$confirm("确定要签收", "警告", { type: "warning" }).then(() => {
qcckGet({ id: row.id }, '/mosty-gsxt/zlxx/qs').then(() => {
proxy.$message({ type: "success", message: "签收成功" });
getList();
})
}).catch(() => {});
}).catch(() => { });
}
// 反馈
const isShowFk = ref(false)
const dataList = ref()
const fkRow = (row) => {
if (row.sfqs=='0') {
if (row.sfqs == '0') {
proxy.$message({ type: "error", message: "请先签收" });
return;
}
isShowFk.value = true;
dataList.value = {...row};
dataList.value = { ...row };
}
const showBtn = (row) => {
let item = row.xfbmList.find(v => v.ssbmdm == userInfo.value.deptCode)
return item?true:false
return item ? true : false
// // if (item) {
// // return item.zlzt == '01' ? 'sign' : item.zlzt == '02' ? 'feedback' : ''
// // } else {
// // 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;

View File

@ -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)

View File

@ -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(); //搜索框

View File

@ -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,15 +79,33 @@ 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);
watch(()=>formState,val=>{
emit('update:modelValue',val)
},{immediate:true})
const toggleCollapse = () => {
isCollapsed.value = !isCollapsed.value;
emit('collapse', isCollapsed.value);
};
watch(() => formState, val => {
emit('update:modelValue', val)
}, { immediate: true })
const renderFields = computed(() => {
@ -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;

View File

@ -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">

View File

@ -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
}

View File

@ -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,17 +18,13 @@
>{{ 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="区域预警" />
<el-option label="布控预警" value="布控预警" />
</el-select>
</el-popover> -->
</el-select>
</el-popover> -->
<!-- <el-popover
placement="right"
:width="240"
@ -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";

View File

@ -25,7 +25,7 @@
</el-button>
</template>
</PageTitle> -->
</PageTitle> -->
<!-- 表格 -->
<div class="margTop">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
@ -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>
@ -155,13 +155,13 @@ const addEdit = (type, row) => {
// 选择系数
const chooseJfShow = ref(false)
const chooseJfBh = ref()
const roleIds=ref()
const roleIds = ref()
const chooseJfFun = (val) => {
chooseJfBh.value=val.id
chooseJfBh.value = val.id
tbGsxtBqzhId(val.id).then(res => {
roleIds.value=res.sjxspzList.map(item => item.xsid)
roleIds.value = res.sjxspzList.map(item => item.xsid)
chooseJfShow.value = true
})
})
}
// 表格高度计算

View File

@ -35,7 +35,7 @@
<template #xwfz>
<el-table-column prop="bqfz" width="80" align="center" label="标签分值" />
<el-table-column prop="pzxs" width="60" align="center" label="系数" />
<el-table-column prop="xwfz" width="90" align="center" label="计算分值"/>
<el-table-column prop="xwfz" width="90" align="center" label="计算分值" />
</template>
<template #expand="{ props }">
<div class="expand-content" style="max-width: 100%">
@ -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,20 +66,16 @@
<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>
<!-- 详情 -->
<AddFrom ref="addModelRef" :dict="{ D_GSXT_YJXX_CZZT, D_BZ_YJJB, D_GS_SSYJ }"></AddFrom>
<!-- 处置建议 -->
<!-- 处置建议 -->
<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>
@ -91,7 +88,7 @@ import Searchs from "@/components/aboutTable/Search.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Items from "./item/items.vue";
import {yjzxXwyjSelectList } from "@/api/yj.js";
import { yjzxXwyjSelectList } from "@/api/yj.js";
import ChooseJf from '@/components/ChooseList/ChooseJf/index.vue'
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import HolographicArchive from '@/views/home/components/holographicArchive.vue'
@ -109,7 +106,7 @@ const czjyRef = ref()
const permission_sfqs = ref(false)
const roleCode = ref(false)
const { proxy } = getCurrentInstance();
const { D_BZ_YJJB,D_GS_SSYJ, D_GSXT_YJXX_CZZT } = proxy.$dict('D_BZ_YJJB',"D_GS_SSYJ", "D_GSXT_YJXX_CZZT"); //获取字典数据
const { D_BZ_YJJB, D_GS_SSYJ, D_GSXT_YJXX_CZZT } = proxy.$dict('D_BZ_YJJB', "D_GS_SSYJ", "D_GSXT_YJXX_CZZT"); //获取字典数据
// 字典数据集合
const dict = ref({
@ -130,7 +127,7 @@ const searchConfiger = ref(
{ label: "电话号码", prop: 'dh', placeholder: "请输入电话号码", showType: "input" },
{ label: "预警标签", prop: 'xwms', placeholder: "请输入预警标签", showType: "input" },
{ label: "部门", prop: 'ssbmdm', placeholder: "请选择部门", showType: "department" },
{ label: "级别", prop: 'bqys', placeholder: "请选择级别", showType: "select" ,options: D_BZ_YJJB},
{ label: "级别", prop: 'bqys', placeholder: "请选择级别", showType: "select", options: D_BZ_YJJB },
{ label: "积分段", prop: 'jfd', placeholder: "请选择积分段", showType: "Slot" },
{ label: "预警时间", prop: 'times', showType: "datetimerange" },
]);
@ -159,8 +156,8 @@ const pageData = reactive({
{ label: "身份证号", prop: "sfzh" },
{ label: "标签", prop: "xwms" },
{ label: "接收单位", prop: "ssbm" },
{ label: "活动频次", prop: "xwcs", showSolt: true,width: 90 },
{ label: "预警分值", prop: "xwfz",showSolt: true },
{ label: "活动频次", prop: "xwcs", showSolt: true, width: 90 },
{ label: "预警分值", prop: "xwfz", showSolt: true },
]
});
@ -178,11 +175,11 @@ const gettbGsxtBqglSelectList = (val) => {
onMounted(() => {
let str = getItem('deptId') ? getItem('deptId')[0].deptLevel : ''
permission_sfqs.value = str.startsWith('2'||'3') ? false : true;
permission_sfqs.value = str.startsWith('2' || '3') ? false : true;
let rols = getItem('roleList') ? getItem('roleList'):[]
let rols = getItem('roleList') ? getItem('roleList') : []
let obj = rols.find(item => {
return ['JS_666666','JS_777777','JS_888888'].includes(item.roleCode)
return ['JS_666666', 'JS_777777', 'JS_888888'].includes(item.roleCode)
})
roleCode.value = obj ? true : false;
@ -193,12 +190,12 @@ onMounted(() => {
});
const handleCzjy = (row) => {
czjyRef.value.init( row)
czjyRef.value.init(row)
}
// 搜索
const onSearch = (val) => {
queryFrom.value = { ...queryFrom.value,...val };
queryFrom.value = { ...queryFrom.value, ...val };
queryFrom.value.startTime = val.times ? val.times[0] : ''
queryFrom.value.endTime = val.times ? val.times[1] : ''
pageData.pageConfiger.pageCurrent = 1;
@ -265,7 +262,7 @@ const bqYs = (val) => {
const assessShow = ref(false)
const dataList = ref()
const pushAssess = (val) => {
return holographicProfileJump(val.yjlx,val) // 全息档案跳转
return holographicProfileJump(val.yjlx, val) // 全息档案跳转
// assessShow.value = true;
// dataList.value = val;
}
@ -327,20 +324,20 @@ const openAddModel = (row) => {
// 选择系数
const chooseJfShow = ref(false)
const chooseJfBh = ref()
const roleIds=ref()
const roleIds = ref()
const chooseJfFun = (val) => {
chooseJfBh.value=val.id
chooseJfBh.value = val.id
yjzxXwyjSelectList(val.id).then(res => {
roleIds.value=res.sjxspzList.map(item => item.xsid)
roleIds.value = res.sjxspzList.map(item => item.xsid)
chooseJfShow.value = true
})
})
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 280;
window.onresize = function() {
window.onresize = function () {
tabHeightFn();
};
};
@ -382,7 +379,7 @@ const handleQs = () => {
let texy = yqs.length > 0 ? `${yqs.length}条已签收预警数据,确认要签收${wqs.length}条未签收预警数据吗?` : '确认要签收所有预警数据吗?'
proxy.$confirm(texy, "警告", { type: "warning" }).then(() => {
let ids = wqs.map(item => item.id)
qcckPost({ids}, '/mosty-gsxt/yjzxXwyj/batchQs').then(() => {
qcckPost({ ids }, '/mosty-gsxt/yjzxXwyj/batchQs').then(() => {
proxy.$message({ type: "success", message: "成功" });
getList();
}).catch(() => {
@ -406,10 +403,9 @@ const handleQs = () => {
outline-color: #0000ff;
}
.tabBox_zdy{
.tabBox_zdy {
.el-table--fit {
overflow: unset !important;
}
}
</style>

View File

@ -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);
/** 触发选中 */

View File

@ -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>

View File

@ -36,7 +36,7 @@
<template #sffz>
<el-table-column prop="bqfz" width="80" align="center" label="标签分值" />
<el-table-column prop="pzxs" width="60" align="center" label="系数" />
<el-table-column prop="sffz" width="90" align="center" label="计算分值"/>
<el-table-column prop="sffz" width="90" align="center" label="计算分值" />
</template>
<template #expand="{ props }">
<div>
@ -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>
@ -148,8 +148,8 @@ const pageData = reactive({
{ label: "身份证号", prop: "sfzh" },
{ label: "标签", prop: "yjbqmc" },
{ label: "接收单位", prop: "ssbm" },
{ label: "活动频次", prop: "sfcs",width:'90' },
{ label: "预警分值", prop: "sffz",showSolt: true },
{ label: "活动频次", prop: "sfcs", width: '90' },
{ label: "预警分值", prop: "sffz", showSolt: true },
]
});
@ -363,7 +363,7 @@ const handleQs = () => {
let texy = yqs.length > 0 ? `${yqs.length}条已签收预警数据,确认要签收${wqs.length}条未签收预警数据吗?` : '确认要签收所有预警数据吗?'
proxy.$confirm(texy, "警告", { type: "warning" }).then(() => {
let ids = wqs.map(item => item.id)
qcckPost({ids}, '/mosty-gsxt/yjzxZhyj/batchQs').then(() => {
qcckPost({ ids }, '/mosty-gsxt/yjzxZhyj/batchQs').then(() => {
proxy.$message({ type: "success", message: "成功" });
getList();
}).catch(() => {

View File

@ -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) => {

View File

@ -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);
@ -603,7 +529,7 @@ const handleQs = () => {
proxy.$message({ type: "error", message: "失败" });
});
})
.catch(() => {});
.catch(() => { });
};
// 详情

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