no message

This commit is contained in:
kuaifan 2025-05-23 11:15:51 +08:00
parent 1df927f771
commit 2905059947
11 changed files with 75 additions and 85 deletions

View File

@ -100,7 +100,7 @@ services:
appstore: appstore:
container_name: "dootask-appstore-${APP_ID}" container_name: "dootask-appstore-${APP_ID}"
privileged: true privileged: true
image: "dootask/appstore:0.0.1" image: "dootask/appstore:0.0.2"
volumes: volumes:
- shared_data:/usr/share/dootask - shared_data:/usr/share/dootask
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock

View File

@ -96,7 +96,7 @@ server {
proxy_pass http://appstore:8080/; proxy_pass http://appstore:8080/;
} }
include /var/www/docker/appstore/configs/*/nginx.conf; include /var/www/docker/appstore/config/*/nginx.conf;
} }
include /var/www/docker/nginx/conf.d/*.conf; include /var/www/docker/nginx/conf.d/*.conf;

View File

@ -4,18 +4,18 @@
v-for="(app, key) in apps" v-for="(app, key) in apps"
:key="key" :key="key"
v-model="app.isOpen" v-model="app.isOpen"
:ref="`ref-${app.name}`" :ref="`ref-${app.id}`"
:size="1200" :size="1200"
:transparent="app.transparent" :transparent="app.transparent"
:autoDarkTheme="app.autoDarkTheme" :autoDarkTheme="app.autoDarkTheme"
:beforeClose="async () => { await onBeforeClose(app.name) }"> :beforeClose="async () => { await onBeforeClose(app.id) }">
<micro-app <micro-app
v-if="app.isOpen" v-if="app.isOpen && app.url"
:name="app.name" :name="app.id"
:url="app.url" :url="app.url"
:keep-alive="app.keepAlive" :keep-alive="app.keepAlive"
:disable-scopecss="app.disableScopecss" :disable-scopecss="app.disableScopecss"
:data="appData(app.name)" :data="appData(app.id)"
@created="created" @created="created"
@beforemount="beforemount" @beforemount="beforemount"
@mounted="mounted" @mounted="mounted"
@ -173,7 +173,7 @@ export default {
// //
finish(e) { finish(e) {
const app = this.apps.find(({name}) => name == e.detail.name); const app = this.apps.find(({id}) => id == e.detail.name);
if (app) { if (app) {
app.isLoading = false app.isLoading = false
} }
@ -181,11 +181,11 @@ export default {
/** /**
* 应用数据 * 应用数据
* @param name * @param id
* @returns {*} * @returns {*}
*/ */
appData(name) { appData(id) {
const app = this.apps.find(item => item.name == name); const app = this.apps.find(item => item.id == id);
if (!app) { if (!app) {
return {}; return {};
} }
@ -225,10 +225,10 @@ export default {
methods: { methods: {
close: (destroy = false) => { close: (destroy = false) => {
this.closeMicroApp(name, destroy) this.closeMicroApp(id, destroy)
}, },
back: () => { back: () => {
this.closeByName(name) this.closeById(id)
}, },
nextZIndex: () => { nextZIndex: () => {
if (typeof window.modalTransferIndex === 'number') { if (typeof window.modalTransferIndex === 'number') {
@ -256,12 +256,12 @@ export default {
let appConfig = {} let appConfig = {}
if (config.url) { if (config.url) {
appConfig = { appConfig = {
name: `url-${await $A.getSHA256Hash(config.url)}`, id: `url-${await $A.getSHA256Hash(config.url)}`,
url: config.url, url: config.url,
} }
delete config.url delete config.url
} else { } else {
const app = this.apps.find(item => item.name == name); const app = this.apps.find(item => item.id == id);
if (!app) { if (!app) {
$A.modalError("应用不存在"); $A.modalError("应用不存在");
return return
@ -271,14 +271,14 @@ export default {
appConfig.transparent = true appConfig.transparent = true
appConfig.keepAlive = false appConfig.keepAlive = false
const apps = (await $A.IDBArray("cacheMicroApps")).filter(item => item.name != appConfig.name); const apps = (await $A.IDBArray("cacheMicroApps")).filter(item => item.id != appConfig.id);
apps.length > 50 && apps.splice(0, 10) apps.length > 50 && apps.splice(0, 10)
apps.push(appConfig) apps.push(appConfig)
await $A.IDBSet("cacheMicroApps", apps); await $A.IDBSet("cacheMicroApps", apps);
await this.$store.dispatch('openChildWindow', { await this.$store.dispatch('openChildWindow', {
name: `single-apps-${$A.randomString(6)}`, name: `single-apps-${$A.randomString(6)}`,
path: `/single/apps/${appConfig.name}`, path: `/single/apps/${appConfig.id}`,
force: false, force: false,
config config
}); });
@ -329,11 +329,11 @@ export default {
* @param config * @param config
*/ */
async observeMicroApp(config) { async observeMicroApp(config) {
const app = this.apps.find(({name}) => name == config.name); const app = this.apps.find(({id}) => id == config.id);
if (app) { if (app) {
// //
if (app.url != config.url) { if (app.url != config.url) {
await microApp.unmountApp(app.name, {destroy: true}) await microApp.unmountApp(app.id, {destroy: true})
app.isLoading = true app.isLoading = true
} }
Object.assign(app, config) Object.assign(app, config)
@ -348,31 +348,31 @@ export default {
}, },
/** /**
* 通过名称关闭微应用 * 通过ID关闭微应用
* @param name * @param id
*/ */
closeByName(name) { closeById(id) {
try { try {
this.$refs[`ref-${name}`][0].onClose() this.$refs[`ref-${id}`][0].onClose()
} catch (e) { } catch (e) {
this.closeMicroApp(name) this.closeMicroApp(id)
} }
}, },
/** /**
* 关闭微应用 * 关闭微应用
* @param name * @param id
* @param destroy * @param destroy
*/ */
closeMicroApp(name, destroy) { closeMicroApp(id, destroy) {
const app = this.apps.find(item => item.name == name); const app = this.apps.find(item => item.id == id);
if (!app) { if (!app) {
return; return;
} }
app.isOpen = false app.isOpen = false
if (destroy) { if (destroy) {
microApp.unmountApp(app.name, {destroy: true}) microApp.unmountApp(app.id, {destroy: true})
} }
}, },
@ -386,14 +386,14 @@ export default {
/** /**
* 关闭之前判断 * 关闭之前判断
* @param name * @param id
* @returns {Promise<unknown>} * @returns {Promise<unknown>}
*/ */
onBeforeClose(name) { onBeforeClose(id) {
return new Promise(resolve => { return new Promise(resolve => {
microApp.forceSetData(name, {type: 'beforeClose'}, array => { microApp.forceSetData(id, {type: 'beforeClose'}, array => {
if (!array?.find(item => item === true)) { if (!array?.find(item => item === true)) {
if (name === 'appstore') { if (id === 'appstore') {
this.$store.dispatch("updateMicroAppsStatus"); this.$store.dispatch("updateMicroAppsStatus");
} }
if ($A.isSubElectron) { if ($A.isSubElectron) {
@ -414,7 +414,7 @@ export default {
return new Promise(resolve => { return new Promise(resolve => {
const app = this.apps.findLast(item => item.isOpen) const app = this.apps.findLast(item => item.isOpen)
if (app) { if (app) {
this.closeByName(app.name) this.closeById(app.id)
} else { } else {
resolve() resolve()
} }

View File

@ -1201,14 +1201,6 @@ export default {
case 'microApp': case 'microApp':
this.$store.dispatch("openMicroApp", params); this.$store.dispatch("openMicroApp", params);
break; break;
case 'appstore':
this.$store.dispatch("openMicroApp", {
name: 'appstore',
url: 'appstore/internal',
disableScopecss: true,
autoDarkTheme: false,
});
break;
} }
}, },

View File

@ -15,22 +15,6 @@
{{ t == 'base' ? $L('常用') : $L('管理员') }} {{ t == 'base' ? $L('常用') : $L('管理员') }}
</div> </div>
<Row :gutter="16"> <Row :gutter="16">
<Col
v-if="t == 'admin'"
:xs="{ span: 6 }"
:sm="{ span: 6 }"
:lg="{ span: 6 }"
:xl="{ span: 6 }"
:xxl="{ span: 3 }">
<div class="apply-col">
<div @click="applyClick({value: 'appstore'})">
<div class="logo">
<div class="apply-icon no-dark-content" :class="getLogoClass('appstore')"></div>
</div>
<p>{{ $L('应用商店') }}</p>
</div>
</div>
</Col>
<Col <Col
v-for="(item, key) in (t == 'base' ? filterMicroAppsMenus : filterMicroAppsMenusAdmin)" v-for="(item, key) in (t == 'base' ? filterMicroAppsMenus : filterMicroAppsMenusAdmin)"
:key="`micro_` + key" :key="`micro_` + key"
@ -395,7 +379,7 @@ export default {
'windowOrientation', 'windowOrientation',
'formOptions', 'formOptions',
'routeLoading', 'routeLoading',
'microAppsNames' 'microAppsIds'
]), ]),
...mapGetters([ ...mapGetters([
'filterMicroAppsMenus', 'filterMicroAppsMenus',
@ -403,10 +387,10 @@ export default {
]), ]),
applyList() { applyList() {
const list = [ const list = [
{value: "approve", label: "审批中心", sort: 30, show: this.microAppsNames.includes('approve')}, {value: "approve", label: "审批中心", sort: 30, show: this.microAppsIds.includes('approve')},
{value: "report", label: "工作报告", sort: 50}, {value: "report", label: "工作报告", sort: 50},
{value: "mybot", label: "我的机器人", sort: 55}, {value: "mybot", label: "我的机器人", sort: 55},
{value: "robot", label: "AI 机器人", sort: 60, show: this.microAppsNames.includes('ai')}, {value: "robot", label: "AI 机器人", sort: 60, show: this.microAppsIds.includes('ai')},
{value: "signin", label: "签到打卡", sort: 70}, {value: "signin", label: "签到打卡", sort: 70},
{value: "meeting", label: "在线会议", sort: 80}, {value: "meeting", label: "在线会议", sort: 80},
{value: "createGroup", label: "创建群组", sort: 85}, {value: "createGroup", label: "创建群组", sort: 85},

View File

@ -2624,7 +2624,7 @@ export default {
return; return;
} }
this.$store.dispatch("openMicroApp", { this.$store.dispatch("openMicroApp", {
app_name: 'okr', id: 'okr',
key: 'details', key: 'details',
url: 'apps/okr/', url: 'apps/okr/',
props: {type: 'details', id}, props: {type: 'details', id},

View File

@ -9,19 +9,19 @@ export default {
components: { MicroApps }, components: { MicroApps },
async mounted() { async mounted() {
const name = this.$route.params.appName; const id = this.$route.params.appId;
if (!name) { if (!id) {
$A.modalError("应用不存在"); $A.modalError("应用不存在");
return return
} }
const app = (await $A.IDBArray("cacheMicroApps")).reverse().find(item => item.name === name); const app = (await $A.IDBArray("cacheMicroApps")).reverse().find(item => item.id === id);
if (!app) { if (!app) {
$A.modalError("应用不存在"); $A.modalError("应用不存在");
return return
} }
this.$refs.app.observeMicroApp(app) await this.$refs.app.observeMicroApp(app)
} }
} }
</script> </script>

View File

@ -155,7 +155,7 @@ export default [
}, },
{ {
name: 'single-apps', name: 'single-apps',
path: '/single/apps/:appName', path: '/single/apps/:appId',
component: () => import('./pages/single/apps.vue') component: () => import('./pages/single/apps.vue')
}, },
{ {

View File

@ -1117,8 +1117,8 @@ export default {
'callAt', 'callAt',
'cacheEmojis', 'cacheEmojis',
'cacheDialogs', 'cacheDialogs',
'microAppsIds',
'microAppsMenus', 'microAppsMenus',
'microAppsNames',
], ],
json: [ json: [
'userInfo' 'userInfo'
@ -4646,7 +4646,7 @@ export default {
* 打开微应用 * 打开微应用
* @param state * @param state
* @param data * @param data
* - name 应用名称 * - id 应用ID
* - url 应用地址 * - url 应用地址
* - props 传递参数 * - props 传递参数
* - transparent 是否透明模式 (true/false)默认 false * - transparent 是否透明模式 (true/false)默认 false
@ -4662,7 +4662,7 @@ export default {
return return
} }
const config = { const config = {
name: data.app_name || data.name, id: data.id,
url: $A.mainUrl(data.url), url: $A.mainUrl(data.url),
props: $A.isJson(data.props) ? data.props : {}, props: $A.isJson(data.props) ? data.props : {},
transparent: typeof data.transparent == 'boolean' ? data.transparent : false, transparent: typeof data.transparent == 'boolean' ? data.transparent : false,
@ -4670,15 +4670,15 @@ export default {
keepAlive: typeof data.keepAlive == 'boolean' ? data.keepAlive : true, keepAlive: typeof data.keepAlive == 'boolean' ? data.keepAlive : true,
disableScopecss: typeof data.disableScopecss == 'boolean' ? data.disableScopecss : false disableScopecss: typeof data.disableScopecss == 'boolean' ? data.disableScopecss : false
} }
if (!config.name) { if (!config.id) {
return return
} }
if (!state.microAppsNames.includes(config.name)) { if (!state.microAppsIds.includes(config.id)) {
$A.modalWarning(`应用「${config.name}」未安装`); $A.modalWarning(`应用「${config.id}」未安装`);
return; return;
} }
if (data.key) { if (data.key) {
config.name += `_${data.key}` config.id += `_${data.key}`
} }
emitter.emit('observeMicroApp:open', config); emitter.emit('observeMicroApp:open', config);
}, },
@ -4695,7 +4695,7 @@ export default {
resolve(false) resolve(false)
return return
} }
resolve(!!state.microAppsNames.includes(appName)) resolve(!!state.microAppsIds.includes(appName))
}) })
}, },
@ -4711,8 +4711,7 @@ export default {
} }
}) })
if (code === 200) { if (code === 200) {
commit("microApps/menus", data.menus || []) commit("microApps/data", data|| [])
commit("microApps/names", data.names || [])
} }
}, },
} }

View File

@ -300,13 +300,28 @@ export default {
}, },
// 微应用管理 // 微应用管理
'microApps/menus': function(state, data) { 'microApps/data': function(state, data) {
state.microAppsMenus = data data.unshift({
$A.IDBSave("microAppsMenus", state.microAppsMenus) id: 'appstore',
}, menu_items: [{
id: 'appstore',
'microApps/names': function(state, data) { location: "application/admin",
state.microAppsNames = [...data, 'appstore'] label: $A.L("应用商店"),
$A.IDBSave("microAppsNames", state.microAppsNames) icon: $A.mainUrl("images/application/appstore.svg"),
url: 'appstore/internal',
disableScopecss: true,
autoDarkTheme: false,
}]
})
const ids = [];
const menus = [];
data.forEach((item) => {
ids.push(item.id);
if (item.menu_items) {
menus.push(...item.menu_items.map(m => Object.assign(m, {id: item.id})));
}
})
$A.IDBSave("microAppsIds", state.microAppsIds = ids);
$A.IDBSave("microAppsMenus", state.microAppsMenus = menus);
}, },
} }

View File

@ -262,6 +262,6 @@ export default {
longpressData: {type: '', data: null, element: null}, longpressData: {type: '', data: null, element: null},
// 微应用数据 // 微应用数据
microAppsIds: [],
microAppsMenus: [], microAppsMenus: [],
microAppsNames: ['appstore'],
}; };