Browse Source

change login form

master
godo 1 month ago
parent
commit
ae8fc76763
  1. 4
      os/components.d.ts
  2. 1
      os/keys/updates.key
  3. 1
      os/keys/updates.key.pub
  4. 19
      os/package.json
  5. 1024
      os/src-tauri/Cargo.lock
  6. 10
      os/src-tauri/Cargo.toml
  7. 2
      os/src-tauri/capabilities/default.json
  8. 14
      os/src-tauri/capabilities/desktop.json
  9. 10
      os/src-tauri/capabilities/mobile.json
  10. 16
      os/src-tauri/src/lib.rs
  11. 11
      os/src-tauri/tauri.conf.json
  12. 124
      os/src/components/auth/AuthLogin.vue
  13. 22
      os/src/components/auth/PasswordLogin.vue
  14. 91
      os/src/components/auth/SetUp.vue
  15. 76
      os/src/components/auth/UserRegister.vue
  16. 1
      os/src/components/loading/WinScreen.vue
  17. 1
      os/src/main.ts
  18. 16
      os/src/stores/login.ts
  19. 40
      os/src/stores/settings.ts
  20. 53
      os/src/stores/settingsConfig.ts
  21. 12
      os/src/styles/login.scss
  22. 2
      os/tsconfig.json
  23. 1
      os/types.d.ts
  24. 147
      os/uno.config.ts
  25. 2
      os/vite.config.ts

4
os/components.d.ts

@ -38,6 +38,7 @@ declare module 'vue' {
ElAside: typeof import('element-plus/es')['ElAside'] ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard'] ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol'] ElCol: typeof import('element-plus/es')['ElCol']
@ -66,6 +67,8 @@ declare module 'vue' {
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover'] ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress'] ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow'] ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect'] ElSelect: typeof import('element-plus/es')['ElSelect']
@ -102,6 +105,7 @@ declare module 'vue' {
SaveFile: typeof import('./src/components/files/SaveFile.vue')['default'] SaveFile: typeof import('./src/components/files/SaveFile.vue')['default']
ScreenRecorder: typeof import('./src/components/taskbar/ScreenRecorder.vue')['default'] ScreenRecorder: typeof import('./src/components/taskbar/ScreenRecorder.vue')['default']
Screenshort: typeof import('./src/components/taskbar/Screenshort.vue')['default'] Screenshort: typeof import('./src/components/taskbar/Screenshort.vue')['default']
SetUp: typeof import('./src/components/auth/SetUp.vue')['default']
ShareFiles: typeof import('./src/components/files/ShareFiles.vue')['default'] ShareFiles: typeof import('./src/components/files/ShareFiles.vue')['default']
SlideBackground: typeof import('./src/components/loading/SlideBackground.vue')['default'] SlideBackground: typeof import('./src/components/loading/SlideBackground.vue')['default']
StartMenu: typeof import('./src/components/taskbar/StartMenu.vue')['default'] StartMenu: typeof import('./src/components/taskbar/StartMenu.vue')['default']

1
os/keys/updates.key

@ -0,0 +1 @@
dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5VHZia2krc3dDK0U1REJiUmFydk5vQTNqWENYVEFrOWhrUE5OSmJkdXpaOEFBQkFBQUFBQUFBQUFBQUlBQUFBQXRmalV2Z3d5bGovak5hLzBnNmRjTCtlelNVeVpDeDdXYkxIbDE3bktKLytadk1WRHhrRWtnV1QxcFMvYmNaQjU2eGl5akF0bWczZUdxT1ZPaGxvNTFwTjNxUDR2NmlJNHJEeXRFaXdFbSt1K0xuUWlJcFNtTmRyNXY0ZUNsWkkxbDA1UU5aS2c2MTg9Cg==

1
os/keys/updates.key.pub

@ -0,0 +1 @@
dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDlGRjlBMjk0MTZCMEZDMEMKUldRTS9MQVdsS0w1bi9FSDk4aXF2T3pDa0s3cE9JTjY1eHgrWHh3bTJpRDQ5Nm9zZDROUFJmVkcK

19
os/package.json

@ -5,14 +5,30 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"dev:desktop": "tauri dev",
"dev:android": "tauri android dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview",
"build:tauri": "tauri build",
"build:android": "tauri android build --apk",
"android-init": "pnpm tauri plugin android init",
"build:ios": "tauri ios build --ipa",
"ios-init": "pnpm tauri plugin ios init"
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.1.0", "@element-plus/icons-vue": "^2.1.0",
"@tauri-apps/plugin-autostart": "~2", "@tauri-apps/plugin-autostart": "~2",
"@tauri-apps/plugin-dialog": "~2.2.1", "@tauri-apps/plugin-dialog": "~2.2.1",
"@tauri-apps/plugin-fs": "~2.2.1", "@tauri-apps/plugin-fs": "~2.2.1",
"@tauri-apps/plugin-notification": "~2.2.2",
"@tauri-apps/plugin-opener": "~2.2.6",
"@tauri-apps/plugin-os": "~2.2.1",
"@tauri-apps/plugin-process": "~2.2.1",
"@tauri-apps/plugin-store": "~2.2.0",
"@tauri-apps/plugin-updater": "~2.7.1",
"@tauri-apps/plugin-upload": "~2.2.1",
"@tauri-apps/plugin-websocket": "~2.3.0",
"@tauri-apps/plugin-window-state": "~2.2.2",
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
"axios": "^1.7.9", "axios": "^1.7.9",
"chart.js": "^4.4.7", "chart.js": "^4.4.7",
@ -48,6 +64,7 @@
"less": "^4.2.2", "less": "^4.2.2",
"sass": "^1.83.4", "sass": "^1.83.4",
"typescript": "^5.0.2", "typescript": "^5.0.2",
"unocss": "66.1.0-beta.13",
"unplugin-auto-import": "^19.0.0", "unplugin-auto-import": "^19.0.0",
"unplugin-vue-components": "^28.0.0", "unplugin-vue-components": "^28.0.0",
"vite": "^4.4.5", "vite": "^4.4.5",

1024
os/src-tauri/Cargo.lock

File diff suppressed because it is too large

10
os/src-tauri/Cargo.toml

@ -25,6 +25,16 @@ tauri = { version = "2.5.0", features = [] }
tauri-plugin-log = "2.0.0-rc" tauri-plugin-log = "2.0.0-rc"
tauri-plugin-fs = "2" tauri-plugin-fs = "2"
tauri-plugin-dialog = "2" tauri-plugin-dialog = "2"
tauri-plugin-store = "2"
tauri-plugin-os = "2"
tauri-plugin-notification = "2"
tauri-plugin-upload = "2"
tauri-plugin-process = "2"
tauri-plugin-opener = "2"
tauri-plugin-websocket = "2"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-autostart = "2" tauri-plugin-autostart = "2"
tauri-plugin-single-instance = "2"
tauri-plugin-updater = "2"
tauri-plugin-window-state = "2"

2
os/src-tauri/capabilities/default.json

@ -7,6 +7,6 @@
], ],
"permissions": [ "permissions": [
"core:default", "core:default",
"fs:default" "updater:default"
] ]
} }

