初始化

This commit is contained in:
砂糖
2025-11-08 10:38:36 +08:00
commit 3beeec7296
1626 changed files with 198488 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
/*!
* 标签管理
*/
import Vue from 'vue'
/**
* 获取标签列表
* @returns {*}
*/
const getLabelList = () => Vue.prototype.$dataRoomAxios.get('/label/getLabelList')
/**
* 获取标签
* @param data
* @returns {*}
*/
const labelList = (data) => Vue.prototype.$dataRoomAxios.get('/label/list', data)
/**
* 获取标签分类
* @returns {*}
*/
const getLabelType = () => Vue.prototype.$dataRoomAxios.get('/label/getLabelType')
/**
* 根据种类移除标签
* @param data
* @returns {*}
*/
const removeLabelByType = (data) => Vue.prototype.$dataRoomAxios.post('/label/removeLabelByType', data)
/**
* 移除标签
* @param id
* @returns {*}
*/
const removeLabel = (id = '-1') => Vue.prototype.$dataRoomAxios.get(`/label/removeLabel/${id}`)
/**
* 检查重复标签
* @param data
* @returns {*}
*/
const checkRepeatLabel = (data) => Vue.prototype.$dataRoomAxios.post('/label/checkRepeat', data)
/**
* 新增/修改标签
* @param data
* @returns {*}
*/
const addOrUpdateLabel = (data) => Vue.prototype.$dataRoomAxios.post('/label/addOrUpdateLabel', data)
/**
* 获取标签详情
* @param id
* @returns {*}
*/
const getLabelDetail = (id = '-1') => Vue.prototype.$dataRoomAxios.get(`/label/getLabelDetail/${id}`)
/**
* 修改标签种类
* @param data
* @returns {*}
*/
const updateLabelType = (data) => Vue.prototype.$dataRoomAxios.post('/label/updateLabelType', data)
/**
* 根据标签id获取数据集id列表
* @param id
*/
const getDataSetIdListByLabelId = (id = '-1') => Vue.prototype.$dataRoomAxios.get(`/label/queryDataSetIdList/${id}`)
/**
* 根据数据集id获取标签列表
* @param id
*/
const getLabelListByDatasetId = (id = '-1') => Vue.prototype.$dataRoomAxios.get(`/label/queryDataSetLabelList/${id}`)
export {
getLabelList,
labelList,
getLabelType,
removeLabelByType,
removeLabel,
checkRepeatLabel,
addOrUpdateLabel,
getLabelDetail,
updateLabelType,
getDataSetIdListByLabelId,
getLabelListByDatasetId
}

View File

@@ -0,0 +1,11 @@
// 颜色选择器的预设颜色
export const predefineColors = [
'#6b74e4',
'#4391f4',
'#38bbe5',
'#69d6fd',
'#36c6a0',
'#007aff',
'#ffffff',
'#0b1833'
]

View File

@@ -0,0 +1,91 @@
/*
* @description: 大屏组件通用属性
* @Date: 2023-03-13 10:04:59
* @Author: xing.heng
* @LastEditors: wujian
* @LastEditTime: 2023-06-01 14:23:23
*/
import getComponentConfig from 'packages/js/utils/getComponentConfig'
import linkageConfig from 'packages/js/config/linkageConfig'
// 关于设置组件在右侧面板可以展示哪些属性配置
export const displayOption = {
serverPagination: {
// 服务端分页
enable: false
},
pageSize: {
// 分页长度
enable: false
},
metricField: {
// 指标
label: '指标',
enable: true,
multiple: true // 是否多选
},
dimensionField: {
// 维度
label: '维度', // 维度/查询字段
enable: true,
multiple: true // 是否多选
},
dimensionList: {
// 维度(只有多折线图会存在两个维度)
label: '维度', // 维度/查询字段
enable: false,
multiple: true // 是否多选
},
seriesField: {
// 数据细分
enable: false,
required: true // 必填
},
dataAllocation: {
// 是否存在数据配置
enable: true
},
params: {
// 参数配置
enable: true
},
dataSourceType: {
// 数据源(数据集或者其他方式:静态数据)
enable: true
}
}
export default function (customConfig) {
return {
...getComponentConfig(customConfig.type),
z: 0, // z轴图层支持
locked: false, // 是否锁定组件
group: '', // 组合组件, 相同group的组件会被组合在一起
code: null,
showTitle: true,
...customConfig.root,
dataSource: {
className:
'com.gccloud.dataroom.core.module.chart.components.datasource.DataSetDataSource',
dataSourceKey: '', // 数据源,选择不同数据库
businessKey: '', // 数据集标识
dimensionField: '', // 维度
metricField: '', // 指标
seriesField: '', // 分类字段
dimensionFieldList: [], // 唯独列表
metricFieldList: [], // 指标列表
seriesFieldList: [], // 分类列表
serverPagination: false, // 服务端分页
pageSize: 10,
params: {},
dataSetType: '', // 数据集类型,
formCode: '',
...customConfig.dataSource // 非通用数据配置
},
customize: {
...customConfig.customize
}, // 自定义设置
...linkageConfig, // 数据联动配置
filterList: [],
dataFlag: false // 判断数据为模拟数据还是真实数据
}
}

View File

@@ -0,0 +1,42 @@
/* eslint-disable no-useless-escape */
/*
* @description: 批量导入pc端大屏组件
* @Date: 2023-03-13 10:04:58
* @Author: xing.heng
* @LastEditors: xing.heng
* @LastEditTime: 2023-05-17 12:40:25
*/
const modules = {};
// 组件名称替换
const replaceName = {};
// 排除的组件
const excludeCommponents = [];
function importComponents(files) {
files.keys().forEach((key) => {
// 正则,取到./和/之间的字符串
const reg = new RegExp("(.\\/)(.*)(\\/)");
let moduleName = key.match(reg)[0].replace(/(\.\/)|(\/)|(src)/g, "");
// 替换组件名称
if (replaceName[moduleName]) {
moduleName = replaceName[moduleName];
}
if (!excludeCommponents.includes(moduleName)) {
modules[moduleName] = files(key).default;
}
});
}
importComponents(
require.context("data-room-ui/BasicComponents", true, /\index.vue$/)
);
importComponents(require.context("data-room-ui/Borders", true, /\index.vue$/));
importComponents(
require.context("data-room-ui/Decorations", true, /\index.vue$/)
);
importComponents(
require.context("data-room-ui/BorderComponents", true, /\index.vue$/)
);
importComponents(
require.context("data-room-ui/Configuration", true, /\index.vue$/)
);
export default modules;

View File

@@ -0,0 +1,100 @@
export function showSize (base64url) {
let str = base64url.replace('data:image/png;base64,', '')
// 找到等号,把等号也去掉
const equalIndex = str.indexOf('=')
if (str.indexOf('=') > 0) {
str = str.substring(0, equalIndex)
}
// 原来的字符流大小,单位为字节
const strLength = base64url.length
// 计算后得到的文件流大小,单位为字节
const fileLength = parseInt(strLength - (strLength / 8) * 2)
// 由字节转换为kb
let size = ''
size = (fileLength / 1024).toFixed(2)
const sizeStr = size + '' // 转成字符串
const index = sizeStr.indexOf('.') // 获取小数点处的索引
const dou = sizeStr.substr(index + 1, 2) // 获取小数点后两位的值
if (dou === '00') {
// 判断后两位是否为00如果是则删除00
return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)
}
return Number(size)
}
export function dataURLtoFile (dataurl, filename) {
// 将base64转换为文件dataurl为base64字符串filename为文件名必须带后缀名如.jpg,.png
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
export function dataURLtoBlob (dataurl) {
const arr = dataurl.split(',')
const _arr = arr[1].substring(0, arr[1].length - 2)
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(_arr)
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], {
type: mime
})
}
export function translateBlobToBase64 (blob, callback) {
const reader = new FileReader()
reader.onload = function (e) {
callback(e.target)
}
reader.readAsDataURL(blob)
// 读取后result属性中将包含一个data:URL格式的Base64字符串用来表示所读取的文件
}
// 压缩方法
export function compressImage (base64, { width: w = 1280, height: h = 720, size = 200, quality = 1 }) {
return new Promise((resolve, reject) => {
const newImage = new Image()
newImage.src = base64
newImage.setAttribute('crossOrigin', 'Anonymous')
let imgWidth, imgHeight
newImage.onload = function () {
imgWidth = 1280
imgHeight = 720
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (Math.max(imgWidth, imgHeight) > w) {
if (imgWidth > imgHeight) {
canvas.width = w
canvas.height = w * imgHeight / imgWidth
} else {
canvas.height = w
canvas.width = w * imgWidth / imgHeight
}
} else {
canvas.width = imgWidth
canvas.height = imgHeight
quality = 1
}
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
let compressedBase64 = canvas.toDataURL('image/jpeg', quality) // 压缩语句
if (showSize(compressedBase64) > Number(size)) {
compressedBase64 = canvas.toDataURL('image/jpeg', quality - 0.2 > 0.4 ? quality - 0.2 : 0.4)
}
resolve(compressedBase64)
}
newImage.onerror = function () {
reject(new Error('Failed to load image'))
}
})
}

