From 16e9746e5da1ac0485fde18e71fb7bf8ee376d42 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Mon, 19 Jan 2026 11:38:00 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/jagzwxm/ja_web
---
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue | 218 +++
uniapps/work-wx/src/subPackages/userDetail/infos/index.vue | 156 +-
applications/task-work-order/src/router/page/index.js | 133 +-
uniapps/work-app/src/hooks/useGlobalWS.js | 104 -
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue | 220 ++++
uniapps/work-app/src/utils/websocket.js | 30
uniapps/work-app/src/store/index.js | 3
applications/task-work-order/src/store/modules/user.js | 769 +++++++-------
uniapps/work-app/src/subPackages/userDetail/infos/index.vue | 37
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue | 291 +++++
applications/mobile-web-view/src/appDataSource/leafletMapIcon/search-normal.svg | 14
applications/task-work-order/src/views/basicManage/maintainRecord/index.vue | 30
applications/task-work-order/src/styles/common/cockpit.scss | 63
applications/task-work-order/src/config/website.js | 139 +-
applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue | 135 --
uniapps/work-app/src/pages/login/index.vue | 22
applications/task-work-order/src/views/wel/index.vue | 4
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue | 178 +++
applications/task-work-order/src/permission.js | 3
uniapps/work-app/src/utils/location.js | 260 ++++
uniapps/work-app/src/App.vue | 17
/dev/null | 19
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/supplyAddApi.js | 55 +
applications/mobile-web-view/src/appComponents/LeafletMap/index.vue | 88 +
applications/task-work-order/src/router/views/index.js | 18
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/evaluateApi.js | 37
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue | 2
uniapps/work-app/src/store/modules/location.js | 137 ++
28 files changed, 2,231 insertions(+), 951 deletions(-)
diff --git a/applications/mobile-web-view/src/appComponents/LeafletMap/index.vue b/applications/mobile-web-view/src/appComponents/LeafletMap/index.vue
index b6add64..8e43521 100644
--- a/applications/mobile-web-view/src/appComponents/LeafletMap/index.vue
+++ b/applications/mobile-web-view/src/appComponents/LeafletMap/index.vue
@@ -156,9 +156,9 @@
let locationFlag = false
let watchId = null
let userLocationMarker = null
-const setMapLocation = () => {
- locationFlag = true
+// 初始化实时位置监听
+const initLocationWatch = () => {
// 在WebView加载的网页中
// 检查浏览器是否支持 geolocation
if (navigator.geolocation) {
@@ -166,7 +166,6 @@
// 停止监听位置
navigator.geolocation.clearWatch(watchId)
}
-
// 开始持续获取用户的位置
watchId = navigator.geolocation.watchPosition(
function (position) {
@@ -174,31 +173,26 @@
const lat = position.coords.latitude // 纬度
const lng = position.coords.longitude // 经度
- if (locationFlag) {
- if (userLocationMarker) {
- userLocationMarker.setLatLng([lat, lng])
- } else {
- userLocationMarker = L.marker([lat, lng], {
- icon: L.icon({
+ // 确保位置标记存在并更新位置
+ if (userLocationMarker) {
+ userLocationMarker.setLatLng([lat, lng])
+ } else {
+ userLocationMarker = L.marker([lat, lng], {
+ icon: L.icon({
iconUrl: userLocationIcon, // 图片路径
- iconSize: [24, 24], // 图标尺寸
- iconAnchor: [12, 12], // 锚点位置
- }),
- }).addTo(map)
- }
+ iconSize: [24, 24], // 图标尺寸
+ iconAnchor: [12, 12], // 锚点位置
+ }),
+ }).addTo(map)
+ }
+ // 如果是点击定位按钮触发的,将地图视图定位到当前位置
+ if (locationFlag) {
mapSetView({
lat,
lng,
})
-
locationFlag = false
-
- return
- }
-
- if (userLocationMarker) {
- userLocationMarker.setLatLng([lat, lng])
}
},
function (error) {
@@ -213,6 +207,24 @@
)
} else {
console.log('该浏览器不支持地理定位功能。')
+ }
+}
+
+const setMapLocation = () => {
+ locationFlag = true
+ // 如果还没有开始监听位置,先初始化监听
+ if (!watchId) {
+ initLocationWatch()
+ } else {
+ // 已经在监听位置,会自动定位到当前位置
+ // 可以添加一个视觉反馈,比如位置标记闪烁效果
+ if (userLocationMarker) {
+ // 添加闪烁效果
+ userLocationMarker.getElement().classList.add('location-blink')
+ setTimeout(() => {
+ userLocationMarker.getElement().classList.remove('location-blink')
+ }, 1000)
+ }
}
}
let lastLocationMarker = null
@@ -450,6 +462,9 @@
initMap()
map.addLayer(layers[0].map)
+ // 初始化实时位置监听
+ initLocationWatch()
+
EventBus.on('mapSetView', mapSetView)
EventBus.on('mapAddMarker', mapAddMarker)
EventBus.on('mapAddAirMarker', mapAddAirMarker)
@@ -466,6 +481,17 @@
})
onUnmounted(() => {
+ // 清理位置监听
+ if (watchId) {
+ navigator.geolocation.clearWatch(watchId)
+ watchId = null
+ }
+ // 移除位置标记
+ if (userLocationMarker) {
+ map.removeLayer(userLocationMarker)
+ userLocationMarker = null
+ }
+
EventBus.off('mapSetView', mapSetView)
EventBus.off('mapAddMarker', mapAddMarker)
EventBus.off('mapAddAirMarker', mapAddAirMarker)
@@ -606,4 +632,24 @@
}
}
}
+
+// 位置标记闪烁效果
+.location-blink {
+ animation: blink 1s ease-in-out;
+}
+
+@keyframes blink {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.8;
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
</style>
diff --git a/applications/mobile-web-view/src/appDataSource/leafletMapIcon/search-normal.svg b/applications/mobile-web-view/src/appDataSource/leafletMapIcon/search-normal.svg
new file mode 100644
index 0000000..cc000d4
--- /dev/null
+++ b/applications/mobile-web-view/src/appDataSource/leafletMapIcon/search-normal.svg
@@ -0,0 +1,14 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="search-normal">
+<g id="search-normal_2">
+<g id="search-normal_3">
+<g id="vuesax/linear/search-normal">
+<g id="search-normal_4">
+<path id="Vector" d="M7.66659 14C11.1644 14 13.9999 11.1644 13.9999 7.66665C13.9999 4.16884 11.1644 1.33331 7.66659 1.33331C4.16878 1.33331 1.33325 4.16884 1.33325 7.66665C1.33325 11.1644 4.16878 14 7.66659 14Z" stroke="#191919" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M14.6666 14.6666L13.3333 13.3333" stroke="#191919" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</g>
+</g>
+</g>
+</g>
+</svg>
diff --git a/applications/task-work-order/src/config/website.js b/applications/task-work-order/src/config/website.js
index 1fc7403..4a718b0 100644
--- a/applications/task-work-order/src/config/website.js
+++ b/applications/task-work-order/src/config/website.js
@@ -4,81 +4,78 @@
* @LastEditors : yuan
* @LastEditTime : 2026-01-16 11:12:30
* @FilePath : \applications\task-work-order\src\config\website.js
- * @Description :
- * Copyright 2026 OBKoro1, All Rights Reserved.
+ * @Description :
+ * Copyright 2026 OBKoro1, All Rights Reserved.
* 2026-01-06 09:47:27
*/
/**
* 全局配置文件
*/
export default {
- title: 'saber',
- logo: 'S',
- key: 'work', //配置主键,目前用于存储
- indexTitle: '',
- clientId: 'saber', // 客户端id
- clientSecret: 'saber_secret', // 客户端密钥
- tenantMode: true, // 是否开启租户模式
- tenantId: '000000', // 管理组租户编号
- captchaMode: true, // 是否开启验证码模式
- switchMode: false, // 是否开启部门切换模式
- lockPage: '/lock',
- tokenTime: 3000,
- tokenHeader: 'Blade-Auth',
- //http的status默认放行不才用统一处理的,
- statusWhiteList: [],
- //配置首页不可关闭
- setting: {
- sidebar: 'vertical',
- tag: true,
- debug: true,
- collapse: true,
- search: true,
- color: true,
- lock: true,
- screenshot: true,
- fullscreen: true,
- theme: true,
- menu: true,
- },
- fistPage: {
- name: '数据驾驶舱',
- path: '/dataCockpit/index',
- // path: '/tickets/ticket',
-
- },
- //配置菜单的属性
- menu: {
- iconDefault: 'icon-caidan',
- label: 'name',
- path: 'path',
- icon: 'source',
- children: 'children',
- query: 'query',
- href: 'path',
- meta: 'meta',
- },
- //oauth2配置
- oauth2: {
- // 是否开启注册功能
- registerMode: true,
- // 使用后端工程 @org.springblade.test.Sm2KeyGenerator 获取
- publicKey: '请配置国密sm2公钥',
- // 第三方系统授权地址
- authUrl: 'http://localhost/blade-auth/oauth/render',
- // 单点登录系统认证(cloud端口为8100,boot端口为80)
- ssoUrl:
- 'http://localhost:8100/oauth/authorize?client_id=saber3&response_type=code&redirect_uri=',
- // 单点登录回调地址(Saber服务的登录界面地址)
- redirectUri: 'http://localhost:2888/login',
- },
- //设计器配置
- design: {
- // 流程设计器类型(true->nutflow,false->flowable)
- designMode: true,
- // 流程设计器地址(flowable模式)
- designUrl: 'http://localhost:9999',
- // 报表设计器地址(cloud端口为8108,boot端口为80)
- reportUrl: 'http://localhost:8108/ureport',
- },
+ title: 'saber',
+ logo: 'S',
+ key: 'work', //配置主键,目前用于存储
+ indexTitle: '',
+ clientId: 'saber', // 客户端id
+ clientSecret: 'saber_secret', // 客户端密钥
+ tenantMode: true, // 是否开启租户模式
+ tenantId: '000000', // 管理组租户编号
+ captchaMode: true, // 是否开启验证码模式
+ switchMode: false, // 是否开启部门切换模式
+ lockPage: '/lock',
+ tokenTime: 3000,
+ tokenHeader: 'Blade-Auth',
+ //http的status默认放行不才用统一处理的,
+ statusWhiteList: [],
+ //配置首页不可关闭
+ setting: {
+ sidebar: 'vertical',
+ tag: true,
+ debug: true,
+ collapse: true,
+ search: true,
+ color: true,
+ lock: true,
+ screenshot: true,
+ fullscreen: true,
+ theme: true,
+ menu: true,
+ },
+ fistPage: {
+ name: '测试页',
+ path: '/test',
+ },
+ //配置菜单的属性
+ menu: {
+ iconDefault: 'icon-caidan',
+ label: 'name',
+ path: 'path',
+ icon: 'source',
+ children: 'children',
+ query: 'query',
+ href: 'path',
+ meta: 'meta',
+ },
+ //oauth2配置
+ oauth2: {
+ // 是否开启注册功能
+ registerMode: true,
+ // 使用后端工程 @org.springblade.test.Sm2KeyGenerator 获取
+ publicKey: '请配置国密sm2公钥',
+ // 第三方系统授权地址
+ authUrl: 'http://localhost/blade-auth/oauth/render',
+ // 单点登录系统认证(cloud端口为8100,boot端口为80)
+ ssoUrl: 'http://localhost:8100/oauth/authorize?client_id=saber3&response_type=code&redirect_uri=',
+ // 单点登录回调地址(Saber服务的登录界面地址)
+ redirectUri: 'http://localhost:2888/login',
+ },
+ //设计器配置
+ design: {
+ // 流程设计器类型(true->nutflow,false->flowable)
+ designMode: true,
+ // 流程设计器地址(flowable模式)
+ designUrl: 'http://localhost:9999',
+ // 报表设计器地址(cloud端口为8108,boot端口为80)
+ reportUrl: 'http://localhost:8108/ureport',
+ },
}
diff --git a/applications/task-work-order/src/permission copy 2.js b/applications/task-work-order/src/permission copy 2.js
deleted file mode 100644
index 821f3dc..0000000
--- a/applications/task-work-order/src/permission copy 2.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * @Author: GuLiMmo 2820890765@qq.com
- * @Date: 2024-08-23 10:51:53
- * @LastEditors: GuLiMmo 2820890765@qq.com
- * @LastEditTime: 2024-08-29 14:10:56
- * @FilePath: /drone-web-manage/src/permission.js
- * @Description:
- * Copyright (c) 2024 by GuLiMmo, All Rights Reserved.
- */
-import router from './router/'
-import store from './store'
-import { getToken } from '@/utils/auth'
-import { getUrlParams } from './utils/validate'
-import NProgress from 'nprogress' // progress bar
-import 'nprogress/nprogress.css' // progress bar style
-NProgress.configure({ showSpinner: false })
-const lockPage = '/lock' //锁屏页
-const urlParams = getUrlParams(window.location.href)
-
-router.beforeEach((to, from, next) => {
- const meta = to.meta || {}
- const isMenu = meta.menu === undefined ? to.query.menu : meta.menu
- store.commit('SET_IS_MENU', isMenu === undefined)
- if (getToken()) {
- if (store.getters.isLock && to.path !== lockPage) {
- //如果系统激活锁屏,全部跳转到锁屏页
- next({ path: lockPage })
- } else if (to.path === '/login') {
- //如果登录成功访问登录页跳转到主页
- next({ path: '/' })
- } else {
- const systemToken = store.getters.token || urlParams?.token
- if (systemToken === 0) {
- store.dispatch('FedLogOut').then(() => {
- next({ path: '/login' })
- })
- } else {
- const meta = to.meta || {}
- const query = to.query || {}
- if (meta.target) {
- window.open(query.url.replace(/#/g, '&'))
- return
- } else if (meta.isTab !== false) {
- store.commit('ADD_TAG', {
- name: query.name || to.name,
- path: to.path,
- fullPath: to.path,
- params: to.params,
- query: to.query,
- meta: meta,
- })
- }
- next()
- }
- }
- } else {
- //判断是否需要认证,没有登录访问去登录页
- if (meta.isAuth === false) {
- next()
- } else {
- next('/login')
- }
- }
-})
-
-router.afterEach(to => {
- NProgress.done()
- let title = router.$avueRouter.generateTitle(to, { label: 'name' })
- router.$avueRouter.setTitle(title)
- store.commit('SET_IS_SEARCH', false)
-})
diff --git a/applications/task-work-order/src/permission copy.js b/applications/task-work-order/src/permission copy.js
deleted file mode 100644
index c244bec..0000000
--- a/applications/task-work-order/src/permission copy.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * @Author: GuLiMmo 2820890765@qq.com
- * @Date: 2024-08-23 10:51:53
- * @LastEditors: GuLiMmo 2820890765@qq.com
- * @LastEditTime: 2024-08-29 14:10:56
- * @FilePath: /drone-web-manage/src/permission.js
- * @Description:
- * Copyright (c) 2024 by GuLiMmo, All Rights Reserved.
- */
-
-import { getStore } from '@/utils/store'
-import router from './router/'
-import store from './store'
-import { getToken } from '@/utils/auth'
-import { getUrlParams } from './utils/validate'
-import NProgress from 'nprogress' // progress bar
-import 'nprogress/nprogress.css' // progress bar style
-NProgress.configure({ showSpinner: false })
-const lockPage = '/lock' //锁屏页
-const urlParams = getUrlParams(window.location.href)
-
-function findRouteByPath (routes, targetPath) {
- // 遍历数组中的每个路由对象
- for (const route of routes) {
- // 如果当前路由的path匹配目标路径,直接返回
- if (route.path === targetPath) {
- return route
- }
-
- // 如果有子路由,递归查找
- if (route.children && route.children.length > 0) {
- const foundInChildren = findRouteByPath(route.children, targetPath)
- if (foundInChildren) {
- return foundInChildren
- }
- }
- }
-
- // 遍历完所有路由都没找到,返回null
- return null
-}
-
-router.beforeEach((to, from, next) => {
- const meta = to.meta || {}
- const isMenu = meta.menu === undefined ? to.query.menu : meta.menu
- store.commit('SET_IS_MENU', isMenu === undefined)
-
- const menuAll = getStore({ name: 'menuAll' })
-
- if (!menuAll) {
- store.dispatch('GetMenu').then(data => {
- if (data.length !== 0) {
- router.$avueRouter.formatRoutes(data, true)
-
- let newMenu = getStore({ name: 'menuAll' })
-
- let firstMenu = newMenu[0]
-
- let toMenu = findRouteByPath(newMenu, to.path)
-
- store.commit('ADD_TAG', {
- name: firstMenu.name,
- path: firstMenu.path,
- fullPath: firstMenu.path,
- params: firstMenu.params || {},
- query: firstMenu.query || {},
- meta: firstMenu.meta || {},
- })
-
- store.commit('ADD_TAG', {
- name: toMenu.name,
- path: toMenu.path,
- fullPath: toMenu.path,
- params: toMenu.params || {},
- query: toMenu.query || {},
- meta: toMenu.meta || {},
- })
-
- next(to.fullPath)
- }
- })
-
- return
- }
-
- if (getToken()) {
- if (store.getters.isLock && to.path !== lockPage) {
- //如果系统激活锁屏,全部跳转到锁屏页
- next({ path: lockPage })
- } else if (to.path === '/login') {
- //如果登录成功访问登录页跳转到主页
- next({ path: '/' })
- } else {
- const systemToken = store.getters.token || urlParams?.token
- if (systemToken === 0) {
- store.dispatch('FedLogOut').then(() => {
- next({ path: '/login' })
- })
- } else {
- const meta = to.meta || {}
- const query = to.query || {}
- if (meta.target) {
- window.open(query.url.replace(/#/g, '&'))
- return
- } else if (meta.isTab !== false) {
- store.commit('ADD_TAG', {
- name: query.name || to.name,
- path: to.path,
- fullPath: to.path,
- params: to.params,
- query: to.query,
- meta: meta,
- })
- }
- next()
- }
- }
- } else {
- //判断是否需要认证,没有登录访问去登录页
- if (meta.isAuth === false) {
- next()
- } else {
- next('/login')
- }
- }
-})
-
-router.afterEach(to => {
- NProgress.done()
- let title = router.$avueRouter.generateTitle(to, { label: 'name' })
- router.$avueRouter.setTitle(title)
- store.commit('SET_IS_SEARCH', false)
-})
diff --git a/applications/task-work-order/src/permission.js b/applications/task-work-order/src/permission.js
index 36ed552..6df8ee9 100644
--- a/applications/task-work-order/src/permission.js
+++ b/applications/task-work-order/src/permission.js
@@ -67,7 +67,6 @@
query: firstMenu.query || {},
meta: firstMenu.meta || {},
})
-
store.commit('ADD_TAG', {
name: toMenu.name,
path: toMenu.path,
@@ -139,4 +138,4 @@
const pageTitle = isLoginPage ? '中图智飞低空感知网平台' : '综合管理平台'
document.title = pageTitle
store.commit('SET_IS_SEARCH', false)
-})
\ No newline at end of file
+})
diff --git a/applications/task-work-order/src/router/page/index.js b/applications/task-work-order/src/router/page/index.js
index 552260d..5974a39 100644
--- a/applications/task-work-order/src/router/page/index.js
+++ b/applications/task-work-order/src/router/page/index.js
@@ -1,77 +1,64 @@
import Store from '@/store/'
export default [
- {
- path: '/login',
- name: '登录页',
- component: () =>
- Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue'),
- meta: {
- keepAlive: true,
- isTab: false,
- isAuth: false,
- },
- },
- {
- path: '/oauth/redirect/:source',
- name: '第三方登录',
- component: () =>
- Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue'),
- meta: {
- keepAlive: true,
- isTab: false,
- isAuth: false,
- },
- },
- {
- path: '/lock',
- name: '锁屏页',
- component: () =>
- Store.getters.isMacOs ? import('@/mac/lock.vue') : import('@/page/lock/index.vue'),
- meta: {
- keepAlive: true,
- isTab: false,
- isAuth: false,
- },
- },
- {
- path: '/404',
- component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/404.vue'),
- name: '404',
- meta: {
- keepAlive: true,
- isTab: false,
- isAuth: false,
- },
- },
- {
- path: '/403',
- component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/403.vue'),
- name: '403',
- meta: {
- keepAlive: true,
- isTab: false,
- isAuth: false,
- },
- },
- {
- path: '/500',
- component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/500.vue'),
- name: '500',
- meta: {
- keepAlive: true,
- isTab: false,
- isAuth: false,
- },
- },
- {
- path: '/',
- name: '主页',
- redirect: '/wel',
- },
- // {
- // path: '/',
- // name: '主页',
- // redirect: '/tickets/ticket',
- // },
+ {
+ path: '/login',
+ name: '登录页',
+ component: () => (Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue')),
+ meta: {
+ keepAlive: true,
+ isTab: false,
+ isAuth: false,
+ },
+ },
+ {
+ path: '/oauth/redirect/:source',
+ name: '第三方登录',
+ component: () => (Store.getters.isMacOs ? import('@/mac/login.vue') : import('@/page/login/index.vue')),
+ meta: {
+ keepAlive: true,
+ isTab: false,
+ isAuth: false,
+ },
+ },
+ {
+ path: '/lock',
+ name: '锁屏页',
+ component: () => (Store.getters.isMacOs ? import('@/mac/lock.vue') : import('@/page/lock/index.vue')),
+ meta: {
+ keepAlive: true,
+ isTab: false,
+ isAuth: false,
+ },
+ },
+ {
+ path: '/404',
+ component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/404.vue'),
+ name: '404',
+ meta: {
+ keepAlive: true,
+ isTab: false,
+ isAuth: false,
+ },
+ },
+ {
+ path: '/403',
+ component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/403.vue'),
+ name: '403',
+ meta: {
+ keepAlive: true,
+ isTab: false,
+ isAuth: false,
+ },
+ },
+ {
+ path: '/500',
+ component: () => import(/* webpackChunkName: "page" */ '@/components/error-page/500.vue'),
+ name: '500',
+ meta: {
+ keepAlive: true,
+ isTab: false,
+ isAuth: false,
+ },
+ },
]
diff --git a/applications/task-work-order/src/router/views/index.js b/applications/task-work-order/src/router/views/index.js
index e01e37a..0dea585 100644
--- a/applications/task-work-order/src/router/views/index.js
+++ b/applications/task-work-order/src/router/views/index.js
@@ -18,24 +18,6 @@
}
],
},
- // 事件工单
- // {
- // path: '/tickets',
- // component: () =>
- // Store.getters.isMacOs ? import('@/mac/index.vue') : import('@/page/index/index.vue'),
- // redirect: '/tickets/ticket',
- // children: [
- // {
- // path: 'ticket',
- // name: '事件工单',
- // meta: {
- // i18n: 'dashboard',
- // },
- // component: () => import(/* webpackChunkName: "views" */ '@/views/tickets/ticket.vue'),
- // },
- // ],
- // },
-
{
path: '/test',
component: Layout,
diff --git a/applications/task-work-order/src/store/modules/user.js b/applications/task-work-order/src/store/modules/user.js
index a111e36..969c21a 100644
--- a/applications/task-work-order/src/store/modules/user.js
+++ b/applications/task-work-order/src/store/modules/user.js
@@ -1,396 +1,385 @@
-import {
- setToken,
- setRefreshToken,
- removeToken,
- removeRefreshToken,
- getRefreshToken,
-} from '@/utils/auth';
-import { setStore, getStore } from '@/utils/store';
-import { validatenull } from '@/utils/validate';
-import { deepClone } from '@/utils/util';
+import { setToken, setRefreshToken, removeToken, removeRefreshToken, getRefreshToken } from '@/utils/auth'
+import { setStore, getStore } from '@/utils/store'
+import { validatenull } from '@/utils/validate'
+import { deepClone } from '@/utils/util'
import defaultAva from '@/assets/images/defaultava.png'
import {
- loginByUsername,
- loginBySocial,
- loginBySso,
- loginByPhone,
- getUserInfo,
- logout,
- refreshToken,
- getButtons,
- registerUser,
- getParentDeptInfo
-} from '@/api/user';
-import { getRoutes, getTopMenu } from '@/api/system/menu';
-import { formatPath } from '@/router/avue-router';
-import { ElMessage } from 'element-plus';
-import { encrypt } from '@/utils/sm2';
-import md5 from 'js-md5';
-
+ loginByUsername,
+ loginBySocial,
+ loginBySso,
+ loginByPhone,
+ getUserInfo,
+ logout,
+ refreshToken,
+ getButtons,
+ registerUser,
+ getParentDeptInfo,
+} from '@/api/user'
+import { getRoutes, getTopMenu } from '@/api/system/menu'
+import { formatPath } from '@/router/avue-router'
+import { ElMessage } from 'element-plus'
+import { encrypt } from '@/utils/sm2'
+import md5 from 'js-md5'
const user = {
- state: {
- tenantId: getStore({ name: 'tenantId' }) || '',
- userInfo: getStore({ name: 'userInfo' }) || [],
- permission: getStore({ name: 'permission' }) || {},
- roles: [],
- menuId: {},
- menu: getStore({ name: 'menu' }) || [],
- menuAll: getStore({ name: 'menuAll' }) || [],
- token: getStore({ name: 'token' }) || '',
- refreshToken: getStore({ name: 'refreshToken' }) || '',
- parentDeptInfo: getStore({ name: 'parentDeptInfo' }) || '',
+ state: {
+ tenantId: getStore({ name: 'tenantId' }) || '',
+ userInfo: getStore({ name: 'userInfo' }) || [],
+ permission: getStore({ name: 'permission' }) || {},
+ roles: [],
+ menuId: {},
+ menu: getStore({ name: 'menu' }) || [],
+ menuAll: getStore({ name: 'menuAll' }) || [],
+ token: getStore({ name: 'token' }) || '',
+ refreshToken: getStore({ name: 'refreshToken' }) || '',
+ parentDeptInfo: getStore({ name: 'parentDeptInfo' }) || '',
+ },
+ actions: {
+ //根据用户名登录
+ LoginByUsername({ commit }, userInfo = {}) {
+ return new Promise((resolve, reject) => {
+ loginByUsername(
+ userInfo.tenantId,
+ userInfo.deptId,
+ userInfo.roleId,
+ userInfo.username,
+ md5(userInfo.password),
+ userInfo.type,
+ userInfo.key,
+ userInfo.code
+ )
+ .then(res => {
+ const data = res.data
+ if (data.error_description) {
+ ElMessage({
+ message: data.error_description,
+ type: 'error',
+ })
+ } else {
+ commit('SET_TOKEN', data.access_token)
+ commit('SET_REFRESH_TOKEN', data.refresh_token)
+ commit('SET_TENANT_ID', data.tenant_id)
+ commit('SET_USER_INFO', data)
+ commit('SET_PARENT_DEPT_INFO', data.dept_id)
+ commit('DEL_ALL_TAG')
+ commit('CLEAR_LOCK')
+ }
+ resolve()
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+ },
+ //根据第三方信息登录
+ LoginBySocial({ commit }, userInfo) {
+ return new Promise((resolve, reject) => {
+ loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state)
+ .then(res => {
+ const data = res.data
+ if (data.error_description) {
+ ElMessage({
+ message: data.error_description,
+ type: 'error',
+ })
+ } else {
+ commit('SET_TOKEN', data.access_token)
+ commit('SET_REFRESH_TOKEN', data.refresh_token)
+ commit('SET_USER_INFO', data)
+ commit('SET_TENANT_ID', data.tenant_id)
+ commit('DEL_ALL_TAG')
+ commit('CLEAR_LOCK')
+ }
+ resolve()
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+ },
+ //根据单点信息登录
+ LoginBySso({ commit }, userInfo) {
+ return new Promise((resolve, reject) => {
+ loginBySso(userInfo.state, userInfo.code)
+ .then(res => {
+ const data = res.data
+ if (data.error_description) {
+ ElMessage({
+ message: data.error_description,
+ type: 'error',
+ })
+ } else {
+ commit('SET_TOKEN', data.access_token)
+ commit('SET_REFRESH_TOKEN', data.refresh_token)
+ commit('SET_USER_INFO', data)
+ commit('SET_TENANT_ID', data.tenant_id)
+ commit('DEL_ALL_TAG')
+ commit('CLEAR_LOCK')
+ }
+ resolve()
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+ },
+ //根据手机信息登录
+ LoginByPhone({ commit }, userInfo) {
+ return new Promise((resolve, reject) => {
+ loginByPhone(userInfo.tenantId, encrypt(userInfo.phone), userInfo.codeId, userInfo.codeValue)
+ .then(res => {
+ const data = res.data
+ if (data.error_description) {
+ ElMessage({
+ message: data.error_description,
+ type: 'error',
+ })
+ } else {
+ commit('SET_TOKEN', data.access_token)
+ commit('SET_REFRESH_TOKEN', data.refresh_token)
+ commit('SET_USER_INFO', data)
+ commit('SET_TENANT_ID', data.tenant_id)
+ commit('DEL_ALL_TAG')
+ commit('CLEAR_LOCK')
+ }
+ resolve()
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+ },
+ //用户注册
+ RegisterUser({ commit }, userInfo = {}) {
+ return new Promise((resolve, reject) => {
+ registerUser(
+ userInfo.tenantId,
+ userInfo.name,
+ userInfo.account,
+ encrypt(userInfo.password),
+ userInfo.phone,
+ userInfo.email
+ ).then(res => {
+ const data = res.data
+ if (data.error_description) {
+ ElMessage({
+ message: data.error_description,
+ type: 'error',
+ })
+ reject(data.error_description)
+ } else {
+ commit('SET_TOKEN', data.access_token)
+ commit('SET_REFRESH_TOKEN', data.refresh_token)
+ commit('SET_USER_INFO', data)
+ commit('SET_TENANT_ID', data.tenant_id)
+ commit('DEL_ALL_TAG')
+ commit('CLEAR_LOCK')
+ }
+ resolve()
+ })
+ })
+ },
+ GetUserInfo({ commit }) {
+ return new Promise((resolve, reject) => {
+ getUserInfo()
+ .then(res => {
+ const data = res.data.data
+ commit('SET_ROLES', data.roles)
+ resolve(data)
+ })
+ .catch(err => {
+ reject(err)
+ })
+ })
+ },
+ //刷新token
+ RefreshToken({ state, commit }, userInfo) {
+ return new Promise((resolve, reject) => {
+ refreshToken(
+ getRefreshToken(),
+ state.tenantId,
+ !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
+ !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
+ )
+ .then(res => {
+ const data = res.data
+ commit('SET_TOKEN', data.access_token)
+ commit('SET_REFRESH_TOKEN', data.refresh_token)
+ commit('SET_USER_INFO', data)
+ resolve()
+ })
+ .catch(error => {
+ reject(error)
+ })
+ })
+ },
+ // 登出
+ LogOut({ commit }) {
+ return new Promise((resolve, reject) => {
+ logout()
+ .then(() => {
+ commit('SET_TOKEN', '')
+ commit('SET_MENU_ALL_NULL', [])
+ commit('SET_MENU', [])
+ commit('SET_ROLES', [])
+ commit('DEL_ALL_TAG', [])
+ commit('CLEAR_LOCK')
+ removeToken()
+ removeRefreshToken()
+ resolve()
+ })
+ .catch(error => {
+ reject(error)
+ })
+ })
+ },
+ //注销session
+ FedLogOut({ commit }) {
+ return new Promise(resolve => {
+ commit('SET_TOKEN', '')
+ commit('SET_MENU_ALL_NULL', [])
+ commit('SET_MENU', [])
+ commit('SET_ROLES', [])
+ commit('DEL_ALL_TAG', [])
+ commit('CLEAR_LOCK')
+ removeToken()
+ removeRefreshToken()
+ removeToken()
+ resolve()
+ })
+ },
+ GetTopMenu() {
+ return new Promise(resolve => {
+ getTopMenu().then(res => {
+ const data = res.data.data || []
+ resolve(data)
+ })
+ })
+ },
+ GetMenu({ commit, dispatch }, tenantId) {
+ const errLogOut = () => {
+ dispatch('LogOut').then(() => {
+ const env = import.meta.env.VITE_APP_ENV
+ const adminUrl = import.meta.env.VITE_APP_DASHBOARD_URL
+ env === 'development'
+ ? (window.location.href = '/task-work-order/login')
+ : window.location.replace(`${adminUrl}#/login`)
+ })
+ }
+ return new Promise(resolve => {
+ getRoutes({ tenantId, sysType: 6 })
+ .then(res => {
+ const data = res.data.data
+ let menu = deepClone(data)
+ if (!res.data?.data?.length) {
+ errLogOut()
+ return
+ }
+ menu.forEach(ele => formatPath(ele, true))
+ commit('SET_MENU', menu)
+ commit('SET_MENU_ALL', menu)
+ dispatch('GetButtons')
+ resolve(menu)
+ })
+ .catch(err => {
+ errLogOut()
+ })
+ })
+ },
+ GetButtons({ commit }) {
+ return new Promise(resolve => {
+ getButtons({ sysType: 6 }).then(res => {
+ const data = res.data.data
+ commit('SET_PERMISSION', data)
+ resolve()
+ })
+ })
+ },
+ },
+ mutations: {
+ SET_PARENT_DEPT_INFO(state, deptId) {
+ getParentDeptInfo({ deptId: deptId }).then(res => {
+ const data = res.data.data
+ state.parentDeptInfo = data
+ setStore({ name: 'parentDeptInfo', content: data })
+ })
+ },
+ SET_TOKEN: (state, token) => {
+ setToken(token)
+ state.token = token
+ setStore({ name: 'token', content: state.token })
+ },
+ SET_REFRESH_TOKEN: (state, refreshToken) => {
+ setRefreshToken(refreshToken)
+ state.refreshToken = refreshToken
+ setStore({ name: 'refreshToken', content: state.refreshToken })
+ },
+ SET_MENU_ID(state, menuId) {
+ state.menuId = menuId
+ },
+ SET_TENANT_ID: (state, tenantId) => {
+ state.tenantId = tenantId
+ setStore({ name: 'tenantId', content: state.tenantId })
+ },
+ SET_USER_INFO: (state, userInfo) => {
+ if (validatenull(userInfo.user_id) && validatenull(userInfo.account)) {
+ state.userInfo = { user_name: 'unauth', role_name: 'unauth' }
+ } else {
+ if (validatenull(userInfo.avatar)) {
+ userInfo.avatar = defaultAva
+ }
+ state.userInfo = userInfo
+ }
+ setStore({ name: 'userInfo', content: state.userInfo })
+ },
+ SET_MENU_ALL: (state, menuAll) => {
+ let menu = state.menuAll
+ menuAll.forEach(ele => {
+ let index = menu.findIndex(item => item.path === ele.path)
+ if (index === -1) {
+ menu.push(ele)
+ } else {
+ menu[index] = ele
+ }
+ })
+ state.menuAll = menu
+ setStore({ name: 'menuAll', content: state.menuAll })
+ },
+ SET_MENU_ALL_NULL: state => {
+ state.menuAll = []
+ setStore({ name: 'menuAll', content: state.menuAll })
+ },
+ SET_MENU: (state, menu) => {
+ state.menu = menu
+ setStore({ name: 'menu', content: state.menu })
+ },
+ SET_ROLES: (state, roles) => {
+ state.roles = roles
+ },
+ SET_PERMISSION: (state, permission) => {
+ let result = []
- },
- actions: {
- //根据用户名登录
- LoginByUsername({ commit }, userInfo = {}) {
- return new Promise((resolve, reject) => {
- loginByUsername(
- userInfo.tenantId,
- userInfo.deptId,
- userInfo.roleId,
- userInfo.username,
- md5(userInfo.password),
- userInfo.type,
- userInfo.key,
- userInfo.code
- )
- .then(res => {
- const data = res.data;
- if (data.error_description) {
- ElMessage({
- message: data.error_description,
- type: 'error',
- });
- } else {
- commit('SET_TOKEN', data.access_token);
- commit('SET_REFRESH_TOKEN', data.refresh_token);
- commit('SET_TENANT_ID', data.tenant_id);
- commit('SET_USER_INFO', data);
- commit('SET_PARENT_DEPT_INFO', data.dept_id);
- commit('DEL_ALL_TAG');
- commit('CLEAR_LOCK');
- }
- resolve();
- })
- .catch(err => {
- reject(err);
- });
- });
- },
- //根据第三方信息登录
- LoginBySocial({ commit }, userInfo) {
- return new Promise((resolve, reject) => {
- loginBySocial(userInfo.tenantId, userInfo.source, userInfo.code, userInfo.state)
- .then(res => {
- const data = res.data;
- if (data.error_description) {
- ElMessage({
- message: data.error_description,
- type: 'error',
- });
- } else {
- commit('SET_TOKEN', data.access_token);
- commit('SET_REFRESH_TOKEN', data.refresh_token);
- commit('SET_USER_INFO', data);
- commit('SET_TENANT_ID', data.tenant_id);
- commit('DEL_ALL_TAG');
- commit('CLEAR_LOCK');
- }
- resolve();
- })
- .catch(err => {
- reject(err);
- });
- });
- },
- //根据单点信息登录
- LoginBySso({ commit }, userInfo) {
- return new Promise((resolve, reject) => {
- loginBySso(userInfo.state, userInfo.code)
- .then(res => {
- const data = res.data;
- if (data.error_description) {
- ElMessage({
- message: data.error_description,
- type: 'error',
- });
- } else {
- commit('SET_TOKEN', data.access_token);
- commit('SET_REFRESH_TOKEN', data.refresh_token);
- commit('SET_USER_INFO', data);
- commit('SET_TENANT_ID', data.tenant_id);
- commit('DEL_ALL_TAG');
- commit('CLEAR_LOCK');
- }
- resolve();
- })
- .catch(err => {
- reject(err);
- });
- });
- },
- //根据手机信息登录
- LoginByPhone({ commit }, userInfo) {
- return new Promise((resolve, reject) => {
- loginByPhone(
- userInfo.tenantId,
- encrypt(userInfo.phone),
- userInfo.codeId,
- userInfo.codeValue
- )
- .then(res => {
- const data = res.data;
- if (data.error_description) {
- ElMessage({
- message: data.error_description,
- type: 'error',
- });
- } else {
- commit('SET_TOKEN', data.access_token);
- commit('SET_REFRESH_TOKEN', data.refresh_token);
- commit('SET_USER_INFO', data);
- commit('SET_TENANT_ID', data.tenant_id);
- commit('DEL_ALL_TAG');
- commit('CLEAR_LOCK');
- }
- resolve();
- })
- .catch(err => {
- reject(err);
- });
- });
- },
- //用户注册
- RegisterUser({ commit }, userInfo = {}) {
- return new Promise((resolve, reject) => {
- registerUser(
- userInfo.tenantId,
- userInfo.name,
- userInfo.account,
- encrypt(userInfo.password),
- userInfo.phone,
- userInfo.email
- ).then(res => {
- const data = res.data;
- if (data.error_description) {
- ElMessage({
- message: data.error_description,
- type: 'error',
- });
- reject(data.error_description);
- } else {
- commit('SET_TOKEN', data.access_token);
- commit('SET_REFRESH_TOKEN', data.refresh_token);
- commit('SET_USER_INFO', data);
- commit('SET_TENANT_ID', data.tenant_id);
- commit('DEL_ALL_TAG');
- commit('CLEAR_LOCK');
- }
- resolve();
- });
- });
- },
- GetUserInfo({ commit }) {
- return new Promise((resolve, reject) => {
- getUserInfo()
- .then(res => {
- const data = res.data.data;
- commit('SET_ROLES', data.roles);
- resolve(data);
- })
- .catch(err => {
- reject(err);
- });
- });
- },
- //刷新token
- RefreshToken({ state, commit }, userInfo) {
- return new Promise((resolve, reject) => {
- refreshToken(
- getRefreshToken(),
- state.tenantId,
- !validatenull(userInfo) ? userInfo.deptId : state.userInfo.dept_id,
- !validatenull(userInfo) ? userInfo.roleId : state.userInfo.role_id
- )
- .then(res => {
- const data = res.data;
- commit('SET_TOKEN', data.access_token);
- commit('SET_REFRESH_TOKEN', data.refresh_token);
- commit('SET_USER_INFO', data);
- resolve();
- })
- .catch(error => {
- reject(error);
- });
- });
- },
- // 登出
- LogOut({ commit }) {
- return new Promise((resolve, reject) => {
- logout()
- .then(() => {
- commit('SET_TOKEN', '');
- commit('SET_MENU_ALL_NULL', []);
- commit('SET_MENU', []);
- commit('SET_ROLES', []);
- commit('DEL_ALL_TAG', []);
- commit('CLEAR_LOCK');
- removeToken();
- removeRefreshToken();
- resolve();
- })
- .catch(error => {
- reject(error);
- });
- });
- },
- //注销session
- FedLogOut({ commit }) {
- return new Promise(resolve => {
- commit('SET_TOKEN', '');
- commit('SET_MENU_ALL_NULL', []);
- commit('SET_MENU', []);
- commit('SET_ROLES', []);
- commit('DEL_ALL_TAG', []);
- commit('CLEAR_LOCK');
- removeToken();
- removeRefreshToken();
- removeToken();
- resolve();
- });
- },
- GetTopMenu() {
- return new Promise(resolve => {
- getTopMenu().then(res => {
- const data = res.data.data || [];
- resolve(data);
- });
- });
- },
- GetMenu({ commit, dispatch }, tenantId) {
- const errLogOut = () => {
- dispatch('LogOut').then(()=>{
- const env = import.meta.env.VITE_APP_ENV
- const adminUrl = import.meta.env.VITE_APP_DASHBOARD_URL
- env === 'development'
- ? window.location.href = "/manage/login"
- : window.location.replace(`${adminUrl}#/login`)
- })
- }
- return new Promise(resolve => {
- getRoutes({tenantId,sysType: 6}).then(res => {
- const data = res.data.data;
- let menu = deepClone(data);
- if (!res.data?.data?.length){
- errLogOut()
- return
- }
- menu.forEach(ele => formatPath(ele, true));
- commit('SET_MENU', menu);
- commit('SET_MENU_ALL', menu);
- dispatch('GetButtons');
- resolve(menu);
- }).catch(err =>{
- errLogOut()
- })
- });
- },
- GetButtons({ commit }) {
- return new Promise(resolve => {
- getButtons({sysType: 6}).then(res => {
- const data = res.data.data;
- commit('SET_PERMISSION', data);
- resolve();
- });
- });
- },
- },
- mutations: {
- SET_PARENT_DEPT_INFO(state, deptId){
- getParentDeptInfo({deptId:deptId}).then(res=>{
- const data = res.data.data;
- state.parentDeptInfo = data;
- setStore({ name: 'parentDeptInfo', content: data });
- })
- },
- SET_TOKEN: (state, token) => {
- setToken(token);
- state.token = token;
- setStore({ name: 'token', content: state.token });
- },
- SET_REFRESH_TOKEN: (state, refreshToken) => {
- setRefreshToken(refreshToken);
- state.refreshToken = refreshToken;
- setStore({ name: 'refreshToken', content: state.refreshToken });
- },
- SET_MENU_ID(state, menuId) {
- state.menuId = menuId;
- },
- SET_TENANT_ID: (state, tenantId) => {
- state.tenantId = tenantId;
- setStore({ name: 'tenantId', content: state.tenantId });
- },
- SET_USER_INFO: (state, userInfo) => {
- if (validatenull(userInfo.user_id) && validatenull(userInfo.account)) {
- state.userInfo = { user_name: 'unauth', role_name: 'unauth' };
- } else {
- if (validatenull(userInfo.avatar)) {
- userInfo.avatar = defaultAva;
- }
- state.userInfo = userInfo;
- }
- setStore({ name: 'userInfo', content: state.userInfo });
- },
- SET_MENU_ALL: (state, menuAll) => {
- let menu = state.menuAll;
- menuAll.forEach(ele => {
- let index = menu.findIndex(item => item.path === ele.path);
- if (index === -1) {
- menu.push(ele);
- } else {
- menu[index] = ele;
- }
- });
- state.menuAll = menu;
- setStore({ name: 'menuAll', content: state.menuAll });
- },
- SET_MENU_ALL_NULL: state => {
- state.menuAll = [];
- setStore({ name: 'menuAll', content: state.menuAll });
- },
- SET_MENU: (state, menu) => {
- state.menu = menu;
- setStore({ name: 'menu', content: state.menu });
- },
- SET_ROLES: (state, roles) => {
- state.roles = roles;
- },
- SET_PERMISSION: (state, permission) => {
- let result = [];
+ function getCode(list) {
+ list.forEach(ele => {
+ if (typeof ele === 'object') {
+ const children = ele.children
+ const code = ele.code
+ if (children) {
+ getCode(children)
+ } else {
+ result.push(code)
+ }
+ }
+ })
+ }
- function getCode(list) {
- list.forEach(ele => {
- if (typeof ele === 'object') {
- const children = ele.children;
- const code = ele.code;
- if (children) {
- getCode(children);
- } else {
- result.push(code);
- }
- }
- });
- }
-
- getCode(permission);
- state.permission = {};
- result.forEach(ele => {
- state.permission[ele] = true;
- });
- setStore({ name: 'permission', content: state.permission, type: 'session' });
- },
- },
-};
-export default user;
+ getCode(permission)
+ state.permission = {}
+ result.forEach(ele => {
+ state.permission[ele] = true
+ })
+ setStore({ name: 'permission', content: state.permission, type: 'session' })
+ },
+ },
+}
+export default user
diff --git a/applications/task-work-order/src/styles/common/cockpit.scss b/applications/task-work-order/src/styles/common/cockpit.scss
index 3e27778..3a21019 100644
--- a/applications/task-work-order/src/styles/common/cockpit.scss
+++ b/applications/task-work-order/src/styles/common/cockpit.scss
@@ -1,3 +1,5 @@
+//变量
+$gd-placeholder: #86909C;
.gd-table {
height: 0;
@@ -20,9 +22,7 @@
border-bottom: 1px solid #DBDFF1 !important;
.cell {
- padding: 0;
- padding-left: 16px;
-
+ padding: 0 0 0 16px;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
@@ -38,9 +38,7 @@
height: 56px;
.cell {
- padding: 0;
- padding-left: 16px;
-
+ padding: 0 0 0 16px;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 14px;
@@ -79,25 +77,25 @@
}
}
+
.gd-input {
- .el-input__wrapper {
+ .el-input__wrapper,.el-textarea__inner {
padding: 0 8px !important;
- background: #DDE2ED;
+ background: #F2F3F5;
box-shadow: none !important;
border: none;
+ }
- .el-input__inner {
- color: #383874;
-
- &::placeholder {
- color: #A1A3D4;
- }
+ .el-input__inner,.el-textarea__inner {
+ &::placeholder {
+ color: $gd-placeholder;
}
}
+
&.is-disabled {
.el-input__wrapper {
- background-color: #DDE2ED;
+ background: #DDE2ED;
}
}
}
@@ -117,7 +115,7 @@
.el-select__placeholder {
&.is-transparent {
- color: #A1A3D4 !important;
+ color: $gd-placeholder !important;
}
&.el-select__selected-item {
@@ -240,7 +238,7 @@
color: #fff;
&::placeholder {
- color: #A1A3D4;
+ color: $gd-placeholder;
}
}
@@ -583,16 +581,6 @@
}
}
- .el-textarea {
-
- .el-textarea__inner {
- color: #fff;
- background: #DDE2ED !important;
- border: none;
- box-shadow: none;
- }
- }
-
.el-button {
color: #fff;
background: #DDE2ED !important;
@@ -661,28 +649,7 @@
}
}
- .el-input {
- .el-input__wrapper {
- padding: 0 8px !important;
- background: #F2F3F5;
- box-shadow: none !important;
- border: none;
- .el-input__inner {
- color: #383874;
-
- &::placeholder {
- color: #86909C;
- }
- }
- }
-
- &.is-disabled {
- .el-input__wrapper {
- background-color: #F2F3F5;
- }
- }
- }
}
}
}
diff --git a/applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue b/applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue
index 9001d6a..1f086ea 100644
--- a/applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue
+++ b/applications/task-work-order/src/views/basicManage/maintainRecord/FormDiaLog.vue
@@ -1,7 +1,12 @@
<template>
- <el-dialog class="gd-dialog" v-model="visible" :title="titleEnum[dialogMode]" @closed="handleClosed" destroy-on-close>
+ <el-dialog
+ class="gd-dialog"
+ v-model="visible"
+ :title="titleEnum[dialogMode]"
+ @closed="visible = false"
+ destroy-on-close
+ >
<div class="detail-container" v-if="dialogReadonly">
- <div class="detail-title">设备详情</div>
<el-row>
<el-col :span="12">
<div class="label">设备名称</div>
@@ -44,29 +49,6 @@
<div class="val">{{ formData.manufacturer }}</div>
</el-col>
</el-row>
-
- <div class="detail-title">维护详情</div>
- <div class="gd-table-container" v-loading="loading">
- <div class="gd-table-content">
- <el-table class="gd-table" :data="list">
- <el-table-column type="index" width="60" label="序号" />
- <el-table-column prop="maintainTime" label="维护时间" />
- <el-table-column prop="maintainContent" label="维护内容" />
- <el-table-column prop="replacePart" label="跟换部件" />
- </el-table>
- </div>
-
- <div class="gd-pagination-parent">
- <el-pagination
- popper-class="gd-select-popper"
- v-model:current-page="searchParams.current"
- v-model:page-size="searchParams.size"
- layout="total, prev, pager, next, sizes"
- :total="total"
- @change="getList"
- />
- </div>
- </div>
</div>
<el-form
@@ -107,30 +89,10 @@
</el-select>
</el-form-item>
</el-col>
- <el-col :span="12">
- <el-form-item label="维护计划时间" prop="planCycleValue">
- <el-select
- class="gd-select"
- popper-class="gd-select-popper"
- v-model="formData.planCycleValue"
- placeholder="请选择"
- clearable
- multiple
- :disabled="!formData.planCycleType"
- >
- <el-option
- v-for="item in planCycleValueOptions"
- :key="item.value"
- :label="item.value"
- :value="item.value"
- />
- </el-select>
- </el-form-item>
- </el-col>
</el-row>
</el-form>
<template #footer>
- <el-button color="#F2F3F5" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
+ <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
<el-button
class="save-btn"
color="#4C34FF"
@@ -149,11 +111,9 @@
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { fieldRules, getDictLabel } from '@ztzf/utils'
-import { fwDeviceMaintainRecordPageApi } from '@/views/basicManage/maintainRecord/fwDeviceMaintainRecord'
import {
fwDeviceMaintainPlanDetailApi,
fwDeviceMaintainPlanSubmitApi,
- fwDevicePageApi,
} from '@/views/basicManage/maintainRecord/maintainRecordApi'
const initForm = () => ({
@@ -163,41 +123,23 @@
})
const planCycleOptions = inject('planCycleOptions')
-const planCycleValueOptions = ref([])
const emit = defineEmits(['success'])
const formRef = ref(null) // 表单实例
const formData = ref(initForm()) // 表单数据
-const visible = ref(false) // 弹框显隐
+const visible = defineModel() // 弹框显隐
const dialogMode = ref('add') // 弹框模式
const submitting = ref(false) // 提交中
const deviceList = ref([]) // 设备列表
const getPlanCycleLabel = inject('getPlanCycleLabel')
const dictObj = inject('dictObj')
const dialogReadonly = computed(() => dialogMode.value === 'view')
-const titleEnum = ref({ edit: '编辑', view: '查看', add: '维护计划' })
-
-const planCycleLabel = computed(() => {
- const item = planCycleOptions.find(option => option.value === formData.value.planCycleType)
- return item?.label || formData.value.planCycleType || '-'
-})
+const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
const rules = {
deviceId: fieldRules(true),
planCycleType: fieldRules(true),
planCycleValue: [{ required: true, message: '请选择', trigger: ['blur', 'change'] }],
-}
-
-// 获取设备列表
-function getDeviceList() {
- return fwDevicePageApi({ current: 1, size: 999 }).then(res => {
- deviceList.value = res?.data?.data?.records ?? []
- })
-}
-
-// 关闭弹框
-function handleCancel() {
- visible.value = false
}
// 提交新增/编辑
@@ -220,70 +162,21 @@
if (!formData.value.id) return
const res = await fwDeviceMaintainPlanDetailApi({ id: formData.value.id })
formData.value = res?.data?.data ?? {}
- console.log(formData.value, 66)
-}
-
-// 关闭后重置
-function handleClosed() {
- formData.value = initForm()
}
const initSearchParams = () => ({
current: 1, // 当前页
size: 10, // 每页大小
})
-const searchParams = ref(initSearchParams())
-const total = ref(0) // 总条数
-const loading = ref(true) // 列表加载中
-const list = ref([]) // 列表数据
-async function getList() {
- loading.value = true
- try {
- const params = { ...searchParams.value, planId: formData.value.id }
- const res = await fwDeviceMaintainRecordPageApi(params)
- list.value = res?.data?.data?.records ?? []
- total.value = res?.data?.data?.total ?? 0
- } finally {
- loading.value = false
- }
-}
// 打开弹框
-async function open({ mode, row } = {}) {
- dialogMode.value = mode || 'add'
- visible.value = true
- await getDeviceList()
- if (dialogMode.value === 'add') {
- formData.value = initForm()
- } else {
- formData.value = row
+async function open({ mode = 'add', row } = {}) {
+ dialogMode.value = mode
+ formData.value = dialogMode.value === 'add' ? initForm() : row
+ if (dialogMode.value !== 'add') {
await loadDetail()
- getList()
}
}
defineExpose({ open })
-
-watch(
- () => formData.value?.planCycleType,
- type => {
- planCycleValueOptions.value = []
- if (!type) return
- if (type === '1') {
- ;[...Array(12)].forEach((item, index) => {
- ;[...Array(31)].forEach((item1, index1) => {
- planCycleValueOptions.value.push({ value: `${index + 1}月${index1 + 1}号` })
- })
- })
- } else if (type === '2') {
- ;[...Array(31)].forEach((item, index) => {
- planCycleValueOptions.value.push({ value: `${index + 1}号` })
- })
- } else if (type === '3') {
- ;[...Array(7)].forEach((item, index) => {
- planCycleValueOptions.value.push({ value: `星期${index + 1}` })
- })
- }
- }
-)
</script>
diff --git a/applications/task-work-order/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue b/applications/task-work-order/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue
deleted file mode 100644
index b0be5ad..0000000
--- a/applications/task-work-order/src/views/basicManage/maintainRecord/MaintenanceDiaLog.vue
+++ /dev/null
@@ -1,177 +0,0 @@
-<template>
- <el-dialog class="gd-dialog" v-model="visible" :title="titleEnum[dialogMode]" @closed="handleClosed" destroy-on-close>
- <div class="detail-container" v-if="dialogReadonly">
- <div class="detail-title">设备详情</div>
- <el-row>
- <el-col :span="12">
- <div class="label">设备名称</div>
- <div class="val">{{ deviceName }}</div>
- </el-col>
- <el-col :span="12">
- <div class="label">维护计划</div>
- <div class="val">{{ planCycleLabel }}</div>
- </el-col>
- </el-row>
- </div>
- <el-form
- class="dialog-form"
- v-else
- ref="formRef"
- :model="formData"
- :rules="rules"
- :disabled="dialogReadonly"
- label-width="110px"
- >
- <el-row>
- <el-col :span="24">
- <el-form-item label="维护内容" prop="maintainContent">
- <el-input
- class="gd-input"
- v-model="formData.maintainContent"
- maxlength="200"
- type="textarea"
- placeholder="请输入"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="更换部件" prop="replacePart">
- <el-input
- class="gd-input"
- v-model="formData.replacePart"
- maxlength="200"
- type="textarea"
- placeholder="请输入"
- clearable
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="实际维护时间" prop="maintainTime">
- <el-date-picker
- class="gd-date-picker"
- popper-class="gd-date-picker-popper"
- v-model="formData.maintainTime"
- type="date"
- placeholder="选择日期"
- value-format="YYYY-MM-DD HH:mm:ss"
- clearable
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <el-button color="#F2F3F5" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
- <el-button
- v-if="!dialogReadonly"
- class="save-btn"
- color="#4C34FF"
- :loading="submitting"
- :disabled="submitting"
- @click="handleSubmit"
- >
- 确定
- </el-button>
- </template>
- </el-dialog>
-</template>
-
-<script setup>
-import { computed, ref } from 'vue'
-import { ElMessage } from 'element-plus'
-import { fieldRules } from '@ztzf/utils'
-import { fwDeviceMaintainRecordSubmitApi } from '@/views/basicManage/maintainRecord/fwDeviceMaintainRecord'
-import { fwDeviceMaintainPlanDetailApi } from '@/views/basicManage/maintainRecord/maintainRecordApi'
-
-const initForm = () => ({
- deviceId: '',
- id: '',
- maintainContent: '',
- replacePart: '',
- maintainTime: '',
-})
-
-const planCycleOptions = [
- { label: '每年', value: '1' },
- { label: '每月', value: '2' },
- { label: '每周', value: '3' },
-]
-
-const emit = defineEmits(['success'])
-const formRef = ref(null) // 表单实例
-const formData = ref(initForm()) // 表单数据
-const visible = ref(false) // 弹框显隐
-const dialogMode = ref('add') // 弹框模式
-const submitting = ref(false) // 提交中
-const deviceList = ref([]) // 设备列表
-
-const dialogReadonly = computed(() => dialogMode.value === 'view')
-const titleEnum = ref({ edit: '编辑', view: '查看', add: '维护计划' })
-
-const planCycleLabel = computed(() => {
- const item = planCycleOptions.find(option => option.value === formData.value.planCycleType)
- return item?.label || formData.value.planCycleType || '-'
-})
-const deviceName = computed(() => {
- const target = deviceList.value.find(item => item.id === formData.value.deviceId)
- return formData.value.deviceName || target?.deviceName || '-'
-})
-
-const rules = {
- maintainContent: fieldRules(true, 200),
- replacePart: fieldRules(true, 200),
- maintainTime: fieldRules(true),
-}
-
-// 关闭弹框
-function handleCancel() {
- visible.value = false
-}
-
-// 提交新增/编辑
-async function handleSubmit() {
- const isValid = await formRef.value?.validate().catch(() => false)
- if (!isValid) return
- submitting.value = true
- try {
- await fwDeviceMaintainRecordSubmitApi(formData.value)
- ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
- visible.value = false
- emit('success')
- } finally {
- submitting.value = false
- }
-}
-
-// 加载详情
-async function loadDetail() {
- console.log(formData.value)
- if (!formData.value.id) return
- const res = await fwDeviceMaintainPlanDetailApi({ id: formData.value.id })
- formData.value = {
- planId: res?.data?.data?.id,
- deviceId: res?.data?.data.deviceId,
- }
-}
-
-// 关闭后重置
-function handleClosed() {
- formData.value = initForm()
-}
-
-// 打开弹框
-async function open({ mode, row } = {}) {
- dialogMode.value = mode || 'add'
- visible.value = true
- if (dialogMode.value === 'add') {
- formData.value = initForm()
- } else {
- formData.value = row
- await loadDetail()
- }
-}
-
-defineExpose({ open })
-</script>
diff --git a/applications/task-work-order/src/views/basicManage/maintainRecord/fwDeviceMaintainRecord.js b/applications/task-work-order/src/views/basicManage/maintainRecord/fwDeviceMaintainRecord.js
deleted file mode 100644
index 07e29be..0000000
--- a/applications/task-work-order/src/views/basicManage/maintainRecord/fwDeviceMaintainRecord.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import request from '@/axios'
-
-// 分页
-export const fwDeviceMaintainRecordPageApi = params => {
- return request({
- url: `/drone-fw/device/fwDeviceMaintainRecord/page`,
- method: 'get',
- params: { descs: 'update_time', ...params },
- })
-}
-
-// 新增或修改
-export const fwDeviceMaintainRecordSubmitApi = data => {
- return request({
- url: `/drone-fw/device/fwDeviceMaintainRecord/submit`,
- method: 'post',
- data,
- })
-}
diff --git a/applications/task-work-order/src/views/basicManage/maintainRecord/index.vue b/applications/task-work-order/src/views/basicManage/maintainRecord/index.vue
index 1a920cb..38b06c2 100644
--- a/applications/task-work-order/src/views/basicManage/maintainRecord/index.vue
+++ b/applications/task-work-order/src/views/basicManage/maintainRecord/index.vue
@@ -50,7 +50,7 @@
</el-form>
<div class="gd-table-toolbar">
- <el-button :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">维护计划</el-button>
+ <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
<el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
</div>
@@ -76,8 +76,8 @@
</el-table-column>
<el-table-column label="操作" class-name="operation-btns">
<template v-slot="{ row }">
- <el-link @click="handleView(row)">查看</el-link>
- <el-link @click="maintenance(row)">维护</el-link>
+ <el-link @click="openForm('view', row)">查看</el-link>
+ <el-link @click="openForm('edit', row)">编辑</el-link>
<el-link @click="handleDelete(row)">删除</el-link>
</template>
</el-table-column>
@@ -96,8 +96,7 @@
</div>
</div>
- <FormDiaLog ref="dialogRef" @success="getList" />
- <MaintenanceDiaLog ref="maintenanceDialogRef" @success="getList" />
+ <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
</basic-container>
</template>
<script setup>
@@ -108,7 +107,6 @@
import { getDeptTree } from '@/api/system/dept'
import { getDictLabel } from '@ztzf/utils'
import FormDiaLog from './FormDiaLog.vue'
-import MaintenanceDiaLog from '@/views/basicManage/maintainRecord/MaintenanceDiaLog.vue'
import {
fwDeviceMaintainPlanPageApi,
fwDeviceMaintainPlanRemoveApi,
@@ -128,7 +126,7 @@
const selectedIds = ref([]) // 勾选的ID列表
const queryParamsRef = ref(null) // 查询表单实例
const dialogRef = ref(null) // 弹框实例
-const maintenanceDialogRef = ref(null) // 弹框实例
+const dialogVisible = ref(false)
const dictObj = ref({
deviceType: [], // 设备类型
deviceAtt: [], // 设备属性
@@ -171,14 +169,13 @@
getList()
}
-// 查看
-function handleView(row) {
- dialogRef.value?.open({ mode: 'view', row: { ...row } })
-}
-// 维护
-function maintenance(row) {
- maintenanceDialogRef.value?.open({ mode: 'edit', row: { ...row } })
+// 新增/编辑/查看 弹框
+function openForm(mode, row) {
+ dialogVisible.value = true
+ nextTick(() => {
+ dialogRef.value?.open({ mode, row })
+ })
}
// 删除
@@ -214,11 +211,6 @@
getDeptTree().then(res => {
deptTree.value = res.data.data
})
-}
-
-// 新增
-function handleAdd() {
- dialogRef.value?.open({ mode: 'add' })
}
function getPlanCycleLabel(row) {
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue
new file mode 100644
index 0000000..1be65c0
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/FormDiaLog.vue
@@ -0,0 +1,220 @@
+<template>
+ <el-dialog
+ class="gd-dialog"
+ v-model="visible"
+ :title="titleEnum[dialogMode]"
+ @closed="visible = false"
+ destroy-on-close
+ >
+ <div class="detail-container" v-if="dialogReadonly">
+ <el-row>
+ <el-col :span="12">
+ <div class="label">标题</div>
+ <div class="val">{{ formData.title }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">数据名称</div>
+ <div class="val">{{ formData.dataName }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">提出部门</div>
+ <div class="val">{{ formData.proposeDeptName }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">数据提供部门</div>
+ <div class="val">{{ formData.dataProvideDeptName }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">评分</div>
+ <div class="val">{{ formData.score }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">是否解决</div>
+ <div class="val">{{ formData.isResolved === '1' ? '是' : '否' }}</div>
+ </el-col>
+ <el-col :span="24">
+ <div class="label">评价内容</div>
+ <div class="val">{{ formData.evaluationContent }}</div>
+ </el-col>
+ </el-row>
+ </div>
+
+ <el-form
+ class="dialog-form"
+ v-else
+ ref="formRef"
+ :model="formData"
+ :rules="rules"
+ :disabled="dialogReadonly"
+ label-width="80px"
+ >
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="标题" prop="title">
+ <el-input class="gd-input" v-model="formData.title" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="数据名称" prop="dataName">
+ <el-input class="gd-input" v-model="formData.dataName" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="提出部门" prop="proposeDeptId">
+ <el-tree-select
+ class="gd-select"
+ popper-class="gd-tree-select-popper"
+ v-model="formData.proposeDeptId"
+ node-key="id"
+ :data="deptTree"
+ :props="treeProps"
+ check-strictly
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="数据提供部门" prop="dataProvideDeptId">
+ <el-tree-select
+ class="gd-select"
+ popper-class="gd-tree-select-popper"
+ v-model="formData.dataProvideDeptId"
+ node-key="id"
+ :data="deptTree"
+ :props="treeProps"
+ check-strictly
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="评分" prop="score">
+ <el-input-number
+ class="gd-input"
+ v-model="formData.score"
+ :min="1"
+ :max="10"
+ placeholder="请输入"
+ controls-position="right"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="是否解决" prop="isResolved">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="formData.isResolved"
+ placeholder="请选择"
+ clearable
+ >
+ <el-option v-for="item in isResolvedOptions" :key="item.value" :label="item.label" :value="item.value" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="24">
+ <el-form-item label="评价内容" prop="evaluationContent">
+ <el-input
+ class="gd-input"
+ v-model="formData.evaluationContent"
+ type="textarea"
+ :rows="4"
+ placeholder="请输入"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
+ <el-button
+ class="save-btn"
+ color="#4C34FF"
+ v-if="!dialogReadonly"
+ :loading="submitting"
+ :disabled="submitting"
+ @click="handleSubmit"
+ >
+ 保存
+ </el-button>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { fieldRules } from '@ztzf/utils'
+import {
+ gdDataEvaluationDetailApi,
+ gdDataEvaluationSubmitApi,
+} from '@/views/orderView/orderDataManage/evaluate/evaluateApi'
+
+// 初始化表单数据
+const initForm = () => ({
+ title: '',
+ dataName: '',
+ proposeDeptId: '',
+ dataProvideDeptId: '',
+ score: null,
+ isResolved: '',
+ evaluationContent: '',
+})
+
+const deptTree = inject('deptTree')
+const treeProps = inject('treeProps')
+const isResolvedOptions = inject('isResolvedOptions')
+
+const emit = defineEmits(['success'])
+const formRef = ref(null) // 表单实例
+const formData = ref(initForm()) // 表单数据
+const visible = defineModel() // 弹框显隐
+const dialogMode = ref('add') // 弹框模式
+const submitting = ref(false) // 提交中
+const dialogReadonly = computed(() => dialogMode.value === 'view')
+const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
+
+const rules = {
+ title: fieldRules(true),
+ dataName: fieldRules(true),
+ proposeDeptId: fieldRules(true),
+ dataProvideDeptId: fieldRules(true),
+ score: fieldRules(true),
+ isResolved: fieldRules(true),
+ evaluationContent: fieldRules(true),
+}
+
+// 提交新增/编辑
+async function handleSubmit() {
+ const isValid = await formRef.value?.validate().catch(() => false)
+ if (!isValid) return
+ submitting.value = true
+ try {
+ await gdDataEvaluationSubmitApi(formData.value)
+ ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
+ visible.value = false
+ emit('success')
+ } finally {
+ submitting.value = false
+ }
+}
+
+// 加载详情
+async function loadDetail() {
+ if (!formData.value.id) return
+ const res = await gdDataEvaluationDetailApi({ id: formData.value.id })
+ formData.value = res?.data?.data ?? {}
+}
+
+// 打开弹框
+async function open({ mode = 'add', row } = {}) {
+ dialogMode.value = mode
+ formData.value = dialogMode.value === 'add' ? initForm() : row
+ if (dialogMode.value !== 'add') {
+ await loadDetail()
+ }
+}
+
+defineExpose({ open })
+</script>
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/evaluateApi.js b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/evaluateApi.js
new file mode 100644
index 0000000..aae98de
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/evaluateApi.js
@@ -0,0 +1,37 @@
+import request from '@/axios'
+
+// 列表
+export const gdDataEvaluationPageApi = params => {
+ return request({
+ url: `/drone-gd/orderdata/gdDataEvaluation/page`,
+ method: 'get',
+ params: { descs: 'update_time', ...params },
+ })
+}
+
+// 新增或编辑
+export const gdDataEvaluationSubmitApi = data => {
+ return request({
+ url: `/drone-gd/orderdata/gdDataEvaluation/submit`,
+ method: 'post',
+ data,
+ })
+}
+
+// 删除
+export const gdDataEvaluationRemoveApi = params => {
+ return request({
+ url: `/drone-gd/orderdata/gdDataEvaluation/remove`,
+ method: 'post',
+ params,
+ })
+}
+
+// 详情
+export const gdDataEvaluationDetailApi = params => {
+ return request({
+ url: `/drone-gd/orderdata/gdDataEvaluation/detail`,
+ method: 'get',
+ params,
+ })
+}
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
index e3b7695..2f5aaec 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
@@ -1,9 +1,177 @@
<template>
- <basic-container>
- 评价管理
- </basic-container>
+ <basic-container>
+ <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
+ <el-form-item label="标题" prop="title">
+ <el-input class="gd-input" v-model="searchParams.title" placeholder="请输入" clearable @clear="handleSearch" />
+ </el-form-item>
+
+ <el-form-item label="是否解决" prop="isResolved">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="searchParams.isResolved"
+ placeholder="请选择"
+ clearable
+ @change="handleSearch"
+ >
+ <el-option v-for="item in isResolvedOptions" :key="item.value" :label="item.label" :value="item.value" />
+ </el-select>
+ </el-form-item>
+
+ <el-form-item class="gd-search-actions">
+ <el-button :icon="RefreshRight" @click="resetForm"></el-button>
+ <el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+ </el-form-item>
+ </el-form>
+
+ <div class="gd-table-toolbar">
+ <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
+ <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
+ </div>
+
+ <div class="gd-table-container" v-loading="loading">
+ <div class="gd-table-content gd-table-content-bg">
+ <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
+ <el-table-column type="selection" width="46" />
+ <el-table-column prop="title" show-overflow-tooltip label="标题" />
+ <el-table-column prop="dataName" show-overflow-tooltip label="数据名称" />
+ <el-table-column prop="proposeDeptName" show-overflow-tooltip label="提出部门" />
+ <el-table-column prop="dataProvideDeptName" show-overflow-tooltip label="数据提供部门" />
+ <el-table-column prop="score" show-overflow-tooltip label="评分" />
+ <el-table-column prop="isResolved" show-overflow-tooltip label="是否解决">
+ <template v-slot="{ row }">
+ {{ row.isResolved === '1' ? '是' : '否' }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="evaluationContent" show-overflow-tooltip label="评价内容" />
+ <el-table-column label="操作" class-name="operation-btns">
+ <template v-slot="{ row }">
+ <el-link @click="openForm('view', row)">查看</el-link>
+ <el-link @click="openForm('edit', row)">编辑</el-link>
+ <el-link @click="handleDelete(row)">删除</el-link>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <div class="gd-pagination-parent">
+ <el-pagination
+ popper-class="gd-select-popper"
+ v-model:current-page="searchParams.current"
+ v-model:page-size="searchParams.size"
+ layout="total, prev, pager, next, sizes"
+ :total="total"
+ @change="getList"
+ />
+ </div>
+ </div>
+
+ <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
+ </basic-container>
</template>
<script setup>
+import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue'
+import { onMounted, ref } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { getDeptTree } from '@/api/system/dept'
+import FormDiaLog from './FormDiaLog.vue'
+import {
+ gdDataEvaluationPageApi,
+ gdDataEvaluationRemoveApi,
+} from '@/views/orderView/orderDataManage/evaluate/evaluateApi'
+
+// 初始化查询参数
+const initSearchParams = () => ({
+ title: '', // 标题
+ isResolved: '', // 是否解决
+ current: 1, // 当前页
+ size: 10, // 每页大小
+})
+const searchParams = ref(initSearchParams()) // 查询参数
+const total = ref(0) // 总条数
+const loading = ref(true) // 列表加载中
+const list = ref([]) // 列表数据
+const selectedIds = ref([]) // 勾选的ID列表
+const queryParamsRef = ref(null) // 查询表单实例
+const dialogRef = ref(null) // 弹框实例
+const dialogVisible = ref(false)
+const deptTree = ref([]) // 部门树
+const treeProps = {
+ label: 'name',
+ children: 'children',
+}
+const isResolvedOptions = [
+ { label: '否', value: '0' },
+ { label: '是', value: '1' },
+]
+provide('deptTree', deptTree)
+provide('treeProps', treeProps)
+provide('isResolvedOptions', isResolvedOptions)
+
+// 获取列表
+async function getList() {
+ loading.value = true
+ try {
+ const res = await gdDataEvaluationPageApi(searchParams.value)
+ list.value = res?.data?.data?.records ?? []
+ total.value = res?.data?.data?.total ?? 0
+ } finally {
+ loading.value = false
+ }
+}
+
+// 查询
+function handleSearch() {
+ searchParams.value.current = 1
+ getList()
+}
+
+// 重置查询
+function resetForm() {
+ queryParamsRef.value?.resetFields()
+ searchParams.value.current = 1
+ getList()
+}
+
+// 新增/编辑/查看 弹框
+function openForm(mode, row) {
+ dialogVisible.value = true
+ nextTick(() => {
+ dialogRef.value?.open({ mode, row })
+ })
+}
+
+// 删除
+async function handleDelete(row) {
+ const tips = row ? '该条' : '选中的项'
+ await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', {
+ type: 'warning',
+ customClass: 'gd-confirm-custom',
+ confirmButtonClass: 'gd-confirm-button',
+ cancelButtonClass: 'gd-confirm-cancel-button',
+ })
+ const ids = row ? row.id : selectedIds.value.join(',')
+ await gdDataEvaluationRemoveApi({ ids })
+ ElMessage.success('删除成功')
+ selectedIds.value = []
+ getList()
+}
+
+// 勾选值设置
+function handleSelectionChange(rows) {
+ selectedIds.value = rows.map(item => item.id)
+}
+
+// 获取部门树
+function getDeptTreeFun() {
+ getDeptTree().then(res => {
+ deptTree.value = res.data.data
+ })
+}
+
+onMounted(() => {
+ getList()
+ getDeptTreeFun()
+})
</script>
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
new file mode 100644
index 0000000..96e29d9
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/FormDiaLog.vue
@@ -0,0 +1,291 @@
+<template>
+ <el-dialog
+ class="gd-dialog"
+ v-model="visible"
+ :title="titleEnum[dialogMode]"
+ @closed="visible = false"
+ destroy-on-close
+ >
+ <div class="detail-container" v-if="dialogReadonly">
+ <el-row>
+ <el-col :span="12">
+ <div class="label">需求名称</div>
+ <div class="val">{{ formData.demandName }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">需求类型</div>
+ <div class="val">{{ getDictLabel(formData.demandType, dictObj.requirementType) }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">需求联系人</div>
+ <div class="val">{{ formData.contactPerson }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">需求联系人电话</div>
+ <div class="val">{{ formData.contactPhone }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">需求邮箱</div>
+ <div class="val">{{ formData.contactEmail }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">更新周期</div>
+ <div class="val">{{ formData.updateCycle }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">申请依据</div>
+ <div class="val">{{ formData.applyBasis }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">共享类型</div>
+ <div class="val">{{ getDictLabel(formData.shareType, dictObj.sharedType) }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">应用场景类型</div>
+ <div class="val">{{ getDictLabel(formData.applicationScene, dictObj.appSceneType) }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">责任部门</div>
+ <div class="val">{{ formData.responsibleDeptName }}</div>
+ </el-col>
+ <el-col :span="12">
+ <div class="label">数据来源依据</div>
+ <div class="val">{{ formData.dataSource }}</div>
+ </el-col>
+ <el-col :span="24">
+ <div class="label">需求信息项</div>
+ <div class="val">{{ formData.demandInfo }}</div>
+ </el-col>
+ </el-row>
+ </div>
+
+ <el-form
+ class="dialog-form"
+ v-else
+ ref="formRef"
+ :model="formData"
+ :rules="rules"
+ :disabled="dialogReadonly"
+ label-width="120px"
+ >
+ <el-row>
+ <el-col :span="12">
+ <el-form-item label="需求名称" prop="demandName">
+ <el-input class="gd-input" v-model="formData.demandName" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="需求类型" prop="demandType">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="formData.demandType"
+ placeholder="请选择"
+ clearable
+ >
+ <el-option
+ v-for="item in dictObj.requirementType"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="需求联系人" prop="contactPerson">
+ <el-input class="gd-input" v-model="formData.contactPerson" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="需求联系人电话" prop="contactPhone">
+ <el-input class="gd-input" v-model="formData.contactPhone" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="需求邮箱" prop="contactEmail">
+ <el-input class="gd-input" v-model="formData.contactEmail" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="更新周期" prop="updateCycle">
+ <el-input class="gd-input" v-model="formData.updateCycle" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="申请依据" prop="applyBasis">
+ <el-input class="gd-input" v-model="formData.applyBasis" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="共享类型" prop="shareType">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="formData.shareType"
+ placeholder="请选择"
+ clearable
+ >
+ <el-option
+ v-for="item in dictObj.sharedType"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="应用场景类型" prop="applicationScene">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="formData.applicationScene"
+ placeholder="请选择"
+ clearable
+ >
+ <el-option
+ v-for="item in dictObj.appSceneType"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="责任部门" prop="responsibleDeptId">
+ <el-tree-select
+ class="gd-select"
+ popper-class="gd-tree-select-popper"
+ v-model="formData.responsibleDeptId"
+ node-key="id"
+ :data="deptTree"
+ :props="treeProps"
+ check-strictly
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="数据来源依据" prop="dataSource">
+ <el-input class="gd-input" v-model="formData.dataSource" placeholder="请输入" clearable />
+ </el-form-item>
+ </el-col>
+ <el-col :span="24">
+ <el-form-item label="需求信息项" prop="demandInfo">
+ <el-input
+ class="gd-input"
+ v-model="formData.demandInfo"
+ type="textarea"
+ :rows="4"
+ placeholder="请输入"
+ clearable
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <el-button color="#F2F3F5" @click="visible = false">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
+ <el-button
+ class="save-btn"
+ color="#4C34FF"
+ v-if="!dialogReadonly"
+ :loading="submitting"
+ :disabled="submitting"
+ @click="handleSubmit"
+ >
+ 保存
+ </el-button>
+ </template>
+ </el-dialog>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { fieldRules } from '@ztzf/utils'
+import { getDictLabel } from '@ztzf/utils'
+import {
+ gdSupplyDemandDetailApi,
+ gdSupplyDemandSubmitApi,
+} from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi'
+
+// 初始化表单数据
+const initForm = () => ({
+ demandName: '',
+ demandType: '',
+ contactPerson: '',
+ contactPhone: '',
+ contactEmail: '',
+ updateCycle: '',
+ applyBasis: '',
+ shareType: '',
+ applicationScene: '',
+ responsibleDeptId: '',
+ dataSource: '',
+ demandInfo: '',
+})
+
+const dictObj = inject('dictObj')
+const deptTree = inject('deptTree')
+const treeProps = inject('treeProps')
+
+const emit = defineEmits(['success'])
+const formRef = ref(null) // 表单实例
+const formData = ref(initForm()) // 表单数据
+const visible = defineModel() // 弹框显隐
+const dialogMode = ref('add') // 弹框模式
+const submitting = ref(false) // 提交中
+const dialogReadonly = computed(() => dialogMode.value === 'view')
+const titleEnum = ref({ edit: '编辑', view: '查看', add: '新增' })
+
+const rules = {
+ demandName: fieldRules(true),
+ demandType: fieldRules(true),
+ contactPerson: fieldRules(true),
+ contactPhone: fieldRules(true),
+ contactEmail: fieldRules(true),
+ updateCycle: fieldRules(true),
+ applyBasis: fieldRules(true),
+ shareType: fieldRules(true),
+ applicationScene: fieldRules(true),
+ responsibleDeptId: fieldRules(true),
+ dataSource: fieldRules(true),
+ demandInfo: fieldRules(true),
+}
+
+// 提交新增/编辑
+async function handleSubmit() {
+ const isValid = await formRef.value?.validate().catch(() => false)
+ if (!isValid) return
+ submitting.value = true
+ try {
+ await gdSupplyDemandSubmitApi(formData.value)
+ ElMessage.success(dialogMode.value === 'add' ? '新增成功' : '更新成功')
+ visible.value = false
+ emit('success')
+ } finally {
+ submitting.value = false
+ }
+}
+
+// 加载详情
+async function loadDetail() {
+ if (!formData.value.id) return
+ const res = await gdSupplyDemandDetailApi({ id: formData.value.id })
+ formData.value = res?.data?.data ?? {}
+}
+
+// 打开弹框
+async function open({ mode = 'add', row } = {}) {
+ dialogMode.value = mode
+ formData.value = dialogMode.value === 'add' ? initForm() : row
+ if (dialogMode.value !== 'add') {
+ await loadDetail()
+ }
+}
+
+defineExpose({ open })
+</script>
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
index faf27af..a234a92 100644
--- a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
@@ -1,9 +1,217 @@
<template>
- <basic-container>
- 供需填报管理
- </basic-container>
+ <basic-container>
+ <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
+ <el-form-item label="需求名称" prop="demandName">
+ <el-input
+ class="gd-input"
+ v-model="searchParams.demandName"
+ placeholder="请输入"
+ clearable
+ @clear="handleSearch"
+ />
+ </el-form-item>
+
+ <el-form-item label="需求状态" prop="demandStatus">
+ <el-select
+ class="gd-select"
+ popper-class="gd-select-popper"
+ v-model="searchParams.demandStatus"
+ placeholder="请选择"
+ clearable
+ @change="handleSearch"
+ >
+ <el-option
+ v-for="item in dictObj.demandStatus"
+ :key="item.dictKey"
+ :label="item.dictValue"
+ :value="item.dictKey"
+ />
+ </el-select>
+ </el-form-item>
+
+ <el-form-item class="gd-search-actions">
+ <el-button :icon="RefreshRight" @click="resetForm"></el-button>
+ <el-button class="search-btn" :icon="Search" @click="handleSearch"></el-button>
+ </el-form-item>
+ </el-form>
+
+ <div class="gd-table-toolbar">
+ <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
+ <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
+ </div>
+
+ <div class="gd-table-container" v-loading="loading">
+ <div class="gd-table-content gd-table-content-bg">
+ <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
+ <el-table-column type="selection" width="46" />
+ <el-table-column prop="demandName" show-overflow-tooltip label="需求名称" />
+ <el-table-column prop="demandType" show-overflow-tooltip label="需求类型">
+ <template v-slot="{ row }">
+ {{ getDictLabel(row.demandType, dictObj.requirementType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="contactPerson" show-overflow-tooltip label="需求联系人" />
+ <el-table-column prop="contactPhone" show-overflow-tooltip label="需求联系人电话" />
+ <el-table-column prop="contactEmail" show-overflow-tooltip label="需求邮箱" />
+ <el-table-column prop="demandStatus" show-overflow-tooltip label="需求状态">
+ <!-- <template v-slot="{ row }">
+ {{ getDictLabel(row.demandStatus, dictObj.demandStatus) }}
+ </template> -->
+ </el-table-column>
+ <el-table-column prop="updateCycle" show-overflow-tooltip label="更新周期" />
+ <el-table-column prop="applyBasis" show-overflow-tooltip label="申请依据" />
+ <el-table-column prop="shareType" show-overflow-tooltip label="共享类型">
+ <template v-slot="{ row }">
+ {{ getDictLabel(row.shareType, dictObj.sharedType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="applicationScene" show-overflow-tooltip label="应用场景类型">
+ <template v-slot="{ row }">
+ {{ getDictLabel(row.applicationScene, dictObj.appSceneType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="responsibleDeptName" show-overflow-tooltip label="责任部门" />
+ <el-table-column prop="dataSource" show-overflow-tooltip label="数据来源依据" />
+ <el-table-column prop="demandInfo" show-overflow-tooltip label="需求信息项" />
+ <el-table-column label="操作" class-name="operation-btns">
+ <template v-slot="{ row }">
+ <el-link @click="openForm('view', row)">查看</el-link>
+ <el-link @click="openForm('edit', row)">编辑</el-link>
+ <el-link @click="handleDelete(row)">删除</el-link>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <div class="gd-pagination-parent">
+ <el-pagination
+ popper-class="gd-select-popper"
+ v-model:current-page="searchParams.current"
+ v-model:page-size="searchParams.size"
+ layout="total, prev, pager, next, sizes"
+ :total="total"
+ @change="getList"
+ />
+ </div>
+ </div>
+
+ <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
+ </basic-container>
</template>
<script setup>
+import { Search, RefreshRight, Plus, Delete } from '@element-plus/icons-vue'
+import { onMounted, ref } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { getDictionaryByCode } from '@/api/system/dictbiz'
+import { getDeptTree } from '@/api/system/dept'
+import { getDictLabel } from '@ztzf/utils'
+import FormDiaLog from './FormDiaLog.vue'
+import {
+ gdSupplyDemandPageApi,
+ gdSupplyDemandRemoveApi,
+} from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi'
+
+// 初始化查询参数
+const initSearchParams = () => ({
+ demandName: '', // 需求名称
+ demandStatus: '', // 需求状态
+ current: 1, // 当前页
+ size: 10, // 每页大小
+})
+const searchParams = ref(initSearchParams()) // 查询参数
+const total = ref(0) // 总条数
+const loading = ref(true) // 列表加载中
+const list = ref([]) // 列表数据
+const selectedIds = ref([]) // 勾选的ID列表
+const queryParamsRef = ref(null) // 查询表单实例
+const dialogRef = ref(null) // 弹框实例
+const dialogVisible = ref(false)
+const dictObj = ref({
+ requirementType: [], // 需求类型
+ sharedType: [], // 共享类型
+ appSceneType: [], // 应用场景类型
+})
+provide('dictObj', dictObj)
+const deptTree = ref([]) // 部门树
+const treeProps = {
+ label: 'name',
+ children: 'children',
+}
+provide('deptTree', deptTree)
+provide('treeProps', treeProps)
+
+// 获取列表
+async function getList() {
+ loading.value = true
+ try {
+ const res = await gdSupplyDemandPageApi(searchParams.value)
+ list.value = res?.data?.data?.records ?? []
+ total.value = res?.data?.data?.total ?? 0
+ } finally {
+ loading.value = false
+ }
+}
+
+// 查询
+function handleSearch() {
+ searchParams.value.current = 1
+ getList()
+}
+
+// 重置查询
+function resetForm() {
+ queryParamsRef.value?.resetFields()
+ searchParams.value.current = 1
+ getList()
+}
+
+// 新增/编辑/查看 弹框
+function openForm(mode, row) {
+ dialogVisible.value = true
+ nextTick(() => {
+ dialogRef.value?.open({ mode, row })
+ })
+}
+
+// 删除
+async function handleDelete(row) {
+ const tips = row ? '该条' : '选中的项'
+ await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', {
+ type: 'warning',
+ customClass: 'gd-confirm-custom',
+ confirmButtonClass: 'gd-confirm-button',
+ cancelButtonClass: 'gd-confirm-cancel-button',
+ })
+ const ids = row ? row.id : selectedIds.value.join(',')
+ await gdSupplyDemandRemoveApi({ ids })
+ ElMessage.success('删除成功')
+ selectedIds.value = []
+ getList()
+}
+
+// 勾选值设置
+function handleSelectionChange(rows) {
+ selectedIds.value = rows.map(item => item.id)
+}
+
+// 获取字典
+function getDictList() {
+ getDictionaryByCode('requirementType,sharedType,appSceneType').then(res => {
+ dictObj.value = res.data.data
+ })
+}
+
+// 获取部门树
+function getDeptTreeFun() {
+ getDeptTree().then(res => {
+ deptTree.value = res.data.data
+ })
+}
+
+onMounted(() => {
+ getList()
+ getDictList()
+ getDeptTreeFun()
+})
</script>
-<style scoped lang="scss">
-</style>
+<style scoped lang="scss"></style>
diff --git a/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/supplyAddApi.js b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/supplyAddApi.js
new file mode 100644
index 0000000..7823047
--- /dev/null
+++ b/applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/supplyAddApi.js
@@ -0,0 +1,55 @@
+import request from '@/axios'
+
+// 获取供需需求列表
+export const gdSupplyDemandPageApi = params => {
+ return request({
+ url: `/drone-gd/orderdata/gdSupplyDemand/page`,
+ method: 'get',
+ params: { descs: 'update_time', ...params },
+ })
+}
+
+// 新增或编辑供需需求
+export const gdSupplyDemandSubmitApi = data => {
+ return request({
+ url: `/drone-gd/orderdata/gdSupplyDemand/submit`,
+ method: 'post',
+ data,
+ })
+}
+
+// 删除供需需求
+export const gdSupplyDemandRemoveApi = params => {
+ return request({
+ url: `/drone-gd/orderdata/gdSupplyDemand/remove`,
+ method: 'post',
+ params,
+ })
+}
+
+// 获取供需需求详情
+export const gdSupplyDemandDetailApi = params => {
+ return request({
+ url: `/drone-gd/orderdata/gdSupplyDemand/detail`,
+ method: 'get',
+ params,
+ })
+}
+
+// 审核通过
+export const gdSupplyDemandAuditPassApi = data => {
+ return request({
+ url: `/drone-gd/orderdata/gdSupplyDemand/audit-pass`,
+ method: 'post',
+ data,
+ })
+}
+
+// 拒绝申请
+export const gdSupplyDemandAuditRejectApi = data => {
+ return request({
+ url: `/drone-gd/orderdata/gdSupplyDemand/audit-reject`,
+ method: 'post',
+ data,
+ })
+}
diff --git a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
index a46e0d8..53f96e2 100644
--- a/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
+++ b/applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
@@ -1,6 +1,6 @@
<template>
<basic-container>
- 基础管理
+ 基础3管理
</basic-container>
</template>
<script setup>
diff --git a/applications/task-work-order/src/views/wel/index.vue b/applications/task-work-order/src/views/wel/index.vue
index f59947f..6077d0a 100644
--- a/applications/task-work-order/src/views/wel/index.vue
+++ b/applications/task-work-order/src/views/wel/index.vue
@@ -1,6 +1,6 @@
<template>
<div>
-
+ 测试
</div>
</template>
@@ -10,4 +10,4 @@
<style lang="scss" scoped>
-</style>
\ No newline at end of file
+</style>
diff --git a/uniapps/work-app/src/App.vue b/uniapps/work-app/src/App.vue
index 020fe6c..3240b20 100644
--- a/uniapps/work-app/src/App.vue
+++ b/uniapps/work-app/src/App.vue
@@ -1,19 +1,32 @@
<script setup>
import { onHide, onLaunch, onShow } from "@dcloudio/uni-app";
-import { useAppStore, useUserStore } from "@/store";
+import { useAppStore, useUserStore, useLocationStore } from "@/store";
import { useGlobalWS } from "@/hooks/useGlobalWS.js";
const appStore = useAppStore();
const userStore = useUserStore();
+const locationStore = useLocationStore();
useGlobalWS();
-onShow(() => {
+onShow(async () => {
console.log("App Show");
+ // 应用从后台返回前台时,重新初始化位置服务
+ if (userStore.userInfo && locationStore) {
+ try {
+ await locationStore.initLocationService();
+ } catch (error) {
+ console.error('重新初始化位置服务失败:', error);
+ }
+ }
});
onHide(() => {
console.log("App Hide");
+ // 应用进入后台时,停止位置监听以节省资源
+ if (locationStore) {
+ locationStore.stopLocationWatch();
+ }
});
onLaunch(() => {
diff --git a/uniapps/work-app/src/hooks/useGlobalWS.js b/uniapps/work-app/src/hooks/useGlobalWS.js
index 64d3d58..0210cb9 100644
--- a/uniapps/work-app/src/hooks/useGlobalWS.js
+++ b/uniapps/work-app/src/hooks/useGlobalWS.js
@@ -5,6 +5,7 @@
export function useGlobalWS() {
const userStore = useUserStore();
const appStore = useAppStore();
+ const callStatus = ref(null)
// 设置默认用户ID为3
const defaultUserId = '3';
@@ -16,10 +17,9 @@
console.log('🌐 全局WebSocket收到消息111111111111111111111:', payload)
// 先尝试直接处理消息(适用于mobile-web-view的voiceCallDetail页面的消息格式)
const t = (payload.type || '').toString()
- const bizCode = payload.biz_code || ''
-
- console.log('📋 消息分析:type=' + t + ', biz_code=' + bizCode)
-
+ // const bizCode = payload.biz_code || ''
+ callStatus.value = t
+ // console.log('📋 消息分析:type=' + t )
// 处理语音通话请求
if (t === 'call') {
console.log('📞 全局收到来电 call,来自', payload.from)
@@ -36,15 +36,8 @@
try {
// 优先使用uni-app的导航API(适用于同应用内跳转)
if (typeof uni !== 'undefined' && uni.navigateTo) {
- console.log('使用uni-app导航API跳转到语音通话页面');
uni.navigateTo({
url: `/subPackages/voiceCallDetail/index?voiceparams=${encodedParams}`,
- success: () => {
- console.log('✅ 应用内导航成功!');
- },
- fail: (err) => {
- console.error('❌ 应用内导航失败:', err);
- }
});
} else {
console.error('无法跳转到语音通话页面:当前环境不支持导航');
@@ -56,64 +49,63 @@
}
// 然后处理biz_code格式的消息
- switch (bizCode) {
- case 'JOB_ISREFRESH':
- appStore.setJobUpdateKeyAdd()
- break
- case 'DEVICE_ISREFRESH':
- appStore.setDeviceUpdateKeyAdd()
- break
- case 'DOWNLOAD_PROGRESS':
- break
- case 'LOGOUT_USER':
- userStore.setUserInfo(null)
- uni.reLaunch({
- url: '/pages/login/index'
- })
- break
- case 'VoiceCall':
- // enterRoom(payload, userId.value)
- break
- default:
- // 记录未处理的消息
- console.log('未处理的WebSocket消息:', payload)
- break;
- }
+ // switch (bizCode) {
+ // case 'JOB_ISREFRESH':
+ // appStore.setJobUpdateKeyAdd()
+ // break
+ // case 'DEVICE_ISREFRESH':
+ // appStore.setDeviceUpdateKeyAdd()
+ // break
+ // case 'DOWNLOAD_PROGRESS':
+ // break
+ // case 'LOGOUT_USER':
+ // userStore.setUserInfo(null)
+ // uni.reLaunch({
+ // url: '/pages/login/index'
+ // })
+ // break
+ // case 'VoiceCall':
+ // // enterRoom(payload, userId.value)
+ // break
+ // default:
+ // // 记录未处理的消息
+ // console.log('未处理的WebSocket消息:', payload)
+ // break;
+ // }
}
// 初始化WebSocket连接
function initWS() {
try {
- // 检查是否已经有活跃的WebSocket连接
- if (!websocketService.getConnected()) {
- // 使用默认用户ID初始化WebSocket连接
- websocketService.init(defaultUserId, WS_BASE);
- console.log('🌐 全局WebSocket初始化成功,默认用户ID:', defaultUserId);
- } else {
- console.log('🌐 WebSocket已存在活跃连接,无需重新初始化');
- }
- // 只设置一次全局消息处理回调
- // 检查是否已经设置了回调
- if (typeof websocketService.getOnMessageCallback() !== 'function') {
- // 设置全局消息处理回调
- websocketService.setOnMessageCallback(messageHandler);
- console.log('✅ 全局WebSocket消息处理器已设置');
+ websocketService.setOnMessageCallback(messageHandler);
+
+ // 获取当前用户ID,优先使用store中的用户信息
+ const userId = userStore.userInfo?.id || defaultUserId;
+
+ // 检查是否已经有活跃的WebSocket连接
+ if (!websocketService.getConnected() || websocketService.userId !== userId) {
+ // 使用用户ID初始化WebSocket连接
+ websocketService.init(userId, WS_BASE);
+ // console.log('🌐 全局WebSocket初始化成功,用户ID:', userId);
} else {
- console.log('✅ WebSocket消息处理器已存在,无需重新设置');
+ websocketService.connect();
+
}
} catch (error) {
- console.error('❌ 全局WebSocket初始化失败:', error);
}
}
-
- // 监听用户信息变化,初始化WebSocket
watch(
- () => userStore.userInfo,
- (newUserInfo) => {
- console.log('👤 用户信息变化,尝试初始化WebSocket');
+ () => callStatus.value,
+ (newValue) => {
+ if (newValue === 'accept') {
+ console.log('📞 通话中,跳过WebSocket初始化');
+ return;
+ }
initWS();
},
- { immediate: true }
+ { immediate: true, deep: true }
)
}
+
+
diff --git a/uniapps/work-app/src/pages/login/index.vue b/uniapps/work-app/src/pages/login/index.vue
index 7158d87..cdf88ae 100644
--- a/uniapps/work-app/src/pages/login/index.vue
+++ b/uniapps/work-app/src/pages/login/index.vue
@@ -44,7 +44,8 @@
import { getAssetsImage } from "@/utils/index.js";
import md5 from "js-md5";
import { loginByUsername } from "@/api/user/index.js";
-import { useUserStore } from "@/store/index.js";
+import { useUserStore, useLocationStore } from "@/store/index.js";
+import locationUtil from "@/utils/location.js";
import websocketService from "@/utils/websocket.js";
import { HOME_PATH, LOGIN_PATH, removeQueryString } from "@/router";
@@ -56,6 +57,7 @@
const agreed = ref(true);
const userStore = useUserStore();
+const locationStore = useLocationStore();
const loginForm = ref({
username: "",
password: "",
@@ -135,8 +137,22 @@
userInfo.key,
userInfo.code
);
- userStore.setUserInfo(res.data.data);
- console.log('登录成功,WebSocket连接将由全局钩子统一管理');
+ userStore.setUserInfo(res.data.data);
+ // 请求位置权限并初始化位置服务
+ try {
+ // 请求位置权限
+ const hasPermission = await locationUtil.requestLocationPermission();
+ if (hasPermission) {
+ console.log('获取位置权限成功');
+ // 初始化位置服务
+ await locationStore.initLocationService();
+ } else {
+ console.log('获取位置权限失败');
+ }
+ } catch (error) {
+ console.error('处理位置服务失败:', error);
+ }
+
uni.reLaunch({
url: "/pages/work/index",
});
diff --git a/uniapps/work-app/src/store/index.js b/uniapps/work-app/src/store/index.js
index bc05f9b..b949962 100644
--- a/uniapps/work-app/src/store/index.js
+++ b/uniapps/work-app/src/store/index.js
@@ -6,6 +6,7 @@
import useAppStore from "./modules/app"
import useUserStore from "./modules/user"
import useMapStore from "./modules/map"
+import useLocationStore from "./modules/location"
// 安装pinia状态管理插件
function setupStore (app) {
@@ -23,5 +24,5 @@
}
// 导出模块
-export { useAppStore, useUserStore, useMapStore }
+export { useAppStore, useUserStore, useMapStore, useLocationStore }
export default setupStore
diff --git a/uniapps/work-app/src/store/modules/location.js b/uniapps/work-app/src/store/modules/location.js
new file mode 100644
index 0000000..ebf8e9d
--- /dev/null
+++ b/uniapps/work-app/src/store/modules/location.js
@@ -0,0 +1,137 @@
+import { defineStore } from 'pinia'
+import locationUtil from '@/utils/location.js'
+
+const useLocationStore = defineStore('location', {
+ state: () => ({
+ // 当前位置信息
+ currentLocation: null,
+ // 位置权限状态
+ hasPermission: false,
+ // 系统定位服务是否开启
+ systemLocationEnabled: true,
+ // 位置更新间隔(毫秒)
+ updateInterval: 5000,
+ // 位置监听器ID
+ watcherId: null
+ }),
+
+ getters: {
+ /**
+ * 获取当前位置
+ * @returns {Object|null} 当前位置信息
+ */
+ getCurrentLocation: (state) => state.currentLocation,
+
+ /**
+ * 获取位置权限状态
+ * @returns {boolean} 是否有位置权限
+ */
+ getPermissionStatus: (state) => state.hasPermission,
+
+ /**
+ * 获取系统定位服务状态
+ * @returns {boolean} 系统定位服务是否开启
+ */
+ getSystemLocationStatus: (state) => state.systemLocationEnabled
+ },
+
+ actions: {
+ /**
+ * 初始化位置服务
+ */
+ async initLocationService() {
+ try {
+ // 检查系统定位服务是否开启
+ this.systemLocationEnabled = await locationUtil.checkSystemLocationEnabled();
+ if (!this.systemLocationEnabled) {
+ console.warn('系统定位服务未开启');
+ }
+
+ // 请求位置权限
+ this.hasPermission = await locationUtil.requestLocationPermission();
+ if (this.hasPermission) {
+ // 获取当前位置
+ await this.updateCurrentLocation();
+ // 开始位置监听
+ this.startLocationWatch();
+ }
+ } catch (error) {
+ console.error('初始化位置服务失败:', error);
+ }
+ },
+
+ /**
+ * 更新当前位置
+ */
+ async updateCurrentLocation() {
+ try {
+ const location = await locationUtil.getCurrentLocation();
+ this.currentLocation = location;
+ console.log('位置更新:', location);
+ return location;
+ } catch (error) {
+ console.error('更新位置失败:', error);
+ return null;
+ }
+ },
+
+ /**
+ * 开始位置监听
+ */
+ startLocationWatch() {
+ if (this.watcherId) {
+ this.stopLocationWatch();
+ }
+
+ this.watcherId = locationUtil.startLocationWatcher((location) => {
+ this.currentLocation = location;
+ // 可以在这里添加位置信息上报逻辑
+ this.reportLocation(location);
+ }, {
+ interval: this.updateInterval
+ });
+ },
+
+ /**
+ * 停止位置监听
+ */
+ stopLocationWatch() {
+ if (this.watcherId) {
+ locationUtil.stopLocationWatcher();
+ this.watcherId = null;
+ }
+ },
+
+ /**
+ * 重新请求位置权限
+ */
+ async reRequestPermission() {
+ this.hasPermission = await locationUtil.requestLocationPermission();
+ if (this.hasPermission) {
+ await this.updateCurrentLocation();
+ this.startLocationWatch();
+ }
+ return this.hasPermission;
+ },
+
+ /**
+ * 位置信息上报(可根据实际需求实现)
+ * @param {Object} location 位置信息
+ */
+ reportLocation(location) {
+ // 这里可以添加位置信息上报到服务器的逻辑
+ // 例如:api.uploadLocation(location)
+ // console.log('位置上报:', location);
+ },
+
+ /**
+ * 清理位置服务
+ */
+ cleanupLocationService() {
+ this.stopLocationWatch();
+ this.currentLocation = null;
+ }
+ }
+})
+
+export default useLocationStore
diff --git a/uniapps/work-app/src/subPackages/userDetail/infos/index.vue b/uniapps/work-app/src/subPackages/userDetail/infos/index.vue
index 8a43f38..02b3c37 100644
--- a/uniapps/work-app/src/subPackages/userDetail/infos/index.vue
+++ b/uniapps/work-app/src/subPackages/userDetail/infos/index.vue
@@ -25,6 +25,21 @@
<div>{{userInfo.deptName}}</div>
</div>
<div class="orderRow">
+ <div class="rowTitle">性别</div>
+ <div>
+ <u-radio-group v-model="userInfo.sex">
+ <up-radio
+ v-for="(item, index) in sexList"
+ :key="index"
+ :label="item.label"
+ :name="item.name"
+ @change="radioChange"
+ >
+ </up-radio>
+ </u-radio-group>
+ </div>
+ </div>
+ <div class="orderRow">
<div class="rowTitle">手机号</div>
<div>{{userInfo.phone}}</div>
<!-- <u-input input-align="right" v-model="userInfo.phone" type="number" placeholder="请输入手机号"
@@ -33,9 +48,9 @@
</div>
<div class="orderRow">
<div class="rowTitle">邮箱</div>
- <div>{{userInfo.email}}</div>
- <!-- <u-input input-align="right" v-model="userInfo.email" type="email" placeholder="请输入邮箱"
- class="input-item" /> -->
+ <!-- <div>{{userInfo.email}}</div> -->
+ <u-input input-align="right" v-model="userInfo.email" type="email" placeholder="请输入邮箱"
+ class="input-item" />
</div>
</div>
</view>
@@ -61,7 +76,22 @@
phone: '',
email: '',
deptName: '',
+ sex: 2,
});
+ const sexList = [
+ {
+ label: '男',
+ name: '0'
+ },
+ {
+ label: '女',
+ name: '1'
+ },
+ {
+ label: '未知',
+ name: '2'
+ }
+ ]
// 校验手机号
const validatePhone = () => {
const phone = userInfo.value.phone
@@ -103,6 +133,7 @@
phone: user.sysDept.phone,
email: user.sysDept.email,
deptName: user.sysDept.deptName,
+ sex: user.sex || 2,
};
});
diff --git a/uniapps/work-app/src/utils/location.js b/uniapps/work-app/src/utils/location.js
new file mode 100644
index 0000000..5bae85e
--- /dev/null
+++ b/uniapps/work-app/src/utils/location.js
@@ -0,0 +1,260 @@
+/**
+ * 位置管理工具类
+ * 用于处理位置权限请求和实时位置获取
+ */
+import permission from './voiceCallByTX/TrtcCloud/permission.js'
+
+// 平台判断
+const isIos = () => {
+ // #ifdef APP-PLUS
+ return plus.os.name === "iOS";
+ // #endif
+ return false;
+};
+
+// 位置更新回调函数
+let locationUpdateCallback = null;
+// 位置监听器ID
+let locationWatcherId = null;
+
+/**
+ * 请求位置权限
+ * @returns {Promise<boolean>} 是否获取到权限
+ */
+export const requestLocationPermission = async () => {
+ return new Promise(async (resolve) => {
+ // #ifdef APP-PLUS
+ if (isIos()) {
+ // iOS平台
+ const hasPermission = permission.judgeIosPermission('location');
+ if (hasPermission) {
+ resolve(true);
+ } else {
+ // iOS需要提示用户手动开启权限
+ uni.showModal({
+ title: '提示',
+ content: '应用需要获取位置信息权限,请在设置中开启',
+ confirmText: '去设置',
+ cancelText: '取消',
+ success: (res) => {
+ if (res.confirm) {
+ permission.gotoAppPermissionSetting();
+ resolve(false);
+ } else {
+ resolve(false);
+ }
+ }
+ });
+ }
+ } else {
+ // Android平台
+ const result = await permission.requestAndroidPermission('android.permission.ACCESS_FINE_LOCATION');
+ if (result === 1) {
+ resolve(true);
+ } else if (result === 0) {
+ // 拒绝本次申请
+ resolve(false);
+ } else if (result === -1) {
+ // 永久拒绝
+ uni.showModal({
+ title: '提示',
+ content: '应用需要获取位置信息权限,请在设置中开启',
+ confirmText: '去设置',
+ cancelText: '取消',
+ success: (res) => {
+ if (res.confirm) {
+ permission.gotoAppPermissionSetting();
+ resolve(false);
+ } else {
+ resolve(false);
+ }
+ }
+ });
+ }
+ }
+ // #endif
+ // #ifdef H5
+ // H5平台使用浏览器原生API请求权限
+ if (navigator.geolocation) {
+ navigator.permissions.query({ name: 'geolocation' }).then((result) => {
+ if (result.state === 'granted') {
+ resolve(true);
+ } else if (result.state === 'prompt') {
+ // 还未请求过权限,会在getLocation时提示
+ resolve(true);
+ } else {
+ resolve(false);
+ }
+ }).catch(() => {
+ resolve(false);
+ });
+ } else {
+ resolve(false);
+ }
+ // #endif
+ // #ifdef MP
+ // 小程序平台
+ uni.getSetting({
+ success: (res) => {
+ if (res.authSetting['scope.userLocation']) {
+ resolve(true);
+ } else {
+ uni.authorize({
+ scope: 'scope.userLocation',
+ success: () => {
+ resolve(true);
+ },
+ fail: () => {
+ uni.showModal({
+ title: '提示',
+ content: '应用需要获取位置信息权限,请在设置中开启',
+ confirmText: '去设置',
+ cancelText: '取消',
+ success: (res) => {
+ if (res.confirm) {
+ uni.openSetting();
+ resolve(false);
+ } else {
+ resolve(false);
+ }
+ }
+ });
+ }
+ });
+ }
+ }
+ });
+ // #endif
+ });
+};
+
+/**
+ * 获取当前位置信息
+ * @returns {Promise<Object>} 位置信息对象
+ */
+export const getCurrentLocation = () => {
+ return new Promise((resolve, reject) => {
+ uni.getLocation({
+ type: 'gcj02',
+ altitude: true,
+ success: (res) => {
+ resolve({
+ latitude: res.latitude,
+ longitude: res.longitude,
+ altitude: res.altitude,
+ accuracy: res.accuracy,
+ speed: res.speed,
+ verticalAccuracy: res.verticalAccuracy,
+ horizontalAccuracy: res.horizontalAccuracy
+ });
+ },
+ fail: (err) => {
+ console.error('获取位置失败:', err);
+ reject(err);
+ }
+ });
+ });
+};
+
+/**
+ * 开始实时位置监听
+ * @param {Function} callback 位置更新回调函数
+ * @param {Object} options 监听选项
+ * @returns {number} 监听器ID
+ */
+export const startLocationWatcher = (callback, options = {}) => {
+ if (locationWatcherId) {
+ stopLocationWatcher();
+ }
+
+ locationUpdateCallback = callback;
+
+ locationWatcherId = uni.startLocationUpdate({
+ success: () => {
+ console.log('开始位置监听成功');
+ },
+ fail: (err) => {
+ console.error('开始位置监听失败:', err);
+ // 如果是因为权限问题,重新请求权限
+ if (err.errCode === 12002) {
+ requestLocationPermission();
+ }
+ }
+ });
+
+ // 监听位置更新
+ uni.onLocationChange((res) => {
+ const locationInfo = {
+ latitude: res.latitude,
+ longitude: res.longitude,
+ altitude: res.altitude,
+ accuracy: res.accuracy,
+ speed: res.speed,
+ verticalAccuracy: res.verticalAccuracy,
+ horizontalAccuracy: res.horizontalAccuracy,
+ timestamp: res.timestamp
+ };
+
+ if (locationUpdateCallback) {
+ locationUpdateCallback(locationInfo);
+ }
+ });
+
+ return locationWatcherId;
+};
+
+/**
+ * 停止位置监听
+ */
+export const stopLocationWatcher = () => {
+ if (locationWatcherId) {
+ uni.stopLocationUpdate({
+ success: () => {
+ console.log('停止位置监听成功');
+ },
+ fail: (err) => {
+ console.error('停止位置监听失败:', err);
+ }
+ });
+ locationWatcherId = null;
+ }
+
+ // 移除位置更新监听
+ uni.offLocationChange();
+ locationUpdateCallback = null;
+};
+
+/**
+ * 检查系统定位服务是否开启
+ * @returns {Promise<boolean>} 是否开启
+ */
+export const checkSystemLocationEnabled = async () => {
+ return new Promise((resolve) => {
+ // #ifdef APP-PLUS
+ const enabled = permission.checkSystemEnableLocation();
+ resolve(enabled);
+ // #endif
+ // #ifdef H5
+ resolve(navigator.geolocation ? true : false);
+ // #endif
+ // #ifdef MP
+ uni.getSystemInfo({
+ success: (res) => {
+ // 小程序无法直接检查系统定位服务是否开启
+ resolve(true);
+ },
+ fail: () => {
+ resolve(false);
+ }
+ });
+ // #endif
+ });
+};
+
+export default {
+ requestLocationPermission,
+ getCurrentLocation,
+ startLocationWatcher,
+ stopLocationWatcher,
+ checkSystemLocationEnabled
+};
diff --git a/uniapps/work-app/src/utils/websocket.js b/uniapps/work-app/src/utils/websocket.js
index 32379d1..12f583c 100644
--- a/uniapps/work-app/src/utils/websocket.js
+++ b/uniapps/work-app/src/utils/websocket.js
@@ -1,4 +1,4 @@
-// WebSocket服务管理
+import { useGlobalWS } from "@/hooks/useGlobalWS.js";// WebSocket服务管理
class WebSocketService {
constructor() {
this.socketTask = null
@@ -34,10 +34,10 @@
this.socketTask = uni.connectSocket({
url: this.url,
success: () => {
- console.log('WebSocket连接已请求')
+ // console.log('WebSocket连接已请求')
},
fail: (error) => {
- console.error('WebSocket连接请求失败:', error)
+ // console.error('WebSocket连接请求失败:', error)
if (this.onErrorCallback) {
this.onErrorCallback(error)
}
@@ -47,7 +47,7 @@
// 监听连接打开
this.socketTask.onOpen(() => {
this.connected = true
- console.log('WebSocket已连接,userId:', this.userId)
+ // console.log('WebSocket已连接,userId:', this.userId)
this.startPing()
if (this.onOpenCallback) {
this.onOpenCallback()
@@ -57,7 +57,7 @@
// 监听连接关闭
this.socketTask.onClose(() => {
this.connected = false
- console.log('WebSocket已关闭')
+ // console.log('WebSocket已关闭')
this.stopPing()
if (this.onCloseCallback) {
this.onCloseCallback()
@@ -66,7 +66,7 @@
// 监听连接错误
this.socketTask.onError((error) => {
- console.error('WebSocket错误:', error)
+ // console.error('WebSocket错误:', error)
this.connected = false
this.stopPing()
if (this.onErrorCallback) {
@@ -78,16 +78,16 @@
this.socketTask.onMessage((res) => {
try {
const message = JSON.parse(res.data)
- console.log('收到WebSocket消息:', message)
+ // console.log('收到WebSocket消息:', message)
if (this.onMessageCallback) {
this.onMessageCallback(message)
}
} catch (error) {
- console.error('解析WebSocket消息失败:', error)
+ // console.error('解析WebSocket消息失败:', error)
}
})
} catch (error) {
- console.error('WebSocket连接失败:', error)
+ // console.error('WebSocket连接失败:', error)
if (this.onErrorCallback) {
this.onErrorCallback(error)
}
@@ -112,10 +112,11 @@
this.socketTask.send({
data: JSON.stringify(message),
success: () => {
- console.log('WebSocket消息发送成功:', message)
+ // console.log('WebSocket消息发送成功:', message)
+ useGlobalWS();
},
fail: (error) => {
- console.error('WebSocket消息发送失败:', error)
+ // console.error('WebSocket消息发送失败:', error)
}
})
}
@@ -146,10 +147,10 @@
code: 1000,
reason: '正常关闭',
success: () => {
- console.log('WebSocket已关闭')
+ // console.log('WebSocket已关闭')
},
fail: (error) => {
- console.error('WebSocket关闭失败:', error)
+ // console.error('WebSocket关闭失败:', error)
}
})
this.socketTask = null
@@ -160,10 +161,9 @@
// 设置消息回调
setOnMessageCallback(callback) {
- console.log('🔔 WebSocket消息回调已设置')
this.onMessageCallback = callback
}
-
+
// 获取当前消息回调(用于检查是否已设置)
getOnMessageCallback() {
return this.onMessageCallback
diff --git a/uniapps/work-wx/src/subPackages/userDetail/infos/index.vue b/uniapps/work-wx/src/subPackages/userDetail/infos/index.vue
index 4dbbbb6..a9c2007 100644
--- a/uniapps/work-wx/src/subPackages/userDetail/infos/index.vue
+++ b/uniapps/work-wx/src/subPackages/userDetail/infos/index.vue
@@ -8,16 +8,27 @@
<view class="detailBox">
<div class="detailCon">
<div class="orderRow">
- <div class="rowTitle">姓名</div>
+ <div class="rowTitle">昵称</div>
<div>{{userInfo.nickName}}</div>
</div>
- <!-- <div class="orderRow">
- <div class="rowTitle">所属单位</div>
- <div>{{userInfo.deptName}}</div>
- </div> -->
<div class="orderRow">
<div class="rowTitle">认证状态</div>
<div>{{userInfo.status === 1 ? '已认证' : '未认证'}}</div>
+ </div>
+ <div class="orderRow">
+ <div class="rowTitle">性别</div>
+ <div>
+ <u-radio-group v-model="userInfo.sex">
+ <up-radio
+ v-for="(item, index) in sexList"
+ :key="index"
+ :label="item.label"
+ :name="item.name"
+ @change="radioChange"
+ >
+ </up-radio>
+ </u-radio-group>
+ </div>
</div>
<div class="orderRow">
<div class="rowTitle">手机号</div>
@@ -41,6 +52,7 @@
</template>
<script setup>
+ import { uploadFileApi } from '@/api/index'
import showDefaultHeader from "@/static/images/user/default-header.png";
import {
getEnvObj,
@@ -62,7 +74,22 @@
phone: '',
email: '',
deptName: '',
+ sex: 2,
});
+ const sexList = [
+ {
+ label: '男',
+ name: '0'
+ },
+ {
+ label: '女',
+ name: '1'
+ },
+ {
+ label: '未知',
+ name: '2'
+ }
+ ]
// 校验手机号
const validatePhone = () => {
const phone = userInfo.value.phone
@@ -97,15 +124,14 @@
const getUserInfoData = () => {
getUserInfo().then(res => {
const user = res.data.data;
- console.log('user',user)
userInfo.value = {
id: user.userId,
avatar: user.avatar,
nickName: user.nickName,
- // realName: user.realName,
phone: user.phonenumber,
email: user.sysDept.email,
deptName: user.sysDept.deptName,
+ sex: user.sex || 2,
};
});
@@ -113,45 +139,47 @@
const reset = () => {
getUserInfoData();
};
-
- const {
- VITE_API_BASE_URL
- } = getEnvObj()
-
- function uploadUtil(options) {
- const {
- formData,
- filePath,
- url
- } = options;
-
- return new Promise((resolve, reject) => {
- let accessToken = useUserStore()?.$state?.userInfo?.access_token;
-
- uni.uploadFile({
- url: `${VITE_API_BASE_URL}${url}`,
- name: 'file',
- header: {
- 'Blade-Auth': 'bearer ' + accessToken
- },
- filePath: filePath,
- formData,
- success: (res) => {
- const resData = JSON.parse(res.data)
- if (resData.code === 200 || resData.code === 0) {
- resolve(res)
- } else {
- showToast(resData.message)
-
- reject(res)
- }
- },
- fail: (err) => {
- reject(err)
- }
- });
- })
- }
+ // 提交文件
+function afterReadFile(event) {
+ console.log('上传的文件:', event);
+
+ // 准备上传参数
+ const uploadParams = {
+ name: event.name, // 服务器端接收文件的字段名
+ file: event.file, // 传入文件对象
+ filePath: event.filePath, // 文件路径
+ };
+
+ // 调用上传文件接口
+ uploadFileApi(uploadParams).then(res => {
+ uni.hideLoading();
+
+ console.log('上传成功结果:', res);
+
+ // 根据接口返回的数据结构处理结果
+ if (res.data && res.data.code === 200) {
+ const uploadResult = res.data.data;
+ userInfo.value.avatar = uploadResult.fileUrl || '文件上传成功';
+
+ uni.showToast({
+ title: '上传成功',
+ icon: 'success'
+ });
+ } else {
+ uni.showToast({
+ title: res.msg || '上传失败',
+ icon: 'none'
+ });
+ }
+ }).catch(err => {
+ uni.hideLoading();
+ console.error('上传失败:', err);
+ uni.showToast({
+ title: '上传失败',
+ icon: 'none'
+ });
+ });
+}
const uploadAvatar = () => {
uni.chooseImage({
count: 1,
@@ -176,35 +204,11 @@
title: '上传中...'
});
- // 上传文件
- uploadUtil({
- filePath: filePath,
- formData: {
- fileName: fileName,
- sn: 'avatar_upload'
- },
- url: '/blade-resource/oss/endpoint/put-file'
- }).then(res => {
- const resData = JSON.parse(res.data);
- if (resData.code === 200 || resData.code === 0) {
- // 更新头像显示
- userInfo.value.avatar = resData.data.link || resData.data.url;
- uni.hideLoading();
- uni.showToast({
- title: '头像上传成功',
- icon: 'success'
- });
- } else {
- throw new Error(resData.message || '上传失败');
-
- }
- }).catch(err => {
- uni.hideLoading();
- uni.showToast({
- title: err.message || '上传失败',
- icon: 'none'
- });
- });
+ afterReadFile({
+ file: tempFile,
+ filePath: filePath,
+ name: fileName,
+ })
}
});
}
@@ -329,7 +333,7 @@
}
.note {
position: absolute;
- bottom: 400rpx;
+ bottom: 300rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 10px;
--
Gitblit v1.9.3