应急搜捞提交

This commit is contained in:
zhangqi 2025-09-08 10:02:48 +08:00
commit c907e27a1d
57 changed files with 5870 additions and 0 deletions

12
.env.development Normal file
View File

@ -0,0 +1,12 @@
# 如需添加更多环境变量,请以 VITE_APP_ 开头声明
# 在代码中使用 import.meta.env.VITE_APP_XXX 获取指定变量
# 环境配置标识
VITE_APP_ENV='development'
# api接口请求地址
VITE_APP_BASE_API='http://crm.hzzxq.com/ds'

10
.env.production Normal file
View File

@ -0,0 +1,10 @@
# 如需添加更多环境变量,请以 VITE_APP_ 开头声明
# 在代码中使用 import.meta.env.VITE_APP_XXX 获取指定变量
# 环境配置标识
VITE_APP_ENV='production'
# api接口请求地址
VITE_APP_BASE_API='http://crm.hzzxq.com/ds'

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# Vue 3 + TypeScript + Vite
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).

BIN
dist (2).zip Normal file

Binary file not shown.

BIN
dist (3).zip Normal file

Binary file not shown.

BIN
dist (4).zip Normal file

Binary file not shown.

BIN
dist.zip Normal file

Binary file not shown.

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>应急搜捞</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

2408
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "task-management-system",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.6.7",
"element-plus": "^2.5.6",
"vue": "^3.4.38",
"vue-baidu-map-3x": "^1.0.40",
"vue-router": "^4.3.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.3",
"sass": "^1.71.1",
"typescript": "^5.5.3",
"vite": "^5.4.2",
"vue-tsc": "^2.1.4"
}
}

BIN
public/vite.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

204
src/App.vue Normal file
View File

@ -0,0 +1,204 @@
<template>
<el-container>
<el-header class="header-bg">
<div class="header-content">
<div class="logo">
<img src="@/assets/logo.png" alt="Logo" />
<span>深海应急搜捞数据管理可视化平台</span>
</div>
<el-menu
mode="horizontal"
:default-active="activeMenu"
:ellipsis="false"
router
class="main-menu"
>
<el-menu-item index="/">首页</el-menu-item>
<el-menu-item index="/demand">任务需求</el-menu-item>
<el-menu-item index="/search">任务检索</el-menu-item>
<el-menu-item index="/statistics">统计分析</el-menu-item>
<el-menu-item index="/contact">联系我们</el-menu-item>
</el-menu>
</div>
<img class="bg" v-show="activeMenu == '/' || activeMenu == '/statistics'" src="@/assets/bg.jpg" alt="背景图片" />
</el-header>
<el-main>
<router-view></router-view>
</el-main>
<el-footer>
<div>
<div class="title">
<img src="@/assets/logo.png" alt="Logo" />
<span>中国科学院深海科学与工程研究所</span>
</div>
<div class="info">
<div class="item">
<div class="icon">
<img src="@/assets/icon_@.png" alt="Logo" />
</div>
<span>联系方式chencx@idsse.ac.cn</span>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/icon_area.png" alt="Logo" />
</div>
<span>地址三亚市鹿回头路28号</span>
</div>
<div class="item">
<div class="icon">
<img src="@/assets/icon_mail.png" alt="Logo" />
</div>
<span>邮编572000</span>
</div>
</div>
</div>
</el-footer>
</el-container>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
const activeMenu = ref('/')
const route = useRoute()
//
watch(
() => route.path,
(newPath) => {
activeMenu.value = newPath
}
)
</script>
<style lang="scss" scoped>
.el-container {
min-height: 100vh;
background: #fff;
}
.header-bg {
background-image: url(@/assets/footer_bg.png);
}
.el-header {
position: relative;
color: white;
height: 100px;
z-index: 0;
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100vh - 120px);
z-index: -1;
}
.header-content {
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.logo {
display: flex;
align-items: center;
gap: 10px;
margin-right: 40px;
img {
width: 56px;
height: 56px;
}
span {
font-size: 30px;
font-weight: bold;
color: white;
}
}
}
}
.main-menu {
background-color: transparent;
border-bottom: none;
:deep(.el-menu-item) {
color: white;
font-size: 18px;
&.is-active {
background-color: transparent;
color: white;
}
&:hover {
background-color: transparent;
}
}
}
.el-main {
background-color: transparent;
padding: 0;
z-index: 2;
}
.el-footer {
height: 120px;
background-image: url(@/assets/footer_bg.png);
display: flex;
justify-content: center;
align-items: center;
.title {
display: flex;
align-items: center;
font-size: 18px;
color: #fff;
margin-bottom: 20px;
img {
width: 30px;
height: 30px;
margin-right: 10px;
}
}
.info {
display: flex;
font-size: 14px;
color: #fff;
.item {
display: flex;
align-items: center;
margin-right: 20px;
.icon {
width: 30px;
height: 30px;
background: #263954;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
margin-right: 5px;
img {
width: 13px;
height: 13px;
}
}
}
}
}
</style>

64
src/api/task.js Normal file
View File

@ -0,0 +1,64 @@
import request from '@/utils/request'
// 获取参数列表
export const getParam = () => {
return request({
url: '/param/list.htm',
method: 'post'
})
}
// 获取航次列表
export const voyageReg = (data) => {
console.log(data)
return request({
baseURL: data.baseURL,
url: '/voyage/reg/list.htm',
method: 'post'
})
}
// 获取任务列表
export const regPage = (data) => {
return request({
url: '/rescue/reg/page.htm',
method: 'post',
data
})
}
// 查询任务详情
export const regFind = (data) => {
return request({
url: '/rescue/reg/find.htm',
method: 'post',
data
})
}
// 新增/编辑任务
export const regEdit = (data) => {
return request({
url: '/rescue/reg/edit.htm',
method: 'post',
data
})
}
// 附件列表
export const regFileList = (data) => {
return request({
url: '/rescue/reg/file/list.htm',
method: 'post',
data
})
}
// 查看附件接口
export const regFileView = () => {
return request({
url: '/rescue/reg/file/view.htm',
method: 'post'
})
}

BIN
src/assets/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
src/assets/bg2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 KiB

BIN
src/assets/footer_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
src/assets/icon_@.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/assets/icon_area.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/assets/icon_mail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/assets/icons/三级.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
src/assets/icons/任务.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/assets/icons/区域.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
src/assets/icons/展开.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

BIN
src/assets/icons/折叠.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
src/assets/icons/潜艇.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/assets/icons/航次.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
src/assets/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -0,0 +1,41 @@
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{ msg: string }>()
const count = ref(0)
</script>
<template>
<h1>{{ msg }}</h1>
<div class="card">
<button type="button" @click="count++">count is {{ count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test HMR
</p>
</div>
<p>
Check out
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
>create-vue</a
>, the official Vue + Vite starter
</p>
<p>
Learn more about IDE Support for Vue in the
<a
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
target="_blank"
>Vue Docs Scaling up Guide</a
>.
</p>
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
</style>

24
src/main.ts Normal file
View File

@ -0,0 +1,24 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'; // 引入中文语言包
import router from './router'
import App from './App.vue'
import BaiduMap from 'vue-baidu-map-3x'
import './style.css'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(BaiduMap, {
ak: 'uu7pXHZLZOejrWXyTK2lVMHASObAg8Fz'
})
app.use(ElementPlus, {
locale: zhCn
})
app.use(router)
app.mount('#app')

52
src/router/index.ts Normal file
View File

@ -0,0 +1,52 @@
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue'),
meta: { title: '首页' }
},
{
path: '/demand',
name: 'TaskDemand',
component: () => import('@/views/TaskDemand.vue'),
meta: { title: '任务需求' }
},
{
path: '/search',
name: 'TaskSearch',
component: () => import('@/views/TaskSearch.vue'),
meta: { title: '任务检索' }
},
{
path: '/input/:id?',
name: 'TaskInput',
component: () => import('@/views/TaskInput.vue'),
meta: { title: '任务需求信息录入' }
},
{
path: '/statistics',
name: 'Statistics',
component: () => import('@/views/Statistics.vue'),
meta: { title: '统计分析' }
},
{
path: '/contact',
name: 'Contact',
component: () => import('@/views/Contact.vue'),
meta: { title: '联系我们' }
}
]
})
router.beforeEach((to, from, next) => {
if (to.meta.title) {
document.title = '应急搜捞 - ' + to.meta.title
}
next()
})
export default router

35
src/style.css Normal file
View File