View File

@@ -0,0 +1,39 @@
/*
* @description: 批量导入所有组件的配置config
* @Date: 2023-03-13 10:04:58
* @Author: xing.heng
* @LastEditors: xing.heng
* @LastEditTime: 2023-05-18 10:39:42
*/
const setModules = {}; // 设置模块
const dataModules = {}; // 数据模块
function importComponentSettingConfig(files) {
files
.keys()
.filter((key) => {
return key.match(/settingConfig/);
})
.forEach((key) => {
const reg = new RegExp("(.\\/)(.*)(\\/)");
let moduleName = key.match(reg)[0].replace(/(\.\/)|(\/)/g, "");
moduleName = moduleName.replace(
moduleName[0],
moduleName[0].toLowerCase()
);
setModules[moduleName] = files(key).settingConfig;
dataModules[moduleName] = files(key).dataConfig;
});
}
importComponentSettingConfig(
require.context("data-room-ui/BasicComponents", true, /\.js$/)
);
importComponentSettingConfig(
require.context("data-room-ui/Borders", true, /\.js$/)
);
importComponentSettingConfig(
require.context("data-room-ui/Decorations", true, /\.js$/)
);
importComponentSettingConfig(
require.context("data-room-ui/Configuration", true, /\.js$/)
);
export { setModules, dataModules };

View File

@@ -0,0 +1,116 @@
/*!
* 数据源管理
*/
import Vue from 'vue'
/**
* 修改数据源
* @param params
* @param flag
* @returns {*}
*/
const add = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/datasource/add', params, flag)
/**
* 删除数据源前查询是否使用
* @param params
* @param flag
* @returns {*}
*/
const dataSourceCheck = (id='-1', flag = false) => Vue.prototype.$dataRoomAxios.post(`/datasource/deleteCheck/${id}`, {}, flag)
/**
* 修改数据源
* @param params
* @param flag
* @returns {*}
*/
const update = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/datasource/update', params, flag)
/**
* 数据源名称校验
* @param params
* @param flag
* @returns {*}
*/
const checkRepeat = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/datasource/checkRepeat', params, flag)
/**
* 数据源连接测试
* @param params
* @param flag
* @returns {*}
*/
const sourceLinkTest = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/datasource/testConnect', params, flag)
/**
* 获取数据源列表
* @param params
* @param flag
* @returns {*}
*/
const datasourcePage = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.get('/datasource/page', params, flag)
/**
* 获取数据源列表
* @param params
* @param flag
* @returns {*}
*/
const datasourceList = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.get('/datasource/list', params, flag)
/**
* 删除数据源
* @param id
* @param flag
* @returns {*}
*/
const sourceRemove = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.post(`/datasource/delete/${id}`, {}, flag)
/**
* 获取数据源下表列表
* @param id
* @param flag
* @returns {*}
*/
const getSourceTable = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.get(`/datasource/getTableList/${id}`, {}, flag)
/**
* 获取数据源下视图列表
* @param id
* @param flag
* @returns {*}
*/
const getSourceView = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.get(`/datasource/getViewList/${id}`, {}, flag)
/**
* 获取数据源下表字段列表
* @param sourceId
* @param tableName
* @param flag
* @returns {Promise<*>}
*/
const getTableFieldList = (sourceId = '-1', tableName = '', flag = false) => Vue.prototype.$dataRoomAxios.get(`/datasource/getFieldList/table/${sourceId}/${tableName}`, {}, flag)
/**
* 获取数据源下视图字段列表
* @param sourceId
* @param viewName
* @param flag
* @returns {Promise<*>}
*/
const getViewFieldList = (sourceId = '-1', viewName = '', flag = false) => Vue.prototype.$dataRoomAxios.get(`/datasource/getFieldList/view/${sourceId}/${viewName}`, {}, flag)
export {
add,
update,
checkRepeat,
sourceLinkTest,
datasourcePage,
datasourceList,
sourceRemove,
getSourceTable,
getSourceView,
getTableFieldList,
getViewFieldList,
dataSourceCheck
}

View File

@@ -0,0 +1,145 @@
/*!
* 数据集管理
*/
import Vue from 'vue'
/**
* 数据集分页查询
* @param params
* @param flag
* @returns {*}
*/
const datasetPage = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.get('/dataset/page', params, flag)
/**
* 删除数据源前查询是否使用
* @param params
* @param flag
* @returns {*}
*/
const datasetCheck = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.post(`/dataset/deleteCheck/${id}`, {}, flag)
/**
* 验证节点是否可删除
* @param params
* @param flag
* @returns {*}
*/
const categoryDele = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.get(`/dataset/getCountByType/${id}`, {}, flag)
/**
* 数据集列表查询
* @param params
* @param flag
* @returns {*}
*/
const datasetList = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.get('/dataset/list', params, flag)
/**
* 数据集名称校验
* @param params
* @param flag
* @returns {*}
*/
const nameCheckRepeat = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/dataset/checkRepeat', params, flag)
/**
* 数据集新增
* @param params
* @param flag
* @returns {*}
*/
const datasetAdd = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/dataset/add', params, flag)
/**
* 数据集修改
* @param params
* @param flag
* @returns {*}
*/
const datasetUpdate = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/dataset/update', params, flag)
/**
* 删除数据集
* @param id
* @param flag
* @returns {*}
*/
const datasetRemove = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.post(`/dataset/delete/${id}`, {}, flag)
/**
* 数据集执行
* @param params
* @param flag
* @returns {*}
*/
const datasetExecuteTest = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/dataset/execute/test', params, flag)
/**
* 获取数据集详情
* @param id
* @param flag
* @returns {*}
*/
const getDataset = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.get(`/dataset/info/${id}`, {}, flag)
/**
* 获取数据集分类
* @param r_dataset
* @param flag
* @returns {*}
*/
const getCategoryTree = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.get('/category/queryTreeList', params, flag)
/**
* 新增分类树节点
* @param params
* @param flag
* @returns {*}
*/
const categoryAdd = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/category/add', params, flag)
/**
* 编辑分类树节点
* @param params
* @param flag
* @returns {*}
*/
const categoryUpdate = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/category/update', params, flag)
/**
* 删除分类树节点
* @param id
* @param flag
* @returns {*}
*/
const categoryRemove = (id = '-1', flag = false) => Vue.prototype.$dataRoomAxios.post(`/category/delete/${id}`, {}, flag)
/**
* 分类名称校验
* @param params
* @param flag
*/
const categoryNameRepeat = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/category/checkRepeat', params, flag)
export {
datasetPage,
datasetList,
datasetAdd,
datasetUpdate,
datasetRemove,
nameCheckRepeat,
datasetExecuteTest,
getDataset,
categoryDele,
getCategoryTree,
categoryAdd,
categoryUpdate,
categoryRemove,
datasetCheck,
categoryNameRepeat
}

