first commit

This commit is contained in:
2026-01-14 14:24:58 +08:00
commit 3ccc482933
37 changed files with 4395 additions and 0 deletions

9
.hbuilderx/launch.json Normal file
View File

@@ -0,0 +1,9 @@
{
"version" : "1.0",
"configurations" : [
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

28
App.vue Normal file
View 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
View 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
View 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
View 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
View 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
View 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>

View 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>

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

13
uni.promisify.adaptor.js Normal file
View 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
View 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;

View File

@@ -0,0 +1,8 @@
{
"hash": "e66e26ef",
"configHash": "95216d54",
"lockfileHash": "e3b0c442",
"browserHash": "965e6bcf",
"optimized": {},
"chunks": {}
}

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

11
unpackage/dist/dev/.nvue/app.css.js vendored Normal file
View 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
View File

@@ -0,0 +1,2 @@
Promise.resolve("./app.css.js").then(() => {
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View 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>

View 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}}}});
})();

View File

@@ -0,0 +1 @@
(function(){})();

View 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

File diff suppressed because one or more lines are too long

View 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"
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long