feat: 初始化版本!
This commit is contained in:
83
src/plugins/auth.ts
Normal file
83
src/plugins/auth.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import useUserStore from "@/store/modules/user";
|
||||
function authPermission(permission: string): boolean {
|
||||
const all_permission = "*:*:*";
|
||||
const permissions: Array<string> = useUserStore().permissions;
|
||||
if (permission && permission.length > 0) {
|
||||
return permissions.some((v) => {
|
||||
return all_permission === v || v === permission;
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function authRole(role: string): boolean {
|
||||
const super_admin = "admin";
|
||||
const roles: Array<string> = useUserStore().roles;
|
||||
if (role && role.length > 0) {
|
||||
return roles.some((v) => {
|
||||
return super_admin === v || v === role;
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 验证用户是否具备某权限
|
||||
* @param permission 权限符
|
||||
* @returns
|
||||
*/
|
||||
hasPermi(permission: string): boolean {
|
||||
return authPermission(permission);
|
||||
},
|
||||
/**
|
||||
* 验证用户是否含有指定权限,只需包含其中一个
|
||||
* @param permissions 权限符数组
|
||||
* @returns
|
||||
*/
|
||||
hasPermiOr(permissions: Array<string>): boolean {
|
||||
return permissions.some((item) => {
|
||||
return authPermission(item);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 验证用户是否含有指定权限,必须全部拥有
|
||||
* @param permissions 权限符数组
|
||||
* @returns
|
||||
*/
|
||||
hasPermiAnd(permissions: Array<string>): boolean {
|
||||
return permissions.every((item) => {
|
||||
return authPermission(item);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 验证用户是否具备某角色
|
||||
* @param role 角色
|
||||
* @returns
|
||||
*/
|
||||
hasRole(role: string): boolean {
|
||||
return authRole(role);
|
||||
},
|
||||
/**
|
||||
* 验证用户是否含有指定角色,只需包含其中一个
|
||||
* @param roles 角色数组
|
||||
* @returns
|
||||
*/
|
||||
hasRoleOr(roles: Array<string>): boolean {
|
||||
return roles.some((item) => {
|
||||
return authRole(item);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 验证用户是否含有指定角色,必须全部拥有
|
||||
* @param roles 角色数组
|
||||
* @returns
|
||||
*/
|
||||
hasRoleAnd(roles: Array<string>): boolean {
|
||||
return roles.every((item) => {
|
||||
return authRole(item);
|
||||
});
|
||||
},
|
||||
};
|
||||
28
src/plugins/bus.ts
Normal file
28
src/plugins/bus.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
const event: { [key: string]: Function } = {}
|
||||
/** 事件句柄 */
|
||||
export default {
|
||||
/** 绑定一个事件 */
|
||||
$on(eventName: string, eventFun: Function) {
|
||||
if (event.hasOwnProperty(eventName)) {
|
||||
throw new Error(`存在事件 => ${eventName}`)
|
||||
} else {
|
||||
event[eventName] = eventFun
|
||||
}
|
||||
},
|
||||
/** 解绑一个事件 */
|
||||
$off(eventName: keyof typeof event) {
|
||||
if (event.hasOwnProperty(eventName)) {
|
||||
delete event[eventName]
|
||||
} else {
|
||||
throw new Error(`不存在事件 => ${eventName}`)
|
||||
}
|
||||
},
|
||||
/** 触发一个事件 */
|
||||
$emit<T>(eventName: keyof typeof event, ...args: any):T {
|
||||
if (event.hasOwnProperty(eventName)) {
|
||||
return event[eventName](...args)
|
||||
} else {
|
||||
throw new Error(`不存在事件 => ${eventName}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/plugins/index.ts
Normal file
32
src/plugins/index.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import Tab from './tab'
|
||||
import Auth from './auth'
|
||||
import Modal from './modal'
|
||||
import Bus from './bus';
|
||||
import Socket from './socketclient'
|
||||
import { App } from 'vue';
|
||||
|
||||
|
||||
export const tab = Tab;
|
||||
export const auth = Auth;
|
||||
export const modal = Modal;
|
||||
export const bus = Bus
|
||||
export const socket = Socket
|
||||
|
||||
/**
|
||||
* 在组合式API中可以通过 import { tab, auth, modal } form '@/plugins' 来使用tab、auth、modal
|
||||
* 在选项式API中可以通过 this.$tab this.$auth this.$modal 来使用tab、auth、modal
|
||||
*/
|
||||
export default {
|
||||
install(app: App): void {
|
||||
// 页面操作
|
||||
app.config.globalProperties.$tab = tab
|
||||
// 认证对象
|
||||
app.config.globalProperties.$auth = auth
|
||||
// 模态框对象
|
||||
app.config.globalProperties.$modal = modal
|
||||
// 全局事件总线
|
||||
app.config.globalProperties.$bus = bus
|
||||
// socket对象
|
||||
app.config.globalProperties.$socket = socket
|
||||
}
|
||||
}
|
||||
99
src/plugins/modal.ts
Normal file
99
src/plugins/modal.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
export default {
|
||||
/**
|
||||
* 消息提示
|
||||
* @param content 消息内容
|
||||
*/
|
||||
msg(content: string): void {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 错误消息
|
||||
* @param content 消息内容
|
||||
*/
|
||||
msgError(content: string): void {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'error'
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 成功消息
|
||||
* @param content 消息内容
|
||||
*/
|
||||
msgSuccess(content: string): void {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'success'
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 隐藏消息
|
||||
*/
|
||||
hideMsg(): void {
|
||||
uni.hideToast()
|
||||
},
|
||||
/**
|
||||
* 弹出提示
|
||||
* @param content 提示内容
|
||||
*/
|
||||
alert(content: string): void {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: content,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 确认窗体
|
||||
* @param content 提示内容
|
||||
* @returns
|
||||
*/
|
||||
confirm(content: string): Promise<unknown> {
|
||||
return new Promise((resolve: Function, reject: Function) => {
|
||||
uni.showModal({
|
||||
title: '系统提示',
|
||||
content: content,
|
||||
cancelText: '取消',
|
||||
confirmText: '确定',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
resolve(res.confirm)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 提示信息
|
||||
* @param option 提示内容或者提示框配置
|
||||
*/
|
||||
showToast(option: string | object): void {
|
||||
if (typeof option === "object") {
|
||||
uni.showToast(option)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: option,
|
||||
icon: "none",
|
||||
duration: 2500
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 打开遮罩层,需要手动关闭遮罩层
|
||||
* @param content 遮罩层内容
|
||||
*/
|
||||
loading(content: string): void {
|
||||
uni.showLoading({
|
||||
title: content
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 关闭遮罩层
|
||||
*/
|
||||
closeLoading(): void {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
165
src/plugins/mqttclient.ts
Normal file
165
src/plugins/mqttclient.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
import { generateUUID } from "@/utils/geek";
|
||||
import * as mqtt from "mqtt/dist/mqtt";
|
||||
const enableJSONDecoding = true // 开启JSON解析消息,需要开启JSON解析消息才能开启uuid和event
|
||||
const enableJSONEncoding = true // 开启JSON消息编码
|
||||
const enableUUID = true // 需要接收信息中包含uuid字段,uuid优先级高于event
|
||||
|
||||
type MqttConnectOptions = {
|
||||
clean: boolean,
|
||||
connectTimeout: number,
|
||||
clientId: string, // 认证信息
|
||||
keepalive: number,
|
||||
protocolId?: string, // 默认 'MQTT'
|
||||
protocolVersion?: number, // 默认4
|
||||
username?: string,
|
||||
password?: string,
|
||||
}
|
||||
type MqttConnectConfig = {
|
||||
url?: string,
|
||||
options: MqttConnectOptions
|
||||
}
|
||||
interface MqttClient {
|
||||
connected:boolean,
|
||||
on: {
|
||||
(event: "connect", fun: () => void): void;
|
||||
(event: "reconnect", fun: () => void): void;
|
||||
(event: "disconnect", fun: () => void): void;
|
||||
(event: "offline", fun: () => void): void;
|
||||
(event: "message", fun: (topic: string, message: any, packet?: any) => void): void;
|
||||
(event: "packetsend", fun: (packet: any) => void): void;
|
||||
(event: "packetreceive", fun: (packet: any) => void): void;
|
||||
(event: "error", fun: (err: any) => void): void;
|
||||
};
|
||||
publish: {
|
||||
(topic: string, message: any, options?: any, callback?: (err: any) => void): void;
|
||||
}
|
||||
subscribe: {
|
||||
(topic: string, options?: any, callback?: (err: any, granted: { topic: string, qos: any }) => void): void
|
||||
}
|
||||
unsubscribe: {
|
||||
(topic: string, callback?: (err: any) => void): void
|
||||
}
|
||||
end(force?:boolean, options?:any, callback?: (err: any) => void): void
|
||||
}
|
||||
|
||||
let _client: MqttClient;
|
||||
let _callback: { [key: string]: (data: any) => void } = {}
|
||||
let onmassage = (topic:string,message:string)=>{}
|
||||
export default {
|
||||
/**
|
||||
* 连接websocket
|
||||
* 最简单的用法就是传入{url:"ws://demo"}
|
||||
* 当连接成功后触发回调函数
|
||||
*/
|
||||
connect(config: MqttConnectConfig) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
if(!_client || !_client.connected){
|
||||
_client = mqtt.connect(config.url, config.options);
|
||||
_client.on('connect', resolve);
|
||||
_client.on('error', reject);
|
||||
_client.on('message', (topic,message) => {
|
||||
if (enableJSONDecoding) {
|
||||
let data = JSON.parse(message)
|
||||
if (enableUUID && (data || {}).uuid !== undefined) {
|
||||
_callback[data.uuid](data)
|
||||
delete _callback[data.uuid]
|
||||
}
|
||||
}
|
||||
onmassage(topic,message)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 发送信息
|
||||
* @param msg 消息,会被处理成json字符串
|
||||
* @param uuid 唯一标识,可以传入uuid,也可以传入true自动生成uuid,flase表示该消息不需要单独处理
|
||||
* @returns
|
||||
*/
|
||||
send(topic: string, msg: any, uuid: string | boolean = false, options: any = undefined) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const useUUID = enableUUID && uuid != undefined && uuid != "" && uuid != false
|
||||
if (useUUID) {
|
||||
if (uuid === true) {
|
||||
msg.uuid = generateUUID()
|
||||
_callback[msg.uuid] = resolve
|
||||
} else {
|
||||
_callback[uuid] = resolve
|
||||
}
|
||||
}
|
||||
if(enableJSONEncoding){
|
||||
msg = JSON.stringify(msg)
|
||||
}
|
||||
_client.publish(topic, msg, options, err => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else if (uuid === false) {
|
||||
resolve(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 关闭连接
|
||||
* @returns 关闭连接的Promise,回调函数只会运行一次
|
||||
*/
|
||||
close(force?: boolean, options?: any, callback?: (err: any) => void) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
_client.end(force,options,()=>{
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 订阅事件
|
||||
* @param event 要监听的事件
|
||||
* @returns 在回调函数中处理事件
|
||||
*/
|
||||
subscribe(topic: string, options: string | undefined = undefined) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
_client.subscribe(topic, options, err => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 取消订阅事件
|
||||
* @param event 要取消监听的事件
|
||||
*/
|
||||
unsubscribe(topic: string) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
_client.unsubscribe(topic, err => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 定义默认监听事件
|
||||
* @param callback 默认监听事件的处理函数
|
||||
*/
|
||||
onMessage(callback: (topic:string,message:string) => void) {
|
||||
onmassage = callback
|
||||
},
|
||||
/**
|
||||
* 定义异常事件
|
||||
* @param callback 默认异常事件的处理函数
|
||||
*/
|
||||
onError(callback: (data: any) => void) {
|
||||
_client.on('error', callback)
|
||||
},
|
||||
/**
|
||||
* 定义关闭事件
|
||||
* @param callback 默认关闭事件的处理函数
|
||||
*/
|
||||
onClose(callback: () => void) {
|
||||
_client.on('disconnect', callback)
|
||||
}
|
||||
}
|
||||
147
src/plugins/socketclient.ts
Normal file
147
src/plugins/socketclient.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { generateUUID } from '@/utils/geek';
|
||||
let _client: UniApp.SocketTask;
|
||||
let _callback: { [key: string]: (data: any) => void } = {}
|
||||
const enableJSON = true // 开启JSON解析消息,需要开启JSON解析消息才能开启uuid和event
|
||||
const enableJSONEncoding = true // 开启JSON消息编码
|
||||
const enableUUID = true // 需要接收信息中包含uuid字段,uuid优先级高于event
|
||||
const enableEvent = true // 需要接收信息中包含event字段
|
||||
|
||||
|
||||
export interface SocketConnectConfig extends UniApp.ConnectSocketOption {
|
||||
headers: {
|
||||
isToken: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 连接websocket
|
||||
* 最简单的用法就是传入{url:"ws://demo"}
|
||||
* 当连接成功后触发回调函数
|
||||
*/
|
||||
connect(config: SocketConnectConfig) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
config.header = config.header || { 'content-type': 'application/json' }
|
||||
if (getToken() && !isToken) {
|
||||
config.header['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
if(_client !== undefined){
|
||||
_client.close({})
|
||||
}
|
||||
_client = uni.connectSocket({
|
||||
url: config.url,
|
||||
header: config.header,
|
||||
method: config.method || 'GET',
|
||||
fail: reject
|
||||
});
|
||||
_client.onError(reject)
|
||||
_client.onOpen(resolve)
|
||||
_client.onMessage(res => {
|
||||
if(enableJSON){
|
||||
let data = JSON.parse((res || {}).data)
|
||||
if (enableUUID && (data || {}).uuid !== undefined) {
|
||||
_callback[data.uuid](data)
|
||||
} else if (enableEvent && (data || {}).event !== undefined) {
|
||||
_callback[data.event](data)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 发送信息
|
||||
* @param msg 消息,会被处理成json字符串
|
||||
* @param uuid 唯一标识,可以传入uuid,也可以传入true自动生成uuid,flase表示该消息不需要单独处理
|
||||
* @returns
|
||||
*/
|
||||
send(msg: any, uuid: string | boolean = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(enableJSONEncoding){
|
||||
msg = JSON.stringify(msg)
|
||||
}
|
||||
if (enableUUID && uuid != undefined && uuid != "" && uuid != false) {
|
||||
if (uuid === true) {
|
||||
msg.uuid = generateUUID()
|
||||
_callback[msg.uuid] = resolve
|
||||
} else {
|
||||
_callback[uuid] = resolve
|
||||
}
|
||||
}
|
||||
_client.send({
|
||||
data: JSON.stringify(msg),
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 关闭连接
|
||||
* @returns 关闭连接的Promise,回调函数只会运行一次
|
||||
*/
|
||||
close() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let onclose = _client.onClose
|
||||
_client.onClose(res => {
|
||||
resolve(res)
|
||||
_client.onClose = onclose
|
||||
})
|
||||
_client.close({
|
||||
fail: reject
|
||||
})
|
||||
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 监听事件
|
||||
* @param event 要监听的事件
|
||||
* @returns 在回调函数中处理事件
|
||||
*/
|
||||
subscribe(event: string) {
|
||||
return new Promise((resolve) => {
|
||||
_callback[event] = resolve
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 取消监听事件
|
||||
* @param event 要取消监听的事件
|
||||
*/
|
||||
unsubscribe(event: string) {
|
||||
delete _callback[event]
|
||||
},
|
||||
/**
|
||||
* 定义默认监听事件
|
||||
* @param callback 默认监听事件的处理函数
|
||||
*/
|
||||
onMessage(callback: (data: any) => void) {
|
||||
_client.onMessage(res => {
|
||||
if(enableJSON){
|
||||
let data = JSON.parse((res || {}).data)
|
||||
if (enableUUID && (data || {}).uuid !== undefined) {
|
||||
_callback[data.uuid](res)
|
||||
delete _callback[data.uuid]
|
||||
} else if (enableEvent && (data || {}).event !== undefined) {
|
||||
_callback[data.event](res)
|
||||
} else {
|
||||
callback(data)
|
||||
}
|
||||
}else{
|
||||
callback(res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 定义异常事件
|
||||
* @param callback 默认异常事件的处理函数
|
||||
*/
|
||||
onError(callback: (data: any) => void) {
|
||||
_client.onError(callback)
|
||||
},
|
||||
/**
|
||||
* 定义关闭事件
|
||||
* @param callback 默认关闭事件的处理函数
|
||||
*/
|
||||
onClose(callback: () => void) {
|
||||
_client.onError(callback)
|
||||
}
|
||||
};
|
||||
93
src/plugins/tab.ts
Normal file
93
src/plugins/tab.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { tansParams } from "@/utils/common";
|
||||
|
||||
let _params:string = "{}"
|
||||
function setParams(params:any){
|
||||
_params = JSON.stringify(params)
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 关闭所有页面,打开到应用内的某个页面
|
||||
* @param url 页面路径
|
||||
* @returns
|
||||
*/
|
||||
reLaunch(url: string, params?: any): Promise<unknown> {
|
||||
setParams(params)
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.reLaunch({
|
||||
url: !!params?url + '?' + tansParams(params):url,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
|
||||
* @param url 页面路径
|
||||
* @returns
|
||||
*/
|
||||
switchTab(url: string, params?: any): Promise<unknown> {
|
||||
setParams(params)
|
||||
console.log(!!params?url + '?' + tansParams(params):url);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.switchTab({
|
||||
url: !!params?url + '?' + tansParams(params):url,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
,
|
||||
/**
|
||||
* 关闭当前页面,跳转到应用内的某个页面
|
||||
* @param url 页面路径
|
||||
* @returns
|
||||
*/
|
||||
redirectTo(url: string, params?: any): Promise<unknown> {
|
||||
setParams(params)
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.redirectTo({
|
||||
url: !!params?url + '?' + tansParams(params):url,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 保留当前页面,跳转到应用内的某个页面
|
||||
* @param url 页面路径
|
||||
* @returns
|
||||
*/
|
||||
navigateTo(url: string, params?: any): Promise<unknown> {
|
||||
setParams(params)
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.navigateTo({
|
||||
url: !!params?url + '?' + tansParams(params):url,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭当前页面,返回上一页面或多级页面
|
||||
* @returns
|
||||
*/
|
||||
navigateBack(): Promise<unknown> {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.navigateBack({
|
||||
success: resolve,
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取当前页面参数
|
||||
*/
|
||||
getParams(): any {
|
||||
return JSON.parse(_params)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user