14
os/src-tauri/capabilities/desktop.json

@ -10,6 +10,18 @@
], ],
"permissions": [ "permissions": [
"autostart:default", "autostart:default",
"autostart:default" "autostart:default",
"store:allow-get",
"store:allow-set",
"store:allow-save",
"store:allow-load",
"fs:default",
"os:default",
"notification:default",
"upload:default",
"updater:default",
"process:default",
"opener:default",
"websocket:default"
] ]
} }

10
os/src-tauri/capabilities/mobile.json

@ -0,0 +1,10 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "mobile-capability",
"description": "Capability for the main window",
"platforms": ["iOS", "android"],
"windows": ["*"],
"permissions": [
"core:default"
]
}

16
os/src-tauri/src/lib.rs

@ -1,8 +1,22 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)] #[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() { pub fn run() {
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|_app, _, _| {
}))
.plugin(tauri_plugin_window_state::Builder::new().build())
.plugin(tauri_plugin_websocket::init())
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_store::Builder::new().build())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_autostart::init()) .plugin(tauri_plugin_autostart::init(
tauri_plugin_autostart::MacosLauncher::LaunchAgent,
Some(vec!["--flag1", "--flag2"]),
))
.plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_fs::init())
.setup(|app| { .setup(|app| {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {

11
os/src-tauri/tauri.conf.json

@ -16,7 +16,7 @@
"width": 1024, "width": 1024,
"height": 768, "height": 768,
"resizable": true, "resizable": true,
"fullscreen": true "fullscreen": false
} }
], ],
"security": { "security": {
@ -33,5 +33,14 @@
"icons/icon.icns", "icons/icon.icns",
"icons/icon.ico" "icons/icon.ico"
] ]
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5VHZia2krc3dDK0U1REJiUmFydk5vQTNqWENYVEFrOWhrUE5OSmJkdXpaOEFBQkFBQUFBQUFBQUFBQUlBQUFBQXRmalV2Z3d5bGovak5hLzBnNmRjTCtlelNVeVpDeDdXYkxIbDE3bktKLytadk1WRHhrRWtnV1QxcFMvYmNaQjU2eGl5akF0bWczZUdxT1ZPaGxvNTFwTjNxUDR2NmlJNHJEeXRFaXdFbSt1K0xuUWlJcFNtTmRyNXY0ZUNsWkkxbDA1UU5aS2c2MTg9Cg==",
"endpoints": [
"https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}}",
"https://github.com/user/repo/releases/latest/download/latest.json"
]
}
} }
} }

124
os/src/components/auth/AuthLogin.vue

