项目初始化
This commit is contained in:
30
src/utils/auth.js
Normal file
30
src/utils/auth.js
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
const TokenKey = "token";
|
||||
|
||||
const ExpiresInKey = "Meta-Enterprise-Expires-In";
|
||||
|
||||
export function getToken() {
|
||||
return Cookies.get(TokenKey);
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
return Cookies.set(TokenKey, token);
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
return Cookies.remove(TokenKey);
|
||||
}
|
||||
|
||||
export function getExpiresIn() {
|
||||
return Cookies.get(ExpiresInKey) || -1;
|
||||
}
|
||||
|
||||
export function setExpiresIn(time) {
|
||||
return Cookies.set(ExpiresInKey, time);
|
||||
}
|
||||
|
||||
export function removeExpiresIn() {
|
||||
return Cookies.remove(ExpiresInKey);
|
||||
}
|
||||
583
src/utils/bigDecimal.js
Normal file
583
src/utils/bigDecimal.js
Normal file
@@ -0,0 +1,583 @@
|
||||
var bigDecimal = (function (e) {
|
||||
var n = {}
|
||||
function t(r) {
|
||||
if (n[r]) return n[r].exports
|
||||
var i = (n[r] = { i: r, l: !1, exports: {} })
|
||||
return e[r].call(i.exports, i, i.exports, t), (i.l = !0), i.exports
|
||||
}
|
||||
return (
|
||||
(t.m = e),
|
||||
(t.c = n),
|
||||
(t.d = function (e, n, r) {
|
||||
t.o(e, n) || Object.defineProperty(e, n, { enumerable: !0, get: r })
|
||||
}),
|
||||
(t.r = function (e) {
|
||||
'undefined' != typeof Symbol &&
|
||||
Symbol.toStringTag &&
|
||||
Object.defineProperty(e, Symbol.toStringTag, { value: 'Module' }),
|
||||
Object.defineProperty(e, '__esModule', { value: !0 })
|
||||
}),
|
||||
(t.t = function (e, n) {
|
||||
if ((1 & n && (e = t(e)), 8 & n)) return e
|
||||
if (4 & n && 'object' == typeof e && e && e.__esModule) return e
|
||||
var r = Object.create(null)
|
||||
if (
|
||||
(t.r(r),
|
||||
Object.defineProperty(r, 'default', { enumerable: !0, value: e }),
|
||||
2 & n && 'string' != typeof e)
|
||||
)
|
||||
for (var i in e)
|
||||
t.d(
|
||||
r,
|
||||
i,
|
||||
function (n) {
|
||||
return e[n]
|
||||
}.bind(null, i)
|
||||
)
|
||||
return r
|
||||
}),
|
||||
(t.n = function (e) {
|
||||
var n =
|
||||
e && e.__esModule
|
||||
? function () {
|
||||
return e.default
|
||||
}
|
||||
: function () {
|
||||
return e
|
||||
}
|
||||
return t.d(n, 'a', n), n
|
||||
}),
|
||||
(t.o = function (e, n) {
|
||||
return Object.prototype.hasOwnProperty.call(e, n)
|
||||
}),
|
||||
(t.p = ''),
|
||||
t((t.s = 6))
|
||||
)
|
||||
})([
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
function r(e) {
|
||||
for (
|
||||
var n = '',
|
||||
t = e.length,
|
||||
r = e.split('.')[1],
|
||||
i = r ? r.length : 0,
|
||||
o = 0;
|
||||
o < t;
|
||||
o++
|
||||
)
|
||||
e[o] >= '0' && e[o] <= '9' ? (n += 9 - parseInt(e[o])) : (n += e[o])
|
||||
return u(n, i > 0 ? '0.' + new Array(i).join('0') + '1' : '1')
|
||||
}
|
||||
function i(e) {
|
||||
var n = e.split('.')
|
||||
for (n[0] || (n[0] = '0'); '0' == n[0][0] && n[0].length > 1;)
|
||||
n[0] = n[0].substring(1)
|
||||
return n[0] + (n[1] ? '.' + n[1] : '')
|
||||
}
|
||||
function o(e, n) {
|
||||
var t = e.split('.'),
|
||||
r = n.split('.'),
|
||||
i = t[0].length,
|
||||
o = r[0].length
|
||||
return (
|
||||
i > o
|
||||
? (r[0] =
|
||||
new Array(Math.abs(i - o) + 1).join('0') + (r[0] ? r[0] : ''))
|
||||
: (t[0] =
|
||||
new Array(Math.abs(i - o) + 1).join('0') + (t[0] ? t[0] : '')),
|
||||
(i = t[1] ? t[1].length : 0),
|
||||
(o = r[1] ? r[1].length : 0),
|
||||
(i || o) &&
|
||||
(i > o
|
||||
? (r[1] =
|
||||
(r[1] ? r[1] : '') + new Array(Math.abs(i - o) + 1).join('0'))
|
||||
: (t[1] =
|
||||
(t[1] ? t[1] : '') + new Array(Math.abs(i - o) + 1).join('0'))),
|
||||
[
|
||||
(e = t[0] + (t[1] ? '.' + t[1] : '')),
|
||||
(n = r[0] + (r[1] ? '.' + r[1] : '')),
|
||||
]
|
||||
)
|
||||
}
|
||||
function u(e, n) {
|
||||
var t
|
||||
; (e = (t = o(e, n))[0]), (n = t[1])
|
||||
for (var r = '', i = 0, u = e.length - 1; u >= 0; u--)
|
||||
if ('.' !== e[u]) {
|
||||
var a = parseInt(e[u]) + parseInt(n[u]) + i
|
||||
; (r = (a % 10) + r), (i = Math.floor(a / 10))
|
||||
} else r = '.' + r
|
||||
return i ? i.toString() + r : r
|
||||
}
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }),
|
||||
(n.pad = n.trim = n.add = void 0),
|
||||
(n.add = function (e, n) {
|
||||
var t
|
||||
void 0 === n && (n = '0')
|
||||
var a = 0,
|
||||
s = -1
|
||||
'-' == e[0] && (a++, (s = 1), (e = e.substring(1)).length),
|
||||
'-' == n[0] && (a++, (s = 2), (n = n.substring(1)).length),
|
||||
(e = i(e)),
|
||||
(n = i(n)),
|
||||
(e = (t = o(i(e), i(n)))[0]),
|
||||
(n = t[1]),
|
||||
1 == a && (1 == s ? (e = r(e)) : (n = r(n)))
|
||||
var d = u(e, n)
|
||||
return a
|
||||
? 2 == a
|
||||
? '-' + i(d)
|
||||
: e.length < d.length
|
||||
? i(d.substring(1))
|
||||
: '-' + i(r(d))
|
||||
: i(d)
|
||||
}),
|
||||
(n.trim = i),
|
||||
(n.pad = o)
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }), (n.roundOff = void 0)
|
||||
var r = t(2)
|
||||
function i(e, n, t, i) {
|
||||
if (!e || e === new Array(e.length + 1).join('0')) return !1
|
||||
if (
|
||||
i === r.RoundingModes.DOWN ||
|
||||
(!t && i === r.RoundingModes.FLOOR) ||
|
||||
(t && i === r.RoundingModes.CEILING)
|
||||
)
|
||||
return !1
|
||||
if (
|
||||
i === r.RoundingModes.UP ||
|
||||
(t && i === r.RoundingModes.FLOOR) ||
|
||||
(!t && i === r.RoundingModes.CEILING)
|
||||
)
|
||||
return !0
|
||||
var o = '5' + new Array(e.length).join('0')
|
||||
if (e > o) return !0
|
||||
if (e < o) return !1
|
||||
switch (i) {
|
||||
case r.RoundingModes.HALF_DOWN:
|
||||
return !1
|
||||
case r.RoundingModes.HALF_UP:
|
||||
return !0
|
||||
case r.RoundingModes.HALF_EVEN:
|
||||
default:
|
||||
return parseInt(n[n.length - 1]) % 2 == 1
|
||||
}
|
||||
}
|
||||
function o(e, n) {
|
||||
void 0 === n && (n = 0),
|
||||
n || (n = 1),
|
||||
'number' == typeof e && e.toString()
|
||||
for (var t = '', r = e.length - 1; r >= 0; r--) {
|
||||
var i = parseInt(e[r]) + n
|
||||
10 == i ? ((n = 1), (i = 0)) : (n = 0), (t += i)
|
||||
}
|
||||
return n && (t += n), t.split('').reverse().join('')
|
||||
}
|
||||
n.roundOff = function e(n, t, u) {
|
||||
if (
|
||||
(void 0 === t && (t = 0),
|
||||
void 0 === u && (u = r.RoundingModes.HALF_EVEN),
|
||||
u === r.RoundingModes.UNNECESSARY)
|
||||
)
|
||||
throw new Error(
|
||||
'UNNECESSARY Rounding Mode has not yet been implemented'
|
||||
)
|
||||
'number' == typeof n && (n = n.toString())
|
||||
var a = !1
|
||||
'-' === n[0] && ((a = !0), (n = n.substring(1)))
|
||||
var s = n.split('.'),
|
||||
d = s[0],
|
||||
l = s[1]
|
||||
if (t < 0) {
|
||||
if (((t = -t), d.length <= t)) return '0'
|
||||
var f = d.substr(0, d.length - t)
|
||||
return (
|
||||
(a ? '-' : '') +
|
||||
(f = e((n = f + '.' + d.substr(d.length - t) + l), 0, u)) +
|
||||
new Array(t + 1).join('0')
|
||||
)
|
||||
}
|
||||
if (0 == t) {
|
||||
d.length
|
||||
return i(s[1], d, a, u) ? (a ? '-' : '') + o(d) : (a ? '-' : '') + d
|
||||
}
|
||||
if (!s[1]) return (a ? '-' : '') + d + '.' + new Array(t + 1).join('0')
|
||||
if (s[1].length < t)
|
||||
return (
|
||||
(a ? '-' : '') +
|
||||
d +
|
||||
'.' +
|
||||
s[1] +
|
||||
new Array(t - s[1].length + 1).join('0')
|
||||
)
|
||||
l = s[1].substring(0, t)
|
||||
var g = s[1].substring(t)
|
||||
return g && i(g, l, a, u) && (l = o(l)).length > t
|
||||
? o(d, parseInt(l[0])) + '.' + l.substring(1)
|
||||
: (a ? '-' : '') + d + '.' + l
|
||||
}
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }),
|
||||
(n.RoundingModes = void 0),
|
||||
(function (e) {
|
||||
; (e[(e.CEILING = 0)] = 'CEILING'),
|
||||
(e[(e.DOWN = 1)] = 'DOWN'),
|
||||
(e[(e.FLOOR = 2)] = 'FLOOR'),
|
||||
(e[(e.HALF_DOWN = 3)] = 'HALF_DOWN'),
|
||||
(e[(e.HALF_EVEN = 4)] = 'HALF_EVEN'),
|
||||
(e[(e.HALF_UP = 5)] = 'HALF_UP'),
|
||||
(e[(e.UNNECESSARY = 6)] = 'UNNECESSARY'),
|
||||
(e[(e.UP = 7)] = 'UP')
|
||||
})(n.RoundingModes || (n.RoundingModes = {}))
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
function r(e) {
|
||||
for (; '0' == e[0];) e = e.substr(1)
|
||||
if (-1 != e.indexOf('.'))
|
||||
for (; '0' == e[e.length - 1];) e = e.substr(0, e.length - 1)
|
||||
return (
|
||||
'' == e || '.' == e
|
||||
? (e = '0')
|
||||
: '.' == e[e.length - 1] && (e = e.substr(0, e.length - 1)),
|
||||
'.' == e[0] && (e = '0' + e),
|
||||
e
|
||||
)
|
||||
}
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }),
|
||||
(n.multiply = void 0),
|
||||
(n.multiply = function (e, n) {
|
||||
; (e = e.toString()), (n = n.toString())
|
||||
var t = 0
|
||||
'-' == e[0] && (t++, (e = e.substr(1))),
|
||||
'-' == n[0] && (t++, (n = n.substr(1))),
|
||||
(e = r(e)),
|
||||
(n = r(n))
|
||||
var i = 0,
|
||||
o = 0
|
||||
; -1 != e.indexOf('.') && (i = e.length - e.indexOf('.') - 1),
|
||||
-1 != n.indexOf('.') && (o = n.length - n.indexOf('.') - 1)
|
||||
var u = i + o
|
||||
if (
|
||||
((e = r(e.replace('.', ''))),
|
||||
(n = r(n.replace('.', ''))),
|
||||
e.length < n.length)
|
||||
) {
|
||||
var a = e
|
||||
; (e = n), (n = a)
|
||||
}
|
||||
if ('0' == n) return '0'
|
||||
for (
|
||||
var s, d, l = n.length, f = 0, g = [], c = l - 1, v = '', p = 0;
|
||||
p < l;
|
||||
p++
|
||||
)
|
||||
g[p] = e.length - 1
|
||||
for (p = 0; p < 2 * e.length; p++) {
|
||||
for (var h = 0, b = n.length - 1; b >= c && b >= 0; b--)
|
||||
g[b] > -1 &&
|
||||
g[b] < e.length &&
|
||||
(h += parseInt(e[g[b]--]) * parseInt(n[b]))
|
||||
; (h += f), (f = Math.floor(h / 10)), (v = (h % 10) + v), c--
|
||||
}
|
||||
return (
|
||||
(v = r(
|
||||
((s = v),
|
||||
0 == (d = u)
|
||||
? s
|
||||
: (s =
|
||||
d >= s.length
|
||||
? new Array(d - s.length + 1).join('0') + s
|
||||
: s).substr(0, s.length - d) +
|
||||
'.' +
|
||||
s.substr(s.length - d, d))
|
||||
)),
|
||||
1 == t && (v = '-' + v),
|
||||
v
|
||||
)
|
||||
})
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }), (n.divide = void 0)
|
||||
var r = t(0),
|
||||
i = t(1)
|
||||
n.divide = function (e, n, t) {
|
||||
if ((void 0 === t && (t = 8), 0 == n))
|
||||
throw new Error('Cannot divide by 0')
|
||||
if (
|
||||
((e = e.toString()),
|
||||
(n = n.toString()),
|
||||
(e = e.replace(/(\.\d*?[1-9])0+$/g, '$1').replace(/\.0+$/, '')),
|
||||
(n = n.replace(/(\.\d*?[1-9])0+$/g, '$1').replace(/\.0+$/, '')),
|
||||
0 == e)
|
||||
)
|
||||
return '0'
|
||||
var o = 0
|
||||
'-' == n[0] && ((n = n.substring(1)), o++),
|
||||
'-' == e[0] && ((e = e.substring(1)), o++)
|
||||
var u = n.indexOf('.') > 0 ? n.length - n.indexOf('.') - 1 : -1
|
||||
if (((n = r.trim(n.replace('.', ''))), u >= 0)) {
|
||||
var a = e.indexOf('.') > 0 ? e.length - e.indexOf('.') - 1 : -1
|
||||
if (-1 == a) e = r.trim(e + new Array(u + 1).join('0'))
|
||||
else if (u > a)
|
||||
(e = e.replace('.', '')),
|
||||
(e = r.trim(e + new Array(u - a + 1).join('0')))
|
||||
else if (u < a) {
|
||||
var s = (e = e.replace('.', '')).length - a + u
|
||||
e = r.trim(e.substring(0, s) + '.' + e.substring(s))
|
||||
} else u == a && (e = r.trim(e.replace('.', '')))
|
||||
}
|
||||
var d = 0,
|
||||
l = n.length,
|
||||
f = '',
|
||||
g =
|
||||
e.indexOf('.') > -1 && e.indexOf('.') < l
|
||||
? e.substring(0, l + 1)
|
||||
: e.substring(0, l)
|
||||
if (
|
||||
((e =
|
||||
e.indexOf('.') > -1 && e.indexOf('.') < l
|
||||
? e.substring(l + 1)
|
||||
: e.substring(l)),
|
||||
g.indexOf('.') > -1)
|
||||
) {
|
||||
var c = g.length - g.indexOf('.') - 1
|
||||
l > (g = g.replace('.', '')).length &&
|
||||
((c += l - g.length), (g += new Array(l - g.length + 1).join('0'))),
|
||||
(d = c),
|
||||
(f = '0.' + new Array(c).join('0'))
|
||||
}
|
||||
for (t += 2; d <= t;) {
|
||||
for (var v = 0; parseInt(g) >= parseInt(n);)
|
||||
(g = r.add(g, '-' + n)), v++
|
||||
; (f += v),
|
||||
e
|
||||
? ('.' == e[0] && ((f += '.'), d++, (e = e.substring(1))),
|
||||
(g += e.substring(0, 1)),
|
||||
(e = e.substring(1)))
|
||||
: (d || (f += '.'), d++, (g += '0'))
|
||||
}
|
||||
return (1 == o ? '-' : '') + r.trim(i.roundOff(f, t - 2))
|
||||
}
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }),
|
||||
(n.negate = n.subtract = void 0)
|
||||
var r = t(0)
|
||||
function i(e) {
|
||||
return (e = '-' == e[0] ? e.substr(1) : '-' + e)
|
||||
}
|
||||
; (n.subtract = function (e, n) {
|
||||
return (e = e.toString()), (n = i((n = n.toString()))), r.add(e, n)
|
||||
}),
|
||||
(n.negate = i)
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
var r = t(0),
|
||||
i = t(1),
|
||||
o = t(3),
|
||||
u = t(4),
|
||||
a = t(7),
|
||||
s = t(8),
|
||||
d = t(5),
|
||||
l = t(2),
|
||||
f = (function () {
|
||||
function e(n) {
|
||||
void 0 === n && (n = '0'), (this.value = e.validate(n))
|
||||
}
|
||||
return (
|
||||
(e.validate = function (e) {
|
||||
if (e) {
|
||||
if (((e = e.toString()), isNaN(e)))
|
||||
throw Error('Parameter is not a number: ' + e)
|
||||
'+' == e[0] && (e = e.substring(1))
|
||||
} else e = '0'
|
||||
if (/e/i.test(e)) {
|
||||
var n = e.split(/[eE]/),
|
||||
t = n[0],
|
||||
i = n[1]
|
||||
; (t = r.trim(t)),
|
||||
(i = parseInt(i) + t.indexOf('.')),
|
||||
(e =
|
||||
(t = t.replace('.', '')).length < i
|
||||
? t + new Array(i - t.length + 1).join('0')
|
||||
: t.length >= i && i > 0
|
||||
? r.trim(t.substring(0, i)) +
|
||||
(t.length > i ? '.' + t.substring(i) : '')
|
||||
: '0.' + new Array(1 - i).join('0') + t)
|
||||
}
|
||||
return e
|
||||
}),
|
||||
(e.prototype.getValue = function () {
|
||||
return this.value
|
||||
}),
|
||||
(e.getPrettyValue = function (n, t, r) {
|
||||
if (t || r) {
|
||||
if (!t || !r)
|
||||
throw Error(
|
||||
'Illegal Arguments. Should pass both digits and separator or pass none'
|
||||
)
|
||||
} else (t = 3), (r = ',')
|
||||
var i = '-' == (n = e.validate(n)).charAt(0)
|
||||
i && (n = n.substring(1))
|
||||
for (
|
||||
var o = n.indexOf('.'), u = '', a = (o = o > 0 ? o : n.length);
|
||||
a > 0;
|
||||
|
||||
)
|
||||
a < t ? ((t = a), (a = 0)) : (a -= t),
|
||||
(u = n.substring(a, a + t) + (a < o - t && a >= 0 ? r : '') + u)
|
||||
return (i ? '-' : '') + u + n.substring(o)
|
||||
}),
|
||||
(e.prototype.getPrettyValue = function (n, t) {
|
||||
return e.getPrettyValue(this.value, n, t)
|
||||
}),
|
||||
(e.round = function (n, t, r) {
|
||||
if (
|
||||
(void 0 === t && (t = 0),
|
||||
void 0 === r && (r = l.RoundingModes.HALF_EVEN),
|
||||
(n = e.validate(n)),
|
||||
isNaN(t))
|
||||
)
|
||||
throw Error('Precision is not a number: ' + t)
|
||||
return i.roundOff(n, t, r)
|
||||
}),
|
||||
(e.prototype.round = function (n, t) {
|
||||
if (
|
||||
(void 0 === n && (n = 0),
|
||||
void 0 === t && (t = l.RoundingModes.HALF_EVEN),
|
||||
isNaN(n))
|
||||
)
|
||||
throw Error('Precision is not a number: ' + n)
|
||||
return new e(i.roundOff(this.value, n, t))
|
||||
}),
|
||||
(e.floor = function (n) {
|
||||
return -1 === (n = e.validate(n)).indexOf('.')
|
||||
? n
|
||||
: e.round(n, 0, l.RoundingModes.FLOOR)
|
||||
}),
|
||||
(e.prototype.floor = function () {
|
||||
return -1 === this.value.indexOf('.')
|
||||
? new e(this.value)
|
||||
: new e(this.value).round(0, l.RoundingModes.FLOOR)
|
||||
}),
|
||||
(e.ceil = function (n) {
|
||||
return -1 === (n = e.validate(n)).indexOf('.')
|
||||
? n
|
||||
: e.round(n, 0, l.RoundingModes.CEILING)
|
||||
}),
|
||||
(e.prototype.ceil = function () {
|
||||
return -1 === this.value.indexOf('.')
|
||||
? new e(this.value)
|
||||
: new e(this.value).round(0, l.RoundingModes.CEILING)
|
||||
}),
|
||||
(e.add = function (n, t) {
|
||||
return (n = e.validate(n)), (t = e.validate(t)), r.add(n, t)
|
||||
}),
|
||||
(e.prototype.add = function (n) {
|
||||
return new e(r.add(this.value, n.getValue()))
|
||||
}),
|
||||
(e.subtract = function (n, t) {
|
||||
return (n = e.validate(n)), (t = e.validate(t)), d.subtract(n, t)
|
||||
}),
|
||||
(e.prototype.subtract = function (n) {
|
||||
return new e(d.subtract(this.value, n.getValue()))
|
||||
}),
|
||||
(e.multiply = function (n, t) {
|
||||
return (n = e.validate(n)), (t = e.validate(t)), o.multiply(n, t)
|
||||
}),
|
||||
(e.prototype.multiply = function (n) {
|
||||
return new e(o.multiply(this.value, n.getValue()))
|
||||
}),
|
||||
(e.divide = function (n, t, r) {
|
||||
return (n = e.validate(n)), (t = e.validate(t)), u.divide(n, t, r)
|
||||
}),
|
||||
(e.prototype.divide = function (n, t) {
|
||||
return new e(u.divide(this.value, n.getValue(), t))
|
||||
}),
|
||||
(e.modulus = function (n, t) {
|
||||
return (n = e.validate(n)), (t = e.validate(t)), a.modulus(n, t)
|
||||
}),
|
||||
(e.prototype.modulus = function (n) {
|
||||
return new e(a.modulus(this.value, n.getValue()))
|
||||
}),
|
||||
(e.compareTo = function (n, t) {
|
||||
return (n = e.validate(n)), (t = e.validate(t)), s.compareTo(n, t)
|
||||
}),
|
||||
(e.prototype.compareTo = function (e) {
|
||||
return s.compareTo(this.value, e.getValue())
|
||||
}),
|
||||
(e.negate = function (n) {
|
||||
return (n = e.validate(n)), d.negate(n)
|
||||
}),
|
||||
(e.prototype.negate = function () {
|
||||
return new e(d.negate(this.value))
|
||||
}),
|
||||
(e.RoundingModes = l.RoundingModes),
|
||||
e
|
||||
)
|
||||
})()
|
||||
e.exports = f
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }), (n.modulus = void 0)
|
||||
var r = t(4),
|
||||
i = t(1),
|
||||
o = t(3),
|
||||
u = t(5),
|
||||
a = t(2)
|
||||
function s(e) {
|
||||
if (-1 != e.indexOf('.'))
|
||||
throw new Error('Modulus of non-integers not supported')
|
||||
}
|
||||
n.modulus = function (e, n) {
|
||||
if (0 == n) throw new Error('Cannot divide by 0')
|
||||
; (e = e.toString()), (n = n.toString()), s(e), s(n)
|
||||
var t = ''
|
||||
return (
|
||||
'-' == e[0] && ((t = '-'), (e = e.substr(1))),
|
||||
'-' == n[0] && (n = n.substr(1)),
|
||||
t +
|
||||
u.subtract(
|
||||
e,
|
||||
o.multiply(n, i.roundOff(r.divide(e, n), 0, a.RoundingModes.FLOOR))
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
function (e, n, t) {
|
||||
'use strict'
|
||||
Object.defineProperty(n, '__esModule', { value: !0 }),
|
||||
(n.compareTo = void 0)
|
||||
var r = t(0)
|
||||
n.compareTo = function (e, n) {
|
||||
var t,
|
||||
i = !1
|
||||
if ('-' == e[0] && '-' != n[0]) return -1
|
||||
if ('-' != e[0] && '-' == n[0]) return 1
|
||||
if (
|
||||
('-' == e[0] &&
|
||||
'-' == n[0] &&
|
||||
((e = e.substr(1)), (n = n.substr(1)), (i = !0)),
|
||||
(e = (t = r.pad(e, n))[0]),
|
||||
(n = t[1]),
|
||||
0 == e.localeCompare(n))
|
||||
)
|
||||
return 0
|
||||
for (var o = 0; o < e.length; o++)
|
||||
if (e[o] != n[o]) return e[o] > n[o] ? (i ? -1 : 1) : i ? 1 : -1
|
||||
return 0
|
||||
}
|
||||
},
|
||||
])
|
||||
export default bigDecimal
|
||||
25
src/utils/emitter.js
Normal file
25
src/utils/emitter.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import mitt from 'mitt';
|
||||
|
||||
class EventEmitter {
|
||||
constructor() {
|
||||
this.emitter = mitt();
|
||||
}
|
||||
|
||||
on(eventName, handler) {
|
||||
this.emitter.on(eventName, handler);
|
||||
}
|
||||
|
||||
off(eventName, handler) {
|
||||
this.emitter.off(eventName, handler);
|
||||
}
|
||||
|
||||
emit(eventName, event) {
|
||||
this.emitter.emit(eventName, event);
|
||||
}
|
||||
|
||||
removeAllListeners() {
|
||||
this.emitter.all.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export default EventEmitter;
|
||||
6
src/utils/errorCode.js
Normal file
6
src/utils/errorCode.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'401': '认证失败,无法访问系统资源',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
'default': '系统未知错误,请反馈给管理员'
|
||||
}
|
||||
127
src/utils/mqtt.js
Normal file
127
src/utils/mqtt.js
Normal file
@@ -0,0 +1,127 @@
|
||||
import mqtt from "mqtt"
|
||||
|
||||
// MQTT 连接选项
|
||||
const options = {
|
||||
clean: true,
|
||||
connectTimeout: 4000,
|
||||
reconnectPeriod: 1000,
|
||||
qos: 1, // 默认 QoS 1
|
||||
}
|
||||
|
||||
const brokerUrl = "wss://push.cnsdt.com:443/mqtt" // 你的 MQTT 服务地址
|
||||
|
||||
class MQTTClient {
|
||||
constructor() {
|
||||
this.client = null
|
||||
this.subscriptions = new Set()
|
||||
this.messageHandlers = new Map()
|
||||
}
|
||||
|
||||
// 连接
|
||||
connect(clientId) {
|
||||
if (this.client && this.client.connected) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client = mqtt.connect(brokerUrl, {
|
||||
...options,
|
||||
clientId: clientId || `client_${Math.random().toString(16).substr(2, 8)}`,
|
||||
})
|
||||
|
||||
this.client.on("connect", () => resolve())
|
||||
this.client.on("error", (error) => reject(error))
|
||||
|
||||
// 消息分发
|
||||
this.client.on("message", (topic, payload) => {
|
||||
try {
|
||||
const message = JSON.parse(payload.toString())
|
||||
// 遍历所有订阅主题,执行通配符匹配
|
||||
this.messageHandlers.forEach((handlers, subTopic) => {
|
||||
if (this.topicMatch(subTopic, topic)) {
|
||||
handlers.forEach((handler) => handler(message, topic))
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.error("MQTT message parse error:", err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 断开
|
||||
disconnect() {
|
||||
if (this.client) {
|
||||
this.client.end()
|
||||
this.client = null
|
||||
this.subscriptions.clear()
|
||||
this.messageHandlers.clear()
|
||||
}
|
||||
}
|
||||
|
||||
// 订阅
|
||||
subscribe(topic, handler) {
|
||||
if (!this.client || !this.client.connected) {
|
||||
console.error("MQTT client not connected")
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.subscriptions.has(topic)) {
|
||||
this.client.subscribe(topic, { qos: 1 }, (err) => {
|
||||
if (err) {
|
||||
console.error("Subscription error:", err)
|
||||
} else {
|
||||
this.subscriptions.add(topic)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handlers = this.messageHandlers.get(topic) || []
|
||||
handlers.push(handler)
|
||||
this.messageHandlers.set(topic, handlers)
|
||||
}
|
||||
|
||||
// 取消订阅
|
||||
unsubscribe(topic, handler) {
|
||||
if (!this.subscriptions.has(topic)) return
|
||||
|
||||
if (handler) {
|
||||
const handlers = this.messageHandlers.get(topic) || []
|
||||
const index = handlers.indexOf(handler)
|
||||
if (index !== -1) {
|
||||
handlers.splice(index, 1)
|
||||
this.messageHandlers.set(topic, handlers)
|
||||
}
|
||||
} else {
|
||||
this.client.unsubscribe(topic)
|
||||
this.subscriptions.delete(topic)
|
||||
this.messageHandlers.delete(topic)
|
||||
}
|
||||
}
|
||||
|
||||
// 发布
|
||||
publish(topic, message) {
|
||||
if (!this.client || !this.client.connected) {
|
||||
console.error("MQTT client not connected")
|
||||
return
|
||||
}
|
||||
this.client.publish(topic, JSON.stringify(message), { qos: 1 })
|
||||
}
|
||||
|
||||
// 通配符匹配
|
||||
topicMatch(subTopic, msgTopic) {
|
||||
const subLevels = subTopic.split("/")
|
||||
const msgLevels = msgTopic.split("/")
|
||||
|
||||
for (let i = 0; i < subLevels.length; i++) {
|
||||
if (subLevels[i] === "#") return true
|
||||
if (subLevels[i] === "+") continue
|
||||
if (msgLevels[i] === undefined) return false
|
||||
if (subLevels[i] !== msgLevels[i]) return false
|
||||
}
|
||||
|
||||
return subLevels.length === msgLevels.length
|
||||
}
|
||||
}
|
||||
|
||||
export const mqttClient = new MQTTClient()
|
||||
194
src/utils/request.js
Normal file
194
src/utils/request.js
Normal file
@@ -0,0 +1,194 @@
|
||||
import axios from "axios";
|
||||
import {
|
||||
ElNotification,
|
||||
ElMessageBox,
|
||||
ElMessage,
|
||||
} from "element-plus";
|
||||
import { tansParams } from "@/utils/ruoyi";
|
||||
import cache from "@/plugins/cache";
|
||||
import { getToken, removeToken } from "@/utils/auth";
|
||||
import router from '@/router';
|
||||
import { useMeterStore } from '@/stores/modules/meter'
|
||||
|
||||
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
|
||||
const meterStore = useMeterStore()
|
||||
meterStore.initUdid()
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||
// 超时
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false;
|
||||
if (getToken() && !isToken) {
|
||||
config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
|
||||
if (meterStore.getSudid()) {
|
||||
config.headers["X-User-Agent"] = `gxtech/web 1.0.0: c=GxTech, udid=${meterStore.getSudid()}, sv=15.4.1, app=stt`;
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.method === "get" && config.params) {
|
||||
|
||||
let url = config.url + "?" + tansParams(config.params);
|
||||
url = url.slice(0, -1);
|
||||
config.params = {};
|
||||
config.url = url;
|
||||
}
|
||||
if (
|
||||
!isRepeatSubmit &&
|
||||
(config.method === "post" || config.method === "put")
|
||||
) {
|
||||
const requestObj = {
|
||||
url: config.url,
|
||||
data:
|
||||
typeof config.data === "object"
|
||||
? JSON.stringify(config.data)
|
||||
: config.data,
|
||||
time: new Date().getTime(),
|
||||
};
|
||||
const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
|
||||
const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
|
||||
if (requestSize >= limitSize) {
|
||||
console.warn(
|
||||
`[${config.url}]: ` +
|
||||
"请求数据大小超出允许的5M限制,无法进行防重复提交验证。"
|
||||
);
|
||||
return config;
|
||||
}
|
||||
const sessionObj = cache.session.getJSON("sessionObj");
|
||||
if (
|
||||
sessionObj === undefined ||
|
||||
sessionObj === null ||
|
||||
sessionObj === ""
|
||||
) {
|
||||
cache.session.setJSON("sessionObj", requestObj);
|
||||
} else {
|
||||
const s_url = sessionObj.url; // 请求地址
|
||||
const s_data = sessionObj.data; // 请求数据
|
||||
const s_time = sessionObj.time; // 请求时间
|
||||
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
|
||||
if (
|
||||
s_data === requestObj.data &&
|
||||
requestObj.time - s_time < interval &&
|
||||
s_url === requestObj.url
|
||||
) {
|
||||
const message = "数据正在处理,请勿重复提交";
|
||||
console.warn(`[${s_url}]: ` + message);
|
||||
return Promise.reject(new Error(message));
|
||||
} else {
|
||||
cache.session.setJSON("sessionObj", requestObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
// 1. 检查响应是否存在
|
||||
if (!response) {
|
||||
ElMessage.error('无响应数据');
|
||||
return Promise.reject(new Error('无响应数据'));
|
||||
}
|
||||
// 2. 安全获取响应数据和状态码
|
||||
const responseData = response.data || {};
|
||||
const statusCode = response.status;
|
||||
const businessCode = responseData.meta?.code || statusCode;
|
||||
|
||||
// 3. 二进制数据直接返回
|
||||
if (
|
||||
response.request.responseType === 'blob' ||
|
||||
response.request.responseType === 'arraybuffer'
|
||||
) {
|
||||
return responseData;
|
||||
}
|
||||
|
||||
// 4. 根据业务码处理不同情况
|
||||
switch (businessCode) {
|
||||
case 200:
|
||||
case 201:
|
||||
return Promise.resolve(responseData);
|
||||
|
||||
case 401:
|
||||
return handleUnauthorized().then(() => {
|
||||
return Promise.reject({ code: 401, message: '未授权' });
|
||||
});
|
||||
|
||||
case 500:
|
||||
const serverErrorMsg = responseData.meta?.message || '服务器内部错误';
|
||||
ElMessage({ message: serverErrorMsg, type: 'error' });
|
||||
return Promise.reject({ code: 500, message: serverErrorMsg });
|
||||
|
||||
default:
|
||||
const errorMsg = responseData.meta?.message || `业务错误 (${businessCode})`;
|
||||
ElNotification.error({ title: errorMsg });
|
||||
return Promise.reject({ code: businessCode, message: errorMsg });
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.error('请求错误:', error);
|
||||
let { message } = error;
|
||||
let code = error?.response?.status || -1;
|
||||
|
||||
if (message == 'Network Error') {
|
||||
message = '后端接口连接异常';
|
||||
ElMessage({ message, type: 'error', duration: 5 * 1000 });
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时';
|
||||
ElMessage({ message, type: 'error', duration: 5 * 1000 });
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
// message = '系统接口' + message.substr(message.length - 3) + '异常';
|
||||
}
|
||||
|
||||
// 返回结构化错误
|
||||
return Promise.reject({
|
||||
code,
|
||||
message,
|
||||
raw: error // 保留原始 error
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// 单独处理401未授权
|
||||
function handleUnauthorized() {
|
||||
return ElMessageBox.confirm(
|
||||
'认证信息已失效,您可以继续留在该页面,或者重新登录',
|
||||
'系统提示',
|
||||
{
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
removeToken()
|
||||
if (router.currentRoute.path !== '/login') {
|
||||
router.push({
|
||||
path: '/login',
|
||||
query: { redirect: router.currentRoute.fullPath }
|
||||
});
|
||||
} else {
|
||||
// 如果在登录页,强制刷新以清除残留状态
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
return Promise.reject('用户取消操作');
|
||||
});
|
||||
}
|
||||
|
||||
export default service;
|
||||
718
src/utils/ruoyi.js
Normal file
718
src/utils/ruoyi.js
Normal file
@@ -0,0 +1,718 @@
|
||||
import bigDecimal from "@/utils/bigDecimal";
|
||||
|
||||
/**
|
||||
* @description 分钟转时间
|
||||
* @author
|
||||
* @date
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function formatMinutes(minutes) {
|
||||
let tiemInfo = Number(minutes);
|
||||
var time = [];
|
||||
var day = parseInt(tiemInfo / 60 / 24);
|
||||
var hour = parseInt((tiemInfo / 60) % 24);
|
||||
var min = parseInt(tiemInfo % 60);
|
||||
time[0] = day > 0 ? day : 0;
|
||||
time[1] = hour > 0 ? hour : 0;
|
||||
time[2] = min > 0 ? parseFloat(min) : 0;
|
||||
return time;
|
||||
}
|
||||
/**
|
||||
* @description 时间转分钟
|
||||
* @author
|
||||
* @date
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function totalMinutes(day, hour, minute) {
|
||||
return day * 1440 + hour * 60 + minute;
|
||||
}
|
||||
/**
|
||||
* @description 数组指定必填项判断校验
|
||||
* @author // arr要判断的数组 data要判断里面那些不能为空的字段
|
||||
* @date
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function everyI(arr, data, text) {
|
||||
let flag = arr.flatMap((item) => {
|
||||
let flag1 = data.flatMap((key) => {
|
||||
if (text == "不校验零") {
|
||||
if (item[key] || item[key] == 0) {
|
||||
return true;
|
||||
} else {
|
||||
false;
|
||||
}
|
||||
} else {
|
||||
if (item[key]) {
|
||||
return true;
|
||||
} else {
|
||||
false;
|
||||
}
|
||||
}
|
||||
});
|
||||
return flag1;
|
||||
});
|
||||
// 如果不只条的时候全部都要填写 every只要有一个不满足就不让走 smoe只要有一个满足就可以走
|
||||
let info = flag.every((val) => val);
|
||||
return info;
|
||||
}
|
||||
/**
|
||||
* @description 找下对应的字段显示上去 arr1枚举表 arr2对比数组 text取出的字段
|
||||
* @author cl
|
||||
* @date 2022-2-17
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function getArr(arr1, arr2, text) {
|
||||
let arrInfo = [];
|
||||
if (!arr2) return;
|
||||
arr1.map((item) => {
|
||||
arr2.split(",").map((n) => {
|
||||
if (n == item.value) {
|
||||
arrInfo.push(item[text]);
|
||||
}
|
||||
});
|
||||
});
|
||||
return arrInfo.join(",");
|
||||
}
|
||||
/**
|
||||
* @description
|
||||
* @author cl
|
||||
* @date 2022-2-18
|
||||
* @param arr要计算的数组数据 Array
|
||||
* @param num2要计算的价格字段 string
|
||||
* @param arr2要合并计算总价的数据 string
|
||||
* @param currency优惠券的币种字段 Array
|
||||
* @param currency要减去的优惠券币种字段 string
|
||||
* @param amount要减去的优惠券价格字段 string
|
||||
* @returns
|
||||
*/
|
||||
export function getPriceI(arr, num1, num2, arr2, currency, amount) {
|
||||
let arrInfo = arr2 ? arr2 : []; // 总计
|
||||
let currencyInfo = currency; // 优惠券币种
|
||||
let amountInfo = amount ? amount : 0; // 优惠价钱
|
||||
let price = {
|
||||
USD: 0,
|
||||
CNY: 0,
|
||||
};
|
||||
arr.concat(arrInfo).flatMap((i) => {
|
||||
if (i[num1] == "USD") {
|
||||
price.USD = Number(bigDecimal.add(price.USD, i[num2]));
|
||||
} else {
|
||||
price.CNY = Number(bigDecimal.add(price.CNY, i[num2]));
|
||||
}
|
||||
});
|
||||
// 有优惠卷的话减去优惠间
|
||||
if (currencyInfo === "CNY") {
|
||||
price.CNY = Number(bigDecimal.subtract(price.CNY, amountInfo));
|
||||
} else {
|
||||
price.USD = Number(bigDecimal.subtract(price.USD, amountInfo));
|
||||
}
|
||||
|
||||
let arrI = [
|
||||
price.USD > 0 ? "USD:" + format_with_array(price.USD) : "USD:0.00",
|
||||
price.CNY > 0 ? "CNY:" + format_with_array(price.CNY) : "CNY:0.00",
|
||||
]
|
||||
.filter((current) => {
|
||||
return current !== "USD:0.00" && current !== "CNY:0.00";
|
||||
})
|
||||
.join(" + ");
|
||||
return arrI;
|
||||
}
|
||||
/**
|
||||
* @description 数组字段拼接回调法
|
||||
* @author cl
|
||||
* @date 2022-12-9
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function _getArr(arr, name, id, child) {
|
||||
arr.forEach((item, index) => {
|
||||
// 作为键值对
|
||||
item.label = item[name];
|
||||
item.value = item[id];
|
||||
if (item.children) {
|
||||
_getArr(item.children, name, id);
|
||||
}
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
/**
|
||||
* 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
|
||||
*
|
||||
* @param {Function} func 要执行的回调函数
|
||||
* @param {Number} wait 延时的时间
|
||||
* @param {Boolean} immediate 是否立即执行
|
||||
* @return null
|
||||
*/
|
||||
let timeout = null;
|
||||
export function debounce(func, wait = 300, immediate = false) {
|
||||
// 清除定时器
|
||||
if (timeout !== null) clearTimeout(timeout);
|
||||
// 立即执行,此类情况一般用不到
|
||||
if (immediate) {
|
||||
const callNow = !timeout;
|
||||
timeout = setTimeout(() => {
|
||||
timeout = null;
|
||||
}, wait);
|
||||
if (callNow) typeof func === "function" && func();
|
||||
} else {
|
||||
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
|
||||
timeout = setTimeout(() => {
|
||||
typeof func === "function" && func();
|
||||
}, wait);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @description 去重对比后去除已存在的替换 arrA已经选择的 arrB数据源 text去重的标识字段 type类型
|
||||
* @author cl
|
||||
* @date 2022-12-9
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function processI(arrA, arrB, text) {
|
||||
// 缓存用于记录
|
||||
const cache = [];
|
||||
for (const t of arrB) {
|
||||
// 检查缓存中是否已经存在
|
||||
if (arrA.find((c) => c[text] === t[text])) {
|
||||
// 已经存在说明以前记录过,现在这个就是多余的,直接忽略
|
||||
continue;
|
||||
}
|
||||
// 不存在就说明以前没遇到过,把它记录下来
|
||||
cache.push(t);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
/**
|
||||
* @description 去重去除已存在的 typeName类型标记
|
||||
* @author cl
|
||||
* @date 2022-2-17
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
export function duplicate(arr1, arr2, text, typeName, type) {
|
||||
arr1.map((item) => {
|
||||
// 检查缓存中是否已经存在
|
||||
if (arr2.find((c) => c[text] == item[text])) {
|
||||
// 已经存在说明以前记录过,现在这个就是多余的,直接忽略
|
||||
return;
|
||||
}
|
||||
// 不存在就说明以前没遇到过,把它记录下来
|
||||
if (typeName) {
|
||||
item[typeName] = type;
|
||||
arr2.push(item);
|
||||
} else {
|
||||
arr2.push(item);
|
||||
}
|
||||
});
|
||||
return arr2;
|
||||
}
|
||||
/**
|
||||
* 手机号格式化
|
||||
* @param {string | number} mobile 手机号
|
||||
* @returns '188 8888 8888'格式的手机号
|
||||
*/
|
||||
|
||||
export function formatMobile(mobile) {
|
||||
const regMobile = /^1\d{10}/;
|
||||
if (!regMobile.test(mobile)) {
|
||||
return "";
|
||||
}
|
||||
return String(mobile).replace(/(^\d{3}|\d{4}\B)/g, "$1 ");
|
||||
}
|
||||
/**
|
||||
* @description 复制
|
||||
* @param {*} id DOM ID
|
||||
*/
|
||||
export function copyDomText(id) {
|
||||
const node = document.getElementById(id);
|
||||
if (node) {
|
||||
let createRange = document.createRange();
|
||||
createRange.selectNodeContents(document.getElementById(id));
|
||||
const selection = document.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(createRange);
|
||||
document.execCommand("Copy");
|
||||
selection.removeAllRanges();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 金额 千分位
|
||||
* @param { number} mobile 金额
|
||||
* @returns '12,300,000' 金额格式
|
||||
*/
|
||||
export function format_with_array(
|
||||
number,
|
||||
decimals,
|
||||
dec_point,
|
||||
thousands_sep,
|
||||
round_tag
|
||||
) {
|
||||
number = (number + "").replace(/[^0-9+-Ee.]/g, "");
|
||||
decimals = decimals || 2; //默认保留2位
|
||||
dec_point = dec_point || "."; //默认是'.';
|
||||
thousands_sep = thousands_sep || ","; //默认是',';
|
||||
round_tag = round_tag || "round"; //默认是四舍五入
|
||||
var n = !isFinite(+number) ? 0 : +number,
|
||||
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
|
||||
sep = typeof thousands_sep === "undefined" ? "," : thousands_sep,
|
||||
dec = typeof dec_point === "undefined" ? "." : dec_point,
|
||||
s = "",
|
||||
toFixedFix = function (n, prec) {
|
||||
var k = Math.pow(10, prec);
|
||||
|
||||
return (
|
||||
"" +
|
||||
parseFloat(
|
||||
Math[round_tag](parseFloat((n * k).toFixed(prec * 2))).toFixed(
|
||||
prec * 2
|
||||
)
|
||||
) /
|
||||
k
|
||||
);
|
||||
};
|
||||
s = (prec ? toFixedFix(n, prec) : "" + Math.round(n)).split(".");
|
||||
var re = /(-?\d+)(\d{3})/;
|
||||
while (re.test(s[0])) {
|
||||
s[0] = s[0].replace(re, "$1" + sep + "$2");
|
||||
}
|
||||
if ((s[1] || "").length < prec) {
|
||||
s[1] = s[1] || "";
|
||||
s[1] += new Array(prec - s[1].length + 1).join("0");
|
||||
}
|
||||
return "¥" + s.join(dec);
|
||||
}
|
||||
|
||||
// 获取两个时间段内的所有日期/月份 日 传入 YYYY-MM , YYYY-MM (2020-09) (2020-12) 返回 YYYY-MM 数组
|
||||
export function getAllDay(start, end) {
|
||||
let result = [];
|
||||
let min = new Date(start);
|
||||
let max = new Date(end);
|
||||
let curr = min;
|
||||
do {
|
||||
let month = new Date(curr).getMonth() + 1;
|
||||
let t = "";
|
||||
if (month < 10) {
|
||||
t = "0" + month;
|
||||
} else t = month;
|
||||
let str = curr.getFullYear() + "-" + t;
|
||||
result.push(str);
|
||||
if (month == 12) {
|
||||
curr.setFullYear(new Date(curr).getFullYear() + 1);
|
||||
curr.setMonth(0);
|
||||
} else curr.setMonth(month);
|
||||
} while (curr <= max);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 日期格式化
|
||||
export function parseTime(time, pattern) {
|
||||
if (arguments.length === 0 || !time) {
|
||||
return null;
|
||||
}
|
||||
const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
|
||||
let date;
|
||||
if (typeof time === "object") {
|
||||
date = time;
|
||||
} else {
|
||||
if (typeof time === "string" && /^[0-9]+$/.test(time)) {
|
||||
time = parseInt(time);
|
||||
} else if (typeof time === "string") {
|
||||
time = time
|
||||
.replace(new RegExp(/-/gm), "/")
|
||||
.replace("T", " ")
|
||||
.replace(new RegExp(/\.[\d]{3}/gm), "");
|
||||
}
|
||||
if (typeof time === "number" && time.toString().length === 10) {
|
||||
time = time * 1000;
|
||||
}
|
||||
date = new Date(time);
|
||||
}
|
||||
const formatObj = {
|
||||
y: date.getFullYear(),
|
||||
m: date.getMonth() + 1,
|
||||
d: date.getDate(),
|
||||
h: date.getHours(),
|
||||
i: date.getMinutes(),
|
||||
s: date.getSeconds(),
|
||||
a: date.getDay(),
|
||||
};
|
||||
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key];
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === "a") {
|
||||
return ["日", "一", "二", "三", "四", "五", "六"][value];
|
||||
}
|
||||
if (result.length > 0 && value < 10) {
|
||||
value = "0" + value;
|
||||
}
|
||||
return value || 0;
|
||||
});
|
||||
return time_str;
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
export function resetForm(refName) {
|
||||
if (this.$refs[refName]) {
|
||||
this.$refs[refName].resetFields();
|
||||
}
|
||||
}
|
||||
|
||||
// 添加日期范围
|
||||
export function addDateRange(params, dateRange, propName) {
|
||||
let search = params;
|
||||
search.params =
|
||||
typeof search.params === "object" &&
|
||||
search.params !== null &&
|
||||
!Array.isArray(search.params)
|
||||
? search.params
|
||||
: {};
|
||||
dateRange = Array.isArray(dateRange) ? dateRange : [];
|
||||
if (typeof propName === "undefined") {
|
||||
search.params["beginTime"] = dateRange[0];
|
||||
search.params["endTime"] = dateRange[1];
|
||||
} else {
|
||||
search.params["begin" + propName] = dateRange[0];
|
||||
search.params["end" + propName] = dateRange[1];
|
||||
}
|
||||
return search;
|
||||
}
|
||||
|
||||
// 回显数据字典
|
||||
export function selectDictLabel(datas, value) {
|
||||
if (value === undefined) {
|
||||
return "";
|
||||
}
|
||||
var actions = [];
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value == "" + value) {
|
||||
actions.push(datas[key].label);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (actions.length === 0) {
|
||||
actions.push(value);
|
||||
}
|
||||
return actions.join("");
|
||||
}
|
||||
|
||||
// 回显数据字典(字符串数组)
|
||||
export function selectDictLabels(datas, value, separator) {
|
||||
if (value === undefined || value.length === 0) {
|
||||
return "";
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
value = value.join(",");
|
||||
}
|
||||
var actions = [];
|
||||
var currentSeparator = undefined === separator ? "," : separator;
|
||||
var temp = value.split(currentSeparator);
|
||||
Object.keys(value.split(currentSeparator)).some((val) => {
|
||||
var match = false;
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value == "" + temp[val]) {
|
||||
actions.push(datas[key].label + currentSeparator);
|
||||
match = true;
|
||||
}
|
||||
});
|
||||
if (!match) {
|
||||
actions.push(temp[val] + currentSeparator);
|
||||
}
|
||||
});
|
||||
return actions.join("").substring(0, actions.join("").length - 1);
|
||||
}
|
||||
|
||||
// 字符串格式化(%s )
|
||||
export function sprintf(str) {
|
||||
var args = arguments,
|
||||
flag = true,
|
||||
i = 1;
|
||||
str = str.replace(/%s/g, function () {
|
||||
var arg = args[i++];
|
||||
if (typeof arg === "undefined") {
|
||||
flag = false;
|
||||
return "";
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
return flag ? str : "";
|
||||
}
|
||||
|
||||
// 转换字符串,undefined,null等转化为""
|
||||
export function parseStrEmpty(str) {
|
||||
if (!str || str == "undefined" || str == "null") {
|
||||
return "";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// 数据合并
|
||||
export function mergeRecursive(source, target) {
|
||||
for (var p in target) {
|
||||
try {
|
||||
if (target[p].constructor == Object) {
|
||||
source[p] = mergeRecursive(source[p], target[p]);
|
||||
} else {
|
||||
source[p] = target[p];
|
||||
}
|
||||
} catch (e) {
|
||||
source[p] = target[p];
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
*/
|
||||
export function handleTree(data, id, parentId, children) {
|
||||
let config = {
|
||||
id: id || "id",
|
||||
parentId: parentId || "parentId",
|
||||
childrenList: children || "children",
|
||||
};
|
||||
|
||||
var childrenListMap = {};
|
||||
var nodeIds = {};
|
||||
var tree = [];
|
||||
|
||||
for (let d of data) {
|
||||
let parentId = d[config.parentId];
|
||||
if (childrenListMap[parentId] == null) {
|
||||
childrenListMap[parentId] = [];
|
||||
}
|
||||
nodeIds[d[config.id]] = d;
|
||||
childrenListMap[parentId].push(d);
|
||||
}
|
||||
|
||||
for (let d of data) {
|
||||
let parentId = d[config.parentId];
|
||||
if (nodeIds[parentId] == null) {
|
||||
tree.push(d);
|
||||
}
|
||||
}
|
||||
|
||||
for (let t of tree) {
|
||||
adaptToChildrenList(t);
|
||||
}
|
||||
|
||||
function adaptToChildrenList(o) {
|
||||
if (childrenListMap[o[config.id]] !== null) {
|
||||
o[config.childrenList] = childrenListMap[o[config.id]];
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
for (let c of o[config.childrenList]) {
|
||||
adaptToChildrenList(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数处理
|
||||
* @param {*} params 参数
|
||||
*/
|
||||
export function tansParams(params) {
|
||||
let result = "";
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName];
|
||||
var part = encodeURIComponent(propName) + "=";
|
||||
if (value !== null && value !== "" && typeof value !== "undefined") {
|
||||
if (typeof value === "object") {
|
||||
for (const key of Object.keys(value)) {
|
||||
if (
|
||||
value[key] !== null &&
|
||||
value[key] !== "" &&
|
||||
typeof value[key] !== "undefined"
|
||||
) {
|
||||
let params = propName + "[" + key + "]";
|
||||
var subPart = encodeURIComponent(params) + "=";
|
||||
result += subPart + encodeURIComponent(value[key]) + "&";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result += part + encodeURIComponent(value) + "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 返回项目路径
|
||||
export function getNormalPath(p) {
|
||||
if (p.length === 0 || !p || p == "undefined") {
|
||||
return p;
|
||||
}
|
||||
let res = p.replace("//", "/");
|
||||
if (res[res.length - 1] === "/") {
|
||||
return res.slice(0, res.length - 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// 验证是否为blob格式
|
||||
export function blobValidate(data) {
|
||||
return data.type !== "application/json";
|
||||
}
|
||||
|
||||
// 处理图片格式
|
||||
export function disposeImage(primary, type = false) {
|
||||
if (primary && (primary.length || !Array.isArray(primary))) {
|
||||
let imgValue = null;
|
||||
if (Array.isArray(primary)) {
|
||||
imgValue = [];
|
||||
primary.forEach((item) => {
|
||||
if (
|
||||
(typeof item == "string" && type) ||
|
||||
(item.url && item.uuid && !type)
|
||||
) {
|
||||
imgValue.push(item);
|
||||
} else {
|
||||
if (type) {
|
||||
if (item.prefix && item.path) {
|
||||
imgValue.push(item.prefix + item.path);
|
||||
} else {
|
||||
imgValue.push(item.url);
|
||||
}
|
||||
} else {
|
||||
imgValue.push({
|
||||
name: item.name,
|
||||
url: item.prefix + item.path,
|
||||
uuid: item.fileId,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (
|
||||
(typeof primary == "string" && type) ||
|
||||
(primary.url && primary.uuid && !type)
|
||||
) {
|
||||
imgValue = primary;
|
||||
} else {
|
||||
if (type) {
|
||||
if (primary.prefix && primary.path) {
|
||||
imgValue = primary.prefix + primary.path;
|
||||
} else {
|
||||
imgValue = primary.url;
|
||||
}
|
||||
} else {
|
||||
imgValue = {
|
||||
name: primary.name,
|
||||
url: primary.prefix + primary.path,
|
||||
uuid: primary.fileId,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return imgValue;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 处理图片格式
|
||||
export function getImage(primary) {
|
||||
if (primary && primary.length) {
|
||||
let imgArr = [];
|
||||
primary.forEach((item) => {
|
||||
imgArr.push(item.uuid);
|
||||
});
|
||||
return imgArr.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export function getUrl(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getFileMessage({ fileId: url })
|
||||
.then((res) => {
|
||||
resolve(disposeImage(res.data));
|
||||
})
|
||||
.catch((row) => {
|
||||
ElMessage({
|
||||
message: "图片获取错误" + row,
|
||||
type: "error",
|
||||
duration: 5 * 1000,
|
||||
});
|
||||
reject(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 获取图片详情
|
||||
export async function getImageMessage(url, type = false) {
|
||||
if (!url || (Array.isArray(url) && !url.length)) {
|
||||
} else {
|
||||
let uuidList = null;
|
||||
if (typeof url == "string" || typeof url == "number") {
|
||||
uuidList = url.toString().split(",");
|
||||
} else if (Array.isArray(url)) {
|
||||
uuidList = url;
|
||||
}
|
||||
let imgurl = [];
|
||||
for (const item in uuidList) {
|
||||
const url = await getUrl(uuidList[item]);
|
||||
if (url) {
|
||||
if (type) {
|
||||
imgurl.push(url);
|
||||
} else {
|
||||
imgurl.push(url.url);
|
||||
}
|
||||
} else {
|
||||
imgurl.push(img);
|
||||
}
|
||||
}
|
||||
return imgurl;
|
||||
}
|
||||
}
|
||||
|
||||
// 克隆
|
||||
export function deepClone(obj) {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
// 如果 obj 是 null 或不是对象,则直接返回 obj
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
// 如果 obj 是数组
|
||||
const clonedArray = [];
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
// 递归克隆数组中的每个元素
|
||||
clonedArray[i] = deepClone(obj[i]);
|
||||
}
|
||||
return clonedArray;
|
||||
}
|
||||
|
||||
// 如果 obj 是普通对象
|
||||
const clonedObj = {};
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
// 递归克隆对象的每个属性
|
||||
clonedObj[key] = deepClone(obj[key]);
|
||||
}
|
||||
}
|
||||
return clonedObj;
|
||||
}
|
||||
|
||||
// 数组去重
|
||||
export function removeDuplicate(arr) {
|
||||
const newArr = [];
|
||||
arr.forEach((item) => {
|
||||
if (newArr.indexOf(item) === -1) {
|
||||
newArr.push(item);
|
||||
}
|
||||
});
|
||||
return newArr; // 返回一个新数组
|
||||
}
|
||||
160
src/utils/tools.js
Normal file
160
src/utils/tools.js
Normal file
@@ -0,0 +1,160 @@
|
||||
// 获取uuid
|
||||
export function generateUUID() {
|
||||
var d = new Date().getTime();
|
||||
var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0;
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16;
|
||||
if (d > 0) {
|
||||
r = (d + r) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
} else {
|
||||
r = (d2 + r) % 16 | 0;
|
||||
d2 = Math.floor(d2 / 16);
|
||||
}
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤掉可信度(confidence)小于0.6的数据项
|
||||
* @param {Array} data - 要过滤的数组,数组项应包含confidence属性
|
||||
* @returns {Array} 过滤后的新数组
|
||||
*/
|
||||
export function filteConfidence(data) {
|
||||
// 检查输入是否为数组
|
||||
if (!Array.isArray(data)) {
|
||||
console.warn('filteConfidence: 输入参数不是数组');
|
||||
return [];
|
||||
}
|
||||
|
||||
// 过滤并返回新数组
|
||||
return data.filter(item => {
|
||||
return item && typeof item === 'object' &&
|
||||
'confidence' in item &&
|
||||
Number(item.confidence) >= 0.6;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据检测结果截取图片中的多个区域
|
||||
* @param {HTMLImageElement|String} image - 图片元素或图片URL
|
||||
* @param {Array} detectionResults - 检测结果数组,包含box坐标
|
||||
* @param {Object} options - 可选配置
|
||||
* @param {Number} options.minConfidence - 最小置信度阈值,默认0.5
|
||||
* @param {String} options.outputFormat - 输出格式,默认'image/png'
|
||||
* @param {Number} options.outputQuality - 输出质量(0-1),默认0.92
|
||||
* @returns {Promise<Array<{blob: Blob, data: Object}>>} 返回截取图片和相关数据的数组
|
||||
*/
|
||||
export async function cropDetectedRegions(image, detectionResults, options = {}) {
|
||||
// 合并默认配置
|
||||
const {
|
||||
minConfidence = 0.6,
|
||||
outputFormat = 'image/png',
|
||||
outputQuality = 0.92
|
||||
} = options;
|
||||
|
||||
// 如果传入的是URL字符串,先加载图片
|
||||
const img = typeof image === 'string'
|
||||
? await loadImage(image)
|
||||
: image;
|
||||
|
||||
// 创建画布
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 存储所有截取结果
|
||||
const croppedResults = [];
|
||||
|
||||
// 遍历所有检测结果
|
||||
for (const result of detectionResults) {
|
||||
// 检查置信度是否达标
|
||||
if (result.confidence < minConfidence) {
|
||||
console.log(`跳过置信度低于阈值(${minConfidence})的检测结果:`, result);
|
||||
continue;
|
||||
}
|
||||
|
||||
const { x1, y1, x2, y2 } = result.box;
|
||||
const width = x2 - x1;
|
||||
const height = y2 - y1;
|
||||
|
||||
// 检查坐标是否有效
|
||||
if (!isValidBox(x1, y1, x2, y2, img.width, img.height)) {
|
||||
console.warn('无效的坐标区域:', result.box);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 设置画布尺寸
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
// 清空画布
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
|
||||
// 绘制截取区域
|
||||
ctx.drawImage(
|
||||
img,
|
||||
x1, y1, // 源图像裁剪起始坐标
|
||||
width, height, // 源图像裁剪宽高
|
||||
0, 0, // 画布起始坐标
|
||||
width, height // 画布绘制宽高
|
||||
);
|
||||
|
||||
// 将画布内容转为Blob对象
|
||||
const blob = await new Promise((resolve) => {
|
||||
canvas.toBlob(
|
||||
(blob) => resolve(blob),
|
||||
outputFormat,
|
||||
outputQuality
|
||||
);
|
||||
});
|
||||
|
||||
// 保存结果及相关数据
|
||||
croppedResults.push({
|
||||
blob,
|
||||
data: {
|
||||
...result,
|
||||
cropInfo: {
|
||||
x: x1,
|
||||
y: y1,
|
||||
width,
|
||||
height
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return croppedResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载图片
|
||||
* @param {String} url - 图片URL
|
||||
* @returns {Promise<HTMLImageElement>}
|
||||
*/
|
||||
export function loadImage(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'Anonymous'; // 处理跨域问题
|
||||
img.onload = () => resolve(img);
|
||||
img.onerror = reject;
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查坐标框是否有效
|
||||
* @param {Number} x1 - 左上角x坐标
|
||||
* @param {Number} y1 - 左上角y坐标
|
||||
* @param {Number} x2 - 右下角x坐标
|
||||
* @param {Number} y2 - 右下角y坐标
|
||||
* @param {Number} imgWidth - 图片宽度
|
||||
* @param {Number} imgHeight - 图片高度
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isValidBox(x1, y1, x2, y2, imgWidth, imgHeight) {
|
||||
return (
|
||||
x1 >= 0 && y1 >= 0 &&
|
||||
x2 > x1 && y2 > y1 &&
|
||||
x2 <= imgWidth && y2 <= imgHeight
|
||||
);
|
||||
}
|
||||
98
src/utils/whiteboardSync.js
Normal file
98
src/utils/whiteboardSync.js
Normal file
@@ -0,0 +1,98 @@
|
||||
import { mqttClient } from "./mqtt";
|
||||
import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api";
|
||||
import { useMeterStore } from '@/stores/modules/meter';
|
||||
|
||||
const meterStore = useMeterStore();
|
||||
meterStore.initUdid();
|
||||
|
||||
let isRemote = false;
|
||||
let canvasInstance = null;
|
||||
|
||||
// 获取本地缓存 userData
|
||||
function getLocalUserData() {
|
||||
const dataStr = localStorage.getItem('userData');
|
||||
if (!dataStr) return null;
|
||||
try {
|
||||
return JSON.parse(dataStr);
|
||||
} catch (e) {
|
||||
console.error("解析 userData 失败:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const WhiteboardSync = {
|
||||
async init(canvas, roomUid) {
|
||||
if (!canvas || !roomUid) return;
|
||||
console.log('初始化多人同步:', roomUid);
|
||||
canvasInstance = canvas;
|
||||
|
||||
const localUser = getLocalUserData();
|
||||
const localUid = localUser?.user?.uid;
|
||||
|
||||
try {
|
||||
// 先连接 MQTT
|
||||
await mqttClient.connect(meterStore.getSudid());
|
||||
console.log("✅ MQTT 已连接");
|
||||
|
||||
// 获取历史数据
|
||||
const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid);
|
||||
if (res.meta.code === 200 && res.data.shapes.length > 0) {
|
||||
canvasInstance.addShape(res.data.shapes);
|
||||
}
|
||||
|
||||
// 订阅当前房间
|
||||
const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`;
|
||||
mqttClient.subscribe(topic, async (shapeData) => {
|
||||
try {
|
||||
isRemote = true;
|
||||
// 如果 shape 来自本地用户,则跳过
|
||||
if (shapeData.user_uid === localUid) return;
|
||||
const res = await getWhiteboardHistory({ after_timestamp: shapeData.created_at }, roomUid);
|
||||
if (res.meta.code === 200) {
|
||||
canvasInstance.addShape(res.data.shapes);
|
||||
} else {
|
||||
console.error("获取历史数据失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("处理MQTT数据失败:", e);
|
||||
} finally {
|
||||
isRemote = false;
|
||||
}
|
||||
});
|
||||
|
||||
console.log("✅ 已订阅:", topic);
|
||||
} catch (err) {
|
||||
console.log("初始化多人同步失败:",err)
|
||||
// console.error("❌ 连接或订阅失败:", err);
|
||||
}
|
||||
|
||||
// 监听画布事件:新增图形
|
||||
canvas.on('drawingEnd', async (shape) => {
|
||||
// 如果来自远程,或不是需要同步的类型,跳过
|
||||
if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return;
|
||||
|
||||
// 如果是本地用户自己的 shape,则不调用接口
|
||||
if (shape.user_uid && shape.user_uid === localUid) return;
|
||||
|
||||
shape.room_uid = roomUid;
|
||||
|
||||
try {
|
||||
await getWhiteboardShapes(shape, roomUid);
|
||||
} catch (err) {
|
||||
console.error("提交形状失败:", err);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听画布事件:清空
|
||||
canvas.on('clear', async () => {
|
||||
if (!isRemote) {
|
||||
try {
|
||||
// TODO: 调用接口,后端再发 MQTT
|
||||
// await clearWhiteboard(roomUid);
|
||||
} catch (err) {
|
||||
console.error("提交清空失败:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user