View File

@@ -0,0 +1,29 @@
function stringifyObjectFunctions (obj) {
// 遍历对象属性
for (const key in obj) {
const value = obj[key]
// 如果属性值是函数类型,将函数转换为字符串
if (typeof value === 'function') {
obj[key] = `(${value.toString()})`
// 如果属性值是对象类型,则递归进行转换
} else if (typeof value === 'object' && value !== null) {
stringifyObjectFunctions(value)
}
}
return JSON.stringify(obj)
}
function stringToFunction (str) {
return JSON.parse(str, (key, value) => {
if (typeof value === 'string' && (value.includes('=>') || value.includes('function'))) {
// eslint-disable-next-line no-eval
return eval(`(${value})`)
}
return value
})
}
export {
stringifyObjectFunctions,
stringToFunction
}

View File

@@ -0,0 +1,34 @@
import Vue from 'vue';
// 创建全局唯一的 EventBus 实例
export const EventBus = new Vue();
// 创建唯一的事件处理函数
function dataInitHandler(_this, formData, bindComponents) {
bindComponents?.forEach(com => {
const maps = com.maps;
const filterList = maps?.map(param => ({
column: param.targetField,
operator: param.queryRule,
value: formData[param.sourceField],
}));
_this.$nextTick(() => {
if (_this.$refs[com.componentKey] && _this.$refs[com.componentKey].dataInit) {
_this.$refs[com.componentKey].dataInit(filterList);
}
});
});
}
// 注册事件监听器
export function dataInit(_this) {
EventBus.$on('dataInit', (formData, bindComponents) => {
// 在回调中调用处理函数并传递组件实例
dataInitHandler(_this, formData, bindComponents);
});
}
export function destroyedEvent() {
EventBus.$off('dataInit', dataInitHandler);
}

View File

@@ -0,0 +1,21 @@
function getFileUrl(url){
// 如果是空的直接返回
if (!url) {
return url
}
// 如果是http开头的直接返回
if (/^http/.test(url)) {
return url
}
// 如果没有以/开头的加上/
if (!/^\//.test(url)) {
url = `/${url}`
}
// return `${window.BS_CONFIG?.httpConfigs?.fileUrlPrefix}${url}`
return `${process.env.VUE_APP_BASE_API}/static${url}`
}
export {
getFileUrl
}

View File

@@ -0,0 +1,22 @@
const fontList = [
{
label: '默认',
value: ''
},
{
label: '时钟加粗倾斜',
value: 'ds-digitalbold_italic'
},
{
label: '时钟加粗正常',
value: 'ds-digitalbold'
},
{
label: '时钟倾斜',
value: 'ds-digitalitalic'
},
{
label: '时钟正常',
value: 'ds-digitalnormal'
}]
export default fontList

View File

