flex,editor
This commit is contained in:
parent
3e39f6c34e
commit
1ad29f234e
|
|
@ -16,6 +16,8 @@
|
|||
"dependencies": {
|
||||
"@ant-design-vue/pro-layout": "^1.0.11",
|
||||
"@antv/data-set": "^0.10.2",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^1.0.2",
|
||||
"ant-design-vue": "^1.7.8",
|
||||
"axios": "^0.26.1",
|
||||
"cesium": "1.101.0",
|
||||
|
|
|
|||
142
src/App.vue
142
src/App.vue
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<a-config-provider :locale="locale" :autoInsertSpaceInButton="false">
|
||||
<div id="app">
|
||||
<router-view/>
|
||||
<router-view />
|
||||
</div>
|
||||
</a-config-provider>
|
||||
</template>
|
||||
|
|
@ -11,53 +11,115 @@ import { domTitle, setDocumentTitle } from '@/utils/domUtil'
|
|||
import { i18nRender } from '@/locales'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
locale () {
|
||||
locale() {
|
||||
// 只是为了切换语言时,更新标题
|
||||
const { title } = this.$route.meta
|
||||
title && (setDocumentTitle(`${i18nRender(title)} - ${domTitle}`))
|
||||
title && setDocumentTitle(`${i18nRender(title)} - ${domTitle}`)
|
||||
|
||||
return this.$i18n.getLocaleMessage(this.$store.getters.lang).antLocale
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.ant-table td { white-space: nowrap !important; }
|
||||
.ant-table th { white-space: nowrap !important; }
|
||||
.ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
||||
padding: 8px 8px !important;
|
||||
overflow-wrap: break-word;
|
||||
font-size: 14px;
|
||||
}
|
||||
.flexRowStart {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.flexRowCenter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.flexCenterCenter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.flexColumnCenterCenter{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.shaixuan_float_left{
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.ant-table td {
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.ant-table th {
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.ant-table-thead > tr > th,
|
||||
.ant-table-tbody > tr > td {
|
||||
padding: 8px 8px !important;
|
||||
overflow-wrap: break-word;
|
||||
font-size: 14px;
|
||||
}
|
||||
.flexRowStart {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.flexRowCenter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.flexCenterCenter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.flexColumnCenterCenter {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.shaixuan_float_left {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.flex-rr {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.flex-c {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
||||
.flex-cr {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.ai-fs {
|
||||
align-items: flex-start;
|
||||
}
|
||||
.ai-s {
|
||||
align-items: stretch;
|
||||
}
|
||||
.ai-fe {
|
||||
align-items: flex-end;
|
||||
}
|
||||
.ai-c {
|
||||
align-items: center;
|
||||
}
|
||||
.ai-s {
|
||||
align-items: stretch;
|
||||
}
|
||||
.jc-c {
|
||||
justify-content: center;
|
||||
}
|
||||
.jc-sb {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.jc-sa {
|
||||
justify-content: space-around;
|
||||
}
|
||||
.jc-fs {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.jc-fe {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.fr-w {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.fr-n {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.fr-wr {
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -32,7 +32,7 @@ export default class MyCesium {
|
|||
// 未完成的在地图上移动类的操作
|
||||
operations = []
|
||||
|
||||
constructor(dom) {
|
||||
constructor(dom, options = {}) {
|
||||
const imageryProvider = new Cesium.UrlTemplateImageryProvider({
|
||||
url: window._CONFIG.ImageryProviderUrl || MyCesium.ImageryProviderUrl,
|
||||
tilingScheme: new Cesium.WebMercatorTilingScheme(),
|
||||
|
|
@ -65,11 +65,13 @@ export default class MyCesium {
|
|||
})
|
||||
this.viewer = viewer
|
||||
|
||||
const { center = MyCesium.center } = options
|
||||
|
||||
// viewer.scene.globe.depthTestAgainstTerrain = true
|
||||
|
||||
viewer.imageryLayers.addImageryProvider(roadProvider)
|
||||
viewer.camera.setView({
|
||||
destination: Cesium.Cartesian3.fromDegrees(...MyCesium.center),
|
||||
destination: Cesium.Cartesian3.fromDegrees(...center),
|
||||
})
|
||||
|
||||
// 不显示Cesium的Logo
|
||||
|
|
@ -93,7 +95,7 @@ export default class MyCesium {
|
|||
// 创建指北针小部件并将其添加到地图
|
||||
new CesiumNavigation(viewer, {
|
||||
// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和Cesium.Rectangle.
|
||||
defaultResetView: Cesium.Cartographic.fromDegrees(...MyCesium.center),
|
||||
defaultResetView: Cesium.Cartographic.fromDegrees(...center),
|
||||
// 用于启用或禁用罗盘。true是启用罗盘,false是禁用罗盘。默认值为true。如果将选项设置为false,则罗盘将不会添加到地图中。
|
||||
enableCompass: true,
|
||||
// 用于启用或禁用缩放控件。true是启用,false是禁用。默认值为true。如果将选项设置为false,则缩放控件 将不会添加到地图中。
|
||||
|
|
@ -275,4 +277,26 @@ export default class MyCesium {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
setViewerByAllCorner(leftUp, rightUp, rightDown, leftDown) {
|
||||
const [leftUpLon, leftUpLat] = leftUp
|
||||
const [rightUpLon, rightUpLat] = rightUp
|
||||
const [rightDownLon, rightDownLat] = rightDown
|
||||
const [leftDownLon, leftDownLat] = leftDown
|
||||
// 计算矩形区域的边界
|
||||
const west = Math.min(leftDownLon, leftUpLon, rightDownLon, rightUpLon)
|
||||
const east = Math.max(leftDownLon, leftUpLon, rightDownLon, rightUpLon)
|
||||
const south = Math.min(leftDownLat, leftUpLat, rightDownLat, rightUpLat)
|
||||
const north = Math.max(leftDownLat, leftUpLat, rightDownLat, rightUpLat)
|
||||
// 创建矩形范围
|
||||
const rectangle = Cesium.Rectangle.fromDegrees(west, south, east, north)
|
||||
this.viewer.camera.setView({
|
||||
destination: rectangle,
|
||||
orientation: {
|
||||
heading: 0.0,
|
||||
pitch: -Cesium.Math.PI_OVER_TWO,
|
||||
roll: 0.0,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
const keyMaps = {
|
||||
c: 'center',
|
||||
fs: 'flex-start',
|
||||
fe: 'flex-end',
|
||||
sb: 'space-between',
|
||||
sa: 'space-around',
|
||||
n: 'nowrap',
|
||||
w: 'wrap',
|
||||
wr: 'wrap-reverse',
|
||||
}
|
||||
|
||||
export default {
|
||||
bind(el, binding, vnode, oldVnode) {
|
||||
// console.log('----bind----', el, binding, vnode, oldVnode)
|
||||
el.style.display = 'flex'
|
||||
if (binding.modifiers.v === true) {
|
||||
el.style.flexDirection = 'column'
|
||||
}
|
||||
if (binding.value && binding.value instanceof Array) {
|
||||
const [ai, jc, fw] = binding.value
|
||||
if (ai) el.style.alignItems = keyMaps[ai] || ai
|
||||
if (jc) el.style.justifyContent = keyMaps[jc] || jc
|
||||
if (fw) el.style.flexWrap = keyMaps[fw] || fw
|
||||
}
|
||||
},
|
||||
inserted(el, binding, vnode, oldVnode) {
|
||||
// console.log('----inserted----', el, binding, vnode, oldVnode)
|
||||
},
|
||||
update(el, binding, vnode, oldVnode) {
|
||||
// console.log('----update----', el, binding, vnode, oldVnode)
|
||||
if (binding.value && binding.value instanceof Array) {
|
||||
const [ai, jc] = binding.value
|
||||
if (ai) el.style.alignItems = keyMaps[ai] || ai
|
||||
if (jc) el.style.justifyContent = keyMaps[jc] || jc
|
||||
}
|
||||
},
|
||||
componentUpdated(el, binding, vnode, oldVnode) {
|
||||
// console.log('----componentUpdated----', el, binding, vnode, oldVnode)
|
||||
},
|
||||
unbind(el, binding, vnode, oldVnode) {
|
||||
// console.log('----unbind----', el, binding, vnode, oldVnode)
|
||||
},
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ function initLoadingDom(el) {
|
|||
el.loadingDom.style.justifyContent = 'center'
|
||||
}
|
||||
function appendLoadingDom(el) {
|
||||
if (document.body.contains(el.loadingDom)) return
|
||||
const { top, left, width, height } = el.getBoundingClientRect()
|
||||
el.loadingDom.style.top = `${top}px`
|
||||
el.loadingDom.style.left = `${left}px`
|
||||
|
|
@ -18,7 +19,9 @@ function appendLoadingDom(el) {
|
|||
el.loadingDom.innerHTML = `<i aria-label="图标: loading" class="anticon anticon-loading"><svg viewBox="0 0 1024 1024" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="anticon-spin"><path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"></path></svg></i>`
|
||||
}
|
||||
function removeLoadingDom(el) {
|
||||
document.body.removeChild(el.loadingDom)
|
||||
if (document.body.contains(el.loadingDom)) {
|
||||
document.body.removeChild(el.loadingDom)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
@ -45,5 +48,6 @@ export default {
|
|||
},
|
||||
unbind(el, binding, vnode, oldVnode) {
|
||||
// console.log('----unbind----', el, binding, vnode, oldVnode)
|
||||
removeLoadingDom(el)
|
||||
},
|
||||
}
|
||||
|
|
|
|||
137
src/components/Common/Form/DurationPicker.vue
Normal file
137
src/components/Common/Form/DurationPicker.vue
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<div class="duration-picker">
|
||||
<template v-if="_showDay">
|
||||
<a-input-number v-model="day" :min="0" :step="1" />
|
||||
<span>天</span>
|
||||
</template>
|
||||
<template v-if="_showHour">
|
||||
<a-input-number v-model="hour" :min="minHour" :step="1" />
|
||||
<span>小时</span>
|
||||
</template>
|
||||
<template v-if="_showMinute">
|
||||
<a-input-number v-model="minute" :min="minMinute" :step="1" />
|
||||
<span>分钟</span>
|
||||
</template>
|
||||
<template v-if="_showSecond">
|
||||
<a-input-number v-model="second" :min="minSecond" :step="1" />
|
||||
<span>秒</span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: { type: Number, required: true },
|
||||
countFormat: { validator: (v) => ['D', 'H', 'm', 's'].includes(v), default: 'm' },
|
||||
showDay: { type: Boolean, default: true },
|
||||
showHour: { type: Boolean, default: true },
|
||||
showMinute: { type: Boolean, default: true },
|
||||
showSecond: { type: Boolean, default: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rateMap: {
|
||||
D: 1 * 60 * 60 * 24,
|
||||
H: 1 * 60 * 60,
|
||||
m: 1 * 60,
|
||||
s: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
baseRate() {
|
||||
return this.rateMap[this.countFormat]
|
||||
},
|
||||
day: {
|
||||
get() {
|
||||
return Math.floor((this.value * this.baseRate) / this.rateMap['D'])
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', this.value + ((v - this.day) * this.rateMap['D']) / this.baseRate)
|
||||
},
|
||||
},
|
||||
hour: {
|
||||
get() {
|
||||
return Math.floor(((this.value * this.baseRate) % this.rateMap['D']) / this.rateMap['H'])
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', this.value + ((v - this.hour) * this.rateMap['H']) / this.baseRate)
|
||||
},
|
||||
},
|
||||
minute: {
|
||||
get() {
|
||||
return Math.floor(((this.value * this.baseRate) % this.rateMap['H']) / this.rateMap['m'])
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', this.value + ((v - this.minute) * this.rateMap['m']) / this.baseRate)
|
||||
},
|
||||
},
|
||||
second: {
|
||||
get() {
|
||||
return Math.floor(((this.value * this.baseRate) % this.rateMap['m']) / this.rateMap['s'])
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', this.value + ((v - this.second) * this.rateMap['s']) / this.baseRate)
|
||||
},
|
||||
},
|
||||
_showDay() {
|
||||
return this.showDay && ['D', 'H', 'm', 's'].includes(this.countFormat)
|
||||
},
|
||||
_showHour() {
|
||||
return this.showHour && ['H', 'm', 's'].includes(this.countFormat)
|
||||
},
|
||||
_showMinute() {
|
||||
return this.showMinute && ['m', 's'].includes(this.countFormat)
|
||||
},
|
||||
_showSecond() {
|
||||
return this.showSecond && ['s'].includes(this.countFormat)
|
||||
},
|
||||
minHour() {
|
||||
return this.day > 0 ? -1 : 0
|
||||
},
|
||||
minMinute() {
|
||||
return this.day > 0 || this.hour > 0 ? -1 : 0
|
||||
},
|
||||
minSecond() {
|
||||
return this.day > 0 || this.hour > 0 || this.minute > 0 ? -1 : 0
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
::v-deep {
|
||||
.ant-input-number {
|
||||
background-color: #0b293a;
|
||||
border: solid 1px #1d5777;
|
||||
color: #ffffff;
|
||||
}
|
||||
.has-error .ant-input-number:hover {
|
||||
background-color: #0b293a;
|
||||
}
|
||||
.has-error .ant-input-number-affix-wrapper .ant-input-number,
|
||||
.has-error .ant-input-number-affix-wrapper .ant-input-number:hover {
|
||||
background-color: #0b293a;
|
||||
}
|
||||
.ant-input-number-handler-wrap {
|
||||
background-color: #aaaaaa;
|
||||
border-left: solid 1px #1d5777;
|
||||
}
|
||||
.ant-input-number-handler {
|
||||
.anticon {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.ant-input-number-handler:hover {
|
||||
.anticon {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
.ant-input-number-handler-up {
|
||||
}
|
||||
.ant-input-number-handler-down {
|
||||
border-top: solid 1px #1d5777;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
152
src/components/Common/WangEditor/Index.vue
Normal file
152
src/components/Common/WangEditor/Index.vue
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div class="wang-editor">
|
||||
<Toolbar class="wang-editor-toolbar" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode" />
|
||||
<Editor
|
||||
class="wang-editor-textarea"
|
||||
:style="{ height }"
|
||||
v-model="_value"
|
||||
:defaultConfig="editorConfig"
|
||||
:mode="mode"
|
||||
@onCreated="onCreated"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Toolbar, Editor } from '@wangeditor/editor-for-vue'
|
||||
import '@wangeditor/editor/dist/css/style.css'
|
||||
import audioMenuRegister from './audioMenuRegister'
|
||||
|
||||
export default {
|
||||
components: { Toolbar, Editor },
|
||||
props: {
|
||||
value: { validator: () => true, default: '' }, // v-model
|
||||
height: { type: String, default: '300px' }, // 编辑区域高度,应至少300px
|
||||
audio: { type: Boolean, default: false }, // 是否上传音频
|
||||
toolbarKeysEnable: { type: [Array, Boolean], default: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
toolbarConfig: {},
|
||||
editorConfig: {
|
||||
placeholder: '请输入内容...',
|
||||
MENU_CONF: {
|
||||
uploadImage: { customUpload: this.customUpload },
|
||||
uploadVideo: { customUpload: this.customUpload },
|
||||
},
|
||||
},
|
||||
mode: 'default',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
_value: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit(
|
||||
'input',
|
||||
val.replace(/<video ([^>]*)>/g, (matchText, $1) => {
|
||||
if ($1.includes('autoplay')) {
|
||||
return matchText
|
||||
} else {
|
||||
return matchText.replace($1, 'autoplay="true" $&')
|
||||
}
|
||||
})
|
||||
)
|
||||
},
|
||||
},
|
||||
hasAudio() {
|
||||
if (typeof this.toolbarKeysEnable === 'boolean') {
|
||||
return this.toolbarKeysEnable
|
||||
}
|
||||
return this.toolbarKeysEnable.includes('uploadAudio')
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.editor == null) return
|
||||
this.editor.destroy()
|
||||
},
|
||||
created() {
|
||||
this.initToolbarKeys()
|
||||
},
|
||||
methods: {
|
||||
initToolbarKeys() {
|
||||
if (this.toolbarKeysEnable === true) {
|
||||
return
|
||||
}
|
||||
if (this.toolbarKeysEnable === false) {
|
||||
this.$set(this.toolbarConfig, 'toolbarKeys', [])
|
||||
return
|
||||
}
|
||||
this.$set(this.toolbarConfig, 'toolbarKeys', this.toolbarKeysEnable)
|
||||
},
|
||||
onCreated(editor) {
|
||||
if (this.hasAudio && this.audio) {
|
||||
audioMenuRegister(editor, this.toolbarConfig, async ([file]) => {
|
||||
this.customUpload(file, (filePath) => {
|
||||
editor.insertNode({
|
||||
type: 'video',
|
||||
src: filePath,
|
||||
autoplay: true,
|
||||
controls: true,
|
||||
width: '300px',
|
||||
height: '50px',
|
||||
children: [{ text: '' }],
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
this.editor = Object.seal(editor)
|
||||
},
|
||||
/** 自定义上传
|
||||
* @params [file] 上传的文件
|
||||
* @return Promise 最终生成的文件绝对路径
|
||||
*/
|
||||
async customUpload(file, insertFn) {
|
||||
const formdata = new FormData()
|
||||
formdata.append('file', file)
|
||||
const res = await this.$http({
|
||||
url: '/file/upload',
|
||||
method: 'post',
|
||||
data: formdata,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
const filePath = res.data
|
||||
insertFn(filePath)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.wang-editor {
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 5px;
|
||||
::v-deep .button-container {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
.wang-editor.w-e-full-screen-container {
|
||||
z-index: 1000;
|
||||
}
|
||||
.wang-editor:not(.w-e-full-screen-container) {
|
||||
::v-deep .w-e-toolbar {
|
||||
background-color: transparent;
|
||||
}
|
||||
::v-deep .w-e-text-container {
|
||||
background-color: transparent;
|
||||
}
|
||||
::v-deep .w-e-textarea-video-container > video {
|
||||
width: 100%;
|
||||
min-height: 60px;
|
||||
}
|
||||
}
|
||||
.wang-editor-toolbar {
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
}
|
||||
.wang-editor-textarea {
|
||||
min-height: 300px;
|
||||
}
|
||||
</style>
|
||||
81
src/components/Common/WangEditor/Readme.md
Normal file
81
src/components/Common/WangEditor/Readme.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#### WangEditor
|
||||
|
||||
基于wangeditor5二次封装的公用组件,添加上传音频的功能
|
||||
|
||||
#### 官方文档
|
||||
https://www.wangeditor.com/
|
||||
|
||||
#### 组件属性
|
||||
|
||||
1. value / v-model 内容
|
||||
|
||||
2. toolbarKeysEnable 可用工具栏,仅限初始化
|
||||
```
|
||||
布尔值 / 操作按钮key组成的数组
|
||||
false / true / []<key>
|
||||
```
|
||||
|
||||
3. audio 是否启用上传音频的功能
|
||||
```
|
||||
false / true
|
||||
```
|
||||
|
||||
#### 工具栏keys配置
|
||||
|
||||
1. 新增功能按钮
|
||||
```
|
||||
上传音频 uploadAudio
|
||||
```
|
||||
|
||||
2. wangeditor5工具栏默认keys配置
|
||||
```
|
||||
[
|
||||
'headerSelect',
|
||||
'blockquote',
|
||||
'|',
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
{
|
||||
key: 'group-more-style',
|
||||
menuKeys: ['through', 'code', 'sup', 'sub', 'clearStyle'],
|
||||
},
|
||||
'color',
|
||||
'bgColor',
|
||||
'|',
|
||||
'fontSize',
|
||||
'fontFamily',
|
||||
'lineHeight',
|
||||
'|',
|
||||
'bulletedList',
|
||||
'numberedList',
|
||||
'todo',
|
||||
{
|
||||
key: 'group-justify',
|
||||
menuKeys: ['justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify'],
|
||||
},
|
||||
{
|
||||
key: 'group-indent',
|
||||
menuKeys: ['indent', 'delIndent'],
|
||||
},
|
||||
'|',
|
||||
'emotion',
|
||||
'insertLink',
|
||||
{
|
||||
key: 'group-image',
|
||||
menuKeys: ['insertImage', 'uploadImage'],
|
||||
},
|
||||
{
|
||||
key: 'group-video',
|
||||
menuKeys: ['insertVideo', 'uploadVideo'],
|
||||
},
|
||||
'insertTable',
|
||||
'codeBlock',
|
||||
'divider',
|
||||
'|',
|
||||
'undo',
|
||||
'redo',
|
||||
'|',
|
||||
'fullScreen',
|
||||
]
|
||||
```
|
||||
65
src/components/Common/WangEditor/audioMenuRegister.js
Normal file
65
src/components/Common/WangEditor/audioMenuRegister.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { Boot } from '@wangeditor/editor'
|
||||
|
||||
class AudioMenu {
|
||||
title = ''
|
||||
iconSvg = ''
|
||||
tag = ''
|
||||
constructor () {
|
||||
this.title = '上传音频'
|
||||
this.iconSvg =
|
||||
'<svg t="1637634971457" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7981" width="16" height="16"><path d="M983.792981 0H40.211115A40.5504 40.5504 0 0 0 0.002048 40.96v942.08c0 22.664533 17.954133 40.96 40.209067 40.96h943.581866a40.5504 40.5504 0 0 0 40.209067-40.96V40.96c0-22.664533-17.954133-40.96-40.209067-40.96z m-235.383466 207.530667v118.784H581.702315v326.8608c0 81.92-62.190933 148.548267-138.8544 148.548266-76.663467 0-138.8544-63.351467-138.8544-141.448533 0-78.097067 62.122667-141.448533 138.8544-141.448533 31.607467 0 60.074667-2.730667 83.3536 16.110933v-327.68l222.208 0.273067z" fill="#999999" p-id="7982"></path></svg>'
|
||||
this.tag = 'button'
|
||||
}
|
||||
getValue (editor) {
|
||||
return ''
|
||||
}
|
||||
isActive (editor) {
|
||||
return false
|
||||
}
|
||||
isDisabled () {
|
||||
return false
|
||||
}
|
||||
exec (editor, value) {
|
||||
if (this.isDisabled(editor)) return
|
||||
const input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = 'audio/*'
|
||||
input.style.cssText = `display: none;`
|
||||
document.body.appendChild(input)
|
||||
input.click()
|
||||
input.addEventListener('change', (event) => {
|
||||
editor.emit('selectFile', event.target.files)
|
||||
})
|
||||
const wf = () => {
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(input)
|
||||
window.removeEventListener('focus', wf)
|
||||
}, 100)
|
||||
}
|
||||
window.addEventListener('focus', wf)
|
||||
}
|
||||
}
|
||||
|
||||
const MenusList = [{ key: 'uploadAudio', index: 24, Class: AudioMenu }]
|
||||
const AudioMenuRegister = function (editor, toolbarConfig, callback = () => {}) {
|
||||
const allRegisterMenu = editor.getAllMenuKeys()
|
||||
const keys = []
|
||||
for (const item of MenusList) {
|
||||
if (allRegisterMenu.indexOf(item.key) < 0) {
|
||||
Boot.registerMenu({
|
||||
key: item.key,
|
||||
factory () {
|
||||
return new item.Class()
|
||||
},
|
||||
})
|
||||
}
|
||||
keys.push(item.key)
|
||||
}
|
||||
toolbarConfig.insertKeys = {
|
||||
index: MenusList[0].index,
|
||||
keys: keys,
|
||||
}
|
||||
editor.on('selectFile', callback)
|
||||
}
|
||||
|
||||
export default AudioMenuRegister
|
||||
|
|
@ -2,9 +2,11 @@ import ModuleWrapper from './Layout/ModuleWrapper.vue'
|
|||
|
||||
import AntOriginSelect from './Form/AntOriginSelect.vue'
|
||||
import AntOriginTreeSelect from './Form/AntOriginTreeSelect.vue'
|
||||
import DurationPicker from './Form/DurationPicker.vue'
|
||||
|
||||
import WangEditor from './WangEditor/Index.vue'
|
||||
|
||||
import GridBox from './Directives/GridBox'
|
||||
import Flex from './Directives/Flex'
|
||||
import Loading from './Directives/Loading'
|
||||
|
||||
import MyCesium from './Cesium/index'
|
||||
|
|
@ -15,9 +17,11 @@ export default {
|
|||
|
||||
Vue.component('AntOriginSelect', AntOriginSelect)
|
||||
Vue.component('AntOriginTreeSelect', AntOriginTreeSelect)
|
||||
Vue.component('DurationPicker', DurationPicker)
|
||||
|
||||
Vue.component('WangEditor', WangEditor)
|
||||
|
||||
Vue.directive('grid-box', GridBox)
|
||||
Vue.directive('flex', Flex)
|
||||
Vue.directive('loading', Loading)
|
||||
|
||||
window.MyCesium = MyCesium
|
||||
|
|
|
|||
|
|
@ -44,3 +44,7 @@
|
|||
line-height: 64px;
|
||||
background: #001529;
|
||||
}
|
||||
|
||||
.ant-layout-footer {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
<div
|
||||
v-for="block in systemModules"
|
||||
:key="block.moduleCode"
|
||||
:class="['system-block', `system-${block.moduleStatus}`]"
|
||||
v-flex.v="['c', 'sb']"
|
||||
:class="['system-block', 'flex-c', 'ai-c', 'jc-sb', `system-${block.moduleStatus}`]"
|
||||
>
|
||||
<img class="icon" :src="systemIconMap[block.moduleCode]" alt="" />
|
||||
<div class="title">{{ block.moduleName }}</div>
|
||||
|
|
@ -17,7 +16,7 @@
|
|||
</div>
|
||||
</ModuleWrapper>
|
||||
<ModuleWrapper v-if="!loadedScenario" title="全部想定" style="grid-column: 1 / 3">
|
||||
<div class="normal" v-flex.v="['c']" v-loading="loading">
|
||||
<div class="normal flex-c ai-c" v-loading="loading">
|
||||
<div class="scenario-wrapper" v-grid-box="{ columns: [1, 1, 1, 1, 1], rows: [1, 1] }">
|
||||
<div v-for="item in scenarioList" :key="item.id" class="scenario-item">
|
||||
<img
|
||||
|
|
@ -47,16 +46,16 @@
|
|||
<template #extra>
|
||||
<a-button type="primary" shape="circle" icon="close" @click="handleCloseSenario()" />
|
||||
</template>
|
||||
<div class="normal" v-flex.v>
|
||||
<div v-flex="['c', 'sb']" style="margin-bottom: 10px">
|
||||
<div v-flex="['c']">
|
||||
<div class="normal flex-c">
|
||||
<div class="flex ai-c jc-sb" style="margin-bottom: 10px">
|
||||
<div class="flex ai-c">
|
||||
<div style="color: #92bacb">运行方式:</div>
|
||||
<a-select style="width: 240px" v-model="runningMode">
|
||||
<a-select-option value="1">人在回路</a-select-option>
|
||||
<a-select-option value="2">人不在回路</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
<div v-flex="['c']">
|
||||
<div class="flex ai-c">
|
||||
<a-button type="primary" icon="caret-right">开始</a-button>
|
||||
<a-button type="primary" icon="pause">暂停</a-button>
|
||||
<a-button type="primary" icon="stop">中止</a-button>
|
||||
|
|
@ -64,27 +63,75 @@
|
|||
<a-button type="primary" icon="step-forward">快进X1</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scenario-info-wrapper" v-flex.v>
|
||||
<div class="scenario-info-wrapper flex-c">
|
||||
<a-radio-group v-model="radioType" button-style="solid">
|
||||
<a-radio-button value="xdsj">想定时间</a-radio-button>
|
||||
<a-radio-button value="xdqy">想定区域</a-radio-button>
|
||||
<a-radio-button value="xdsm">想定说明</a-radio-button>
|
||||
</a-radio-group>
|
||||
<a-row v-if="radioType === 'xdsj'">想定时间</a-row>
|
||||
<a-row v-if="radioType === 'xdqy'">想定区域</a-row>
|
||||
<a-row v-if="radioType === 'xdsm'" style="flex: 1; padding: 10px 16px; overflow-y: auto">
|
||||
<a-col :span="12" v-flex="['c']">
|
||||
<a-row v-show="radioType === 'xdsj'">
|
||||
<a-col :span="24">
|
||||
<div>想定当前时间:</div>
|
||||
<div>
|
||||
<a-date-picker :value="scenarioDetail.planDate" valueFormat="YYYY-MM-DD" style="width: 100%" />
|
||||
<a-time-picker :value="scenarioDetail.planTime" valueFormat="HH:mm:ss" style="width: 100%" />
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<div>想定开始时间:</div>
|
||||
<div>
|
||||
<a-date-picker :value="scenarioDetail.startDate" valueFormat="YYYY-MM-DD" style="width: 100%" />
|
||||
<a-time-picker :value="scenarioDetail.startTime" valueFormat="HH:mm:ss" style="width: 100%" />
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<div>想定持续时间:</div>
|
||||
<div>
|
||||
<DurationPicker v-model="scenarioDetail.continueTime" />
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<div>想定消耗时间:</div>
|
||||
<div>
|
||||
<DurationPicker v-model="scenarioDetail.wasterTime" />
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div v-show="radioType === 'xdqy'" class="flex-1 flex">
|
||||
<div style="width: 150px">
|
||||
<div>经纬度坐标</div>
|
||||
<div>左上</div>
|
||||
<a-input v-model="scenarioDetail.leftUpLon" style="width: 100%" />
|
||||
<a-input v-model="scenarioDetail.leftUpLat" style="width: 100%" />
|
||||
<div>右上</div>
|
||||
<a-input v-model="scenarioDetail.rightUpLon" style="width: 100%" />
|
||||
<a-input v-model="scenarioDetail.rightUpLat" style="width: 100%" />
|
||||
<div>右下</div>
|
||||
<a-input v-model="scenarioDetail.rightDownLon" style="width: 100%" />
|
||||
<a-input v-model="scenarioDetail.rightDownLat" style="width: 100%" />
|
||||
<div>左下</div>
|
||||
<a-input v-model="scenarioDetail.leftDownLon" style="width: 100%" />
|
||||
<a-input v-model="scenarioDetail.leftDownLat" style="width: 100%" />
|
||||
</div>
|
||||
<div class="flex-1" style="position: relative">
|
||||
<div id="jwd-cesium" style="width: 100%; height: 100%"></div>
|
||||
<div style="position: absolute; left: 0; top: 0; width: 100%; height: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<a-row v-show="radioType === 'xdsm'" style="flex: 1; padding: 10px 16px; overflow-y: auto">
|
||||
<a-col :span="12" class="flex ai-c">
|
||||
<div>想定名称:</div>
|
||||
<div>{{ scenarioDetail.planName }}</div>
|
||||
</a-col>
|
||||
<a-col :span="12" v-flex="['c']">
|
||||
<a-col :span="12" class="flex ai-c">
|
||||
<div>作者:</div>
|
||||
<div>{{ scenarioDetail.author }}</div>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<div>想定说明:</div>
|
||||
<div class="xdsm-wrapper">
|
||||
<iframe v-html="scenarioDetail.planDesc" frameborder="0"></iframe>
|
||||
<WangEditor v-model="scenarioDetail.planDesc" />
|
||||
<!-- <iframe v-html="scenarioDetail.planDesc" frameborder="0"></iframe> -->
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
|
@ -95,7 +142,7 @@
|
|||
<template #extra>
|
||||
<a-checkbox v-model="visible">显示</a-checkbox>
|
||||
</template>
|
||||
<div class="io-event-list" test="1" style="display: block">
|
||||
<div class="io-event-list">
|
||||
<div v-for="item in ioEventList" :key="item.id" class="io-event-item">
|
||||
<span style="margin-right: 20px">{{ item.eventTime }}</span>
|
||||
<span>{{ item.eventDesc }}</span>
|
||||
|
|
@ -122,8 +169,9 @@ export default {
|
|||
},
|
||||
|
||||
runningMode: '1',
|
||||
radioType: 'xdsm',
|
||||
radioType: 'xdsj',
|
||||
scenarioDetail: {},
|
||||
cesium: null,
|
||||
|
||||
visible: false,
|
||||
ioEventList: [
|
||||
|
|
@ -175,12 +223,30 @@ export default {
|
|||
url: `/baseData/scenario/${item.id}`,
|
||||
method: 'get',
|
||||
})
|
||||
this.scenarioDetail = JSON.parse(res.data.data.content)
|
||||
this.scenarioDetail = JSON.parse(res.data.content)
|
||||
console.log('----', this.scenarioDetail)
|
||||
this.loadedScenario = item.id
|
||||
this.$nextTick(() => {
|
||||
this.initCesium()
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
initCesium() {
|
||||
const { leftUpLat, rightUpLat, rightDownLat, leftDownLat, leftUpLon, rightUpLon, rightDownLon, leftDownLon } =
|
||||
this.scenarioDetail
|
||||
const centerLon = (leftUpLon + rightUpLon + rightDownLon + leftDownLon) / 4
|
||||
const centerLat = (leftUpLat + rightUpLat + rightDownLat + leftDownLat) / 4
|
||||
this.cesium = new window.MyCesium('jwd-cesium', { center: [centerLon, centerLat] })
|
||||
|
||||
this.cesium.setViewerByAllCorner(
|
||||
[leftUpLon, leftUpLat],
|
||||
[rightUpLon, rightUpLat],
|
||||
[rightDownLon, rightDownLat],
|
||||
[leftDownLon, leftDownLat]
|
||||
)
|
||||
},
|
||||
handleCloseSenario() {
|
||||
this.loadedScenario = ''
|
||||
},
|
||||
|
|
@ -238,8 +304,6 @@ export default {
|
|||
.scenario-item {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.scenario-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -298,15 +362,51 @@ export default {
|
|||
.xdsm-wrapper {
|
||||
background-color: #ffffff;
|
||||
color: #666666;
|
||||
padding: 8px 10px;
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
::v-deep {
|
||||
.ant-calendar-picker-input,
|
||||
.ant-time-picker-input {
|
||||
background-color: #0b293a;
|
||||
border: solid 1px #1d5777;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.ant-calendar-picker {
|
||||
color: #ffffff;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.ant-time-picker {
|
||||
margin: 5px 0;
|
||||
}
|
||||
.ant-calendar-picker::v-deep {
|
||||
.anticon {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.ant-calendar-picker:hover::v-deep {
|
||||
.anticon {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
.ant-time-picker::v-deep {
|
||||
.anticon {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.ant-time-picker:hover::v-deep {
|
||||
.anticon {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
.ant-input {
|
||||
background-color: #0b293a;
|
||||
border: solid 1px #1d5777;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.io-event-list {
|
||||
|
|
@ -315,7 +415,6 @@ export default {
|
|||
background-color: #082532;
|
||||
padding: 20px;
|
||||
overflow-y: scroll;
|
||||
display: block !important;
|
||||
.io-event-item {
|
||||
padding: 10px 0;
|
||||
font-size: 16px;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="simulation-scene-page" v-flex.v>
|
||||
<div class="simulation-scene-page flex-c">
|
||||
<div v-if="title" class="simulation-scene-header">
|
||||
{{ title }}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,23 @@
|
|||
<template>
|
||||
<div class="scene-editing-page" v-grid-box="{ columns: ['320px', 1, '320px'], rows: [45, 30, 25], gap: '0px' }">
|
||||
<ModuleWrapper title="作战/保障力量" style="grid-column: 1 / 2; grid-row: 1 / 2">
|
||||
<div class="normal" style="padding: 5px">
|
||||
<a-tree :treeData="zb.zbTreeData"></a-tree>
|
||||
<div class="normal" style="padding: 5px; overflow-y: auto">
|
||||
<a-tree
|
||||
:treeData="zb.zbTreeData"
|
||||
:selectedKeys.sync="zb.selectedKeys"
|
||||
:replaceFields="{ children: 'children', title: 'name', key: 'id' }"
|
||||
@select="handleSelectTree"
|
||||
></a-tree>
|
||||
</div>
|
||||
</ModuleWrapper>
|
||||
<ModuleWrapper title="装备元素" style="grid-column: 1 / 2; grid-row: 2 / 4">
|
||||
<div class="normal" style="padding: 5px" v-flex.v>
|
||||
<div class="normal flex-c" style="padding: 5px">
|
||||
<a-input-search v-model="ys.keyword" placeholder="输入关键词搜索..." @search="onSearch" />
|
||||
<div style="height: 0; flex: 1; overflow-y: auto">
|
||||
<a-row>
|
||||
<template v-for="item in ys.ysList">
|
||||
<a-col :key="item.id" :span="24">{{ item.title }}</a-col>
|
||||
<a-col v-for="it in item.children" :key="it.id" :span="12" v-flex.v="['c']">
|
||||
<a-col v-for="it in item.children" :key="it.id" :span="12" class="flex-c ai-c">
|
||||
<img class="ys-image" :src="it.image" alt="" />
|
||||
<span>{{ it.title }}</span>
|
||||
</a-col>
|
||||
|
|
@ -31,11 +36,11 @@
|
|||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<img class="image" :src="zt.image" />
|
||||
<div class="name">{{ zt.name }}</div>
|
||||
<div v-for="item in zt.ztList" :key="item.label" class="zt-item" v-flex="['c']">
|
||||
<div v-for="item in zt.ztList" :key="item.label" class="zt-item flex ai-c">
|
||||
<span>{{ item.label }}:</span>
|
||||
<img :src="item.icon" alt="" />
|
||||
<span>{{ item.text }}</span>
|
||||
<div v-if="'progress' in item" class="progress-bar" v-flex>
|
||||
<div v-if="'progress' in item" class="progress-bar flex">
|
||||
<div class="progress" :style="{ width: item.progress }"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -45,7 +50,7 @@
|
|||
<ModuleWrapper title="作战单元武器" style="grid-column: 3 / 4; grid-row: 3 / 4">
|
||||
<div class="normal" style="padding: 15px 0">
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<div v-for="(item, index) in zzdywq.wqList" :key="index" class="wq-item" v-flex>
|
||||
<div v-for="(item, index) in zzdywq.wqList" :key="index" class="wq-item flex">
|
||||
<span>{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -60,42 +65,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
cesium: null,
|
||||
zb: {
|
||||
zbTreeData: [
|
||||
{
|
||||
key: '1',
|
||||
title: '红方',
|
||||
children: [
|
||||
{
|
||||
key: '1-1',
|
||||
title: '作战力量',
|
||||
children: [
|
||||
{ key: '1-1-1', title: '左翼夺控群火力分队' },
|
||||
{ key: '1-1-2', title: '左翼攻击分队' },
|
||||
{ key: '1-1-3', title: '右翼攻击分队' },
|
||||
{ key: '1-1-4', title: '右翼夺控群反装甲分队' },
|
||||
{ key: '1-1-5', title: '防空火力队' },
|
||||
{ key: '1-1-6', title: '左翼牵制群右翼攻击分队' },
|
||||
{ key: '1-1-7', title: '电子对抗兵队超短波干扰分队' },
|
||||
{ key: '1-1-8', title: '纵深夺控群火力分队' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: '1-2',
|
||||
title: '保障力量',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
title: '蓝方',
|
||||
children: [
|
||||
{ key: '1-1', title: '作战力量' },
|
||||
{ key: '1-2', title: '保障力量' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
scenarioId: null,
|
||||
zb: { zbTreeData: [], selectedKeys: [] },
|
||||
ys: {
|
||||
keyword: '',
|
||||
ysList: [
|
||||
|
|
@ -159,8 +130,46 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.cesium = new window.MyCesium('cesium-container')
|
||||
this.scenarioId = 2733
|
||||
this.getZbTree()
|
||||
},
|
||||
methods: {
|
||||
async getZbTree() {
|
||||
try {
|
||||
const res = await this.$http({
|
||||
url: `/scenario/power/${this.scenarioId}`,
|
||||
method: 'get',
|
||||
})
|
||||
this.zb.zbTreeData = [
|
||||
{
|
||||
id: '1',
|
||||
name: '红方',
|
||||
selectable: false,
|
||||
children: [
|
||||
{ id: '1-1', name: '作战力量', selectable: false, children: res.data.red.fight },
|
||||
{ id: '1-2', name: '保障力量', selectable: false, children: res.data.red.guarantee },
|
||||
{ id: '1-3', name: '指挥力量', selectable: false, children: res.data.red.command },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '蓝方',
|
||||
selectable: false,
|
||||
children: [
|
||||
{ id: '2-1', name: '作战力量', selectable: false, children: res.data.red.fight },
|
||||
{ id: '2-2', name: '保障力量', selectable: false, children: res.data.red.guarantee },
|
||||
{ id: '2-3', name: '指挥力量', selectable: false, children: res.data.red.command },
|
||||
],
|
||||
},
|
||||
]
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
handleSelectTree(selectedKeys, { node }) {
|
||||
console.log(...arguments)
|
||||
// node.dataRef
|
||||
},
|
||||
onSearch(e) {
|
||||
console.log('----', e, e.target.value)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
<ModuleWrapper title="资源" style="grid-column: 3 / 4; grid-row: 3 / 4">
|
||||
<div class="normal" style="padding: 15px 0">
|
||||
<div style="height: 100%; padding: 0 15px; overflow-y: auto">
|
||||
<div v-for="item in zy.zyList" :key="item.label" class="zy-item" v-flex>
|
||||
<div v-for="item in zy.zyList" :key="item.label" class="zy-item flex">
|
||||
<span>{{ item.label }}:</span>
|
||||
<span style="flex: 1; white-space: nowrap; overflow: hidden" v-html="zy.placeholder"></span>
|
||||
<span>{{ item.text }}</span>
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@
|
|||
<div
|
||||
v-for="(block, index) in systemModules"
|
||||
:key="block.moduleCode"
|
||||
:class="['system-block', `system-${block.moduleStatus}`]"
|
||||
:class="['system-block', 'flex-c', 'ai-c', 'jc-sb', `system-${block.moduleStatus}`]"
|
||||
:style="blockStyleMap[index]"
|
||||
v-flex.v="['c', 'sb']"
|
||||
@click="handleClick(block)"
|
||||
>
|
||||
<img class="icon" :src="systemIconMap[block.moduleCode]" alt="" />
|
||||
|
|
|
|||
|
|
@ -395,13 +395,13 @@ export default {
|
|||
}
|
||||
}
|
||||
::v-deep {
|
||||
.ant-input-lg {
|
||||
.ant-input {
|
||||
height: 52px;
|
||||
background-color: #0b293a;
|
||||
border: solid 1px #1d5777;
|
||||
color: #ffffff;
|
||||
}
|
||||
.ant-input-lg:-webkit-autofill {
|
||||
.ant-input:-webkit-autofill {
|
||||
-webkit-text-fill-color: #fff !important;
|
||||
transition: background-color 5000s ease-in-out 0s;
|
||||
caret-color: #acfff2;
|
||||
|
|
@ -415,11 +415,11 @@ export default {
|
|||
.ant-input-suffix .anticon:hover {
|
||||
color: #ffffffcc;
|
||||
}
|
||||
.has-error .ant-input-lg:hover {
|
||||
.has-error .ant-input:hover {
|
||||
background-color: #0b293a;
|
||||
}
|
||||
.has-error .ant-input-affix-wrapper .ant-input-lg,
|
||||
.has-error .ant-input-affix-wrapper .ant-input-lg:hover {
|
||||
.has-error .ant-input-affix-wrapper .ant-input,
|
||||
.has-error .ant-input-affix-wrapper .ant-input:hover {
|
||||
background-color: #0b293a;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user