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. 138
      os/src/components/auth/AuthLogin.vue
  13. 22
      os/src/components/auth/PasswordLogin.vue
  14. 91
      os/src/components/auth/SetUp.vue
  15. 238
      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. 46
      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']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
@ -66,6 +67,8 @@ declare module 'vue' {
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
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']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
@ -102,6 +105,7 @@ declare module 'vue' {
SaveFile: typeof import('./src/components/files/SaveFile.vue')['default']
ScreenRecorder: typeof import('./src/components/taskbar/ScreenRecorder.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']
SlideBackground: typeof import('./src/components/loading/SlideBackground.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",
"scripts": {
"dev": "vite",
"dev:desktop": "tauri dev",
"dev:android": "tauri android dev",
"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": {
"@element-plus/icons-vue": "^2.1.0",
"@tauri-apps/plugin-autostart": "~2",
"@tauri-apps/plugin-dialog": "~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",
"axios": "^1.7.9",
"chart.js": "^4.4.7",
@ -48,6 +64,7 @@
"less": "^4.2.2",
"sass": "^1.83.4",
"typescript": "^5.0.2",
"unocss": "66.1.0-beta.13",
"unplugin-auto-import": "^19.0.0",
"unplugin-vue-components": "^28.0.0",
"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-fs = "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]
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": [
"core:default",
"fs:default"
"updater:default"
]
}

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

@ -10,6 +10,18 @@
],
"permissions": [
"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)]
pub fn run() {
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_autostart::init())
.plugin(tauri_plugin_autostart::init(
tauri_plugin_autostart::MacosLauncher::LaunchAgent,
Some(vec!["--flag1", "--flag2"]),
))
.plugin(tauri_plugin_fs::init())
.setup(|app| {
if cfg!(debug_assertions) {

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

@ -16,7 +16,7 @@
"width": 1024,
"height": 768,
"resizable": true,
"fullscreen": true
"fullscreen": false
}
],
"security": {
@ -33,5 +33,14 @@
"icons/icon.icns",
"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"
]
}
}
}

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

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

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

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

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

