no message

This commit is contained in:
kuaifan 2025-05-17 09:09:59 +08:00
parent 98e4c81b9b
commit 7d28181b16
6 changed files with 103 additions and 88 deletions

View File

@ -98,7 +98,6 @@ import emitter from "./store/events";
import SearchBox from "./components/SearchBox.vue"; import SearchBox from "./components/SearchBox.vue";
import UserDetail from "./pages/manage/components/UserDetail.vue"; import UserDetail from "./pages/manage/components/UserDetail.vue";
import {languageName} from "./language"; import {languageName} from "./language";
import {closeLastMicroAggregate} from "./components/MicroApps/queue";
export default { export default {
mixins: [ctrlPressed], mixins: [ctrlPressed],
@ -551,9 +550,6 @@ export default {
} }
window.__onBeforeUnload = () => { window.__onBeforeUnload = () => {
this.$store.dispatch("onBeforeUnload"); this.$store.dispatch("onBeforeUnload");
if (closeLastMicroAggregate()) {
return;
}
if (this.$Modal.removeLast()) { if (this.$Modal.removeLast()) {
return true; return true;
} }

View File

@ -7,6 +7,7 @@
:ref="`ref-${app.name}`" :ref="`ref-${app.name}`"
:size="1200" :size="1200"
:transparent="app.transparent" :transparent="app.transparent"
:inheritDarkMode="app.inheritDarkMode"
:beforeClose="async () => { await onBeforeClose(app.name) }"> :beforeClose="async () => { await onBeforeClose(app.name) }">
<micro-app <micro-app
v-if="app.isOpen" v-if="app.isOpen"
@ -31,6 +32,17 @@
v-model="userSelectOptions.value" v-model="userSelectOptions.value"
v-bind="userSelectOptions.config" v-bind="userSelectOptions.config"
module/> module/>
<!--窗口助理-->
<Modal
v-model="assistShow"
:closable="true"
:mask="false"
:mask-closable="false"
:footer-hide="true"
:transition-names="['', '']"
:beforeClose="onAssistClose"
class-name="micro-app-assist"/>
</div> </div>
</template> </template>
@ -51,6 +63,15 @@
background-color: rgba(255, 255, 255, 0.6); background-color: rgba(255, 255, 255, 0.6);
} }
} }
.micro-app-assist {
width: 0;
height: 0;
opacity: 0;
display: none;
visibility: hidden;
pointer-events: none;
}
</style> </style>
<script> <script>
@ -65,7 +86,6 @@ import emitter from "../../store/events";
import TransferDom from "../../directives/transfer-dom"; import TransferDom from "../../directives/transfer-dom";
import store from "../../store"; import store from "../../store";
import MicroModal from "./modal.vue"; import MicroModal from "./modal.vue";
import {setMicroAggregate} from "./queue";
export default { export default {
name: "MicroApps", name: "MicroApps",
@ -75,7 +95,7 @@ export default {
data() { data() {
return { return {
apps: [], apps: [],
assistShow: false,
userSelectOptions: {value: [], config: {}}, userSelectOptions: {value: [], config: {}},
} }
}, },
@ -89,14 +109,10 @@ export default {
mounted() { mounted() {
emitter.on('observeMicroApp:open', this.observeMicroApp); emitter.on('observeMicroApp:open', this.observeMicroApp);
emitter.on('observeMicroApp:close', this.closeByName);
document.addEventListener('keydown', this.escClose);
}, },
beforeDestroy() { beforeDestroy() {
emitter.off('observeMicroApp:open', this.observeMicroApp); emitter.off('observeMicroApp:open', this.observeMicroApp);
emitter.off('observeMicroApp:close', this.closeByName);
document.removeEventListener('keydown', this.escClose);
}, },
watch: { watch: {
@ -111,7 +127,7 @@ export default {
}, },
apps: { apps: {
handler(apps) { handler(apps) {
setMicroAggregate(apps.filter(item => item.isOpen).map(item => item.name)) this.assistShow = !!apps.find(item => item.isOpen)
}, },
deep: true, deep: true,
} }
@ -317,6 +333,7 @@ export default {
* - transparent 是否透明模式 (true/false)默认 false * - transparent 是否透明模式 (true/false)默认 false
* - keepAlive 是否开启微应用保活 (true/false)默认 true * - keepAlive 是否开启微应用保活 (true/false)默认 true
* - disableScopecss 是否禁用样式隔离 (true/false)默认 false * - disableScopecss 是否禁用样式隔离 (true/false)默认 false
* - inheritDarkMode 是否继承暗黑模式 (true/false)默认 false
*/ */
observeMicroApp(config) { observeMicroApp(config) {
// //
@ -326,6 +343,7 @@ export default {
config.transparent = typeof config.transparent == 'boolean' ? config.transparent : false config.transparent = typeof config.transparent == 'boolean' ? config.transparent : false
config.keepAlive = typeof config.keepAlive == 'boolean' ? config.keepAlive : true config.keepAlive = typeof config.keepAlive == 'boolean' ? config.keepAlive : true
config.disableScopecss = typeof config.disableScopecss == 'boolean' ? config.disableScopecss : false config.disableScopecss = typeof config.disableScopecss == 'boolean' ? config.disableScopecss : false
config.inheritDarkMode = typeof config.inheritDarkMode == 'boolean' ? config.inheritDarkMode : false
// //
const app = this.apps.find(({name}) => name == config.name); const app = this.apps.find(({name}) => name == config.name);
@ -352,21 +370,6 @@ export default {
} }
}, },
/**
* ESC 关闭微应用
* @param e
*/
escClose(e) {
if (e.keyCode !== 27) {
return;
}
const app = this.apps.findLast(item => item.isOpen);
if (!app) {
return;
}
this.closeByName(app.name)
},
/** /**
* 通过名称关闭微应用 * 通过名称关闭微应用
* @param name * @param name
@ -425,6 +428,21 @@ export default {
}) })
}) })
}, },
/**
* 关闭之前判断助理
* @returns {Promise<unknown>}
*/
onAssistClose() {
return new Promise(resolve => {
const app = this.apps.findLast(item => item.isOpen)
if (app) {
this.closeByName(app.name)
} else {
resolve()
}
})
},
} }
} }
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-transfer-dom :data-transfer="true" :class="{'micro-modal': value, 'transparent-mode': transparent }"> <div v-transfer-dom :data-transfer="true" :class="className">
<transition :name="transitions[0]"> <transition :name="transitions[0]">
<div v-if="value" class="micro-modal-mask" @click="onClose" :style="maskStyle"></div> <div v-if="value" class="micro-modal-mask" @click="onClose" :style="maskStyle"></div>
</transition> </transition>
@ -19,7 +19,7 @@
:reverse="true" :reverse="true"
:beforeResize="beforeResize" :beforeResize="beforeResize"
@on-change="onChangeResize"/> @on-change="onChangeResize"/>
<div class="micro-modal-body"> <div ref="body" class="micro-modal-body">
<slot></slot> <slot></slot>
</div> </div>
</div> </div>
@ -52,6 +52,10 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
}, },
inheritDarkMode: {
type: Boolean,
default: false
},
beforeClose: Function beforeClose: Function
}, },
data() { data() {
@ -61,12 +65,13 @@ export default {
} }
}, },
computed: { computed: {
maskStyle({zIndex}) { className({value, transparent, inheritDarkMode}) {
return {zIndex} return {
}, 'micro-modal': true,
contentStyle({dynamicSize, zIndex}) { 'micro-hidden': !value,
const width = dynamicSize <= 100 ? `${dynamicSize}%` : `${dynamicSize}px` 'no-dark-content': !inheritDarkMode,
return {width, zIndex} 'transparent-mode': transparent
}
}, },
transitions({transparent}) { transitions({transparent}) {
if (transparent) { if (transparent) {
@ -74,6 +79,13 @@ export default {
} }
return ['micro-modal-fade', 'micro-modal-slide'] return ['micro-modal-fade', 'micro-modal-slide']
}, },
maskStyle({zIndex}) {
return {zIndex}
},
contentStyle({dynamicSize, zIndex}) {
const width = dynamicSize <= 100 ? `${dynamicSize}%` : `${dynamicSize}px`
return {width, zIndex}
},
}, },
watch: { watch: {
value: { value: {
@ -108,7 +120,9 @@ export default {
}, },
updateSize() { updateSize() {
this.dynamicSize = this.$refs.body.clientWidth; if (this.$refs.body) {
this.dynamicSize = this.$refs.body.clientWidth;
}
}, },
onClose() { onClose() {
@ -132,10 +146,37 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.micro-modal { .micro-modal {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
will-change: auto;
--modal-mask-bg: rgba(0, 0, 0, .4);
--modal-close-color: #ffffff;
img,
video,
iframe,
canvas,
[style*="background:url"],
[style*="background: url"],
[style*="background-image:url"],
[style*="background-image: url"],
[background] {
will-change: auto;
}
&.micro-hidden {
animation: hidden 0s forwards;
animation-delay: 300ms;
@keyframes hidden {
to {
display: none;
}
}
}
&-mask { &-mask {
position: fixed; position: fixed;
@ -143,7 +184,7 @@ export default {
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
background-color: rgba(55, 55, 55, .6); background-color: var(--modal-mask-bg);
} }
&-close { &-close {
@ -157,7 +198,7 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: #fff; color: var(--modal-close-color);
cursor: pointer; cursor: pointer;
> svg { > svg {
@ -289,4 +330,14 @@ export default {
} }
} }
} }
//
body.dark-mode-reverse {
.micro-modal {
&:not(.no-dark-content) {
--modal-mask-bg: rgba(230, 230, 230, 0.6);
--modal-close-color: #323232;
}
}
}
</style> </style>

View File

@ -1,22 +0,0 @@
import emitter from "../../store/events";
let microAggregate = [];
const setMicroAggregate = (names) => {
microAggregate = names;
}
const hasMicroAggregate = () => {
return microAggregate.length > 0;
}
const closeLastMicroAggregate = () => {
const name = microAggregate.pop();
if (!name) {
return false;
}
emitter.emit("observeMicroApp:close", name);
return true;
}
export { setMicroAggregate, hasMicroAggregate, closeLastMicroAggregate};

View File

@ -6,7 +6,6 @@
<script> <script>
import {mapState} from "vuex"; import {mapState} from "vuex";
import {closeLastMicroAggregate, hasMicroAggregate} from "../MicroApps/queue";
export default { export default {
name: "MobileBack", name: "MobileBack",
@ -111,9 +110,6 @@ export default {
if (!this.mobileTabbar) { if (!this.mobileTabbar) {
return true; return true;
} }
if (hasMicroAggregate()) {
return true;
}
if (this.$Modal.visibleList().length > 0) { if (this.$Modal.visibleList().length > 0) {
return true; return true;
} }
@ -138,11 +134,6 @@ export default {
// //
this.$store.commit('menu/operation', {}) this.$store.commit('menu/operation', {})
//
if (closeLastMicroAggregate()) {
return;
}
// //
if (this.$Modal.removeLast()) { if (this.$Modal.removeLast()) {
return; return;

View File

@ -1095,25 +1095,6 @@ import {convertLocalResourcePath} from "../components/Replace/utils";
${this.utils.noneFilter()} ${this.utils.noneFilter()}
} }
/* Micro App */
.micro-modal {
${this.utils.reverseFilter()}
will-change: auto;
}
.micro-modal img,
.micro-modal video,
.micro-modal iframe,
.micro-modal canvas,
.micro-modal [style*="background:url"],
.micro-modal [style*="background: url"],
.micro-modal [style*="background-image:url"],
.micro-modal [style*="background-image: url"],
.micro-modal [background] {
${this.utils.noneFilter()}
will-change: auto;
}
/* Text contrast */ /* Text contrast */
html { html {
text-shadow: 0 0 0 !important; text-shadow: 0 0 0 !important;