合并
2
.env
@ -1,5 +1,5 @@
|
||||
# 标题
|
||||
VITE_APP_TITLE=芋道管理系统
|
||||
VITE_APP_TITLE=RCS智能设备调度系统
|
||||
|
||||
# 项目本地运行端口号
|
||||
VITE_PORT=80
|
||||
|
6
.env.dev
@ -4,7 +4,9 @@ NODE_ENV=production
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
|
||||
# VITE_BASE_URL='http://192.168.0.66:48080'
|
||||
# VITE_BASE_URL='http://192.168.0.189:48080'
|
||||
VITE_BASE_URL='http://10.10.5.5:48080'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||
VITE_UPLOAD_TYPE=server
|
||||
@ -31,7 +33,7 @@ VITE_OUT_DIR=dist
|
||||
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
|
||||
|
||||
# 验证码的开关
|
||||
VITE_APP_CAPTCHA_ENABLE=true
|
||||
VITE_APP_CAPTCHA_ENABLE=false
|
||||
|
||||
# GoView域名
|
||||
VITE_GOVIEW_URL='http://127.0.0.1:3000'
|
@ -4,7 +4,9 @@ NODE_ENV=development
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://localhost:48080'
|
||||
# VITE_BASE_URL='http://192.168.77.50:48080'
|
||||
# VITE_BASE_URL='http://10.10.100.32:48080'
|
||||
VITE_BASE_URL='http://10.10.5.5:48080'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||
VITE_UPLOAD_TYPE=server
|
||||
|
9
.vscode/settings.json
vendored
@ -62,16 +62,16 @@
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[html]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[css]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[less]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
@ -141,5 +141,6 @@
|
||||
"package.json": "pnpm-lock.yaml,yarn.lock,LICENSE,README*,CHANGELOG*,CNAME,.gitattributes,.eslintrc-auto-import.json,.gitignore,prettier.config.js,stylelint.config.js,commitlint.config.js,.stylelintignore,.prettierignore,.gitpod.yml,.eslintrc.js,.eslintignore"
|
||||
},
|
||||
"terminal.integrated.scrollback": 10000,
|
||||
"nuxt.isNuxtApp": false
|
||||
"nuxt.isNuxtApp": false,
|
||||
"liveServer.settings.port": 5502
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
@ -136,7 +136,7 @@
|
||||
<div class="app-loading">
|
||||
<div class="app-loading-wrap">
|
||||
<div class="app-loading-title">
|
||||
<img src="/logo.gif" class="app-loading-logo" alt="Logo" />
|
||||
<!-- <img src="/logo.gif" class="app-loading-logo" alt="Logo" /> -->
|
||||
<div class="app-loading-title">%VITE_APP_TITLE%</div>
|
||||
</div>
|
||||
<div class="app-loading-item">
|
||||
|
31850
package-lock.json
generated
Normal file
@ -28,6 +28,7 @@
|
||||
"@element-plus/icons-vue": "^2.1.0",
|
||||
"@form-create/designer": "^3.2.6",
|
||||
"@form-create/element-ui": "^3.2.11",
|
||||
"@gausszhou/vue3-drag-resize-rotate": "^3.0.2",
|
||||
"@iconify/iconify": "^3.1.1",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"@videojs-player/vue": "^1.0.0",
|
||||
@ -51,6 +52,7 @@
|
||||
"fast-xml-parser": "^4.3.2",
|
||||
"highlight.js": "^11.9.0",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"json-bigint": "^1.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markmap-common": "^0.16.0",
|
||||
@ -66,9 +68,11 @@
|
||||
"qs": "^6.12.0",
|
||||
"sortablejs": "^1.15.3",
|
||||
"steady-xml": "^0.1.0",
|
||||
"swiper": "^8.4.7",
|
||||
"url": "^0.11.3",
|
||||
"video.js": "^7.21.5",
|
||||
"vue": "3.5.12",
|
||||
"vue-awesome-swiper": "^5.0.1",
|
||||
"vue-dompurify-html": "^4.1.4",
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-router": "4.4.5",
|
||||
|
11
src/App.vue
@ -22,7 +22,7 @@ const setDefaultTheme = () => {
|
||||
}
|
||||
appStore.setIsDark(isDarkTheme)
|
||||
}
|
||||
setDefaultTheme()
|
||||
// setDefaultTheme()
|
||||
</script>
|
||||
<template>
|
||||
<ConfigGlobal :size="currentSize">
|
||||
@ -54,4 +54,13 @@ body {
|
||||
.#{$prefix-cls}-grey-mode {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
.indexpage-custom-message-style {
|
||||
// padding: 0 !important;
|
||||
background: #c60606;
|
||||
border: none;
|
||||
padding: 9px 20px !important;
|
||||
.el-message-icon--info {
|
||||
color: #ffffff !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
8
src/api/boardCharts/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
|
||||
|
||||
//获取整体看板信息
|
||||
export const bulletinBoardGet = async (params) => {
|
||||
return await request.get({ url: `/system/bulletinBoard/get`, params })
|
||||
}
|
72
src/api/car/index.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//agv 下载
|
||||
export const agvDownload = async (params) => {
|
||||
return await request.download({ url: `/system/position-map/agvDownload`, params })
|
||||
}
|
||||
//点位地图列表
|
||||
export const getPositionMapList = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/list`, params })
|
||||
}
|
||||
|
||||
//删除车辆信息
|
||||
export const deleteRobotInformation = async (id: number) => {
|
||||
return await request.delete({ url: `/system/robot/information/delete?id=` + id })
|
||||
}
|
||||
|
||||
//查询所有车辆
|
||||
export const getAllRobot = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/getAllRobot`, data })
|
||||
}
|
||||
//获得车辆信息 详情
|
||||
export const getRobotInformation = async (params) => {
|
||||
return await request.get({ url: `/system/robot/information/get`, params })
|
||||
}
|
||||
|
||||
//分页查询车辆列表 看板信息车辆目前用的是这个
|
||||
export const robotInformationPage = async (params) => {
|
||||
return await request.get({ url: `/system/robot/information/page`, params })
|
||||
}
|
||||
//统计车辆待命-任务中-离线
|
||||
export const robotInformationStatistics = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/statistics`, data })
|
||||
}
|
||||
|
||||
// 创建车辆信息
|
||||
export const robotInformationCreate = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/create`, data })
|
||||
}
|
||||
// 编辑车辆信息
|
||||
export const robotInformationUpdate = async (data) => {
|
||||
return await request.put({ url: `/system/robot/information/update`, data })
|
||||
}
|
||||
//分页查询车辆列表 看板信息车辆目前用的是这个
|
||||
export const robotGetAllModel = async (params) => {
|
||||
return await request.get({ url: `/system/robot/model/getAllModel`, params })
|
||||
}
|
||||
// 范围选择
|
||||
export const robotPositionGetMap = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/getMap`, params })
|
||||
}
|
||||
// 完整范围选择
|
||||
export const robotPositionGetMapAll = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/getAllMap`, params })
|
||||
}
|
||||
// 完整范围选择 修改成这个了 车辆那边
|
||||
export const robotPositionGetMapAllNew = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/getMap`, params })
|
||||
}
|
||||
|
||||
//获得车辆列表 新
|
||||
export const getRobotInformationList = async (params) => {
|
||||
return await request.get({ url: `/system/robot/information/list`, params })
|
||||
}
|
||||
|
||||
// 清除交管
|
||||
export const cleanTrafficManagement = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/cleanTrafficManagement?robotNo=${data.robotNo}`, data })
|
||||
}
|
||||
// 恢复任务
|
||||
export const doTaskContinue = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/doTaskContinue?robotNo=${data.robotNo}`, data })
|
||||
}
|
17
src/api/carError/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
|
||||
//获得机器人告警信息分页
|
||||
export const getRobotWarnMsgPage = async (params) => {
|
||||
return await request.get({ url: `/system/robot/warn-msg/page`, params })
|
||||
}
|
||||
|
||||
//更新已读状态
|
||||
export const robotWarnMsgUpdate= async (data) => {
|
||||
return await request.put({ url: `/system/robot/warn-msg/update`, data })
|
||||
}
|
||||
|
||||
//更新已读状态 全部已读
|
||||
export const robotWarnMsgUpdateAll= async (data) => {
|
||||
return await request.post({ url: `/system/robot/warn-msg/allRead`, data })
|
||||
}
|
43
src/api/device/index.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
|
||||
|
||||
//分页查询设备列表 看板信息设备目前用的是这个
|
||||
export const deviceInformationPage = async (params) => {
|
||||
return await request.get({ url: `/system/device/information/page`, params })
|
||||
}
|
||||
//统计车辆待命-任务中-离线
|
||||
export const robotInformationStatistics = async (data) => {
|
||||
return await request.post({ url: `/system/robot/information/statistics`, data })
|
||||
}
|
||||
|
||||
// 创建设备信息
|
||||
export const deviceInformationCreate = async (data) => {
|
||||
return await request.post({ url: `/system/device/information/create`, data })
|
||||
}
|
||||
// 编辑设备信息
|
||||
export const deviceInformationUpdate = async (data) => {
|
||||
return await request.put({ url: `/system/device/information/update`, data })
|
||||
}
|
||||
// 地图绑定设备
|
||||
export const deviceInformationGet = async (params) => {
|
||||
return await request.get({ url: `/system/device/information/get`, params })
|
||||
}
|
||||
|
||||
//删除设备信息
|
||||
export const deleteDeviceInformation = async (id: number) => {
|
||||
return await request.delete({ url: `/system/device/information/delete?id=` + id })
|
||||
}
|
||||
// 获取设备列表
|
||||
export const deviceNumber = async (params) => {
|
||||
return await request.get({ url: `/system/device/information/deviceNumber`, params })
|
||||
}
|
||||
|
||||
// 获取设备列表 新不分页
|
||||
export const deviceGetInformationList = async (params) => {
|
||||
return await request.get({ url: `/system/device/information/getInformationList`, params })
|
||||
}
|
||||
// 获取设备列表
|
||||
export const getMapDeviceImageUrl = async (params) => {
|
||||
return await request.get({ url: `/system/device/information/getMapImageUrl`, params })
|
||||
}
|
16
src/api/map/binLocation.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//获得获得库位
|
||||
export const getHouseLocation = async (id: number) => {
|
||||
return await request.get({ url: `/system/ware/house-location/get?id=` + id })
|
||||
}
|
||||
|
||||
// 更新库位
|
||||
export const updateHouseLocation = (data) => {
|
||||
return request.put({ url: '/system/ware/house-location/update', data })
|
||||
}
|
||||
|
||||
//获得库位分页
|
||||
export const getHouseLocationPage = async (data) => {
|
||||
return await request.post({ url: `/system/ware/house-location/page`, data })
|
||||
}
|
16
src/api/map/logList.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//任务日志分页
|
||||
export const getRobotTaskPage = async (data) => {
|
||||
return await request.post({ url: `/system/robot/task/logPage`, data })
|
||||
}
|
||||
|
||||
//获得车辆动作记录分页
|
||||
export const getTaskDetailPage = async (params) => {
|
||||
return await request.get({ url: `/system/robot/task-detail-action-log/page`, params })
|
||||
}
|
||||
|
||||
//用户操作记录
|
||||
export const getUserOperationLogPage = async (params) => {
|
||||
return await request.get({ url: `/system/log/user-operation-log/page`, params })
|
||||
}
|
250
src/api/map/map.ts
Normal file
@ -0,0 +1,250 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//agv 下载
|
||||
export const agvDownload = async (params) => {
|
||||
return await request.download({ url: `/system/position-map/agvDownload`, params })
|
||||
}
|
||||
//点位地图列表
|
||||
export const getPositionMapList = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/list`, params })
|
||||
}
|
||||
//点位地图列表 map分好组
|
||||
export const getPositionMapGetMap = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/getMap`, params })
|
||||
}
|
||||
//点位地图列表 详细数据
|
||||
export const getPositionMapDownloadPng = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/downloadPng`, params })
|
||||
}
|
||||
//点位地图 base64
|
||||
export const getPositionMapdDwnloadPngBase64 = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/downloadPngBase64`, params })
|
||||
}
|
||||
//删除仓库点位地图
|
||||
export const deletePositionMap = async (id: number) => {
|
||||
return await request.delete({ url: `/system/position-map/delete?id=` + id })
|
||||
}
|
||||
//下载文件
|
||||
export const downloadPositionMap = async (params) => {
|
||||
return await request.get({ url: `/system/position-map/download`, params })
|
||||
}
|
||||
//获得仓库点位地图
|
||||
export const getPositionMap = async (id) => {
|
||||
return await request.get({ url: `/system/position-map/get?id=` + id })
|
||||
}
|
||||
// 文件上传
|
||||
export const uploadPositionMap = async (data) => {
|
||||
return await request.post({ url: `/system/position-map/upload`, data })
|
||||
}
|
||||
//创建编辑仓库点位地图连线
|
||||
export const createOrEditPositionMapLine = async (data) => {
|
||||
return await request.post({ url: `/system/position-map-line/createOrEdit`, data })
|
||||
}
|
||||
//删除仓库点位地图连线
|
||||
export const deletePositionMapLine = async (data) => {
|
||||
return await request.delete({ url: `/system/position-map-line/delete`, data })
|
||||
}
|
||||
//获得仓库点位地图连线
|
||||
export const getPositionMapLine = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-line/get`, params })
|
||||
}
|
||||
//通过地图id获取连线列表
|
||||
export const getPositionMapLineList = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-line/list`, params })
|
||||
}
|
||||
//批量新增编辑删除节点
|
||||
export const batchSaveOrEditOrDelMapItem = async (positionMapId, data) => {
|
||||
return await request.post({
|
||||
url: `/system/position-map-item/batchSaveOrEditOrDel?positionMapId=${positionMapId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
//导出仓库点位地图子表 Excel
|
||||
export const exportPositionMapItemExcel = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-item/export-excel`, params })
|
||||
}
|
||||
//获得仓库点位地图子表
|
||||
export const getPositionMapItem = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-item/get`, params })
|
||||
}
|
||||
//获取仓库点位地图节点列表
|
||||
export const getPositionMapItemList = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-item/list`, params })
|
||||
}
|
||||
//获得设备信息列表
|
||||
export const getDeviceInformationList = async (params) => {
|
||||
return await request.get({ url: `/system/device/information/list`, params })
|
||||
}
|
||||
//地图绑定设备
|
||||
export const mapBindDeviceInfo = async (data) => {
|
||||
return await request.post({ url: `/system/device/information/mapBindDeviceInfo`, data })
|
||||
}
|
||||
//创建修改删除库区
|
||||
export const createOrEditOrDelHouseArea = async (data) => {
|
||||
return await request.post({ url: `/system/ware/house-area/createOrEditOrDel`, data })
|
||||
}
|
||||
//创建修改删除线库
|
||||
export const createOrEditOrDelHouseLane = async (data) => {
|
||||
return await request.post({ url: `/system/ware/house-lane/createOrEditOrDel`, data })
|
||||
}
|
||||
//根据点位获取库位信息列表
|
||||
export const houseLocationGetByMapItemId = async (params) => {
|
||||
return await request.get({ url: `/system/ware/house-location/getByMapItemId`, params })
|
||||
}
|
||||
// 更新库位
|
||||
export const updateHouseLocation = async (data) => {
|
||||
return await request.put({ url: `/system/ware/house-location/update`, data })
|
||||
}
|
||||
//创建编辑删除仓库点位地图连线
|
||||
export const createOrEditOrDelPositionMapLine = async (positionMapId, data) => {
|
||||
return await request.post({
|
||||
url: `/system/position-map-line/createOrEditOrDel?positionMapId=${positionMapId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
// 获得仓库点位地图连线
|
||||
export const getPositionMapLineById = async (id: number) => {
|
||||
return await request.get({ url: `/system/position-map-line/get?id=` + id })
|
||||
}
|
||||
// 通过地图id获取连线列表
|
||||
export const getPositionMapLineByPositionMapId = async (positionMapId: number) => {
|
||||
return await request.get({ url: `/system/position-map-line/list?positionMapId=` + positionMapId })
|
||||
}
|
||||
|
||||
//获取仓库点位地图节点列表
|
||||
export const getWareHouseAreaPage = async (params) => {
|
||||
return await request.get({ url: `/system/ware/house-area/page`, params })
|
||||
}
|
||||
//删除仓库点位地图
|
||||
export const deleteWareHouseArea = async (id: number) => {
|
||||
return await request.delete({ url: `/system/ware/house-area/delete?id=` + id })
|
||||
}
|
||||
//获得线库分页
|
||||
export const getWareHouseLanePage = async (params) => {
|
||||
return await request.get({ url: `/system/ware/house-lane/page`, params })
|
||||
}
|
||||
//删除仓库点位地图
|
||||
export const deleteWareLaneArea = async (id: number) => {
|
||||
return await request.delete({ url: `/system/ware/house-lane/delete?id=` + id })
|
||||
}
|
||||
// 获取仓库点位连线
|
||||
export const mapLineGet = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-line/get`, params })
|
||||
}
|
||||
|
||||
//通过地图id获取连线列表
|
||||
export const mapLineListGet = async (params) => {
|
||||
return await request.get({ url: `/system/position-map-line/list`, params })
|
||||
}
|
||||
|
||||
// 获得车辆信息分页
|
||||
export const getRobotInformationPage = async (params) => {
|
||||
return await request.get({ url: `/system/robot/information/page`, params })
|
||||
}
|
||||
|
||||
//获取AGV点位信息
|
||||
export const getAGVPointInformation = async (macAddress) => {
|
||||
return await request.get({
|
||||
url: `/system/position-map-item/getAGVPointInformation?macAddress=` + macAddress
|
||||
})
|
||||
}
|
||||
//根据地图id获取车辆列表
|
||||
export const getListByMapId = async (mapId) => {
|
||||
return await request.get({
|
||||
url: `/system/robot/information/getListByMapId?mapId=` + mapId
|
||||
})
|
||||
}
|
||||
//批量更新库位
|
||||
export const updateBatchHouseLocation = async (data) => {
|
||||
return await request.put({
|
||||
url: `/system/ware/house-location/updateBatch`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取楼层区域对应的机器人编号
|
||||
export const getRobotByFloorAndArea = async (params) => {
|
||||
return await request.post({ url: `/system/robot/information/getRobotByFloorAndArea`, params })
|
||||
}
|
||||
|
||||
//根据点位获取库位信息列表
|
||||
export const getByMapItemId = async (mapId, mapItemId) => {
|
||||
return await request.get({
|
||||
url: `/system/ware/house-location/getByMapItemId?mapItemId=${mapItemId}&mapId=${mapId}`
|
||||
})
|
||||
}
|
||||
|
||||
//线上加点保存点位
|
||||
export const lineAddItem = async (data) => {
|
||||
return await request.post({
|
||||
url: `/system/position-map-item/lineAddItem`,
|
||||
data
|
||||
})
|
||||
}
|
||||
//获取id
|
||||
export const getNodeId = async () => {
|
||||
return await request.get({
|
||||
url: `/system/position-map-item/getUUid`
|
||||
})
|
||||
}
|
||||
//一键急停or一键恢复地图上所有AGV
|
||||
export const emergencyStopOrRecovery = async (params) => {
|
||||
return await request.get({
|
||||
url: `/system/position-map/emergencyStopOrRecovery`,
|
||||
params
|
||||
})
|
||||
}
|
||||
// 根据地图id获取暂停的地图
|
||||
export const getMapIsStop = async (params) => {
|
||||
return await request.get({
|
||||
url: `/system/robot/map-stop/getByMapId`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
//创建区域变更点绑定
|
||||
export const bindingPositionChangePoint = async (data) => {
|
||||
return await request.post({
|
||||
url: `/system/position-change-point-binding/create`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//根据点位id,查询此点位已经绑定的转换点信息
|
||||
export const getPositionChangePoint = async (params) => {
|
||||
return await request.get({
|
||||
url: `/system/position-change-point-binding/get`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
//更新区域变更点绑定
|
||||
export const updatePositionChangePoint = async (data) => {
|
||||
return await request.put({
|
||||
url: `/system/position-change-point-binding/update`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//根据排序查询点位信息
|
||||
export const getPositionChangePointBySortNum = async (params) => {
|
||||
return await request.get({
|
||||
url: `/system/position-change-point-binding/getItemBySortNum`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
//删除区域变更点绑定
|
||||
export const deletePositionChangePoint = async (data) => {
|
||||
return await request.delete({
|
||||
url: `/system/position-change-point-binding/delete`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export const checkHaveTask = async (data) => {
|
||||
return await request.post({
|
||||
url: `/system/robot/task/checkHaveTask`,
|
||||
data
|
||||
})
|
||||
}
|
46
src/api/map/mapTask.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//获取取货位置
|
||||
export const getLocationByName = (data) => {
|
||||
return request.post({ url: '/system/ware/house-location/getLocationByName', data })
|
||||
}
|
||||
|
||||
//获得任务号
|
||||
export const getTaskNo = async (id: number) => {
|
||||
return await request.get({ url: `/system/robot/task/getTaskNo?id=` + id })
|
||||
}
|
||||
|
||||
// 查询能正常使用的车辆
|
||||
export const getCanUseRobot = () => {
|
||||
return request.post({ url: '/system/robot/information/getAllRobot' })
|
||||
}
|
||||
|
||||
// 创建机器人任务主表
|
||||
export const createTask = (data) => {
|
||||
return request.post({ url: '/system/robot/task/create', data })
|
||||
}
|
||||
|
||||
// 删除机器人任务主表
|
||||
export const deleteTask = (id: number) => {
|
||||
return request.delete({ url: '/system/robot/task/delete?id=' + id })
|
||||
}
|
||||
|
||||
// 更新机器人任务主表
|
||||
export const updateTask = (data) => {
|
||||
return request.post({ url: '/system/robot/task-detail/manuallyCompleted?id=' + data.id })
|
||||
}
|
||||
|
||||
// 更新机器人任务主表
|
||||
export const closeTask = (data) => {
|
||||
return request.put({ url: '/system/robot/task/close', data })
|
||||
}
|
||||
|
||||
//更新优先级
|
||||
export const updateRobotTask = (data) => {
|
||||
return request.put({ url: '/system/robot/task/update', data })
|
||||
}
|
||||
|
||||
//获得机器人任务主表分页
|
||||
export const getTaskPageList = async (data) => {
|
||||
return await request.post({ url: `/system/robot/task/page`, data })
|
||||
}
|
21
src/api/map/statistics.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
//统计车辆状态分类
|
||||
export const robotStatusClassification = async (params) => {
|
||||
return await request.get({ url: `/system/statistics/robotStatusClassification`, params })
|
||||
}
|
||||
|
||||
//统计任务人工完成-自动完成
|
||||
export const robotTaskAutomaticArtificial = async (params) => {
|
||||
return await request.get({ url: `/system/statistics/robotTaskAutomaticArtificial`, params })
|
||||
}
|
||||
|
||||
//统计故障根因分析
|
||||
export const robotWarnMsgClassification = async (params) => {
|
||||
return await request.get({ url: `/system/statistics/robotWarnMsgClassification`, params })
|
||||
}
|
||||
|
||||
//车辆工作时长统计
|
||||
export const robotWorkHourStatistics = async (params) => {
|
||||
return await request.get({ url: `/system/statistics/robotWorkHourStatistics`, params })
|
||||
}
|
21
src/api/parameterSetting/index.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
|
||||
//获得通用配置分页 固定参数 configType 1
|
||||
export const getCommonConfig = async (params) => {
|
||||
return await request.get({ url: `/system/common/config/get`, params })
|
||||
}
|
||||
|
||||
//更新通用配置 固定参数 configType 1
|
||||
export const updateCommonConfig = async (data) => {
|
||||
return await request.put({ url: `/system/common/config/update`, data })
|
||||
}
|
||||
|
||||
//创建通用配置 固定参数 configType 1
|
||||
export const createCommonConfig = async (data) => {
|
||||
return await request.post({ url: `/system/common/config/create`, data })
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -47,3 +47,9 @@ export const getUnreadNotifyMessageList = async () => {
|
||||
export const getUnreadNotifyMessageCount = async () => {
|
||||
return await request.get({ url: '/system/notify-message/get-unread-count' })
|
||||
}
|
||||
|
||||
// 获得当前用户的未读站内信数量 车辆异常
|
||||
export const warnMsgReadPage = async () => {
|
||||
return await request.get({ url: '/system/robot/warn-msg/readPage ' })
|
||||
}
|
||||
|
||||
|
BIN
src/assets/imgs/allBoard/dianlianggreen.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
src/assets/imgs/allBoard/dianliangred.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
src/assets/imgs/allBoard/dianliangyellow.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
src/assets/imgs/chache.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/imgs/gaojing.png
Normal file
After Width: | Height: | Size: 649 B |
BIN
src/assets/imgs/gaojing1.png
Normal file
After Width: | Height: | Size: 655 B |
BIN
src/assets/imgs/gaojing2.png
Normal file
After Width: | Height: | Size: 652 B |
BIN
src/assets/imgs/gaojing3.png
Normal file
After Width: | Height: | Size: 650 B |
BIN
src/assets/imgs/indexPage/chache-4@2x(1).png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 2@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 3@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 4@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 5@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 6@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 7@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 8@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 9@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chongdianzhuang_ceshi@2x.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/imgs/indexPage/shusongxian-youhuo@2x.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/imgs/indexPage/shusongxian@2x.png
Normal file
After Width: | Height: | Size: 727 B |
BIN
src/assets/imgs/indexPage/tuopan备份 18@2x.png
Normal file
After Width: | Height: | Size: 767 B |
BIN
src/assets/imgs/indexPage/tuopan备份 62@2x.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
src/assets/imgs/indexPage/编组 12.png
Normal file
After Width: | Height: | Size: 855 B |
BIN
src/assets/imgs/indexPage/编组 12@2x.png
Normal file
After Width: | Height: | Size: 860 B |
BIN
src/assets/imgs/indexPage/编组 13@2x.png
Normal file
After Width: | Height: | Size: 551 B |
BIN
src/assets/imgs/indexPage/编组 14.png
Normal file
After Width: | Height: | Size: 856 B |
BIN
src/assets/imgs/indexPage/编组 15.png
Normal file
After Width: | Height: | Size: 794 B |
BIN
src/assets/imgs/indexPage/编组 15@2x(1).png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
src/assets/imgs/indexPage/编组 15@2x.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份 2@2x.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份 3@2x.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份 4@2x.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份@2x.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/imgs/indexPage/编组 18@2x.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/imgs/indexPage/编组 22.png
Normal file
After Width: | Height: | Size: 666 B |
BIN
src/assets/imgs/indexPage/编组 24@2x.png
Normal file
After Width: | Height: | Size: 443 B |
BIN
src/assets/imgs/indexPage/编组 2@2x.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
src/assets/imgs/indexPage/编组 3@2x.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
src/assets/imgs/indexPage/编组 4@2x.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/imgs/indexPage/编组 6@2x.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/imgs/indexPage/编组 7@2x.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/imgs/indexPage/编组 8@2x.png
Normal file
After Width: | Height: | Size: 481 B |
BIN
src/assets/imgs/indexPage/编组 9@2x.png
Normal file
After Width: | Height: | Size: 859 B |
BIN
src/assets/imgs/indexPage/编组@2x.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
src/assets/imgs/map.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
src/assets/login-bg.png
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
src/assets/search.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
@ -11,7 +11,7 @@ const prefixCls = getPrefixCls('content-wrap')
|
||||
defineProps({
|
||||
title: propTypes.string.def(''),
|
||||
message: propTypes.string.def(''),
|
||||
bodyStyle: propTypes.object.def({ padding: '10px' })
|
||||
bodyStyle: propTypes.object.def({ padding: '16px' })
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
</el-select>
|
||||
</ElDialog>
|
||||
<div v-else class="custom-hover" @click.stop="showTopSearch = !showTopSearch">
|
||||
<Icon icon="ep:search" />
|
||||
<Icon icon="ep:search" color="var(--top-header-text-color)" />
|
||||
<el-select
|
||||
@click.stop
|
||||
filterable
|
||||
|
@ -1,5 +1,6 @@
|
||||
import UploadImg from './src/UploadImg.vue'
|
||||
import UploadImgs from './src/UploadImgs.vue'
|
||||
import UploadFile from './src/UploadFile.vue'
|
||||
import UploadFileNew from './src/UploadFileNew.vue'
|
||||
|
||||
export { UploadImg, UploadImgs, UploadFile }
|
||||
export { UploadImg, UploadImgs, UploadFile ,UploadFileNew}
|
||||
|
271
src/components/UploadFile/src/UploadFileNew.vue
Normal file
@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<div class="upload-box">
|
||||
<el-upload
|
||||
:id="uuid"
|
||||
:accept="fileType.join(',')"
|
||||
:action="uploadUrl"
|
||||
:before-upload="beforeUpload"
|
||||
:class="['upload', drag ? 'no-border' : '']"
|
||||
:disabled="disabled"
|
||||
:drag="drag"
|
||||
:http-request="httpRequest"
|
||||
:multiple="false"
|
||||
:on-error="uploadError"
|
||||
:on-success="uploadSuccess"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<template v-if="modelValue">
|
||||
<img :src="modelValue" class="upload-image" />
|
||||
<div class="upload-handle" @click.stop>
|
||||
<div v-if="!disabled" class="handle-icon" @click="editImg">
|
||||
<Icon icon="ep:edit" />
|
||||
<span v-if="showBtnText">{{ t('action.edit') }}</span>
|
||||
</div>
|
||||
<div class="handle-icon" @click="imagePreview(modelValue)">
|
||||
<Icon icon="ep:zoom-in" />
|
||||
<span v-if="showBtnText">{{ t('action.detail') }}</span>
|
||||
</div>
|
||||
<div v-if="showDelete && !disabled" class="handle-icon" @click="deleteImg">
|
||||
<Icon icon="ep:delete" />
|
||||
<span v-if="showBtnText">{{ t('action.del') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="upload-empty">
|
||||
<slot name="empty">
|
||||
<Icon icon="ep:plus" />
|
||||
<!-- <span>请上传图片</span> -->
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<div class="el-upload__tip">
|
||||
<slot name="tip"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { UploadProps } from 'element-plus'
|
||||
|
||||
import { generateUUID } from '@/utils'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { createImageViewer } from '@/components/ImageViewer'
|
||||
import { useUpload } from '@/components/UploadFile/src/useUpload'
|
||||
|
||||
defineOptions({ name: 'UploadImg' })
|
||||
|
||||
type FileTypes =
|
||||
| 'image/apng'
|
||||
| 'image/bmp'
|
||||
| 'image/gif'
|
||||
| 'image/jpeg'
|
||||
| 'image/pjpeg'
|
||||
| 'image/png'
|
||||
| 'image/svg+xml'
|
||||
| 'image/tiff'
|
||||
| 'image/webp'
|
||||
| 'image/x-icon'
|
||||
|
||||
// 接受父组件参数
|
||||
const props = defineProps({
|
||||
modelValue: propTypes.string.def(''),
|
||||
drag: propTypes.bool.def(true), // 是否支持拖拽上传 ==> 非必传(默认为 true)
|
||||
disabled: propTypes.bool.def(false), // 是否禁用上传组件 ==> 非必传(默认为 false)
|
||||
fileSize: propTypes.number.def(5), // 图片大小限制 ==> 非必传(默认为 5M)
|
||||
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"])
|
||||
height: propTypes.string.def('150px'), // 组件高度 ==> 非必传(默认为 150px)
|
||||
width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px)
|
||||
borderradius: propTypes.string.def('8px'), // 组件边框圆角 ==> 非必传(默认为 8px)
|
||||
showDelete: propTypes.bool.def(true), // 是否显示删除按钮
|
||||
showBtnText: propTypes.bool.def(true) // 是否显示按钮文字
|
||||
})
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
// 生成组件唯一id
|
||||
const uuid = ref('id-' + generateUUID())
|
||||
// 查看图片
|
||||
const imagePreview = (imgUrl: string) => {
|
||||
createImageViewer({
|
||||
zIndex: 9999999,
|
||||
urlList: [imgUrl]
|
||||
})
|
||||
}
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const deleteImg = () => {
|
||||
emit('update:modelValue', '')
|
||||
}
|
||||
|
||||
const { uploadUrl, httpRequest } = useUpload()
|
||||
|
||||
const editImg = () => {
|
||||
const dom = document.querySelector(`#${uuid.value} .el-upload__input`)
|
||||
dom && dom.dispatchEvent(new MouseEvent('click'))
|
||||
}
|
||||
|
||||
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||
const imgSize = rawFile.size / 1024 / 1024 < props.fileSize
|
||||
const imgType = props.fileType
|
||||
if (!imgType.includes(rawFile.type as FileTypes))
|
||||
message.notifyWarning('上传图片不符合所需的格式!')
|
||||
if (!imgSize) message.notifyWarning(`上传图片大小不能超过 ${props.fileSize}M!`)
|
||||
return imgType.includes(rawFile.type as FileTypes) && imgSize
|
||||
}
|
||||
|
||||
// 图片上传成功提示
|
||||
const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
|
||||
message.success('上传成功')
|
||||
emit('update:modelValue', res.data)
|
||||
}
|
||||
|
||||
// 图片上传错误提示
|
||||
const uploadError = () => {
|
||||
message.notifyError('图片上传失败,请您重新上传!')
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.is-error {
|
||||
.upload {
|
||||
:deep(.el-upload),
|
||||
:deep(.el-upload-dragger) {
|
||||
border: 1px dashed var(--el-color-danger) !important;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.disabled) {
|
||||
.el-upload,
|
||||
.el-upload-dragger {
|
||||
cursor: not-allowed !important;
|
||||
background: var(--el-disabled-bg-color);
|
||||
border: 1px dashed var(--el-border-color-darker) !important;
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-border-color-darker) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-box {
|
||||
.no-border {
|
||||
:deep(.el-upload) {
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.upload) {
|
||||
.el-upload {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: v-bind(width);
|
||||
height: v-bind(height);
|
||||
overflow: hidden;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderradius);
|
||||
transition: var(--el-transition-duration-fast);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
|
||||
.upload-handle {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-dragger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderradius);
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-dragger.is-dragover {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
border: 2px dashed var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
.upload-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.upload-empty {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
color: var(--el-color-info);
|
||||
|
||||
.el-icon {
|
||||
font-size: 28px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.upload-handle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
background: rgb(0 0 0 / 60%);
|
||||
opacity: 0;
|
||||
box-sizing: border-box;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.handle-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 6%;
|
||||
color: aliceblue;
|
||||
|
||||
.el-icon {
|
||||
margin-bottom: 40%;
|
||||
font-size: 130%;
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 85%;
|
||||
line-height: 85%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload__tip {
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -7,8 +7,10 @@ import axios from 'axios'
|
||||
* 获得上传 URL
|
||||
*/
|
||||
export const getUploadUrl = (): string => {
|
||||
// return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
|
||||
return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
|
||||
}
|
||||
|
||||
|
||||
export const useUpload = () => {
|
||||
// 后端上传地址
|
||||
|
@ -0,0 +1,76 @@
|
||||
@charset "UTF-8";
|
||||
/* 改变主题色变量 */
|
||||
/* 改变 icon 字体路径变量,必需 */
|
||||
@use '~element-ui/packages/theme-chalk/src/index';
|
||||
.el-table td,
|
||||
.el-table th {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.el-drawer__header {
|
||||
padding: 16px 16px 8px 16px;
|
||||
margin: 0;
|
||||
line-height: 24px;
|
||||
font-size: 18px;
|
||||
color: #303133;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
div[class^='el-drawer']:focus,
|
||||
span:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.el-drawer__body {
|
||||
box-sizing: border-box;
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
margin-top: 50vh !important;
|
||||
transform: translateY(-50%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
overflow: hidden;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
padding: 16px 16px 8px 16px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 16px;
|
||||
max-height: 80vh;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.el-dialog__close {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-divider:not(.el-divider--horizontal) {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.el-divider.el-divider--horizontal {
|
||||
margin: 16px 0;
|
||||
}
|
1
src/components/bpmnProcessDesigner/package/theme/element-variables.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
@use '~element-ui/packages/theme-chalk/src/index';.el-table td,.el-table th{color:#333}.el-drawer__header{padding:16px 16px 8px 16px;margin:0;line-height:24px;font-size:18px;color:#303133;box-sizing:border-box;border-bottom:1px solid #e8e8e8}div[class^='el-drawer']:focus,span:focus{outline:none}.el-drawer__body{box-sizing:border-box;padding:16px;width:100%;overflow-y:auto}.el-dialog{margin-top:50vh !important;transform:translateY(-50%);overflow:hidden}.el-dialog__wrapper{overflow:hidden;max-height:100vh}.el-dialog__header{padding:16px 16px 8px 16px;box-sizing:border-box;border-bottom:1px solid #e8e8e8}.el-dialog__body{padding:16px;max-height:80vh;box-sizing:border-box;overflow-y:auto}.el-dialog__footer{padding:16px;box-sizing:border-box;border-top:1px solid #e8e8e8}.el-dialog__close{font-weight:600}.el-select{width:100%}.el-divider:not(.el-divider--horizontal){margin:0 8px}.el-divider.el-divider--horizontal{margin:16px 0}
|
@ -5,6 +5,7 @@ import qs from 'qs'
|
||||
import { config } from '@/config/axios/config'
|
||||
import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
|
||||
import errorCode from './errorCode'
|
||||
import JSONBigInt from 'json-bigint'
|
||||
|
||||
import { resetRouter } from '@/router'
|
||||
import { deleteUserCache } from '@/hooks/web/useCache'
|
||||
@ -36,6 +37,16 @@ const service: AxiosInstance = axios.create({
|
||||
paramsSerializer: (params) => {
|
||||
return qs.stringify(params, { allowDots: true })
|
||||
}
|
||||
// transformResponse: [
|
||||
// (data) => {
|
||||
// try {
|
||||
// // 使用 json-bigint 解析,大数字会转为字符串
|
||||
// return JSONBigInt.parse(data)
|
||||
// } catch (e) {
|
||||
// return data
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
})
|
||||
|
||||
// request拦截器
|
||||
@ -220,4 +231,5 @@ const handleAuthorized = () => {
|
||||
}
|
||||
return Promise.reject(t('sys.api.timeoutMessage'))
|
||||
}
|
||||
|
||||
export { service }
|
||||
|
@ -59,7 +59,7 @@ export default defineComponent({
|
||||
|
||||
<Backtop></Backtop>
|
||||
|
||||
<Setting></Setting>
|
||||
{/* <Setting></Setting> */}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ const getCaches = computed((): string[] => {
|
||||
|
||||
const tagsView = computed(() => appStore.getTagsView)
|
||||
|
||||
const { currentRoute } = useRouter() // 路由
|
||||
|
||||
//region 无感刷新
|
||||
const routerAlive = ref(true)
|
||||
// 无感刷新,防止出现页面闪烁白屏
|
||||
@ -35,6 +37,27 @@ provide('reload', reload)
|
||||
|
||||
<template>
|
||||
<section
|
||||
v-if="
|
||||
currentRoute.name === 'editMapPageRealTimeMap' || currentRoute.name === 'MapPageRealTimeMap'
|
||||
"
|
||||
:class="[
|
||||
'w-full bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
|
||||
{
|
||||
'!min-h-[calc(100vh-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))] pb-0':
|
||||
footer
|
||||
}
|
||||
]"
|
||||
>
|
||||
<router-view v-if="routerAlive">
|
||||
<template #default="{ Component, route }">
|
||||
<keep-alive :include="getCaches">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</template>
|
||||
</router-view>
|
||||
</section>
|
||||
<section
|
||||
v-else
|
||||
:class="[
|
||||
'p-[var(--app-content-padding)] w-full bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div :style="{ 'background-color': appStore.getTheme.topHeaderBgColor }">
|
||||
<router-link
|
||||
:class="[
|
||||
prefixCls,
|
||||
@ -80,6 +80,7 @@ watch(
|
||||
layout === 'topLeft' || layout === 'top' || layout === 'cutMenu'
|
||||
}
|
||||
]"
|
||||
style="font-size: 13px"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
|
@ -171,7 +171,8 @@ $prefix-cls: #{$namespace}-menu;
|
||||
.#{$elNamespace}-menu {
|
||||
.#{$elNamespace}-sub-menu__title,
|
||||
.#{$elNamespace}-menu-item:not(.is-active) {
|
||||
background-color: var(--left-menu-bg-light-color) !important;
|
||||
// background-color: var(--left-menu-bg-light-color) !important;
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,22 +13,30 @@ const list = ref<any[]>([]) // 消息列表
|
||||
|
||||
// 获得消息列表
|
||||
const getList = async () => {
|
||||
list.value = await NotifyMessageApi.getUnreadNotifyMessageList()
|
||||
// list.value = await NotifyMessageApi.getUnreadNotifyMessageList()
|
||||
list.value = await NotifyMessageApi.warnMsgReadPage()
|
||||
console.log(list.value)
|
||||
// 强制设置 unreadCount 为 0,避免小红点因为轮询太慢,不消除
|
||||
unreadCount.value = 0
|
||||
}
|
||||
|
||||
// 获得未读消息数
|
||||
const getUnreadCount = async () => {
|
||||
NotifyMessageApi.getUnreadNotifyMessageCount().then((data) => {
|
||||
unreadCount.value = data
|
||||
// NotifyMessageApi.getUnreadNotifyMessageCount().then((data) => {
|
||||
// unreadCount.value = data
|
||||
// })
|
||||
NotifyMessageApi.warnMsgReadPage().then((data) => {
|
||||
// console.log(data)
|
||||
unreadCount.value = data && data.length ? data.length : 0
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转我的站内信
|
||||
const popoverRef = ref()
|
||||
const goMyList = () => {
|
||||
popoverRef.value.hide()
|
||||
push({
|
||||
name: 'MyNotifyMessage'
|
||||
name: 'SystemCarError'
|
||||
})
|
||||
}
|
||||
|
||||
@ -45,16 +53,22 @@ onMounted(() => {
|
||||
unreadCount.value = 0
|
||||
}
|
||||
},
|
||||
1000 * 60 * 2
|
||||
1000 * 60 * 1
|
||||
)
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div class="message">
|
||||
<ElPopover :width="400" placement="bottom" trigger="click">
|
||||
<ElPopover ref="popoverRef" :width="400" placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<ElBadge :is-dot="unreadCount > 0" class="item">
|
||||
<Icon :size="18" class="cursor-pointer" icon="ep:bell" @click="getList" />
|
||||
<Icon
|
||||
:size="18"
|
||||
class="cursor-pointer"
|
||||
icon="ep:bell"
|
||||
@click="getList"
|
||||
color="var(--top-header-text-color)"
|
||||
/>
|
||||
</ElBadge>
|
||||
</template>
|
||||
<ElTabs v-model="activeName">
|
||||
@ -62,10 +76,12 @@ onMounted(() => {
|
||||
<el-scrollbar class="message-list">
|
||||
<template v-for="item in list" :key="item.id">
|
||||
<div class="message-item">
|
||||
<img alt="" class="message-icon" src="@/assets/imgs/avatar.gif" />
|
||||
<!-- <img alt="" class="message-icon" src="@/assets/imgs/avatar.gif" /> -->
|
||||
|
||||
<div class="message-content">
|
||||
<!-- <div style="margin-bottom: 5px;">异常等级:{{ item.warnLevel }}</div> -->
|
||||
<span class="message-title">
|
||||
{{ item.templateNickname }}:{{ item.templateContent }}
|
||||
{{ item.warnMsg }}
|
||||
</span>
|
||||
<span class="message-date">
|
||||
{{ formatDate(item.createTime) }}
|
||||
|
@ -297,6 +297,6 @@ $prefix-cls: #{$namespace}-setting;
|
||||
|
||||
.#{$prefix-cls} {
|
||||
border-radius: 6px 0 0 6px;
|
||||
z-index: 1200;/*修正没有z-index会被表格层覆盖,值不要超过4000*/
|
||||
z-index: 1200; /*修正没有z-index会被表格层覆盖,值不要超过4000*/
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="tsx">
|
||||
import { defineComponent, computed } from 'vue'
|
||||
import { Message } from '@/layout/components//Message'
|
||||
import { Message } from '@/layout/components/Message'
|
||||
import { Collapse } from '@/layout/components/Collapse'
|
||||
import { UserInfo } from '@/layout/components/UserInfo'
|
||||
import { Screenfull } from '@/layout/components/Screenfull'
|
||||
@ -52,6 +52,7 @@ export default defineComponent({
|
||||
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between',
|
||||
'dark:bg-[var(--el-bg-color)]'
|
||||
]}
|
||||
style="height:51px"
|
||||
>
|
||||
{layout.value !== 'top' ? (
|
||||
<div class="h-full flex items-center">
|
||||
|
@ -68,10 +68,10 @@ const toDocument = () => {
|
||||
<Icon icon="ep:tools" />
|
||||
<div @click="toProfile">{{ t('common.profile') }}</div>
|
||||
</ElDropdownItem>
|
||||
<ElDropdownItem>
|
||||
<!-- <ElDropdownItem>
|
||||
<Icon icon="ep:menu" />
|
||||
<div @click="toDocument">{{ t('common.document') }}</div>
|
||||
</ElDropdownItem>
|
||||
</ElDropdownItem> -->
|
||||
<ElDropdownItem divided>
|
||||
<Icon icon="ep:lock" />
|
||||
<div @click="lockScreen">{{ t('lock.lockScreen') }}</div>
|
||||
|
@ -55,7 +55,8 @@ export const useRenderLayout = () => {
|
||||
'w-[var(--left-menu-max-width)]': !appStore.getCollapse
|
||||
}
|
||||
]}
|
||||
style="transition: all var(--transition-time-02);"
|
||||
style="transition: all var(--transition-time-02);height:50px;display: flex;
|
||||
align-items: center;"
|
||||
></Logo>
|
||||
) : undefined}
|
||||
<Menu class={[{ '!h-[calc(100%-var(--logo-height))]': logo.value }]}></Menu>
|
||||
@ -106,9 +107,9 @@ export const useRenderLayout = () => {
|
||||
]}
|
||||
></ToolHeader>
|
||||
|
||||
{tagsView.value ? (
|
||||
{/* {tagsView.value ? (
|
||||
<TagsView class="layout-border__top layout-border__bottom"></TagsView>
|
||||
) : undefined}
|
||||
) : undefined} */}
|
||||
</div>
|
||||
|
||||
<AppView></AppView>
|
||||
|
14
src/main.ts
@ -41,11 +41,16 @@ import '@/plugins/tongji' // 百度统计
|
||||
import Logger from '@/utils/Logger'
|
||||
|
||||
import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
|
||||
|
||||
import VueDragResizeRotate from '@gausszhou/vue3-drag-resize-rotate'
|
||||
import '@gausszhou/vue3-drag-resize-rotate/lib/bundle.esm.css'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
import { vDrag } from './utils/drag'
|
||||
// 创建实例
|
||||
const setupAll = async () => {
|
||||
const app = createApp(App)
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
await setupI18n(app)
|
||||
|
||||
setupStore(app)
|
||||
@ -63,9 +68,10 @@ const setupAll = async () => {
|
||||
setupMountedFocus(app)
|
||||
|
||||
await router.isReady()
|
||||
|
||||
// 注册全局指令
|
||||
app.directive('drag', vDrag)
|
||||
app.use(VueDOMPurifyHTML)
|
||||
|
||||
app.use(VueDragResizeRotate)
|
||||
app.mount('#app')
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,10 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/Home/Index.vue'),
|
||||
name: 'Index',
|
||||
component: () => import('@/views/mapPage/realTimeMap/index.vue'),
|
||||
name: 'MapPageRealTimeMap',
|
||||
meta: {
|
||||
title: t('router.home'),
|
||||
title: '实时地图',
|
||||
icon: 'ep:home-filled',
|
||||
noCache: false,
|
||||
affix: true
|
||||
@ -70,6 +70,62 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// path: '/',
|
||||
// component: Layout,
|
||||
// redirect: '/index',
|
||||
// name: 'Home',
|
||||
// meta: {},
|
||||
// children: [
|
||||
// {
|
||||
// path: 'index',
|
||||
// component: () => import('@/views/Home/Index.vue'),
|
||||
// name: 'Index',
|
||||
// meta: {
|
||||
// title: t('router.home'),
|
||||
// icon: 'ep:home-filled',
|
||||
// noCache: false,
|
||||
// affix: true
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
//地图
|
||||
{
|
||||
path: '/warehouse/map',
|
||||
component: Layout,
|
||||
name: 'warehouseMap',
|
||||
meta: {
|
||||
hidden: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'edit',
|
||||
component: () => import('@/views/mapPage/realTimeMap/editMap.vue'),
|
||||
name: 'editMapPageRealTimeMap',
|
||||
meta: {
|
||||
noCache: true, // 需要缓存
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
icon: 'ep:edit',
|
||||
title: '地图编辑'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'test',
|
||||
component: () => import('@/views/mapPage/realTimeMap/test.vue'),
|
||||
name: 'testMapPageRealTimeMap',
|
||||
meta: {
|
||||
noCache: true, // 需要缓存
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
icon: 'ep:edit',
|
||||
title: '测试'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
path: '/user',
|
||||
component: Layout,
|
||||
|
@ -47,7 +47,6 @@ export const useAppStore = defineStore('app', {
|
||||
mobile: false, // 是否是移动端
|
||||
title: import.meta.env.VITE_APP_TITLE, // 标题
|
||||
pageLoading: false, // 路由跳转loading
|
||||
|
||||
breadcrumb: true, // 面包屑
|
||||
breadcrumbIcon: true, // 面包屑图标
|
||||
collapse: false, // 折叠菜单
|
||||
@ -56,49 +55,49 @@ export const useAppStore = defineStore('app', {
|
||||
screenfull: true, // 全屏图标
|
||||
search: true, // 搜索图标
|
||||
size: true, // 尺寸图标
|
||||
locale: true, // 多语言图标
|
||||
locale: false, // 多语言图标
|
||||
message: true, // 消息图标
|
||||
tagsView: true, // 标签页
|
||||
tagsView: false, // 标签页
|
||||
tagsViewImmerse: false, // 标签页沉浸
|
||||
tagsViewIcon: true, // 是否显示标签图标
|
||||
logo: true, // logo
|
||||
fixedHeader: true, // 固定toolheader
|
||||
footer: true, // 显示页脚
|
||||
footer: false, // 显示页脚
|
||||
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
||||
fixedMenu: wsCache.get('fixedMenu') || false, // 是否固定菜单
|
||||
|
||||
layout: wsCache.get(CACHE_KEY.LAYOUT) || 'classic', // layout布局
|
||||
isDark: wsCache.get(CACHE_KEY.IS_DARK) || false, // 是否是暗黑模式
|
||||
// isDark: wsCache.get(CACHE_KEY.IS_DARK) || false, // 是否是暗黑模式
|
||||
isDark: false, // 是否是暗黑模式
|
||||
currentSize: wsCache.get('default') || 'default', // 组件尺寸
|
||||
theme: wsCache.get(CACHE_KEY.THEME) || {
|
||||
// 主题色
|
||||
elColorPrimary: '#409eff',
|
||||
elColorPrimary: '#00329F',
|
||||
// 左侧菜单边框颜色
|
||||
leftMenuBorderColor: 'inherit',
|
||||
// 左侧菜单背景颜色
|
||||
leftMenuBgColor: '#001529',
|
||||
leftMenuBgColor: '#ffffff',
|
||||
// 左侧菜单浅色背景颜色
|
||||
leftMenuBgLightColor: '#0f2438',
|
||||
// 左侧菜单选中背景颜色
|
||||
leftMenuBgActiveColor: 'var(--el-color-primary)',
|
||||
leftMenuBgActiveColor: '#EBF1FF',
|
||||
// 左侧菜单收起选中背景颜色
|
||||
leftMenuCollapseBgActiveColor: 'var(--el-color-primary)',
|
||||
leftMenuCollapseBgActiveColor: '#EBF1FF',
|
||||
// 左侧菜单字体颜色
|
||||
leftMenuTextColor: '#bfcbd9',
|
||||
leftMenuTextColor: '#98A4BF',
|
||||
// 左侧菜单选中字体颜色
|
||||
leftMenuTextActiveColor: '#fff',
|
||||
leftMenuTextActiveColor: '#00329F',
|
||||
// logo字体颜色
|
||||
logoTitleTextColor: '#fff',
|
||||
// logo边框颜色
|
||||
logoBorderColor: 'inherit',
|
||||
// 头部背景颜色
|
||||
topHeaderBgColor: '#fff',
|
||||
topHeaderBgColor: '#00329F',
|
||||
// 头部字体颜色
|
||||
topHeaderTextColor: 'inherit',
|
||||
topHeaderTextColor: '#ffffff',
|
||||
// 头部悬停颜色
|
||||
topHeaderHoverColor: '#f6f6f6',
|
||||
topHeaderHoverColor: '#215bd8',
|
||||
// 头部边框颜色
|
||||
topToolBorderColor: '#eee'
|
||||
topToolBorderColor: '#E2E7F5'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
19
src/styles/FormCreate/index.css
Normal file
@ -0,0 +1,19 @@
|
||||
@font-face {
|
||||
font-family: "fc-icon";
|
||||
src: url("@/styles/FormCreate/fonts/fontello.woff") format("woff");
|
||||
}
|
||||
.icon-doc-text:before {
|
||||
content: "\f0f6";
|
||||
}
|
||||
|
||||
.icon-server:before {
|
||||
content: "\f233";
|
||||
}
|
||||
|
||||
.icon-address-card-o:before {
|
||||
content: "\f2bc";
|
||||
}
|
||||
|
||||
.icon-user-o:before {
|
||||
content: "\f2c0";
|
||||
}/*# sourceMappingURL=index.css.map */
|
1
src/styles/FormCreate/index.css.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":["index.scss","index.css"],"names":[],"mappings":"AAEA;EACE,sBAAA;EACA,kEAAA;ACDF;ADIA;EACE,gBAAA;ACFF;;ADKA;EACE,gBAAA;ACFF;;ADKA;EACE,gBAAA;ACFF;;ADKA;EACE,gBAAA;ACFF","file":"index.css"}
|
@ -1,13 +1,15 @@
|
||||
:root {
|
||||
--el-color-primary: #00329f;
|
||||
|
||||
--login-bg-color: #293146;
|
||||
|
||||
--left-menu-max-width: 200px;
|
||||
|
||||
--left-menu-min-width: 64px;
|
||||
|
||||
--left-menu-bg-color: #001529;
|
||||
--left-menu-bg-color: #ffffff;
|
||||
|
||||
--left-menu-bg-light-color: #0f2438;
|
||||
--left-menu-bg-light-color: #ffffff;
|
||||
|
||||
--left-menu-bg-active-color: var(--el-color-primary);
|
||||
|
||||
@ -19,7 +21,7 @@
|
||||
/* left menu end */
|
||||
|
||||
/* logo start */
|
||||
--logo-height: 50px;
|
||||
--logo-height: 40px;
|
||||
|
||||
--logo-title-text-color: #fff;
|
||||
/* logo end */
|
||||
@ -29,13 +31,15 @@
|
||||
|
||||
--top-header-text-color: 'inherit';
|
||||
|
||||
--top-header-hover-color: #f6f6f6;
|
||||
--top-header-hover-color: #215bd8;
|
||||
|
||||
--top-tool-height: var(--logo-height);
|
||||
/* --top-tool-height: var(--logo-height); */
|
||||
--top-tool-height: 50px;
|
||||
|
||||
--top-tool-p-x: 0;
|
||||
|
||||
--tags-view-height: 35px;
|
||||
/* --tags-view-height: 35px; 开启面包屑时 */
|
||||
--tags-view-height: 0px;
|
||||
/* header start */
|
||||
|
||||
/* tab menu start */
|
||||
|
@ -239,5 +239,10 @@ export enum DICT_TYPE {
|
||||
IOT_PRODUCT_FUNCTION_TYPE = 'iot_product_function_type', // IOT 产品功能类型
|
||||
IOT_DATA_TYPE = 'iot_data_type', // IOT 数据类型
|
||||
IOT_UNIT_TYPE = 'iot_unit_type', // IOT 单位类型
|
||||
IOT_RW_TYPE = 'iot_rw_type' // IOT 读写类型
|
||||
IOT_RW_TYPE = 'iot_rw_type', // IOT 读写类型
|
||||
|
||||
// ========== wcs 地图 ==========
|
||||
ROBOT_TASK_STATUS = 'robot_task_status', //机器人的任务状态
|
||||
ROBOT_QUEST_PHASES = 'robot_quest_phases', //机器人的任务阶段
|
||||
DEVICE_TYPE = 'device_type'
|
||||
}
|
||||
|
81
src/utils/drag.ts
Normal file
@ -0,0 +1,81 @@
|
||||
// directives.js
|
||||
export const vDrag = {
|
||||
mounted(el, binding) {
|
||||
const enableDrag = binding.value; // 获取指令绑定的值
|
||||
// if (!enableDrag) return; // 如果为 false,则不执行后续拖拽逻辑
|
||||
el.style.position = 'absolute';
|
||||
|
||||
// 记录元素的初始位置
|
||||
const initialTop = el.offsetTop;
|
||||
const initialLeft = el.offsetLeft;
|
||||
|
||||
let startX, startY, initialMouseX, initialMouseY;
|
||||
|
||||
const mousemove = (e) => {
|
||||
const dx = e.clientX - initialMouseX;
|
||||
const dy = e.clientY - initialMouseY;
|
||||
el.style.top = `${startY + dy}px`;
|
||||
el.style.left = `${startX + dx}px`;
|
||||
};
|
||||
|
||||
const mouseup = () => {
|
||||
document.removeEventListener('mousemove', mousemove);
|
||||
document.removeEventListener('mouseup', mouseup);
|
||||
};
|
||||
|
||||
const mousedown = (e) => {
|
||||
startX = el.offsetLeft;
|
||||
startY = el.offsetTop;
|
||||
initialMouseX = e.clientX;
|
||||
initialMouseY = e.clientY;
|
||||
document.addEventListener('mousemove', mousemove);
|
||||
document.addEventListener('mouseup', mouseup);
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
el.addEventListener('mousedown', mousedown);
|
||||
// 保存 mousedown 事件处理函数,以便在 updated 中使用
|
||||
el.__vDragMousedown = mousedown;
|
||||
// 保存初始位置,以便后续还原
|
||||
el.__vDragInitialTop = initialTop;
|
||||
el.__vDragInitialLeft = initialLeft;
|
||||
if(!enableDrag){
|
||||
// 如果之前启用,现在禁用,移除 mousedown 事件监听器
|
||||
el.removeEventListener('mousedown', el.__vDragMousedown);
|
||||
// 确保在禁用时停止正在进行的拖拽
|
||||
document.removeEventListener('mousemove', el.__vDragMousemove);
|
||||
document.removeEventListener('mouseup', el.__vDragMouseup);
|
||||
}
|
||||
},
|
||||
updated(el, binding) {
|
||||
// console.log('会走这边吗');
|
||||
const enableDrag = binding.value;
|
||||
const prevEnableDrag = binding.oldValue;
|
||||
|
||||
if (enableDrag && !prevEnableDrag) {
|
||||
// 如果之前禁用,现在启用,添加 mousedown 事件监听器
|
||||
el.addEventListener('mousedown', el.__vDragMousedown);
|
||||
} else if (!enableDrag && prevEnableDrag) {
|
||||
// 如果之前启用,现在禁用,移除 mousedown 事件监听器
|
||||
el.removeEventListener('mousedown', el.__vDragMousedown);
|
||||
// 确保在禁用时停止正在进行的拖拽
|
||||
document.removeEventListener('mousemove', el.__vDragMousemove);
|
||||
document.removeEventListener('mouseup', el.__vDragMouseup);
|
||||
}
|
||||
},
|
||||
beforeUnmount(el) {
|
||||
// 在元素卸载前移除 mousedown 事件监听器
|
||||
if (el.__vDragMousedown) {
|
||||
el.removeEventListener('mousedown', el.__vDragMousedown);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 定义一个还原位置的函数
|
||||
export const resetDragPosition = (el) => {
|
||||
console.log(el);
|
||||
if (el.__vDragInitialTop!== undefined && el.__vDragInitialLeft!== undefined) {
|
||||
el.style.top = `${el.__vDragInitialTop}px`;
|
||||
el.style.left = `${el.__vDragInitialLeft}px`;
|
||||
}
|
||||
};
|
@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div
|
||||
:class="prefixCls"
|
||||
class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px"
|
||||
class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px login-page"
|
||||
>
|
||||
<div class="relative mx-auto h-full flex">
|
||||
<div
|
||||
:class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"
|
||||
:class="`${prefixCls}__left flex-1 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"
|
||||
>
|
||||
<!-- 左上角的 logo + 系统标题 -->
|
||||
<div class="relative flex items-center text-white">
|
||||
<!-- <div class="relative flex items-center text-white">
|
||||
<img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
|
||||
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- 左边的背景图 + 欢迎语 -->
|
||||
<div class="h-[calc(100%-60px)] flex items-center justify-center">
|
||||
<!-- <div class="h-[calc(100%-60px)] flex items-center justify-center">
|
||||
<TransitionGroup
|
||||
appear
|
||||
enter-active-class="animate__animated animate__bounceInLeft"
|
||||
@ -25,7 +25,7 @@
|
||||
{{ t('login.message') }}
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div
|
||||
class="relative flex-1 p-30px dark:bg-[var(--login-bg-color)] lt-sm:p-10px overflow-x-hidden overflow-y-auto"
|
||||
@ -33,15 +33,15 @@
|
||||
<!-- 右上角的主题、语言选择 -->
|
||||
<div
|
||||
class="flex items-center justify-between at-2xl:justify-end at-xl:justify-end"
|
||||
style="color: var(--el-text-color-primary);"
|
||||
style="color: var(--el-text-color-primary)"
|
||||
>
|
||||
<div class="flex items-center at-2xl:hidden at-xl:hidden">
|
||||
<img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
|
||||
<span class="text-20px font-bold" >{{ underlineToHump(appStore.getTitle) }}</span>
|
||||
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-end space-x-10px h-48px">
|
||||
<ThemeSwitch />
|
||||
<LocaleDropdown />
|
||||
<!-- <LocaleDropdown /> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右边的登录界面 -->
|
||||
@ -106,7 +106,7 @@ $prefix-cls: #{$namespace}-login;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.dark .login-form {
|
||||
.el-divider__text {
|
||||
background-color: var(--login-bg-color);
|
||||
@ -116,4 +116,16 @@ $prefix-cls: #{$namespace}-login;
|
||||
background-color: var(--login-bg-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.login-page {
|
||||
background-image: url('@/assets/login-bg.png');
|
||||
/* 让背景图片覆盖整个元素 */
|
||||
background-size: cover;
|
||||
/* 让背景图片居中显示 */
|
||||
background-position: center;
|
||||
/* 禁止背景图片重复 */
|
||||
background-repeat: no-repeat;
|
||||
/* 设置元素的宽度和高度为视口的宽度和高度 */
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
|
@ -4,85 +4,88 @@
|
||||
ref="formLogin"
|
||||
:model="loginData.loginForm"
|
||||
:rules="LoginRules"
|
||||
class="login-form"
|
||||
label-position="top"
|
||||
label-width="120px"
|
||||
size="large"
|
||||
>
|
||||
<el-row style="margin-right: -10px; margin-left: -10px">
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item>
|
||||
<LoginFormTitle style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-form-item v-if="loginData.tenantEnable === 'true'" prop="tenantName">
|
||||
<el-input
|
||||
v-model="loginData.loginForm.tenantName"
|
||||
:placeholder="t('login.tenantNamePlaceholder')"
|
||||
:prefix-icon="iconHouse"
|
||||
link
|
||||
type="primary"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="loginData.loginForm.username"
|
||||
:placeholder="t('login.usernamePlaceholder')"
|
||||
:prefix-icon="iconAvatar"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="loginData.loginForm.password"
|
||||
:placeholder="t('login.passwordPlaceholder')"
|
||||
:prefix-icon="iconLock"
|
||||
show-password
|
||||
type="password"
|
||||
@keyup.enter="getCode()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="24"
|
||||
style="padding-right: 10px; padding-left: 10px; margin-top: -20px; margin-bottom: -20px"
|
||||
>
|
||||
<el-form-item>
|
||||
<el-row justify="space-between" style="width: 100%">
|
||||
<el-col :span="6">
|
||||
<el-checkbox v-model="loginData.loginForm.rememberMe">
|
||||
{{ t('login.remember') }}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :offset="6" :span="12">
|
||||
<el-link style="float: right" type="primary">{{ t('login.forgetPassword') }}</el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-form-item>
|
||||
<XButton
|
||||
:loading="loginLoading"
|
||||
:title="t('login.login')"
|
||||
class="w-[100%]"
|
||||
type="primary"
|
||||
@click="getCode()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<Verify
|
||||
ref="verify"
|
||||
:captchaType="captchaType"
|
||||
:imgSize="{ width: '400px', height: '200px' }"
|
||||
mode="pop"
|
||||
@success="handleLogin"
|
||||
/>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<div class="login-form">
|
||||
<div class="login-tip">欢迎登录</div>
|
||||
<el-col :span="24">
|
||||
<el-form-item v-if="loginData.tenantEnable === 'true'">
|
||||
<el-input
|
||||
:disabled="true"
|
||||
placeholder="中鼐智能"
|
||||
:prefix-icon="iconHouse"
|
||||
type="primary"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="loginData.loginForm.username"
|
||||
:placeholder="t('login.usernamePlaceholder')"
|
||||
:prefix-icon="iconAvatar"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
v-model="loginData.loginForm.password"
|
||||
:placeholder="t('login.passwordPlaceholder')"
|
||||
:prefix-icon="iconLock"
|
||||
show-password
|
||||
type="password"
|
||||
@keyup.enter="getCode()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" style="margin-top: -10px; margin-bottom: 20px">
|
||||
<el-form-item>
|
||||
<el-row justify="space-between" style="width: 100%">
|
||||
<el-col :span="6">
|
||||
<el-checkbox v-model="loginData.loginForm.rememberMe">
|
||||
{{ t('login.remember') }}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
<!--
|
||||
忘记密码
|
||||
<el-col :offset="6" :span="12">
|
||||
<el-link style="float: right" type="primary">{{
|
||||
t('login.forgetPassword')
|
||||
}}</el-link>
|
||||
</el-col> -->
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item>
|
||||
<XButton
|
||||
:loading="loginLoading"
|
||||
:title="t('login.login')"
|
||||
class="w-[100%]"
|
||||
type="primary"
|
||||
@click="getCode()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<Verify
|
||||
ref="verify"
|
||||
:captchaType="captchaType"
|
||||
:imgSize="{ width: '400px', height: '200px' }"
|
||||
mode="pop"
|
||||
@success="handleLogin"
|
||||
/>
|
||||
</div>
|
||||
<!--
|
||||
<el-col :span="24" >
|
||||
<el-form-item>
|
||||
<el-row :gutter="5" justify="space-between" style="width: 100%">
|
||||
<el-col :span="8">
|
||||
@ -109,8 +112,8 @@
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>
|
||||
<el-col :span="24" >
|
||||
<el-form-item>
|
||||
<div class="w-[100%] flex justify-between">
|
||||
<Icon
|
||||
@ -126,7 +129,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-divider content-position="center">萌新必读</el-divider>
|
||||
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
|
||||
<el-col :span="24" >
|
||||
<el-form-item>
|
||||
<div class="w-[100%] flex justify-between">
|
||||
<el-link href="https://doc.iocoder.cn/" target="_blank">📚开发指南</el-link>
|
||||
@ -139,7 +142,7 @@
|
||||
</el-link>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
@ -352,4 +355,25 @@ onMounted(() => {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form {
|
||||
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
padding: 40px 42px 32px 42px;
|
||||
margin-top: 20px;
|
||||
|
||||
.login-tip {
|
||||
margin-bottom: 28px;
|
||||
font-family:
|
||||
PingFangSC,
|
||||
PingFang SC;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
color: #0d162a;
|
||||
line-height: 22px;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<h2 class="enter-x mb-3 text-center text-2xl font-bold xl:text-center xl:text-3xl">
|
||||
{{ getFormTitle }}
|
||||
<h2 class="form-title">
|
||||
<!-- {{ getFormTitle }} -->
|
||||
RCS智能设备调度系统
|
||||
</h2>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
@ -24,3 +25,11 @@ const getFormTitle = computed(() => {
|
||||
return titleObj[unref(getLoginState)]
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.form-title {
|
||||
color: #34335b;
|
||||
font-size: 44px;
|
||||
line-height: 62px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
@ -133,7 +133,7 @@ const loginData = reactive({
|
||||
},
|
||||
loginForm: {
|
||||
uuid: '',
|
||||
tenantName: '芋道源码',
|
||||
tenantName: '中鼐科技',
|
||||
mobileNumber: '',
|
||||
code: ''
|
||||
}
|
||||
|
@ -22,9 +22,9 @@
|
||||
<el-tab-pane :label="t('profile.info.resetPwd')" name="resetPwd">
|
||||
<ResetPwd />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="t('profile.info.userSocial')" name="userSocial">
|
||||
<!-- <el-tab-pane :label="t('profile.info.userSocial')" name="userSocial">
|
||||
<UserSocial v-model:activeName="activeName" />
|
||||
</el-tab-pane>
|
||||
</el-tab-pane> -->
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-card>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div class="chat-empty">
|
||||
<!-- title -->
|
||||
<div class="center-container">
|
||||
<div class="title">芋道 AI</div>
|
||||
<div class="title">中鼐 AI</div>
|
||||
<div class="role-list">
|
||||
<div
|
||||
class="role-item"
|
||||
|