@@ -0,0 +1,223 @@
/*
* @description: 得到边框组件配置
* @Date: 2023-03-16 10:49:11
*/
export default function getComponentConfig (type, classNameType) {
const className =
'com.gccloud.dataroom.core.module.chart.components.ScreenBorderChart'
switch (type) {
case 'border1':
return {
name: '边框一',
title: '边框一',
icon: null,
img: require('data-room-ui/Borders/images/border-1.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border2':
return {
name: '边框二',
title: '边框二',
icon: null,
img: require('data-room-ui/Borders/images/border-2.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border3':
return {
name: '边框三',
title: '边框三',
icon: null,
img: require('data-room-ui/Borders/images/border-3.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border4':
return {
name: '边框四',
title: '边框四',
icon: null,
img: require('data-room-ui/Borders/images/border-4.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border5':
return {
name: '边框五',
title: '边框五',
icon: null,
img: require('data-room-ui/Borders/images/border-5.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border6':
return {
name: '边框六',
title: '边框六',
icon: null,
img: require('data-room-ui/Borders/images/border-6.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border7':
return {
name: '边框七',
title: '边框七',
icon: null,
img: require('data-room-ui/Borders/images/border-7.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border8':
return {
name: '边框八',
title: '边框八',
icon: null,
img: require('data-room-ui/Borders/images/border-8.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border9':
return {
name: '边框九',
title: '边框九',
icon: null,
img: require('data-room-ui/Borders/images/border-9.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border10':
return {
name: '边框十',
title: '边框十',
icon: null,
img: require('data-room-ui/Borders/images/border-10.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border11':
return {
name: '边框十一',
title: '边框十一',
icon: null,
img: require('data-room-ui/Borders/images/border-11.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border12':
return {
name: '边框十二',
title: '边框十二',
icon: null,
img: require('data-room-ui/Borders/images/border-12.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border13':
return {
name: '边框十三',
title: '边框十三',
icon: null,
img: require('data-room-ui/Borders/images/border-13.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border14':
return {
name: '边框十四',
title: '边框十四',
icon: null,
img: require('data-room-ui/Borders/images/border-14.png'),
component: null,
className,
w: 450,
h: 320,
x: 0,
y: 0,
type
}
case 'border15':
return {
name: '边框十五',
title: '边框十五',
icon: null,
img: require('data-room-ui/Borders/images/border-15.png'),
component: null,
className,
w: 450,
h: 450,
x: 0,
y: 0,
type
}
default:
return {}
}
}

View File

@@ -0,0 +1,369 @@
import Icon from "data-room-ui/assets/images/bigScreenIcon/export";
export default function getComponentConfig(type) {
switch (type) {
case "texts":
return {
name: "文本",
title: "文本",
icon: Icon.getNameList()[0],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenTextChart",
w: 200,
h: 60,
x: 0,
y: 0,
type,
dataHandler: {}, // 数据自定义处理js脚本
};
case "numbers":
return {
name: "数字",
title: "数字",
icon: Icon.getNameList()[28],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenNumbersChart",
w: 200,
h: 60,
x: 0,
y: 0,
type,
};
case "linkChart":
return {
name: "超链接",
title: "超链接",
icon: Icon.getNameList()[15],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenLinkChart",
w: 200,
h: 60,
x: 0,
y: 0,
type,
};
case "horizontalLine":
return {
name: "水平线",
title: "水平线",
icon: Icon.getNameList()[24],
component: null,
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenBorderChart",
w: 300,
h: 40,
x: 0,
y: 0,
type,
};
case "verticalLine":
return {
name: "垂直线",
title: "垂直线",
icon: Icon.getNameList()[25],
component: null,
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenBorderChart",
w: 40,
h: 300,
x: 0,
y: 0,
type,
};
case "picture":
return {
name: "图片",
title: "图片",
icon: Icon.getNameList()[1],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenPictureChart",
// w: 280,
// h: 200,
// x: 0,
// y: 0,
type,
};
case "screenScrollBoard":
return {
name: "轮播表",
title: "轮播表",
icon: Icon.getNameList()[2],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenScrollBoardChart",
w: 600,
h: 400,
x: 0,
y: 0,
type,
};
case "screenScrollRanking":
return {
name: "排名表",
title: "排名表",
icon: Icon.getNameList()[3],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenScrollRankingChart",
w: 600,
h: 400,
x: 0,
y: 0,
type,
};
case "tables":
return {
name: "表格",
title: "表格",
icon: Icon.getNameList()[4],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenTablesChart",
w: 600,
h: 400,
x: 0,
y: 0,
type,
};
case "currentTime":
return {
name: "当前时间",
title: "当前时间",
icon: Icon.getNameList()[6],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenCurrentTimeChart",
w: 300,
h: 60,
x: 0,
y: 0,
type,
};
case "timeCountDown":
return {
name: "倒计时",
title: "倒计时",
icon: Icon.getNameList()[7],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenTimeCountDownChart",
w: 300,
h: 60,
x: 0,
y: 0,
type,
};
case "iframeChart":
return {
name: "外链",
title: "外链",
icon: Icon.getNameList()[8],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenIframeChart",
w: 600,
h: 400,
x: 0,
y: 0,
type,
};
case "digitalFlop":
return {
name: "翻牌器",
title: "翻牌器",
icon: null,
img: require("data-room-ui/BasicComponents/DigitalFlop/images/fanpaiqi.png"),
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenDigitalFlopChart",
w: 800,
h: 150,
x: 0,
y: 0,
type,
};
case "customHtml":
return {
name: "自定义HTML",
title: "自定义HTML",
icon: Icon.getNameList()[29],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenCustomHtmlChart",
w: 600,
h: 150,
x: 0,
y: 0,
type,
};
case "video":
return {
name: "播放器",
title: "播放器",
icon: Icon.getNameList()[12],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenVideoChart",
w: 600,
h: 400,
x: 0,
y: 0,
type,
};
case "input":
return {
name: "输入框",
title: "输入框",
icon: Icon.getNameList()[13],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenInputChart",
w: 450,
h: 60,
x: 0,
y: 0,
type,
};
case "button":
return {
name: "按钮",
title: "按钮",
icon: Icon.getNameList()[14],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenButtonChart",
w: 80,
h: 40,
x: 0,
y: 0,
type,
};
case "marquee":
return {
name: "跑马灯",
title: "跑马灯",
icon: Icon.getNameList()[16],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenMarqueeChart",
w: 250,
h: 150,
x: 0,
y: 0,
type,
};
case "chartTab":
return {
name: "图表Tab页",
title: "图表Tab页",
icon: Icon.getNameList()[19],
className:
"com.gccloud.dataroom.core.module.chart.components.ChartTabChart",
w: 600,
h: 400,
x: 0,
y: 0,
type,
};
case "themeSelect":
return {
name: "主题切换",
title: "主题切换",
icon: Icon.getNameList()[20],
className:
"com.gccloud.dataroom.core.module.chart.components.ThemeSelectChart",
w: 200,
h: 100,
x: 0,
y: 0,
type,
};
case "select":
return {
name: "选择器",
title: "选择器",
icon: Icon.getNameList()[21],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenSelectChart",
w: 450,
h: 60,
x: 0,
y: 0,
type,
};
case "timePicker":
return {
name: "时间选择器",
title: "时间选择器",
icon: Icon.getNameList()[22],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenTimePickerChart",
w: 200,
h: 60,
x: 0,
y: 0,
type,
};
case "dateTimePicker":
return {
name: "日期时间选择器",
title: "日期时间选择器",
icon: Icon.getNameList()[23],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenDateTimePickerChart",
w: 500,
h: 60,
x: 0,
y: 0,
type,
};
case "indicatorCard":
return {
name: "指标卡一",
title: "指标卡一",
icon: Icon.getNameList()[30],
// img: require('data-room-ui/assets/images/cardImg/card.png'),
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenIndicatorCardChart",
w: 300,
h: 114,
x: 0,
y: 0,
type,
};
case "indicatorCard2":
return {
name: "指标卡二",
title: "指标卡二",
icon: Icon.getNameList()[31],
// img: require('data-room-ui/assets/images/cardImg/card2.png'),
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenIndicatorCardChart",
w: 300,
h: 114,
x: 0,
y: 0,
type,
};
case "indexCard":
return {
name: "指标卡三",
title: "指标卡三",
icon: Icon.getNameList()[32],
// img: require('data-room-ui/assets/images/cardImg/indicard.png'),
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenIndexCardChart",
w: 300,
h: 114,
x: 0,
y: 0,
type,
};
case "indexCard2":
return {
name: "指标卡四",
title: "指标卡四",
icon: Icon.getNameList()[33],
// img: require('data-room-ui/assets/images/cardImg/indcard2.png'),
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenIndexCardChart",
w: 300,
h: 114,
x: 0,
y: 0,
type,
};
default:
return {};
}
}

View File

@@ -0,0 +1,57 @@
/*
* @description: 得到装饰组件配置
*/
import Icon from "data-room-ui/assets/images/bigScreenIcon/export";
export default function getComponentConfig(type, classNameType) {
const className =
"com.gccloud.dataroom.core.module.chart.components.ScreenConfigurationChart";
switch (type) {
case "horizontalLine2":
return {
name: "水平线2",
title: "水平线2",
// icon: Icon.getNameList()[36],
img: require("data-room-ui/Configuration/images/水平线.png"),
component: null,
className,
w: 300,
h: 20,
x: 0,
y: 0,
type,
};
case "verticalLine2":
return {
name: "垂直线2",
title: "垂直线2",
// icon: Icon.getNameList()[36],
img: require("data-room-ui/Configuration/images/垂直线.png"),
component: null,
className,
w: 20,
h: 300,
x: 0,
y: 0,
type,
};
case "warning":
return {
name: "告警灯",
title: "告警灯",
icon: Icon.getNameList()[37],
className:
"com.gccloud.dataroom.core.module.chart.components.ScreenTextChart",
w: 200,
h: 200,
x: 0,
y: 0,
type,
dataHandler: {}, // 数据自定义处理js脚本
};
default:
return {};
}
}

View File

@@ -0,0 +1,180 @@
/*
* @description: 得到装饰组件配置
*/
export default function getComponentConfig (type, classNameType) {
const className =
'com.gccloud.dataroom.core.module.chart.components.ScreenDecorationChart'
switch (type) {
case 'decoration1':
return {
name: '装饰一',
title: '装饰一',
img: require('data-room-ui/Decorations/images/01.png'),
component: null,
className,
w: 350,
h: 30,
x: 0,
y: 0,
type
}
case 'decoration2':
return {
name: '装饰三',
title: '装饰三',
img: require('data-room-ui/Decorations/images/03.png'),
component: null,
className,
w: 350,
h: 20,
x: 0,
y: 0,
type
}
case 'decoration2Reverse':
return {
name: '装饰三(旋转)',
title: '装饰三(旋转)',
img: require('data-room-ui/Decorations/images/03_reverse.png'),
component: null,
className,
w: 20,
h: 350,
x: 0,
y: 0,
type
}
case 'decoration3':
return {
name: '装饰二',
title: '装饰二',
img: require('data-room-ui/Decorations/images/02.png'),
component: null,
className,
w: 350,
h: 30,
x: 0,
y: 0,
type
}
case 'decoration4':
return {
name: '装饰四',
title: '装饰四',
img: require('data-room-ui/Decorations/images/04.png'),
component: null,
className,
w: 30,
h: 320,
x: 0,
y: 0,
type
}
case 'decoration4Reverse':
return {
name: '装饰四(旋转)',
title: '装饰四(旋转)',
img: require('data-room-ui/Decorations/images/04_reverse.png'),
component: null,
className,
w: 320,
h: 30,
x: 0,
y: 0,
type
}
case 'decoration5':
return {
name: '装饰五',
title: '装饰五',
img: require('data-room-ui/Decorations/images/05.png'),
component: null,
className,
w: 350,
h: 50,
x: 0,
y: 0,
type
}
case 'decoration6':
return {
name: '装饰六',
title: '装饰六',
img: require('data-room-ui/Decorations/images/06.png'),
component: null,
className,
w: 350,
h: 30,
x: 0,
y: 0,
type
}
case 'decoration8':
return {
name: '装饰七',
title: '装饰七',
img: require('data-room-ui/Decorations/images/07.png'),
component: null,
className,
w: 350,
h: 50,
x: 0,
y: 0,
type
}
case 'decoration8Reverse':
return {
name: '装饰七(旋转)',
title: '装饰七(旋转)',
img: require('data-room-ui/Decorations/images/07_reverse.png'),
component: null,
className,
w: 350,
h: 50,
x: 0,
y: 0,
type
}
case 'decoration9':
return {
name: '装饰八',
title: '装饰八',
img: require('data-room-ui/Decorations/images/08.png'),
component: null,
className,
w: 150,
h: 150,
x: 0,
y: 0,
type
}
case 'decoration10':
return {
name: '装饰九',
title: '装饰九',
img: require('data-room-ui/Decorations/images/09.png'),
component: null,
className,
w: 350,
h: 50,
x: 0,
y: 0,
type
}
case 'decoration11':
return {
name: '装饰十',
title: '装饰十',
img: require('data-room-ui/Decorations/images/10.png'),
component: null,
className,
w: 350,
h: 50,
x: 0,
y: 0,
type
}
default:
return {}
}
}

View File

@@ -0,0 +1,231 @@
import axios from 'axios'
import qs from 'qs'
// import _ from 'lodash'
import merge from 'lodash/merge'
import { Message } from 'element-ui'
import { getToken } from '@/utils/auth'
/**
* 统一进行异常输出
* 如果异常只是弹框显示即可,可使用该实例
*/
const httpConfig = {
timeout: 1000 * 30,
withCredentials: true,
baseURL: process.env.VUE_APP_BASE_API,
headers: {
'Content-Type': 'application/json; charset=utf-8',
"AuthToken" : 'Bearer ' + getToken()
}
}
const httpCustom = axios.create(httpConfig)
/**
*对于出现异常时还需要做其他操作,可使用该实例
*/
const http = axios.create(httpConfig)
/**
* 封装的异常对象
* @param message
* @param code
* @constructor
*
*/
function EipException (message, code) {
this.msg = message
this.code = code
}
/**
* 请求拦截
*/
http.interceptors.request.use(config => {
return {
...config,
...merge(httpConfig, window.BS_CONFIG?.httpConfigs)
}
}, error => {
return Promise.reject(error)
})
/**
* 自定义请求拦截
*/
httpCustom.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
/**
* 响应拦截
*/
http.interceptors.response.use(response => {
const res = response.data
// 异常拦截
// eslint-disable-next-line no-empty
if (res && res.code === 401) {
} else if (res && res.code !== 200) {
// return Promise.reject(response.data.msg)
Message({
message: response.data.msg,
type: 'error'
})
throw new EipException(response.data.msg, response.data.code)
} else {
return res
}
}, error => {
if (error.message && error.message === 'Network Error') {
Message({
message: error.message,
type: 'error'
})
return Promise.reject(error)
// eslint-disable-next-line no-empty
} else {
}
Message({
message: '服务异常',
type: 'error'
})
return Promise.reject(error)
})
/**
* 响应拦截
*/
httpCustom.interceptors.response.use(response => {
const res = response.data
return res
}, error => {
if (error.message && error.message === 'Network Error') {
return Promise.reject(error)
// eslint-disable-next-line no-empty
} else {
}
Message({
message: '服务异常',
type: 'error'
})
return Promise.reject(error)
})
/**
* get请求
* @param url
* @param params
* @returns {Promise<any>}
*/
export function get (url, params = {}, customHandlerException = false) {
// if (!url.startsWith('http')) {
// url = window.BS_CONFIG?.httpConfigs?.baseURL + url
// }
// 如果是ie浏览器要添加个时间戳解决浏览器缓存问题
if (!!window.ActiveXObject || 'ActiveXObject' in window) {
params._t = new Date().getTime()
}
const axiosInstance = customHandlerException ? httpCustom : http
return new Promise((resolve, reject) => {
axiosInstance.get(url, {
params: params,
paramsSerializer: params => {
return qs.stringify(params, { indices: false })
}
}).then(response => {
if (customHandlerException) {
resolve(response)
} else {
resolve(response.data)
}
}).catch(err => {
reject(err)
})
})
}
/**
* Post 请求
* @param url
* @param params
* @returns {Promise<any>}
*/
export function post (url, data = {}, customHandlerException = false) {
// if (!url.startsWith('http')) {
// url = window.BS_CONFIG?.httpConfigs?.baseURL + url
// }
const axiosInstance = customHandlerException ? httpCustom : http
data = JSON.stringify(data)
return new Promise((resolve, reject) => {
axiosInstance.post(url, data).then(response => {
if (customHandlerException) {
resolve(response)
} else {
resolve(response.data)
}
}).catch(err => {
reject(err)
})
})
}
/**
* download 请求
* @returns {Promise<any>}
*/
export function download (url, headers = {}, params = {}, body = {}) {
// if (!url.startsWith('http')) {
// url = window.BS_CONFIG?.httpConfigs?.baseURL + url
// }
// 如果是ie浏览器要添加个时间戳解决浏览器缓存问题
if (!!window.ActiveXObject || 'ActiveXObject' in window) {
params._t = new Date().getTime()
}
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: httpConfig.baseURL+ url,
headers: httpConfig.headers,
params: params,
data: body,
withCredentials: false,
responseType: 'arraybuffer'
}).then(res => {
// IE10,11采用自带下载文件流方法
if ((!!window.ActiveXObject || 'ActiveXObject' in window) && window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(new Blob([res.data]), res.headers.filename)
return
}
const fileUrl = window.URL.createObjectURL(new Blob([res.data]))
// 创建超链接
const fileLink = document.createElement('a')
fileLink.href = fileUrl
// 设置下载文件名
let responseFileName = res.headers.filename
// 解决中文乱码
responseFileName = window.decodeURI(responseFileName)
fileLink.setAttribute('download', responseFileName)
document.body.appendChild(fileLink)
// 模拟人工点击下载超链接
fileLink.click()
// 释放资源
document.body.removeChild(fileLink)
window.URL.revokeObjectURL(fileUrl)
}).catch(e => {
const status = e?.response?.status
if (status === 404) {
Message({
message: '文件不存在或已被删除',
type: 'error'
})
return
}
Message({
message: '服务异常',
type: 'error'
})
console.error('服务异常')
})
})
}

View File

@@ -0,0 +1,143 @@
import axios from 'axios'
// import { Loading, Message } from 'element-ui'
// import _ from 'lodash'
import cloneDeep from 'lodash/cloneDeep'
export default function axiosFormatting (customConfig) {
const newCustomConfig = replaceParams(customConfig)
// 将请求头和请求参数的值转化为对象形式
const httpConfig = {
timeout: 1000 * 30,
baseURL: '',
headers: { 'Content-Type': 'application/json', ...newCustomConfig.headers }
}
// let loadingInstance = null // 加载全局的loading
const instance = axios.create(httpConfig)
/** 添加请求拦截器 **/
instance.interceptors.request.use(config => {
/**
* 在这里:可以根据业务需求可以在发送请求之前做些什么。
* config.headers['token'] = sessionStorage.getItem('token') || ''
*/
// 执行请求脚本
// https://mock.presstime.cn/mock/64bf8a00ce1b0ea640809069/test_copy_copy_copy/httpData?token=123&ss=ss
const req = { ...config, url: {} }
eval(newCustomConfig.requestScript)
for (const key in req.url) {
newCustomConfig.url = replaceUrlParam(newCustomConfig.url, key, req.url[key])
}
config = { ...config, ...req, url: newCustomConfig.url }
return config
}, error => {
// 对请求错误做些什么
return Promise.reject(error)
})
/** 添加响应拦截器 **/
instance.interceptors.response.use(response => {
const resp = response.data
// console.log('resp: ', resp);
// 执行响应脚本
if (newCustomConfig.responseScript) {
// eslint-disable-next-line no-new-func
const getResp = new Function('resp', newCustomConfig.responseScript)
const res = getResp(resp)
return Promise.resolve(res)
} else {
return Promise.resolve(resp)
}
})
const body = newCustomConfig?.body.replace(/: ,/g, ':undefined,').replace(/, }/g, ',undefined}')
/** 发送请求 **/
return new Promise((resolve, reject) => {
instance({
method: newCustomConfig.method,
url: newCustomConfig.url,
params: newCustomConfig.params,
// params 序列化操作
paramsSerializer: (params) => {
return Object.keys(params)
.map(key => {
if (Array.isArray(params[key])) {
return params[key].map(value => `${key}=${value}`).join('&')
} else {
return `${key}=${params[key]}`
}
})
.join('&')
},
data: newCustomConfig.method === 'post' ? body : undefined
}).then(response => {
resolve(response)
}).catch(error => {
reject(error)
})
})
}
// 动态替换url后面参数的值
function replaceUrlParam (url, paramName, paramValue) {
const regex = new RegExp(`([?&])${paramName}=.*?(&|$)`, 'i')
const separator = url.indexOf('?') !== -1 ? '&' : '?'
if (url.match(regex)) {
return url.replace(regex, `$1${paramName}=${paramValue}$2`)
} else {
return `${url}${separator}${paramName}=${paramValue}`
}
}
// 将参数的值替换掉其他配置中对应属性的值
function replaceParams (customConfig) {
const newConfig = cloneDeep(customConfig)
newConfig.url = evalStrFunc(newConfig.paramsList, newConfig.url)
newConfig.headers = evalArrFunc(newConfig.paramsList, newConfig.headers)
newConfig.params = evalArrFunc(newConfig.paramsList, newConfig.params)
newConfig.body = evalStrFunc(newConfig.paramsList, newConfig.body)
return newConfig
}
function evalStrFunc (paramsList, string) {
// 取name作为变量名, value作为变量值 { name: '站三', token: '123'}
const params = paramsList.reduce((acc, cur) => {
acc[cur.name] = cur.value
return acc
}, {})
// 将url中 ${xxx} 替换成 ${params.xxx}
const str = string.replace(/\$\{(\w+)\}/g, (match, p1) => {
return '${params.' + p1 + '}'
})
const transformStr = ''
// 将字符串中的${}替换为变量, 使用eval执行
eval('transformStr = `' + str + '`')
return transformStr
}
function evalArrFunc (paramsList, arr) {
// 取name作为变量名, value作为变量值 { name: '站三', token: '123'}
const params = paramsList.reduce((acc, cur) => {
acc[cur.name] = cur.value
return acc
}, {})
// 取name作为变量名, value作为变量值 { _name: '${name}', _token: '${token}'}
const paramsListObj = arr.reduce((acc, cur) => {
if (acc[cur.key]) {
if (Array.isArray(acc[cur.key])) {
acc[cur.key].push(cur.value)
} else {
acc[cur.key] = [acc[cur.key], cur.value]
}
} else {
acc[cur.key] = cur.value
}
return acc
}, {})
// 转成字符串
const paramsListStr = JSON.stringify(paramsListObj)
// 将url中 ${xxx} 替换成 ${params.xxx}
const str = paramsListStr.replace(/\$\{(\w+)\}/g, (match, p1) => {
return '${params.' + p1 + '}'
})
const transformStr = ''
// 将字符串中的${}替换为变量, 使用eval执行
eval('transformStr = `' + str + '`')
const obj = JSON.parse(transformStr)
return obj
}

View File

@@ -0,0 +1,57 @@
// import _ from 'lodash'
import upperFirst from 'lodash/upperFirst'
export const randomString = e => {
e = e || 32
const t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'
const a = t.length
let n = ''
for (let i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a))
return n
}
export const resolveComponentType = type => {
return `${upperFirst(type)}`
}
export function deepCompare (obj1, obj2, excludeKeys = []) {
// eslint-disable-next-line eqeqeq
if (obj1 == obj2) {
return false
}
// 如果两个对象中的一个是基本类型,则它们不相等
if (typeof obj1 !== 'object' || obj1 === null ||
typeof obj2 !== 'object' || obj2 === null) {
return true
}
// 如果两个对象的类型不相同,则它们不相等
if (obj1.constructor !== obj2.constructor) {
return true
}
// 递归地比较对象的属性
for (const prop in obj1) {
// 如果prop是要排除的key则跳过
if (excludeKeys.includes(prop)) {
continue
}
if (obj1.hasOwnProperty(prop)) {
if (!obj2.hasOwnProperty(prop)) {
return true
}
if (deepCompare(obj1[prop], obj2[prop])) {
return true
}
}
}
// 检查 obj2 中是否有 obj1 没有的属性
for (const prop in obj2) {
if (obj2.hasOwnProperty(prop) && !obj1.hasOwnProperty(prop)) {
return true
}
}
// 如果上面的检查都通过,则对象是相等的
return false
}

View File

@@ -0,0 +1,23 @@
// 自定义序列化方法解决JSON.stringify方法忽略函数属性的问题
export function customSerialize(obj) {
// 将对象属性和函数转换为字符串形式
const serializedObj = JSON.stringify(obj, function (key, value) {
if (typeof value === "function") {
return value.toString(); // 将函数转换为字符串
}
return value; // 保持其他属性不变
});
return serializedObj;
}
// 自定义反序列化方法
export function customDeserialize(serializedObj) {
const parsedObject = JSON.parse(serializedObj, function (key, value) {
if (typeof value === "string" && value.indexOf("function") === 0) {
// 将字符串还原为函数
return new Function("return " + value)();
}
return value; // 保持其他属性不变
});
return parsedObject;
}

View File

@@ -0,0 +1,86 @@
/*!
* 地图数据管理
*/
import Vue from 'vue'
/**
* 获取地图列表
* @param params
* @param flag
* @returns {*}
*/
const mapList = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.get('/bigScreen/map/list', params, flag)
/**
* 新增地图
* @param params
* @param flag
* @returns {*}
*/
const mapAdd = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/bigScreen/map/add', params, flag)
/**
* 更新地图
* @param params
* @param flag
* @returns {*}
*/
const mapUpdate = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/bigScreen/map/update', params, flag)
/**
* 删除地图
* @param id
*/
const mapDelete = (id = '-1') => Vue.prototype.$dataRoomAxios.post(`/bigScreen/map/delete/${id}`)
/**
* 级联删除地图
* @param id
*/
const mapCascadeDelete = (id = '-1') => Vue.prototype.$dataRoomAxios.post(`/bigScreen/map/cascadingDelete/${id}`)
/**
* 根据父编码解析父级json中的子级
* @param code
*/
const getMapChildFromGeoJson = (code = '-1') => Vue.prototype.$dataRoomAxios.get(`/bigScreen/map/getMapChildFromGeoJson/${code}`)
/**
* 上传地图json
* @param params
* @param flag
*/
const uploadGeoJson = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/bigScreen/map/upload', params, flag)
/**
* 编码重复校验
* @param params
* @param flag
*/
const repeatCheck = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/bigScreen/map/repeat/code', params, flag)
/**
* 名称重复校验
* @param params
* @param flag
*/
const nameRepeatCheck = (params = {}, flag = false) => Vue.prototype.$dataRoomAxios.post('/bigScreen/map/repeat/name', params, flag)
/**
* 根据父编码解析父级json中的子级
* @param id
*/
const mapInfo = (id = '-1') => Vue.prototype.$dataRoomAxios.get(`/bigScreen/map/info/${id}`)
export {
mapList,
mapAdd,
mapUpdate,
mapDelete,
mapCascadeDelete,
getMapChildFromGeoJson,
uploadGeoJson,
repeatCheck,
nameRepeatCheck,
mapInfo
}

View File

@@ -0,0 +1,68 @@
// mqttClient.js
import mqtt from 'mqtt';
class MqttClient {
constructor(brokerUrl, options) {
this.brokerUrl = brokerUrl || '';
this.clientId = options.clientId || "SW-VIEWS" + new Date().getTime();
this.username = options.username || 'admin';
this.password = options.password || '123456';
this.client = null;
}
// 连接 MQTT broker
connect() {
this.client = mqtt.connect(this.brokerUrl, {
clientId: this.clientId,
username: this.username,
password: this.password
});
this.client.on('connect', () => {
console.log('mqtt 已经连接成功');
});
this.client.on('reconnect', () => {
console.log("mqtt reconnect");
});
this.client.on('offline', () => {
console.log("mqtt offline");
});
this.client.on('error', (error) => {
console.log("mqtt error");
console.log(error);
});
}
// 订阅某个主题
subscribe(topic, callback) {
if (this.client) {
this.client.subscribe(topic, (err) => {
if (!err) {
console.log(`mqtt 订阅主题 ${topic} 成功`);
} else {
console.log(`mqtt 订阅主题 ${topic} 失败`);
}
});
this.client.on('message', (topic, message) => {
console.log(`mqtt 收到来自 ${topic} 的消息`);
callback(topic, message);
});
} else {
console.error('MQTT client is not connected');
}
}
// 断开连接
disconnect() {
if (this.client) {
this.client.end();
console.log('mqtt 连接已断开');
}
}
}
export default MqttClient;

View File

@@ -0,0 +1,198 @@
/**
* 对象属性合并,与 Object.assign 语法不同
* @param target
* @param source
* @returns {{}}
*/
function configDeepMerge (target, source) {
const merged = {}
for (const each in source) {
if (target.hasOwnProperty(each) && source.hasOwnProperty(each)) {
if (
typeof target[each] === 'object' &&
typeof source[each] === 'object'
) {
merged[each] = configDeepMerge(target[each], source[each])
} else {
merged[each] = source[each]
}
} else if (source.hasOwnProperty(each)) {
merged[each] = source[each]
}
}
for (const eachTarget in target) {
if (!(eachTarget in source) && target.hasOwnProperty(eachTarget)) {
merged[eachTarget] = target[eachTarget]
}
}
return merged
}
// 自动注册路由
function registerRouters (config, router) {
// 没有router对象不注册路由
if (!router) {
return
}
const routers = [
// 页面管理
{
path: config?.routers?.pageManagementUrl || '/management',
redirect: config?.routers?.pageListUrl || '/big-screen-list',
component: () => import('data-room-ui/Layout/BigScreenHomeLayout'),
children: [
{
path: config?.routers?.pageListUrl || '/big-screen-list',
name: 'BigScreenList',
component: () =>
require.ensure([], () => require('data-room-ui/BigScreenMag')),
meta: {
title: '大屏管理'
}
},
{
path: config?.routers?.templateListUrl || '/big-screen-template',
name: 'BigScreenTemplate',
component: () =>
require.ensure([], () => require('data-room-ui/BigScreenTempMag')),
meta: {
title: '模版管理'
}
},
{
path: config?.routers?.dataSourceUrl || '/big-screen-dataSource',
component: () => import('data-room-ui/DataSourceManagement'),
meta: {
title: '数据源管理'
}
},
{
path: config?.routers?.dataSetUrl || '/big-screen-dataSet',
component: () => import('data-room-ui/DataSetManagement'),
meta: {
title: '数据集管理'
}
},
{
path: config?.routers?.mapData || '/big-screen-map-data',
component: () => import('data-room-ui/MapDataManagement'),
meta: {
title: '地图数据管理'
}
},
{
path: config?.routers?.SourceUrl || '/big-screen-source',
component: () => import('data-room-ui/SourceManagement'),
meta: {
title: '资源库'
}
},
{
path: config?.routers?.componentUrl || '/big-screen-components',
component: () => import('data-room-ui/BigScreenComponentMag'),
meta: {
title: '资源管理'
}
}
]
},
{
path: config?.routers?.designUrl || '/big-screen/design',
name: 'BigScreenDesign',
component: () =>
require.ensure([], () => require('data-room-ui/BigScreenDesign'))
},
{
path: config?.routers?.previewUrl || '/big-screen/preview',
name: 'BigScreenPreview',
component: () =>
require.ensure([], () => require('data-room-ui/BigScreenRun'))
},
{
path: '/dataRoom-redirect',
name: 'Redirect',
component: () => import('data-room-ui/Layout/Redirect/index.vue')
},
{
path: config?.routers?.bizComponentDesignUrl || '/big-screen-biz-component-design',
component: () => import('data-room-ui/BizComponent'),
meta: {
title: '业务组件'
}
},
{
path: config?.routers?.bizComponentPreviewUrl || '/big-screen-biz-component-preview',
component: () => import('data-room-ui/BizComponent/Preview.vue'),
meta: {
title: '业务组件预览'
}
}
]
// 如果router有addRoutes方法
if (router?.addRoutes) {
router?.addRoutes(routers)
} else {
// eslint-disable-next-line no-unused-expressions
routers?.forEach((route) => {
// eslint-disable-next-line no-unused-expressions
router?.addRoute(route)
})
}
}
// 注册配置
function registerTheme (config) {
const defaultTheme = {
'--db-background-appmain': '#f0f2f5',
'--bs-el-color-primary': '#409EFF', // elment-ui主题色激活
'--bs-background-1': '#151a26', // 整体背景色
'--bs-background-2': '#232832', // 布局背景色
'--bs-el-background-1': '#151A26', // 组件背景色,输入框...
'--bs-el-background-2': '#35393F', // 组件背景色,按钮、分页、加载...
'--bs-el-background-3': '#303640', // 组件背景色表格头部、下拉框hover...
'--bs-el-title': '#ffffff', // 标题字体颜色
'--bs-el-text': '#ffffff', // 一般字体颜色
'--bs-el-border': 'transparent', // 边框颜色
'--bs-el-color-primary-active': '64, 158, 255'
}
const customTheme= {
'--db-background-appmain': '#151a26',
'--db-background-header': '#007aff', // 头部颜色
'--db-background-leftPanel': '#eef2f7', // 左侧组件栏背景色
'--db-background-1': '#fff', // 整体背景色
'--db-background-2': '#fff', // 布局背景色
'--db-background-3': '#f6f7fb', // 列表背景色
'--db-el-background-1': '#fff', // 组件背景色,输入框...
'--db-el-background-2': '#F5F7FA', // 组件背景色,按钮、分页、加载...
'--db-el-background-3': '#F5F7FA', // 组件背景色表格头部、下拉框hover...
'--db-el-title': '#76838f', // 标题字体颜色
'--db-el-text': '#36474f', // 一般字体颜色
'--db-el-color-primary': '#409EFF', // elment-ui主题色激活
'--db-el-border': 'transparent' // 边框颜色
}
const mergedTheme = { ...defaultTheme, ...config?.customTheme }
const style = document.createElement('style')
style.type = 'text/css'
let themeStr = ''
for (const key in mergedTheme) {
themeStr += `${key}:${mergedTheme[key]};`
}
// 给body添加class bs-body-theme-wrap
document.body.classList.add('bs-body-theme-wrap')
style.innerHTML = `.bs-body-theme-wrap {${themeStr}}`
document.getElementsByTagName('head')[0].appendChild(style)
}
// 注册配置
export default function (config, router) {
window.BS_CONFIG = {}
window.BS_CONFIG = configDeepMerge(window.BS_CONFIG, config)
if (!config?.httpConfigs?.fileUrlPrefix) {
// 如果没有配置文件访问前缀使用baseURL加上/static作为文件前缀
window.BS_CONFIG.httpConfigs.fileUrlPrefix = window.BS_CONFIG.httpConfigs.baseURL + '/static'
}
// 注册路由
registerRouters(config, router)
// 注册自定义主题
registerTheme(config)
}

View File

@@ -0,0 +1,42 @@
/*
* @description: 批量导入所有右侧配置组件
* @Date: 2023-03-13 10:04:58
* @Author: xing.heng
* @LastEditors: xing.heng
* @LastEditTime: 2023-05-17 13:18:36
*/
const modules = {};
const replaceName = {};
// 排除的组件
const excludeCommponents = []; // 有的话就添加进去
function importComponentSetting(files) {
files
.keys()
.filter((key) => {
return key.match(/setting/);
})
.forEach((key) => {
// 正则,取到./和/之间的字符串
const reg = new RegExp("(.\\/)(.*)(\\/)");
let moduleName = key.match(reg)[0].replace(/(\.\/)|(\/)/g, "");
// 替换组件名称
if (replaceName[moduleName]) {
moduleName = replaceName[moduleName];
}
// 去掉排除的组件
if (!excludeCommponents.includes(moduleName)) {
modules[moduleName] = files(key).default;
}
});
}
importComponentSetting(
require.context("data-room-ui/BasicComponents", true, /\.vue$/)
);
importComponentSetting(require.context("data-room-ui/Borders", true, /\.vue$/));
importComponentSetting(
require.context("data-room-ui/Decorations", true, /\.vue$/)
);
importComponentSetting(
require.context("data-room-ui/Configuration", true, /\.vue$/)
);
export default modules;

View File

@@ -0,0 +1,64 @@
// 设置表格高度
const doResize = async (el, binding, vnode) => {
// 获取表格Dom对象
const {
componentInstance: $table
} = await vnode
// 获取调用传递过来的数据
const {
value
} = binding
if (!$table.height) {
throw new Error("使用v-table指令,el-table需设置height,例如: height='0'")
}
// 获取距底部距离(用于展示页码等信息)
const bottomOffset = value || 100
if (!$table) return
// 计算列表高度并设置
let height = window.innerHeight - el.getBoundingClientRect().top - bottomOffset
height = height + 32 // 针对没有底部适配
$table.layout.setHeight(height)
$table.doLayout()
}
// 节流函数
const throttle = (fn) => {
let flag = null
return function () {
if (!flag) {
flag = setTimeout(() => {
fn()
flag = null
}
, 500)
}
}
}
export default {
// 初始化设置
bind (el, binding, vnode) {
// 设置resize监听方法
el.resizeListener = async () => {
await doResize(el, binding, vnode)
}
// 绑定监听方法
window.addEventListener('resize', throttle(el.resizeListener))
},
// 绑定默认高度
async inserted (el, binding, vnode) {
await doResize(el, binding, vnode)
},
// 更新数据时延时绑定高度
async componentUpdated (el, binding, vnode) {
await setTimeout(() => {
doResize(el, binding, vnode)
}, 500)
},
// 销毁时设置
unbind (el) {
// 移除resize监听
window.removeEventListener('resize', throttle(el.resizeListener))
}
}

View File

@@ -0,0 +1,121 @@
/**
* @Description: 主题设置格式化
* @author liu.shiyi
* @date 2023/8/17 14:47
*/
// 将组件中的setting里面的主题设置颜色存放到theme里面
export function settingToTheme (config, type) {
// 考虑与上一次保存过的主题进行合并
// 排除掉主题非暗黑非明亮的情况
if (['dark', 'light'].includes(type)) {
const theme = { dark: { ...config?.theme?.dark }, light: { ...config?.theme?.light } }
// 根据组件的type来判断主题的转化方式
// 如果是g2组件或者远程组件
if (['customComponent', 'remoteComponent', 'echartsComponent'].includes(config.type)) {
config.setting.forEach((setItem) => {
if (['gradual', 'colorPicker', 'colorSelect'].includes(setItem.type)) {
theme[type][setItem.field] = setItem.value
}
})
} else {
// 如果是普通组件
if (config.customize && Object.keys(config.customize).length) {
// customize属性存在层级
for (const item in config.customize) {
const value = config.customize[item]
// 如果包含二级属性
if (value && typeof value === 'object' && Object.keys(value).length) {
// 对于二级属性
for (const subKey in value) {
if (subKey.includes('color') || subKey.includes('Color') || subKey.includes('BGC')) {
theme[type][`${item}_${subKey}`] = value[subKey]
}
}
} else {
// 如果只有一级属性
if (item.includes('color') || item.includes('Color') || item.includes('BGC')) {
theme[type][item] = config.customize[item]
}
}
}
}
}
return theme
} else {
return config?.theme || { dark: {}, light: {} }
}
}
// 将保存的theme主题设置颜色存放到chartList
export function themeToSetting (chartList, type) {
let modifiedChartList = chartList
let finalChartList = chartList
// 排除掉主题非暗黑非明亮的情况
if (['dark', 'light'].includes(type)) {
modifiedChartList = chartList.map((item) => {
// 使用 map 方法遍历 chartList 数组并执行操作chartThemeToSetting
return chartThemeToSetting(item, type)
})
finalChartList = modifiedChartList.map((item) => {
// 如果当前项的 type 为 'chartTab',遍历其 tabList 数组并执行操作chartThemeToSetting
if (item.type === 'chartTab' && Array.isArray(item.customize.tabList) && item.customize.tabList.length) {
const modifiedChildren = item.customize.tabList.map((child) => {
return { ...child, chart: chartThemeToSetting(child.chart, type) }
})
return { ...item, customize: { ...item.customize, tabList: modifiedChildren } }
}
return item
})
}
return finalChartList
}
// 对单个组件进行主题设置从theme到Setting
function chartThemeToSetting (chart, type) {
if (chart.option && chart.option.theme) {
chart.option.theme = type === 'dark' ? 'transparent' : 'light'
}
if (chart.theme && chart.theme[type]) {
// 如果是g2组件或者远程组件
if (['customComponent', 'remoteComponent', 'echartsComponent'].includes(chart.type)) {
for (const item of chart.setting) {
// 检查 obj 中是否存在与 item.field 相对应的属性
if (Object.prototype.hasOwnProperty.call(chart.theme[type], item.field)) {
// 更新 setting 中对应项的 value 值为 theme 中的属性值
item.value = chart.theme[type][item.field]
}
}
} else {
// 如果是普通组件
if (chart.customize && Object.keys(chart.customize).length) {
for (const key in chart.theme[type]) {
const value = chart.theme[type][key]
// 如果对应的是二级属性
if (key.includes('_')) {
const [propertyName, subPropertyName] = key.split('_')
if (!chart.customize[propertyName]) {
chart.customize[propertyName] = {}
} else {
chart.customize[propertyName][subPropertyName] = value
}
} else {
// 对应的一级属性
if (Object.prototype.hasOwnProperty.call(chart.customize, key)) {
// 更新 customize 中对应项的值为 theme 中的属性值
chart.customize[key] = chart.theme[type][key]
}
}
}
for (const item in chart.customize) {
// 检查 obj 中是否存在与 customize 相对应的属性
if (Object.prototype.hasOwnProperty.call(chart.theme[type], item)) {
// 更新 customize 中对应项的值为 theme 中的属性值
chart.customize[item] = chart.theme[type][item]
}
}
}
}
}
return chart
}

View File

@@ -0,0 +1,13 @@
export default function updateTheme (data) {
const querySelectorName = data === false ? false : !data ? '.el-button--primary' : data
if (querySelectorName) {
window.requestAnimationFrame(() => {
const primaryButton = document.querySelector(querySelectorName)
if (primaryButton) {
const backgroundColor = window.getComputedStyle(primaryButton).getPropertyValue('background-color')
const element = document.querySelector('.bs-body-theme-wrap')
element.style.setProperty('--bs-el-color-primary', backgroundColor)
}
})
}
}

View File

@@ -0,0 +1,8 @@
// 是否是火狐浏览器
export const isFirefox = () => {
const userAgent = navigator.userAgent
if (userAgent.indexOf('Firefox') > -1) {
return true
}
return false
}

View File

@@ -0,0 +1,35 @@
/**
* @description 文字转语音方法
* @public
* @param { text, rate, lang, volume, pitch } object
* @param text 要合成的文字内容,字符串
* @param rate 读取文字的语速 0.1~10 正常1
* @param lang 读取文字时的语言
* @param volume 读取时声音的音量 0~1 正常1
* @param pitch 读取时声音的音高 0~2 正常1
* @returns SpeechSynthesisUtterance
*/
export default function speak ({ text, speechRate, lang, volume, pitch }, endEvent, startEvent) {
if (!window.SpeechSynthesisUtterance) {
console.warn('当前浏览器不支持文字转语音服务')
return
}
if (!text) {
return
}
const speechUtterance = new SpeechSynthesisUtterance()
speechUtterance.text = text
speechUtterance.rate = speechRate || 1
speechUtterance.lang = lang || 'zh-CN'
speechUtterance.volume = volume || 1
speechUtterance.pitch = pitch || 1
speechUtterance.onend = function () {
endEvent && endEvent()
}
speechUtterance.onstart = function () {
startEvent && startEvent()
}
speechSynthesis.speak(speechUtterance)
}