@ -1,122 +1,82 @@
<script setup lang="ts"> <script setup lang="ts">
import { useLoginStore } from "@/stores/login"; import { useLoginStore } from "@/stores/login";
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { List, MapLocation } from "@element-plus/icons-vue";
import LdapLogin from "./LdapLogin.vue";
const store = useLoginStore();
import LdapLogin from "./LdapLogin.vue"; onMounted(() => {
const store = useLoginStore();
onMounted(() => {
store.initThirdPartyLogin(); store.initThirdPartyLogin();
}); });
// //
const isLock = ref(false); const isLock = ref(false);
</script> </script>
<template> <template>
<div class="login-container"> <div class="login-container">
<SlideBackground /> <SlideBackground />
<div class="lockscreen"> <div class="lockscreen">
<el-card
v-if="!isLock" <el-card v-if="!isLock" class="login-box" shadow="never">
class="login-box" <!-- <div class="absolute top-2 right-2 group flex items-center gap-2">
shadow="never" <el-button type="primary" :icon="MapLocation" circle />
> </div> -->
<!-- 顶部欢迎词和 logo --> <!-- 顶部欢迎词和 logo -->
<div <div class="header">
class="header" <el-avatar size="large" class="logo">
v-if="store.thirdPartyLoginMethod != 'register'" <img src="/logo.png" alt="Logo" />
>
<el-avatar
size="large"
class="logo"
>
<img
src="/logo.png"
alt="Logo"
/>
</el-avatar> </el-avatar>
<h3>欢迎使用 GodoOS 系统</h3> <h3>欢迎使用 GodoOS</h3>
</div> </div>
<!-- 登录注册 --> <!-- 登录注册 -->
<div <div class="login-register" v-if="
class="login-register"
v-if="
store.thirdPartyLoginMethod !== 'dingding' && store.thirdPartyLoginMethod !== 'dingding' &&
store.thirdPartyLoginMethod !== 'qyweixin' store.thirdPartyLoginMethod !== 'qyweixin'
" ">
>
<!-- 滑块 --> <!-- 滑块 -->
<div class="slider"> <div class="slider">
<span <span @click="store.thirdPartyLoginMethod = 'password'" :class="{
@click="store.thirdPartyLoginMethod = 'password'"
:class="{
active: active:
store.thirdPartyLoginMethod !== 'register', store.thirdPartyLoginMethod !== 'register' && store.thirdPartyLoginMethod !== 'setup'
}" }">登录</span>
>登录</span <span @click="store.thirdPartyLoginMethod = 'register'" :class="{
>
<span
@click="store.thirdPartyLoginMethod = 'register'"
:class="{
active: active:
store.thirdPartyLoginMethod === 'register', store.thirdPartyLoginMethod === 'register',
}" }">注册</span>
>注册</span <span @click="store.thirdPartyLoginMethod = 'setup'" :class="{
> active:
store.thirdPartyLoginMethod === 'setup',
}">设置</span>
</div> </div>
</div> </div>
<!-- 登录功能 --> <!-- 登录功能 -->
<PasswordLogin <PasswordLogin v-if="store.thirdPartyLoginMethod === 'password'" />
v-if="store.thirdPartyLoginMethod === 'password'" <SetUp v-if="store.thirdPartyLoginMethod === 'setup'" />
/>
<PhoneLogin v-if="store.thirdPartyLoginMethod === 'phone'" /> <PhoneLogin v-if="store.thirdPartyLoginMethod === 'phone'" />
<EmailLogin v-if="store.thirdPartyLoginMethod === 'email'" /> <EmailLogin v-if="store.thirdPartyLoginMethod === 'email'" />
<LdapLogin v-if="store.thirdPartyLoginMethod === 'ldap'" /> <LdapLogin v-if="store.thirdPartyLoginMethod === 'ldap'" />
<div <div class="qr-code dingding" v-if="store.thirdPartyLoginMethod === 'dingding'">
class="qr-code dingding" <div class="qr-code-container" id="dd-qr-code"></div>
v-if="store.thirdPartyLoginMethod === 'dingding'"
>
<div
class="qr-code-container"
id="dd-qr-code"
></div>
</div> </div>
<div <div class="qr-code-qyweixin" v-if="store.thirdPartyLoginMethod === 'qyweixin'">
class="qr-code-qyweixin"
v-if="store.thirdPartyLoginMethod === 'qyweixin'"
>
<div id="qywechat-qr-code"></div> <div id="qywechat-qr-code"></div>
</div> </div>
<UserRegister <UserRegister class="register-form" v-if="store.thirdPartyLoginMethod === 'register'" />
class="register-form"
v-if="store.thirdPartyLoginMethod === 'register'"
/>
<template <template v-else-if="store.thirdPartyLoginMethod !== 'register'">
v-else-if="store.thirdPartyLoginMethod !== 'register'" <div class="divider" v-if="store.thirdpartyList.length > 0">
>
<div class="divider">
<span>第三方登录</span> <span>第三方登录</span>
</div> </div>
<div class="third-party-login"> <div class="third-party-login">
<el-button <el-button v-for="platform in store.thirdpartyList" :key="platform.name"
v-for="platform in store.thirdpartyList" class="third-party-login-button" @click="store.onThirdPartyLogin(platform.name)" :style="{
:key="platform.name"
class="third-party-login-button"
@click="store.onThirdPartyLogin(platform.name)"
:style="{
backgroundColor: backgroundColor:
store.thirdPartyLoginMethod === store.thirdPartyLoginMethod ===
platform.name platform.name
? '#f2ecec' ? '#f2ecec'
: 'transparent', : 'transparent',
}" }">
> <img class="third-party-login-icon" :src="platform.icon" />
<img
class="third-party-login-icon"
:src="platform.icon"
/>
</el-button> </el-button>
</div> </div>
</template> </template>
@ -126,5 +86,5 @@
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@use "@/styles/login.scss"; @use "@/styles/login.scss";
</style> </style>

22
os/src/components/auth/PasswordLogin.vue

