初始化
This commit is contained in:
commit
5ca705b074
|
@ -0,0 +1,21 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<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="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"name": "uni-preset-vue",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev:custom": "uni -p",
|
||||
"dev:h5": "uni",
|
||||
"dev:h5:ssr": "uni --ssr",
|
||||
"dev:mp-alipay": "uni -p mp-alipay",
|
||||
"dev:mp-baidu": "uni -p mp-baidu",
|
||||
"dev:mp-jd": "uni -p mp-jd",
|
||||
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
||||
"dev:mp-lark": "uni -p mp-lark",
|
||||
"dev:mp-qq": "uni -p mp-qq",
|
||||
"dev:mp-toutiao": "uni -p mp-toutiao",
|
||||
"dev:mp-weixin": "uni -p mp-weixin",
|
||||
"dev:mp-xhs": "uni -p mp-xhs",
|
||||
"dev:quickapp-webview": "uni -p quickapp-webview",
|
||||
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
||||
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
||||
"build:custom": "uni build -p",
|
||||
"build:h5": "uni build",
|
||||
"build:h5:ssr": "uni build --ssr",
|
||||
"build:mp-alipay": "uni build -p mp-alipay",
|
||||
"build:mp-baidu": "uni build -p mp-baidu",
|
||||
"build:mp-jd": "uni build -p mp-jd",
|
||||
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||
"build:mp-lark": "uni build -p mp-lark",
|
||||
"build:mp-qq": "uni build -p mp-qq",
|
||||
"build:mp-toutiao": "uni build -p mp-toutiao",
|
||||
"build:mp-weixin": "uni build -p mp-weixin",
|
||||
"build:mp-xhs": "uni build -p mp-xhs",
|
||||
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-app-harmony": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-app-plus": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-components": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-h5": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-alipay": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-baidu": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-jd": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-kuaishou": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-lark": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-qq": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-toutiao": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-weixin": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-mp-xhs": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-quickapp-webview": "3.0.0-4040520250104002",
|
||||
"axios": "^1.8.4",
|
||||
"vue": "^3.4.21",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dcloudio/types": "^3.4.8",
|
||||
"@dcloudio/uni-automator": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-cli-shared": "3.0.0-4040520250104002",
|
||||
"@dcloudio/uni-stacktracey": "3.0.0-4040520250104002",
|
||||
"@dcloudio/vite-plugin-uni": "3.0.0-4040520250104002",
|
||||
"@dcloudio/vue-cli-plugin-uni": "^2.0.2-4040520250103001",
|
||||
"@vue/runtime-core": "^3.4.21",
|
||||
"vite": "5.2.8"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/// <reference types='@dcloudio/types' />
|
||||
import 'vue'
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
|
||||
interface ComponentCustomOptions extends Hooks {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<script>
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function () {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
console.log('App Hide')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/*每个页面公共css */
|
||||
</style>
|
|
@ -0,0 +1,10 @@
|
|||
import {
|
||||
createSSRApp
|
||||
} from "vue";
|
||||
import App from "./App.vue";
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
return {
|
||||
app,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"name" : "",
|
||||
"appid" : "",
|
||||
"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"
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/Homepage/Homepage",
|
||||
"style": {
|
||||
"navigationBarTitleText": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/Profession/profession",
|
||||
"style": {
|
||||
"navigationBarTitleText": "职业测试"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/protest/protest",
|
||||
"style": {
|
||||
"navigationBarTitleText": "职业开始测试"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/proresult/proresult",
|
||||
"style": {
|
||||
"navigationBarTitleText": "测试结果"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "MBTI性格测试"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/test/test",
|
||||
"style": {
|
||||
"navigationBarTitleText": "开始测试"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/result/result",
|
||||
"style": {
|
||||
"navigationBarTitleText": "测试结果"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "MBTI性格测试",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<div class="button-container">
|
||||
<button class="custom-button" @click="goToPersonalityTest">性格测试</button>
|
||||
<button class="custom-button" @click="goToProfessionTest">职业测试</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
|
||||
methods: {
|
||||
goToPersonalityTest() {
|
||||
const targetUrl = '/pages/index/index'; // 目标路径
|
||||
console.log('目标路径:', targetUrl); // 打印目标路径,确保路径正确
|
||||
try {
|
||||
// 使用 navigateTo 进行跳转
|
||||
uni.navigateTo ({
|
||||
url: targetUrl
|
||||
});
|
||||
console.log('跳转成功');
|
||||
} catch (error) {
|
||||
console.error('跳转失败:', error);
|
||||
}
|
||||
|
||||
console.log('111');
|
||||
},
|
||||
goToProfessionTest() {
|
||||
console.log('职业测试按钮被点击了'); // 打印调试信息
|
||||
uni.navigateTo({
|
||||
url: '/pages/Profession/profession' // 跳转到职业测试页面
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.custom-button {
|
||||
margin: 20px 0;
|
||||
padding: 18px 0; /* 适当增加上下内边距让按钮在垂直方向更饱满 */
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
background-image: url('../../static/homepage-background.jpg'); /* 使用示例图片,可替换为实际背景图URL */
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
color: white;
|
||||
font-size: 20px; /* 增大字体大小 */
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
width: 80%; /* 增大按钮宽度,这里设置为容器宽度的80% */
|
||||
max-width: 400px; /* 限制最大宽度,避免在大屏幕上过宽 */
|
||||
}
|
||||
|
||||
.custom-button:hover {
|
||||
transform: scale(1.05); /* 鼠标悬停时按钮稍微放大 */
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 鼠标悬停时添加阴影效果 */
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="header">
|
||||
<text class="title">职业倾向测试</text>
|
||||
<text class="subtitle">探索适合你的职业方向</text>
|
||||
</view>
|
||||
|
||||
<view class="description">
|
||||
<text>本职业倾向测试将帮助你了解自己适合的职业类型。本次测试共有60道题,约需15分钟,请选择开始测试:</text>
|
||||
</view>
|
||||
|
||||
<view class="test-options">
|
||||
<view class="test-card" @click="startTest">
|
||||
<text class="card-title">开始测试</text>
|
||||
<text class="card-subtitle">60题 · 约15分钟</text>
|
||||
<text class="card-description">全面了解你的职业倾向</text>
|
||||
<button class="start-button primary">开始测试</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '职业倾向测试'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startTest() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/protest/protest`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 40rpx;
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.description {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 40rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.test-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.test-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 40rpx;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.card-description {
|
||||
font-size: 26rpx;
|
||||
color: #888;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.start-button {
|
||||
width: 80%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.start-button.primary {
|
||||
background-color: #4CAF50;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.test-card:hover {
|
||||
transform: translateY(-2rpx);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<view class="header">
|
||||
<text class="title">MBTI性格测试</text>
|
||||
<text class="subtitle">了解你的性格类型</text>
|
||||
</view>
|
||||
|
||||
<view class="description">
|
||||
<text>MBTI(迈尔斯-布里格斯类型指标)是一个帮助你了解自己性格特征的测试工具。请选择适合您的测试版本:</text>
|
||||
</view>
|
||||
|
||||
<view class="test-options">
|
||||
<view class="test-card" @click="startTest('simple')">
|
||||
<text class="card-title">简单版</text>
|
||||
<text class="card-subtitle">40题 · 约10分钟</text>
|
||||
<text class="card-description">适合快速了解自己的性格类型</text>
|
||||
<button class="start-button primary">开始测试</button>
|
||||
</view>
|
||||
|
||||
<view class="test-card" @click="startTest('detailed')">
|
||||
<text class="card-title">详细版</text>
|
||||
<text class="card-subtitle">80题 · 约20分钟</text>
|
||||
<text class="card-description">提供更准确的性格分析结果</text>
|
||||
<button class="start-button">开始测试</button>
|
||||
</view>
|
||||
|
||||
<view class="test-card" @click="startTest('full')">
|
||||
<text class="card-title">超详细版</text>
|
||||
<text class="card-subtitle">120题 · 约30分钟</text>
|
||||
<text class="card-description">最全面的性格测试体验</text>
|
||||
<button class="start-button">开始测试</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'MBTI性格测试'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startTest(type) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/test/test?type=${type}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 40rpx;
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.description {
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 40rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.test-options {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.test-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 40rpx;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.card-description {
|
||||
font-size: 26rpx;
|
||||
color: #888;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.start-button {
|
||||
width: 80%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.start-button.primary {
|
||||
background-color: #4CAF50;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.test-card:hover {
|
||||
transform: translateY(-2rpx);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,314 @@
|
|||
<template>
|
||||
<view class="result-container">
|
||||
<view v-if="loading" class="loading">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
<view v-else class="result-content">
|
||||
<view class="result-header">
|
||||
<text class="result-title">您的职业类型是</text>
|
||||
<text class="mbti-type">{{ result.primaryType.cateName }}</text>
|
||||
</view>
|
||||
<view class="scores-section">
|
||||
<view class="score-item" v-for="(score, category) in result.scores" :key="category">
|
||||
<text class="category-label">{{ category }}:</text>
|
||||
<text class="score-value">{{ score }} 分</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="report-section">
|
||||
<text class="report-title">职业类型描述</text>
|
||||
<rich-text :nodes="result.primaryType.typeDesc"></rich-text>
|
||||
</view>
|
||||
<view class="button-group">
|
||||
<button class="share-button" @click="shareResult">分享结果</button>
|
||||
<button class="export-button" @click="exportPDF">导出PDF</button>
|
||||
<button class="restart-button" @click="restartTest">重新测试</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
result: {
|
||||
primaryType: {
|
||||
cateName: '',
|
||||
typeDesc: ''
|
||||
},
|
||||
scores: {}
|
||||
},
|
||||
answers: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
formattedReport() {
|
||||
return this.result.primaryType.typeDesc;
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.answers) {
|
||||
this.answers = JSON.parse(options.answers);
|
||||
this.fetchResult();
|
||||
}
|
||||
},
|
||||
onMounted() {
|
||||
const loadScript = (src) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
script.src = src;
|
||||
script.onload = resolve;
|
||||
script.onerror = reject;
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
loadScript('https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js'),
|
||||
loadScript('https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js')
|
||||
]).catch((error) => {
|
||||
console.error('加载CDN资源失败:', error);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async fetchResult() {
|
||||
try {
|
||||
console.log("即将发送请求,answers:", this.answers);
|
||||
const response = await uni.request({
|
||||
url: `http://localhost:8080/api/results`,
|
||||
method: 'POST',
|
||||
data: { answers: this.answers },
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
console.log('响应状态码:', response.statusCode);
|
||||
console.log('响应数据:', response.data);
|
||||
|
||||
if (response.statusCode === 200 && response.data.code === 0) {
|
||||
this.result = response.data.data;
|
||||
} else {
|
||||
let errorMessage = '获取结果失败';
|
||||
if (response.data && response.data.error) {
|
||||
errorMessage = response.data.error;
|
||||
}
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: `获取结果失败: ${error.message}`,
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
shareResult() {
|
||||
uni.showToast({
|
||||
title: '分享功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
restartTest() {
|
||||
uni.redirectTo({
|
||||
url: '/pages/protest/protest'
|
||||
});
|
||||
},
|
||||
async exportPDF() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '正在生成PDF...'
|
||||
});
|
||||
|
||||
const element = document.querySelector('.result-content');
|
||||
const canvas = await window.html2canvas(element, {
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
logging: false
|
||||
});
|
||||
|
||||
const { jsPDF } = window.jspdf;
|
||||
const pdf = new jsPDF({
|
||||
orientation: 'portrait',
|
||||
unit: 'mm',
|
||||
format: 'a4'
|
||||
});
|
||||
|
||||
const imgWidth = 210;
|
||||
const pageHeight = 297;
|
||||
const imgHeight = canvas.height * imgWidth / canvas.width;
|
||||
|
||||
const imgData = canvas.toDataURL('image/jpeg', 1.0);
|
||||
pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight);
|
||||
|
||||
const fileName = `职业测试结果_${this.result.primaryType.cateName}_${new Date().toLocaleDateString()}.pdf`;
|
||||
|
||||
pdf.save(fileName);
|
||||
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: 'PDF导出成功',
|
||||
icon: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('PDF导出失败:', error);
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: 'PDF导出失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.result-container {
|
||||
padding: 30rpx;
|
||||
min-height: 100vh;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.result-content {
|
||||
max-width: 800rpx;
|
||||
margin: 0 auto;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
text-align: center;
|
||||
margin-bottom: 50rpx;
|
||||
animation: fadeIn 0.8s ease-out;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mbti-type {
|
||||
font-size: 72rpx;
|
||||
font-weight: bold;
|
||||
color: #007AFF;
|
||||
display: block;
|
||||
letter-spacing: 4rpx;
|
||||
text-shadow: 2rpx 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scores-section {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx;
|
||||
margin: 40rpx 0;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
animation: slideUp 0.8s ease-out;
|
||||
}
|
||||
|
||||
.score-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.category-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.score-value {
|
||||
color: #007AFF;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx;
|
||||
margin: 40rpx 0;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
animation: slideUp 1s ease-out;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-top: 40rpx;
|
||||
animation: slideUp 1.2s ease-out;
|
||||
}
|
||||
|
||||
.share-button,
|
||||
.restart-button,
|
||||
.export-button {
|
||||
width: 100%;
|
||||
padding: 25rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.share-button {
|
||||
background: linear-gradient(135deg, #007AFF, #0056b3);
|
||||
}
|
||||
|
||||
.restart-button {
|
||||
background: linear-gradient(135deg, #34C759, #28a745);
|
||||
}
|
||||
|
||||
.export-button {
|
||||
background: linear-gradient(135deg, #9254de, #722ed1);
|
||||
}
|
||||
|
||||
.share-button:active,
|
||||
.restart-button:active,
|
||||
.export-button:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30rpx);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,305 @@
|
|||
<template>
|
||||
<view class="test-container">
|
||||
<view class="progress-bar">
|
||||
<view class="progress" :style="{ width: progress + '%' }"></view>
|
||||
</view>
|
||||
|
||||
<view v-if="loading" class="loading">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<view v-else-if="questions.length === 0" class="no-questions">
|
||||
<text>未获取到题目,请稍后重试。</text>
|
||||
</view>
|
||||
|
||||
<view class="question-card" v-else>
|
||||
<text class="question-number">问题 {{ currentIndex + 1 }}/60</text>
|
||||
<text class="question-text">{{ currentQuestion.title }}</text>
|
||||
|
||||
<view class="options">
|
||||
<button
|
||||
class="option-button"
|
||||
@click="selectOption(true)"
|
||||
:class="{ selected: answers[currentQuestion.cateKey] === true }"
|
||||
>
|
||||
是
|
||||
</button>
|
||||
<button
|
||||
class="option-button"
|
||||
@click="selectOption(false)"
|
||||
:class="{ selected: answers[currentQuestion.cateKey] === false }"
|
||||
>
|
||||
不是
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="navigation-buttons">
|
||||
<button class="nav-button" @click="previousQuestion" :disabled="currentIndex === 0">上一题</button>
|
||||
<button
|
||||
v-if="currentIndex === 59"
|
||||
class="nav-button submit"
|
||||
@click="submitTest"
|
||||
:disabled="!this.currentQuestion ||!this.answers[this.currentQuestion.cateKey]"
|
||||
>提交测试</button>
|
||||
<button
|
||||
v-else
|
||||
class="nav-button next"
|
||||
@click="nextQuestion"
|
||||
:disabled="!this.currentQuestion ||!this.answers[this.currentQuestion.cateKey]"
|
||||
>下一题</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
answers: {},
|
||||
questions: [],
|
||||
loading: true,
|
||||
_testStartTime: Date.now()
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
progress() {
|
||||
return ((this.currentIndex + 1) / 60) * 100;
|
||||
},
|
||||
currentQuestion() {
|
||||
if (this.questions.length > 0 && this.currentIndex < this.questions.length) {
|
||||
return this.questions[this.currentIndex];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.fetchQuestions();
|
||||
},
|
||||
methods: {
|
||||
async fetchQuestions() {
|
||||
try {
|
||||
const response = await uni.request({
|
||||
url: 'http://localhost:8080/api/questionsH',
|
||||
method: 'GET'
|
||||
});
|
||||
if (typeof response.data === 'object' && response.data!== null && Array.isArray(response.data.data)) {
|
||||
this.questions = response.data.data.slice(0, 60);
|
||||
const validQuestions = this.questions.filter(question => question.hasOwnProperty('cateKey'));
|
||||
if (validQuestions.length!== this.questions.length) {
|
||||
console.warn('部分问题缺少 cateKey 属性,已过滤无效问题');
|
||||
}
|
||||
this.questions = validQuestions;
|
||||
|
||||
this.questions.forEach(question => {
|
||||
const cateKey = question.cateKey;
|
||||
if (!this.answers[cateKey]) {
|
||||
this.answers[cateKey] = 0;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new Error(`获取题目失败: 数据格式不正确,response.data: ${JSON.stringify(response.data)}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取题目出错:', error);
|
||||
this.handleError('获取题目失败', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
selectOption(value) {
|
||||
const currentQuestion = this.currentQuestion;
|
||||
if (currentQuestion && currentQuestion.hasOwnProperty('cateKey')) {
|
||||
const cateKey = currentQuestion.cateKey;
|
||||
if (value) {
|
||||
this.answers[cateKey]++;
|
||||
}
|
||||
if (this.currentIndex < 59) {
|
||||
this.nextQuestion();
|
||||
}
|
||||
}
|
||||
},
|
||||
nextQuestion() {
|
||||
if (this.currentIndex < 59) {
|
||||
this.currentIndex++;
|
||||
}
|
||||
},
|
||||
previousQuestion() {
|
||||
if (this.currentIndex > 0) {
|
||||
this.currentIndex--;
|
||||
}
|
||||
},
|
||||
async submitTest() {
|
||||
try {
|
||||
await this.showLoadingDialog();
|
||||
const response = await this.submitAnswers();
|
||||
await this.handleSubmitResponse(response);
|
||||
} catch (error) {
|
||||
this.handleError('提交失败', error);
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
showLoadingDialog() {
|
||||
return uni.showLoading({
|
||||
title: 'AI正在深入分析您的答案\n请耐心等待(约1分钟)',
|
||||
mask: true
|
||||
});
|
||||
},
|
||||
async submitAnswers() {
|
||||
const requestData = {
|
||||
answers: this.answers
|
||||
};
|
||||
const response = await uni.request({
|
||||
url: 'http://localhost:8080/api/results',
|
||||
method: 'POST',
|
||||
timeout: 600000,
|
||||
data: requestData,
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
return response;
|
||||
},
|
||||
async handleSubmitResponse(response) {
|
||||
if (response.statusCode === 200 && response.data?.code === 0) {
|
||||
const { resultCode, scores, primaryType } = response.data.data;
|
||||
// 这里可以根据需要对结果进行处理,例如存储到本地或跳转到结果页面
|
||||
console.log('结果代码:', resultCode);
|
||||
console.log('分数:', scores);
|
||||
console.log('主要类型:', primaryType);
|
||||
|
||||
// 跳转到结果页面,将 answers 作为参数传递
|
||||
await this.navigateToResult();
|
||||
} else {
|
||||
throw new Error(response.data?.message || '提交失败,未获取到有效结果');
|
||||
}
|
||||
},
|
||||
async navigateToResult() {
|
||||
try {
|
||||
await uni.navigateTo({
|
||||
url: `/pages/proresult/proresult?answers=${JSON.stringify(this.answers)}`
|
||||
});
|
||||
} catch (err) {
|
||||
this.handleError('跳转结果页面失败', err);
|
||||
}
|
||||
},
|
||||
handleError(message, error) {
|
||||
console.error(message, error);
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.test-container {
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 4px;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 100%;
|
||||
background-color: #4CAF50;
|
||||
border-radius: 2px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.question-card {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.question-number {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.question-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.option-button {
|
||||
padding: 12px 20px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
background-color: #e0e0e0;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.option-button.selected {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navigation-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 40px;
|
||||
position: relative;
|
||||
padding: 0 20px;
|
||||
margin-bottom: 30px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
flex: 1;
|
||||
padding: 12px 20px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
minimum-width: 100px;
|
||||
}
|
||||
|
||||
.nav-button:disabled {
|
||||
background-color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.nav-button.submit {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
image: url('loading.gif');
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.no-questions {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: red;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,341 @@
|
|||
<template>
|
||||
<view class="result-container">
|
||||
<view v-if="loading" class="loading">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<view v-else class="result-content">
|
||||
<view class="result-header">
|
||||
<text class="result-title">您的MBTI类型是</text>
|
||||
<text class="mbti-type">{{ result.type }}</text>
|
||||
</view>
|
||||
|
||||
<view class="dimensions-section">
|
||||
<view class="dimension-item" v-for="(dimension, index) in result.dimensions" :key="index">
|
||||
<view class="dimension-labels">
|
||||
<text class="dimension-label">{{dimension.left}}</text>
|
||||
<text class="dimension-label">{{dimension.right}}</text>
|
||||
</view>
|
||||
<view class="dimension-bar">
|
||||
<view class="dimension-progress left" :style="{ width: dimension.rightValue + '%' }"></view>
|
||||
<view class="dimension-progress right" :style="{ width: dimension.leftValue + '%' }"></view>
|
||||
</view>
|
||||
<view class="dimension-scores">
|
||||
<text class="score-text">{{dimension.rightValue}}%</text>
|
||||
<text class="score-text">{{dimension.leftValue}}%</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="report-section">
|
||||
<rich-text :nodes="formattedReport"></rich-text>
|
||||
</view>
|
||||
|
||||
<view class="button-group">
|
||||
<button class="share-button" @click="shareResult">分享结果</button>
|
||||
<button class="export-button" @click="exportPDF">导出PDF</button>
|
||||
<button class="restart-button" @click="restartTest">重新测试</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
result: {
|
||||
type: '',
|
||||
dimensions: [
|
||||
{ left: 'E (外向)', right: 'I (内向)', leftValue: 0, rightValue: 0 },
|
||||
{ left: 'S (感觉)', right: 'N (直觉)', leftValue: 0, rightValue: 0 },
|
||||
{ left: 'T (思维)', right: 'F (情感)', leftValue: 0, rightValue: 0 },
|
||||
{ left: 'J (判断)', right: 'P (知觉)', leftValue: 0, rightValue: 0 }
|
||||
],
|
||||
report: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
formattedReport() {
|
||||
return this.result.report;
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.fetchResult(options.id)
|
||||
}
|
||||
},
|
||||
onMounted() {
|
||||
const loadScript = (src) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script')
|
||||
script.src = src
|
||||
script.onload = resolve
|
||||
script.onerror = reject
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
loadScript('https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js'),
|
||||
loadScript('https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js')
|
||||
]).catch(error => {
|
||||
console.error('加载CDN资源失败:', error)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
async fetchResult(resultId) {
|
||||
try {
|
||||
const response = await uni.request({
|
||||
url: `http://localhost:8080/api/result/${resultId}`,
|
||||
method: 'GET'
|
||||
})
|
||||
|
||||
if (response.statusCode === 200) {
|
||||
this.result = response.data
|
||||
} else {
|
||||
throw new Error('获取结果失败')
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '获取结果失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
shareResult() {
|
||||
uni.showToast({
|
||||
title: '分享功能开发中',
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
restartTest() {
|
||||
uni.redirectTo({
|
||||
url: '/pages/test/test'
|
||||
})
|
||||
},
|
||||
async exportPDF() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '正在生成PDF...'
|
||||
});
|
||||
|
||||
const element = document.querySelector('.result-content');
|
||||
const canvas = await window.html2canvas(element, {
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
logging: false
|
||||
});
|
||||
|
||||
const { jsPDF } = window.jspdf;
|
||||
const pdf = new jsPDF({
|
||||
orientation: 'portrait',
|
||||
unit: 'mm',
|
||||
format: 'a4'
|
||||
});
|
||||
|
||||
const imgWidth = 210;
|
||||
const pageHeight = 297;
|
||||
const imgHeight = canvas.height * imgWidth / canvas.width;
|
||||
|
||||
const imgData = canvas.toDataURL('image/jpeg', 1.0);
|
||||
pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight);
|
||||
|
||||
const fileName = `MBTI测试结果_${this.result.type}_${new Date().toLocaleDateString()}.pdf`;
|
||||
|
||||
pdf.save(fileName);
|
||||
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: 'PDF导出成功',
|
||||
icon: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('PDF导出失败:', error);
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: 'PDF导出失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.result-container {
|
||||
padding: 30rpx;
|
||||
min-height: 100vh;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.result-content {
|
||||
max-width: 800rpx;
|
||||
margin: 0 auto;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.result-header {
|
||||
text-align: center;
|
||||
margin-bottom: 50rpx;
|
||||
animation: fadeIn 0.8s ease-out;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mbti-type {
|
||||
font-size: 72rpx;
|
||||
font-weight: bold;
|
||||
color: #007AFF;
|
||||
display: block;
|
||||
letter-spacing: 4rpx;
|
||||
text-shadow: 2rpx 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dimensions-section {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx;
|
||||
margin: 40rpx 0;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
animation: slideUp 0.8s ease-out;
|
||||
}
|
||||
|
||||
.dimension-item {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.dimension-labels {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.dimension-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.dimension-bar {
|
||||
height: 24rpx;
|
||||
background: #f0f0f0;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dimension-progress {
|
||||
height: 100%;
|
||||
transition: width 0.6s ease;
|
||||
}
|
||||
|
||||
.dimension-progress.left {
|
||||
background: linear-gradient(to right, #4CAF50, #81C784);
|
||||
}
|
||||
|
||||
.dimension-progress.right {
|
||||
background: linear-gradient(to right, #2196F3, #64B5F6);
|
||||
}
|
||||
|
||||
.dimension-scores {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.score-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.report-section {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx;
|
||||
margin: 40rpx 0;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
animation: slideUp 1s ease-out;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-top: 40rpx;
|
||||
animation: slideUp 1.2s ease-out;
|
||||
}
|
||||
|
||||
.share-button,
|
||||
.restart-button,
|
||||
.export-button {
|
||||
width: 100%;
|
||||
padding: 25rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.share-button {
|
||||
background: linear-gradient(135deg, #007AFF, #0056b3);
|
||||
}
|
||||
|
||||
.restart-button {
|
||||
background: linear-gradient(135deg, #34C759, #28a745);
|
||||
}
|
||||
|
||||
.export-button {
|
||||
background: linear-gradient(135deg, #9254de, #722ed1);
|
||||
}
|
||||
|
||||
.share-button:active,
|
||||
.restart-button:active,
|
||||
.export-button:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30rpx);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,117 @@
|
|||
.test-container {
|
||||
padding: 30rpx;
|
||||
min-height: 100vh;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 8rpx;
|
||||
background-color: rgba(239, 239, 244, 0.9);
|
||||
border-radius: 8rpx;
|
||||
margin-bottom: 30rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 100%;
|
||||
background-color: #007AFF;
|
||||
border-radius: 8rpx;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.loading text {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.question-card {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
margin-bottom: 30rpx;
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.question-number {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.question-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.option-button {
|
||||
background-color: rgba(239, 239, 244, 0.9);
|
||||
border: none;
|
||||
padding: 24rpx 30rpx;
|
||||
border-radius: 12rpx;
|
||||
text-align: left;
|
||||
font-size: 28rpx;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05);
|
||||
width: 100%;
|
||||
min-width: 500rpx;
|
||||
max-width: 600rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.option-button.selected {
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.option-button:active {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.navigation-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
position: fixed;
|
||||
bottom: 40rpx;
|
||||
left: 30rpx;
|
||||
right: 30rpx;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #007AFF;
|
||||
color: white;
|
||||
border: none;
|
||||
font-size: 28rpx;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 122, 255, 0.2);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.nav-button:disabled {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background-color: #4CAF50;
|
||||
}
|
|
@ -0,0 +1,411 @@
|
|||
<template>
|
||||
<view class="test-container">
|
||||
<view class="progress-bar">
|
||||
<view class="progress" :style="{ width: progress + '%' }"></view>
|
||||
</view>
|
||||
|
||||
<view v-if="loading" class="loading">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<view class="question-card" v-else-if="currentQuestion">
|
||||
<text class="question-number">问题 {{ currentIndex + 1 }}/{{ totalQuestions }}</text>
|
||||
<text class="question-text">{{ currentQuestion.text }}</text>
|
||||
|
||||
<view class="options">
|
||||
<view class="option-labels">
|
||||
<text class="extreme-label left">非常不符合</text>
|
||||
<text class="extreme-label right">非常符合</text>
|
||||
</view>
|
||||
<view class="option-circles">
|
||||
<view
|
||||
class="option-circle"
|
||||
v-for="value in 7"
|
||||
:key="value"
|
||||
@click="selectOption(value)"
|
||||
:class="{ selected: answers[currentIndex] === value }"
|
||||
:style="{ transform: `scale(${0.8 + value * 0.05})` }"
|
||||
>
|
||||
<text class="option-value">{{ value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="option-description">
|
||||
<text v-if="answers[currentIndex]">您的选择是:{{ getOptionLabel(answers[currentIndex]) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="navigation-buttons">
|
||||
<button class="nav-button" @click="previousQuestion" :disabled="currentIndex === 0">上一题</button>
|
||||
<button
|
||||
v-if="currentIndex === totalQuestions - 1"
|
||||
class="nav-button submit"
|
||||
@click="submitTest"
|
||||
:disabled="answers[currentIndex] === undefined"
|
||||
>提交测试</button>
|
||||
<button
|
||||
v-else
|
||||
class="nav-button next"
|
||||
@click="nextQuestion"
|
||||
:disabled="answers[currentIndex] === undefined"
|
||||
>下一题</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import './test.css';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentIndex: 0,
|
||||
answers: [],
|
||||
questions: [],
|
||||
loading: true,
|
||||
_testStartTime: Date.now()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalQuestions() {
|
||||
return this.questions.length
|
||||
},
|
||||
currentQuestion() {
|
||||
return this.questions[this.currentIndex]
|
||||
},
|
||||
progress() {
|
||||
return (this.currentIndex / this.totalQuestions) * 100
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.testType = options.type || 'simple'
|
||||
this.fetchQuestions()
|
||||
},
|
||||
methods: {
|
||||
async fetchQuestions() {
|
||||
try {
|
||||
const response = await uni.request({
|
||||
url: 'http://localhost:8080/api/questions',
|
||||
method: 'GET',
|
||||
data: {
|
||||
type: this.testType
|
||||
}
|
||||
})
|
||||
|
||||
if (response.statusCode === 200 && Array.isArray(response.data)) {
|
||||
this.questions = this.formatQuestions(response.data)
|
||||
this.initializeAnswers()
|
||||
} else {
|
||||
throw new Error(`获取题目失败: ${response.statusCode}`)
|
||||
}
|
||||
} catch (error) {
|
||||
this.handleError('获取题目失败', error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
formatQuestions(data) {
|
||||
return data.map(question => ({
|
||||
text: question.question || '',
|
||||
dimension: question.dimension,
|
||||
direction: question.direction
|
||||
}))
|
||||
},
|
||||
getOptionLabel(value) {
|
||||
switch(value) {
|
||||
case 1: return '非常不符合'
|
||||
case 2: return '较为不符合'
|
||||
case 3: return '稍微不符合'
|
||||
case 4: return '中立'
|
||||
case 5: return '稍微符合'
|
||||
case 6: return '较为符合'
|
||||
case 7: return '非常符合'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
initializeAnswers() {
|
||||
this.answers = new Array(this.totalQuestions).fill(undefined)
|
||||
},
|
||||
selectOption(value) {
|
||||
try {
|
||||
this.answers[this.currentIndex] = value
|
||||
// 直接跳转到下一题,但不在最后一题时跳转
|
||||
if (this.currentIndex < this.totalQuestions - 1) {
|
||||
this.nextQuestion()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('选择答案失败:', error)
|
||||
uni.showToast({
|
||||
title: '选择答案失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
nextQuestion() {
|
||||
if (this.currentIndex < this.totalQuestions - 1) {
|
||||
this.currentIndex++
|
||||
}
|
||||
},
|
||||
previousQuestion() {
|
||||
if (this.currentIndex > 0) {
|
||||
this.currentIndex--
|
||||
}
|
||||
},
|
||||
async submitTest() {
|
||||
try {
|
||||
await this.showLoadingDialog()
|
||||
const dimensions = this.calculateDimensions()
|
||||
const response = await this.submitAnswers(dimensions)
|
||||
await this.handleSubmitResponse(response)
|
||||
} catch (error) {
|
||||
this.handleError('提交失败', error)
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
showLoadingDialog() {
|
||||
return uni.showLoading({
|
||||
title: 'AI正在深入分析您的答案\n请耐心等待(约1分钟)',
|
||||
mask: true
|
||||
})
|
||||
},
|
||||
calculateDimensions() {
|
||||
const dimensions = { EI: 0, SN: 0, TF: 0, JP: 0 }
|
||||
const dimensionCounts = { EI: 0, SN: 0, TF: 0, JP: 0 }
|
||||
|
||||
// 计算每个维度的得分
|
||||
this.answers.forEach((answer, index) => {
|
||||
if (answer === undefined) return
|
||||
|
||||
const question = this.questions[index]
|
||||
const dimensionKey = question.dimension
|
||||
const direction = question.direction
|
||||
|
||||
let score = answer
|
||||
if (direction < 0) {
|
||||
score = 8 - score // 反向题目:7->1, 6->2, 5->3, 4->4, 3->5, 2->6, 1->7
|
||||
} else {
|
||||
score = score // 正向题目保持原始分数
|
||||
}
|
||||
score = ((score - 1) / 6.0) * 100 // 将1-7转换为0-100范围的百分比
|
||||
|
||||
dimensions[dimensionKey] += score
|
||||
dimensionCounts[dimensionKey]++
|
||||
})
|
||||
|
||||
// 计算每个维度的最终百分比
|
||||
for (const key in dimensions) {
|
||||
const totalQuestions = dimensionCounts[key]
|
||||
if (totalQuestions === 0) continue
|
||||
|
||||
const averageScore = dimensions[key] / totalQuestions
|
||||
|
||||
dimensions[key] = {
|
||||
leftValue: Math.round(averageScore),
|
||||
rightValue: Math.round(100 - averageScore)
|
||||
}
|
||||
}
|
||||
|
||||
return dimensions
|
||||
},
|
||||
async submitAnswers(dimensions) {
|
||||
return await uni.request({
|
||||
url: 'http://localhost:8080/api/submit',
|
||||
method: 'POST',
|
||||
timeout: 600000,
|
||||
data: {
|
||||
answers: this.answers,
|
||||
dimensions,
|
||||
userInfo: {
|
||||
testDate: new Date().toISOString(),
|
||||
totalQuestions: this.totalQuestions,
|
||||
completionTime: Date.now() - this._testStartTime
|
||||
}
|
||||
},
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
},
|
||||
async handleSubmitResponse(response) {
|
||||
if (response.statusCode === 200 && response.data?.resultId) {
|
||||
await this.navigateToResult(response.data.resultId)
|
||||
} else {
|
||||
throw new Error('提交失败,未获取到结果ID')
|
||||
}
|
||||
},
|
||||
async navigateToResult(resultId) {
|
||||
try {
|
||||
await uni.navigateTo({
|
||||
url: `/pages/result/result?id=${resultId}`
|
||||
})
|
||||
} catch (err) {
|
||||
this.handleError('跳转结果页面失败', err)
|
||||
}
|
||||
},
|
||||
handleError(message, error) {
|
||||
console.error(message, error)
|
||||
uni.showToast({
|
||||
title: message,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.test-container {
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 4px;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 100%;
|
||||
background-color: #4CAF50;
|
||||
border-radius: 2px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.question-card {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.question-number {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.question-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px 0;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.option-labels {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.extreme-label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.option-circles {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 20px;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #e3e6e8 100%);
|
||||
border-radius: 12px;
|
||||
margin: 10px 0;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.option-circle {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.option-circle:nth-child(1) { background: #FFD700; }
|
||||
.option-circle:nth-child(2) { background: #FFB347; }
|
||||
.option-circle:nth-child(3) { background: #FF8C00; }
|
||||
.option-circle:nth-child(4) { background: #9370DB; }
|
||||
.option-circle:nth-child(5) { background: #8A2BE2; }
|
||||
.option-circle:nth-child(6) { background: #800080; }
|
||||
.option-circle:nth-child(7) { background: #4B0082; }
|
||||
|
||||
.option-circle:hover {
|
||||
transform: scale(1.15);
|
||||
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.option-circle.selected {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
|
||||
.option-value {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.option-description {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.option-description text {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.navigation-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 40px;
|
||||
position: relative;
|
||||
padding: 0 20px;
|
||||
margin-bottom: 30px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
flex: 1;
|
||||
padding: 12px 20px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.nav-button:disabled {
|
||||
background-color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.nav-button.submit {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,6 @@
|
|||
export {};
|
||||
|
||||
declare module "vue" {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
interface ComponentCustomOptions extends Hooks {}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 601 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
|
@ -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: #fff;
|
||||
$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: 16;
|
||||
|
||||
/* 图片尺寸 */
|
||||
$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: #555; // 二级标题颜色
|
||||
$uni-font-size-subtitle: 18px;
|
||||
$uni-color-paragraph: #3f536e; // 文章段落颜色
|
||||
$uni-font-size-paragraph: 15px;
|
|
@ -0,0 +1,8 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import uni from '@dcloudio/vite-plugin-uni'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
uni(),
|
||||
],
|
||||
})
|
Loading…
Reference in New Issue