mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-01-03 20:35:29 +08:00
JeecgBoot 3.3.0 版本发布,基于代码生成器的企业级低代码平台
This commit is contained in:
@ -387,7 +387,7 @@
|
||||
<a-menu-item v-if="col.allowDownload!==false" @click="handleClickDownloadFile(id)">
|
||||
<span><a-icon type="download"/> 下载</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="col.allowRemove!==false" @click="handleClickDelFile(id)">
|
||||
<a-menu-item v-if="col.allowRemove!==false" @click="handleClickDelFile(id, row, col)">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
@ -475,7 +475,7 @@
|
||||
<a-menu-item v-if="col.allowDownload!==false" @click="handleClickDownFileByUrl(id)">
|
||||
<span><a-icon type="download"/> 下载</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleClickDelFile(id)">
|
||||
<a-menu-item @click="handleClickDelFile(id, row, col)">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleMoreOperation(id,col,col)">
|
||||
@ -532,7 +532,7 @@
|
||||
<a-menu-item v-if="col.allowDownload!==false" @click="handleClickDownFileByUrl(id)">
|
||||
<span><a-icon type="download"/> 下载</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleClickDelFile(id)">
|
||||
<a-menu-item @click="handleClickDelFile(id, row, col)">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleMoreOperation(id,'img',col)">
|
||||
@ -1865,6 +1865,8 @@
|
||||
})
|
||||
// 强制更新formValues
|
||||
this.forceUpdateFormValues()
|
||||
// 【issues/3828】重新计算统计列
|
||||
this.recalcAllStatisticsColumns()
|
||||
},
|
||||
/**
|
||||
* 设置单个组件的值
|
||||
@ -2590,8 +2592,9 @@
|
||||
return id;
|
||||
},
|
||||
|
||||
handleClickDelFile(id) {
|
||||
handleClickDelFile(id, row, col) {
|
||||
this.uploadValues[id] = null
|
||||
this.elemValueChange(col.type, row, col, null);
|
||||
},
|
||||
handleClickDownloadFile(id) {
|
||||
let { path } = this.uploadValues[id] || {}
|
||||
@ -3074,7 +3077,11 @@
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// 根据id获取dataSource中的一行数据
|
||||
getOriginData(id){
|
||||
return this.dataSource.filter(item=>item.id == id);
|
||||
},
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
||||
@ -68,6 +68,9 @@
|
||||
branding: false,
|
||||
menubar: false,
|
||||
toolbar_drawer: false,
|
||||
//update-begin-author:taoyan date:2022-5-6 for: issues/I4BCC3 富文本编辑器在服务器图片上传是相对路径
|
||||
convert_urls: false,
|
||||
//update-end-author:taoyan date:2022-5-6 for: issues/I4BCC3 富文本编辑器在服务器图片上传是相对路径
|
||||
images_upload_handler: (blobInfo, success) => {
|
||||
let formData = new FormData()
|
||||
formData.append('file', blobInfo.blob(), blobInfo.filename());
|
||||
|
||||
@ -49,7 +49,8 @@
|
||||
|
||||
.jeecg-form-container-disabled .ant-upload-select{display:none}
|
||||
.jeecg-form-container-disabled .ant-upload-list{cursor:grabbing}
|
||||
.jeecg-form-container-disabled fieldset[disabled] .ant-upload-list{
|
||||
.jeecg-form-container-disabled fieldset[disabled] .ant-upload-list,
|
||||
.jeecg-form-container-disabled fieldset[disabled] iframe{
|
||||
-ms-pointer-events: auto !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
v-on="$listeners"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
destroyOnClose
|
||||
:destroyOnClose="destroyOnClose"
|
||||
>
|
||||
|
||||
<slot></slot>
|
||||
@ -49,13 +49,17 @@
|
||||
|
||||
import { getClass, getStyle } from '@/utils/props-util'
|
||||
import { triggerWindowResizeEvent } from '@/utils/util'
|
||||
import ModalDragMixins from './ModalDragMixins'
|
||||
|
||||
export default {
|
||||
name: 'JModal',
|
||||
mixins: [ModalDragMixins],
|
||||
props: {
|
||||
title: String,
|
||||
// 可使用 .sync 修饰符
|
||||
visible: Boolean,
|
||||
// 是否开启拖拽
|
||||
draggable: Boolean,
|
||||
// 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
|
||||
fullscreen: {
|
||||
type: Boolean,
|
||||
@ -71,6 +75,11 @@ export default {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 关闭时销毁弹窗内容
|
||||
destroyOnClose: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -162,6 +171,16 @@ export default {
|
||||
toggleFullscreen() {
|
||||
this.innerFullscreen = !this.innerFullscreen
|
||||
triggerWindowResizeEvent()
|
||||
// 全屏的时候禁止拖动
|
||||
if (this.innerFullscreen) {
|
||||
// 还原弹窗的位置为0,0
|
||||
this.setModalPosition(0, 0, false)
|
||||
this.dragSettings.headerEl.style.cursor = null
|
||||
} else {
|
||||
// 取消全屏的时候,将弹窗移动到上次记录的位置
|
||||
this.resetModalPosition()
|
||||
this.dragSettings.headerEl.style.cursor = 'move'
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,152 @@
|
||||
import {getRefPromise} from '@/utils/util'
|
||||
|
||||
/** JModal 的拖拽混入 */
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 拖动配置
|
||||
dragSettings: {
|
||||
// 上次拖动top记录
|
||||
top: null,
|
||||
// 上次拖动left记录
|
||||
left: null,
|
||||
wrapEl: null,
|
||||
dragEl: null,
|
||||
headerEl: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible() {
|
||||
if (!this.visible || !this.draggable) {
|
||||
return
|
||||
}
|
||||
this.handleDrag()
|
||||
},
|
||||
draggable() {
|
||||
if (!this.visible || !this.draggable) {
|
||||
return
|
||||
}
|
||||
this.handleDrag()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async handleDrag() {
|
||||
let modalRef = await getRefPromise(this, 'modal')
|
||||
const dragWraps = modalRef.$el.querySelectorAll('.ant-modal-wrap')
|
||||
let wrapEl = dragWraps[0]
|
||||
if (!wrapEl) return
|
||||
this.dragSettings.wrapEl = wrapEl
|
||||
this.dragSettings.dragEl = wrapEl.querySelector('.ant-modal')
|
||||
this.dragSettings.headerEl = wrapEl.querySelector('.ant-modal-header')
|
||||
const display = getStyle(wrapEl, 'display')
|
||||
const draggable = wrapEl.getAttribute('data-drag')
|
||||
if (display !== 'none') {
|
||||
// 拖拽位置
|
||||
if (draggable === null || this.destroyOnClose) {
|
||||
this.enableDrag(wrapEl)
|
||||
}
|
||||
}
|
||||
},
|
||||
/** 启用拖拽 */
|
||||
enableDrag() {
|
||||
let {wrapEl, dragEl, headerEl} = this.dragSettings
|
||||
if (!wrapEl) return
|
||||
wrapEl.setAttribute('data-drag', this.draggable)
|
||||
if (!headerEl || !dragEl || !this.draggable) return
|
||||
|
||||
// 还原上一次移动的位置
|
||||
this.resetModalPosition()
|
||||
|
||||
headerEl.style.cursor = 'move'
|
||||
headerEl.onmousedown = (e) => {
|
||||
if (!e) return
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX
|
||||
const disY = e.clientY
|
||||
const screenWidth = document.body.clientWidth // body当前宽度
|
||||
const screenHeight = document.documentElement.clientHeight // 可见区域高度(应为body高度,可某些环境下无法获取)
|
||||
|
||||
const dragElWidth = dragEl.offsetWidth // 对话框宽度
|
||||
const dragElHeight = dragEl.offsetHeight // 对话框高度
|
||||
|
||||
const minDragElLeft = dragEl.offsetLeft
|
||||
|
||||
const maxDragElLeft = screenWidth - dragEl.offsetLeft - dragElWidth
|
||||
const minDragElTop = dragEl.offsetTop
|
||||
const maxDragElTop = screenHeight - dragEl.offsetTop - dragElHeight
|
||||
// 获取到的值带px 正则匹配替换
|
||||
const domLeft = getStyle(dragEl, 'left')
|
||||
const domTop = getStyle(dragEl, 'top')
|
||||
let styL = +domLeft
|
||||
let styT = +domTop
|
||||
|
||||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||
if (domLeft.includes('%')) {
|
||||
styL = +document.body.clientWidth * (+domLeft.replace(/%/g, '') / 100)
|
||||
styT = +document.body.clientHeight * (+domTop.replace(/%/g, '') / 100)
|
||||
} else {
|
||||
styL = +domLeft.replace(/px/g, '')
|
||||
styT = +domTop.replace(/px/g, '')
|
||||
}
|
||||
|
||||
document.onmousemove = (e) => {
|
||||
// 全屏时不触发移动方法
|
||||
if (this.innerFullscreen) {
|
||||
return
|
||||
}
|
||||
// 通过事件委托,计算移动的距离
|
||||
let left = e.clientX - disX
|
||||
let top = e.clientY - disY
|
||||
|
||||
// 边界处理
|
||||
if (-left > minDragElLeft) {
|
||||
left = -minDragElLeft
|
||||
} else if (left > maxDragElLeft) {
|
||||
left = maxDragElLeft
|
||||
}
|
||||
|
||||
if (-top > minDragElTop) {
|
||||
top = -minDragElTop
|
||||
} else if (top > maxDragElTop) {
|
||||
top = maxDragElTop
|
||||
}
|
||||
|
||||
this.setModalPosition(top + styT, left + styL)
|
||||
}
|
||||
|
||||
document.onmouseup = () => {
|
||||
document.onmousemove = null
|
||||
document.onmouseup = null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 移动弹窗位置
|
||||
* @param top 顶部位置
|
||||
* @param left 左侧位置
|
||||
* @param remember 是否记录位置,默认 true
|
||||
*/
|
||||
setModalPosition(top, left, remember = true) {
|
||||
// 记录移动位置
|
||||
if (remember) {
|
||||
this.dragSettings.top = top
|
||||
this.dragSettings.left = left
|
||||
}
|
||||
// 移动当前元素
|
||||
this.dragSettings.dragEl.style.cssText += `;left:${left}px;top:${top}px;`
|
||||
},
|
||||
/**
|
||||
* 将弹窗移动到上次记录的位置
|
||||
*/
|
||||
resetModalPosition() {
|
||||
this.setModalPosition(this.dragSettings.top, this.dragSettings.left, false)
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
function getStyle(dom, attr) {
|
||||
return getComputedStyle(dom)[attr]
|
||||
}
|
||||
@ -29,6 +29,7 @@
|
||||
@cancel="handleCancel"
|
||||
:mask="false"
|
||||
:fullscreen="izMobile"
|
||||
draggable
|
||||
class="j-super-query-modal"
|
||||
style="top:5%;max-height: 95%;"
|
||||
>
|
||||
@ -163,8 +164,10 @@
|
||||
<a-time-picker v-else-if="item.type==='time'" :value="item.val ? moment(item.val,'HH:mm:ss') : null" format="HH:mm:ss" style="width: 100%" @change="(time,value)=>item.val=value"/>
|
||||
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
|
||||
<a-select v-else-if="item.type=='switch'" placeholder="请选择" v-model="item.val">
|
||||
<a-select-option value="Y">是</a-select-option>
|
||||
<a-select-option value="N">否</a-select-option>
|
||||
<!-- update-begin-author:taoyan for: VUEN-242【online表单 高级查询】开关组件设置扩展参数为[0,1] 时,高级查询选择后查询仍然是Y/N -->
|
||||
<a-select-option :value="item.extendOption[0]">是</a-select-option>
|
||||
<a-select-option :value="item.extendOption[1]">否</a-select-option>
|
||||
<!-- update-end-author:taoyan for: VUEN-242【online表单 高级查询】开关组件设置扩展参数为[0,1] 时,高级查询选择后查询仍然是Y/N -->
|
||||
</a-select>
|
||||
<a-input v-else v-model="item.val" placeholder="请输入值"/>
|
||||
</a-col>
|
||||
@ -426,10 +429,17 @@
|
||||
item['dictCode'] = dictCode
|
||||
item['dictTable'] = dictTable
|
||||
item['dictText'] = dictText
|
||||
//update-begin-author:taoyan for: VUEN-242【online表单 高级查询】开关组件设置扩展参数为[0,1] 时,高级查询选择后查询仍然是Y/N
|
||||
item['extendOption'] = node.dataRef.extendOption || ['Y', 'N']
|
||||
//update-begin-author:taoyan for: VUEN-242【online表单 高级查询】开关组件设置扩展参数为[0,1] 时,高级查询选择后查询仍然是Y/N
|
||||
item['customReturnField'] = customReturnField
|
||||
if (popup) {
|
||||
item['popup'] = popup
|
||||
}
|
||||
// 格式化字符串,一般用于高级查询的日期格式处理
|
||||
if (node.dataRef.formatStr) {
|
||||
item['formatStr'] = node.dataRef.formatStr
|
||||
}
|
||||
this.$set(item, 'val', undefined)
|
||||
},
|
||||
handleOpen() {
|
||||
|
||||
@ -71,6 +71,12 @@
|
||||
let className = target.className || ''
|
||||
className = typeof className === 'string' ? className : className.toString()
|
||||
|
||||
// 获取 td 父级
|
||||
let td = getParentNodeByTagName(target, 'td');
|
||||
// 点击的是拖拽排序列,不做处理
|
||||
if (td && td.querySelector('.j-vxe-ds-icons')) {
|
||||
return
|
||||
}
|
||||
// 点击的是expand,不做处理
|
||||
if (className.includes('vxe-table--expand-btn')) {
|
||||
return
|
||||
|
||||
@ -763,6 +763,8 @@ export default {
|
||||
console.warn(`JVxeTable.setValues:必须传递数组`)
|
||||
return
|
||||
}
|
||||
// 是否更新了数据
|
||||
let updated = false
|
||||
values.forEach((item, idx) => {
|
||||
let {rowKey, values: record} = item
|
||||
let {row} = this.getIfRowById(rowKey)
|
||||
@ -775,6 +777,7 @@ export default {
|
||||
let oldValue = row[colKey]
|
||||
let newValue = record[colKey]
|
||||
if (newValue !== oldValue) {
|
||||
updated = true
|
||||
this.$set(row, colKey, newValue)
|
||||
// 触发 valueChange 事件
|
||||
this.trigger('valueChange', {
|
||||
@ -791,6 +794,14 @@ export default {
|
||||
}
|
||||
})
|
||||
})
|
||||
// 【issues/3828】数据更新后,重新计算统计列
|
||||
if (updated && this.statistics.has) {
|
||||
this.$nextTick(async () => {
|
||||
let {xTable} = this.$refs.vxe.$refs;
|
||||
await xTable.updateCache(true);
|
||||
await xTable.updateData();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取所有的数据,包括values、deleteIds */
|
||||
@ -1406,7 +1417,7 @@ const fooPatterns = [
|
||||
{title: '字母', value: 's', pattern: /^[A-Z|a-z]+$/},
|
||||
{title: '数字', value: 'n', pattern: /^-?\d+(\.?\d+|\d?)$/},
|
||||
{title: '整数', value: 'z', pattern: /^-?\d+$/},
|
||||
{title: '金额', value: 'money', pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/},
|
||||
{title: '金额', value: 'money', pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,5}))$/},
|
||||
]
|
||||
|
||||
/** 旧版handler转为新版Validator */
|
||||
|
||||
@ -133,6 +133,10 @@
|
||||
value['message'] = file.response.message || '未知错误'
|
||||
}
|
||||
this.innerFile = value
|
||||
// issues/I5FTO6 JVxeTypes.upload 文件上传的时候,触发不了事件
|
||||
if (value.path) {
|
||||
this.handleChangeCommon(fileGetValue(value));
|
||||
}
|
||||
},
|
||||
|
||||
// handleClickPreviewFile(id) {
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import store from '@/store/'
|
||||
import { randomUUID } from '@/utils/util'
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
|
||||
// vxe socket
|
||||
const vs = {
|
||||
// 页面唯一 id,用于标识同一用户,不同页面的websocket
|
||||
@ -52,7 +55,10 @@ const vs = {
|
||||
const domain = window._CONFIG['domianURL'].replace('https://', 'wss://').replace('http://', 'ws://')
|
||||
const url = `${domain}/vxeSocket/${userId}/${this.pageId}`
|
||||
|
||||
this.ws = new WebSocket(url)
|
||||
//update-begin-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
let token = Vue.ls.get(ACCESS_TOKEN)
|
||||
this.ws = new WebSocket(url, [token])
|
||||
//update-end-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
this.ws.onopen = this.on.open.bind(this)
|
||||
this.ws.onerror = this.on.error.bind(this)
|
||||
this.ws.onmessage = this.on.message.bind(this)
|
||||
|
||||
@ -7,12 +7,15 @@
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||
import { TENANT_ID } from "@/store/mutation-types"
|
||||
import PageLayout from '../page/PageLayout'
|
||||
import RouteView from './RouteView'
|
||||
import {mixinDevice} from '@/utils/mixin'
|
||||
|
||||
export default {
|
||||
name: "IframePageContent",
|
||||
inject:['closeCurrent'],
|
||||
mixins: [mixinDevice],
|
||||
data () {
|
||||
return {
|
||||
url: "",
|
||||
@ -47,10 +50,21 @@
|
||||
} else {
|
||||
this.url = url
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai ---date:20220711 for:[VUEN-1638]菜单tenantId需要动态生成------------
|
||||
let tenantIdStr = '${tenantId}'
|
||||
let tenantUrl = this.url
|
||||
if (tenantUrl.indexOf(tenantIdStr) != -1) {
|
||||
let tenantId = Vue.ls.get(TENANT_ID)
|
||||
this.url = tenantUrl.replace(tenantIdStr, tenantId)
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220711 for:[VUEN-1638]菜单tenantId需要动态生成--------------
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
// 是否允许打开外部页面,需要非Mobile模式且打开多页签模式
|
||||
let allowOpen = !this.isMobile() && this.$store.state.app.multipage
|
||||
/*update_begin author:wuxianquan date:20190908 for:判断打开方式,新窗口打开时this.$route.meta.internalOrExternal==true */
|
||||
if(this.$route.meta.internalOrExternal != undefined && this.$route.meta.internalOrExternal==true){
|
||||
if(allowOpen && this.$route.meta.internalOrExternal === true){
|
||||
this.closeCurrent();
|
||||
window.open(this.url);
|
||||
}
|
||||
|
||||
@ -70,7 +70,9 @@
|
||||
/* update_begin author:wuxianquan date:20190828 for: 关闭当前tab页,供子页面调用 ->望菜单能配置外链,直接弹出新页面而不是嵌入iframe #428 */
|
||||
provide(){
|
||||
return{
|
||||
closeCurrent:this.closeCurrent
|
||||
closeCurrent:this.closeCurrent,
|
||||
changeTitle: this.changeTitle,
|
||||
changeTabTitle: this.changeTabTitle,
|
||||
}
|
||||
},
|
||||
/* update_end author:wuxianquan date:20190828 for: 关闭当前tab页,供子页面调用->望菜单能配置外链,直接弹出新页面而不是嵌入iframe #428 */
|
||||
@ -176,6 +178,10 @@
|
||||
// update-end-author:sunjianlei date:20191223 for: 修复从单页模式切换回多页模式后首页不居第一位的 BUG
|
||||
|
||||
// update-begin-author:sunjianlei date:20200120 for: 动态更改页面标题
|
||||
/**
|
||||
* 修改当前页面的窗口标题
|
||||
* @param title 要修改的新标题
|
||||
*/
|
||||
changeTitle(title) {
|
||||
let projectTitle = "Jeecg-Boot 企业级低代码平台"
|
||||
// 首页特殊处理
|
||||
@ -185,6 +191,19 @@
|
||||
document.title = title + ' · ' + projectTitle
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 修改tab标签的标题
|
||||
* @param title 要修改的新标题
|
||||
* @param fullPath 要修改的路由全路径,如果不填就是修改当前路由
|
||||
*/
|
||||
changeTabTitle(title, fullPath = '') {
|
||||
if (title) {
|
||||
let currentRoute = this.pageList.find((r) => r.fullPath === (fullPath ? fullPath : this.$route.fullPath))
|
||||
if (currentRoute != null) {
|
||||
currentRoute.meta = {...currentRoute.meta, title}
|
||||
}
|
||||
}
|
||||
},
|
||||
// update-end-author:sunjianlei date:20200120 for: 动态更改页面标题
|
||||
|
||||
changePage(key) {
|
||||
|
||||
@ -81,7 +81,8 @@
|
||||
import ShowAnnouncement from './ShowAnnouncement'
|
||||
import store from '@/store/'
|
||||
import DynamicNotice from './DynamicNotice'
|
||||
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: "HeaderNotice",
|
||||
@ -107,6 +108,8 @@
|
||||
stopTimer:false,
|
||||
websock: null,
|
||||
lockReconnect:false,
|
||||
//websocket错误连接次数
|
||||
wsConnectErrorTime:1,
|
||||
heartCheck:null,
|
||||
formData:{},
|
||||
openPath:''
|
||||
@ -201,7 +204,10 @@
|
||||
var userId = store.getters.userInfo.id;
|
||||
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
|
||||
//console.log(url);
|
||||
this.websock = new WebSocket(url);
|
||||
//update-begin-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
let token = Vue.ls.get(ACCESS_TOKEN)
|
||||
this.websock = new WebSocket(url, [token]);
|
||||
//update-end-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
this.websock.onopen = this.websocketOnopen;
|
||||
this.websock.onerror = this.websocketOnerror;
|
||||
this.websock.onmessage = this.websocketOnmessage;
|
||||
@ -213,12 +219,21 @@
|
||||
//this.heartCheck.reset().start();
|
||||
},
|
||||
websocketOnerror: function (e) {
|
||||
console.log("WebSocket连接发生错误");
|
||||
console.log("WebSocket连接发生错误,第%s次",this.wsConnectErrorTime);
|
||||
|
||||
this.wsConnectErrorTime = this.wsConnectErrorTime + 1;
|
||||
if(this.wsConnectErrorTime>5){
|
||||
console.log("WebSocket连接错误超过5次,就不再重新连了!");
|
||||
this.lockReconnect = true
|
||||
return;
|
||||
}
|
||||
|
||||
this.reconnect();
|
||||
},
|
||||
websocketOnmessage: function (e) {
|
||||
console.log("-----接收消息-------",e.data);
|
||||
var data = eval("(" + e.data + ")"); //解析对象
|
||||
this.voiceBroadcast(data.msgTxt)
|
||||
if(data.cmd == "topic"){
|
||||
//系统通知
|
||||
this.loadData();
|
||||
@ -243,7 +258,13 @@
|
||||
console.log("send failed (" + err.code + ")");
|
||||
}
|
||||
},
|
||||
|
||||
//语音播报系统通知
|
||||
voiceBroadcast(text){
|
||||
var url = "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=" + encodeURI(text); // baidu文字转语音
|
||||
var voiceContent = new Audio(url);
|
||||
voiceContent.src = url;
|
||||
voiceContent.play();
|
||||
},
|
||||
openNotification (data) {
|
||||
var text = data.msgTxt;
|
||||
const key = `open${Date.now()}`;
|
||||
@ -275,7 +296,7 @@
|
||||
console.info("尝试重连...");
|
||||
that.initWebSocket();
|
||||
that.lockReconnect = false;
|
||||
}, 5000);
|
||||
}, 20000);
|
||||
},
|
||||
heartCheckFun(){
|
||||
var that = this;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import xss from "xss"
|
||||
<template>
|
||||
<j-modal
|
||||
:title="title"
|
||||
@ -24,6 +25,7 @@
|
||||
|
||||
<script>
|
||||
import {getUserList} from '@/api/api'
|
||||
import xss from 'xss'
|
||||
export default {
|
||||
name: "SysAnnouncementModal",
|
||||
components: {
|
||||
@ -70,6 +72,11 @@
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220107 for:将其它页面传递过来的用户名改成用户真实姓名
|
||||
this.visible = true;
|
||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
if(record.msgContent){
|
||||
record.msgContent = xss(record.msgContent)
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
this.record = record;
|
||||
},
|
||||
handleCancel () {
|
||||
|
||||
Reference in New Issue
Block a user