@ -0,0 +1,35 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
min-width: 320px;
min-height: 100vh;
}
#app {
width: 100%;
margin: 0 auto;
}

228
src/utils/index.js Normal file
View File

@ -0,0 +1,228 @@
/**
* 通用js方法封装处理
* Copyright (c) 2019 ruoyi
*/
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields()
}
}
// 添加日期范围
export function addDateRange(params, dateRange, propName) {
let search = params
search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}
dateRange = Array.isArray(dateRange) ? dateRange : []
if (typeof (propName) === 'undefined') {
search.params['beginTime'] = dateRange[0]
search.params['endTime'] = dateRange[1]
} else {
search.params['begin' + propName] = dateRange[0]
search.params['end' + propName] = dateRange[1]
}
return search
}
// 回显数据字典
export function selectDictLabel(datas, value) {
if (value === undefined) {
return ""
}
var actions = []
Object.keys(datas).some((key) => {
if (datas[key].value == ('' + value)) {
actions.push(datas[key].label)
return true
}
})
if (actions.length === 0) {
actions.push(value)
}
return actions.join('')
}
// 回显数据字典(字符串、数组)
export function selectDictLabels(datas, value, separator) {
if (value === undefined || value.length ===0) {
return ""
}
if (Array.isArray(value)) {
value = value.join(",")
}
var actions = []
var currentSeparator = undefined === separator ? "," : separator
var temp = value.split(currentSeparator)
Object.keys(value.split(currentSeparator)).some((val) => {
var match = false
Object.keys(datas).some((key) => {
if (datas[key].value == ('' + temp[val])) {
actions.push(datas[key].label + currentSeparator)
match = true
}
})
if (!match) {
actions.push(temp[val] + currentSeparator)
}
})
return actions.join('').substring(0, actions.join('').length - 1)
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments, flag = true, i = 1
str = str.replace(/%s/g, function () {
var arg = args[i++]
if (typeof arg === 'undefined') {
flag = false
return ''
}
return arg
})
return flag ? str : ''
}
// 转换字符串undefined,null等转化为""
export function parseStrEmpty(str) {
if (!str || str == "undefined" || str == "null") {
return ""
}
return str
}
// 数据合并
export function mergeRecursive(source, target) {
for (var p in target) {
try {
if (target[p].constructor == Object) {
source[p] = mergeRecursive(source[p], target[p])
} else {
source[p] = target[p]
}
} catch (e) {
source[p] = target[p]
}
}
return source
}
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
*/
export function handleTree(data, id, parentId, children) {
let config = {
id: id || 'id',
parentId: parentId || 'parentId',
childrenList: children || 'children'
}
var childrenListMap = {}
var tree = []
for (let d of data) {
let id = d[config.id]
childrenListMap[id] = d
if (!d[config.childrenList]) {
d[config.childrenList] = []
}
}
for (let d of data) {
let parentId = d[config.parentId]
let parentObj = childrenListMap[parentId]
if (!parentObj) {
tree.push(d)
} else {
parentObj[config.childrenList].push(d)
}
}
return tree
}
/**
* 参数处理
* @param {*} params 参数
*/
export function tansParams(params) {
let result = ''
for (const propName of Object.keys(params)) {
const value = params[propName]
var part = encodeURIComponent(propName) + "="
if (value !== null && value !== "" && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']'
var subPart = encodeURIComponent(params) + "="
result += subPart + encodeURIComponent(value[key]) + "&"
}
}
} else {
result += part + encodeURIComponent(value) + "&"
}
}
}
return result
}
// 返回项目路径
export function getNormalPath(p) {
if (p.length === 0 || !p || p == 'undefined') {
return p
}
let res = p.replace('//', '/')
if (res[res.length - 1] === '/') {
return res.slice(0, res.length - 1)
}
return res
}
// 验证是否为blob格式
export function blobValidate(data) {
return data.type !== 'application/json'
}

99
src/utils/request.js Normal file
View File

