Compare commits
38 Commits
9fb505eb8e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 883416417f | |||
| cd8347d3d1 | |||
| 9fa073546b | |||
| 836bcf196c | |||
| a1e247c2e3 | |||
| a2a7335536 | |||
| dbc6ecf62d | |||
| cf455216f9 | |||
| e4a044944d | |||
| ebdd319f9f | |||
| 92c1f0be41 | |||
| c4cc33bee3 | |||
| 96e97de237 | |||
| 5bb7ca0515 | |||
| 00c9f1e07f | |||
| 76df2bc42c | |||
| aa1af80bdf | |||
| 0020d383bf | |||
| 571e149313 | |||
| 6b563f728f | |||
| 52095b5fb9 | |||
| f31be82805 | |||
| 35c6849b43 | |||
| baa818153f | |||
| 70ed05c67a | |||
| f4747be3bc | |||
| e676fc9000 | |||
| 04cedbc438 | |||
| a3464a53cb | |||
| f09a8a0083 | |||
| fbf259663b | |||
| 763057ed9f | |||
| 970596f922 | |||
| ef3c23a03a | |||
| 582b8677fc | |||
| af838854fa | |||
| 60de16032f | |||
| c181530639 |
@ -1 +1 @@
|
||||
src/
|
||||
# 取消忽略 src 目录,让 ESLint 正常检查源代码
|
||||
@ -1,6 +1,7 @@
|
||||
{
|
||||
"semi":true,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "none",
|
||||
"spaced-comment":2
|
||||
"spacedComment": 2,
|
||||
"quoteProps": "preserve"
|
||||
}
|
||||
94
check_unused_dicts.js
Normal file
94
check_unused_dicts.js
Normal file
@ -0,0 +1,94 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const baseDir = path.join(__dirname, 'src/views/backOfficeSystem');
|
||||
|
||||
// Find all .vue files with proxy.$dict
|
||||
function findVueFiles(dir) {
|
||||
let results = [];
|
||||
const files = fs.readdirSync(dir);
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
results = results.concat(findVueFiles(filePath));
|
||||
} else if (file.endsWith('.vue')) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
if (content.includes('proxy.$dict')) {
|
||||
results.push(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// Parse dict variables and their usage
|
||||
function analyzeFile(filePath) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
// Find the dict destructuring pattern
|
||||
// Pattern: const { VAR1, VAR2, ... } = proxy.$dict("KEY1", "KEY2", ...)
|
||||
|
||||
// Extract the destructured variable names
|
||||
const destructMatch = content.match(/const\s*\{([^}]+)\}\s*=\s*proxy\.\$dict\s*\(/);
|
||||
if (!destructMatch) return null;
|
||||
|
||||
const varsStr = destructMatch[1];
|
||||
const dictVars = varsStr.split(',').map(v => v.trim().replace(/\/\/.*$/, '').trim()).filter(v => v && !v.startsWith('//'));
|
||||
|
||||
// Extract the dict keys
|
||||
const dictCallMatch = content.match(/proxy\.\$dict\s*\(([^)]+)\)/s);
|
||||
if (!dictCallMatch) return null;
|
||||
|
||||
const dictKeysStr = dictCallMatch[1];
|
||||
const dictKeys = dictKeysStr.split(',').map(k => k.trim().replace(/['"]/g, '').replace(/\/\/.*$/, '').trim()).filter(k => k && !k.startsWith('//'));
|
||||
|
||||
// Now check which dict vars are actually used in the file
|
||||
// Remove the dict declaration part first
|
||||
const scriptContent = content.replace(/const\s*\{[^}]+\}\s*=\s*proxy\.\$dict\s*\([^)]+\)[^;\n]*;?/s, '');
|
||||
|
||||
const unusedVars = [];
|
||||
const usedVars = [];
|
||||
|
||||
for (const varName of dictVars) {
|
||||
if (!varName) continue;
|
||||
// Check if the variable name appears elsewhere in the file (outside the dict declaration)
|
||||
// Look for: varName in template, searchConfiger, getMultiDictVal, DictTag :options, :dict= etc.
|
||||
const regex = new RegExp('\\b' + varName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\b');
|
||||
const matches = scriptContent.match(regex);
|
||||
if (matches && matches.length > 0) {
|
||||
usedVars.push(varName);
|
||||
} else {
|
||||
unusedVars.push(varName);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
filePath,
|
||||
dictVars,
|
||||
dictKeys,
|
||||
unusedVars,
|
||||
usedVars
|
||||
};
|
||||
}
|
||||
|
||||
const vueFiles = findVueFiles(baseDir);
|
||||
console.log(`Found ${vueFiles.length} files with proxy.$dict\n`);
|
||||
|
||||
let totalUnused = 0;
|
||||
const filesWithUnused = [];
|
||||
|
||||
for (const filePath of vueFiles) {
|
||||
const result = analyzeFile(filePath);
|
||||
if (result && result.unusedVars.length > 0) {
|
||||
const relPath = path.relative(__dirname, filePath).replace(/\\/g, '/');
|
||||
console.log(`\n${relPath}:`);
|
||||
console.log(` Unused: ${result.unusedVars.join(', ')}`);
|
||||
filesWithUnused.push(result);
|
||||
totalUnused += result.unusedVars.length;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n\n=== Summary ===`);
|
||||
console.log(`Total files with unused dicts: ${filesWithUnused.length}`);
|
||||
console.log(`Total unused dict variables: ${totalUnused}`);
|
||||
129
docs/navigation-issue-solution.md
Normal file
129
docs/navigation-issue-solution.md
Normal file
@ -0,0 +1,129 @@
|
||||
# 首页导航跳转问题分析与解决方案
|
||||
|
||||
## 问题现象
|
||||
|
||||
接口请求完成之前,首页的导航菜单无法跳转;接口请求完成后,导航跳转正常。
|
||||
|
||||
---
|
||||
|
||||
## 问题根源
|
||||
|
||||
### 核心问题:SideBarMenu.vue 的页面刷新逻辑
|
||||
|
||||
```javascript
|
||||
// 问题代码(已修复)
|
||||
if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
|
||||
setTimeout(() => {
|
||||
router.go(0); // 触发页面刷新!
|
||||
}, 200);
|
||||
}
|
||||
```
|
||||
|
||||
当动态路由还没添加完成时,这个条件会触发页面不断刷新,导致导航不可用。
|
||||
|
||||
---
|
||||
|
||||
## 已完成的修复
|
||||
|
||||
### 1. 修改 `src/store/modules/permission.js`
|
||||
|
||||
**修改内容**:优化 `routeReady` 状态管理(0: 未开始 → 1: 进行中 → 2: 完成)
|
||||
|
||||
```javascript
|
||||
actions: {
|
||||
filterRoutes(context, menus) {
|
||||
// 开始处理,标记为进行中
|
||||
context.commit('setRouteReady', 1);
|
||||
|
||||
let routes = [];
|
||||
if (menus && menus.length > 0) {
|
||||
routes = filter(privateRoutes, menus);
|
||||
}
|
||||
routes.push({ path: '/:catchAll(.*)', redirect: '/404' });
|
||||
|
||||
context.commit('setRoutes', routes);
|
||||
// 处理完成,标记为已完成
|
||||
context.commit('setRouteReady', 2); // ← 新增:完成时设为 2
|
||||
|
||||
return routes;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 修改 `src/permission.js`
|
||||
|
||||
**修改内容**:移除了在路由守卫开始时设置 `setRouteReady(1)` 的代码,让 `filterRoutes` action 统一管理状态。
|
||||
|
||||
### 3. 修改 `src/layout/components/SideBar/SideBarMenu.vue`
|
||||
|
||||
**修改内容**:移除自动刷新页面的逻辑,改为监听路由加载状态
|
||||
|
||||
```javascript
|
||||
// 原代码(已移除):
|
||||
// if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
|
||||
// store.commit("user/setIsReady", {});
|
||||
// setTimeout(() => {
|
||||
// router.go(0);
|
||||
// }, 200);
|
||||
// }
|
||||
|
||||
// 新代码:监听路由加载完成状态
|
||||
if (store.state.permission.routeReady !== 2) {
|
||||
const unwatch = watch(
|
||||
() => store.state.permission.routeReady,
|
||||
(val) => {
|
||||
if (val === 2) {
|
||||
unwatch();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 修改 `src/utils/route.js`
|
||||
|
||||
**修改内容**:添加空值安全检查,避免 `deptId` 或 `roleList` 为空时报错
|
||||
|
||||
```javascript
|
||||
// 原代码(可能报错):
|
||||
// const { deptBizType, deptLevel } = getItem('deptId')[0]
|
||||
|
||||
// 新代码(安全):
|
||||
const deptIdData = getItem('deptId');
|
||||
const deptInfo = deptIdData && deptIdData.length > 0 ? deptIdData[0] : {};
|
||||
const deptBizType = deptInfo.deptBizType || '';
|
||||
const deptLevel = deptInfo.deptLevel || '';
|
||||
const roleListData = getItem('roleList') || [];
|
||||
const roleList = roleListData.filter(item => item.roleCode == 'JS_666666').length > 0;
|
||||
const xjLsit = roleListData.filter(item => item.roleCode == 'JS_999999').length > 0;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 修复后的流程
|
||||
|
||||
```
|
||||
登录成功 → window.location.href = '/' → 页面加载
|
||||
↓
|
||||
permission.js 路由守卫执行
|
||||
↓
|
||||
filterRoutes 开始执行 → routeReady = 1(进行中)
|
||||
↓
|
||||
动态路由添加完成 → routeReady = 2(完成)
|
||||
↓
|
||||
SideBarMenu.vue 监听到 routeReady === 2
|
||||
↓
|
||||
导航菜单正常渲染,可以跳转
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 修复文件列表
|
||||
|
||||
| 文件路径 | 修改内容 |
|
||||
|---------|---------|
|
||||
| `src/store/modules/permission.js` | 优化 routeReady 状态管理(0→1→2) |
|
||||
| `src/permission.js` | 移除重复的 setRouteReady 调用 |
|
||||
| `src/layout/components/SideBar/SideBarMenu.vue` | 移除自动刷新逻辑,改为监听状态 |
|
||||
| `src/utils/route.js` | 添加空值安全检查 |
|
||||
463
docs/菜单权限逻辑文档.md
Normal file
463
docs/菜单权限逻辑文档.md
Normal file
@ -0,0 +1,463 @@
|
||||
# 菜单权限逻辑文档
|
||||
|
||||
## 概述
|
||||
|
||||
本项目采用**动态路由注册**方案实现权限控制。用户登录后,系统根据后端返回的菜单权限码动态注册路由,无权限的路由**根本不会注册**到 Vue Router,从根本上杜绝了越权访问的可能。
|
||||
|
||||
---
|
||||
|
||||
## 整体流程图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 用户登录 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 调用登录接口 │
|
||||
│ 返回:jwtToken、menuList、menuCodeSet、deptList 等 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 存储权限数据 │
|
||||
│ - localStorage.menusPermission = menuCodeSet(菜单权限码集合) │
|
||||
│ - Vuex: user.userInfo.permission.menus = menuCodeSet │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 路由守卫(permission.js) │
|
||||
│ 首次进入时:获取 menusPermission → 调用 filterRoutes 动态注册路由 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Vuex: permission/filterRoutes │
|
||||
│ 1. 根据 menusPermission 过滤 privateRoutes │
|
||||
│ 2. 通过 router.addRoute() 动态注册有权限的路由 │
|
||||
│ 3. 最后注册 404 兜底路由 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ SideBarMenu.vue 组件 │
|
||||
│ 从已注册的路由中筛选并渲染侧边栏菜单 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心文件说明
|
||||
|
||||
| 文件路径 | 作用 |
|
||||
|---------|------|
|
||||
| `src/router/index.js` | 路由配置,定义 `publicRoutes`(公开路由)和 `privateRoutes`(私有路由) |
|
||||
| `src/store/modules/permission.js` | 权限模块,处理路由过滤和动态注册逻辑 |
|
||||
| `src/store/modules/user.js` | 用户模块,处理登录和退出登录 |
|
||||
| `src/permission.js` | 路由守卫,控制路由初始化时机 |
|
||||
| `src/utils/route.js` | 路由工具函数,处理菜单生成 |
|
||||
| `src/layout/components/SideBar/SideBarMenu.vue` | 侧边栏菜单组件,渲染权限菜单 |
|
||||
| `src/views/error/404.vue` | 无权限/页面不存在页面 |
|
||||
| `src/directives/permission.js` | 按钮级权限指令 |
|
||||
|
||||
---
|
||||
|
||||
## 路由分类
|
||||
|
||||
### 公开路由(publicRoutes)
|
||||
|
||||
应用启动时静态注册,所有用户都能访问:
|
||||
|
||||
| 路由路径 | 说明 |
|
||||
|---------|------|
|
||||
| `/login` | 登录页 |
|
||||
| `/oatuh_login` | OAuth 登录页 |
|
||||
| `/zeroTrust_login` | 零信任登录页 |
|
||||
| `/` | 首页 |
|
||||
| `/401` | 无权限页(保留) |
|
||||
| `/404` | 页面不存在/无权限页 |
|
||||
| `/mapNavigation` | 地图导航 |
|
||||
| `/KeyPopulations` | 重点人详情 |
|
||||
| `/deploymentApproval` | 布控审核 |
|
||||
| `/clueVerification` | 线索核实 |
|
||||
| 其他特殊路由... | 无需菜单权限校验的业务路由 |
|
||||
|
||||
### 私有路由(privateRoutes)
|
||||
|
||||
登录后根据权限动态注册,包含所有业务功能页面。
|
||||
|
||||
---
|
||||
|
||||
## 详细逻辑分析
|
||||
|
||||
### 1. 登录阶段 - 获取并存储权限
|
||||
|
||||
**文件**: `src/store/modules/user.js`
|
||||
|
||||
```javascript
|
||||
// 登录成功后存储权限数据
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setMenuList", data.menuList);
|
||||
setItem("menusPermission", data.menuCodeSet); // 核心:菜单权限码集合
|
||||
|
||||
this.commit("user/setUserInfo", {
|
||||
token: data.jwtToken,
|
||||
permission: {
|
||||
buttonPermission: ["removeTest", "viewTest"],
|
||||
menus: data.menuCodeSet
|
||||
},
|
||||
menuList: data.menuList,
|
||||
deptList: data.deptList
|
||||
});
|
||||
```
|
||||
|
||||
**权限码示例**:
|
||||
```javascript
|
||||
["FourColorWarning", "YjData", "IntelligentControl", "userList", "departmentList", ...]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. 路由守卫 - 控制初始化
|
||||
|
||||
**文件**: `src/permission.js`
|
||||
|
||||
```javascript
|
||||
const whiteList = ['/login', '/oatuh_login', '/404', '/401', '/zeroTrust_login',
|
||||
'/focusExploration', '/clueVerification', '/deploymentApproval'];
|
||||
|
||||
let routesInitialized = false;
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
if (store.getters.token) {
|
||||
if (!routesInitialized) {
|
||||
// ★ 首次进入:动态注册路由
|
||||
routesInitialized = true;
|
||||
const afterMenuList = getItem('menusPermission');
|
||||
|
||||
// 根据权限动态注册路由
|
||||
await store.dispatch('permission/filterRoutes', afterMenuList);
|
||||
|
||||
// 重新导航,确保刚注册的路由能正确匹配
|
||||
next({ ...to, replace: true });
|
||||
return;
|
||||
}
|
||||
next();
|
||||
} else {
|
||||
// 未登录:白名单放行,否则跳转登录
|
||||
if (whiteList.indexOf(to.path) > -1) {
|
||||
next();
|
||||
} else {
|
||||
// 跳转登录逻辑...
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 权限过滤与动态注册
|
||||
|
||||
**文件**: `src/store/modules/permission.js`
|
||||
|
||||
```javascript
|
||||
import router from '@/router'
|
||||
import { publicRoutes, privateRoutes } from '@/router'
|
||||
|
||||
/**
|
||||
* 递归过滤路由(保留 component 引用)
|
||||
* 规则:
|
||||
* 1. 路由有 name 且在权限列表中 → 保留
|
||||
* 2. 路由无 name 但有子路由 → 检查子路由权限,有权限子路由则保留父路由
|
||||
*/
|
||||
function filter(data, menus) {
|
||||
const result = []
|
||||
|
||||
data.forEach(route => {
|
||||
const newRoute = { ...route } // 浅拷贝,保留 component 引用
|
||||
|
||||
if (route.name && menus?.includes(route.name)) {
|
||||
// 有权限:递归处理子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
newRoute.children = filter(route.children, menus)
|
||||
}
|
||||
result.push(newRoute)
|
||||
} else if (!route.name && route.children && route.children.length > 0) {
|
||||
// 父路由无 name:检查子路由
|
||||
const filteredChildren = filter(route.children, menus)
|
||||
if (filteredChildren.length > 0) {
|
||||
newRoute.children = filteredChildren
|
||||
result.push(newRoute)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
actions: {
|
||||
filterRoutes(context, menus) {
|
||||
let routes = []
|
||||
|
||||
if (menus && menus.length > 0) {
|
||||
routes = filter(privateRoutes, menus)
|
||||
}
|
||||
|
||||
// ★★★ 关键:动态添加路由到 Vue Router ★★★
|
||||
routes.forEach(route => {
|
||||
router.addRoute(route)
|
||||
})
|
||||
|
||||
// 404 兜底路由必须最后添加
|
||||
router.addRoute({
|
||||
path: '/:catchAll(.*)',
|
||||
redirect: '/404'
|
||||
})
|
||||
|
||||
context.commit('setRoutes', routes)
|
||||
return routes
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**重要说明**:
|
||||
- 不能使用 `JSON.parse(JSON.stringify())` 深拷贝,会丢失 `component` 函数引用导致页面空白
|
||||
- 使用 `{ ...route }` 浅拷贝保留 `component` 引用
|
||||
|
||||
---
|
||||
|
||||
### 4. 侧边栏菜单渲染
|
||||
|
||||
**文件**: `src/layout/components/SideBar/SideBarMenu.vue`
|
||||
|
||||
```javascript
|
||||
// 从已注册的路由中获取并过滤
|
||||
const routes = computed(() => {
|
||||
const fRoutes = filterRoutes(router.getRoutes());
|
||||
const data = fRoutes.filter((item) => !EXCLUDE_NAMES.includes(item.name));
|
||||
|
||||
const menusPermission = getItem("menusPermission");
|
||||
|
||||
if (menusPermission === null || menusPermission === undefined) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const menusSet = new Set(menusPermission.map((item) => `${item}`));
|
||||
|
||||
const permissionFiltered = menusSet.size
|
||||
? filterRoutesByMenusPermission(data, menusSet)
|
||||
: [];
|
||||
|
||||
return generateMenus(permissionFiltered);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 404 无权限页面
|
||||
|
||||
**文件**: `src/views/error/404.vue`
|
||||
|
||||
无权限访问时统一跳转此页面,显示提示信息和操作按钮:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="error-page">
|
||||
<div class="error-content">
|
||||
<h1>404</h1>
|
||||
<h2>无权限访问</h2>
|
||||
<p>您没有权限访问此页面,请联系上级部门添加相关权限。</p>
|
||||
<el-button type="primary" @click="goHome">返回首页</el-button>
|
||||
<el-button @click="logout">退出登录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const logout = () => {
|
||||
window.opener = null;
|
||||
window.open('', '_self');
|
||||
window.close();
|
||||
store.commit("app/clearTag", null, { immediate: true });
|
||||
store.commit("permission/deleteRouter", { immediate: true });
|
||||
store.commit("user/deleteKeepLiiveRoute", "home");
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. 退出登录
|
||||
|
||||
**文件**: `src/store/modules/user.js`
|
||||
|
||||
```javascript
|
||||
async logout(ctx) {
|
||||
const res = await loginOut();
|
||||
if (res) {
|
||||
// 重置动态路由
|
||||
resetRouter();
|
||||
// 重置路由守卫初始化标记
|
||||
resetRoutesInit();
|
||||
// 清除权限模块状态
|
||||
ctx.dispatch("permission/resetRoutes");
|
||||
// 清除用户状态
|
||||
ctx.commit("user/setToken", "");
|
||||
ctx.commit("user/setUserName", "admin");
|
||||
ctx.commit("user/setUserInfo", {});
|
||||
// 清除本地存储
|
||||
removeAllItem();
|
||||
// 跳转统一门户
|
||||
window.location.href = `https://tyyy.lz.dsj.xz/portal/home`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 权限判断核心
|
||||
|
||||
### 匹配公式
|
||||
|
||||
```
|
||||
用户权限码:menusPermission = ["FourColorWarning", "YjData", "userList", ...]
|
||||
|
||||
路由配置:
|
||||
{
|
||||
path: "/FourColorWarning",
|
||||
name: "FourColorWarning", // ← 必须与权限码一致
|
||||
meta: { title: "预警中心", icon: "article-ranking" },
|
||||
children: [...]
|
||||
}
|
||||
|
||||
判断逻辑:
|
||||
menusPermission.includes(route.name) ? 有权限 : 无权限
|
||||
```
|
||||
|
||||
### 关键点
|
||||
|
||||
| 要素 | 说明 |
|
||||
|-----|------|
|
||||
| **权限来源** | 后端登录接口返回的 `menuCodeSet` |
|
||||
| **存储位置** | `localStorage.menusPermission` |
|
||||
| **匹配字段** | 路由的 `name` 属性 |
|
||||
| **匹配方式** | 数组 `includes` 检查 |
|
||||
| **父路由处理** | 无 `name` 时检查子路由,有权限子路由则保留父路由 |
|
||||
|
||||
---
|
||||
|
||||
## 权限控制层级
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ 权限控制层级 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第一层:路由守卫 │
|
||||
│ - 控制登录状态 │
|
||||
│ - 未登录跳转登录页 │
|
||||
│ - 白名单路由直接放行 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第二层:动态路由注册 │
|
||||
│ - 根据权限码筛选路由 │
|
||||
│ - 无权限路由不注册 → 用户输入 URL 直接 404 │
|
||||
│ - 只在登录时计算一次,性能最优 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第三层:侧边栏菜单过滤 │
|
||||
│ - 从已注册路由中筛选 │
|
||||
│ - 只显示有权限的菜单项 │
|
||||
│ - 支持特殊部门/角色的额外过滤 │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ 第四层:按钮级权限 │
|
||||
│ - 使用 v-permission 指令控制按钮显示 │
|
||||
│ - 根据用户的功能权限动态移除无权限元素 │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 安全特性
|
||||
|
||||
### 动态路由方案的安全优势
|
||||
|
||||
| 特性 | 说明 |
|
||||
|-----|------|
|
||||
| **路由不存在** | 无权限路由不会注册到 Vue Router,从根本上杜绝越权访问 |
|
||||
| **URL 直接访问** | 用户输入无权限 URL 直接跳转 404 |
|
||||
| **性能最优** | 只在登录时计算一次,后续跳转无需校验 |
|
||||
| **业界标准** | Vue 官方推荐的权限控制方案 |
|
||||
|
||||
### 无权限访问流程
|
||||
|
||||
```
|
||||
用户访问无权限 URL(如 /user/userList)
|
||||
│
|
||||
▼
|
||||
路由是否已注册?
|
||||
│
|
||||
┌─────┴─────┐
|
||||
│ 否 │ 是
|
||||
▼ ▼
|
||||
跳转 404 正常访问(但不会发生,因为无权限路由不会注册)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 特殊权限处理
|
||||
|
||||
### 部门类型 + 角色组合
|
||||
|
||||
系统根据部门类型(`deptBizType`)和角色(`roleList`)进行特殊路由控制:
|
||||
|
||||
| 条件 | 排除的路由 |
|
||||
|-----|----------|
|
||||
| `deptBizType == '23'` 且有 `JS_666666` 角色 | 不排除任何路由 |
|
||||
| `deptBizType == '23'` 且有 `JS_999999` 角色 | 排除 `/internalAuditor` |
|
||||
| 其他情况 | 排除 `/internalAuditor` 和 `/auditList` |
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 页面空白?
|
||||
|
||||
检查项:
|
||||
1. 是否使用了 `JSON.parse(JSON.stringify())` 深拷贝路由(会丢失 component)
|
||||
2. 路由的 `name` 是否与权限码一致
|
||||
3. 控制台是否有报错
|
||||
|
||||
### Q2: 菜单不显示?
|
||||
|
||||
检查项:
|
||||
1. `localStorage.menusPermission` 是否存在
|
||||
2. 路由是否包含 `meta.title` 和 `meta.icon`
|
||||
3. 路由是否在 `EXCLUDE_NAMES` 列表中
|
||||
|
||||
### Q3: 刷新后 404?
|
||||
|
||||
检查项:
|
||||
1. `localStorage.menusPermission` 是否存在
|
||||
2. 路由守卫是否正确重新初始化
|
||||
|
||||
### Q4: 退出登录后无法重新登录?
|
||||
|
||||
检查项:
|
||||
1. 是否正确调用了 `resetRoutesInit()` 重置初始化标记
|
||||
2. 是否正确清除了 localStorage
|
||||
|
||||
---
|
||||
|
||||
## 相关文件索引
|
||||
|
||||
| 文件 | 说明 |
|
||||
|-----|------|
|
||||
| `src/router/index.js` | 路由配置(publicRoutes / privateRoutes) |
|
||||
| `src/store/modules/permission.js` | 权限路由模块(过滤 + 动态注册) |
|
||||
| `src/store/modules/user.js` | 用户模块(登录/退出) |
|
||||
| `src/permission.js` | 路由守卫 |
|
||||
| `src/utils/route.js` | 路由工具函数 |
|
||||
| `src/layout/components/SideBar/SideBarMenu.vue` | 侧边栏菜单 |
|
||||
| `src/layout/components/NavBar.vue` | 导航栏(退出登录) |
|
||||
| `src/views/error/404.vue` | 无权限/404 页面 |
|
||||
| `src/directives/permission.js` | 按钮级权限指令 |
|
||||
209
docs/麒麟系统文件下载兼容性修复方案.md
Normal file
209
docs/麒麟系统文件下载兼容性修复方案.md
Normal file
@ -0,0 +1,209 @@
|
||||
# 麒麟系统浏览器文件下载兼容性修复方案
|
||||
|
||||
## 一、问题现象
|
||||
|
||||
**下载成功,但文件打不开**。文件已保存到本地,但用对应软件打开时提示损坏或格式错误。
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 可能原因 1:`URL.revokeObjectURL` 释放过早(文件内容损坏)
|
||||
|
||||
当前代码(第300-313行):
|
||||
|
||||
```javascript
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const link = document.createElement("a");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href); // 同步释放,可能过早
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
`link.click()` 在麒麟浏览器中是异步的,同步调用 `revokeObjectURL` 会在 Blob 数据写入磁盘前就销毁它,导致文件内容不完整。
|
||||
|
||||
---
|
||||
|
||||
### 可能原因 2:文件名无后缀 / 后缀被篡改
|
||||
|
||||
分析文件名传递链路:
|
||||
|
||||
**上传时**,`handlerSuccess` 保存的是 `{ id, name }`,`name` 来自浏览器原始文件名(带后缀),这部分没问题。
|
||||
|
||||
**但回显时**,watch 中第183-188行存在一个关键问题:
|
||||
|
||||
```javascript
|
||||
// 当 modelValue 元素是字符串(非对象)时:
|
||||
} else {
|
||||
return {
|
||||
url: String(`/mosty-api/mosty-base/minio/image/download/` + el || ""),
|
||||
id: el
|
||||
// ← 没有 name 属性!
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
此时 `file.name` 为 `undefined`,传入 `downloadFile(file.url, file.name)`:
|
||||
|
||||
```javascript
|
||||
link.download = undefined; // 文件名丢失
|
||||
```
|
||||
|
||||
**麒麟浏览器的行为**:当 `download` 属性为空或 `undefined` 时,浏览器会:
|
||||
- 从 URL 路径提取文件名(如 `/minio/image/download/abc123` → 文件名变成 `abc123`,**无后缀**)
|
||||
- 或根据 Blob 的 `type` 自动添加后缀(如服务端返回的 Content-Type 是 `application/json` → 强制加 `.json` 后缀)
|
||||
|
||||
**结果**:一个 `.docx` 文件下载后变成了 `.json` 或无后缀文件,自然打不开。
|
||||
|
||||
**验证方法**:在麒麟系统上下载一个文件,查看下载后的文件名是否和原始文件名一致(包括后缀)。
|
||||
|
||||
---
|
||||
|
||||
### 可能原因 3:麒麟系统安全机制拦截
|
||||
|
||||
麒麟系统(基于 Linux)自带安全中心,可能触发以下行为:
|
||||
|
||||
| 安全机制 | 行为 | 结果 |
|
||||
|----------|------|------|
|
||||
| 文件隔离 | 将下载的文件标记为不可信,移到隔离区 | 文件存在但被锁,其他程序无法读取 |
|
||||
| 执行权限 | 给文件添加可执行标记,或删除可执行标记 | 程序拒绝打开带危险标记的文件 |
|
||||
| 杀毒扫描 | 实时扫描下载文件,误报则隔离 | 文件被移动或内容被修改 |
|
||||
| WINE 兼容层 | 试图用 WINE 打开 Windows 格式文件 | 文件关联错误,打开方式不对 |
|
||||
|
||||
**验证方法**:
|
||||
1. 在麒麟系统终端执行 `ls -la` 查看下载文件是否有特殊权限标记
|
||||
2. 检查 `/tmp` 或隔离区目录是否有被拦截的文件
|
||||
3. 暂时关闭麒麟安全中心,重新下载测试
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 方案 A:综合修复(推荐)
|
||||
|
||||
同时解决原因1和原因2,并在下载失败时给出明确提示:
|
||||
|
||||
```javascript
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
// 补全文件名后缀
|
||||
function ensureFilename(file) {
|
||||
if (file.name) return file.name
|
||||
// name 丢失时,从 URL 中尝试提取,或使用默认名
|
||||
const urlId = file.url?.split('/').pop()
|
||||
return urlId ? `文件_${urlId}` : '未命名文件'
|
||||
}
|
||||
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载失败: ${response.status}`)
|
||||
}
|
||||
return response.blob()
|
||||
})
|
||||
.then((blob) => {
|
||||
// saveAs 内部处理了 Blob 释放时序,不会过早 revoke
|
||||
saveAs(blob, filename)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('下载失败:', error)
|
||||
ElMessage.error('文件下载失败,请重试')
|
||||
})
|
||||
}
|
||||
|
||||
const handleDownload = (file) => {
|
||||
if (file?.response?.data) {
|
||||
window.open(file.response.data)
|
||||
} else if (file?.url) {
|
||||
const filename = ensureFilename(file)
|
||||
downloadFile(file.url, filename)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**改动内容**:
|
||||
1. 引入 `file-saver`(项目已有依赖)→ 解决 Blob 释放过早
|
||||
2. `ensureFilename` 补全文件名 → 解决后缀丢失
|
||||
3. 响应状态校验 → 发现服务端错误时提示用户
|
||||
|
||||
---
|
||||
|
||||
### 方案 B:仅修复 Blob 释放时序(最小改动)
|
||||
|
||||
```javascript
|
||||
function downloadFile(url, filename) {
|
||||
fetch(url)
|
||||
.then((response) => response.blob())
|
||||
.then((blob) => {
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = blobUrl;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
// 延迟释放,确保浏览器完成 Blob 数据拷贝
|
||||
setTimeout(() => URL.revokeObjectURL(blobUrl), 3000);
|
||||
})
|
||||
.catch((error) => console.error("下载失败:", error));
|
||||
}
|
||||
```
|
||||
|
||||
**改动量**:1 行。但未修复文件名丢失问题。
|
||||
|
||||
---
|
||||
|
||||
### 方案 C:window.open 直接下载
|
||||
|
||||
```javascript
|
||||
const handleDownload = (file) => {
|
||||
if (file?.url) {
|
||||
window.open(file.url, "_blank");
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**前提**:后端接口需设置 `Content-Disposition: attachment; filename="xxx.docx"` 响应头,浏览器才能正确处理文件名和下载行为。
|
||||
|
||||
---
|
||||
|
||||
## 四、排查步骤
|
||||
|
||||
建议按以下顺序验证,定位到底是哪个原因:
|
||||
|
||||
1. **检查文件名**:在麒麟系统下载后,文件名是否带正确后缀(如 `.docx`、`.pdf`)?
|
||||
- 后缀丢失/被改 → **原因2(文件名问题)**
|
||||
- 后缀正确 → 排除原因2
|
||||
|
||||
2. **检查文件大小**:下载的文件大小是否和服务端一致?
|
||||
- 文件明显偏小或0字节 → **原因1(Blob 释放过早)**
|
||||
- 大小一致 → 排除原因1
|
||||
|
||||
3. **关闭安全中心测试**:暂时关闭麒麟安全中心,重新下载
|
||||
- 能正常打开 → **原因3(安全拦截)**
|
||||
- 仍打不开 → 排除原因3
|
||||
|
||||
---
|
||||
|
||||
## 五、方案对比
|
||||
|
||||
| | 方案 A 综合修复 | 方案 B 延迟释放 | 方案 C window.open |
|
||||
|---|---|---|---|
|
||||
| 修复原因1(Blob释放) | ✅ | ✅ | 不涉及 |
|
||||
| 修复原因2(文件名后缀) | ✅ | ❌ | 取决于后端 |
|
||||
| 处理原因3(安全拦截) | ❌ 需系统配置 | ❌ | ❌ |
|
||||
| 改动量 | ~15行 | 1行 | 最小 |
|
||||
|
||||
**建议**:先执行排查步骤确认根因,再选择对应方案。如果原因1和2同时存在,直接用方案A。
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v3.0
|
||||
**创建日期**: 2026-04-24
|
||||
25540
package-lock.json
generated
25540
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -52,6 +52,10 @@
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.29.0",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
|
||||
"@babel/preset-env": "^7.29.2",
|
||||
"@element-plus/icons": "^0.0.11",
|
||||
"@toast-ui/editor": "^3.0.2",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
@ -79,14 +83,5 @@
|
||||
"sass-loader": "^8.0.2",
|
||||
"svg-sprite-loader": "^6.0.9",
|
||||
"vue-cli-plugin-element-plus": "0.0.13"
|
||||
},
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,vue}": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,6 @@ onMounted(() => {
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*@Descripttion:图片页面初始化
|
||||
*@Author: PengShuai
|
||||
|
||||
@ -620,7 +620,7 @@ export const idCardNoLogin = (data) => {
|
||||
method: "POST",
|
||||
data
|
||||
});
|
||||
}
|
||||
};
|
||||
// 通过身份证号获取会话信息
|
||||
export const getSessionForSfzh = (params) => {
|
||||
return request({
|
||||
@ -636,7 +636,7 @@ export const idCardNoLoginPcs = (data) => {
|
||||
method: "POST",
|
||||
data
|
||||
});
|
||||
}
|
||||
};
|
||||
// 通过身份证号获取会话信息
|
||||
export const getSessionForSfzhPcs = (params) => {
|
||||
return request({
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
import request from "@/utils/request";
|
||||
const api = "/mosty-api/mosty-gsxt";
|
||||
|
||||
// 情报采集关注
|
||||
export const xxcjCare = (data) => {
|
||||
return request({
|
||||
url: api + "/xxcj/cjgz",
|
||||
method: "POST",
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// 情报采集新增
|
||||
export const xxcjAddEntity = (data) => {
|
||||
return request({
|
||||
@ -65,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`,
|
||||
@ -236,3 +254,12 @@ export const xxcjXxcjSh = (data) => {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 上报区厅
|
||||
export const xxcjReportGat = (data) => {
|
||||
return request({
|
||||
url: api + `/xxcj/reportGat`,
|
||||
method: "post",
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ header {
|
||||
}
|
||||
|
||||
&::v-deep .el-form-item--default {
|
||||
width: 23%;
|
||||
// width: 23%;
|
||||
padding-bottom: 20px;
|
||||
margin: 0 1%;
|
||||
}
|
||||
|
||||
@ -241,6 +241,10 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vam {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/**********文本省略***********/
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
@ -287,6 +291,10 @@
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/**********字体大小和边距***********/
|
||||
@for $i from 1 through 100 {
|
||||
.f#{$i} {
|
||||
@ -345,7 +353,7 @@
|
||||
}
|
||||
|
||||
.ww#{$i} {
|
||||
width: #{$i}+"%";
|
||||
width: #{$i * 1%};
|
||||
}
|
||||
|
||||
.hh#{$i} {
|
||||
@ -430,10 +438,13 @@
|
||||
|
||||
// 警情闪速动画
|
||||
@keyframes alert-flash {
|
||||
0%, 100% {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.3;
|
||||
transform: scale(1.05);
|
||||
@ -444,19 +455,25 @@
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(255, 77, 79, 0.7);
|
||||
}
|
||||
|
||||
70% {
|
||||
box-shadow: 0 0 0 10px rgba(255, 77, 79, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(255, 77, 79, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes alert-blink {
|
||||
0%, 49% {
|
||||
|
||||
0%,
|
||||
49% {
|
||||
opacity: 1;
|
||||
}
|
||||
50%, 100% {
|
||||
|
||||
50%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@ -489,3 +506,9 @@
|
||||
color: #df6c07;
|
||||
animation: alert-flash 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.margTop {
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
background-color: #fff;
|
||||
}
|
||||
BIN
src/assets/images/01.mp3
Normal file
BIN
src/assets/images/01.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/02.mp3
Normal file
BIN
src/assets/images/02.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/03.mp3
Normal file
BIN
src/assets/images/03.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/04.mp3
Normal file
BIN
src/assets/images/04.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/05.mp3
Normal file
BIN
src/assets/images/05.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/06.mp3
Normal file
BIN
src/assets/images/06.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/07.mp3
Normal file
BIN
src/assets/images/07.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/08.mp3
Normal file
BIN
src/assets/images/08.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/09.mp3
Normal file
BIN
src/assets/images/09.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/10.mp3
Normal file
BIN
src/assets/images/10.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/11.mp3
Normal file
BIN
src/assets/images/11.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/12.mp3
Normal file
BIN
src/assets/images/12.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/13.mp3
Normal file
BIN
src/assets/images/13.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/14.mp3
Normal file
BIN
src/assets/images/14.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/15.mp3
Normal file
BIN
src/assets/images/15.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/16.mp3
Normal file
BIN
src/assets/images/16.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/17.mp3
Normal file
BIN
src/assets/images/17.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/18.mp3
Normal file
BIN
src/assets/images/18.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/19.mp3
Normal file
BIN
src/assets/images/19.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/jqjc.mp3
Normal file
BIN
src/assets/images/jqjc.mp3
Normal file
Binary file not shown.
@ -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,
|
||||
|
||||
@ -7,9 +7,17 @@
|
||||
@close="closed"
|
||||
>
|
||||
<div>
|
||||
<div class="flex" style="margin-bottom: 10px;">
|
||||
<el-button :type="bqLb === '01' ? 'success' : 'info'" @click="qihuan('01')">标签大类</el-button>
|
||||
<el-button :type="bqLb === '02' ? 'success' : 'info'" @click="qihuan('02')"> 标签小类 </el-button>
|
||||
<div class="mark-tabs">
|
||||
<span class="label">标签类型:</span>
|
||||
<el-radio-group v-model="bqLx" @change="changeBqLx">
|
||||
<el-radio-button label="02">行为标签</el-radio-button>
|
||||
<el-radio-button label="01">身份标签</el-radio-button>
|
||||
</el-radio-group>
|
||||
<span class="label" style="margin-left: 20px;">类别:</span>
|
||||
<el-radio-group v-model="bqLb" @change="qihuan">
|
||||
<el-radio-button label="01">大类</el-radio-button>
|
||||
<el-radio-button label="02">小类</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<el-form :model="listQuery" class="mosty-from-wrap" :inline="true">
|
||||
<el-form-item label="标签名称">
|
||||
@ -83,7 +91,7 @@
|
||||
|
||||
<script setup>
|
||||
import { qcckGet } from "@/api/qcckApi.js";
|
||||
import { defineProps, ref, getCurrentInstance, watch } from "vue";
|
||||
import { defineProps, ref, getCurrentInstance, watch, nextTick } from "vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_BQ_DJ, D_GS_SSYJ } = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ"); //获取字典数据
|
||||
const props = defineProps({
|
||||
@ -107,6 +115,11 @@ const props = defineProps({
|
||||
roleIds: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
// 标签类型:02-行为标签,01-身份标签
|
||||
bqLx: {
|
||||
type: String,
|
||||
default: "02"
|
||||
}
|
||||
});
|
||||
const loading = ref(false);
|
||||
@ -120,6 +133,8 @@ const keyVal = ref();
|
||||
const multipleUserRef = ref(null);
|
||||
const multipleSelectionUser = ref([]);
|
||||
const tableData = ref([]);
|
||||
const bqLx = ref(props.bqLx);
|
||||
const bqLb = ref("01");
|
||||
const emits = defineEmits(["update:modelValue", "choosed"]);
|
||||
const keyid = (row) => {
|
||||
return row.id;
|
||||
@ -148,9 +163,9 @@ const onComfirm = () => {
|
||||
closed();
|
||||
};
|
||||
const qihuan = (val) => {
|
||||
bqLb.value = val
|
||||
getListData()
|
||||
}
|
||||
listQuery.value.pageCurrent = 1;
|
||||
getListData();
|
||||
};
|
||||
/**
|
||||
* pageSize 改变触发
|
||||
*/
|
||||
@ -168,7 +183,7 @@ const handleCurrentChange = (currentPage) => {
|
||||
const getListData = () => {
|
||||
keyVal.value++;
|
||||
loading.value = true;
|
||||
const params = { ...listQuery.value, bqLx: "02",bqLb:bqLb.value };
|
||||
const params = { ...listQuery.value, bqLx: bqLx.value, bqLb: bqLb.value };
|
||||
qcckGet(params, "/mosty-gsxt/tbGsxtBqgl/selectPage")
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
@ -183,23 +198,25 @@ const getListData = () => {
|
||||
|
||||
//列表回显 - 优化版,确保已选择数据正确回显
|
||||
function multipleUser() {
|
||||
if (!multipleUserRef.value || !tableData.value || tableData.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
nextTick(() => {
|
||||
if (!multipleUserRef.value || !tableData.value || tableData.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 先清除所有选中状态
|
||||
tableData.value.forEach((item) => {
|
||||
multipleUserRef.value.toggleRowSelection(item, false);
|
||||
});
|
||||
|
||||
// 再根据roleIds重新设置选中状态
|
||||
if (props.roleIds && Array.isArray(props.roleIds) && props.roleIds.length > 0) {
|
||||
// 先清除所有选中状态
|
||||
tableData.value.forEach((item) => {
|
||||
if (props.roleIds.some((id) => id == item.id)) {
|
||||
multipleUserRef.value.toggleRowSelection(item, true);
|
||||
}
|
||||
multipleUserRef.value.toggleRowSelection(item, false);
|
||||
});
|
||||
}
|
||||
|
||||
// 再根据roleIds重新设置选中状态
|
||||
if (props.roleIds && Array.isArray(props.roleIds) && props.roleIds.length > 0) {
|
||||
tableData.value.forEach((item) => {
|
||||
if (props.roleIds.some((id) => id == item.id)) {
|
||||
multipleUserRef.value.toggleRowSelection(item, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const handleFilter = () => {
|
||||
@ -218,7 +235,11 @@ const handleSelectionChange = (val) => {
|
||||
multipleSelectionUser.value = val;
|
||||
}
|
||||
};
|
||||
const bqLb=ref('01')
|
||||
const changeBqLx = (val) => {
|
||||
listQuery.value.pageCurrent = 1;
|
||||
multipleUserRef.value?.clearSelection();
|
||||
getListData();
|
||||
};
|
||||
// 监听弹窗打开状态,打开时重新加载数据
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
@ -233,19 +254,40 @@ watch(
|
||||
// 监听roleIds变化,确保数据回显正确
|
||||
watch(
|
||||
() => props.roleIds,
|
||||
(newRoleIds) => {
|
||||
// 使用setTimeout确保在表格数据加载完成后再进行选择
|
||||
setTimeout(() => {
|
||||
() => {
|
||||
nextTick(() => {
|
||||
multipleUser();
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 监听外部传入的 bqLx 变化
|
||||
watch(
|
||||
() => props.bqLx,
|
||||
(newVal) => {
|
||||
bqLx.value = newVal;
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/assets/css/layout.scss";
|
||||
@import "@/assets/css/element-plus.scss";
|
||||
|
||||
.mark-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding: 10px 15px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 6px;
|
||||
|
||||
.label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.tabBoxRadio .el-checkbox__inner {
|
||||
|
||||
@ -67,13 +67,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getItem } from "@/utils/storage";
|
||||
import { timeValidate } from '@/utils/tools'
|
||||
import { ref,defineEmits, onMounted } from 'vue'
|
||||
const props = defineProps({
|
||||
modelValue:Boolean,
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue','save'])
|
||||
const baseInfo = localStorage.getItem('rhInfo') ? JSON.parse(localStorage.getItem('rhInfo')) : {};
|
||||
const baseInfo = getItem('rhInfo') || {};
|
||||
const formData = ref({
|
||||
alarm:1,
|
||||
duration:'30',
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getItem } from "@/utils/storage";
|
||||
import useCallModule from '@/components/Consultation/sdk/call';
|
||||
import useRecorder from '@/components/Consultation/hooks/recorder';
|
||||
import DraggableResizableVue from "draggable-resizable-vue3";
|
||||
@ -43,7 +44,7 @@ const props = defineProps({
|
||||
modelValue:Boolean,
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const baseInfo = localStorage.getItem('rhInfo') ? JSON.parse(localStorage.getItem('rhInfo')) : {};
|
||||
const baseInfo = getItem('rhInfo') || {};
|
||||
let waveContainer;
|
||||
let audioWave = SiriWave || undefined;
|
||||
const element = ref({
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getItem } from "@/utils/storage";
|
||||
import { timeValidate } from '@/utils/tools'
|
||||
import DraggerAble from './components/draggerAble.vue'
|
||||
import useConfernceEvent from './components/js/useConfernceEvent';
|
||||
@ -21,8 +22,9 @@ import { useStore } from "vuex";
|
||||
const emit = defineEmits(['update']);
|
||||
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) //打开会议
|
||||
@ -95,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, //预计时长 (分钟)
|
||||
@ -105,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;
|
||||
@ -135,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,' 加入会议失败......');
|
||||
})
|
||||
@ -145,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);
|
||||
// 会议存在 ? 进入会议 : 创建会议 ;
|
||||
@ -153,58 +154,20 @@ const fetchConferences = (it) =>{
|
||||
}).catch(err=> {})
|
||||
}
|
||||
|
||||
|
||||
const Init = () => {
|
||||
let token = window.localStorage.getItem("rhToken");
|
||||
if (!token) {
|
||||
let userInfo = {
|
||||
username: "sgxtcs",
|
||||
password: "123456",
|
||||
realm: "puc.com",
|
||||
webpucUrl: "https://89.40.9.95:16888"
|
||||
};
|
||||
lemon.login.login(userInfo).then((esacpe) => {
|
||||
token = esacpe.token;
|
||||
window.localStorage.setItem("rhToken", esacpe.token);
|
||||
listenerEvents()
|
||||
});
|
||||
} else {
|
||||
ConnectWebsocket(token);
|
||||
}
|
||||
};
|
||||
|
||||
const ConnectWebsocket = (token) => {
|
||||
lemon.login.reConnectWebsocket({
|
||||
username: "sgxtcs",
|
||||
realm: "puc.com",
|
||||
webpucUrl: "https://89.40.9.95:16888",
|
||||
token: token
|
||||
}).then((resp) => {
|
||||
if(resp.result != 0){
|
||||
localStorage.removeItem('rhToken')
|
||||
localStorage.removeItem('user_basedata_id')
|
||||
let messge = jsonData.value['errorCode'][resp.result] +',请重新刷新页面'
|
||||
ElMessage.error(messge);
|
||||
lemon.login.logout().then(res=> {}).catch(err=> {})
|
||||
}else{
|
||||
listenerEvents();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化后需要监听的方法
|
||||
const listenerEvents = () =>{
|
||||
getLoginAccountInfo() //前账号的登录信息
|
||||
useConfernceEvent()// 注册会议管理相关事件
|
||||
// 无人机对讲机的监听时事件
|
||||
window.lemon.call.addMediaStream((call_id, stream, type) => {
|
||||
console.log(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 => {
|
||||
@ -226,7 +189,6 @@ const openInit = (it,type) =>{
|
||||
// 会议号存在 ? 获取会议列表里面是否包含该条会议 : 创建会议 ;
|
||||
it.number ? fetchConferences(it) : conferenceActionSDK(it);
|
||||
}).catch(()=>{ })
|
||||
|
||||
}
|
||||
|
||||
if(['对讲机','无人机'].includes(type)){
|
||||
@ -238,6 +200,44 @@ const openInit = (it,type) =>{
|
||||
}
|
||||
|
||||
|
||||
const Init = () => {
|
||||
let token = window.localStorage.getItem("rhToken");
|
||||
if (!token || 'undefined' == token || token == 'null') {
|
||||
let userInfo = {
|
||||
username: inDustRialId, //用户名
|
||||
password: "123456",
|
||||
realm: "puc.com",
|
||||
webpucUrl: "https://89.40.9.95:16888"
|
||||
};
|
||||
lemon.login.login(userInfo).then((esacpe) => {
|
||||
token = esacpe.token;
|
||||
window.localStorage.setItem("rhToken", esacpe.token);
|
||||
listenerEvents()
|
||||
})
|
||||
} else {
|
||||
ConnectWebsocket(token);
|
||||
}
|
||||
};
|
||||
|
||||
const ConnectWebsocket = (token) => {
|
||||
lemon.login.reConnectWebsocket({
|
||||
username: inDustRialId, //用户名
|
||||
realm: "puc.com",
|
||||
webpucUrl: "https://89.40.9.95:16888",
|
||||
token: token
|
||||
}).then((resp) => {
|
||||
if(resp.result != 0){
|
||||
localStorage.removeItem('rhToken')
|
||||
localStorage.removeItem('user_basedata_id')
|
||||
let messge = jsonData.value['errorCode'][resp.result] +',请重新刷新页面'
|
||||
ElMessage.error(messge);
|
||||
lemon.login.logout().then(res=> {}).catch(err=> {})
|
||||
}else{
|
||||
listenerEvents();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(()=>{
|
||||
jsonData.value = require('./components/zh_CN.json');
|
||||
nextTick(()=>{
|
||||
@ -250,7 +250,7 @@ onUnmounted(()=>{
|
||||
lemon.login.removeLoginStatusChangeListener(loginStatusCallbackId.value);
|
||||
})
|
||||
|
||||
defineExpose({openInit});
|
||||
defineExpose({openInit,Init});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div :id="mapid" class="map"></div>
|
||||
<div class="changeMap_box" v-if="props.isShow">
|
||||
<!-- <el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况" style="--el-switch-color:#13ce66;--el-switch-off-color:#ff4949;" /> -->
|
||||
<el-switch
|
||||
v-model="conditionRoute"
|
||||
@change="handleSwitch"
|
||||
active-text="打开路况"
|
||||
inactive-text="关闭路况"
|
||||
style="--el-switch-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
/>
|
||||
<!-- <el-carousel type="card" height="75px" :autoplay="false" indicator-position="none" :initial-index="3" @change="onMapImageChange">
|
||||
<el-carousel-item>
|
||||
<div class="mapImageItem">
|
||||
@ -30,8 +36,14 @@
|
||||
</el-carousel> -->
|
||||
<!-- 地图缩放 -->
|
||||
<div class="zoomTargetBox">
|
||||
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom">
|
||||
</el-input-number>
|
||||
<el-input-number
|
||||
:min="7"
|
||||
:max="18"
|
||||
v-model="zoomTarget"
|
||||
:step="1"
|
||||
step-strictly
|
||||
@change="handleZoom"
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -44,7 +56,7 @@ import { getItem } from "@/utils/storage";
|
||||
const conditionRoute = ref(true); //路况
|
||||
const mMap = ref(null); //地图对象
|
||||
const mapUtil = ref(null); //地图工具对象
|
||||
const zoomTarget = ref(6);
|
||||
const zoomTarget = ref(15);
|
||||
|
||||
const props = defineProps({
|
||||
mapid: {
|
||||
@ -70,8 +82,7 @@ const props = defineProps({
|
||||
isShowDraw: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
try {
|
||||
const userInfo = getItem("deptId")[0].deptCode;
|
||||
@ -89,66 +100,40 @@ onMounted(() => {
|
||||
|
||||
map = new EliMap({
|
||||
id: props.mapid,
|
||||
crs: "EPSG:3857",
|
||||
crs: "EPSG:4490",
|
||||
style: {
|
||||
glyphs: "./fonts/{fontstack}/{range}.pbf",
|
||||
center: [94.36,29.65],
|
||||
zoom: 11
|
||||
center: [94.36057012, 29.64276831],
|
||||
zoom: 15
|
||||
},
|
||||
minZoom: 7,
|
||||
maxZoom: 18,
|
||||
transformRequest: (url) => {
|
||||
if (url.indexOf("TileMatrix=") != -1) {
|
||||
const arr = url.split("TileMatrix=");
|
||||
const arr1 = arr[1].split("&");
|
||||
const nurl = `${arr[0]}&TileMatrix=${Number(arr1[0])}&${arr1[1]}&${arr1[2]}`;
|
||||
|
||||
}
|
||||
}
|
||||
minZoom: 5,
|
||||
maxZoom: 20
|
||||
});
|
||||
|
||||
window.map = map;
|
||||
map.mapboxGLMap.on("load", () => {
|
||||
map.addGaudLayer({
|
||||
url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
|
||||
})
|
||||
zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||
// 地图加载完成后发出事件
|
||||
// emit('mapLoaded')
|
||||
map.addWMTSLayer(
|
||||
"/PGIS_S_TileMapServer/Maps/XZDJ_DJ/EzMap",
|
||||
{
|
||||
Service: "getImage",
|
||||
Type: "RGB",
|
||||
ZoomOffset: "0",
|
||||
V: "0.3",
|
||||
Zoom: "{z}",
|
||||
Row: "{y}",
|
||||
Col: "{x}"
|
||||
},
|
||||
{
|
||||
tileSize: 300
|
||||
}
|
||||
);
|
||||
// WMTS图层加载完成后延时设置zoom
|
||||
setTimeout(() => {
|
||||
map.mapboxGLMap.setZoom(18);
|
||||
zoomTarget.value = 18;
|
||||
}, 500);
|
||||
});
|
||||
mapUtil.value = new MapUtil(map);
|
||||
// map = new EliMap({
|
||||
// id: props.mapid,
|
||||
// crs: "EPSG:4490",
|
||||
// style: {
|
||||
// glyphs: "./fonts/{fontstack}/{range}.pbf",
|
||||
// center: [94.36057012, 29.64276831],
|
||||
// zoom: 15
|
||||
// },
|
||||
// minZoom: 7,
|
||||
// maxZoom: 18,
|
||||
// });
|
||||
// window.map = map;
|
||||
// map.mapboxGLMap.on("load", () => {
|
||||
// map.addWMTSLayer(
|
||||
// "/PGIS_S_TileMapServer/Maps/XZDJ_SL/EzMap"
|
||||
// ,
|
||||
// {
|
||||
// Service: "getImage",
|
||||
// Type: "RGB",
|
||||
// ZoomOffset: "0",
|
||||
// V: "0.3",
|
||||
// Zoom: "{z}",
|
||||
// Row: "{y}",
|
||||
// Col: "{x}"
|
||||
// },
|
||||
// {
|
||||
// tileSize: 300
|
||||
// }
|
||||
// );
|
||||
// zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||
// });
|
||||
// mapUtil.value = new MapUtil(map);
|
||||
|
||||
mapUtil.value.Drawplot(); //初始化加载绘制工具
|
||||
|
||||
// 设置地图中心点及图层
|
||||
@ -184,6 +169,10 @@ onMounted(() => {
|
||||
emitter.on("showSquire", (obj) => {
|
||||
mapUtil.value.zdySquire(obj);
|
||||
});
|
||||
// 展示气泡框
|
||||
emitter.on("makerPopup", (obj) => {
|
||||
mapUtil.value.makerPopup(obj);
|
||||
});
|
||||
|
||||
// 绘制图形 - 回显区域
|
||||
emitter.on("drawShape", (res) => {
|
||||
@ -289,7 +278,6 @@ const mapSetLayer = (id, source) => {
|
||||
|
||||
//获取地图绘制的数据
|
||||
const resFun = (coord, type, flag, data) => {
|
||||
|
||||
emitter.emit("coordString", {
|
||||
coord: coord,
|
||||
type: type,
|
||||
@ -303,12 +291,6 @@ const handleZoom = (val) => {
|
||||
map.mapboxGLMap.setZoom(val);
|
||||
};
|
||||
|
||||
emitter.on("map-resize", () => {
|
||||
if (map && map.mapboxGLMap) {
|
||||
map.mapboxGLMap.resize();
|
||||
}
|
||||
});
|
||||
|
||||
// 是否打开或者关闭路况
|
||||
const handleSwitch = (val) => {
|
||||
if (val) {
|
||||
@ -325,6 +307,7 @@ onUnmounted(() => {
|
||||
emitter.off("showPoint");
|
||||
emitter.off("deletePointArea");
|
||||
emitter.off("deletePointAreaOne");
|
||||
emitter.off("makerPopup");
|
||||
emitter.off("drawShape");
|
||||
emitter.off("echoPlane");
|
||||
emitter.off("removeEara");
|
||||
@ -338,7 +321,6 @@ onUnmounted(() => {
|
||||
emitter.off("diffusionCircle");
|
||||
emitter.off("SsCircle");
|
||||
emitter.off("ClearssCircle");
|
||||
emitter.off("map-resize");
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -361,29 +343,35 @@ onUnmounted(() => {
|
||||
right: 398px;
|
||||
bottom: 4px;
|
||||
z-index: 9;
|
||||
|
||||
.mapImageItem {
|
||||
border: 1px solid #08aae8;
|
||||
background: rgb(9, 26, 70);
|
||||
|
||||
& > img {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
& > div {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
.zoomTargetBox {
|
||||
margin-top: 10px;
|
||||
margin-left: 23px;
|
||||
}
|
||||
|
||||
::v-deep .el-input-number__decrease,
|
||||
::v-deep .el-input-number__increase {
|
||||
background: #133362;
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .el-input__inner {
|
||||
background: #0c1641;
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
<template>
|
||||
<div :id="mapid" class="map"></div>
|
||||
<div class="changeMap_box" v-if="props.isShow">
|
||||
<el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况"
|
||||
style="--el-switch-color: #13ce66; --el-switch-off-color: #ff4949" />
|
||||
<!-- <el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况" style="--el-switch-color:#13ce66;--el-switch-off-color:#ff4949;" /> -->
|
||||
<!-- <el-carousel type="card" height="75px" :autoplay="false" indicator-position="none" :initial-index="3" @change="onMapImageChange">
|
||||
<el-carousel-item>
|
||||
<div class="mapImageItem">
|
||||
@ -31,7 +30,15 @@
|
||||
</el-carousel> -->
|
||||
<!-- 地图缩放 -->
|
||||
<div class="zoomTargetBox">
|
||||
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom"></el-input-number>
|
||||
<el-input-number
|
||||
:min="7"
|
||||
:max="18"
|
||||
v-model="zoomTarget"
|
||||
:step="1"
|
||||
step-strictly
|
||||
@change="handleZoom"
|
||||
>
|
||||
</el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -44,7 +51,7 @@ import { getItem } from "@/utils/storage";
|
||||
const conditionRoute = ref(true); //路况
|
||||
const mMap = ref(null); //地图对象
|
||||
const mapUtil = ref(null); //地图工具对象
|
||||
const zoomTarget = ref(15);
|
||||
const zoomTarget = ref(6);
|
||||
|
||||
const props = defineProps({
|
||||
mapid: {
|
||||
@ -74,7 +81,7 @@ const props = defineProps({
|
||||
});
|
||||
try {
|
||||
const userInfo = getItem("deptId")[0].deptCode;
|
||||
} catch (error) { }
|
||||
} catch (error) {}
|
||||
let map;
|
||||
let mapLayer;
|
||||
let mapLayer1;
|
||||
@ -88,37 +95,67 @@ onMounted(() => {
|
||||
|
||||
map = new EliMap({
|
||||
id: props.mapid,
|
||||
crs: "EPSG:4490",
|
||||
crs: "EPSG:3857",
|
||||
style: {
|
||||
glyphs: "./fonts/{fontstack}/{range}.pbf",
|
||||
center: [94.36057012, 29.64276831],
|
||||
center: [94.36, 29.65],
|
||||
zoom: 15
|
||||
},
|
||||
minZoom: 5,
|
||||
minZoom: 7,
|
||||
maxZoom: 18,
|
||||
transformRequest: (url) => {
|
||||
if (url.indexOf("TileMatrix=") != -1) {
|
||||
const arr = url.split("TileMatrix=");
|
||||
const arr1 = arr[1].split("&");
|
||||
const nurl = `${arr[0]}&TileMatrix=${Number(arr1[0])}&${arr1[1]}&${
|
||||
arr1[2]
|
||||
}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.map = map;
|
||||
map.mapboxGLMap.on("load", () => {
|
||||
map.addWMTSLayer(
|
||||
"/PGIS_S_TileMapServer/Maps/XZDJ_DJ/EzMap"
|
||||
,
|
||||
{
|
||||
Service: "getImage",
|
||||
Type: "RGB",
|
||||
ZoomOffset: "0",
|
||||
V: "0.3",
|
||||
Zoom: "{z}",
|
||||
Row: "{y}",
|
||||
Col: "{x}"
|
||||
},
|
||||
{
|
||||
tileSize: 300
|
||||
}
|
||||
);
|
||||
map.addGaudLayer({
|
||||
url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"
|
||||
});
|
||||
zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||
// 地图加载完成后发出事件
|
||||
// emit('mapLoaded')
|
||||
});
|
||||
mapUtil.value = new MapUtil(map);
|
||||
|
||||
// map = new EliMap({
|
||||
// id: props.mapid,
|
||||
// crs: "EPSG:4490",
|
||||
// style: {
|
||||
// glyphs: "./fonts/{fontstack}/{range}.pbf",
|
||||
// center: [94.36057012, 29.64276831],
|
||||
// zoom: 15
|
||||
// },
|
||||
// minZoom: 7,
|
||||
// maxZoom: 18,
|
||||
// });
|
||||
// window.map = map;
|
||||
// map.mapboxGLMap.on("load", () => {
|
||||
// map.addWMTSLayer(
|
||||
// "/PGIS_S_TileMapServer/Maps/XZDJ_SL/EzMap"
|
||||
// ,
|
||||
// {
|
||||
// Service: "getImage",
|
||||
// Type: "RGB",
|
||||
// ZoomOffset: "0",
|
||||
// V: "0.3",
|
||||
// Zoom: "{z}",
|
||||
// Row: "{y}",
|
||||
// Col: "{x}"
|
||||
// },
|
||||
// {
|
||||
// tileSize: 300
|
||||
// }
|
||||
// );
|
||||
// zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||
// });
|
||||
// mapUtil.value = new MapUtil(map);
|
||||
mapUtil.value.Drawplot(); //初始化加载绘制工具
|
||||
|
||||
// 设置地图中心点及图层
|
||||
@ -154,10 +191,6 @@ onMounted(() => {
|
||||
emitter.on("showSquire", (obj) => {
|
||||
mapUtil.value.zdySquire(obj);
|
||||
});
|
||||
// 展示气泡框
|
||||
emitter.on("makerPopup", (obj) => {
|
||||
mapUtil.value.makerPopup(obj);
|
||||
});
|
||||
|
||||
// 绘制图形 - 回显区域
|
||||
emitter.on("drawShape", (res) => {
|
||||
@ -276,6 +309,12 @@ const handleZoom = (val) => {
|
||||
map.mapboxGLMap.setZoom(val);
|
||||
};
|
||||
|
||||
emitter.on("map-resize", () => {
|
||||
if (map && map.mapboxGLMap) {
|
||||
map.mapboxGLMap.resize();
|
||||
}
|
||||
});
|
||||
|
||||
// 是否打开或者关闭路况
|
||||
const handleSwitch = (val) => {
|
||||
if (val) {
|
||||
@ -292,7 +331,6 @@ onUnmounted(() => {
|
||||
emitter.off("showPoint");
|
||||
emitter.off("deletePointArea");
|
||||
emitter.off("deletePointAreaOne");
|
||||
emitter.off("makerPopup");
|
||||
emitter.off("drawShape");
|
||||
emitter.off("echoPlane");
|
||||
emitter.off("removeEara");
|
||||
@ -306,6 +344,7 @@ onUnmounted(() => {
|
||||
emitter.off("diffusionCircle");
|
||||
emitter.off("SsCircle");
|
||||
emitter.off("ClearssCircle");
|
||||
emitter.off("map-resize");
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -328,35 +367,29 @@ onUnmounted(() => {
|
||||
right: 398px;
|
||||
bottom: 4px;
|
||||
z-index: 9;
|
||||
|
||||
.mapImageItem {
|
||||
border: 1px solid #08aae8;
|
||||
background: rgb(9, 26, 70);
|
||||
|
||||
&>img {
|
||||
& > img {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
&>div {
|
||||
& > div {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
.zoomTargetBox {
|
||||
margin-top: 10px;
|
||||
margin-left: 23px;
|
||||
}
|
||||
|
||||
::v-deep .el-input-number__decrease,
|
||||
::v-deep .el-input-number__increase {
|
||||
background: #133362;
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep .el-input__inner {
|
||||
background: #0c1641;
|
||||
}
|
||||
55
src/components/MyComponents/PackageSelect/index.vue
Normal file
55
src/components/MyComponents/PackageSelect/index.vue
Normal file
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="form-item-box zj-packageSelect-wrap" :style="{ width: width }">
|
||||
<el-select v-bind="$attrs" :model-value="modelValue" @change="hanlderSelect"
|
||||
:popper-class="selectOption.length > 20 ? 'nation-select' : ''" :placeholder="placeholder">
|
||||
<el-option v-for="item in selectOption" :key="item.dm" :label="item.zdmc" :value="item.dm">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { COMPONENT_WIDTH } from '@/constant';
|
||||
import { nextTick, onBeforeMount, ref } from "vue";
|
||||
import { getDictInfoByDictEnum } from "@/api/sysDict";
|
||||
const emits = defineEmits(["handleChange"]); //子组件向父组件事件传递
|
||||
const props = defineProps({
|
||||
//获取组件传值
|
||||
placeholder: {
|
||||
default: "请选择",
|
||||
type: String
|
||||
},
|
||||
modelValue: {
|
||||
default: "",
|
||||
type: String
|
||||
},
|
||||
dictEnum: {
|
||||
default: "",
|
||||
type: String
|
||||
},
|
||||
width: {
|
||||
default: COMPONENT_WIDTH,
|
||||
type: String
|
||||
}
|
||||
});
|
||||
const selectOption = ref([]);
|
||||
onBeforeMount(async () => {
|
||||
const res = await getDictInfoByDictEnum({ dictElementEnum: props.dictEnum });
|
||||
//正常下拉结构
|
||||
if (res.zdlx === 1) {
|
||||
selectOption.value = [...res.itemList];
|
||||
} else {
|
||||
//树形结构数据
|
||||
}
|
||||
});
|
||||
const hanlderSelect = (data) => {
|
||||
emits("handleChange", data);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.zj-packageSelect-wrap {
|
||||
::v-deep .el-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -3,8 +3,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { defineComponent, onMounted, onBeforeUnmount, ref, watch } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
@ -12,137 +12,141 @@ const props = defineProps({
|
||||
},
|
||||
color: {
|
||||
type: Array,
|
||||
default:() => []
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
const chartRef = ref(null)
|
||||
let chart = null
|
||||
});
|
||||
const chartRef = ref(null);
|
||||
let chart = null;
|
||||
|
||||
// 保存 resize 处理函数的引用
|
||||
const handleResize = () => {
|
||||
chart && chart.resize();
|
||||
};
|
||||
|
||||
const initChart = () => {
|
||||
if (!chartRef.value) return
|
||||
chart = echarts.init(chartRef.value)
|
||||
if (!chartRef.value) return;
|
||||
chart = echarts.init(chartRef.value);
|
||||
const option = {
|
||||
// backgroundColor: '#1a213c',
|
||||
tooltip: {
|
||||
formatter: '{b}: {c} ({d}%)',
|
||||
backgroundColor: 'rgba(0,0,0,0.7)',
|
||||
borderColor: '#1a213c',
|
||||
formatter: "{b}: {c} ({d}%)",
|
||||
backgroundColor: "rgba(0,0,0,0.7)",
|
||||
borderColor: "#1a213c",
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
color: "#fff"
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll', // 启用滚动图例
|
||||
selectedMode: 'multiple',
|
||||
orient: 'vertical',
|
||||
right: '0%',
|
||||
top: 'center',
|
||||
type: "scroll", // 启用滚动图例
|
||||
selectedMode: "multiple",
|
||||
orient: "vertical",
|
||||
right: "0%",
|
||||
top: "center",
|
||||
textStyle: {
|
||||
color: '#fff'
|
||||
color: "#fff"
|
||||
},
|
||||
formatter: function (name) {
|
||||
const data = option.series[0].data
|
||||
const total = data.reduce((sum, item) => sum + item.value, 0)
|
||||
const target = data.find(item => item.name === name)
|
||||
const percentage = ((target.value / total) * 100).toFixed(0)
|
||||
return `${name} ${target.value}`
|
||||
const data = option.series[0].data;
|
||||
const total = data.reduce((sum, item) => sum + item.value, 0);
|
||||
const target = data.find((item) => item.name === name);
|
||||
const percentage = ((target.value / total) * 100).toFixed(0);
|
||||
return `${name} ${target.value}`;
|
||||
},
|
||||
// 图例翻页配置
|
||||
pageIconColor: '#fff', // 翻页按钮颜色
|
||||
pageTextStyle: { color: '#fff' }, // 翻页文字颜色
|
||||
pageIconColor: "#fff", // 翻页按钮颜色
|
||||
pageTextStyle: { color: "#fff" }, // 翻页文字颜色
|
||||
pageIconSize: 12, // 翻页按钮大小
|
||||
pageButtonItemGap: 5, // 分页按钮之间的间距
|
||||
pageButtonGap: 10, // 分页按钮与图例项之间的间距
|
||||
pageIconInactiveColor: '#555', // 不激活的翻页按钮颜色
|
||||
pageButtonPosition: 'end' // 翻页按钮的位置
|
||||
pageIconInactiveColor: "#555", // 不激活的翻页按钮颜色
|
||||
pageButtonPosition: "end" // 翻页按钮的位置
|
||||
},
|
||||
series: [{
|
||||
type: 'pie',
|
||||
radius: ['30%', '55%'],
|
||||
center: ['40%', '50%'],
|
||||
roseType: false,
|
||||
zlevel: 10,
|
||||
startAngle: 35,
|
||||
selectedMode: 'single',
|
||||
selectedOffset: 10,
|
||||
data:[...props.data],
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{d}%',
|
||||
color: '#fff',
|
||||
position: 'outside',
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'self',
|
||||
scaleSize: 10,
|
||||
series: [
|
||||
{
|
||||
type: "pie",
|
||||
radius: ["30%", "55%"],
|
||||
center: ["40%", "50%"],
|
||||
roseType: false,
|
||||
zlevel: 10,
|
||||
startAngle: 35,
|
||||
selectedMode: "single",
|
||||
selectedOffset: 10,
|
||||
data: [...props.data],
|
||||
label: {
|
||||
show: true,
|
||||
formatter: "{d}%",
|
||||
color: "#fff",
|
||||
position: "outside",
|
||||
fontSize: 14,
|
||||
fontWeight: "bold"
|
||||
},
|
||||
emphasis: {
|
||||
focus: "self",
|
||||
scaleSize: 10,
|
||||
itemStyle: {
|
||||
shadowBlur: 20,
|
||||
shadowOffsetX: 5,
|
||||
shadowOffsetY: 5,
|
||||
shadowColor: "rgba(0, 0, 0, 0.5)"
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
shadowBlur: 20,
|
||||
shadowOffsetX: 5,
|
||||
shadowOffsetY: 5,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
borderRadius: 4,
|
||||
borderColor: "#1a213c",
|
||||
borderWidth: 2
|
||||
},
|
||||
// 启用全局动画控制器
|
||||
animation: true,
|
||||
// 关键:设置animationDelayUpdate确保数据更新时也有动画
|
||||
animationDelayUpdate: function (idx) {
|
||||
return idx * 300;
|
||||
},
|
||||
// 逐个显示的动画效果 - 改为从透明到不透明的过渡效果
|
||||
animationType: "opacity",
|
||||
animationEasing: "cubicOut",
|
||||
|
||||
// 关键:设置初始样式,让每个扇形从透明状态开始
|
||||
// 使用动画帧序列来控制动画过程
|
||||
animation: true,
|
||||
animationDuration: 1000,
|
||||
animationDelay: function (idx) {
|
||||
// 按照索引顺序依次显示,设置更明显的延迟
|
||||
return idx * 400;
|
||||
},
|
||||
|
||||
// 动画开始前的回调,确保动画效果
|
||||
animationBegin: function () {
|
||||
// 可以在这里进行额外的动画初始化
|
||||
return 0;
|
||||
},
|
||||
|
||||
// 动画帧序列,控制每个关键帧的样式
|
||||
animationFrame: function (idx, percent) {
|
||||
// percent参数是从0到1的动画进度
|
||||
return {
|
||||
opacity: percent,
|
||||
scale: 0.8 + percent * 0.2 // 从0.8放大到1
|
||||
};
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderRadius: 4,
|
||||
borderColor: '#1a213c',
|
||||
borderWidth: 2
|
||||
},
|
||||
// 启用全局动画控制器
|
||||
animation: true,
|
||||
// 关键:设置animationDelayUpdate确保数据更新时也有动画
|
||||
animationDelayUpdate: function (idx) {
|
||||
return idx * 300;
|
||||
},
|
||||
// 逐个显示的动画效果 - 改为从透明到不透明的过渡效果
|
||||
animationType: 'opacity',
|
||||
animationEasing: 'cubicOut',
|
||||
|
||||
// 关键:设置初始样式,让每个扇形从透明状态开始
|
||||
// 使用动画帧序列来控制动画过程
|
||||
animation: true,
|
||||
animationDuration: 1000,
|
||||
animationDelay: function (idx) {
|
||||
// 按照索引顺序依次显示,设置更明显的延迟
|
||||
return idx * 400;
|
||||
},
|
||||
|
||||
// 动画开始前的回调,确保动画效果
|
||||
animationBegin: function() {
|
||||
// 可以在这里进行额外的动画初始化
|
||||
return 0;
|
||||
},
|
||||
|
||||
// 动画帧序列,控制每个关键帧的样式
|
||||
animationFrame: function (idx, percent) {
|
||||
// percent参数是从0到1的动画进度
|
||||
return {
|
||||
opacity: percent,
|
||||
scale: 0.8 + percent * 0.2 // 从0.8放大到1
|
||||
};
|
||||
}
|
||||
}],
|
||||
media: [
|
||||
{
|
||||
query: { minAspectRatio: 1 },
|
||||
option: {
|
||||
series: [
|
||||
{ center: ['36%', '50%'] },
|
||||
|
||||
]
|
||||
],
|
||||
media: [
|
||||
{
|
||||
query: { minAspectRatio: 1 },
|
||||
option: {
|
||||
series: [{ center: ["36%", "50%"] }]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
chart.setOption(option);
|
||||
};
|
||||
|
||||
chart.setOption(option)
|
||||
}
|
||||
onMounted(() => {
|
||||
initChart()
|
||||
window.addEventListener('resize', () => {
|
||||
chart && chart.resize()
|
||||
})
|
||||
})
|
||||
initChart();
|
||||
window.addEventListener("resize", handleResize);
|
||||
});
|
||||
|
||||
// 监听数据变化,确保动画在数据更新时也能触发
|
||||
watch(
|
||||
@ -150,30 +154,21 @@ watch(
|
||||
(newData) => {
|
||||
if (chart && newData && newData.length > 0) {
|
||||
// 使用clear方法强制重新渲染并触发动画
|
||||
chart.clear()
|
||||
initChart()
|
||||
chart.clear();
|
||||
initChart();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
);
|
||||
|
||||
// 组件卸载时清理资源
|
||||
const cleanup = () => {
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
if (chart) {
|
||||
chart.dispose()
|
||||
chart = null
|
||||
chart.dispose();
|
||||
chart = null;
|
||||
}
|
||||
window.removeEventListener('resize', () => {
|
||||
chart && chart.resize()
|
||||
})
|
||||
}
|
||||
|
||||
// 组件卸载时执行清理
|
||||
onUnmounted(() => {
|
||||
cleanup()
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -1,45 +1,103 @@
|
||||
<template>
|
||||
<div class="form-item-box" :class="props.showBtn ? 'showBtn-upload' : ''" :style="{ width: width }">
|
||||
<div
|
||||
class="form-item-box"
|
||||
: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"
|
||||
:on-exceed="handleExceed"
|
||||
:on-success="handlerSuccess"
|
||||
:before-upload="beforeImgUpload">
|
||||
: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" :src="file.url || ''" alt="" />
|
||||
<img
|
||||
class="el-upload-list__item-thumbnail"
|
||||
:src="file.url || ''"
|
||||
alt=""
|
||||
/>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
||||
<span
|
||||
class="el-upload-list__item-preview"
|
||||
@click="handlePictureCardPreview(file)"
|
||||
>
|
||||
<el-icon> <zoom-in /></el-icon>
|
||||
</span>
|
||||
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file, fileList)">
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file, fileList)"
|
||||
>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 文件卡片模式 -->
|
||||
<div v-else>
|
||||
<div class="file-wrap">
|
||||
<span><svg-icon :icon="getSuffix(file.name)" /></span>
|
||||
<span class="file-name">{{ file.name }}</span>
|
||||
</div>
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleDownload(file)"
|
||||
>
|
||||
<el-icon><Download /></el-icon>
|
||||
</span>
|
||||
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file, fileList)">
|
||||
<span
|
||||
v-if="!disabled"
|
||||
class="el-upload-list__item-delete"
|
||||
@click="handleRemove(file, fileList)"
|
||||
>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</span>
|
||||
</span>
|
||||
@ -54,8 +112,17 @@
|
||||
|
||||
<script setup>
|
||||
import { COMPONENT_WIDTH } from "@/constant";
|
||||
import { ref, defineProps, defineEmits, computed, watch, onMounted, onUnmounted } from "vue";
|
||||
import {
|
||||
ref,
|
||||
defineProps,
|
||||
defineEmits,
|
||||
computed,
|
||||
watch,
|
||||
onMounted,
|
||||
onUnmounted
|
||||
} from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { saveAs } from "file-saver";
|
||||
import { useStore } from "vuex";
|
||||
const props = defineProps({
|
||||
//获取组件传值
|
||||
@ -98,35 +165,42 @@ const headers = ref({
|
||||
});
|
||||
const fileList = ref([]);
|
||||
|
||||
watch(() => props.modelValue,(val) => {
|
||||
let arr = val ? (Array.isArray(val) ? val :[val]): [];
|
||||
if(arr.length == 0 ) return fileList.value = [];
|
||||
fileList.value = arr.map((el) => {
|
||||
if (Object.prototype.toString.call(el) === "[object Object]") {
|
||||
// 确保file.url始终是字符串URL
|
||||
const fileUrl = props.isAll ? `/mosty-api/mosty-base/minio/image/download/` + el.id : el.url;
|
||||
return {
|
||||
...el,
|
||||
url: String(fileUrl || ''),
|
||||
name: el.name || '',
|
||||
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
url: String(`/mosty-api/mosty-base/minio/image/download/` + el || ''),
|
||||
id: el
|
||||
};
|
||||
}
|
||||
});
|
||||
console.log(fileList.value, "fileList.value");
|
||||
|
||||
},{ immediate: true,deep:true });
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
let arr = val ? (Array.isArray(val) ? val : [val]) : [];
|
||||
if (arr.length == 0) return (fileList.value = []);
|
||||
fileList.value = arr.map((el) => {
|
||||
if (Object.prototype.toString.call(el) === "[object Object]") {
|
||||
// 确保file.url始终是字符串URL
|
||||
const fileUrl = props.isAll
|
||||
? `/mosty-api/mosty-base/minio/image/download/` + el.id
|
||||
: el.url;
|
||||
return {
|
||||
...el,
|
||||
url: String(fileUrl || ""),
|
||||
name: el.name || ""
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
url: String(`/mosty-api/mosty-base/minio/image/download/` + el || ""),
|
||||
id: el,
|
||||
name: el
|
||||
};
|
||||
}
|
||||
});
|
||||
console.log(fileList.value, "fileList.value");
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
const actionUrl = computed(() => {
|
||||
if (props.isAll) {
|
||||
return "/mosty-api/mosty-base/minio/image/upload/id";
|
||||
} else {
|
||||
return props.isImg ? "/mosty-api/mosty-base/minio/image/upload/id": "/mosty-api/mosty-base/minio/file/uploadObj";
|
||||
return props.isImg
|
||||
? "/mosty-api/mosty-base/minio/image/upload/id"
|
||||
: "/mosty-api/mosty-base/minio/file/uploadObj";
|
||||
}
|
||||
});
|
||||
|
||||
@ -158,7 +232,17 @@ const getSuffix = (fileName) => {
|
||||
//pdf
|
||||
if (suffix === "pdf") return "PDF";
|
||||
//视频 音频
|
||||
var videolist = ["mp4","m2v","mkv","rmvb","wmv","avi","flv","mov","m4v"];
|
||||
var videolist = [
|
||||
"mp4",
|
||||
"m2v",
|
||||
"mkv",
|
||||
"rmvb",
|
||||
"wmv",
|
||||
"avi",
|
||||
"flv",
|
||||
"mov",
|
||||
"m4v"
|
||||
];
|
||||
if (videolist.includes(suffix)) return "VIDEO";
|
||||
var musiclist = ["mp3", "wav", "wmv"];
|
||||
if (musiclist.includes(suffix)) return "MUSIC";
|
||||
@ -177,19 +261,19 @@ const handlerSuccess = (res, file) => {
|
||||
file.url = `/mosty-api/mosty-base/minio/image/download/` + res.data;
|
||||
file.id = res.data;
|
||||
fileList.value.push(file);
|
||||
let arr = []
|
||||
if(props.isImg){
|
||||
arr = fileList.value.map((el) => el.id)
|
||||
let arr = [];
|
||||
if (props.isImg) {
|
||||
arr = fileList.value.map((el) => el.id);
|
||||
} else {
|
||||
console.log(fileList,"测试");
|
||||
console.log(fileList, "测试");
|
||||
arr = fileList.value.map((el) => {
|
||||
console.log(el,'xunhuan');
|
||||
console.log(el, "xunhuan");
|
||||
return {
|
||||
id: el.id, name: el.name
|
||||
}
|
||||
})
|
||||
console.log(arr,"测试2222");
|
||||
|
||||
id: el.id,
|
||||
name: el.name
|
||||
};
|
||||
});
|
||||
console.log(arr, "测试2222");
|
||||
}
|
||||
emits("update:modelValue", arr);
|
||||
};
|
||||
@ -201,7 +285,7 @@ const handleExceed = (files, fileList) => {
|
||||
const beforeImgUpload = (file) => {
|
||||
if (props.isImg) {
|
||||
let isIMG = false;
|
||||
if (getSuffix(file.name) === "IMG") isIMG = true;
|
||||
if (getSuffix(file.name) === "IMG") isIMG = true;
|
||||
const isLt5M = file.size / 1024 / 1024 < 5;
|
||||
if (!isIMG) ElMessage.error("上传图片只能是jpg/png/jpeg/bmp/gif格式!");
|
||||
if (!isLt5M) ElMessage.error("上传图片大小不能超过 5MB!");
|
||||
@ -212,28 +296,38 @@ const beforeImgUpload = (file) => {
|
||||
};
|
||||
//查询图片
|
||||
const handlePictureCardPreview = (file) => {
|
||||
dialogImageUrl.value = file.url || '';
|
||||
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) => {
|
||||
@ -247,7 +341,7 @@ const beforeRemove = (file) => {
|
||||
});
|
||||
props.modelValue.splice(index, 1);
|
||||
emits("update:modelValue", props.modelValue);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemove = (file) => {
|
||||
let index = fileList.value.findIndex(function (item) {
|
||||
@ -257,7 +351,6 @@ const handleRemove = (file) => {
|
||||
props.modelValue.splice(index, 1);
|
||||
emits("update:modelValue", props.modelValue);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -312,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>
|
||||
|
||||
@ -18,6 +18,7 @@ import MarkdownEdit from "./MarkdownEdit/index.vue";
|
||||
import FileUpload from "./FileUpload/index.vue";
|
||||
import Date from "./Date/index.vue";
|
||||
import Empty from "./Empty/index.vue";
|
||||
import PackageSelect from "./PackageSelect/index.vue";
|
||||
export {
|
||||
AddressSelect,
|
||||
FrameWork,
|
||||
@ -38,5 +39,6 @@ export {
|
||||
MarkdownEdit,
|
||||
FileUpload,
|
||||
Date,
|
||||
Empty
|
||||
Empty,
|
||||
PackageSelect
|
||||
};
|
||||
|
||||
@ -108,7 +108,7 @@ import {
|
||||
reactive,
|
||||
ref,
|
||||
watch,
|
||||
watchEffect
|
||||
shallowRef
|
||||
} from "vue";
|
||||
const props = defineProps({
|
||||
tableConfiger: {
|
||||
@ -200,10 +200,14 @@ let getConfiger = reactive({
|
||||
});
|
||||
const radioChoose = ref("");
|
||||
|
||||
watchEffect(() => {
|
||||
getConfiger = { ...getConfiger, ...props.tableConfiger };
|
||||
// 使用 watch 替代 watchEffect,避免无限循环
|
||||
// 只有当 tableConfiger 的 JSON 字符串表示变化时才触发
|
||||
watch(() => JSON.stringify(props.tableConfiger), () => {
|
||||
Object.keys(props.tableConfiger).forEach(key => {
|
||||
getConfiger[key] = props.tableConfiger[key];
|
||||
});
|
||||
setDefaultChoose();
|
||||
});
|
||||
}, { immediate: true });
|
||||
|
||||
onMounted(() => {
|
||||
setDefaultChoose();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-form ref="elform" :model="listQuery" :label-width="props.labelWidth" :rules="props.rules" :inline="props.inline" label-position="right" :disabled="props.disabled">
|
||||
|
||||
<el-form-item v-for="(item, idx) in props.formList" :style="item.width && { width: item.width }" :prop="item.prop" :label="item.label" :label-width="item.labelWidth" :key="idx">
|
||||
<el-form-item v-for="(item, idx) in props.formList" v-show="item.show !== false" :style="item.width && { width: item.width }" :prop="item.prop" :label="item.label" :label-width="item.labelWidth" :key="idx">
|
||||
<!-- input表单 input-->
|
||||
<MOSTY.Other v-if="item.type == 'input'" width="100%" clearable v-model="listQuery[item.prop]" :placeholder="`请输入${item.label}`" :disabled="item.disabled" :readonly="item.readonly" @blur="inputBlur($event,item)" />
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<el-input-number v-model="listQuery[item.prop]" v-else-if="item.type == 'number'" :step="item.step || 1" style="width: 100%" :min="item.min || 0" :max="item.max || 1000" :disabled="item.disabled" />
|
||||
|
||||
<!--选择 select-->
|
||||
<MOSTY.Select v-else-if="item.type == 'select'" filterable :multiple="item.multiple" v-model="listQuery[item.prop]" :dictEnum="item.options" width="100%" clearable :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
|
||||
<MOSTY.Select v-else-if="item.type == 'select'" :filterable="item.filterable" :multiple="item.multiple" v-model="listQuery[item.prop]" :dictEnum="item.options" width="100%" clearable :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
|
||||
|
||||
<!-- 部门department -->
|
||||
<template v-else-if="item.type === 'department'">
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, onMounted, reactive, ref, watch, watchEffect } from "vue";
|
||||
import { nextTick, onMounted, reactive, ref, watch, shallowRef } from "vue";
|
||||
const props = defineProps({
|
||||
tableConfiger: {
|
||||
type: Object,
|
||||
@ -117,10 +117,14 @@ let getConfiger = reactive({
|
||||
radioChoose: "", // 单选时选中的值------------- 待完成
|
||||
rowHeight: "41" // 每行的高度
|
||||
});
|
||||
watchEffect(() => {
|
||||
getConfiger = { ...getConfiger, ...props.tableConfiger };
|
||||
// 使用 watch 替代 watchEffect,避免无限循环
|
||||
// 只有当 tableConfiger 的 JSON 字符串表示变化时才触发
|
||||
watch(() => JSON.stringify(props.tableConfiger), () => {
|
||||
Object.keys(props.tableConfiger).forEach(key => {
|
||||
getConfiger[key] = props.tableConfiger[key];
|
||||
});
|
||||
setDefaultChoose();
|
||||
});
|
||||
}, { immediate: true });
|
||||
onMounted(() => {
|
||||
setDefaultChoose();
|
||||
});
|
||||
|
||||
553
src/components/aboutTable/Search copy.vue
Normal file
553
src/components/aboutTable/Search copy.vue
Normal file
@ -0,0 +1,553 @@
|
||||
<template>
|
||||
<div v-loading="loadingPage" class="pageSearch searchBox main-container"
|
||||
:style="`margin-bottom: ${marginBottom}px;background-color: ${backgroundColor}`">
|
||||
<div class="filter-title">
|
||||
<span class="filter-label"><el-icon>
|
||||
<Filter />
|
||||
</el-icon>筛选条件</span>
|
||||
</div>
|
||||
<div class="content-container">
|
||||
<div class="box">
|
||||
<div v-for="(item, index) in getArr" :key="index" class="item">
|
||||
<div class="label" v-if="item.label">{{ item.label }}</div>
|
||||
<!-- select -->
|
||||
<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>
|
||||
<el-option v-for="obj in getOptions[item.prop]" :key="obj.value" :label="obj.label || obj.lable"
|
||||
:value="obj.value" />
|
||||
</el-select>
|
||||
<!-- input -->
|
||||
<el-input v-else-if="item.showType === 'input'" class="input" v-model="searchObj[item.prop]"
|
||||
:clearable="item.clearable" :placeholder="item.placeholder" />
|
||||
<!-- input -->
|
||||
<el-input v-else-if="item.showType === 'number'" class="input" v-model="searchObj[item.prop]"
|
||||
:clearable="item.clearable" :placeholder="item.placeholder" type="number" />
|
||||
<!-- 日期段选择器 -->
|
||||
<el-date-picker v-else-if="item.showType === 'daterange'" v-model="searchObj[item.prop]" type="daterange"
|
||||
unlink-panels :range-separator="item.rangeSeparator" :start-placeholder="item.startPlaceholder"
|
||||
:end-placeholder="item.endPlaceholder" :shortcuts="item.shortcuts" :disabledDate="disabledDate"
|
||||
value-format="YYYY-MM-DD" />
|
||||
<el-date-picker v-else-if="item.showType === 'datetimerange'" v-model="searchObj[item.prop]"
|
||||
type="datetimerange" unlink-panels :range-separator="item.rangeSeparator || '至'"
|
||||
:start-placeholder="item.startPlaceholder || '开始日期'" :end-placeholder="item.endPlaceholder || '结束日期'"
|
||||
:shortcuts="item.shortcuts" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||
<el-date-picker v-else-if="item.showType === 'date'" v-model="searchObj[item.prop]" type="date"
|
||||
:placeholder="item.placeholder" :disabled-date="disabledDate" :shortcuts="item.shortcuts"
|
||||
value-format="YYYY-MM-DD">
|
||||
</el-date-picker>
|
||||
<el-date-picker v-else-if="item.showType === 'datetime'" v-model="searchObj[item.prop]" type="datetime"
|
||||
:placeholder="item.placeholder" value-format="YYYY-MM-DD HH:mm:ss">
|
||||
</el-date-picker>
|
||||
|
||||
<!-- checkbox -->
|
||||
<template v-else-if="item.showType === 'department'">
|
||||
<MOSTY.Department clearable v-model="searchObj[item.prop]" />
|
||||
</template>
|
||||
<!-- checkbox -->
|
||||
<template v-else-if="item.showType === 'checkbox'">
|
||||
<el-checkbox v-if="item.showSelectAll" v-model="item.checkAll" :indeterminate="item.isIndeterminate"
|
||||
@change="
|
||||
(val) => {
|
||||
handleCheckAllChange(val, item);
|
||||
}
|
||||
">全选</el-checkbox>
|
||||
<el-checkbox-group v-model="searchObj[item.prop]" @change="
|
||||
(val) => {
|
||||
handleCheckedCitiesChange(val, item);
|
||||
}
|
||||
">
|
||||
<el-checkbox v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</template>
|
||||
<!-- radio -->
|
||||
<el-radio-group v-else-if="item.showType === 'radio'" v-model="searchObj[item.prop]" @change="
|
||||
(val) => {
|
||||
handleRadioChange(val, item);
|
||||
}
|
||||
">
|
||||
<el-radio v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 级联选择 -->
|
||||
<el-cascader v-else-if="item.showType === 'cascader'" v-model="searchObj[item.prop]" :props="item.props"
|
||||
:show-all-levels="item.showAllLevels" :clearable="item.clearable" :options="getOptions[item.prop]"
|
||||
:placeholder="item.placeholder" />
|
||||
<div v-if="item.showType === 'Slot'">
|
||||
<slot :name="item.prop"></slot>
|
||||
</div>
|
||||
<div v-if="item.showType === 'defaultSlot'">
|
||||
<slot name="defaultSlot"></slot>
|
||||
</div>
|
||||
<div v-if="item.showType === 'nameSlot'">
|
||||
<slot name="nameSlot"></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<div class="flex">
|
||||
<el-button type="primary" @click="submit" size="small">确定</el-button>
|
||||
<el-button type="" @click="reset" size="small">重置</el-button>
|
||||
<slot> </slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
watchEffect,
|
||||
getCurrentInstance,
|
||||
watch,
|
||||
computed
|
||||
} from "vue";
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const props = defineProps({
|
||||
searchArr: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [
|
||||
{
|
||||
showType: "select",
|
||||
prop: "selectKey",
|
||||
options: [
|
||||
{
|
||||
value: 1,
|
||||
label: "选择1"
|
||||
}
|
||||
],
|
||||
defaultVal: "",
|
||||
label: "选择",
|
||||
dict: "" // 字典编码
|
||||
},
|
||||
{
|
||||
showType: "input",
|
||||
prop: "inputKey",
|
||||
defaultVal: "",
|
||||
label: "输入"
|
||||
},
|
||||
{
|
||||
showType: "department",
|
||||
prop: "deptKey",
|
||||
defaultVal: "",
|
||||
label: "输入"
|
||||
},
|
||||
{
|
||||
showType: "daterange",
|
||||
prop: "daterangeKey",
|
||||
defaultVal: "",
|
||||
label: "输入"
|
||||
},
|
||||
{
|
||||
showType: "date",
|
||||
prop: "date",
|
||||
defaultVal: ""
|
||||
},
|
||||
{
|
||||
showType: "checkbox",
|
||||
prop: "checkboxKey1",
|
||||
options: [
|
||||
{
|
||||
value: 1,
|
||||
label: "选择1"
|
||||
}
|
||||
],
|
||||
defaultVal: ""
|
||||
},
|
||||
{
|
||||
showType: "cascader",
|
||||
prop: "cascaderKey",
|
||||
label: "级联选择",
|
||||
checkStrictly: false, //点击任意选中
|
||||
defaultVal: ""
|
||||
},
|
||||
{
|
||||
showType: "radio",
|
||||
defaultVal: ""
|
||||
},
|
||||
{
|
||||
showType: "defaultTime",
|
||||
prop: "timeField",
|
||||
options: []
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
marginBottom: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: "rgb(255, 255, 255, 1)"
|
||||
},
|
||||
bool: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
});
|
||||
let loadingPage = ref(false);
|
||||
const emit = defineEmits(["submit", "reset"]);
|
||||
let searchObj = reactive({});
|
||||
|
||||
// select 的一些默认配置
|
||||
const selectDefault = {
|
||||
clearable: true, // 是否可以清空
|
||||
filterable: true, // 是否可以筛选
|
||||
multiple: false, // 是否多选
|
||||
placeholder: "请选择"
|
||||
};
|
||||
// 重新定义下拉框的选项
|
||||
let getOptions = reactive({});
|
||||
// input 的一些默认配置
|
||||
const inputDefault = {
|
||||
clearable: true, // 是否可以清空
|
||||
placeholder: "请输入"
|
||||
};
|
||||
const shortcuts = [
|
||||
{
|
||||
text: "今天",
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 0);
|
||||
return [start, end];
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "昨天",
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
|
||||
end.setTime(end.getTime() - 3600 * 1000 * 24 * 1);
|
||||
return [start, end];
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "最近7天",
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||||
return [start, end];
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "最近30天",
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||
return [start, end];
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "最近90天",
|
||||
value: () => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||
return [start, end];
|
||||
}
|
||||
}
|
||||
];
|
||||
// daterange 的一些默认配置
|
||||
const daterangeDefault = {
|
||||
rangeSeparator: "至",
|
||||
startPlaceholder: "开始日期",
|
||||
endPlaceholder: "结束日期",
|
||||
shortcuts: [], // 快捷选择
|
||||
defaultShortcuts: true // 是否显示快捷选择 如果要自定义快捷选择传入一个shortcuts就可以了
|
||||
};
|
||||
// date 的一些默认配置
|
||||
const defaultDate = {
|
||||
clearable: true, // 是否可以清空
|
||||
placeholder: "请输入",
|
||||
shortcuts: [], // 快捷选择
|
||||
defaultShortcuts: true // 是否显示快捷选择 如果要自定义快捷选择传入一个shortcuts就可以了
|
||||
};
|
||||
const dateShortcuts = [
|
||||
{
|
||||
text: "今天",
|
||||
value: new Date()
|
||||
},
|
||||
{
|
||||
text: "昨天",
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() - 3600 * 1000 * 24);
|
||||
return date;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "7天前",
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
|
||||
return date;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "30天前",
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() - 3600 * 1000 * 24 * 30);
|
||||
return date;
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "90天前",
|
||||
value: () => {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() - 3600 * 1000 * 24 * 90);
|
||||
return date;
|
||||
}
|
||||
}
|
||||
];
|
||||
// 设置不可选的日期
|
||||
const disabledDate = (time) => {
|
||||
return time.getTime() > Date.now();
|
||||
};
|
||||
// checkbox 的一些默认配置
|
||||
const defaultCheckbox = reactive({
|
||||
defaultVal: [],
|
||||
checkAll: false, // 全选的值
|
||||
isIndeterminate: false, // 控制全选按钮样式
|
||||
showSelectAll: true // 是否显示全选
|
||||
});
|
||||
// 全选复选框的选中与不选中
|
||||
const handleCheckAllChange = (val, obj) => {
|
||||
searchObj[obj.prop] = val ? obj.checkboxValueArr : [];
|
||||
obj.isIndeterminate = false;
|
||||
};
|
||||
// 单个复选框的选中与不选中
|
||||
const handleCheckedCitiesChange = (value, obj) => {
|
||||
const checkedCount = value.length;
|
||||
obj.checkAll = checkedCount === obj.checkboxValueArr.length;
|
||||
obj.isIndeterminate =
|
||||
checkedCount > 0 && checkedCount < obj.checkboxValueArr.length;
|
||||
};
|
||||
//单选
|
||||
const handleRadioChange = (val, obj) => {
|
||||
console.log(val, obj);
|
||||
};
|
||||
// cascader 的一些默认配置
|
||||
let defaultCascader = {
|
||||
filterable: true, // 是否可以搜索
|
||||
clearable: true, // 是否可以清空
|
||||
placeholder: "请选择",
|
||||
checkStrictly: true, // 控制是否父子联动(是否可以选择任意节点)
|
||||
showAllLevels: false, // 是否显示完整路径
|
||||
lazy: false, // 是否懒加载 当设置为false时就要传入options
|
||||
portUrl: "", // 这里必须写 接口地址
|
||||
props: {
|
||||
label: "label",
|
||||
value: "value",
|
||||
children: "children"
|
||||
},
|
||||
options: []
|
||||
};
|
||||
// 在懒加载状态下cascader 的props的一些配置
|
||||
const cascaderLazyProps = reactive({
|
||||
value: "value",
|
||||
label: "label",
|
||||
lazy: false,
|
||||
lazyLoad(node, resolve) {
|
||||
// 这里要根据实际情况修改
|
||||
const { level } = node;
|
||||
let options = [];
|
||||
switch (level) {
|
||||
case 0:
|
||||
options = [
|
||||
{
|
||||
value: 1,
|
||||
label: "选择1",
|
||||
leaf: false // 表示有下一级 必须有这个表示 不然获取不到值
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: "选择2",
|
||||
leaf: false // 表示有下一级
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: "选择3",
|
||||
leaf: false // 表示有下一级
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: "选择4",
|
||||
leaf: true // 表示没有下一级了
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 1:
|
||||
options = [
|
||||
{
|
||||
value: 11,
|
||||
label: "选择1_1",
|
||||
leaf: true // 表示没有下一级了
|
||||
},
|
||||
{
|
||||
value: 21,
|
||||
label: "选择2_1",
|
||||
leaf: true // 表示没有下一级了
|
||||
},
|
||||
{
|
||||
value: 31,
|
||||
label: "选择3_1",
|
||||
leaf: true // 表示没有下一级了
|
||||
},
|
||||
{
|
||||
value: 41,
|
||||
label: "选择4_1",
|
||||
leaf: true // 表示没有下一级了
|
||||
}
|
||||
];
|
||||
}
|
||||
resolve(options);
|
||||
}
|
||||
});
|
||||
// 获取到传过来的参数
|
||||
let getArr = reactive([]);
|
||||
const submit = () => {
|
||||
emit("submit", searchObj);
|
||||
};
|
||||
const reset = () => {
|
||||
getArr.forEach((item) => {
|
||||
searchObj[item.prop] = item.defaultVal;
|
||||
});
|
||||
emit("reset", true);
|
||||
emit("submit", searchObj);
|
||||
};
|
||||
|
||||
// 暴露searchObj给父组件
|
||||
defineExpose({
|
||||
searchObj,
|
||||
submit,
|
||||
reset
|
||||
});
|
||||
watchEffect(() => {
|
||||
loadingPage.value = true;
|
||||
let arr = JSON.parse(JSON.stringify(props.searchArr));
|
||||
getArr = arr.map((item) => {
|
||||
switch (item.showType) {
|
||||
case "select":
|
||||
item = { ...selectDefault, ...item };
|
||||
item.options = reactive(item.options);
|
||||
getOptions[item.prop] = item.options;
|
||||
break;
|
||||
case "input":
|
||||
item = { ...inputDefault, ...item };
|
||||
break;
|
||||
case "daterange":
|
||||
item = { ...daterangeDefault, ...item };
|
||||
if (item.defaultShortcuts) item.shortcuts = shortcuts;
|
||||
break;
|
||||
case "date":
|
||||
item = { ...defaultDate, ...item };
|
||||
if (item.defaultShortcuts) {
|
||||
item.shortcuts = dateShortcuts;
|
||||
}
|
||||
break;
|
||||
case "checkbox":
|
||||
item = reactive({ ...defaultCheckbox, ...item });
|
||||
item.checkboxValueArr = item.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;
|
||||
} else {
|
||||
item.props = {
|
||||
...defaultCascader.props,
|
||||
...(item.props || {}),
|
||||
...{ checkStrictly: item.checkStrictly }
|
||||
};
|
||||
getOptions[item.prop] = reactive(item.options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
loadingPage.value = false;
|
||||
searchObj[item.prop] = item.defaultVal;
|
||||
return item;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pageSearch {
|
||||
.main-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
display: flex;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
|
||||
padding: 5px 15px;
|
||||
|
||||
.filter-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
margin-right: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-line {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background-color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
flex: 1;
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin: auto;
|
||||
margin-right: 5px;
|
||||
white-space: nowrap;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-date-editor .el-range-separator {
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
@ -1,77 +1,74 @@
|
||||
<template>
|
||||
<div v-loading="loadingPage" class="pageSearch searchBox main-container"
|
||||
:style="`margin-bottom: ${marginBottom}px;background-color: ${backgroundColor}`">
|
||||
<div class="filter-title">
|
||||
<span class="filter-label"><el-icon>
|
||||
<Filter />
|
||||
</el-icon>筛选条件</span>
|
||||
</div>
|
||||
<div class="content-container">
|
||||
<div class="box">
|
||||
<div v-for="(item, index) in getArr" :key="index" class="item">
|
||||
<div class="label" v-if="item.label">{{ item.label }}</div>
|
||||
<div v-loading="loadingPage" class="query-wrap">
|
||||
<div class="query-title">查询条件</div>
|
||||
<div class="query-grid">
|
||||
<div v-for="(item, index) in getArr" :key="index" class="query-cell">
|
||||
<div class="cell-label">{{ item.label }}</div>
|
||||
<div class="cell-control">
|
||||
<!-- select -->
|
||||
<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>
|
||||
<el-option v-for="obj in getOptions[item.prop]" :key="obj.value" :label="obj.label || obj.lable"
|
||||
collapse-tags-tooltip class="control-select">
|
||||
<el-option v-for="obj in (getOptions[item.prop] || [])" :key="obj.value" :label="obj.label || obj.lable"
|
||||
:value="obj.value" />
|
||||
</el-select>
|
||||
<!-- input -->
|
||||
<el-input v-else-if="item.showType === 'input'" class="input" v-model="searchObj[item.prop]"
|
||||
:clearable="item.clearable" :placeholder="item.placeholder" />
|
||||
<!-- input -->
|
||||
<el-input v-else-if="item.showType === 'number'" class="input" v-model="searchObj[item.prop]"
|
||||
<el-input v-else-if="item.showType === 'input'" class="control-input" v-model="searchObj[item.prop]"
|
||||
:clearable="item.clearable" :placeholder="item.placeholder" />
|
||||
<!-- input -->
|
||||
<el-input v-else-if="item.showType === 'number'" class="control-input" v-model="searchObj[item.prop]"
|
||||
:clearable="item.clearable" :placeholder="item.placeholder" type="number" />
|
||||
<!-- 日期段选择器 -->
|
||||
<el-date-picker v-else-if="item.showType === 'daterange'" v-model="searchObj[item.prop]" type="daterange"
|
||||
unlink-panels :range-separator="item.rangeSeparator" :start-placeholder="item.startPlaceholder"
|
||||
:end-placeholder="item.endPlaceholder" :shortcuts="item.shortcuts" :disabledDate="disabledDate"
|
||||
value-format="YYYY-MM-DD" />
|
||||
value-format="YYYY-MM-DD" class="control-date" />
|
||||
<el-date-picker v-else-if="item.showType === 'datetimerange'" v-model="searchObj[item.prop]"
|
||||
type="datetimerange" unlink-panels :range-separator="item.rangeSeparator || '至'"
|
||||
:start-placeholder="item.startPlaceholder || '开始日期'" :end-placeholder="item.endPlaceholder || '结束日期'"
|
||||
:shortcuts="item.shortcuts" value-format="YYYY-MM-DD HH:mm:ss" />
|
||||
:shortcuts="item.shortcuts" value-format="YYYY-MM-DD HH:mm:ss" class="control-date" />
|
||||
<el-date-picker v-else-if="item.showType === 'date'" v-model="searchObj[item.prop]" type="date"
|
||||
:placeholder="item.placeholder" :disabled-date="disabledDate" :shortcuts="item.shortcuts"
|
||||
value-format="YYYY-MM-DD">
|
||||
value-format="YYYY-MM-DD" class="control-date">
|
||||
</el-date-picker>
|
||||
<el-date-picker v-else-if="item.showType === 'datetime'" v-model="searchObj[item.prop]" type="datetime"
|
||||
:placeholder="item.placeholder" value-format="YYYY-MM-DD HH:mm:ss">
|
||||
:placeholder="item.placeholder" value-format="YYYY-MM-DD HH:mm:ss" class="control-date">
|
||||
</el-date-picker>
|
||||
|
||||
<!-- checkbox -->
|
||||
<template v-else-if="item.showType === 'department'">
|
||||
<MOSTY.Department clearable v-model="searchObj[item.prop]" />
|
||||
<MOSTY.Department clearable v-model="searchObj[item.prop]" class="control-select" />
|
||||
</template>
|
||||
<!-- checkbox -->
|
||||
<template v-else-if="item.showType === 'checkbox'">
|
||||
<el-checkbox v-if="item.showSelectAll" v-model="item.checkAll" :indeterminate="item.isIndeterminate"
|
||||
@change="
|
||||
<div class="checkbox-wrap">
|
||||
<el-checkbox v-if="item.showSelectAll" v-model="item.checkAll" :indeterminate="item.isIndeterminate"
|
||||
@change="
|
||||
(val) => {
|
||||
handleCheckAllChange(val, item);
|
||||
}
|
||||
">全选</el-checkbox>
|
||||
<el-checkbox-group v-model="searchObj[item.prop]" @change="
|
||||
(val) => {
|
||||
handleCheckAllChange(val, item);
|
||||
handleCheckedCitiesChange(val, item);
|
||||
}
|
||||
">全选</el-checkbox>
|
||||
<el-checkbox-group v-model="searchObj[item.prop]" @change="
|
||||
(val) => {
|
||||
handleCheckedCitiesChange(val, item);
|
||||
}
|
||||
">
|
||||
<el-checkbox v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
" class="checkbox-group">
|
||||
<el-checkbox v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</template>
|
||||
<!-- radio -->
|
||||
<el-radio-group v-else-if="item.showType === 'radio'" v-model="searchObj[item.prop]" @change="
|
||||
(val) => {
|
||||
handleRadioChange(val, item);
|
||||
}
|
||||
">
|
||||
" class="radio-group">
|
||||
<el-radio v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 级联选择 -->
|
||||
<el-cascader v-else-if="item.showType === 'cascader'" v-model="searchObj[item.prop]" :props="item.props"
|
||||
:show-all-levels="item.showAllLevels" :clearable="item.clearable" :options="getOptions[item.prop]"
|
||||
:placeholder="item.placeholder" />
|
||||
:placeholder="item.placeholder" class="control-select" />
|
||||
<div v-if="item.showType === 'Slot'">
|
||||
<slot :name="item.prop"></slot>
|
||||
</div>
|
||||
@ -82,16 +79,16 @@
|
||||
<slot name="nameSlot"></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<div class="flex">
|
||||
<el-button type="primary" @click="submit" size="small">确定</el-button>
|
||||
<el-button type="" @click="reset" size="small">重置</el-button>
|
||||
<slot> </slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="query-action">
|
||||
<div>
|
||||
<slot> </slot>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" @click="submit" size="small">查询</el-button>
|
||||
<el-button type="default" @click="reset" size="small">重置</el-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -415,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);
|
||||
@ -433,121 +430,228 @@ defineExpose({
|
||||
submit,
|
||||
reset
|
||||
});
|
||||
watchEffect(() => {
|
||||
// 监听 searchArr 变化,同时监听内部 options 的异步更新
|
||||
watch(() => props.searchArr, (newArr) => {
|
||||
loadingPage.value = true;
|
||||
let arr = JSON.parse(JSON.stringify(props.searchArr));
|
||||
getArr = arr.map((item) => {
|
||||
switch (item.showType) {
|
||||
case "select":
|
||||
item = { ...selectDefault, ...item };
|
||||
item.options = reactive(item.options);
|
||||
getOptions[item.prop] = item.options;
|
||||
break;
|
||||
case "input":
|
||||
item = { ...inputDefault, ...item };
|
||||
break;
|
||||
case "daterange":
|
||||
item = { ...daterangeDefault, ...item };
|
||||
if (item.defaultShortcuts) item.shortcuts = shortcuts;
|
||||
break;
|
||||
case "date":
|
||||
item = { ...defaultDate, ...item };
|
||||
if (item.defaultShortcuts) {
|
||||
item.shortcuts = dateShortcuts;
|
||||
}
|
||||
break;
|
||||
case "checkbox":
|
||||
item = reactive({ ...defaultCheckbox, ...item });
|
||||
item.checkboxValueArr = item.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;
|
||||
} else {
|
||||
item.props = {
|
||||
...defaultCascader.props,
|
||||
...(item.props || {}),
|
||||
...{ checkStrictly: item.checkStrictly }
|
||||
};
|
||||
getOptions[item.prop] = reactive(item.options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
try {
|
||||
// 不再深拷贝,保留响应式引用
|
||||
getArr.value = newArr.map((item) => {
|
||||
const itemCopy = { ...item }; // 浅拷贝即可
|
||||
switch (itemCopy.showType) {
|
||||
case "select":
|
||||
Object.assign(itemCopy, { ...selectDefault, ...itemCopy });
|
||||
// 直接引用原 options,保持响应式
|
||||
getOptions[itemCopy.prop] = itemCopy.options || [];
|
||||
break;
|
||||
case "input":
|
||||
Object.assign(itemCopy, { ...inputDefault, ...itemCopy });
|
||||
break;
|
||||
case "daterange":
|
||||
Object.assign(itemCopy, { ...daterangeDefault, ...itemCopy });
|
||||
if (itemCopy.defaultShortcuts) itemCopy.shortcuts = shortcuts;
|
||||
break;
|
||||
case "date":
|
||||
Object.assign(itemCopy, { ...defaultDate, ...itemCopy });
|
||||
if (itemCopy.defaultShortcuts) {
|
||||
itemCopy.shortcuts = dateShortcuts;
|
||||
}
|
||||
break;
|
||||
case "checkbox":
|
||||
Object.assign(itemCopy, { ...defaultCheckbox, ...itemCopy });
|
||||
itemCopy.checkboxValueArr = (itemCopy.options || []).map((obj) => {
|
||||
return obj.value;
|
||||
});
|
||||
break;
|
||||
case "cascader":
|
||||
Object.assign(itemCopy, { ...defaultCascader, ...itemCopy });
|
||||
if (itemCopy.lazy) {
|
||||
cascaderLazyProps.checkStrictly = itemCopy.checkStrictly;
|
||||
itemCopy.props = { ...cascaderLazyProps, ...(itemCopy.props || {}) };
|
||||
delete itemCopy.options;
|
||||
} else {
|
||||
itemCopy.props = {
|
||||
...defaultCascader.props,
|
||||
...(itemCopy.props || {}),
|
||||
...{ checkStrictly: itemCopy.checkStrictly }
|
||||
};
|
||||
getOptions[itemCopy.prop] = itemCopy.options || [];
|
||||
}
|
||||
break;
|
||||
}
|
||||
searchObj[itemCopy.prop] = itemCopy.defaultVal;
|
||||
return itemCopy;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Search组件解析searchArr失败:', e);
|
||||
} finally {
|
||||
loadingPage.value = false;
|
||||
searchObj[item.prop] = item.defaultVal;
|
||||
return item;
|
||||
});
|
||||
});
|
||||
}
|
||||
}, { immediate: true, deep: true }); // 开启深度监听,检测 options 变化
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pageSearch {
|
||||
.main-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
display: flex;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
|
||||
padding: 5px 15px;
|
||||
|
||||
.filter-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
margin-right: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filter-line {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background-color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
flex: 1;
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin: auto;
|
||||
margin-right: 5px;
|
||||
white-space: nowrap;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
<style scoped lang="scss">
|
||||
.query-wrap {
|
||||
border: 1px solid #b8d3ff;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-date-editor .el-range-separator {
|
||||
color: #333;
|
||||
.query-title {
|
||||
height: 32px;
|
||||
background: linear-gradient(to right, #9ed7ff, #e6f0f8);
|
||||
line-height: 32px;
|
||||
padding-left: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #0d2148;
|
||||
border-bottom: 1px solid #b8d3ff;
|
||||
}
|
||||
|
||||
.query-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.query-cell {
|
||||
display: flex;
|
||||
min-height: 40px;
|
||||
border-right: 1px solid #b8d3ff;
|
||||
border-bottom: 1px solid #b8d3ff;
|
||||
}
|
||||
|
||||
.query-cell:nth-child(4n) {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.cell-label {
|
||||
width: 130px;
|
||||
flex-shrink: 0;
|
||||
border-right: 1px solid #b8d3ff;
|
||||
font-size: 14px;
|
||||
color: #0d2148;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.cell-control {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 4px 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell-control.is-checkbox {
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.control-input,
|
||||
.control-select,
|
||||
.control-date {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.control-input .el-input__wrapper),
|
||||
:deep(.control-select .el-select__wrapper),
|
||||
:deep(.control-date .el-input__wrapper) {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-height: 28px;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 0 0 1px #b8d3ff inset;
|
||||
}
|
||||
|
||||
:deep(.control-date.el-date-editor) {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.control-date.el-date-editor .el-range-input) {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.control-input .el-input__inner),
|
||||
:deep(.control-select .el-select__placeholder),
|
||||
:deep(.control-date .el-input__inner) {
|
||||
font-size: 14px;
|
||||
color: #0d2148;
|
||||
}
|
||||
|
||||
:deep(.control-date .el-range-input) {
|
||||
font-size: 14px;
|
||||
color: #0d2148;
|
||||
}
|
||||
|
||||
:deep(.control-date .el-range__icon),
|
||||
:deep(.control-date .el-range__close-icon) {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.checkbox-wrap {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
:deep(.checkbox-wrap .el-checkbox) {
|
||||
margin-right: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.checkbox-wrap .el-checkbox__inner) {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.query-action {
|
||||
height: 36px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
:deep(.el-button--primary) {
|
||||
background-color: #0f5bbd;
|
||||
border-color: #0f5bbd;
|
||||
}
|
||||
|
||||
:deep(.el-button--primary:hover) {
|
||||
background-color: #1a73e8;
|
||||
border-color: #1a73e8;
|
||||
}
|
||||
|
||||
:deep(.el-button--default) {
|
||||
background-color: #ffffff;
|
||||
border-color: #dcdfe6;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
:deep(.el-button--default:hover) {
|
||||
color: #409eff;
|
||||
border-color: #c6e2ff;
|
||||
background-color: #ecf5ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -26,6 +26,7 @@ const checkAll = ref(false);
|
||||
const isIndeterminate = ref(true);
|
||||
const hasChecked = ref([]); //已经全选的数据
|
||||
const checkedList = ref([]);
|
||||
const isInit = ref(true); // 标记是否为初始化
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
@ -38,16 +39,28 @@ watch(
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
// 监听hasChecked变化,初始化完成后才触发changeData
|
||||
watch(
|
||||
hasChecked,
|
||||
(val) => {
|
||||
if (isInit.value) {
|
||||
isInit.value = false;
|
||||
return;
|
||||
}
|
||||
emits("changeData", val);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
// 全选
|
||||
function handleCheckAll(val) {
|
||||
hasChecked.value = val ? checkedList.value : [];
|
||||
isIndeterminate.value = false;
|
||||
emits("changeData", hasChecked.value);
|
||||
// emits 由 watch 处理
|
||||
}
|
||||
// 处理多选框改变
|
||||
function handleCheckedChange(val) {
|
||||
handleChange(val);////判断是否全选
|
||||
emits("changeData", hasChecked.value);
|
||||
// emits 由 watch 处理
|
||||
}
|
||||
//判断是否全选
|
||||
function handleChange(val) {
|
||||
|
||||
@ -17,147 +17,201 @@
|
||||
|
||||
<script setup>
|
||||
// 测试div组件,用于在后台和大屏页面都显示
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
import emitter from "@/utils/eventBus.js"; // 导入事件总线
|
||||
import { qcckGet } from '@/api/qcckApi'
|
||||
import Item from './item.vue'
|
||||
import { AudioPlayerClass } from '@/utils/audioPlayer.js'
|
||||
import {getItem} from '@/utils/storage.js'
|
||||
const dataList = ref([])
|
||||
const timekeeping = ref(null)
|
||||
const countdown = ref(0) // 倒计时时间(秒)
|
||||
import { qcckGet } from "@/api/qcckApi";
|
||||
import Item from "./item.vue";
|
||||
import { AudioPlayerClass } from "@/utils/audioPlayer.js";
|
||||
import { getItem } from "@/utils/storage.js";
|
||||
const dataList = ref([]);
|
||||
const timekeeping = ref(null);
|
||||
const countdown = ref(0); // 倒计时时间(秒)
|
||||
|
||||
// 音频播放器实例映射
|
||||
const audioPlayers = ref({
|
||||
'02': null, // 信息上报
|
||||
'03': null, // 研判审批
|
||||
'04': null, // 研判指令
|
||||
'05': null // 线索下发
|
||||
})
|
||||
const audioPlayers = new Map();
|
||||
|
||||
// 预加载音频播放器(仅加载 playAudioByType 中实际用到的类型)
|
||||
const initAudioPlayers = async () => {
|
||||
const usedTypes = ["03", "09", "10", "11", "12", "13", "16", "17", "18", "19"];
|
||||
await Promise.all(
|
||||
usedTypes.map(
|
||||
(type) =>
|
||||
new Promise((resolve) => {
|
||||
const player = new AudioPlayerClass();
|
||||
audioPlayers.set(type, player);
|
||||
player.init(audioPaths[type], false).then(resolve).catch(resolve);
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
// 获取指定类型的音频播放器
|
||||
const getAudioPlayer = (type) => {
|
||||
return audioPlayers.get(type);
|
||||
};
|
||||
|
||||
// 音频文件路径映射
|
||||
const audioPaths = {
|
||||
'02': require('@/assets/images/cjyp.mp3'),
|
||||
'03': require('@/assets/images/ypbg.mp3'),
|
||||
'04': require('@/assets/images/ypzl.mp3'),
|
||||
'05': require('@/assets/images/xsyp.mp3')
|
||||
}
|
||||
|
||||
// 初始化音频播放器
|
||||
const initAudioPlayers = () => {
|
||||
Object.keys(audioPaths).forEach(type => {
|
||||
try {
|
||||
audioPlayers.value[type] = new AudioPlayerClass()
|
||||
audioPlayers.value[type].init(audioPaths[type], false)
|
||||
} catch (error) {
|
||||
console.error(`初始化类型${type}的音频播放器失败:`, error)
|
||||
}
|
||||
})
|
||||
}
|
||||
"01": require("@/assets/images/01.mp3"), //高级预计信息前置
|
||||
"02": require("@/assets/images/02.mp3"), //一般预警信息前置
|
||||
"03": require("@/assets/images/03.mp3"), //信息前置
|
||||
"04": require("@/assets/images/04.mp3"), //红色预警
|
||||
"05": require("@/assets/images/05.mp3"), //新的重点人
|
||||
"06": require("@/assets/images/06.mp3"), //一级临控预警
|
||||
"07": require("@/assets/images/07.mp3"), //有新的布控预警情
|
||||
"08": require("@/assets/images/08.mp3"), //有新的标签预警
|
||||
"09": require("@/assets/images/09.mp3"), //信息汇聚系统有新信息
|
||||
"10": require("@/assets/images/10.mp3"), //林安码
|
||||
"11": require("@/assets/images/11.mp3"), //发布了新的"线索"
|
||||
"12": require("@/assets/images/12.mp3"), //有新的研判指令
|
||||
"13": require("@/assets/images/13.mp3"), //有新的研判约稿通知
|
||||
"14": require("@/assets/images/14.mp3"), //有新的公文发布
|
||||
"15": require("@/assets/images/15.mp3"), //有新的警情监测预警,请注意查收
|
||||
"16": require("@/assets/images/16.mp3"), //有新的一级临控预警,请及时签收处理!
|
||||
"17": require("@/assets/images/17.mp3"), //有新的紧急预警信息,请及时签收处理!
|
||||
"18": require("@/assets/images/18.mp3"), //滴滴滴~~~叮~~~~
|
||||
"19": require("@/assets/images/19.mp3") //有新的预警信息,请您注意查收
|
||||
};
|
||||
|
||||
// 根据类型播放音频
|
||||
const playAudioByType = (type) => {
|
||||
if (audioPlayers.value[type]) {
|
||||
try {
|
||||
audioPlayers.value[type].play()
|
||||
} catch (error) {
|
||||
console.error(`播放类型${type}的音频失败:`, error)
|
||||
}
|
||||
const playAudioByType = (val) => {
|
||||
switch (val.typeMasgeLx) {
|
||||
case "01": //预警
|
||||
// 01 布控预警、02 七类重点人、03 政保
|
||||
switch (val.yjlb) {
|
||||
case "01":
|
||||
case "02":
|
||||
if (val.sfQs == '1') return
|
||||
if (val.yjJb == "01") {
|
||||
getAudioPlayer("18")?.play();
|
||||
getAudioPlayer("17")?.play();
|
||||
} else {
|
||||
getAudioPlayer("19")?.play();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "02": //信息汇聚
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("09")?.play();
|
||||
break;
|
||||
case "03": //约稿
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("13")?.play();
|
||||
break;
|
||||
case "04": //指令
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("12")?.play();
|
||||
break;
|
||||
case "05": //新线索
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("11")?.play();
|
||||
break;
|
||||
case "06": //检测警情
|
||||
if (val.jqdjdm == "01") {
|
||||
getAudioPlayer("18")?.play();
|
||||
getAudioPlayer("17")?.play();
|
||||
} else {
|
||||
getAudioPlayer("19")?.play();
|
||||
}
|
||||
break;
|
||||
case "08": //林安码
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("10")?.play();
|
||||
break;
|
||||
case "11":
|
||||
getAudioPlayer("03")?.play();
|
||||
getAudioPlayer("19")?.play();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
// 手动关闭
|
||||
const handleClose = () => {
|
||||
if (timekeeping.value) {
|
||||
clearInterval(timekeeping.value)
|
||||
timekeeping.value = null
|
||||
clearInterval(timekeeping.value);
|
||||
timekeeping.value = null;
|
||||
}
|
||||
dataList.value = []
|
||||
}
|
||||
dataList.value = [];
|
||||
};
|
||||
|
||||
// 重置倒计时
|
||||
const resetCountdown = () => {
|
||||
if (timekeeping.value) {
|
||||
clearInterval(timekeeping.value)
|
||||
clearInterval(timekeeping.value);
|
||||
}
|
||||
countdown.value = 15
|
||||
countdown.value = 15;
|
||||
timekeeping.value = setInterval(() => {
|
||||
countdown.value--
|
||||
countdown.value--;
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timekeeping.value)
|
||||
dataList.value = []
|
||||
timekeeping.value = null
|
||||
clearInterval(timekeeping.value);
|
||||
dataList.value = [];
|
||||
timekeeping.value = null;
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// 做一个定时器15s一次
|
||||
const checkNews = ref(null)
|
||||
const checkNewsInterval = 15000 // 15秒
|
||||
checkNews.value = setInterval(() => {
|
||||
dataModel()
|
||||
}, checkNewsInterval)
|
||||
const checkNews = ref(null);
|
||||
const checkNewsInterval = 15000; // 15秒
|
||||
const idEntityCard = ref(getItem("idEntityCard"));
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化音频播放器
|
||||
initAudioPlayers()
|
||||
emitter.on('webSocketMessage', (newsDate) => {
|
||||
if (newsDate) {
|
||||
dataList.value = newsDate
|
||||
// dataList.value.unshift({...newsDate.data,typeMasgeLx:newsDate.type})
|
||||
// 根据消息类型播放音频
|
||||
playAudioByType(newsDate[0].typeMasgeLx)
|
||||
resetCountdown()
|
||||
}
|
||||
})
|
||||
})
|
||||
const idEntityCard = ref(getItem('idEntityCard'))
|
||||
// 音频初始化在后台进行,不阻塞组件渲染
|
||||
initAudioPlayers().then(() => {
|
||||
// 音频预加载完成后再启动轮询
|
||||
checkNews.value = setInterval(() => {
|
||||
dataModel();
|
||||
}, checkNewsInterval);
|
||||
});
|
||||
|
||||
// 注册事件监听(需在 onUnmounted 中精确解绑)
|
||||
emitter.on("webSocketMessage", handleWebSocketMessage);
|
||||
});
|
||||
|
||||
// 处理 WebSocket 消息事件(需在 onUnmounted 中解绑,提取到模块作用域)
|
||||
const handleWebSocketMessage = (newsDate) => {
|
||||
if (newsDate) {
|
||||
dataList.value = newsDate;
|
||||
playAudioByType(newsDate[0]);
|
||||
resetCountdown();
|
||||
}
|
||||
};
|
||||
const dataModel = () => {
|
||||
qcckGet({}, '/mosty-gsxt/dsjJbxx/message').then(res => {
|
||||
qcckGet({}, "/mosty-gsxt/dsjJbxx/message").then((res) => {
|
||||
if (res) {
|
||||
const yjmasg = res.filter(item => item.type === '01')
|
||||
if (yjmasg.length > 0) {
|
||||
emitter.emit('openYp', yjmasg[0].obj); // 触发音频播放
|
||||
} else {
|
||||
const data=res.filter(item=>item.sfzList.includes(idEntityCard.value))
|
||||
const infoMasge =data.map(item => {
|
||||
return {
|
||||
...item.obj,
|
||||
typeMasgeLx: item.type
|
||||
}
|
||||
})
|
||||
console.log(infoMasge);
|
||||
emitter.emit('webSocketMessage', infoMasge)
|
||||
}
|
||||
const data = res.filter((item) =>
|
||||
item.sfzList.includes(idEntityCard.value)
|
||||
);
|
||||
const infoMasge = data.map((item) => {
|
||||
return {
|
||||
...item.obj,
|
||||
typeMasgeLx: item.type
|
||||
};
|
||||
});
|
||||
emitter.emit("webSocketMessage", infoMasge);
|
||||
}
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// if (newsDate.type === '01') {
|
||||
// // 触发音频播放
|
||||
// console.log('触发音频播放');
|
||||
// emitter.emit('openYp', newsDate.data); // 传递消息数据
|
||||
// } else {
|
||||
onUnmounted(() => {
|
||||
emitter.off('webSocketMessage')
|
||||
emitter.off("webSocketMessage", handleWebSocketMessage);
|
||||
if (timekeeping.value) {
|
||||
clearInterval(timekeeping.value)
|
||||
clearInterval(timekeeping.value);
|
||||
}
|
||||
// 销毁所有音频播放器实例
|
||||
Object.values(audioPlayers.value).forEach(player => {
|
||||
if (player) {
|
||||
player.destroy()
|
||||
}
|
||||
})
|
||||
audioPlayers.forEach((player) => {
|
||||
player.destroy();
|
||||
});
|
||||
audioPlayers.clear();
|
||||
// 清除定时器
|
||||
if (checkNews.value) {
|
||||
clearInterval(checkNews.value)
|
||||
checkNews.value = null
|
||||
clearInterval(checkNews.value);
|
||||
checkNews.value = null;
|
||||
}
|
||||
// 组件卸载时执行的操作
|
||||
console.log('组件卸载时执行的操作')
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -207,7 +261,7 @@ onUnmounted(() => {
|
||||
text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
|
||||
@ -1,79 +1,150 @@
|
||||
<template>
|
||||
<div class="test-item" v-if="item.typeMasgeLx == '02'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '01' || item.typeMasgeLx == '11'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx, item)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.qbmc || '' }}</div>
|
||||
<div class="item-title">{{ item.yjBt || "" }}</div>
|
||||
<div class="item-type">
|
||||
{{
|
||||
item.yjlb == "01"
|
||||
? "布控预警"
|
||||
: item.yjlb == "02"
|
||||
? "七类重点人"
|
||||
: "政保"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-message">{{ item.yjNr }}</div>
|
||||
<div class="item-time">{{ item.yjSj || "" }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '02'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.qbmc || "" }}</div>
|
||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||
</div>
|
||||
<div class="item-message">{{ item.qbnr }}</div>
|
||||
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
||||
<div class="item-time">{{ item.xtCjsj || "" }}</div>
|
||||
</div>
|
||||
<div class="test-item" v-if="item.typeMasgeLx == '03'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '03'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.bgmc || '' }}</div>
|
||||
<div class="item-title">{{ item.ypyt || "" }}</div>
|
||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||
</div>
|
||||
<div class="item-message" v-html="item.bgnr"></div>
|
||||
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
||||
<div class="item-message">{{ item.ssbm }}</div>
|
||||
<div class="item-time">{{ item.ypsj || "" }}</div>
|
||||
</div>
|
||||
<div class="test-item" v-if="item.typeMasgeLx == '04'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '04'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.zlbt || '' }}</div>
|
||||
<div class="item-title">{{ item.zlbt || "" }}</div>
|
||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||
</div>
|
||||
<div class="item-message" v-html="item.zlnr"></div>
|
||||
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
||||
<div class="item-time">{{ item.xtCjsj || "" }}</div>
|
||||
</div>
|
||||
<div class="test-item" v-if="item.typeMasgeLx == '05'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '05'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.zlbt || '' }}</div>
|
||||
<div class="item-title">{{ item.zlbt || "" }}</div>
|
||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||
</div>
|
||||
<div class="item-message" v-html="item.zlnr"></div>
|
||||
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
||||
<div class="item-time">{{ item.xtCjsj || "" }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '06'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.gxdwmc || "" }}</div>
|
||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||
</div>
|
||||
<div class="item-message">{{ item.bcjjnr }}</div>
|
||||
<div class="item-time">{{ item.bjsj || "" }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="test-item"
|
||||
v-if="item.typeMasgeLx == '08'"
|
||||
@click="goDetail(item.id, item.typeMasgeLx)"
|
||||
>
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ item.qbmc || "" }}</div>
|
||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||
</div>
|
||||
<div class="item-message">{{ item.qbnr }}</div>
|
||||
<div class="item-time">{{ item.sxsbsj || "" }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
import { useRouter } from "vue-router";
|
||||
import emitter from "@/utils/eventBus.js"; // 导入
|
||||
const router = useRouter();
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
});
|
||||
const informationMap = {
|
||||
'01': '报警信息',
|
||||
'02': '信息上报',
|
||||
'03': '研判审批',
|
||||
'04': '研判指令',
|
||||
'05': '线索下发',
|
||||
}
|
||||
const emit=defineEmits(['goDetail'])
|
||||
const goDetail = (id, lx) => {
|
||||
let path = ''
|
||||
"01": "预警信息",
|
||||
"02": "信息上报",
|
||||
"03": "研判约稿",
|
||||
"04": "研判指令",
|
||||
"05": "线索下发",
|
||||
"06": "警情监测",
|
||||
"08": "林安码信息"
|
||||
};
|
||||
const emit = defineEmits(["goDetail"]);
|
||||
const goDetail = (id, lx, val) => {
|
||||
let path = "";
|
||||
switch (lx) {
|
||||
case '02':
|
||||
path = '/InfoCollection'
|
||||
case "01":
|
||||
case "11":
|
||||
emitter.emit("openYp", val);
|
||||
break;
|
||||
case '03':
|
||||
path = '/strategicResearchs'
|
||||
case "02":
|
||||
path = "/InfoCollection";
|
||||
break;
|
||||
default:
|
||||
case '04':
|
||||
path = '/judgmentCommand'
|
||||
case "03":
|
||||
path = "/dataReduction";
|
||||
break;
|
||||
case "04":
|
||||
path = "/judgmentCommand";
|
||||
break;
|
||||
case "05":
|
||||
path = "/InstructionInformation";
|
||||
break;
|
||||
case "06":
|
||||
path = "/policeReport";
|
||||
break;
|
||||
case "08":
|
||||
path = "/lamXs";
|
||||
break;
|
||||
case '05':
|
||||
path = '/InstructionInformation'
|
||||
break;
|
||||
}
|
||||
router.push({
|
||||
path: path,
|
||||
query: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.test-item {
|
||||
|
||||
@ -26,14 +26,14 @@
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
<div class="container-box" v-else>
|
||||
<div v-for="(item, index) in userList" :key="item.id">
|
||||
<div v-for="item in userList" :key="item.id">
|
||||
<div v-if="checkList.includes(item.nodeId)">
|
||||
<el-divider content-position="left">{{ item.nodeName }}</el-divider>
|
||||
<template v-if="Array.isArray(item.userList)">
|
||||
<div class="reloBox" v-for="items in item.userList">
|
||||
<div class="reloBox" v-for="(items,idx) in item.userList" :key="idx">
|
||||
<div class="orgName">{{ items.name }}</div>
|
||||
<el-checkbox-group v-model="items.checkList">
|
||||
<el-checkbox :label="it.userid" v-for="(it, index) in items.users" :key="it.id">{{
|
||||
<el-checkbox :label="it.userid" v-for="it in items.users" :key="it.id">{{
|
||||
it.username }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
||||
@ -21,8 +21,13 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<SelectingPeople v-model="showDialog" :createProcess="createProcess" @close="close" :radioData="radioData"
|
||||
:path="path" @getList="emit('getList')" :userData="userData" />
|
||||
<SelectingPeople
|
||||
v-model="showDialog"
|
||||
:createProcess="createProcess"
|
||||
@close="close" :radioData="radioData"
|
||||
:path="path"
|
||||
@getList="emit('getList')"
|
||||
:userData="userData" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
@ -115,28 +115,29 @@ onMounted(() => {
|
||||
} else {
|
||||
showFxq.value = true
|
||||
}
|
||||
emitter.on("handleClick", () => {
|
||||
idEntityCard.value = getItem('idEntityCard')
|
||||
emitter.on("handleClick", handleClickHandler);
|
||||
// 清除旧定时器,避免多个定时器同时运行
|
||||
if (intTime.value) {
|
||||
clearInterval(intTime.value)
|
||||
}
|
||||
intTime.value = setInterval(() => {
|
||||
handleClick()
|
||||
// 清除旧定时器,避免多个定时器同时运行
|
||||
if (intTime.value) {
|
||||
clearInterval(intTime.value)
|
||||
}
|
||||
intTime.value = setInterval(() => {
|
||||
handleClick()
|
||||
}, 60000)
|
||||
});
|
||||
}, 60000)
|
||||
|
||||
})
|
||||
const handleClickHandler = () => {
|
||||
idEntityCard.value = getItem('idEntityCard')
|
||||
handleClick()
|
||||
}
|
||||
onUnmounted(() => {
|
||||
clearInterval(intTime.value)
|
||||
emitter.off("handleClick")
|
||||
emitter.off("handleClick", handleClickHandler)
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// 蜂群组件样式
|
||||
.fxqx {
|
||||
border-radius: 34px;
|
||||
border-radius: 34px;
|
||||
width: 34px;
|
||||
background-color: rgb(1, 127, 245);
|
||||
margin-bottom: 18px;
|
||||
|
||||
@ -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;
|
||||
|
||||
83
src/layout/components/SideBar/SideBarMenu copy 2.vue
Normal file
83
src/layout/components/SideBar/SideBarMenu copy 2.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<el-menu class="el-menu-vertical-demo" :collapse="!$store.getters.sidebarOpened" :default-active="activeMenu"
|
||||
:unique-opened="true" background-color="rgba(0, 0, 0, 0)" :text-color="$store.getters.cssVar.menuText"
|
||||
:active-text-color="$store.getters.cssVar.menuActiveText" router>
|
||||
<SideBarItem v-for="item in routes" :key="item.path" :route="item"></SideBarItem>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } 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 = ["warningLists", "behaviorWarnings", "identityWarnings", "combinedWarnings", "DeploymentAreas", "mpvPeos", "myControls"];
|
||||
const filterRoutesByMenusPermission = (routes, menusSet) => {
|
||||
return routes.reduce((result, route) => {
|
||||
const children = Array.isArray(route.children) ? filterRoutesByMenusPermission(route.children, menusSet) : [];
|
||||
const routeName = route.name ? `${route.name}` : "";
|
||||
const selfMatched = routeName && menusSet.has(routeName);
|
||||
if (selfMatched || children.length > 0) {
|
||||
result.push({ ...route, children });
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
};
|
||||
const routes = computed(() => {
|
||||
const fRoutes = filterRoutes(router.getRoutes());
|
||||
const data = fRoutes.filter((item) => !EXCLUDE_NAMES.includes(item.name));
|
||||
const menusPermission = getItem("menusPermission");
|
||||
const menusSet = new Set(Array.isArray(menusPermission) ? menusPermission.map((item) => `${item}`) : []);
|
||||
const permissionFiltered = menusSet.size ? filterRoutesByMenusPermission(data, menusSet) : data;
|
||||
return generateMenus(permissionFiltered);
|
||||
});
|
||||
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);
|
||||
}
|
||||
//默认激活项
|
||||
const route = useRoute();
|
||||
const activeMenu = computed(() => {
|
||||
const { path } = route;
|
||||
return path;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .el-menu-item {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
::v-deep .el-sub-menu__title {
|
||||
height: 48px;
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: rgb(20, 46, 78);
|
||||
}
|
||||
|
||||
::v-deep .el-menu-item.is-active {
|
||||
background-image: linear-gradient(to right, #2356d4 0%, #8efbde 100%);
|
||||
margin: 0 14px;
|
||||
border-radius: 4px;
|
||||
// padding-left: 46px !important;
|
||||
}
|
||||
|
||||
::v-deep .el-sub-menu .el-menu-item {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.el-menu-vertical-demo:not(.el-menu--collapse) {
|
||||
width: 240px;
|
||||
min-height: 400px;
|
||||
}
|
||||
</style>
|
||||
79
src/layout/components/SideBar/SideBarMenu copy.vue
Normal file
79
src/layout/components/SideBar/SideBarMenu copy.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<el-menu class="el-menu-vertical-demo" :collapse="!$store.getters.sidebarOpened" :default-active="activeMenu"
|
||||
:unique-opened="true" background-color="rgba(0, 0, 0, 0)" :text-color="$store.getters.cssVar.menuText"
|
||||
:active-text-color="$store.getters.cssVar.menuActiveText" router>
|
||||
<SideBarItem v-for="item in routes" :key="item.path" :route="item"></SideBarItem>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { useStore } from "vuex";
|
||||
import { filterRoutes, generateMenus } from "@/utils/route";
|
||||
import SideBarItem from "./SideBarItem.vue";
|
||||
const store = useStore();
|
||||
const router = useRouter();
|
||||
const routes = computed(() => {
|
||||
const fRoutes = filterRoutes(router.getRoutes());
|
||||
|
||||
const data = fRoutes.filter(item => {
|
||||
if (item.name != "warningLists"
|
||||
&& item.name != "behaviorWarnings"
|
||||
&& item.name != "identityWarnings"
|
||||
&& item.name != "combinedWarnings"
|
||||
&& item.name != "DeploymentAreas"
|
||||
&& item.name != "mpvPeos"
|
||||
&& item.name != "myControls") {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
)
|
||||
return generateMenus(data);
|
||||
});
|
||||
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);
|
||||
}
|
||||
//默认激活项
|
||||
const route = useRoute();
|
||||
const activeMenu = computed(() => {
|
||||
const { path } = route;
|
||||
return path;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .el-menu-item {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
::v-deep .el-sub-menu__title {
|
||||
height: 48px;
|
||||
color: rgb(255, 255, 255);
|
||||
background-color: rgb(20, 46, 78);
|
||||
}
|
||||
|
||||
::v-deep .el-menu-item.is-active {
|
||||
background-image: linear-gradient(to right, #2356d4 0%, #8efbde 100%);
|
||||
margin: 0 14px;
|
||||
border-radius: 4px;
|
||||
// padding-left: 46px !important;
|
||||
}
|
||||
|
||||
::v-deep .el-sub-menu .el-menu-item {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.el-menu-vertical-demo:not(.el-menu--collapse) {
|
||||
width: 240px;
|
||||
min-height: 400px;
|
||||
}
|
||||
</style>
|
||||
@ -1,43 +1,108 @@
|
||||
<template>
|
||||
<el-menu class="el-menu-vertical-demo" :collapse="!$store.getters.sidebarOpened" :default-active="activeMenu"
|
||||
:unique-opened="true" background-color="rgba(0, 0, 0, 0)" :text-color="$store.getters.cssVar.menuText"
|
||||
:active-text-color="$store.getters.cssVar.menuActiveText" router>
|
||||
<SideBarItem v-for="item in routes" :key="item.path" :route="item"></SideBarItem>
|
||||
<el-menu
|
||||
class="el-menu-vertical-demo"
|
||||
:collapse="!$store.getters.sidebarOpened"
|
||||
:default-active="activeMenu"
|
||||
:unique-opened="true"
|
||||
background-color="rgba(0, 0, 0, 0)"
|
||||
:text-color="$store.getters.cssVar.menuText"
|
||||
:active-text-color="$store.getters.cssVar.menuActiveText"
|
||||
router
|
||||
>
|
||||
<SideBarItem
|
||||
v-for="item in routes"
|
||||
:key="item.path"
|
||||
:route="item"
|
||||
></SideBarItem>
|
||||
</el-menu>
|
||||
</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 = [
|
||||
"warningLists",
|
||||
"behaviorWarnings",
|
||||
"identityWarnings",
|
||||
"combinedWarnings",
|
||||
"DeploymentAreas",
|
||||
"mpvPeos",
|
||||
"myControls"
|
||||
];
|
||||
|
||||
const filterRoutesByMenusPermission = (routes, menusSet) => {
|
||||
return routes.reduce((result, route) => {
|
||||
const children = Array.isArray(route.children)
|
||||
? filterRoutesByMenusPermission(route.children, menusSet)
|
||||
: [];
|
||||
const routeName = route.name ? `${route.name}` : "";
|
||||
const selfMatched = routeName && menusSet.has(routeName);
|
||||
if (selfMatched || children.length > 0) {
|
||||
result.push({ ...route, children });
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
};
|
||||
const routes = computed(() => {
|
||||
const fRoutes = filterRoutes(router.getRoutes());
|
||||
const data = fRoutes.filter(item => {
|
||||
if (item.name != "warningLists"
|
||||
&& item.name != "behaviorWarnings"
|
||||
&& item.name != "identityWarnings"
|
||||
&& item.name != "combinedWarnings"
|
||||
&& item.name != "DeploymentAreas"
|
||||
&& item.name != "mpvPeos"
|
||||
&& item.name != "myControls") {
|
||||
return item;
|
||||
}
|
||||
// 排除不需要显示的菜单,包括 forumPost(单独处理)
|
||||
const data = fRoutes.filter((item) =>
|
||||
!EXCLUDE_NAMES.includes(item.name) && item.name !== 'forumPost'
|
||||
);
|
||||
const menusPermission = getItem("menusPermission");
|
||||
|
||||
// 情报论坛菜单(所有人可见,始终显示在最后)
|
||||
const forumMenu = {
|
||||
path: '/forumPost',
|
||||
meta: { title: '情报论坛', icon: 'article-ranking' },
|
||||
children: []
|
||||
};
|
||||
|
||||
// 如果 menusPermission 为 null 或 undefined,只显示情报论坛菜单
|
||||
if (menusPermission === null || menusPermission === undefined) {
|
||||
return [forumMenu];
|
||||
}
|
||||
)
|
||||
return generateMenus(data);
|
||||
|
||||
const menusSet = new Set(
|
||||
Array.isArray(menusPermission)
|
||||
? menusPermission.map((item) => `${item}`)
|
||||
: []
|
||||
);
|
||||
|
||||
// 先按权限过滤
|
||||
let permissionFiltered = menusSet.size
|
||||
? filterRoutesByMenusPermission(data, menusSet)
|
||||
: [];
|
||||
|
||||
// 生成菜单
|
||||
const menus = generateMenus(permissionFiltered);
|
||||
|
||||
// 最后添加情报论坛菜单(所有人可见,放到最后)
|
||||
menus.push(forumMenu);
|
||||
|
||||
return menus;
|
||||
});
|
||||
if (!store.getters.token) {
|
||||
router.push("/login");
|
||||
}
|
||||
if (router.getRoutes().length <= 7 && store.state.permission.routeReady <= 1) {
|
||||
store.commit("user/setIsReady", {});
|
||||
setTimeout(() => {
|
||||
router.go(0);
|
||||
}, 200);
|
||||
// 路由未完成加载时,等待加载完成,不再刷新页面
|
||||
if (store.state.permission.routeReady !== 2) {
|
||||
const unwatch = watch(
|
||||
() => store.state.permission.routeReady,
|
||||
(val) => {
|
||||
if (val === 2) {
|
||||
unwatch();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
}
|
||||
//默认激活项
|
||||
const route = useRoute();
|
||||
|
||||
@ -9,62 +9,55 @@ import {
|
||||
import {
|
||||
getCookie
|
||||
} from "@/utils/cookie";
|
||||
// 白名单
|
||||
|
||||
// 白名单路由(无需登录即可访问)
|
||||
const whiteList = ['/login', '/oatuh_login', '/404', '/401', '/zeroTrust_login', '/focusExploration', '/clueVerification', '/deploymentApproval']
|
||||
|
||||
// 标记路由是否已初始化
|
||||
let routesInitialized = false;
|
||||
|
||||
/**
|
||||
* 路由前置守卫
|
||||
* to 去哪里
|
||||
* from 来自哪
|
||||
* next 往下走
|
||||
*/
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// 存在 token ,进入主页
|
||||
// if (store.state.user.token) {
|
||||
// 快捷访问
|
||||
// console.log(store.getters.token);
|
||||
console.log('[permission.js] 路由守卫触发:', from.path, '->', to.path, '时间:', Date.now());
|
||||
|
||||
if (store.getters.token) {
|
||||
// console.log("路由1");
|
||||
// 已登录
|
||||
if (!routesInitialized) {
|
||||
// 首次进入:根据权限动态注册路由
|
||||
console.log('[permission.js] 首次初始化路由...');
|
||||
routesInitialized = true;
|
||||
const afterMenuList = getItem('menusPermission');
|
||||
console.log('[permission.js] menusPermission:', afterMenuList?.length);
|
||||
|
||||
// 判断用户资料是否获取
|
||||
// 若不存在用户信息,则需要获取用户信息
|
||||
// 触发获取用户信息的 action,并获取用户当前权限
|
||||
store.commit('permission/setRouteReady', 1)
|
||||
// 添加完动态路由之后,需要在进行一次主动跳转
|
||||
const afterMenuList = getItem('menusPermission');
|
||||
// 处理用户权限,筛选出需要添加的权限
|
||||
// console.log(store.state.permission.routes);
|
||||
// 动态注册有权限的路由
|
||||
await store.dispatch('permission/filterRoutes', afterMenuList);
|
||||
console.log('[permission.js] 路由初始化完成');
|
||||
|
||||
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()
|
||||
// 重新导航到目标路由,确保刚注册的路由能正确匹配
|
||||
next({ ...to, replace: true });
|
||||
return;
|
||||
}
|
||||
// 利用 addRoute 循环添加
|
||||
|
||||
// 处理 keep-alive 缓存(使用组件名称,而非路由名称)
|
||||
if (to.meta.keepAlive && to.meta.componentName) {
|
||||
store.commit('user/setKeepLiiveRoute', to.meta.componentName);
|
||||
}
|
||||
|
||||
console.log('[permission.js] 放行跳转');
|
||||
next();
|
||||
} else {
|
||||
// 没有token的情况下,可以进入白名单
|
||||
// 未登录:白名单放行,否则跳转登录
|
||||
if (whiteList.indexOf(to.path) > -1) {
|
||||
// console.log("路由2");
|
||||
next()
|
||||
} else {
|
||||
const cookie = getCookie("clientKey");
|
||||
if (cookie) {
|
||||
// console.log("路由3");
|
||||
next(`/zeroTrust_login`)
|
||||
} else {
|
||||
// console.log("路由4");
|
||||
const isOatuh = getItem('isOatuh')
|
||||
// 没有token的情况下,可以进入白名单
|
||||
if (isOatuh) {
|
||||
// console.log("路由5");
|
||||
const idEntityCard = getItem('idEntityCard')
|
||||
next(`/oatuh_login?token=${Base64.encode(idEntityCard)}`)
|
||||
} else {
|
||||
@ -74,3 +67,15 @@ router.beforeEach(async (to, from, next) => {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 添加路由后置守卫,确认路由变化
|
||||
router.afterEach((to, from) => {
|
||||
console.log('[permission.js] 路由跳转完成:', from.path, '->', to.path, '时间:', Date.now());
|
||||
})
|
||||
|
||||
/**
|
||||
* 重置路由初始化状态(退出登录时调用)
|
||||
*/
|
||||
export function resetRoutesInit() {
|
||||
routesInitialized = false;
|
||||
}
|
||||
|
||||
@ -1,26 +1,24 @@
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import layout from "@/layout/index"; //layout直接引用 其他使用路由懒加载
|
||||
import layout from "@/layout/index";
|
||||
import store from "@/store";
|
||||
|
||||
// import Home from '../views/Home.vue'
|
||||
/**
|
||||
* 关于路由配置描述
|
||||
* 1.meta && meta.title && meta.icon 则在菜单栏显示
|
||||
* 2.如果存在children , 则以el-sub-menu子菜单显示
|
||||
* 否则不在menu菜单显示
|
||||
* 如果只展示单级别菜单 需要像developer这样配置
|
||||
* 路由配置说明
|
||||
*
|
||||
* 1. publicRoutes(公开路由)- 所有用户都能访问,应用启动时静态注册
|
||||
* 包括:登录页、首页、错误页等
|
||||
*
|
||||
* 2. privateRoutes(私有路由)- 需要权限才能访问,登录后动态注册
|
||||
* 包括:所有业务功能路由
|
||||
*
|
||||
* 3. 路由的 name 属性必须与后端返回的菜单权限码(menuCodeSet)一致
|
||||
*/
|
||||
|
||||
/**
|
||||
* 私有路由表
|
||||
*/
|
||||
|
||||
export const privateRoutes = [];
|
||||
|
||||
/**
|
||||
* 公开路由表
|
||||
* 公开路由表 - 所有人都能访问
|
||||
*/
|
||||
export const publicRoutes = [
|
||||
// 登录相关路由
|
||||
{
|
||||
path: "/oatuh_login",
|
||||
name: "oatuh_login",
|
||||
@ -36,44 +34,57 @@ export const publicRoutes = [
|
||||
name: "zeroTrust_login",
|
||||
component: () => import("@/views/login/zeroTrust_login")
|
||||
},
|
||||
// 错误页面
|
||||
{
|
||||
path: "/401",
|
||||
name: "401",
|
||||
component: () => import("@/views/error/401.vue")
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "404",
|
||||
component: () => import("@/views/error/404.vue")
|
||||
},
|
||||
// 首页(所有登录用户都可访问)
|
||||
{
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: () => import("@/views/home/index") //系统登录
|
||||
component: () => import("@/views/home/index"),
|
||||
meta: { keepAlive: true, componentName: 'HomePage' }
|
||||
},
|
||||
// 公共访问页面(无需权限校验)
|
||||
{
|
||||
path: "/mapNavigation",
|
||||
name: "mapNavigation",
|
||||
component: () => import("@/views/home/model/mapNavigation.vue") //系统登录
|
||||
component: () => import("@/views/home/model/mapNavigation.vue")
|
||||
},
|
||||
{
|
||||
path: "/KeyPopulations",
|
||||
name: "KeyPopulations",
|
||||
component: () => import("@/views/KeyPopulations/index") //系统登录
|
||||
component: () => import("@/views/KeyPopulations/index")
|
||||
},
|
||||
// 布控审核信息
|
||||
// 以下路由虽然在白名单中,但仍需要登录才能访问
|
||||
// 它们是特殊业务路由,登录后所有人都能访问(不依赖菜单权限)
|
||||
{
|
||||
path: "/deploymentApproval",
|
||||
name: "deploymentApproval",
|
||||
component: () => import("@/views/backOfficeSystem/ApprovalInformation/deploycontrol/deploymentApproval.vue"),
|
||||
},
|
||||
// 标签布控审核
|
||||
{
|
||||
path: "/shym",
|
||||
name: "shym",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/marksControl/components/shym.vue"),
|
||||
},
|
||||
// 布控审核信息
|
||||
{
|
||||
path: "/information",
|
||||
name: "information",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/internalAuditor/information.vue"),
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/Spdloyment",
|
||||
name: "Spdloyment",
|
||||
component: () => import("@/views/backOfficeSystem/HumanIntelligence/auditList/components/spdloyment.vue"),
|
||||
},
|
||||
// 线索
|
||||
{
|
||||
path: "/clueVerification",
|
||||
name: "clueVerification",
|
||||
@ -84,13 +95,40 @@ export const publicRoutes = [
|
||||
name: "ReviewListSH",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/ReviewList/detail.vue"),
|
||||
},
|
||||
// 重点人发掘
|
||||
{
|
||||
path: "/focusExploration",
|
||||
name: "focusExploration",
|
||||
component: () => import("@/views/backOfficeSystem/ApprovalInformation/FocusExploration/index.vue"),
|
||||
},
|
||||
//开放到派出所路由
|
||||
// 情报论坛(所有登录用户都可访问)
|
||||
{
|
||||
path: "/forumPost",
|
||||
name: "forumPost",
|
||||
component: layout,
|
||||
meta: {
|
||||
title: "情报论坛",
|
||||
icon: "article-ranking"
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "forumPostPage",
|
||||
component: () => import("@/views/backOfficeSystem/luntan/index.vue"),
|
||||
meta: {
|
||||
title: "情报论坛",
|
||||
icon: "article-ranking"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 私有路由表 - 需要权限才能访问
|
||||
* 登录后根据用户的 menuCodeSet 动态注册
|
||||
*/
|
||||
export const privateRoutes = [
|
||||
// 派出所开放路由(特殊权限,不在菜单显示)
|
||||
{
|
||||
path: "/warningLists",
|
||||
name: "warningLists",
|
||||
@ -100,7 +138,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/behaviorWarnings",
|
||||
name: "behaviorWarnings",
|
||||
@ -127,7 +164,8 @@ export const publicRoutes = [
|
||||
title: "重点人管理",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/myControls",
|
||||
name: "myControls",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/myControl/index"),
|
||||
@ -135,7 +173,8 @@ export const publicRoutes = [
|
||||
title: "我的布控",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/DeploymentAreas",
|
||||
name: "DeploymentAreas",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/DeploymentArea/index"),
|
||||
@ -144,8 +183,9 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// 主业务路由(带 layout)
|
||||
{
|
||||
path: "/editPassword", // 注意:带有路径“/”的记录中的组件“默认”是一个不返回 Promise 的函数
|
||||
path: "/editPassword",
|
||||
redirect: "/IdentityManage",
|
||||
component: layout,
|
||||
children: [
|
||||
@ -154,125 +194,51 @@ 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",
|
||||
meta: { title: "预警列表", icon: "article-create" },
|
||||
component: () => import("@/views/backOfficeSystem/fourColorManage/YjData/index.vue"),
|
||||
},
|
||||
// {
|
||||
// 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: "/jqjc",
|
||||
name: "jqjc",
|
||||
meta: { title: "警情监测", icon: "article-create" },
|
||||
children: [
|
||||
{
|
||||
path: "/policeReport",
|
||||
name: "policeReport",
|
||||
component: () => import("@/views/backOfficeSystem/policeReport/index.vue"),
|
||||
meta: {
|
||||
title: "警情信息",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/policeSituations",
|
||||
name: "policeSituations",
|
||||
component: () => import("@/views/backOfficeSystem/PoliceIncidentMonitoring/index.vue"),
|
||||
meta: {
|
||||
title: "警情预警监测",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
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",
|
||||
@ -314,24 +280,15 @@ 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"
|
||||
// }
|
||||
// }
|
||||
{
|
||||
path: "/ReviewListControl",
|
||||
name: "ReviewListControl",
|
||||
component: () => import("@/views/backOfficeSystem/IntelligentControl/ReviewListControl/index"),
|
||||
meta: {
|
||||
title: "审核列表",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -356,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",
|
||||
@ -397,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"
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -434,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",
|
||||
@ -456,21 +375,8 @@ export const publicRoutes = [
|
||||
icon: "article"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/InformationFlows",
|
||||
// name: "InformationFlows",
|
||||
// meta: { title: "情报流转", icon: "article-create" },
|
||||
// // redirect: "/InformationFlow",
|
||||
// // children: [
|
||||
|
||||
|
||||
// // ]
|
||||
// },
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: "/JudgmentHome",
|
||||
name: "JudgmentHome",
|
||||
@ -480,15 +386,6 @@ export const publicRoutes = [
|
||||
icon: "article-ranking"
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/policeReport",
|
||||
name: "policeReport",
|
||||
component: () => import("@/views/backOfficeSystem/policeReport/index.vue"),
|
||||
meta: {
|
||||
title: "警情管理",
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/policeManagement",
|
||||
name: "policeManagement",
|
||||
@ -516,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",
|
||||
@ -562,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",
|
||||
@ -618,7 +496,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/mpvGroup",
|
||||
name: "mpvGroup",
|
||||
@ -628,7 +505,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/mpvCar",
|
||||
name: "mpvCar",
|
||||
@ -647,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"
|
||||
// }
|
||||
// },
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -685,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" },
|
||||
@ -693,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",
|
||||
@ -785,7 +579,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/FileData",
|
||||
name: "FileData",
|
||||
@ -795,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",
|
||||
@ -839,7 +614,8 @@ export const publicRoutes = [
|
||||
title: "操作记录",
|
||||
icon: "article-create"
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/dataMonitor",
|
||||
name: "dataMonitor",
|
||||
meta: { title: "数据监控", icon: "article-ranking" },
|
||||
@ -866,57 +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: "/forumPost",
|
||||
name: "forumPost",
|
||||
component: () => import("@/views/forumPost/index.vue"),
|
||||
meta: {
|
||||
title: "情报论坛",
|
||||
icon: "article-ranking"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/systemConfig",
|
||||
// component: layout,
|
||||
name: "systemConfigModel",
|
||||
// redirect: "/dict/index",
|
||||
meta: {
|
||||
title: "系统管理",
|
||||
icon: "article-ranking"
|
||||
@ -931,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"
|
||||
@ -945,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"
|
||||
@ -955,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: "字典数据"
|
||||
}
|
||||
@ -975,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: "管理用户"
|
||||
}
|
||||
@ -997,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"),
|
||||
@ -1074,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"
|
||||
@ -1102,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"
|
||||
@ -1152,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"
|
||||
@ -1168,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"
|
||||
@ -1180,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"),
|
||||
@ -1207,7 +900,8 @@ export const publicRoutes = [
|
||||
}
|
||||
},
|
||||
]
|
||||
}, {
|
||||
},
|
||||
{
|
||||
path: "/tacticalResearch",
|
||||
name: "tacticalResearch",
|
||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/tacticalResearch/index.vue"),
|
||||
@ -1216,7 +910,6 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: "/strategicResearch",
|
||||
name: "strategicResearch",
|
||||
@ -1235,43 +928,26 @@ export const publicRoutes = [
|
||||
icon: "article-create"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: "/ResearchHome",
|
||||
// name: "ResearchHome",
|
||||
// component: () => import("@/views/backOfficeSystem/JudgmentHome/ResearchHome/index"),
|
||||
// meta: {
|
||||
// title: "战术研判",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: "/situationHome",
|
||||
// name: "situationHome",
|
||||
// component: () => import("@/views/backOfficeSystem/JudgmentHome/situationHome/index"),
|
||||
// meta: {
|
||||
// title: "战略研判",
|
||||
// icon: "article-create"
|
||||
// }
|
||||
// },
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// 创建路由实例,只注册公开路由
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: publicRoutes
|
||||
});
|
||||
//初始化路由表
|
||||
|
||||
// 重置路由(退出登录时调用)
|
||||
export function resetRouter() {
|
||||
if (store.getters?.routeReady && store.getters?.userInfo?.permission?.menus) {
|
||||
|
||||
|
||||
const menus = store.getters.userInfo.permission.menus;
|
||||
menus.forEach((menu) => {
|
||||
router.removeRoute(menu);
|
||||
});
|
||||
}
|
||||
// 移除所有动态添加的路由
|
||||
router.getRoutes().forEach(route => {
|
||||
if (route.name && !publicRoutes.find(r => r.name === route.name)) {
|
||||
router.removeRoute(route.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default router;
|
||||
|
||||
@ -1,23 +1,60 @@
|
||||
// 专门处理权限路由的模块
|
||||
import router from '@/router'
|
||||
import { publicRoutes, privateRoutes } from '@/router'
|
||||
|
||||
/**
|
||||
* 递归过滤路由(保留 component 引用)
|
||||
* 规则:
|
||||
* 1. 如果路由有 name 且在权限列表中,保留
|
||||
* 2. 如果路由没有 name 但有子路由,检查子路由是否有权限
|
||||
* 3. 子路由有权限时保留父路由
|
||||
*
|
||||
* @param {Array} data - 路由数据
|
||||
* @param {Array} menus - 菜单权限码集合
|
||||
* @returns {Array} - 过滤后的路由
|
||||
*/
|
||||
function filter(data, menus) {
|
||||
var newData = data.filter(x => menus?.includes(x.name))
|
||||
newData.forEach(x => x.children && (x.children = filter(x.children, menus)))
|
||||
return newData
|
||||
const result = []
|
||||
|
||||
data.forEach(route => {
|
||||
// 创建新路由对象,保留原有属性(包括 component)
|
||||
const newRoute = { ...route }
|
||||
|
||||
// 如果有 name 且在权限列表中,保留此路由
|
||||
if (route.name && menus?.includes(route.name)) {
|
||||
// 递归处理子路由
|
||||
if (route.children && route.children.length > 0) {
|
||||
newRoute.children = filter(route.children, menus)
|
||||
}
|
||||
result.push(newRoute)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果没有 name 但有 children,检查子路由是否有权限
|
||||
if (!route.name && route.children && route.children.length > 0) {
|
||||
const filteredChildren = filter(route.children, menus)
|
||||
// 只要子路由有匹配项,就保留父路由
|
||||
if (filteredChildren.length > 0) {
|
||||
newRoute.children = filteredChildren
|
||||
result.push(newRoute)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
routes: [],// 路由表:初始拥有静态路由权限
|
||||
routeReady: 0
|
||||
routes: [], // 最终路由表:公开路由 + 有权限的私有路由
|
||||
routeReady: 0 // 0: 未开始, 1: 进行中, 2: 完成
|
||||
},
|
||||
mutations: {
|
||||
/**
|
||||
* 增加路由
|
||||
* 设置路由
|
||||
*/
|
||||
setRoutes(state, newRoutes) {
|
||||
// 永远在静态路由的基础上增加新路由
|
||||
state.routes = [...publicRoutes, ...newRoutes]
|
||||
},
|
||||
setRouteReady(state, num) {
|
||||
@ -32,9 +69,14 @@ export default {
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 根据权限筛选路由
|
||||
* 根据权限过滤并动态注册路由
|
||||
* @param {Object} context - Vuex context
|
||||
* @param {Array} menus - 用户菜单权限码集合
|
||||
*/
|
||||
filterRoutes(context, menus) {
|
||||
// 开始处理,标记为进行中
|
||||
context.commit('setRouteReady', 1);
|
||||
|
||||
let routes = []
|
||||
|
||||
/**
|
||||
@ -45,16 +87,36 @@ export default {
|
||||
routes = filter(privateRoutes, menus)
|
||||
}
|
||||
|
||||
// 最后添加 不匹配路由进入 404
|
||||
routes.push({
|
||||
// ★★★ 关键:动态添加路由到 Vue Router ★★★
|
||||
routes.forEach(route => {
|
||||
router.addRoute(route)
|
||||
})
|
||||
|
||||
// 404 兜底路由必须最后添加(否则动态路由会匹配到 404)
|
||||
router.addRoute({
|
||||
path: '/:catchAll(.*)',
|
||||
redirect: '/404'
|
||||
})
|
||||
|
||||
context.commit('setRoutes', routes);
|
||||
context.commit('setRouteReady', 1);
|
||||
// 处理完成,标记为已完成
|
||||
context.commit('setRouteReady', 2);
|
||||
|
||||
return routes
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置路由(退出登录时调用)
|
||||
*/
|
||||
resetRoutes(context) {
|
||||
// 移除所有动态添加的路由
|
||||
router.getRoutes().forEach(route => {
|
||||
if (route.name && !publicRoutes.find(r => r.name === route.name)) {
|
||||
router.removeRoute(route.name);
|
||||
}
|
||||
});
|
||||
context.commit('deleteRouter');
|
||||
context.commit('resetrouteReady');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,27 +5,14 @@ import {
|
||||
refreshToken,
|
||||
loginOut
|
||||
} from "@/api/sys";
|
||||
import {
|
||||
unifiedLogin
|
||||
} from "@/api/user-manage";
|
||||
import { unifiedLogin } from "@/api/user-manage";
|
||||
import Base64 from "base-64";
|
||||
import {
|
||||
setItem,
|
||||
getItem,
|
||||
removeAllItem
|
||||
} from "@/utils/storage";
|
||||
import {
|
||||
TOKEN
|
||||
} from "@/constant";
|
||||
import router, {
|
||||
resetRouter
|
||||
} from "@/router";
|
||||
import {
|
||||
setTimeStamp
|
||||
} from "@/utils/auth";
|
||||
import {
|
||||
TAGS_VIEW
|
||||
} from "@/constant/index.js";
|
||||
import { setItem, getItem, removeAllItem } from "@/utils/storage";
|
||||
import { TOKEN } from "@/constant";
|
||||
import router, { resetRouter } from "@/router";
|
||||
import { setTimeStamp } from "@/utils/auth";
|
||||
import { TAGS_VIEW } from "@/constant/index.js";
|
||||
import { resetRoutesInit } from "@/permission";
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: () => ({
|
||||
@ -37,7 +24,7 @@ export default {
|
||||
isReady: 0,
|
||||
userName: getItem("USERNAME") || "",
|
||||
keepLiiveRoute: [], //需要缓存的路由
|
||||
activeId: '',//警组点击的唯一标识
|
||||
activeId: "" //警组点击的唯一标识
|
||||
}),
|
||||
mutations: {
|
||||
setToken(state, token) {
|
||||
@ -69,14 +56,16 @@ export default {
|
||||
},
|
||||
//保存路由
|
||||
setKeepLiiveRoute(state, val) {
|
||||
// state.keepLiiveRoute.push(val);
|
||||
if (!state.keepLiiveRoute.includes(val)) {
|
||||
state.keepLiiveRoute.push(val);
|
||||
}
|
||||
},
|
||||
//删除缓存路由
|
||||
deleteKeepLiiveRoute(state, val) {
|
||||
// state.keepLiiveRoute = state.keepLiiveRoute.filter((item) => {
|
||||
// return item != val;
|
||||
// });
|
||||
},
|
||||
state.keepLiiveRoute = state.keepLiiveRoute.filter((item) => {
|
||||
return item != val;
|
||||
});
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
/*
|
||||
@ -84,37 +73,43 @@ export default {
|
||||
*/
|
||||
login(ctx, userInfo) {
|
||||
const { userName, password, kaptcha } = userInfo;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ userName, password: Base64.encode(password), kaptcha }).then((data) => {
|
||||
if (data.deptList.length === 1) {
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setDeptId", data.deptList);
|
||||
this.commit("user/setUserName", data.userName);
|
||||
setItem('isOatuh', 0)
|
||||
setItem('fzUserId', data.fzUserId)
|
||||
setItem("USERNAME", data.userName);
|
||||
setItem("roleList", data.sysRole ? data.sysRole : []);
|
||||
setItem("SFRH", data.sfrh);
|
||||
setItem("USERID", data.userId);
|
||||
setItem("PermissionsInfo", data.permissionsInfo);
|
||||
this.commit("user/setMenuList", data.menuList);
|
||||
setItem("menusPermission", data.menuCodeSet);
|
||||
setItem("idEntityCard", data.idEntityCard);
|
||||
this.commit("user/setUserInfo", {
|
||||
token: data.jwtToken,
|
||||
permission: {
|
||||
buttonPermission: ["removeTest", "viewTest"],
|
||||
menus: data.menuCodeSet
|
||||
},
|
||||
menuList: data.menuList,
|
||||
deptList: data.deptList
|
||||
});
|
||||
}
|
||||
// 保存登录时间
|
||||
setTimeStamp();
|
||||
resolve(data);
|
||||
login({
|
||||
userName,
|
||||
password: Base64.encode(password),
|
||||
kaptcha,
|
||||
ssxt: "sgxt"
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.deptList.length === 1) {
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setDeptId", data.deptList);
|
||||
this.commit("user/setUserName", data.userName);
|
||||
setItem("isOatuh", 0);
|
||||
setItem("fzUserId", data.fzUserId);
|
||||
setItem("inDustRialId", data.inDustRialId);
|
||||
setItem("USERNAME", data.userName);
|
||||
setItem("roleList", data.sysRole ? data.sysRole : []);
|
||||
setItem("SFRH", data.sfrh);
|
||||
setItem("USERID", data.userId);
|
||||
setItem("PermissionsInfo", data.permissionsInfo);
|
||||
this.commit("user/setMenuList", data.menuList);
|
||||
setItem("menusPermission", data.menuCodeSet);
|
||||
setItem("idEntityCard", data.idEntityCard);
|
||||
this.commit("user/setUserInfo", {
|
||||
token: data.jwtToken,
|
||||
permission: {
|
||||
buttonPermission: ["removeTest", "viewTest"],
|
||||
menus: data.menuCodeSet
|
||||
},
|
||||
menuList: data.menuList,
|
||||
deptList: data.deptList
|
||||
});
|
||||
}
|
||||
// 保存登录时间
|
||||
setTimeStamp();
|
||||
resolve(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
@ -124,21 +119,22 @@ export default {
|
||||
*单点登录
|
||||
*/
|
||||
oatuhLogin(ctx, userInfo) {
|
||||
const { token, systemId, } = userInfo;
|
||||
const { token, systemId } = userInfo;
|
||||
return new Promise((resolve, reject) => {
|
||||
unifiedLogin({ token, systemId }).then((data) => {
|
||||
unifiedLogin({ token, systemId, ssxt: "sgxt" }).then((data) => {
|
||||
if (data.deptList.length === 1) {
|
||||
this.commit("user/setToken", data.jwtToken);
|
||||
this.commit("user/setDeptId", data.deptList);
|
||||
this.commit("user/setUserName", data.userName);
|
||||
setItem("USERNAME", data.userName);
|
||||
setItem('fzUserId', data.fzUserId)
|
||||
setItem("fzUserId", data.fzUserId);
|
||||
setItem("inDustRialId", data.inDustRialId);
|
||||
setItem("SFRH", data.sfrh);
|
||||
setItem("USERID", data.userId);
|
||||
setItem("PermissionsInfo", data.permissionsInfo);
|
||||
this.commit("user/setMenuList", data.menuList);
|
||||
setItem("menusPermission", data.menuCodeSet);
|
||||
setItem('isOatuh', 1)
|
||||
setItem("isOatuh", 1);
|
||||
setItem("idEntityCard", data.idEntityCard);
|
||||
this.commit("user/setUserInfo", {
|
||||
token: data.jwtToken,
|
||||
@ -153,10 +149,9 @@ export default {
|
||||
// 保存登录时间
|
||||
setTimeStamp();
|
||||
resolve(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
}).catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@ -214,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");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,29 +23,18 @@ class AudioPlayerClass {
|
||||
this.audioPlayer = new Audio(audioPath);
|
||||
this.audioPlayer.loop = loop; // 设置循环播放
|
||||
|
||||
// 监听音频加载完成事件
|
||||
this.audioPlayer.addEventListener('canplaythrough', () => {
|
||||
console.log('音频加载完成,可以播放');
|
||||
this.isLoaded = true;
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
// 监听错误事件
|
||||
this.audioPlayer.addEventListener('error', (error) => {
|
||||
console.error('音频加载错误:', error);
|
||||
console.error('错误代码:', error.code);
|
||||
console.error('音频网络状态:', this.audioPlayer.networkState);
|
||||
console.error('音频就绪状态:', this.audioPlayer.readyState);
|
||||
reject(error);
|
||||
});
|
||||
|
||||
// 预加载音频
|
||||
console.log('开始预加载音频...');
|
||||
this.audioPlayer.load();
|
||||
console.log('音频预加载请求已发送');
|
||||
} catch (error) {
|
||||
console.error('初始化音频播放器失败:', error);
|
||||
console.error('错误详情:', error.stack);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
@ -79,26 +68,19 @@ class AudioPlayerClass {
|
||||
this.audioPlayer.play()
|
||||
.then(() => {
|
||||
this.isPlaying = true;
|
||||
console.log('音频播放成功');
|
||||
resolve(true);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.name === 'NotAllowedError') {
|
||||
console.error('播放被浏览器自动播放策略阻止,需要用户交互后才能播放');
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
.catch(error => reject(error));
|
||||
}, 0);
|
||||
} else {
|
||||
this.audioPlayer.play()
|
||||
.then(() => {
|
||||
this.isPlaying = true;
|
||||
console.log('音频播放成功');
|
||||
resolve(true);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.name === 'NotAllowedError') {
|
||||
console.error('播放被浏览器自动播放策略阻止,需要用户交互后才能播放');
|
||||
// 浏览器自动播放策略阻止,静默忽略
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
@ -117,7 +99,6 @@ class AudioPlayerClass {
|
||||
if (this.audioPlayer) {
|
||||
this.audioPlayer.pause();
|
||||
this.isPlaying = false;
|
||||
console.log('音频已暂停');
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +148,6 @@ class AudioPlayerClass {
|
||||
this.audioPlayer = null;
|
||||
this.isLoaded = false;
|
||||
this.isPlaying = false;
|
||||
console.log('音频播放器已销毁');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { ref, toRefs, isRef } from 'vue';
|
||||
import { getSysDictByCode, fzdict } from '@/api/sysDict' //引入封装数字字典接口
|
||||
import { ref, toRefs, isRef } from "vue";
|
||||
import { getSysDictByCode, fzdict } from "@/api/sysDict"; //引入封装数字字典接口
|
||||
|
||||
import { getLocalDic } from "@/utils/localDic/index.js"
|
||||
import { getLocalDic } from "@/utils/localDic/index.js";
|
||||
/**
|
||||
* 获取字典数据
|
||||
*/
|
||||
let list = []
|
||||
let list = [];
|
||||
/** 是否取本地字典 (需要本地加载就加这里,不需要就删除) */
|
||||
export function isLocalDict(dictCode) {
|
||||
let localDicObj = {
|
||||
@ -14,10 +14,9 @@ export function isLocalDict(dictCode) {
|
||||
D_GS_BQ_DJ: true, // "岗哨系统标签管理标签等级"
|
||||
D_GS_SSYJ: true, // "岗哨系统四色预警"
|
||||
D_BZ_SF: true, // "是否"
|
||||
BD_BK_CLYJBQ: true, // "车辆预警标签"
|
||||
D_YJXX_CZCSLX: true, //常控处置措施类型
|
||||
}
|
||||
return localDicObj[dictCode]
|
||||
BD_BK_CLYJBQ: true // "车辆预警标签"
|
||||
};
|
||||
return localDicObj[dictCode];
|
||||
}
|
||||
export function getDict(...args) {
|
||||
const res = ref({});
|
||||
@ -26,32 +25,32 @@ export function getDict(...args) {
|
||||
res.value[d] = [];
|
||||
// 本地字典拦截,如果本地字典存在,则使用本地字典,否则使用远程字典
|
||||
if (isLocalDict(d) && getLocalDic(d)) {
|
||||
res.value[d] = getLocalDic(d)
|
||||
res.value[d] = getLocalDic(d);
|
||||
} else {
|
||||
|
||||
getSysDictByCode({
|
||||
dictCode: d
|
||||
}).then(result => {
|
||||
result = result || {}
|
||||
result.itemList = Array.isArray(result.itemList) ? result.itemList : []
|
||||
result.itemList.forEach(p => {
|
||||
p.label = p.zdmc
|
||||
p.value = p.dm
|
||||
p.id = p.dm
|
||||
p.elTagType = p.dictType
|
||||
}).then((result) => {
|
||||
result = result || {};
|
||||
result.itemList = Array.isArray(result.itemList)
|
||||
? result.itemList
|
||||
: [];
|
||||
result.itemList.forEach((p) => {
|
||||
p.label = p.zdmc;
|
||||
p.value = p.dm;
|
||||
p.id = p.dm;
|
||||
p.elTagType = p.dictType;
|
||||
if (p?.itemList && p.itemList?.length > 0) {
|
||||
getChildren(p)
|
||||
getChildren(p);
|
||||
}
|
||||
p.children = p.itemList
|
||||
})
|
||||
res.value[d] = result.itemList
|
||||
p.children = p.itemList;
|
||||
});
|
||||
res.value[d] = result.itemList;
|
||||
//
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
return toRefs(res.value);
|
||||
})()
|
||||
})();
|
||||
}
|
||||
export function getFzDict(...args) {
|
||||
const res = ref({});
|
||||
@ -64,7 +63,7 @@ export function getFzDict(...args) {
|
||||
} else {
|
||||
fzdict({
|
||||
dictLabel: d
|
||||
}).then(result => {
|
||||
}).then((result) => {
|
||||
result = result || {};
|
||||
// result.itemList = Array.isArray(result.itemList) ? result.itemList : [];
|
||||
// result.itemList.forEach(p => {
|
||||
@ -79,26 +78,25 @@ export function getFzDict(...args) {
|
||||
// });
|
||||
// console.log(res.value);
|
||||
|
||||
res.value[d] = result
|
||||
res.value[d] = result;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 使用toRefs确保返回的是响应式对象
|
||||
return toRefs(res.value);
|
||||
})()
|
||||
|
||||
})();
|
||||
}
|
||||
export function getChildren(item) {
|
||||
item.label = item.zdmc
|
||||
item.value = item.dm
|
||||
item.id = item.dm
|
||||
item.label = item.zdmc;
|
||||
item.value = item.dm;
|
||||
item.id = item.dm;
|
||||
if (item.itemList && item.itemList.length > 0) {
|
||||
item.itemList.forEach(v => {
|
||||
getChildren(v)
|
||||
})
|
||||
item.itemList.forEach((v) => {
|
||||
getChildren(v);
|
||||
});
|
||||
}
|
||||
item.children = item.itemList
|
||||
item.children = item.itemList;
|
||||
}
|
||||
/**
|
||||
* 设置级联选择器回显
|
||||
@ -106,17 +104,17 @@ export function getChildren(item) {
|
||||
* @param {*} array 级联数据树
|
||||
* @param {*} childDeptList 子集变量
|
||||
*/
|
||||
export function setCascader(id, array, childDeptList = 'childDeptList', fun) {
|
||||
export function setCascader(id, array, childDeptList = "childDeptList", fun) {
|
||||
if (array) {
|
||||
array.forEach(item => {
|
||||
array.forEach((item) => {
|
||||
if (item.childDeptList && item.id != id) {
|
||||
setCascader(id, item.childDeptList, childDeptList, fun)
|
||||
setCascader(id, item.childDeptList, childDeptList, fun);
|
||||
} else if (item.childDeptList && item.id == id) {
|
||||
fun(item)
|
||||
fun(item);
|
||||
} else if (!item.childDeptList && item.id == id) {
|
||||
fun(item)
|
||||
fun(item);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -127,58 +125,64 @@ export function setCascader(id, array, childDeptList = 'childDeptList', fun) {
|
||||
*/
|
||||
export function IdCard(IdCard, type) {
|
||||
let user = {
|
||||
birthday: '',
|
||||
sex: '',
|
||||
age: ''
|
||||
}
|
||||
if (type === 1 || type == 'all') {
|
||||
birthday: "",
|
||||
sex: "",
|
||||
age: ""
|
||||
};
|
||||
if (type === 1 || type == "all") {
|
||||
//获取出生日期
|
||||
let birthday = IdCard.substring(6, 10) + "-" + IdCard.substring(10, 12) + "-" + IdCard.substring(12, 14)
|
||||
if (type == 'all') {
|
||||
user.birthday = birthday
|
||||
let birthday =
|
||||
IdCard.substring(6, 10) +
|
||||
"-" +
|
||||
IdCard.substring(10, 12) +
|
||||
"-" +
|
||||
IdCard.substring(12, 14);
|
||||
if (type == "all") {
|
||||
user.birthday = birthday;
|
||||
} else {
|
||||
return birthday
|
||||
return birthday;
|
||||
}
|
||||
}
|
||||
if (type === 2 || type == 'all') {
|
||||
if (type === 2 || type == "all") {
|
||||
//获取性别
|
||||
if (parseInt(IdCard.substr(16, 1)) % 2 === 1) {
|
||||
if (type == 'all') {
|
||||
user.sex = '男'
|
||||
if (type == "all") {
|
||||
user.sex = "男";
|
||||
} else {
|
||||
return "男女"
|
||||
return "男";
|
||||
}
|
||||
} else {
|
||||
if (type == 'all') {
|
||||
user.sex = '女'
|
||||
if (type == "all") {
|
||||
user.sex = "女";
|
||||
} else {
|
||||
return "女"
|
||||
return "女";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type === 3 || type == 'all') {
|
||||
if (type === 3 || type == "all") {
|
||||
//获取年龄
|
||||
var ageDate = new Date()
|
||||
var month = ageDate.getMonth() + 1
|
||||
var day = ageDate.getDate()
|
||||
var age = ageDate.getFullYear() - IdCard.substring(6, 10) - 1
|
||||
if (IdCard.substring(10, 12) < month || IdCard.substring(10, 12) === month && IdCard.substring(12, 14) <= day) {
|
||||
age++
|
||||
var ageDate = new Date();
|
||||
var month = ageDate.getMonth() + 1;
|
||||
var day = ageDate.getDate();
|
||||
var age = ageDate.getFullYear() - IdCard.substring(6, 10) - 1;
|
||||
if (
|
||||
IdCard.substring(10, 12) < month ||
|
||||
(IdCard.substring(10, 12) === month && IdCard.substring(12, 14) <= day)
|
||||
) {
|
||||
age++;
|
||||
}
|
||||
if (age <= 0) {
|
||||
age = 1
|
||||
age = 1;
|
||||
}
|
||||
if (type == 'all') {
|
||||
user.age = age
|
||||
if (type == "all") {
|
||||
user.age = age;
|
||||
} else {
|
||||
return age
|
||||
return age;
|
||||
}
|
||||
|
||||
}
|
||||
return user
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*翻译字典数据
|
||||
* @export
|
||||
@ -186,14 +190,14 @@ export function IdCard(IdCard, type) {
|
||||
* @param {*} array
|
||||
*/
|
||||
export function getDictValue(dm, array) {
|
||||
let item = array.value.find(item => {
|
||||
let item = array.value.find((item) => {
|
||||
if (item.value) {
|
||||
return item.value == dm;
|
||||
} else if (item.dm) {
|
||||
return item.dm == dm;
|
||||
}
|
||||
})
|
||||
return item ? item.label : ""
|
||||
});
|
||||
return item ? item.label : "";
|
||||
}
|
||||
|
||||
/** 获取多个字典值(一个值也可以) 字典内容 value-label
|
||||
@ -201,15 +205,15 @@ export function getDictValue(dm, array) {
|
||||
* @param {Array} dict 字典内容
|
||||
*/
|
||||
export function getMultiDictVal(values, dict) {
|
||||
if (typeof values === 'string' && values?.length) values = values.split(',')
|
||||
if (!Array.isArray(values)) return ''
|
||||
if (isRef(dict)) dict = dict.value
|
||||
if (!Array.isArray(dict)) return ''
|
||||
if (typeof values === "string" && values?.length) values = values.split(",");
|
||||
if (!Array.isArray(values)) return "";
|
||||
if (isRef(dict)) dict = dict.value;
|
||||
if (!Array.isArray(dict)) return "";
|
||||
|
||||
return values.map(v => {
|
||||
const item = dict.find(item => item.value === v);
|
||||
return item ? item.label : v;
|
||||
}).join(',');
|
||||
return values
|
||||
.map((v) => {
|
||||
const item = dict.find((item) => item.value === v);
|
||||
return item ? item.label : v;
|
||||
})
|
||||
.join(",");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,10 +6,62 @@ export function getLocalDic(key) {
|
||||
let dicobj = {
|
||||
/** "岗哨系统重点人员预警等级" */
|
||||
D_GS_ZDR_YJDJ: [
|
||||
{ "itemList": null, "id": "01", "zdId": 59588112, "zdbh": "D_GS_ZDR_YJDJ", "zdmc": "一级", "dm": "01", "py": "YJ", "px": 1, "bz": "", "label": "一级", "value": "01", "children": null },
|
||||
{ "itemList": null, "id": "02", "zdId": 59588112, "zdbh": "D_GS_ZDR_YJDJ", "zdmc": "二级", "dm": "02", "py": "EJ", "px": 2, "bz": "", "label": "二级", "value": "02", "children": null },
|
||||
{ "itemList": null, "id": "03", "zdId": 59588112, "zdbh": "D_GS_ZDR_YJDJ", "zdmc": "三级", "dm": "03", "py": "SJ", "px": 3, "bz": "", "label": "三级", "value": "03", "children": null },
|
||||
{ "itemList": null, "id": "04", "zdId": 59588112, "zdbh": "D_GS_ZDR_YJDJ", "zdmc": "四级", "dm": "04", "py": "SJ", "px": 4, "bz": "", "label": "四级", "value": "04", "children": null }
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "01",
|
||||
"zdId": 59588112,
|
||||
"zdbh": "D_GS_ZDR_YJDJ",
|
||||
"zdmc": "一级",
|
||||
"dm": "01",
|
||||
"py": "YJ",
|
||||
"px": 1,
|
||||
"bz": "",
|
||||
"label": "一级",
|
||||
"value": "01",
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "02",
|
||||
"zdId": 59588112,
|
||||
"zdbh": "D_GS_ZDR_YJDJ",
|
||||
"zdmc": "二级",
|
||||
"dm": "02",
|
||||
"py": "EJ",
|
||||
"px": 2,
|
||||
"bz": "",
|
||||
"label": "二级",
|
||||
"value": "02",
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "03",
|
||||
"zdId": 59588112,
|
||||
"zdbh": "D_GS_ZDR_YJDJ",
|
||||
"zdmc": "三级",
|
||||
"dm": "03",
|
||||
"py": "SJ",
|
||||
"px": 3,
|
||||
"bz": "",
|
||||
"label": "三级",
|
||||
"value": "03",
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "04",
|
||||
"zdId": 59588112,
|
||||
"zdbh": "D_GS_ZDR_YJDJ",
|
||||
"zdmc": "四级",
|
||||
"dm": "04",
|
||||
"py": "SJ",
|
||||
"px": 4,
|
||||
"bz": "",
|
||||
"label": "四级",
|
||||
"value": "04",
|
||||
"children": null
|
||||
}
|
||||
],
|
||||
/** 性别 */
|
||||
D_BZ_XB: [
|
||||
@ -235,66 +287,8 @@ export function getLocalDic(key) {
|
||||
"value": "1",
|
||||
"children": null
|
||||
}
|
||||
],
|
||||
]
|
||||
/** 常控处置措施类型 */
|
||||
D_YJXX_CZCSLX: [
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "01",
|
||||
"zdId": 59589206,
|
||||
"zdbh": "D_YJXX_CZCSLX",
|
||||
"zdmc": "抓捕",
|
||||
"dm": "01",
|
||||
"py": "ZP",
|
||||
"px": 1,
|
||||
"bz": "",
|
||||
"label": "抓捕",
|
||||
"value": "01",
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "02",
|
||||
"zdId": 59589206,
|
||||
"zdbh": "D_YJXX_CZCSLX",
|
||||
"zdmc": "管控",
|
||||
"dm": "02",
|
||||
"py": "GK",
|
||||
"px": 2,
|
||||
"bz": "",
|
||||
"label": "管控",
|
||||
"value": "02",
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "03",
|
||||
"zdId": 59589206,
|
||||
"zdbh": "D_YJXX_CZCSLX",
|
||||
"zdmc": "经营",
|
||||
"dm": "03",
|
||||
"py": "JY",
|
||||
"px": 3,
|
||||
"bz": "",
|
||||
"label": "经营",
|
||||
"value": "03",
|
||||
"children": null
|
||||
},
|
||||
{
|
||||
"itemList": null,
|
||||
"id": "04",
|
||||
"zdId": 59589206,
|
||||
"zdbh": "D_YJXX_CZCSLX",
|
||||
"zdmc": "关注",
|
||||
"dm": "04",
|
||||
"py": "GZ",
|
||||
"px": 4,
|
||||
"bz": "",
|
||||
"label": "关注",
|
||||
"value": "04",
|
||||
"children": null
|
||||
}
|
||||
],
|
||||
}
|
||||
return dicobj[key]
|
||||
};
|
||||
return dicobj[key];
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -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) {
|
||||
if (deptBizType == '23') {
|
||||
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);
|
||||
} else {
|
||||
result.push(...route.children);
|
||||
}
|
||||
// 有 JS_999999 角色:只排除 /internalAuditor
|
||||
filteredChildren = route.children.filter(child => !excludePathsForBiz23WithRole.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);
|
||||
}
|
||||
// 其他:排除 /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);
|
||||
}
|
||||
// 非 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import ImageCompressor from "image-compressor.js";
|
||||
|
||||
// 生成10位数的随机数
|
||||
@ -13,23 +11,34 @@ export function generateRandom10Digits() {
|
||||
// 随机颜色 - 把16进制的颜色换成rgba格式
|
||||
export function choseRbgb(color, opcity) {
|
||||
if (color) {
|
||||
return 'rgba(' + parseInt('0x' + color.slice(1, 3)) + ',' + parseInt('0x' + color.slice(3, 5)) + ',' + parseInt('0x' + color.slice(5, 7)) + ',' + opcity + ')'
|
||||
return (
|
||||
"rgba(" +
|
||||
parseInt("0x" + color.slice(1, 3)) +
|
||||
"," +
|
||||
parseInt("0x" + color.slice(3, 5)) +
|
||||
"," +
|
||||
parseInt("0x" + color.slice(5, 7)) +
|
||||
"," +
|
||||
opcity +
|
||||
")"
|
||||
);
|
||||
} else {
|
||||
let r = Math.floor(Math.random() * 256)
|
||||
let g = Math.floor(Math.random() * 256)
|
||||
let b = Math.floor(Math.random() * 256)
|
||||
let a = opcity ? opcity : 1
|
||||
return `rgba(${r},${g},${b},${a})`
|
||||
let r = Math.floor(Math.random() * 256);
|
||||
let g = Math.floor(Math.random() * 256);
|
||||
let b = Math.floor(Math.random() * 256);
|
||||
let a = opcity ? opcity : 1;
|
||||
return `rgba(${r},${g},${b},${a})`;
|
||||
}
|
||||
}
|
||||
|
||||
// 随机十六进制颜色
|
||||
export function randomHexColor() { // 随机生成十六进制颜色
|
||||
export function randomHexColor() {
|
||||
// 随机生成十六进制颜色
|
||||
var hex = Math.floor(Math.random() * 16777216).toString(16);
|
||||
while (hex.length < 6) {
|
||||
hex = '0' + hex;
|
||||
hex = "0" + hex;
|
||||
}
|
||||
return '#' + hex;
|
||||
return "#" + hex;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,23 +56,30 @@ export function compressImage(file, quality = 0.6) {
|
||||
},
|
||||
error(e) {
|
||||
reject("图片压缩失败,请稍后再试");
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// 今天周几
|
||||
export function weekValidate() {
|
||||
let week = new Date().getDay()
|
||||
let weekenday = ''
|
||||
let week = new Date().getDay();
|
||||
let weekenday = "";
|
||||
switch (week) {
|
||||
case 0: return weekenday = '星期日'
|
||||
case 1: return weekenday = '星期一'
|
||||
case 2: return weekenday = '星期二'
|
||||
case 3: return weekenday = '星期三'
|
||||
case 4: return weekenday = '星期四'
|
||||
case 5: return weekenday = '星期五'
|
||||
case 6: return weekenday = '星期六'
|
||||
case 0:
|
||||
return (weekenday = "星期日");
|
||||
case 1:
|
||||
return (weekenday = "星期一");
|
||||
case 2:
|
||||
return (weekenday = "星期二");
|
||||
case 3:
|
||||
return (weekenday = "星期三");
|
||||
case 4:
|
||||
return (weekenday = "星期四");
|
||||
case 5:
|
||||
return (weekenday = "星期五");
|
||||
case 6:
|
||||
return (weekenday = "星期六");
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,45 +102,44 @@ export function formatDuring(mss) {
|
||||
|
||||
// 转换时间格式
|
||||
export function timeValidate(date, type) {
|
||||
const time = date ? new Date(date) : new Date()
|
||||
const yyyy = time.getFullYear()
|
||||
const MM = (time.getMonth() + 1).toString().padStart(2, 0)
|
||||
const dd = time.getDate().toString().padStart(2, '0')
|
||||
const hh = time.getHours().toString().padStart(2, '0')
|
||||
const mm = time.getMinutes().toString().padStart(2, '0')
|
||||
const ss = time.getSeconds().toString().padStart(2, '0')
|
||||
const time = date ? new Date(date) : new Date();
|
||||
const yyyy = time.getFullYear();
|
||||
const MM = (time.getMonth() + 1).toString().padStart(2, 0);
|
||||
const dd = time.getDate().toString().padStart(2, "0");
|
||||
const hh = time.getHours().toString().padStart(2, "0");
|
||||
const mm = time.getMinutes().toString().padStart(2, "0");
|
||||
const ss = time.getSeconds().toString().padStart(2, "0");
|
||||
|
||||
if (type == 'ymd') {
|
||||
if (type == "ymd") {
|
||||
return `${yyyy}-${MM}-${dd}`;
|
||||
}
|
||||
if (type == 'md') {
|
||||
return `${MM}.${dd}`
|
||||
if (type == "md") {
|
||||
return `${MM}.${dd}`;
|
||||
}
|
||||
if (type == 'td') {
|
||||
return `${yyyy}年${MM}月${dd}日`
|
||||
if (type == "td") {
|
||||
return `${yyyy}年${MM}月${dd}日`;
|
||||
}
|
||||
if (type == 'ny') {
|
||||
return `${yyyy}年${MM}月`
|
||||
if (type == "ny") {
|
||||
return `${yyyy}年${MM}月`;
|
||||
}
|
||||
if (type == 'yd') {
|
||||
return `${yyyy}`
|
||||
if (type == "yd") {
|
||||
return `${yyyy}`;
|
||||
}
|
||||
if (type == 'ym') {
|
||||
return MM
|
||||
if (type == "ym") {
|
||||
return MM;
|
||||
}
|
||||
if (type == 'rm') {
|
||||
return dd
|
||||
if (type == "rm") {
|
||||
return dd;
|
||||
}
|
||||
if (type == 'mm') {
|
||||
return `${yyyy}${MM}${dd}${hh}${mm}${ss}`
|
||||
if (type == "mm") {
|
||||
return `${yyyy}${MM}${dd}${hh}${mm}${ss}`;
|
||||
}
|
||||
if (type == 'ydm') {
|
||||
return `${yyyy}年${MM}月${dd}日${hh}时${mm}分${ss}秒`
|
||||
if (type == "ydm") {
|
||||
return `${yyyy}年${MM}月${dd}日${hh}时${mm}分${ss}秒`;
|
||||
}
|
||||
return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}`
|
||||
return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}`;
|
||||
}
|
||||
|
||||
|
||||
export function timeSlotChange(val) {
|
||||
let startTime, endTime;
|
||||
let now = new Date(); //当前日期
|
||||
@ -132,89 +147,93 @@ export function timeSlotChange(val) {
|
||||
let nowDay = now.getDate(); //当前日
|
||||
let nowMonth = now.getMonth(); //当前月
|
||||
let nowYear = now.getFullYear(); //当前年
|
||||
let jd = Math.ceil((nowMonth + 1) / 3)
|
||||
let jd = Math.ceil((nowMonth + 1) / 3);
|
||||
switch (val) {
|
||||
case '天':
|
||||
case '日':
|
||||
case "天":
|
||||
case "日":
|
||||
// 设置当天的开始时间(00:00:00)
|
||||
const startDate = new Date();
|
||||
startDate.setHours(0, 0, 0, 0);
|
||||
startTime = timeValidate(startDate, 'ymd');
|
||||
startTime = timeValidate(startDate, "ymd");
|
||||
|
||||
// 设置当天的结束时间(23:59:59)
|
||||
const endDate = new Date();
|
||||
endDate.setHours(23, 59, 59, 999);
|
||||
endTime = timeValidate(endDate, 'ymd');
|
||||
endTime = timeValidate(endDate, "ymd");
|
||||
console.log(startTime, endTime);
|
||||
|
||||
break;
|
||||
case "本周":
|
||||
case "周":
|
||||
startTime = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek)
|
||||
endTime = new Date(nowYear, nowMonth, nowDay + 6 - nowDayOfWeek)
|
||||
startTime = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek);
|
||||
endTime = new Date(nowYear, nowMonth, nowDay + 6 - nowDayOfWeek);
|
||||
|
||||
break;
|
||||
case "本月":
|
||||
case "月":
|
||||
startTime = new Date(nowYear, nowMonth, 1)
|
||||
endTime = new Date(nowYear, nowMonth + 1, 0)
|
||||
startTime = new Date(nowYear, nowMonth, 1);
|
||||
endTime = new Date(nowYear, nowMonth + 1, 0);
|
||||
console.log(startTime, endTime);
|
||||
break;
|
||||
case "本季度":
|
||||
case "季度":
|
||||
startTime = new Date(nowYear, (jd - 1) * 3, 1)
|
||||
endTime = new Date(nowYear, jd * 3, 0)
|
||||
break
|
||||
startTime = new Date(nowYear, (jd - 1) * 3, 1);
|
||||
endTime = new Date(nowYear, jd * 3, 0);
|
||||
break;
|
||||
case "本年":
|
||||
case "年":
|
||||
startTime = new Date(nowYear, 0, 1)
|
||||
endTime = new Date(nowYear, 11, 31)
|
||||
break
|
||||
startTime = new Date(nowYear, 0, 1);
|
||||
endTime = new Date(nowYear, 11, 31);
|
||||
break;
|
||||
}
|
||||
return [timeValidate(startTime, 'ymd'), timeValidate(endTime, 'ymd')]
|
||||
return [timeValidate(startTime, "ymd"), timeValidate(endTime, "ymd")];
|
||||
}
|
||||
|
||||
|
||||
// 获取当前近多少天 7后7天 -7 前五天
|
||||
export function getRecentDay(n) {
|
||||
var currentDate = new Date();
|
||||
var preDate = new Date(currentDate.getTime() + n * 24 * 3600 * 1000)
|
||||
let year = preDate.getFullYear()
|
||||
let mon = preDate.getMonth() + 1
|
||||
let day = preDate.getDate()
|
||||
let s = year + '-' + (mon < 10 ? ('0' + mon) : mon) + '-' + (day < 10 ? ('0' + day) : day)
|
||||
return s
|
||||
var preDate = new Date(currentDate.getTime() + n * 24 * 3600 * 1000);
|
||||
let year = preDate.getFullYear();
|
||||
let mon = preDate.getMonth() + 1;
|
||||
let day = preDate.getDate();
|
||||
let s =
|
||||
year +
|
||||
"-" +
|
||||
(mon < 10 ? "0" + mon : mon) +
|
||||
"-" +
|
||||
(day < 10 ? "0" + day : day);
|
||||
return s;
|
||||
}
|
||||
|
||||
// 获取n近7月 7后7 -7 前
|
||||
export function getnRencebtMonth(n) {
|
||||
let date = new Date();
|
||||
date.setMonth(date.getMonth() - n)
|
||||
date.toLocaleDateString()
|
||||
let y = date.getFullYear()
|
||||
let m = date.getMonth() + 1
|
||||
m = m < 10 ? ('0' + m) : m + ''
|
||||
return y + m
|
||||
date.setMonth(date.getMonth() - n);
|
||||
date.toLocaleDateString();
|
||||
let y = date.getFullYear();
|
||||
let m = date.getMonth() + 1;
|
||||
m = m < 10 ? "0" + m : m + "";
|
||||
return y + m;
|
||||
}
|
||||
/**
|
||||
* 数据去重 相同数据值累加
|
||||
* @param {Object} array 数据
|
||||
*/
|
||||
export function setArray(array) {
|
||||
let newArr = []
|
||||
array.forEach(item => {
|
||||
const res = newArr.findIndex(ol => {
|
||||
let newArr = [];
|
||||
array.forEach((item) => {
|
||||
const res = newArr.findIndex((ol) => {
|
||||
//组织机构代码相同 并且报警类别相同
|
||||
return item.ssbmdm == ol.ssbmdm && item.bjlb == ol.bjlb
|
||||
})
|
||||
return item.ssbmdm == ol.ssbmdm && item.bjlb == ol.bjlb;
|
||||
});
|
||||
if (res !== -1) {
|
||||
newArr[res].sl = newArr[res].sl + item.sl
|
||||
newArr[res].sl = newArr[res].sl + item.sl;
|
||||
} else {
|
||||
newArr.push(item)
|
||||
newArr.push(item);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return newArr
|
||||
return newArr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,44 +241,49 @@ export function setArray(array) {
|
||||
* @param {Object} array 数据
|
||||
*/
|
||||
export function hbArray(array, item1, item2, item3) {
|
||||
let newArr = []
|
||||
array.forEach(item => {
|
||||
const res = newArr.findIndex(ol => {
|
||||
let newArr = [];
|
||||
array.forEach((item) => {
|
||||
const res = newArr.findIndex((ol) => {
|
||||
//组织机构代码相同 并且报警类别相同
|
||||
return item.product == ol.product
|
||||
})
|
||||
return item.product == ol.product;
|
||||
});
|
||||
if (res !== -1) {
|
||||
newArr[res][item1] = newArr[res][item1] + item[item1]
|
||||
newArr[res][item2] = newArr[res][item2] + item[item2]
|
||||
newArr[res][item3] = newArr[res][item3] + item[item3]
|
||||
newArr[res][item1] = newArr[res][item1] + item[item1];
|
||||
newArr[res][item2] = newArr[res][item2] + item[item2];
|
||||
newArr[res][item3] = newArr[res][item3] + item[item3];
|
||||
} else {
|
||||
newArr.push(item)
|
||||
newArr.push(item);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return newArr
|
||||
return newArr;
|
||||
}
|
||||
//时间格式
|
||||
export function dateFormat(type, time) {
|
||||
let date
|
||||
let date;
|
||||
if (time) {
|
||||
date = new Date(time);
|
||||
} else {
|
||||
date = new Date();
|
||||
}
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||
let month =
|
||||
date.getMonth() + 1 < 10
|
||||
? "0" + (date.getMonth() + 1)
|
||||
: date.getMonth() + 1;
|
||||
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
let day
|
||||
let minutes =
|
||||
date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||
let seconds =
|
||||
date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||
let day;
|
||||
|
||||
if (type == 'z') {
|
||||
if (type == "z") {
|
||||
//前一天日期
|
||||
day = date.getDate() - 1;
|
||||
day = day < 10 ? "0" + day : day;
|
||||
return `${year}-${month}-${day}`;
|
||||
} else if (type == 'all') {
|
||||
} else if (type == "all") {
|
||||
//格式化日期时间
|
||||
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||
@ -269,42 +293,78 @@ export function dateFormat(type, time) {
|
||||
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
return day
|
||||
return day;
|
||||
}
|
||||
|
||||
//数字超长处理
|
||||
export function handleNum(num) {
|
||||
var data = 0
|
||||
var data = 0;
|
||||
if (num) {
|
||||
try {
|
||||
if (num * 1 > 100000) {
|
||||
data = (num / 10000).toFixed(0) + '万'
|
||||
data = (num / 10000).toFixed(0) + "万";
|
||||
} else {
|
||||
data = (num * 1).toFixed(0)
|
||||
data = (num * 1).toFixed(0);
|
||||
}
|
||||
} catch (error) {
|
||||
data = 0
|
||||
data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* 文件是否是图片
|
||||
* @param {*} val
|
||||
*/
|
||||
export function IS_PNG(val) {
|
||||
return ['bmp', 'jpg', 'png', 'tif', 'gif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo',
|
||||
'eps', 'ai', 'raw', 'wmf', 'webp', 'avif', 'apng'
|
||||
].indexOf(val.toLowerCase()) !== -1
|
||||
return (
|
||||
[
|
||||
"bmp",
|
||||
"jpg",
|
||||
"png",
|
||||
"tif",
|
||||
"gif",
|
||||
"pcx",
|
||||
"tga",
|
||||
"exif",
|
||||
"fpx",
|
||||
"svg",
|
||||
"psd",
|
||||
"cdr",
|
||||
"pcd",
|
||||
"dxf",
|
||||
"ufo",
|
||||
"eps",
|
||||
"ai",
|
||||
"raw",
|
||||
"wmf",
|
||||
"webp",
|
||||
"avif",
|
||||
"apng"
|
||||
].indexOf(val.toLowerCase()) !== -1
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 文件是否是音频
|
||||
* @param {*} val
|
||||
*/
|
||||
export function IS_MP3(val) {
|
||||
return ['mp3', 'wav', 'wma', 'mp2', 'flac', 'midi', 'ra', 'ape', 'aac', 'cda', 'mov'].indexOf(val.toLowerCase()) !==
|
||||
-1
|
||||
return (
|
||||
[
|
||||
"mp3",
|
||||
"wav",
|
||||
"wma",
|
||||
"mp2",
|
||||
"flac",
|
||||
"midi",
|
||||
"ra",
|
||||
"ape",
|
||||
"aac",
|
||||
"cda",
|
||||
"mov"
|
||||
].indexOf(val.toLowerCase()) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,26 +372,39 @@ export function IS_MP3(val) {
|
||||
* @param {*} val
|
||||
*/
|
||||
export function IS_MP4(val) {
|
||||
return ['avi', 'wmv', 'mpeg', 'mp4', 'm4v', 'mov', 'asf', 'fiv', 'f4v', 'mvb', 'rm', '3gp', 'vob'].indexOf(val
|
||||
.toLowerCase()) !== -1
|
||||
return (
|
||||
[
|
||||
"avi",
|
||||
"wmv",
|
||||
"mpeg",
|
||||
"mp4",
|
||||
"m4v",
|
||||
"mov",
|
||||
"asf",
|
||||
"fiv",
|
||||
"f4v",
|
||||
"mvb",
|
||||
"rm",
|
||||
"3gp",
|
||||
"vob"
|
||||
].indexOf(val.toLowerCase()) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function handelArr(arr) {
|
||||
let brr = []
|
||||
let brr = [];
|
||||
if (arr && arr.length > 0) {
|
||||
let obj = {}
|
||||
let obj = {};
|
||||
let coords = "";
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
coords += arr[i] + ","
|
||||
coords += arr[i] + ",";
|
||||
}
|
||||
obj.coords = coords
|
||||
brr.push(obj)
|
||||
obj.coords = coords;
|
||||
brr.push(obj);
|
||||
}
|
||||
return brr
|
||||
return brr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 时间 天数
|
||||
* @param {*} val
|
||||
@ -341,29 +414,31 @@ export function setEchartTime(val) {
|
||||
let arrTime = [];
|
||||
if (val == 0) {
|
||||
for (let i = 0; i < 24; i++) {
|
||||
arrTime.push(i)
|
||||
arrTime.push(i);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < val; i++) {
|
||||
let date1 = new Date(date.getTime() - i * 24 * 60 * 60 * 1000)
|
||||
arrTime.push(_setTime(date1))
|
||||
let date1 = new Date(date.getTime() - i * 24 * 60 * 60 * 1000);
|
||||
arrTime.push(_setTime(date1));
|
||||
}
|
||||
arrTime.reverse()
|
||||
arrTime.reverse();
|
||||
}
|
||||
return arrTime
|
||||
return arrTime;
|
||||
}
|
||||
//设置时间
|
||||
function _setTime(date) {
|
||||
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||
let month =
|
||||
date.getMonth() + 1 < 10
|
||||
? "0" + (date.getMonth() + 1)
|
||||
: date.getMonth() + 1;
|
||||
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||
return `${month}-${day}`;
|
||||
}
|
||||
|
||||
|
||||
//拼接地址
|
||||
export function setAddress(val) {
|
||||
const url = '/mosty-api/mosty-base/minio/image/download/'
|
||||
return url + val
|
||||
const url = "/mosty-api/mosty-base/minio/image/download/";
|
||||
return url + val;
|
||||
}
|
||||
export function getUUid() {
|
||||
var list = [];
|
||||
@ -379,27 +454,31 @@ export function getUUid() {
|
||||
}
|
||||
// 预警等级颜色
|
||||
export const bqYs = (val) => {
|
||||
if (val == '01') {
|
||||
return '#ff0202'
|
||||
} else if (val == '02') {
|
||||
return '#ff8c00'
|
||||
} else if (val == '03') {
|
||||
return '#ffd208ff'
|
||||
} else if (val == '04') {
|
||||
return '#0000ff'
|
||||
if (val == "01") {
|
||||
return "#ff0202";
|
||||
} else if (val == "02") {
|
||||
return "#ff8c00";
|
||||
} else if (val == "03") {
|
||||
return "#ffd208ff";
|
||||
} else if (val == "04") {
|
||||
return "#0000ff";
|
||||
}
|
||||
}
|
||||
};
|
||||
/** 全息档案跳转
|
||||
* @param {string} szhm 身证号
|
||||
*/
|
||||
export function holographicProfileJump(lx, val) {
|
||||
if (!val) return
|
||||
if (lx == 1 || !lx) {
|
||||
const sfzh = val.sfzh || val.rysfzh || val.yjRysfzh
|
||||
window.open(`https://tyyy.lz.dsj.xz/profile/people/person-manage?sfzhm=${sfzh}&from=portal`)
|
||||
if (!val) return;
|
||||
if (lx == 1 || !lx || lx == "01") {
|
||||
const sfzh = val.sfzh || val.rysfzh || val.yjRysfzh;
|
||||
window.open(
|
||||
`https://tyyy.lz.dsj.xz/profile/people/person-manage?sfzhm=${sfzh}&from=portal`
|
||||
);
|
||||
} else {
|
||||
const cph = val.cph || val.yjClcph
|
||||
window.open(`https://tyyy.lz.dsj.xz/profile/car/car-manage?cphm=${cph}&from=portal`)
|
||||
const cph = val.cph || val.yjClcph;
|
||||
window.open(
|
||||
`https://tyyy.lz.dsj.xz/profile/car/car-manage?cphm=${cph}&from=portal`
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -416,6 +495,6 @@ export function getErrMsg(fields, msgObj) {
|
||||
if (!firstErrorField) return;
|
||||
/** 第一个错误字段的内容 @type{<Array>Object} - [message, field, fieldValue] */
|
||||
let firstErrorFieldObj = fields?.[firstErrorField];
|
||||
let errMsg = firstErrorFieldObj?.[0]?.message
|
||||
return errMsg
|
||||
let errMsg = firstErrorFieldObj?.[0]?.message;
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ const btns = ref(['重点人','重点群体'])
|
||||
const active = ref('重点人');
|
||||
const keywords = ref(''); // 搜索关键字
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDQT_ZT,D_BZ_RYBQ,D_GS_ZDQT_FXDJ } = proxy.$dict('D_GS_ZDQT_ZT','D_BZ_RYBQ','D_GS_ZDQT_FXDJ') //获取字典数据
|
||||
const { D_GS_ZDQT_ZT,/* D_BZ_RYBQ, */D_GS_ZDQT_FXDJ } = proxy.$dict('D_GS_ZDQT_ZT',/* 'D_BZ_RYBQ', */'D_GS_ZDQT_FXDJ') //获取字典数据
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
keyCount: 0,
|
||||
|
||||
@ -49,8 +49,16 @@ import { onMounted, getCurrentInstance, ref, reactive } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { setAddress } from '@/utils/tools'
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||
proxy.$dict("D_BZ_SF", "D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX"); //获取字典数据
|
||||
const {
|
||||
// D_BZ_SF,
|
||||
D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX,
|
||||
// D_GS_XS_QTLX
|
||||
} =
|
||||
proxy.$dict(
|
||||
// "D_BZ_SF",
|
||||
"D_BZ_XB", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX"
|
||||
// , "D_GS_XS_QTLX"
|
||||
); //获取字典数据
|
||||
|
||||
// 基础信息
|
||||
const basicInformation = ref(
|
||||
|
||||
@ -4,13 +4,8 @@
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<!-- <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<el-button type="primary" size="small" @click="addEdit('add')">新增</el-button>
|
||||
</template>
|
||||
</PageTitle> -->
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<div class="margTop">
|
||||
<MyTable
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
@ -91,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();
|
||||
|
||||
@ -2,16 +2,13 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<el-button type="primary" size="small" @click="addEdit('add')">新增</el-button>
|
||||
<!-- <el-button type="danger" size="small" @click="handleRow()">批量删除</el-button> -->
|
||||
</template>
|
||||
</PageTitle>
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" >
|
||||
<el-button type="primary" size="small" @click="addEdit('add')">新增</el-button>
|
||||
</Search>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<div class="margTop">
|
||||
<MyTable
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
@ -68,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([]);
|
||||
@ -273,7 +289,7 @@ const deleteRow = (id) =>{
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 240;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -2,20 +2,14 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch">
|
||||
<el-button type="primary" size="small" @click="addEdit('add')">新增</el-button>
|
||||
<!-- <el-button type="danger" size="small" @click="handleRow()">批量删除</el-button> -->
|
||||
</template>
|
||||
</PageTitle>
|
||||
|
||||
</Search>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<div class="margTop" style="padding: 0;">
|
||||
<WarnDataTable :data="pageData.tableData" :columns="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:loading="pageData.tableConfiger.loading" @selection-change="chooseData">
|
||||
<template #bqList="{ row }">
|
||||
<ul>
|
||||
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
||||
@ -25,9 +19,7 @@
|
||||
<template #ryXb="{ row }">
|
||||
<DictTag :tag="false" :value="row.ryXb" :options="D_BZ_XB" />
|
||||
</template>
|
||||
<template #ryJg="{ row }">
|
||||
<DictTag :tag="false" :value="row.ryJg" :options="D_BZ_XZQHDM" />
|
||||
</template>
|
||||
|
||||
<template #ryMz="{ row }">
|
||||
<DictTag :tag="false" :value="row.ryMz" :options="D_BZ_MZ" />
|
||||
</template>
|
||||
@ -52,12 +44,13 @@
|
||||
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link size="small" type="success" @click="handleSend(row.id)">移入</el-link>
|
||||
<el-link size="small" type="success" @click="handleSend(row.id)">移入重点人</el-link>
|
||||
<el-link size="small" type="success" @click="handleMoveToFocus(row.id)">移入关注库</el-link>
|
||||
<el-link size="small" type="primary" @click="addEdit('edit', row)">编辑</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteRow(row.id)" v-if="isShiQzDelet">删除</el-link>
|
||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
</WarnDataTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
@ -73,7 +66,7 @@
|
||||
import { ElMessage } from "element-plus";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.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 "@/views/backOfficeSystem/DeploymentDisposal/mpvPeo/components/addForm.vue";
|
||||
@ -81,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();
|
||||
@ -132,24 +140,25 @@ const pageData = reactive({
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 150,
|
||||
controlsWidth: 340,
|
||||
tableColumn: [
|
||||
{ label: "姓名", prop: "ryXm", width: 150 },
|
||||
{ label: "性别", prop: "ryXb", showSolt: true, width: 100 },
|
||||
{ label: "籍贯", prop: "ryJg", showSolt: true, width: 100 },
|
||||
{ label: "性别", prop: "ryXb", slotName: "ryXb" },
|
||||
{ label: "籍贯", prop: "ryJg", width: 100 },
|
||||
{ label: "身份证", prop: "rySfzh", width: 200 },
|
||||
{ label: "民族", prop: "ryMz", showSolt: true, width: 100 },
|
||||
{ label: "户籍地区划", prop: "hjdQh", showSolt: true, width: 150 },
|
||||
{ label: "户籍派出所", prop: "hjdPcsmc", width: 200 },
|
||||
{ label: "民族", prop: "ryMz", slotName: "ryMz" },
|
||||
{ label: "户籍地区划", prop: "hjdQh", width: 150, slotName: "hjdQh" },
|
||||
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
||||
{ label: "户籍地详址", prop: "hjdXz", width: 200 },
|
||||
{ label: "审核状态", prop: "zdrZt", showSolt: true },
|
||||
{ label: "审核状态", prop: "zdrZt", slotName: "zdrZt" },
|
||||
{ label: "操作", prop: "controls", slotName: "controls", width: 280 },
|
||||
]
|
||||
});
|
||||
const isShiQzDelet = ref(false)
|
||||
onMounted(() => {
|
||||
getList();
|
||||
tabHeightFn();
|
||||
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
|
||||
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
|
||||
if (isShiQz) isShiQzDelet.value = true
|
||||
});
|
||||
|
||||
@ -193,7 +202,14 @@ const handleSend = (id) => {
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
const handleMoveToFocus = (id) => {
|
||||
proxy.$confirm("确定要移至关注库?", "警告", { type: "warning" }).then(() => {
|
||||
qcckPost({ id, rylx: '03' }, "/mosty-gsxt/tbGsxtZdry/rylxyd").then(() => {
|
||||
proxy.$message({ type: "success", message: "移除成功" });
|
||||
getList();
|
||||
});
|
||||
})
|
||||
}
|
||||
const chooseData = (data) => {
|
||||
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
||||
choosList.value = Array.isArray(data) ? data : [];
|
||||
@ -263,7 +279,7 @@ const addEdit = (type, row) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 270;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -19,7 +19,7 @@ import { generateRandom10Digits } from '@/utils/tools'
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_ZFNR_MBLX } = proxy.$dict("D_ZFNR_MBLX")
|
||||
// const { D_ZFNR_MBLX } = proxy.$dict("D_ZFNR_MBLX") // 未使用,已注释
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
:class="activeSection === 'character-section' ? 'active' : ''">背景信息</li>
|
||||
<li @click="scrollToSection('controlInfo-section')"
|
||||
:class="activeSection === 'controlInfo-section' ? 'active' : ''" v-if="!butShow">管控信息</li>
|
||||
<li @click="scrollToSection('featinfo-section')"
|
||||
:class="activeSection === 'featinfo-section' ? 'active' : ''" v-if="!butShow">全要素布控</li>
|
||||
<li @click="scrollToSection('featinfo-section')" :class="activeSection === 'featinfo-section' ? 'active' : ''"
|
||||
v-if="!butShow">全要素布控</li>
|
||||
<li @click="scrollToSection('demandsInfo-section')"
|
||||
:class="activeSection === 'demandsInfo-section' ? 'active' : ''" v-if="!butShow">密切联系人</li>
|
||||
<li @click="scrollToSection('requestInfo-section')"
|
||||
@ -69,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',
|
||||
@ -221,7 +221,7 @@ const submit = async () => {
|
||||
|
||||
// 关闭
|
||||
const close = () => {
|
||||
if (route.query.id) {
|
||||
if (route.query.id) {
|
||||
const query = { ...route.query };
|
||||
delete query.id;
|
||||
router.replace({ query });
|
||||
|
||||
@ -1,48 +1,21 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
|
||||
</template>
|
||||
<div class="flex just-center">
|
||||
<el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm"
|
||||
@click="handleApplication(it)">{{ it.zdmc }}</el-button>
|
||||
</div>
|
||||
</el-popover> -->
|
||||
<!-- <el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)">指定分配</el-button>
|
||||
</template>
|
||||
<div>
|
||||
<el-input readonly v-model="obj.fpmc" @click="chooseUserVisible = true" placeholder="请选择民警"></el-input>
|
||||
<div class="flex just-center mt10">
|
||||
<el-button @click="(visiblefp = false), (obj = {})" size="small">取消</el-button>
|
||||
<el-button type="primary" @click="handlefp" size="small">分配</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover> -->
|
||||
<!-- <el-button size="small" type="primary" @click="handleZxs">转线索</el-button> -->
|
||||
<!-- <el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
|
||||
<!-- <el-button size="small" type="primary">导入</el-button> -->
|
||||
<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>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</PageTitle>
|
||||
</Search>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<div class="margTop" style="padding: 0;">
|
||||
<WarnDataTable :data="pageData.tableData" :columns="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:loading="pageData.tableConfiger.loading" @selection-change="chooseData">
|
||||
<template #bqList="{ row }">
|
||||
<ul>
|
||||
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
||||
@ -80,7 +53,8 @@
|
||||
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link size="small" type="success" @click="handleremove(row.id)">移除</el-link>
|
||||
<el-link size="small" type="success" @click="handleremove(row.id)">移入基础库</el-link>
|
||||
<el-link size="small" type="success" @click="handleZdr(row.id)">移入重点人</el-link>
|
||||
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||
@click="handleSend(row.id)">送审</el-link>
|
||||
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||
@ -88,14 +62,14 @@
|
||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
</WarnDataTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></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" />
|
||||
@ -110,18 +84,20 @@ import { ElMessage } from "element-plus";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
import ZxsForm from "./components/zxsForm.vue";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.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();
|
||||
@ -174,28 +150,29 @@ const pageData = reactive({
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 250,
|
||||
controlsWidth: 280,
|
||||
tableColumn: [
|
||||
{ label: "姓名", prop: "ryXm",width: 100 },
|
||||
{ label: "性别", prop: "ryXb", showSolt: true, width: 80 },
|
||||
{ label: "姓名", prop: "ryXm", width: 100 },
|
||||
{ label: "性别", prop: "ryXb", slotName: "ryXb", width: 80 },
|
||||
{ label: "身份证", prop: "rySfzh", width: 170 },
|
||||
{ label: "民族", prop: "ryMz", showSolt: true, width: 80 },
|
||||
{ label: "民族", prop: "ryMz", slotName: "ryMz", width: 80 },
|
||||
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
||||
{ label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true },
|
||||
{ label: "标签", prop: "bqList", slotName: "bqList", showOverflowTooltip: true },
|
||||
{ label: "管辖单位", prop: "gxSsbmmc" },
|
||||
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true,showSolt: true, width: 100 },
|
||||
{ label: "审核状态", prop: "zdrZt", showSolt: true, width: 100 },
|
||||
{ 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: 300 },
|
||||
]
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
tabHeightFn();
|
||||
tabHeightFn();
|
||||
if (route.query.id) {
|
||||
addEdit('x', {
|
||||
id: route.query.id
|
||||
})
|
||||
}else{
|
||||
} else {
|
||||
getList();
|
||||
}
|
||||
});
|
||||
@ -221,7 +198,7 @@ const getList = () => {
|
||||
pageData.tableConfiger.loading = true;
|
||||
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
|
||||
// rylx: '01',
|
||||
let data = {...pageData.pageConfiger, ...queryFrom.value,rylx: '03' };
|
||||
let data = { ...pageData.pageConfiger, ...queryFrom.value, rylx: '03' };
|
||||
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
|
||||
pageData.tableData = res.records || [];
|
||||
pageData.total = res.total;
|
||||
@ -250,6 +227,14 @@ const handleremove = (id) => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleZdr = (id) => {
|
||||
proxy.$confirm("确定要移至重点人?", "警告", { type: "warning" }).then(() => {
|
||||
qcckPost({ id, rylx: '01' }, "/mosty-gsxt/tbGsxtZdry/rylxyd").then(() => {
|
||||
proxy.$message({ type: "success", message: "移除成功" });
|
||||
getList();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const chooseData = (data) => {
|
||||
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
||||
@ -328,7 +313,7 @@ const addEdit = (type, row) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ import { ref, getCurrentInstance, onMounted } from 'vue'
|
||||
import GdMap from "@/components/GdMap/index.vue";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_ZJLX } = proxy.$dict("D_BZ_ZJLX")
|
||||
// const { D_BZ_ZJLX } = proxy.$dict("D_BZ_ZJLX") // 未使用,已注释
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = ref({
|
||||
|
||||
@ -25,7 +25,7 @@ import CaseLodig from "../component/caseLodig.vue";
|
||||
import { tbGsxtZdryAjxxSaveOrUpdateAjxx, tbGsxtZdryAjxx, tbGsxtZdryAjxxselectAjxx } from '@/api/zdr.js'
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); //获取字典数据
|
||||
// const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); // 未使用,已注释
|
||||
const chooseMarksVisible = ref(false)
|
||||
const props = defineProps({
|
||||
dataList: {
|
||||
|
||||
@ -2,10 +2,21 @@
|
||||
<div>
|
||||
<div class="headClass" style="">
|
||||
<h3>密切联系人</h3>
|
||||
<el-button type="primary" @click="openDialog('新增密切联系人', {}, true)" v-if="showBut">新增</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="openDialog('新增密切联系人', {}, true)"
|
||||
v-if="showBut"
|
||||
>新增</el-button
|
||||
>
|
||||
</div>
|
||||
<div class="headSelect">
|
||||
<el-form :model="formData" :inline="true" ref="formRef" :rules="rulesForm" class="form-inline">
|
||||
<el-form
|
||||
:model="formData"
|
||||
:inline="true"
|
||||
ref="formRef"
|
||||
:rules="rulesForm"
|
||||
class="form-inline"
|
||||
>
|
||||
<el-form-item label="身份证号码">
|
||||
<el-input v-model="formData.rySfzh" placeholder="请输入身份证号码" />
|
||||
</el-form-item>
|
||||
@ -16,177 +27,216 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<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 #dygx="{ row }">
|
||||
<DictTag :tag="false" :value="row.dygx" :options="D_BZ_QSGXDM" />
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
|
||||
<el-link type="danger" @click="openDialog('修改密切联系人', row, false)">修改</el-link>
|
||||
<el-link type="danger" @click="openDialog('修改密切联系人', row, false)"
|
||||
>修改</el-link
|
||||
>
|
||||
</template>
|
||||
</MyTable>
|
||||
<diaLogForm v-model="dialogVisible" :data="diaLogRuleForm" @submit="addPersonOrModifica" :title="Tips"
|
||||
:dict="{ D_BZ_QSGXDM }">
|
||||
<diaLogForm
|
||||
v-model="dialogVisible"
|
||||
:data="diaLogRuleForm"
|
||||
@submit="addPersonOrModifica"
|
||||
:title="Tips"
|
||||
:dict="{ D_BZ_QSGXDM }"
|
||||
>
|
||||
</diaLogForm>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { identityCardRule } from "@/utils/rules"
|
||||
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
|
||||
import { identityCardRule } from "@/utils/rules";
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
watch,
|
||||
toRaw,
|
||||
getCurrentInstance,
|
||||
onMounted,
|
||||
onUnmounted
|
||||
} from "vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import diaLogForm from "../component/diaLogForm.vue";
|
||||
import { tbZdryClxxUpdate, tbGsxtZdryLxrsaveOrUpdateLxr,tbGsxtZdryLxrselectLxrBy ,tbGsxtZdryLxr} from '@/api/zdr.js'
|
||||
import {
|
||||
tbZdryClxxUpdate,
|
||||
tbGsxtZdryLxrsaveOrUpdateLxr,
|
||||
tbGsxtZdryLxrselectLxrBy,
|
||||
tbGsxtZdryLxr
|
||||
} from "@/api/zdr.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_QSGXDM } = proxy.$dict("D_BZ_QSGXDM"); //获取字典数据
|
||||
const props = defineProps({
|
||||
dataList: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
}, disabled: {
|
||||
default: () => {}
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showBut: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
})
|
||||
const dialogVisible = ref(false)
|
||||
const listData = ref({})
|
||||
const Tips = ref("密切联系人")
|
||||
}
|
||||
});
|
||||
const dialogVisible = ref(false);
|
||||
const listData = ref({});
|
||||
const Tips = ref("密切联系人");
|
||||
// 表格数据
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
tableColumn: [{
|
||||
prop: 'ryXm',
|
||||
label: '人员姓名',
|
||||
}, {
|
||||
prop: 'rySfzh',
|
||||
label: '身份证号码',
|
||||
}, {
|
||||
prop: 'dygx',
|
||||
label: '关系',
|
||||
showSolt: true,
|
||||
}, {
|
||||
prop: 'lxrDh',
|
||||
label: '联系电话',
|
||||
}],
|
||||
tableHeight: '200px',
|
||||
tableColumn: [
|
||||
{
|
||||
prop: "ryXm",
|
||||
label: "人员姓名"
|
||||
},
|
||||
{
|
||||
prop: "rySfzh",
|
||||
label: "身份证号码"
|
||||
},
|
||||
{
|
||||
prop: "dygx",
|
||||
label: "关系",
|
||||
showSolt: true
|
||||
},
|
||||
{
|
||||
prop: "lxrDh",
|
||||
label: "联系电话"
|
||||
}
|
||||
],
|
||||
tableHeight: "200px",
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
border: true,
|
||||
stripe: true,
|
||||
showHeader: true,
|
||||
showIndex: true,
|
||||
indexLabel: '序号',
|
||||
indexLabel: "序号",
|
||||
indexWidth: 60,
|
||||
align: 'center',
|
||||
align: "center",
|
||||
showOverflowTooltip: true,
|
||||
haveControls: !props.disabled
|
||||
},
|
||||
controlsWidth: 200,
|
||||
})
|
||||
controlsWidth: 200
|
||||
});
|
||||
// 表单数据
|
||||
const formData = ref({
|
||||
username: "",
|
||||
ID: ""
|
||||
})
|
||||
const touchIn = ref(true)
|
||||
const rulesForm = ref(identityCardRule({ validator: true }, 'rySfzh'))
|
||||
const diaLogRuleForm = ref({})
|
||||
watch(() => props.dataList, (val) => {
|
||||
if (val) {
|
||||
listData.value = val
|
||||
getContact()
|
||||
}
|
||||
}, { deep: true })
|
||||
});
|
||||
const touchIn = ref(true);
|
||||
const rulesForm = ref(identityCardRule({ validator: true }, "rySfzh"));
|
||||
const diaLogRuleForm = ref({});
|
||||
watch(
|
||||
() => props.dataList,
|
||||
(val) => {
|
||||
if (val) {
|
||||
listData.value = val;
|
||||
getContact();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
// 弹出增加或者修改弹窗
|
||||
const openDialog = (type, formVal, bool) => {
|
||||
touchIn.value = bool
|
||||
dialogVisible.value = true
|
||||
Tips.value = type
|
||||
diaLogRuleForm.value = { ...formVal }
|
||||
}
|
||||
touchIn.value = bool;
|
||||
dialogVisible.value = true;
|
||||
Tips.value = type;
|
||||
diaLogRuleForm.value = { ...formVal };
|
||||
};
|
||||
// 提交表单
|
||||
const addPersonOrModifica = (val) => {
|
||||
if (touchIn.value) {
|
||||
const item = pageData.tableData.findIndex(item => item.rySfzh == val.rySfzh)
|
||||
console.log(pageData.tableData);
|
||||
|
||||
const item = pageData.tableData.findIndex(
|
||||
(item) => item.rySfzh == val.rySfzh
|
||||
);
|
||||
if (item != -1) {
|
||||
proxy.$message({
|
||||
message: '该人员已存在',
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
message: "该人员已存在",
|
||||
type: "warning"
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
const promes = {
|
||||
...val,
|
||||
zdryId: listData.value.id
|
||||
}
|
||||
tbGsxtZdryLxrsaveOrUpdateLxr(promes).then((res) => {
|
||||
proxy.$message({
|
||||
message: '操作成功',
|
||||
type: 'success'
|
||||
})
|
||||
getContact()
|
||||
}).catch((err) => {
|
||||
proxy.$message({
|
||||
message: '操作失败',
|
||||
type: 'error'
|
||||
})
|
||||
});
|
||||
}
|
||||
const delDictItem = (val) => {
|
||||
ElMessageBox.confirm(
|
||||
'是否删除该联系人',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
|
||||
tbGsxtZdryLxr(val).then((res) => {
|
||||
proxy.$message({
|
||||
message: '删除成功',
|
||||
type: 'success'
|
||||
})
|
||||
getContact()
|
||||
}).catch((err) => {
|
||||
|
||||
};
|
||||
tbGsxtZdryLxrsaveOrUpdateLxr(promes)
|
||||
.then((res) => {
|
||||
proxy.$message({
|
||||
message: "操作成功",
|
||||
type: "success"
|
||||
});
|
||||
getContact();
|
||||
})
|
||||
.catch((err) => {
|
||||
proxy.$message({
|
||||
message: "操作失败",
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
};
|
||||
const delDictItem = (val) => {
|
||||
ElMessageBox.confirm("是否删除该联系人", "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
tbGsxtZdryLxr(val)
|
||||
.then((res) => {
|
||||
proxy.$message({
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
getContact();
|
||||
})
|
||||
.catch((err) => {});
|
||||
})
|
||||
.catch(() => {
|
||||
proxy.$message({
|
||||
message: '删除失败',
|
||||
type: 'info',
|
||||
})
|
||||
})
|
||||
}
|
||||
message: "删除失败",
|
||||
type: "info"
|
||||
});
|
||||
});
|
||||
};
|
||||
const getContact = () => {
|
||||
const promes = { zdryId: listData.value.id }
|
||||
const promes = { zdryId: listData.value.id };
|
||||
tbGsxtZdryLxrselectLxrBy(promes).then((res) => {
|
||||
pageData.tableData = res
|
||||
})
|
||||
}
|
||||
pageData.tableData = res;
|
||||
});
|
||||
};
|
||||
const resetForm = () => {
|
||||
formData.value = {}
|
||||
getContact()
|
||||
}
|
||||
formData.value = {};
|
||||
getContact();
|
||||
};
|
||||
const check = () => {
|
||||
if (formData.value.rySfzh) {
|
||||
// 模糊查询:检查身份证号码是否包含输入的内容
|
||||
pageData.tableData = pageData.tableData.filter(item => item.rySfzh && item.rySfzh.includes(formData.value.rySfzh))
|
||||
pageData.tableData = pageData.tableData.filter(
|
||||
(item) => item.rySfzh && item.rySfzh.includes(formData.value.rySfzh)
|
||||
);
|
||||
} else {
|
||||
// 如果输入为空,显示所有数据
|
||||
getContact()
|
||||
getContact();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 抛出数据并验证标签列表不为空
|
||||
const throwData = () => {
|
||||
@ -197,10 +247,10 @@ const throwData = () => {
|
||||
// }
|
||||
resolve(pageData.tableData);
|
||||
});
|
||||
}
|
||||
};
|
||||
defineExpose({
|
||||
throwData
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -211,8 +261,6 @@ defineExpose({
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.left_box {
|
||||
width: 200px;
|
||||
border: 1px solid #c8c8c89a;
|
||||
@ -287,8 +335,6 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// .headClass::after {
|
||||
// content: '';
|
||||
// position: absolute;
|
||||
|
||||
@ -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%" },
|
||||
]);
|
||||
@ -171,17 +171,17 @@ const gettbGsxtZdryUpdate = () => {
|
||||
}
|
||||
elform.value.submit((data) => {
|
||||
tbGsxtZdryUpdate(promes).then((res) => {
|
||||
listQuery.value.ryzp = []
|
||||
proxy.$message({
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
})
|
||||
}).catch((err) => {
|
||||
listQuery.value.ryzp = []
|
||||
proxy.$message({
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
})
|
||||
}).catch((err) => {
|
||||
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
});
|
||||
})
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -3,10 +3,17 @@
|
||||
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch">
|
||||
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</Search>
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<!-- <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left> -->
|
||||
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
|
||||
@ -30,16 +37,11 @@
|
||||
</el-popover>
|
||||
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
|
||||
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
|
||||
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</PageTitle>
|
||||
|
||||
<!-- </template>
|
||||
</PageTitle> -->
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<div class="margTop">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
@ -191,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 },
|
||||
]
|
||||
@ -315,7 +317,7 @@ const addEdit = (type, row) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -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'])
|
||||
|
||||
@ -3,46 +3,17 @@
|
||||
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="flex just-center">
|
||||
<el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm"
|
||||
@click="handleApplication(it)">{{ it.zdmc }}</el-button>
|
||||
</div>
|
||||
</el-popover>
|
||||
<el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)">指定分配</el-button>
|
||||
</template>
|
||||
<div>
|
||||
<el-input readonly v-model="obj.fpmc" @click="chooseUserVisible = true" placeholder="请选择民警"></el-input>
|
||||
<div class="flex just-center mt10">
|
||||
<el-button @click="(visiblefp = false), (obj = {})" size="small">取消</el-button>
|
||||
<el-button type="primary" @click="handlefp" size="small">分配</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
||||
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
|
||||
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
|
||||
<!-- <el-button size="small" type="primary" >导入</el-button> -->
|
||||
<el-button type="primary" size="small" @click="addEdit('add', null)">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" >
|
||||
<el-button type="primary" size="small" @click="addEdit('add', null)">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</PageTitle>
|
||||
</Search>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<div class="margTop">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData" fixed="right">
|
||||
@ -99,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([]);
|
||||
@ -317,7 +288,7 @@ const deleteRow = (id) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -3,10 +3,17 @@
|
||||
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" >
|
||||
<el-button type="primary" size="small" @click="addEdit('add', null)">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</Search>
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<!-- <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left> -->
|
||||
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请
|
||||
@ -30,16 +37,11 @@
|
||||
</el-popover>
|
||||
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
|
||||
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
|
||||
<el-button type="primary" size="small" @click="addEdit('add', null)">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</PageTitle>
|
||||
|
||||
<!-- </template>
|
||||
</PageTitle> -->
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<div class="margTop">
|
||||
<MyTable
|
||||
:tableData="pageData.tableData"
|
||||
:tableColumn="pageData.tableColumn"
|
||||
|
||||
@ -3,80 +3,239 @@
|
||||
<div class="head_box">
|
||||
<span class="title">{{ title }}重点人管理</span>
|
||||
<div>
|
||||
<el-button type="primary" size="small" v-if="butShow" :loading="loading" @click="submit">保存</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
v-if="butShow"
|
||||
:loading="loading"
|
||||
@click="submit"
|
||||
>保存</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
v-if="showAuditShBtn && showButData"
|
||||
@click="openAuditDialog('sh')"
|
||||
>审核</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
v-if="showAuditSpBtn && showButData"
|
||||
@click="openAuditDialog('sp')"
|
||||
>审批</el-button
|
||||
>
|
||||
<el-button size="small" @click="close">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<AuditDialog
|
||||
v-model="auditDialogVisible"
|
||||
:title="auditTitle"
|
||||
:formData="auditForm"
|
||||
:rules="auditRules"
|
||||
:reasonProp="auditReasonProp"
|
||||
:loading="auditLoading"
|
||||
:dictEnum="D_BZ_SF"
|
||||
@cancel="handleAuditCancel"
|
||||
@submit="handleAuditSubmit"
|
||||
/>
|
||||
<div class="form_cnt flex just-between">
|
||||
<div class="left_box">
|
||||
<ul class="anchor-list">
|
||||
<li @click="scrollToSection('info-section')" :class="activeSection === 'info-section' ? 'active' : ''">人员信息
|
||||
<li
|
||||
@click="scrollToSection('info-section')"
|
||||
:class="activeSection === 'info-section' ? 'active' : ''"
|
||||
>
|
||||
人员信息
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('backinfo-section')"
|
||||
:class="activeSection === 'backinfo-section' ? 'active' : ''"
|
||||
>
|
||||
人员标签
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('groupLabels-section')"
|
||||
:class="activeSection === 'groupLabels-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
关联车辆
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('character-section')"
|
||||
: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('demandsInfo-section')"
|
||||
:class="activeSection === 'demandsInfo-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
密切联系人
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('requestInfo-section')"
|
||||
:class="activeSection === 'requestInfo-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
动态轨迹
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('personnel-section')"
|
||||
:class="activeSection === 'personnel-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
行为信息
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('judgmentRecord-section')"
|
||||
:class="activeSection === 'judgmentRecord-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
走访记录
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('historyAssembly-section')"
|
||||
:class="activeSection === 'historyAssembly-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
案件信息
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('joblogging-section')"
|
||||
:class="activeSection === 'joblogging-section' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
现实表现
|
||||
</li>
|
||||
<li
|
||||
@click="scrollToSection('joblogging-joblog')"
|
||||
:class="activeSection === 'joblogging-joblog' ? 'active' : ''"
|
||||
v-if="!butShow"
|
||||
>
|
||||
操作日志
|
||||
</li>
|
||||
<li @click="scrollToSection('backinfo-section')"
|
||||
:class="activeSection === 'backinfo-section' ? 'active' : ''">人员标签</li>
|
||||
<li @click="scrollToSection('groupLabels-section')"
|
||||
:class="activeSection === 'groupLabels-section' ? 'active' : ''" v-if="!butShow">关联车辆</li>
|
||||
<li @click="scrollToSection('character-section')"
|
||||
: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('demandsInfo-section')"
|
||||
:class="activeSection === 'demandsInfo-section' ? 'active' : ''" v-if="!butShow">密切联系人</li>
|
||||
<li @click="scrollToSection('requestInfo-section')"
|
||||
:class="activeSection === 'requestInfo-section' ? 'active' : ''" v-if="!butShow">动态轨迹</li>
|
||||
<li @click="scrollToSection('personnel-section')"
|
||||
:class="activeSection === 'personnel-section' ? 'active' : ''" v-if="!butShow">行为信息</li>
|
||||
<li @click="scrollToSection('judgmentRecord-section')"
|
||||
:class="activeSection === 'judgmentRecord-section' ? 'active' : ''" v-if="!butShow">走访记录</li>
|
||||
<li @click="scrollToSection('historyAssembly-section')"
|
||||
:class="activeSection === 'historyAssembly-section' ? 'active' : ''" v-if="!butShow">案件信息</li>
|
||||
<li @click="scrollToSection('joblogging-section')"
|
||||
:class="activeSection === 'joblogging-section' ? 'active' : ''" v-if="!butShow">现实表现</li>
|
||||
<li @click="scrollToSection('joblogging-joblog')"
|
||||
:class="activeSection === 'joblogging-joblog' ? 'active' : ''" v-if="!butShow">操作日志</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right_box" ref="rightBox">
|
||||
<div id="info-section">
|
||||
<Info ref="info" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<Info
|
||||
ref="info"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
@close="close"
|
||||
/>
|
||||
</div>
|
||||
<div id="backinfo-section">
|
||||
<PersonnelTags ref="personnelTags" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<PersonnelTags
|
||||
ref="personnelTags"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="groupLabels-section" v-if="!butShow">
|
||||
<Vehicle ref="vehicle" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<Vehicle
|
||||
ref="vehicle"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="character-section">
|
||||
<BackInfo ref="backInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<BackInfo
|
||||
ref="backInfo"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="controlInfo-section" v-if="!butShow">
|
||||
<ControlInfo ref="controlInfo" title="重点人" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<ControlInfo
|
||||
ref="controlInfo"
|
||||
title="重点人"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="featinfo-section" v-if="!butShow">
|
||||
<Deployment ref="deployment" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<Deployment
|
||||
ref="deployment"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="demandsInfo-section" v-if="!butShow">
|
||||
<Contact ref="contact" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<Contact
|
||||
ref="contact"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="requestInfo-section" v-if="!butShow">
|
||||
<DynamicTrajectory ref="dynamicTrajectory" :disabled="disabled" :showBut="showBut" />
|
||||
<DynamicTrajectory
|
||||
ref="dynamicTrajectory"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
/>
|
||||
</div>
|
||||
<div id="personnel-section" v-if="!butShow">
|
||||
<BehaviorInfo ref="behaviorInfo" :disabled="disabled" :showBut="showBut" />
|
||||
<BehaviorInfo
|
||||
ref="behaviorInfo"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
/>
|
||||
</div>
|
||||
<div id="judgmentRecord-section" v-if="!butShow">
|
||||
<VisitRecord ref="visitRecord" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<VisitRecord
|
||||
ref="visitRecord"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="historyAssembly-section" v-if="!butShow" >
|
||||
<CaseInfo ref="caseInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<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" />
|
||||
<ActualPerformance
|
||||
ref="actualPerformance"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
<div id="joblogging-joblog" v-if="!butShow" >
|
||||
<CzModel ref="czModel" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||
<div id="joblogging-joblog" v-if="!butShow">
|
||||
<CzModel
|
||||
ref="czModel"
|
||||
:disabled="disabled"
|
||||
:showBut="showBut"
|
||||
:dataList="listQuery"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -87,73 +246,107 @@
|
||||
import { getItem } from "@/utils/storage";
|
||||
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||
import { tbGsxtZdrySelectVoById, tbGsxtZdrySave } from "@/api/zdr.js";
|
||||
import ControlInfo from '../../mpvGroup/model/controlInfo.vue'
|
||||
import AuditDialog from "./auditDialog.vue";
|
||||
import ControlInfo from "../../mpvGroup/model/controlInfo.vue";
|
||||
import Info from "../model/info.vue";
|
||||
import PersonnelTags from '../model/personnelTags.vue'
|
||||
import Vehicle from '../model/vehicle.vue'
|
||||
import BackInfo from '../model/bakInfo.vue'
|
||||
import Deployment from '../model/deployment.vue'
|
||||
import Contact from '../model/contact.vue'
|
||||
import DynamicTrajectory from '../model/dynamicTrajectory.vue'
|
||||
import BehaviorInfo from '../model/behaviorInfo.vue'
|
||||
import VisitRecord from '../model/visitRecord.vue'
|
||||
import CaseInfo from '../model/caseInfo.vue'
|
||||
import ActualPerformance from '../model/actualPerformance.vue'
|
||||
import CzModel from '../model/czModel.vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { ref, onUnmounted, getCurrentInstance } from "vue";
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
import PersonnelTags from "../model/personnelTags.vue";
|
||||
import Vehicle from "../model/vehicle.vue";
|
||||
import BackInfo from "../model/bakInfo.vue";
|
||||
import Deployment from "../model/deployment.vue";
|
||||
import Contact from "../model/contact.vue";
|
||||
import DynamicTrajectory from "../model/dynamicTrajectory.vue";
|
||||
import BehaviorInfo from "../model/behaviorInfo.vue";
|
||||
import VisitRecord from "../model/visitRecord.vue";
|
||||
import CaseInfo from "../model/caseInfo.vue";
|
||||
import ActualPerformance from "../model/actualPerformance.vue";
|
||||
import CzModel from "../model/czModel.vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { ref, onUnmounted, getCurrentInstance, computed, reactive } from "vue";
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_SF } = proxy.$dict("D_BZ_SF");
|
||||
const emit = defineEmits(["updateDate"]);
|
||||
const chooseMarksVisible = ref(false);
|
||||
const dialogForm = ref(false); //弹窗
|
||||
const loading = ref(false);
|
||||
const disabled = ref(false)
|
||||
const showBut = ref(false)
|
||||
const disabled = ref(false);
|
||||
const showBut = ref(false);
|
||||
const listQuery = ref({});
|
||||
const butShow = ref(false)
|
||||
const title = ref('新增')
|
||||
const showData = ref(false)
|
||||
const butShow = ref(false);
|
||||
const title = ref("新增");
|
||||
const showData = ref(false);
|
||||
const modeType = ref("detail");
|
||||
const currentRowId = ref("");
|
||||
const auditDialogVisible = ref(false);
|
||||
const auditLoading = ref(false);
|
||||
const auditForm = reactive({
|
||||
id: "",
|
||||
sftg: undefined,
|
||||
shBtgyy: "",
|
||||
spBtgyy: ""
|
||||
});
|
||||
const auditRules = reactive({
|
||||
sftg: [{ required: true, message: "请选择是否通过", trigger: "change" }],
|
||||
shBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }],
|
||||
spBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }]
|
||||
});
|
||||
const auditTitle = computed(() => (modeType.value === "sp" ? "审批" : "审核"));
|
||||
const auditReasonProp = computed(() =>
|
||||
modeType.value === "sp" ? "spBtgyy" : "shBtgyy"
|
||||
);
|
||||
const showAuditShBtn = computed(
|
||||
() => modeType.value === "detail" && dataListQuery.value?.zdrZt == "02"
|
||||
);
|
||||
const showAuditSpBtn = computed(
|
||||
() => modeType.value === "detail" && dataListQuery.value?.zdrZt == "04"
|
||||
);
|
||||
const props = defineProps({
|
||||
rylx: {
|
||||
type: String,
|
||||
default: '01'
|
||||
default: "01"
|
||||
},
|
||||
showButData: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
});
|
||||
const dataListQuery = ref({});
|
||||
// 初始化数据
|
||||
const init = (type, row) => {
|
||||
dialogForm.value = true;
|
||||
if (type == 'add') {
|
||||
butShow.value = true
|
||||
title.value = '新增'
|
||||
disabled.value = false
|
||||
showBut.value = false
|
||||
modeType.value = type;
|
||||
currentRowId.value = row?.id || "";
|
||||
if (type == "add") {
|
||||
butShow.value = true;
|
||||
title.value = "新增";
|
||||
disabled.value = false;
|
||||
showBut.value = false;
|
||||
listQuery.value = {};
|
||||
} else {
|
||||
|
||||
butShow.value = false
|
||||
tbGsxtZdrySelectVoById({ id: row.id }).then(res => {
|
||||
listQuery.value = { ...res }
|
||||
})
|
||||
if (type == 'edit') {
|
||||
showBut.value = true
|
||||
disabled.value = false
|
||||
title.value = '编辑'
|
||||
butShow.value = false;
|
||||
dataListQuery.value = { ...row };
|
||||
tbGsxtZdrySelectVoById({ id: row.id }).then((res) => {
|
||||
listQuery.value = { ...res };
|
||||
});
|
||||
if (type == "edit") {
|
||||
showBut.value = true;
|
||||
disabled.value = false;
|
||||
title.value = "编辑";
|
||||
} else if (type == "del") {
|
||||
disabled.value = true
|
||||
showBut.value = false
|
||||
title.value = '删除'
|
||||
}
|
||||
else {
|
||||
disabled.value = true
|
||||
showBut.value = false
|
||||
title.value = '详情'
|
||||
disabled.value = true;
|
||||
showBut.value = false;
|
||||
title.value = "删除";
|
||||
} else {
|
||||
disabled.value = true;
|
||||
showBut.value = false;
|
||||
title.value = "详情";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const activeSection = ref('info-section')
|
||||
const rightBox = ref(null)
|
||||
const activeSection = ref("info-section");
|
||||
const rightBox = ref(null);
|
||||
// 滚动到指定区域
|
||||
const scrollToSection = (sectionId) => {
|
||||
const element = document.getElementById(sectionId);
|
||||
@ -162,21 +355,30 @@ const scrollToSection = (sectionId) => {
|
||||
const elementTop = element.offsetTop;
|
||||
rightBox.value.scrollTo({
|
||||
top: elementTop - 150, // 减去一些偏移量,让内容更好看
|
||||
behavior: 'smooth' // 平滑滚动
|
||||
behavior: "smooth" // 平滑滚动
|
||||
});
|
||||
activeSection.value = sectionId;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 监听滚动,更新当前激活的锚点
|
||||
const handleScroll = () => {
|
||||
if (!rightBox.value) return;
|
||||
const scrollPosition = rightBox.value.scrollTop + 50;
|
||||
const sections = [
|
||||
'info-section', 'backinfo-section', 'groupLabels-section',
|
||||
'character-section', 'controlInfo-section', 'featinfo-section',
|
||||
'demandsInfo-section', 'requestInfo-section', 'personnel-section',
|
||||
'judgmentRecord-section', 'historyAssembly-section', 'joblogging-section', "czModel-section"
|
||||
"info-section",
|
||||
"backinfo-section",
|
||||
"groupLabels-section",
|
||||
"character-section",
|
||||
"controlInfo-section",
|
||||
"featinfo-section",
|
||||
"demandsInfo-section",
|
||||
"requestInfo-section",
|
||||
"personnel-section",
|
||||
"judgmentRecord-section",
|
||||
"historyAssembly-section",
|
||||
"joblogging-section",
|
||||
"czModel-section"
|
||||
];
|
||||
|
||||
for (let i = sections.length - 1; i >= 0; i--) {
|
||||
@ -186,26 +388,26 @@ const handleScroll = () => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 监听右侧区域的滚动事件
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('load', () => {
|
||||
if (typeof window !== "undefined") {
|
||||
window.addEventListener("load", () => {
|
||||
if (rightBox.value) {
|
||||
rightBox.value.addEventListener('scroll', handleScroll);
|
||||
rightBox.value.addEventListener("scroll", handleScroll);
|
||||
}
|
||||
});
|
||||
|
||||
// 组件卸载时移除事件监听
|
||||
onUnmounted(() => {
|
||||
if (rightBox.value) {
|
||||
rightBox.value.removeEventListener('scroll', handleScroll);
|
||||
rightBox.value.removeEventListener("scroll", handleScroll);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const info = ref()
|
||||
const personnelTags = ref()
|
||||
const info = ref();
|
||||
const personnelTags = ref();
|
||||
// 提交
|
||||
const submit = async () => {
|
||||
// 使用Promise.all处理所有子组件的验证和数据获取
|
||||
@ -213,21 +415,62 @@ const submit = async () => {
|
||||
info.value.throwData()
|
||||
// personnelTags.value.throwData(),
|
||||
]);
|
||||
tbGsxtZdrySave({...infoData,rylx:props.rylx}).then(res => {
|
||||
tbGsxtZdrySave({ ...infoData, rylx: props.rylx }).then((res) => {
|
||||
proxy.$message({
|
||||
message: '新增成功',
|
||||
type: 'success',
|
||||
})
|
||||
close()
|
||||
})
|
||||
message: "新增成功",
|
||||
type: "success"
|
||||
});
|
||||
close();
|
||||
});
|
||||
console.log(infoData);
|
||||
|
||||
};
|
||||
|
||||
const butzt = ref();
|
||||
const openAuditDialog = (type) => {
|
||||
// modeType.value = type;
|
||||
butzt.value = type;
|
||||
auditForm.id = currentRowId.value || listQuery.value?.id || "";
|
||||
auditForm.sftg = undefined;
|
||||
auditForm.shBtgyy = "";
|
||||
auditForm.spBtgyy = "";
|
||||
auditDialogVisible.value = true;
|
||||
};
|
||||
|
||||
const handleAuditCancel = () => {
|
||||
auditDialogVisible.value = false;
|
||||
auditLoading.value = false;
|
||||
// modeType.value = "detail";
|
||||
auditForm.id = "";
|
||||
auditForm.sftg = undefined;
|
||||
auditForm.shBtgyy = "";
|
||||
auditForm.spBtgyy = "";
|
||||
};
|
||||
|
||||
const handleAuditSubmit = () => {
|
||||
auditLoading.value = true;
|
||||
const url =
|
||||
butzt.value === "sp"
|
||||
? "/mosty-gsxt/tbGsxtZdry/updateSp"
|
||||
: "/mosty-gsxt/tbGsxtZdry/updateSh";
|
||||
const successMsg = modeType.value === "sp" ? "审批成功" : "审核成功";
|
||||
qcckPost(auditForm, url)
|
||||
.then(() => {
|
||||
proxy.$message({
|
||||
message: successMsg,
|
||||
type: "success"
|
||||
});
|
||||
auditDialogVisible.value = false;
|
||||
modeType.value = "detail";
|
||||
close();
|
||||
})
|
||||
.catch(() => {
|
||||
auditLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const close = () => {
|
||||
if (route.query.id) {
|
||||
if (route.query.id) {
|
||||
const query = { ...route.query };
|
||||
delete query.id;
|
||||
router.replace({ query });
|
||||
@ -235,7 +478,15 @@ const close = () => {
|
||||
|
||||
dialogForm.value = false;
|
||||
loading.value = false;
|
||||
emit('updateDate')
|
||||
auditLoading.value = false;
|
||||
auditDialogVisible.value = false;
|
||||
modeType.value = "detail";
|
||||
currentRowId.value = "";
|
||||
auditForm.id = "";
|
||||
auditForm.sftg = undefined;
|
||||
auditForm.shBtgyy = "";
|
||||
auditForm.spBtgyy = "";
|
||||
emit("updateDate");
|
||||
};
|
||||
|
||||
defineExpose({ init });
|
||||
@ -246,7 +497,6 @@ defineExpose({ init });
|
||||
@import "~@/assets/css/element-plus.scss";
|
||||
|
||||
.behaviorInfo {
|
||||
|
||||
margin: 0 0 10px 0;
|
||||
// padding-bottom: 10px;
|
||||
border-bottom: 2px solid #409eff;
|
||||
@ -257,7 +507,6 @@ defineExpose({ init });
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.textContent {
|
||||
@ -346,7 +595,7 @@ defineExpose({ init });
|
||||
scrollbar-color: #999 #f1f1f1;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
|
||||
::v-deep .el-tabs--card > .el-tabs__header .el-tabs__item.is-active {
|
||||
color: #0072ff;
|
||||
background: rgba(0, 114, 255, 0.3);
|
||||
}
|
||||
@ -428,7 +677,7 @@ defineExpose({ init });
|
||||
}
|
||||
|
||||
.anchor-list li.active::before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
@ -446,7 +695,7 @@ defineExpose({ init });
|
||||
// border: 1px solid #ebeef5;
|
||||
border-radius: 6px;
|
||||
|
||||
.right_box>div {
|
||||
.right_box > div {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
padding: 20px;
|
||||
@ -454,7 +703,7 @@ defineExpose({ init });
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.right_box>div:hover {
|
||||
.right_box > div:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
@ -469,7 +718,7 @@ defineExpose({ init });
|
||||
}
|
||||
|
||||
.right_box h3::after {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -2px;
|
||||
@ -527,6 +776,6 @@ defineExpose({ init });
|
||||
}
|
||||
|
||||
::v-deep .avatar-uploader {
|
||||
display: flex
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<el-dialog :model-value="modelValue" :title="title" width="500px" @update:model-value="handleModelValueChange"
|
||||
@close="handleCancel">
|
||||
<el-form :model="formData" ref="elAuditForm" label-width="100px" :rules="rules" style="width: 100%;">
|
||||
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10">
|
||||
<MOSTY.Select filterable v-model="formData.sftg" :dictEnum="dictEnum" style="width: 100%;" clearable
|
||||
placeholder="请选择是否通过" />
|
||||
</el-form-item>
|
||||
<el-form-item label="不通过原因" :prop="reasonProp" v-if="formData.sftg == 0">
|
||||
<MOSTY.Other style="width: 100%;" clearable v-model="formData[reasonProp]" type="textarea"
|
||||
placeholder="请输入不通过原因" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="flex just-center">
|
||||
<el-button @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" v-loading="loading">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import { ref } from "vue";
|
||||
|
||||
defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "审核"
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
rules: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
reasonProp: {
|
||||
type: String,
|
||||
default: "shBtgyy"
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dictEnum: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "cancel", "submit"]);
|
||||
const elAuditForm = ref();
|
||||
|
||||
const handleModelValueChange = (val) => {
|
||||
emit("update:modelValue", val);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
emit("cancel");
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
elAuditForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
emit("submit");
|
||||
});
|
||||
};
|
||||
</script>
|
||||
@ -1,52 +1,36 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
|
||||
</template>
|
||||
<div class="flex just-center">
|
||||
<el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm"
|
||||
@click="handleApplication(it)">{{ it.zdmc }}</el-button>
|
||||
</div>
|
||||
</el-popover> -->
|
||||
<!-- <el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
|
||||
<template #reference>
|
||||
<el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)">指定分配</el-button>
|
||||
</template>
|
||||
<div>
|
||||
<el-input readonly v-model="obj.fpmc" @click="chooseUserVisible = true" placeholder="请选择民警"></el-input>
|
||||
<div class="flex just-center mt10">
|
||||
<el-button @click="(visiblefp = false), (obj = {})" size="small">取消</el-button>
|
||||
<el-button type="primary" @click="handlefp" size="small">分配</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover> -->
|
||||
<!-- <el-button size="small" type="primary" @click="handleZxs">转线索</el-button> -->
|
||||
<!-- <el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
|
||||
<!-- <el-button size="small" type="primary">导入</el-button> -->
|
||||
<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>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</PageTitle>
|
||||
</Search>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
<div class="margTop" style="padding: 0">
|
||||
<WarnDataTable
|
||||
:data="pageData.tableData"
|
||||
:columns="pageData.tableColumn"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:loading="pageData.tableConfiger.loading"
|
||||
@selection-change="chooseData"
|
||||
>
|
||||
<template #bqList="{ row }">
|
||||
<ul>
|
||||
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
||||
item.bqFz || 0 }} 分) </li>
|
||||
<li
|
||||
:style="{ background: Bqys(item.bqYs) }"
|
||||
class="one_text_detail marks mb4"
|
||||
:key="index"
|
||||
v-for="(item, index) in row.bqList"
|
||||
>
|
||||
{{ item.bqMc }}({{ item.bqFz || 0 }} 分)
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template #ryXb="{ row }">
|
||||
@ -65,7 +49,7 @@
|
||||
<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" />
|
||||
</template>
|
||||
<template #zdrBkZt="{ row }">
|
||||
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_ZDRGK_GKZT" />
|
||||
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_BZ_RCBKZT" />
|
||||
</template>
|
||||
<template #zdrCzzt="{ row }">
|
||||
<DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" />
|
||||
@ -73,35 +57,101 @@
|
||||
<template #zdrZt="{ row }">
|
||||
<DictTag :tag="false" :value="row.zdrZt" :options="D_GS_ZDQT_ZT" />
|
||||
</template>
|
||||
<template #zdrSsjz="{ row }">
|
||||
<DictTag :tag="false" :value="row.zdrSsjz" :options="D_GS_BK_SSJZ" />
|
||||
</template>
|
||||
<template #zdrSjjz="{ row }">
|
||||
<DictTag :tag="false" :value="row.zdrSjjz" :options="D_GS_BK_SSJZ" />
|
||||
</template>
|
||||
|
||||
<template #xtSjzt="{ row }">
|
||||
<div> {{ row.xtSjzt == 0 ? "注销" : row.xtSjzt == 1 ? "正常" : "封存" }}</div>
|
||||
<div>
|
||||
{{ row.xtSjzt == 0 ? "注销" : row.xtSjzt == 1 ? "正常" : "封存" }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link size="small" type="success" @click="handleremove(row.id)">移除</el-link>
|
||||
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||
@click="handleSend(row.id)">送审</el-link>
|
||||
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||
@click="addEdit('edit', row)">编辑</el-link>
|
||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
|
||||
<!-- <el-link size="small" type="success" @click="handleremove(row.id)">移至关注库</el-link> -->
|
||||
<el-link
|
||||
size="small"
|
||||
type="success"
|
||||
@click="handleMoveToFocus(row.id)"
|
||||
>移入关注库</el-link
|
||||
>
|
||||
<el-link size="small" type="success" @click="handleremove(row.id)"
|
||||
>移入基础库</el-link
|
||||
>
|
||||
<el-link
|
||||
size="small"
|
||||
type="success"
|
||||
v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||
@click="handleSend(row.id)"
|
||||
>送审</el-link
|
||||
>
|
||||
<el-link
|
||||
size="small"
|
||||
type="primary"
|
||||
v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||
@click="addEdit('edit', row)"
|
||||
>编辑</el-link
|
||||
>
|
||||
<el-link size="small" type="primary" @click="addEdit('detail', row)"
|
||||
>详情</el-link
|
||||
>
|
||||
<el-link size="small" type="danger" @click="deleteRow(row.id)"
|
||||
>删除</el-link
|
||||
>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"></Pages>
|
||||
</WarnDataTable>
|
||||
<Pages
|
||||
@changeNo="changeNo"
|
||||
@changeSize="changeSize"
|
||||
:tableHeight="pageData.tableHeight"
|
||||
:pageConfiger="{
|
||||
...pageData.pageConfiger,
|
||||
total: pageData.total
|
||||
}"
|
||||
></Pages>
|
||||
</div>
|
||||
<!-- 详情 -->
|
||||
<AddForm ref="addFormDiloag" @updateDate="getList"
|
||||
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRGK_GKZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
|
||||
<AddForm
|
||||
ref="addFormDiloag"
|
||||
@updateDate="getList"
|
||||
:dic="{
|
||||
D_GS_ZDR_RYJB,
|
||||
D_BZ_XB,
|
||||
D_BZ_MZ,
|
||||
D_BZ_XZQHDM,
|
||||
D_ZDRGK_GKZT,
|
||||
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" />
|
||||
<ChooseUser
|
||||
v-model="chooseUserVisible"
|
||||
@choosedUsers="handleUserSelected"
|
||||
:roleIds="roleIds"
|
||||
/>
|
||||
<!-- 转线索 -->
|
||||
<ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList"
|
||||
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }"></ZxsForm>
|
||||
<ZxsForm
|
||||
v-if="showzxs"
|
||||
ref="zxsDilof"
|
||||
@change="getList"
|
||||
:dic="{
|
||||
D_BZ_SF,
|
||||
D_BZ_XB,
|
||||
D_GS_XS_LY,
|
||||
D_BZ_SSZT,
|
||||
D_GS_XS_LX,
|
||||
D_GS_XS_QTLX
|
||||
}"
|
||||
></ZxsForm>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -110,19 +160,58 @@ import { ElMessage } from "element-plus";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
import ZxsForm from "./components/zxsForm.vue";
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.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 { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
|
||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { getItem } from "@/utils/storage.js";
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRGK_GKZT, 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_ZDRGK_GKZT", "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_RCBKZT,
|
||||
D_BZ_XZQHDM,
|
||||
D_ZDRGK_GKZT,
|
||||
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_BZ_RCBKZT",
|
||||
"D_GS_ZDR_RYJB",
|
||||
"D_BZ_XB",
|
||||
"D_BZ_MZ",
|
||||
"D_BZ_XZQHDM",
|
||||
"D_ZDRGK_GKZT",
|
||||
"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 showzxs = ref(false);
|
||||
const zxsDilof = ref();
|
||||
@ -160,6 +249,20 @@ const searchConfiger = ref([
|
||||
showType: "select",
|
||||
options: D_GS_ZDR_RYJB
|
||||
},
|
||||
{
|
||||
label: "所属警种",
|
||||
prop: "zdrSsjz",
|
||||
placeholder: "请选择所属警种",
|
||||
showType: "select",
|
||||
options: D_GS_BK_SSJZ
|
||||
},
|
||||
{
|
||||
label: "涉及警种",
|
||||
prop: "zdrSjjz",
|
||||
placeholder: "请选择涉及警种",
|
||||
showType: "select",
|
||||
options: D_GS_BK_SSJZ
|
||||
},
|
||||
]);
|
||||
const queryFrom = ref({});
|
||||
const pageData = reactive({
|
||||
@ -175,30 +278,51 @@ const pageData = reactive({
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 250,
|
||||
tableColumn: [
|
||||
{ label: "姓名", prop: "ryXm",width: 100 },
|
||||
{ label: "性别", prop: "ryXb", showSolt: true, width: 80 },
|
||||
{ label: "姓名", prop: "ryXm", width: 100 },
|
||||
{ label: "性别", prop: "ryXb", slotName: "ryXb", width: 80 },
|
||||
{ label: "身份证", prop: "rySfzh", width: 170 },
|
||||
{ label: "民族", prop: "ryMz", showSolt: true, width: 80 },
|
||||
{ label: "民族", prop: "ryMz", slotName: "ryMz", width: 80 },
|
||||
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
||||
{ label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true },
|
||||
{ label: "管辖单位", prop: "gxSsbmmc" },
|
||||
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true,showSolt: true, width: 100 },
|
||||
{ label: "审核状态", prop: "zdrZt", showSolt: true, width: 100 },
|
||||
{ label: "入库时间", prop: "zdrRkkssj", },
|
||||
{
|
||||
label: "标签",
|
||||
prop: "bqList",
|
||||
slotName: "bqList",
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{ label: "协管单位", prop: "gxSsbmmc" },
|
||||
{
|
||||
label: "管控状态",
|
||||
prop: "zdrBkZt",
|
||||
showOverflowTooltip: true,
|
||||
slotName: "zdrBkZt",
|
||||
width: 100
|
||||
},
|
||||
{ label: "审核状态", prop: "zdrZt", slotName: "zdrZt", width: 100 },
|
||||
{ label: "入库时间", prop: "zdrRkkssj" },
|
||||
{ label: "所属警种", prop: "zdrSsjz",slotName: "zdrSsjz", },
|
||||
{ label: "涉及警种", prop: "zdrSjjz",slotName: "zdrSjjz", },
|
||||
{
|
||||
label: "操作",
|
||||
prop: "controls",
|
||||
slotName: "controls",
|
||||
align: "center",
|
||||
width: 350
|
||||
}
|
||||
]
|
||||
});
|
||||
const isShiQzDelet = ref(false)
|
||||
const isShiQzDelet = ref(false);
|
||||
onMounted(() => {
|
||||
tabHeightFn();
|
||||
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
|
||||
if (isShiQz) isShiQzDelet.value = true
|
||||
const isShiQz =
|
||||
getItem("roleList").find((item) => item.roleCode == "JS_777777") !=
|
||||
undefined;
|
||||
if (isShiQz) isShiQzDelet.value = true;
|
||||
if (route.query.id) {
|
||||
addEdit('x', {
|
||||
addEdit("x", {
|
||||
id: route.query.id
|
||||
})
|
||||
}else{
|
||||
});
|
||||
} else {
|
||||
getList();
|
||||
}
|
||||
});
|
||||
@ -224,14 +348,16 @@ const getList = () => {
|
||||
pageData.tableConfiger.loading = true;
|
||||
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
|
||||
// rylx: '01',
|
||||
let data = {...pageData.pageConfiger, ...queryFrom.value,rylx: '01' };
|
||||
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
|
||||
pageData.tableData = res.records || [];
|
||||
pageData.total = res.total;
|
||||
pageData.tableConfiger.loading = false;
|
||||
}).catch(() => {
|
||||
pageData.tableConfiger.loading = false;
|
||||
});
|
||||
let data = { ...pageData.pageConfiger, ...queryFrom.value, rylx: "01" };
|
||||
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage")
|
||||
.then((res) => {
|
||||
pageData.tableData = res.records || [];
|
||||
pageData.total = res.total;
|
||||
pageData.tableConfiger.loading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
pageData.tableConfiger.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
//送审
|
||||
@ -241,18 +367,27 @@ const handleSend = (id) => {
|
||||
proxy.$message({ type: "success", message: "送审成功" });
|
||||
getList();
|
||||
});
|
||||
})
|
||||
});
|
||||
};
|
||||
// 移除
|
||||
const handleremove = (id) => {
|
||||
proxy.$confirm("确定要移除此重点人员?", "警告", { type: "warning" }).then(() => {
|
||||
qcckPost({ id, rylx: '02' }, "/mosty-gsxt/tbGsxtZdry/update").then(() => {
|
||||
proxy
|
||||
.$confirm("确定要移除此重点人员?", "警告", { type: "warning" })
|
||||
.then(() => {
|
||||
qcckPost({ id, rylx: "02" }, "/mosty-gsxt/tbGsxtZdry/update").then(() => {
|
||||
proxy.$message({ type: "success", message: "移除成功" });
|
||||
getList();
|
||||
});
|
||||
});
|
||||
};
|
||||
const handleMoveToFocus = (id) => {
|
||||
proxy.$confirm("确定要移至关注库?", "警告", { type: "warning" }).then(() => {
|
||||
qcckPost({ id, rylx: "03" }, "/mosty-gsxt/tbGsxtZdry/rylxyd").then(() => {
|
||||
proxy.$message({ type: "success", message: "移除成功" });
|
||||
getList();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
const chooseData = (data) => {
|
||||
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
||||
@ -260,14 +395,17 @@ const chooseData = (data) => {
|
||||
};
|
||||
// 选择申请数据数据
|
||||
const handleApplication = () => {
|
||||
if (ids.value.length === 0) return ElMessage.error("请先选择需要布控的重点人");
|
||||
qcckPost({ ids: ids.value }, "/mosty-gsxt/tbGsxtZdry/addBksq").then(() => {
|
||||
ElMessage.success("申请成功");
|
||||
visible.value = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
ElMessage.error("布控申请失败");
|
||||
});
|
||||
if (ids.value.length === 0)
|
||||
return ElMessage.error("请先选择需要布控的重点人");
|
||||
qcckPost({ ids: ids.value }, "/mosty-gsxt/tbGsxtZdry/addBksq")
|
||||
.then(() => {
|
||||
ElMessage.success("申请成功");
|
||||
visible.value = false;
|
||||
getList();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.error("布控申请失败");
|
||||
});
|
||||
};
|
||||
|
||||
const handleUserSelected = (val) => {
|
||||
@ -277,33 +415,43 @@ const handleUserSelected = (val) => {
|
||||
|
||||
// 处理分配
|
||||
const handlefp = () => {
|
||||
if (ids.value.length === 0) return ElMessage.error("请先选择需要布控的重点人");
|
||||
qcckPost({ ids: ids.value, uid: obj.value.fpid }, "/mosty-gsxt/tbGsxtZdry/addGkmj").then(() => {
|
||||
ElMessage.success("分配成功");
|
||||
visible.value = false;
|
||||
visiblefp.value = false;
|
||||
getList();
|
||||
}).catch(() => {
|
||||
ElMessage.error("分配失败");
|
||||
});
|
||||
if (ids.value.length === 0)
|
||||
return ElMessage.error("请先选择需要布控的重点人");
|
||||
qcckPost(
|
||||
{ ids: ids.value, uid: obj.value.fpid },
|
||||
"/mosty-gsxt/tbGsxtZdry/addGkmj"
|
||||
)
|
||||
.then(() => {
|
||||
ElMessage.success("分配成功");
|
||||
visible.value = false;
|
||||
visiblefp.value = false;
|
||||
getList();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.error("分配失败");
|
||||
});
|
||||
};
|
||||
|
||||
// 移交管控
|
||||
const handleMove = () => {
|
||||
if (ids.value.length === 0) return ElMessage.error("请先选择需要移交管控的重点群体");
|
||||
if (ids.value.length === 0)
|
||||
return ElMessage.error("请先选择需要移交管控的重点群体");
|
||||
proxy.$confirm("是否确定移交?", "警告", { type: "warning" }).then(() => {
|
||||
qcckPost({ ids: ids.value }, "/mosty-gsxt/tbGsxtZdry/addSfyj").then(() => {
|
||||
ElMessage.success("移交管控成功");
|
||||
getList();
|
||||
}).catch(() => {
|
||||
ElMessage.error("移交管控失败");
|
||||
});
|
||||
qcckPost({ ids: ids.value }, "/mosty-gsxt/tbGsxtZdry/addSfyj")
|
||||
.then(() => {
|
||||
ElMessage.success("移交管控成功");
|
||||
getList();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.error("移交管控失败");
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 转线索
|
||||
const handleZxs = () => {
|
||||
if (ids.value.length === 0) return ElMessage.error("请先选择需要转线索的重点群体");
|
||||
if (ids.value.length === 0)
|
||||
return ElMessage.error("请先选择需要转线索的重点群体");
|
||||
showzxs.value = true;
|
||||
nextTick(() => {
|
||||
zxsDilof.value.init(choosList.value);
|
||||
@ -320,22 +468,38 @@ const deleteRow = (id) => {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
//新增编辑
|
||||
const addEdit = (type, row) => {
|
||||
show.value = true;
|
||||
nextTick(() => {
|
||||
addFormDiloag.value.init(type, row);
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
pageData.tableHeight =
|
||||
window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
};
|
||||
|
||||
// 标签颜色
|
||||
const Bqys = (ys) => {
|
||||
switch (ys) {
|
||||
case "01":
|
||||
return "#fd4343";
|
||||
case "02":
|
||||
return "#c26e09";
|
||||
case "03":
|
||||
return "#ffd208ff";
|
||||
case "04":
|
||||
return "#01abee";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -3,112 +3,258 @@
|
||||
<div class="headClass">
|
||||
<h3>人员信息</h3>
|
||||
<!-- @click="gettbGsxtZdqtUpdate" -->
|
||||
<el-button type="primary" v-if="showBut" :disabled="disabled" @click="submit">保存</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="showBut"
|
||||
:disabled="disabled"
|
||||
@click="submit"
|
||||
>保存</el-button
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform"
|
||||
:rules="rules">
|
||||
<FormMessage
|
||||
:disabled="disabled"
|
||||
v-model="listQuery"
|
||||
:formList="formData"
|
||||
labelWidth="130px"
|
||||
ref="elform"
|
||||
:rules="rules"
|
||||
>
|
||||
<template #ryzp>
|
||||
<div style="width: 100%; padding-left: 50px">
|
||||
<MOSTY.Upload :showBtn="false" :limit="1" v-model="listQuery.ryzp" />
|
||||
<MOSTY.Upload
|
||||
:showBtn="false"
|
||||
:limit="1"
|
||||
v-model="listQuery.ryzp"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #ryLxdh>
|
||||
<div class="phone-input-container">
|
||||
<div class="inputGroup" v-for="(item, index) in listQuery.ryLxdh" :key="index">
|
||||
<el-input v-model="listQuery.ryLxdh[index]" class="group" placeholder="请输入电话号码" />
|
||||
<div class="flex align-center but" >
|
||||
<el-button type="primary" :icon="Plus" circle @click="addPhone" title="添加电话号码"
|
||||
v-if="listQuery.ryLxdh.length - 1 == index" />
|
||||
<el-button type="success" :icon="Minus" circle @click="removePhone(index)" title="删除电话号码" />
|
||||
</div>
|
||||
</div>
|
||||
<template #gkMjXm>
|
||||
<div>
|
||||
<el-input
|
||||
v-model="listQuery.gkMjXm"
|
||||
class="group"
|
||||
placeholder="请输入管控民警姓名"
|
||||
readonly
|
||||
@click="chooseMarksVisible = true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- <template #gkMjSfzh>
|
||||
<div>
|
||||
<el-input v-model="listQuery.gkMjSfzh" class="group" placeholder="请输入管控民警身份证号" readonly
|
||||
@click="chooseMarksVisible = true" />
|
||||
</div>
|
||||
</template> -->
|
||||
<!-- { label: "管控民警", prop: "gkMjXm", type: "slot" }, -->
|
||||
<!-- { label: "管控民警身份证号", prop: "gkMjSfzh", type: "slot" }, -->
|
||||
</FormMessage>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <ChooseMarks v-model="chooseMarksVisible" @choosed="choosed" :roleIds="roleIds" /> -->
|
||||
<ChooseUser
|
||||
v-model="chooseMarksVisible"
|
||||
@choosedUsers="choosed"
|
||||
:roleIds="roleIds"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as rule from "@/utils/rules.js";
|
||||
import { IdCard } from "@/utils/validate.js";
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import { Plus, Minus } from "@element-plus/icons-vue";
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
|
||||
import { ref, reactive, onMounted, getCurrentInstance, watch } from "vue";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
import { ref, reactive, onMounted, getCurrentInstance, watch, computed } from "vue";
|
||||
import { tbGsxtZdryUpdate } from "@/api/zdr.js";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_XB, D_BZ_ZZMM, D_BZ_HYZK, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRY_RYLX, D_BZ_RCBKZT, D_GS_ZDR_RYJB, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_ZDR_CZZT, D_BZ_WHCD, D_ZDRY_ZYLB } =
|
||||
proxy.$dict('D_BZ_XB', 'D_BZ_ZZMM', 'D_BZ_HYZK', 'D_BZ_MZ', "D_ZDRY_RYLX", 'D_BZ_XZQHDM', 'D_BZ_RCBKZT', 'D_GS_ZDR_RYJB', 'D_GS_ZDR_YJDJ', 'D_GS_BK_SSJZ', 'D_GS_ZDR_CZZT', 'D_BZ_WHCD', 'D_ZDRY_ZYLB')
|
||||
const {
|
||||
D_BZ_XB,
|
||||
D_BZ_ZZMM,
|
||||
D_BZ_HYZK,
|
||||
D_BZ_MZ,
|
||||
D_BZ_XZQHDM,
|
||||
D_ZDRY_RYLX,
|
||||
D_BZ_RCBKZT,
|
||||
D_GS_ZDR_RYJB,
|
||||
D_GS_ZDR_YJDJ,
|
||||
D_GS_BK_SSJZ,
|
||||
D_GS_ZDR_CZZT,
|
||||
D_BZ_WHCD,
|
||||
D_ZDRY_ZYLB
|
||||
} = proxy.$dict(
|
||||
"D_BZ_XB",
|
||||
"D_BZ_ZZMM",
|
||||
"D_BZ_HYZK",
|
||||
"D_BZ_MZ",
|
||||
"D_ZDRY_RYLX",
|
||||
"D_BZ_XZQHDM",
|
||||
"D_BZ_RCBKZT",
|
||||
"D_GS_ZDR_RYJB",
|
||||
"D_GS_ZDR_YJDJ",
|
||||
"D_GS_BK_SSJZ",
|
||||
"D_GS_ZDR_CZZT",
|
||||
"D_BZ_WHCD",
|
||||
"D_ZDRY_ZYLB"
|
||||
);
|
||||
const props = defineProps({
|
||||
dataList: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
}, disabled: {
|
||||
default: () => {}
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showBut: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
})
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(["close"]);
|
||||
const rules = reactive({
|
||||
ryXm: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||
...rule.identityCardRule({ validator: true }, 'rySfzh'), //身份证校验
|
||||
...rule.phoneRule({ validator: true }, "ryLxdh"), // 是否必填 是否进行校验,
|
||||
...rule.identityCardRule({ validator: true }, "rySfzh"), //身份证校验
|
||||
...rule.phoneRule({ validator: true }, "gkMjLxfs"), // 是否必填 是否进行校验,
|
||||
rySfzh: [{ required: true, message: "请输入身份证号", trigger: "blur" }],
|
||||
ryLxdh: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
|
||||
ryXb: [{ required: true, message: "请选择性别", trigger: "change" }],
|
||||
zyBm: [{ required: true, message: "请选择职业", trigger: "change" }],
|
||||
ryMz: [{ required: true, message: "请选择民族", trigger: "change" }],
|
||||
ryCsrq: [{ required: true, message: "请选择出生日期", trigger: "change" }],
|
||||
ryJg: [{ required: true, message: "请选择籍贯", trigger: "change" }],
|
||||
zdrRyjb: [{ required: true, message: "请选择人员级别", trigger: "change" }],
|
||||
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }],
|
||||
gxSsbmdm: [{ required: true, message: "请选择协管单位", trigger: "change" }],
|
||||
zdrRkkssj: [
|
||||
{ required: true, message: "请选择入库开始时间", trigger: "change" }
|
||||
],
|
||||
zdrRkjssj: [
|
||||
{ required: true, message: "请选择入库结束时间", trigger: "change" }
|
||||
],
|
||||
gkMjLxfs: [{ required: true, message: "请输入民警联系方式", trigger: "blur" }]
|
||||
// gkMjXm: [{ required: true, message: "请选择管控民警", trigger: "change" }],
|
||||
// gkMjSfzh: [{ required: true, message: "请选择管控民警身份证号", trigger: "change" }],
|
||||
// rylx: [{ required: true, message: "请选择人员类型", trigger: "change" }]
|
||||
});
|
||||
const listQuery = ref({ ryLxdh: [""] }); //表单
|
||||
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" },
|
||||
{ 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: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT },
|
||||
// { label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT },
|
||||
{ label: "姓名", prop: "ryXm", type: "input", width: "30%" },
|
||||
{ label: "身份证号", prop: "rySfzh", type: "input", width: "30%" },
|
||||
{
|
||||
label: "性别",
|
||||
prop: "ryXb",
|
||||
type: "select",
|
||||
options: D_BZ_XB.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "出生日期", prop: "ryCsrq", type: "date", width: "30%" },
|
||||
{
|
||||
label: "民族",
|
||||
prop: "ryMz",
|
||||
type: "select",
|
||||
options: D_BZ_MZ.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "协管单位",
|
||||
prop: "gxSsbmdm",
|
||||
depMc: "gxSsbmmc",
|
||||
type: "department",
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "预警等级",
|
||||
prop: "zdrYjdj",
|
||||
type: "select",
|
||||
options: D_GS_ZDR_YJDJ.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "管控民警", prop: "gkMjXm", type: "slot", width: "30%" },
|
||||
{ label: "民警联系方式", prop: "gkMjLxfs", type: "input", width: "30%" },
|
||||
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime", width: "30%" },
|
||||
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime", width: "30%" },
|
||||
{ label: "重点人联系电话", prop: "ryLxdh", type: "input", width: "30%" },
|
||||
{ label: "籍贯", prop: "ryJg", type: "input", width: "30%" },
|
||||
{ label: "曾用名", prop: "cym", type: "input", width: "30%" },
|
||||
{
|
||||
label: "文化程度",
|
||||
prop: "whcdBm",
|
||||
type: "select",
|
||||
options: D_BZ_WHCD.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "政治面貌",
|
||||
prop: "zzmm",
|
||||
type: "select",
|
||||
options: D_BZ_ZZMM.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "职业", prop: "zyBm", type: "input", width: "30%" },
|
||||
{
|
||||
label: "人员级别",
|
||||
prop: "zdrRyjb",
|
||||
type: "select",
|
||||
options: D_GS_ZDR_RYJB.value,
|
||||
width: "30%"
|
||||
},
|
||||
{ label: "户籍地区划", prop: "hjdQh", type: "input", width: "30%" },
|
||||
{ label: "户籍地详址", prop: "hjdXz", type: "input", width: "30%" },
|
||||
{ label: "户籍地派出所", prop: "hjdPcsmc", type: "input", width: "30%" },
|
||||
{ label: "现住地区划", prop: "xzdQh", type: "input", width: "30%" },
|
||||
{ label: "现住地详址", prop: "xzdXz", type: "input", width: "30%" },
|
||||
{
|
||||
label: "现住地派出所",
|
||||
prop: "xzdPcsdm",
|
||||
depMc: "xzdPcsmc",
|
||||
type: "department",
|
||||
width: "30%"
|
||||
},
|
||||
|
||||
// { label: "民警身份证", prop: "gkMjSfzh", type: "slot" },
|
||||
{ label: "诉求单位", prop: "sqSsbmmc", type: "input", width: "30%" },
|
||||
{ label: "责任单位", prop: "zrSsbmmc", type: "input", width: "30%" },
|
||||
{
|
||||
label: "所属警种",
|
||||
prop: "zdrSsjz",
|
||||
type: "select",
|
||||
options: D_GS_BK_SSJZ.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "涉及警种",
|
||||
prop: "zdrSjjz",
|
||||
type: "select",
|
||||
options: D_GS_BK_SSJZ.value,
|
||||
multiple: true,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "婚姻状态",
|
||||
prop: "hyzk",
|
||||
type: "select",
|
||||
options: D_BZ_HYZK.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "处置状态",
|
||||
prop: "zdrCzzt",
|
||||
type: "select",
|
||||
options: D_GS_ZDR_CZZT.value,
|
||||
width: "30%"
|
||||
},
|
||||
{
|
||||
label: "布控状态",
|
||||
prop: "zdrBkZt",
|
||||
type: "select",
|
||||
options: D_BZ_RCBKZT.value,
|
||||
width: "30%"
|
||||
},
|
||||
// { 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: "Mac地址", prop: "macDz", type: "input", width: "30%" },
|
||||
// { label: "标签选择", prop: "tags", type: "slot", width: "100%" },
|
||||
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" },
|
||||
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" }
|
||||
]);
|
||||
const loading = ref(false);
|
||||
const elform = ref();
|
||||
@ -116,14 +262,14 @@ const disabled = ref(false);
|
||||
// phoneList已重构为listQuery.value.ryLxdh
|
||||
// 创建一个工具函数进行深拷贝
|
||||
const deepClone = (obj) => {
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
return obj;
|
||||
}
|
||||
if (obj instanceof Date) {
|
||||
return new Date(obj.getTime());
|
||||
}
|
||||
if (obj instanceof Array) {
|
||||
return obj.map(item => deepClone(item));
|
||||
return obj.map((item) => deepClone(item));
|
||||
}
|
||||
const clonedObj = {};
|
||||
for (const key in obj) {
|
||||
@ -133,124 +279,123 @@ const deepClone = (obj) => {
|
||||
}
|
||||
return clonedObj;
|
||||
};
|
||||
// 监听props.dataList变化,处理初始化数据
|
||||
watch(() => props.dataList, (val) => {
|
||||
if (val) {
|
||||
// 使用深拷贝避免直接引用同一个对象
|
||||
listQuery.value = deepClone(val);
|
||||
// 处理照片数据
|
||||
listQuery.value.ryzp = val.ryzp == null || val.ryzp == '' ? [] : [val.ryzp];
|
||||
listQuery.value.zdrSjjz = val.zdrSjjz == null || val.zdrSjjz == '' ? [] : JSON.parse(val.zdrSjjz);
|
||||
// 处理标签ID数据,确保数据回显
|
||||
if (val.tagIds && Array.isArray(val.tagIds) && val.tagIds.length > 0) {
|
||||
roleIds.value = [...val.tagIds];
|
||||
} else if (val.bqIds && Array.isArray(val.bqIds) && val.bqIds.length > 0) {
|
||||
roleIds.value = [...val.bqIds];
|
||||
} else {
|
||||
roleIds.value = [];
|
||||
// 监听身份证号变化,自动填充性别、出生日期和民族
|
||||
watch(
|
||||
() => listQuery.value.rySfzh,
|
||||
(val) => {
|
||||
if (val && val.length === 18) {
|
||||
// 使用IdCard方法提取出生日期
|
||||
listQuery.value.ryCsrq = IdCard(val, 1);
|
||||
// 使用IdCard方法提取性别
|
||||
const genderText = IdCard(val, 2);
|
||||
listQuery.value.ryXb = D_BZ_XB.value.find(
|
||||
(item) => item.zdmc === genderText
|
||||
).dm;
|
||||
}
|
||||
}
|
||||
}, { deep: true })
|
||||
);
|
||||
|
||||
// 监听props.dataList变化,处理初始化数据
|
||||
watch(
|
||||
() => props.dataList,
|
||||
(val) => {
|
||||
if (val) {
|
||||
console.log(val);
|
||||
|
||||
// 使用深拷贝避免直接引用同一个对象
|
||||
listQuery.value = deepClone(val);
|
||||
// 处理照片数据
|
||||
listQuery.value.ryzp =
|
||||
val.ryzp == null || val.ryzp == "" ? [] : [val.ryzp];
|
||||
listQuery.value.zdrSjjz =
|
||||
val.zdrSjjz == null || val.zdrSjjz == "" ? [] : JSON.parse(val.zdrSjjz);
|
||||
// 处理标签ID数据,确保数据回显
|
||||
if (val.tagIds && Array.isArray(val.tagIds) && val.tagIds.length > 0) {
|
||||
roleIds.value = [...val.tagIds];
|
||||
} else if (
|
||||
val.bqIds &&
|
||||
Array.isArray(val.bqIds) &&
|
||||
val.bqIds.length > 0
|
||||
) {
|
||||
roleIds.value = [...val.bqIds];
|
||||
} else {
|
||||
roleIds.value = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
// 提交
|
||||
const submit = () => {
|
||||
loading.value = true
|
||||
gettbGsxtZdryUpdate()
|
||||
loading.value = true;
|
||||
gettbGsxtZdryUpdate();
|
||||
};
|
||||
//
|
||||
const gettbGsxtZdryUpdate = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
const promes = {
|
||||
...listQuery.value,
|
||||
ryzp: listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : "",
|
||||
ryLxdh: listQuery.value.ryLxdh,
|
||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
||||
|
||||
}
|
||||
ryzp:
|
||||
listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : "",
|
||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz)
|
||||
};
|
||||
elform.value.submit((data) => {
|
||||
tbGsxtZdryUpdate(promes).then((res) => {
|
||||
listQuery.value.ryzp = []
|
||||
proxy.$message({
|
||||
message: '更新成功',
|
||||
type: 'success',
|
||||
})
|
||||
}).catch((err) => {
|
||||
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
tbGsxtZdryUpdate(promes)
|
||||
.then((res) => {
|
||||
listQuery.value.ryzp = [];
|
||||
proxy.$message({
|
||||
message: "更新成功",
|
||||
type: "success"
|
||||
});
|
||||
emit("close");
|
||||
})
|
||||
.catch((err) => {})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
// 添加电话号码
|
||||
const addPhone = () => {
|
||||
// 确保新添加的电话号码与现有数据结构一致
|
||||
// 创建深拷贝以避免响应式更新问题
|
||||
const newPhoneList = [...listQuery.value.ryLxdh];
|
||||
newPhoneList.push('');
|
||||
// 用全新数组替换现有数组,确保Vue正确检测到变化
|
||||
listQuery.value.ryLxdh = newPhoneList;
|
||||
}
|
||||
|
||||
// 删除电话号码
|
||||
const removePhone = (index) => {
|
||||
if (listQuery.value.ryLxdh.length > 1) {
|
||||
listQuery.value.ryLxdh.splice(index, 1);
|
||||
} else {
|
||||
// 清空输入但保留输入框
|
||||
listQuery.value.ryLxdh[0] = '';
|
||||
proxy.$message.warning('至少保留一个联系电话');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const throwData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (elform.value && elform.value.validate) {
|
||||
elform.value.submit((data) => {
|
||||
// 过滤掉空的电话号码
|
||||
const validPhones = listQuery.value.ryLxdh.filter(phone => phone && phone.trim());
|
||||
if (validPhones.length === 0) {
|
||||
proxy.$message.warning('请至少输入一个有效的联系电话');
|
||||
reject(new Error('请至少输入一个有效的联系电话'));
|
||||
return;
|
||||
}
|
||||
resolve({
|
||||
...listQuery.value,
|
||||
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
|
||||
ryLxdh: validPhones,
|
||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
||||
ryzp:
|
||||
listQuery.value.ryzp && listQuery.value.ryzp.length > 0
|
||||
? listQuery.value.ryzp.toString()
|
||||
: "",
|
||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz)
|
||||
});
|
||||
})
|
||||
});
|
||||
} else {
|
||||
elform.value.submit((data) => {
|
||||
// 如果没有验证方法,直接返回数据
|
||||
const validPhones = listQuery.value.ryLxdh.filter(phone => phone && phone.trim());
|
||||
if (validPhones.length === 0) {
|
||||
proxy.$message.warning('请至少输入一个有效的联系电话');
|
||||
reject(new Error('请至少输入一个有效的联系电话'));
|
||||
return;
|
||||
}
|
||||
|
||||
resolve({
|
||||
...listQuery.value,
|
||||
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
|
||||
ryLxdh: validPhones,
|
||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
||||
ryzp:
|
||||
listQuery.value.ryzp && listQuery.value.ryzp.length > 0
|
||||
? listQuery.value.ryzp.toString()
|
||||
: "",
|
||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz)
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const choosed = (val) => {
|
||||
roleIds.value = [val[0].id];
|
||||
listQuery.value.gkMjXm = val[0].userName;
|
||||
listQuery.value.gkMjSfzh = val[0].idEntityCard;
|
||||
listQuery.value.gkMjLxfs = val[0].mobile;
|
||||
listQuery.value.gkMjJh = val[0].inDustRialId;
|
||||
console.log(listQuery.value);
|
||||
};
|
||||
defineExpose({
|
||||
throwData,
|
||||
throwData
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -294,7 +439,7 @@ defineExpose({
|
||||
}
|
||||
|
||||
.headClass::after {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -2px;
|
||||
|
||||
@ -2,10 +2,21 @@
|
||||
<div>
|
||||
<div class="headClass" style="">
|
||||
<h3>人员标签</h3>
|
||||
<el-button type="primary" :disabled="disabled" @click="chooseMarksVisible = true">选择</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="disabled"
|
||||
@click="chooseMarksVisible = true"
|
||||
>选择</el-button
|
||||
>
|
||||
</div>
|
||||
<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 #bqLx="{ row }">
|
||||
<DictTag :tag="false" :value="row.bqLx" :options="D_GS_BQ_DJ" />
|
||||
</template>
|
||||
@ -18,143 +29,181 @@
|
||||
</template>
|
||||
</MyTable>
|
||||
</div>
|
||||
<ChooseMarks v-model="chooseMarksVisible" @choosed="addMarks" :roleIds="roleIds" />
|
||||
<ChooseMarks
|
||||
v-model="chooseMarksVisible"
|
||||
@choosed="addMarks"
|
||||
:roleIds="roleIds"
|
||||
:bqLx="defaultBqLx"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
watch,
|
||||
toRaw,
|
||||
computed,
|
||||
getCurrentInstance,
|
||||
onMounted,
|
||||
onUnmounted
|
||||
} from "vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
|
||||
import { tbGsxtZdryUpdate } from '@/api/zdr.js'
|
||||
import { tbGsxtZdryUpdate } from "@/api/zdr.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_GS_BQ_DJ, D_GS_SSYJ } = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ"); //获取字典数据
|
||||
const chooseMarksVisible = ref(false)
|
||||
const chooseMarksVisible = ref(false);
|
||||
const props = defineProps({
|
||||
dataList: {
|
||||
type: Object,
|
||||
default: () => { },
|
||||
}, disabled: {
|
||||
default: () => {}
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showBut: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
})
|
||||
const listData = ref({})
|
||||
watch(() => props.dataList, (val) => {
|
||||
if (val) {
|
||||
listData.value = val
|
||||
pageData.tableData = val.bqList
|
||||
roleIds.value = val.bqList.map(v => v.bqId)
|
||||
console.log(roleIds.value);
|
||||
|
||||
}
|
||||
}, { deep: true })
|
||||
const roleIds = ref([])
|
||||
});
|
||||
|
||||
const listData = ref({});
|
||||
const roleIds = ref([]);
|
||||
|
||||
watch(
|
||||
() => props.dataList,
|
||||
(val) => {
|
||||
if (val) {
|
||||
listData.value = val;
|
||||
pageData.tableData = val.bqList;
|
||||
roleIds.value = val.bqList.map((v) => v.bqId);
|
||||
console.log(roleIds.value);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 表格数据
|
||||
const pageData = reactive({
|
||||
tableData: [],
|
||||
tableColumn: [{
|
||||
prop: 'bqMc',
|
||||
label: '标签名称',
|
||||
showOverflowTooltip: true
|
||||
}, {
|
||||
prop: 'bqDm',
|
||||
label: '标签代码',
|
||||
}, {
|
||||
showSolt: true,
|
||||
prop: 'bqLx',
|
||||
label: '标签类型',
|
||||
}, {
|
||||
showSolt: true,
|
||||
prop: 'bqLb',
|
||||
label: '标签类别',
|
||||
}],
|
||||
tableHeight: '200px',
|
||||
tableColumn: [
|
||||
{
|
||||
prop: "bqMc",
|
||||
label: "标签名称",
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: "bqDm",
|
||||
label: "标签代码"
|
||||
},
|
||||
{
|
||||
showSolt: true,
|
||||
prop: "bqLx",
|
||||
label: "标签类型"
|
||||
},
|
||||
{
|
||||
showSolt: true,
|
||||
prop: "bqLb",
|
||||
label: "标签类别"
|
||||
}
|
||||
],
|
||||
tableHeight: "200px",
|
||||
keyCount: 0,
|
||||
tableConfiger: {
|
||||
border: true,
|
||||
stripe: true,
|
||||
showHeader: true,
|
||||
showIndex: true,
|
||||
indexLabel: '序号',
|
||||
indexLabel: "序号",
|
||||
indexWidth: 60,
|
||||
align: 'center',
|
||||
align: "center",
|
||||
showOverflowTooltip: true,
|
||||
haveControls: !props.disabled
|
||||
},
|
||||
controlsWidth: 200,
|
||||
})
|
||||
controlsWidth: 200
|
||||
});
|
||||
|
||||
// 计算默认的标签类型:如果已选数据中有身份标签则默认显示身份标签,否则默认显示行为标签
|
||||
const defaultBqLx = computed(() => {
|
||||
if (roleIds.value && roleIds.value.length > 0) {
|
||||
const selectedItem = pageData.tableData.find((item) => roleIds.value.includes(item.bqId));
|
||||
if (selectedItem && selectedItem.bqLx) {
|
||||
return selectedItem.bqLx;
|
||||
}
|
||||
}
|
||||
return "02";
|
||||
});
|
||||
// 修改数据接口
|
||||
const zdqtUpdate = (val) => {
|
||||
const params = {
|
||||
id: listData.value.id,
|
||||
bqList: pageData.tableData,
|
||||
rySfzh: listData.value.rySfzh,
|
||||
}
|
||||
tbGsxtZdryUpdate(params).then(res => {
|
||||
rySfzh: listData.value.rySfzh
|
||||
};
|
||||
tbGsxtZdryUpdate(params).then((res) => {
|
||||
proxy.$message({
|
||||
message: val,
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
}
|
||||
type: "success"
|
||||
});
|
||||
});
|
||||
};
|
||||
// 新增标签
|
||||
const addMarks = (val) => {
|
||||
pageData.tableData = val.map(v => {
|
||||
return { bqDm: v.bqDm, bqId: v.id, bqLb: v.bqLb, bqLx: v.bqLx, bqMc: v.bqMc }
|
||||
pageData.tableData = val.map((v) => {
|
||||
return {
|
||||
bqDm: v.bqDm,
|
||||
bqId: v.id,
|
||||
bqLb: v.bqLb,
|
||||
bqLx: v.bqLx,
|
||||
bqMc: v.bqMc,
|
||||
bqYs: v.bqYs
|
||||
};
|
||||
});
|
||||
roleIds.value = val.map(v => v.id)
|
||||
roleIds.value = val.map((v) => v.id);
|
||||
if (!props.disabled && props.showBut) {
|
||||
zdqtUpdate("标签添加成功")
|
||||
zdqtUpdate("标签添加成功");
|
||||
}
|
||||
}
|
||||
};
|
||||
// 删除标签
|
||||
const delDictItem = (val) => {
|
||||
if (!props.disabled && props.showBut) {
|
||||
ElMessageBox.confirm(
|
||||
'是否删除标签',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
pageData.tableData = pageData.tableData.filter(v => v.bqId != val)
|
||||
roleIds.value = roleIds.value.filter(v => v != val)
|
||||
zdqtUpdate("标签删除成功")
|
||||
ElMessageBox.confirm("是否删除标签", "提示", {
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: 'info',
|
||||
message: '取消删除',
|
||||
.then(() => {
|
||||
pageData.tableData = pageData.tableData.filter((v) => v.bqId != val);
|
||||
roleIds.value = roleIds.value.filter((v) => v != val);
|
||||
zdqtUpdate("标签删除成功");
|
||||
})
|
||||
})
|
||||
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "info",
|
||||
message: "取消删除"
|
||||
});
|
||||
});
|
||||
} else {
|
||||
pageData.tableData = pageData.tableData.filter(v => v.bqId != val)
|
||||
roleIds.value = roleIds.value.filter(v => v != val)
|
||||
pageData.tableData = pageData.tableData.filter((v) => v.bqId != val);
|
||||
roleIds.value = roleIds.value.filter((v) => v != val);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
// 抛出数据并验证标签列表不为空
|
||||
const throwData = () => {
|
||||
return new Promise((resolve) => {
|
||||
// 验证:确保标签列表不为空
|
||||
if (!pageData.tableData || pageData.tableData.length === 0) {
|
||||
throw new Error('请选择群体标签');
|
||||
throw new Error("请选择群体标签");
|
||||
}
|
||||
resolve(pageData.tableData);
|
||||
});
|
||||
}
|
||||
};
|
||||
defineExpose({
|
||||
throwData
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -196,7 +245,7 @@ defineExpose({
|
||||
}
|
||||
|
||||
.headClass::after {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -2px;
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
</template>
|
||||
</PageTitle> -->
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox heightBox">
|
||||
<div class="margTop">
|
||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
||||
@chooseData="chooseData">
|
||||
@ -96,48 +96,6 @@
|
||||
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-popover placement="left" :visible="row.visible" :width="400" trigger="manual">
|
||||
<template #reference>
|
||||
<el-link size="small" type="warning" v-if="row.zdrZt == '02'"
|
||||
@click="row.visible = !row.visible, chooseRow.id = row.id">审核</el-link>
|
||||
</template>
|
||||
<el-form :model="chooseRow" ref="elRowForm" :inline="true" label-width="100px" :rules="rules">
|
||||
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;">
|
||||
<MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable
|
||||
placeholder="请选择是否通过" />
|
||||
</el-form-item>
|
||||
<el-form-item label="不通过原因" prop="shBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;">
|
||||
<MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.shBtgyy" type="textarea"
|
||||
placeholder="请输入不通过原因" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="flex just-center mt10">
|
||||
<el-button @click.stop="cancelRow(row)">取消</el-button>
|
||||
<el-button type="primary" @click.stop="handleSend(row)" v-loading="btnloading">确定</el-button>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
||||
<el-popover placement="left" :visible="row.visible1" :width="400" trigger="manual">
|
||||
<template #reference>
|
||||
<el-link size="small" type="primary" v-if="row.zdrZt == '04'"
|
||||
@click="row.visible1 = !row.visible1, chooseRow.id = row.id">审批</el-link>
|
||||
</template>
|
||||
<el-form :model="chooseRow" ref="elRowForm1" :inline="true" label-width="100px" :rules="rules">
|
||||
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;">
|
||||
<MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable
|
||||
placeholder="请选择是否通过" />
|
||||
</el-form-item>
|
||||
<el-form-item label="不通过原因" prop="spBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;">
|
||||
<MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.spBtgyy" type="textarea"
|
||||
placeholder="请输入不通过原因" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="flex just-center mt10">
|
||||
<el-button @click.stop="cancelRowSp(row)">取消</el-button>
|
||||
<el-button type="primary" @click.stop="handleSendSp(row)" v-loading="btnloading">确定</el-button>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
@ -147,19 +105,18 @@
|
||||
}"></Pages>
|
||||
</div>
|
||||
<!-- 详情 -->
|
||||
<AddForm ref="addFormDiloag" @updateDate="getList"
|
||||
<AddForm ref="addFormDiloag" @updateDate="getList" :showButData="true"
|
||||
: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" />
|
||||
<!-- 转线索 -->
|
||||
<ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList"
|
||||
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }"></ZxsForm>
|
||||
<Ypdolog v-model="showYpdolog" :dataList="ids"/>
|
||||
<Ypdolog v-model="showYpdolog" :dataList="ids" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as MOSTY from "@/components/MyComponents/index";
|
||||
import { ElMessage } from "element-plus";
|
||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||
import ZxsForm from "../mpvPeo/components/zxsForm.vue";
|
||||
@ -184,15 +141,6 @@ const ids = ref([]);
|
||||
const choosList = ref([]);
|
||||
const visible = ref(false);
|
||||
const visiblefp = ref(false);
|
||||
const chooseRow = ref({})
|
||||
const btnloading = ref(false)
|
||||
const elRowForm = ref()
|
||||
const elRowForm1 = ref()
|
||||
const rules = reactive({
|
||||
sftg: [{ required: true, message: "请选择是否通过", trigger: "change" }],
|
||||
shBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }],
|
||||
spBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }]
|
||||
});
|
||||
|
||||
const searchConfiger = ref([
|
||||
{
|
||||
@ -346,50 +294,7 @@ const handleZxs = () => {
|
||||
};
|
||||
|
||||
|
||||
const cancelRow = (row) => {
|
||||
row.visible = false;
|
||||
chooseRow.value = {};
|
||||
btnloading.value = false;
|
||||
elRowForm.value.resetFields()
|
||||
};
|
||||
|
||||
// 审核
|
||||
const handleSend = (val) => {
|
||||
elRowForm.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
btnloading.value = true;
|
||||
qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSh").then(() => {
|
||||
proxy.$message({ type: "success", message: "审核成功" });
|
||||
cancelRow(val)
|
||||
getList();
|
||||
}).catch(() => {
|
||||
btnloading.value = false;
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 审批
|
||||
const cancelRowSp = (row) => {
|
||||
row.visible1 = false;
|
||||
chooseRow.value = {};
|
||||
btnloading.value = false;
|
||||
elRowForm1.value.resetFields()
|
||||
}
|
||||
// 审批
|
||||
const handleSendSp = (val) => {
|
||||
elRowForm1.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
btnloading.value = true;
|
||||
qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSp").then(() => {
|
||||
proxy.$message({ type: "success", message: "审批成功" });
|
||||
cancelRowSp(val);
|
||||
getList();
|
||||
}).catch(() => {
|
||||
btnloading.value = false;
|
||||
});
|
||||
})
|
||||
}
|
||||
const showYpdolog=ref(false)
|
||||
const showYpdolog = ref(false)
|
||||
|
||||
//新增编辑
|
||||
const addEdit = (type, row) => {
|
||||
@ -401,7 +306,7 @@ const addEdit = (type, row) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 200;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -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"
|
||||
);
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
<div class="head_box">
|
||||
<span class="title">线索{{ title }}</span>
|
||||
<div>
|
||||
<el-button type="primary" v-if="!disabled" :loading="loading" @click="submit">保存</el-button>
|
||||
<el-button @click="close">关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -19,6 +20,7 @@
|
||||
|
||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||
import { qbcjAdd, qbcjUpdate, qbcjSelectByid } from "@/api/Intelligence.js";
|
||||
import { qcckGet, qcckPost } from '@/api/qcckApi'
|
||||
import pursueContent from "@/views/backOfficeSystem/HumanIntelligence/components/pursueContent.vue";
|
||||
import { ref, defineExpose, onMounted, defineEmits, watch, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance()
|
||||
@ -33,6 +35,12 @@ const props = defineProps({
|
||||
const loading = ref(false)
|
||||
const dialogForm = ref(false); //弹窗
|
||||
const formData = ref();
|
||||
const rules = ref({
|
||||
qbmc: [{ required: true, message: "请输入情报标题", trigger: ["blur"] }],
|
||||
zxssj: [{ required: true, message: "请选择转线索时间", trigger: ["blur"] }],
|
||||
qbnr: [{ required: true, message: "请输入情报内容", trigger: ["blur"] }],
|
||||
});
|
||||
|
||||
|
||||
|
||||
watch(() => dialogForm.value, (val) => {
|
||||
@ -48,29 +56,45 @@ watch(() => dialogForm.value, (val) => {
|
||||
}
|
||||
}, { deep: true })
|
||||
const listQuery = ref({}); //表单
|
||||
const elform = ref();
|
||||
onMounted(() => {
|
||||
})
|
||||
const addForm = ref()
|
||||
const msgeDat = ref()
|
||||
const title = ref("")
|
||||
const showPj = ref(false)
|
||||
const disabled = ref(false)
|
||||
// 初始化数据
|
||||
const init = (type, row) => {
|
||||
console.log(row,"测试");
|
||||
|
||||
title.value = type == "add" ? "新增" : type == "info" ? "详情" : "编辑"
|
||||
disabled.value = type == 'info' ? true : false
|
||||
// disabled.value = type == 'info' ? true : false
|
||||
dialogForm.value = true;
|
||||
if (type == 'info' || type == 'edit') {
|
||||
if (type != 'add') {
|
||||
showPj.value = true
|
||||
listQuery.value = row
|
||||
if (type == 'info') {
|
||||
disabled.value = true
|
||||
} else {
|
||||
disabled.value = false
|
||||
}
|
||||
} else {
|
||||
disabled.value = false
|
||||
}
|
||||
};
|
||||
// 新增修改
|
||||
const submit = () => {
|
||||
const promes = { ...listQuery.value }
|
||||
const url = title.value == "新增" ? "/mosty-gsxt/xxcj/zxs/addEntity" : "/mosty-gsxt/xxcj/zxs/updateEntity"
|
||||
qcckPost({...promes,qbly:'0'}, url).then(res => {
|
||||
proxy.$message({
|
||||
message: "操作成功",
|
||||
type: "success",
|
||||
});
|
||||
emit("getList")
|
||||
close()
|
||||
})
|
||||
|
||||
};
|
||||
const close = () => {
|
||||
dialogForm.value = false;
|
||||
listQuery.value = {};
|
||||
};
|
||||
|
||||
defineExpose({ init });
|
||||
@ -185,7 +209,8 @@ defineExpose({ init });
|
||||
color: #f78989;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
::v-deep .el-textarea.is-disabled .el-textarea__inner{
|
||||
|
||||
::v-deep .el-textarea.is-disabled .el-textarea__inner {
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,7 +2,15 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10 mb10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" />
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
|
||||
<el-button type="primary" size="small" @click="getDataById('add', null)">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
<el-button type="danger" size="small" @click="handleRow()">批量删除</el-button>
|
||||
</Search>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox heightBox">
|
||||
@ -15,9 +23,14 @@
|
||||
<template #cjlx="{ row }">
|
||||
<DictTag :tag="false" :value="row.cjLx" :options="D_BZ_CJLX" />
|
||||
</template>
|
||||
<template #qbly="{ row }">
|
||||
<DictTag :tag="false" :value="row.qbly" :options="D_GS_XS_LY" />
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<template #controls="{ row }">
|
||||
<el-link size="small" type="primary" @click="getDataById(row)">详情</el-link>
|
||||
<el-link size="small" type="primary" @click="getDataById('info',row)">详情</el-link>
|
||||
<el-link size="small" type="primary" @click="getDataById('edit',row)">编辑</el-link>
|
||||
<el-link size="small" type="danger" @click="handleRow(row.id)">删除</el-link>
|
||||
</template>
|
||||
</MyTable>
|
||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||
@ -26,21 +39,21 @@
|
||||
}"></Pages>
|
||||
</div>
|
||||
</div>
|
||||
<AddForm ref="addForm" :dict="{ D_BZ_CJLX, D_GS_XS_LX }" />
|
||||
<AddForm ref="addForm" :dict="{ D_BZ_CJLX, D_GS_XS_LX }" @getList="getList" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||
import Pages from "@/components/aboutTable/Pages.vue";
|
||||
import Search from "@/components/aboutTable/Search.vue";
|
||||
import { useRoute } from 'vue-router'
|
||||
import { xxcjZxsSelectPage } from "@/api/xxcj.js";
|
||||
import { qcckGet, qcckPost } from '@/api/qcckApi'
|
||||
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
|
||||
import AddForm from "./addForm.vue"
|
||||
import { getItem } from '@//utils/storage.js'
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { D_BZ_CJLX, D_GS_XS_LX } = proxy.$dict("D_BZ_CJLX", "D_GS_XS_LX"); //获取字典数据
|
||||
const { D_BZ_CJLX, D_GS_XS_LX,D_GS_XS_LY } = proxy.$dict("D_BZ_CJLX", "D_GS_XS_LX","D_GS_XS_LY"); //获取字典数据
|
||||
const detailDiloag = ref();
|
||||
const searchBox = ref(); //搜索框
|
||||
const ids = ref([])
|
||||
@ -90,12 +103,12 @@ const pageData = reactive({
|
||||
pageSize: 20,
|
||||
pageCurrent: 1
|
||||
},
|
||||
controlsWidth: 100,
|
||||
controlsWidth: 180,
|
||||
tableColumn: [
|
||||
{ label: "情报标题", prop: "qbmc",width:250 },
|
||||
{ label: "编号", prop: "xsBh",width:190 },
|
||||
// { label: "情报类型", prop: "qblx", showSolt: true },
|
||||
// { label: "情报来源", prop: "cjlx", showSolt: true },
|
||||
{ label: "情报来源", prop: "qbly", showSolt: true },
|
||||
{ label: "转线索时间", prop: "zxssj",width:190 },
|
||||
{ label: "情报内容", prop: "qbnr",width:190 },
|
||||
{ label: "所属部门", prop: "ssbm" },
|
||||
@ -126,17 +139,36 @@ const getList = () => {
|
||||
pageData.tableConfiger.loading = true;
|
||||
let data = { ...pageData.pageConfiger, ...queryFrom.value };
|
||||
delete data.times;
|
||||
xxcjZxsSelectPage(data).then(res => {
|
||||
pageData.tableData = res.records || [];
|
||||
pageData.total = res.total;
|
||||
pageData.tableConfiger.loading = false;
|
||||
}).catch(() => { pageData.tableConfiger.loading = false; })
|
||||
}
|
||||
qcckGet(data, "/mosty-gsxt/xxcj/zxs/selectPage").then((res) => {
|
||||
pageData.tableData = res.records || [];
|
||||
pageData.total = res.total;
|
||||
}).catch(() => {
|
||||
}).finally(() => {
|
||||
pageData.tableConfiger.loading = false;
|
||||
})
|
||||
|
||||
// xxcjZxsSelectPage(data).then(res => {
|
||||
// pageData.tableData = res.records || [];
|
||||
// pageData.total = res.total;
|
||||
// pageData.tableConfiger.loading = false;
|
||||
// }).catch(() => { pageData.tableConfiger.loading = false; })
|
||||
}
|
||||
// 删除
|
||||
const handleRow = (id) => {
|
||||
const promes = {
|
||||
ids: id ? [id] : ids.value
|
||||
}
|
||||
proxy.$confirm("确定要删除?", "警告", { type: "warning" }).then(() => {
|
||||
qcckPost(promes, "/mosty-gsxt/xxcj/zxs/deletes").then(() => {
|
||||
proxy.$message({ type: "success", message: "删除成功" });
|
||||
getList();
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 200;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
@ -147,10 +179,8 @@ const getRouter = () => {
|
||||
routerMate.value = route.meta
|
||||
}
|
||||
const addForm = ref(null)
|
||||
const getDataById = (row) => {
|
||||
addForm.value.init('info', row);
|
||||
console.log(row);
|
||||
|
||||
const getDataById = (type,row) => {
|
||||
addForm.value.init(type, row);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@ -9,23 +9,14 @@
|
||||
</div>
|
||||
<div class="form_cnt">
|
||||
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" :disabled="title == '详情'">
|
||||
<template #bkyj>
|
||||
<el-divider content-position="left"><span style="color: blue;">布控预警</span></el-divider>
|
||||
<template #yjNum>
|
||||
<el-divider content-position="left"><span style="color: blue;">预警</span></el-divider>
|
||||
</template>
|
||||
<template #clyj>
|
||||
<el-divider content-position="left"><span style="color: blue;">车辆预警</span></el-divider>
|
||||
<template #csfs>
|
||||
<el-divider content-position="left"><span style="color: blue;">信息</span></el-divider>
|
||||
</template>
|
||||
<template #qlry>
|
||||
<el-divider content-position="left"><span style="color: blue;">7类重点人员预警</span></el-divider>
|
||||
</template>
|
||||
<template #rxyj>
|
||||
<el-divider content-position="left"><span style="color: blue;">人像预警</span></el-divider>
|
||||
</template>
|
||||
<template #zbyj>
|
||||
<el-divider content-position="left"><span style="color: blue;">政保预警</span></el-divider>
|
||||
</template>
|
||||
<template #fs>
|
||||
<el-divider content-position="left"><span style="color: blue;">考核分数</span></el-divider>
|
||||
<template #ypNum>
|
||||
<el-divider content-position="left"><span style="color: blue;">研判</span></el-divider>
|
||||
</template>
|
||||
</FormMessage>
|
||||
</div>
|
||||
@ -62,25 +53,21 @@ const formData = ref([
|
||||
{ label: "考核开始日期", prop: "ksrq", type: "date" },
|
||||
{ label: "考核结束日期", prop: "jsrq", type: "date" },
|
||||
{ label: "考核描述", prop: "khzbms", type: "textarea", width: "100%" },
|
||||
{ prop: "fs", type: "slot", width: "100%" },
|
||||
{ label: "采集分数", prop: "cjfs", type: "number", min: 0, max: 100, step: 1 },
|
||||
{ label: "研判分数", prop: "ypfs", type: "number", min: 0, max: 100, step: 1 },
|
||||
{ prop: "bkyj", type: "slot", width: "100%" },
|
||||
{ prop: "yjNum", type: "slot", width: "100%" },
|
||||
{ label: "布控预警反馈率", prop: "bkyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "布控预警签收率", prop: "bkyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ prop: "clyj", type: "slot", width: "100%" },
|
||||
{ label: "车辆预警反馈率", prop: "clyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "车辆预警签收率", prop: "clyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ prop: "qlry", type: "slot", width: "100%" },
|
||||
{ label: "7类重点人员反馈率", prop: "qlryFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "7类重点人员签收率", prop: "qlryQsl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ prop: "rxyj", type: "slot", width: "100%" },
|
||||
{ label: "人像预警反馈率", prop: "rxyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "7类重点人员反馈率", prop: "qlryFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "人像预警签收率", prop: "rxyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ prop: "zbyj", type: "slot", width: "100%" },
|
||||
{ label: "政保预警反馈率", prop: "zbyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "人像预警反馈率", prop: "rxyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ label: "政保预警签收率", prop: "zbyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
|
||||
{ label: "政保预警反馈率", prop: "zbyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
|
||||
{ prop: "csfs", type: "slot", width: "100%" },
|
||||
{ label: "采集分数", prop: "cjfs", type: "number", min: 0, max: 100, step: 1 },
|
||||
{ prop: "ypNum", type: "slot", width: "100%" },
|
||||
{ label: "研判分数", prop: "ypfs", type: "number", min: 0, max: 100, step: 1 },
|
||||
]);
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
@ -2,20 +2,22 @@
|
||||
<div>
|
||||
<!-- 搜索 -->
|
||||
<div ref="searchBox" class="mt10">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" />
|
||||
</div>
|
||||
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
<el-button size="small" type="primary" @click="addEdit('add', '')">
|
||||
<Search :searchArr="searchConfiger" @submit="onSearch" >
|
||||
<el-button size="small" type="primary" @click="addEdit('add', '')">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<CirclePlus />
|
||||
</el-icon>
|
||||
<span style="vertical-align: middle">新增</span>
|
||||
</el-button>
|
||||
</Search>
|
||||
</div>
|
||||
<!-- <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
|
||||
<template #left>
|
||||
|
||||
</template>
|
||||
</PageTitle>
|
||||
</PageTitle> -->
|
||||
<!-- 表格 -->
|
||||
<div class="tabBox">
|
||||
<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"
|
||||
@ -157,7 +159,7 @@ const addEdit = (type, row) => {
|
||||
|
||||
// 表格高度计算
|
||||
const tabHeightFn = () => {
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
|
||||
window.onresize = function () {
|
||||
tabHeightFn();
|
||||
};
|
||||
|
||||
@ -26,11 +26,13 @@
|
||||
<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" />
|
||||
<div style="display: flex;">
|
||||
市审核状态:
|
||||
<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" />
|
||||
<div style="display: flex;">
|
||||
县审核状态:
|
||||
<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(() => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user