Browse Source

style:完善开始菜单样式

master
秋田弘 6 months ago
parent
commit
d77b75d393
  1. 36
      frontend/components.d.ts
  2. 3635
      frontend/pnpm-lock.yaml
  3. 98
      frontend/public/font/demo_index.html
  4. 22
      frontend/public/font/iconfont.css
  5. 2
      frontend/public/font/iconfont.js
  6. 28
      frontend/public/font/iconfont.json
  7. BIN
      frontend/public/font/iconfont.ttf
  8. BIN
      frontend/public/font/iconfont.woff
  9. BIN
      frontend/public/font/iconfont.woff2
  10. 25
      frontend/src/components/desktop/LockDesktop.vue
  11. 306
      frontend/src/components/taskbar/StartOption.vue
  12. 7
      frontend/src/i18n/lang/en.json
  13. 1
      frontend/src/i18n/lang/zh.json

36
frontend/components.d.ts

@ -63,19 +63,55 @@ declare module 'vue' {
DownModelInfo: typeof import('./src/components/ai/DownModelInfo.vue')['default'] DownModelInfo: typeof import('./src/components/ai/DownModelInfo.vue')['default']
EditFileName: typeof import('./src/components/builtin/EditFileName.vue')['default'] EditFileName: typeof import('./src/components/builtin/EditFileName.vue')['default']
EditType: typeof import('./src/components/builtin/EditType.vue')['default'] EditType: typeof import('./src/components/builtin/EditType.vue')['default']
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBadge: typeof import('element-plus/es')['ElBadge']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard'] ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel'] ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem'] ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElForm: typeof import('element-plus/es')['ElForm'] ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon'] ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput'] ElInput: typeof import('element-plus/es')['ElInput']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress'] ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow'] ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSpace: typeof import('element-plus/es')['ElSpace']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTransfer: typeof import('element-plus/es')['ElTransfer']
ElTree: typeof import('element-plus/es')['ElTree']
Error: typeof import('./src/components/taskbar/Error.vue')['default'] Error: typeof import('./src/components/taskbar/Error.vue')['default']
FileIcon: typeof import('./src/components/builtin/FileIcon.vue')['default'] FileIcon: typeof import('./src/components/builtin/FileIcon.vue')['default']
FileIconImg: typeof import('./src/components/builtin/FileIconImg.vue')['default'] FileIconImg: typeof import('./src/components/builtin/FileIconImg.vue')['default']

3635
frontend/pnpm-lock.yaml

File diff suppressed because it is too large

98
frontend/public/font/demo_index.html

@ -54,6 +54,30 @@
<div class="content unicode" style="display: block;"> <div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe626;</span>
<div class="name">微信</div>
<div class="code-name">&amp;#xe626;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6af;</span>
<div class="name">QQ</div>
<div class="code-name">&amp;#xe6af;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe634;</span>
<div class="name">logout</div>
<div class="code-name">&amp;#xe634;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe676;</span>
<div class="name">恢复</div>
<div class="code-name">&amp;#xe676;</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont">&#x100c2;</span> <span class="icon iconfont">&#x100c2;</span>
<div class="name">workchat</div> <div class="name">workchat</div>
@ -708,9 +732,9 @@
<pre><code class="language-css" <pre><code class="language-css"
>@font-face { >@font-face {
font-family: 'iconfont'; font-family: 'iconfont';
src: url('iconfont.woff2?t=1726139300607') format('woff2'), src: url('iconfont.woff2?t=1733206776617') format('woff2'),
url('iconfont.woff?t=1726139300607') format('woff'), url('iconfont.woff?t=1733206776617') format('woff'),
url('iconfont.ttf?t=1726139300607') format('truetype'); url('iconfont.ttf?t=1733206776617') format('truetype');
} }
</code></pre> </code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -736,6 +760,42 @@
<div class="content font-class"> <div class="content font-class">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-weixin"></span>
<div class="name">
微信
</div>
<div class="code-name">.icon-weixin
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-qq"></span>
<div class="name">
QQ
</div>
<div class="code-name">.icon-qq
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-logout"></span>
<div class="name">
logout
</div>
<div class="code-name">.icon-logout
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-huifu"></span>
<div class="name">
恢复
</div>
<div class="code-name">.icon-huifu
</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont icon-workchat"></span> <span class="icon iconfont icon-workchat"></span>
<div class="name"> <div class="name">
@ -1717,6 +1777,38 @@
<div class="content symbol"> <div class="content symbol">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-weixin"></use>
</svg>
<div class="name">微信</div>
<div class="code-name">#icon-weixin</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-qq"></use>
</svg>
<div class="name">QQ</div>
<div class="code-name">#icon-qq</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-logout"></use>
</svg>
<div class="name">logout</div>
<div class="code-name">#icon-logout</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-huifu"></use>
</svg>
<div class="name">恢复</div>
<div class="code-name">#icon-huifu</div>
</li>
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-workchat"></use> <use xlink:href="#icon-workchat"></use>