@ -4,12 +4,6 @@
import { reactive, ref } from "vue"; import { reactive, ref } from "vue";
const store = useLoginStore(); const store = useLoginStore();
const loginForm = ref({
username: "",
password: "",
});
const rules = reactive({ const rules = reactive({
username: [ username: [
{ required: true, message: "请输入用户名", trigger: "blur" }, { required: true, message: "请输入用户名", trigger: "blur" },
@ -38,7 +32,7 @@
if (valid) { if (valid) {
store.onLogin({ store.onLogin({
loginType: "password", loginType: "password",
params: loginForm.value, params: store.loginForm,
}); });
} else { } else {
ElMessage.error("请检查输入内容"); ElMessage.error("请检查输入内容");
@ -52,14 +46,14 @@
<el-form <el-form
ref="formRef" ref="formRef"
label-position="left" label-position="left"
:model="loginForm" :model="store.loginForm"
:rules="rules" :rules="rules"
label-width="0px" label-width="0px"
> >
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input
style="border-radius: 50px; height: 45px" style="border-radius: 50px; height: 45px"
v-model="loginForm.username" v-model="store.loginForm.username"
size="large" size="large"
placeholder="请输入用户名" placeholder="请输入用户名"
autofocus autofocus
@ -69,7 +63,7 @@
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input
style="border-radius: 50px; height: 45px" style="border-radius: 50px; height: 45px"
v-model="loginForm.password" v-model="store.loginForm.password"
size="large" size="large"
type="password" type="password"
placeholder="请输入登录密码" placeholder="请输入登录密码"
@ -77,6 +71,9 @@
prefix-icon="Key" prefix-icon="Key"
@keyup.enter="submitForm" @keyup.enter="submitForm"
></el-input> ></el-input>
</el-form-item>
<el-form-item class="remember-me">
<el-checkbox v-model:checked="store.loginForm.rememberMe" size="large">记住密码</el-checkbox>
</el-form-item> </el-form-item>
<el-form-item class="button-center"> <el-form-item class="button-center">
<el-button <el-button
@ -99,6 +96,11 @@
border-radius: 50px; border-radius: 50px;
} }
} }
.remember-me {
display: flex;
justify-content: flex-start;
margin-left: 5px;
}
:deep(.el-input__wrapper) { :deep(.el-input__wrapper) {
border-radius: 50px; border-radius: 50px;

91
os/src/components/auth/SetUp.vue

@ -0,0 +1,91 @@
<script lang="ts" setup>
import { reactive, ref } from "vue";
const setForm = ref({
userRole: "person",
storeType: "local",
netUrl: "",
});
const rules = reactive({
username: [
{ required: true, message: "请输入用户名", trigger: "blur" },
{
min: 3,
max: 20,
message: "长度在 3 到 20 个字符",
trigger: "blur",
},
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{
min: 6,
max: 20,
message: "长度在 6 到 20 个字符",
trigger: "blur",
},
],
});
const setSave = () => {
};
</script>
<template>
<el-form :model="setForm" :rules="rules" ref="emailLoginFormRef" label-position="left" label-width="0px">
<el-form-item label-position="right">
<el-button-group>
<el-button :type="setForm.userRole == 'person' ? 'primary' : ''" @click="setForm.userRole = 'person'" icon="ArrowLeft" round>个人用户</el-button>
<el-button :type="setForm.userRole == 'member' ? 'primary' : ''" @click="setForm.userRole = 'member'" icon="ArrowRight" round>企业用户</el-button>
</el-button-group>
</el-form-item>
<el-form-item label-position="right" v-if="setForm.userRole === 'person'">
<el-button-group>
<el-button :type="setForm.storeType == 'local' ? 'primary' : ''" @click="setForm.storeType = 'local'" icon="ArrowLeft" round>本地服务</el-button>
<el-button :type="setForm.storeType == 'net' ? 'primary' : ''" @click="setForm.storeType = 'net'" icon="ArrowRight" round>远程服务</el-button>
</el-button-group>
</el-form-item>
<!-- <el-form-item label-position="right">
<el-radio-group v-model="setForm.userRole" aria-label="label position">
<el-radio-button value="person" round>个人用户</el-radio-button>
<el-radio-button value="member">企业用户</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label-position="right" v-if="setForm.userRole === 'person'">
<el-radio-group v-model="setForm.storeType" aria-label="label position">
<el-radio-button value="local">本地存储</el-radio-button>
<el-radio-button value="brower">浏览器存储</el-radio-button>
<el-radio-button value="net">远程存储</el-radio-button>
</el-radio-group>
</el-form-item> -->
<el-form-item prop="neturl" v-if="setForm.storeType === 'net' || setForm.userRole === 'member'">
<el-input v-model="setForm.netUrl" size="large" placeholder="请输入远程地址" autofocus
prefix-icon="Link"></el-input>
</el-form-item>
<el-form-item class="button-center">
<el-button class="login-button" type="primary" size="large" @click="setSave">保存</el-button>
</el-form-item>
</el-form>
</template>
<style scoped>
.button-center {
width: 100%;
.login-button {
width: 100%;
border-radius: 50px;
}
}
:deep(.el-button-group){
margin: auto;
}
:deep(.el-button){
height: 45px;
}
:deep(.el-radio-group) {
margin-left: 30px;
}
:deep(.el-input__wrapper) {
border-radius: 50px;
height: 45px;
}
</style>

76
os/src/components/auth/UserRegister.vue

@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useLoginStore } from "@/stores/login"; import { useLoginStore } from "@/stores/login";
import { ref, Ref } from "vue"; import { ref, Ref } from "vue";
const store = useLoginStore(); const store = useLoginStore();
interface RegisterInfo { interface RegisterInfo {
username: string; username: string;
nickname: string; nickname: string;
password: string; password: string;
@ -12,9 +12,9 @@
union_id: string; union_id: string;
platform: string; platform: string;
confirmPassword: string; confirmPassword: string;
} }
// //
const registerInfo: Ref<RegisterInfo> = ref({ const registerInfo: Ref<RegisterInfo> = ref({
username: "", username: "",
nickname: "", nickname: "",
password: "", password: "",
@ -24,8 +24,8 @@
union_id: "", union_id: "",
platform: "", platform: "",
confirmPassword: "", confirmPassword: "",
}); });
const rules = { const rules = {
username: [ username: [
{ required: true, message: "用户名不能为空", trigger: "blur" }, { required: true, message: "用户名不能为空", trigger: "blur" },
{ {
@ -85,23 +85,13 @@
trigger: "blur", trigger: "blur",
}, },
], ],
}; };
</script> </script>
<template> <template>
<el-form <el-form label-position="left" label-width="0px" :model="registerInfo" ref="regFormRef" :rules="rules">
label-position="left"
label-width="0px"
:model="registerInfo"
ref="regFormRef"
:rules="rules"
>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input v-model="registerInfo.username" size="large" placeholder="请输入用户名"
v-model="registerInfo.username" prefix-icon="UserFilled"></el-input>
size="large"
placeholder="请输入用户名"
prefix-icon="UserFilled"
></el-input>
</el-form-item> </el-form-item>
<!-- <el-form-item prop="nickname"> <!-- <el-form-item prop="nickname">
<el-input <el-input
@ -128,48 +118,34 @@
></el-input> ></el-input>
</el-form-item> --> </el-form-item> -->
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input v-model="registerInfo.password" size="large" type="password" placeholder="请输入密码" show-password
v-model="registerInfo.password" prefix-icon="Key"></el-input>
size="large"
type="password"
placeholder="请输入密码"
show-password
prefix-icon="Key"
></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="confirmPassword"> <el-form-item prop="confirmPassword">
<el-input <el-input v-model="registerInfo.confirmPassword" size="large" type="password" placeholder="请再次输入密码"
v-model="registerInfo.confirmPassword" show-password prefix-icon="Lock"></el-input>
size="large"
type="password"
placeholder="请再次输入密码"
show-password
prefix-icon="Lock"
></el-input>
</el-form-item> </el-form-item>
<el-form-item class="button-center"> <el-form-item class="button-center">
<el-button <el-button class="login-button" type="primary" size="large" @click="store.onRegister">注册</el-button>
class="login-button"
type="primary"
size="large"
@click="store.onRegister"
>注册</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<style scoped> <style scoped>
.button-center { .button-center {
width: 100%; width: 100%;
.login-button { .login-button {
width: 100%; width: 100%;
height: 45px; height: 45px;
border-radius: 50px; border-radius: 50px;
} }
} }
:deep(.el-input__wrapper) {
:deep(.el-input__wrapper) {
border-radius: 50px; border-radius: 50px;
height: 45px; height: 45px;
} }
</style> </style>

1
os/src/components/loading/WinScreen.vue

@ -55,6 +55,7 @@ onMounted(async () => {
}, 1000); }, 1000);
}); });
const initSystem = async () => { const initSystem = async () => {
settingsStore.osInit();
messageStore.initMessage(); messageStore.initMessage();
await assistantStore.initPrompt(); await assistantStore.initPrompt();
await modelStore.initModel(); await modelStore.initModel();

1
os/src/main.ts

@ -1,6 +1,7 @@
import * as ElementPlusIconsVue from '@element-plus/icons-vue' import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
import 'virtual:uno.css'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

16
os/src/stores/login.ts

@ -19,7 +19,11 @@ export const useLoginStore = defineStore('login', () => {
// 第三方列表 // 第三方列表
const thirdpartyList: Ref<any[]> = ref([]) const thirdpartyList: Ref<any[]> = ref([])
const desktopStore = useDesktopStore() const desktopStore = useDesktopStore()
const loginForm = ref({
username: "",
password: "",
rememberMe: false
});
// 用户信息 // 用户信息
const userInfo: Ref<any> = ref({}) const userInfo: Ref<any> = ref({})
@ -44,7 +48,12 @@ export const useLoginStore = defineStore('login', () => {
param: params.params, param: params.params,
} }
loginIn(postData).then((res: any) => { loginIn(postData).then((res: any) => {
console.log(res) //console.log(res)
if(!params.params.rememberMe) {
loginForm.value.rememberMe = false
loginForm.value.username = ''
loginForm.value.password = ''
}
if (res.success) { if (res.success) {
successMsg('登录成功') successMsg('登录成功')
userInfo.value = res.data.user userInfo.value = res.data.user
@ -246,6 +255,7 @@ export const useLoginStore = defineStore('login', () => {
return { return {
userInfo, userInfo,
loginForm,
isLoginState, isLoginState,
isLogining, isLogining,
thirdPartyPlatform, thirdPartyPlatform,
@ -264,6 +274,6 @@ export const useLoginStore = defineStore('login', () => {
}, { }, {
persist: { persist: {
key: 'loginStore', key: 'loginStore',
pick: ['userInfo', 'isLoginState'], pick: ['userInfo', 'isLoginState','loginForm'],
}, },
}) })

40
os/src/stores/settings.ts

@ -1,12 +1,14 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { ref } from "vue"; import { ref } from "vue";
import { systemSettingList,settingsConfig } from "@/stores/settingsConfig"; import { systemSettingList, settingsConfig } from "@/stores/settingsConfig";
import { md5 } from "js-md5"; import { md5 } from "js-md5";
import { type as osType, platform } from "@tauri-apps/plugin-os";
export const useSettingsStore = defineStore('settings', () => { export const useSettingsStore = defineStore('settings', () => {
const settingList = ref(systemSettingList); const settingList = ref(systemSettingList);
const config:any = ref(settingsConfig); const config: any = ref(settingsConfig);
const isLockScreen = ref(false); const isLockScreen = ref(false);
const systemInfo: any = ref({});
const updateConfig = (newConfig: any) => { const updateConfig = (newConfig: any) => {
config.value = newConfig; config.value = newConfig;
} }
@ -21,19 +23,19 @@ export const useSettingsStore = defineStore('settings', () => {
} }
const setLockTime = () => { const setLockTime = () => {
if(config.value.lock.timeout > 0 && !isLockScreen.value){ if (config.value.lock.timeout > 0 && !isLockScreen.value) {
config.value.lock.activeTime = new Date().getTime() + config.value.lock.timeout*1000; config.value.lock.activeTime = new Date().getTime() + config.value.lock.timeout * 1000;
} }
} }
const checkLockPassword = (password: string) => { const checkLockPassword = (password: string) => {
return config.value.lock.password === md5(password); return config.value.lock.password === md5(password);
} }
const unLockScreen = () => { const unLockScreen = () => {
config.value.lock.activeTime = new Date().getTime() + config.value.lock.timeout*1000; config.value.lock.activeTime = new Date().getTime() + config.value.lock.timeout * 1000;
isLockScreen.value = false; isLockScreen.value = false;
} }
const checkIsLock = () => { const checkIsLock = () => {
if(config.value.lock.timeout > 0){ if (config.value.lock.timeout > 0) {
const now = new Date().getTime(); const now = new Date().getTime();
isLockScreen.value = now > config.value.lock.activeTime; isLockScreen.value = now > config.value.lock.activeTime;
//console.log(isLockScreen.value) //console.log(isLockScreen.value)
@ -42,6 +44,24 @@ export const useSettingsStore = defineStore('settings', () => {
isLockScreen.value = false; isLockScreen.value = false;
return false; return false;
} }
const osInit = () => {
try {
systemInfo.value.platform = platform();
}
catch (error) {
systemInfo.value.platform = "web";
}
try {
systemInfo.value.ostype = osType();
}
catch (error) {
// console.warn(error);
systemInfo.value.ostype = "web";
}
systemInfo.value.isMobile = ["android", "ios"].includes(systemInfo.value.ostype);
systemInfo.value.isWeb = systemInfo.value.platform === "web";
systemInfo.value.isDesktop = !systemInfo.value.isMobile && !systemInfo.value.isWeb;
}
return { return {
settingList, settingList,
config, config,
@ -53,11 +73,13 @@ export const useSettingsStore = defineStore('settings', () => {
setLockTime, setLockTime,
checkIsLock, checkIsLock,
unLockScreen, unLockScreen,
checkLockPassword checkLockPassword,
osInit,
systemInfo,
} }
},{ }, {
persist: { persist: {
key: 'settingsStore', key: 'settingsStore',
pick: ['config'], pick: ['config', 'systemInfo'],
}, },
}) })

53
os/src/stores/settingsConfig.ts

@ -48,28 +48,28 @@ export const systemSettingList = [
}, },
], ],
}, },
// { {
// key: "custom", key: "custom",
// title: "代理", title: "代理",
// desc: "本地代理、远程代理", desc: "本地代理、远程代理",
// icon: "proxy", icon: "proxy",
// content: "SetCustom", content: "SetCustom",
// children: [ children: [
// { {
// key: "local", key: "local",
// title: "本地代理", title: "本地代理",
// icon: "local", icon: "local",
// content: "nas/SetLocal", content: "nas/SetLocal",
// }, },
// { {
// key: "remote", key: "remote",
// title: "远程代理", title: "远程代理",
// icon: "netproxy", icon: "netproxy",
// content: "nas/SetRemote", content: "nas/SetRemote",
// } }
// ], ],
// }, },
{ {
key: "nas", key: "nas",
title: "存储", title: "存储",
@ -137,6 +137,17 @@ export const settingsConfig = {
activeTime: 0, activeTime: 0,
password: '' password: ''
}, },
system : {
userType: "person",
storeType: "local",
netUrl: "",
},
wallpaper: {
type: "image",
color: "#ffffff",
imageList: [bg1, bg2, bg3, bg4, bg5, bg6, bg7, bg8, bg9],
url: bg6,
},
storeType: "local", storeType: "local",
storePath: "", storePath: "",
netPort: "", netPort: "",

12
os/src/styles/login.scss

@ -131,7 +131,7 @@
.slider { .slider {
display: flex; display: flex;
width: 40%; width: 60%;
height: 45px; height: 45px;
background-color: rgb(215, 212, 212); background-color: rgb(215, 212, 212);
border-radius: 50px; border-radius: 50px;
@ -178,7 +178,15 @@
@media (max-width: 768px) { @media (max-width: 768px) {
.login-container { .login-container {
.login-box { .login-box {
width: 90%; width: 80vw;
height: 60vh;
} }
:deep(.el-card__body){
width: 80%;
} }
}
.register-form {
width: 100%;
}
} }

2
os/tsconfig.json

@ -25,7 +25,7 @@
"paths": { "paths": {
"@/*": ["src/*"] "@/*": ["src/*"]
}, },
"types": ["vite/client"] "types": ["element-plus/global","vite/client"]
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types.d.ts"], "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types.d.ts"],
} }

1
os/types.d.ts

@ -1 +1,2 @@
/// <reference types="element-plus/global" />
declare module 'pinia-plugin-persist'; declare module 'pinia-plugin-persist';

147
os/uno.config.ts

@ -0,0 +1,147 @@
import {
defineConfig,
presetAttributify,
presetIcons,
presetTypography,
presetUno,
presetWebFonts,
transformerDirectives,
transformerVariantGroup,
} from "unocss";
// @unocss-include
export default defineConfig({
shortcuts: [
["card-default", "bg-white dark:bg-dark-5 rounded-1.5"],
["card-bg-color", "bg-white dark:bg-dark-5"],
["form-bg-color", "bg-white dark:bg-[#1b1b1b]"],
["card-bg-color-2", "bg-[#f2f2f2] dark:bg-[#1b1b1b]"],
["input-bg-color", "bg-[#f2f2f2] dark:bg-dark-8"],
["card-default-br", "bg-[#ffffff93] dark:(bg-dark-5 bg-op-60) rounded-1.5 backdrop-blur-12px backdrop-saturate-180"],
["card-default-br-2", "bg-light bg-op-90 dark:(bg-dark-5 bg-op-90) rounded-1.5 backdrop-blur-8px backdrop-saturate-180"],
["blur-card", "backdrop-blur-4 bg-[#75757528] rounded-1.5"],
["card-rounded-df", " rounded-1.5"],
["btn-default", "border-0 cursor-pointer rounded-4px hover:text-[var(--el-color-primary)] transition-200 text-white"],
["btn-primary-bg", " cursor-pointer rounded-4px hover:bg-[var(--el-color-primary)] hover:text-white"],
// 颜色
["bg-color", "bg-white dark:bg-dark-5"],
["bg-color-2", "bg-[#f2f2f2] dark:bg-[#111111]"], // 次要背景色
["bg-color-3", "bg-[#f2f2f2] dark:bg-dark-9"],
["bg-color-br", "bg-[#ffffff93] dark:(bg-dark-5 bg-op-60) backdrop-blur-12px"],
["bg-color-df", "bg-[#f2f2f2] dark:bg-dark-9"],
["bg-menu-color", "bg-[#f6f6f6] dark:bg-dark-8"],
["bg-color-second", "bg-light-5 dark:bg-dark"],
["bg-skeleton", "bg-gray-1 dark:bg-[#1f1f1f]"],
// dialog颜色
["dialog-bg-color", "bg-white dark:bg-dark-9"],
// 文本颜色
["text-color", "text-black dark:text-white"],
["text-default", "text-1em text-black dark:text-white"],
["text-mini", "text-dark-50 dark:text-[#979898] text-xs"],
["text-mini-50", "text-xs text-[#717171] dark:text-[#979898]"],
["text-color-primary", "text-[var(--el-color-primary)]"],
["text-color-info", "text-[var(--el-color-info)]"],
["text-color-success", "text-[var(--el-color-success)]"],
["text-small", "text-dark-50 dark:text-[#979898] text-sm"],
["text-small-50", "text-sm text-dark-50 dark:text-[#717171]"],
["text-small-color", "text-dark-50 dark:text-[#979898]"],
// 边框
["border-default", "border-1px border-solid border-gray-200 dark:border-dark-300"],
["border-default-r", "border-solid border-gray-200 border-0 border-r-1px dark:border-dark-300"],
["border-default-l", "border-solid border-gray-200 border-0 border-l-1px dark:border-dark-300"],
["border-default-t", "border-solid border-gray-200 border-0 border-t-1px dark:border-dark-300"],
["border-default-b", "border-solid border-gray-200 border-0 border-b-1px dark:border-dark-300"],
["border-default-2", "border-1px border-solid border-[rgba(22,_22,_22,_0.1)] dark:border-[rgba(73,_73,_73,_0.2)]"],
["border-default-2-r", "border-r-(1px #7e7e7e0e solid) dark:border-dark-300 border-opacity-5"],
["border-default-2-l", "border-l-(1px #7e7e7e0e solid) dark:border-dark-300 border-opacity-5"],
["border-default-2-t", "border-t-(1px #7e7e7e0e solid) dark:border-dark-300 border-opacity-5"],
["border-default-2-b", "border-b-(1px #7e7e7e0e solid) dark:border-dark-300 border-opacity-5"],
["border-default-dashed", "hover:shadow-sm border-2px border-default border-dashed"],
["border-default-sm", "border-1px border-solid border-gray-200 dark:border-dark-500"],
["border-default-hover", "transition-200 border-1px border-solid border-[rgba(22,_22,_22,_0.1)] dark:border-[rgba(73,_73,_73,_0.2)] hover:(border-gray-200 dark:border-dark-100)"],
["border-default-2-hover", "transition-200 border-1px border-solid border-[rgba(20,_20,_20,_0.05)] dark:border-[rgba(76,_76,_76,_0.1)] hover:(border-gray-200 dark:border-dark-100)"],
["border-default-dashed", "border-2px border-default border-dashed"],
["border-default-dashed-hover", "transition-200 hover:border-solid hover:border-[var(--el-color-primary)] border-default-dashed"],
// 布局
["flex-row-c-c", "flex flex-row flex-justify-center flex-items-center"],
["flex-row-bt-c", "flex flex-row flex-justify-between flex-items-center"],
["layout-default", "mx-a sm:px-2rem py-4 w-94vw md:w-1400px"],
["layout-default-md", "mx-a sm:px-2rem py-4 w-94vw md:w-1400px"],
["layout-default-xm", "mx-a sm:px-2rem py-4 w-94vw md:w-1200px"],
["layout-default-se", "mx-a sm:px-2rem py-4 w-94vw md:w-1000px"],
["absolute-center", "absolute left-1/2 -translate-x-1/2"],
["absolute-center-center", "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"],
["absolute-center-x", "absolute left-1/2 -translate-x-1/2"],
// element风格按钮
["btn-info", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-info)]"],
["btn-success", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-success)]"],
["btn-primary", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-primary)]"],
["btn-danger", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-danger)]"],
["btn-warning", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-warning)]"],
["btn-info-text", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-info)]"],
["btn-success-text", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-success)]"],
["btn-primary-text", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-primary)]"],
["btn-danger-text", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-danger)]"],
["btn-warning-text", "transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-warning)]"],
["btn-info-bg", "transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-info)])"],
["btn-success-bg", "transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-success)])"],
["btn-primary-bg", "transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-primary)])"],
["btn-danger-bg", "transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-danger)])"],
["btn-warning-bg", "transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-warning)])"],
["group-btn-info", "transition-200 cursor-pointer rounded-4px group-hover:text-[var(--el-color-info)]"],
["group-btn-success", "transition-200 cursor-pointer rounded-4px group-hover:text-[var(--el-color-success)]"],
["group-btn-primary", "transition-200 cursor-pointer rounded-4px group-hover:text-[var(--el-color-primary)]"],
["group-btn-danger", "transition-200 cursor-pointer rounded-4px group-hover:text-[var(--el-color-danger)]"],
["group-btn-warning", "transition-200 cursor-pointer rounded-4px group-hover:text-[var(--el-color-warning)]"],
["btn-light-bg", "transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-light)])"],
],
rules: [
// color: info success primary danger warning
// 文字
[/^el-color-(\w*)$/, ([_, color]) => ({ color: `var(--el-color-${color})` })],
[/^el-bg-(\w*)$/, ([_, color]) => ({ "background-color": `var(--el-color-${color})` })],
// 文字按钮
// [/^btn-(\w*)$/, ([_, color]) => ({
// "--at-apply": `transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-${color})]`,
// })],
// [/^btn-(\w*)-text$/, ([_, color]) => ({
// "--at-apply": `transition-200 cursor-pointer rounded-4px hover:text-[var(--el-color-${color})]`,
// })],
// // 文字背景按钮
// [/^btn-(\w*)-bg$/, ([_, color]) => ({
// "--at-apply": `transition-200 cursor-pointer rounded-4px hover:(text-white bg-[var(--el-color-${color})]) `,
// })],
// // 文字按钮组
// [/^group-btn-(\w*)$/, ([_, color]) => ({
// "--at-apply": `transition-200 cursor-pointer rounded-4px group-hover:text-[var(--el-color-${color})]`,
// })],
],
theme: {
// ...
colors: {
theme: {
primary: "var(--el-color-primary)",
danger: "var(--el-color-danger)",
error: "var(--el-color-error)",
warning: "var(--el-color-warning)",
info: "var(--el-color-info)",
success: "var(--el-color-success)",
}, // class="text-very-cool"
tip: {
main: "var(--el-color-primary)", // class="--el-color-primary"
green: "hsla(var(--hue, 217), 78%, 51%)", // class="bg-brand-primary"
},
},
},
presets: [
presetUno(),
presetAttributify(),
presetTypography(),
presetWebFonts({}),
],
transformers: [
transformerDirectives(),
transformerVariantGroup(),
],
});

2
os/vite.config.ts

@ -4,6 +4,7 @@ import AutoImport from 'unplugin-auto-import/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite' import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import UnoCSS from 'unocss/vite'
// import vueDevTools from 'vite-plugin-vue-devtools' // import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig(({ mode }) => { export default defineConfig(({ mode }) => {
const serverConfig: any = { const serverConfig: any = {
@ -23,6 +24,7 @@ export default defineConfig(({ mode }) => {
return { return {
plugins: [ plugins: [
vue(), vue(),
UnoCSS(),
// vueDevTools(), // vueDevTools(),
AutoImport({ AutoImport({
resolvers: [ElementPlusResolver()], resolvers: [ElementPlusResolver()],

Loading…
Cancel
Save