物管理前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

848 lines
28 KiB

window.isJSON = function (str) {
if (typeof str != 'string') { // 1、传入值必须是 字符串
return false;
}
try {
var obj = JSON.parse(str); // 2、仅仅通过 JSON.parse(str),不能完全检验一个字符串是JSON格式的字符串
if (typeof obj == 'object' && obj) { //3、还必须是 object 类型
return true;
} else {
return false;
}
} catch (e) {
return false;
}
return false;
}
// 解析最新值
window.resolveScadaNewValue = (defaultValue) => {
if (defaultValue) {
let valueParsed = [{
val: ''
}];
let realValue = ''
try {
valueParsed = JSON.parse(defaultValue) || [{ val: '' }];
if (valueParsed[0]) {
realValue = valueParsed[0].val;
} else {
realValue = valueParsed[0] === undefined ? '' : valueParsed[0]
}
} catch (err) {
console.log('err', err)
}
return realValue;
} else {
return ''
}
}
// 字体颜色动态改变
window.changeFontColor = (style, properties) => {
const { uiData } = properties.dynamic || {};
if (uiData) {
const realValue = window.resolveScadaNewValue(uiData.defaultValue)
if (realValue !== '') {
uiData.conditionVariables.forEach((item) => {
if (item.type === 'rangeColor') {
let from = item.from;
let to = item.to;
if (item.from >= item.to) {
from = item.to;
to = item.from;
}
if (item.fontColor && Number(realValue) >= from && Number(realValue) <= to) {
style.color = item.fontColor
}
} else if (item.type === 'equal') {
if (Number(realValue) === Number(item.value)) {
item.fontColor && (style.color = item.fontColor);
}
} else if (item.type === 'boolean') {
if (realValue === 'true' || realValue === true) {
item.fontColor && (style.color = item.backColor);
}
}
})
}
}
}
// 背景颜色改变
window.changeBackgroundColor = (style, properties) => {
const { uiData } = properties.dynamic || {};
if (uiData) {
const realValue = window.resolveScadaNewValue(uiData.defaultValue)
if (realValue !== '') {
uiData.conditionVariables.forEach((item) => {
if (item.type === 'rangeColor') {
let from = item.from;
let to = item.to;
if (item.from >= item.to) {
from = item.to;
to = item.from;
}
if (item.backColor && Number(realValue) >= from && Number(realValue) <= to) {
style.fill = item.backColor
}
} else if (item.type === 'equal') {
if (Number(realValue) === Number(item.value)) {
item.backColor && (style.fill = item.backColor);
}
} else if (item.type === 'boolean') {
if (realValue === 'true' || realValue === true) {
item.backColor && (style.fill = item.backColor);
}
}
})
}
}
}
// 创建 svg 图案
window.createSvgPattern = (id, href, width, height) => {
const defsId = 'defs-' + id;
const patternId = 'pattern-' + id;
const oldDefs = document.getElementById(defsId);
const oldPattern = document.getElementById(patternId);
if (oldDefs) {
oldDefs.remove();
}
if (oldPattern) {
oldPattern.remove();
}
const defs = document.createElement('defs');
defs.setAttribute('id', 'defs-' + id);
const pattern = document.createElement('pattern');
pattern.setAttribute('id', 'pattern-' + id);
pattern.setAttribute('width', '1');
pattern.setAttribute('height', '1');
pattern.setAttribute('patternUnits', 'objectBoundingBox');
const img = document.createElement('image');
img.setAttribute('width', width);
img.setAttribute('height', height);
img.setAttribute("xlink:href", href);
pattern.appendChild(img);
defs.append(pattern);
const canvasOverlay = document.querySelector('.lf-canvas-overlay')
canvasOverlay.prepend(defs);
}
var messageFn = (msg) => {
layui.use('layer', function () {
const layer = layui.layer;
layer.msg(msg);
});
}
window.totalListeners = {
'click': [],
'dbclick': [],
'mouseenter': [],
'mouseleave': []
}
// 没有明确点击下发指令的部件,像普通的图形或图片也有可能会下发指令,因此也需要绑定好事件监听。
window.nodeEventsListeners = (self) => {
const clickHandler = function ({ data }) {
if (data.id !== this.id) return
this.graphModel.eventCenter.emit('myNode:click', { data: this, e: this.realValue })
};
const clickHandlerBound = clickHandler.bind(self)
window.totalListeners.click.push(clickHandlerBound)
const dbclickHandler = function ({ data }) {
if (data.id !== this.id) return
this.graphModel.eventCenter.emit('myNode:dbclick', { data: this, e: this.realValue })
}
const dbclickHandlerBound = dbclickHandler.bind(self)
window.totalListeners.dbclick.push(dbclickHandlerBound)
const mouseEnterHandler = function ({ data }) {
if (data.id !== this.id) return
this.graphModel.eventCenter.emit('myNode:mouseenter', { data: this, e: this.realValue })
}
const mouseEnterHandlerBound = mouseEnterHandler.bind(self)
window.totalListeners.mouseenter.push(mouseEnterHandlerBound)
const mouseLeaveHandler = function ({ data }) {
if (data.id !== this.id) return
this.graphModel.eventCenter.emit('myNode:mouseleave', { data: this, e: this.realValue })
}
const mouseLeaveHandlerBound = mouseLeaveHandler.bind(self)
window.totalListeners.mouseleave.push(mouseLeaveHandlerBound)
}
// 判断矩形是否相交
function calcBoundingBox(boundingBox) {
const boundingBoxLeft = boundingBox.x
const boundingBoxRight = boundingBox.x + boundingBox.width || boundingBox.properties.width
const boundingBoxTop = boundingBox.y
const boundingBoxBottom = boundingBox.y + boundingBox.height || boundingBox.properties.height
return {
boundingBoxLeft,
boundingBoxRight,
boundingBoxTop,
boundingBoxBottom,
}
}
function getEdgeWidthHeight(edge) {
if (!edge)
return
let edgeStartPoint = {
x: 0,
y: 0,
}
let edgeEndPoint = {
x: 0,
y: 0,
}
if (edge.modelType === 'line-edge') {
edgeStartPoint = edge.startPoint
edgeEndPoint = edge.endPoint
}
else {
edgeStartPoint = edge.pointsList[0]
edgeEndPoint = edge.pointsList[edge.pointsList.length - 1]
}
const width = Math.abs(edgeEndPoint.x - edgeStartPoint.x)
const height = Math.abs(edgeEndPoint.y - edgeStartPoint.y)
return {
x: edgeStartPoint.x < edgeEndPoint.x ? edgeStartPoint.x : edgeEndPoint.x,
y: edgeStartPoint.y < edgeEndPoint.y ? edgeStartPoint.y : edgeEndPoint.y,
width,
height,
}
}
// 应该取名为是否相交(图层上移下移用到),为了避免影响原来的代码,就叫这个吧。
const isInsideBoundingBox = function (elementBox, boundingBox) {
const elementLeft = elementBox.x
const elementRight = elementBox.x + elementBox.width
const elementTop = elementBox.y
const elementBottom = elementBox.y + elementBox.height
const { boundingBoxLeft, boundingBoxRight, boundingBoxBottom, boundingBoxTop } = calcBoundingBox(boundingBox)
if (
elementRight < boundingBoxLeft
|| elementLeft > boundingBoxRight
|| elementTop > boundingBoxBottom
|| elementBottom < boundingBoxTop
)
return false // 两个矩形不相交
return true // 两个矩形相交
}
const isRealInsideBoundingBox = function (elementBox, boundingBox) {
const elementLeft = elementBox.x
const elementRight = elementBox.x + elementBox.width
const elementTop = elementBox.y
const elementBottom = elementBox.y + elementBox.height
const { boundingBoxLeft, boundingBoxRight, boundingBoxBottom, boundingBoxTop } = calcBoundingBox(boundingBox)
if (
(elementLeft >= boundingBoxLeft && elementLeft < boundingBoxRight)
&& (elementRight <= boundingBoxRight && elementRight > boundingBoxLeft)
&& (elementTop >= boundingBoxTop && elementTop < boundingBoxBottom)
&& (elementBottom <= boundingBoxBottom && elementBottom > boundingBoxTop)
)
return true // 一个矩形在另一个矩形之内
return false
}
const getMaxBoundingBox = function (selects) {
const { nodes, edges } = selects
let maxBoundingNode = nodes[0]
let maxBoundingEdge = getEdgeWidthHeight(edges[0])
if (nodes.length > 0) {
nodes.forEach((node, index) => {
if (node.type === 'helper-circle-point')
return
const area = node.properties.width * node.properties.height
const oldArea = maxBoundingNode.properties.width * maxBoundingNode.properties.height
if (area > oldArea)
maxBoundingNode = node
})
}
if (maxBoundingNode) {
const w = maxBoundingNode.width || maxBoundingNode.properties.width
const h = maxBoundingNode.height || maxBoundingNode.properties.height
maxBoundingNode = {
x: maxBoundingNode.x - w / 2,
y: maxBoundingNode.y - h / 2,
width: w,
height: h,
}
}
if (edges.length > 0) {
edges.forEach((edge, index) => {
const edgeWidthHeight = getEdgeWidthHeight(edge)
if (edgeWidthHeight) {
const { width, height } = edgeWidthHeight
const area = width * height
if (maxBoundingEdge) {
const { width: oldWidth, height: oldHeight } = maxBoundingEdge
const oldArea = oldWidth * oldHeight
if (area > oldArea)
maxBoundingEdge = edge
}
}
})
}
if (maxBoundingNode && !maxBoundingEdge) {
return maxBoundingNode
}
else if (!maxBoundingNode && maxBoundingEdge) {
return maxBoundingEdge
}
else if (maxBoundingNode && maxBoundingEdge) {
if ((maxBoundingNode.width * maxBoundingNode.height) > (maxBoundingEdge.width * maxBoundingEdge.height))
return maxBoundingNode
else
return maxBoundingEdge
}
}
// 计算某个元素内部的所有节点元素(不包括连线)
window.calcInsideAreaElements = (lf, selects) => {
// 矩形相交的元素
let areaElements = []
// 获取最大的 boundingBox
const maxBounding = getMaxBoundingBox(selects)
if (!maxBounding)
return
lf.graphModel.nodes.forEach((node) => {
if (node.type === 'helper-circle-point')
return
const ABox = {
x: node.x - node.width / 2,
y: node.y - node.height / 2,
width: node.width,
height: node.height,
}
const isIn = isRealInsideBoundingBox(ABox, maxBounding)
if (isIn) {
areaElements.push(node)
}
})
return areaElements
}
// 数据点绑定时候的 数据处理函数, 全局的。
window.dataProcessFn = function (event) {
const { info, apiid, defaultValueIndex, values, deviceIdCodeMap } = event;
const {
context, service, nodeId, dataPointStr, dynamicFlag,
dataSource, deviceCode, devices, enableDataHandle, deviceAttrs, calcRules, uniquePoint, dataPoint, attrs, callBacks,
} = info
// console.log('nodeId', nodeId);
// console.log('开始数据处理了', deviceIdCodeMap)
const totalValues = []
if (calcRules && calcRules.length > 0) {
if (deviceAttrs && deviceAttrs.table && deviceAttrs.table.length > 0) {
const newDeviceTable = []
const valuesGroup = {}
const codeAttrToNumMap = {}
const nums = deviceAttrs.table.map(i => {
const code = deviceIdCodeMap[i.devices]
valuesGroup[i.num] = []
codeAttrToNumMap[code + '-' + i.dataPoint] = i.num
newDeviceTable.push({
...i,
deviceCode: code
})
return i.num
})
// 根据 物+属性 聚合分类
values.forEach((val) => {
const findNum = codeAttrToNumMap[val.thingCode + '-' + val.attrKey]
if (findNum) {
valuesGroup[findNum].push({ ...val })
}
})
calcRules.forEach((rule) => {
const findNum = newDeviceTable.find(d => d.num === rule.resultAttr)
if (findNum) {
// 计算结果属性为已经存在的序号
valuesGroup[findNum.num].forEach((val, index) => {
let newFormular = rule.formular
nums.forEach(n => {
if (newFormular.includes(n)) {
const otherValue = valuesGroup[n][index].val
newFormular = newFormular.replace(n, otherValue)
}
})
const fn = new Function('', `return ${newFormular}`)
let newValue = fn()
val.val = newValue
})
} else {
// 创建新的属性
if (nums.length > 0) {
// 默认使用第一组的数据长度做为新的数据长度
const newThingAndAttr = valuesGroup[nums[0]].map((val, index) => {
let newFormular = rule.formular
nums.forEach(n => {
if (newFormular.includes(n)) {
const otherValue = valuesGroup[n][index].val
newFormular = newFormular.replace(n, otherValue)
}
})
let newValue = eval(newFormular)
return {
thingCode: rule.resultAttr,
attrKey: rule.resultAttr,
ts: val.ts,
val: newValue
}
})
valuesGroup[rule.resultAttr] = newThingAndAttr
}
}
})
// console.log('valuesGroup', valuesGroup);
if (uniquePoint && nums.includes(uniquePoint)) {
totalValues.push(...valuesGroup[uniquePoint])
} else {
Object.values(valuesGroup).forEach(valGroup => {
totalValues.push(...valGroup)
})
}
// console.log('totalValues', totalValues)
let dataPointValue = JSON.stringify(totalValues)
return dataPointValue
}
}
}
// 寻找最低采集频率
window.filterMinimumFrequency = (info, historyDatas) => {
let totals = [];
const thingGrouped = window._.groupBy(historyDatas, 'thingCode');
for (const thingKey in thingGrouped) {
const attrGrouped = window._.groupBy(thingGrouped[thingKey], 'attrKey')
Object.keys(attrGrouped).forEach((attrkey) => {
totals.push(info[thingKey].attrs[attrkey].rate);
})
}
const filteredTotals = totals.filter(Boolean)
if (filteredTotals.length === 0) {
return 0
} else {
return Math.min(...filteredTotals)
}
}
// 柱状图和折线图的完整时间(数据补全用到)
window.completeTimesForChart = function (apiDetails, info, historyDatas, apiid) {
if (!apiDetails) return;
// 首先确定开始和结束时间
let startTime = null
let endTime = null
if (apiDetails.type === 'range') {
startTime = apiDetails.startTime
endTime = apiDetails.endTime
} else if (apiDetails.type === 'nearest') {
const { day, hour, minute } = apiDetails.nearest
endTime = window.dayjs()
startTime = endTime.subtract(day, 'days').subtract(hour, 'hours').subtract(minute, 'minutes')
} else if (apiDetails.type === 'interval') {
const { duration, type } = apiDetails.interval
if (type === 'day') {
endTime = window.dayjs().endOf('day')
startTime = endTime.subtract(duration, 'day').add(1, 'second')
} else if (type === 'week') {
endTime = window.dayjs().endOf('week')
startTime = endTime.subtract(duration, 'week').add(1, 'second')
} else if (type === 'month') {
endTime = window.dayjs().endOf('month');
const lastDayofMonth = endTime.subtract(duration, 'month');
startTime = lastDayofMonth.endOf('month').add(1, 'second');
} else if (type === 'year') {
endTime = window.dayjs().endOf('year')
startTime = endTime.subtract(duration, 'year').add(1, 'second')
}
}
if (startTime && endTime) {
const totalTimes = [dayjs(startTime).millisecond(0).valueOf()];
const { day, hour, minute } = apiDetails.agg;
let newEndTime = null;
if (day) {
newEndTime = dayjs(startTime).add(day, 'days').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(day, 'days').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
return totalTimes;
} else if (hour) {
newEndTime = dayjs(startTime).add(hour, 'hours').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(hour, 'hours').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
return totalTimes;
} else if (minute) {
newEndTime = dayjs(startTime).add(minute, 'minutes').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(minute, 'minutes').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
return totalTimes;
} else if (apiDetails.type === 'interval' && !apiDetails.func && !day && !hour && !minute) {
const { duration, type } = apiDetails.interval
const min = window.filterMinimumFrequency(info, historyDatas);
if (!min) {
if (type === 'day') {
newEndTime = dayjs(startTime).add(1, 'hours').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'hours').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
} else if (type === 'week') {
newEndTime = dayjs(startTime).add(1, 'days').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'days').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
} else if (type === 'month') {
newEndTime = dayjs(startTime).add(1, 'days').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'days').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
} else if (type === 'year') {
newEndTime = dayjs(startTime).add(1, 'months').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'months').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
}
} else {
newEndTime = dayjs(startTime).add(min, 'seconds').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(min, 'seconds').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
}
return totalTimes;
} else if (apiDetails.type !== 'interval' && !apiDetails.func && !day && !hour && !minute) {
const days = startTime.diff(endTime, 'day');
const months = startTime.diff(endTime, 'month');
const min = window.filterMinimumFrequency(info, historyDatas);
if (!min) {
if (months === 0 && days === 0) {
newEndTime = dayjs(startTime).add(1, 'hours').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'hours').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
} else if (months === 0 && days > 0) {
newEndTime = dayjs(startTime).add(1, 'days').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'days').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
} else if (months > 0 && days >= 0) {
newEndTime = dayjs(startTime).add(1, 'months').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(1, 'months').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
}
} else {
newEndTime = dayjs(startTime).add(min, 'seconds').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(min, 'seconds').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
}
return totalTimes;
} else if (day && hour && minute) {
newEndTime = dayjs(startTime).add(day, 'days').add(hour, 'hours').add(minute, 'minutes').millisecond(0).valueOf();
totalTimes.push(newEndTime);
while (dayjs(newEndTime).isBefore(dayjs(endTime))) {
newEndTime = dayjs(newEndTime).add(day, 'days').add(hour, 'hours').add(minute, 'minutes').millisecond(0).valueOf();
if (dayjs(newEndTime).isBefore(dayjs(endTime))) {
totalTimes.push(newEndTime);
}
}
return totalTimes;
}
}
}
// 柱状图/折线图时间分割,今日-昨日,当月-上月,今年-去年
window.splitTimes = function (totalTimes, timeCompare) {
const prev = []
const curr = []
if (timeCompare === 'day') {
totalTimes.forEach((t) => {
if (dayjs(t).isBefore(dayjs().startOf('day'))) {
prev.push(t)
} else {
curr.push(t)
}
})
} else if (timeCompare === 'month') {
totalTimes.forEach((t) => {
if (dayjs(t).month() < dayjs().month()) {
prev.push(t)
} else {
curr.push(t)
}
})
} else if (timeCompare === 'year') {
totalTimes.forEach((t) => {
if (dayjs(t).year() < dayjs().year()) {
prev.push(t)
} else {
curr.push(t)
}
})
}
return {
prev, curr
}
}
// 把 css 渐变颜色转换成 svg 渐变标签
window.generateSVGGradient = function (gradientString, gradientId) {
// 解析渐变颜色字符串
// 解析渐变颜色字符串
const regex = /linear-gradient\((.+?),(.+?)\s([0-9]+%)\s?,\s(.+?)\s([0-9]+%)\)/;
const matches = gradientString.match(regex);
if (!matches || matches.length < 6) {
return null;
}
const direction = matches[1];
const startColor = matches[2];
const startPercentage = matches[3];
const endColor = matches[4];
const endPercentage = matches[5];
// 确定渐变方向和坐标范围
let x1, y1, x2, y2;
if (direction.includes("deg")) {
const degrees = parseFloat(direction);
const radians = (degrees * Math.PI) / 180;
x1 = Math.cos(radians).toFixed(2);
y1 = Math.sin(radians).toFixed(2);
x2 = Math.cos(radians + Math.PI).toFixed(2);
y2 = Math.sin(radians + Math.PI).toFixed(2);
} else {
// 处理其他方向信息(例如 to top, to bottom, to left, to right 等)
// 根据具体需求进行处理
return null;
}
// 渐变元素
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
const linearGradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
// 设置渐变元素属性值
linearGradient.setAttribute("id", gradientId);
linearGradient.setAttribute("x1", x1);
linearGradient.setAttribute("y1", y1);
linearGradient.setAttribute("x2", x2);
linearGradient.setAttribute("y2", y2);
// 创建 stop 元素并设置属性值
const startStop = document.createElementNS("http://www.w3.org/2000/svg", "stop");
startStop.setAttribute("offset", startPercentage);
startStop.style.stopColor = startColor;
const endStop = document.createElementNS("http://www.w3.org/2000/svg", "stop");
endStop.setAttribute("offset", endPercentage);
endStop.style.stopColor = endColor;
// 将 stop 元素添加到渐变元素中
linearGradient.appendChild(startStop);
linearGradient.appendChild(endStop);
// 将渐变元素添加到 SVG 元素中
defs.appendChild(linearGradient);
// 返回生成的 渐变标签
return defs;
}
// 登录获取唯一标识
const getUuid = () => {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
// 创建登录弹框
window.createLoginDialog = function () {
const { createApp, createVNode, render } = Vue;
const app = createApp({})
const Login = {
template: `<div style="position: absolute;top: 50%;left: 50%;margin-top: -178px;margin-left: -170px;z-index: 1000;background-color: #ffffff;">
<div class="layui-field-box">
<div class="layui-form-item logo-title">
<h1 style="color: #1E9FFF; font-size: 20px;text-align: center">登录系统<span style="float: right; cursor: pointer" @click="remove"><i class="layui-icon layui-icon-close"></i></span></h1>
</div>
<form class="layui-form layui-form-pane">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input v-model="username" type="text" name="username" lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input v-model="password" type="password" name="password" lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn layui-btn-normal layui-btn-fluid" @click="loginHandler">立即登录</button>
</div>
</form>
</div>
</div>`,
props: {
},
emits: ["loginFinished"],
setup(props, { emit }) {
const { ref, watch } = Vue
const username = ref('')
const password = ref('')
const loginHandler = (e) => {
e.preventDefault();
e.stopPropagation();
if (!username || !password) {
return;
}
const loadIdx = window.layer.load(1, {
shade: [0.2, '#000'],
})
window.service.post("/login/noCaptcha", {
username: username.value,
password: password.value,
uuid: getUuid(),
captcha: "11"
})
.then((res) => {
if (res.code !== 0) {
window.layer.close(loadIdx);
window.layui.use('layer', function(){
const layer = layui.layer;
layer.msg(res.msg);
});
return;
}
sessionStorage.setItem('v1@CacheToken', JSON.stringify(res.data), true);
emit("loginFinished");
window.layer.close(loadIdx);
setTimeout(() => {
window.location.reload();
}, 500)
})
.catch(() => {
});
}
function remove () {
const loginDom = document.getElementById('loginModal');
loginDom && document.body.removeChild(loginDom);
}
return {
username,
password,
loginHandler,
remove,
}
}
}
const el = document.createElement('div');
el.id = 'loginModal';
el.style = `position: absolute; top:0; bottom: 0; width: 100%; height: 100%; z-index: 990;background-color: rgba(0,0,0,0.8);`
const loginHandler = () => {
document.body.removeChild(el);
}
const loginDom = document.getElementById('loginModal');
if (!loginDom) {
const instance = createVNode(Login, {
onLoginFinished: loginHandler
})
instance.appContext = app._context
render(instance, el);
document.body.appendChild(el);
}
}