@ -0,0 +1,99 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: import.meta.env.VITE_APP_BASE_API,
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
console.log(config)
// 过滤掉参数值为空的参数项
if (config.params) {
config.params = filterEmptyParams(config.params);
}
if (config.data && typeof config.data === 'object') {
// 根据Content-Type处理不同格式的数据
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
// 表单编码数据需要特殊处理
config.data = filterFormData(config.data);
} else {
config.data = filterEmptyParams(config.data);
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
/**
* 过滤空值参数
* @param {Object} params 参数对象
* @returns {Object} 过滤后的参数对象
*/
function filterEmptyParams(params) {
const filtered = {};
for (const key in params) {
const value = params[key];
// 保留非空值非null、非undefined、非空字符串、非空数组
if (value !== null && value !== undefined && value !== '') {
if (Array.isArray(value) && value.length === 0) {
continue; // 跳过空数组
}
filtered[key] = value;
}
}
return filtered;
}
/**
* 过滤表单编码数据
* @param {Object|string} data 表单数据
* @returns {string} 过滤后的表单字符串
*/
function filterFormData(data) {
if (typeof data === 'string') {
// 如果是字符串尝试解析为URLSearchParams
const params = new URLSearchParams(data);
for (const [key, value] of params.entries()) {
if (value === '' || value === 'null' || value === 'undefined') {
params.delete(key);
}
}
return params.toString();
} else if (typeof data === 'object') {
// 如果是对象先过滤空值再转换为URLSearchParams
const filtered = filterEmptyParams(data);
return new URLSearchParams(filtered).toString();
}
return data;
}
// 响应拦截器
service.interceptors.response.use(res => {
const code = res.data.errorCode || 0
const msg = res.data.errorMsg || ''
if (code === 20000) {
ElMessage({ message: msg, type: 'error' })
} else {
return Promise.resolve(res.data)
}
},
error => {
console.log('err' + error)
let { message } = error
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
export default service

59
src/views/Contact.vue Normal file
View File

@ -0,0 +1,59 @@
<template>
<div class="aboutUs">
<div class="banner">
<p class="bold">关于我们</p>
<p>团队成员主要由海洋地球物理学家软件工程师和数据管理员构成隶属于中国科学院深海科学与工程研究所开展船潜载地球物理数据处理和深海数据系统信息化工具开发的应用基础研究服务支撑fundingOptions深海深渊科考深海考古等国家重大需求</p>
<p class="bold">团队组成</p>
<p><span class="fw-700">陈传绪</span>团队负责人船潜载地球物理数据处理算法开发DSDS架构总设计</p>
<p class="fw-700">* DSDSDeep-Sea Data System</p>
<p><span class="fw-700">邹小珊</span>软件工程师负责 C/S 框架客户端软件和信息化工具开发</p>
<p><span class="fw-700">黄云明</span>软件工程师负责 B/S 框架航次潜次数据门户及应用开发</p>
<p><span class="fw-700">冯万丽</span>数据管理员负责航次和潜次数据预处理清洁规范化归档入库</p>
<p class="fw-700">* OUGPOnboard-Underwater Geophysics Processing</p>
<p><span class="fw-700">张汉羽</span>地球物理船潜载地球物理数据处理算法开发分布式光纤传感方向负责人</p>
<p><span class="fw-700">谢欣彤</span>地球物理船潜载地球物理数据处理和三维可视化</p>
<p><span class="fw-700">李栋</span>地球物理海底地震仪数据处理成像</p>
<p><span class="fw-700">廖佩铃</span>地球物理船潜载声学探测数据处理和成像</p>
<p><span class="fw-700">常瀚文</span>信息安全软件开发和数据安全</p>
<p class="bold">联系我们</p>
<p><span class="fw-700">陈传绪</span>chencx@idsse.ac.cn</p>
<p><span class="fw-700">张汉羽</span>zhanghy@idsse.ac.cn</p>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style lang="scss" scoped>
.aboutUs {
width: 100%;
background-image: url(@/assets/bg2.png);
background-size: 100% 100%;
display: flex;
justify-content: center;
}
.banner {
width: 1200px;
color: #ffffff;
padding: 100px 0;
font-size: 20px;
}
.bold {
text-align: center;
font-weight: bold;
margin: 40px 0 10px;
font-size: 30px;
}
p {
margin-bottom: 10px;
line-height: 50px;
}
.fw-700 {
font-weight: 700;
}
</style>

395
src/views/Home.vue Normal file
View File

@ -0,0 +1,395 @@
<template>
<div class="home-container">
<div class="banner">
<div class="title">
<div class="fs-56 bold">面向国家深海安全重大需求</div>
<div class="fs-48 bold">依托船潜作业平台</div>
<div class="fs-48">构建应急搜寻处置快速响应能力</div>
</div>
<div class="nums">
<div class="item">
<img src="@/assets/icons/任务.png" alt="任务" />
<div class="right">
<div><span>560</span></div>
<div>应急任务累计完成</div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/区域.png" alt="区域" />
<div class="right">
<div><span>2650</span></div>
<div>专项涧查区斌题盖</div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/航次.png" alt="航次" />
<div class="right">
<div><span>387</span></div>
<div>执行航次</div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/潜水艇.png" alt="潜水艇" />
<div class="right">
<div><span>260</span></div>
<div>载人深潜</div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/潜艇.png" alt="潜艇" />
<div class="right">
<div><span>893</span></div>
<div>无人潜水器作业</div>
</div>
</div>
</div>
</div>
<div class="module-title">搜寻处置任务</div>
<baidu-map class="map" :center="center" :zoom="zoom" @ready="handler">
<bm-view class="map-view"></bm-view>
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
<bm-marker
v-for="(item, index) in markers"
:key="index"
:position="item.position"
:icon="{url: item.icon, size: {width: 16, height: 16}}"
@click="markerClick(item.id)"
>
</bm-marker>
</baidu-map>
<div class="module-title">任务更新动态</div>
<div class="task">
<div class="item" v-for="(item, index) in dataList" :key="index">
<div class="icon">
<img :src="formatIcon(item.rescue_type, item.rescue_response_level)" alt="" />
</div>
<div class="right">
<div class="top">
<div class="tag" :class="{tag2: item.rescue_type === 'SI'}">{{ item.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</div>
<div class="name">{{ item.rescue_code }}{{ item.rescue_status }} <span v-if="item.rescue_type === 'SAR'">快速响应等级为{{ item.rescue_response_level }}</span></div>
</div>
<div class="info">
<el-row :gutter="20">
<el-col :span="12"><div class="label">搜寻处置目标<span>{{ item.rescue_target_name }}</span></div></el-col>
<el-col :span="12"><div class="label">搜寻处置目标尺寸<span>{{ item.rescue_target_length }} {{ item.rescue_target_width }} {{ item.rescue_target_height }}</span></div></el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12"><div class="label">搜寻处置目标位置<span>经度{{ item.rescue_target_lon }} 纬度{{ item.rescue_target_lat }}</span></div></el-col>
<el-col :span="12"><div class="label">发布时间<span>{{ item.fill_time }}</span></div></el-col>
</el-row>
</div>
</div>
</div>
</div>
<el-dialog
v-model="dialogVisible"
title="任务详情"
width="500"
>
<div class="item">
<div class="name">{{ currentMarker.rescue_code }}</div>
<div class="time">{{ currentMarker.fill_time }}</div>
<div class="row">
<div class="col">航次<span>{{ currentMarker.voyage_name }}</span></div>
<div class="col">任务状态<span>{{ currentMarker.rescue_status }}</span></div>
</div>
<div class="row">
<div class="col">快速响应等级<span>{{ currentMarker.rescue_response_level }}</span></div>
<div class="col">目标名称<span>{{ currentMarker.rescue_target_name }}</span></div>
</div>
<div class="row">
<div class="col">任务类型<span>{{ currentMarker.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</span></div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// icon
import waring1 from "@/assets/icons/告警级别1.png";
import waring2 from "@/assets/icons/告警级别2.png";
import waring3 from "@/assets/icons/告警级别3.png";
import success from "@/assets/icons/任务完成.png";
import markerIcon1 from "@/assets/icons/标注点1.png";
import markerIcon2 from "@/assets/icons/标注点2.png";
import markerIcon3 from "@/assets/icons/标注点3.png";
import { regPage } from '@/api/task.js'
//
const center = ref({ lng: 116.443, lat: 20.422 })
const zoom = ref(7)
const handler = ({ BMap, map }) => {
}
const dialogVisible = ref(false)
const currentMarker = ref(null)
const markerClick = (id) => {
currentMarker.value = dataList.value.find(item => item.tsy_id === id)
dialogVisible.value = true
console.log('标记被点击', currentMarker.value)
}
//
const hideWatermark = () => {
const originShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = (...args) => {
const shadowRoot = originShadow.call(this, ...args)
const style = document.createElement("style")
style.innerHTML = "div { display: none !important; }"
shadowRoot.appendChild(style)
return shadowRoot
};
}
// icon
const formatIcon = (type, level) => {
let img = null
if (type === 'SAR') {
if (level === '一级') {
img = waring1;
}
if (level === '二级') {
img = waring2;
}
if (level === '三级') {
img = waring3;
}
} else {
img = success;
}
return img
}
//
const dataList = ref([])
const markers = ref([])
//
const getDataList = () => {
regPage({
start: 0,
limit: 8
}).then(res => {
dataList.value = res.page.records
const data = []
dataList.value.forEach(item => {
if (item.rescue_status === '任务开始') {
data.push({
position: {
lng: item.rescue_target_lon,
lat: item.rescue_target_lat
},
icon: markerIcon1,
id: item.tsy_id
})
}
if (item.rescue_status === '任务处理中') {
data.push({
position: {
lng: item.rescue_target_lon,
lat: item.rescue_target_lat
},
icon: markerIcon2,
id: item.tsy_id
})
}
if (item.rescue_status === '任务已完成') {
data.push({
position: {
lng: item.rescue_target_lon,
lat: item.rescue_target_lat
},
icon: markerIcon3,
id: item.tsy_id
})
}
})
markers.value = data
})
}
onMounted(() => {
getDataList()
hideWatermark()
})
</script>
<style lang="scss" scoped>
.home-container {
padding: 20px 0;
.banner {
padding: 0 8%;
height: 650px;
.fs-56 {
font-size: 56px;
}
.fs-48 {
font-size: 48px;
}
.bold {
font-weight: bold;
color: rgb(76,213,243);
}
.nums {
margin-top: 120px;
display: flex;
justify-content: space-between;
column-gap: 10px;
.item {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
padding: 30px;
border-radius: 10px;
background-color: rgba(33, 54, 87, 0.7);
img {
width: 60px;
height: 60px;
}
span {
font-size: 40px;
font-weight: bold;
margin-right: 5px;
}
}
}
}
.module-title {
padding: 50px;
text-align: center;
font-size: 36px;
color: #242424;
font-weight: bold;
position: relative;
&::before,
&::after {
content: "";
display: inline-block;
width: 64px; /* 线条长度 */
height: 4px;
border-radius: 2px;
background-color: rgb(202,208,212);
vertical-align: middle;
margin: 0 30px; /* 控制文字与线条的间距 */
}
}
.map {
width: 100%;
height: 800px;
.map-view {
width: 100%;
height: 100%;
}
&:deep(.BMap_cpyCtrl) {
display: none;
}
&:deep(.anchorBL) {
display: none;
}
}
.task {
padding: 0 8%;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
color: #242424;
.item {
display: flex;
padding: 20px;
border-radius: 10px;
border: 2px solid #eee;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
transition: box-shadow 0.3s ease; /* 悬停动画 */
&:hover {
cursor: pointer;
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
border: 2px solid rgb(18,150,219);
}
.icon {
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
background-color: #eee;
margin-right: 20px;
img {
width: 60px;
height: 60px;
}
}
.right {
flex: 1;
.top {
display: flex;
align-items: center;
.tag {
margin-right: 12px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
padding: 0 8px;
color: #fdbb13;
border: 2px solid #fdbb13;
}
.tag2 {
color: rgb(18,150,219);
border: 2px solid rgb(18,150,219);
}
.name {
color: #000;
font-weight: bold;
}
}
.info {
width: 100%;
margin-top: 12px;
.label {
color: #aaa;
span {
color: #242424;
}
}
}
}
}
}
}
</style>

89
src/views/Statistics.vue Normal file
View File

@ -0,0 +1,89 @@
<template>
<div class="container">
<div class="title">深海应急搜捞 统计分析</div>
<div class="nums">
<div class="item">
<img src="@/assets/icons/任务.png" alt="任务" />
<div class="right">
<div>完成航次</div>
<div><span>2650</span></div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/区域.png" alt="区域" />
<div class="right">
<div>潜水次数</div>
<div><span>2650</span></div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/航次.png" alt="航次" />
<div class="right">
<div>挽回经济损失</div>
<div><span>2650</span></div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/潜水艇.png" alt="潜水艇" />
<div class="right">
<div>专项调查区域覆盖</div>
<div><span>2650</span>平方公里</div>
</div>
</div>
<div class="item">
<img src="@/assets/icons/潜艇.png" alt="潜艇" />
<div class="right">
<div>航行时间</div>
<div><span>2650</span>小时</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style lang="scss" scoped>
.container {
padding: 0 8%;
.title {
margin-top: 100px;
text-align: center;
font-size: 40px;
font-weight: bold;
}
.nums {
margin-top: 200px;
display: flex;
justify-content: space-between;
padding: 30px;
border-radius: 10px;
background-color: rgba(33, 54, 87, 0.7);
.item {
flex: 1;
display: flex;
align-items: center;
img {
width: 60px;
height: 60px;
margin-right: 20px;
}
span {
font-size: 40px;
font-weight: bold;
margin-right: 5px;
}
}
}
}
</style>

355
src/views/TaskDemand.vue Normal file
View File

@ -0,0 +1,355 @@
<template>
<div class="container">
<div class="left" v-show="isShow">
<img class="fold" v-show="isShow" src="@/assets/icons/折叠.png" @click="handleFold">
<div class="search">
<div class="input-bar">
<el-input
v-model="rescueCode"
style="width: 120px"
size="large"
placeholder="任务编号"
/>
<el-select
v-model="rescueType"
placeholder="任务类型"
size="large"
style="width: 120px"
>
<el-option label="应急搜捞" value="SAR" />
<el-option label="专项调查" value="SI" />
</el-select>
<el-select
v-model="rescueResponseLevel"
placeholder="响应等级"
size="large"
style="width: 120px"
>
<el-option label="一级" value="一级" />
<el-option label="二级" value="二级" />
<el-option label="三级" value="三级" />
</el-select>
</div>
</div>
<div class="btn-bar">
<el-button :icon="RefreshRight" @click="onReset">重置</el-button>
<el-button type="primary" :icon="Search" @click="onSearch">搜索</el-button>
</div>
<div class="line" />
<div class="list">
<div class="item" v-for="item in dataList" :key="item.id">
<div class="name">{{ item.rescue_code }}</div>
<div class="time">{{ item.fill_time }}</div>
<div class="row">
<div class="col">航次<span>{{ item.voyage_name }}</span></div>
<div class="col">任务状态<span>{{ item.rescue_status }}</span></div>
</div>
<div class="row">
<div class="col">快速响应等级<span>{{ item.rescue_response_level }}</span></div>
<div class="col">目标名称<span>{{ item.rescue_target_name }}</span></div>
</div>
<div class="row">
<div class="col">任务类型<span>{{ item.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</span></div>
</div>
</div>
</div>
<div class="pagination">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
/>
</div>
</div>
<baidu-map class="map" :center="center" :zoom="zoom" @ready="handler">
<img class="unfold" v-show="!isShow" src="@/assets/icons/展开.png" @click="handleUnfold">
<bm-view class="map-view"></bm-view>
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
<bm-marker
v-for="(item, index) in markers"
:key="index"
:position="item.position"
:icon="{url: item.icon, size: {width: 16, height: 16}}"
@click="markerClick(item.id)"
>
</bm-marker>
</baidu-map>
<el-dialog
v-model="dialogVisible"
title="任务详情"
width="500"
>
<div class="item">
<div class="name">{{ currentMarker.rescue_code }}</div>
<div class="time">{{ currentMarker.fill_time }}</div>
<div class="row">
<div class="col">航次<span>{{ currentMarker.voyage_name }}</span></div>
<div class="col">任务状态<span>{{ currentMarker.rescue_status }}</span></div>
</div>
<div class="row">
<div class="col">快速响应等级<span>{{ currentMarker.rescue_response_level }}</span></div>
<div class="col">目标名称<span>{{ currentMarker.rescue_target_name }}</span></div>
</div>
<div class="row">
<div class="col">任务类型<span>{{ currentMarker.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</span></div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import {ref, onMounted} from 'vue'
import { Search, RefreshRight } from '@element-plus/icons-vue'
import { regPage } from '@/api/task.js'
// icon
import markerIcon1 from "@/assets/icons/标注点1.png";
import markerIcon2 from "@/assets/icons/标注点2.png";
import markerIcon3 from "@/assets/icons/标注点3.png";
import {BaiduMap} from "vue-baidu-map-3x";
//
const isShow = ref(true)
const handleFold = () => {
isShow.value = false
}
const handleUnfold = () => {
isShow.value = true
}
const rescueCode = ref('')
const rescueType = ref('')
const rescueResponseLevel = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const start = ref(0)
const total = ref(0)
//
const dataList = ref([])
const markers = ref([])
const handleCurrentChange = (val) => {
currentPage.value = val
start.value = pageSize.value * (val -1)
getDataList()
}
//
const getDataList = () => {
regPage({
start: start.value,
limit: 10,
rescue_type: rescueType.value,
rescue_response_level: rescueResponseLevel.value,
rescue_code: rescueCode.value,
}).then(res => {
dataList.value = res.page.records
const data = []
dataList.value.forEach(item => {
if (item.rescue_status === '任务开始') {
data.push({
position: {
lng: item.rescue_target_lon,
lat: item.rescue_target_lat
},
icon: markerIcon1,
id: item.tsy_id
})
}
if (item.rescue_status === '任务处理中') {
data.push({
position: {
lng: item.rescue_target_lon,
lat: item.rescue_target_lat
},
icon: markerIcon2,
id: item.tsy_id
})
}
if (item.rescue_status === '任务已完成') {
data.push({
position: {
lng: item.rescue_target_lon,
lat: item.rescue_target_lat
},
icon: markerIcon3,
id: item.tsy_id
})
}
})
markers.value = data
total.value = res.page.total
})
}
const onReset = () => {
rescueType.value = ''
rescueResponseLevel.value = ''
rescueCode.value = ''
start.value = 0
getDataList()
}
const onSearch = () => {
start.value = 0
getDataList()
}
//
const center = ref({ lng: 116.443, lat: 20.422 })
const zoom = ref(7)
const handler = ({ BMap, map }) => {
}
const dialogVisible = ref(false)
const currentMarker = ref(null)
const markerClick = (id) => {
currentMarker.value = dataList.value.find(item => item.tsy_id === id)
dialogVisible.value = true
console.log('标记被点击', currentMarker.value)
}
//
const hideWatermark = () => {
const originShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = (...args) => {
const shadowRoot = originShadow.call(this, ...args)
const style = document.createElement("style")
style.innerHTML = "div { display: none !important; }"
shadowRoot.appendChild(style)
return shadowRoot
};
}
onMounted(() => {
getDataList()
hideWatermark()
})
</script>
<style lang="scss" scoped>
.container {
height: 820px;
display: flex;
.left {
width: 450px;
position: relative;
padding: 30px;
box-sizing: border-box;
.fold {
position: absolute;
top: 350px;
right: 0;
}
.search {
.input-bar {
display: flex;
justify-content: space-between;
:deep(.el-input-group__append) {
background-color: #409eff;
color: white;
box-shadow: none;
}
}
}
.btn-bar {
margin-top: 10px;
display: flex;
justify-content: center;
}
.line {
margin-top: 10px;
width: 100%;
height: 1px;
background-color: #ddd;
}
.list {
color: #333;
height: 640px;
overflow-y: scroll;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
.item {
padding: 30px 0;
border-bottom: 1px solid #dddddd;
&:hover .name {
color: #409eff;
}
.name {
padding-bottom: 5px;
color: #000;
font-weight: bold;
}
.row {
padding: 5px 0;
display: flex;
gap: 20px;
.col {
flex: 1;
color: #999;
span {
color: #333;
}
}
}
}
}
}
.map {
flex: 1;
width: 100%;
height: 100%;
position: relative;
.unfold {
position: absolute;
top: 350px;
left: 0;
}
.map-view {
width: 100%;
height: 100%;
}
&:deep(.BMap_cpyCtrl) {
display: none;
}
&:deep(.anchorBL) {
display: none;
}
}
}
.pagination {
margin: 10px 0 20px;
display: flex;
justify-content: center;
}
</style>

507
src/views/TaskInput.vue Normal file
View File

@ -0,0 +1,507 @@
<template>
<div class="container">
<div class="title">任务需求信息录入</div>
<el-divider />
<div class="info">任务信息</div>
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
label-width="auto"
class="ruleForm"
:size="formSize"
status-icon
>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="关联航次" prop="voyage_name">
<el-select v-model="ruleForm.voyage_name" >
<el-option v-for="(item, index) in voyageOptions" :key="index" :label="item.voyage_name" :value="item.voyage_name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态信息" prop="rescue_status">
<el-select v-model="ruleForm.rescue_status" >
<el-option label="任务开始" value="任务开始" />
<el-option label="任务处理中" value="任务处理中" />
<el-option label="任务已完成" value="任务已完成" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态变更时间" prop="rescue_status_time">
<el-date-picker
style="width: 100%"
v-model="ruleForm.rescue_status_time"
type="datetime"
placeholder="请选择"
format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="状态变更说明" prop="rescue_status_note">
<el-input placeholder="请输入" v-model="ruleForm.rescue_status_note" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="任务类型" prop="rescue_type">
<el-select v-model="ruleForm.rescue_type" >
<el-option label="应急搜捞" value="SAR" />
<el-option label="专项调查" value="SI" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标类别" prop="rescue_target_type">
<el-select v-model="ruleForm.rescue_target_type" >
<el-option label="大型沉物" value="Wreck" />
<el-option label="锚系类目标" value="Mooring" />
<el-option label="非合作方目标" value="NCT" />
<el-option label="其他" value="Other" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="目标名称" prop="rescue_target_name">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_name" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标经度" prop="rescue_target_lon">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_lon" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标纬度" prop="rescue_target_lat">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_lat" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="搜寻范围半径" prop="rescue_target_radius">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_radius">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标宽度" prop="rescue_target_width">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_width">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目标长度" prop="rescue_target_length">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_length">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="目标高度" prop="rescue_target_height">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_height">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="搜寻处置目标重量(空气中)" prop="rescue_air_weight">
<el-input placeholder="请输入" v-model="ruleForm.rescue_air_weight">
<template #append>千克</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="搜寻处置目标重量(水中)" prop="rescue_water_weight">
<el-input placeholder="请输入" v-model="ruleForm.rescue_water_weight">
<template #append>千克</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="搜寻处置目标水深" prop="rescue_water_depth">
<el-input placeholder="请输入" v-model="ruleForm.rescue_water_depth">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="搜寻处置目标预估价值" prop="rescue_target_price">
<el-input placeholder="请输入" v-model="ruleForm.rescue_target_price" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="快速响应等级" prop="rescue_response_level">
<el-select v-model="ruleForm.rescue_response_level" >
<el-option label="一级" value="一级" />
<el-option label="二级" value="二级" />
<el-option label="三级" value="三级" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="是否涉密" prop="rescue_secrecy">
<el-select v-model="ruleForm.rescue_secrecy" >
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="搜捞目标的所属单位" prop="rescue_unit">
<el-input placeholder="请输入" v-model="ruleForm.rescue_unit" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="快速响应时间要求" prop="rescue_response_day">
<el-input placeholder="请输入" v-model="ruleForm.rescue_response_day">
<template #append></template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="填报时间" prop="fill_time">
<el-date-picker
style="width: 100%"
v-model="ruleForm.fill_time"
type="datetime"
placeholder="请选择"
format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系人姓名" prop="fill_person">
<el-input placeholder="请输入" v-model="ruleForm.fill_person" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系人电话" prop="fill_tel">
<el-input placeholder="请输入" v-model="ruleForm.fill_tel" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="其他信息" prop="rescue_note">
<el-input placeholder="请输入" v-model="ruleForm.rescue_note" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="填报来源描述" prop="fill_note">
<el-input placeholder="请输入" v-model="ruleForm.fill_note" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="其他附件">
<el-button type="primary" @click="onFileList">查看附件</el-button>
</el-form-item>
</el-col>
</el-row>
<div class="btn-bar">
<el-button type="primary" @click="submitForm(ruleFormRef)">保存</el-button>
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
</div>
</el-form>
<el-dialog v-model="dialogTableVisible" title="附件列表" width="800">
<div class="upload-btn">
<el-upload
v-model:file-list="fileList"
class="upload-demo"
action="http://crm.hzzxq.com/ds/rescue/reg/file/upload.htm"
:show-file-list="false"
:data="{
rescue_id: rescueId
}"
:on-success="onSuccess"
>
<el-button type="primary">上传附件</el-button>
</el-upload>
</div>
<el-table :data="fileData">
<el-table-column property="file_org_name" label="文件名称" />
<el-table-column property="file_length" label="文件大小" width="150">
<template #default="scope">
<span class="file-size">{{ formatFileSize(scope.row.file_length) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center">
<template #default="scope">
<el-button link type="primary" size="small" @click="handleDownload(scope.row.tsy_id)">下载</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import axios from 'axios'
import { reactive, ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import type { ComponentSize, FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import { getParam, voyageReg, regEdit, regFind, regFileList } from '@/api/task.js'
const dialogTableVisible = ref(false)
const fileList = ref([])
const fileData = ref([])
const route = useRoute();
const rescueId = route.params.id; //
const formSize = ref<ComponentSize>('default')
const ruleFormRef = ref<FormInstance>()
const ruleForm = ref({
voyage_name: '',
rescue_status: '',
rescue_status_time: '',
rescue_status_note: '',
rescue_type: '',
rescue_target_type: '',
rescue_target_name: '',
rescue_target_lon: '',
rescue_target_lat: '',
rescue_target_radius: '',
rescue_target_width: '',
rescue_target_length: '',
rescue_target_height: '',
rescue_air_weight: '',
rescue_water_weight: '',
rescue_water_depth: '',
rescue_target_price: '',
rescue_response_level: '',
rescue_secrecy: '',
rescue_unit: '',
rescue_response_day: '',
fill_time: '',
fill_person: '',
fill_tel: '',
rescue_note: '',
fill_note: '',
})
const rules = reactive({
voyage_name: [
{ required: true, message: '请选择', trigger: 'change' },
],
rescue_status: [
{ required: true, message: '请选择', trigger: 'change' },
],
rescue_status_time: [
{ required: true, message: '请选择', trigger: 'change' },
],
rescue_status_note: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_type: [
{ required: true, message: '请选择', trigger: 'change' },
],
rescue_target_type: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_name: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_lon: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_lat: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_radius: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_width: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_length: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_height: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_air_weight: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_water_weight: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_water_depth: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_target_price: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_response_level: [
{ required: true, message: '请选择', trigger: 'change' },
],
rescue_secrecy: [
{ required: true, message: '请选择', trigger: 'change' },
],
rescue_unit: [
{ required: true, message: '请输入', trigger: 'blur' },
],
rescue_response_day: [
{ required: true, message: '请输入', trigger: 'blur' },
],
fill_time: [
{ required: true, message: '请选择', trigger: 'change' },
],
fill_person: [
{ required: true, message: '请输入', trigger: 'blur' },
],
fill_tel: [
{ required: true, message: '请输入', trigger: 'blur' },
],
})
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
regEdit(ruleForm.value).then(res => {
ruleForm.value = res.entity
ElMessage({
message: '提交成功',
type: 'success'
})
})
} else {
console.log('error submit!', fields)
}
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
//
const getDetail = () => {
regFind({rescue_id: rescueId}).then(res => {
ruleForm.value = res.entity
})
}
//
const onFileList = () => {
dialogTableVisible.value = true
regFileList({rescue_id: rescueId}).then(res => {
fileData.value = res.array
})
}
//
const formatFileSize = (bytes) => {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
//
const onSuccess = () => {
regFileList({rescue_id: rescueId}).then(res => {
fileData.value = res.array
})
}
//
const handleDownload = async (fileId) => {
console.log(`${import.meta.env.VITE_APP_BASE_API}/rescue/reg/file/download.htm?file_id=${fileId}`)
window.open(`${import.meta.env.VITE_APP_BASE_API}/rescue/reg/file/download.htm?file_id=${fileId}`)
}
const VoyageSocketUrl = ref('')
//
const getParamsList = () => {
getParam().then(res => {
const data = res.array.find(item => item.param_name === 'VoyageSocketUrl')
VoyageSocketUrl.value = data.param_value
getVoyageReg()
})
}
const voyageOptions = ref([])
//
const getVoyageReg = () => {
voyageReg({ baseURL: VoyageSocketUrl.value }).then(res => {
voyageOptions.value = res.array
})
}
onMounted(() => {
getParamsList()
if (rescueId) {
getDetail()
}
})
</script>
<style lang="scss" scoped>
.container {
padding: 20px;
color: #242424;
.title {
font-weight: bold;
color: #333;
}
.info {
display: inline-block;
padding: 0 20px 10px;
border-bottom: 2px solid #409eff;
}
.ruleForm {
margin-top: 20px;
.btn-bar {
display: flex;
justify-content: center;
}
}
}
.upload-btn {
text-align: right;
}
</style>

299
src/views/TaskSearch.vue Normal file
View File

@ -0,0 +1,299 @@
<template>
<div class="task-list">
<div class="search-bar">
<div class="left">
<el-input
v-model="searchQuery"
placeholder="请输入任务关键词"
class="search-input"
size="large"
>
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
<el-select v-model="rescueType" placeholder="请选择" class="filter-select" size="large">
<template #prefix>任务类型</template>
<el-option label="全部" value="" />
<el-option label="应急搜捞" value="SAR" />
<el-option label="专项调查" value="SI" />
</el-select>
<el-select v-model="rescueResponseLevel" placeholder="请选择" class="filter-select" size="large">
<template #prefix>快速响应等级</template>
<el-option label="全部" value="" />
<el-option label="一级" value="一级" />
<el-option label="二级" value="二级" />
<el-option label="三级" value="三级" />
</el-select>
<el-select v-model="rescueSecrecy" placeholder="请选择" class="filter-select" size="large">
<template #prefix>是否涉密</template>
<el-option label="全部" value="" />
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
<el-button size="large" :icon="Search" type="primary" @click="handleSearch">检索</el-button>
</div>
<div class="right">
<el-button size="large" type="primary">批量导入</el-button>
<el-button size="large" type="success" @click="handleInput">航次录入</el-button>
</div>
</div>
<div class="table">
<div class="row" v-for="(item,index) in dataList" :key="index" @click="onDetail(item.tsy_id)">
<div class="info">
<div class="top">
<div class="tag" :class="{tag2: item.rescue_type === 'SI'}">{{ item.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</div>
<div class="code">{{ item.rescue_code }}</div>
</div>
<div class="bottom">
<el-row :gutter="20">
<el-col :span="2">
<div class="label">状态</div>
<div class="value">{{ item.rescue_status }}</div>
</el-col>
<el-col :span="3">
<div class="label">搜寻处置目标</div>
<div class="value">{{ item.rescue_target_name }}</div>
</el-col>
<el-col :span="3">
<div class="label">快速响应等级</div>
<div class="value">{{ item.rescue_response_level }}</div>
</el-col>
<el-col :span="2">
<div class="label">是否涉密</div>
<div class="value">{{ item.rescue_secrecy }}</div>
</el-col>
<el-col :span="2">
<div class="label">联系人</div>
<div class="value">{{ item.fill_person }}</div>
</el-col>
<el-col :span="3">
<div class="label">填报时间</div>
<div class="value">{{ item.fill_time }}</div>
</el-col>
<el-col :span="3">
<div class="label">搜寻处置目标位置</div>
<div class="value">{{ item.rescue_target_lat }}{{ item.rescue_target_lon }}</div>
</el-col>
<el-col :span="3">
<div class="label">建议搜寻区域范围</div>
<div class="value">{{ item.rescue_target_radius }}</div>
</el-col>
<el-col :span="3">
<div class="label">搜寻处置目标价值</div>
<div class="value">{{ item.rescue_target_price }}</div>
</el-col>
</el-row>
</div>
</div>
<div class="right">
<el-icon><ArrowRightBold /></el-icon>
</div>
</div>
</div>
<div class="pagination">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router';
import { Search } from '@element-plus/icons-vue'
import { regPage } from '@/api/task.js'
const router = useRouter();
const searchQuery = ref('')
const rescueType = ref('')
const rescueResponseLevel = ref('')
const rescueSecrecy = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const start = ref(0)
const total = ref(0)
const dataList = ref([])
const handleSearch = () => {
start.value = 0
currentPage.value = 1
getDataList()
}
const handleInput = () => {
router.push('/input')
}
const handleSizeChange = (val: number) => {
pageSize.value = val
start.value = 0
currentPage.value = 1
getDataList()
}
const handleCurrentChange = (val: number) => {
currentPage.value = val
start.value = pageSize.value * (val -1)
getDataList()
}
//
const getDataList = () => {
regPage({
start: start.value,
limit: pageSize.value,
query: searchQuery.value,
rescue_type: rescueType.value,
rescue_response_level: rescueResponseLevel.value,
rescue_secrecy: rescueSecrecy.value,
}).then(res => {
dataList.value = res.page.records
total.value = res.page.total
})
}
//
const onDetail = (id: number) => {
router.push(`/input/${id}`)
}
onMounted(() => {
getDataList()
})
</script>
<style lang="scss" scoped>
.task-list {
padding: 20px 8%;
box-sizing: border-box;
min-height: calc(100vh - 220px);
background-color: rgb(241,244,251);
.search-bar {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
.left {
display: flex;
gap: 15px;
.search-input {
width: 200px;
}
.filter-select {
width: 200px;
}
}
}
.table {
color: #242424;
.row {
margin-bottom: 20px;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;
border-radius: 10px;
border: 2px solid transparent;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
&:hover {
cursor: pointer;
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
border: 2px solid rgb(18,150,219);
.right {
border: 2px solid transparent;
background-color: rgb(0,160,243);
color: #fff;
}
}
.info {
flex: 1;
.top {
display: flex;
align-items: center;
.tag {
margin-right: 12px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
padding: 0 8px;
color: #fdbb13;
border: 2px solid #fdbb13;
}
.tag2 {
color: rgb(18,150,219);
border: 2px solid rgb(18,150,219);
}
.code {
color: #000;
font-weight: bold;
}
}
.bottom {
margin-top: 10px;
.label {
font-size: 12px;
color: #bbb;
}
.value {
font-size: 14px;
color: #242424;
}
}
}
.right {
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
border: 2px solid rgb(0,160,243);
color: rgb(0,160,243);
font-size: 26px;
}
}
}
.pagination {
margin: 50px;
display: flex;
justify-content: center;
}
}
</style>

1
src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

24
tsconfig.app.json Normal file
View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

1
tsconfig.app.tsbuildinfo Normal file
View File

@ -0,0 +1 @@
{"root":["./src/main.ts","./src/vite-env.d.ts","./src/router/index.ts","./src/app.vue","./src/components/helloworld.vue","./src/views/contact.vue","./src/views/home.vue","./src/views/statistics.vue","./src/views/taskdemand.vue","./src/views/taskinput.vue","./src/views/tasksearch.vue"],"errors":true,"version":"5.8.3"}

12
tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"noEmitOnError": false, // 使 TS
"skipLibCheck": true, //
"strict": false //
}
}

22
tsconfig.node.json Normal file
View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}

View File

@ -0,0 +1 @@
{"root":["./vite.config.ts"],"errors":true,"version":"5.8.3"}

15
vite.config.ts Normal file
View File

@ -0,0 +1,15 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path';
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@components': resolve(__dirname, 'src/components'),
},
},
})

845
yarn.lock Normal file
View File

@ -0,0 +1,845 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/helper-string-parser@^7.25.9":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz"
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
"@babel/helper-validator-identifier@^7.25.9":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz"
integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
"@babel/parser@^7.25.3":
version "7.27.0"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz"
integrity sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==
dependencies:
"@babel/types" "^7.27.0"
"@babel/types@^7.27.0":
version "7.27.0"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz"
integrity sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==
dependencies:
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
"@ctrl/tinycolor@^3.4.1":
version "3.6.1"
resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz"
integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
"@element-plus/icons-vue@^2.3.1":
version "2.3.1"
resolved "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz"
integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==
"@esbuild/win32-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz"
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
"@floating-ui/core@^1.6.0":
version "1.6.9"
resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz"
integrity sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==
dependencies:
"@floating-ui/utils" "^0.2.9"
"@floating-ui/dom@^1.0.1":
version "1.6.13"
resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz"
integrity sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==
dependencies:
"@floating-ui/core" "^1.6.0"
"@floating-ui/utils" "^0.2.9"
"@floating-ui/utils@^0.2.9":
version "0.2.9"
resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz"
integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==
"@jridgewell/sourcemap-codec@^1.5.0":
version "1.5.0"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
"@parcel/watcher-win32-x64@2.5.1":
version "2.5.1"
resolved "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz"
integrity sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==
"@parcel/watcher@^2.4.1":
version "2.5.1"
resolved "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz"
integrity sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==
dependencies:
detect-libc "^1.0.3"
is-glob "^4.0.3"
micromatch "^4.0.5"
node-addon-api "^7.0.0"
optionalDependencies:
"@parcel/watcher-android-arm64" "2.5.1"
"@parcel/watcher-darwin-arm64" "2.5.1"
"@parcel/watcher-darwin-x64" "2.5.1"
"@parcel/watcher-freebsd-x64" "2.5.1"
"@parcel/watcher-linux-arm-glibc" "2.5.1"
"@parcel/watcher-linux-arm-musl" "2.5.1"
"@parcel/watcher-linux-arm64-glibc" "2.5.1"
"@parcel/watcher-linux-arm64-musl" "2.5.1"
"@parcel/watcher-linux-x64-glibc" "2.5.1"
"@parcel/watcher-linux-x64-musl" "2.5.1"
"@parcel/watcher-win32-arm64" "2.5.1"
"@parcel/watcher-win32-ia32" "2.5.1"
"@parcel/watcher-win32-x64" "2.5.1"
"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
version "2.11.7"
resolved "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz"
integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==
"@rollup/rollup-win32-x64-msvc@4.40.0":
version "4.40.0"
resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz"
integrity sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==
"@types/estree@1.0.7":
version "1.0.7"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz"
integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
"@types/lodash-es@*", "@types/lodash-es@^4.17.6":
version "4.17.12"
resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz"
integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==
dependencies:
"@types/lodash" "*"
"@types/lodash@*", "@types/lodash@^4.14.182":
version "4.17.16"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz"
integrity sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==
"@types/web-bluetooth@^0.0.16":
version "0.0.16"
resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz"
integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
"@vitejs/plugin-vue@^5.1.3":
version "5.2.3"
resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.3.tgz"
integrity sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==
"@volar/language-core@~2.4.11", "@volar/language-core@2.4.12":
version "2.4.12"
resolved "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.12.tgz"
integrity sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==
dependencies:
"@volar/source-map" "2.4.12"
"@volar/source-map@2.4.12":
version "2.4.12"
resolved "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.12.tgz"
integrity sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==
"@volar/typescript@~2.4.11":
version "2.4.12"
resolved "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.12.tgz"
integrity sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==
dependencies:
"@volar/language-core" "2.4.12"
path-browserify "^1.0.1"
vscode-uri "^3.0.8"
"@vue/compiler-core@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz"
integrity sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==
dependencies:
"@babel/parser" "^7.25.3"
"@vue/shared" "3.5.13"
entities "^4.5.0"
estree-walker "^2.0.2"
source-map-js "^1.2.0"
"@vue/compiler-dom@^3.5.0", "@vue/compiler-dom@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz"
integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==
dependencies:
"@vue/compiler-core" "3.5.13"
"@vue/shared" "3.5.13"
"@vue/compiler-sfc@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz"
integrity sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==
dependencies:
"@babel/parser" "^7.25.3"
"@vue/compiler-core" "3.5.13"
"@vue/compiler-dom" "3.5.13"
"@vue/compiler-ssr" "3.5.13"
"@vue/shared" "3.5.13"
estree-walker "^2.0.2"
magic-string "^0.30.11"
postcss "^8.4.48"
source-map-js "^1.2.0"
"@vue/compiler-ssr@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz"
integrity sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==
dependencies:
"@vue/compiler-dom" "3.5.13"
"@vue/shared" "3.5.13"
"@vue/compiler-vue2@^2.7.16":
version "2.7.16"
resolved "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz"
integrity sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==
dependencies:
de-indent "^1.0.2"
he "^1.2.0"
"@vue/devtools-api@^6.6.4":
version "6.6.4"
resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz"
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
"@vue/language-core@2.2.8":
version "2.2.8"
resolved "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.8.tgz"
integrity sha512-rrzB0wPGBvcwaSNRriVWdNAbHQWSf0NlGqgKHK5mEkXpefjUlVRP62u03KvwZpvKVjRnBIQ/Lwre+Mx9N6juUQ==
dependencies:
"@volar/language-core" "~2.4.11"
"@vue/compiler-dom" "^3.5.0"
"@vue/compiler-vue2" "^2.7.16"
"@vue/shared" "^3.5.0"
alien-signals "^1.0.3"
minimatch "^9.0.3"
muggle-string "^0.4.1"
path-browserify "^1.0.1"
"@vue/reactivity@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz"
integrity sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==
dependencies:
"@vue/shared" "3.5.13"
"@vue/runtime-core@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz"
integrity sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==
dependencies:
"@vue/reactivity" "3.5.13"
"@vue/shared" "3.5.13"
"@vue/runtime-dom@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz"
integrity sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==
dependencies:
"@vue/reactivity" "3.5.13"
"@vue/runtime-core" "3.5.13"
"@vue/shared" "3.5.13"
csstype "^3.1.3"
"@vue/server-renderer@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz"
integrity sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==
dependencies:
"@vue/compiler-ssr" "3.5.13"
"@vue/shared" "3.5.13"
"@vue/shared@^3.5.0", "@vue/shared@3.5.13":
version "3.5.13"
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz"
integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
"@vueuse/core@^9.1.0":
version "9.13.0"
resolved "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz"
integrity sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==
dependencies:
"@types/web-bluetooth" "^0.0.16"
"@vueuse/metadata" "9.13.0"
"@vueuse/shared" "9.13.0"
vue-demi "*"
"@vueuse/metadata@9.13.0":
version "9.13.0"
resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz"
integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==
"@vueuse/shared@9.13.0":
version "9.13.0"
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz"
integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==
dependencies:
vue-demi "*"
"@yangjianfei/bmaplib.lushu@^1.0.0":
version "1.0.0"
resolved "https://registry.npmmirror.com/@yangjianfei/bmaplib.lushu/-/bmaplib.lushu-1.0.0.tgz"
integrity sha512-qZVijbgUgNs6tsP1muS67x0XzE5fJ3kFireouDvXO3bUYVV6XbpjZXksQTsggihLMIEvC1DO9GS9vVF8CnEeqQ==
alien-signals@^1.0.3:
version "1.0.13"
resolved "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz"
integrity sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==
async-validator@^4.2.5:
version "4.2.5"
resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz"
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@^1.6.7:
version "1.8.4"
resolved "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz"
integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
bmaplib.curveline@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/bmaplib.curveline/-/bmaplib.curveline-1.0.0.tgz"
integrity sha512-9wcFMVhiYxNPqpvsLDAADn3qDhNzXp2mA6VyHSHg2XOAgSooC7ZiujdFhy0sp+0QYjTfJ/MjmLuNoUg2HHxH4Q==
bmaplib.distancetool@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/bmaplib.distancetool/-/bmaplib.distancetool-1.0.2.tgz"
integrity sha512-EvxMnQRH6xM036zx5OLPyTg5tMCTbFBuGTTHOtExLy2/T0X6v5Va0YE7c3IPm/a/Eo5V/ynYpOLOLZbRY8ccyA==
bmaplib.heatmap@^1.0.4:
version "1.0.4"
resolved "https://registry.npmmirror.com/bmaplib.heatmap/-/bmaplib.heatmap-1.0.4.tgz"
integrity sha512-rmhqUARBpUSJ9jXzUI2j7dIOqnc38bqubkx/8a349U2qtw/ulLUwyzRD535OrA8G7w5cz4aPKm6/rNvUAarg/Q==
bmaplib.markerclusterer@^1.0.13:
version "1.0.13"
resolved "https://registry.npmmirror.com/bmaplib.markerclusterer/-/bmaplib.markerclusterer-1.0.13.tgz"
integrity sha512-VrLyWSiuDEVNi0yUfwOhFQ6z1oEEHS4w36GNu3iASu6p52QIx9uAXMUkuSCHReNR0bj2Cp9SA1dSx5RpojXajQ==
dependencies:
bmaplib.texticonoverlay "^1.0.2"
bmaplib.texticonoverlay@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/bmaplib.texticonoverlay/-/bmaplib.texticonoverlay-1.0.2.tgz"
integrity sha512-4ZTWr4ZP3B6qEWput5Tut16CfZgII38YwM3bpyb4gFTQyORlKYryFp9WHWrwZZaHlOyYDAXG9SX0hka43jTADg==
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
chokidar@^4.0.0:
version "4.0.3"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz"
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
dependencies:
readdirp "^4.0.1"
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
dayjs@^1.11.13:
version "1.11.13"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz"
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
de-indent@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz"
integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
detect-libc@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz"
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-errors "^1.3.0"
gopd "^1.2.0"
element-plus@^2.5.6:
version "2.9.7"
resolved "https://registry.npmjs.org/element-plus/-/element-plus-2.9.7.tgz"
integrity sha512-6vjZh5SXBncLhUwJGTVKS5oDljfgGMh6J4zVTeAZK3YdMUN76FgpvHkwwFXocpJpMbii6rDYU3sgie64FyPerQ==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.3.1"
"@floating-ui/dom" "^1.0.1"
"@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7"
"@types/lodash" "^4.14.182"
"@types/lodash-es" "^4.17.6"
"@vueuse/core" "^9.1.0"
async-validator "^4.2.5"
dayjs "^1.11.13"
escape-html "^1.0.3"
lodash "^4.17.21"
lodash-es "^4.17.21"
lodash-unified "^1.0.2"
memoize-one "^6.0.0"
normalize-wheel-es "^1.2.0"
entities@^4.5.0:
version "4.5.0"
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
dependencies:
es-errors "^1.3.0"
es-set-tostringtag@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
dependencies:
es-errors "^1.3.0"
get-intrinsic "^1.2.6"
has-tostringtag "^1.0.2"
hasown "^2.0.2"
esbuild@^0.21.3:
version "0.21.5"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz"
integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
optionalDependencies:
"@esbuild/aix-ppc64" "0.21.5"
"@esbuild/android-arm" "0.21.5"
"@esbuild/android-arm64" "0.21.5"
"@esbuild/android-x64" "0.21.5"
"@esbuild/darwin-arm64" "0.21.5"
"@esbuild/darwin-x64" "0.21.5"
"@esbuild/freebsd-arm64" "0.21.5"
"@esbuild/freebsd-x64" "0.21.5"
"@esbuild/linux-arm" "0.21.5"
"@esbuild/linux-arm64" "0.21.5"
"@esbuild/linux-ia32" "0.21.5"
"@esbuild/linux-loong64" "0.21.5"
"@esbuild/linux-mips64el" "0.21.5"
"@esbuild/linux-ppc64" "0.21.5"
"@esbuild/linux-riscv64" "0.21.5"
"@esbuild/linux-s390x" "0.21.5"
"@esbuild/linux-x64" "0.21.5"
"@esbuild/netbsd-x64" "0.21.5"
"@esbuild/openbsd-x64" "0.21.5"
"@esbuild/sunos-x64" "0.21.5"
"@esbuild/win32-arm64" "0.21.5"
"@esbuild/win32-ia32" "0.21.5"
"@esbuild/win32-x64" "0.21.5"
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
follow-redirects@^1.15.6:
version "1.15.9"
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz"
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
form-data@^4.0.0:
version "4.0.2"
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz"
integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
es-set-tostringtag "^2.1.0"
mime-types "^2.1.12"
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
get-intrinsic@^1.2.6:
version "1.3.0"
resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
dependencies:
call-bind-apply-helpers "^1.0.2"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.1.1"
function-bind "^1.1.2"
get-proto "^1.0.1"
gopd "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
math-intrinsics "^1.1.0"
get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
dependencies:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
has-tostringtag@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
he@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
immutable@^5.0.2:
version "5.1.1"
resolved "https://registry.npmjs.org/immutable/-/immutable-5.1.1.tgz"
integrity sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
lodash-es@*, lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash-unified@^1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz"
integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==
lodash@*, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
magic-string@^0.30.11:
version "0.30.17"
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz"
integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.5.0"
math-intrinsics@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
micromatch@^4.0.5:
version "4.0.8"
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
braces "^3.0.3"
picomatch "^2.3.1"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
minimatch@^9.0.3:
version "9.0.5"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
dependencies:
brace-expansion "^2.0.1"
muggle-string@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz"
integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==
nanoid@^3.3.8:
version "3.3.11"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz"
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
node-addon-api@^7.0.0:
version "7.1.1"
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz"
integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==
normalize-wheel-es@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz"
integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
path-browserify@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz"
integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
postcss@^8.4.43, postcss@^8.4.48:
version "8.5.3"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz"
integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==
dependencies:
nanoid "^3.3.8"
picocolors "^1.1.1"
source-map-js "^1.2.1"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
readdirp@^4.0.1:
version "4.1.2"
resolved "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz"
integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
rollup@^4.20.0:
version "4.40.0"
resolved "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz"
integrity sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==
dependencies:
"@types/estree" "1.0.7"
optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.40.0"
"@rollup/rollup-android-arm64" "4.40.0"
"@rollup/rollup-darwin-arm64" "4.40.0"
"@rollup/rollup-darwin-x64" "4.40.0"
"@rollup/rollup-freebsd-arm64" "4.40.0"
"@rollup/rollup-freebsd-x64" "4.40.0"
"@rollup/rollup-linux-arm-gnueabihf" "4.40.0"
"@rollup/rollup-linux-arm-musleabihf" "4.40.0"
"@rollup/rollup-linux-arm64-gnu" "4.40.0"
"@rollup/rollup-linux-arm64-musl" "4.40.0"
"@rollup/rollup-linux-loongarch64-gnu" "4.40.0"
"@rollup/rollup-linux-powerpc64le-gnu" "4.40.0"
"@rollup/rollup-linux-riscv64-gnu" "4.40.0"
"@rollup/rollup-linux-riscv64-musl" "4.40.0"
"@rollup/rollup-linux-s390x-gnu" "4.40.0"
"@rollup/rollup-linux-x64-gnu" "4.40.0"
"@rollup/rollup-linux-x64-musl" "4.40.0"
"@rollup/rollup-win32-arm64-msvc" "4.40.0"
"@rollup/rollup-win32-ia32-msvc" "4.40.0"
"@rollup/rollup-win32-x64-msvc" "4.40.0"
fsevents "~2.3.2"
sass@*, sass@^1.71.1:
version "1.86.3"
resolved "https://registry.npmjs.org/sass/-/sass-1.86.3.tgz"
integrity sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==
dependencies:
chokidar "^4.0.0"
immutable "^5.0.2"
source-map-js ">=0.6.2 <2.0.0"
optionalDependencies:
"@parcel/watcher" "^2.4.1"
source-map-js@^1.2.0, source-map-js@^1.2.1, "source-map-js@>=0.6.2 <2.0.0":
version "1.2.1"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
tiny-emitter@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
typescript@*, typescript@^5.5.3, typescript@>=5.0.0:
version "5.8.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz"
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
"vite@^5.0.0 || ^6.0.0", vite@^5.4.2:
version "5.4.18"
resolved "https://registry.npmjs.org/vite/-/vite-5.4.18.tgz"
integrity sha512-1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA==
dependencies:
esbuild "^0.21.3"
postcss "^8.4.43"
rollup "^4.20.0"
optionalDependencies:
fsevents "~2.3.3"
vscode-uri@^3.0.8:
version "3.1.0"
resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz"
integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==
vue-baidu-map-3x@^1.0.40:
version "1.0.40"
resolved "https://registry.npmmirror.com/vue-baidu-map-3x/-/vue-baidu-map-3x-1.0.40.tgz"
integrity sha512-Rq3g1KNsNztkuX3SJIuCpy6HE3xHVX8ySgqS2xC3jut/hvVr5kFBS0Nu7uYppk3xYVz69S1JFxU8WUI0Xftpyg==
dependencies:
"@yangjianfei/bmaplib.lushu" "^1.0.0"
bmaplib.curveline "^1.0.0"
bmaplib.distancetool "^1.0.2"
bmaplib.heatmap "^1.0.4"
bmaplib.markerclusterer "^1.0.13"
tiny-emitter "^2.1.0"
vue "^3.2.25"
vue-router "^4.0.14"
vue-demi@*:
version "0.14.10"
resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz"
integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==
vue-router@^4.0.14, vue-router@^4.3.0:
version "4.5.0"
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz"
integrity sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==
dependencies:
"@vue/devtools-api" "^6.6.4"
vue-tsc@^2.1.4:
version "2.2.8"
resolved "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.8.tgz"
integrity sha512-jBYKBNFADTN+L+MdesNX/TB3XuDSyaWynKMDgR+yCSln0GQ9Tfb7JS2lr46s2LiFUT1WsmfWsSvIElyxzOPqcQ==
dependencies:
"@volar/typescript" "~2.4.11"
"@vue/language-core" "2.2.8"
"vue@^3.0.0-0 || ^2.6.0", vue@^3.2.0, vue@^3.2.25, vue@^3.4.38, vue@3.5.13:
version "3.5.13"
resolved "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz"
integrity sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==
dependencies:
"@vue/compiler-dom" "3.5.13"
"@vue/compiler-sfc" "3.5.13"
"@vue/runtime-dom" "3.5.13"
"@vue/server-renderer" "3.5.13"
"@vue/shared" "3.5.13"