创建新仓库

This commit is contained in:
2025-07-03 17:39:09 +08:00
commit c781d38c0c
12944 changed files with 807291 additions and 0 deletions

View File

@ -0,0 +1,51 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path" v-if="item.meta.title">
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{item.meta.title}}</span>
<router-link v-else :to="item.redirect||item.path">{{item.meta.title}}</router-link>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
export default {
created() {
this.getBreadcrumb()
},
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
methods: {
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name)
const first = matched[0]
if (first && first.name !== 'dashboard') {
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
}
this.levelList = matched
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 10px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@ -0,0 +1,182 @@
<template>
<Dialog ref="dialog" class="building-add" :title="form.id ? '修改楼栋' : '添加楼栋'" height="200px" left="300px" top="30%"
:closeCallback="clean">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="网格名称:">
<el-input class="name col" size="mini" v-model="form.grid_name" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="楼栋名称:">
<el-input class="name col" size="mini" v-model="form.name" placeholder="请输入内容"></el-input>
</el-form-item>
<!-- <el-form-item label="楼层数:">
<el-input class="name col" size="mini" v-model="form.floors" placeholder="请输入内容"></el-input>
</el-form-item> -->
</el-form>
<template slot="foot">
<button class="btn" @click="drawRange">绘制范围</button>
<button class="btn" @click="onSubmit">确认</button>
</template>
</Dialog>
</template>
<script>
import Dialog from './Dialog.vue'
export default {
components: {
Dialog,
},
props: {
options: {
type: Object,
default: {}
}
},
data() {
return {
form: {
name: '',
grid_name: '',
// content: 2,
range: []
}
}
},
created() {
},
mounted() {
this.$nextTick(() => {
})
},
methods: {
open(data) {
if (data && (data.id || data.ID)) {
this.clean()
this.form = {
id: data.id || data.ID,
name: data.name,
grid_name: data.grid_name,
// content: data.floor,
range: JSON.parse(data.range),
}
this.options.dth.activate()
this.options.dth.addBuildingPrimitive([{ ID: 'temporary', range: data.range }])
}
this.$refs.dialog.open()
},
close() {
this.$refs.dialog.close()
},
async onSubmit() {
try {
if (!this.form.grid_name) {
this.$message({
message: '网格名称不能为空!',
type: 'warning',
duration: 1500
});
return
}
if (!this.form.name) {
this.$message({
message: '楼栋名称不能为空!',
type: 'warning',
duration: 1500
});
return
}
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
if (this.form.id) {
url = this.options.host + '/api/v1/dth/build/edit'
}
else {
url = this.options.host + '/api/v1/dth/build/add'
}
}
else {
if (this.form.id) {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/edit'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/add'
}
}
let response = await fetch(url, {
method: 'post',
body: JSON.stringify(this.form),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: this.form.id ? '修改成功!' : '添加成功!',
type: 'success',
duration: 1500
});
this.close()
this.options.dth.clearAllDthPrimitive()
this.options.dth.clearBuildingPrimitive('temporary')
this.$emit('BuildingOnSubmitCallBack')
}
else {
this.$message({
message: data.message,
type: 'warning',
duration: 1500
});
}
}
} catch (error) {
console.log(error)
}
},
drawRange() {
this.options.dth.deactivate()
this.options.dth.clearBuildingPrimitive('temporary')
this.Draw && this.Draw.end()
this.Draw = new YJ.Draw.DrawPolygon(this.options.sdk)
this.Draw.start((a, positions) => {
if (positions.length < 3) {
this.$message({
message: '至少需要三个点',
type: 'warning',
duration: 1500
});
return
}
else {
this.options.dth.activate()
this.options.dth.addBuildingPrimitive([{ ID: 'temporary', range: JSON.stringify(positions) }])
this.form.range = positions
this.Draw = null
// this.options.dth.savePrimitive()
}
})
},
clean() {
this.form = {
name: '',
// content: 2,
range: []
}
this.Draw && this.Draw.end()
this.Draw = null
this.options.dth.clearBuildingPrimitive('temporary')
}
},
beforeDestroy() {
this.clean()
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,214 @@
<template>
<Dialog ref="dialog" class="dth-add" title="添加户型" width="300px" height="380px" left="765px" top="100px" :closeCallback="clean">
<el-form ref="form" :model="form" label-width="90px">
<el-form-item label="户型名称:">
<el-input size="mini" v-model="form.name" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="底部高程:">
<el-input-number size="mini" v-model="form.bottom" controls-position="right" @change="createDth" :min="0"
:max="9999999" :step="0.1"></el-input-number>
</el-form-item>
<el-form-item label="楼层数:">
<el-input-number size="mini" v-model="form.floor" controls-position="right" @change="createDth" :min="0"
:max="999"></el-input-number>
</el-form-item>
<el-form-item label="层高:">
<el-input-number size="mini" v-model="form.height" controls-position="right" @change="createDth" :min="0"
:max="999"></el-input-number>
</el-form-item>
<el-form-item label="房间号:">
<el-input-number size="mini" v-model="form.room_num" controls-position="right" :min="0"
:max="999999"></el-input-number>
</el-form-item>
<el-form-item label="最小楼层号:">
<el-input-number size="mini" v-model="form.min_floor_num" controls-position="right" :min="0"
:max="999999"></el-input-number>
</el-form-item>
</el-form>
<template slot="foot">
<!-- <button @click="drawRange">绘制范围</button> -->
<button @click="onSubmit">确认</button>
</template>
<span class="custom-divider"></span>
</Dialog>
</template>
<script>
import Dialog from './Dialog.vue'
export default {
components: {
Dialog,
},
props: {
options: {
type: Object,
default: {}
}
},
data() {
return {
params: [],
form: {
height: 3,
floor: 2,
bottom: 0,
room_num: 1,
min_floor_num: 1
}
}
},
created() {
},
mounted() {
this.$nextTick(() => {
})
},
methods: {
open() {
this.$refs.dialog.open()
},
close() {
this.$refs.dialog.close()
},
clean() {
this.Draw && this.Draw.end()
this.Draw = null
this.options.dth.clearAllUnitPrimitive()
this.options.dth.clearDthPrimitive('temporary')
},
async onSubmit() {
if (!this.form.name) {
this.$message({
message: '户型名称不能为空!',
type: 'warning',
duration: 1500
});
return
}
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/huxing/add'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/huxing/add'
}
try {
let params = this.initData()
let response = await fetch(url, {
method: 'post',
body: JSON.stringify({ name: this.form.name, build_id: this.build.ID, dan_yuan_id: this.unit.ID, params }),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '添加成功!',
type: 'success',
duration: 1500
});
this.close()
this.options.dth.clearAllUnitPrimitive()
this.options.dth.clearDthPrimitive()
this.$emit('getHXList', this.unit.ID)
// this.$emit('onSubmitCallBack')
}
}
} catch (error) {
console.log(error)
}
},
drawRange(data) {
this.build = data.build
this.unit = data.unit
this.options.dth.deactivate()
this.Draw && this.Draw.end()
this.Draw = new YJ.Draw.DrawPolygon(this.options.sdk)
this.Draw.start((a, positions) => {
this.options.dth.activate()
if (positions.length < 3) {
this.$message({
message: '至少需要三个点',
type: 'warning',
duration: 1500
});
this.options.dth.clearAllUnitPrimitive()
return
}
else {
let range = JSON.parse(this.unit.range)
let array = []
for (let i = 0; i < range.length; i++) {
array.push([range[i].lng, range[i].lat])
}
let unit = turf.polygon([array]);
let array2 = []
for (let i = 0; i < positions.length; i++) {
array2.push([positions[i].lng, positions[i].lat])
}
array2.push([positions[0].lng, positions[0].lat])
let hx = turf.polygon([array2]);
let intersection = turf.intersect(unit, hx);
console.log(intersection)
if (!intersection) {
this.$message({
message: '请在单元范围内绘制!',
type: 'warning',
duration: 1500
});
this.options.dth.clearAllUnitPrimitive()
return
}
let hxPos = []
for (let i = 0; i < intersection.geometry.coordinates[0].length; i++) {
hxPos.push({ lng: intersection.geometry.coordinates[0][i][0], lat: intersection.geometry.coordinates[0][i][1] })
}
this.open()
this.form.range = hxPos
let bottom = positions[0].alt
for (let i = 1; i < positions.length; i++) {
if (bottom > positions[i].alt) {
bottom = positions[i].alt
}
}
this.form.bottom = Number(bottom.toFixed(2))
this.createDth()
}
})
},
createDth() {
this.options.dth.clearDthPrimitive('temporary')
let params = this.initData()
for (let i = 0; i < params.length; i++) {
params[i].ID = 'temporary'
}
this.options.dth.addDthPrimitive(params, this.build, this.unit)
},
initData() {
let array = []
for (let i = 0; i < this.form.floor; i++) {
array.push({
range: JSON.stringify(this.form.range),
bottom: this.form.bottom + (i * this.form.height),
top: this.form.bottom + ((i + 1) * this.form.height),
height: this.form.height,
room_num: (this.form.min_floor_num + i) + '-' + this.form.room_num,
floor_num: this.form.min_floor_num + i
})
}
return array
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,236 @@
<template>
<Dialog ref="dialog" class="dth-add" title="添加单元" width="300px" height="160px" left="765px" top="100px"
:closeCallback="clean">
<el-form ref="form" :model="form" label-width="90px">
<el-form-item label="单元名称:">
<el-input size="mini" v-model="form.name" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<template slot="foot">
<button @click="drawRange">绘制范围</button>
<button v-if="form.dan_yuan_id" @click="onSubmitEdit">确认</button>
<button v-else @click="onSubmit">确认</button>
</template>
</Dialog>
</template>
<script>
import Dialog from './Dialog.vue'
export default {
components: {
Dialog,
},
props: {
options: {
type: Object,
default: {}
}
},
data() {
return {
params: [],
buildInfo: null,
form: {
name: '',
build_id: '',
range: ''
}
}
},
created() {
},
mounted() {
this.$nextTick(() => {
})
},
methods: {
open(data) {
this.buildInfo = { ...data.build }
this.form.build_id = this.buildInfo.ID
if (data.unit) {
this.form.dan_yuan_id = data.unit.ID
this.form.name = data.unit.name
this.form.range = data.unit.range
}
this.$refs.dialog.open()
},
close() {
this.$refs.dialog.close()
},
clean() {
this.form = {
name: '',
build_id: '',
range: ''
}
this.buildInfo = null
this.Draw && this.Draw.end()
this.Draw = null
this.options.dth.clearAllUnitPrimitive()
},
async onSubmit() {
if (!this.form.name) {
this.$message({
message: '单元名称不能为空!',
type: 'warning',
duration: 1500
});
return
}
if (!this.form.range) {
this.$message({
message: '请先绘制范围!',
type: 'warning',
duration: 1500
});
return
}
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/danyuan/add'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/add'
}
try {
let response = await fetch(url, {
method: 'post',
body: JSON.stringify({ build_id: this.form.build_id, name: this.form.name, range: this.form.range }),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '添加成功!',
type: 'success',
duration: 1500
});
this.options.dth.clearAllUnitPrimitive()
this.$emit('getUnitList', this.form.build_id)
this.close()
} else if (data.code == 50) {
this.$message({
message: data.message,
type: 'warning',
duration: 1500
});
}
}
} catch (error) {
console.log(error)
}
},
async onSubmitEdit() {
if (!this.form.name) {
this.$message({
message: '单元名称不能为空!',
type: 'warning',
duration: 1500
});
return
}
if (!this.form.range) {
this.$message({
message: '请先绘制范围!',
type: 'warning',
duration: 1500
});
return
}
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/danyuan/edit'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/edit'
}
try {
let response = await fetch(url, {
method: 'post',
body: JSON.stringify({ dan_yuan_id: this.form.dan_yuan_id, build_id: this.form.build_id, name: this.form.name, range: this.form.range }),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '修改成功!',
type: 'success',
duration: 1500
});
this.options.dth.clearAllDthPrimitive()
this.options.dth.clearAllUnitPrimitive()
this.$emit('getUnitList', this.form.build_id)
this.close()
}
}
} catch (error) {
console.log(error)
}
},
drawRange() {
this.Draw && this.Draw.end()
this.Draw = new YJ.Draw.DrawPolygon(this.options.sdk)
this.Draw.start((a, positions) => {
if (positions.length < 3) {
this.$message({
message: '至少需要三个点',
type: 'warning',
duration: 1500
});
return
}
else {
let range = JSON.parse(this.buildInfo.range)
let array = []
for (let i = 0; i < range.length; i++) {
array.push([range[i].lng, range[i].lat])
}
array.push([range[0].lng, range[0].lat])
let build = turf.polygon([array]);
let array2 = []
for (let i = 0; i < positions.length; i++) {
array2.push([positions[i].lng, positions[i].lat])
}
array2.push([positions[0].lng, positions[0].lat])
let unit = turf.polygon([array2]);
let intersection = turf.intersect(build, unit);
let unitPos = []
if (!intersection || !intersection.geometry) {
this.$message({
message: '请在楼栋范围内添加',
type: 'warning',
duration: 1500
});
return
}
for (let i = 0; i < intersection.geometry.coordinates[0].length; i++) {
unitPos.push({ lng: intersection.geometry.coordinates[0][i][0], lat: intersection.geometry.coordinates[0][i][1] })
}
this.options.dth.activate()
this.options.dth.addUnitPrimitive([{ ID: 'temporary', range: JSON.stringify(unitPos) }])
this.form.range = JSON.stringify(unitPos)
this.Draw = null
// this.options.dth.savePrimitive()
}
})
}
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,828 @@
<template>
<Dialog ref="dialog" class="building-list" title="楼栋列表" height="62vh" left="180px" top="100px">
<div class="building">
<el-table :data="building.list" ref="buildingTable" border style="width: 100%" size="mini"
height="calc(100% - 40px)" @row-click="openUnitList" @row-contextmenu="flyto" @select="selectEvent"
@select-all="selectEvent">
<el-table-column type="expand" width="25">
<template slot-scope="props">
<el-table :data="unit[props.row.ID]" border style="width: 545px;" size="mini" height="145px"
@row-click="openHXList">
<el-table-column type="index" label="序号" width="50" align="center">
</el-table-column>
<el-table-column prop="name" width="240" label="单元名称" header-align="center" align="center">
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<div style="display: flex;justify-content: space-around;">
<button size="mini" type="text" @click.stop="openAddHX(props.row, scope.row)">添加户型</button>
<button size="mini" type="text" @click.stop="openUpdateUnit(props.row, scope.row)">修改</button>
<el-popconfirm title="确定删除该单元吗?" @confirm="deleteUnit(props.row.ID, scope.row.ID)">
<button class="danger" slot="reference" @click.stop>删除</button>
</el-popconfirm>
</div>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column type="selection" width="40" align="center">
</el-table-column>
<el-table-column type="index" label="序号" width="50" align="center">
</el-table-column>
<el-table-column prop="name" label="楼栋名称" width="140" header-align="center" align="center">
</el-table-column>
<el-table-column prop="grid_name" label="网格名称" width="110" header-align="center" align="center">
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<div style="display: flex;flex-wrap: wrap;justify-content: space-around;height: 58px;">
<!-- <el-button size="mini" type="text" @click.stop="openAddDth(scope.row)">添加单体化</el-button> -->
<button @click.stop="openAddUnit(scope.row)">添加单元</button>
<button @click.stop="checkUser(scope.row)">查看用户</button>
<button style="margin-left: 0px;width: 70px;justify-content: center;"
@click.stop="cilckOpenEditBuilding(scope.row)">修改</button>
<el-popconfirm popper-class="yj-dth-el-popper" title="确定删除该楼栋吗?"
:popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }"
@confirm="deleteBuilding([scope.row.ID])">
<button class="danger" slot="reference" style="width: 70px;" @click.stop>删除</button>
</el-popconfirm>
</div>
</template>
</el-table-column>
<!-- <el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button @click.native.prevent="openDthList(scope.row.id)" type="text" size="small">
单体化列表
</el-button>
</template>
</el-table-column> -->
</el-table>
<el-pagination medium layout="sizes, prev, pager, next" :total="building.total"
:page-sizes="[10, 50, 100, 200, 300, 400, 500]" :page-size="building.page_size" @current-change="currentChange"
@size-change="handleSizeChange">
</el-pagination>
</div>
<div class="hx" v-show="showHX">
<el-table :data="hx.list" border style="width: 270px" size="mini" height="calc(100% - 40px)">
<el-table-column type="index" label="序号" width="50" align="center">
</el-table-column>
<el-table-column prop="name" label="户型名称" width="120" align="center">
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<div style="display: flex;justify-content: space-around;">
<button size="mini" type="text" style="margin-left: 0px;" <!--
@click.stop="openEditHX(scope.row)">修改</button> -->
<el-popconfirm title="确定删除该户型吗?" @confirm="deleteHX(scope.row.ID)">
<button class="danger" slot="reference" size="mini" type="text" style="color: #ff0000;margin-left: 0px;"
@click.stop>删除</button>
</el-popconfirm>
</div>
</template>
</el-table-column>
</el-table>
<!-- <el-pagination small layout="prev, pager, next" :total="dth.total" @current-change="currentChange">
</el-pagination> -->
</div>
<template slot="foot">
<div class="building">
<div>
显示全部:
<el-switch v-model="allShowStatus" @change="showAllBuilding" active-color="#13ce66" inactive-color="#ff4949">
</el-switch>
</div>
<button @click="openAddBuilding">增加楼栋</button>
<button @click="importBuilding">导入楼栋</button>
<button @click="importUnit">导入单元</button>
<button @click="batchDeleteBuilding">删除楼栋</button>
<!-- <el-popconfirm :title="`是否确定删除选中的 ${selectionBuild.length} 条楼栋数据?`"
@confirm="deleteUnit(props.row.ID, scope.row.ID)">
<button class="danger" @click="deleteBuilding">删除楼栋</button>
</el-popconfirm> -->
</div>
</template>
</Dialog>
</template>
<script>
import Dialog from './Dialog.vue'
export default {
components: {
Dialog,
},
props: {
options: {
type: Object,
default: {}
}
},
data() {
return {
showHX: false,
allShowStatus: false,
selectionBuild: [],
building: {
total: 0,
page: 1,
page_size: 10,
list: []
},
unit: {},
hx: {
build_id: null,
list: []
}
}
},
created() {
},
mounted() {
this.$nextTick(() => {
})
},
methods: {
open(data) {
this.showHX = false
this.$refs.dialog.open()
this.building.total = 0
this.building.page = 1
this.building.page_size = 10
this.building.list = []
this.tools = new YJ.Tools(this.options.sdk)
this.getList()
},
close() {
this.$refs.dialog.close()
},
currentChange(page) {
this.building.page = page
this.getList()
},
handleSizeChange(val) {
this.building.page_size = val
this.getList()
},
// 获取楼栋列表
async getList() {
try {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/build/list'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/list'
}
url = url + `?page=${this.building.page}&page_size=${this.building.page_size}`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.building.total = data.data.total
this.building.list = data.data.list
this.$nextTick(() => {
for (let i = 0; i < this.building.list.length; i++) {
for (let j = 0; j < this.selectionBuild.length; j++) {
if (this.building.list[i].ID === this.selectionBuild[j].ID) {
this.$refs.buildingTable.toggleRowSelection(this.building.list[i]);
}
}
}
})
for (let i = 0; i < this.building.list.length; i++) {
this.getUnitList(this.building.list[i].ID)
}
if (this.building.list.length === 0 && this.building.page > 1) {
this.building.page--
this.getList()
}
}
}
} catch (error) {
console.log(error)
}
},
batchDeleteBuilding() {
if (this.selectionBuild.length === 0) {
this.$message({
message: '请选择要删除的楼栋!',
type: 'warning',
duration: 1500
});
return;
}
else {
const h = this.$createElement
this.$confirm('', {
message: h('div', null, [
h('i', { class: 'el-icon-question', style: 'color:#f90;font-size:30px;' }),
h('span', { style: 'margin-left:10px;font-size:16px;line-height:30px;font-weight:600;vertical-align:top;' }, '提示'),
h('p', { style: 'margin:10px 0 0 40px;' }, `是否确定删除选中的 ${this.selectionBuild.length} 条楼栋数据?`)
]),
confirmButtonText: '确定',
cancelButtonText: '取消',
customClass: 'del-model',
closeOnClickModal: false,
closeOnPressEscape: false,
})
.then(_ => {
let ids = []
for (let i = 0; i < this.selectionBuild.length; i++) {
ids.push(this.selectionBuild[i].ID)
}
this.deleteBuilding(ids)
})
.catch(_ => { });
}
},
// 删除楼栋
async deleteBuilding(ids) {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/build/del'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/del'
}
try {
let response = await fetch(url, {
method: 'post',
body: JSON.stringify({ ids: ids }),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '删除成功!',
type: 'success',
duration: 1500
});
for (let i = 0; i < ids.length; i++) {
if (this.hx && this.hx.list[0] && ids[i] === this.hx.list[0].build_id) {
this.hx.list = []
this.showHX = false
break
}
}
this.selectionBuild = this.selectionBuild.filter(item => !ids.includes(item.ID));
this.getList()
this.showAllBuilding()
}
}
} catch (error) {
console.log(error)
}
},
// 获取单元列表
async getUnitList(id) {
try {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/danyuan/list'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/list'
}
url = url + `?build_id=${id}`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.unit[id] = data.data.list
this.$refs.buildingTable.toggleRowExpansion()
}
}
} catch (error) {
console.log(error)
}
},
// 删除单元
async deleteUnit(build_id, unit_id) {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/danyuan/del'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/del'
}
try {
let response = await fetch(url, {
method: 'post',
body: JSON.stringify({ dan_yuan_id: unit_id }),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '删除成功!',
type: 'success',
duration: 1500
});
this.getUnitList(build_id)
}
}
} catch (error) {
console.log(error)
}
},
// 修改单元
// async updateUnit(build_id, unit_id) {
// let url = ""
// if (this.options.host.endsWith("yjearth4.0")) {
// url = this.options.host + '/api/v1/dth/danyuan/edit'
// }
// else {
// url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/edit'
// }
// try {
// let response = await fetch(url, {
// method: 'post',
// body: JSON.stringify({ dan_yuan_id: unit_id }),
// headers: {
// 'Content-Type': 'application/json',
// "token": this.options.token,
// "Authorization": "Bearer " + this.options.token,
// }
// })
// if (response.status === 200) {
// let data = await response.json()
// if (data.code === 200 || data.code === 0) {
// this.$message({
// message: '删除成功!',
// type: 'success',
// duration: 1500
// });
// this.getUnitList(build_id)
// }
// }
// } catch (error) {
// console.log(error)
// }
// },
// 显示全部楼栋
async showAllBuilding() {
this.options.dth.clearAllBuildingPrimitive()
// this.options.dth.clearAllDthPrimitive()
if (this.allShowStatus) {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/build/list'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/list'
}
url = url + `?page=1&page_size=100000`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.options.dth.addBuildingPrimitive(data.data.list)
// 显示所有单体化
return
let buildingList = data.data.list
for (let i = 0; i < buildingList.length; i++) {
let url2 = ""
if (this.options.host.endsWith("yjearth4.0")) {
url2 = this.options.host + '/api/v1/dth/dth/list'
}
else {
url2 = this.options.host + '/yjearth4.0/api/v1/dth/dth/list'
}
url2 = url2 + `?build_id=${buildingList[i].ID}`
let response2 = await fetch(url2, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response2.status === 200) {
let data2 = await response2.json()
if (data2.code === 200 || data2.code === 0) {
this.options.dth.addDthPrimitive(data2.data.list)
}
}
}
}
}
}
},
// 打开添加楼栋
openAddBuilding() {
this.$emit('addBuilding')
},
// 修改楼栋
openEditBuilding(data) {
this.$emit('addBuilding', data)
},
// 点击修改楼栋
cilckOpenEditBuilding(data) {
this.flyTo(JSON.parse(data.range))
this.openEditBuilding(data)
},
// 打开单元列表
openUnitList(row) {
this.$refs.buildingTable.toggleRowExpansion(row)
},
// 飞入
flyto(row) {
console.log('rowrowrowrow', row);
this.flyTo(JSON.parse(row.range))
},
// 打开户型列表
openHXList(row) {
this.showHX = true
this.getHXList(row.ID)
},
// 获取户型列表
async getHXList(id) {
try {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/huxing/list'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/huxing/list'
}
url = url + `?dan_yuan_id=${id}`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.hx = { unitId: id, list: data.data.list }
}
}
} catch (error) {
console.log(error)
}
},
// 删除户型
async deleteHX(id) {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/huxing/del'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/huxing/del'
}
try {
let response = await fetch(url, {
method: 'post',
body: JSON.stringify({ hu_xing_id: id }),
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '删除成功!',
type: 'success',
duration: 1500
});
this.getHXList(this.hx.unitId)
}
}
} catch (error) {
console.log(error)
}
},
// 添加单元
openAddUnit(row) {
this.$emit('openAddUnit', { build: row })
},
// 打开修改单元
openUpdateUnit(build, unit) {
this.$emit('openAddUnit', { build: build, unit: unit })
},
// 打开添加户型
openAddHX(build, unit) {
this.options.dth.clearAllUnitPrimitive()
this.options.dth.addUnitPrimitive([{ ID: 'temporary', range: unit.range }])
this.$emit('addHX', { build: build, unit: unit })
},
// 打开修改
openEditHX(row) {
let build
let unit = this.unit[row.build_id]
for (let i = 0; i < this.building.list.length; i++) {
if (this.building.list[i].ID === row.build_id) {
build = this.building.list[i]
break
}
}
this.options.dth.addUnitPrimitive([{ ID: 'temporary', range: unit.range }])
this.$emit('addHX', { build: build, unit: unit, hx: row })
},
// 导入楼栋
importBuilding() {
const input = document.createElement("input");
input.type = 'file'
input.accept = '.shp,.cpg,.dbf,.prj,.sbn,.sbx,.shx';
input.multiple = 'multiple'
input.click()
input.addEventListener('change', async (event) => {
let files = event.target.files
let url = ""
console.log(files)
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files', files[i]);
}
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/build/import'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/import'
}
try {
let response = await fetch(url, {
method: 'post',
body: formData,
headers: {
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '导入成功!',
type: 'success',
duration: 1500
});
this.getList()
}
else {
this.$message({
message: data.message,
type: 'warning',
duration: 1500
});
}
}
} catch (error) {
console.log(error)
}
})
},
// 导入单元
importUnit() {
const input = document.createElement("input");
input.type = 'file'
input.accept = '.shp,.cpg,.dbf,.prj,.sbn,.sbx,.shx';
input.multiple = 'multiple'
input.click()
input.addEventListener('change', async (event) => {
let files = event.target.files
let url = ""
console.log(files)
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files', files[i]);
}
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/danyuan/import'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/import'
}
try {
let response = await fetch(url, {
method: 'post',
body: formData,
headers: {
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '导入成功!',
type: 'success',
duration: 1500
});
this.getList()
}
else {
this.$message({
message: data.message,
type: 'warning',
duration: 1500
});
}
}
} catch (error) {
console.log(error)
}
})
},
//导入用户
importUser(row) {
const input = document.createElement("input");
input.type = 'file'
input.accept = '.xlsx';
input.click()
input.addEventListener('change', async (event) => {
let file = event.target.files[0]
let url = ""
const formData = new FormData();
formData.append('file', file);
formData.append('build_id', row.ID || row.id);
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/customization/chongqing/dazu/community/users/import'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/customization/chongqing/dazu/community/users/import'
}
try {
let response = await fetch(url, {
method: 'post',
body: formData,
headers: {
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.$message({
message: '导入成功!',
type: 'success',
duration: 1500
});
}
else {
this.$message({
message: data.message,
type: 'warning',
duration: 1500
});
}
}
} catch (error) {
console.log(error)
}
})
},
// 查看用户
checkUser(row) {
this.$emit('openInfoList', 'Build', { build_info: row })
},
// 清空用户
cleanUser(row) { },
// 飞到
async flyTo(positions) {
this.options.dth.flyTo(positions)
},
selectEvent(selection, row) {
// this.selectionBuild.concat(selection)
if (row) {
let status = false
for (let i = 0; i < selection.length; i++) {
if (selection[i].ID === row.ID) {
status = true
break
}
}
for (let i = 0; i < selection.length; i++) {
let flag = false
for (let j = 0; j < this.selectionBuild.length; j++) {
if (selection[i].ID === this.selectionBuild[j].ID) {
flag = true
}
}
if (!flag) {
this.selectionBuild.push(selection[i])
}
}
if (!status) {
// 取消选中
this.selectionBuild.concat(selection)
for (let i = 0; i < this.selectionBuild.length; i++) {
if (this.selectionBuild[i].ID === row.ID) {
this.selectionBuild.splice(i, 1)
break
}
}
}
}
else {
if (selection.length === 0) {
// 取消选中
for (let i = this.building.list.length - 1; i >= 0; i--) {
for (let j = this.selectionBuild.length - 1; j >= 0; j--) {
if (this.building.list[i].ID === this.selectionBuild[j].ID) {
this.selectionBuild.splice(j, 1)
break
}
}
}
}
else {
for (let i = 0; i < selection.length; i++) {
let flag = false
for (let j = 0; j < this.selectionBuild.length; j++) {
if (selection[i].ID === this.selectionBuild[j].ID) {
flag = true
}
}
if (!flag) {
this.selectionBuild.push(selection[i])
}
}
}
}
}
}
}
</script>
<style scoped>
.yj-dth .building-list .content .el-table .cell button.danger {
color: #ff0000;
margin-left: 0px;
justify-content: center;
background-color: rgba(229, 93, 93, 0.2);
border-color: rgba(229, 93, 93, 0.5);
}
.yj-dth .building-list .content .el-table .cell button.danger:hover {
border-color: rgba(255, 0, 0, 0.8) !important;
}
</style>

View File