22
frontend/public/font/iconfont.css

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4412427 */ font-family: "iconfont"; /* Project id 4412427 */
src: url('iconfont.woff2?t=1726139300607') format('woff2'), src: url('iconfont.woff2?t=1733206776617') format('woff2'),
url('iconfont.woff?t=1726139300607') format('woff'), url('iconfont.woff?t=1733206776617') format('woff'),
url('iconfont.ttf?t=1726139300607') format('truetype'); url('iconfont.ttf?t=1733206776617') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,22 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-weixin:before {
content: "\e626";
}
.icon-qq:before {
content: "\e6af";
}
.icon-logout:before {
content: "\e634";
}
.icon-huifu:before {
content: "\e676";
}
.icon-workchat:before { .icon-workchat:before {
content: "\100c2"; content: "\100c2";
} }

2
frontend/public/font/iconfont.js

File diff suppressed because one or more lines are too long

28
frontend/public/font/iconfont.json

@ -5,6 +5,34 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "77156",
"name": "微信",
"font_class": "weixin",
"unicode": "e626",
"unicode_decimal": 58918
},
{
"icon_id": "386271",
"name": "QQ",
"font_class": "qq",
"unicode": "e6af",
"unicode_decimal": 59055
},
{
"icon_id": "1381411",
"name": "logout",
"font_class": "logout",
"unicode": "e634",
"unicode_decimal": 58932
},
{
"icon_id": "5651486",
"name": "恢复",
"font_class": "huifu",
"unicode": "e676",
"unicode_decimal": 58998
},
{ {
"icon_id": "41842645", "icon_id": "41842645",
"name": "workchat", "name": "workchat",

BIN
frontend/public/font/iconfont.ttf

Binary file not shown.

BIN
frontend/public/font/iconfont.woff

Binary file not shown.

BIN
frontend/public/font/iconfont.woff2

Binary file not shown.

25
frontend/src/components/desktop/LockDesktop.vue

@ -72,6 +72,7 @@
> >
<a <a
href="#" href="#"
v-if="config.userType !== 'member'"
@click.prevent="toggleUserSwitch" @click.prevent="toggleUserSwitch"
>切换角色</a >切换角色</a
> >
@ -164,18 +165,18 @@
const isRegisterMode = ref(false); const isRegisterMode = ref(false);
const thirdPartyPlatforms = [ const thirdPartyPlatforms = [
{ // {
name: "wechat", // name: "wechat",
icon: new URL("@/assets/login/wechat.png", import.meta.url).href, // icon: new URL("@/assets/login/wechat.png", import.meta.url).href,
}, // },
{ // {
name: "qq", // name: "qq",
icon: new URL("@/assets/login/qq.png", import.meta.url).href, // icon: new URL("@/assets/login/qq.png", import.meta.url).href,
}, // },
{ // {
name: "sina", // name: "sina",
icon: new URL("@/assets/login/sina.png", import.meta.url).href, // icon: new URL("@/assets/login/sina.png", import.meta.url).href,
}, // },
{ {
name: "github", name: "github",
icon: new URL("@/assets/login/github.png", import.meta.url).href, icon: new URL("@/assets/login/github.png", import.meta.url).href,

306
frontend/src/components/taskbar/StartOption.vue

@ -1,167 +1,175 @@
<template> <template>
<div class="s-option"> <div class="s-option">
<div class="s-option-inner"> <div class="s-option-inner">
<div class="s-option-button" @click.stop="($ev) => handleClick(0, $ev)" v-glowing> <div
<div class="s-option-button_img"> v-if="sys.getConfig('userType') == 'member'"
<svg class="icon" aria-hidden="true"> class="s-option-button"
<use xlink:href="#icon-setup"></use> @click.stop="handleLogout"
</svg> v-glowing
</div> >
<div class="s-option-button_title"> <div class="s-option-button_img">
{{ t("startMenu.power") }} <svg
</div> class="icon"
</div> aria-hidden="true"
<div class="s-option-button" @click.stop="($ev) => handleClick(1, $ev)" v-glowing> >
<div class="s-option-button_img"> <use xlink:href="#icon-logout"></use>
<svg class="icon" aria-hidden="true"> </svg>
<use xlink:href="#icon-setting"></use> </div>
</svg> <div class="s-option-button_title">
</div> {{ t("startMenu.logout") }}
<div class="s-option-button_title"> </div>
{{ t("setting") }} </div>
</div> <div
</div> class="s-option-button"
</div> @click.stop="handleRecover"
</div> v-glowing
>
<div class="s-option-button_img">
<svg
class="icon"
aria-hidden="true"
>
<use xlink:href="#icon-huifu"></use>
</svg>
</div>
<div class="s-option-button_title">
{{ t("startMenu.recover") }}
</div>
</div>
<div
class="s-option-button"
@click.stop="($ev) => handleClick(1, $ev)"
v-glowing
>
<div class="s-option-button_img">
<svg
class="icon"
aria-hidden="true"
>
<use xlink:href="#icon-setting"></use>
</svg>
</div>
<div class="s-option-button_title">
{{ t("setting") }}
</div>
</div>
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { emitEvent } from "@/system/event"; import { BrowserWindow, Dialog, t, useSystem } from "@/system";
import { useSystem, Dialog, t, Menu, BrowserWindow } from "@/system"; import { fetchGet } from "@/system/config";
import { vGlowing } from "@/util/glowingBorder"; import { emitEvent } from "@/system/event";
import { fetchGet } from "@/system/config"; import { vGlowing } from "@/util/glowingBorder";
import { RestartApp } from "@/util/goutil"; import { RestartApp } from "@/util/goutil";
const sys = useSystem();
const sys = useSystem(); function handleLogout() {
function handleClick(key: number, ev: MouseEvent) { const userInfo: any = sys.getConfig("userInfo");
switch (key) { fetchGet(userInfo.url + "/member/loginout").then(() => {
case 0: RestartApp();
const actions = [ });
{ }
label: t("startMenu.shutdown"),
click: () => {
emitEvent("system.shutdown");
},
},
{
label: t("startMenu.recover"),
click: () => {
Dialog.showMessageBox({
title: t("startMenu.recover"),
message: t("is.recover"),
buttons: [t("startMenu.recover"), t("cancel")],
}).then((res) => {
//console.log(res)
if (res.response === -1) {
emitEvent("system.recover");
}
});
},
},
]
if(sys.getConfig('userType') == 'member'){
actions.push({
label: '退出',
click: () => {
const userInfo:any = sys.getConfig('userInfo')
fetchGet(userInfo.url + "/member/loginout").then(() => {
RestartApp()
})
},
})
}
Menu.buildFromTemplate(actions).popup(ev);
break; function handleRecover() {
case 1: { Dialog.showMessageBox({
emitEvent("startMenu.set.click", { title: t("startMenu.recover"),
mouse: ev, message: t("is.recover"),
}); buttons: [t("startMenu.recover"), t("cancel")],
//console.log(sys._rootState.windowMap) }).then((res) => {
const winopt = sys._rootState.windowMap["Menulist"].get("setting"); if (res.response === -1) {
emitEvent("system.recover");
}
});
}
if (winopt) { function handleClick(key: number, ev: MouseEvent) {
if (winopt._hasShow) { if (key === 1) {
return; emitEvent("startMenu.set.click", {
} else { mouse: ev,
winopt._hasShow = true; });
const win = new BrowserWindow(winopt.window); const winopt = sys._rootState.windowMap["Menulist"].get("setting");
win.show();
win.on("close", () => {
winopt._hasShow = false;
});
}
}
break;
}
default: if (winopt) {
break; if (winopt._hasShow) {
} return;
} } else {
winopt._hasShow = true;
const win = new BrowserWindow(winopt.window);
win.show();
win.on("close", () => {
winopt._hasShow = false;
});
}
}
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.s-option { .s-option {
position: relative; position: relative;
width: var(--startmenu-icon-size); width: var(--startmenu-icon-size);
height: 100%; height: 100%;
z-index: 40; z-index: 40;
user-select: none; user-select: none;
.s-option-inner { .s-option-inner {
position: absolute; position: absolute;
height: 100%; height: 100%;
width: var(--startmenu-icon-size); width: var(--startmenu-icon-size);
background-color: #f5f5f5; background-color: #f5f5f5;
// background-color: var(--theme-main-color-opacity); // background-color: var(--theme-main-color-opacity);
transition: width 0.1s ease-in-out, box-shadow 0.1s ease-in-out; transition: width 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
transition-delay: 0s; transition-delay: 0s;
display: flex; display: flex;
flex-direction: column-reverse; flex-direction: column-reverse;
overflow: hidden; overflow: hidden;
.s-option-button { .s-option-button {
height: var(--start-option-size); height: var(--start-option-size);
width: var(--startmenu-icon-size-hover); width: var(--startmenu-icon-size-hover);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: relative; position: relative;
z-index: 1; z-index: 1;
.s-option-button_img { .s-option-button_img {
height: var(--start-option-size); height: var(--start-option-size);
width: var(--start-option-size); width: var(--start-option-size);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
svg { svg {
width: 40%; width: 40%;
} }
} }
.s-option-button_title { .s-option-button_title {
width: 100%; width: 100%;
height: var(--start-option-size); height: var(--start-option-size);
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
opacity: 0.8; opacity: 0.8;
} }
} }
.s-option-button:hover { .s-option-button:hover {
// background-color: var(--color-gray-hover); // background-color: var(--color-gray-hover);
} }
} }
} }
.s-option:hover { .s-option:hover {
.s-option-inner { .s-option-inner {
transition-delay: 0.5s; transition-delay: 0.5s;
width: var(--startmenu-icon-size-hover); width: var(--startmenu-icon-size-hover);
box-shadow: 10px 0px 20px 0px rgba(0, 0, 0, 0.216); box-shadow: 10px 0px 20px 0px rgba(0, 0, 0, 0.216);
} }
} }
</style> </style>

7
frontend/src/i18n/lang/en.json

@ -2,6 +2,7 @@
"hello": "hello", "hello": "hello",
"startMenu.power": "Power", "startMenu.power": "Power",
"setting": "Setting", "setting": "Setting",
"startMenu.logout": "Logout",
"progressmanger": "Progress", "progressmanger": "Progress",
"startMenu.shutdown": "Shutdown", "startMenu.shutdown": "Shutdown",
"startMenu.recover": "Recover", "startMenu.recover": "Recover",
@ -104,7 +105,7 @@
"whiteBoard": "WhiteBoard", "whiteBoard": "WhiteBoard",
"piceditor": "PhotoEditor", "piceditor": "PhotoEditor",
"gantt": "Gantt", "gantt": "Gantt",
"aiHelper":"AIHelper", "aiHelper": "AIHelper",
"browser": "Browser", "browser": "Browser",
"aiModule": "AI Module", "aiModule": "AI Module",
"aiSetting": "AI Setting", "aiSetting": "AI Setting",
@ -156,7 +157,7 @@
"installSuccess": "Installation successful!", "installSuccess": "Installation successful!",
"uninstallSuccess": "Uninstalling successful", "uninstallSuccess": "Uninstalling successful",
"downloadError": "Download failed!", "downloadError": "Download failed!",
"downloadSuccess":"Download successful!", "downloadSuccess": "Download successful!",
"cantStream": "Streaming download is currently not supported!", "cantStream": "Streaming download is currently not supported!",
"setting": "Setting", "setting": "Setting",
"stop": "Stop", "stop": "Stop",
@ -256,7 +257,7 @@
"video": "Video", "video": "Video",
"embed": "Embeding", "embed": "Embeding",
"embeddings": "Embeddings", "embeddings": "Embeddings",
"reranker":"Reranker", "reranker": "Reranker",
"tts": "Txt2Audio", "tts": "Txt2Audio",
"audio": "Audio2Txt", "audio": "Audio2Txt",
"assistant": "Assistant", "assistant": "Assistant",

1
frontend/src/i18n/lang/zh.json

@ -1,6 +1,7 @@
{ {
"hello": "你好", "hello": "你好",
"startMenu.power": "电源", "startMenu.power": "电源",
"startMenu.logout": "退出",
"startMenu.shutdown": "关机", "startMenu.shutdown": "关机",
"startMenu.recover": "恢复", "startMenu.recover": "恢复",
"windows.setting": "系统设置", "windows.setting": "系统设置",

Loading…
Cancel
Save