完成统计分析板块
This commit is contained in:
parent
80a377b599
commit
db0448b468
|
|
@ -18,7 +18,7 @@ module.exports = merge(prodEnv, {
|
|||
|
||||
VUE_APP_BASE_API: '"/api"',
|
||||
// VUE_APP_BASE_APIURL: '"http://ds2.hzzxq.com/api2"',
|
||||
VUE_APP_BASE_APIURL: '"http://crm.hzzxq.com/ds"',
|
||||
VUE_APP_BASE_APIURL: '"http://test.gopmas.com/ds"',
|
||||
VUE_APP_FULL_API: '"http://10.10.151.5:5555"',
|
||||
VUE_APP_BASE_API_FRONT: '"http://10.10.150.128:8080/satellitePub/pub/index.html"',
|
||||
VUE_APP_FILE_API: '"http://10.10.151.5:5555/archives"',
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module.exports = {
|
|||
// target: 'http://10.0.90.70', // 测试环境
|
||||
// target: 'http://1.95.42.191:8080', // 测试环境
|
||||
// target: 'http://ds2.hzzxq.com/api2', // 测试环境
|
||||
target: 'http://crm.hzzxq.com/ds', // 测试环境
|
||||
target: 'http://test.gopmas.com/ds', // 测试环境
|
||||
changeOrigin: true, // 是否跨域
|
||||
secure: false, // 是否使用https
|
||||
pathRewrite: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 报表配置查询接口
|
||||
export function reportList(data) {
|
||||
return request({
|
||||
url: '/report/type/list.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 科考船汇总统计属性
|
||||
export function shipTotal(data) {
|
||||
return request({
|
||||
url: '/report/ship/total.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 科考船航次统计
|
||||
export function shipVoyage(data) {
|
||||
return request({
|
||||
url: '/report/ship/voyage.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 科考船参航单位统计
|
||||
export function shipUnit(data) {
|
||||
return request({
|
||||
url: '/report/ship/unit.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 科考船参航单位统计(年度)
|
||||
export function shipUnitYear(data) {
|
||||
return request({
|
||||
url: '/report/ship/unit/year.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 载人潜水器汇总统计属性
|
||||
export function platformHov(data) {
|
||||
return request({
|
||||
url: '/report/platform/hov.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 载人潜水器潜次统计
|
||||
export function hovDiving(data) {
|
||||
return request({
|
||||
url: '/report/platform/hov/diving.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 载人潜水器参航单位统计
|
||||
export function hovUnit(data) {
|
||||
return request({
|
||||
url: '/report/platform/hov/unit.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 载人潜水器参航单位统计(年度)
|
||||
export function hovUnitYear(data) {
|
||||
return request({
|
||||
url: '/report/platform/hov/unit/year.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 无人航行潜水器统计
|
||||
export function platformAuv(data) {
|
||||
return request({
|
||||
url: '/report/platform/auv.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 遥控潜水器潜水器统计
|
||||
export function platformRov(data) {
|
||||
return request({
|
||||
url: '/report/platform/rov.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
/* ********************************* 角色列表 **************************************/
|
||||
|
||||
// 角色列表
|
||||
export function roleList(data) {
|
||||
return request({
|
||||
url: '/frame/role/page.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/* ********************************* 用户列表 **************************************/
|
||||
|
||||
// 用户列表
|
||||
export function optrList(data) {
|
||||
return request({
|
||||
url: '/frame/optr/page.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户新增
|
||||
export function optrAdd(data) {
|
||||
return request({
|
||||
url: '/frame/optr/add.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户编辑
|
||||
export function optrEdit(data) {
|
||||
return request({
|
||||
url: '/frame/optr/edit.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户删除
|
||||
export function optrDelete(data) {
|
||||
return request({
|
||||
url: '/frame/optr/delete.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/* ********************************* 航次管理 **************************************/
|
||||
// 航次列表
|
||||
export function regList(data) {
|
||||
return request({
|
||||
url: '/voyage/reg/list.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 分配航次
|
||||
export function regGrant(data) {
|
||||
return request({
|
||||
url: '/voyage/reg/optr/grant.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 清除航次
|
||||
export function regClear(data) {
|
||||
return request({
|
||||
url: '/voyage/reg/optr/clear.htm',
|
||||
method: 'post',
|
||||
type: 'application/x-www-form-urlencoded',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -170,11 +170,11 @@ export default {
|
|||
path:"visitorUnit",
|
||||
children:[]
|
||||
},
|
||||
{
|
||||
name:"共享单位",
|
||||
path:"sharedUnit",
|
||||
children:[]
|
||||
},
|
||||
// {
|
||||
// name:"共享单位",
|
||||
// path:"sharedUnit",
|
||||
// children:[]
|
||||
// },
|
||||
{
|
||||
name:"资助机构",
|
||||
path:"fundingAgencies",
|
||||
|
|
@ -195,11 +195,11 @@ export default {
|
|||
path:"roleManage",
|
||||
children:[]
|
||||
},
|
||||
{
|
||||
name:"单位管理",
|
||||
path:"unitManage",
|
||||
children:[]
|
||||
}
|
||||
// {
|
||||
// name:"单位管理",
|
||||
// path:"unitManage",
|
||||
// children:[]
|
||||
// }
|
||||
]
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -358,6 +358,16 @@ export const constantRoutes = [
|
|||
loginAuthority: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'hov',
|
||||
name: 'hov',
|
||||
component: () => import('@/views/statistics/HovStatistics.vue'),
|
||||
meta: {
|
||||
title: '载人潜水器汇总统计',
|
||||
icon: 'peoples',
|
||||
loginAuthority: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'AboutUs',
|
||||
name: 'AboutUs',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
export function getYearRange(date) {
|
||||
// 获取传入日期的年份
|
||||
const year = date.getFullYear()
|
||||
|
||||
// 创建年份开始日期 (当年1月1日)
|
||||
const startOfYear = new Date(year, 0, 1)
|
||||
|
||||
// 创建年份结束日期 (当年12月31日)
|
||||
const endOfYear = new Date(year, 11, 31)
|
||||
|
||||
// 格式化日期为 YYYY-MM-DD
|
||||
function formatDate(dateObj) {
|
||||
const y = dateObj.getFullYear()
|
||||
const m = String(dateObj.getMonth() + 1).padStart(2, '0') // 月份从0开始,需要+1
|
||||
const d = String(dateObj.getDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${d}`
|
||||
}
|
||||
|
||||
return {
|
||||
start: formatDate(startOfYear),
|
||||
end: formatDate(endOfYear)
|
||||
}
|
||||
}
|
||||
|
||||
export function filterDictItems(data, dictName) {
|
||||
return data.filter(item => item.report_type === dictName)
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="aboutUs">
|
||||
<div class="banner">
|
||||
<p class="bold">关于我们</p>
|
||||
<p>团队成员主要由海洋地球物理学家、软件工程师和数据管理员构成,隶属于中国科学院深海科学与工程研究所,开展船潜载地球物理数据处理和深海数据系统信息化工具开发的应用基础研究,服务支撑fundingOptions、深海深渊科考、深海考古等国家重大需求。</p>
|
||||
<p>团队成员主要由海洋地球物理学家、软件工程师和数据管理员构成,隶属于中国科学院深海科学与工程研究所,开展船潜载地球物理数据处理和深海数据系统信息化工具开发的应用基础研究,服务支撑、深海深渊科考、深海考古等国家重大需求。</p>
|
||||
<p class="bold">团队组成</p>
|
||||
<p><span class="fw-700">陈传绪</span>:团队负责人,船潜载地球物理数据处理、算法开发,DSDS架构总设计。</p>
|
||||
<p class="fw-700">* DSDS(Deep-Sea Data System)</p>
|
||||
|
|
|
|||
|
|
@ -27,11 +27,19 @@
|
|||
</div>
|
||||
<div class="left4" v-if="radio == '数据样品集'">
|
||||
<div v-for="(item, index) in dataList" :key="index" :id="item.tsy_id" class="left4_1" >
|
||||
|
||||
<div class="left4_top">
|
||||
<p @click="openList(item, 'list')" style="font-weight: 400;font-size: 14px;cursor: pointer;color: #409eff" >{{ item.dataset_name }} <span class="mileage">{{ item.file_total }}</span></p>
|
||||
<span class="org">{{ item.create_time }}</span>
|
||||
</div>
|
||||
<ul v-show="currenId == item.tsy_id && fold">
|
||||
<li :class="sample.tsy_id == currenSample ? 'bg-color' : ''" class="sample" :id="sample.tsy_id"
|
||||
v-for="(sample, i) in item.sampleArray" :key="i" @click.stop="onSample(sample)">{{ sample.sample_name }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="left4_list">
|
||||
<div class="list1">
|
||||
<p>航次:</p>
|
||||
<span class="hover-color" @click="turnDeatilPage(item)">{{ item.voyage_name }}</span>
|
||||
<span class="hover-color" style="color: #409eff" @click="turnDeatilPage(item)">{{ item.voyage_name }}</span>
|
||||
</div>
|
||||
<div class="list1">
|
||||
<p>平台类型:</p>
|
||||
|
|
@ -65,24 +73,15 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div class="left4_top">
|
||||
<p @click="openList(item, 'list')" style="font-weight: 400;font-size: 14px;cursor: pointer" :style="currentSample === item.tsy_id ? 'color: #409eff' : ''">{{ item.dataset_name }} <span class="mileage">{{ item.file_total }}</span></p>
|
||||
<span class="org">{{ item.create_time }}</span>
|
||||
</div>
|
||||
<ul v-show="currenId == item.tsy_id && fold">
|
||||
<li :class="sample.tsy_id == currenSample ? 'bg-color' : ''" class="sample" :id="sample.tsy_id"
|
||||
v-for="(sample, i) in item.sampleArray" :key="i" @click.stop="onSample(sample)">{{ sample.sample_name }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="left4" v-if="radio == '航次'">
|
||||
<div v-for="(item, index) in dataList" :key="index" class="left4_1" style="cursor: pointer" :id="item.tsy_id" @click="turnDeatilPage(item)">
|
||||
<div v-for="(item, index) in dataList" :key="index" class="left4_1" style="cursor: pointer" :id="item.tsy_id">
|
||||
<div class="left4_top">
|
||||
<p :style="currentVoyage === item.tsy_id ? 'color: #409eff' : ''">{{ item.voyage_name }} <span
|
||||
class="mileage">{{ item.voyage_mileage }}海里</span></p>
|
||||
<p :style="currentVoyage === item.tsy_id ? 'color: #409eff' : ''">
|
||||
<span style="color: #409eff" @click="turnDeatilPage(item)">{{ item.voyage_name }}</span>
|
||||
<span class="mileage">{{ item.voyage_mileage }}海里</span></p>
|
||||
<span class="org">{{ item.funding_org }}</span>
|
||||
</div>
|
||||
<div class="left4_list">
|
||||
|
|
@ -271,9 +270,6 @@ export default {
|
|||
rendered: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getParams()
|
||||
},
|
||||
watch: {
|
||||
radio(val) {
|
||||
this.dataList = []
|
||||
|
|
@ -314,23 +310,11 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 获取从参数列表
|
||||
getParams() {
|
||||
getParamsList().then(res => {
|
||||
const arr = res.array
|
||||
if (arr.length) {
|
||||
arr.forEach(item => {
|
||||
if (item.param_name === 'CesiumHostAddr') {
|
||||
// this.CesiumHostAddr = item.param_value
|
||||
this.CesiumHostAddr = `${window.location.protocol}//${window.location.hostname}:${window.location.port}/tiles/`
|
||||
mounted() {
|
||||
this.imageryViewModels = setImageryViewModels(this.CesiumHostAddr)
|
||||
this.initCesium()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 获取菜单
|
||||
handleMenu() {
|
||||
this.dataList = []
|
||||
|
|
@ -642,12 +626,13 @@ export default {
|
|||
this.viewer.imageryLayers.addImageryProvider(contour6000)
|
||||
},
|
||||
turnDeatilPage(item) {
|
||||
this.$router.push({
|
||||
const routeData = this.$router.resolve({
|
||||
name: 'dataDetail',
|
||||
query: {
|
||||
voyage_name: item.voyage_name
|
||||
}
|
||||
})
|
||||
window.open(routeData.href, '_blank')
|
||||
},
|
||||
shousuo() {
|
||||
this.show = true
|
||||
|
|
@ -807,12 +792,13 @@ export default {
|
|||
font-size: 16px;
|
||||
color: #212121;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
//display: flex;
|
||||
//justify-content: space-between;
|
||||
|
||||
.mileage {
|
||||
font-size: 12px;
|
||||
color: #909fa7;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,13 @@
|
|||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" v-if="form.sample_tag_name === '应急搜捞'">
|
||||
<el-form-item label="覆盖宽度" prop="conver_width">
|
||||
<el-input v-model="form.conver_width">
|
||||
<template slot="append">米</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
|
|
@ -264,7 +271,8 @@ export default {
|
|||
start_lat: '',
|
||||
end_lon: '',
|
||||
end_lat: '',
|
||||
line_deep: ''
|
||||
line_deep: '',
|
||||
conver_width: ''
|
||||
},
|
||||
rules: {
|
||||
publish_rule: [
|
||||
|
|
@ -308,6 +316,9 @@ export default {
|
|||
],
|
||||
line_deep: [
|
||||
{ required: true, message: '此处为必填项', trigger: 'blur' }
|
||||
],
|
||||
conver_width: [
|
||||
{ required: true, message: '此处为必填项', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
// 公开期限下拉数据
|
||||
|
|
@ -445,7 +456,8 @@ export default {
|
|||
start_lat: '',
|
||||
end_lon: '',
|
||||
end_lat: '',
|
||||
line_deep: ''
|
||||
line_deep: '',
|
||||
conver_width: ''
|
||||
}
|
||||
this.dynamicTags = []
|
||||
this.$refs['form'].resetFields()
|
||||
|
|
|
|||
|
|
@ -365,8 +365,11 @@ import {
|
|||
voyageRegNav,
|
||||
uploadNavigation,
|
||||
voyageRegPeople,
|
||||
voyageRegPeopleDelete, voyageRegPeopleEdit, voyageRegPeopleUpload, voyageRegImport
|
||||
} from '@/api/dataTransfer'
|
||||
voyageRegPeopleDelete,
|
||||
voyageRegPeopleEdit,
|
||||
voyageRegPeopleUpload,
|
||||
voyageRegImport
|
||||
} from '../../api/dataTransfer'
|
||||
import { time } from '@/utils/validate'
|
||||
import { fundingAll } from '@/api/dicManage'
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
<el-table ref="tableData" v-loading="loading" stripe border :data="tableData" :header-cell-style="{ background: '#dddfe6',color: '#555960',textAlign: 'center' }" :cell-style="{ textAlign: 'center' }">
|
||||
<el-table-column type="index" label="#" width="50"/>
|
||||
<el-table-column prop="unit_name" label="参航单位名称" />
|
||||
<el-table-column prop="unit_type" label="参航单位类型" width="200" />
|
||||
<el-table-column prop="unit_lon" label="经度" width="200" />
|
||||
<el-table-column prop="unit_lat" label="纬度" width="200" />
|
||||
<el-table-column label="操作" width="120">
|
||||
|
|
@ -61,6 +62,9 @@
|
|||
<el-form-item label="所在纬度" prop="unit_lat">
|
||||
<el-input v-model="form.unit_lat" />
|
||||
</el-form-item>
|
||||
<el-form-item label="单位类型" prop="unit_type">
|
||||
<el-input v-model="form.unit_type" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注信息" prop="unit_remark">
|
||||
<el-input v-model="form.unit_remark" type="textarea" />
|
||||
</el-form-item>
|
||||
|
|
@ -99,6 +103,7 @@ export default {
|
|||
unit_addr: '',
|
||||
unit_lon: '',
|
||||
unit_lat: '',
|
||||
unit_type: '',
|
||||
unit_remark: ''
|
||||
},
|
||||
rules: {
|
||||
|
|
@ -110,6 +115,9 @@ export default {
|
|||
],
|
||||
unit_lat: [
|
||||
{ required: true, message: '此处为必填项', trigger: 'blur' }
|
||||
],
|
||||
unit_type: [
|
||||
{ required: true, message: '此处为必填项', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ export default {
|
|||
},
|
||||
{
|
||||
pic: require('../../static/images/shuju2_bg3.png'),
|
||||
title: '支撑大科学计划',
|
||||
title: '构建应急搜寻处置快速响应能力',
|
||||
des: '应急搜捞应用',
|
||||
routerName: 'SalvageHome'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ export default {
|
|||
},
|
||||
updateInfoVisible: false,
|
||||
updateInfoForm: {
|
||||
tsy_id: '',
|
||||
optr_id: '',
|
||||
optr_name: '',
|
||||
optr_sex: '',
|
||||
optr_status: '',
|
||||
|
|
@ -310,7 +310,7 @@ export default {
|
|||
|
||||
this.info = data
|
||||
|
||||
this.updateInfoForm.tsy_id = data.tsy_id
|
||||
this.updateInfoForm.optr_id = data.optr_id
|
||||
this.updateInfoForm.optr_name = data.optr_name
|
||||
this.updateInfoForm.optr_sex = data.optr_sex
|
||||
this.updateInfoForm.optr_status = data.optr_status
|
||||
|
|
@ -337,7 +337,7 @@ export default {
|
|||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
updatePassword({
|
||||
tsy_id: this.info.tsy_id,
|
||||
optr_id: this.info.optr_id,
|
||||
old_password: this.updatePwdForm.old_password,
|
||||
new_pass: this.updatePwdForm.new_pass
|
||||
}).then(res => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,489 @@
|
|||
<template>
|
||||
<div class="statistics">
|
||||
<div class="banner">
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="titles">{{ currentTitle }}<i class="el-icon-arrow-down el-icon--right" /></span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="全部载人潜水器">全部载人潜水器</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-for="item in titles"
|
||||
:key="item.tsy_id"
|
||||
:command="item.report_name"
|
||||
>
|
||||
{{ item.report_name }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<div class="numbers">
|
||||
<div v-for="(item, index) in numbers" :key="index" class="item">
|
||||
<div class="value">{{ item.value }}<span class="unit">{{ item.unit }}</span></div>
|
||||
<div class="label">{{ item.label }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 地图板块-->
|
||||
<div class="map-module">
|
||||
<div class="bezel">
|
||||
<div class="map-title">下潜单位</div>
|
||||
<baidu-map
|
||||
:center="baiduCenter"
|
||||
:zoom="baiduZoom"
|
||||
:scroll-wheel-zoom="true"
|
||||
map-type="BMAP_SATELLITE_MAP"
|
||||
style="width: 100%; height: 100%"
|
||||
>
|
||||
<bm-marker
|
||||
v-for="(item, index) in baiduMarker"
|
||||
:key="index"
|
||||
:position="item.position"
|
||||
:dragging="true"
|
||||
:icon="item.icon"
|
||||
@click="tapBaidu(item, index)"
|
||||
>
|
||||
<bm-label
|
||||
:content="item.content"
|
||||
:offset="item.offset"
|
||||
/>
|
||||
</bm-marker>
|
||||
</baidu-map>
|
||||
</div>
|
||||
<div class="bezel">
|
||||
<div class="map-title">下潜地图</div>
|
||||
<div id="cesiumContainer" ref="cesiumContainer" style="height: 100%;width:100%;" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- echarts板块-->
|
||||
<div class="echarts-module">
|
||||
<div class="bezel">
|
||||
<BarChart
|
||||
:title="barData1.title"
|
||||
:chart-data="barData1.salesData"
|
||||
:categories="barData1.productCategories"
|
||||
chart-type="single"
|
||||
/>
|
||||
</div>
|
||||
<div class="bezel">
|
||||
<BarChart
|
||||
:title="barData2.title"
|
||||
:chart-data="barData2.salesData"
|
||||
:categories="barData2.productCategories"
|
||||
chart-type="stacked"
|
||||
stack-name="新增单位数"
|
||||
/>
|
||||
</div>
|
||||
<div class="bezel">
|
||||
<BarChart
|
||||
:title="barData3.title"
|
||||
:chart-data="barData3.salesData"
|
||||
:categories="barData3.productCategories"
|
||||
/>
|
||||
</div>
|
||||
<div class="bezel">
|
||||
<BarChart
|
||||
:title="barData4.title"
|
||||
:chart-data="barData4.salesData"
|
||||
:categories="barData4.productCategories"
|
||||
/>
|
||||
</div>
|
||||
<div class="bezel">
|
||||
<BarChart
|
||||
:title="barData5.title"
|
||||
:chart-data="barData5.salesData"
|
||||
:categories="barData5.productCategories"
|
||||
/>
|
||||
</div>
|
||||
<div class="bezel">
|
||||
<PieChart
|
||||
:chart-data="pieData"
|
||||
title="下潜单位类型"
|
||||
chart-type="ring"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BarChart from './components/BarChart.vue'
|
||||
import PieChart from './components/PieChart.vue'
|
||||
import { setImageryViewModels } from '../../utils/common'
|
||||
import { reportList, platformHov, hovUnit, hovUnitYear, hovDiving } from '../../api/statistics'
|
||||
import { filterDictItems } from '../../utils/index'
|
||||
const Cesium = window.Cesium
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BarChart,
|
||||
PieChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentTitle: '全部载人潜水器',
|
||||
titles: [],
|
||||
numbers: [
|
||||
{
|
||||
label: '潜次数',
|
||||
value: '',
|
||||
unit: '次'
|
||||
},
|
||||
{
|
||||
label: '下潜人数',
|
||||
value: '',
|
||||
unit: '人'
|
||||
},
|
||||
{
|
||||
label: '下潜单位',
|
||||
value: '',
|
||||
unit: '家'
|
||||
},
|
||||
{
|
||||
label: '数据样品个数',
|
||||
value: '',
|
||||
unit: '个'
|
||||
}
|
||||
],
|
||||
baiduCenter: { lng: 114.4040, lat: 30.5196 },
|
||||
baiduZoom: 5,
|
||||
baiduMarker: [],
|
||||
activeMarkerIndex: -1, // 当前激活的标记点索引
|
||||
viewer: null,
|
||||
// 地图图层基础地址
|
||||
CesiumHostAddr: `${window.location.protocol}//${window.location.hostname}:${window.location.port}/`,
|
||||
trackLineLayers: [],
|
||||
barData1: {},
|
||||
barData2: {},
|
||||
barData3: {},
|
||||
barData4: {},
|
||||
barData5: {},
|
||||
pieData: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getTypeList()
|
||||
this.getHovList()
|
||||
this.getHovUnit()
|
||||
this.gitHovDiving()
|
||||
this.gitHovUnitYear()
|
||||
this.getChartBar({ year: '2025' })
|
||||
},
|
||||
mounted() {
|
||||
this.imageryViewModels = setImageryViewModels(this.CesiumHostAddr)
|
||||
this.initCesium()
|
||||
},
|
||||
methods: {
|
||||
// 载人潜水器数据
|
||||
getTypeList() {
|
||||
reportList().then(res => {
|
||||
this.titles = filterDictItems(res.array, '载人潜水器')
|
||||
})
|
||||
},
|
||||
// 选择载人潜水器
|
||||
handleCommand(command) {
|
||||
this.currentTitle = command
|
||||
this.removeSingleLineImg()
|
||||
if (command === '全部载人潜水器') {
|
||||
this.getHovList()
|
||||
this.gitHovDiving()
|
||||
this.gitHovUnitYear()
|
||||
this.getChartBar({ year: '2025' })
|
||||
} else {
|
||||
this.getHovList({ platform_name: command })
|
||||
this.gitHovDiving({ platform_name: command })
|
||||
this.gitHovUnitYear({ platform_name: command })
|
||||
this.getChartBar({ year: '2025', platform_name: command })
|
||||
}
|
||||
},
|
||||
// 汇总统计数据
|
||||
getHovList(params = {}) {
|
||||
platformHov(params).then(res => {
|
||||
const obj = res.array[0]
|
||||
this.numbers[0].value = obj.diving_total
|
||||
this.numbers[1].value = obj.driver_member_total
|
||||
this.numbers[2].value = obj.unit_total
|
||||
this.numbers[3].value = obj.dataset_total
|
||||
})
|
||||
},
|
||||
// 下潜单位统计
|
||||
getHovUnit() {
|
||||
hovUnit().then(res => {
|
||||
this.baiduMarker = res.array.map(item => {
|
||||
return {
|
||||
position: {
|
||||
lng: item.unit_lon,
|
||||
lat: item.unit_lat
|
||||
},
|
||||
content: item.unit_name,
|
||||
offset: { width: 16, height: 32 },
|
||||
icon: {
|
||||
url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAE9klEQVR4AZxXXWgcVRT+zkwaBS0mu1FpSyHFbKoIQjFoRSh5EX8QbYVKq4I+hLa7qRWCf32QRoh/gfqSzcYQiyDUlgZFffHnoRGhQsFQwWLYbKx9kFokuwkRSrHZuf3OzOzuTGaS3c3lfnPO/c65Z76Zu3Nn1kIT7Y6Jy9sSuUJfe64wRZsnlnzkfa5Pc5ooiYYEdOTmHkzkZsftGzcusfiEAL0AuomNPrp9bkJzNFfnMFa31xWQzBWOOjC/AnIAXrtK870IPjTi7FeorxyhMRo5oHOSnMvBmn1NAYnR/KAB3q9VkKFSJrWJeLKYTh1dSG8/rVBfOWITIEPwm87VGv4w1qwqIJEr7IVYx/xZ05a9YXMp0/WOP17VaI7mMmGagNZwayG+xQpIjv/1MNPPEOBVfF7KpHrmD3b+o+NGoLk6R+f6+Wf8mv6wZmIFGKf8mpsi+Hshk3rZ9ddxcOeyhk6t1tRBABEB7dn8UzBmv5/T59uQSY7lH+JtPZ7IzX3poXBcuVBSbeDVYE23do13vYgAse3dGjEG35TSqR/UDyKZze8xRr4jNwCY5zxgQDmNkQ91rWFYS8lKbfUriAjg1e9xg4I/XBs4tI3NdBrL/hiQBID/mHvKhfrkNKY5jIV7pZYxXu1ANCRgY3YmyVgHwQuzfndt4GCZFv42TCepi9zCdpb6u19QqO9yMJ1eDkfBbqq1OvxzVKMhAS0GmysR28B7jCqEZ3UHpDg5VzqUqt4h1zdyzkuBl4NaC9YKnkMzQgJ4C20lFSLXr6gNgmu5RcfGKv+kNogKV8kJxhzH8XdIwLY3tAZjIQGL/d2/MbhIoIxbHlAbhAi+1bEYK/JoVrhKjuZVsQGPVPxWe3Gm4qsNCVDCAD+7ViQiAIJJjRFPtPON2DZS6FWorxyBQA6qzXFcAQJcuHKw51qVpxMRIMa5QJ7dPM5DqOsjReIEwfOg17IxpRCgsu4n/BwEm4j1jI65PGfVBhERANtyt2CB2a1XF0xWn1tsH094mL7+SBdoFdPKaYzjUE9kZx/jXd3hkctfebZ2jAhwf9HwbrXVIpG11qnFTGqUJ+shEj56lNNYBJY873NnS/33/eL7VRMR4Ee8tTbmlbi74OfUNW3Z2V1M8rZi4BT9SI8VwKuahHg/RrFxLDKrQcKyRJcKWos1P0VMixXg5jl4Ty3XtrfeR4XmrUQyW3iW3F4CMMi6NuawqoBSf+pH5nPf55EfJk0txeBUi7HwNmfyVcGXWiY1qX4cVhWgycvX/9e7cFH9ZpYiedcWPflOzrtmO+XqJxrHkb6mgKWB+0tGREVwGdHQUrSNFXbweVcBOmdo/tV7+UEbOW+VWFOAZi2ku07TfkYAXIqOXMHdVBDT7hz993bLYAQit1HEFB/ND2LSQlRdAZq93Hrr67TnCfBzezgxOrdV/ZUoy+IEuUcBuWrb1ptooDUkYKlva0kco98CJUC2Q5xhrGiJ3Bw52ac0n5z0/KF71rz1mqdoSIAmFg93n+fv4Yj6gOxrH52tXiFPzj8t5g2wcQs/Usx0fU23od6wAK22kE6dhGAQbCLyUfvYn0+3fXJpFx/0cbCRGy5mukfoNtybEqBV+bZ7VwxOqs8357hVLvsvL3xRTHe9pXwzaFqAFi/2p14C5DLATzjB3aBfzKRexDraugToeUqZrm20+kqe9n0Oo70ecxMAAP//0tEICQAAAAZJREFUAwDQYMDuVKkB5gAAAABJRU5ErkJggg==',
|
||||
size: { width: 32, height: 32 }
|
||||
}
|
||||
}
|
||||
})
|
||||
const typeCount = res.array.reduce((acc, unit) => {
|
||||
const type = unit.unit_type
|
||||
acc[type] = (acc[type] || 0) + 1 // 如果类型已存在则计数+1,否则初始化为1
|
||||
return acc
|
||||
}, {})
|
||||
this.pieData = Object.entries(typeCount).map(([type, count]) => ({
|
||||
name: type,
|
||||
value: count
|
||||
}))
|
||||
})
|
||||
},
|
||||
// 潜次统计
|
||||
gitHovDiving(params = {}) {
|
||||
hovDiving(params).then(res => {
|
||||
// 添加轨迹图层
|
||||
res.array.forEach(item => {
|
||||
this.addSingleLineImg(item)
|
||||
})
|
||||
})
|
||||
},
|
||||
tapBaidu(item, index) {
|
||||
// 重置所有标记点为普通图标
|
||||
this.baiduMarker.forEach(marker => {
|
||||
marker.icon.url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAE9klEQVR4AZxXXWgcVRT+zkwaBS0mu1FpSyHFbKoIQjFoRSh5EX8QbYVKq4I+hLa7qRWCf32QRoh/gfqSzcYQiyDUlgZFffHnoRGhQsFQwWLYbKx9kFokuwkRSrHZuf3OzOzuTGaS3c3lfnPO/c65Z76Zu3Nn1kIT7Y6Jy9sSuUJfe64wRZsnlnzkfa5Pc5ooiYYEdOTmHkzkZsftGzcusfiEAL0AuomNPrp9bkJzNFfnMFa31xWQzBWOOjC/AnIAXrtK870IPjTi7FeorxyhMRo5oHOSnMvBmn1NAYnR/KAB3q9VkKFSJrWJeLKYTh1dSG8/rVBfOWITIEPwm87VGv4w1qwqIJEr7IVYx/xZ05a9YXMp0/WOP17VaI7mMmGagNZwayG+xQpIjv/1MNPPEOBVfF7KpHrmD3b+o+NGoLk6R+f6+Wf8mv6wZmIFGKf8mpsi+Hshk3rZ9ddxcOeyhk6t1tRBABEB7dn8UzBmv5/T59uQSY7lH+JtPZ7IzX3poXBcuVBSbeDVYE23do13vYgAse3dGjEG35TSqR/UDyKZze8xRr4jNwCY5zxgQDmNkQ91rWFYS8lKbfUriAjg1e9xg4I/XBs4tI3NdBrL/hiQBID/mHvKhfrkNKY5jIV7pZYxXu1ANCRgY3YmyVgHwQuzfndt4GCZFv42TCepi9zCdpb6u19QqO9yMJ1eDkfBbqq1OvxzVKMhAS0GmysR28B7jCqEZ3UHpDg5VzqUqt4h1zdyzkuBl4NaC9YKnkMzQgJ4C20lFSLXr6gNgmu5RcfGKv+kNogKV8kJxhzH8XdIwLY3tAZjIQGL/d2/MbhIoIxbHlAbhAi+1bEYK/JoVrhKjuZVsQGPVPxWe3Gm4qsNCVDCAD+7ViQiAIJJjRFPtPON2DZS6FWorxyBQA6qzXFcAQJcuHKw51qVpxMRIMa5QJ7dPM5DqOsjReIEwfOg17IxpRCgsu4n/BwEm4j1jI65PGfVBhERANtyt2CB2a1XF0xWn1tsH094mL7+SBdoFdPKaYzjUE9kZx/jXd3hkctfebZ2jAhwf9HwbrXVIpG11qnFTGqUJ+shEj56lNNYBJY873NnS/33/eL7VRMR4Ee8tTbmlbi74OfUNW3Z2V1M8rZi4BT9SI8VwKuahHg/RrFxLDKrQcKyRJcKWos1P0VMixXg5jl4Ty3XtrfeR4XmrUQyW3iW3F4CMMi6NuawqoBSf+pH5nPf55EfJk0txeBUi7HwNmfyVcGXWiY1qX4cVhWgycvX/9e7cFH9ZpYiedcWPflOzrtmO+XqJxrHkb6mgKWB+0tGREVwGdHQUrSNFXbweVcBOmdo/tV7+UEbOW+VWFOAZi2ku07TfkYAXIqOXMHdVBDT7hz993bLYAQit1HEFB/ND2LSQlRdAZq93Hrr67TnCfBzezgxOrdV/ZUoy+IEuUcBuWrb1ptooDUkYKlva0kco98CJUC2Q5xhrGiJ3Bw52ac0n5z0/KF71rz1mqdoSIAmFg93n+fv4Yj6gOxrH52tXiFPzj8t5g2wcQs/Usx0fU23od6wAK22kE6dhGAQbCLyUfvYn0+3fXJpFx/0cbCRGy5mukfoNtybEqBV+bZ7VwxOqs8357hVLvsvL3xRTHe9pXwzaFqAFi/2p14C5DLATzjB3aBfzKRexDraugToeUqZrm20+kqe9n0Oo70ecxMAAP//0tEICQAAAAZJREFUAwDQYMDuVKkB5gAAAABJRU5ErkJggg=='
|
||||
marker.icon.size = { width: 32, height: 32 }
|
||||
marker.offset = { width: 16, height: 32 }
|
||||
})
|
||||
// 设置当前点击的标记点为高亮图标
|
||||
this.baiduMarker[index].icon.url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAIN0lEQVR4AbQZW2wc1fWcWduktEX1ziYtKYJ61rJUBVKVGvWhVo3afjQqqOEV4IO3xBuFZ5TdNWQN3l1eAvIBSvgAJAQCAgQEQoAEfPB+BAGyAwTvJqBgIN51UECQ2N65nHNn7syd9czsw8vVPfe8z7nnzuzMnbsGdKmZQ7nfJq3MFSkr94pp5cbNdPYL08p+L0HSuXHWJcmGbbuUFhZdgJnOrKFJPQTzYg8C3iFA/B1ArAABy2mSP5MgabGCdWzDtuzDvqRfVO+4AFrhc8yBzMsgcBtN6ox2ZyF9yJdjcKx2/ZV9RwWkrOyzIOA+QFylAimMCFsJ1gPCuQYY/2NgGhHWE2xVdh7mGBRLxvSErRNtF2Ba2U8FwOpgCtwOgJf2GmJZtVxcS3BrrVy8f7oy9iwD0ywjWMs2bEtAPuA1jsmxPUGLRFsFUALKA4N+bJxAxAtrlcIwwd1fTZamfV04xTZsSzDMvgA4AX4bdHP4kiZUywVQ4CeCsSixbZ9SLRfuCcpb56QvxYBgEbAwF0S2lgowrVyJIpxI4HSEN2kFj67tLn3sCDofOQbHot/Jm1qUE92cmiicbFpAcjC7lh6LGzT3nbVy8a8a3xXSjbnTDyY2OLl9SRgVX8CqfA/a4hrN8YBhw2ka31XSjX1ABZW5aQ6KD8OxBZifz14NgMeBaig2Tu8uvq/YWPynC3rNo0Z+zwBEx9q6ShmbcrgsITzOmQORET22API5j0B2BHitVi7dIpmYIclbBSu73dyX+g4S9g4Gpk2SJUkX4ypVnINzScYZznNQ+BhZgPm7zJ/JZYjA6cJoOnnTyj2GtJ0gh2MJ+ghUZ/pY1rGNEkbiYK4hdy6h5pEFAOJ/NI/91UN7ntP4BaRpZW6mH/vJCxQLBOJkx3aBwhO4ufZ7guBcPDET0QWA8AtAeAMm8rPsEAZmeuRfALgeVEOYojfeqDBoA8cAMAokU2ogW8cHwhvn4pyeVpuLJ3OI6AIQLccEKDe8CLHNLmjqt3AehmcqxfzMZGmHBKJZRjZvEbg94OPKfISg5dTm4ls4VHgBq/I9pD6SQHYUxoQkQobUUdnDQcBflArBGKt+VvwSGhrLkHSgGvlIX8U3YAzmPBKcOTVYQfj3QOrzg97qs8ecPb+DcRjYCfybJt9frYw9o/EB0tV593aDb8C2MWfjnJRx+BUw8BfKgHHvz5dUGYcBCjhcyRFgNzRpuo3u2+jWc4hdC8qMw4K8w4UWUJ389AN6otQdE4D6gbmVim7EImG/pGT0w11pWhv8F59SuJh1bOOyoPsqmcJivi8Qp+9Ab+hdEFoAwNY6CHxbBTMERBbAP1II7CaNLEQ2XYcTjm+EsbD1AsanpvLfh1lGFECmhvA+OOhb9g8AJIvopH9MU61JpXMXHHZEPqlkTLOM+DUEsjf4SFnDMKx4umrjim7EkQXQvao7ecEaAzDPj0x61k4xzSCE2NLbN7uH3rrjDEyzjHUS6J0gfSSzcPh1Or+MpP57CCBy2x5ZACV8j4KoPpxKZ09XTBhGgf9vkNOJBJ1O8AkFANG+Fhfa+kqi5uyDJxD6FYHsCRuekkTIEFlArXLTO2T/NIHTBZzlEOFjtVJ4t9Zf5T3PXeEWUnoX27Ct5CIG+tQ83lMhPD8dswOOLIADIOAjjBnoPlxNTxH9srI4CNvvmatVipfZCMcgiosAxQMMTLOMdUA2Qacgt2xwJE1PQL4CjkKIyNVng9gCqv3Tj5KR/5WExpnEN+37ysXxarm0hbbGZzEwzbKmjmRg1+2zATABTtuPdXzSIcPH2AJ4tVCAdxWAbqOlA5l/hIdavJRXXxhwiYqEiI/wFkTxYTi+APKwEwm/AOIFYobQT9Ln7foltEimCk633b2KjsJNC5iZvHGCJn2bCiB/C+ns5YrvFu63rjsGAb3VB8AHZyYL+kkFhLWmBbBTjy24gDLTEoTILk1v0A64pHRRgwG0+gBLvCCITVefbVsqYO+u4te0OlwE+xDgb2yRiNkykEkbPTWQ46fORZrLtlp5zNtjafIFZEsFsFe1UtgMgC+A18S5yYHcqR7bIbF8ef5QgeI63R1BtLT67NNyAdJY2GOEvU9LNCCzdEU+sPUmfVv94JKDPHlv40a/sdFqpRT5TdEYvK0CpneVXqFHW84LIsQf7R9mO76VTCv7bwDUT/22xe2RIKS1VQD7V8sF/i08zrQLmWR65L8u3R5C4NVXPuWEYVyrmFZx2wVwYBQGX4U9TDOgsDfxS4jpViFpZTeDgH969ojX7p0c8590niKe6KiA6q6xT+ippF/6obot7oxP5WuTVuZ6BLhQSQTAaK1c2Kb4dnBHBXACeio9iIA3MO2AOJ7+JrrdoaPH5MDI+eQ3qlk81O59r/mGn0roBnE0FbGRVu9hZUP0lSkrpz/PlUri/nR2NWJ9i2Sc4d1DevrWOWRnY8dXQKXrRTkB7+OHPhU3hZ269Q9kV9K3Nb9LvJ0mbVHWTe3MR554qBxxeNEFfF3O77UBeRW/dRP1Af2ok4Mbj3B5+OVQPkWJeOW9wzJAWDdTLryubDrFFLdTV99vX6XwKt0+V3gSgKPRntuk+L752c00Ye/0juSlGv2LSXjRvSsF8CxmKkV6/eNNTLtwkmll72YgXj+1frxWKXb88qNYgd61AjhqrVLIEH6CQPWLiWAgBHQR4EPokbcbdKt1tQCeVF3gVTTTj5gOgICabdN/yjsLXwTki2S6XsA3uwqfCYQrG+b1HaJxzszuQtMPlAa/pmzXC+CMM5PF54VA+nsW6XQPt6Ntn1CtjLW8w+QYrcKPAAAA//9QcJOrAAAABklEQVQDALykzWblMgKeAAAAAElFTkSuQmCC'
|
||||
this.baiduMarker[index].icon.size = { width: 48, height: 48 } // 高亮时稍大一些
|
||||
this.baiduMarker[index].offset = { width: 24, height: 48 } // 高亮时稍大一些
|
||||
// 记录当前激活的标记点索引
|
||||
this.activeMarkerIndex = index
|
||||
},
|
||||
// 初始化cesium
|
||||
initCesium() {
|
||||
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkY2Y5NWY2Ni1mODQ1LTQ3YTUtYjc4Zi1jYzhjMGI2YzcxMWYiLCJpZCI6MTI5ODMwLCJpYXQiOjE2Nzk0Njk5NTd9.DTH54ioOH-HLqeNIetBe9hFyrPOX2Vp1AQmZzw8TIZ4'
|
||||
this.viewer = new Cesium.Viewer('cesiumContainer', {
|
||||
sceneMode: Cesium.SceneMode.SCENE2D,
|
||||
shadows: false,
|
||||
timeline: false,
|
||||
baseLayerPicker: false,
|
||||
// 设置自定义底图
|
||||
imageryProviderViewModels: this.imageryViewModels,
|
||||
// 关闭默认的地形底图
|
||||
terrainProviderViewModels: [],
|
||||
fullscreenButton: false,
|
||||
selectionIndicator: false,
|
||||
homeButton: false,
|
||||
sceneModePicker: false,
|
||||
animation: false,
|
||||
infoBox: false,
|
||||
geocoder: false,
|
||||
navigationHelpButton: false
|
||||
})
|
||||
this.viewer._cesiumWidget._creditContainer.style.display = 'none'
|
||||
this.viewer.scene.sun.show = false
|
||||
this.viewer.scene.moon.show = false
|
||||
this.viewer.scene.fog.enabled = false
|
||||
this.viewer.scene.skyAtmosphere.show = false
|
||||
this.viewer.scene.sun.show = false
|
||||
this.viewer.scene.skyBox.show = false
|
||||
this.viewer.scene.globe.enableLighting = false
|
||||
this.viewer.shadowMap.darkness = 0.8
|
||||
this.viewer.scene._sunBloom = false
|
||||
this.viewer.scene.globe.showGroundAtmosphere = false
|
||||
this.viewer.scene.postProcessStages.fxaa.enabled = true
|
||||
|
||||
this.viewer.camera.setView({
|
||||
// 指定相机初始位置
|
||||
destination: Cesium.Cartesian3.fromDegrees(112, 18, 4000000)
|
||||
})
|
||||
},
|
||||
// 添加轨迹图层
|
||||
addSingleLineImg(item) {
|
||||
const trackLine = new Cesium.WebMapTileServiceImageryProvider(
|
||||
{
|
||||
url: `${this.CesiumHostAddr}geoserver/gwc/service/wmts/rest/dsds:${item.diving_sn}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png`,
|
||||
layer: `dsds:${item.diving_sn}`,
|
||||
style: 'default',
|
||||
format: 'image/png',
|
||||
tileMatrixSetID: 'EPSG:4326',
|
||||
tilingScheme: new Cesium.GeographicTilingScheme()
|
||||
}
|
||||
)
|
||||
const trackLineLayer = this.viewer.imageryLayers.addImageryProvider(trackLine)
|
||||
this.trackLineLayers.push(trackLineLayer)
|
||||
},
|
||||
// 移除轨迹图层
|
||||
removeSingleLineImg() {
|
||||
if (this.trackLineLayers.length) {
|
||||
this.trackLineLayers.forEach(line => {
|
||||
this.viewer.imageryLayers.remove(line)
|
||||
})
|
||||
}
|
||||
},
|
||||
// 参潜单位年度
|
||||
gitHovUnitYear(params = {}) {
|
||||
hovUnitYear(params).then(res => {
|
||||
const originalData = res.array
|
||||
const sortedData = originalData.sort((a, b) => a.voyage_year - b.voyage_year)
|
||||
this.barData2 = {
|
||||
title: '年度参潜单位',
|
||||
salesData: [
|
||||
{
|
||||
name: '参潜单位',
|
||||
data: sortedData.map(item => item.unit_total),
|
||||
stack: '新增单位数'
|
||||
},
|
||||
{
|
||||
name: '新增单位',
|
||||
data: sortedData.map(item => item.year_unit_total),
|
||||
stack: '新增单位数'
|
||||
}
|
||||
],
|
||||
productCategories: sortedData.map(item => item.voyage_year.toString())
|
||||
}
|
||||
})
|
||||
},
|
||||
// 柱状图数据
|
||||
getChartBar(params) {
|
||||
platformHov(params).then(res => {
|
||||
const originalData = res.array
|
||||
const sortedData = originalData.sort((a, b) => a.year - b.year)
|
||||
this.barData1 = {
|
||||
title: '年度潜次数',
|
||||
salesData: sortedData.map(item => item.diving_total),
|
||||
productCategories: sortedData.map(item => item.year.toString())
|
||||
}
|
||||
this.barData3 = {
|
||||
title: '样品集个数',
|
||||
salesData: sortedData.map(item => item.dataset_total),
|
||||
productCategories: sortedData.map(item => item.year.toString())
|
||||
}
|
||||
this.barData4 = {
|
||||
title: '水中时间',
|
||||
salesData: sortedData.map(item => item.water_total),
|
||||
productCategories: sortedData.map(item => item.year.toString())
|
||||
}
|
||||
this.barData5 = {
|
||||
title: '水中作业时间',
|
||||
salesData: sortedData.map(item => item.job_total),
|
||||
productCategories: sortedData.map(item => item.year.toString())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.statistics {
|
||||
background-color: #ebf1f7;
|
||||
|
||||
.banner {
|
||||
background-image: url(../../../static/images/bannerny1.jpg);
|
||||
width: 100%;
|
||||
height: 480px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
|
||||
.titles {
|
||||
margin-bottom: 40px;
|
||||
font-size: 56px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.numbers {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 80px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.value {
|
||||
font-size: 56px;
|
||||
font-weight: bold;
|
||||
.unit {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
.label {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.map-module {
|
||||
padding: 50px 50px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 50px;
|
||||
.bezel {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 520px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
|
||||
.map-title {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
color: white;
|
||||
z-index: 8888;
|
||||
font-size: 22px;
|
||||
}
|
||||
.map-year {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
color: white;
|
||||
z-index: 8888;
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.echarts-module {
|
||||
padding: 0 50px 50px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 50px;
|
||||
grid-auto-rows: 300px;
|
||||
|
||||
.bezel {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
|
||||
.map-title {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
color: white;
|
||||
z-index: 8888;
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
/* 隐藏百度地图Logo和版权信息 */
|
||||
.anchorBL {
|
||||
display: none !important;
|
||||
}
|
||||
.BMap_cpyCtrl {
|
||||
display: none !important;
|
||||
}
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,435 @@
|
|||
<template>
|
||||
<div ref="chartContainer" style="width: 100%; height: 300px;"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
name: 'AdvancedMixedChart',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '图表标题'
|
||||
},
|
||||
chartData: {
|
||||
type: [Array, Object],
|
||||
default: () => []
|
||||
},
|
||||
categories: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
chartType: {
|
||||
type: String,
|
||||
default: 'single', // 'single' | 'multiple' | 'mixed' | 'stacked'
|
||||
validator: (value) => ['single', 'multiple', 'mixed', 'stacked'].includes(value)
|
||||
},
|
||||
colors: {
|
||||
type: Array,
|
||||
default: () => ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272']
|
||||
},
|
||||
// 新增:是否显示双Y轴
|
||||
dualYAxis: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 新增:堆叠组名称(用于stacked模式)
|
||||
stackName: {
|
||||
type: String,
|
||||
default: '总量'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myChart: null
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.initChart();
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.myChart) {
|
||||
this.myChart.dispose();
|
||||
}
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.$nextTick(() => {
|
||||
this.myChart = echarts.init(this.$refs.chartContainer);
|
||||
this.renderChart();
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
});
|
||||
},
|
||||
|
||||
// 处理数据格式
|
||||
processChartData() {
|
||||
if (this.chartType === 'single') {
|
||||
// 单系列柱状图
|
||||
const data = Array.isArray(this.chartData) && this.chartData.length > 0
|
||||
? this.chartData
|
||||
: new Array(this.categories.length).fill(0);
|
||||
|
||||
return [{
|
||||
name: '数量',
|
||||
type: 'bar',
|
||||
data: data
|
||||
}];
|
||||
} else if (this.chartType === 'multiple') {
|
||||
// 多系列柱状图
|
||||
if (Array.isArray(this.chartData) && this.chartData.every(item => typeof item === 'number')) {
|
||||
return [{
|
||||
name: '系列1',
|
||||
type: 'bar',
|
||||
data: this.chartData
|
||||
}];
|
||||
} else if (Array.isArray(this.chartData)) {
|
||||
return this.chartData.map((series, index) => ({
|
||||
name: series.name || `系列${index + 1}`,
|
||||
type: series.type || 'bar',
|
||||
data: series.data || [],
|
||||
yAxisIndex: series.yAxisIndex || 0
|
||||
}));
|
||||
}
|
||||
} else if (this.chartType === 'mixed') {
|
||||
// 柱状图和折线图组合
|
||||
if (Array.isArray(this.chartData)) {
|
||||
return this.chartData.map((series, index) => ({
|
||||
name: series.name || (series.type === 'line' ? '折线' : '柱状') + (index + 1),
|
||||
type: series.type || (index === 0 ? 'bar' : 'line'),
|
||||
data: series.data || [],
|
||||
yAxisIndex: series.yAxisIndex || (this.dualYAxis && index > 0 ? 1 : 0)
|
||||
}));
|
||||
}
|
||||
} else if (this.chartType === 'stacked') {
|
||||
// 堆叠柱状图 [2,3](@ref)
|
||||
if (Array.isArray(this.chartData) && this.chartData.every(item => typeof item === 'number')) {
|
||||
// 如果是数字数组,转换为单个堆叠系列
|
||||
return [{
|
||||
name: '数量',
|
||||
type: 'bar',
|
||||
data: this.chartData,
|
||||
stack: this.stackName // 设置堆叠属性 [2](@ref)
|
||||
}];
|
||||
} else if (Array.isArray(this.chartData)) {
|
||||
// 处理多系列堆叠柱状图
|
||||
return this.chartData.map((series, index) => ({
|
||||
name: series.name || `系列${index + 1}`,
|
||||
type: 'bar',
|
||||
data: series.data || [],
|
||||
yAxisIndex: series.yAxisIndex || 0,
|
||||
stack: series.stack || this.stackName // 设置堆叠属性,相同stack值的系列会堆叠 [2,3](@ref)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return [{
|
||||
name: '数据',
|
||||
type: 'bar',
|
||||
data: new Array(this.categories.length).fill(0)
|
||||
}];
|
||||
},
|
||||
|
||||
// 获取Y轴配置
|
||||
getYAxisConfig() {
|
||||
if (!this.dualYAxis) {
|
||||
// 单Y轴配置
|
||||
return [{
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#666'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#f0f0f0',
|
||||
type: 'solid'
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
// 双Y轴配置
|
||||
return [
|
||||
{
|
||||
type: 'value',
|
||||
name: '左轴',
|
||||
position: 'left',
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: this.colors[0]
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#666',
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '右轴',
|
||||
position: 'right',
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: this.colors[1]
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#666',
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
];
|
||||
},
|
||||
|
||||
// 获取系列配置
|
||||
getSeriesConfig(processedSeries) {
|
||||
return processedSeries.map((series, index) => {
|
||||
const isLine = series.type === 'line';
|
||||
const isStacked = this.chartType === 'stacked';
|
||||
|
||||
// 基础配置,包含堆叠属性 [2](@ref)
|
||||
const baseConfig = {
|
||||
name: series.name,
|
||||
type: series.type,
|
||||
data: series.data,
|
||||
yAxisIndex: series.yAxisIndex || 0,
|
||||
stack: series.stack // 保留堆叠属性,如果存在
|
||||
};
|
||||
|
||||
if (isLine) {
|
||||
// 折线图配置
|
||||
return {
|
||||
...baseConfig,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: this.colors[index % this.colors.length]
|
||||
},
|
||||
itemStyle: {
|
||||
color: this.colors[index % this.colors.length]
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// 柱状图配置
|
||||
const barConfig = {
|
||||
...baseConfig,
|
||||
barWidth: this.chartType === 'single' ? '60%' : '40%',
|
||||
itemStyle: {
|
||||
color: this.colors[index % this.colors.length]
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
color: this.colors[index % this.colors.length],
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 为堆叠柱状图调整柱宽和样式 [3](@ref)
|
||||
if (isStacked) {
|
||||
barConfig.barWidth = '50%';
|
||||
barConfig.itemStyle.borderRadius = [2, 2, 0, 0]; // 顶部圆角
|
||||
}
|
||||
|
||||
return barConfig;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 渲染图表
|
||||
renderChart() {
|
||||
const processedSeries = this.processChartData();
|
||||
const seriesConfig = this.getSeriesConfig(processedSeries);
|
||||
const yAxisConfig = this.getYAxisConfig();
|
||||
|
||||
// 计算图例显示条件:单系列时不显示图例
|
||||
const showLegend = this.chartType !== 'single';
|
||||
|
||||
// 堆叠柱状图的tooltip配置 [2](@ref)
|
||||
const tooltipFormatter = this.chartType === 'stacked'
|
||||
? this.getStackedTooltipFormatter
|
||||
: null;
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: this.title,
|
||||
left: 'left',
|
||||
top: 10,
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: this.chartType === 'stacked' ? 'shadow' : 'line' // 堆叠模式使用阴影指针 [2](@ref)
|
||||
},
|
||||
formatter: tooltipFormatter || this.getDefaultTooltipFormatter(),
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
||||
borderColor: '#ddd',
|
||||
borderWidth: 1,
|
||||
textStyle: {
|
||||
color: '#333'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: showLegend,
|
||||
data: seriesConfig.map(s => s.name),
|
||||
right: 10,
|
||||
top: 10,
|
||||
orient: 'horizontal',
|
||||
type: 'scroll',
|
||||
textStyle: {
|
||||
color: '#666'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: this.dualYAxis ? '8%' : '3%',
|
||||
bottom: '8%',
|
||||
top: showLegend ? 60 : 40,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.categories,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#666',
|
||||
interval: 0,
|
||||
rotate: this.categories.length > 6 ? 45 : 0,
|
||||
margin: 10
|
||||
}
|
||||
},
|
||||
yAxis: yAxisConfig,
|
||||
series: seriesConfig
|
||||
};
|
||||
|
||||
this.myChart.setOption(option);
|
||||
},
|
||||
|
||||
// 默认tooltip格式化器
|
||||
getDefaultTooltipFormatter() {
|
||||
return (params) => {
|
||||
let result = `<div style="font-weight: bold; margin-bottom: 8px; font-size: 14px;">${params[0].name}</div>`;
|
||||
params.forEach(param => {
|
||||
const color = param.color;
|
||||
const seriesName = param.seriesName;
|
||||
const value = param.value;
|
||||
const marker = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${color};"></span>`;
|
||||
|
||||
result += `
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0; min-width: 120px;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
${marker}
|
||||
<span style="margin-right: 15px;">${seriesName}</span>
|
||||
</div>
|
||||
<span style="font-weight: bold; font-size: 13px;">${value}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
return result;
|
||||
};
|
||||
},
|
||||
|
||||
// 堆叠柱状图tooltip格式化器 [2](@ref)
|
||||
getStackedTooltipFormatter(params) {
|
||||
let result = `<div style="font-weight: bold; margin-bottom: 8px; font-size: 14px;">${params[0].name}</div>`;
|
||||
let total = 0;
|
||||
|
||||
// 计算总和
|
||||
params.forEach(param => {
|
||||
total += param.value || 0;
|
||||
});
|
||||
|
||||
params.forEach(param => {
|
||||
const color = param.color;
|
||||
const seriesName = param.seriesName;
|
||||
const value = param.value;
|
||||
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
|
||||
const marker = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${color};"></span>`;
|
||||
|
||||
result += `
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0; min-width: 150px;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
${marker}
|
||||
<span style="margin-right: 15px;">${seriesName}</span>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<span style="font-weight: bold; font-size: 13px;">${value}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
handleResize() {
|
||||
if (this.myChart) {
|
||||
this.myChart.resize();
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
handler() {
|
||||
if (this.myChart) {
|
||||
this.renderChart();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
categories() {
|
||||
if (this.myChart) {
|
||||
this.renderChart();
|
||||
}
|
||||
},
|
||||
chartType() {
|
||||
if (this.myChart) {
|
||||
this.renderChart();
|
||||
}
|
||||
},
|
||||
dualYAxis() {
|
||||
if (this.myChart) {
|
||||
this.renderChart();
|
||||
}
|
||||
},
|
||||
stackName() {
|
||||
if (this.myChart && this.chartType === 'stacked') {
|
||||
this.renderChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
<template>
|
||||
<div ref="chartContainer" :style="{ width: width, height: height }"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
name: 'AdvancedPieChart',
|
||||
props: {
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '300px'
|
||||
},
|
||||
chartData: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
title: {
|
||||
type: [String, Object],
|
||||
default: ''
|
||||
},
|
||||
// 图表类型:'normal'普通饼图, 'ring'环形图, 'nightingale'南丁格尔图
|
||||
chartType: {
|
||||
type: String,
|
||||
default: 'normal',
|
||||
validator: (value) => ['normal', 'ring', 'nightingale'].includes(value)
|
||||
},
|
||||
// 是否显示标签
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示数值
|
||||
showValue: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myChart: null
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
handler(newVal) {
|
||||
this.updateChart(newVal);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart();
|
||||
});
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.myChart) {
|
||||
this.myChart.dispose();
|
||||
}
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
if (!this.$refs.chartContainer) return;
|
||||
|
||||
this.myChart = echarts.init(this.$refs.chartContainer);
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: typeof this.title === 'string' ? this.title : '',
|
||||
left: 10,
|
||||
top: 10,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
color: '#333'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: this.getTooltipFormatter()
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'right',
|
||||
textStyle: {
|
||||
color: '#666'
|
||||
}
|
||||
},
|
||||
series: this.getSeriesConfig()
|
||||
};
|
||||
|
||||
this.myChart.setOption(option);
|
||||
this.myChart.on('click', (params) => {
|
||||
this.$emit('chartClick', params);
|
||||
});
|
||||
},
|
||||
|
||||
getSeriesConfig() {
|
||||
const baseConfig = {
|
||||
name: typeof this.title === 'string' ? this.title : '数据',
|
||||
type: 'pie',
|
||||
data: this.chartData,
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
},
|
||||
label: this.getLabelConfig()
|
||||
};
|
||||
|
||||
switch (this.chartType) {
|
||||
case 'ring':
|
||||
return {
|
||||
...baseConfig,
|
||||
radius: ['40%', '70%']
|
||||
};
|
||||
case 'nightingale':
|
||||
return {
|
||||
...baseConfig,
|
||||
radius: [20, 140],
|
||||
roseType: 'area'
|
||||
};
|
||||
default:
|
||||
return {
|
||||
...baseConfig,
|
||||
radius: '70%'
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
getLabelConfig() {
|
||||
if (!this.showLabel) {
|
||||
return { show: false };
|
||||
}
|
||||
|
||||
let formatter = '{b}';
|
||||
if (this.showValue) {
|
||||
formatter += ': {c}';
|
||||
}
|
||||
|
||||
return {
|
||||
show: true,
|
||||
formatter: formatter
|
||||
};
|
||||
},
|
||||
|
||||
getTooltipFormatter() {
|
||||
return '{a} <br/>{b}: {c} ({d}%)';
|
||||
},
|
||||
|
||||
updateChart(newData) {
|
||||
if (!this.myChart) return;
|
||||
|
||||
this.myChart.setOption({
|
||||
series: [{
|
||||
data: newData
|
||||
}]
|
||||
});
|
||||
},
|
||||
|
||||
handleResize() {
|
||||
if (this.myChart) {
|
||||
this.myChart.resize();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
</div>
|
||||
<div class="card-info">
|
||||
<h3 class="card-title">科考船汇总统计</h3>
|
||||
<p class="card-count">4艘</p>
|
||||
<p class="card-desc">探索一号、探索二号、探索三号、海警101船</p>
|
||||
<p class="card-count">{{ ship.length }}艘</p>
|
||||
<p class="card-desc"><span v-for="(item, index) in ship" :key="index">{{ item.report_name }}<span v-if="index !== ship.length - 1">、</span></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -39,8 +39,8 @@
|
|||
</div>
|
||||
<div class="card-info">
|
||||
<h3 class="card-title">载人潜水器汇总统计</h3>
|
||||
<p class="card-count">2型</p>
|
||||
<p class="card-desc">深海勇士、奋斗者等</p>
|
||||
<p class="card-count">{{ hov.length }}艘</p>
|
||||
<p class="card-desc"><span v-for="(item, index) in hov" :key="index">{{ item.report_name }}<span v-if="index !== hov.length - 1">、</span></span> </p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -59,8 +59,8 @@
|
|||
</div>
|
||||
<div class="card-info">
|
||||
<h3 class="card-title">遥控潜水器汇总统计</h3>
|
||||
<p class="card-count loading">数据加载中</p>
|
||||
<p class="card-desc"></p>
|
||||
<p class="card-count">{{ rov.length }}艘</p>
|
||||
<p class="card-desc"><span v-for="(item, index) in rov" :key="index">{{ item.report_name }}<span v-if="index !== rov.length - 1">、</span></span> </p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -79,8 +79,8 @@
|
|||
</div>
|
||||
<div class="card-info">
|
||||
<h3 class="card-title">无人航行潜水器汇总统计</h3>
|
||||
<p class="card-count loading">数据加载中</p>
|
||||
<p class="card-desc"></p>
|
||||
<p class="card-count">{{ uuv.length }}艘</p>
|
||||
<p class="card-desc"><span v-for="(item, index) in uuv" :key="index">{{ item.report_name }}<span v-if="index !== uuv.length - 1">、</span></span> </p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -100,7 +100,6 @@
|
|||
<div class="card-info">
|
||||
<h3 class="card-title">基站汇总统计</h3>
|
||||
<p class="card-count no-data">暂无数据</p>
|
||||
<p class="card-desc">深海站、深渊站、国际站</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -130,17 +129,34 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { reportList } from '../../api/statistics'
|
||||
import { filterDictItems } from '../../utils/index'
|
||||
|
||||
export default {
|
||||
name: 'MainDashboard',
|
||||
data() {
|
||||
return {
|
||||
|
||||
ship: [],
|
||||
hov: [],
|
||||
rov: [],
|
||||
uuv: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getTypeList()
|
||||
},
|
||||
methods: {
|
||||
goToDetail(type) {
|
||||
this.$router.push(`/container/${type}`);
|
||||
}
|
||||
},
|
||||
getTypeList() {
|
||||
reportList().then(res => {
|
||||
this.ship = filterDictItems(res.array, '科考船')
|
||||
this.hov = filterDictItems(res.array, '载人潜水器')
|
||||
this.rov = filterDictItems(res.array, '遥控潜水器')
|
||||
this.uuv = filterDictItems(res.array, '无人航行潜水器')
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -8,380 +8,71 @@
|
|||
<el-breadcrumb-item>角色管理</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="filter-container">
|
||||
<div class="checkBtn">
|
||||
<el-button type="primary" size="medium" @click="batchImport">添加角色</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table ref="tableData" stripe border :data="tableData" :header-cell-style="{ background: '#dddfe6',color: '#555960',textAlign: 'center' }" :cell-style="{ textAlign: 'center' }" height="600px" @row-click="openModal">
|
||||
<el-table ref="tableData" stripe border :data="tableData" :header-cell-style="{ background: '#dddfe6',color: '#555960',textAlign: 'center' }" :cell-style="{ textAlign: 'center' }" height="600px">
|
||||
<el-table-column
|
||||
type="index"
|
||||
width="50"
|
||||
/>
|
||||
<el-table-column prop="userName" label="角色名称" />
|
||||
<el-table-column prop="describe" label="角色描述" />
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip class="item" effect="dark" content="修改" placement="top-end">
|
||||
<el-button id="mod" size="mini" type="warning" class="el-icon-edit" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="删除" placement="top-end">
|
||||
<el-button id="del" size="mini" type="danger" class="el-icon-delete" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="授权" placement="top-end">
|
||||
<el-button id="permission" size="mini" type="warning" class="el-icon-orange" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="role_name" label="角色名称" />
|
||||
<el-table-column prop="role_note" label="角色描述" />
|
||||
</el-table>
|
||||
<div class="pagination-box">
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="currentPage"
|
||||
:page-sizes="[15, 30, 50]"
|
||||
:page-size="pagesize"
|
||||
:page-sizes="[10, 20, 30]"
|
||||
:page-size="params.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="count"
|
||||
:total="total"
|
||||
:current-page="pageNum"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
<div class="modal">
|
||||
<el-dialog
|
||||
:title="userStatus? '添加角色' : '修改角色'"
|
||||
:visible.sync="showUserForm"
|
||||
width="30%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="140px" :rules="rules">
|
||||
<el-form-item label="角色名称" prop="userName">
|
||||
<el-input v-model="form.userName" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色描述" prop="describe">
|
||||
<el-input v-model="form.describe" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-button
|
||||
style="width: 100px"
|
||||
type="primary"
|
||||
size="medium"
|
||||
@click="saveData"
|
||||
>确定</el-button>
|
||||
<el-button
|
||||
size="medium"
|
||||
style="margin-left: 10px; width: 100px"
|
||||
type="info"
|
||||
plain
|
||||
@click="showUserForm = false;clearInput();resetForm();"
|
||||
>取消</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
title="权限分配"
|
||||
:visible.sync="showAuthorForm"
|
||||
width="30%"
|
||||
:before-close="handleCloseAuthor"
|
||||
>
|
||||
<el-form ref="form2" :model="form" label-width="10px" :rules="rules">
|
||||
<el-form-item label="" prop="sex">
|
||||
<el-select v-model="author" multiple placeholder="请选择" size="medium" style="width:100%">
|
||||
<el-option
|
||||
v-for="item in authorOption"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-button
|
||||
style="width: 100px"
|
||||
type="primary"
|
||||
size="medium"
|
||||
@click="saveAuthorData"
|
||||
>确定</el-button>
|
||||
<el-button
|
||||
size="medium"
|
||||
style="margin-left: 10px; width: 100px"
|
||||
type="info"
|
||||
plain
|
||||
@click="showAuthorForm = false;resetForm2();"
|
||||
>取消</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {roleList} from '../../api/sysManage'
|
||||
|
||||
export default {
|
||||
name: 'RoleManage',
|
||||
data() {
|
||||
return {
|
||||
// 新建
|
||||
userStatus: true,
|
||||
// 数据model
|
||||
recordEnabled: 0,
|
||||
showUserForm: false,
|
||||
showAuthorForm: false,
|
||||
delDialogVisible: false,
|
||||
currentPage: 1,
|
||||
pagesize: 15,
|
||||
count: 0,
|
||||
form: {
|
||||
userName: '',
|
||||
describe: ''
|
||||
loading: false,
|
||||
// 分页请求参数
|
||||
params: {
|
||||
start: 0,
|
||||
limit: 10,
|
||||
group: 10
|
||||
},
|
||||
rules: {
|
||||
userName: [
|
||||
{ required: true, message: '请输入角色名称', trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' }
|
||||
],
|
||||
unit: [
|
||||
{ required: true, message: '请输入单位', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
author: ['用户管理','角色管理'],
|
||||
tableData: [
|
||||
{
|
||||
userName: 'admin',
|
||||
describe: '管理员',
|
||||
createTime: '2022.3.4 12: 20: 00'
|
||||
},
|
||||
{
|
||||
userName: 'admin',
|
||||
describe: '管理员',
|
||||
createTime: '2022.3.4 12: 20: 00'
|
||||
},
|
||||
{
|
||||
userName: 'admin',
|
||||
describe: '管理员',
|
||||
createTime: '2022.3.4 12: 20: 00'
|
||||
}
|
||||
|
||||
],
|
||||
companyOption: [
|
||||
{
|
||||
label: '深海所',
|
||||
value: '深海所'
|
||||
},
|
||||
{
|
||||
label: '机构B',
|
||||
value: '机构B'
|
||||
}
|
||||
],
|
||||
sexOption: [
|
||||
{
|
||||
label: '男',
|
||||
value: '男'
|
||||
},
|
||||
{
|
||||
label: '女',
|
||||
value: '女'
|
||||
}
|
||||
],
|
||||
authorOption: [
|
||||
{
|
||||
label: '用户管理',
|
||||
value: '用户管理'
|
||||
},
|
||||
{
|
||||
label: '角色管理',
|
||||
value: '角色管理'
|
||||
},
|
||||
{
|
||||
label: '单位管理',
|
||||
value: '单位管理'
|
||||
},
|
||||
{
|
||||
label: '字典管理',
|
||||
value: '字典管理'
|
||||
},
|
||||
{
|
||||
label: '统计分析',
|
||||
value: '统计分析'
|
||||
},
|
||||
{
|
||||
label: '数据汇交',
|
||||
value: '数据汇交'
|
||||
},
|
||||
{
|
||||
label: '数据检索',
|
||||
value: '数据检索'
|
||||
}
|
||||
]
|
||||
pageNum: 1,
|
||||
// 列表数据
|
||||
tableData: [],
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const isLogin = localStorage.getItem('isLogin')
|
||||
if (isLogin == 'false' || isLogin == '' || isLogin == undefined) {
|
||||
this.$router.push({ name: 'home' })
|
||||
return
|
||||
}
|
||||
// this.init()
|
||||
this.getData()
|
||||
},
|
||||
methods: {
|
||||
batchImport() {
|
||||
this.showUserForm = true
|
||||
this.userStatus = true
|
||||
},
|
||||
tableIndex(index) {
|
||||
return (this.currentPage - 1) * this.pagesize + index + 1
|
||||
},
|
||||
openModal(row, event, column) {
|
||||
// 判断操作内容
|
||||
var opType = column.target.id
|
||||
if (opType == 'del') {
|
||||
this.$confirm('确定删除选中的数据吗?此操作不可撤销!', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.deleteData(row.id)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
} else if (opType == 'mod') {
|
||||
this.showUserForm = true
|
||||
this.userStatus = false
|
||||
this.form = JSON.parse(JSON.stringify(row))
|
||||
} else if (opType == 'permission') {
|
||||
this.showAuthorForm = true
|
||||
}
|
||||
},
|
||||
async deleteData(id) {
|
||||
this.loading = true
|
||||
const data = {
|
||||
id
|
||||
}
|
||||
try {
|
||||
const res = await deletePlanPage(data)
|
||||
if (res.code == 2000) {
|
||||
this.init()
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
init() {
|
||||
this.currentPage = 1
|
||||
this.getData()
|
||||
},
|
||||
// 初始页currentPage、初始每页数据数pagesize和数据data
|
||||
handleSizeChange: function(size) {
|
||||
this.pagesize = size
|
||||
this.getData()
|
||||
},
|
||||
handleCurrentChange: function(currentPage) {
|
||||
this.currentPage = currentPage
|
||||
this.getData()
|
||||
},
|
||||
fuzzyQueryFunction() {
|
||||
this.currentPage = 1
|
||||
this.getData()
|
||||
},
|
||||
reset() {
|
||||
this.queryName = ''
|
||||
},
|
||||
getData() {
|
||||
// 分页查询以及带条件模糊查询方法
|
||||
this.$http
|
||||
.post(process.env.baseUrl + '/node/findPage', { pageRequest: { pageNum: this.currentPage, pageSize: this.pagesize }, queryName: this.queryName })
|
||||
.then(res => {
|
||||
if (res.code == 2000) { // 1表示成功
|
||||
this.tableData = res.data.page.content
|
||||
this.count = res.data.page.totalSize
|
||||
} else {
|
||||
this.$message.error(res.msg) // 后台出现异常的提示
|
||||
}
|
||||
this.loading = true
|
||||
roleList(this.params).then(res => {
|
||||
this.tableData = res.page.records
|
||||
this.total = Number(res.page.total)
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
saveData() {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.showStatus) {
|
||||
this.addFunction()
|
||||
} else {
|
||||
this.updateFunction()
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
// 分页
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
this.params.start = val * this.params.limit - this.params.limit
|
||||
this.getData()
|
||||
},
|
||||
saveAuthorData() {
|
||||
this.showAuthorForm = false
|
||||
handleSizeChange(val) {
|
||||
this.params.limit = val
|
||||
this.getData()
|
||||
},
|
||||
async addFunction() {
|
||||
this.loading = true
|
||||
const data = {
|
||||
deviceId: this.form.deviceId,
|
||||
deviceName: this.form.deviceName,
|
||||
description: this.form.description,
|
||||
// userId: 123456,
|
||||
userName: this.$store.state.user.user
|
||||
}
|
||||
try {
|
||||
const res = await addPlanPage(data)
|
||||
if (res.code === 2000) {
|
||||
this.$emit('handleConfirm')
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
async updateFunction() {
|
||||
this.loading = true
|
||||
const data = {
|
||||
deviceId: this.form.deviceId,
|
||||
deviceName: this.form.deviceName,
|
||||
description: this.form.description,
|
||||
// userId: 123456,
|
||||
userName: this.$store.state.user.user,
|
||||
id: Number(this.id)
|
||||
}
|
||||
try {
|
||||
const res = await updatePlanPage(data)
|
||||
if (res.code === 2000) {
|
||||
this.$emit('handleConfirm')
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs['form'].resetFields()
|
||||
},
|
||||
resetForm2() {
|
||||
this.$refs['form2'].resetFields()
|
||||
},
|
||||
handleClose(done) { // 加一个点击遮罩和关闭按钮时的回调函数
|
||||
this.clearInput()
|
||||
this.resetForm()
|
||||
done()
|
||||
},
|
||||
handleCloseAuthor(done) {
|
||||
done()
|
||||
},
|
||||
clearInput() {
|
||||
this.form = {
|
||||
userName: '',
|
||||
name: '',
|
||||
describe: '',
|
||||
address: '',
|
||||
unit: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -10,31 +10,33 @@
|
|||
</div>
|
||||
<div class="filter-container">
|
||||
<div class="checkBtn">
|
||||
<el-button type="primary" size="medium" @click="batchImport">添加用户</el-button>
|
||||
<el-button type="primary" size="medium" @click="handleAdd">添加用户</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table ref="tableData" stripe border :data="tableData" :header-cell-style="{ background: '#dddfe6',color: '#555960',textAlign: 'center' }" :cell-style="{ textAlign: 'center' }" height="600px" @row-click="openModal">
|
||||
<el-table ref="tableData" stripe border :data="tableData" :header-cell-style="{ background: '#dddfe6',color: '#555960',textAlign: 'center' }" :cell-style="{ textAlign: 'center' }" height="600px">
|
||||
<el-table-column
|
||||
type="index"
|
||||
width="50"
|
||||
/>
|
||||
<el-table-column prop="userName" label="用户名" />
|
||||
<el-table-column prop="name" label="姓名" />
|
||||
<el-table-column prop="sex" label="性别" />
|
||||
<el-table-column prop="phone" label="电话" />
|
||||
<el-table-column prop="address" label="邮箱" />
|
||||
<el-table-column prop="unit" label="单位" />
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column prop="optr_name" label="操作员名称" />
|
||||
<el-table-column prop="login_name" label="登录名称" />
|
||||
<el-table-column prop="optr_alias" label="别名" />
|
||||
<el-table-column prop="optr_sex" label="性别" />
|
||||
<el-table-column prop="optr_status" label="状态" />
|
||||
<el-table-column prop="optr_email" label="邮箱" />
|
||||
<el-table-column prop="optr_mobile" label="联系电话" />
|
||||
<el-table-column prop="optr_tel" label="办公电话" />
|
||||
<el-table-column prop="role_names" label="角色" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip class="item" effect="dark" content="修改" placement="top-end">
|
||||
<el-button id="mod" size="mini" type="warning" class="el-icon-edit" />
|
||||
<el-button size="mini" type="warning" class="el-icon-edit" @click="handleEdit(scope.row)" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="删除" placement="top-end">
|
||||
<el-button id="del" size="mini" type="danger" class="el-icon-delete" />
|
||||
<el-button size="mini" type="danger" class="el-icon-delete" @click="handleDelete(scope.row)" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="授权" placement="top-end">
|
||||
<el-button id="permission" size="mini" type="warning" class="el-icon-orange" />
|
||||
<el-tooltip class="item" effect="dark" content="分配航次" placement="top-end">
|
||||
<el-button size="mini" type="primary" class="el-icon-s-unfold" @click="handleReg(scope.row)" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -42,54 +44,64 @@
|
|||
<div class="pagination-box">
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="currentPage"
|
||||
:page-sizes="[15, 30, 50]"
|
||||
:page-size="pagesize"
|
||||
:page-sizes="[10, 20, 30]"
|
||||
:page-size="params.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="count"
|
||||
:total="total"
|
||||
:current-page="pageNum"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
<div class="modal">
|
||||
<!-- 新增编辑用户弹窗-->
|
||||
<el-dialog
|
||||
:title="userStatus? '添加用户' : '修改用户'"
|
||||
:visible.sync="showUserForm"
|
||||
:title="title"
|
||||
:visible.sync="open"
|
||||
width="30%"
|
||||
:before-close="handleClose"
|
||||
:before-close="cancel"
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="140px" :rules="rules">
|
||||
<el-form-item label="用户名" prop="userName">
|
||||
<el-input v-model="form.userName" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
<el-form-item label="操作员名称" prop="optr_name">
|
||||
<el-input v-model="form.optr_name" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="form.name" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
<el-form-item label="登录名称" prop="login_name">
|
||||
<el-input v-model="form.login_name" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="phone">
|
||||
<el-input v-model="form.phone" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
<el-form-item label="登录密码" prop="login_pass">
|
||||
<el-input v-model="form.login_pass" size="medium" auto-complete="off" placeholder="请输入" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="address">
|
||||
<el-input v-model="form.address" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
<el-form-item label="别名" prop="optr_alias">
|
||||
<el-input v-model="form.optr_alias" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-select v-model="form.sex" placeholder="请选择" size="medium">
|
||||
<el-form-item label="邮箱" prop="optr_email">
|
||||
<el-input v-model="form.optr_email" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="optr_mobile">
|
||||
<el-input v-model="form.optr_mobile" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="办公电话" prop="optr_tel">
|
||||
<el-input v-model="form.optr_tel" size="medium" auto-complete="off" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色" prop="role_ids">
|
||||
<el-select v-model="form.role_ids" placeholder="请选择" size="medium">
|
||||
<el-option
|
||||
v-for="item in sexOption"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
v-for="item in roleOptions"
|
||||
:key="item.role_id"
|
||||
:label="item.role_name"
|
||||
:value="item.role_id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="单位" prop="unit">
|
||||
<el-select v-model="form.unit" placeholder="请选择" size="medium">
|
||||
<el-option
|
||||
v-for="item in companyOption"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-form-item label="性别" prop="optr_sex">
|
||||
<el-radio-group v-model="form.optr_sex">
|
||||
<el-radio v-for="(item,index) in frameSex" :key="index" :label="item.dict_value">{{ item.dict_text }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="optr_status">
|
||||
<el-radio-group v-model="form.optr_status">
|
||||
<el-radio v-for="(item,index) in frameStatus" :key="index" :label="item.dict_value">{{ item.dict_text }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="center">
|
||||
|
|
@ -97,347 +109,279 @@
|
|||
style="width: 100px"
|
||||
type="primary"
|
||||
size="medium"
|
||||
@click="saveData"
|
||||
@click="submitForm"
|
||||
>确定</el-button>
|
||||
<el-button
|
||||
size="medium"
|
||||
style="margin-left: 10px; width: 100px"
|
||||
type="info"
|
||||
plain
|
||||
@click="showUserForm = false;clearInput();resetForm();"
|
||||
@click="cancel"
|
||||
>取消</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
<!-- 航次分配弹窗-->
|
||||
<el-dialog
|
||||
title="用户授权"
|
||||
:visible.sync="showAuthorForm"
|
||||
width="30%"
|
||||
:before-close="handleCloseAuthor"
|
||||
title="航次列表"
|
||||
:visible.sync="openReg"
|
||||
width="80%"
|
||||
:before-close="cancelReg"
|
||||
>
|
||||
<el-form ref="form2" :model="form" label-width="10px" :rules="rules">
|
||||
<el-form-item label="" prop="sex">
|
||||
<el-select v-model="author" multiple placeholder="请选择" size="medium" style="width:100%">
|
||||
<el-option
|
||||
v-for="item in authorOption"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-button
|
||||
style="width: 100px"
|
||||
type="primary"
|
||||
size="medium"
|
||||
@click="saveAuthorData"
|
||||
>确定</el-button>
|
||||
<el-button
|
||||
size="medium"
|
||||
style="margin-left: 10px; width: 100px"
|
||||
type="info"
|
||||
plain
|
||||
@click="showAuthorForm = false;resetForm2();"
|
||||
>取消</el-button>
|
||||
</el-row>
|
||||
<div class="top-btns">
|
||||
<el-button size="mini" type="danger" @click="handleRegClear">清除</el-button>
|
||||
<el-button size="mini" type="primary" :disabled="multipleSelection.length === 0" @click="handleRegGrant">分配</el-button>
|
||||
</div>
|
||||
<el-table ref="tableData" v-loading="regLoading" stripe border :data="regData" max-height="500" @selection-change="handleSelectionChange" :header-cell-style="{ background: '#dddfe6',color: '#555960',textAlign: 'center' }" :cell-style="{ textAlign: 'center' }">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="voyage_name" label="航次名称" />
|
||||
<el-table-column prop="ship_name" label="科考船舶" />
|
||||
<el-table-column prop="voyage_start_date" label="航次开始">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.voyage_start_date ? scope.row.voyage_start_date.slice(0,10) : '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="voyage_end_date" label="航次结束">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.voyage_end_date ? scope.row.voyage_end_date.slice(0,10) : '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="voyage_officer" label="首席" />
|
||||
<el-table-column prop="member_total" label="参航人数" />
|
||||
<el-table-column prop="funding_org" label="资助机构" />
|
||||
<el-table-column prop="funding_code" label="资助编号" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { roleList, optrAdd, optrEdit, optrList, optrDelete, regList, regGrant, regClear } from '../../api/sysManage'
|
||||
import { initInfo } from '../../api/login'
|
||||
|
||||
export default {
|
||||
name: 'UserManage',
|
||||
data() {
|
||||
return {
|
||||
// 新建
|
||||
userStatus: true,
|
||||
// 数据model
|
||||
recordEnabled: 0,
|
||||
showUserForm: false,
|
||||
showAuthorForm: false,
|
||||
delDialogVisible: false,
|
||||
currentPage: 1,
|
||||
pagesize: 15,
|
||||
count: 0,
|
||||
loading: false,
|
||||
// 分页请求参数
|
||||
params: {
|
||||
start: 0,
|
||||
limit: 10,
|
||||
group: 10,
|
||||
query: ''
|
||||
},
|
||||
pageNum: 1,
|
||||
// 列表数据
|
||||
tableData: [],
|
||||
total: 0,
|
||||
// 新增和编辑表单参数
|
||||
open: false,
|
||||
title: '新增',
|
||||
form: {
|
||||
userName: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
unit: ''
|
||||
optr_dept: 0,
|
||||
optr_name: '',
|
||||
login_name: '',
|
||||
login_pass: '',
|
||||
optr_alias: '',
|
||||
optr_sex: '',
|
||||
optr_status: '',
|
||||
optr_email: '',
|
||||
optr_mobile: '',
|
||||
optr_tel: '',
|
||||
role_ids: ''
|
||||
},
|
||||
rules: {
|
||||
userName: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' }
|
||||
optr_name: [
|
||||
{ required: true, message: '请输入操作员名称', trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' }
|
||||
login_name: [
|
||||
{ required: true, message: '请输入登录名称', trigger: 'blur' }
|
||||
],
|
||||
unit: [
|
||||
{ required: true, message: '请输入单位', trigger: 'blur' }
|
||||
login_pass: [
|
||||
{ required: true, message: '请输入登录密码', trigger: 'blur' }
|
||||
],
|
||||
optr_alias: [
|
||||
{ required: true, message: '请输入别名', trigger: 'blur' }
|
||||
],
|
||||
optr_sex: [
|
||||
{ required: true, message: '请选择操作员性别', trigger: 'change' }
|
||||
],
|
||||
optr_status: [
|
||||
{ required: true, message: '请选择操作员状态', trigger: 'change' }
|
||||
],
|
||||
optr_email: [
|
||||
{ required: true, message: '请输入电子邮件地址', trigger: 'blur' }
|
||||
],
|
||||
optr_mobile: [
|
||||
{ required: true, message: '请输入联系电话', trigger: 'blur' }
|
||||
],
|
||||
optr_tel: [
|
||||
{ required: true, message: '请输入办公电话', trigger: 'blur' }
|
||||
],
|
||||
role_ids: [
|
||||
{ required: true, message: '请选择角色', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
author: ['系统管理员'],
|
||||
tableData: [
|
||||
{
|
||||
userName: 'admin',
|
||||
name: '管理员',
|
||||
sex: '男',
|
||||
phone: '13827182976',
|
||||
address: '134@163.com',
|
||||
unit: '深海所',
|
||||
createTime: '2022.3.4 12: 20: 00'
|
||||
},
|
||||
{
|
||||
userName: 'user',
|
||||
name: 'USER',
|
||||
sex: '男',
|
||||
phone: '13827182976',
|
||||
address: '134@163.com',
|
||||
unit: '深海所',
|
||||
createTime: '2022.3.4 12: 20: 00'
|
||||
},
|
||||
{
|
||||
userName: 'user1',
|
||||
name: 'USER1',
|
||||
sex: '男',
|
||||
phone: '13827182976',
|
||||
address: '134@163.com',
|
||||
unit: '深海所',
|
||||
createTime: '2022.3.4 12: 20: 00'
|
||||
}
|
||||
],
|
||||
companyOption: [
|
||||
{
|
||||
label: '深海所',
|
||||
value: '深海所'
|
||||
},
|
||||
{
|
||||
label: '机构B',
|
||||
value: '机构B'
|
||||
}
|
||||
],
|
||||
sexOption: [
|
||||
{
|
||||
label: '男',
|
||||
value: '男'
|
||||
},
|
||||
{
|
||||
label: '女',
|
||||
value: '女'
|
||||
}
|
||||
],
|
||||
authorOption: [
|
||||
{
|
||||
label: '超级管理员',
|
||||
value: '超级管理员'
|
||||
},
|
||||
{
|
||||
label: '系统管理员',
|
||||
value: '系统管理员'
|
||||
},
|
||||
{
|
||||
label: '普通用户',
|
||||
value: '普通用户'
|
||||
}
|
||||
]
|
||||
frameSex: [],
|
||||
frameStatus: [],
|
||||
roleOptions: [],
|
||||
regLoading: false,
|
||||
openReg: false,
|
||||
regData: [],
|
||||
multipleSelection: [],
|
||||
voyageIds: [],
|
||||
currentUserId: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const isLogin = localStorage.getItem('isLogin')
|
||||
if (isLogin == 'false' || isLogin == '' || isLogin == undefined) {
|
||||
this.$router.push({ name: 'home' })
|
||||
return
|
||||
this.getFrameDictArray()
|
||||
this.getRole()
|
||||
this.getData()
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.loading = true
|
||||
optrList(this.params).then(res => {
|
||||
this.tableData = res.page.records
|
||||
this.total = Number(res.page.total)
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 新增
|
||||
handleAdd() {
|
||||
this.title = '新增'
|
||||
this.open = true
|
||||
},
|
||||
// 编辑
|
||||
handleEdit(row) {
|
||||
this.title = '编辑'
|
||||
this.open = true
|
||||
this.form = JSON.parse(JSON.stringify(row))
|
||||
this.form.role_ids = Number(this.form.role_id)
|
||||
},
|
||||
// 提交表单
|
||||
submitForm() {
|
||||
this.$refs['form'].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.title === '新增') {
|
||||
optrAdd(this.form).then(res => {
|
||||
this.$message.success('已添加新用户!')
|
||||
this.getData()
|
||||
this.cancel()
|
||||
})
|
||||
} else {
|
||||
optrEdit(this.form).then(res => {
|
||||
this.$message.success('用户信息已更新!')
|
||||
this.getData()
|
||||
this.cancel()
|
||||
})
|
||||
}
|
||||
// this.init()
|
||||
const arr = [
|
||||
{
|
||||
key: 1,
|
||||
value: 11
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
value: 22
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
value: 33
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
value: 44
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
value: 55
|
||||
}
|
||||
]
|
||||
arr.map((item, index) => {
|
||||
if (index < arr.length - 1) {
|
||||
console.log(item, arr[index + 1])
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
batchImport() {
|
||||
this.showUserForm = true
|
||||
this.userStatus = true
|
||||
// 关闭弹窗
|
||||
cancel() {
|
||||
this.open = false
|
||||
this.reset()
|
||||
},
|
||||
tableIndex(index) {
|
||||
return (this.currentPage - 1) * this.pagesize + index + 1
|
||||
cancelReg() {
|
||||
this.openReg = false
|
||||
},
|
||||
openModal(row, event, column) {
|
||||
// 判断操作内容
|
||||
var opType = column.target.id
|
||||
if (opType == 'del') {
|
||||
this.$confirm('确定删除选中的数据吗?此操作不可撤销!', '提示', {
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
optr_dept: 0,
|
||||
optr_name: '',
|
||||
login_name: '',
|
||||
login_pass: '',
|
||||
optr_alias: '',
|
||||
optr_sex: '',
|
||||
optr_status: '',
|
||||
optr_email: '',
|
||||
optr_mobile: '',
|
||||
optr_tel: '',
|
||||
role_ids: ''
|
||||
}
|
||||
this.$refs['form'].resetFields()
|
||||
},
|
||||
getFrameDictArray() {
|
||||
initInfo().then(res => {
|
||||
const frameDictArray = res.map.FrameDictArray
|
||||
this.frameStatus = this.filterDictItems(frameDictArray, "FrameStatus")
|
||||
this.frameSex = this.filterDictItems(frameDictArray, "FrameSex")
|
||||
})
|
||||
},
|
||||
filterDictItems(data, dictName) {
|
||||
return data.filter(item => item.dict_name === dictName)
|
||||
},
|
||||
getRole() {
|
||||
roleList().then(res => {
|
||||
this.roleOptions = res.page.records
|
||||
})
|
||||
},
|
||||
// 删除
|
||||
handleDelete(row) {
|
||||
this.$confirm('确定要删除该用户吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
optrDelete(row).then(() => {
|
||||
this.$message.success('删除成功!')
|
||||
this.getData()
|
||||
})
|
||||
.then(() => {
|
||||
this.deleteData(row.id)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
} else if (opType == 'mod') {
|
||||
this.showUserForm = true
|
||||
this.userStatus = false
|
||||
this.form = JSON.parse(JSON.stringify(row))
|
||||
} else if (opType == 'permission') {
|
||||
this.showAuthorForm = true
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
async deleteData(id) {
|
||||
this.loading = true
|
||||
const data = {
|
||||
id
|
||||
}
|
||||
try {
|
||||
const res = await deletePlanPage(data)
|
||||
if (res.code == 2000) {
|
||||
this.init()
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
init() {
|
||||
this.currentPage = 1
|
||||
// 分页
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
this.params.start = val * this.params.limit - this.params.limit
|
||||
this.getData()
|
||||
},
|
||||
// 初始页currentPage、初始每页数据数pagesize和数据data
|
||||
handleSizeChange: function(size) {
|
||||
this.pagesize = size
|
||||
handleSizeChange(val) {
|
||||
this.params.limit = val
|
||||
this.getData()
|
||||
},
|
||||
handleCurrentChange: function(currentPage) {
|
||||
this.currentPage = currentPage
|
||||
this.getData()
|
||||
},
|
||||
fuzzyQueryFunction() {
|
||||
this.currentPage = 1
|
||||
this.getData()
|
||||
},
|
||||
reset() {
|
||||
this.queryName = ''
|
||||
},
|
||||
getData() {
|
||||
// 分页查询以及带条件模糊查询方法
|
||||
this.$http
|
||||
.post(process.env.baseUrl + '/node/findPage', { pageRequest: { pageNum: this.currentPage, pageSize: this.pagesize }, queryName: this.queryName })
|
||||
.then(res => {
|
||||
if (res.code == 2000) { // 1表示成功
|
||||
this.tableData = res.data.page.content
|
||||
this.count = res.data.page.totalSize
|
||||
} else {
|
||||
this.$message.error(res.msg) // 后台出现异常的提示
|
||||
}
|
||||
// 航次分配
|
||||
handleReg(row) {
|
||||
this.openReg = true
|
||||
this.regLoading = true
|
||||
this.currentUserId = row.optr_id
|
||||
|
||||
regList().then(res => {
|
||||
this.regData = res.array
|
||||
this.regLoading = false
|
||||
})
|
||||
},
|
||||
saveData() {
|
||||
this.$refs['form'].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.showStatus) {
|
||||
this.addFunction()
|
||||
} else {
|
||||
this.updateFunction()
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
// 清除所以已分配航次
|
||||
handleRegClear() {
|
||||
regClear({ optr_id: this.currentUserId }).then(res => {
|
||||
this.$message.success('清除成功!')
|
||||
})
|
||||
},
|
||||
saveAuthorData() {
|
||||
this.showAuthorForm = false
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
this.voyageIds = val.map(item => item.tsy_id)
|
||||
console.log(val)
|
||||
},
|
||||
async addFunction() {
|
||||
this.loading = true
|
||||
const data = {
|
||||
deviceId: this.form.deviceId,
|
||||
deviceName: this.form.deviceName,
|
||||
description: this.form.description,
|
||||
// userId: 123456,
|
||||
userName: this.$store.state.user.user
|
||||
}
|
||||
try {
|
||||
const res = await addPlanPage(data)
|
||||
if (res.code === 2000) {
|
||||
this.$emit('handleConfirm')
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
async updateFunction() {
|
||||
this.loading = true
|
||||
const data = {
|
||||
deviceId: this.form.deviceId,
|
||||
deviceName: this.form.deviceName,
|
||||
description: this.form.description,
|
||||
// userId: 123456,
|
||||
userName: this.$store.state.user.user,
|
||||
id: Number(this.id)
|
||||
}
|
||||
try {
|
||||
const res = await updatePlanPage(data)
|
||||
if (res.code === 2000) {
|
||||
this.$emit('handleConfirm')
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
this.loading = false
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs['form'].resetFields()
|
||||
},
|
||||
resetForm2() {
|
||||
this.$refs['form2'].resetFields()
|
||||
},
|
||||
handleClose(done) { // 加一个点击遮罩和关闭按钮时的回调函数
|
||||
this.clearInput()
|
||||
this.resetForm()
|
||||
done()
|
||||
},
|
||||
handleCloseAuthor(done) {
|
||||
done()
|
||||
},
|
||||
clearInput() {
|
||||
this.form = {
|
||||
userName: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
unit: ''
|
||||
}
|
||||
// 确认分配
|
||||
handleRegGrant() {
|
||||
regGrant({
|
||||
optr_id: this.currentUserId,
|
||||
voyage_ids: this.voyageIds
|
||||
}).then(res => {
|
||||
this.$message.success('分配成功!')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.top-btns {
|
||||
margin-bottom: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 2.1 KiB |
Loading…
Reference in New Issue