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.
 
 
 

293 lines
7.5 KiB

import $ from 'jquery'
import _ from 'lodash'
import localforage from 'localforage'
import JSON5 from 'json5'
import hotkeys from 'hotkeys-js'
import { defineComponent, h, markRaw, nextTick, reactive, toRaw, unref, type App, createApp, type Component } from 'vue'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import { QuestionFilled } from '@element-plus/icons-vue'
import { renderIcon, createShortUUID, setQueryParam, getQueryParams } from '@/utils/webutils.ts'
import type { showDialogOption } from '@/SystemOption'
import ShowDialogWrap from '@/components/ShowDialogWrap.vue'
import LoadingDialog from '@/components/LoadingDialog.vue'
export default class System {
_ = _
$ = $
createApp = createApp
toRaw = toRaw
unref = unref
nextTick = nextTick
defer = _.defer
defineComponent = defineComponent
markRaw = markRaw
reactive = reactive
renderIcon = renderIcon
hotkeys = hotkeys
localforage = localforage
JSON5 = JSON5
json5 = JSON5
app!: App
errorDialogContent: string[] = reactive([])
errorDialogIsShowing: boolean = false
/**
* 对话框元素栈
*/
rootElementList: { cmp: Component, props: any }[] = reactive([])
createUUID = createShortUUID
setQueryParam = setQueryParam
getQueryParams = getQueryParams
constructor(app: App) {
this.app = app
window['_'] = _
window['$'] = $
window['JSON5'] = JSON5
}
/**
* 轻量级提示信息
* @param message 消息内容
* @param type 消息类型,默认为 'info'
*/
msg(message: string, type: 'success' | 'warning' | 'info' | 'error' = 'info'): void {
console.trace(message)
ElMessage({ message, type })
// const $body = $('body')
//
// $body.find('[xtype=tooltip]').remove()
// const $w = $(
// '<div xtype="tooltip" class="yvan-msg yvan-anim yvan-anim-00">' +
// ' <div class="yvan-msg-content">' +
// _.escape(message) +
// '</div></div>'
// )
// $body.append($w)
//
// const iframeWidth = $w.parent().width() as number
// const iframeHeight = $w.parent().height() as number
//
// const windowWidth = $w.width() as number
// const windowHeight = $w.height() as number
//
// let setWidth = (iframeWidth - windowWidth) / 2
// let setHeight = (iframeHeight - windowHeight) / 2
// if (iframeHeight < windowHeight || setHeight < 0) {
// setHeight = 0
// }
// if (iframeWidth < windowWidth || setWidth < 0) {
// setWidth = 0
// }
// $w.css({ left: setWidth, top: setHeight })
// setTimeout(() => {
// $w.remove()
// }, 3000)
}
/**
* 弹出用户必须点击确认的错误信息
*/
showErrorDialog(msgOrTitle: string, msg?: string, dangerouslyUseHTMLString?: boolean, closeCallBack?: () => void) {
let title, message
if (!msg) {
console.trace(msgOrTitle)
title = '错误'
message = msgOrTitle
} else {
console.trace(msg)
title = msgOrTitle
message = msg
}
// 如果有一样的内容,就不添加
if (_.findIndex(this.errorDialogContent, r => r === message) >= 0) {
return
}
this.errorDialogContent.push(message)
if (!this.errorDialogIsShowing) {
// 只有在没有弹出对话框的清空下才弹出
this.errorDialogIsShowing = true
ElMessageBox.alert(
//@ts-ignore
() => {
if (this.errorDialogContent.length <= 0) {
return ''
}
return _.map(this.errorDialogContent, (item) =>
h('div', null, item)
)
},
title,
{
dangerouslyUseHTMLString: false,
closeOnPressEscape: true,
closeOnClickModal: true,
confirmButtonText: '关闭',
type: 'error',
draggable: true,
callback: () => {
this.errorDialogIsShowing = false
nextTick(() => {
this.errorDialogContent.splice(0, this.errorDialogContent.length)
})
if (closeCallBack) closeCallBack()
}
}
)
}
}
/**
* 弹出用户必须确认的提示信息
*/
showInfoDialog(content: string, option: showDialogOption = {
confirmButtonText: '关闭',
draggable: true,
showCancelButton: false,
showClose: false,
dangerouslyUseHTMLString: true,
autofocus: true,
closeOnClickModal: false,
closeOnPressEscape: true
}) {
return this.alert(content, option)
}
/**
* 信息提示内容,强提示,必须用户点击确认
*/
alert(msg: string, option?: showDialogOption): Promise<any> {
console.trace(msg)
// 将 msg 转译为 html enable 格式
msg = _.join(_.split(_.escape(msg), '\n'), '<br />')
const newOption = _.extend({
confirmButtonText: '关闭',
draggable: true,
showCancelButton: false,
showClose: false,
dangerouslyUseHTMLString: true,
autofocus: true,
closeOnClickModal: false,
closeOnPressEscape: true
}, option)
//@ts-ignore
return ElMessageBox.alert(msg, '提示', newOption)
}
/**
* 弹出确认对话框
* @param msg 消息内容
*/
confirm(msg: string): Promise<void> {
return new Promise((resolve, reject) => {
ElMessageBox.confirm(msg, '再次确认',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
icon: markRaw(QuestionFilled)
}
).then(() => {
resolve()
}).catch(() => {
reject()
})
})
}
showDialog(childCmp: Component, param: ShowDialogOption = {}) {
return new Promise<any>((resolve, reject) => {
const fullProps: any = {
title: '未命名对话框',
draggable: true,
width: 800,
height: 600,
showClose: true,
showMax: true,
modal: true,
dialogClass: '',
closeOnClickModal: false,
closeOnPressEscape: true,
_insId: _.uniqueId('tmp_dlg_'),
showCancelButton: true,
showOkButton: true,
cancelButtonText: '取消',
okButtonText: '确定',
...param,
dialogResolve: resolve,
dialogReject: reject,
childCmp: markRaw(childCmp),
_input: param.data || {}
}
system.rootElementList.push({
cmp: h(ShowDialogWrap, fullProps),
props: fullProps
})
})
}
globalLoadingHandle = null // "正在载入..." 对话框
/**
* 全局 “正在载入...” 对话框
*/
public showLoading(msg?: string): void {
if (this.globalLoadingHandle) {
// 存在 "正在载入..." 对话框
this.clearLoading()
}
const _insId = _.uniqueId('_dlg')
system.rootElementList.push({
cmp: markRaw(LoadingDialog),
props: {
_insId: _insId,
msg: msg
}
})
this.globalLoadingHandle = () => {
_.remove(system.rootElementList, (item: any) => item.props._insId === _insId)
}
}
/**
* 关闭 “正在载入...” 对话框
*/
public clearLoading(): void {
if (typeof this.globalLoadingHandle === 'function') {
this.globalLoadingHandle()
}
this.globalLoadingHandle = null
}
}
export interface ShowDialogOption {
title?: string
draggable?: boolean
width?: number
height?: number
showClose?: boolean
showMax?: boolean
modal?: boolean
dialogClass?: string
closeOnClickModal?: boolean
closeOnPressEscape?: boolean
data?: any
showCancelButton?: boolean
showOkButton?: boolean
cancelButtonText?: string
okButtonText?: string
}