@ -0,0 +1,175 @@
<template>
<div v-if="dialogVisible" class="YJ-custom-base-dialog" ref="dialogDispatch"
:style="`width: ${width}; height: ${height}; left: ${isleft}; top: ${istop}; bottom: ${isbottom}; right: ${isright};`">
<div class="title-box">
<span class="title">{{ title }}</span>
<span class="close-box" @click="close"><span class="close"></span><i></i></span>
<span class="custom-divider"></span>
</div>
<div class="content" style="height: calc(100% - 124px);">
<slot></slot>
</div>
<div class="foot">
<slot name="foot"></slot>
<!-- <button class="close" @click="close">关闭</button> -->
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: ''
},
width: {
type: String,
default: '400px'
},
height: {
type: String,
default: '600px'
},
left: {
type: String,
default: '0'
},
right: {
type: String,
default: 'unset'
},
top: {
type: String,
default: '0'
},
bottom: {
type: String,
default: 'unset'
},
closeCallback: {
type: Function,
default: () => {}
}
},
data() {
return {
isleft: this.left,
isright: this.right,
istop: this.top,
isbottom: this.bottom,
first: false,
dialogVisible: false
}
},
created() {
// this.FontChart = FontChart
},
mounted() {
},
methods: {
open(data) {
this.dialogVisible = true
this.$nextTick(() => {
this.moveDiv()
})
},
close() {
this.closeCallback()
this.dialogVisible = false
},
moveDiv() {
let x = 0
let y = 0
let l = 0
let t = 0
let oClickDiv = this.$refs.dialogDispatch
let _this = this
oClickDiv.onmousedown = (e) => {
if (e.toElement.className !== 'title-box') {
return
}
// dialog的宽度、高度
// let oMoveDivHeight = that.oMoveDiv.offsetHeight
let oMoveDivHeight = oClickDiv.offsetHeight
// let oMoveDivWidth = that.oMoveDiv.offsetWidth
let oMoveDivWidth = oClickDiv.offsetWidth
x = e.clientX
y = e.clientY
let leftPx = window.getComputedStyle(oClickDiv).left
let topPx = window.getComputedStyle(oClickDiv).top
l = leftPx.substr(0, leftPx.indexOf('px')) * 1
t = topPx.substr(0, topPx.indexOf('px')) * 1
// 视口大小
let windowHeight = document.documentElement.clientHeight
let windowWidth = document.documentElement.clientWidth
//鼠标移动
window.onmousemove = function (e) {
e.preventDefault()
//获取x和y
let nx = e.clientX
let ny = e.clientY
//计算移动后的左偏移量和顶部的偏移量
let leftPx = nx - (x - l)
let topPx = ny - (y - t)
if (leftPx < 0) {
leftPx = 0
} else if (leftPx + oMoveDivWidth > windowWidth) {
leftPx = windowWidth - oMoveDivWidth
}
if (topPx <= 0) {
topPx = 0
} else if (topPx + oMoveDivHeight > windowHeight) {
topPx = windowHeight - oMoveDivHeight
}
oClickDiv.style.left = _this.isleft = leftPx + 'px'
oClickDiv.style.top = _this.istop = topPx + 'px'
oClickDiv.style.bottom = _this.isbottom = 'unset'
oClickDiv.style.right = _this.isright = 'unset'
}
}
//鼠标抬起事件
window.onmouseup = function (e) {
window.onmousemove = null
}
},
async getList() {
try {
let url = ""
if (host.endsWith("yjearth4.0")) {
url = host + '/api/v1/dth/build_list'
}
else {
url = host + '/yjearth4.0/api/v1/dth/build_list'
}
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": getToken(),
"Authorization": "Bearer " + getToken(),
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) { }
}
} catch (error) {
console.log(error)
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,164 @@
<template>
<div class="user-table-box">
<div class="user-info-list-box">
<div class="search-box">
<el-form ref="form" :model="condition">
<el-form-item label="法人姓名:">
<el-input size="mini" v-model="condition.fa_ren_xing_ming" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="网格名称:">
<el-input size="mini" v-model="condition.grid_name" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="一标三识:">
<el-input size="mini" v-model="condition.addr" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="法人电话:">
<el-input size="mini" v-model="condition.tel" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item>
<button size="mini" class="search-btn" type='button' @click="search">查询</button>
</el-form-item>
</el-form>
</div>
<myTable :data="data" type="build"></myTable>
<el-pagination medium layout="total, prev, pager, next" :total="total" :current-page="page"
@current-change="currentChange">
</el-pagination>
</div>
</div>
</template>
<script>
import Dialog from '../../Dialog.vue'
import myTable from '../table/business.vue'
export default {
components: {
Dialog,
myTable
},
props: {
options: {
type: Object,
default: {}
},
propsData: {
type: Object,
default: {}
}
},
data() {
return {
condition: {
fa_ren_xing_ming: '',
grid_name: '',
addr: '',
tel: ''
},
is_important: [
{
value: '0',
label: '0'
},
{
value: '1',
label: '1'
},
{
value: '2',
label: '2'
},
{
value: '3',
label: '3'
},
{
value: '4',
label: '4'
},
{
value: '5',
label: '5'
}
],
keyWord: '',
data: {},
total: 0,
page: 1,
apiUrl: ''
}
},
watch: {
propsData: {
handler: function (newValue, oldValue) {
this.condition = {
fa_ren_xing_ming: '',
grid_name: '',
addr: '',
tel: ''
}
this.data = { ...this.propsData }
if (this.options.host.endsWith("yjearth4.0")) {
this.apiUrl = this.options.host + '/api/v1/customization/chongqing/dazu/community/business/list'
}
else {
this.apiUrl = this.options.host + '/yjearth4.0/api/v1/customization/chongqing/dazu/community/business/list'
}
if (this.data.business_info) {
this.page = 1
this.total = this.data.business_info.total
this.data.business_info.list && (this.data.business_info.business = [...this.data.business_info.list])
}
else {
this.getUserInfoList(1)
}
},
immediate: true,
deep: true
}
},
created() {
},
mounted() {
},
methods: {
currentChange(page) {
this.getUserInfoList(page)
},
search() {
this.getUserInfoList(1)
},
async getUserInfoList(page) {
this.page = page
try {
let url = this.apiUrl
url = url + `?fa_ren_xing_ming=${this.condition.fa_ren_xing_ming}&grid_name=${this.condition.grid_name}&addr=${this.condition.addr}&tel=${this.condition.tel}&page=${page}&page_size=10`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.data.business_info = data.data
this.data = { ...this.data }
this.data.business_info.list && (this.data.business_info.business = [...this.data.business_info.list])
this.total = this.data.business_info.total
}
}
} catch (error) {
console.log(error)
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,53 @@
<template>
<Dialog ref="dialog" class="user-info-list" :title="title" width="580px" height="62vh" left="calc(50% + 5px)"
top="100px">
<Content :propsData="data" :options="options" />
<template slot="foot">
<!-- <button @click="drawRange">绘制范围</button> -->
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script>
import Dialog from '../../Dialog.vue'
import Content from './content'
export default {
components: {
Dialog,
Content
},
props: {
options: {
type: Object,
default: {}
}
},
data() {
return {
title: '',
data: {},
total: 0,
}
},
created() {
},
mounted() {
this.$nextTick(() => {
})
},
methods: {
open(data) {
this.data = { ...data }
this.title = data.build_info && data.build_info.name + ' - 网格商户'
this.$refs.dialog.open()
},
close() {
this.$refs.dialog.close()
},
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,174 @@
<template>
<div class="user-info-list-box">
<div class="search-box">
<el-form ref="form" :model="condition">
<el-form-item label="姓名:">
<el-input size="mini" v-model="condition.name" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="身份证:">
<el-input size="mini" v-model="condition.id_card" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="联系电话:">
<el-input size="mini" v-model="condition.tel" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="是否重点人员:">
<el-select v-model="condition.is_important" placeholder="请选择" clearable>
<el-option v-for="item in is_important" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="网格:">
<el-input size="mini" v-model="condition.wang_ge" placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item>
<button size="mini" class="search-btn" type='button' @click="search">查询</button>
</el-form-item>
</el-form>
</div>
<myTable :options="options" :data="data" type="build"></myTable>
<el-pagination medium layout="total, prev, pager, next" :total="total" :current-page="page"
@current-change="currentChange">
</el-pagination>
</div>
</template>
<script>
import Dialog from '../../../Dialog.vue'
import myTable from '../../table/user.vue'
export default {
components: {
Dialog,
myTable
},
props: {
options: {
type: Object,
default: ()=>{
return {}
}
},
propsData: {
type: Object,
default: ()=>{
return {}
}
}
},
data() {
return {
condition: {
name: '',
id_card: '',
tel: '',
is_important: '',
wang_ge: ''
},
is_important: [
{
value: '0',
label: '0'
},
{
value: '1',
label: '1'
},
{
value: '2',
label: '2'
},
{
value: '3',
label: '3'
},
{
value: '4',
label: '4'
},
{
value: '5',
label: '5'
}
],
keyWord: '',
data: {},
total: 0,
page: 1,
apiUrl: ''
}
},
watch: {
propsData: {
handler: function (newValue, oldValue) {
this.condition = {
name: '',
id_card: '',
tel: '',
is_important: '',
wang_ge: ''
}
this.data = { ...this.propsData }
if (this.options.host.endsWith("yjearth4.0")) {
this.apiUrl = this.options.host + '/api/v1/dth/build/getUserInfoByBuildName'
}
else {
this.apiUrl = this.options.host + '/yjearth4.0/api/v1/dth/build/getUserInfoByBuildName'
}
if (this.data.user_info) {
this.page = 1
this.total = this.data.user_info.total
this.data.user_info.list && (this.data.user_info.users = [...this.data.user_info.list])
}
else {
this.getUserInfoList(1)
}
},
immediate: true,
deep: true
}
},
created() {
},
mounted() {
},
methods: {
currentChange(page) {
this.getUserInfoList(page)
},
search() {
this.getUserInfoList(1)
},
async getUserInfoList(page) {
this.page = page
try {
let url = this.apiUrl
url = url + `?build_name=${this.data.build_info.name}&name=${this.condition.name}&id_card=${this.condition.id_card}&tel=${this.condition.tel}&is_important=${this.condition.is_important}&wang_ge=${this.condition.wang_ge}&page=${page}&page_size=10`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.data.user_info = data.data
this.data = { ...this.data }
this.data.user_info.list && (this.data.user_info.users = [...this.data.user_info.list])
this.total = this.data.user_info.total
}
}
} catch (error) {
console.log(error)
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,39 @@
<template>
<div class="user-table-box">
<User :options="options" :propsData="propsData" />
<!-- <Business :options="options" :propsData="propsData" /> -->
</div>
</template>
<script>
import User from './User'
// import Business from '../Business'
export default {
components: {
User,
// Business
},
props: {
options: {
type: Object,
default: ()=>{
return {}
}
},
propsData: {
type: Object,
default: {}
}
},
data() {
return {
}
},
watch: {
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,93 @@
<template>
<div>
<myTable :data="data" :options="options"></myTable>
<el-pagination medium layout="total, prev, pager, next" :total="total" :current-page="page"
@current-change="currentChange">
</el-pagination>
</div>
</template>
<script>
import Dialog from '../../../Dialog.vue'
import myTable from '../../table/user.vue'
export default {
components: {
Dialog,
myTable
},
props: {
options: {
type: Object,
default: {}
},
propsData: {
type: Object,
default: {}
}
},
data() {
return {
data: {
user_info: null
},
total: 0,
page: 1,
}
},
watch: {
propsData: {
handler: function (newValue, oldValue) {
this.data = this.propsData
this.getUserInfoList(1)
},
immediate: true,
deep: true
}
},
created() {
},
mounted() {
},
methods: {
currentChange(page) {
this.getUserInfoList(page)
},
async getUserInfoList(page) {
this.page = page
try {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/huxing/query'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/huxing/query'
}
url = url + `?build_name=${this.data.build_info ? this.data.build_info.name :''}&dan_yuan_name=${this.data.unit_info.name}&men_pai_hao=${this.data.room_num}&page=${page}&page_size=10`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.data.user_info = {...data.data.user_info}
this.data = {...this.data}
this.total = this.data.user_info.total
}
}
} catch (error) {
console.log(error)
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,34 @@
<template>
<div>
<User :options="options" :propsData="propsData" />
</div>
</template>
<script>
import User from './User'
export default {
components: {
User
},
props: {
options: {
type: Object,
default: {}
},
propsData: {
type: Object,
default: {}
}
},
data() {
return {
}
},
watch: {
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,92 @@
<template>
<div>
<myTable :data="data" :options="options"></myTable>
<el-pagination medium layout="total, prev, pager, next" :total="total" :current-page="page"
@current-change="currentChange">
</el-pagination>
</div>
</template>
<script>
import Dialog from '../../../Dialog.vue'
import myTable from '../../table/user.vue'
export default {
components: {
Dialog,
myTable
},
props: {
options: {
type: Object,
default: {}
},
propsData: {
type: Object,
default: {}
}
},
data() {
return {
data: {},
total: 0,
page: 1,
}
},
watch: {
propsData: {
handler: function (newValue, oldValue) {
this.data = this.propsData
this.getUserInfoList(1)
},
immediate: true,
deep: true
}
},
created() {
},
mounted() {
},
methods: {
currentChange(page) {
this.getUserInfoList(page)
},
async getUserInfoList(page) {
this.page = page
try {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/danyuan/query'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/danyuan/query'
}
url = url + `?dan_yuan_id=${this.data.unit_info.ID || this.data.unit_info.id}&page=${page}&page_size=10`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.data.user_info = {...data.data.user_info}
this.data = {...this.data}
this.total = this.data.user_info.total
}
}
} catch (error) {
console.log(error)
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,34 @@
<template>
<div>
<User :options="options" :propsData="propsData" />
</div>
</template>
<script>
import User from './User'
export default {
components: {
User
},
props: {
options: {
type: Object,
default: {}
},
propsData: {
type: Object,
default: {}
}
},
data() {
return {
}
},
watch: {
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,74 @@
<template>
<Dialog ref="dialog" class="user-info-list" :title="title" width="580px" height="62vh" left="calc(50% - 585px)"
top="100px">
<component :is="currentComponent" :propsData="data" :options="options"></component>
<template slot="foot">
<!-- <button @click="drawRange">绘制范围</button> -->
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script>
import Dialog from '../Dialog.vue'
import Build from './ByBuild'
import Unit from './ByUnit'
import RoomNum from './ByRoomNum'
import Business from './Business'
export default {
components: {
Dialog,
Build,
Unit,
RoomNum,
Business
},
props: {
options: {
type: Object,
default: {}
}
},
data() {
return {
currentComponent: 'Build',
title: '',
data: {},
total: 0,
}
},
created() {
},
mounted() {
this.$nextTick(() => {
})
},
methods: {
open(type, data) {
this.data = { ...data }
switch (type) {
case 'Build':
case 'Business':
this.title = data.build_info && data.build_info.name + ' - 住户'
break;
case 'Unit':
this.title = data.build_info && (data.build_info.name + '-' + data.unit_info.name)
break;
case 'RoomNum':
this.title = data.build_info && (data.build_info.name + '-' + data.unit_info.name + '-' + data.room_num)
break;
default:
break;
}
this.currentComponent = type
this.$refs.dialog.open()
},
close() {
this.$refs.dialog.close()
},
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,50 @@
<template>
<el-table :data="data.business_info ? data.business_info.business : []" border style="width: 100%" size="mini"
:height="type==='build' ? 'calc(62vh - 300px)' : 'calc(62vh - 184px)'">
<el-table-column type="index" label="序号" width="50" align="center">
</el-table-column>
<el-table-column prop="xiao_zu_xu_hao" label="小组序号" width="80" align="center">
</el-table-column>
<el-table-column prop="grid_name" label="网格名称" width="100" align="center">
</el-table-column>
<el-table-column prop="addr" label="一标三识地址" width="120">
</el-table-column>
<el-table-column prop="dan_wei_ming_cheng" label="实际单位名称" width="120" align="center">
</el-table-column>
<el-table-column prop="zhu_ce_dan_wei_ming_cheng" label="注册单位名称" width="140" align="center">
</el-table-column>
<el-table-column prop="fa_ren_xing_ming" label="法人姓名" width="80" align="center">
</el-table-column>
<el-table-column prop="tel" label="法人联系方式" width="120" align="center">
</el-table-column>
<el-table-column prop="cong_ye_ren_yuan_xing_ming" label="从业人员姓名" width="100" align="center">
</el-table-column>
<el-table-column prop="is_xiao_zu_zhang" label="是否小组长" width="100" align="center">
</el-table-column>
<el-table-column prop="deng_ji_ren" label="登记人" width="80" align="center">
</el-table-column>
<el-table-column prop="bei_zhu" label="备注" width="150">
</el-table-column>
</el-table>
</template>
<script>
export default {
props: {
data: {
type: Object,
default: {}
},
type: {
type: String,
default: ''
},
},
data() {
return {
}
}
}
</script>

View File

@ -0,0 +1,102 @@
<template>
<el-table :data="data.user_info ? data.user_info.users : []" border style="width: 100%" size="mini"
:height="type === 'build' ? 'calc(62vh - 300px)' : 'calc(62vh - 184px)'">
<el-table-column type="index" label="序号" width="50" align="center">
</el-table-column>
<el-table-column label="姓名" width="65" align="center">
<template slot-scope="scope">
<p class="user-name-click" @click="rowclick(scope.row)">{{ scope.row.name }}</p>
</template>
</el-table-column>
<el-table-column prop="sex" label="性别" width="65" align="center">
</el-table-column>
<el-table-column prop="tel" label="联系电话" width="130" align="center">
</el-table-column>
<el-table-column prop="lu" label="居住地街路巷" width="120" align="cmediumenter">
</el-table-column>
<el-table-column prop="hao" label="号" width="60" align="center">
</el-table-column>
<el-table-column prop="chuang" label="幢" width="60" align="center">
</el-table-column>
<el-table-column prop="dan_yuan" label="单元" width="60" align="center">
</el-table-column>
<el-table-column prop="men_pai_hao" label="门牌号" width="60" align="center">
</el-table-column>
<el-table-column prop="id_card" label="身份证" width="150" align="center">
</el-table-column>
<el-table-column prop="is_important" label="是否重点人员" width="100" align="center">
</el-table-column>
<el-table-column prop="street_name" label="街道名称" width="120">
</el-table-column>
<el-table-column prop="community_name" label="社区名称" width="120">
</el-table-column>
<el-table-column prop="di_qu" label="地区" width="100">
</el-table-column>
<el-table-column prop="fu_wu_chu_suo" label="服务处所" width="120">
</el-table-column>
<el-table-column prop="min_jing_ze_ren_qu" label="民警责任区" width="250">
</el-table-column>
<el-table-column prop="bei_zhu" label="备注" width="150">
</el-table-column>
</el-table>
</template>
<script>
export default {
props: {
options: {
type: Object,
ddefault: () => {
return {}
}
},
data: {
type: Object,
default: () => {
return {}
}
},
type: {
type: String,
default: ''
},
},
data() {
return {
}
},
methods: {
async rowclick(row) {
try {
let url = ""
if (this.options.host.endsWith("yjearth4.0")) {
url = this.options.host + '/api/v1/dth/build/query_by_userid'
}
else {
url = this.options.host + '/yjearth4.0/api/v1/dth/build/query_by_userid'
}
url = url + `?user_id=${row.ID}`
let response = await fetch(url, {
method: 'get',
headers: {
'Content-Type': 'application/json',
"token": this.options.token,
"Authorization": "Bearer " + this.options.token,
}
})
if (response.status === 200) {
let data = await response.json()
if (data.code === 200 || data.code === 0) {
this.options.dth.processQueryByPointResults(data.data, true, {pitch: -30})
}
}
} catch (error) {
console.log(error)
}
}
}
}
</script>

View File

@ -0,0 +1,656 @@
<template>
<div class="yj-dth">
<BuildingList ref="BuildingList" @addBuilding="addBuilding" @addHX="addHX" @getUnitList="getUnitList"
@openUpdateUnit="openUpdateUnit" @openAddUnit="openAddUnit" @openInfoList="openInfoList" :options="options" />
<AddBuilding ref="AddBuilding" :options="options" @BuildingOnSubmitCallBack="BuildingOnSubmitCallBack" />
<AddHX ref="AddHX" :options="options" @getHXList="getHXList" />
<AddUnit ref="AddUnit" :options="options" @getUnitList="getUnitList" />
<InfoList ref="InfoList" :options="options" />
<Business ref="Business" :options="options"></Business>
<!-- <UserInfoListByBuild ref="UserInfoListByBuild" :options="options" />
<UserInfoListByUnit ref="UserInfoListByUnit" :options="options" />
<UserInfoListByRoomNum ref="UserInfoListByRoomNum" :options="options" /> -->
</div>
</template>
<script>
import BuildingList from './BuildingList.vue'
import AddBuilding from './AddBuilding.vue'
import AddHX from './AddHX.vue'
import AddUnit from './AddUnit.vue'
import InfoList from './InfoList/index.vue'
import Business from './InfoList/Business'
export default {
components: {
BuildingList,
AddBuilding,
AddHX,
AddUnit,
InfoList,
Business
},
props: {
host: {
type: String,
default: ''
},
token: {
type: String
}
},
data() {
return {
options: {
host: this.host,
token: this.token
},
}
},
created() {
},
mounted() {
},
methods: {
setSdk(sdk) {
this.sdk = sdk
this.options.sdk = this.sdk
let dth = new YJ.Global.DTH(this.sdk, { host: this.host })
// 楼栋点击回调
dth.PickCallback(this, (v) => {
console.log(v)
switch (v.type) {
case 'yj-dth-build':
if (v.user_info) {
this.openInfoList('Build', v)
}
break;
case 'yj-dth-dth':
case 'yj-dth-highlight':
this.openInfoList('RoomNum', v)
break;
case 'yj-dth-unit':
this.openInfoList('Unit', v)
break;
default:
break;
}
if (v.user_info) {
this.openInfoList('Build', v)
}
})
dth.activate()
this.options.dth = dth
},
getDth() {
return this.options.dth
},
open() {
this.$refs.BuildingList.open()
},
addBuilding(data) {
this.$refs.AddBuilding.open(data)
},
getUnitList(id) {
this.$refs.BuildingList.getUnitList(id)
},
openAddUnit(data) {
this.$refs.AddUnit.open(data)
},
openUpdateUnit(data) {
this.$refs.AddUnit.open(data)
},
addHX(data) {
this.$refs.AddHX.drawRange(data)
},
getHXList(id) {
this.$refs.BuildingList.getHXList(id)
},
getBuildingList() {
this.$refs.BuildingList.getList()
},
BuildingOnSubmitCallBack() {
this.$refs.BuildingList.getList()
this.$refs.BuildingList.showAllBuilding()
},
openInfoList(type, data) {
this.$refs.InfoList.open(type, data)
if (type === 'Build') {
this.$refs.Business.open(data)
}
},
}
}
</script>
<style>
.yj-dth-el-popper {
z-index: 999999 !important;
}
.yj-dth .YJ-custom-base-dialog {
z-index: 2000;
}
.yj-dth .YJ-custom-base-dialog .el-pagination {
display: flex;
align-items: center;
color: #ffffff;
padding: 20px 0 10px 0;
}
.yj-dth .YJ-custom-base-dialog .el-pagination button:disabled {
color: #ffffff;
background-color: #ffffff00;
}
.yj-dth .YJ-custom-base-dialog .el-pagination .btn-next,
.yj-dth .YJ-custom-base-dialog .el-pagination .btn-prev {
background-color: #ffffff00;
background-size: 16px;
color: #ffffff;
}
.yj-dth .YJ-custom-base-dialog .el-pagination .el-pager li {
background: #ffffff00;
}
.yj-dth .YJ-custom-base-dialog .el-pagination .el-pager li.btn-quicknext,
.yj-dth .YJ-custom-base-dialog .el-pagination .el-pager li.btn-quickprev {
color: #ffffff;
}
.yj-dth .YJ-custom-base-dialog .el-pagination .el-pager li.active,
.yj-dth .YJ-custom-base-dialog .el-pagination .el-pager li:hover {
color: rgba(var(--color-sdk-base-rgb), 1);
}
.yj-dth .YJ-custom-base-dialog .el-pagination button {
padding: 0 10px;
font-size: 13px;
height: 28px;
line-height: 28px;
text-align: center;
border: none
}
.yj-dth .YJ-custom-base-dialog .el-pagination button:hover {
color: rgba(var(--color-sdk-base-rgb), 1);
}
.yj-dth .YJ-custom-base-dialog .input-box {
position: relative;
}
.yj-dth .YJ-custom-base-dialog .input-box.error input {
border-color: #ff0000;
}
.yj-dth .YJ-custom-base-dialog .input-box.error .input-error-text {
color: #ff0000;
position: absolute;
left: 10px;
bottom: -16px;
font-size: 12px;
}
.yj-dth .YJ-custom-base-dialog>.content {
padding: 10px 20px;
}
.yj-dth .YJ-custom-base-dialog>.content select option[disabled] {
color: #c0c4cc;
}
.yj-dth .YJ-custom-base-dialog>.content .row {
width: 100%;
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.yj-dth .YJ-custom-base-dialog>.content .row>.col {
flex: 1;
display: flex;
align-items: center;
}
.yj-dth .YJ-custom-base-dialog>.content .row>.col>.row {
margin-bottom: 0px;
}
.yj-dth .YJ-custom-base-dialog>.content .row .label {
flex: 0 0 80px;
text-align: right;
margin-right: 20px;
white-space: nowrap;
}
.yj-dth .YJ-custom-base-dialog>.content .el-form {
color: #000;
}
.yj-dth .YJ-custom-base-dialog>.content .el-form>.el-form-item {
color: #000 !important;
}
.yj-dth .YJ-custom-base-dialog>.content .el-form>.el-form-item>.el-form-item__label {
color: #ffffff !important;
}
.yj-dth .YJ-custom-base-dialog>.content .input-group {
display: flex;
align-items: stretch;
}
.yj-dth .YJ-custom-base-dialog>.content .input-group input {
border-radius: 5px 0 0 5px;
}
.yj-dth .YJ-custom-base-dialog>.content .input-group button {
border-radius: 0px 4px 4px 0;
padding: 1px 20px 0 20px;
}
.yj-dth .YJ-custom-base-dialog>.content .input-group.radio {
cursor: pointer;
}
.yj-dth .YJ-custom-base-dialog>.content .input-group.radio * {
-webkit-pointer-events: none;
-moz-pointer-events: none;
-ms-pointer-events: none;
-o-pointer-events: none;
pointer-events: none;
}
.yj-dth .YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add {
width: 250px;
}
.yj-dth .YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add_btn {
font-size: 20px;
}
.yj-dth .YJ-custom-base-dialog>.content .table {
background-color: #fff;
color: #000;
}
.yj-dth .YJ-custom-base-dialog>.content .table {
background-color: #fff;
color: #000;
overflow: hidden;
}
.yj-dth .YJ-custom-base-dialog>.content .table input {
color: #000;
}
.yj-dth .YJ-custom-base-dialog>.content .table .tr {
display: flex;
border: 1px solid #dfdfdf;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-body .tr {
border-bottom: none;
}
.yj-dth .YJ-custom-base-dialog>.content .attribute-content-link .table .tr {
width: 560px;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-empty {
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
color: #747474;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-head {
color: #747474;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-body {
overflow-x: hidden;
overflow-y: auto;
}
.yj-dth .YJ-custom-base-dialog>.content .attribute-content-link .table .table-body {
max-height: 172px;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-body::-webkit-scrollbar {
width: 4px;
height: 4px;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-body::-webkit-scrollbar-thumb {
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background-color: #99a9bf;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 5px;
background-color: #d3dce6;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-body .tr:last-child {
border-bottom: 1px solid #dfdfdf;
}
.yj-dth .YJ-custom-base-dialog>.content .table .tr .th,
.yj-dth .YJ-custom-base-dialog>.content .table .tr .td {
flex: 1;
border-right: 1px solid #dfdfdf;
padding: 5px 10px;
display: flex;
align-items: center;
min-height: 18px;
word-break: break-all;
}
.yj-dth .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(2),
.yj-dth .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(2) {
flex: 0 0 300px;
}
.yj-dth .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td .input {
border-radius: 5px 0 0 5px;
}
.yj-dth .YJ-custom-base-dialog>.content .table .tr .th:last-child,
.yj-dth .YJ-custom-base-dialog>.content .table .tr .td:last-child {
border-right: none;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table {
overflow-x: auto;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr {
display: inline-flex;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr .td span {
white-space: nowrap;
margin-left: 10px;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr .td input[type=checkbox] {
cursor: pointer;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .table-body {
display: inline-flex;
overflow: auto;
flex-direction: column;
height: 186px;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr .th,
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr .td {
flex: 0 100px;
width: 100px;
min-width: 100px;
}
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr .th:first-child,
.yj-dth .YJ-custom-base-dialog>.content .table.camera-table .tr .td:first-child {
flex: 0 74px;
min-width: 74px;
}
.yj-dth .YJ-custom-base-dialog>.content .table .table-empty {
display: flex;
}
.yj-dth .YJ-custom-base-dialog>.content select>option {
color: #000;
}
.yj-dth .foot {
padding: 5px 20px 10px 20px;
display: flex;
justify-content: flex-end;
}
.yj-dth .foot button {
margin-left: 10px;
}
.yj-dth .dth-add .el-input-number--mini .el-input__inner {
text-align: left;
}
.yj-dth .building-list {
width: auto !important;
}
.yj-dth .building-list .content {
display: flex;
}
.yj-dth .building-list .foot {
justify-content: unset;
}
.yj-dth .building-list .el-pagination,
.yj-dth .user-info-list .el-pagination {
padding: 10px 0;
}
.yj-dth .user-info-list .el-pagination .el-pagination__total {
color: #ffffff;
margin-right: 20px;
}
.yj-dth .user-info-list .title {
font-size: 22px;
text-align: center;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table__expand-icon {
color: #ffffff;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table .el-table__expanded-cell {
padding-left: 64px;
}
.yj-dth .building-list .content .hx {
padding-left: 10px;
display: flex;
flex: 0 0 270px;
}
.yj-dth .building-list .building {
flex: 0 0 570px;
width: 570px;
}
.yj-dth .building-list .foot .building {
display: flex;
align-items: center;
justify-content: flex-end;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table {
color: #ffffff;
background-color: #ffffff00;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table thead {
color: #ffffff;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table th {
font-weight: 500;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table tr,
.yj-dth .YJ-custom-base-dialog>.content .el-table tr td {
background-color: #ffffff00;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table .cell {
line-height: 16px;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table th.el-table__cell {
background-color: #ffffff00;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table .el-table__cell button {
padding: 5px 10px 4px 10px;
height: 26px;
line-height: 14px
}
.yj-dth .YJ-custom-base-dialog>.content .el-table td.el-table__cell,
.yj-dth .YJ-custom-base-dialog>.content .el-table th.el-table__cell.is-leaf {
border-bottom: 1px solid rgba(var(--color-sdk-base-rgb), 0.5);
}
.yj-dth .YJ-custom-base-dialog>.content .el-table--border .el-table__cell,
.yj-dth .YJ-custom-base-dialog>.content .el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed {
border-right: 1px solid rgba(var(--color-sdk-base-rgb), 0.5);
}
.yj-dth .YJ-custom-base-dialog>.content .el-table--border th.el-table__cell.gutter:last-of-type {
border-bottom: 1px solid rgba(var(--color-sdk-base-rgb), 0.5);
}
.yj-dth .YJ-custom-base-dialog>.content .el-table--border::after,
.yj-dth .YJ-custom-base-dialog>.content .el-table--group::after,
.yj-dth .YJ-custom-base-dialog>.content .el-table::before {
background-color: rgba(var(--color-sdk-base-rgb), 0.5);
}
.yj-dth .YJ-custom-base-dialog>.content .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
background-color: rgba(var(--color-sdk-base-rgb), 0.1);
}
.yj-dth .YJ-custom-base-dialog>.content .el-table--border,
.yj-dth .YJ-custom-base-dialog>.content .el-table--group {
border: 1px solid rgba(var(--color-sdk-base-rgb), 0.5);
}
.yj-dth .YJ-custom-base-dialog>.content .el-table .el-table__row {
cursor: pointer;
}
.yj-dth .YJ-custom-base-dialog>.content .building>.el-table>.el-table__body-wrapper>table>tbody>.el-table__row td:nth-of-type(2) {
padding: 0;
}
.yj-dth .YJ-custom-base-dialog>.content .building>.el-table>.el-table__body-wrapper>table>tbody>.el-table__row td:nth-of-type(2) .cell {
padding: 0;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table .el-table__row .el-table__cell button {
margin: 0;
}
.yj-dth .YJ-custom-base-dialog>.content .el-table .el-table__cell .el-checkbox .el-checkbox__input {
display: unset;
}
.yj-dth .dth-add .el-input-number--mini {
width: 100%;
}
.yj-dth .user-info-list-box .search-box {
padding: 10px 0;
margin-bottom: 5px;
}
.yj-dth .user-info-list-box .search-box h4 {
margin-left: 10px;
margin-bottom: 10px;
font-size: 16px;
}
.yj-dth .user-info-list-box .el-input-number--mini {
width: 100%;
}
.yj-dth .user-info-list-box .search-box>.el-form {
display: flex;
flex-wrap: wrap;
}
.yj-dth .user-info-list-box .search-box>.el-form>.el-form-item {
display: flex;
align-items: center;
}
.yj-dth .user-info-list-box .search-box>.el-form>.el-form-item>.el-form-item__label {
margin-left: 20px;
}
.yj-dth .user-info-list-box .search-box>.el-form>.el-form-item:last-of-type {
flex: 1;
margin-right: 12px;
justify-content: flex-end;
}
.yj-dth .user-info-list-box .search-box>.el-form .el-input {
width: 100px;
}
.yj-dth .user-info-list-box .search-box>.el-form .el-input .el-input__inner {
color: #ffffff;
}
.yj-dth .user-info-list-box .search-box>.el-form .el-select {
width: 100px;
color: #ffffff;
}
.yj-dth .user-info-list-box .el-table>.el-table__body-wrapper .user-name-click {
cursor: pointer;
color: #409eff;
}
.yj-dth .user-info-list-box .el-table>.el-table__body-wrapper .user-name-click:hover {
color: #0d84fa;
}
.yj-dth .user-table-box {
display: flex;
justify-content: space-between;
}
.yj-dth .user-table-box>* {
width: 100%;
}
.yj-dth .YJ-custom-base-dialog>.content .el-form {
margin-bottom: 10px;
}
.yj-dth .YJ-custom-base-dialog>.content .el-form .el-input-number__decrease,
.yj-dth .YJ-custom-base-dialog>.content .el-form .el-input-number__increase {
background: #ffffff00;
border-left: 1px solid #DCDFE600;
color: #ffffff;
}
.yj-dth .YJ-custom-base-dialog>.content .el-form .el-input-number.is-controls-right .el-input-number__increase {
border-bottom: 1px solid #DCDFE600;
}
.yj-dth .YJ-custom-base-dialog>.content .el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled), .yj-dth .YJ-custom-base-dialog>.content .el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled) {
border-color: rgba(var(--color-sdk-base-rgb), 1);
}
</style>

View File

@ -0,0 +1,764 @@
<template>
<div class="newEvent" id="newEvent">
<!--<img src="http://127.0.0.1:8894/static/img/GEMarker/A-airliner.png" alt="">-->
<div class="nav" id="newEventNav">
<span></span>
<span class="title">{{ selectNode.name }}-态势事件</span>
<span class="close" @click="close">
<i class="el-icon-close"></i>
</span>
</div>
<div class="contentBody">
<div class="sort">
<!-- <template v-for="(item,index) in events">
<div :class="{ active: index==isActive,typeItem:true }" @click="changeSort(item,index)">{{ item.label }}</div>
</template>-->
<el-tree
:data="events"
:props="defaultProps"
:expand-on-click-node="false"
:default-expanded-keys="['common']"
accordion
ref="treeRef"
node-key="value"
@node-click="changeSort"
>
</el-tree>
</div>
<div class="content">
<template v-if="selectEvent != null">
<div class="params">
<div class="item">
<label for="name">事件名称</label>
<input autocomplete="off" v-model="eventForm.name" id="name"/>
</div>
<div class="item">
<label for="start_time">开始时间</label>
<input
id="start_time"
type="datetime-local"
step="1"
autocomplete="off"
v-model="eventForm.start_time"
@blur="account('start_time')"
/>
</div>
<div class="item">
<label for="duration">持续时间</label>
<input
autocomplete="off"
v-model.number="eventForm.duration"
id="duration"
@blur="account('duration')"
@input="durationInput"
/>
</div>
<div class="item">
<label for="end_time">结束时间</label>
<input
id="end_time"
type="datetime-local"
step="1"
autocomplete="off"
v-model="eventForm.end_time"
@blur="account('end_time')"
/>
</div>
<template v-if="selectEvent.value == 'pathMove'">
<div class="item">
<span>是否包含模型点:</span>
<el-switch
size="mini"
v-model.number="eventForm.detail.includeModelPoint"
></el-switch>
</div>
<div class="item">
<el-button type="primary" size="mini" @click="draw">
绘制路径
</el-button>
</div>
</template>
<template v-if="selectEvent.value == 'audio'">
<div class="item" style="display:flex;align-items: center">
<label for="audio">音频文件</label>
<el-select id="audio" v-model="audioId" placeholder="请选择" size="mini">
<el-option
v-for="item in audioOption"
:key="item.id"
:label="item.fileName"
:value="item.id">
</el-option>
</el-select>
<div style="width: 50px;float: left;padding-left: 5px;opacity: 0"></div>
</div>
<div class="item" style="display:flex;align-items: center">
<label for="audio">音频音量</label>
<el-slider style="flex: auto" v-model="volume" :show-tooltip="false"></el-slider>
<div style="width: 50px;float: left;padding-left: 5px">{{ volume }}</div>
</div>
</template>
<template v-if="selectEvent.value == 'Animation'">
<div class="item" style="display:flex;align-items: center">
<label for="audio">动画选择</label>
<el-select id="audio" v-model="animationId" placeholder="请选择" size="mini">
<el-option
v-for="(item,index) in animationOption"
:key="item+index"
:label="item"
:value="item">
</el-option>
</el-select>
<div style="width: 50px;float: left;padding-left: 5px;opacity: 0"></div>
</div>
</template>
</div>
<div class="btn">
<el-button type="primary" size="mini" @click="submit"
>确定
</el-button
>
<el-button type="primary" size="mini" @click="cancel"
>取消
</el-button
>
</div>
</template>
<!-- <template v-if="selectSortEvents.length">
<div class="params">
<div class="item">
<label for="event-choose">事件</label>
<select name="event" id="event-choose" v-model="selectSortEvent">
<template v-for="item in selectSortEvents">
<option :value="item.value">{{ item.label }}</option>
</template>
</select>
</div>
<div class="item">
<span>开始时间</span>
</div>
<div class="item">
<span>持续时间</span>
</div>
<div class="item">
<span>结束时间</span>
</div>
</div>
<div class="btn">
<el-button type="primary" size="mini" @click="cancel">取消</el-button>
<el-button type="primary" size="mini" @click="submit">确定</el-button>
</div>
</template>-->
</div>
</div>
</div>
</template>
<script>
import {addEvent, previewList} from "@/api/aboutCabin";
import {setMove} from "../myHeaderAll/systemPopup/js/moveDiv";
import nodeType from "@/components/treeNode";
export default {
name: "newEvent",
data() {
return {
isActive: -1,
volume: 50,
events: [
{
label: "常用事件",
value: "common",
children: [
{
label: "显示",
value: "display",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "隐藏",
value: "hide",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "闪烁",
value: "flicker",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "机动事件",
value: "pathMove",
detail: {
startTime: "",
duration: "",
endTime: "",
positions: [],
},
},
{
label: "音频",
value: "audio",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
],
},
],
defaultProps: {
children: "children",
label: "label",
},
/*
selectSortEvents: [],
selectSortEvent: "",
selectSortEventDetail: {},
symbolParams: [
{
startTime: "开始时间"
},
{ duration: "持续时间" },
{
endTime: "结束时间"
}],*/
eventForm: {
name: "",
source_id: "",
start_time: "",
duration: "",
end_time: "",
detail: {},
},
selectEvent: null,
selectNode: {
name: "",
},
audioOption: [],
animationOption: [],
audioId: "",
animationId: "",
};
},
watch: {},
mounted() {
setMove("newEventNav", "newEvent");
window.addEventListener("initEvent", () => {
previewList(res => {
console.log("previewList", res)
this.audioOption = res.filter(item => item.format.toLowerCase() == 'mp3')
})
let ztreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let nodes = ztreeObj.getSelectedNodes();
this.selectNode = nodes[0];
this.eventForm.start_time = TSTYOBJ.store.currentTimestamp
//新增30
if (
["fire", "fountain", "smoke", "water_flow", "polygon", "polyline", "stand_text", "circle"].includes(
this.selectNode.type
)
) {
this.events = [
{
label: "常用事件",
value: "common",
children: [
{
label: "显示",
value: "display",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "隐藏",
value: "hide",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "音频",
value: "audio",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
],
},
];
} else if (["pincerarrow", "attackarrow",].includes(this.selectNode.type)) {
this.events = [
{
label: "常用事件",
value: "common",
children: [
{
label: "显示",
value: "display",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "隐藏",
value: "hide",
detail: {
startTime: "",
duration: "",
endTime: "",
},
}, {
label: "延伸",
value: "extend",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "音频",
value: "audio",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
],
},
];
} else if (["model"].includes(this.selectNode.type)) {
this.events = [
{
label: "常用事件",
value: "common",
children: [
{
label: "显示",
value: "display",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "隐藏",
value: "hide",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "闪烁",
value: "flicker",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "机动事件",
value: "pathMove",
detail: {
startTime: "",
duration: "",
endTime: "",
positions: [],
includeModelPoint: true
},
},
{
label: "音频",
value: "audio",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
{
label: "动画",
value: "Animation",
detail: {
startTime: "",
duration: "",
endTime: "",
},
},
],
},
];
}
window.dispatchEvent(window.EventsNameMap.get("changeStampEventBox"))
});
this.$nextTick(() => {
window.addEventListener("changeStampEventBox", () => {
// this.eventForm.start_time = Store.currentTimestamp;
let key = ""
if (["start_time", "end_time"].includes(document.activeElement.id)) {
key = document.activeElement.id
// window.dispatchEvent(window.EventsNameMap.get("changeStamp"));
} else {
key = "start_time"
}
TSTYOBJ.store.currentTimestamp = Math.round(TSTYOBJ.store.currentTimestamp / 1000) * 1000
this.eventForm[key] = TSTYOBJ.clock.parseTime(TSTYOBJ.store.currentTimestamp).replace(' ', 'T');
console.log(TSTYOBJ.clock.parseTime(TSTYOBJ.store.currentTimestamp));
console.log(this.eventForm);
});
})
window.addEventListener("changeStampUp", () => {
TSTYOBJ.store.currentTimestamp = parseInt(TSTYOBJ.store.currentTimestamp / 1000) * 1000;
// this.eventForm[document.activeElement.id] = Clock.parseTime(Store.currentTimestamp);
// document.getElementById("currentTimestamp").innerHTML = Clock.parseTime(Store.currentTimestamp);
//根据调整后的时间戳,调整光标位置
let offset = TSTYOBJ.store.currentTimestamp - TSTYOBJ.store.startTimestamp;
let left = (offset * TSTYOBJ.store.scales.preSecondPx) / 1000;
document.getElementsByClassName("timeline-box")[0].style.left =
left + "px";
// window.dispatchEvent(window.EventsNameMap.get("changeStamp"));
// console.log(left);
// window.dispatchEvent(window.EventsNameMap.get("changeStampEventBox"));
});
},
methods: {
draw() {
console.log("ss");
let detail = {};
let draw = new YJ.Draw.DrawPolyline(earth);
draw.start((err, positions) => {
if (err) return err;
if (positions && positions.length > 1) {
this.eventForm.detail.positions = positions
/*{
ground: false,
viewFollow: false, //视角跟随
line: {
show: false, //路径显隐
smooth: false, //路径圆滑
}, //视角跟随
routeDirection: true, //路径方向
: position,
};*/
// includeModelPoint
}
});
},
durationInput(event) {
let str = event.target.value.replace(/[^\d.]/g, '')
this.eventForm[event.target.id] = str
},
//开始时间,持续时间,结束时间
account(key) {
console.log(this.eventForm);
// this.eventForm.start_time= Clock.parseTime(Store.currentTimestamp)
if (key != "start_time" && this.eventForm.start_time != "") {
if (key == "end_time") {
let endTimestamp = TSTYOBJ.clock.timeToStamp(this.eventForm.end_time)
let startTimestamp = TSTYOBJ.clock.timeToStamp(this.eventForm.start_time)
this.eventForm.duration = (endTimestamp - startTimestamp) / 1000;
} else if (key == "duration") {
let time =
TSTYOBJ.clock.timeToStamp(this.eventForm.start_time) +
this.eventForm.duration * 1000;
this.eventForm.end_time = TSTYOBJ.clock.parseTime(time, "{y}-{m}-{d}T{h}:{i}:{s}");
}
} else if (
this.eventForm.start_time == "" &&
this.eventForm.end_time &&
this.eventForm.duration
) {
let time =
TSTYOBJ.clock.timeToStamp(this.eventForm.end_time) -
this.eventForm.duration * 1000;
this.eventForm.start_time = TSTYOBJ.clock.parseTime(time, "{y}-{m}-{d}T{h}:{i}:{s}");
}
},
close() {
// this.$changeComponentShow(".newEventBox", false);
this.$parent.eventBox = false;
this.eventForm = {
name: "",
source_id: "",
startTime: "",
duration: "",
endTime: "",
};
this.selectEvent = null;
},
cancel() {
this.close();
},
submit() {
this.eventForm.callback = this.selectEvent.value;
this.eventForm.source_id = this.selectNode.id;
this.eventForm.start_time = TSTYOBJ.clock.timeToStamp(this.eventForm.start_time);
this.eventForm.end_time = TSTYOBJ.clock.timeToStamp(this.eventForm.end_time);
console.log("this.eventForm", this.eventForm);
this.eventForm.plan_id = window.currentPlan.plan_id;
this.eventForm.plan_id == undefined && (this.eventForm.plan_id = 111);
let canSubmit = false;
if (this.eventForm.start_time && this.eventForm.end_time && this.eventForm.duration) {
if (this.eventForm.detail.hasOwnProperty("positions") && this.eventForm.detail.positions.length == 0) {
canSubmit = false;
} else {
canSubmit = true;
}
}
if (canSubmit) {
if (this.eventForm.duration <= 0) {
this.eventForm.duration = ""
this.eventForm.end_time = ""
this.$message.warning("事件参数不合法,请检查!");
} else {
if (this.eventForm.callback == "pathMove") {
let position = [...this.eventForm.detail.positions]
if (this.eventForm.detail.includeModelPoint) {
position.unshift(this.selectNode.detail.positions || this.selectNode.detail.position)
}
this.eventForm.detail.positions = position;
}
if (this.eventForm.callback == "flicker") {
let obj = {
times: 500,
number: 3,
};
obj.times = Math.round(this.eventForm.duration * 1000 / obj.number)
this.eventForm.detail = obj;
}
if (this.eventForm.callback == "audio") {
this.eventForm.detail = {
id: this.audioId,
volume: this.volume,
}
}
if (this.eventForm.callback == "Animation") {
this.eventForm.detail = {
animationName: this.animationId,
}
}
this.eventForm.detail = JSON.stringify(this.eventForm.detail);
if (typeof this.eventForm.duration != 'number') {
this.eventForm.duration = Number(this.eventForm.duration)
}
addEvent(this.eventForm, (res) => {
console.log(res);
this.eventForm.ID = res.id || res.ID;
$root_home_index.$refs.Deduction.$refs.Chart.$emit("action", {
action: "add-task",
obj: this.eventForm,
});
if (this.eventForm.callback == 'pathMove') {
nodeType.guiji.render(this.eventForm)
}
if (this.eventForm.callback == "extend") {
ts_Map.get(Number(this.eventForm.source_id)).spreadTime = this.eventForm.duration * 1000
}
this.close();
});
}
} else {
this.$message.warning("事件参数不完整,请检查!");
}
},
changeSort(data = null, node = null, tree = null) {
if (node.childNodes && node.childNodes.length) {
this.selectEvent = null;
return;
} else {
this.selectEvent = data;
}
this.eventForm.name = data.label + this.selectNode.name;
if (data.value == "pathMove") {
this.eventForm.detail = {
ground: false,
viewFollow: false, //视角跟随
line: {
show: false, //路径显隐
smooth: false, //路径圆滑
}, //视角跟随
routeDirection: true, //路径方向
positions: [],
includeModelPoint: true
};
} else if (data.value == "flicker") {
this.eventForm.detail = {
times: 500,
number: 3,
};
} else if (data.value == "audio") {
this.eventForm.detail = {
id: this.audioId,
volume: this.volume
}
} else this.eventForm.detail = {};
if (data.value == "Animation") {
ts_Map.get(this.selectNode.id).getModelAnimations()
.then(list => {
console.log("getModelAnimations", list)
let arr = []
list.forEach(item => {
arr.push(item.name)
})
this.animationOption = arr
})
}
/* if (data.value == "pathMove") {
this.eventForm.positions = [];
} else
delete this.eventForm.positions;*/
window.dispatchEvent(window.EventsNameMap.get("changeStampEventBox"))
console.log(data, node, tree);
console.log(this.$refs.treeRef);
/*this.isActive = index;
console.log(item);
this.selectSortEvents = item.children;
this.selectSortEvent = item.children[0].value;
this.selectSortEventDetail = item.children[0].detail;*/
},
},
};
</script>
<style lang="scss" scoped>
.newEvent {
width: vw(400);
height: vh(265);
position: absolute;
top: 35%;
left: 45%;
z-index: 99999;
//transform: translate(-50%, -50%);
border: vw(1.5) solid rgba(0, 255, 255, 1);
color: #fff;
background: linear-gradient(
180deg,
rgba(0, 255, 255, 0.2) 0%,
rgba(0, 255, 255, 0) 100%
),
rgba(0, 0, 0, 0.5);
.nav {
display: flex;
justify-content: space-between;
border-bottom: vw(1) solid rgba(0, 255, 255, 1);
align-items: center;
//padding: vh(5) 0;
height: vh(38);
.title {
font-size: px2font(18);
}
.close {
font-size: px2font(24);
cursor: pointer;
}
}
.active {
background: linear-gradient(
90deg,
rgba(0, 255, 255, 0) 0%,
rgba(0, 255, 255, 0.5) 48.91%,
rgba(0, 255, 255, 0) 100%
);
}
.contentBody {
display: flex;
height: vh(225);
.sort {
width: vw(110);
overflow-y: auto;
border-right: vw(1) solid rgba(0, 255, 255, 1);
.typeItem {
height: vh(25);
line-height: vh(25);
font-size: px2font(12);
cursor: pointer;
}
}
.content {
border: 1px solid red;
flex: auto;
display: flex;
flex-direction: column;
.params {
flex: auto;
.item {
text-align: left;
font-size: px2font(12);
margin: 5px 0;
input {
height: vh(22);
border: none;
&:focus {
outline: none;
}
}
}
}
.btn {
text-align: center;
}
}
}
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<div>
<svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
p-id="1692"></path>
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
p-id="1693"></path>
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
p-id="1694"></path>
</svg>
</div>
</template>
<script>
export default {
name: 'hamburger',
props: {
isActive: {
type: Boolean,
default: false
},
toggleClick: {
type: Function,
default: null
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
cursor: pointer;
width: 20px;
height: 20px;
transform: rotate(90deg);
transition: .38s;
transform-origin: 50% 50%;
}
.hamburger.is-active {
transform: rotate(0deg);
}
</style>

View File

@ -0,0 +1,315 @@
<template>
<div class="leftBox">
<div class="left animate__animated">
<!--右侧区域背景图-->
<svg-icon :class-name="['absolute', 'zIndex-1', 'left_bg']" :icon-class="'leftMenuBg' + menuList.length">
</svg-icon>
<!--流动效果区域-->
<div class="line">
<img :class="[appVersion !== 'earth' ? 'scrollBar81' : 'scrollBar']" :src="require('@/assets/images/shijing/' + skinInfo + '/scrollBar.png')
" alt="" />
</div>
<!--右侧菜单-->
<div class="menus">
<div class="itemBox" v-for="(item, index) in menuList" @click="item.fun(item, index, $event)"
:title="$t(`leftMenu.firstMenu.${item.name}`)">
<div class="item_icon">
<svg-icon :class-name="['absolute', 'zIndex-1', 'left_item_bg']" icon-class="leftMenuItemBg"></svg-icon>
<svg-icon :class-name="['left_item_icon']" :icon-class="item.svg"></svg-icon>
</div>
<div class="item_text">
{{ $t(`leftMenu.firstMenu.${item.name}`) }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { $changeComponentShow } from "../../utils/communication";
import { getSelectedNode } from "../Tree/treeNode";
import test from "./test";
import secondMenuFun from "./secondMenuFun";
export default {
name: "firstMenu",
mixins: [test, secondMenuFun],
data() {
return {
treeObj: null,
menuList: [
// 方案库(无)
// 标准版本
// {
// name: "situation",
// svg: "situation",
// fun: this.toSituation,
// key: "situation",
// },
// 模型库
{
name: "modelLibrary",
svg: "personalModel",
fun: this.openModel,
key: "model",
},
// 特效库
{
name: "effect",
svg: "effect",
fun: this.showSecondMenu,
key: "effect",
},
// 测量
{
name: "measure",
svg: "measure",
fun: this.showSecondMenu,
key: "measure",
},
// 分析
{
name: "analysis",
svg: "analysis",
fun: this.showSecondMenu,
key: "analysis",
},
// 工具
{
name: "tool",
svg: "tool",
fun: this.showSecondMenu,
key: "tool",
},
// 军标 // 标准版本
{
name: "militaryMark",
svg: "militaryMark",
fun: this.openGroundImg,
key: "militaryMark",
},
// // 在线图源
// {
// name: "onlinePictureSource",
// svg: "onlinePictureSource",
// fun: this.showSecondMenu,
// key: 'onlinePictureSource'
// },
// // 大数据
// {
// name: 'bigData',
// fun: this.showBigDataPage,
// svg: "bigData",
// key: 'bigData',
// },
// 三维军标 标准版本
{
name: "junbiao3d",
fun: this.openGround3d,
svg: "junbiao3d",
key: "junbiao3d",
},
// 二三维
{
name: "ersanwei",
fun: this.map2d,
svg: "ersanwei",
key: "ersanwei",
},
],
skinInfo: JSON.parse(localStorage.getItem("systemSetting")).skinInfo,
appVersion: localStorage.getItem("appVersion"),
};
},
created() { },
mounted() {
const that = this;
window.addEventListener("setItemEvent", (e) => {
if (e.key == "systemSetting") {
let obj = JSON.parse(e.newValue);
that.skinInfo = obj.skinInfo;
}
});
// let width, height = "380px", menusHeight = "350px"
/* switch (this.menuList.length) {
case 6:
height = "420px"
menusHeight = "390px"
break
}*/
let menusHeight = this.menuList.length * 65 + "px";
let height = this.menuList.length * 65 + 30 + "px";
$(".leftBox")[0].style.height = height;
$(".left .menus")[0].style.height = menusHeight;
this.$recvChanel("getTreeObj", (treeObj) => {
console.log(treeObj);
this.treeObj = treeObj;
this.$removeChanel("getTreeObj");
});
},
methods: {
// 态势
toSituation() {
// this.
if (window.Earth1) YJ.Global.multiViewportMode.off(window.Earth1);
// this.$enterFullscreen();
$root_home_index.$refs.myHeaderAll.$refs.setTool.fullScreen();
this.$sendChanel("checkSituation", true);
this.$changeComponentShow("#secondMenu", false);
},
openGround3d() {
if (window.checkAuthIsValid) {
$changeComponentShow(".junbiao3dBox", true);
$root_home_index.$refs.junbiao3d.open();
} else {
this.$message({
message: "您没有该功能的权限",
type: "warning",
});
}
// junbiao3d
},
openModel() {
/* let selectedNode = getSelectedNode(this.treeObj)
if (selectedNode) {*/
if (window.checkAuthIsValid) {
$changeComponentShow(".modelBox", true);
$root_home_index.$refs.model.open();
} else {
this.$message({
message: "您没有该功能的权限",
type: "warning",
});
}
/* } else {
this.$message.warning("请选中一节点后操作")
}*/
},
openGroundImg() {
/* let selectedNode = getSelectedNode(this.treeObj)
if (selectedNode) {*/
if (window.checkAuthIsValid) {
$changeComponentShow(".junbiaoBox", true);
$root_home_index.$refs.junbiao.open();
} else {
this.$message({
message: "您没有该功能的权限",
type: "warning",
});
}
/* } else {
this.$message.warning("请选中一节点后操作")
}*/
},
// 打开二级菜单页面
showSecondMenu(item, index, event) {
let reset = index == this.menuList.length - 1 ? 65 : 0;
// 打开弹窗位置
let topNum = Number(event.clientY) - reset; //100
// 打开弹窗触发方法
this.$changeComponentShow("#secondMenu", true, `top: ${topNum}px`);
// 给二级菜单页面传点击的一级菜单具体值
this.$sendChanel("currentSecondMenu", { item, index });
},
// 展示大数据页面
showBigDataPage() {
console.log("展示大数据页面");
},
},
};
</script>
<style lang="scss" scoped>
.leftBox {
width: 112px;
height: 380px;
position: absolute;
left: 0.5em;
bottom: calc(7vw + 2px);
}
.left {
width: 100%;
height: 100%;
user-select: none;
//width: 7vw;
color: red;
display: flex;
flex-direction: row;
justify-content: space-between;
.line {
width: 5.2vw;
}
.scrollBar81 {
position: absolute;
top: 33px;
left: 8px;
}
.scrollBar {
position: absolute;
top: 33px;
left: 11px;
height: 270px;
}
.menus {
//width: 85%;
display: flex;
flex-direction: column;
justify-content: space-around;
/* bottom: 10vh;
padding: 35px 10px 15px 0;*/
height: 350px;
margin-top: 20px;
//align-self: center;
padding: 0 8px 0 5px;
.itemBox {
//width: 77px;
//height: 65px;
height: 6.5vh;
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: auto;
.item_icon {
width: 100%;
//height: 5vh;
height: 4.2vh;
//width: 77px;
//height: 48px;
position: relative;
}
.item_text {
width: 100%;
height: 2vh;
font-size: 16px;
text-align: center;
//height: 17px;
//line-height: 17px;
color: #fff;
max-width: 75px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.itemBox:hover {
transition-duration: 0.5s;
transform: scale(0.8);
}
}
}
</style>

View File

@ -0,0 +1,355 @@
<template>
<div class="leftBox">
<div class="left animate__animated">
<div class="menus">
<div class="menus_itemBox" v-for="(item, index) in menuList" @click="item.fun(item, index, $event)"
:title="$t(`leftMenu.firstMenu.${item.name}`)">
<div class="item_icon">
<!-- <svg-icon :class-name="['absolute', 'zIndex-1', 'left_item_bg']" icon-class="bg2"></svg-icon> -->
<svg-icon style="width: 20px; position: absolute; left: 30px; top: 5px; height: 20px; font-size: 20px;"
:class-name="['left_item_icon']" :icon-class="item.svg"></svg-icon>
<div class="item_text">
{{ $t(`leftMenu.firstMenu.${item.name}`) }}
</div>
</div>
</div>
</div>
</div>
<div class="left_bottom" @click="fold"></div>
</div>
</template>
<script>
import { $changeComponentShow } from "../../utils/communication";
import { getSelectedNode } from "../Tree/treeNode";
import test from "./test";
import secondMenuFun from "./secondMenuFun";
import _ from 'lodash';
export default {
name: "firstMenu",
mixins: [test, secondMenuFun],
data() {
return {
treeObj: null,
menuList: [
// 方案库(无)
// 标准版本
// {
// name: "situation",
// svg: "situation",
// fun: this.toSituation,
// key: "situation",
// },
// 模型库
{
name: "modelLibrary",
svg: "personalModel",
fun: this.openModel,
key: "model",
},
// 特效库
{
name: "effect",
svg: "effect",
fun: this.showSecondMenu,
key: "effect",
},
// 测量
{
name: "measure",
svg: "measure",
fun: this.showSecondMenu,
key: "measure",
},
// 分析
{
name: "analysis",
svg: "analysis",
fun: this.showSecondMenu,
key: "analysis",
},
// 工具
{
name: "tool",
svg: "tool",
fun: this.showSecondMenu,
key: "tool",
},
// 军标 // 标准版本
// {
// name: "militaryMark",
// svg: "militaryMark",
// fun: this.openGroundImg,
// key: "militaryMark",
// },
/*
// 在线图源
{
name: "onlinePictureSource",
svg: "onlinePictureSource",
fun: this.showSecondMenu,
key: 'onlinePictureSource'
},
// 大数据
{
name: 'bigData',
fun: this.showBigDataPage,
svg: "bigData",
key: 'bigData',
}*/
// 三维军标 标准版本
// {
// name: "junbiao3d",
// fun: this.openGround3d,
// svg: "junbiao3d",
// key: "junbiao3d",
// },
// 二三维
{
name: "ersanwei",
fun: this.map2d,
svg: "ersanwei",
key: "ersanwei",
},
],
skinInfo: JSON.parse(localStorage.getItem("systemSetting")).skinInfo,
appVersion: localStorage.getItem("appVersion"),
isFolded: false, // 添加折叠状态
initialPositions: {}, // 保存初始位置
isAnimating: false, // 添加动画状态
};
},
created() { },
mounted() {
const that = this;
window.addEventListener("setItemEvent", (e) => {
if (e.key == "systemSetting") {
let obj = JSON.parse(e.newValue);
that.skinInfo = obj.skinInfo;
}
});
let menusHeight = this.menuList.length * 65 + "px";
let height = this.menuList.length * 65 + 30 + "px";
$(".leftBox")[0].style.height = height;
$(".left .menus")[0].style.height = menusHeight;
this.$recvChanel("getTreeObj", (treeObj) => {
console.log(treeObj);
this.treeObj = treeObj;
this.$removeChanel("getTreeObj");
});
const items = document.querySelectorAll('.menus_itemBox');
items.forEach((item, index) => {
this.initialPositions[index] = item.style.transform || 'translateX(0)';
});
},
methods: {
// 收缩展开
fold() {
// 如果正在动画中,直接返回
if (this.isAnimating) return;
// 设置动画状态为true
this.isAnimating = true;
const items = document.querySelectorAll('.menus_itemBox');
const left_bottom = document.querySelector('.left_bottom');
const itemCount = items.length;
const itemDelay = 100;
const itemDuration = 300;
if (this.isFolded) {
left_bottom.style.bottom = '7em';
left_bottom.style.left = '72px';
left_bottom.style.transform = 'rotate(0deg)';
// 恢复初始状态
items.forEach((item, index) => {
setTimeout(() => {
item.style.transition = 'transform 0.3s ease';
item.style.transform = this.initialPositions[index];
}, index * itemDelay);
});
} else {
// 折叠状态
items.forEach((item, index) => {
setTimeout(() => {
item.style.transition = 'transform 0.3s ease';
item.style.transform = 'translateX(-110%)';
}, index * itemDelay);
});
// 同步left_bottom的动画
setTimeout(() => {
left_bottom.style.bottom = '50%';
left_bottom.style.left = '10px';
left_bottom.style.transform = 'rotate(180deg)';
}, (itemCount - 1) * itemDelay);
}
// 在所有动画完成后重置状态
setTimeout(() => {
this.isFolded = !this.isFolded;
this.isAnimating = false;
}, (itemCount - 1) * itemDelay + itemDuration);
},
// 态势
toSituation() {
// this.
if (window.Earth1) YJ.Global.multiViewportMode.off(window.Earth1);
// this.$enterFullscreen();
$root_home_index.$refs.myHeaderAll.$refs.setTool.fullScreen();
this.$sendChanel("checkSituation", true);
this.$changeComponentShow("#secondMenu", false);
},
openGround3d() {
$changeComponentShow(".junbiao3dBox", true);
$root_home_index.$refs.junbiao3d.open();
// junbiao3d
},
openModel() {
/* let selectedNode = getSelectedNode(this.treeObj)
if (selectedNode) {*/
$changeComponentShow(".modelBox", true);
$root_home_index.$refs.model.open();
/* } else {
this.$message.warning("请选中一节点后操作")
}*/
},
openGroundImg() {
/* let selectedNode = getSelectedNode(this.treeObj)
if (selectedNode) {*/
$changeComponentShow(".junbiaoBox", true);
$root_home_index.$refs.junbiao.open();
/* } else {
this.$message.warning("请选中一节点后操作")
}*/
},
// 打开二级菜单页面
showSecondMenu(item, index, event) {
let reset = index == this.menuList.length - 1 ? 65 : 0;
// 打开弹窗位置
let topNum = Number(event.clientY) - reset; //100
// 打开弹窗触发方法
this.$changeComponentShow("#secondMenu", true, `top: ${topNum}px`);
// 给二级菜单页面传点击的一级菜单具体值
this.$sendChanel("currentSecondMenu", { item, index });
},
// 展示大数据页面
showBigDataPage() {
console.log("展示大数据页面");
},
},
};
</script>
<style lang="scss" scoped>
.leftBox {
width: 162px;
height: 380px;
position: absolute;
left: 1em;
bottom: calc(7vw + 2px);
}
.left {
width: 100%;
height: 100%;
user-select: none;
//width: 7vw;
color: red;
display: flex;
flex-direction: row;
justify-content: space-between;
.line {
width: 5.2vw;
}
.scrollBar81 {
position: absolute;
top: 33px;
left: 8px;
}
.scrollBar {
position: absolute;
top: 33px;
left: 11px;
height: 270px;
}
.menus {
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
/* bottom: 10vh;
padding: 35px 10px 15px 0;*/
height: 350px;
margin-top: 20px;
//align-self: center;
padding: 0 8px 0 5px;
.menus_itemBox {
width: 100%;
//width: 77px;
//height: 65px;
height: 6.5vh;
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: auto;
.item_icon {
width: 100%;
//height: 5vh;
height: 4.2vh;
//width: 77px;
//height: 48px;
position: relative;
background: url('../../assets/images/hongse/left.png') no-repeat;
background-size: 100% 100%;
}
.item_text {
position: absolute;
top: 13px;
left: 50px;
width: 100%;
height: 2vh;
font-size: 18px;
text-align: center;
//height: 17px;
//line-height: 17px;
color: #fff;
max-width: 75px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-family: 'alimamashuheiti';
font-weight: 700;
text-shadow: 0px 0px 9px #1476FF;
}
}
.menus_itemBox:hover .item_icon {
background: url('../../assets/images/hongse/left1.png') no-repeat;
background-size: 100% 100%;
}
.menus_itemBox:hover .item_text {
color: rgba(0, 255, 255, 1);
}
}
}
.left_bottom {
position: fixed;
bottom: 6em;
left: 72px;
width: 32px;
height: 32px;
background: url('../../assets/images/hongse/shou.png') no-repeat;
transition: all 0.3s ease;
cursor: pointer;
}
</style>

View File

@ -0,0 +1,769 @@
<template>
<div class="left_second" id="secondMenu" style="color: #fff" ref="secondMenu">
<!--二级菜单背景图-->
<svg-icon :class-name="['left_second_menu_bg']" icon-class="secondMenuBg"></svg-icon>
<!--菜单列表-->
<div class="menus_box">
<div v-for="item in currentItem" @click.right="item.rightfun(item)" @click="item.fun(item)" class="menus_item">
<div class="item_icon">
<template v-if="item.hasOwnProperty('svg')">
<svg-icon :class-name="['second_menu_icon']" :icon-class="item.svg"></svg-icon>
</template>
<template v-else>
<img width="100%" height="100%" :src="item.poster_url" alt="" />
<!-- <el-button icon="el-icon-document" style="width: 100%;height: 100%"></el-button>-->
<!-- <i class="el-icon-document-add"></i>-->
<!-- <i class="el-icon-document" style="width: 100%;height: 100%"></i>-->
</template>
</div>
<template v-if="item.hasOwnProperty('svg')">
<template v-if="item.hasOwnProperty('trueName') && item.status">
<div :class="['item_text', !item.status ? '' : 'active']">
{{ $t(`leftMenu.secondMenu.${item.trueName}`) }}
</div>
</template>
<template v-else>
<div :class="['item_text', !item.status ? '' : 'active']">
{{ $t(`leftMenu.secondMenu.${item.name}`) }}
</div>
</template>
</template>
<template v-else>
<div class="item_text">{{ item.model_name || item.ts_name }}</div>
</template>
</div>
</div>
</div>
</template>
<script>
import secondMenuFun from "./secondMenuFun";
import { listSituation, modelList } from "../../api/gisAPI";
export default {
name: "secondMenu",
mixins: [secondMenuFun],
data() {
return {
menuList: [
// 菜单内容来源于文件
{
list: [],
key: "situation",
},
// 模型库二级菜单
{
list: [],
key: "model",
},
// 特效库二级菜单
{
list: [
//轨迹运动
{
fun: this.toDo,
name: "trajectoryMotion",
svg: "trajectoryMotion",
},
//电子围墙
{
fun: this.toDo,
name: "electronicFence",
svg: "electronicFence",
},
// 实体墙
{
fun: this.toDo,
name: "entityWall",
svg: "entityWall",
},
//扩散光波
{
fun: this.toDo,
name: "radarLightWave",
svg: "radarLightWave",
},
//雷达光波
{
fun: this.toDo,
name: "diffusedLightWave",
svg: "diffusedLightWave",
},
//立体雷达
{
fun: this.toDo,
name: "scanStereoscopic",
svg: "scanStereoscopic",
},
//多边体
{
fun: this.toDo,
name: "multilateralBody",
svg: "multilateralBody",
},
//水面
{
fun: this.toDo,
name: "waterSurface",
svg: "waterSurface",
},
//贴地文字
// {
// fun: this.toDo,
// name: "groundText",
// svg: "groundText",
// },
// //立体文字
// {
// fun: this.toDo,
// name: "standText",
// svg: "standText",
// },
/*
{
fun: this.toDo,
name: 'cube',
svg: "cube",
},
{
fun: this.toDo,
name: 'trajectoryMotion',
svg: "trajectoryMotion",
},
*/
//绘制道路(无)
// {
// fun: this.toDo,
// name: "roadDraw",
// svg: "roadDraw",
// },
// //线路绘制(无)
// {
// fun: this.toDo,
// name: "lineDraw",
// svg: "lineDraw",
// },
//喷泉
{
fun: this.toDo,
name: "fountain",
svg: "fountain",
},
// // 水流
{
fun: this.toDo,
name: "waterL",
svg: "waterL",
},
//火焰
{
fun: this.toDo,
name: "fire",
svg: "fire",
},
//爆炸
{
fun: this.toDo,
name: "explosion",
svg: "explosion",
},
//烟雾
{
fun: this.toDo,
name: "smoke",
svg: "smoke",
},
//夜视
{
fun: this.toDo,
name: "nightVision",
svg: "nightVision",
status: false,
},
// 雨
{
fun: this.toDo,
name: "rain",
svg: "rain",
status: false,
},
// 雪
{
fun: this.toDo,
name: "snow",
svg: "snow",
status: false,
},
//雾
{
fun: this.toDo,
name: "fog",
svg: "fog",
status: false,
},
//光照
{
fun: this.toDo,
name: "illumination",
svg: "illumination",
status: false,
},
//星空
{
fun: this.toDo,
name: "skystarry",
svg: "skystarry",
status: false,
},
/* {
fun: this.toDo,
name: 'light',
svg: "light",
status: false
},*/
//热力图(无)
// {
// fun: this.toDo,
// name: "heatMap",
// svg: "heatMap",
// },
// 椭圆
// {
// fun: this.toDo,
// name: "ellipse",
// svg: "ellipse",
// },
// // 扇形
// {
// fun: this.toDo,
// name: "sector",
// svg: "sector",
// },
],
key: "effect",
},
// 分析二级菜单
{
list: [
//淹没分析
{
fun: this.toDo,
name: "inundationAnalysis",
svg: "inundationAnalysis",
},
//剖面分析
{
fun: this.toDo,
name: "profileAnalysis",
svg: "profileAnalysis",
},
//通视
{
fun: this.toDo,
name: "Intervisibility",
svg: "Intervisibility",
},
//视域分析
{
fun: this.toDo,
name: "visualFieldAnalysis",
svg: "visualFieldAnalysis",
},
// 视域分析(地形)
{
fun: this.toDo,
name: "visualFieldAnalysis2",
svg: "visualFieldAnalysis2",
},
//坡度坡向
{
fun: this.toDo,
name: "slopeDirection",
svg: "slopeDirection",
},
//土方分析
{
fun: this.toDo,
name: "cutFill",
svg: "cutFill",
},
//范围查询
// {
// fun: this.toDo,
// name: "rangeQuery",
// svg: "rangeQuery",
// },
//透视
// {
// fun: this.toDo,
// name: "perspective",
// svg: "perspective",
// status: false,
// },
//等高线
{
fun: this.toDo,
name: "contour",
svg: "contour",
},
//清除
{
fun: this.toDo,
name: "clear",
svg: "clearMeasure",
},
],
key: "analysis",
},
{
list: [
// 投影面积
{
fun: this.toDo,
name: "projectionArea",
svg: "projectionArea",
},
// 贴地面积
{
fun: this.toDo,
name: "areaMeasure",
svg: "areaMeasure",
},
// 投影距离
{
fun: this.toDo,
name: "projectionDistanceMeasure",
svg: "projectionDistanceMeasure",
},
// // 贴地距离
{
fun: this.toDo,
name: "distanceMeasure",
svg: "distanceMeasure",
},
// 高度测量
{
fun: this.toDo,
name: "heightMeasure",
svg: "heightMeasure",
},
// 三角测量
{
fun: this.toDo,
name: "triangleMeasure",
svg: "triangleMeasure",
},
// 方位角测量
{
fun: this.toDo,
name: "MeasureAzimuth",
svg: "MeasureAzimuth",
},
//夹角测量(无)
{
fun: this.toDo,
name: "MeasureAngle",
svg: "MeasureAngle",
},
// 坡度测量
{
fun: this.toDo,
name: "lopeDistanceMeasures",
svg: "lopeDistanceMeasures",
},
// 坐标测量
{
fun: this.toDo,
name: "coorMeasure",
svg: "coorMeasure",
},
// 清楚测量
{
fun: this.toDo,
name: "clearMeasure",
svg: "clearMeasure",
},
],
key: "measure",
},
// 工具二级菜单
{
list: [
//BIM编辑
// {
// fun: this.toDo,
// name: "BIMEdit",
// svg: "BIMEdit",
// status: false,
// },
// 路径规划
{
fun: this.toDo,
name: "routePlan",
svg: "routePlan",
},
// 清除路径规划
{
fun: this.toDo,
name: "clearTrajectoryMotion",
svg: "clearTrajectoryMotion",
},
/*{
fun: this.toDo,
name: 'floodSimulation',
svg: 'floodSimulation'
},*/
/* {
fun: this.toDo,
name: 'clearQuery',
svg: 'clearQuery'
},*/
/* {
fun: this.toDo,
name: 'videoRecord',
svg: 'videoRecord'
},*/
//涂鸦
{
fun: this.toDo,
name: "graffiti",
svg: "graffiti",
status: false,
},
//清除涂鸦
{
fun: this.toDo,
name: "clearGraffiti",
svg: "clearGraffiti",
},
// 飞行漫游
{
fun: this.toDo,
name: "path",
svg: "path",
},
// 坐标定位
{
fun: this.toDo,
name: "coorLocation",
svg: "coorLocation",
},
//鼠标定位
{
fun: this.toDo,
name: "mouseLocation",
trueName: "mouseOver",
svg: "mouseLocation",
status: false,
},
//标注点聚合
{
fun: this.toDo,
name: "annotationAggregation",
svg: "annotationAggregation",
status: false,
},
// // 卷帘对比
{
fun: this.toDo,
name: "splitScreen",
svg: "splitScreen",
status: false,
},
// // 全景导入222
// {
// fun: this.toDo,
// name: "importPanorama",
// svg: "importPanorama",
// },
// // //照片定位222
// {
// fun: this.toDo,
// name: "pictureLocation",
// svg: "pictureLocation",
// },
// 屏幕截图(无)
{
fun: this.toDo,
name: "HDScreen",
svg: "HDScreen",
},
// 高清出图2
{
fun: this.toDo,
name: "HDScreenHD",
svg: "HDScreenHD",
},
// 视频录制222
{
fun: this.toDo,
name: "videoRecording",
trueName: "destoryRecord",
svg: "videoRecord",
status: false,
},
//模型压平
{
fun: this.pressModel,
name: "pressModel",
svg: "pressModel",
},
//地形开挖
{
fun: this.terrainDig,
name: "terrainDig",
svg: "terrainDig",
},
// 剖切
{
fun: this.tilesetClipping,
name: "tilesetClipping",
svg: "tilesetClipping",
},
//清除剖切
{
fun: this.clearTilesetClipping,
name: "clearTilesetClipping",
svg: "clearTilesetClipping",
},
//范围截图(无)
// {
// fun: this.toDo,
// name: "areaScreen",
// svg: "areaScreen",
// },
// 模型转换
// {
// fun: this.toDo,
// name: "transform",
// svg: "transform",
// },
//照片定位
// 度分秒转换
{
fun: this.toDo,
name: "projConvert",
svg: "projConvert",
status1: false,
},
// 投影转换
{
fun: this.toDo,
name: "projectionConvert",
svg: "projectionConvert",
status1: false,
},
// 全景关联222
// {
// fun: this.toDo,
// name: "importImg",
// svg: "importImg",
// },
// gdb导入222
{
fun: this.toDo,
name: "gdbImport",
svg: "gdbImport",
},
// obj模型
// {
// fun: this.toDo,
// name: "objModel",
// svg: "gdbImport",
// },
// 人房关联222
// {
// fun: this.toDo,
// name: "peopleRoomLink",
// svg: "peopleRoomLink",
// },
// {
// fun: this.toDo,
// name: "airLine",
// svg: "peopleRoomLink",
// },
// 物资关联222
// 圆形统计
{
fun: this.goodsSearchCircle,
name: "goodsSearchCircle",
svg: "goodsSearchCircle",
},
// 多边形统计
{
fun: this.goodsSearchPolgon,
name: "goodsSearchPolgon",
svg: "goodsSearchPolgon",
},
// 分屏
],
key: "tool",
},
// 菜单内容来源于文件
// 军标二级菜单
{
list: [],
key: "militaryMark",
},
// 在线图源二级菜单
{
key: "onlinePictureSource",
},
],
currentItem: [],
currentIndex: 0,
};
},
created() { },
mounted() {
// 接收一级菜单页面传过来的具体值,并指定当前页面将要显示的二级菜单具体值
this.$recvChanel("currentSecondMenu", (params) => {
console.log(params);
let arr = ["importImg", "gdbImport", "importPanorama"];
this.menuList.forEach((it, i) => {
if (it.key == params.item.key) {
if (["model"].includes(it.key)) {
this.currentItem = [];
console.log("secondMenu的mounted");
modelList((res) => {
it.list = res.list;
it.list.forEach((item) => {
item.fun = this.addGlb;
});
this.currentItem = it.list;
});
// this.currentItem = [{name: 'imports',}]
} else if (["situation"].includes(it.key)) {
this.currentItem = [];
console.log("secondMenu的mounted");
listSituation({}, (res) => {
console.log(res);
it.list = res.list;
it.list.forEach((item) => {
item.rightfun = this.editTs;
item.fun = this.tsOnclick;
});
this.currentItem = it.list;
this.currentItem.unshift({ ts_name: "新建", fun: this.newTs });
});
// this.currentItem = [{name: 'imports',}]
} else {
this.currentItem = it.list;
}
// this.currentIndex = i
}
});
});
},
methods: {
toDo(item) {
if (window.checkAuthIsValid) {
if (!item.hasOwnProperty("status"))
this.$changeComponentShow(".left_second", false);
this[item.name](item, this.menuList);
} else {
this.$message({
message: "您没有该功能的权限",
type: "warning",
});
}
},
},
};
</script>
<style scoped lang="scss">
#secondMenu {
user-select: none;
-webkit-user-select: none;
z-index: 888;
display: none;
transform: translateY(-50%);
/*width: 17vw;
height: 30vh;*/
width: 15vw;
height: 13.5vw;
left: 6.5vw;
//border: 1px solid greenyellow;
.menus_box {
width: 95%;
height: 85%;
position: absolute; // 绝对定位
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
//background: #0bcb9a;
//margin: auto;
display: flex;
flex-direction: row;
justify-content: start;
align-content: flex-start;
text-align: center;
flex-wrap: wrap;
overflow: auto;
.menus_item {
margin-top: 0.6em;
cursor: pointer;
//width: 4vw;
//height: 5vh;
width: 25%;
height: 20%;
//background: salmon;
//padding: .4em;
.item_icon {
width: 50%;
height: 60%;
position: relative;
margin: auto;
}
.item_text {
font-size: 12px;
color: #fff;
text-align: center;
padding-top: 0.5em;
}
}
}
.menus_box::-webkit-scrollbar-track {
border: 1px solid #66b8cd;
background-color: #fff;
border-radius: 10px;
}
.menus_box::-webkit-scrollbar {
width: 8px;
background-color: #193a49;
}
.menus_box::-webkit-scrollbar-thumb {
background-color: #28e4fc;
border-radius: 15px;
}
.item_icon {
.el-button {
padding: 0;
}
}
.active {
color: #f00 !important;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,936 @@
<template>
<div class="left_second" id="secondMenu" style="color: #fff" ref="secondMenu">
<!--二级菜单背景图-->
<!-- <svg-icon :class-name="['left_second_menu_bg']" icon-class="secondMenuBg"></svg-icon> -->
<!--菜单列表-->
<div class="menus_box">
<div v-for="item in currentItem" @click.right="item.rightfun(item)" @click="item.fun(item)" class="menus_item"
@mouseover="mouseover(item)" @mouseleave="mouseout(item)">
<div class="item_icon">
<template v-if="item.hasOwnProperty('svg')">
<svg-icon v-show="!item.isMoveIn" :class-name="['second_menu_icon']" :icon-class="item.svg"></svg-icon>
<img style="width: 100%;height: 100%;" v-if="item.isMoveIn" :src="'/static/animation/' + item.svg + '.png'"
alt="">
</template>
<template v-else>
<img width="100%" height="100%" :src="item.poster_url" alt="" />
<!-- <el-button icon="el-icon-document" style="width: 100%;height: 100%"></el-button>-->
<!-- <i class="el-icon-document-add"></i>-->
<!-- <i class="el-icon-document" style="width: 100%;height: 100%"></i>-->
</template>
</div>
<template v-if="item.hasOwnProperty('svg')">
<template v-if="item.hasOwnProperty('trueName') && item.status">
<div :class="['item_text', !item.status ? '' : 'active']">
{{ $t(`leftMenu.secondMenu.${item.trueName}`) }}
</div>
</template>
<template v-else>
<div :class="['item_text', !item.status ? '' : 'active']">
{{ $t(`leftMenu.secondMenu.${item.name}`) }}
</div>
</template>
</template>
<template v-else>
<div class="item_text">{{ item.model_name || item.ts_name }}</div>
</template>
</div>
</div>
</div>
</template>
<script>
import secondMenuFun from "./secondMenuFun";
import { listSituation, modelList } from "../../api/gisAPI";
export default {
name: "secondMenu",
mixins: [secondMenuFun],
data() {
return {
menuList: [
// 菜单内容来源于文件
{
list: [],
key: "situation",
},
// 模型库二级菜单
{
list: [],
key: "model",
},
// 特效库二级菜单
{
list: [
//轨迹运动
{
fun: this.toDo,
name: "trajectoryMotion",
svg: "trajectoryMotion",
// 是否移入
isMoveIn: false,
},
//电子围墙
{
fun: this.toDo,
name: "electronicFence",
svg: "electronicFence",
// 是否移入
isMoveIn: false,
},
//扩散光波
{
fun: this.toDo,
name: "radarLightWave",
svg: "radarLightWave",
// 是否移入
isMoveIn: false,
},
//雷达光波
{
fun: this.toDo,
name: "diffusedLightWave",
svg: "diffusedLightWave",
// 是否移入
isMoveIn: false,
},
//立体雷达
{
fun: this.toDo,
name: "scanStereoscopic",
svg: "scanStereoscopic",
// 是否移入
isMoveIn: false,
},
//多边体
{
fun: this.toDo,
name: "multilateralBody",
svg: "multilateralBody",
// 是否移入
isMoveIn: false,
},
//水面
{
fun: this.toDo,
name: "waterSurface",
svg: "waterSurface",
// 是否移入
isMoveIn: false,
},
//贴地文字
// {
// fun: this.toDo,
// name: "groundText",
// svg: "groundText",
// },
// //立体文字
// {
// fun: this.toDo,
// name: "standText",
// svg: "standText",
// },
/*
{
fun: this.toDo,
name: 'cube',
svg: "cube",
},
{
fun: this.toDo,
name: 'trajectoryMotion',
svg: "trajectoryMotion",
},
*/
//绘制道路(无)
// {
// fun: this.toDo,
// name: "roadDraw",
// svg: "roadDraw",
// },
// //线路绘制(无)
// {
// fun: this.toDo,
// name: "lineDraw",
// svg: "lineDraw",
// },
//喷泉
{
fun: this.toDo,
name: "fountain",
svg: "fountain",
// 是否移入
isMoveIn: false,
},
// // 水流
{
fun: this.toDo,
name: "waterL",
svg: "waterL",
// 是否移入
isMoveIn: false,
},
//火焰
{
fun: this.toDo,
name: "fire",
svg: "fire",
// 是否移入
isMoveIn: false,
},
//爆炸
{
fun: this.toDo,
name: "explosion",
svg: "explosion",
// 是否移入
isMoveIn: false,
},
//烟雾
{
fun: this.toDo,
name: "smoke",
svg: "smoke",
// 是否移入
isMoveIn: false,
},
//夜视
{
fun: this.toDo,
name: "nightVision",
svg: "nightVision",
status: false,
// 是否移入
isMoveIn: false,
},
// 雨
{
fun: this.toDo,
name: "rain",
svg: "rain",
status: false,
// 是否移入
isMoveIn: false,
},
// 雪
{
fun: this.toDo,
name: "snow",
svg: "snow",
status: false,
// 是否移入
isMoveIn: false,
},
//雾
{
fun: this.toDo,
name: "fog",
svg: "fog",
status: false,
// 是否移入
isMoveIn: false,
},
//光照
{
fun: this.toDo,
name: "illumination",
svg: "illumination",
status: false,
// 是否移入
isMoveIn: false,
},
//星空
{
fun: this.toDo,
name: "skystarry",
svg: "skystarry",
status: false,
// 是否移入
isMoveIn: false,
},
/* {
fun: this.toDo,
name: 'light',
svg: "light",
status: false
},*/
//热力图(无)
// {
// fun: this.toDo,
// name: "heatMap",
// svg: "heatMap",
// },
],
key: "effect",
},
// 分析二级菜单
{
list: [
//淹没分析
{
fun: this.toDo,
name: "inundationAnalysis",
svg: "inundationAnalysis",
// 是否移入
isMoveIn: false,
},
//剖面分析
{
fun: this.toDo,
name: "profileAnalysis",
svg: "profileAnalysis",
// 是否移入
isMoveIn: false,
},
//通视
{
fun: this.toDo,
name: "Intervisibility",
svg: "Intervisibility",
// 是否移入
isMoveIn: false,
},
//视域分析
{
fun: this.toDo,
name: "visualFieldAnalysis",
svg: "visualFieldAnalysis",
// 是否移入
isMoveIn: false,
},
// 视域分析(地形)
{
fun: this.toDo,
name: "visualFieldAnalysis2",
svg: "visualFieldAnalysis2",
// 是否移入
isMoveIn: false,
},
//坡度坡向
{
fun: this.toDo,
name: "slopeDirection",
svg: "slopeDirection",
// 是否移入
isMoveIn: false,
},
//土方分析
{
fun: this.toDo,
name: "cutFill",
svg: "cutFill",
// 是否移入
isMoveIn: false,
},
//范围查询
// {
// fun: this.toDo,
// name: "rangeQuery",
// svg: "rangeQuery",
// },
//透视
// {
// fun: this.toDo,
// name: "perspective",
// svg: "perspective",
// status: false,
// },
//等高线
{
fun: this.toDo,
name: "contour",
svg: "contour",
// 是否移入
isMoveIn: false,
},
//清除分析
{
fun: this.toDo,
name: "clear",
svg: "clearMeasure",
// 是否移入
isMoveIn: false,
},
],
key: "analysis",
},
{
list: [
// 投影面积
{
fun: this.toDo,
name: "projectionArea",
svg: "projectionArea",
// 是否移入
isMoveIn: false,
},
// 贴地面积
{
fun: this.toDo,
name: "areaMeasure",
svg: "areaMeasure",
// 是否移入
isMoveIn: false,
},
// 投影距离
{
fun: this.toDo,
name: "projectionDistanceMeasure",
svg: "projectionDistanceMeasure",
// 是否移入
isMoveIn: false,
},
// // 贴地距离
{
fun: this.toDo,
name: "distanceMeasure",
svg: "distanceMeasure",
// 是否移入
isMoveIn: false,
},
// 高度测量
{
fun: this.toDo,
name: "heightMeasure",
svg: "heightMeasure",
// 是否移入
isMoveIn: false,
},
// 三角测量
{
fun: this.toDo,
name: "triangleMeasure",
svg: "triangleMeasure",
// 是否移入
isMoveIn: false,
},
// 方位角测量
{
fun: this.toDo,
name: "MeasureAzimuth",
svg: "MeasureAzimuth",
// 是否移入
isMoveIn: false,
},
//夹角测量(无)
{
fun: this.toDo,
name: "MeasureAngle",
svg: "MeasureAngle",
// 是否移入
isMoveIn: false,
},
// 坡度测量
{
fun: this.toDo,
name: "lopeDistanceMeasures",
svg: "lopeDistanceMeasures",
// 是否移入
isMoveIn: false,
},
// 坐标测量
{
fun: this.toDo,
name: "coorMeasure",
svg: "coorMeasure",
// 是否移入
isMoveIn: false,
},
// 清除测量
{
fun: this.toDo,
name: "clearMeasure",
svg: "clearMeasure",
// 是否移入
isMoveIn: false,
},
],
key: "measure",
},
// 工具二级菜单
{
list: [
//BIM编辑
// {
// fun: this.toDo,
// name: "BIMEdit",
// svg: "BIMEdit",
// status: false,
// },
// 路径规划
{
fun: this.toDo,
name: "routePlan",
svg: "routePlan",
// 是否移入
isMoveIn: false,
},
// 清除路径规划
{
fun: this.toDo,
name: "clearTrajectoryMotion",
svg: "clearTrajectoryMotion",
// 是否移入
isMoveIn: false,
},
/*{
fun: this.toDo,
name: 'floodSimulation',
svg: 'floodSimulation'
},*/
/* {
fun: this.toDo,
name: 'clearQuery',
svg: 'clearQuery'
},*/
/* {
fun: this.toDo,
name: 'videoRecord',
svg: 'videoRecord'
},*/
//涂鸦
{
fun: this.toDo,
name: "graffiti",
svg: "graffiti",
status: false,
// 是否移入
isMoveIn: false,
},
//清除涂鸦
{
fun: this.toDo,
name: "clearGraffiti",
svg: "clearGraffiti",
// 是否移入
isMoveIn: false,
},
// 飞行漫游
{
fun: this.toDo,
name: "path",
svg: "path",
// 是否移入
isMoveIn: false,
},
// 坐标定位
{
fun: this.toDo,
name: "coorLocation",
svg: "coorLocation",
// 是否移入
isMoveIn: false,
},
//鼠标定位
{
fun: this.toDo,
name: "mouseLocation",
trueName: "mouseOver",
svg: "mouseLocation",
status: false,
// 是否移入
isMoveIn: false,
},
//标注点聚合
{
fun: this.toDo,
name: "annotationAggregation",
svg: "annotationAggregation",
status: false,
// 是否移入
isMoveIn: false,
},
// 卷帘对比
{
fun: this.toDo,
name: "splitScreen",
svg: "splitScreen",
status: false,
// 是否移入
isMoveIn: false,
},
// // 全景导入222
// {
// fun: this.toDo,
// name: "importPanorama",
// svg: "importPanorama",
// },
// // //照片定位222
// {
// fun: this.toDo,
// name: "pictureLocation",
// svg: "pictureLocation",
// },
// 屏幕截图(无)
{
fun: this.toDo,
name: "HDScreen",
svg: "HDScreen",
// 是否移入
isMoveIn: false,
},
// 高清出图2
{
fun: this.toDo,
name: "HDScreenHD",
svg: "HDScreenHD",
// 是否移入
isMoveIn: false,
},
// 视频录制222
{
fun: this.toDo,
name: "videoRecording",
trueName: "destoryRecord",
svg: "videoRecord",
status: false,
// 是否移入
isMoveIn: false,
},
//模型压平
{
fun: this.pressModel,
name: "pressModel",
svg: "pressModel",
// 是否移入
isMoveIn: false,
},
//地形开挖
{
fun: this.terrainDig,
name: "terrainDig",
svg: "terrainDig",
// 是否移入
isMoveIn: false,
},
// 剖切
{
fun: this.tilesetClipping,
name: "tilesetClipping",
svg: "tilesetClipping",
// 是否移入
isMoveIn: false,
},
//清除剖切
{
fun: this.clearTilesetClipping,
name: "clearTilesetClipping",
svg: "clearTilesetClipping",
// 是否移入
isMoveIn: false,
},
//范围截图(无)
// {
// fun: this.toDo,
// name: "areaScreen",
// svg: "areaScreen",
// },
// 模型转换
// {
// fun: this.toDo,
// name: "transform",
// svg: "transform",
// },
//照片定位
// 度分秒转换
{
fun: this.toDo,
name: "projConvert",
svg: "projConvert",
status1: false,
// 是否移入
isMoveIn: false,
},
// 投影转换
{
fun: this.toDo,
name: "projectionConvert",
svg: "projectionConvert",
status1: false,
// 是否移入
isMoveIn: false,
},
// 全景关联222
// {
// fun: this.toDo,
// name: "importImg",
// svg: "importImg",
// },
// gdb导入222
{
fun: this.toDo,
name: "gdbImport",
svg: "gdbImport",
// 是否移入
isMoveIn: false,
},
// obj模型
// {
// fun: this.toDo,
// name: "objModel",
// svg: "gdbImport",
// },
// 人房关联222
{
fun: this.toDo,
name: "peopleRoomLink",
svg: "peopleRoomLink",
// 是否移入
isMoveIn: false,
},
// {
// fun: this.toDo,
// name: "airLine",
// svg: "peopleRoomLink",
// },
// 物资关联222
// 圆形统计
{
fun: this.goodsSearchCircle,
name: "goodsSearchCircle",
svg: "goodsSearchCircle",
// 是否移入
isMoveIn: false,
af
},
// 多边形统计
{
fun: this.goodsSearchPolgon,
name: "goodsSearchPolgon",
svg: "goodsSearchPolgon",
// 是否移入
isMoveIn: false,
},
// 分屏
],
key: "tool",
},
// 菜单内容来源于文件
// 军标二级菜单
{
list: [],
key: "militaryMark",
},
// 在线图源二级菜单
{
key: "onlinePictureSource",
},
],
currentItem: [],
currentIndex: 0,
};
},
created() { },
mounted() {
// 接收一级菜单页面传过来的具体值,并指定当前页面将要显示的二级菜单具体值
this.$recvChanel("currentSecondMenu", (params) => {
console.log(params);
let arr = ["importImg", "gdbImport", "importPanorama"];
this.menuList.forEach((it, i) => {
if (it.key == params.item.key) {
if (["model"].includes(it.key)) {
this.currentItem = [];
console.log("secondMenu的mounted");
modelList((res) => {
it.list = res.list;
it.list.forEach((item) => {
item.fun = this.addGlb;
});
this.currentItem = it.list;
});
// this.currentItem = [{name: 'imports',}]
} else if (["situation"].includes(it.key)) {
this.currentItem = [];
console.log("secondMenu的mounted");
listSituation({}, (res) => {
console.log(res);
it.list = res.list;
it.list.forEach((item) => {
item.rightfun = this.editTs;
item.fun = this.tsOnclick;
});
this.currentItem = it.list;
this.currentItem.unshift({ ts_name: "新建", fun: this.newTs });
});
// this.currentItem = [{name: 'imports',}]
} else {
this.currentItem = it.list;
}
// this.currentIndex = i
}
});
});
},
methods: {
// 鼠标移入
mouseover(item) {
if (item.hasOwnProperty("isMoveIn")) item.isMoveIn = true;
},
// 鼠标移出
mouseout(item) {
if (item.hasOwnProperty("isMoveIn")) item.isMoveIn = false;
},
toDo(item) {
if (!item.hasOwnProperty("status"))
this.$changeComponentShow(".left_second", false);
this[item.name](item, this.menuList);
},
},
};
</script>
<style scoped lang="scss">
#secondMenu {
user-select: none;
-webkit-user-select: none;
z-index: 888;
display: none;
transform: translateY(-50%);
/*width: 17vw;
height: 30vh;*/
width: 15vw;
left: 9vw;
//border: 1px solid greenyellow;
.menus_box {
width: 95%;
position: absolute; // 绝对定位
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
//background: #0bcb9a;
//margin: auto;
display: flex;
flex-direction: row;
justify-content: start;
align-content: flex-start;
text-align: center;
flex-wrap: wrap;
overflow: auto;
background: url('../../assets/images/hongse/leftbg.png') no-repeat;
background-size: 100% 100%;
padding: 10px;
.menus_item {
margin-top: 0.6em;
cursor: pointer;
//width: 4vw;
//height: 5vh;
width: 25%;
height: 20%;
//background: salmon;
//padding: .4em;
.item_icon {
height: 20px;
width: 20px;
position: relative;
margin: auto;
}
.item_text {
font-size: 12px;
color: #fff;
text-align: center;
padding-top: 0.5em;
}
}
}
.menus_box::-webkit-scrollbar-track {
border: 1px solid #66b8cd;
background-color: #fff;
border-radius: 10px;
}
.menus_box::-webkit-scrollbar {
width: 8px;
background-color: #193a49;
}
.menus_box::-webkit-scrollbar-thumb {
background-color: #28e4fc;
border-radius: 15px;
}
.item_icon {
.el-button {
padding: 0;
}
}
.active {
color: #f00 !important;
}
}
</style>

View File

@ -0,0 +1,340 @@
import { get_source_list } from "../../api/gisAPI";
const test = {
data() {
return {
earthsDom: ["earth", "map2d"],
};
},
mounted() {},
methods: {
callback(Event) {
console.log(Event);
this.earthsDom.forEach((dom) => {
$("#" + dom).removeClass("selectedEarthCss");
});
$("#" + Event.path[4].id).addClass("selectedEarthCss");
if (Event.path[4].id == "earths") {
window.Earth1 = window.Earths;
copy(window.right_entityMap);
} else {
window.Earth1 = window.Earth;
copy(window.left_entityMap);
}
function copy(map) {
if (map == "undefined") {
map = new Map();
}
window._entityMap.clear();
// empty = null
window._entityMap = new Map([...map]);
console.log("copy之后");
console.log(_entityMap);
console.log(right_entityMap);
// console.log(Earth1)
// console.log(Earth)
// console.log(Earths)
}
},
tongbu() {
let _this = this.$refs.tree;
// this.$refs.tree.
// $("#earths").click()
window.Earth1 = window.Earths;
$("#earths").addClass("selectedEarthCss");
$("#earth").removeClass("selectedEarthCss");
get_source_list().then((response) => {
if ([0, 200].includes(response.code)) {
let data = JSON.parse(JSON.stringify(response.data.list || []));
data.sort(_this.keysort("tree_index"));
//给node设置树形如icon是否允许添加子节点以及右键菜单
if (window.right_entityMap == "undefined")
window.right_entityMap = new Map();
console.log("被同步的数据", data);
console.log("被同步的数据", window.Earth1);
console.log("window.right_entityMap", window.right_entityMap);
data.forEach((node) => {
console.log(
"node.source_type",
node.source_type,
[
"point",
"line",
"panel",
"circle",
"attackArrow",
"pincerArrow",
"groundImage",
"layer",
"ArcgisWXImagery",
].includes(node.source_type)
);
if (
!window.right_entityMap.get(node.source_id) &&
[
"model",
"point",
"line",
"panel",
"circle",
"attackArrow",
"pincerArrow",
"groundImage",
"layer",
"ArcgisWXImagery",
].includes(node.source_type)
) {
if (node.detail) node.detail = JSON.parse(node.detail);
//设置树上图标,并渲染到地球上
_this.setOptions(node);
}
});
if (window.right_entityMap == "undefined")
window.right_entityMap = new Map();
window.right_entityMap = new Map([...window._entityMap]);
}
});
},
/* twoscreen() {
// window.earth = null
//
this.$changeComponentShow(".tongbu", true)
this.halfEarth = !this.halfEarth
console.log(this.halfEarth)
if (this.halfEarth) {
$("#earth").addClass("halfEarth")
$("#earths").addClass("halfEarth")
$("#earths")[0].style.left = "50%"
let earths = new YJ.YJEarth('earths')
// YJ.setSecondEarth(earths.earth)
// earths.earth.czm.viewer.scene.mode = Cesium.SceneMode.SCENE2D
// earths.earth.czm.viewer.scene.screenSpaceCameraController.enableTranslate = true
window.Earths = earths
// console.log("earth", earths)
// console.log(
// earths.earth.sceneTree.$refs
// )
YJ.Global.setMode2D(earths.earth)
$("#earth").addClass("selectedEarthCss")
this.earthsDom.forEach(dom => {
$("#" + dom)[0].addEventListener("click", this.callback, {capture: true})
})
window.right_entityMap = new Map()
window.left_entityMap = new Map([...window._entityMap])
} else {
this.$changeComponentShow(".tongbu", false)
this.earthsDom.forEach(dom => {
$("#" + dom)[0].removeEventListener("click", this.callback, {capture: true})
$("#" + dom).removeClass("halfEarth")
$("#" + dom).removeClass("selectedEarthCss")
})
window._entityMap = window.left_entityMap
window.Earth1 = window.Earth
window.Earths.earth.destroy()
$("#earths").empty();
window.Earths = null
}
},*/
tongbu2D() {
let _this = $root_home_index.$refs.tree;
get_source_list().then((response) => {
if ([0, 200].includes(response.code)) {
let data = JSON.parse(JSON.stringify(response.data.list || []));
data.sort(_this.keysort("tree_index"));
//给node设置树形如icon是否允许添加子节点以及右键菜单
if (!window.right_entityMap) window.right_entityMap = new Map();
console.log("被同步的数据", data);
console.log("被同步的数据", window.Earth1);
console.log("window.right_entityMap", window.right_entityMap);
data.forEach((node) => {
if (
!window.right_entityMap.get(node.source_id) &&
[
"point",
"line",
"panel",
"circle",
"attackArrow",
"pincerArrow",
"layer",
].includes(node.source_type)
) {
if (node.detail) node.detail = JSON.parse(node.detail);
//设置树上图标,并渲染到地球上
_this.setOptions2d(node);
}
});
/*if (window.right_entityMap == 'undefined')
window.right_entityMap = new Map()
window.right_entityMap = new Map([...window._entityMap])*/
}
});
},
map2d() {
window.multiViewportMode = true;
window.splitScreen = false
console.log('window.splitScreen',window.splitScreen,'window.multiViewportMode',window.multiViewportMode);
// 判断window.menuList是否存在
if (window.checkAuthIsValid) {
if (window.menuList) {
let tool = window.menuList[5].list;
tool.forEach((item) => {
if (item.name == "splitScreen") {
if (item.status == true) {
item.status = false;
this.halfEarth = false;
}
}
});
}
this.halfEarth = !this.halfEarth;
if (this.halfEarth) {
YJ.Global.multiViewportMode.on(window.Earth1);
} else {
YJ.Global.multiViewportMode.off(window.Earth1);
}
} else {
this.$message({
message: "您没有该功能的权限",
type: "warning",
});
}
// this.$changeComponentShow(".tongbu", true)
// if (this.halfEarth) {
// $("#earth").addClass("halfEarth")
// $("#map2d").removeClass("zIndex1")
// $(".ol-control")[0].style.bottom = ".5em"
// $(".ol-zoom").css("top", '')
// } else {
// this.$changeComponentShow(".tongbu", false)
// // $("#" + dom)[0].removeEventListener("click", this.callback, {capture: true})
// $("#earth").removeClass("halfEarth")
// $("#map2d").addClass("zIndex1")
// }
/* this.$changeComponentShow(".tongbu", true)
this.halfEarth = !this.halfEarth
console.log(this.halfEarth)
if (this.halfEarth) {
$("#earth").addClass("halfEarth")
$("#map2d").addClass("halfEarth")
$("#map2d")[0].style.left = "50%"
// window.map2d = new YJMap.Map("map2d")
/!* new YJMap.Obj.Tms(map2d, {
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer',
})*!/
/!* const projection = new ol.proj.Projection({
code: 'EPSG:4326',
extent: [-180, -90, 180, 90],
metersPerUnit: 2 * Math.PI * 6378137 / 360
})
let GGLWLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
attributions:
'Tiles © <a href="https://services.arcgisonline.com/ArcGIS/' +
'rest/services/World_Topo_Map/MapServer">ArcGIS</a>',
url:
'https://server.arcgisonline.com/ArcGIS/rest/services/' +
'World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
}),
/!* source: new ol.source.XYZ({
url: "http://t4.tianditu.com/DataServer?T=vec_c&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d"
}),
visible: false*!/
})
window.Map = new ol.Map({
target: "map2d",
layers: [
GGLWLayer
],
view: new ol.View({
center: [106.814931000, 34.945231000, 16000],
projection: projection,
minZoom: 4,
maxZoom: 21,
// extent : maxExtent, //限定到地图视图拖动范围
zoom: 5 // 地图初始化的缩放级别
})
})*!/
$(".ol-control")[0].style.bottom = ".5em"
$(".ol-zoom").css("top", '')
} else {
this.$changeComponentShow(".tongbu", false)
this.earthsDom.forEach(dom => {
$("#" + dom)[0].removeEventListener("click", this.callback, {capture: true})
$("#" + dom).removeClass("halfEarth")
$("#" + dom).removeClass("selectedEarthCss")
})
// window._entityMap = window.left_entityMap
// window.Earth1 = window.Earth
// window.Earths.earth.destroy()
// window.map2d.map.setTarget(null);
// window.map2d.map.dispose();
// $("#map2d").empty();
// window.Earths = null
// window._rightMap.clear()
}*/
},
testglb() {
// let rocketPrimitive: Cesium.Model
let position = Cesium.Cartesian3.fromDegrees(
106.31598580143364,
29.62610729142745,
264.2444551526038
);
const hpRoll = new Cesium.HeadingPitchRoll();
const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
"north",
"west"
);
const rocketPrimitive = window.Earth1.earth._viewer.scene.primitives.add(
Cesium.Model.fromGltf({
url: "https://assets.agi.com/models/launchvehicle.glb",
modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
position,
hpRoll,
Cesium.Ellipsoid.WGS84,
fixedFrameTransform
),
minimumPixelSize: 128,
})
);
/*rocketPrimitive.setArticulationStage( //对应属性改变参数值
'SRBFlames Size',
1
);
rocketPrimitive.applyArticulations(); //使得修改的属性生效*/
window.rocketPrimitive = rocketPrimitive;
},
},
};
export default test;

View File

@ -0,0 +1,223 @@
import { request,request_get } from "@/utils/request";
//人员管理
export function getPeopleList(params) {
return /*new Promise()*/ request({
url: "/api/v1/patrol/list",
method: "get",
params
});
}
export function peopleAdd(data) {
return /*new Promise()*/ request({
url: "/api/v1/patrol/add",
method: "post",
data
});
}
export function peopleDelete(data) {
return /*new Promise()*/ request({
url: "/api/v1/patrol/del",
method: "post",
data
});
}
export function peopleEdit(data) {
return /*new Promise()*/ request({
url: "/api/v1/patrol/edit",
method: "post",
data
});
}
//上传头像
export function singleImg(data) {
return /*new Promise()*/ request({
url: "/api/v1/patrol/singleImg",
method: "post",
data
});
}
//区域管理
//添加地区
export function areaAdd(data) {
return /*new Promise()*/ request({
url: "/api/v1/area/add",
method: "post",
data
});
}
//地区列表
export function areaList(query) {
return /*new Promise()*/ request({
url: "/api/v1/area/list",
method: "get",
params: query
});
}
//删除地区
export function areaDel(data) {
return /*new Promise()*/ request({
url: "/api/v1/area/del",
method: "post",
data
});
}
//编辑
export function areaEdit(data) {
return /*new Promise()*/ request({
url: "/api/v1/area/edit",
method: "post",
data
});
}
let requestCallback = (res, cb, notice = true) => {
console.log("requestCallback", res);
if ([0, 200].includes(res.code)) {
if (notice) $root_home.$message.success("操作成功");
cb(res.data);
} else {
$root_home.$message.error(res.message);
cb("error");
}
};
//设备管理
//列表
export function deviceDataList(params,cb) {
/* return /!*new Promise()*!/ request({
url: "/api/v1/deviceData/list",
method: "get",
params
});*/
request_get("/api/v1/deviceData/list", params).then(res => {
requestCallback(res, cb, false);
});
}
//添加设备
export function deviceDataAdd(data) {
return /*new Promise()*/ request({
url: "/api/v1/deviceData/add",
method: "post",
data
});
}
//编辑设备
export function deviceDataEdit(data) {
return /*new Promise()*/ request({
url: "/api/v1/deviceData/edit",
method: "post",
data
});
}
//更新资源名称和资源自定义参数
export function updateInfo(data) {
return /*new Promise()*/ request({
url: "/api/v1/source/update-info",
method: "post",
data
});
}
//根据地区获取id视频
export function listByAreaId(params) {
return /*new Promise()*/ request({
url: "/api/v1/channelData/listByAreaId",
method: "get",
params: params
});
}
//实时查询车流量
export function selectFlow(data) {
return /*new Promise()*/ request({
url: "/api/v1/deviceData/selectFlow",
method: "post",
data
});
}
//同步资源
export function sync() {
return /*new Promise()*/ request({
url: "/api/v1/source/tongbu",
method: "post"
});
}
//添加摄像头
export function cameraDataAdd(data) {
return /*new Promise()*/ request({
url: "/api/v1/cameraData/add",
method: "post",
data
});
}
//编辑摄像头
export function cameraDataEdit(data) {
return /*new Promise()*/ request({
url: "/api/v1/cameraData/edit",
method: "post",
data
});
}
//删除摄像头
export function cameraDatadel(data) {
return /*new Promise()*/ request({
url: "/api/v1/cameraData/del",
method: "post",
data
});
}
//获取摄像头列表
export function cameraDataList(params,cb) {
/* return /!*new Promise()*!/ request({
url: "/api/v1/cameraData/list",
method: "get",
params
});*/
request_get("/api/v1/cameraData/list", params).then(res => {
requestCallback(res, cb, false);
});
}
//开启摄像头
export function start(data) {
return /*new Promise()*/ request({
url: "/api/v1/cameraData/start",
method: "post",
data
});
}
//关闭摄像头
export function stops(params) {
return /*new Promise()*/ request({
url: "/api/v1/cameraData/stop",
method: "get",
params
});
}
//获取摄像头详情
export function getById(params,cb) {
/*return /!*new Promise()*!/ request({
url: "/api/v1/cameraData/getById",
method: "get",
params
});*/
request_get("/api/v1/cameraData/getById", params).then(res => {
requestCallback(res, cb, false);
});
}
//获取摄像头详情
export function uploadSingle(data) {
return /*new Promise()*/ request({
url: "/api/v1/cameraData/excelAdd",
method: "post",
data
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -0,0 +1,101 @@
<script>
import title from '../../../assets/title.png'
import table from '../../../assets/table.png'
export default {
name: "onDuty",
props:{
text:String,
required:true
},
data(){
return{
title,
table
}
}
}
</script>
<template>
<div class="onDuty">
<img :src="title" alt="" class="icon-img">
<span class="title">{{text}}</span>
<div style="height: 10px"></div>
<img :src="table" alt="">
<table class="table">
<tr>
<td>姓名</td>
<td>职务</td>
<td>电话</td>
</tr>
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
</table>
</div>
</template>
<style scoped lang="scss">
@keyframes rowup {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, -307px, 0);
transform: translate3d(0, -307px, 0);
}
}
.onDuty{
margin-top: 10px;
position: relative;
color: white;
.icon-img{
width: 100%;
height: 100%;
}
.title{
position: absolute;
color:rgb(192,220,255);
font-size: 20px;
top:3px;
left:30px;
font-weight: 600;
}
.table{
width:365px;
text-align: center;
position: absolute;
top:44px;
border: 2px solid rgb(9,197,193);
border-collapse: collapse;
table-layout: fixed;
overflow: scroll;
height: 100px;
tr {
border: 2px solid rgb(9,197,193);
border-left: none;
border-right: none;
}
tr :nth-child(n+1){
height: 30px;
}
td{
border:none;
}
}
}
</style>

View File

@ -0,0 +1,142 @@
<script>
import title from "../../../assets/title.png";
import table from "../../../assets/table.png";
export default {
name: "onDuty",
props: {
text: String,
value: Array
},
data() {
return {
title,
table
};
},
methods: {
addKeyFrames() {
const scroll = document.getElementById("scroll");
const height =
scroll.children.length * (scroll.children[0].offsetHeight || 20) + 10;
const style = document.createElement("style");
style.type = "text/css";
const keyFrames = `
@-webkit-keyframes rowup2 {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, ${height}px, 0);
transform: translate3d(0, -${height}px, 0);
}
}
@keyframes rowup2 {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, ${height}px, 0);
transform: translate3d(0, -${height}px, 0);
}
}`;
style.innerHTML = keyFrames;
document.getElementsByTagName("head")[0].appendChild(style);
}
},
mounted() {
if (this.value.length > 3) {
setTimeout(() => {
this.addKeyFrames();
}, 2000);
}
}
};
</script>
<template>
<div class="onDuty">
<img :src="title" alt="" class="icon-img" />
<span class="title">{{ text }}</span>
<div style="height: 10px"></div>
<img :src="table" alt="" />
<table class="table">
<tr>
<td>姓名</td>
<td>职务</td>
<td>电话</td>
</tr>
</table>
<div class="scroll" id="scroll" v-if="value">
<div class="item" v-for="item in value" :key="item.ID">
<el-row>
<el-col :span="8"
><div class="grid-content bg-purple">{{ item.name }}</div></el-col
>
<el-col :span="8"
><div class="grid-content bg-purple-light">
{{ item.positions || "" }}
</div></el-col
>
<el-col :span="8"
><div class="grid-content bg-purple">
{{ item.phone || "" }}
</div></el-col
>
</el-row>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.grid-content {
display: flex;
justify-content: center;
}
.onDuty {
margin-top: 10px;
position: relative;
color: white;
.icon-img {
width: 100%;
height: 100%;
}
.title {
position: absolute;
color: rgb(192, 220, 255);
font-size: 20px;
top: 3px;
left: 30px;
font-weight: 600;
}
.table {
width: 365px;
text-align: center;
position: absolute;
top: 44px;
line-height: 20px;
border: 2px solid rgb(9, 197, 193);
border-bottom: none;
tr {
border: none;
}
}
.scroll {
position: absolute;
top: 74px;
height: 89px;
width: 365px;
overflow: hidden;
}
.item {
margin-top: 2px;
animation: 10s rowup2 linear infinite normal;
height: 20px;
border: 2px solid rgb(9, 197, 193);
}
}
</style>

View File

@ -0,0 +1,122 @@
<script>
import title from "../../../assets/title.png";
import table from "../../../assets/List.png";
export default {
name: "onDutyOf",
props:{
text:String,
value:Array,
},
data(){
return{
title,
table,
}
},
methods:{
addKeyFrames(){
const scroll = document.getElementById('marquee')
const height = (scroll.childElementCount * (scroll.children[0].offsetHeight || 20)) + 20
const style = document.createElement('style');
style.type = 'text/css';
const keyFrames = `
@-webkit-keyframes rowup {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, ${height}px, 0);
transform: translate3d(0, -${height}px, 0);
}
}
@keyframes rowup {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
100% {
-webkit-transform: translate3d(0, ${height}px, 0);
transform: translate3d(0, -${height}px, 0);
}
}`;
style.innerHTML = keyFrames
document.getElementsByTagName('head')[0].appendChild(style);
}
},
mounted() {
if(this.value.length > 3){
setTimeout(()=>{this.addKeyFrames()},2000)
}
}
}
</script>
<template>
<div class="onDutyOf">
<img :src="title" alt="" class="icon-img">
<span class="title">{{text}}</span>
<div style="height: 10px"></div>
<div class="scroll" id="marquee">
<div style="position: relative;" v-for="item in value " :key="item.ID">
<img :src="table" alt="">
<p class="info">姓名{{item.name ||' ' }}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;电话{{item.phone ||' '}}</p>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.onDutyOf{
position: relative;
color: white;
top:100px;
.scroll{
height: 99px;
overflow: hidden;
div{
animation: 10s rowup linear infinite normal;
}
}
.info{
position: absolute;
left: 20px;
top:-9px;
}
.icon-img{
width: 100%;
height: 100%;
}
.title{
position: absolute;
color:rgb(192,220,255);
font-size: 20px;
top:3px;
left:30px;
font-weight: 600;
}
.table{
width:365px;
text-align: center;
position: absolute;
top:44px;
border: 2px solid rgb(9,197,193);
border-collapse: collapse;
table-layout: fixed;
tr {
border: 2px solid rgb(9,197,193);
border-left: none;
border-right: none;
}
tr :nth-child(n+1){
height: 30px;
}
td{
border:none;
}
}
}
</style>

View File

@ -0,0 +1,61 @@
<script>
import title from '../../../assets/title.png'
export default {
name: "photoWall",
props:{
text:String,
value:Object,
},
data(){
return{
title
}
}
}
</script>
<template>
<div class="photoWall" v-if="value">
<img :src="title" alt="" class="icon-img">
<span class="title">{{text}}</span>
<div style="height: 10px"></div>
<img :src="value.imageUrl ||' '" alt="" class="img">
<div class="content">
<p>姓名{{ value.name || ' ' }}</p>
<p>职务{{ value.positions ||' ' }}</p>
<p>电话{{ value.phone||' ' }}</p>
</div>
</div>
</template>
<style scoped lang="scss">
.photoWall{
margin-top: 10px;
position: relative;
color: white;
.icon-img{
width: 100%;
height: 100%;
}
.title{
position: absolute;
color:rgb(192,220,255);
font-size: 20px;
top:3px;
left:30px;
font-weight: 600;
}
.img{
height: 85px;
width: 70px;
object-fit: cover;
}
.content{
position: absolute;
font-size: 17px;
left: 90px;
font-weight: 500;
top:25px;
}
}
</style>

View File

@ -0,0 +1,86 @@
<script>
import photoWall from "./components/photoWall.vue";
import onDuty from "./components/onDuty.vue";
import onDutyOf from "./components/onDutyOf.vue";
import { getPeopleList } from "../../api";
export default {
name: "leftBar",
components: {
photoWall,
onDuty,
onDutyOf
},
data() {
return {
peopleDataList: [],
weatherInfo: {},
//值班领导
List0: [],
// 1值班科长
List1: [],
//2值班长
List2: [],
//3值班员
List3: [],
// 4大队值班
List4: []
};
},
methods: {
async getList() {
const res = await getPeopleList({
page: 1,
pageSize: 9999,
positionType: 1
});
if (res.code === 0) {
const list = res.data.list;
this.peopleDataList = list;
this.List0 = list.filter(item => {
return item.patrolType === "0";
});
this.List1 = list.filter(item => {
return item.patrolType === "1";
});
this.List2 = list.filter(item => {
return item.patrolType === "2";
});
this.List3 = list.filter(item => {
return item.patrolType === "3";
});
this.List4 = list.filter(item => {
return item.patrolType === "4";
});
}
}
},
mounted() {
this.getList();
}
};
</script>
<template>
<div class="left-bar">
<div style="width: 380px;margin-left: 20px;margin-top: 110px">
<photoWall text="值班领导" :value="List0[0]" />
<photoWall text="值班领导" :value="List0[1] || {}" />
<photoWall text="值班科长" :value="List1[0] || {}" />
<photoWall text="值班长" :value="List2[0] || {}" />
<onDuty text="值班员" :value="List3 || []"></onDuty>
<onDutyOf text="大队值班" :value="List4 || []"></onDutyOf>
</div>
</div>
</template>
<style scoped lang="scss">
.left-bar {
display: none;
position: absolute;
left: 0px;
top: 0px;
height: 100vh;
width: 500px;
background: url("../../assets/lbg.png") repeat-y;
}
</style>

View File

@ -0,0 +1,223 @@
<script>
import { areaAdd, areaDel, areaEdit, areaList } from "../../../api";
export default {
name: "camera",
data() {
return {
page: {
page: 1,
pageSize: 10,
total: 0
},
dialogVisible: false,
addForm: {},
areaList: [],
editdialogVisible: false,
edit: {}
};
},
methods: {
show() {
this.dialogVisible = true;
this.$changeComponentShow("#modal", true, "z-index:12");
},
getList() {
const param = { ...this.page };
delete param.total;
areaList(param).then(res => {
if (res.code === 0) {
this.areaList = res.data.list;
this.page.total = res.data.total;
}
});
},
submit() {
if (
this.addForm.name === "" ||
this.addForm.name === undefined ||
this.addForm.name === null
) {
this.$message({
message: "请输入名称",
type: "warning"
});
return;
}
areaAdd(this.addForm).then(res => {
if (res.code === 0) {
this.$message({
message: "添加成功",
type: "success"
});
this.dialogVisible = false;
this.getList();
this.$changeComponentShow("#modal", false, "z-index:12");
}
});
},
showEdit(row) {
this.editdialogVisible = true;
this.edit = { ...row, name: row.area_name };
this.$changeComponentShow("#modal", true, "z-index:12");
},
submitEdit() {
if (
this.edit.name === "" ||
this.edit.name === undefined ||
this.edit.name === null
) {
this.$message({
message: "请输入名称",
type: "warning"
});
return;
}
areaEdit(this.edit).then(res => {
if (res.code === 0) {
this.$message({
message: "已保存",
type: "success"
});
this.editdialogVisible = false;
this.getList();
this.$changeComponentShow("#modal", true, "z-index:12");
}
});
},
deletePeople(row) {
this.$confirm("此操作将永久删除, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
const res = await areaDel({ id: row.ID });
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!"
});
this.getList();
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
},
handleSizeChange(value) {
this.page.pageSize = value;
this.getList();
},
hadleCurrentChange(value) {
this.page.page = value;
this.getList();
},
cancel() {
this.dialogVisible = false;
this.$changeComponentShow("#modal", false, "z-index:12");
},
cancel1() {
this.editdialogVisible = false;
this.$changeComponentShow("#modal", false, "z-index:12");
},
close(done) {
this.$changeComponentShow("#modal", false, "z-index:12");
done();
}
},
mounted() {
this.getList();
}
};
</script>
<template>
<div class="camera">
<el-dialog
:visible.sync="dialogVisible"
title="添加地区"
:modal="false"
width="90%"
center
:before-close="close"
>
<el-form label-width="100px" :model="addForm" style="max-width: 460px">
<el-form-item label="名称">
<el-input v-model="addForm.name" />
</el-form-item>
</el-form>
<template #footer>
<span class="footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submit">
确定
</el-button>
</span>
</template>
</el-dialog>
<el-dialog
:visible.sync="editdialogVisible"
title="编辑"
:modal="false"
width="90%"
center
:before-close="close"
>
<el-form label-width="100px" :model="edit" style="max-width: 460px">
<el-form-item label="名称">
<el-input v-model="edit.name" />
</el-form-item>
</el-form>
<template #footer>
<span class="footer">
<el-button @click="cancel1">取消</el-button>
<el-button type="primary" @click="submitEdit">
确定
</el-button>
</span>
</template>
</el-dialog>
<div style="display: flex">
<el-button type="primary" @click="show" size="mini">添加地区</el-button>
</div>
<el-table
:data="areaList"
style="width: 100%;padding-left: 10px;margin-top: 10px"
>
<el-table-column prop="area_name" label="名称" width="180">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" @click="showEdit(scope.row)">编辑</el-button>
<el-button type="text" danger @click="deletePeople(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<el-pagination
style="display: flex;justify-content: center"
@size-change="handleSizeChange"
@current-change="hadleCurrentChange"
:current-page="page.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
/>
</div>
</template>
<style scoped lang="scss">
.camera {
height: 100%;
width: 100%;
.footer {
display: flex;
justify-content: center;
}
}
</style>

View File

@ -0,0 +1,427 @@
<template>
<div>
<el-dialog :visible.sync="pDialogVisible" :modal="false" title="添加设备" width="100%" style="height: 600px;" center
:before-close="close">
<el-form label-width="100px" :model="addForm" :rules="peopleRules" ref="peopleFormRef">
<el-form-item label="名称" prop="cameraName">
<el-input v-model="addForm.cameraName" />
</el-form-item>
<el-form-item label="设备IP" prop="ip">
<el-input v-model="addForm.ip"></el-input>
</el-form-item>
<el-form-item label="设备端口" prop="port">
<el-input v-model="addForm.port"></el-input>
</el-form-item>
<el-form-item label="用户名" prop="userName">
<el-input v-model="addForm.userName"></el-input>
</el-form-item>
<el-form-item label="密码" prop="passWord">
<el-input v-model="addForm.passWord"></el-input>
</el-form-item>
<el-form-item label="设备类型" prop="type">
<el-select v-model="addForm.type" filterable placeholder="请选择">
<el-option label="海康" value="1"> </el-option>
<el-option label="大华" value="2"> </el-option>
<!-- <el-option label="手动录入" value="3"> </el-option> -->
</el-select>
</el-form-item>
<el-form-item v-if="addForm.type === '3'" label="视频流地址" prop="flvUrl">
<el-input v-model="addForm.flvUrl"></el-input>
</el-form-item>
<el-form-item label="通道号" prop="channel">
<el-input v-model="addForm.channel"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer" style="display: flex;justify-content: center">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submitProtal">
添加
</el-button>
</span>
</template>
</el-dialog>
<el-dialog :visible.sync="pEditDialogVisible" :modal="false" title="编辑" width="100%" style="height: 600px" center
:before-close="close">
<el-form label-width="100px" :model="editForm" :rules="peopleRules" ref="editFormRef">
<el-form-item label="名称" prop="cameraName">
<el-input v-model="editForm.cameraName" />
</el-form-item>
<el-form-item label="设备IP" prop="ip">
<el-input v-model="editForm.ip"></el-input>
</el-form-item>
<el-form-item label="设备端口" prop="port">
<el-input v-model="editForm.port"></el-input>
</el-form-item>
<el-form-item label="用户名" prop="userName">
<el-input v-model="editForm.userName"></el-input>
</el-form-item>
<el-form-item label="密码" prop="passWord">
<el-input v-model="editForm.passWord"></el-input>
</el-form-item>
<el-form-item label="设备类型" prop="type">
<el-select v-model="editForm.type" filterable placeholder="请选择">
<el-option label="海康" value="1"> </el-option>
<el-option label="大华" value="2"> </el-option>
<!-- <el-option label="手动录入" value="3"> </el-option> -->
</el-select>
</el-form-item>
<el-form-item v-if="editForm.type === '3'" label="视频流地址" prop="flvUrl">
<el-input v-model="editForm.flvUrl"></el-input>
</el-form-item>
<el-form-item label="通道号" prop="channel">
<el-input v-model="editForm.channel"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer" style="display: flex;justify-content: center">
<el-button @click="cancel1">取消</el-button>
<el-button type="primary" @click="editSubmit">
确定
</el-button>
</span>
</template>
</el-dialog>
<div style="display: flex;margin-bottom: 5px;">
<el-button type="primary" size="mini" @click="show">
<svg-icon icon-class="gcadd" style="width: 12px;height: 12px;" />
{{ $t("headerTitles.equipment.addEquipment") }}
</el-button>
<el-button type="primary" size="mini" @click="download">
<svg-icon icon-class="pl" style="width: 12px;height: 12px;" />
{{ $t("headerTitles.equipment.downloadEquipment") }}
</el-button>
<el-button type="primary" size="mini" @click="attachUpload" style="margin-left: 10px;">
<svg-icon icon-class="sbadd" style="width: 12px;height: 12px;" />
{{ $t("headerTitles.equipment.bulkImport") }}
</el-button>
</div>
<div class="equipmentTable">
<el-table :data="peopleDataList" style="width: 100%" max-height="250">
<el-table-column prop="cameraName" label="设备名称" width="100" align="center">
</el-table-column>
<el-table-column align="left" prop="deviceType" label="设备类型">
<template slot-scope="scope">
{{ statusTrans(scope.row.type) }}
</template>
</el-table-column>
<el-table-column align="left" prop="ip" label="设备IP" width="100">
</el-table-column>
<el-table-column align="left" prop="port" label="设备端口" width="100">
</el-table-column>
<el-table-column align="left" prop="userName" label="用户名" width="100">
</el-table-column>
<el-table-column align="left" prop="passWord" label="密码" width="100">
</el-table-column>
<el-table-column align="left" prop="channel" label="通道号" width="100">
</el-table-column>
<el-table-column align="left" prop="flvUrl" label="flv地址" width="200">
</el-table-column>
<el-table-column fixed="right" label="操作" width="auto" align="center">
<template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" danger @click="deletePeople(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- <el-table
:data="peopleDataList"
style="width: 100%;padding-left: 10px;margin-top: 10px"
>
<el-table-column prop="cameraName" label="设备名称" width="100">
</el-table-column>
<el-table-column prop="deviceType" label="设备类型">
<template slot-scope="scope">
{{ statusTrans(scope.row.type) }}
</template>
</el-table-column>
<el-table-column prop="ip" label="设备IP" width="100">
</el-table-column>
<el-table-column prop="port" label="设备端口" width="100">
</el-table-column>
<el-table-column prop="userName" label="用户名" width="100">
</el-table-column>
<el-table-column prop="passWord" label="密码" width="100">
</el-table-column>
<el-table-column prop="channel" label="通道号" width="100">
</el-table-column>
<el-table-column prop="flvUrl" label="flv地址" width="200">
</el-table-column>
<el-table-column label="操作" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" danger @click="deletePeople(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>-->
<el-pagination style="display: flex;justify-content: center" @size-change="handleSizeChange"
@current-change="hadleCurrentChange" :current-page="page.page" :page-sizes="[10, 20, 30, 40]"
:page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total" />
</div>
</div>
</template>
<script>
import {
areaList,
cameraDataAdd,
cameraDatadel,
cameraDataEdit,
cameraDataList,
peopleEdit,
uploadSingle,
singleImg,
} from "../../../api";
import { debounce } from "../../../utils";
import fs from "fs";
export default {
name: "equipment",
data() {
return {
page: {
page: 1,
pageSize: 10,
total: 0,
},
peopleRules: {
cameraName: [
{ required: true, message: "请输入名称", trigger: "blur" },
],
ip: [{ required: true, message: "请输入ip", trigger: "blur" }],
port: [
{ required: true, message: "请输入设备端口号", trigger: "blur" },
],
userName: [
{ required: true, message: "请输入用户名", trigger: "blur" },
],
passWord: [{ required: true, message: "请输入密码", trigger: "blur" }],
type: [{ required: true, message: "请选择设备类型", trigger: "blur" }],
},
pDialogVisible: false,
pEditDialogVisible: false,
editForm: {},
addForm: {
ip: "192.168.110.29",
port: "554",
userName: "admin",
channel: "1",
},
peopleDataList: [],
peopleImg: "",
areaLists: [],
};
},
methods: {
download() {
let serve = localStorage.getItem("service");
let p = "xlsx";
if (process.platform == "linux") {
p = "et";
}else{
p = "xlsx";
}
let url =
serve + "/static/excel/%E8%AE%BE%E5%A4%87%E6%A8%A1%E6%9D%BF." + p;
this.$sendElectronChanel("saveNetFile", {
title: "保存文件",
filename: "模板",
filters: [{ name: "保存文件", extensions: [p] }],
url,
});
this.$recvElectronChanel("saveNetFileRes", (e, key) => {
this.$message[key]("下载结束");
this.$removeElectronChanel("saveNetFileRes",(res)=>{
console.log(res);
});
});
// this.$recvElectronChanel("selectedFileItem", (e, path) => {
// console.log(e,path);
// /* fs.writeFile(path, dataBuffer, res => {
// console.log(res);
// });*/
// });
},
debounce,
//获取列表
getList() {
const param = { ...this.page };
delete param.total;
// const res = cameraDataList(param);
cameraDataList(param, (res) => {
this.peopleDataList = res.list;
this.page.total = res.total;
});
},
deletePeople(row) {
this.$confirm("确定删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
const res = await cameraDatadel({
id: row.ID,
});
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!",
});
this.getList();
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
submitProtal() {
this.$refs["peopleFormRef"].validate(async (valid) => {
if (valid) {
console.log(this.addForm);
if (
this.addForm.channel === undefined ||
this.addForm.channel === "" ||
this.addForm.channel === null
) {
this.addForm.channel = 1;
}
const res = await cameraDataAdd(this.addForm);
if (res.code === 50) {
this.$message.warning(res.message);
return;
}
if (res.code === 0) {
this.$message.success("添加成功");
this.pDialogVisible = false;
this.getList();
this.$changeComponentShow("#modal", false, "z-index:12");
}
} else {
console.log("error submit!!");
return false;
}
});
},
editSubmit() {
this.$refs["editFormRef"].validate(async (valid) => {
if (valid) {
const res = await cameraDataEdit(this.editForm);
if (res.code === 50) {
this.$message.warning(res.message);
return;
}
if (res.code === 0) {
this.$message.success("修改成功");
this.pEditDialogVisible = false;
this.getList();
this.$changeComponentShow("#modal", false, "z-index:12");
}
} else {
console.log("error submit!!");
return false;
}
});
},
handleSizeChange(value) {
this.page.pageSize = value;
this.getList();
},
hadleCurrentChange(value) {
this.page.page = value;
this.getList();
},
close(done) {
this.$changeComponentShow("#modal", false, "z-index:12");
done();
},
edit(row) {
this.editForm = JSON.parse(JSON.stringify(row));
this.editForm.areaId = +row.areaId;
this.imageUrl = row.imageUrl;
this.pEditDialogVisible = true;
this.$changeComponentShow("#modal", true, "z-index:12");
},
changeStatue: debounce(function (row) {
const data = { ...row };
data.positionType = "1";
peopleEdit(data).then((res) => {
if (res.code === 0) {
this.$message.success("修改成功");
this.getList();
this.$changeComponentShow("#modal", false, "z-index:12");
}
});
}, 500),
statusTrans(id) {
switch (id) {
case "1":
return "海康";
case "2":
return "大华";
case "3":
return "手动录入";
}
},
getAreaList() {
areaList({ page: 1, pageSize: 9999 }).then((res) => {
this.areaLists = res.data.list;
});
},
show() {
// this.getAreaList();
this.addForm = {
ip: "192.168.110.29",
port: "554",
userName: "admin",
channel: "1",
};
this.pDialogVisible = true;
this.$changeComponentShow("#modal", true, "z-index:12");
},
cancel() {
this.pDialogVisible = false;
this.addForm = {};
this.$changeComponentShow("#modal", false, "z-index:12");
},
cancel1() {
this.pEditDialogVisible = false;
this.$changeComponentShow("#modal", false, "z-index:12");
},
//批量导入
attachUpload() {
const input = document.createElement("input");
input.type = "file";
input.accept = ".xls,.xlsx";
input.click();
input.onchange = () => {
const file = input.files[0];
const formData = new FormData();
formData.append("file", file);
uploadSingle(formData).then((res) => {
if (res.code === 0) {
this.$message.success("导入成功");
this.getList();
}
});
};
},
},
mounted() {
// this.getAreaList();
this.getList();
},
};
</script>
<style lang="scss">
.el-form-item__label {
color: black;
}
</style>

View File

@ -0,0 +1,582 @@
<template>
<div class="equipment">
<div class="modelDialog" v-show="pDialogVisible">
<div class="modelDialog_title"> 添加设备 </div>
<span @click="close" class="close"></span>
<el-form label-width="100px" :model="addForm" :rules="peopleRules" ref="peopleFormRef">
<el-form-item label="名称" prop="cameraName">
<el-input v-model="addForm.cameraName" placeholder="请输入内容" clearable />
</el-form-item>
<el-form-item label="设备IP" prop="ip">
<el-input v-model="addForm.ip" placeholder="192.168.110.29" clearable></el-input>
</el-form-item>
<el-form-item label="设备端口" prop="port">
<el-input v-model="addForm.port" placeholder="554" clearable></el-input>
</el-form-item>
<el-form-item label="用户名" prop="userName">
<el-input v-model="addForm.userName" placeholder="admin" clearable></el-input>
</el-form-item>
<el-form-item label="密码" prop="passWord">
<el-input v-model="addForm.passWord" placeholder="请输入密码" show-password clearable></el-input>
</el-form-item>
<el-form-item label="设备类型" prop="type">
<el-select v-model="addForm.type" style="width: 100% !important;" filterable placeholder="请选择">
<el-option label="海康" value="1"> </el-option>
<el-option label="大华" value="2"> </el-option>
<el-option label="手动录入" value="3"> </el-option>
</el-select>
</el-form-item>
<el-form-item v-if="addForm.type === '3'" label="视频流地址" prop="flvUrl">
<el-input v-model="addForm.flvUrl" clearable></el-input>
</el-form-item>
<el-form-item label="通道号" prop="channel">
<el-input v-model="addForm.channel" placeholder="1" clearable></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer" style="display: flex;justify-content: center">
<el-button @click="cancel" type="primary" class="cancel-btn">取消</el-button>
<el-button type="primary" @click="submitProtal" class="confirm-btn">
确定
</el-button>
</span>
</div>
<div class="modelDialog" v-show="pEditDialogVisible">
<div class="modelDialog_title"> 编辑 </div>
<span @click="close1" class="close"></span>
<el-form label-width="100px" :model="editForm" :rules="peopleRules" ref="editFormRef">
<el-form-item label="名称" prop="cameraName">
<el-input v-model="editForm.cameraName" />
</el-form-item>
<el-form-item label="设备IP" prop="ip">
<el-input v-model="editForm.ip"></el-input>
</el-form-item>
<el-form-item label="设备端口" prop="port">
<el-input v-model="editForm.port"></el-input>
</el-form-item>
<el-form-item label="用户名" prop="userName">
<el-input v-model="editForm.userName"></el-input>
</el-form-item>
<el-form-item label="密码" prop="passWord">
<el-input v-model="editForm.passWord"></el-input>
</el-form-item>
<el-form-item label="设备类型" prop="type">
<el-select v-model="editForm.type" filterable style="width: 100% !important;" placeholder="请选择">
<el-option label="海康" value="1"> </el-option>
<el-option label="大华" value="2"> </el-option>
<el-option label="手动录入" value="3"> </el-option>
</el-select>
</el-form-item>
<el-form-item v-if="editForm.type === '3'" label="视频流地址" prop="flvUrl">
<el-input v-model="editForm.flvUrl"></el-input>
</el-form-item>
<el-form-item label="通道号" prop="channel">
<el-input v-model="editForm.channel"></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer" style="display: flex;justify-content: center">
<el-button type="primary" @click="cancel1">取消</el-button>
<el-button type="primary" @click="editSubmit"> 确定 </el-button>
</span>
</div>
<div style="display: flex;justify-content: space-between;" class="btns">
<div>
<el-button type="primary" size="mini" @click="show">
<svg-icon icon-class="gcadd" style="width: 12px;height: 12px;" />
{{ $t("headerTitles.equipment.addEquipment") }}
</el-button>
<el-button type="primary" size="mini" @click="download">
<svg-icon icon-class="pl" style="width: 12px;height: 12px;" />
{{ $t("headerTitles.equipment.downloadEquipment") }}
</el-button>
<el-button type="primary" size="mini" @click="attachUpload" style="margin-left: 10px;">
<svg-icon icon-class="sbadd" style="width: 12px;height: 12px;" />
{{ $t("headerTitles.equipment.bulkImport") }}
</el-button>
</div>
<el-input v-model="input" style="width: 200px;" size="small" placeholder="请输入内容"
suffix-icon="el-icon-search"></el-input>
</div>
<div class="equipmentTable">
<el-table border :data="peopleDataList" style="width: 100%;" max-height="300">
<el-table-column prop="cameraName" label="设备名称" width="100" align="center">
</el-table-column>
<el-table-column align="center" prop="deviceType" label="设备类型">
<template slot-scope="scope">
{{ statusTrans(scope.row.type) }}
</template>
</el-table-column>
<el-table-column align="center" prop="ip" label="设备IP" width="100">
</el-table-column>
<el-table-column align="center" prop="port" label="设备端口" width="100">
</el-table-column>
<el-table-column align="center" prop="userName" label="用户名" width="100">
</el-table-column>
<el-table-column align="center" prop="passWord" label="密码" width="100">
</el-table-column>
<el-table-column align="center" prop="channel" label="通道号" width="100">
</el-table-column>
<el-table-column align="center" prop="flvUrl" label="flv地址" width="200">
</el-table-column>
<!-- fixed="right" -->
<el-table-column label="操作" align="center" width="200">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="edit(scope.row)">编辑</el-button>
<el-button type="primary" size="mini" danger @click="deletePeople(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination style="display: flex;justify-content: center" @size-change="handleSizeChange"
@current-change="hadleCurrentChange" :current-page="page.page" :page-sizes="[10, 20, 30, 40]"
:page-size="page.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="page.total" />
</div>
</div>
</template>
<script>
import {
areaList,
cameraDataAdd,
cameraDatadel,
cameraDataEdit,
cameraDataList,
peopleEdit,
uploadSingle,
singleImg,
} from "../../../api";
import { debounce } from "../../../utils";
import fs from "fs";
export default {
name: "equipment",
data() {
return {
page: {
page: 1,
pageSize: 10,
total: 0,
},
peopleRules: {
cameraName: [
{ required: true, message: "请输入名称", trigger: "blur" },
],
ip: [{ required: true, message: "请输入ip", trigger: "blur" }],
port: [
{ required: true, message: "请输入设备端口号", trigger: "blur" },
],
userName: [
{ required: true, message: "请输入用户名", trigger: "blur" },
],
passWord: [{ required: true, message: "请输入密码", trigger: "blur" }],
type: [{ required: true, message: "请选择设备类型", trigger: "blur" }],
},
pDialogVisible: false,
pEditDialogVisible: false,
editForm: {},
addForm: {
ip: "192.168.110.29",
port: "554",
userName: "admin",
channel: "1",
},
peopleDataList: [],
peopleImg: "",
areaLists: [],
input: "",
};
},
methods: {
download() {
let serve = localStorage.getItem("service");
let p = "xlsx";
process.platform == "linux" ? (p = "et") : "";
let url =
serve + "/static/excel/%E8%AE%BE%E5%A4%87%E6%A8%A1%E6%9D%BF." + p;
this.$sendElectronChanel("saveNetFile", {
title: "保存文件",
filename: "模板",
filters: [{ name: "保存文件", extensions: [p] }],
url,
});
this.$recvElectronChanel("saveNetFileRes", (e, key) => {
this.$message[key]("下载结束");
this.$removeElectronChanel("saveNetFileRes");
});
// this.$recvElectronChanel("selectedFileItem", (e, path) => {
// console.log(e,path);
// /* fs.writeFile(path, dataBuffer, res => {
// console.log(res);
// });*/
// });
},
debounce,
//获取列表
getList() {
const param = { ...this.page };
delete param.total;
// const res = cameraDataList(param);
cameraDataList(param, (res) => {
this.peopleDataList = res.list;
this.page.total = res.total;
});
},
deletePeople(row) {
this.$confirm("确定删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
const res = await cameraDatadel({
id: row.ID,
});
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!",
});
this.getList();
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
submitProtal() {
this.$refs["peopleFormRef"].validate(async (valid) => {
if (valid) {
console.log(this.addForm);
if (
this.addForm.channel === undefined ||
this.addForm.channel === "" ||
this.addForm.channel === null
) {
this.addForm.channel = 1;
}
const res = await cameraDataAdd(this.addForm);
if (res.code === 50) {
this.$message.warning(res.message);
return;
}
if (res.code === 0) {
this.$message.success("添加成功");
this.pDialogVisible = false;
this.getList();
this.$changeComponentShow("#modal", false, "z-index:12");
}
} else {
console.log("error submit!!");
return false;
}
});
},
editSubmit() {
this.$refs["editFormRef"].validate(async (valid) => {
if (valid) {
const res = await cameraDataEdit(this.editForm);
if (res.code === 50) {
this.$message.warning(res.message);
return;
}
if (res.code === 0) {
this.$message.success("修改成功");
this.pEditDialogVisible = false;
this.getList();
this.$changeComponentShow("#modal", false, "z-index:12");
}
} else {
console.log("error submit!!");
return false;
}
});
},
handleSizeChange(value) {
this.page.pageSize = value;
this.getList();
},
hadleCurrentChange(value) {
this.page.page = value;
this.getList();
},
close() {
this.pDialogVisible = false;
},
close1() {
this.pEditDialogVisible = false;
},
edit(row) {
this.editForm = JSON.parse(JSON.stringify(row));
this.editForm.areaId = +row.areaId;
this.imageUrl = row.imageUrl;
this.pEditDialogVisible = true;
},
changeStatue: debounce(function (row) {
const data = { ...row };
data.positionType = "1";
peopleEdit(data).then((res) => {
if (res.code === 0) {
this.$message.success("修改成功");
this.getList();
}
});
}, 500),
statusTrans(id) {
switch (id) {
case "1":
return "海康";
case "2":
return "大华";
case "3":
return "手动录入";
}
},
getAreaList() {
areaList({ page: 1, pageSize: 9999 }).then((res) => {
this.areaLists = res.data.list;
});
},
show() {
// this.getAreaList();
this.addForm = {
ip: "192.168.110.29",
port: "554",
userName: "admin",
channel: "1",
};
this.pDialogVisible = true;
},
cancel() {
this.pDialogVisible = false;
this.addForm = {};
},
cancel1() {
this.pEditDialogVisible = false;
},
//批量导入
attachUpload() {
const input = document.createElement("input");
input.type = "file";
input.accept = ".xls,.xlsx";
input.click();
input.onchange = () => {
const file = input.files[0];
const formData = new FormData();
formData.append("file", file);
uploadSingle(formData).then((res) => {
if (res.code === 0) {
this.$message.success("导入成功");
this.getList();
}
});
};
},
},
mounted() {
// this.getAreaList();
this.getList();
},
};
</script>
<style lang="scss">
.modelDialog {
position: fixed;
left: 20%;
top: -10%;
width: 515px;
height: 600px;
z-index: 3000;
background: linear-gradient(45deg, rgba(0, 255, 255, .3) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.6);
padding: 20px 30px;
border: 1.5px solid;
/* 设置边框宽度 */
border-image: linear-gradient(to bottom, #00FFFF, #00C8FF) 1;
/* 应用线性渐变边框 */
backdrop-filter: blur(2px);
.close {
position: absolute;
top: -1px;
right: -1px;
display: inline-block;
width: 30px;
height: 30px;
background: rgba(0, 255, 255, 0.5);
line-height: 30px;
text-align: center;
border-radius: 0 0 0 30px;
color: #fff;
cursor: pointer;
}
.modelDialog_title {
font-family: 'alimamashuheiti';
font-size: 18px;
font-weight: 700;
color: rgba(255, 255, 255, 1);
padding-bottom: 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
margin-bottom: 20px;
}
.el-form-item__label {
color: #fff;
}
.el-dialog .el-form-item__label {
color: #00ffff;
}
.el-input__inner {
background-color: rgb(0, 0, 0, .5);
border: 1px solid rgba(0, 255, 255, .5);
color: #fff;
}
.el-select .el-input.is-focus .el-input__inner {
border-color: #00ffff;
}
.el-button--primary {
background-color: rgb(0, 255, 255, .2);
border: 1px solid rgb(0, 255, 255, .5);
color: #fff;
}
.el-button--primary.is-active,
.el-button--primary:active,
.el-button--primary:focus,
.el-button--primary:hover {
border-color: rgb(0, 255, 255, 1);
}
// 添加关闭按钮样式
.el-dialog__headerbtn .el-dialog__close {
color: #00ffff;
}
}
.modelDialog::after {
display: block;
position: absolute;
content: "";
left: -1.5px;
top: -6px;
width: 70.5px;
height: 6px;
opacity: 1;
background: rgba(0, 255, 255, 1);
clip-path: polygon(0 0, calc(100% - 3px) 0, 100% 6px, 0 6px);
z-index: 3000;
}
.btns {
margin-bottom: 10px;
.el-button--primary {
background: rgba(0, 255, 255, 0.2);
border: 1px solid rgba(0, 255, 255, 0.5);
}
.el-button--primary {
color: #fff;
}
.el-input__inner {
background: transparent;
border: 1px solid rgba(0, 255, 255, 0.5);
}
}
.equipmentTable {
.el-button--primary {
background-color: rgb(0, 255, 255, .2);
border: 1px solid rgb(0, 255, 255, .5);
color: #fff;
}
.el-button--primary.is-active,
.el-button--primary:active,
.el-button--primary:focus,
.el-button--primary:hover {
border-color: rgb(0, 255, 255, 1);
}
.el-table,
.el-table tr,
.el-table tr th {
background: transparent;
}
.el-table td.el-table__cell,
.el-table th.el-table__cell.is-leaf {
border-color: #00ffff;
}
.el-table--border::after,
.el-table--group::after,
.el-table::before {
background: transparent;
}
/**改变表头背景颜色 */
.el-table thead.is-group th.el-table__cell {
background: #00ffff;
}
/**改变边框颜色*/
.el-table--border,
.el-table--group {
border: 1px solid rgba(0, 255, 255, 0.5) !important;
}
/**改变表格内竖线颜色*/
.el-table--border td,
.el-table--border th,
.el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed {
border-right: 1px solid rgba(0, 255, 255, 0.5) !important;
color: #fff;
}
/**改变合并单元格中横线颜色 */
.el-table--border th.el-table__cell {
border-bottom: 1px solid rgba(0, 255, 255, 0.5);
color: #fff;
}
/**改变表格内常规行线颜色*/
.el-table td,
.el-table th.is-leaf {
border-bottom: 1px solid rgba(0, 255, 255, 0.5) !important;
}
.el-input__inner {
background: transparent;
color: #fff;
}
.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
background: #00ffff4a;
}
// 美化滚动条
.el-table__body-wrapper::-webkit-scrollbar {
width: 5px !important;
height: 5px !important;
}
.el-table__body-wrapper::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #00ffff !important;
}
.el-table__body-wrapper::-webkit-scrollbar-track {
border-radius: 5px;
background-color: transparent !important;
}
}
</style>

View File

@ -0,0 +1,393 @@
<script>
import {
getPeopleList,
peopleAdd,
peopleDelete,
peopleEdit,
singleImg
} from "../../../api";
import { debounce } from "../../../utils";
export default {
name: "people",
data() {
return {
page: {
page: 1,
pageSize: 10,
total: 10
},
peopleRules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{
pattern: /^1[3456789]\d{9}$/,
message: "手机号码格式不正确",
trigger: "blur"
}
],
patrolType: [
{ required: true, message: "请选择值班类型", trigger: "blur" }
]
},
pDialogVisible: false,
pEditDialogVisible: false,
editForm: {},
addForm: {},
peopleDataList: [],
peopleImg: "",
imageUrl: ""
};
},
methods: {
show() {
this.pDialogVisible = true;
this.$changeComponentShow("#modal", true, "z-index:12");
},
debounce,
//获取列表
async getList() {
const param = { ...this.page };
delete param.total;
const res = await getPeopleList(param);
if (res.code === 0) {
this.peopleDataList = res.data.list;
this.page.total = res.data.total;
}
},
deletePeople(row) {
this.$confirm("确定删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
const res = await peopleDelete({
id: row.ID
});
if (res.code === 0) {
this.$message({
type: "success",
message: "删除成功!"
});
this.getList();
}
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
},
//获取值班列表
uploadPictrue(id) {
//上传照片
const input = document.createElement("input");
input.type = "file";
input.accept = "image/*";
input.click();
input.onchange = () => {
const file = input.files[0];
const formData = new FormData();
formData.append("file", file);
singleImg(formData).then(res => {
if (res.code === 0) {
this.$message.success("上传成功");
this.imageUrl = res.data.fullPath;
if (id === 1) {
this.editForm.imageUrl = res.data.fullPath;
} else {
this.addForm.imageUrl = res.data.fullPath;
}
}
});
};
},
//添加值班
submitProtal() {
this.$refs["peopleFormRef"].validate(async valid => {
if (valid) {
this.addForm.positionType = "0";
const res = await peopleAdd(this.addForm);
if (res.code === 0) {
this.$message.success("添加成功");
this.pDialogVisible = false;
this.addForm = {};
this.getList();
this.$changeComponentShow("#modal", true, "z-index:12");
}
} else {
console.log("error submit!!");
return false;
}
});
},
editSubmit() {
this.$refs["editFormRef"].validate(async valid => {
if (valid) {
const res = await peopleEdit(this.editForm);
if (res.code === 0) {
this.$message.success("添加成功");
this.pEditDialogVisible = false;
this.editForm = {};
this.$changeComponentShow("#modal", false, "z-index:12");
this.getList();
}
} else {
console.log("error submit!!");
return false;
}
});
},
handleSizeChange(value) {
this.page.pageSize = value;
this.getList();
},
hadleCurrentChange(value) {
this.page.page = value;
this.getList();
},
edit(row) {
this.editForm = JSON.parse(JSON.stringify(row));
this.imageUrl = row.imageUrl;
this.pEditDialogVisible = true;
this.$changeComponentShow("#modal", true, "z-index:12");
},
cancel() {
this.pDialogVisible = false;
this.addForm = {};
this.imageUrl = "";
this.$changeComponentShow("#modal", false, "z-index:12");
},
cancel1() {
this.pEditDialogVisible = false;
this.imageUrl = "";
this.$changeComponentShow("#modal", false, "z-index:12");
},
changeStatue: debounce(function(row) {
const data = { ...row };
data.positionType = "1";
peopleEdit(data).then(res => {
if (res.code === 0) {
this.$message.success("修改成功");
this.$changeComponentShow("#modal", true, "z-index:12");
}
});
}, 500),
statusTrans(id) {
switch (id) {
case "0":
return "值班领导";
case "1":
return "值班科长";
case "2":
return "值班长";
case "3":
return "值班员";
case "4":
return "大队值班";
}
},
close(done) {
this.$changeComponentShow("#modal", false, "z-index:12");
done();
}
},
mounted() {
this.getList();
}
};
</script>
<template>
<div>
<el-dialog
:before-close="close"
:visible.sync="pDialogVisible"
:modal="false"
title="添加值班人员"
width="100%"
style="height: 600px"
center
>
<el-form
label-width="100px"
:model="addForm"
:rules="peopleRules"
ref="peopleFormRef"
>
<el-form-item label="名称" prop="name">
<el-input v-model="addForm.name" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="addForm.phone" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="addForm.remark" />
</el-form-item>
<el-form-item label="值班类型" prop="patrolType">
<el-select v-model="addForm.patrolType">
<el-option value="0" label="值班领导"></el-option>
<el-option value="1" label="值班科长"></el-option>
<el-option value="2" label="值班长"></el-option>
<el-option value="3" label="值班员"></el-option>
<el-option value="4" label="大队值班"></el-option>
</el-select>
</el-form-item>
<el-form-item label="职务">
<el-input v-model="addForm.positions" />
</el-form-item>
<el-form-item label="上传照片">
<el-button type="primary" size="medium" @click="uploadPictrue(2)"
>上传</el-button
>
<img
v-if="imageUrl"
:src="imageUrl"
alt="无网络"
style="height: 100px;width: 100px;margin-left: 20px"
/>
</el-form-item>
</el-form>
<template #footer>
<span
class="dialog-footer"
style="display: flex;justify-content: center"
>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submitProtal">
添加
</el-button>
</span>
</template>
</el-dialog>
<el-dialog
:before-close="close"
:visible.sync="pEditDialogVisible"
:modal="false"
title="编辑"
width="100%"
style="height: 500px"
center
>
<el-form
label-width="100px"
:model="editForm"
:rules="peopleRules"
ref="editFormRef"
>
<el-form-item label="名称" prop="name">
<el-input v-model="editForm.name" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="editForm.phone" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="editForm.remark" />
</el-form-item>
<el-form-item label="值班类型" prop="patrolType">
<el-select v-model="editForm.patrolType">
<el-option value="0" label="值班领导"></el-option>
<el-option value="1" label="值班科长"></el-option>
<el-option value="2" label="值班长"></el-option>
<el-option value="3" label="值班员"></el-option>
<el-option value="4" label="大队值班"></el-option>
</el-select>
</el-form-item>
<el-form-item label="职务">
<el-input v-model="editForm.positions" />
</el-form-item>
<el-form-item label="上传照片">
<el-button type="primary" size="medium" @click="uploadPictrue(1)"
>上传</el-button
>
<img
v-if="imageUrl"
:src="imageUrl"
alt="无网络"
style="height: 50px;width: 50px;margin-left: 20px"
/>
</el-form-item>
</el-form>
<template #footer>
<span
class="dialog-footer"
style="display: flex;justify-content: center"
>
<el-button @click="cancel1">取消</el-button>
<el-button type="primary" @click="editSubmit">
确定
</el-button>
</span>
</template>
</el-dialog>
<div style="display: flex">
<el-button type="primary" size="mini" @click="show"
>添加值班人员</el-button
>
</div>
<div>
<el-table
:data="peopleDataList"
style="width: 100%;padding-left: 10px;margin-top: 10px"
>
<el-table-column prop="name" label="名称" width="100">
</el-table-column>
<el-table-column prop="phone" label="电话" width="100">
</el-table-column>
<el-table-column prop="remark" label="备注"> </el-table-column>
<el-table-column prop="patrolType" label="值班类型">
<template slot-scope="scope">
{{ statusTrans(scope.row.patrolType) }}
</template>
</el-table-column>
<el-table-column prop="imageUrl" label="头像">
<template slot-scope="scope">
<img
:src="scope.row.imageUrl"
alt="无网络"
style="height: 50px;width: 50px"
/>
</template>
</el-table-column>
<el-table-column label="是否值班">
<template slot-scope="scope">
<el-switch
@change="changeStatue(scope.row)"
v-model="scope.row.positionType"
active-value="1"
inactive-value="2"
active-color="#13ce66"
inactive-color="#ff4949"
>
</el-switch>
</template>
</el-table-column>
<el-table-column prop="positions" label="职务"> </el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" danger @click="deletePeople(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<el-pagination
style="display: flex;justify-content: center"
@size-change="handleSizeChange"
@current-change="hadleCurrentChange"
:current-page="page.page"
:page-sizes="[10, 20, 30, 40]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
/>
</div>
</div>
</template>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,219 @@
<script>
import title from "../../../assets/title.png";
import table from "../../../assets/table.png";
import * as echarts from "echarts";
import { areaList, selectFlow } from "../../../api";
export default {
name: "bayonet",
props: {
text: String,
required: true
},
data() {
return {
title,
table,
option: {
tooltip: {
trigger: "item"
},
legend: {
top: "20%",
right: "right",
left: "60%",
orient: "vertical",
itemGap: 10,
height: "100px",
textStyle: {
color: "rgb(29,211,232)"
},
align: "right"
},
series: [
{
type: "pie",
radius: ["30%", "80%"],
center: ["25%", "60%"],
avoidLabelOverlap: false,
label: {
show: true,
position: "inside",
formatter: "{d}%",
color: "white"
},
emphasis: {
label: {
show: true,
fontSize: 20,
fontWeight: "bold",
color: "rgb(29,211,232)"
}
},
labelLine: {
show: false
},
data: [
{ value: 1048, name: "空调" },
{ value: 735, name: "崆峒" },
{ value: 580, name: "卡扣" },
{ value: 484, name: "55" },
{ value: 300, name: "66" }
]
}
]
},
option2: {
xAxis: {
type: "category",
data: [
"卡口1",
"卡口2",
"卡口3",
"卡口4",
"卡口5",
"卡口6",
"卡口7",
"卡口8"
]
},
yAxis: {
type: "value",
name: "/辆",
nameTextStyle: {
color: "rgb(29,211,232)",
nameLocation: "start"
},
axisLabel: {
//x轴文字的配置
show: true,
textStyle: {
color: "orange"
}
}
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130, 140],
type: "bar",
itemStyle: {
normal: {
//这里是颜色
color: function(params) {
//注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
var colorList = [
"#00A3E0",
"#FFA100",
"#ffc0cb",
"#CCCCCC",
"#BBFFAA",
"#749f83",
"#ca8622"
];
return colorList[params.dataIndex];
}
}
}
}
]
},
areaList: [],
query: {
times: ""
}
};
},
methods: {
init() {
var chartDom = document.getElementById("bayonet");
var myChart = echarts.init(chartDom);
this.option && myChart.setOption(this.option);
var chartDom2 = document.getElementById("bayonetCar");
var myChart2 = echarts.init(chartDom2);
this.option2 && myChart2.setOption(this.option2);
},
//车流量信息
getFlow() {
console.log(this.query);
/* selectFlow(this.query).then(res => {
if (res.data.code === 0) {
}
});*/
}
},
mounted() {
this.init();
//解决canvas点击时间选择不会失去焦点的问题
setTimeout(() => {
const canvas = document.getElementsByTagName("canvas");
canvas[0].addEventListener("click", () => {
this.$refs.timeselect.hidePicker();
});
}, 3000);
}
};
</script>
<template>
<div class="bayonet">
<div class="time">
<el-date-picker
style="width: 230px;"
v-model="query.times"
type="daterange"
value-format="yyyy-MM-dd"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
ref="timeselect"
size="mini"
>
</el-date-picker>
</div>
<img :src="title" alt="" class="icon-img" />
<span class="title">{{ text }}</span>
<div style="height: 10px"></div>
<div class="table">
<p style="position: absolute;left: 110px;top:20px">
各区县车流量占比情况
</p>
<div id="bayonet" style="height: 170px;width: 400px"></div>
<p style="position: absolute;left: 130px">各卡口车流量</p>
<div id="bayonetCar" style="height: 250px;width: 400px"></div>
</div>
</div>
</template>
<style scoped lang="scss">
.bayonet {
margin-top: 10px;
position: relative;
color: rgb(29, 211, 232);
font-size: 18px;
font-weight: 600;
text-align: center;
.time {
width: 300px;
top: 0px;
right: -40px;
position: absolute;
z-index: 66;
}
.icon-img {
width: 100%;
height: 100%;
}
.title {
position: absolute;
color: rgb(192, 220, 255);
font-size: 20px;
top: 3px;
left: 30px;
font-weight: 600;
}
.table {
height: 350px;
width: 400px;
}
}
</style>

View File

@ -0,0 +1,75 @@
<script>
import { listByAreaId } from "../../../api";
export default {
name: "camera",
data() {
return {
page: {
page: 1,
pageSize: 2
},
camearaList: []
};
},
mounted() {
this.getCameraList();
this.$recvChanel("videoId", params => {
this.page.page = 1;
console.log("params", params);
});
},
methods: {
async getCameraList() {
const result = await listByAreaId({ areaId: 6 });
this.camearaList = result.data.data.list;
this.initFlv();
},
initFlv() {
const index = this.page.page;
//slice不包含end 所以+1
const flvs = this.camearaList.slice(index - 1, index + 1);
new window.YJ.Video.Flv("cameras", {
url: flvs[0]["String"]
});
new window.YJ.Video.Flv("cameras2", {
url: flvs[1]["String"]
});
}
}
};
</script>
<template>
<div class="camera">
<video id="cameras" class="video-content"></video>
<video id="cameras2" class="video-content"></video>
<div class="action">
<div>
<el-button type="primary" icon="el-icon-top" circle></el-button>
</div>
<div style="margin-top: 20px">
<el-button type="primary" icon="el-icon-bottom" circle></el-button>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.camera {
position: relative;
margin-top: -50px;
height: 300px;
width: 400px;
.video-content {
height: 190px;
width: 350px;
border: #00ffed solid 2px;
}
.action {
position: absolute;
top: 150px;
left: -80px;
}
}
</style>

View File

@ -0,0 +1,137 @@
<script>
import title from "../../../assets/title.png";
import table from "../../../assets/table.png";
import * as echarts from "echarts";
import { areaList } from "../../../api";
export default {
name: "videos",
props: {
text: String,
required: true
},
data() {
return {
title,
table,
option: {
tooltip: {
trigger: "item"
},
legend: {
top: "20%",
right: "right",
left: "60%",
orient: "vertical",
itemGap: 10,
height: "100px",
textStyle: {
color: "rgb(29,211,232)"
},
align: "right"
},
series: [
{
type: "pie",
radius: ["30%", "80%"],
center: ["25%", "60%"],
avoidLabelOverlap: false,
label: {
show: true,
position: "inside",
formatter: "{c}",
color: "white"
},
emphasis: {
label: {
show: true,
fontSize: 20,
fontWeight: "bold",
color: "rgb(29,211,232)"
}
},
labelLine: {
show: false
},
data: [
{ value: 1048, name: "空调" },
{ value: 735, name: "崆峒" },
{ value: 580, name: "卡扣" },
{ value: 484, name: "55" },
{ value: 300, name: "66" }
]
}
]
},
MyCharts: null
};
},
methods: {
init() {
let that = this;
var chartDom = document.getElementById("videos");
var myChart = echarts.init(chartDom);
this.option && myChart.setOption(this.option);
myChart.on("click", function(params, charts, event) {
that.send(params.data);
});
},
getList() {
areaList({ page: 1, pageSize: 9999 }).then(res => {
if (res.code === 0) {
this.areaList = res.data.list;
this.option.series[0].data = this.areaList.map(item => {
return { value: 1, name: item.area_name, ...item };
});
this.init();
}
});
},
send(data) {
this.$sendChanel("videoId", data);
}
},
mounted() {
// this.getList();
}
};
</script>
<template>
<div class="videos">
<img :src="title" alt="" class="icon-img" />
<span class="title">{{ text }}</span>
<div style="height: 10px"></div>
<div class="table">
<p style="position: absolute;left: 100px;top:30px">各区域摄像头数量</p>
<div id="videos" style="height: 170px;width: 400px"></div>
</div>
</div>
</template>
<style scoped lang="scss">
.videos {
margin-top: 20px;
position: relative;
color: rgb(29, 211, 232);
font-size: 18px;
font-weight: 600;
text-align: center;
.icon-img {
width: 100%;
height: 100%;
}
.title {
position: absolute;
color: rgb(192, 220, 255);
font-size: 20px;
top: 3px;
left: 30px;
font-weight: 600;
}
.table {
height: 230px;
width: 400px;
}
}
</style>

View File

@ -0,0 +1,36 @@
<script>
import bayonet from "./components/bayonet.vue";
import videos from "./components/video.vue";
import camera from "./components/camera.vue";
export default {
name: "rightBar",
components: {
bayonet,
videos,
camera
}
};
</script>
<template>
<div class="right-bar">
<div style="width: 400px;margin-left: 70px;margin-top: 110px">
<bayonet text="卡口车流量"></bayonet>
<videos text="摄像头情况"></videos>
<camera style="margin-left: 40px"></camera>
</div>
</div>
</template>
<style scoped lang="scss">
.right-bar {
display: none;
position: absolute;
top: 0;
right: 0;
z-index: -1;
height: 100vh;
width: 480px;
background: url("../../assets/rgb.png") repeat-y;
}
</style>

View File

@ -0,0 +1,87 @@
<script>
import top from "../../assets/top.png";
import exit from "../../assets/exit.png";
import * as dayjs from "dayjs";
export default {
name: "topBar",
data() {
return {
top,
exit,
time: dayjs().format("MM月D日 周d HH:mm:ss"),
week: ["日", "一", "二", "三", "四", "五", "六"]
};
},
methods: {
back() {
const arr2 = ["left-bar", "top", "right-bar"];
arr2.forEach(item => {
this.$changeComponentShow(`.${item}`, false);
});
const arr = ["bottomMenu", "TreeIndex", "logo", "header_top"];
arr.forEach(item => {
this.$changeComponentShow(`.${item}`, true);
});
const arr3 = ["bottomMenu", "left"];
arr3.forEach(item => {
const ele = document.querySelector("." + item);
ele.style.display = "flex";
});
}
},
mounted() {
setInterval(() => {
this.time =
dayjs().format("MM月D日 ") +
"周" +
this.week[dayjs().format("d")] +
dayjs().format(" HH:mm:ss");
}, 1000);
}
};
</script>
<template>
<div class="top">
<img :src="top" alt="" />
<div class="weather"></div>
<div class="exit" @click="back">
<img :src="exit" alt="" />
</div>
<div class="time">
{{ time }}
</div>
</div>
</template>
<style scoped lang="scss">
.top {
display: none;
color: white;
font-size: 24px;
width: 100vw;
img {
width: 100%;
}
}
.weather {
position: absolute;
left: 10px;
top: 0px;
height: 50px;
width: 170px;
display: flex;
justify-content: space-around;
align-items: flex-end;
}
.exit {
position: absolute;
top: 15px;
right: 35px;
}
.time {
position: absolute;
top: 20px;
right: 90px;
}
</style>

View File

@ -0,0 +1,17 @@
export function debounce(fn, wait = 1000) {
// 通过闭包缓存一个定时器 id
let timer = null
// 将 debounce 处理结果当作函数返回
// 触发事件回调时执行这个返回函数
return function(...args) {
// this保存给context
const context = this
// 如果已经设定过定时器就清空上一次的定时器
if (timer) clearTimeout(timer)
// 开始设定一个新的定时器,定时器结束后执行传入的函数 fn
timer = setTimeout(() => {
fn.apply(context, args)
}, wait)
}
}

View File

@ -0,0 +1,115 @@
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:pager-count="pagerCount"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
import { scrollTo } from '@/utils/scroll-to'
export default {
name: 'Pagination',
props: {
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50]
}
},
// 移动端页码按钮的数量端默认值5
pagerCount: {
type: Number,
default: document.body.clientWidth < 992 ? 5 : 7
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
data() {
return {
};
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
methods: {
handleSizeChange(val) {
if (this.currentPage * val > this.total) {
this.currentPage = 1
}
this.$emit('pagination', { page: this.currentPage, limit: val })
if (this.autoScroll) {
scrollTo(0, 800)
}
},
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize })
if (this.autoScroll) {
scrollTo(0, 800)
}
}
}
}
</script>
<style scoped>
.pagination-container {
background: transparent;
padding: 15px;
text-align: right;
}
.pagination-container.hidden {
display: none;
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<div class="loading-overlay" v-if="isShowLoading">
<el-progress type="circle" :percentage="progress" :stroke-width="20" color="rgb(56, 201, 253)"></el-progress>
<div class="custom_box" style="width: 100%; height: 0%">
<svg width="100%" height="100%">
<defs>
<linearGradient id="custom-color" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color: rgb(35, 231, 169); stop-opacity: 0.8" />
<stop offset="100%" style="stop-color: rgb(31, 197, 255); stop-opacity: 0.8" />
</linearGradient>
</defs>
<defs>
<linearGradient id="dismantle" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color: #ef07f7; stop-opacity: 1" />
<stop offset="100%" style="stop-color: #945fff; stop-opacity: 1" />
</linearGradient>
</defs>
</svg>
</div>
<p class="tips_css">{{ tips }}</p>
</div>
</template>
<script>
export default ({
name: 'index',
props: {
progress: {
type: Number,
default: -1,
},
tips: {
type: String,
default: '正在奋力加载中,请稍后……',
},
},
data() {
return {
isShowLoading: false
}
},
watch: {
progress: {
handler(newValue, oldValue) {
if (newValue >= 100 || newValue < 0) {
// 关闭遮罩或执行其他操作
this.isShowLoading = false;
} else {
this.isShowLoading = true;
}
},
deep: true,
immediate: true,
}
}
});
</script>
<style scoped lang="scss">
.loading-overlay {
flex-direction: column;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
pointer-events: none;
::v-deep .el-progress-circle {
// 进度条颜色
svg > path:nth-child(2) {
stroke: url(#custom-color); // 该url() 中填入的是, 对应组件中的 id 名
}
}
}
::v-deep .el-progress__text {
font-size: 24px !important;
color: #23d6d4 !important;
}
::v-deep .el-progress-circle {
width: 150px !important;
height: 150px !important;
}
.tips_css {
margin-top: 15px;
font-family: 'SourceHanSansCN-Regular';
font-size: 20px;
color: #23d6d4;
}</style>

View File

@ -0,0 +1,58 @@
<template>
<div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll">
<div class="scroll-wrapper" ref="scrollWrapper" :style="{ top: top + 'px' }">
<slot></slot>
</div>
</div>
</template>
<script>
const delta = 15
export default {
name: 'scrollBar',
data() {
return {
top: 0
}
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 3
const $container = this.$refs.scrollContainer
const $containerHeight = $container.offsetHeight
const $wrapper = this.$refs.scrollWrapper
const $wrapperHeight = $wrapper.offsetHeight
if (eventDelta > 0) {
this.top = Math.min(0, this.top + eventDelta)
} else {
if ($containerHeight - delta < $wrapperHeight) {
if (this.top < -($wrapperHeight - $containerHeight + delta)) {
this.top = this.top
} else {
this.top = Math.max(this.top + eventDelta, $containerHeight - $wrapperHeight - delta)
}
} else {
this.top = 0
}
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import '../../styles/variables.scss';
.scroll-container {
position: relative;
width: 100%;
height: 100%;
background-color: $menuBg;
.scroll-wrapper {
position: absolute;
width: 100% !important;
}
}
</style>

View File

@ -0,0 +1,47 @@
/*
底部菜单的图标样式
*/
.svg-icon-public {
width: 30px;
height: 30px;
}
.svg-icon-bottomMenuItemBg {
width: 70px;
height: 45px;
left: 0;
top: -2px;
}
.svg-icon-bottomMenuBg {
width: 100%;
height: 100%;
left: 0;
top: 0;
}
@media screen and (max-width: 1550px) {
.svg-icon-public {
width: 30px;
height: 30px;
}
.svg-icon-bottomMenuItemBg {
width: 60px;
height: 50px;
}
}
@media (min-width: 1550px) and (max-width: 1680px) {
.svg-icon-public {
width: 34px;
height: 34px;
}
.svg-icon-bottomMenuItemBg {
width: 68px;
height: 60px;
}
}
[id^="icon-bottomMenuBg"] [id$="bg"] {
fill: var(--svg-divBgColor);
}

View File

@ -0,0 +1,90 @@
/*
顶部抬头图标样式
*/
.svg-icon-headItem {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.svg-icon-systemItem {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.svg-icon-systemTitle_icon {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.svg-icon-empower_icon {
width: 20px;
height: 20px;
margin-left: 15px;
cursor: pointer;
}
.svg-icon-out_icon {
width: 16px;
height: 16px;
margin-right: 10px;
}
.svg-icon-header_public {
width: 24px;
height: 24px;
margin-top: 4px;
}
.svg-icon-selected {
fill: #00ff37 !important;
}
.svg-icon-satelliteFail {
fill: #7f7f7f !important;
}
[id$="_head_background"] {
fill: var(--svg-headColor1);
}
[id$="_head_cube"] {
fill: var(--svg-headColor2);
}
[id$="_head_line"] {
/* CSS样式 */
fill: var(--svg-baseLineColor);
}
[id$="_head_font"] {
fill: var(--svg-baseLineColor);
}
[id$="head_bg"] {
fill: var(--svg-divBgColor);
}
[id$="head_button_line"] {
/* CSS样式 */
stroke: var(--svg-baseLineColor);
}
#icon-system_fill {
fill: var(--svg-systemColor1);
}
/*#icon-system_borser {
fill: var(--svg-systemColor2);
}*/
#icon-system_Corner {
fill: var(--svg-baseLineColor);
}

View File

@ -0,0 +1,14 @@
/*默认情况svg的颜色全为荧光色*/
[class^="svg-icon"]:not(.svg-icon-special) {
fill: var(--svg-baseLineColor);
}
/*绝对定位*/
.svg-icon-absolute {
position: absolute;
}
/*层级-1*/
.svg-icon-zIndex-1 {
z-index: -1;
}

View File

@ -0,0 +1,60 @@
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: "svg-icon",
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: Array,
},
},
computed: {
iconName() {
// return `#icon`
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className && this.className.length) {
let attr = [];
this.className.forEach((item) => {
attr.push("svg-icon-" + item);
});
return attr.join(" ");
} else {
return "svg-icon";
}
},
},
};
</script>
<style scoped>
@import "index.scss";
@import "bottomMenu.scss";
@import "headAll.css";
@import "leftMenu.css";
@import "tree.css";
.svg-icon-login_icon {
width: 40px;
height: 40px;
}
.svg-icon-password_icon {
width: 28px;
height: 28px;
}
.svg-icon-eye_icon {
width: 32px;
height: 40px;
}
</style>

View File

@ -0,0 +1,67 @@
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: "svg-icon",
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: Array,
},
},
computed: {
iconName() {
// return `#icon`
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className && this.className.length) {
let attr = [];
this.className.forEach((item) => {
attr.push("svg-icon-" + item);
});
return attr.join(" ");
} else {
return "svg-icon";
}
},
},
};
</script>
<style scoped>
@import "index.scss";
@import "bottomMenu.scss";
@import "headAll.css";
@import "leftMenu.css";
@import "tree.css";
/* yuan */
/* .svg-icon-login_icon {
width: 40px;
height: 40px;
}
.svg-icon-password_icon {
width: 28px;
height: 28px;
}
.svg-icon-eye_icon {
width: 32px;
height: 40px;
} */
.svg-icon-login_icon,
.svg-icon-password_icon,
.svg-icon-eye_icon {
width: 16px;
height: 16px;
}
</style>

View File

@ -0,0 +1,37 @@
.svg-icon-left_bg {
width: 100%;
height: 100%;
}
.svg-icon-left_item_bg {
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.svg-icon-left_item_icon {
width: 100%;
height: 2.8vh;
margin-top: .7vh;
}
.svg-icon-left_second_menu_bg {
width: 100%;
height: 100%;
position: absolute;
}
.svg-icon-second_menu_icon {
width: 100%;
height: 100%;
}
[id^="icon-leftMenuBg"] [ id$="bg"] {
fill: var(--svg-divBgColor);
}
#icon-secondMenuBg_bg {
fill: var(--svg-divBgColor);
}

View File

@ -0,0 +1,15 @@
.svg-icon-layerTitleBg {
width: 4vh !important;
}
#icon-rightMenuBg_B {
fill: var(--svg-rightMenuColorB);
}
#icon-rightMenuBg_A {
fill: var(--svg-rightMenuBgColor);
}
#icon-LayerBorder_bg {
fill: var(--svg-divBgColor);
}

View File

@ -0,0 +1,369 @@
<template>
<div class="Bars">
<!-- @mouseleave="(e)=>{mouseleave(e,task) } @mouseup="mouseup""-->
<div class="bar" v-for="(task, index) in showTasks" :style="cellStyle"
@contextmenu="contextmenu"
@mousemove="mousemove" @mousedown="clickProgress">
<div class="progress" :id="task.ID" :data-task="JSON.stringify(task)" :style="progressStyle(task)"
@dblclick="()=>{editEvent(task)}" @click.right="(e) => { rightClick(e, task, index); }">
<!--"-->
<!--<div class="pre">|</div>-->
<div class="content" @click="clickContent">
<div :style="'display:'+displayVal(task)" class="pre"></div>
<div :style="'display:'+displayVal(task)" class="next"></div>
</div>
<!--<div class="next">|</div>-->
<!--{{ task.start_time }}-->
</div>
</div>
</div>
</template>
<script>
import {eventUpdate} from "@/api/aboutCabin";
export default {
name: "Bars",
props: ['Store'],
computed: {
allTasks: {
get() { return this.Store.tasks; }, // 直接访问window上的变量但实际上是访问内部的_someGlobalVar因为我们已经定义了getter和setter。
set(newValue) { this.showTasks = newValue; } // 设置操作实际上会触发setter从而更新_someGlobalVar。
},
showTasks(){
/* this.$nextTick(()=>{
let treeObj = $.fn.zTree.getZTreeObj("treeDemos");
let nodes = treeObj.getCheckedNodes(true);
console.log("getCheckedNodes",nodes)
})*/
return this.Store.tasks
},
cellStyle() {
return {
touched: null,
touchTimer: null,
height: this.Store.scales.cellHeight + "px",
};
},
},
data() {
return {
taskEvent: null
}
},
watch: {
},
mounted() {
},
methods: {
handleEvent(event){
console.log('Event triggered:', event);
},
displayVal(task) {
return (task.duration * this.Store.scales.preSecondPx) < 10 ? "none" : "block"
},
rightClick(e, task, index) {
if (TSTYOBJ.clock.status != TSTYOBJ.timeStatus.PLAY) {
this.taskEvent = null
window.currentTask = task;
let top = index * this.Store.scales.cellHeight + e.layerY
let style = {
left: e.screenX - this.Store.scales.gridWidth + this.Store.scales.scrollLeft + "px",
top: (top > 0 ? top : 0) + "px",
transform: "translateX(15px)",
display: "flex"
}
this.Store.getDomElement(".taskRightMenu", 0).style.left = style.left
this.Store.getDomElement(".taskRightMenu", 0).style.top = style.top
this.Store.getDomElement(".taskRightMenu", 0).style.transform = style.transform
this.Store.getDomElement(".taskRightMenu", 0).style.display = style.display
}
},
editEvent(task) {
console.log("editEvent", task)
// $root_home_index.$changeComponentShow(".eventEditors",true)
/* let hasDetailTask = ["flicker", "pathMove"];
if (hasDetailTask.includes(task.callback)) {
// this.$nextTick(()=>{
this.$changeComponentShow(".eventEditors", true);
this.$nextTick(()=>{
window.dispatchEvent(window.EventsNameMap.get("openEventDetail"));
})
}else{
this.$message.warning("当前事件无详细参数");
}*/
},
mouseleave(e, task) {
/*this.taskEvent = null
this.endDrag()*/
/* this.taskEvent = null
console.log(e.target)
let dom=document.querySelector(`div[id="${task.ID}"]`)
dom.style.left=this.getWidth(task.start_time - this.Store.startTimestamp)+"px"*/
// this.endDrag()
},
contextmenu(e) {
if (!this.touched || !this.touchTimer) {
e.preventDefault();
return false;
}
},
mouseup(e) {
if (this.taskEvent) {
const {id, mode, dx, domNode, left, width, start} = this.taskEvent;
const time = (Math.round(dx / this.Store.scales.distanceOfTicTiny) * this.Store.scales.preMains[this.Store.scales.preMainIndex]) / 30;
this.$emit("action", {
action: "update-task-time",
obj: {mode, width, dx, id, left, time},
});
this.taskEvent = null
this.endDrag(id)
document.removeEventListener("mousemove", this.mousemove);
document.removeEventListener("mousemove", this.mouseup);
}
},
mousemove(e) {
if( TSTYOBJ.clock.status!=TSTYOBJ.timeStatus.PLAY){
this.move(e);}
},
move(e) {
// 是否存在点击对象
if (this.taskEvent) {
let {x, mode, domNode, left, width, id} = this.taskEvent
let {clientX} = e
let dx = clientX - x
// 避免不必要的更新
if (dx === this.taskEvent.dx) return;
this.taskEvent.dx = dx;
domNode = document.querySelector(`div[id="${id}"]`)
if (mode === "content") {
console.log("mode === \"move\"")
domNode.style.left = `${left + dx}px`;
} else if (mode === "next") {
domNode.style.width = `${width + dx}px`;
} else if (mode === "pre") {
domNode.style.left = `${left + dx}px`;
domNode.style.width = `${width - dx}px`;
}
window.changeData = true
console.log("domNode.style", domNode.style.left.split("px"))
} else {
/* let mode = this.getMoveMode(e)
this.startDrag(mode)*/
}
},
clickContent(e) {
console.log("content", e)
},
clickProgress(e) {
if( TSTYOBJ.clock.status!=TSTYOBJ.timeStatus.PLAY){
window.changeData=false
//只监听左键,右键不执行
if (event.button === 0) {
// console.log("clickProgress", e)
//根据点击事件对象获取带有data-task属性的dom元素如果没有则退出逻辑
let domNode = this.Store.locate(e)
if (!domNode) return;
// console.log(domNode)
this.down(domNode, e)
}
}
},
down(domNode, e) {
const {clientX, clientY} = e;
const id = JSON.parse(domNode.dataset.task).ID;
window.currentTask = domNode.dataset.task
let mode = this.getMoveMode(e)
// console.log(e)
this.taskEvent = {
id,
mode,
domNode,
x: clientX,
dx: 0,
left: parseInt(domNode.style.left),
width: parseInt(domNode.style.width)
}
console.log("down", this.taskEvent)
this.startDrag(mode)
if (mode != 'content') {
}
document.addEventListener("mousemove", this.mousemove);
document.addEventListener("mouseup", this.mouseup);
},
startDrag(mode) {
// document.body.style.userSelect = "none";
// console.log("startDrag", mode)
let cursor = {"pre": "col-resize", "next": "col-resize", "content": "move"}
document.body.style.cursor = cursor[mode] || mode
},
endDrag(id) {
document.body.style.cursor = ""
if (window.changeData) {
//更新数据库
console.log("endDrag", id)
let event = this.Store.getTaskById(id);
let param = {
id: event.ID,
name: event.name,
start_time: event.start_time,
end_time: event.duration * 1000 + event.start_time,
duration: event.duration,
source_id: event.source_id,
callback: event.callback,
detail: event.detail,
};
if (param.callback == 'pathMove') {
let TrajectoryMotionObject = ts_Map.get(param.id + param.callback + param.source_id,);
let distance = new YJ.Tools().computeDistance(
param.detail.positions
);
let speed = (distance / param.duration);
TrajectoryMotionObject.speed = speed * TSTYOBJ.store.multiplier
TrajectoryMotionObject.oldSpeed = speed
}
eventUpdate(param, (res) => {
console.log(res);
});}
window.changeData=false
},
//获取移动模式
getMoveMode(e) {
const rect = e.target.getBoundingClientRect();
const afterWidth = 4; // 假设伪元素宽度
const afterHeight = 21; // 假设伪元素高度
//
if (e.layerX <= rect.width && e.layerX > rect.left) {
console.log('点击了rect区域');
}
/* const afterX = rect.left + (rect.width - afterWidth) / 2;
const afterY = rect.top + (rect.height - afterHeight) / 2;
if (e.clientX >= afterX && e.clientX <= afterX + afterWidth &&
e.clientY >= afterY && e.clientY <= afterY + afterHeight) {
console.log('点击了 ::after 伪类区域');
}*/
console.log(rect)
console.log(e)
return ["pre", "next", "content"].includes(e.target.className) ? e.target.className : "";
},
getWidth(durationTime) {
let progressSecond = durationTime / 1000;
let width = (progressSecond) * this.Store.scales.preSecondPx;
//左偏移量中 竖线所占宽度
let widthOfTiny = Math.floor(width / this.Store.scales.distanceOfTicTiny)
return width;
},
progressStyle(task) {
// console.log(task)
let taskLeft = task.start_time - this.Store.startTimestamp;
// console.log(taskLeft)
/*let getWidth = (durationTime) => {
let progressSecond = durationTime / 1000;
let width = (progressSecond) * this.Store.scales.preSecondPx;
//左偏移量中 竖线所占宽度
let widthOfTiny = Math.floor(width / this.Store.scales.distanceOfTicTiny)
return width;
};*/
return {
width: this.getWidth(task.duration) * 1000 + "px",
left: this.getWidth(taskLeft) + "px",
};
}
},
beforeDestroy() {
// 清理,避免内存泄漏
delete window.allTasks;
}
}
</script>
<style lang="scss" scoped>
.Bars {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
user-select: none;
.bar {
box-sizing: border-box;
border-bottom: 1px solid #00ffff;
position: relative;
.progress {
position: absolute;
top: 50%;
transform: translate(0, -50%);
width: 300px;
height: 81%;
box-sizing: border-box;
white-space: nowrap;
line-height: inherit;
text-align: center;
border: 1px solid #2898b0;
background-color: #00bed7;
border-radius: 2px;
display: flex;
align-items: center;
span {
display: inline-block;
flex: auto;
}
.pre, {
//transform: translateX(-100%);
cursor: col-resize;
}
.content {
height: 100%;
width: 100%;
display: flex;
justify-content: space-between;
cursor: move;
& > div {
width: 5px;
height: 100%;
background: #9b9b9b8f;
}
/* &:after {
content: "|";
position: absolute;
right: -5px;
pointer-events: none;
}*/
}
.next {
//transform: translateX(100%);
cursor: col-resize;
}
}
}
}
</style>

View File

@ -0,0 +1,178 @@
<template>
<div class="Chart" @scroll="scroll">
<div class="area" :style="areaStyle" @click.right="rightClick">
<div class="taskRightMenu popup">
<div @click="del">删除</div>
<div @click="edit">编辑</div>
</div>
<Bars :Store="Store" @action="action"></Bars>
</div>
</div>
</template>
<script>
import Bars from "@/components/TS/chart/Bars.vue";
import {eventDel} from "@/api/aboutCabin";
export default {
name: "Chart",
props: ["Store", "action"],
components: {
Bars,
},
data() {
return {
oldLeft: 0
}
},
computed: {
areaStyle() {
let a=this.Store.scales.fullHeight?`${this.Store.scales.fullHeight }px`:"100%"
return {
width: `${this.Store.scales.fullWidth || 1500}px`,
height: a,
};
},
},
mounted() {
console.log("chart", this.Store)
this.oldLeft = this.Store.scales.originOffset
},
methods: {
rightClick(e) {
// console.log("area右击", e)
// window.currentTask = task;
},
del() {
this.$changeComponentShow(".taskRightMenu", false);
eventDel({ ids:[ currentTask.ID ]}, (res) => {
this.$emit("action", {
action: "del-task",
obj:{id: currentTask.ID,}
});
if(window.currentTask.callback=='pathMove'){
let moveEntity=ts_Map.get(currentTask.source_id)
if(moveEntity){
let zTreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let idKey = zTreeObj.setting.data.simpleData.idKey;
let node = zTreeObj.getNodeByParam(idKey, currentTask.source_id, null);
moveEntity.setPosition({
position:node.detail.positions||node.detail.position||{}
})
}
let key=currentTask.ID+"pathMove"+currentTask.source_id
ts_Map.get(key).remove()
ts_Map.delete(key)
}
// $root_home_index.tasks = Store.tasks;
window.currentTask = null;
});
},
edit() {
let hasDetailTask = ["flicker", "pathMove"];
if (hasDetailTask.includes(currentTask.callback)) {
// this.$nextTick(()=>{
this.$changeComponentShow(".eventEditors", true);
this.$nextTick(()=>{
window.dispatchEvent(window.EventsNameMap.get("openEventDetail"));
})
}else{
this.$message.warning("当前事件无详细参数");
}
},
getOriginOffset(e, distance) {
let originOffset = (e.srcElement.scrollLeft) % distance/* + 7*/
/*let offset = e.srcElement.scrollLeft - this.oldLeft
let symbols = offset / Math.abs(offset)*/
return originOffset /** symbols*/ * -1
},
scroll(e,) {
/* console.log("scroll", e)
console.log("scroll", e.deltaX)
console.log("scroll", e.deltaY)*/
// if(TSTYOBJ.clock.status!=TSTYOBJ.timeStatus.PLAY) {
let scrollLeft = e.srcElement.scrollLeft
let scrollTop = e.srcElement.scrollTop
// if (e.deltaX !== undefined || e.deltaY !== undefined)
this.$emit("action", {
action: "scroll-chart",
obj: {
top: scrollTop,
left: scrollLeft,
deltaX: e.deltaX,
deltaY: e.deltaY,// !== 0发生竖向滚动
cb: this.$nextTick
}
});
// }
// console.log(" e.srcElement.scrollLeft", e.srcElement.scrollLeft)
// console.log(" e.srcElement.scrollLeft", e.srcElement.scrollTop)
// console.log(" e.srcElement.scrollLeft - this.oldLeft", e.srcElement.scrollLeft - this.oldLeft)
/* this.Store.scales.originOffset = this.getOriginOffset(e, this.Store.scales.distanceOfTicTiny)
this.Store.scales.originSubOffset = this.getOriginOffset(e, this.Store.scales.distanceOfTicSub)
this.Store.scales.originMainOffset = this.getOriginOffset(e, this.Store.scales.distanceOfTicMain)
this.$nextTick(() => {
this.Store.moveHalf()
})*/
// this.oldLeft = e.srcElement.scrollLeft
/* let originOffset = e.srcElement.scrollLeft % this.Store.scales.distanceOfTicTiny
let offset = e.srcElement.scrollLeft - this.oldLeft
let symbols = offset / Math.abs(offset)
this.Store.scales.originOffset = originOffset * symbols * -1
this.oldLeft = e.srcElement.scrollLeft*/
//
/* console.log({
action: "scroll-chart",
top: this.chart.scrollTop,
left: this.chart.scrollLeft
});*/
/* this.$emit("action", {
action: "scroll-chart",
top: this.chart.scrollTop,
left: this.chart.scrollLeft,
});*/
/*this.$nextTick(() => {
window.Store.moveHalf();
});*/
// this.dataRequest();
},
},
}
</script>
<style lang="scss" scoped>
.Chart {
flex: 1 1 auto;
background: #5fa5a97d;
overflow: auto;
.area {
position: relative;
.taskRightMenu {
z-index: 9;
position: absolute;
color: #fff;
display: none;
background: #00000073;
padding: 5px;
flex-direction: column;
user-select: none;
& > div {
&:hover {
color: cyan;
cursor: pointer;
}
}
}
}
}
</style>

View File

@ -0,0 +1,610 @@
<template>
<div class="layoutBox ts-zyl">
<div class="control">
<span>{{ TSTYOBJ.store.parseTime(TSTYOBJ.store.currentTimestamp) }}</span>
<!--<span>{{ TSTYOBJ.store.currentTimestamp }}</span>-->
<!-- <button :disabled="TSTYOBJ.editorMode.PLAYING==TSTYOBJ.store.editorMode" @click="play">play</button>
<button :disabled="TSTYOBJ.editorMode.EDITING==TSTYOBJ.store.editorMode" @click="stop">stop</button>-->
<div class="btn">
<svg
:aria-disabled="true"
v-if="TSTYOBJ.clock.status==TSTYOBJ.timeStatus.STOP||TSTYOBJ.clock.status==TSTYOBJ.timeStatus.PAUSE"
class="icon icon-bofang"
aria-hidden="true"
@click="play"
>
<use xlink:href="#icon-bofang"></use>
</svg>
<svg
v-else
class="icon icon-bofang"
aria-hidden="true"
@click="pause"
>
<use xlink:href="#icon-zanting"></use>
</svg>
<!---->
<svg
:class="['icon' ,'icon-zhongzhi']"
aria-hidden="true"
@click=" ()=>{stop()}">
<use xlink:href="#icon-zhongzhi"></use>
</svg>
</div>
<div
:class="[(TSTYOBJ.clock.status==TSTYOBJ.timeStatus.PLAY&&TSTYOBJ.store.editorMode==TSTYOBJ.editorMode.PLAYING)?'disabledBtn':'','multiple']"
@click="openMultiple">
<!--新增25-->
倍数×{{ TSTYOBJ.store.multiplier }}
</div>
</div>
<div class="layoutBoxs">
<div class="layout">
<Grid :Store="TSTYOBJ.store"></Grid>
<div class="TLContainer">
<div class="timelineCursorBox" :style="cursorStyle">
<!--@mousedown="mousedown"-->
<!--@mouseup="mouseup"-->
<!--@mousemove="mousemove"-->
<span class="timeline-icon16" v-drags="timing"></span>
</div>
<TimeScale :Store="TSTYOBJ.store" :Clock="TSTYOBJ.clock" @action="action"></TimeScale>
<Chart ref="Chart" :Store="TSTYOBJ.store" :action="action" @action="action"></Chart>
</div>
<!--<eventDetail></eventDetail>-->
</div>
</div>
<div class="multipleSelect">
<template v-for="item in multipliers">
<!--新增-->
<div @click="changeMultiple(item)">{{ item }}</div>
</template>
</div>
</div>
</template>
<script>
import Grid from "@/components/TS/grid/Grid.vue";
import TimeScale from "@/components/TS/scale/TimeScale.vue"
import Chart from "@/components/TS/chart/Chart.vue"
import {dragElement} from "./utils/drag";
import "./rootCss.css"
// import eventDetail from "@/components/TS/detail/eventDetail.vue";
export default {
name: "deduction",
props: ['TSTYOBJ', "action"],
components: {
Grid,
TimeScale,
Chart,
/*eventDetail*/
},
computed: {
cursorStyle() {
return {
left: `${this.TSTYOBJ.store.scales.cursorLeft || 0}px`,
};
},
},
data() {
return {
multipliers: [
0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 6, 8, 16, 32, 64, 128, 256,
],
}
},
directives: {
drags: dragElement,
},
beforeCreate() {
},
mounted() {
console.log("+++", this.TSTYOBJ)
},
methods: {
changeMultiple(item) {
this.TSTYOBJ.store.multiplier = item;
// 播放状态下,才生效
if (this.TSTYOBJ.clock.status != this.TSTYOBJ.timeStatus.PLAY) {
// 新增27
let guijis = this.returnFun();
guijis.forEach((key) => {
ts_Map.get(key).speed = ts_Map.get(key).speed * item;
});
function isextend(task) {
return task.callback == 'extend';
}
let filtered = this.TSTYOBJ.store.tasks.filter(isextend);
filtered.forEach(task => {
ts_Map.get(Number(task.source_id)).spreadTime = (task.duration * 1000 / item)
})
/*let guijis = this.returnFun();
guijis.forEach((key) => {
ts_Map.get(key).speed = ts_Map.get(key).oneSpeed * Store.multiplier;
});
if (Clock.isAction) {
this.stop();
// this.start(1);
this.start(1);
}*/
}
this.$changeComponentShow(".multipleSelect", false);
},
openMultiple(e) {
if (!(TSTYOBJ.clock.status == TSTYOBJ.timeStatus.PLAY && TSTYOBJ.store.editorMode == TSTYOBJ.editorMode.PLAYING)) {
this.$changeComponentShow(".multipleSelect", true);
$(".multipleSelect")[0].style.left = e.layerX + 10 + "px";
$(".multipleSelect")[0].style.top = e.layerY + 5 + "px";
}
},
timing() {
let currentTasks = TSTYOBJ.store.getTaskInStamp()
currentTasks.forEach(task => {
if (task) {
// console.log("执行事件对象", task);
if (task.detail && typeof task.detail == "string") {
task.detail = JSON.parse(task.detail);
}
switch (task.callback) {
case 'pathMove':
let TrajectoryMotionObject = ts_Map.get(task.ID + task.callback + task.source_id,);
/*
TrajectoryMotionObject.moveCallBack(tsEntitys);*/
let tsEntitys = ts_Map.get(Number(task.source_id));
tsEntitys.show = true
// console.log("(TSTYOBJ.store.currentTimestamp-task.start_time)/1000/TSTYOBJ.store.multiplier",(TSTYOBJ.store.currentTimestamp-task.start_time)/1000/TSTYOBJ.store.multiplier)
TrajectoryMotionObject.speed = TrajectoryMotionObject.oldSpeed
TrajectoryMotionObject.setMovePositionByTime((TSTYOBJ.store.currentTimestamp - task.start_time) / 1000)
break;
case 'extend':
let entity = ts_Map.get(Number(task.source_id))
entity.spreadTime = (task.duration * 1000)
entity.setSpreadProgressByTime((TSTYOBJ.store.currentTimestamp - task.start_time))
break
default:
//新增0918
let tsEntity = ts_Map.get(Number(task.source_id));
if (tsEntity && typeof tsEntity[task.callback] == "function") {
if (task.callback == "flicker") {
let detail = task.detail;
typeof detail == "string" && (detail = JSON.parse(detail));
tsEntity[task.callback](detail.times / this.TSTYOBJ.store.multiplier, detail.number);
} else tsEntity[task.callback]();
}
break;
}
}
})
if ($root_home_index.eventBox) {
window.dispatchEvent(window.EventsNameMap.get("changeStampEventBox"));
}
},
// 停止
stop(isStopBtn = true) {
console.log("stop", isStopBtn)
// 不管任何情况,停止按钮都将当前时间设为初始时间
// 并将编辑器模式设为编辑模式,时间轴设为停止状态
// (暂停播放除外)
this.TSTYOBJ.store.editorMode = this.TSTYOBJ.editorMode.EDITING
this.TSTYOBJ.clock.stopAnimation()
Array.from(AudioMap.values()).forEach(item => {
item.pause()
})
if (isStopBtn) {
this.pauseTrajectoryMotion()
TSTYOBJ.store.currentTimestamp = TSTYOBJ.store.startTimestamp
this.TSTYOBJ.clock.status = this.TSTYOBJ.timeStatus.STOP
this.TSTYOBJ.store.scales.scrollLeft = 0
this.TSTYOBJ.store.scales.cursorLeft = 0
this.Revert()
} else {
this.pauseTrajectoryMotion()
this.Revert("pause")
this.TSTYOBJ.clock.status = this.TSTYOBJ.timeStatus.PAUSE
}
/* console.log("stop")
if(this.TSTYOBJ.clock.status==this.TSTYOBJ.timeStatus.PAUSE&&isPause!=null){
console.log("暂停事件")
//暂停事件
this.TrajectoryMotion("pause")
}else if (this.TSTYOBJ.store.editorMode != this.TSTYOBJ.editorMode.EDITING) {
this.TSTYOBJ.clock.status=this.TSTYOBJ.timeStatus.STOP
// 停止事件
console.log("停止事件")
this.TrajectoryMotion("stop")
// 恢复原始状态
this.Revert()
if(!isPause){
this.TSTYOBJ.store.editorMode = this.TSTYOBJ.editorMode.EDITING
// this.TSTYOBJ.store.panelWidth -= this.TSTYOBJ.store.scales.gridWidth
this.$nextTick(() => {
TSTYOBJ.renderLine(this.$nextTick)
TSTYOBJ.renderLabel({left: 0})
// TSTYOBJ.store.updateTimeLineRightRest()
})
// this.TSTYOBJ.store.currentTimestamp=this.TSTYOBJ.store.startTimestamp
this.TSTYOBJ.store.scales.scrollLeft=0
this.TSTYOBJ.store.scales.cursorLeft=0
}else{
}
}else if(!isPause){
this.TSTYOBJ.store.scales.scrollLeft=0
this.TSTYOBJ.store.scales.cursorLeft=0
// 恢复原始状态
this.Revert()
}
*/
// 停止时间流逝
},
Revert(flag = null) {
if (flag == null) {
this.TSTYOBJ.store.tasks.forEach(item => {
console.log("Revert", item)
let zTreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let idKey = zTreeObj.setting.data.simpleData.idKey;
let node = zTreeObj.getNodeByParam(idKey, item.source_id, null);
let entity = ts_Map.get(Number(item.source_id));
switch (item.callback) {
case "flicker":
entity && entity.flicker(1, 1);
break;
case "extend":
console.log(" entity.spreadState=false")
entity.spreadState = false
entity.spreadTime = (item.duration * 1000)
entity.setSpreadProgressByTime(item.duration * 1000)
break
case "Animation":
ts_Map.get(Number(item.source_id)).activeAnimate=""
break
case "pathMove":
/*let TrajectoryMotionMapKey = item.ID + "pathMove" + item.source_id
let TrajectoryMotionObject = ts_Map.get(TrajectoryMotionMapKey);
TrajectoryMotionObject.setMovePositionByTime(0)*/
// 将模型改回节点树上编辑的样子
let model=ts_Map.get(Number(item.source_id))
model.rotateX=node.detail.rotate.x
model.rotateY=node.detail.rotate.y
model.rotateZ=node.detail.rotate.z
model.lng= node.detail.position.lng
model.lat= node.detail.position.lat
model.alt= node.detail.position.alt
break;
}
})
} else if (flag == 'pause') {
this.TSTYOBJ.store.tasks.forEach(item => {
let zTreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let idKey = zTreeObj.setting.data.simpleData.idKey;
let node = zTreeObj.getNodeByParam(idKey, item.source_id, null);
let entity = ts_Map.get(Number(item.source_id));
switch (item.callback) {
case "flicker":
entity && entity.flicker(1, 1);
break;
case "extend":
entity.spreadState = false
break
}
})
}
},
// 暂停模式
pause() {
// this.TSTYOBJ.clock.status=this.TSTYOBJ.timeStatus.PAUSE
this.TSTYOBJ.store.editorMode = this.TSTYOBJ.editorMode.EDITING
// TSTYOBJ.store.currentTimestamp = TSTYOBJ.store.startTimestamp
this.TSTYOBJ.clock.status = this.TSTYOBJ.timeStatus.PAUSE
this.stop(false)
},
// 播放按钮
play() {
// 如果编辑器在编辑模式,时间轴为停止状态则先将当前时间设为起始时间
if (this.TSTYOBJ.store.editorMode == this.TSTYOBJ.editorMode.EDITING &&
(this.TSTYOBJ.clock.status == this.TSTYOBJ.timeStatus.STOP && TSTYOBJ.store.currentTimestamp != TSTYOBJ.store.startTimestamp ||
this.TSTYOBJ.store.currentTimestamp > this.TSTYOBJ.store.getTotalTime())) {
console.log("++++++++++++++")
this.Revert()
TSTYOBJ.store.currentTimestamp = TSTYOBJ.store.startTimestamp
}
// 编辑器为播放模式,时间轴为播放状态
this.TSTYOBJ.store.editorMode = this.TSTYOBJ.editorMode.PLAYING
this.TSTYOBJ.clock.status = this.TSTYOBJ.timeStatus.PLAY
// this.TSTYOBJ.store.editorMode = (this.TSTYOBJ.store.editorMode==0?1:0)
// this.TSTYOBJ.clock.status =( this.TSTYOBJ.clock.status==1?2:1)//this.TSTYOBJ.timeStatus.PLAY==
this.$nextTick(() => {
TSTYOBJ.renderLine(this.$nextTick)
TSTYOBJ.renderLabel({left: 0})
TSTYOBJ.store.updateTimeLineRightRest()
})
//新情况
let currentTasks = this.TSTYOBJ.store.getTaskInStamp()
currentTasks.forEach(task => {
console.log("play的todoEvent")
this.todoEvent(null, task);
})
// this.TrajectoryMotion("resume")
this.TSTYOBJ.clock.animation(this.TSTYOBJ.store, (currentTime, diff, timeStamp) => {
this.TSTYOBJ.store.currentTimestamp = currentTime
// 当前与初始时间戳差值
let goTimestamp = currentTime - this.TSTYOBJ.store.startTimestamp;
// 当前时间相对起始点的位置
let left = (goTimestamp / 1000) * this.TSTYOBJ.store.scales.preSecondPx
// 获取光标轴dom元素
let dom = document.getElementsByClassName("timelineCursorBox")[0]
//光标原始位置
let originLeft = dom.style.left.split("px")[0] || 0
// dom.style.left = left - originLeft - this.TSTYOBJ.store.scales.scrollLeft + "px"
// dom.style.transform = `translateX(${left - originLeft - this.TSTYOBJ.store.scales.scrollLeft}px)`
// document.documentElement.style.setProperty('--timelineCursorBox-left', left - originLeft - this.TSTYOBJ.store.scales.scrollLeft + "px");
/* console.log(dom.style.left)
console.log(this.TSTYOBJ.store.preSecondPx)
console.log(left)
console.log(originLeft)
console.log(this.TSTYOBJ.store.scales.scrollLeft)*/
this.$forceUpdate();
// console.log("444", currentTime, diff, timeStamp)
}, this.animation)
},
//操作机动事件对象
pauseTrajectoryMotion() {
//status:pause,resume,stop(0)
let currentTasks = TSTYOBJ.store.getTaskInStamp()
console.log("currentTasks", currentTasks)
currentTasks.forEach(task => {
if (task.callback == 'pathMove') {
let TrajectoryMotionMapKey = task.ID + task.callback + task.source_id
let TrajectoryMotionObject = ts_Map.get(TrajectoryMotionMapKey);
TrajectoryMotionObject.pause()
}
})
},
animation() {
if (TSTYOBJ.clock.status == TSTYOBJ.timeStatus.PLAY) {
let timeId = Math.round(this.TSTYOBJ.store.currentTimestamp / 1000);
timeId *= 1000;
let taskIds = [];
// 原始情况
// 以起始时间+resouce_id为key生成事件map+
let dataMap = this.TSTYOBJ.store.dealData("start_time");
let endTimeEventMap = this.TSTYOBJ.store.dealData("end_time");
// 新增26
// 循环获取key
let fun = (map, isEnd = false) => {
let keys = Array.from(map.keys());
for (let i = 0; i < keys.length; i++) {
if (String(keys[i]).indexOf(timeId) > -1) {
taskIds.push(keys[i]);
}
}
taskIds.forEach((item) => {
let res = map.get(item);
this.todoEvent(timeId, res, isEnd);
});
}
fun(dataMap)
fun(endTimeEventMap, true)
if (this.TSTYOBJ.store.currentTimestamp > this.TSTYOBJ.store.getTotalTime()) {
this.stop(false);
}
}
},
todoEvent(item, res, isEnd = false) {
if (res) {
if (res.detail && typeof res.detail == "string") {
res.detail = JSON.parse(res.detail);
}
// 执行时间滑块的结束事件
if (isEnd) {
console.log("执行结束事件", res);
switch (res.callback) {
case 'audio':
Array.from(AudioMap.values()).forEach(item => {
item.pause()
})
break
case 'Animation':
ts_Map.get(Number(res.source_id)).activeAnimate=""
break
}
} else {
console.log("执行事件对象", res);
// 执行时间滑块的开始事件
switch (res.callback) {
case 'pathMove':
let TrajectoryMotionObject = ts_Map.get(res.ID + res.callback + res.source_id);
TrajectoryMotionObject.speed = TrajectoryMotionObject.oldSpeed * this.TSTYOBJ.store.multiplier
TrajectoryMotionObject.state = !TrajectoryMotionObject.state
TrajectoryMotionObject.setMovePositionByTime((this.TSTYOBJ.store.currentTimestamp - res.start_time) / 1000 / this.TSTYOBJ.store.multiplier)
// TrajectoryMotionObject.state=true
break
case 'extend':
// ts_Map.get(Number(res.source_id))
console.log("暂停后继续播放 相对时间", (TSTYOBJ.store.currentTimestamp - res.start_time))
ts_Map.get(Number(res.source_id)).setSpreadProgressByTime((TSTYOBJ.store.currentTimestamp - res.start_time))
ts_Map.get(Number(res.source_id)).spreadTime = (res.duration * 1000) / this.TSTYOBJ.store.multiplier
ts_Map.get(Number(res.source_id)).spreadState = true
break
case 'audio':
let audio = new Audio();
audio.src = "/admin/yjearth4.0/api/v1/preview/pdf?id=" + res.detail.id;
audio.loop = true
audio.volume = res.detail.volume||0.5
audio.playbackRate = this.TSTYOBJ.store.multiplier
audio.addEventListener("canplaythrough", event => {
/* 音频可以播放;如果权限允许则播放 */
audio.play();
});
AudioMap.set(res.ID, audio)
// new Audio
break
case 'Animation':
ts_Map.get(Number(res.source_id)).activeAnimate= res.detail.animationName
break
default:
//新增0918
let tsEntity = ts_Map.get(Number(res.source_id));
if (tsEntity && typeof tsEntity[res.callback] == "function") {
if (res.callback == "flicker") {
let detail = res.detail;
typeof detail == "string" && (detail = JSON.parse(detail));
tsEntity[res.callback](detail.times / this.TSTYOBJ.store.multiplier, detail.number);
} else tsEntity[res.callback]();
}
break;
}
}
}
},
//返回机动对象key
returnFun() {
function isTrajectoryMotion(element) {
return String(element).indexOf("pathMove") > -1;
}
let filtered = Array.from(ts_Map.keys()).filter(isTrajectoryMotion);
return filtered;
},
},
}
</script>
<style lang="scss" scoped>
.layoutBox {
//height: 230px;
background: rgba(0, 0, 0, 0.53);
//display: flex;
//flex-direction: column;
//position: relative;
.control {
display: flex;
height: 30px;
line-height: 30px;
color: #fff;
justify-content: space-between;
width: 400px;
& > span {
display: inline-block;
width: 200px;
}
.icon {
width: 18px;
height: 18px;
cursor: pointer;
}
.btn {
margin: 0 vw(15);
}
.disabledBtn {
cursor: no-drop;
filter: brightness(0.7);
}
}
.layoutBoxs {
//height: 230px;
height: vh(230);;
position: relative;
}
.multipleSelect {
border: 1px solid;
position: absolute;
z-index: 999;
top: 0;
color: #fff;
width: vw(82);
height: vh(165);
background: rgba(0, 63, 63, 1);
overflow-y: auto;
font-size: px2font(16);
display: none;
& > div {
cursor: pointer;
margin: vh(4) 0;
}
}
.layout {
display: flex;
width: 100%;
flex: auto;
height: 100%;
position: absolute;
.TLContainer {
position: relative;
overflow: hidden;
flex: auto;
display: flex;
flex-direction: column;
.timelineCursorBox {
position: absolute;
border-right: 0.5px red solid;
height: calc(100% - 16px);
z-index: 9;
//left: 10px;
top: 16px;
transition: transform 0.001s ease-in-out;
.timeline-icon16 {
display: block;
position: absolute;
width: 16px;
height: 16px;
//width: vw(16);
//height: vw(16);
transform: translate(-50%, -16px);
background: url("../../assets/img/indicator.png") no-repeat;
cursor: pointer;
}
}
}
}
}
</style>

View File

@ -0,0 +1,237 @@
<template>
<div class="eventDetail">
<div class="layout">
<div class="nav">
<span></span>
<span>事件参数</span>
<span class="close" @click="close">
<i class="el-icon-close"></i>
</span>
</div>
<div class="eventDetailBody">
<template v-if="currentTask.callback == 'flicker'">
<div class="item">
<span>闪烁间隔:</span>
<div>
<el-input size="mini" v-model.number="flicker.times"></el-input>
</div>
<span>ms</span>
</div>
<div class="item">
<span>闪烁次数:</span>
<div>
<el-input size="mini" v-model.number="flicker.number"></el-input>
</div>
</div>
</template>
<template v-if="currentTask.callback == 'pathMove'">
<!-- <div class="item">
<span>视角跟随:</span>
<div>
<el-switch size="mini" v-model.number="pathMove.viewFollow"></el-switch>
</div>
</div>-->
<div class="item">
<span>路径显示:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.line.show"
></el-switch>
</div>
</div>
<div class="item">
<span>是否圆滑:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.line.smooth"
></el-switch>
</div>
</div>
<div class="item">
<span>是否贴地:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.ground"
></el-switch>
</div>
</div>
<div class="item">
<span>路径方向:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.routeDirection"
></el-switch>
</div>
</div>
<div class="item">
<el-button size="mini" @click="drawPath">更换路径</el-button>
</div>
</template>
</div>
<div style="text-align: center">
<el-button size="mini" @click="submit">确认</el-button>
</div>
</div>
</div>
</template>
<script>
import { eventUpdate } from "@/api/aboutCabin";
export default {
name: "eventDetail",
data() {
return {
flicker: {
// 默认参数
times: 500,
number: null,
},
pathMove: {
viewFollow: false, //视角跟随
line: {
show: false, //路径显隐
smooth: false, //路径圆滑
}, //视角跟随
routeDirection: true, //路径方向
},
currentTask: {},
};
},
mounted() {
window.addEventListener("openEventDetail", () => {
this.currentTask = JSON.parse(window.currentTask);
console.log(window.currentTask);
// 有详细参数的事件
let hasDetailTask = ["flicker", "pathMove"];
if (hasDetailTask.includes(window.currentTask.callback)) {
this.$changeComponentShow(".eventDetail", true);
let obj = this[window.currentTask.callback];
for (const objElement in obj) {
let taskDetail = window.currentTask.detail;
if (taskDetail && typeof taskDetail == "string")
taskDetail = JSON.parse(taskDetail);
if (taskDetail.hasOwnProperty(objElement)) {
this[window.currentTask.callback][objElement] =
taskDetail[objElement];
}
}
} else {
this.$message.warning("当前事件无详细参数");
}
});
},
methods: {
drawPath() {
let draw = new YJ.Draw.DrawPolyline(earth);
draw.start((err, positions) => {
if (err) return err;
if (positions && positions.length > 1) {
this.pathMove.positions = positions;
this.$message.success("绘制成功");
}
});
},
close() {
this.$changeComponentShow(".eventDetail", false);
this.flicker = {
// 默认参数
times: 500,
number: null,
};
this.pathMove = {
viewFollow: false, //视角跟随
line: {
show: false, //路径显隐
smooth: false, //路径圆滑
}, //视角跟随
routeDirection: true, //路径方向
};
this.currentTask = {};
},
submit() {
// currentTask.
let obj = this[window.currentTask.callback];
for (const objElement in obj) {
let isNUll =
this.currentTask.detail && typeof this.currentTask.detail == "string";
if (isNUll) {
this.currentTask.detail = JSON.parse(this.currentTask.detail);
}
this.currentTask.detail[objElement] = obj[objElement];
}
/* $root_home_index.$refs.Deduction.$refs.chart.$emit("action", {
action: "del-task",
id: this.currentTask.task_id,
});
this.currentTask.detail = JSON.stringify(this.currentTask.detail);
$root_home_index.$refs.Deduction.$refs.chart.$emit("action", {
action: "add-task",
obj: this.currentTask,
});*/
this.currentTask.id = this.currentTask.task_id;
eventUpdate(this.currentTask, (res) => {
console.log(res);
// if (!res) this.$message.success("操作成功");
this.close();
});
// $root_home_index.tasks = Store.tasks;
},
},
};
</script>
<style lang="scss" scoped>
.eventDetail {
width: vw(400);
display: none;
color: #fff;
.layout {
//display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 5px;
height: 100%;
}
.nav {
padding: 5px 0;
display: flex;
justify-content: space-between;
.close {
font-size: 16px;
cursor: pointer;
}
}
.eventDetailBody {
//flex: auto;
height: 68%;
overflow-y: auto;
.item {
display: flex;
align-items: center;
padding-bottom: 5px;
span {
display: inline-block;
width: fit-content;
}
}
}
button {
color: #fff;
}
}
</style>

View File

@ -0,0 +1,366 @@
<template>
<div id="eventEditors" class="eventEditors">
<div class="layout">
<div id="eventEditorsNav" class="nav">
<span></span>
<span>事件参数</span>
<span class="close" @click="close">
<i class="el-icon-close"></i>
</span>
</div>
<div class="eventDetailBody">
<template v-if="currentTask.callback == 'flicker'">
<div class="item">
<span>闪烁总时:</span>
<div style="display: flex;align-items: center;">
<el-input size="mini" :disabled="!changeTotalTime" v-model.number="flickerDuration"></el-input>
<span style="margin-right: 15px">s</span>
<el-checkbox v-model="changeTotalTime">修改总时长</el-checkbox>
</div>
</div>
<div class="item">
<span>闪烁间隔:</span>
<div>
<el-input size="mini" v-model.number="flicker.times" @blur="countTime('number','times')"></el-input>
</div>
<span>ms</span>
</div>
<div class="item">
<span>闪烁次数:</span>
<div>
<el-input size="mini" v-model.number="flicker.number" @blur="countTime('times','number')"></el-input>
</div>
</div>
</template>
<template v-if="currentTask.callback == 'pathMove'">
<!-- <div class="item">
<span>视角跟随:</span>
<div>
<el-switch size="mini" v-model.number="pathMove.viewFollow"></el-switch>
</div>
</div>-->
<div class="item">
<span>路径显示:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.line.show"
></el-switch>
</div>
</div>
<div class="item">
<span>是否圆滑:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.line.smooth"
></el-switch>
</div>
</div>
<div class="item">
<span>是否贴地:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.ground"
></el-switch>
</div>
</div>
<div class="item">
<span>是否包含模型点:</span>
<el-switch
size="mini"
v-model.number="includeModelPoint"
@change="changeIncludeModelPoint"
></el-switch>
</div>
<div class="item">
<span>路径方向:</span>
<div>
<el-switch
size="mini"
v-model.number="pathMove.routeDirection"
></el-switch>
</div>
</div>
<div class="item">
<el-button size="mini" @click="drawPath">更换路径</el-button>
</div>
</template>
</div>
<div style="text-align: center">
<el-button size="mini" @click="submit">确认</el-button>
</div>
</div>
</div>
</template>
<script>
import {eventUpdate} from "@/api/aboutCabin";
import {setMove} from "@/components/myHeaderAll/systemPopup/js/moveDiv";
export default {
name: "eventEditor",
data() {
return {
includeModelPoint: true,
changeTotalTime: true,
flickerDuration: 0,
flicker: {
// 默认参数
times: 500,
number: null,
},
pathMove: {
viewFollow: false, //视角跟随
ground: false, //视角跟随
line: {
show: false, //路径显隐
smooth: false, //路径圆滑
}, //视角跟随
routeDirection: true, //路径方向
includeModelPoint:true
},
currentTask: {},
}
},
mounted() {
setMove("eventEditorsNav", "eventEditors");
window.addEventListener("openEventDetail", () => {
if (window.currentTask && typeof window.currentTask == 'string') {
this.currentTask = JSON.parse(window.currentTask)
}
this.currentTask = window.currentTask
if (this.currentTask && typeof this.currentTask == 'string') {
this.currentTask = JSON.parse(this.currentTask)
}
// 有详细参数的事件
let hasDetailTask = ["flicker", "pathMove"];
if (hasDetailTask.includes(this.currentTask.callback)) {
if (this.currentTask.callback == 'flicker') {
this.flickerDuration = this.currentTask.duration
}
// this.$nextTick(()=>{
$root_home_index.$changeComponentShow(".eventDetails", true);
// })
// let obj = this[this.currentTask.callback];
let taskDetail = this.currentTask.detail;
if (taskDetail && typeof taskDetail == "string")
taskDetail = JSON.parse(taskDetail);
/*for (let objElement in obj) {
if (taskDetail.hasOwnProperty(objElement)) {
this[this.currentTask.callback][objElement] =
taskDetail[objElement];
console.log("taskDetail[objElement]",taskDetail[objElement])
}
}*/
this[this.currentTask.callback] = taskDetail
this.includeModelPoint=taskDetail.hasOwnProperty("includeModelPoint")?taskDetail.includeModelPoint:true
} else {
this.$message.warning("当前事件无详细参数");
}
});
},
methods: {
changeIncludeModelPoint(){
let positions=[...this.pathMove.positions]
let zTreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let idKey = zTreeObj.setting.data.simpleData.idKey;
let node = zTreeObj.getNodeByParam(idKey, this.currentTask.source_id, null);
console.log(this.includeModelPoint)
if(this.includeModelPoint){
positions.unshift(node.detail.position)
}else{
positions.shift()
}
this.pathMove.positions=positions
console.log(this.currentTask)
console.log(this.pathMove)
console.log(node)
},
countTime(resKey, paramKey) {
if (!this.changeTotalTime)
this.flicker[resKey] = Math.round(this.flickerDuration * 1000 / this.flicker[paramKey])
else {
let times = (this.flicker.times * this.flicker.number)
this.flickerDuration=times / 1000
}
console.log(this.flickerDuration)
console.log(this.flicker.times)
console.log(this.flicker.number)
},
drawPath() {
console.log(this.pathMove)
let draw = new YJ.Draw.DrawPolyline(earth);
draw.start((err, positions) => {
let zTreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let idKey = zTreeObj.setting.data.simpleData.idKey;
let node = zTreeObj.getNodeByParam(idKey, this.currentTask.source_id, null);
if (err) return err;
if (positions && positions.length > 1) {
let p=[...positions]
if(this.includeModelPoint){
p.unshift(node.detail.position)
}
this.pathMove.positions =p;
this.$message.success("绘制成功");
}
});
},
close() {
this.$changeComponentShow(".eventEditors", false);
this.flicker = {
// 默认参数
times: 500,
number: null,
};
this.pathMove = {
viewFollow: false, //视角跟随
line: {
show: false, //路径显隐
smooth: false, //路径圆滑
}, //视角跟随
routeDirection: true, //路径方向
};
this.currentTask = {};
},
submit() {
// currentTask.
/*let obj = this[window.currentTask.callback];
for (const objElement in obj) {
let isNUll =
this.currentTask.detail && typeof this.currentTask.detail == "string";
if (isNUll) {
this.currentTask.detail = JSON.parse(this.currentTask.detail);
}
this.currentTask.detail[objElement] = obj[objElement];
}
$root_home_index.$refs.Deduction.$refs.chart.$emit("action", {
action: "del-task",
id: this.currentTask.task_id,
});
this.currentTask.detail = JSON.stringify(this.currentTask.detail);
$root_home_index.$refs.Deduction.$refs.chart.$emit("action", {
action: "add-task",
obj: this.currentTask,
});*/
let task = window.currentTask || TSTYOBJ.store.getTaskById(this.currentTask.ID) || null
if (task) {
task.id = task.ID
if (task.detail && typeof task.detail == "string")
task.detail = JSON.parse(task.detail);
switch (task.callback) {
case "flicker":
task.duration = this.flickerDuration
task.end_time = task.start_time + this.flickerDuration*1000
task.detail = JSON.stringify(this.flicker)
break
case "pathMove":
console.log("this.pathMove", this.pathMove)
// task.detail = JSON.stringify(this.pathMove)
let o = ts_Map.get(task.id + "pathMove" + task.source_id)
console.log("this.pathMove", o)
task.detail.line.show = this.pathMove.line.show
task.detail.line.smooth = this.pathMove.line.smooth
task.detail.ground = this.pathMove.ground
task.detail.routeDirection = this.pathMove.routeDirection
task.detail.includeModelPoint=this.includeModelPoint
o.line.show = this.pathMove.line.show
o.smooth = this.pathMove.line.smooth
o.ground = this.pathMove.ground
o.routeDirection = this.pathMove.routeDirection
if (this.pathMove.hasOwnProperty("positions")) {
o.renewLinePositions(this.pathMove.positions)
let distance = new YJ.Tools().computeDistance(
this.pathMove.positions
);
let speed =
(distance / task.duration) * TSTYOBJ.store.multiplier;
o.oldSpeed = (distance / task.duration)
o.speed = speed
task.detail.positions = this.pathMove.positions
}
let zTreeObj = $.fn.zTree.getZTreeObj("treeDemos");
let idKey = zTreeObj.setting.data.simpleData.idKey;
let node = zTreeObj.getNodeByParam(idKey, this.currentTask.source_id, null);
let model= ts_Map.get(Number(this.currentTask.source_id))
model.lng=node.detail.position.lng
model.lat=node.detail.position.lat
model.alt=node.detail.position.alt
model.rotateX=node.detail.rotate.x
model.rotateY=node.detail.rotate.y
model.rotateZ=node.detail.rotate.z
break
}
eventUpdate(task, (res) => {
console.log(res);
// if (!res) this.$message.success("操作成功");
this.close();
});
} else {
this.$message.warning("无法获取当前事件对象")
}
// $root_home_index.tasks = TSTYOBJ.store.tasks;
},
}
}
</script>
<style lang="scss" scoped>
.eventEditors {
width: vw(400);
display: none;
color: #fff;
.layout {
//display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 5px;
height: 100%;
}
.nav {
padding: 5px 0;
display: flex;
justify-content: space-between;
.close {
font-size: 16px;
cursor: pointer;
}
}
.eventDetailBody {
//flex: auto;
height: 68%;
overflow-y: auto;
.item {
display: flex;
align-items: center;
padding-bottom: 5px;
span {
display: inline-block;
width: fit-content;
}
}
}
button {
color: #fff;
}
}
</style>

View File

@ -0,0 +1,111 @@
<template>
<!--zIndex:-1-->
<div class="Body table gridBody"
@wheel.passive="wheel">
<div :class="['row',]"
v-for="task in Store.tasks"
:style="{ height: Store.scales.cellHeight + 'px' }"
@dblclick="locationProgress(task)">
<div
v-for="column in Store.columns"
:key="column.name"
class="cell"
:style="cellStyle(column)"
>
<!--:style="cellStyle(column)"-->
<template v-if="column.action">
<span class="el-icon-plus add" :data-action="column.action"></span>
</template>
<template v-else-if="column.name=='start_time'">
{{ label(task[column.name]) }}
<!--{{ new TSTY.Global().parseTime(task[column.name]) }}-->
<!-- {{ Clock.makeLabel() }}-->
</template>
<template v-else>
{{ task[column.name] }}
</template>
<!-- <template v-if="column.name === 'text'">
<div class="content" :style="contentStyle(task)">
<div
class="icon"
:class="getIcon(task)"
data-action="toggle-task"
></div>
{{ column.template(task) }}
</div>
</template>
<template v-else>
{{ column.template(task) }}
</template>-->
</div>
</div>
<div :style="style">
aa
</div>
</div>
</template>
<script>
export default {
name: "Body",
props: ['Store'],
computed: {
gridBodyStyle() {
return {
height: `${this.Store.scales.fullHeight || 1600}px`,
};
},
},
data() {
return {style: {}}
},
mounted() {
let Chart = document.getElementsByClassName("Chart")[0]
console.log(this.Store.scales.fullHeight)
console.log(Chart.getBoundingClientRect().height)
this.style = {
height: `${this.Store.scales.fullHeight - Chart.getBoundingClientRect().height + 10}px`,
opacity: 0
}
},
methods: {
locationProgress(task) {
console.log(task)
console.log()
this.$nextTick(() => {
this.Store.scales.scrollLeft = Number(document.getElementById(task.ID).style.left.split("px")[0])
})
},
label(stamp) {
return this.Store.parseTime(stamp, "{y}-{m}-{d} {h}:{i}:{s}");
},
cellStyle(column) {
const align = `text-align:${column.align}`;
const width =
column.width === "100%" ? `flex:1` : `width:${column.width}`;
return `${width};${align};padding-left:5px`;
},
wheel() {
}
},
}
</script>
<style lang="scss" scoped>
.Body {
font: 400 13px Arial;
color: #fff;
position: relative;
width: 100%;
overflow-y: inherit;
.row {
display: flex;
align-items: center;
box-sizing: border-box;
border-bottom: 1px solid #00ffff;
}
}
</style>

View File

@ -0,0 +1,37 @@
<template>
<div ref="Grid" class="Grid">
<Header :Store="Store"></Header>
<Body :Store="Store"></Body>
</div>
</template>
<script>
import Header from "@/components/TS/grid/Header.vue";
import Body from "@/components/TS/grid/Body.vue";
export default {
name: "Grid",
props: ['Store'],
components: {
Header,
Body
},
data() {
return {}
},
mounted() {
this.$refs.Grid.style.flex = `0 0 ${this.Store.scales.gridWidth}px`
}
}
</script>
<style lang="scss" scoped>
.Grid {
display: flex;
flex-direction: column;
flex: 0 0 400px;
overflow: hidden;
user-select: none;
}
</style>

View File

@ -0,0 +1,67 @@
<template>
<div class="Header table">
<div :style="headerStyle()">
<div class="row">
<div
v-for="column in Store.columns"
:key="column.name"
class="cell"
:style="cellStyle(column)"
>
{{ column.label }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Header",
props: ['Store'],
data() {
return {}
},
mounted() {
console.log(this.Store)
},
methods: {
headerStyle() {
return {
height: this.Store.scales.scaleHeight + "px",
display: "flex",
flexDirection: "column"
}
},
cellStyle(column) {
const align = `text-align:${column.align}`;
const width =
column.width === "100%" ? `flex:1` : `width:${column.width}`;
return `${width};${align};padding-left:5px`;
},
},
}
</script>
<style lang="scss" scoped>
.Header {
position: relative;
background: linear-gradient(to bottom, rgba(116, 117, 119, 1) 0%, rgba(58, 68, 82, 1) 11%, rgba(46, 50, 56, 1) 46%, rgba(53, 53, 53, 1) 81%, rgba(53, 53, 53, 1) 100%);
.row {
flex: auto;
box-sizing: border-box;
display: flex;
align-items: center;
border-bottom: 1px solid #00ffff;
//font-size: px2font(16);
.cell {
box-sizing: border-box;
flex: 0 0 auto;
font: 400 12px Arial;
text-transform: capitalize;
color: #fff;
}
}
}
</style>

View File

@ -0,0 +1,13 @@
:root {
--timelineCursorBox-left: 0px;
}
.timelineCursorBox {
left: var(--timelineCursorBox-left);
}
.el-slider__runway{
margin: 5px 0 !important;
}
.newEventBox .params .el-select{
width: 175px;
}

View File

@ -0,0 +1,169 @@
<template>
<div class="TimeScale" :style="scaleStyle" @click.prevent="toTime">
<div class="timeline-bar" @wheel="wheel" :style="scaleStyle">
<template v-for="(item,index) in Store.scales.ticTiny">
<span class="timeline-ticTiny"
:style="'left:'+(index*Store.scales.distanceOfTicTiny+Store.scales.originOffset)+'px'"></span>
</template>
<template v-for="(item,index) in Store.scales.ticSub">
<span class="timeline-ticSub"
:style="'left:'+(index*Store.scales.distanceOfTicSub+Store.scales.originSubOffset)+'px'"></span>
</template>
<template v-for="(item,index) in (Store.scales.ticMain+1)">
<span class="timeline-ticMain"
:style="'left:'+(index*Store.scales.distanceOfTicMain+Store.scales.originMainOffset)+'px'"></span>
<span class="timeline-ticLabel"
:style="'left:'+(index*Store.scales.distanceOfTicMain+Store.scales.originMainOffset)+'px'">
{{ ticLabel(index) }}
</span>
</template>
</div>
</div>
</template>
<script>
export default {
name: "TimeScale",
props: ['Store', 'Clock'],
computed: {
scaleStyle() {
return {
// width: `${this.Store.scales.fullWidth || 2800}px`,
// width: this.Store.panelWidth ? (this.Store.panelWidth + "px") : "100%",
height: this.Store.scales.scaleHeight + "px",
// left: -this.scales.scrollLeft + "px"
};
}
},
data() {
return {
/*distanceOfTicTinyRange: [7, 8, 9, 10, 11, 12, 13],//单个小格子的宽度可选值
distanceOfTicTiny: 10,//单个小格子的宽度
ticTiny: 0,//小格数量
originOffset: 0,//起始小格偏移量
numOfSubRange: [3, 4, 6, 8, 12, 24],//相邻中格之间的小格数量可选值
numOfSub: 6,// 相邻中格之间的小格数量
ticSub: 0,//中格数量
originSubOffset: 0,
numOfMain: 0,// 相邻大格之间的中格数量
ticMain: 0,
originMainOffset: 0,*/
}
},
mounted() {
/*let panelWidth = Math.floor(document.getElementsByClassName("TimeScale")[0].getBoundingClientRect().width)
document.getElementsByClassName("TimeScale")[0].style.width = panelWidth + "px"
let nums = Math.ceil(panelWidth / this.Store.scales.distanceOfTicTiny)
let rest = panelWidth % this.Store.scales.distanceOfTicTiny
//第一个刻度线的偏移量
// this.Store.scales.originOffset = -(this.Store.scales.distanceOfTicTiny - rest)
// console.log("this.Store.scales.originOffset", this.Store.scales.originOffset)
// console.log("this.Store.scales.originOffset", rest)
this.Store.scales.ticTiny = nums
// console.log("nums", nums)
//相邻中格宽度
let aSubWidth = this.Store.scales.numOfSub * this.Store.scales.distanceOfTicTiny
let subNums = Math.ceil(panelWidth / aSubWidth)
let restSubWidth = panelWidth % aSubWidth
//第一个刻度线的偏移量
// this.Store.scales.originSubOffset = -(aSubWidth - restSubWidth)
this.Store.scales.ticSub = subNums
this.Store.scales.numOfMain = 24 / this.Store.scales.numOfSub
let aMainWidth = aSubWidth * this.Store.scales.numOfMain
let mainNums = Math.ceil(panelWidth / aMainWidth)
let restMainWidth = panelWidth % aMainWidth
//第一个刻度线的偏移量
// this.Store.scales.originMainOffset = -(aMainWidth - restMainWidth)
this.Store.scales.ticMain = mainNums*/
this.$nextTick(() => {
this.Store.moveHalf()
})
},
methods: {
toTime(event){
console.log("toTime",event)
// event.
this.Store.scales.cursorLeft=event.clientX-this.Store.scales.gridWidth
},
wheel(event) {
// console.log("wheel", event)
//放大缩小
let num = event.wheelDelta > 0 ? 1 : -1;
this.$emit("action", {
action: "wheel-timeLine",
num,
cb: this.$nextTick
});
},
ticLabel(val) {
let timeLabels = []
/* console.log("timeLabels", this.Store.scales.ticMain)
for (let i = 0; i < this.Store.scales.ticMain; i++) {
// console.log("timeLabels", this.Store.scales.ticMain)
}*/
let stamp = this.Store.startTimestamp + val * this.Store.scales.preMains[this.Store.scales.preMainIndex] * 1000// this.Store.scales.preMains[this.Store.scales.preMainIndex] * 1000
// return
return this.Clock.makeLabel(this.Store.scales.timeLabels[val], "{y}-{m}-{d} {h}:{i}:{s}");
}
},
}
</script>
<style lang="scss" scoped>
.TimeScale {
position: relative;
background: linear-gradient(to bottom, rgba(116, 117, 119, 0.8) 0%, rgba(58, 68, 82, 0.8) 11%, rgba(46, 50, 56, 0.8) 46%, rgba(53, 53, 53, 0.8) 81%, rgba(53, 53, 53, 0.8) 100%);
width: 100%;
.timeline-bar {
position: relative;
left: 0;
top: 0;
overflow: hidden;
cursor: pointer;
width: 100%;
}
.timeline-ticTiny {
position: absolute;
bottom: 0;
left: 0;
width: 1px;
height: 25%;
background: #888;
}
.timeline-ticSub {
position: absolute;
bottom: 0;
left: 0;
width: 1px;
height: 33%;
background: #aaa;
}
.timeline-ticMain {
position: absolute;
bottom: 0;
left: 0;
width: 1px;
height: 50%;
background: #eee;
}
.timeline-ticLabel {
position: absolute;
top: 0;
left: 0;
white-space: nowrap;
font-size: 80%;
color: #eee;
}
}
</style>

View File

@ -0,0 +1,168 @@
export let dragElement = {
inserted: function (el, binding) {
console.log("binding", binding)
let startX,
startY,
currentX = 0,
currentY = 0;
// el.style.position = "relative";
// el.parentNode.style.position = "relative";
el.style.cursor = "pointer";
// currentX = el.style.left
el.addEventListener("mousedown", function (event) {
event.preventDefault();
startX = event.pageX - currentX;
startY = event.pageY - currentY;
console.log("mousedown", startX)
console.log("currentX", currentX)
console.log("currentX", event.pageX)
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
});
/* el.addEventListener("touchstart", function (event) {
event.preventDefault();
startX = event.touches[0].clientX - currentX;
startY = event.touches[0].clientY - currentY;
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
});
*/
function onMouseUp() {
window.dispatchEvent(window.EventsNameMap.get("changeStampEventBox"));
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
clearInterval(window.intervalID)
window.intervalID=null
}
/* function onTouchEnd() {
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
}*/
/* function onTouchMove(event) {
event.preventDefault();
currentX = event.touches[0].clientX - startX;
currentY = event.touches[0].clientY - startY;
drag(el);
}*/
function onMouseMove(event) {
event.preventDefault();
currentX = event.pageX - startX;
currentY = event.pageY - startY;
/* console.log("currentX", currentX)
console.log("event.pageX", event.pageX)
console.log("startX", startX)*/
drag(event, el);
}
function drag(event, el) {
// el.style.top = currentY + "px";
// el.parentNode.style.left = currentX /*- TSTYOBJ.store.scales.scrollLeft*/ + "px";
// if (TSTYOBJ.store.editorMode == TSTYOBJ.editorMode.EDITING)
let newX = currentX + startX - TSTYOBJ.store.scales.gridWidth
let isSide = (newX > TSTYOBJ.store.panelWidth - 50) || (newX < 50)
console.log(isSide)
// 到达边界之后,先滚动滚条
if (isSide) {
if (window.intervalID)
return
if (newX <= 0) {
newX = 0
TSTYOBJ.store.scales.cursorLeft = newX
} else if (newX < 50) {
// 如果已经滚动到最左边,则直接减少
if (TSTYOBJ.store.scales.scrollLeft == 0) {
TSTYOBJ.store.scales.cursorLeft = newX
clearInterval(window.intervalID);
window.intervalID=null}
else {
/*let newLeft = TSTYOBJ.store.scales.scrollLeft - 10;
let finalX = newLeft
// 如果滚动条不够滚则直接变为0
if (newLeft < 0)
finalX = 0
TSTYOBJ.store.scales.scrollLeft = finalX*/
/* let fun=()=>{
let newLeft = TSTYOBJ.store.scales.scrollLeft - 1;
let finalX = newLeft
if (newLeft < 0)
finalX = 0
TSTYOBJ.store.scales.scrollLeft = finalX
}*/
window.intervalID = setInterval(()=>{
let newLeft = TSTYOBJ.store.scales.scrollLeft - 1;
let finalX = newLeft
if (newLeft < 0)
finalX = 0
TSTYOBJ.store.scales.scrollLeft = finalX
}, 10)
}
} else if (newX + TSTYOBJ.store.scales.scrollLeft >= TSTYOBJ.store.scales.fullWidth) {
newX = TSTYOBJ.store.panelWidth
TSTYOBJ.store.scales.cursorLeft = newX
} else {
let maxScroll = TSTYOBJ.store.scales.fullWidth - TSTYOBJ.store.panelWidth
if (TSTYOBJ.store.scales.scrollLeft == maxScroll) {
TSTYOBJ.store.scales.cursorLeft = newX
clearInterval(window.intervalID);
window.intervalID=null}
else {
/* let fun = () => {
console.log("intervalID",intervalID)
let newLeft = TSTYOBJ.store.scales.scrollLeft + 1;
let finalX = newLeft
if (newLeft >= maxScroll) {
TSTYOBJ.store.scales.cursorLeft = newX
clearInterval(intervalID);
window.intervalID=null
finalX = maxScroll
}
TSTYOBJ.store.scales.scrollLeft = finalX
}*/
// fun()
window.intervalID = setInterval( () => {
// console.log("intervalID",intervalID)
let newLeft = TSTYOBJ.store.scales.scrollLeft + 1;
let finalX = newLeft
if (newLeft >= maxScroll) {
TSTYOBJ.store.scales.cursorLeft = newX
clearInterval(window.intervalID);
window.intervalID=null
finalX = maxScroll
}
TSTYOBJ.store.scales.scrollLeft = finalX
}, 10)
}
}
} else {
console.log("intervalID",intervalID)
clearInterval(window.intervalID)
window.intervalID=null
// window.intervalID=null
TSTYOBJ.store.scales.cursorLeft = newX
}
binding.value()
/*let transform = el.parentNode.style.transform
let translate = 0
if (transform) {
let arr = transform.split("translateX(")
translate = arr[1].split("px")[0]
translate = Number(translate)
}
console.log("translate", translate)
el.parentNode.style.transform = `translateX(${currentX}px)`// Number(translate) + currentX + "px";//currentX*/
}
},
};

View File

@ -0,0 +1,170 @@
<template>
<div class="rightMenu" id="rMenu">
<svg-icon icon-class="rightMenuBg" :class-name="['absolute', 'zIndex-1', 'special']"></svg-icon>
<div class="menuItem custom_scroll_bar">
<div>
<div v-for="item in menus" class="itemBox" @click="itemClick(item)"
@mouseup="$changeComponentShow('#rMenu', false)">
{{ $t(`rightMenu.${item.key}`) }}
</div>
</div>
<!-- <span v-for="item in menus" @click="item.callback" @mouseup="$changeComponentShow('#rMenu', false)">{{
}}</span>-->
</div>
</div>
</template>
<script>
import rightMenuOption from "./rightMenuOption";
import { getIP } from "../../../utils";
import { updateInfo, delSource } from "../../../api/gisAPI";
import { cusUpdateNode, cusRemoveNode, getSelectedNodes } from "../treeNode";
import { ipcRenderer } from "electron";
export default {
name: "rightMenu",
mixins: [rightMenuOption],
data() {
return {
menus: [],
rightClickTreeNode: null,
};
},
mounted() {
/* $("#rMenu")[0].addEventListener('mousedown', (event) => {
console.log("aaa", event)
if (event.target.nodeName == "SPAN") {
setTimeout(() => {
console.log("#######")
this.
}, 500)
}
})*/
ipcRenderer.on("changeFields", (event, detail) => {
let shpId = detail.currentNode.fid || detail.currentNode.source_id
let options = _entityMap.get(shpId).options
_entityMap.get(shpId).field = detail.field;
// _entityMap.get(detail.currentNode.fid || detail.currentNode.source_id).field = detail.field;
// let data = {
// ...options
// }
// data.field = detail.field;
this.shpConfirmCallBack({ id: shpId, field: detail.field, fileName: options.fileName }, shpId)
// _entityMap.get(source_id).field = detail;
})
},
methods: {
initMenu(arr, treeNode) {
let rightMenu = [];
if (treeNode) {
this.rightClickTreeNode = treeNode;
arr.forEach((menuId) => {
if (menuId == "addResource" || menuId == "addBIM") {
if (
["127.0.0.1", "localhost"].includes(
new URL(getIP()).hostname
)
) {
rightMenu.push(this.rightMenus[menuId]);
// console.log(this.rightMenus[menuId]);
}
} else {
rightMenu.push(this.rightMenus[menuId]);
// console.log(this.rightMenus[menuId]);
}
});
} else rightMenu = [this.rightMenus.addDirectory];
this.menus = rightMenu;
},
//菜单节点的点击功能
itemClick(menuItem) {
if (
menuItem.key === "edit" &&
this.rightClickTreeNode.source_type === "directory"
) {
let selectNode = null
selectNode = this.rightClickTreeNode ? this.rightClickTreeNode : node
// $root_home_index.$changeComponentShow(".editor", true)
let menuBox = document.querySelector(".editor");
menuBox.style.display = "block";
$root_home_index.$refs.editor.rightClickTreeNode = selectNode
$root_home_index.$refs.editor.setFormData()
return
}
return menuItem.callback();
},
},
};
</script>
<style lang="scss" scoped>
.rightMenu {
user-select: none;
//height: 25.5vh;
//width: 8vw;
width: 163px;
height: 255px;
visibility: hidden;
svg {
width: 100%;
height: 100%;
}
.menuItem {
//padding: 1vh .5vw;
font-size: 12px;
overflow-y: auto;
height: calc(100% - 20px);
margin-top: 16px;
&>div {
display: flex;
flex-direction: column;
align-items: center;
width: 80%;
margin: 0 auto;
//span{
line-height: 20px;
.itemBox {
cursor: pointer;
font-size: 16px;
padding-bottom: 5px;
}
.itemBox:hover {
transition-duration: 0.5s;
transform: scale(0.9);
}
//}
}
}
}
/*.rightMenu {
height: 22vh;
width: 8vw;
visibility: hidden;
svg {
width: 100%;
height: 100%;
}
.menuItem {
padding: 1vh .5vw;
font-size: 12px;
border: 1px solid red;
display: flex;
flex-direction: column;
height: 100%;
span {
line-height: 20px;
cursor: pointer;
}
}
}*/
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,297 @@
import rightMenuOption from "./components/rightMenuOption";
import { getById } from "../PLTraffic/api";
import * as path from "path";
import { GetHomeDir } from "../../../main/back/config";
import { cameraDataList } from "../PLTraffic/api/index";
let staticPort = $root_home.$remote.getGlobal("sharedObject").avilablePort;
let treeObj = null;
let index = 0;
$root_home.$recvChanel("getTreeObj", (obj) => {
treeObj = obj;
});
let icon =
process.env.NODE_ENV === "development"
? path.join(GetHomeDir(), "static/logo_ico/81.ico")
: path.join(
GetHomeDir(),
"resources/app.asar/" + "dist/electron/static/logo_ico/81.png"
);
const option = {
width: 1300,
height: 700,
minWidth: 600,
minHeight: 400,
frame: true, //是否显示边缘框
// simpleFullscreen: true,
resizable: true,
useContentSize: true,
icon: icon,
// transparent: true,
alwaysOnTop: true,
// fullScreen: true,
// backgroundColor: '#00000000',
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
// devTools: true,
// fullScreen: true,
devTools: false,
},
};
function leftClick(nodes) {
console.log("nodes", nodes);
let id = nodes.source_id;
let node = treeObj.getNodeByParam("source_id", id, null);
console.log("node111111", node);
const info = {
text: node.detail.richTextContent,
type: node.detail.attributeType,
// todo
hrefs: node.detail.attribute
? node.detail.attribute.link
? node.detail.attribute.link.content
: []
: [],
camera: node.detail.attribute
? node.detail.attribute.camera
? node.detail.attribute.camera.content
: []
: [],
// 0827
ISC: node.detail.attribute
? node.detail.attribute.ISC
? node.detail.attribute.ISC.content
: []
: [],
vr: node.detail.attribute
? node.detail.attribute.vr
? node.detail.attribute.vr.content
: []
: [],
goods: node.detail.attribute
? node.detail.attribute.goods
? node.detail.attribute.goods.content
: []
: [],
// camera: node.detail.attribute? node.detail.attribute.camera.content: {},
// node.detail.attributeType === "panorama" node.detail.attribute.panorama.content[0]
// : node.detail.attributeType === "panorama" ? node.detail.attribute.panorama.content[0].url
// vrPath: node.source_type === "vr" ? node.detail.url : "",
source_path: node.source_path,
env: localStorage.getItem("service"),
};
// 0828
info.ISC &&
info.ISC.forEach((item) => {
item.previewUrl = "";
getIscPreviewURL({ cameraIndexCode: item.cameraIndexCode }, (res) => {
item.previewUrl = res.url;
});
});
if (node) {
console.log("info", info);
if (
!node.detail.richTextContent &&
!info.hrefs.length &&
!info.vr.length &&
!info.goods.length &&
!info.camera.length
) {
// $root_home.$message.info("该标注标绘无属性信息");
$root_home.$message({
message: "该标注标绘无属性信息",
type: "info",
});
} else {
if (
node.detail.richTextContent ||
info.hrefs.length ||
info.vr.length ||
info.goods.length
) {
tankuang(id, node, info);
}
if (info.camera && info.camera.length) {
if (index == 0) {
$root_home.$message.success("摄像头打开中请稍后");
//测试
/* {
$root_home.$sendElectronChanel("openFFPlay", {
url: "WeChat_20230316160037.mp4" //res.data.flvUrl
});
}*/
cameraDataList(
{
page: 1,
pageSize: 9999,
},
(res) => {
let areaLists = res.list;
areaLists.forEach((element) => {
info.camera.forEach((item) => {
if (element.ID == item.ID) {
item.deviceId = element.deviceId;
}
});
});
info.camera.forEach((element) => {
index++;
getById({ deviceId: element.deviceId }, (res) => {
console.log(res);
if (res) {
$root_home.$sendElectronChanel("openFFPlay", {
url: res.rtspUrl, //
cameraName: res.cameraName, //
ip: res.ip, //
name: node.source_name,
deviceId: res.deviceId, //
});
$root_home.$recvElectronChanel(
"openFFPlayOut",
(e, err) => {
index--;
if (err) {
$root_home.$message.error("设备错误,打开失败!");
}
}
);
} else {
index--;
$root_home.$message.error("视频流错误");
}
// start({
// streamName: arr[0],
// url: res.data.rtspUrl
// }).then(() => {
// $root_home.$sendElectronChanel("openFFPlay", {
// url: res.data.flvUrl //
// });
// });
});
});
}
);
} else {
$root_home.$message.info("该摄像头已打开或未绑定");
}
//if (info.type == "vr")
}
}
}
}
function tankuang(id, node, info) {
treeObj.selectNode(node);
let win = $root_home.$remote.BrowserWindow;
console.log("node.detail.namenode.detail.namenode.detail.name", node.detail);
if (!window._winMap.has(id)) {
let webPreferences = {
nodeIntegration: true,
contextIsolation: false,
webSecurity: false,
enableRemoteModule: true,
// 如果是开发模式可以使用devTools
// devTools: process.env.NODE_ENV === 'development',
devTools: true,
// 在macos中启用橡皮动画
};
let newDataWin = new win({
...option,
title: node.detail.name,
});
// $root_home.$remote.globalShortcut.register("Esc", () => {
// newDataWin.setFullScreen(false);
// });
// newDataWin.maximize();
// $root_home.$remote.Menu.setApplicationMenu(null)
newDataWin.openDevTools(true);
newDataWin.loadURL(`http://localhost:${staticPort}/infoShow.html`);
newDataWin.on("ready-to-show", () => {
newDataWin.webContents.send("data", {
info: info,
source_name: node.source_name,
source_type: node.source_type,
});
});
window._winMap.set(id, newDataWin.id);
newDataWin.on("close", function(event) {
window._winMap.delete(id);
});
} else {
win.fromId(window._winMap.get(id)).show();
}
}
function rightClick(nodes) {
console.log("nodesmmmmmm", nodes);
let id = nodes.source_id;
let node = treeObj.getNodeByParam("source_id", id, null);
if (node) treeObj.selectNode(node);
// rightMenuOption.methods.editNode(node);
YJ.Global.splitScreen.setActiveId([id]);
}
function tileClick(pickedObjectId) {
console.log("BIM左键点击pickedObjectId", pickedObjectId);
$root_home_index.$changeComponentShow(".bimInfoBox", true);
$root_home_index.$refs.bimInfo.init(pickedObjectId);
}
function vrLeftClick(nodes) {
let id = nodes.source_id;
let node = treeObj.getNodeByParam("source_id", id, null);
let path = node.source_path;
if (node) {
// treeObj.selectNode(node);
let win = $root_home.$remote.BrowserWindow;
if (!window._winMap.has(id)) {
let newDataWin = new win({ ...option, title: node.detail.name });
// $root_home.$remote.Menu.setApplicationMenu(null)
newDataWin.openDevTools(true);
// newDataWin.openDevTools(false);
newDataWin.loadURL(`http://localhost:${staticPort}/infoShow.html`);
newDataWin.on("ready-to-show", () => {
newDataWin.webContents.send("data", {
path: path,
});
});
window._winMap.set(id, newDataWin.id);
newDataWin.on("close", function(event) {
window._winMap.delete(id);
});
} else {
win.fromId(window._winMap.get(id)).show();
}
}
}
function shpTotal(movement, id, pos) {
// let id = "1eb9bb82de86ee083098fbaa56553a40"
let node = treeObj.getNodeByParam("source_id", id, null);
if (node) treeObj.selectNode(node);
// $root_home_index.goodSearchDialog = true;
// window.$root_home_index.$refs.secondMenu.renderCanvas([{
// source_type: "Feature",
// detail: {
// properties
// }
// }
// ])
window.$root_home_index.$refs.tree.$refs.rightMenu.showAttr(node);
}
function shpSelect(movement, id, pos) {
let node = treeObj.getNodeByParam("source_id", id, null);
if (node) treeObj.selectNode(node);
}
export { leftClick, rightClick, tileClick, vrLeftClick, shpTotal, shpSelect };

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Some files were not shown because too many files have changed in this diff Show More