first commit
This commit is contained in:
9
.hbuilderx/launch.json
Normal file
9
.hbuilderx/launch.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"version" : "1.0",
|
||||
"configurations" : [
|
||||
{
|
||||
"playground" : "standard",
|
||||
"type" : "uni-app:app-android"
|
||||
}
|
||||
]
|
||||
}
|
||||
28
App.vue
Normal file
28
App.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 全局样式 */
|
||||
/* uni-input .uni-input-input {
|
||||
color: #e2e8f0 !important;
|
||||
} */
|
||||
|
||||
/* 不使用 scoped,这样样式可以穿透组件 */
|
||||
/* .form-group uni-input .uni-input-input {
|
||||
color: #2c3e50 !important;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 15px 18px;
|
||||
border-radius: 12px;
|
||||
} */
|
||||
</style>
|
||||
20
index.html
Normal file
20
index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
22
main.js
Normal file
22
main.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import App from './App'
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
Vue.config.productionTip = false
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import { createSSRApp } from 'vue'
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
72
manifest.json
Normal file
72
manifest.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name" : "111",
|
||||
"appid" : "__UNI__B742B9E",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "3"
|
||||
}
|
||||
35
pages.json
Normal file
35
pages.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/light-theme/light-theme",
|
||||
"style": {
|
||||
"navigationBarTitleText": "YXD",
|
||||
"navigationBarHidden": true,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/index/index",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "YXD",
|
||||
"navigationBarHidden": true,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/night-theme/night-theme",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"uniIdRouter": {}
|
||||
}
|
||||
306
pages/index/index.vue
Normal file
306
pages/index/index.vue
Normal file
@@ -0,0 +1,306 @@
|
||||
<template>
|
||||
<div class="main-view">
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<image src="/static/logo.png" alt="YXD"></image>
|
||||
</div>
|
||||
<h1>访问 YXD 智能应用</h1>
|
||||
|
||||
<p class="description">点击下方按钮跳转至浏览器访问 YXD 智能应用平台,体验智能服务。</p>
|
||||
|
||||
<div class="url-display">
|
||||
<!-- <i class="fas fa-lock"></i> -->
|
||||
<input placeholder="请输入网址" :value="url" />
|
||||
</div>
|
||||
|
||||
<button class="access-btn" ref="accessButton" @click="openExternalLink">
|
||||
<i class="fas fa-external-link-alt"></i> 立即访问
|
||||
</button>
|
||||
|
||||
<!-- <p class="alternative">如果无法自动跳转,请 <a href="https://ws.yuxindazhineng.com/" ref="directLink" @click="handleDirectLinkClick">点击此处直接访问</a></p> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
|
||||
const url = ref("https://ws.yuxindazhineng.com");
|
||||
// 打开外部链接的通用方法
|
||||
function openExternalLink() {
|
||||
// #ifdef H5
|
||||
window.open(url.value, '_blank')
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(url.value)
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.setClipboardData({
|
||||
data: url.value,
|
||||
success: () => {
|
||||
uni.showModal({
|
||||
content: '链接已复制,请在浏览器中打开',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 访问按钮点击事件处理
|
||||
const handleAccessClick = () => {
|
||||
|
||||
// 模拟短暂延迟,增强用户体验
|
||||
setTimeout(() => {
|
||||
window.location.href = url.value;
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// 直接链接点击事件处理
|
||||
const handleDirectLinkClick = (e) => {
|
||||
e.preventDefault();
|
||||
if (loadingElement.value) {
|
||||
loadingElement.value.style.display = 'block';
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = url.value;
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// 在组件挂载后执行的操作
|
||||
onMounted(() => {
|
||||
// 组件挂载后,DOM元素已准备就绪
|
||||
console.log('组件已挂载,DOM元素可用');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background: linear-gradient(135deg, #0f1419 0, #1a1f2e 100%);
|
||||
}
|
||||
|
||||
.main-view {
|
||||
z-index: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: radial-gradient(ellipse at center, #0f1419 0%, #0a0e1a 70%);
|
||||
color: #e8f4f8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: auto;
|
||||
height: 90vh;
|
||||
max-width: 500px;
|
||||
background: rgba(26, 31, 46, .8);
|
||||
border: 1px solid rgba(139, 195, 232, 0.2);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
/* box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); */
|
||||
box-shadow: 0 0 30px rgba(139, 195, 232, 0.5);
|
||||
text-align: center;
|
||||
/* align-items: center; */
|
||||
justify-content: center;
|
||||
padding: 40px 30px;
|
||||
margin: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.logo {
|
||||
z-index: 1;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto 25px;
|
||||
background: rgba(139, 195, 232, 0.2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 40px;
|
||||
box-shadow: 0 0 20px rgba(139, 195, 232, 0.3);
|
||||
overflow: hidden;
|
||||
/* 确保图片不会超出圆形容器 */
|
||||
padding: 10px;
|
||||
/* 增加内边距,让图片与边缘有间距 */
|
||||
}
|
||||
|
||||
.logo image {
|
||||
z-index: 2;
|
||||
max-width: 100%;
|
||||
/* 图片最大宽度不超过容器 */
|
||||
max-height: 100%;
|
||||
/* 图片最大高度不超过容器 */
|
||||
object-fit: contain;
|
||||
/* 保持图片比例,完整显示在容器内 */
|
||||
display: block;
|
||||
/* 去除图片底部可能出现的空白 */
|
||||
/* border-radius: 50%;
|
||||
box-shadow: 0 0 20px rgba(139, 195, 232, 0.1); */
|
||||
}
|
||||
|
||||
/* h1 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 15px;
|
||||
font-size: 24px;
|
||||
background: linear-gradient(135deg, #8bc3e8, #6ba3d6);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 5px rgba(74, 139, 194, 0.2));
|
||||
} */
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
background: linear-gradient(135deg, #8bc3e8, #6ba3d6);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
/* margin-bottom: 10px; */
|
||||
filter: drop-shadow(0 0 5px rgba(74, 139, 194, 0.2));
|
||||
text-shadow: 0 0 10px rgba(139, 195, 232, 0.3);
|
||||
}
|
||||
|
||||
.description {
|
||||
color: #9db4c0;
|
||||
font-size: 0.9rem;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.url-display {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 25px;
|
||||
border: 1px solid #eaeaea;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
color: #5a6570;
|
||||
}
|
||||
|
||||
.access-btn {
|
||||
background: linear-gradient(135deg, #8bc3e8, #6ba3d6);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 16px 40px;
|
||||
border-radius: 20px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
/* box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15); */
|
||||
box-shadow: 0 0 20px rgba(139, 195, 232, 0.3);
|
||||
display: inline-block;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.access-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.access-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.access-btn:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
margin: 20px 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 15px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 16px;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.alternative {
|
||||
margin-top: 25px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #eaeaea;
|
||||
font-size: 14px;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.alternative a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.alternative a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.container {
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.access-btn {
|
||||
padding: 14px 30px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
815
pages/light-theme/light-theme.vue
Normal file
815
pages/light-theme/light-theme.vue
Normal file
@@ -0,0 +1,815 @@
|
||||
<template>
|
||||
<div class="main-view">
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<image src="/static/logo.png" alt="YXD"></image>
|
||||
</div>
|
||||
<h1>登录 YXD 智能应用</h1>
|
||||
|
||||
<div class="login-form">
|
||||
<div class="form-group">
|
||||
<label for="username">账号</label>
|
||||
<input id="username" v-model="username" type="text" placeholder="请输入账号/邮箱/手机号"
|
||||
:class="{ 'error': usernameError }" @input="clearError('username')" />
|
||||
<div v-if="usernameError" class="error-message">{{ usernameError }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">密码</label>
|
||||
<div class="password-input">
|
||||
<input id="password" v-model="password" :type="showPassword ? 'text' : 'password'"
|
||||
placeholder="请输入密码" :class="{ 'error': passwordError }" @input="clearError('password')"
|
||||
@keyup.enter="handleLogin" />
|
||||
<button type="button" class="toggle-password" @click="showPassword = !showPassword">
|
||||
<span v-if="showPassword">🙈</span>
|
||||
<span v-else>👁️</span>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="passwordError" class="error-message">{{ passwordError }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-options">
|
||||
<!-- <label class="remember-me">
|
||||
<checkbox-group @change="toggleRememberMe">
|
||||
<checkbox :checked="rememberMe"></checkbox>
|
||||
</checkbox-group>
|
||||
<span>记住账号</span>
|
||||
</label> -->
|
||||
<!-- <a href="#" class="forgot-password">忘记密码?</a> -->
|
||||
<label class="remember-me" @click="toggleRememberMe">
|
||||
<!-- 自定义勾选框 -->
|
||||
<div class="custom-checkbox-wrapper">
|
||||
<div class="custom-checkbox" :class="{ 'checked': rememberMe }">
|
||||
<span v-if="rememberMe">✓</span>
|
||||
</div>
|
||||
</div>
|
||||
<span>记住账号</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button class="login-btn" @click="handleLogin" :disabled="isLoggingIn">
|
||||
<span v-if="isLoggingIn">⏳</span>
|
||||
<span v-else>🔑</span>
|
||||
{{ isLoggingIn ? '登录中...' : '立即登录' }}
|
||||
</button>
|
||||
|
||||
<div v-if="loginError" class="login-error">
|
||||
<span class="error-icon">⚠</span>
|
||||
{{ loginError }}
|
||||
</div>
|
||||
|
||||
<!-- 登录成功后的网址显示 -->
|
||||
<div v-if="redirectUrl" class="redirect-section">
|
||||
<div class="success-message">
|
||||
<span class="success-icon">✅</span>
|
||||
登录成功!正在为您跳转...
|
||||
</div>
|
||||
<!-- <div class="url-display">
|
||||
<input :value="redirectUrl" readonly />
|
||||
<button class="copy-btn" @click="copyToClipboard" :title="copySuccess ? '已复制' : '复制链接'">
|
||||
<span :class="copySuccess ? 'copied-icon' : 'copy-icon'">
|
||||
{{ copySuccess ? '✓' : '📋' }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<button class="access-btn" @click="openExternalLink">
|
||||
<span class="external-icon">🔗</span> 立即访问
|
||||
</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
|
||||
// 表单数据
|
||||
const username = ref('');
|
||||
const password = ref('');
|
||||
const rememberMe = ref(false);
|
||||
const showPassword = ref(false);
|
||||
|
||||
// 状态
|
||||
const isLoggingIn = ref(false);
|
||||
const redirectUrl = ref('');
|
||||
const copySuccess = ref(false);
|
||||
|
||||
// 错误信息
|
||||
const usernameError = ref('');
|
||||
const passwordError = ref('');
|
||||
const loginError = ref('');
|
||||
|
||||
// 切换记住账号状态
|
||||
const toggleRememberMe = () => {
|
||||
rememberMe.value = !rememberMe.value;
|
||||
};
|
||||
|
||||
// 模拟登录API - 实际项目中替换为真实API
|
||||
const mockLoginApi = (user, pwd) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// 模拟登录验证
|
||||
if (user && pwd) {
|
||||
// 模拟返回的跳转URL
|
||||
resolve({
|
||||
success: true,
|
||||
redirectUrl: 'https://ws.yuxindazhineng.com',
|
||||
userInfo: {
|
||||
username: user,
|
||||
name: '用户' + user.substring(0, 3)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject({
|
||||
success: false,
|
||||
message: '账号或密码错误'
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
});
|
||||
};
|
||||
|
||||
// 表单验证
|
||||
const validateForm = () => {
|
||||
let isValid = true;
|
||||
|
||||
usernameError.value = '';
|
||||
passwordError.value = '';
|
||||
|
||||
if (!username.value.trim()) {
|
||||
usernameError.value = '请输入账号';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!password.value) {
|
||||
passwordError.value = '请输入密码';
|
||||
isValid = false;
|
||||
} else if (password.value.length < 6) {
|
||||
passwordError.value = '密码至少6位字符';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
// 清除错误信息
|
||||
const clearError = (field) => {
|
||||
if (field === 'username') {
|
||||
usernameError.value = '';
|
||||
} else if (field === 'password') {
|
||||
passwordError.value = '';
|
||||
}
|
||||
loginError.value = '';
|
||||
};
|
||||
|
||||
// 处理登录
|
||||
const handleLogin = async () => {
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isLoggingIn.value = true;
|
||||
loginError.value = '';s
|
||||
|
||||
try {
|
||||
// 发起实际API请求
|
||||
const res = await uni.request({
|
||||
url: 'http://cloud_test.yuxindazhineng.com/cloud_api/app/verify_domain',
|
||||
method: 'POST',
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: {
|
||||
username: username.value,
|
||||
password: password.value
|
||||
}
|
||||
});
|
||||
|
||||
// 网络层面的错误判断
|
||||
if (res.statusCode !== 200) {
|
||||
throw new Error(`接口请求失败,状态码:${res.statusCode}`);
|
||||
}
|
||||
|
||||
// 解析接口响应数据
|
||||
const responseData = res.data;
|
||||
|
||||
// 业务层面的成功判断
|
||||
if (responseData.success) {
|
||||
// 存储用户信息
|
||||
if (rememberMe.value) {
|
||||
uni.setStorageSync('yxd_username', username.value);
|
||||
} else {
|
||||
uni.removeStorageSync('yxd_username');
|
||||
}
|
||||
|
||||
// 从响应的data字段中获取域名数据
|
||||
const domainData = responseData.data;
|
||||
console.log('完整域名:', domainData.full_domain);
|
||||
console.log('域名前缀:', domainData.domain_prefix);
|
||||
|
||||
// 构建跳转URL
|
||||
redirectUrl.value = `https://${domainData.full_domain}`;
|
||||
|
||||
// 自动跳转
|
||||
setTimeout(() => {
|
||||
openExternalLink();
|
||||
}, 2000);
|
||||
} else {
|
||||
// 接口返回业务失败
|
||||
throw new Error(responseData.message || '登录失败,请检查账号密码');
|
||||
}
|
||||
} catch (error) {
|
||||
loginError.value = error.message || '登录失败,请检查账号密码';
|
||||
} finally {
|
||||
isLoggingIn.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 打开外部链接的通用方法
|
||||
function openExternalLink() {
|
||||
if (!redirectUrl.value) return;
|
||||
|
||||
// #ifdef H5
|
||||
window.open(redirectUrl.value, '_blank')
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(redirectUrl.value)
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.setClipboardData({
|
||||
data: redirectUrl.value,
|
||||
success: () => {
|
||||
uni.showModal({
|
||||
content: '链接已复制,请在浏览器中打开',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 复制到剪贴板
|
||||
const copyToClipboard = () => {
|
||||
if (!redirectUrl.value) return;
|
||||
|
||||
// #ifdef H5
|
||||
navigator.clipboard.writeText(redirectUrl.value).then(() => {
|
||||
copySuccess.value = true;
|
||||
setTimeout(() => {
|
||||
copySuccess.value = false;
|
||||
}, 2000);
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN || APP-PLUS
|
||||
uni.setClipboardData({
|
||||
data: redirectUrl.value,
|
||||
success: () => {
|
||||
copySuccess.value = true;
|
||||
setTimeout(() => {
|
||||
copySuccess.value = false;
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
};
|
||||
|
||||
// 在组件挂载后执行的操作
|
||||
onMounted(() => {
|
||||
// 检查是否记住账号 - 修改这里
|
||||
const savedUsername = uni.getStorageSync('yxd_username');
|
||||
if (savedUsername) {
|
||||
username.value = savedUsername;
|
||||
rememberMe.value = true;
|
||||
}
|
||||
console.log('登录组件已挂载');
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background: linear-gradient(135deg, #f8fcff 0%, #f0f8ff 100%);
|
||||
}
|
||||
|
||||
.main-view {
|
||||
z-index: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #f8fcff 0%, #f0f8ff 100%);
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 15px 35px rgba(33, 150, 243, 0.08),
|
||||
0 5px 15px rgba(0, 0, 0, 0.05),
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.9);
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 45px 35px;
|
||||
margin: 10px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin: 0 auto 30px;
|
||||
background: linear-gradient(135deg, rgba(33, 150, 243, 0.1), rgba(100, 181, 246, 0.15));
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
box-shadow:
|
||||
0 8px 25px rgba(33, 150, 243, 0.12),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.9),
|
||||
inset 0 0 15px rgba(255, 255, 255, 0.8);
|
||||
overflow: hidden;
|
||||
padding: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.logo::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.6));
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.logo image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
filter: drop-shadow(0 2px 5px rgba(33, 150, 243, 0.3));
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.1rem;
|
||||
font-weight: 700;
|
||||
color: #1565c0;
|
||||
margin-bottom: 18px;
|
||||
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: #5d7b9f;
|
||||
font-size: 0.95rem;
|
||||
margin: 0 0 30px 0;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 22px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
color: #2c5282;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-group uni-input {
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 12px;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.form-group uni-input .uni-input-input {
|
||||
width: 100%;
|
||||
padding: 15px 18px;
|
||||
border: 1px solid #e1f5fe;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow:
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.04),
|
||||
0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
color: #2c3e50 !important;
|
||||
}
|
||||
|
||||
.form-group uni-input .uni-input-input:focus {
|
||||
outline: none;
|
||||
border-color: #4fc3f7;
|
||||
background: white;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(79, 195, 247, 0.2),
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.form-group uni-input .uni-input-input::placeholder {
|
||||
color: #90a4ae !important;
|
||||
}
|
||||
|
||||
.form-group uni-input .uni-input-input.error {
|
||||
border-color: #ff7043;
|
||||
background: rgba(255, 112, 67, 0.03);
|
||||
}
|
||||
|
||||
.form-group uni-input:focus {
|
||||
outline: none;
|
||||
border-color: #4fc3f7;
|
||||
background: white;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(79, 195, 247, 0.2),
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.form-group uni-input::placeholder {
|
||||
color: #90a4ae !important;
|
||||
}
|
||||
|
||||
.form-group uni-input.error {
|
||||
border-color: #ff7043;
|
||||
background: rgba(255, 112, 67, 0.03);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #ff7043;
|
||||
font-size: 13px;
|
||||
margin-top: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.password-input {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.password-input uni-button::after,
|
||||
.password-input uni-button::before {
|
||||
border: none
|
||||
}
|
||||
|
||||
|
||||
.toggle-password {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
transition: all 0.2s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* .toggle-password:hover {
|
||||
color: #2196f3;
|
||||
border-color: #4fc3f7;
|
||||
background: white;
|
||||
box-shadow: 0 2px 5px rgba(33, 150, 243, 0.15);
|
||||
} */
|
||||
|
||||
.toggle-password span {
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.form-options {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.remember-me {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #5d7b9f;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.custom-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-checkbox.checked {
|
||||
/* background: #3b82f6; */
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.custom-checkbox.checked i {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* uni-checkbox样式 */
|
||||
.remember-me uni-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:checked {
|
||||
background: #3b82f6;
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
color: #29b6f6;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.forgot-password:hover {
|
||||
color: #0288d1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
background: linear-gradient(135deg, #29b6f6, #0288d1);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 6px 20px rgba(41, 182, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.login-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.login-btn:hover:not(:disabled)::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.login-btn:hover:not(:disabled) {
|
||||
transform: translateY(-3px);
|
||||
box-shadow:
|
||||
0 10px 25px rgba(41, 182, 246, 0.4),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.3);
|
||||
background: linear-gradient(135deg, #4fc3f7, #039be5);
|
||||
}
|
||||
|
||||
.login-btn:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(41, 182, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.login-btn:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.login-error {
|
||||
margin-top: 18px;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, rgba(255, 112, 67, 0.08), rgba(255, 112, 67, 0.05));
|
||||
border: 1px solid #ffccbc;
|
||||
border-radius: 12px;
|
||||
color: #e64a19;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 8px rgba(255, 112, 67, 0.08);
|
||||
}
|
||||
|
||||
.redirect-section {
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
border-top: 1px solid #e1f5fe;
|
||||
animation: fadeIn 0.5s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(15px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.success-message {
|
||||
color: #00c853;
|
||||
font-weight: 600;
|
||||
margin-bottom: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.url-display {
|
||||
background: linear-gradient(135deg, #f8fdff, #e3f2fd);
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 18px;
|
||||
border: 1px solid #bbdefb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.url-display input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
color: #1565c0;
|
||||
outline: none;
|
||||
font-family: 'Monaco', 'Consolas', monospace;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
background: white;
|
||||
border: 1px solid #bbdefb;
|
||||
border-radius: 8px;
|
||||
padding: 9px 14px;
|
||||
color: #29b6f6;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
background: #e3f2fd;
|
||||
color: #0288d1;
|
||||
border-color: #90caf9;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.access-btn {
|
||||
background: linear-gradient(135deg, #26c6da, #0097a7);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 6px 20px rgba(38, 198, 218, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.access-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 10px 25px rgba(38, 198, 218, 0.35),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.3);
|
||||
background: linear-gradient(135deg, #4dd0e1, #00acc1);
|
||||
}
|
||||
|
||||
.access-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(38, 198, 218, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.container {
|
||||
padding: 35px 25px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
|
||||
.form-options {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 95px;
|
||||
height: 95px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
823
pages/night-theme/night-theme.vue
Normal file
823
pages/night-theme/night-theme.vue
Normal file
@@ -0,0 +1,823 @@
|
||||
<template>
|
||||
<div class="main-view">
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<image src="/static/logo.png" alt="YXD" />
|
||||
</div>
|
||||
<h1>登录 YXD 智能应用</h1>
|
||||
|
||||
<div class="login-form">
|
||||
<div class="form-group">
|
||||
<label for="username">账号</label>
|
||||
<input id="username" v-model="username" type="text" placeholder="请输入账号/邮箱/手机号"
|
||||
:class="{ 'error': usernameError }" @input="clearError('username')" />
|
||||
<div v-if="usernameError" class="error-message">{{ usernameError }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">密码</label>
|
||||
<div class="password-input">
|
||||
<input id="password" v-model="password" :type="showPassword ? 'text' : 'password'"
|
||||
placeholder="请输入密码" :class="{ 'error': passwordError }" @input="clearError('password')"
|
||||
@keyup.enter="handleLogin" />
|
||||
<button type="button" class="toggle-password" @click="showPassword = !showPassword">
|
||||
<span v-if="showPassword">🙈</span>
|
||||
<span v-else>👁️</span>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="passwordError" class="error-message">{{ passwordError }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-options">
|
||||
<!-- <label class="remember-me">
|
||||
<checkbox-group @change="toggleRememberMe">
|
||||
<checkbox :checked="rememberMe"></checkbox>
|
||||
</checkbox-group>
|
||||
<span>记住账号</span>
|
||||
</label> -->
|
||||
|
||||
<label class="remember-me" @click="toggleRememberMe">
|
||||
<!-- 自定义勾选框 -->
|
||||
<div class="custom-checkbox-wrapper">
|
||||
<div class="custom-checkbox" :class="{ 'checked': rememberMe }">
|
||||
<span v-if="rememberMe">✓</span>
|
||||
</div>
|
||||
</div>
|
||||
<span>记住账号</span>
|
||||
</label>
|
||||
<!-- <a href="#" class="forgot-password">忘记密码?</a> -->
|
||||
</div>
|
||||
|
||||
<button class="login-btn" @click="handleLogin" :disabled="isLoggingIn">
|
||||
<span v-if="isLoggingIn">⏳</span>
|
||||
<span v-else>🔑</span>
|
||||
{{ isLoggingIn ? '登录中...' : '立即登录' }}
|
||||
</button>
|
||||
|
||||
<div v-if="loginError" class="login-error">
|
||||
<span>⚠️</span>
|
||||
{{ loginError }}
|
||||
</div>
|
||||
|
||||
<!-- 登录成功后的网址显示 -->
|
||||
<div v-if="redirectUrl" class="redirect-section">
|
||||
<div class="success-message">
|
||||
<span>✅</span>
|
||||
登录成功!正在为您跳转...
|
||||
</div>
|
||||
<!-- <div class="url-display">
|
||||
<input :value="redirectUrl" readonly />
|
||||
<button class="copy-btn" @click="copyToClipboard" :title="copySuccess ? '已复制' : '复制链接'">
|
||||
<span v-if="copySuccess">✓</span>
|
||||
<span v-else>📋</span>
|
||||
</button>
|
||||
</div>
|
||||
<button class="access-btn" @click="openExternalLink">
|
||||
<span>🔗</span> 立即访问
|
||||
</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
|
||||
// 表单数据
|
||||
const username = ref('');
|
||||
const password = ref('');
|
||||
const rememberMe = ref(false);
|
||||
const showPassword = ref(false);
|
||||
|
||||
// 状态
|
||||
const isLoggingIn = ref(false);
|
||||
const redirectUrl = ref('');
|
||||
const copySuccess = ref(false);
|
||||
|
||||
// 错误信息
|
||||
const usernameError = ref('');
|
||||
const passwordError = ref('');
|
||||
const loginError = ref('');
|
||||
|
||||
// 切换记住账号状态
|
||||
const toggleRememberMe = () => {
|
||||
rememberMe.value = !rememberMe.value;
|
||||
console.log("触发toggleRememberMe");
|
||||
};
|
||||
|
||||
// 模拟登录API - 实际项目中替换为真实API
|
||||
const mockLoginApi = (user, pwd) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
// 模拟登录验证
|
||||
if (user && pwd) {
|
||||
// 模拟返回的跳转URL
|
||||
resolve({
|
||||
success: true,
|
||||
redirectUrl: 'https://ws.yuxindazhineng.com/',
|
||||
userInfo: {
|
||||
username: user,
|
||||
name: '用户' + user.substring(0, 3)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject({
|
||||
success: false,
|
||||
message: '账号或密码错误'
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
});
|
||||
};
|
||||
|
||||
// 表单验证
|
||||
const validateForm = () => {
|
||||
let isValid = true;
|
||||
|
||||
usernameError.value = '';
|
||||
passwordError.value = '';
|
||||
|
||||
if (!username.value.trim()) {
|
||||
usernameError.value = '请输入账号';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!password.value) {
|
||||
passwordError.value = '请输入密码';
|
||||
isValid = false;
|
||||
} else if (password.value.length < 6) {
|
||||
passwordError.value = '密码至少6位字符';
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
// 清除错误信息
|
||||
const clearError = (field) => {
|
||||
if (field === 'username') {
|
||||
usernameError.value = '';
|
||||
} else if (field === 'password') {
|
||||
passwordError.value = '';
|
||||
}
|
||||
loginError.value = '';
|
||||
};
|
||||
|
||||
// 处理登录
|
||||
const handleLogin = async () => {
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
isLoggingIn.value = true;
|
||||
loginError.value = '';
|
||||
|
||||
try {
|
||||
// 实际项目中替换为真实API调用
|
||||
const response = await mockLoginApi(username.value, password.value);
|
||||
|
||||
if (response.success) {
|
||||
// 存储用户信息(实际项目中应该使用更安全的方式)
|
||||
if (rememberMe.value) {
|
||||
// 使用 uni.setStorageSync 代替 localStorage.setItem
|
||||
uni.setStorageSync('yxd_username', username.value);
|
||||
} else {
|
||||
// 如果不记住账号,清除存储
|
||||
uni.removeStorageSync('yxd_username');
|
||||
}
|
||||
|
||||
// 获取返回的跳转URL
|
||||
redirectUrl.value = response.redirectUrl;
|
||||
|
||||
// 自动跳转(可选)
|
||||
setTimeout(() => {
|
||||
openExternalLink();
|
||||
}, 2000);
|
||||
}
|
||||
} catch (error) {
|
||||
loginError.value = error.message || '登录失败,请检查账号密码';
|
||||
} finally {
|
||||
isLoggingIn.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 打开外部链接的通用方法
|
||||
function openExternalLink() {
|
||||
if (!redirectUrl.value) return;
|
||||
|
||||
// #ifdef H5
|
||||
window.open(redirectUrl.value, '_blank')
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(redirectUrl.value)
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.setClipboardData({
|
||||
data: redirectUrl.value,
|
||||
success: () => {
|
||||
uni.showModal({
|
||||
content: '链接已复制,请在浏览器中打开',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 复制到剪贴板
|
||||
const copyToClipboard = () => {
|
||||
if (!redirectUrl.value) return;
|
||||
|
||||
// #ifdef H5
|
||||
navigator.clipboard.writeText(redirectUrl.value).then(() => {
|
||||
copySuccess.value = true;
|
||||
setTimeout(() => {
|
||||
copySuccess.value = false;
|
||||
}, 2000);
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN || APP-PLUS
|
||||
uni.setClipboardData({
|
||||
data: redirectUrl.value,
|
||||
success: () => {
|
||||
copySuccess.value = true;
|
||||
setTimeout(() => {
|
||||
copySuccess.value = false;
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
};
|
||||
|
||||
// 在组件挂载后执行的操作
|
||||
onMounted(() => {
|
||||
// 检查是否记住账号 - 修改这里
|
||||
const savedUsername = uni.getStorageSync('yxd_username');
|
||||
if (savedUsername) {
|
||||
username.value = savedUsername;
|
||||
rememberMe.value = true;
|
||||
}
|
||||
console.log('登录组件已挂载');
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* 移除全局body样式,改为在main-view中设置背景 */
|
||||
.main-view {
|
||||
z-index: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #0a0e17 0%, #131826 100%);
|
||||
color: #e8f4f8;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: linear-gradient(135deg, rgba(23, 32, 56, 0.9), rgba(19, 28, 46, 0.95));
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 20px 50px rgba(0, 10, 30, 0.5),
|
||||
0 0 0 1px rgba(59, 130, 246, 0.15),
|
||||
inset 0 0 30px rgba(0, 0, 0, 0.5);
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 45px 35px;
|
||||
margin: 10px;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin: 0 auto 30px;
|
||||
background: linear-gradient(135deg, rgba(23, 32, 56, 0.8), rgba(59, 130, 246, 0.2));
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
box-shadow:
|
||||
0 10px 30px rgba(0, 0, 0, 0.5),
|
||||
0 0 0 1px rgba(59, 130, 246, 0.3),
|
||||
inset 0 0 20px rgba(59, 130, 246, 0.2);
|
||||
overflow: hidden;
|
||||
padding: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.logo::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(59, 130, 246, 0.05));
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.logo image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
filter: drop-shadow(0 0 10px rgba(59, 130, 246, 0.5));
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.1rem;
|
||||
font-weight: 700;
|
||||
color: #60a5fa;
|
||||
margin-bottom: 18px;
|
||||
text-shadow: 0 0 15px rgba(96, 165, 250, 0.5);
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: #93c5fd;
|
||||
font-size: 0.95rem;
|
||||
margin: 0 0 30px 0;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 22px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
color: #93c5fd;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-group uni-input {
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 12px;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
|
||||
.form-group uni-input .uni-input-input {
|
||||
width: 100%;
|
||||
padding: 15px 20px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(15, 23, 42, 0.8);
|
||||
box-shadow:
|
||||
inset 0 2px 10px rgba(0, 0, 0, 0.3),
|
||||
0 1px 0 rgba(255, 255, 255, 0.05);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
/* 修复输入框无法选中的问题 */
|
||||
.form-group uni-input .uni-input-input {
|
||||
pointer-events: auto !important;
|
||||
user-select: auto !important;
|
||||
-webkit-user-select: auto !important;
|
||||
-moz-user-select: auto !important;
|
||||
-ms-user-select: auto !important;
|
||||
}
|
||||
|
||||
.form-group uni-input:focus {
|
||||
outline: none;
|
||||
border-color: #3b82f6;
|
||||
background: rgba(15, 23, 42, 0.9);
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(59, 130, 246, 0.2),
|
||||
inset 0 2px 10px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.form-group uni-input::placeholder {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.form-group uni-input.error {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.05);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #fca5a5;
|
||||
font-size: 13px;
|
||||
margin-top: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.password-input {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toggle-password {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
transition: all 0.2s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* .toggle-password:hover {
|
||||
color: #60a5fa;
|
||||
border-color: #3b82f6;
|
||||
background: rgba(30, 41, 59, 0.9);
|
||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.2);
|
||||
} */
|
||||
|
||||
.toggle-password span {
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.form-options {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.remember-me {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.custom-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-checkbox.checked {
|
||||
/* background: #3b82f6; */
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.custom-checkbox.checked i {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 对✓字符加粗效果有限 */
|
||||
/* .custom-checkbox span {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
} */
|
||||
|
||||
/* checkbox样式 */
|
||||
/* .remember-me uni-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:checked {
|
||||
background: #3b82f6;
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
|
||||
} */
|
||||
|
||||
.forgot-password {
|
||||
color: #60a5fa;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.forgot-password:hover {
|
||||
color: #3b82f6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 8px 25px rgba(59, 130, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.login-btn span {
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.login-btn:disabled span {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.login-btn:hover:not(:disabled)::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.login-btn:hover:not(:disabled) {
|
||||
transform: translateY(-3px);
|
||||
box-shadow:
|
||||
0 12px 30px rgba(59, 130, 246, 0.4),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
background: linear-gradient(135deg, #60a5fa, #2563eb);
|
||||
}
|
||||
|
||||
.login-btn:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(59, 130, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.login-btn:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.login-error {
|
||||
margin-top: 18px;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05));
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
border-radius: 12px;
|
||||
color: #fca5a5;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
|
||||
.login-error span {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.redirect-section {
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
border-top: 1px solid rgba(59, 130, 246, 0.2);
|
||||
animation: fadeIn 0.5s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(15px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.success-message {
|
||||
color: #4ade80;
|
||||
font-weight: 600;
|
||||
margin-bottom: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 15px;
|
||||
text-shadow: 0 0 10px rgba(74, 222, 128, 0.3);
|
||||
}
|
||||
|
||||
.success-message span {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.url-display {
|
||||
background: linear-gradient(135deg, rgba(15, 23, 42, 0.8), rgba(30, 41, 59, 0.8));
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 18px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.url-display input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
color: #60a5fa;
|
||||
outline: none;
|
||||
font-family: 'Monaco', 'Consolas', monospace;
|
||||
font-weight: 500;
|
||||
pointer-events: auto !important;
|
||||
user-select: auto !important;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 9px 14px;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.copy-btn span {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
color: #60a5fa;
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.access-btn {
|
||||
background: linear-gradient(135deg, #0ea5e9, #0369a1);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 8px 25px rgba(14, 165, 233, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.access-btn span {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.access-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 12px 30px rgba(14, 165, 233, 0.35),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
background: linear-gradient(135deg, #38bdf8, #0284c7);
|
||||
}
|
||||
|
||||
.access-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(14, 165, 233, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.container {
|
||||
padding: 35px 25px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
|
||||
.form-options {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 95px;
|
||||
height: 95px;
|
||||
}
|
||||
|
||||
.form-group uni-input input {
|
||||
padding: 14px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
static/logo.png
Normal file
BIN
static/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
13
uni.promisify.adaptor.js
Normal file
13
uni.promisify.adaptor.js
Normal file
@@ -0,0 +1,13 @@
|
||||
uni.addInterceptor({
|
||||
returnValue (res) {
|
||||
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
|
||||
return res;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
res.then((res) => {
|
||||
if (!res) return resolve(res)
|
||||
return res[0] ? reject(res[0]) : resolve(res[1])
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
76
uni.scss
Normal file
76
uni.scss
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 这里是uni-app内置的常用样式变量
|
||||
*
|
||||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||
*
|
||||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||
*/
|
||||
|
||||
/* 颜色变量 */
|
||||
|
||||
/* 行为相关颜色 */
|
||||
$uni-color-primary: #007aff;
|
||||
$uni-color-success: #4cd964;
|
||||
$uni-color-warning: #f0ad4e;
|
||||
$uni-color-error: #dd524d;
|
||||
|
||||
/* 文字基本颜色 */
|
||||
$uni-text-color:#333;//基本色
|
||||
$uni-text-color-inverse:#fff;//反色
|
||||
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||
$uni-text-color-placeholder: #808080;
|
||||
$uni-text-color-disable:#c0c0c0;
|
||||
|
||||
/* 背景颜色 */
|
||||
$uni-bg-color:#ffffff;
|
||||
$uni-bg-color-grey:#f8f8f8;
|
||||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||
|
||||
/* 边框颜色 */
|
||||
$uni-border-color:#c8c7cc;
|
||||
|
||||
/* 尺寸变量 */
|
||||
|
||||
/* 文字尺寸 */
|
||||
$uni-font-size-sm:12px;
|
||||
$uni-font-size-base:14px;
|
||||
$uni-font-size-lg:16px;
|
||||
|
||||
/* 图片尺寸 */
|
||||
$uni-img-size-sm:20px;
|
||||
$uni-img-size-base:26px;
|
||||
$uni-img-size-lg:40px;
|
||||
|
||||
/* Border Radius */
|
||||
$uni-border-radius-sm: 2px;
|
||||
$uni-border-radius-base: 3px;
|
||||
$uni-border-radius-lg: 6px;
|
||||
$uni-border-radius-circle: 50%;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-row-sm: 5px;
|
||||
$uni-spacing-row-base: 10px;
|
||||
$uni-spacing-row-lg: 15px;
|
||||
|
||||
/* 垂直间距 */
|
||||
$uni-spacing-col-sm: 4px;
|
||||
$uni-spacing-col-base: 8px;
|
||||
$uni-spacing-col-lg: 12px;
|
||||
|
||||
/* 透明度 */
|
||||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||
|
||||
/* 文章场景相关 */
|
||||
$uni-color-title: #2C405A; // 文章标题颜色
|
||||
$uni-font-size-title:20px;
|
||||
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||
$uni-font-size-subtitle:26px;
|
||||
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||
$uni-font-size-paragraph:15px;
|
||||
8
unpackage/dist/cache/.vite/deps/_metadata.json
vendored
Normal file
8
unpackage/dist/cache/.vite/deps/_metadata.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"hash": "e66e26ef",
|
||||
"configHash": "95216d54",
|
||||
"lockfileHash": "e3b0c442",
|
||||
"browserHash": "965e6bcf",
|
||||
"optimized": {},
|
||||
"chunks": {}
|
||||
}
|
||||
3
unpackage/dist/cache/.vite/deps/package.json
vendored
Normal file
3
unpackage/dist/cache/.vite/deps/package.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
11
unpackage/dist/dev/.nvue/app.css.js
vendored
Normal file
11
unpackage/dist/dev/.nvue/app.css.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
};
|
||||
var require_app_css = __commonJS({
|
||||
"app.css.js"(exports) {
|
||||
const _style_0 = {};
|
||||
exports.styles = [_style_0];
|
||||
}
|
||||
});
|
||||
export default require_app_css();
|
||||
2
unpackage/dist/dev/.nvue/app.js
vendored
Normal file
2
unpackage/dist/dev/.nvue/app.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
Promise.resolve("./app.css.js").then(() => {
|
||||
});
|
||||
16
unpackage/dist/dev/app-plus/__uniappautomator.js
vendored
Normal file
16
unpackage/dist/dev/app-plus/__uniappautomator.js
vendored
Normal file
File diff suppressed because one or more lines are too long
32
unpackage/dist/dev/app-plus/__uniappchooselocation.js
vendored
Normal file
32
unpackage/dist/dev/app-plus/__uniappchooselocation.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
unpackage/dist/dev/app-plus/__uniapperror.png
vendored
Normal file
BIN
unpackage/dist/dev/app-plus/__uniapperror.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
32
unpackage/dist/dev/app-plus/__uniappopenlocation.js
vendored
Normal file
32
unpackage/dist/dev/app-plus/__uniappopenlocation.js
vendored
Normal file
File diff suppressed because one or more lines are too long
33
unpackage/dist/dev/app-plus/__uniapppicker.js
vendored
Normal file
33
unpackage/dist/dev/app-plus/__uniapppicker.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
unpackage/dist/dev/app-plus/__uniappquill.js
vendored
Normal file
8
unpackage/dist/dev/app-plus/__uniappquill.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
unpackage/dist/dev/app-plus/__uniappquillimageresize.js
vendored
Normal file
1
unpackage/dist/dev/app-plus/__uniappquillimageresize.js
vendored
Normal file
File diff suppressed because one or more lines are too long
32
unpackage/dist/dev/app-plus/__uniappscan.js
vendored
Normal file
32
unpackage/dist/dev/app-plus/__uniappscan.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
unpackage/dist/dev/app-plus/__uniappsuccess.png
vendored
Normal file
BIN
unpackage/dist/dev/app-plus/__uniappsuccess.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
24
unpackage/dist/dev/app-plus/__uniappview.html
vendored
Normal file
24
unpackage/dist/dev/app-plus/__uniappview.html
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>View</title>
|
||||
<link rel="icon" href="data:,">
|
||||
<link rel="stylesheet" href="app.css" />
|
||||
<script>var __uniConfig = {"globalStyle":{},"darkmode":false}</script>
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="uni-app-view.umd.js"></script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
11
unpackage/dist/dev/app-plus/app-config-service.js
vendored
Normal file
11
unpackage/dist/dev/app-plus/app-config-service.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
;(function(){
|
||||
let u=void 0,isReady=false,onReadyCallbacks=[],isServiceReady=false,onServiceReadyCallbacks=[];
|
||||
const __uniConfig = {"pages":[],"globalStyle":{"backgroundColor":"#F8F8F8","navigationBar":{"backgroundColor":"#F8F8F8","titleText":"uni-app","type":"default","titleColor":"#000000"},"isNVue":false},"nvue":{"compiler":"uni-app","styleCompiler":"uni-app","flex-direction":"column"},"renderer":"auto","appname":"111","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":true},"compilerVersion":"4.87","entryPagePath":"pages/light-theme/light-theme","entryPageQuery":"","realEntryPagePath":"","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000},"locales":{},"darkmode":false,"themeConfig":{}};
|
||||
const __uniRoutes = [{"path":"pages/light-theme/light-theme","meta":{"isQuit":true,"isEntry":true,"navigationBarHidden":true,"navigationBar":{"titleText":"YXD","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/index/index","meta":{"navigationBarHidden":true,"navigationBar":{"titleText":"YXD","style":"custom","type":"default"},"isNVue":false}},{"path":"pages/night-theme/night-theme","meta":{"navigationBar":{"titleText":"","type":"default"},"isNVue":false}}].map(uniRoute=>(uniRoute.meta.route=uniRoute.path,__uniConfig.pages.push(uniRoute.path),uniRoute.path='/'+uniRoute.path,uniRoute));
|
||||
__uniConfig.styles=[];//styles
|
||||
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
||||
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
|
||||
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:16})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:u,window:u,document:u,frames:u,self:u,location:u,navigator:u,localStorage:u,history:u,Caches:u,screen:u,alert:u,confirm:u,prompt:u,fetch:u,XMLHttpRequest:u,WebSocket:u,webkit:u,print:u}}}});
|
||||
})();
|
||||
|
||||
1
unpackage/dist/dev/app-plus/app-config.js
vendored
Normal file
1
unpackage/dist/dev/app-plus/app-config.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
(function(){})();
|
||||
664
unpackage/dist/dev/app-plus/app-service.js
vendored
Normal file
664
unpackage/dist/dev/app-plus/app-service.js
vendored
Normal file
@@ -0,0 +1,664 @@
|
||||
if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
|
||||
Promise.prototype.finally = function(callback) {
|
||||
const promise = this.constructor;
|
||||
return this.then(
|
||||
(value) => promise.resolve(callback()).then(() => value),
|
||||
(reason) => promise.resolve(callback()).then(() => {
|
||||
throw reason;
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
;
|
||||
if (typeof uni !== "undefined" && uni && uni.requireGlobal) {
|
||||
const global = uni.requireGlobal();
|
||||
ArrayBuffer = global.ArrayBuffer;
|
||||
Int8Array = global.Int8Array;
|
||||
Uint8Array = global.Uint8Array;
|
||||
Uint8ClampedArray = global.Uint8ClampedArray;
|
||||
Int16Array = global.Int16Array;
|
||||
Uint16Array = global.Uint16Array;
|
||||
Int32Array = global.Int32Array;
|
||||
Uint32Array = global.Uint32Array;
|
||||
Float32Array = global.Float32Array;
|
||||
Float64Array = global.Float64Array;
|
||||
BigInt64Array = global.BigInt64Array;
|
||||
BigUint64Array = global.BigUint64Array;
|
||||
}
|
||||
;
|
||||
if (uni.restoreGlobal) {
|
||||
uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval);
|
||||
}
|
||||
(function(vue) {
|
||||
"use strict";
|
||||
function formatAppLog(type, filename, ...args) {
|
||||
if (uni.__log__) {
|
||||
uni.__log__(type, filename, ...args);
|
||||
} else {
|
||||
console[type].apply(console, [...args, filename]);
|
||||
}
|
||||
}
|
||||
const _imports_0 = "/static/logo.png";
|
||||
const _export_sfc = (sfc, props) => {
|
||||
const target = sfc.__vccOpts || sfc;
|
||||
for (const [key, val] of props) {
|
||||
target[key] = val;
|
||||
}
|
||||
return target;
|
||||
};
|
||||
const _sfc_main$3 = {
|
||||
__name: "light-theme",
|
||||
setup(__props, { expose: __expose }) {
|
||||
__expose();
|
||||
const username = vue.ref("");
|
||||
const password = vue.ref("");
|
||||
const rememberMe = vue.ref(false);
|
||||
const showPassword = vue.ref(false);
|
||||
const isLoggingIn = vue.ref(false);
|
||||
const redirectUrl = vue.ref("");
|
||||
const copySuccess = vue.ref(false);
|
||||
const usernameError = vue.ref("");
|
||||
const passwordError = vue.ref("");
|
||||
const loginError = vue.ref("");
|
||||
const toggleRememberMe = () => {
|
||||
rememberMe.value = !rememberMe.value;
|
||||
formatAppLog("log", "at pages/light-theme/light-theme.vue:109", "111");
|
||||
};
|
||||
const mockLoginApi = (user, pwd) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
if (user && pwd) {
|
||||
resolve({
|
||||
success: true,
|
||||
redirectUrl: "https://ws.yuxindazhineng.com",
|
||||
userInfo: {
|
||||
username: user,
|
||||
name: "用户" + user.substring(0, 3)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject({
|
||||
success: false,
|
||||
message: "账号或密码错误"
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
});
|
||||
};
|
||||
const validateForm = () => {
|
||||
let isValid = true;
|
||||
usernameError.value = "";
|
||||
passwordError.value = "";
|
||||
if (!username.value.trim()) {
|
||||
usernameError.value = "请输入账号";
|
||||
isValid = false;
|
||||
}
|
||||
if (!password.value) {
|
||||
passwordError.value = "请输入密码";
|
||||
isValid = false;
|
||||
} else if (password.value.length < 6) {
|
||||
passwordError.value = "密码至少6位字符";
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
};
|
||||
const clearError = (field) => {
|
||||
if (field === "username") {
|
||||
usernameError.value = "";
|
||||
} else if (field === "password") {
|
||||
passwordError.value = "";
|
||||
}
|
||||
loginError.value = "";
|
||||
};
|
||||
const handleLogin = async () => {
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
isLoggingIn.value = true;
|
||||
loginError.value = "";
|
||||
try {
|
||||
const res = await uni.request({
|
||||
url: "http://cloud_test.yuxindazhineng.com/cloud_api/app/verify_domain",
|
||||
method: "POST",
|
||||
header: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
data: {
|
||||
username: username.value,
|
||||
password: password.value
|
||||
}
|
||||
});
|
||||
if (res.statusCode !== 200) {
|
||||
throw new Error(`接口请求失败,状态码:${res.statusCode}`);
|
||||
}
|
||||
const responseData = res.data;
|
||||
if (responseData.success) {
|
||||
if (rememberMe.value) {
|
||||
uni.setStorageSync("yxd_username", username.value);
|
||||
} else {
|
||||
uni.removeStorageSync("yxd_username");
|
||||
}
|
||||
const domainData = responseData.data;
|
||||
formatAppLog("log", "at pages/light-theme/light-theme.vue:212", "完整域名:", domainData.full_domain);
|
||||
formatAppLog("log", "at pages/light-theme/light-theme.vue:213", "域名前缀:", domainData.domain_prefix);
|
||||
redirectUrl.value = `https://${domainData.full_domain}`;
|
||||
setTimeout(() => {
|
||||
openExternalLink();
|
||||
}, 2e3);
|
||||
} else {
|
||||
throw new Error(responseData.message || "登录失败,请检查账号密码");
|
||||
}
|
||||
} catch (error) {
|
||||
loginError.value = error.message || "登录失败,请检查账号密码";
|
||||
} finally {
|
||||
isLoggingIn.value = false;
|
||||
}
|
||||
};
|
||||
function openExternalLink() {
|
||||
if (!redirectUrl.value)
|
||||
return;
|
||||
plus.runtime.openURL(redirectUrl.value);
|
||||
}
|
||||
const copyToClipboard = () => {
|
||||
if (!redirectUrl.value)
|
||||
return;
|
||||
uni.setClipboardData({
|
||||
data: redirectUrl.value,
|
||||
success: () => {
|
||||
copySuccess.value = true;
|
||||
setTimeout(() => {
|
||||
copySuccess.value = false;
|
||||
}, 2e3);
|
||||
}
|
||||
});
|
||||
};
|
||||
vue.onMounted(() => {
|
||||
const savedUsername = uni.getStorageSync("yxd_username");
|
||||
if (savedUsername) {
|
||||
username.value = savedUsername;
|
||||
rememberMe.value = true;
|
||||
}
|
||||
formatAppLog("log", "at pages/light-theme/light-theme.vue:292", "登录组件已挂载");
|
||||
});
|
||||
const __returned__ = { username, password, rememberMe, showPassword, isLoggingIn, redirectUrl, copySuccess, usernameError, passwordError, loginError, toggleRememberMe, mockLoginApi, validateForm, clearError, handleLogin, openExternalLink, copyToClipboard, ref: vue.ref, onMounted: vue.onMounted };
|
||||
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
||||
return __returned__;
|
||||
}
|
||||
};
|
||||
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
return vue.openBlock(), vue.createElementBlock("div", { class: "main-view" }, [
|
||||
vue.createElementVNode("div", { class: "container" }, [
|
||||
vue.createElementVNode("div", { class: "logo" }, [
|
||||
vue.createElementVNode("image", {
|
||||
src: _imports_0,
|
||||
alt: "YXD"
|
||||
})
|
||||
]),
|
||||
vue.createElementVNode("h1", null, "登录 YXD 智能应用"),
|
||||
vue.createElementVNode("div", { class: "login-form" }, [
|
||||
vue.createElementVNode("div", { class: "form-group" }, [
|
||||
vue.createElementVNode("label", { for: "username" }, "账号"),
|
||||
vue.withDirectives(vue.createElementVNode(
|
||||
"input",
|
||||
{
|
||||
id: "username",
|
||||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.username = $event),
|
||||
type: "text",
|
||||
placeholder: "请输入账号/邮箱/手机号",
|
||||
class: vue.normalizeClass({ "error": $setup.usernameError }),
|
||||
onInput: _cache[1] || (_cache[1] = ($event) => $setup.clearError("username"))
|
||||
},
|
||||
null,
|
||||
34
|
||||
/* CLASS, NEED_HYDRATION */
|
||||
), [
|
||||
[vue.vModelText, $setup.username]
|
||||
]),
|
||||
$setup.usernameError ? (vue.openBlock(), vue.createElementBlock(
|
||||
"div",
|
||||
{
|
||||
key: 0,
|
||||
class: "error-message"
|
||||
},
|
||||
vue.toDisplayString($setup.usernameError),
|
||||
1
|
||||
/* TEXT */
|
||||
)) : vue.createCommentVNode("v-if", true)
|
||||
]),
|
||||
vue.createElementVNode("div", { class: "form-group" }, [
|
||||
vue.createElementVNode("label", { for: "password" }, "密码"),
|
||||
vue.createElementVNode("div", { class: "password-input" }, [
|
||||
vue.withDirectives(vue.createElementVNode("input", {
|
||||
id: "password",
|
||||
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.password = $event),
|
||||
type: $setup.showPassword ? "text" : "password",
|
||||
placeholder: "请输入密码",
|
||||
class: vue.normalizeClass({ "error": $setup.passwordError }),
|
||||
onInput: _cache[3] || (_cache[3] = ($event) => $setup.clearError("password")),
|
||||
onKeyup: vue.withKeys($setup.handleLogin, ["enter"])
|
||||
}, null, 42, ["type"]), [
|
||||
[vue.vModelDynamic, $setup.password]
|
||||
]),
|
||||
vue.createElementVNode("button", {
|
||||
type: "button",
|
||||
class: "toggle-password",
|
||||
onClick: _cache[4] || (_cache[4] = ($event) => $setup.showPassword = !$setup.showPassword)
|
||||
}, [
|
||||
$setup.showPassword ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, "🙈")) : (vue.openBlock(), vue.createElementBlock("span", { key: 1 }, "👁️"))
|
||||
])
|
||||
]),
|
||||
$setup.passwordError ? (vue.openBlock(), vue.createElementBlock(
|
||||
"div",
|
||||
{
|
||||
key: 0,
|
||||
class: "error-message"
|
||||
},
|
||||
vue.toDisplayString($setup.passwordError),
|
||||
1
|
||||
/* TEXT */
|
||||
)) : vue.createCommentVNode("v-if", true)
|
||||
]),
|
||||
vue.createElementVNode("div", { class: "form-options" }, [
|
||||
vue.createElementVNode("label", {
|
||||
class: "remember-me",
|
||||
onClick: $setup.toggleRememberMe
|
||||
}, [
|
||||
vue.createElementVNode("div", { class: "custom-checkbox-wrapper" }, [
|
||||
vue.createElementVNode(
|
||||
"div",
|
||||
{
|
||||
class: vue.normalizeClass(["custom-checkbox", { "checked": $setup.rememberMe }])
|
||||
},
|
||||
[
|
||||
$setup.rememberMe ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, "✓")) : vue.createCommentVNode("v-if", true)
|
||||
],
|
||||
2
|
||||
/* CLASS */
|
||||
)
|
||||
]),
|
||||
vue.createElementVNode("span", null, "记住账号")
|
||||
])
|
||||
]),
|
||||
vue.createElementVNode("button", {
|
||||
class: "login-btn",
|
||||
onClick: $setup.handleLogin,
|
||||
disabled: $setup.isLoggingIn
|
||||
}, [
|
||||
$setup.isLoggingIn ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, "⏳")) : (vue.openBlock(), vue.createElementBlock("span", { key: 1 }, "🔑")),
|
||||
vue.createTextVNode(
|
||||
" " + vue.toDisplayString($setup.isLoggingIn ? "登录中..." : "立即登录"),
|
||||
1
|
||||
/* TEXT */
|
||||
)
|
||||
], 8, ["disabled"]),
|
||||
$setup.loginError ? (vue.openBlock(), vue.createElementBlock("div", {
|
||||
key: 0,
|
||||
class: "login-error"
|
||||
}, [
|
||||
vue.createElementVNode("span", { class: "error-icon" }, "⚠"),
|
||||
vue.createTextVNode(
|
||||
" " + vue.toDisplayString($setup.loginError),
|
||||
1
|
||||
/* TEXT */
|
||||
)
|
||||
])) : vue.createCommentVNode("v-if", true),
|
||||
$setup.redirectUrl ? (vue.openBlock(), vue.createElementBlock("div", {
|
||||
key: 1,
|
||||
class: "redirect-section"
|
||||
}, [
|
||||
vue.createElementVNode("div", { class: "success-message" }, [
|
||||
vue.createElementVNode("span", { class: "success-icon" }, "✅"),
|
||||
vue.createTextVNode(" 登录成功!正在为您跳转... ")
|
||||
])
|
||||
])) : vue.createCommentVNode("v-if", true)
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
const PagesLightThemeLightTheme = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2], ["__scopeId", "data-v-68542e3f"], ["__file", "D:/Projects/uniapp/app-test/fronted-phone/pages/light-theme/light-theme.vue"]]);
|
||||
const _sfc_main$2 = {
|
||||
__name: "index",
|
||||
setup(__props, { expose: __expose }) {
|
||||
__expose();
|
||||
const url = vue.ref("https://ws.yuxindazhineng.com");
|
||||
function openExternalLink() {
|
||||
plus.runtime.openURL(url.value);
|
||||
}
|
||||
const handleAccessClick = () => {
|
||||
setTimeout(() => {
|
||||
window.location.href = url.value;
|
||||
}, 1e3);
|
||||
};
|
||||
const handleDirectLinkClick = (e) => {
|
||||
e.preventDefault();
|
||||
if (loadingElement.value) {
|
||||
loadingElement.value.style.display = "block";
|
||||
}
|
||||
setTimeout(() => {
|
||||
window.location.href = url.value;
|
||||
}, 500);
|
||||
};
|
||||
vue.onMounted(() => {
|
||||
formatAppLog("log", "at pages/index/index.vue:79", "组件已挂载,DOM元素可用");
|
||||
});
|
||||
const __returned__ = { url, openExternalLink, handleAccessClick, handleDirectLinkClick, ref: vue.ref, onMounted: vue.onMounted };
|
||||
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
||||
return __returned__;
|
||||
}
|
||||
};
|
||||
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
return vue.openBlock(), vue.createElementBlock("div", { class: "main-view" }, [
|
||||
vue.createElementVNode("div", { class: "container" }, [
|
||||
vue.createElementVNode("div", { class: "logo" }, [
|
||||
vue.createElementVNode("image", {
|
||||
src: _imports_0,
|
||||
alt: "YXD"
|
||||
})
|
||||
]),
|
||||
vue.createElementVNode("h1", null, "访问 YXD 智能应用"),
|
||||
vue.createElementVNode("p", { class: "description" }, "点击下方按钮跳转至浏览器访问 YXD 智能应用平台,体验智能服务。"),
|
||||
vue.createElementVNode("div", { class: "url-display" }, [
|
||||
vue.createElementVNode("input", {
|
||||
placeholder: "请输入网址",
|
||||
value: $setup.url
|
||||
}, null, 8, ["value"])
|
||||
]),
|
||||
vue.createElementVNode(
|
||||
"button",
|
||||
{
|
||||
class: "access-btn",
|
||||
ref: "accessButton",
|
||||
onClick: $setup.openExternalLink
|
||||
},
|
||||
[
|
||||
vue.createElementVNode("i", { class: "fas fa-external-link-alt" }),
|
||||
vue.createTextVNode(" 立即访问 ")
|
||||
],
|
||||
512
|
||||
/* NEED_PATCH */
|
||||
)
|
||||
])
|
||||
]);
|
||||
}
|
||||
const PagesIndexIndex = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__scopeId", "data-v-1cf27b2a"], ["__file", "D:/Projects/uniapp/app-test/fronted-phone/pages/index/index.vue"]]);
|
||||
const _sfc_main$1 = {
|
||||
__name: "night-theme",
|
||||
setup(__props, { expose: __expose }) {
|
||||
__expose();
|
||||
const username = vue.ref("");
|
||||
const password = vue.ref("");
|
||||
const rememberMe = vue.ref(false);
|
||||
const showPassword = vue.ref(false);
|
||||
const isLoggingIn = vue.ref(false);
|
||||
const redirectUrl = vue.ref("");
|
||||
const copySuccess = vue.ref(false);
|
||||
const usernameError = vue.ref("");
|
||||
const passwordError = vue.ref("");
|
||||
const loginError = vue.ref("");
|
||||
const toggleRememberMe = () => {
|
||||
rememberMe.value = !rememberMe.value;
|
||||
formatAppLog("log", "at pages/night-theme/night-theme.vue:109", "触发toggleRememberMe");
|
||||
};
|
||||
const mockLoginApi = (user, pwd) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
if (user && pwd) {
|
||||
resolve({
|
||||
success: true,
|
||||
redirectUrl: "https://ws.yuxindazhineng.com/",
|
||||
userInfo: {
|
||||
username: user,
|
||||
name: "用户" + user.substring(0, 3)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject({
|
||||
success: false,
|
||||
message: "账号或密码错误"
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
});
|
||||
};
|
||||
const validateForm = () => {
|
||||
let isValid = true;
|
||||
usernameError.value = "";
|
||||
passwordError.value = "";
|
||||
if (!username.value.trim()) {
|
||||
usernameError.value = "请输入账号";
|
||||
isValid = false;
|
||||
}
|
||||
if (!password.value) {
|
||||
passwordError.value = "请输入密码";
|
||||
isValid = false;
|
||||
} else if (password.value.length < 6) {
|
||||
passwordError.value = "密码至少6位字符";
|
||||
isValid = false;
|
||||
}
|
||||
return isValid;
|
||||
};
|
||||
const clearError = (field) => {
|
||||
if (field === "username") {
|
||||
usernameError.value = "";
|
||||
} else if (field === "password") {
|
||||
passwordError.value = "";
|
||||
}
|
||||
loginError.value = "";
|
||||
};
|
||||
const handleLogin = async () => {
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
isLoggingIn.value = true;
|
||||
loginError.value = "";
|
||||
try {
|
||||
const response = await mockLoginApi(username.value, password.value);
|
||||
if (response.success) {
|
||||
if (rememberMe.value) {
|
||||
uni.setStorageSync("yxd_username", username.value);
|
||||
} else {
|
||||
uni.removeStorageSync("yxd_username");
|
||||
}
|
||||
redirectUrl.value = response.redirectUrl;
|
||||
setTimeout(() => {
|
||||
openExternalLink();
|
||||
}, 2e3);
|
||||
}
|
||||
} catch (error) {
|
||||
loginError.value = error.message || "登录失败,请检查账号密码";
|
||||
} finally {
|
||||
isLoggingIn.value = false;
|
||||
}
|
||||
};
|
||||
function openExternalLink() {
|
||||
if (!redirectUrl.value)
|
||||
return;
|
||||
plus.runtime.openURL(redirectUrl.value);
|
||||
}
|
||||
const copyToClipboard = () => {
|
||||
if (!redirectUrl.value)
|
||||
return;
|
||||
uni.setClipboardData({
|
||||
data: redirectUrl.value,
|
||||
success: () => {
|
||||
copySuccess.value = true;
|
||||
setTimeout(() => {
|
||||
copySuccess.value = false;
|
||||
}, 2e3);
|
||||
}
|
||||
});
|
||||
};
|
||||
vue.onMounted(() => {
|
||||
const savedUsername = uni.getStorageSync("yxd_username");
|
||||
if (savedUsername) {
|
||||
username.value = savedUsername;
|
||||
rememberMe.value = true;
|
||||
}
|
||||
formatAppLog("log", "at pages/night-theme/night-theme.vue:267", "登录组件已挂载");
|
||||
});
|
||||
const __returned__ = { username, password, rememberMe, showPassword, isLoggingIn, redirectUrl, copySuccess, usernameError, passwordError, loginError, toggleRememberMe, mockLoginApi, validateForm, clearError, handleLogin, openExternalLink, copyToClipboard, ref: vue.ref, onMounted: vue.onMounted };
|
||||
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
||||
return __returned__;
|
||||
}
|
||||
};
|
||||
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
return vue.openBlock(), vue.createElementBlock("div", { class: "main-view" }, [
|
||||
vue.createElementVNode("div", { class: "container" }, [
|
||||
vue.createElementVNode("div", { class: "logo" }, [
|
||||
vue.createElementVNode("image", {
|
||||
src: _imports_0,
|
||||
alt: "YXD"
|
||||
})
|
||||
]),
|
||||
vue.createElementVNode("h1", null, "登录 YXD 智能应用"),
|
||||
vue.createElementVNode("div", { class: "login-form" }, [
|
||||
vue.createElementVNode("div", { class: "form-group" }, [
|
||||
vue.createElementVNode("label", { for: "username" }, "账号"),
|
||||
vue.withDirectives(vue.createElementVNode(
|
||||
"input",
|
||||
{
|
||||
id: "username",
|
||||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.username = $event),
|
||||
type: "text",
|
||||
placeholder: "请输入账号/邮箱/手机号",
|
||||
class: vue.normalizeClass({ "error": $setup.usernameError }),
|
||||
onInput: _cache[1] || (_cache[1] = ($event) => $setup.clearError("username"))
|
||||
},
|
||||
null,
|
||||
34
|
||||
/* CLASS, NEED_HYDRATION */
|
||||
), [
|
||||
[vue.vModelText, $setup.username]
|
||||
]),
|
||||
$setup.usernameError ? (vue.openBlock(), vue.createElementBlock(
|
||||
"div",
|
||||
{
|
||||
key: 0,
|
||||
class: "error-message"
|
||||
},
|
||||
vue.toDisplayString($setup.usernameError),
|
||||
1
|
||||
/* TEXT */
|
||||
)) : vue.createCommentVNode("v-if", true)
|
||||
]),
|
||||
vue.createElementVNode("div", { class: "form-group" }, [
|
||||
vue.createElementVNode("label", { for: "password" }, "密码"),
|
||||
vue.createElementVNode("div", { class: "password-input" }, [
|
||||
vue.withDirectives(vue.createElementVNode("input", {
|
||||
id: "password",
|
||||
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.password = $event),
|
||||
type: $setup.showPassword ? "text" : "password",
|
||||
placeholder: "请输入密码",
|
||||
class: vue.normalizeClass({ "error": $setup.passwordError }),
|
||||
onInput: _cache[3] || (_cache[3] = ($event) => $setup.clearError("password")),
|
||||
onKeyup: vue.withKeys($setup.handleLogin, ["enter"])
|
||||
}, null, 42, ["type"]), [
|
||||
[vue.vModelDynamic, $setup.password]
|
||||
]),
|
||||
vue.createElementVNode("button", {
|
||||
type: "button",
|
||||
class: "toggle-password",
|
||||
onClick: _cache[4] || (_cache[4] = ($event) => $setup.showPassword = !$setup.showPassword)
|
||||
}, [
|
||||
$setup.showPassword ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, "🙈")) : (vue.openBlock(), vue.createElementBlock("span", { key: 1 }, "👁️"))
|
||||
])
|
||||
]),
|
||||
$setup.passwordError ? (vue.openBlock(), vue.createElementBlock(
|
||||
"div",
|
||||
{
|
||||
key: 0,
|
||||
class: "error-message"
|
||||
},
|
||||
vue.toDisplayString($setup.passwordError),
|
||||
1
|
||||
/* TEXT */
|
||||
)) : vue.createCommentVNode("v-if", true)
|
||||
]),
|
||||
vue.createElementVNode("div", { class: "form-options" }, [
|
||||
vue.createElementVNode("label", {
|
||||
class: "remember-me",
|
||||
onClick: $setup.toggleRememberMe
|
||||
}, [
|
||||
vue.createElementVNode("div", { class: "custom-checkbox-wrapper" }, [
|
||||
vue.createElementVNode(
|
||||
"div",
|
||||
{
|
||||
class: vue.normalizeClass(["custom-checkbox", { "checked": $setup.rememberMe }])
|
||||
},
|
||||
[
|
||||
$setup.rememberMe ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, "✓")) : vue.createCommentVNode("v-if", true)
|
||||
],
|
||||
2
|
||||
/* CLASS */
|
||||
)
|
||||
]),
|
||||
vue.createElementVNode("span", null, "记住账号")
|
||||
])
|
||||
]),
|
||||
vue.createElementVNode("button", {
|
||||
class: "login-btn",
|
||||
onClick: $setup.handleLogin,
|
||||
disabled: $setup.isLoggingIn
|
||||
}, [
|
||||
$setup.isLoggingIn ? (vue.openBlock(), vue.createElementBlock("span", { key: 0 }, "⏳")) : (vue.openBlock(), vue.createElementBlock("span", { key: 1 }, "🔑")),
|
||||
vue.createTextVNode(
|
||||
" " + vue.toDisplayString($setup.isLoggingIn ? "登录中..." : "立即登录"),
|
||||
1
|
||||
/* TEXT */
|
||||
)
|
||||
], 8, ["disabled"]),
|
||||
$setup.loginError ? (vue.openBlock(), vue.createElementBlock("div", {
|
||||
key: 0,
|
||||
class: "login-error"
|
||||
}, [
|
||||
vue.createElementVNode("span", null, "⚠️"),
|
||||
vue.createTextVNode(
|
||||
" " + vue.toDisplayString($setup.loginError),
|
||||
1
|
||||
/* TEXT */
|
||||
)
|
||||
])) : vue.createCommentVNode("v-if", true),
|
||||
$setup.redirectUrl ? (vue.openBlock(), vue.createElementBlock("div", {
|
||||
key: 1,
|
||||
class: "redirect-section"
|
||||
}, [
|
||||
vue.createElementVNode("div", { class: "success-message" }, [
|
||||
vue.createElementVNode("span", null, "✅"),
|
||||
vue.createTextVNode(" 登录成功!正在为您跳转... ")
|
||||
])
|
||||
])) : vue.createCommentVNode("v-if", true)
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
const PagesNightThemeNightTheme = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__scopeId", "data-v-197fbf56"], ["__file", "D:/Projects/uniapp/app-test/fronted-phone/pages/night-theme/night-theme.vue"]]);
|
||||
__definePage("pages/light-theme/light-theme", PagesLightThemeLightTheme);
|
||||
__definePage("pages/index/index", PagesIndexIndex);
|
||||
__definePage("pages/night-theme/night-theme", PagesNightThemeNightTheme);
|
||||
const _sfc_main = {
|
||||
onLaunch: function() {
|
||||
formatAppLog("log", "at App.vue:4", "App Launch");
|
||||
},
|
||||
onShow: function() {
|
||||
formatAppLog("log", "at App.vue:7", "App Show");
|
||||
},
|
||||
onHide: function() {
|
||||
formatAppLog("log", "at App.vue:10", "App Hide");
|
||||
}
|
||||
};
|
||||
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "D:/Projects/uniapp/app-test/fronted-phone/App.vue"]]);
|
||||
function createApp() {
|
||||
const app = vue.createVueApp(App);
|
||||
return {
|
||||
app
|
||||
};
|
||||
}
|
||||
const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp();
|
||||
uni.Vuex = __Vuex__;
|
||||
uni.Pinia = __Pinia__;
|
||||
__app__.provide("__globalStyles", __uniConfig.styles);
|
||||
__app__._component.mpType = "app";
|
||||
__app__._component.render = () => {
|
||||
};
|
||||
__app__.mount("#app");
|
||||
})(Vue);
|
||||
15
unpackage/dist/dev/app-plus/app.css
vendored
Normal file
15
unpackage/dist/dev/app-plus/app.css
vendored
Normal file
File diff suppressed because one or more lines are too long
107
unpackage/dist/dev/app-plus/manifest.json
vendored
Normal file
107
unpackage/dist/dev/app-plus/manifest.json
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"@platforms": [
|
||||
"android",
|
||||
"iPhone",
|
||||
"iPad"
|
||||
],
|
||||
"id": "__UNI__B742B9E",
|
||||
"name": "111",
|
||||
"version": {
|
||||
"name": "1.0.0",
|
||||
"code": "100"
|
||||
},
|
||||
"description": "",
|
||||
"developer": {
|
||||
"name": "",
|
||||
"email": "",
|
||||
"url": ""
|
||||
},
|
||||
"permissions": {
|
||||
"UniNView": {
|
||||
"description": "UniNView原生渲染"
|
||||
}
|
||||
},
|
||||
"plus": {
|
||||
"useragent": {
|
||||
"value": "uni-app",
|
||||
"concatenate": true
|
||||
},
|
||||
"splashscreen": {
|
||||
"target": "id:1",
|
||||
"autoclose": true,
|
||||
"waiting": true,
|
||||
"delay": 0
|
||||
},
|
||||
"popGesture": "close",
|
||||
"launchwebview": {
|
||||
"render": "always",
|
||||
"id": "1",
|
||||
"kernel": "WKWebview"
|
||||
},
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"distribute": {
|
||||
"google": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
"apple": {},
|
||||
"plugins": {
|
||||
"audio": {
|
||||
"mp3": {
|
||||
"description": "Android平台录音支持MP3格式文件"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"statusbar": {
|
||||
"immersed": "supportedDevice",
|
||||
"style": "dark",
|
||||
"background": "#F8F8F8"
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"allowsInlineMediaPlayback": true,
|
||||
"uni-app": {
|
||||
"control": "uni-v3",
|
||||
"vueVersion": "3",
|
||||
"compilerVersion": "4.87",
|
||||
"nvueCompiler": "uni-app",
|
||||
"renderer": "auto",
|
||||
"nvue": {
|
||||
"flex-direction": "column"
|
||||
},
|
||||
"nvueLaunchMode": "normal",
|
||||
"webView": {
|
||||
"minUserAgentVersion": "49.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app-harmony": {
|
||||
"useragent": {
|
||||
"value": "uni-app",
|
||||
"concatenate": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
"launch_path": "__uniappview.html"
|
||||
}
|
||||
198
unpackage/dist/dev/app-plus/pages/index/index.css
vendored
Normal file
198
unpackage/dist/dev/app-plus/pages/index/index.css
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
|
||||
*[data-v-1cf27b2a] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
body[data-v-1cf27b2a] {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background: linear-gradient(135deg, #0f1419 0, #1a1f2e 100%);
|
||||
}
|
||||
.main-view[data-v-1cf27b2a] {
|
||||
z-index: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: radial-gradient(ellipse at center, #0f1419 0%, #0a0e1a 70%);
|
||||
color: #e8f4f8;
|
||||
}
|
||||
.container[data-v-1cf27b2a] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: auto;
|
||||
height: 90vh;
|
||||
max-width: 500px;
|
||||
background: rgba(26, 31, 46, .8);
|
||||
border: 1px solid rgba(139, 195, 232, 0.2);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
/* box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); */
|
||||
box-shadow: 0 0 30px rgba(139, 195, 232, 0.5);
|
||||
text-align: center;
|
||||
/* align-items: center; */
|
||||
justify-content: center;
|
||||
padding: 40px 30px;
|
||||
margin: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.logo[data-v-1cf27b2a] {
|
||||
z-index: 1;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto 25px;
|
||||
background: rgba(139, 195, 232, 0.2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 40px;
|
||||
box-shadow: 0 0 20px rgba(139, 195, 232, 0.3);
|
||||
overflow: hidden;
|
||||
/* 确保图片不会超出圆形容器 */
|
||||
padding: 10px;
|
||||
/* 增加内边距,让图片与边缘有间距 */
|
||||
}
|
||||
.logo uni-image[data-v-1cf27b2a] {
|
||||
z-index: 2;
|
||||
max-width: 100%;
|
||||
/* 图片最大宽度不超过容器 */
|
||||
max-height: 100%;
|
||||
/* 图片最大高度不超过容器 */
|
||||
object-fit: contain;
|
||||
/* 保持图片比例,完整显示在容器内 */
|
||||
display: block;
|
||||
/* 去除图片底部可能出现的空白 */
|
||||
/* border-radius: 50%;
|
||||
box-shadow: 0 0 20px rgba(139, 195, 232, 0.1); */
|
||||
}
|
||||
|
||||
/* h1 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 15px;
|
||||
font-size: 24px;
|
||||
background: linear-gradient(135deg, #8bc3e8, #6ba3d6);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 5px rgba(74, 139, 194, 0.2));
|
||||
} */
|
||||
h1[data-v-1cf27b2a] {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 2px;
|
||||
background: linear-gradient(135deg, #8bc3e8, #6ba3d6);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
/* margin-bottom: 10px; */
|
||||
filter: drop-shadow(0 0 5px rgba(74, 139, 194, 0.2));
|
||||
text-shadow: 0 0 10px rgba(139, 195, 232, 0.3);
|
||||
}
|
||||
.description[data-v-1cf27b2a] {
|
||||
color: #9db4c0;
|
||||
font-size: 0.9rem;
|
||||
margin: 20px;
|
||||
}
|
||||
.url-display[data-v-1cf27b2a] {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 25px;
|
||||
border: 1px solid #eaeaea;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
color: #5a6570;
|
||||
}
|
||||
.access-btn[data-v-1cf27b2a] {
|
||||
background: linear-gradient(135deg, #8bc3e8, #6ba3d6);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 16px 40px;
|
||||
border-radius: 20px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
/* box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15); */
|
||||
box-shadow: 0 0 20px rgba(139, 195, 232, 0.3);
|
||||
display: inline-block;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
.access-btn[data-v-1cf27b2a]:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.access-btn[data-v-1cf27b2a]:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.access-btn[data-v-1cf27b2a]:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.loading-container[data-v-1cf27b2a] {
|
||||
margin: 20px 0;
|
||||
display: none;
|
||||
}
|
||||
.spinner[data-v-1cf27b2a] {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin-1cf27b2a 1s linear infinite;
|
||||
margin: 0 auto 15px;
|
||||
}
|
||||
@keyframes spin-1cf27b2a {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loading-text[data-v-1cf27b2a] {
|
||||
font-size: 16px;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
.alternative[data-v-1cf27b2a] {
|
||||
margin-top: 25px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #eaeaea;
|
||||
font-size: 14px;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
.alternative a[data-v-1cf27b2a] {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
.alternative a[data-v-1cf27b2a]:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.container[data-v-1cf27b2a] {
|
||||
padding: 30px 20px;
|
||||
}
|
||||
h1[data-v-1cf27b2a] {
|
||||
font-size: 22px;
|
||||
}
|
||||
.access-btn[data-v-1cf27b2a] {
|
||||
padding: 14px 30px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
470
unpackage/dist/dev/app-plus/pages/light-theme/light-theme.css
vendored
Normal file
470
unpackage/dist/dev/app-plus/pages/light-theme/light-theme.css
vendored
Normal file
@@ -0,0 +1,470 @@
|
||||
|
||||
*[data-v-68542e3f] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
body[data-v-68542e3f] {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background: linear-gradient(135deg, #f8fcff 0%, #f0f8ff 100%);
|
||||
}
|
||||
.main-view[data-v-68542e3f] {
|
||||
z-index: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #f8fcff 0%, #f0f8ff 100%);
|
||||
color: #333;
|
||||
}
|
||||
.container[data-v-68542e3f] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 15px 35px rgba(33, 150, 243, 0.08),
|
||||
0 5px 15px rgba(0, 0, 0, 0.05),
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.9);
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 45px 35px;
|
||||
margin: 10px;
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.logo[data-v-68542e3f] {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin: 0 auto 30px;
|
||||
background: linear-gradient(135deg, rgba(33, 150, 243, 0.1), rgba(100, 181, 246, 0.15));
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
box-shadow:
|
||||
0 8px 25px rgba(33, 150, 243, 0.12),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.9),
|
||||
inset 0 0 15px rgba(255, 255, 255, 0.8);
|
||||
overflow: hidden;
|
||||
padding: 12px;
|
||||
position: relative;
|
||||
}
|
||||
.logo[data-v-68542e3f]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.6));
|
||||
z-index: 1;
|
||||
}
|
||||
.logo uni-image[data-v-68542e3f] {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
filter: drop-shadow(0 2px 5px rgba(33, 150, 243, 0.3));
|
||||
}
|
||||
h1[data-v-68542e3f] {
|
||||
font-size: 2.1rem;
|
||||
font-weight: 700;
|
||||
color: #1565c0;
|
||||
margin-bottom: 18px;
|
||||
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.description[data-v-68542e3f] {
|
||||
color: #5d7b9f;
|
||||
font-size: 0.95rem;
|
||||
margin: 0 0 30px 0;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
}
|
||||
.login-form[data-v-68542e3f] {
|
||||
width: 100%;
|
||||
}
|
||||
.form-group[data-v-68542e3f] {
|
||||
margin-bottom: 22px;
|
||||
text-align: left;
|
||||
}
|
||||
.form-group uni-label[data-v-68542e3f] {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
color: #2c5282;
|
||||
font-size: 14px;
|
||||
}
|
||||
.form-group uni-input[data-v-68542e3f] {
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 12px;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.form-group uni-input .uni-input-input[data-v-68542e3f] {
|
||||
width: 100%;
|
||||
padding: 15px 18px;
|
||||
border: 1px solid #e1f5fe;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow:
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.04),
|
||||
0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
color: #2c3e50 !important;
|
||||
}
|
||||
.form-group uni-input .uni-input-input[data-v-68542e3f]:focus {
|
||||
outline: none;
|
||||
border-color: #4fc3f7;
|
||||
background: white;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(79, 195, 247, 0.2),
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
.form-group uni-input .uni-input-input[data-v-68542e3f]::-webkit-input-placeholder {
|
||||
color: #90a4ae !important;
|
||||
}
|
||||
.form-group uni-input .uni-input-input[data-v-68542e3f]::placeholder {
|
||||
color: #90a4ae !important;
|
||||
}
|
||||
.form-group uni-input .uni-input-input.error[data-v-68542e3f] {
|
||||
border-color: #ff7043;
|
||||
background: rgba(255, 112, 67, 0.03);
|
||||
}
|
||||
.form-group uni-input[data-v-68542e3f]:focus {
|
||||
outline: none;
|
||||
border-color: #4fc3f7;
|
||||
background: white;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(79, 195, 247, 0.2),
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
.form-group uni-input[data-v-68542e3f]::-webkit-input-placeholder {
|
||||
color: #90a4ae !important;
|
||||
}
|
||||
.form-group uni-input[data-v-68542e3f]::placeholder {
|
||||
color: #90a4ae !important;
|
||||
}
|
||||
.form-group uni-input.error[data-v-68542e3f] {
|
||||
border-color: #ff7043;
|
||||
background: rgba(255, 112, 67, 0.03);
|
||||
}
|
||||
.error-message[data-v-68542e3f] {
|
||||
color: #ff7043;
|
||||
font-size: 13px;
|
||||
margin-top: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.password-input[data-v-68542e3f] {
|
||||
position: relative;
|
||||
}
|
||||
.password-input uni-button[data-v-68542e3f]::after,
|
||||
.password-input uni-button[data-v-68542e3f]::before {
|
||||
border: none
|
||||
}
|
||||
.toggle-password[data-v-68542e3f] {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
transition: all 0.2s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* .toggle-password:hover {
|
||||
color: #2196f3;
|
||||
border-color: #4fc3f7;
|
||||
background: white;
|
||||
box-shadow: 0 2px 5px rgba(33, 150, 243, 0.15);
|
||||
} */
|
||||
.toggle-password span[data-v-68542e3f] {
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.form-options[data-v-68542e3f] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.remember-me[data-v-68542e3f] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #5d7b9f;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
.custom-checkbox[data-v-68542e3f] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.custom-checkbox.checked[data-v-68542e3f] {
|
||||
/* background: #3b82f6; */
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
.custom-checkbox.checked i[data-v-68542e3f] {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* uni-checkbox样式 */
|
||||
.remember-me uni-checkbox[data-v-68542e3f] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.remember-me uni-checkbox[data-v-68542e3f]:checked {
|
||||
background: #3b82f6;
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
.remember-me uni-checkbox[data-v-68542e3f]:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.remember-me uni-checkbox[data-v-68542e3f]:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
.forgot-password[data-v-68542e3f] {
|
||||
color: #29b6f6;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.forgot-password[data-v-68542e3f]:hover {
|
||||
color: #0288d1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.login-btn[data-v-68542e3f] {
|
||||
background: linear-gradient(135deg, #29b6f6, #0288d1);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 6px 20px rgba(41, 182, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.login-btn[data-v-68542e3f]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
.login-btn[data-v-68542e3f]:hover:not(:disabled)::before {
|
||||
left: 100%;
|
||||
}
|
||||
.login-btn[data-v-68542e3f]:hover:not(:disabled) {
|
||||
transform: translateY(-3px);
|
||||
box-shadow:
|
||||
0 10px 25px rgba(41, 182, 246, 0.4),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.3);
|
||||
background: linear-gradient(135deg, #4fc3f7, #039be5);
|
||||
}
|
||||
.login-btn[data-v-68542e3f]:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(41, 182, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.login-btn[data-v-68542e3f]:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
}
|
||||
.login-error[data-v-68542e3f] {
|
||||
margin-top: 18px;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, rgba(255, 112, 67, 0.08), rgba(255, 112, 67, 0.05));
|
||||
border: 1px solid #ffccbc;
|
||||
border-radius: 12px;
|
||||
color: #e64a19;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 8px rgba(255, 112, 67, 0.08);
|
||||
}
|
||||
.redirect-section[data-v-68542e3f] {
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
border-top: 1px solid #e1f5fe;
|
||||
animation: fadeIn-68542e3f 0.5s ease;
|
||||
}
|
||||
@keyframes fadeIn-68542e3f {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(15px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.success-message[data-v-68542e3f] {
|
||||
color: #00c853;
|
||||
font-weight: 600;
|
||||
margin-bottom: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
.url-display[data-v-68542e3f] {
|
||||
background: linear-gradient(135deg, #f8fdff, #e3f2fd);
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 18px;
|
||||
border: 1px solid #bbdefb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.url-display uni-input[data-v-68542e3f] {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
color: #1565c0;
|
||||
outline: none;
|
||||
font-family: 'Monaco', 'Consolas', monospace;
|
||||
font-weight: 500;
|
||||
}
|
||||
.copy-btn[data-v-68542e3f] {
|
||||
background: white;
|
||||
border: 1px solid #bbdefb;
|
||||
border-radius: 8px;
|
||||
padding: 9px 14px;
|
||||
color: #29b6f6;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.copy-btn[data-v-68542e3f]:hover {
|
||||
background: #e3f2fd;
|
||||
color: #0288d1;
|
||||
border-color: #90caf9;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.access-btn[data-v-68542e3f] {
|
||||
background: linear-gradient(135deg, #26c6da, #0097a7);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 6px 20px rgba(38, 198, 218, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.access-btn[data-v-68542e3f]:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 10px 25px rgba(38, 198, 218, 0.35),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.3);
|
||||
background: linear-gradient(135deg, #4dd0e1, #00acc1);
|
||||
}
|
||||
.access-btn[data-v-68542e3f]:active {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(38, 198, 218, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.container[data-v-68542e3f] {
|
||||
padding: 35px 25px;
|
||||
}
|
||||
h1[data-v-68542e3f] {
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
.form-options[data-v-68542e3f] {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 15px;
|
||||
}
|
||||
.logo[data-v-68542e3f] {
|
||||
width: 95px;
|
||||
height: 95px;
|
||||
}
|
||||
}
|
||||
500
unpackage/dist/dev/app-plus/pages/night-theme/night-theme.css
vendored
Normal file
500
unpackage/dist/dev/app-plus/pages/night-theme/night-theme.css
vendored
Normal file
@@ -0,0 +1,500 @@
|
||||
|
||||
*[data-v-197fbf56] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* 移除全局body样式,改为在main-view中设置背景 */
|
||||
.main-view[data-v-197fbf56] {
|
||||
z-index: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #0a0e17 0%, #131826 100%);
|
||||
color: #e8f4f8;
|
||||
}
|
||||
.container[data-v-197fbf56] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: linear-gradient(135deg, rgba(23, 32, 56, 0.9), rgba(19, 28, 46, 0.95));
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
box-shadow:
|
||||
0 20px 50px rgba(0, 10, 30, 0.5),
|
||||
0 0 0 1px rgba(59, 130, 246, 0.15),
|
||||
inset 0 0 30px rgba(0, 0, 0, 0.5);
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 45px 35px;
|
||||
margin: 10px;
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
.logo[data-v-197fbf56] {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin: 0 auto 30px;
|
||||
background: linear-gradient(135deg, rgba(23, 32, 56, 0.8), rgba(59, 130, 246, 0.2));
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
box-shadow:
|
||||
0 10px 30px rgba(0, 0, 0, 0.5),
|
||||
0 0 0 1px rgba(59, 130, 246, 0.3),
|
||||
inset 0 0 20px rgba(59, 130, 246, 0.2);
|
||||
overflow: hidden;
|
||||
padding: 12px;
|
||||
position: relative;
|
||||
}
|
||||
.logo[data-v-197fbf56]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(59, 130, 246, 0.05));
|
||||
z-index: 1;
|
||||
}
|
||||
.logo uni-image[data-v-197fbf56] {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
filter: drop-shadow(0 0 10px rgba(59, 130, 246, 0.5));
|
||||
}
|
||||
h1[data-v-197fbf56] {
|
||||
font-size: 2.1rem;
|
||||
font-weight: 700;
|
||||
color: #60a5fa;
|
||||
margin-bottom: 18px;
|
||||
text-shadow: 0 0 15px rgba(96, 165, 250, 0.5);
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.description[data-v-197fbf56] {
|
||||
color: #93c5fd;
|
||||
font-size: 0.95rem;
|
||||
margin: 0 0 30px 0;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.login-form[data-v-197fbf56] {
|
||||
width: 100%;
|
||||
}
|
||||
.form-group[data-v-197fbf56] {
|
||||
margin-bottom: 22px;
|
||||
text-align: left;
|
||||
}
|
||||
.form-group uni-label[data-v-197fbf56] {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 500;
|
||||
color: #93c5fd;
|
||||
font-size: 14px;
|
||||
}
|
||||
.form-group uni-input[data-v-197fbf56] {
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 12px;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.form-group uni-input .uni-input-input[data-v-197fbf56] {
|
||||
width: 100%;
|
||||
padding: 15px 20px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(15, 23, 42, 0.8);
|
||||
box-shadow:
|
||||
inset 0 2px 10px rgba(0, 0, 0, 0.3),
|
||||
0 1px 0 rgba(255, 255, 255, 0.05);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
/* 修复输入框无法选中的问题 */
|
||||
.form-group uni-input .uni-input-input[data-v-197fbf56] {
|
||||
pointer-events: auto !important;
|
||||
user-select: auto !important;
|
||||
-webkit-user-select: auto !important;
|
||||
-moz-user-select: auto !important;
|
||||
-ms-user-select: auto !important;
|
||||
}
|
||||
.form-group uni-input[data-v-197fbf56]:focus {
|
||||
outline: none;
|
||||
border-color: #3b82f6;
|
||||
background: rgba(15, 23, 42, 0.9);
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(59, 130, 246, 0.2),
|
||||
inset 0 2px 10px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.form-group uni-input[data-v-197fbf56]::-webkit-input-placeholder {
|
||||
color: #64748b;
|
||||
}
|
||||
.form-group uni-input[data-v-197fbf56]::placeholder {
|
||||
color: #64748b;
|
||||
}
|
||||
.form-group uni-input.error[data-v-197fbf56] {
|
||||
border-color: #ef4444;
|
||||
background: rgba(239, 68, 68, 0.05);
|
||||
}
|
||||
.error-message[data-v-197fbf56] {
|
||||
color: #fca5a5;
|
||||
font-size: 13px;
|
||||
margin-top: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.password-input[data-v-197fbf56] {
|
||||
position: relative;
|
||||
}
|
||||
.toggle-password[data-v-197fbf56] {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
transition: all 0.2s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* .toggle-password:hover {
|
||||
color: #60a5fa;
|
||||
border-color: #3b82f6;
|
||||
background: rgba(30, 41, 59, 0.9);
|
||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.2);
|
||||
} */
|
||||
.toggle-password span[data-v-197fbf56] {
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.form-options[data-v-197fbf56] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.remember-me[data-v-197fbf56] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
.custom-checkbox[data-v-197fbf56] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.custom-checkbox.checked[data-v-197fbf56] {
|
||||
/* background: #3b82f6; */
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
.custom-checkbox.checked i[data-v-197fbf56] {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 对✓字符加粗效果有限 */
|
||||
/* .custom-checkbox span {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
} */
|
||||
|
||||
/* checkbox样式 */
|
||||
/* .remember-me uni-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 4px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:checked {
|
||||
background: #3b82f6;
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.remember-me uni-checkbox:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
|
||||
} */
|
||||
.forgot-password[data-v-197fbf56] {
|
||||
color: #60a5fa;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.forgot-password[data-v-197fbf56]:hover {
|
||||
color: #3b82f6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.login-btn[data-v-197fbf56] {
|
||||
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 8px 25px rgba(59, 130, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.login-btn span[data-v-197fbf56] {
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.login-btn:disabled span[data-v-197fbf56] {
|
||||
animation: spin-197fbf56 1s linear infinite;
|
||||
}
|
||||
@keyframes spin-197fbf56 {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.login-btn[data-v-197fbf56]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
.login-btn[data-v-197fbf56]:hover:not(:disabled)::before {
|
||||
left: 100%;
|
||||
}
|
||||
.login-btn[data-v-197fbf56]:hover:not(:disabled) {
|
||||
transform: translateY(-3px);
|
||||
box-shadow:
|
||||
0 12px 30px rgba(59, 130, 246, 0.4),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
background: linear-gradient(135deg, #60a5fa, #2563eb);
|
||||
}
|
||||
.login-btn[data-v-197fbf56]:active:not(:disabled) {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(59, 130, 246, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.login-btn[data-v-197fbf56]:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none !important;
|
||||
}
|
||||
.login-error[data-v-197fbf56] {
|
||||
margin-top: 18px;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05));
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
border-radius: 12px;
|
||||
color: #fca5a5;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
.login-error span[data-v-197fbf56] {
|
||||
font-size: 16px;
|
||||
}
|
||||
.redirect-section[data-v-197fbf56] {
|
||||
margin-top: 30px;
|
||||
padding-top: 30px;
|
||||
border-top: 1px solid rgba(59, 130, 246, 0.2);
|
||||
animation: fadeIn-197fbf56 0.5s ease;
|
||||
}
|
||||
@keyframes fadeIn-197fbf56 {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(15px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.success-message[data-v-197fbf56] {
|
||||
color: #4ade80;
|
||||
font-weight: 600;
|
||||
margin-bottom: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 15px;
|
||||
text-shadow: 0 0 10px rgba(74, 222, 128, 0.3);
|
||||
}
|
||||
.success-message span[data-v-197fbf56] {
|
||||
font-size: 16px;
|
||||
}
|
||||
.url-display[data-v-197fbf56] {
|
||||
background: linear-gradient(135deg, rgba(15, 23, 42, 0.8), rgba(30, 41, 59, 0.8));
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 18px;
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.url-display uni-input[data-v-197fbf56] {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 14px;
|
||||
color: #60a5fa;
|
||||
outline: none;
|
||||
font-family: 'Monaco', 'Consolas', monospace;
|
||||
font-weight: 500;
|
||||
pointer-events: auto !important;
|
||||
-webkit-user-select: auto !important;
|
||||
user-select: auto !important;
|
||||
}
|
||||
.copy-btn[data-v-197fbf56] {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 9px 14px;
|
||||
color: #93c5fd;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.copy-btn span[data-v-197fbf56] {
|
||||
font-size: 16px;
|
||||
}
|
||||
.copy-btn[data-v-197fbf56]:hover {
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
color: #60a5fa;
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.access-btn[data-v-197fbf56] {
|
||||
background: linear-gradient(135deg, #0ea5e9, #0369a1);
|
||||
color: white;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 8px 25px rgba(14, 165, 233, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.access-btn span[data-v-197fbf56] {
|
||||
font-size: 16px;
|
||||
}
|
||||
.access-btn[data-v-197fbf56]:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 12px 30px rgba(14, 165, 233, 0.35),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
background: linear-gradient(135deg, #38bdf8, #0284c7);
|
||||
}
|
||||
.access-btn[data-v-197fbf56]:active {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(14, 165, 233, 0.25),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.container[data-v-197fbf56] {
|
||||
padding: 35px 25px;
|
||||
}
|
||||
h1[data-v-197fbf56] {
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
.form-options[data-v-197fbf56] {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 15px;
|
||||
}
|
||||
.logo[data-v-197fbf56] {
|
||||
width: 95px;
|
||||
height: 95px;
|
||||
}
|
||||
.form-group uni-input uni-input[data-v-197fbf56] {
|
||||
padding: 14px 16px;
|
||||
}
|
||||
}
|
||||
BIN
unpackage/dist/dev/app-plus/static/logo.png
vendored
Normal file
BIN
unpackage/dist/dev/app-plus/static/logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
7
unpackage/dist/dev/app-plus/uni-app-view.umd.js
vendored
Normal file
7
unpackage/dist/dev/app-plus/uni-app-view.umd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
unpackage/dist/dev/cache/.app-plus/tsc/app-android/.tsbuildInfo
vendored
Normal file
1
unpackage/dist/dev/cache/.app-plus/tsc/app-android/.tsbuildInfo
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user