@ -1,107 +1,97 @@
<script setup lang="ts">
import { useLoginStore } from "@/stores/login";
import { ref, Ref } from "vue";
const store = useLoginStore();
interface RegisterInfo {
username: string;
nickname: string;
password: string;
email: string;
phone: string;
third_user_id: string;
union_id: string;
platform: string;
confirmPassword: string;
}
//
const registerInfo: Ref<RegisterInfo> = ref({
username: "",
nickname: "",
password: "",
email: "",
phone: "",
third_user_id: "",
union_id: "",
platform: "",
confirmPassword: "",
});
const rules = {
username: [
{ required: true, message: "用户名不能为空", trigger: "blur" },
{
min: 3,
max: 20,
message: "用户名长度应在3到20个字符之间",
trigger: "blur",
},
{
pattern: /^[a-zA-Z0-9]+$/,
message: "用户名只能包含英文和数字",
trigger: "blur",
},
],
password: [
{ required: true, message: "密码不能为空", trigger: "blur" },
{ min: 6, message: "密码长度不能小于6位", trigger: "blur" },
],
confirmPassword: [
{ required: true, message: "请再次输入密码", trigger: "blur" },
{
validator: (rule: any, value: any, callback: any) => {
console.log(rule);
if (value === "") {
callback(new Error("请再次输入密码"));
} else if (value !== registerInfo.value.password) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
},
trigger: "blur",
},
],
email: [
{ required: true, message: "邮箱不能为空", trigger: "blur" },
{
type: "email",
message: "请输入有效的邮箱地址",
trigger: ["blur", "change"],
},
],
phone: [
{ required: true, message: "手机号不能为空", trigger: "blur" },
{
pattern: /^1[3-9]\d{9}$/,
message: "请输入有效的手机号",
trigger: "blur",
},
],
nickname: [
{ required: true, message: "昵称不能为空", trigger: "blur" },
{
min: 2,
max: 20,
message: "昵称长度应在2到20个字符之间",
trigger: "blur",
import { useLoginStore } from "@/stores/login";
import { ref, Ref } from "vue";
const store = useLoginStore();
interface RegisterInfo {
username: string;
nickname: string;
password: string;
email: string;
phone: string;
third_user_id: string;
union_id: string;
platform: string;
confirmPassword: string;
}
//
const registerInfo: Ref<RegisterInfo> = ref({
username: "",
nickname: "",
password: "",
email: "",
phone: "",
third_user_id: "",
union_id: "",
platform: "",
confirmPassword: "",
});
const rules = {
username: [
{ required: true, message: "用户名不能为空", trigger: "blur" },
{
min: 3,
max: 20,
message: "用户名长度应在3到20个字符之间",
trigger: "blur",
},
{
pattern: /^[a-zA-Z0-9]+$/,
message: "用户名只能包含英文和数字",
trigger: "blur",
},
],
password: [
{ required: true, message: "密码不能为空", trigger: "blur" },
{ min: 6, message: "密码长度不能小于6位", trigger: "blur" },
],
confirmPassword: [
{ required: true, message: "请再次输入密码", trigger: "blur" },
{
validator: (rule: any, value: any, callback: any) => {
console.log(rule);
if (value === "") {
callback(new Error("请再次输入密码"));
} else if (value !== registerInfo.value.password) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
},
],
};
trigger: "blur",
},
],
email: [
{ required: true, message: "邮箱不能为空", trigger: "blur" },
{
type: "email",
message: "请输入有效的邮箱地址",
trigger: ["blur", "change"],
},
],
phone: [
{ required: true, message: "手机号不能为空", trigger: "blur" },
{
pattern: /^1[3-9]\d{9}$/,
message: "请输入有效的手机号",
trigger: "blur",
},
],
nickname: [
{ required: true, message: "昵称不能为空", trigger: "blur" },
{
min: 2,
max: 20,
message: "昵称长度应在2到20个字符之间",
trigger: "blur",
},
],
};
</script>
<template>
<el-form
label-position="left"
label-width="0px"
:model="registerInfo"
ref="regFormRef"
:rules="rules"
>
<el-form label-position="left" label-width="0px" :model="registerInfo" ref="regFormRef" :rules="rules">
<el-form-item prop="username">
<el-input
v-model="registerInfo.username"
size="large"
placeholder="请输入用户名"
prefix-icon="UserFilled"
></el-input>
<el-input v-model="registerInfo.username" size="large" placeholder="请输入用户名"
prefix-icon="UserFilled"></el-input>
</el-form-item>
<!-- <el-form-item prop="nickname">
<el-input
@ -128,48 +118,34 @@
></el-input>
</el-form-item> -->
<el-form-item prop="password">
<el-input
v-model="registerInfo.password"
size="large"
type="password"
placeholder="请输入密码"
show-password
prefix-icon="Key"
></el-input>
<el-input v-model="registerInfo.password" size="large" type="password" placeholder="请输入密码" show-password
prefix-icon="Key"></el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input
v-model="registerInfo.confirmPassword"
size="large"
type="password"
placeholder="请再次输入密码"
show-password
prefix-icon="Lock"
></el-input>
<el-input v-model="registerInfo.confirmPassword" size="large" type="password" placeholder="请再次输入密码"
show-password prefix-icon="Lock"></el-input>
</el-form-item>
<el-form-item class="button-center">
<el-button
class="login-button"
type="primary"
size="large"
@click="store.onRegister"
>注册</el-button
>
<el-button class="login-button" type="primary" size="large" @click="store.onRegister">注册</el-button>
</el-form-item>
</el-form>
</template>
<style scoped>
.button-center {
.button-center {
width: 100%;
.login-button {
width: 100%;
.login-button {
width: 100%;
height: 45px;
border-radius: 50px;
}
}
:deep(.el-input__wrapper) {
border-radius: 50px;
height: 45px;
border-radius: 50px;
}
}
:deep(.el-input__wrapper) {
border-radius: 50px;
height: 45px;
}
</style>

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

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

1
os/src/main.ts

@ -1,6 +1,7 @@
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'virtual:uno.css'
import { createPinia } from 'pinia'
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 desktopStore = useDesktopStore()
const loginForm = ref({
username: "",
password: "",
rememberMe: false
});
// 用户信息
const userInfo: Ref<any> = ref({})
@ -44,7 +48,12 @@ export const useLoginStore = defineStore('login', () => {
param: params.params,
}
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) {
successMsg('登录成功')
userInfo.value = res.data.user
@ -246,6 +255,7 @@ export const useLoginStore = defineStore('login', () => {
return {
userInfo,
loginForm,
isLoginState,
isLogining,
thirdPartyPlatform,
@ -264,6 +274,6 @@ export const useLoginStore = defineStore('login', () => {
}, {
persist: {
key: 'loginStore',
pick: ['userInfo', 'isLoginState'],
pick: ['userInfo', 'isLoginState','loginForm'],
},
})

46
os/src/stores/settings.ts

@ -1,12 +1,14 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { systemSettingList,settingsConfig } from "@/stores/settingsConfig";
import { systemSettingList, settingsConfig } from "@/stores/settingsConfig";
import { md5 } from "js-md5";
import { type as osType, platform } from "@tauri-apps/plugin-os";
export const useSettingsStore = defineStore('settings', () => {
const settingList = ref(systemSettingList);
const config:any = ref(settingsConfig);
const config: any = ref(settingsConfig);
const isLockScreen = ref(false);
const systemInfo: any = ref({});
const updateConfig = (newConfig: any) => {
config.value = newConfig;
}
@ -21,19 +23,19 @@ export const useSettingsStore = defineStore('settings', () => {
}
const setLockTime = () => {
if(config.value.lock.timeout > 0 && !isLockScreen.value){
config.value.lock.activeTime = new Date().getTime() + config.value.lock.timeout*1000;
if (config.value.lock.timeout > 0 && !isLockScreen.value) {
config.value.lock.activeTime = new Date().getTime() + config.value.lock.timeout * 1000;
}
}
const checkLockPassword = (password: string) => {
return config.value.lock.password === md5(password);
}
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;
}
const checkIsLock = () => {
if(config.value.lock.timeout > 0){
if (config.value.lock.timeout > 0) {
const now = new Date().getTime();
isLockScreen.value = now > config.value.lock.activeTime;
//console.log(isLockScreen.value)
@ -42,9 +44,27 @@ export const useSettingsStore = defineStore('settings', () => {
isLockScreen.value = false;
return false;
}
return {
settingList,
config,
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 {
settingList,
config,
isLockScreen,
updateConfig,
setConfig,
@ -53,11 +73,13 @@ export const useSettingsStore = defineStore('settings', () => {
setLockTime,
checkIsLock,
unLockScreen,
checkLockPassword
checkLockPassword,
osInit,
systemInfo,
}
},{
}, {
persist: {
key: 'settingsStore',
pick: ['config'],
pick: ['config', 'systemInfo'],
},
})

53
os/src/stores/settingsConfig.ts

@ -48,28 +48,28 @@ export const systemSettingList = [
},
],
},
// {
// key: "custom",
// title: "代理",
// desc: "本地代理、远程代理",
// icon: "proxy",
// content: "SetCustom",
// children: [
// {
// key: "local",
// title: "本地代理",
// icon: "local",
// content: "nas/SetLocal",
// },
// {
// key: "remote",
// title: "远程代理",
// icon: "netproxy",
// content: "nas/SetRemote",
// }
{
key: "custom",
title: "代理",
desc: "本地代理、远程代理",
icon: "proxy",
content: "SetCustom",
children: [
{
key: "local",
title: "本地代理",
icon: "local",
content: "nas/SetLocal",
},
{
key: "remote",
title: "远程代理",
icon: "netproxy",
content: "nas/SetRemote",
}
// ],
// },
],
},
{
key: "nas",
title: "存储",
@ -137,6 +137,17 @@ export const settingsConfig = {
activeTime: 0,
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",
storePath: "",
netPort: "",

12
os/src/styles/login.scss

@ -131,7 +131,7 @@
.slider {
display: flex;
width: 40%;
width: 60%;
height: 45px;
background-color: rgb(215, 212, 212);
border-radius: 50px;
@ -178,7 +178,15 @@
@media (max-width: 768px) {
.login-container {
.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": {
"@/*": ["src/*"]
},
"types": ["vite/client"]
"types": ["element-plus/global","vite/client"]
},
"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';

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

Loading…
Cancel
Save