From 80edeb00ec5f9647b568a48503e63f485505aca8 Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期五, 20 六月 2025 10:00:16 +0800
Subject: [PATCH] gx语音播报
---
src/assets/logo.png | 0
package-lock.json | 76 ++++++++++
src/views/registerSuu/index.vue | 17 ++
package.json | 2
src/utils/httpApi.ts | 28 ++++
src/views/register/index.vue | 224 ++++++++++++++++++++++++++++++++
src/router/index.ts | 18 +
src/main.ts | 7
8 files changed, 363 insertions(+), 9 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e693b8c..040633a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "my-project",
"version": "0.0.0",
"dependencies": {
+ "@vant/icons": "^3.0.2",
"@zxing/library": "^0.21.3",
"axios": "^1.9.0",
"echarts": "^5.6.0",
@@ -15,6 +16,7 @@
"event-source-polyfill": "^1.0.31",
"qs": "^6.14.0",
"speak-tts": "^2.0.8",
+ "vant": "^3.4.3",
"vue": "^3.5.13",
"vue-router": "^4.0.13"
},
@@ -802,6 +804,27 @@
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==",
"license": "MIT"
+ },
+ "node_modules/@vant/icons": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/@vant/icons/-/icons-3.0.2.tgz",
+ "integrity": "sha512-4OlRVMd0uiDtD9hgSISZW8hB95vU0fFtc41tQchRIyiXkR0tS+DydZOLb8/bQkithrNWhW7Uud38MbKjlJ9lJw==",
+ "license": "MIT"
+ },
+ "node_modules/@vant/popperjs": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
+ "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==",
+ "license": "MIT"
+ },
+ "node_modules/@vant/use": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
+ "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
},
"node_modules/@vitejs/plugin-vue": {
"version": "5.2.1",
@@ -2076,6 +2099,26 @@
"node": ">=14.17"
}
},
+ "node_modules/vant": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmmirror.com/vant/-/vant-3.4.3.tgz",
+ "integrity": "sha512-vkOgMspRxqhTwX6huPjEiWgTDULZZVVVv2IaAeyXq21heKIJazv2Nymolhzmk4Ar/ZFfoxC/yOeG7MhnhTbrew==",
+ "license": "MIT",
+ "dependencies": {
+ "@vant/icons": "^1.7.1",
+ "@vant/popperjs": "^1.1.0",
+ "@vant/use": "^1.3.5"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/vant/node_modules/@vant/icons": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmmirror.com/@vant/icons/-/icons-1.8.0.tgz",
+ "integrity": "sha512-sKfEUo2/CkQFuERxvkuF6mGQZDKu3IQdj5rV9Fm0weJXtchDSSQ+zt8qPCNUEhh9Y8shy5PzxbvAfOOkCwlCXg==",
+ "license": "MIT"
+ },
"node_modules/vite": {
"version": "6.0.7",
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.7.tgz",
@@ -2616,6 +2659,22 @@
"version": "0.0.16",
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+ },
+ "@vant/icons": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/@vant/icons/-/icons-3.0.2.tgz",
+ "integrity": "sha512-4OlRVMd0uiDtD9hgSISZW8hB95vU0fFtc41tQchRIyiXkR0tS+DydZOLb8/bQkithrNWhW7Uud38MbKjlJ9lJw=="
+ },
+ "@vant/popperjs": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
+ "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
+ },
+ "@vant/use": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
+ "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
+ "requires": {}
},
"@vitejs/plugin-vue": {
"version": "5.2.1",
@@ -3482,6 +3541,23 @@
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"devOptional": true
},
+ "vant": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmmirror.com/vant/-/vant-3.4.3.tgz",
+ "integrity": "sha512-vkOgMspRxqhTwX6huPjEiWgTDULZZVVVv2IaAeyXq21heKIJazv2Nymolhzmk4Ar/ZFfoxC/yOeG7MhnhTbrew==",
+ "requires": {
+ "@vant/icons": "^1.7.1",
+ "@vant/popperjs": "^1.1.0",
+ "@vant/use": "^1.3.5"
+ },
+ "dependencies": {
+ "@vant/icons": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmmirror.com/@vant/icons/-/icons-1.8.0.tgz",
+ "integrity": "sha512-sKfEUo2/CkQFuERxvkuF6mGQZDKu3IQdj5rV9Fm0weJXtchDSSQ+zt8qPCNUEhh9Y8shy5PzxbvAfOOkCwlCXg=="
+ }
+ }
+ },
"vite": {
"version": "6.0.7",
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.7.tgz",
diff --git a/package.json b/package.json
index 979ded9..8718734 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "@vant/icons": "^3.0.2",
"@zxing/library": "^0.21.3",
"axios": "^1.9.0",
"echarts": "^5.6.0",
@@ -17,6 +18,7 @@
"event-source-polyfill": "^1.0.31",
"qs": "^6.14.0",
"speak-tts": "^2.0.8",
+ "vant": "^3.4.3",
"vue": "^3.5.13",
"vue-router": "^4.0.13"
},
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 0000000..7e585df
--- /dev/null
+++ b/src/assets/logo.png
Binary files differ
diff --git a/src/main.ts b/src/main.ts
index ae667b1..7bc77dd 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,8 +1,9 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
-import 'element-plus/dist/index.css'
+import 'element-plus/dist/index.css'
+import Vant from 'vant'
+import 'vant/lib/index.css'
import router from './router';
-import './style.css'
import App from './App.vue'
-createApp(App).use(router).use(ElementPlus).mount('#app')
+createApp(App).use(router).use(ElementPlus).use(Vant).mount('#app')
diff --git a/src/router/index.ts b/src/router/index.ts
index e4a5179..e4a8204 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -4,6 +4,8 @@
import deviceWindows from '../views/deviceWindows.vue'
import deviceWindows2 from '../views/deviceWindoes2.vue'
import test from '../views/test.vue'; // 搜索结果页,接收查询参数
+import registerForNutrition from '../views/register/index.vue'
+import registerSuu from '../views/registerSuu/index.vue'
// 定义路由规则,并为每个路由指定类型安全的 props
const routes: Array<RouteRecordRaw> = [
@@ -18,12 +20,16 @@
component: test,
props: true, // 路径参数将作为 props 传递给组件
},
-// {
-// path: '/search',
-// name: 'Search',
-// component: Search,
-// props: (route) => ({ query: route.query.q as string }), // 将查询参数 q 作为 prop 传递给组件
-// }
+ {
+ path: '/registerForNutrition',
+ name: 'registerForNutrition',
+ component: registerForNutrition
+ },
+ {
+ path: '/register-success',
+ name: 'registerSuu',
+ component: registerSuu
+ }
];
// 创建路由器实例,并指定类型
diff --git a/src/utils/httpApi.ts b/src/utils/httpApi.ts
index d633a12..b2f1e18 100644
--- a/src/utils/httpApi.ts
+++ b/src/utils/httpApi.ts
@@ -29,4 +29,32 @@
console.error('Error setting timeout alert:', error);
throw error;
}
+};
+
+export const sendValidateCode = async (requestData): Promise<ApiResponse> => {
+ try {
+ const response = await axios.post(`${apiBaseUrl}/user/info/sendValidateCodeForRegister`, requestData, {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ }
+ });
+ return response.data;
+ } catch (error) {
+ console.error('Error setting timeout alert:', error);
+ throw error;
+ }
+};
+
+export const registerForNutrition = async (requestData): Promise<ApiResponse> => {
+ try {
+ const response = await axios.post(`${apiBaseUrl}/user/info/registerForNutrition`, requestData, {
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+ return response.data;
+ } catch (error) {
+ console.error('Error setting timeout alert:', error);
+ throw error;
+ }
};
\ No newline at end of file
diff --git a/src/views/register/index.vue b/src/views/register/index.vue
new file mode 100644
index 0000000..331e8d9
--- /dev/null
+++ b/src/views/register/index.vue
@@ -0,0 +1,224 @@
+<template>
+ <div class="register-form">
+ <van-image width="100" height="100" :src="logo" />
+ <h1>用户注册</h1>
+ <p>创建您的账户,开始使用我们的服务</p>
+
+ <van-form @submit="onSubmit">
+ <!-- 用户名 -->
+ <van-field
+ v-model="formData.username"
+ name="用户名"
+ label="用户姓名*"
+ placeholder="请输入您的姓名"
+ :rules="[{ required: true, message: '请填写用户名' }]"
+ />
+
+ <!-- 手机号 -->
+ <van-field
+ v-model="formData.phone"
+ type="tel"
+ name="手机号"
+ label="手机号*"
+ placeholder="请输入您的手机号"
+ :rules="[
+ { required: true, message: '请填写手机号' },
+ { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码'}
+ ]"
+ />
+
+ <!-- 验证码 -->
+ <van-field
+ v-model="formData.code"
+ center
+ clearable
+ name="验证码"
+ label="手机验证码*"
+ placeholder="请输入验证码"
+ :rules="[{ required: true, message: '请填写验证码' }]"
+ >
+ <template #button>
+ <van-button size="small" type="primary" @click="sendCode" :disabled="isSendingCode">{{ sendButtonText }}</van-button>
+ </template>
+ </van-field>
+
+ <!-- 邮箱地址 -->
+ <van-field
+ v-model="formData.email"
+ type="email"
+ name="邮箱地址"
+ label="邮箱地址*"
+ placeholder="请输入您的邮箱地址"
+ :rules="[
+ { pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/, message: '请输入正确的邮箱格式'}
+ ]"
+ />
+
+ <!-- 密码 -->
+ <van-field
+ v-model="formData.password"
+ type="password"
+ name="密码"
+ label="密码*"
+ placeholder="请输入您的密码"
+ :rules="[
+ { required: true, message: '请填写密码' },
+ { min: 6, message: '密码长度不能少于6位'}
+ ]"
+ />
+
+ <!-- 确认密码 -->
+ <van-field
+ v-model="formData.confirmPassword"
+ type="password"
+ name="确认密码"
+ label="确认密码*"
+ placeholder="请确认您的密码"
+ :rules="[
+ { validator: validatePass, message: '两次输入密码不一致' },
+ { required: true, message: '请确认密码' }
+ ]"
+ />
+
+ <!-- 提交按钮 -->
+ <div style="margin: 16px;">
+ <van-button round block type="primary" native-type="submit">立即注册</van-button>
+ </div>
+ </van-form>
+ </div>
+ </template>
+
+ <script setup>
+ import { ref } from 'vue';
+ import { Toast } from 'vant';
+ import logo from '@/assets/logo.png'
+ import { useRouter } from 'vue-router';
+ import { sendValidateCode,registerForNutrition } from "@/utils/httpApi";
+
+ const router = useRouter();
+ const formData = ref({
+ username: '',
+ phone: '',
+ code: '',
+ email: '',
+ password: '',
+ confirmPassword: ''
+ });
+ const submitLoadion=ref(false)
+ const isSendingCode = ref(false);
+ const sendButtonText = ref('发送验证码');
+ let countdownTimer = null;
+ const countdown = ref(60);
+
+ // 自定义验证手机号格式
+ const isValidPhone = (phone) => {
+ const phoneReg = /^1[3456789]\d{9}$/;
+ return phoneReg.test(phone);
+ };
+
+ // 发送验证码
+ const sendCode = () => {
+ if (!formData.value.phone) {
+ Toast.fail('请先填写手机号');
+ return;
+ }
+
+ if (!isValidPhone(formData.value.phone)) {
+ Toast.fail('请输入正确的手机号码');
+ return;
+ }
+
+ // 开始发送验证码
+ isSendingCode.value = true;
+ // 模拟发送验证码请求
+ console.log('发送验证码至:', formData.value.phone);
+ sendValidateCode('mobileNo='+formData.value.phone).then(re=>{
+ Toast.success('验证码已发送');
+ // 启动倒计时
+ countdown.value = 60;
+ sendButtonText.value = `${countdown.value}秒后重发`;
+
+ countdownTimer = setInterval(() => {
+ countdown.value--;
+ sendButtonText.value = `${countdown.value}秒后重发`;
+ if (countdown.value <= 0) {
+ clearInterval(countdownTimer);
+ isSendingCode.value = false;
+ sendButtonText.value = '重新发送';
+ }
+ }, 1000);
+ }).finally(()=>{
+
+ })
+
+ };
+
+ // 验证两次输入的密码是否一致
+ const validatePass = (val) => val === formData.value.password;
+
+ // 表单提交
+ const onSubmit = (values) => {
+ console.log('submit', values);
+ const mono={
+ 手机验证码:values.验证码,
+ 用户姓名:values.用户名,
+ 手机号:values.手机号,
+ 密码:values.确认密码,
+ Email:values.邮箱地址
+ }
+ console.log(mono)
+ Toast.loading({
+ message: '加载中...',
+ forbidClick: true,
+ loadingType: 'spinner',
+ });
+ submitLoadion.value=true
+ registerForNutrition(mono).then(re=>{
+ console.log(re)
+ if(re.code===400){
+ Toast(re.message);
+ }else if(re.code===200){
+ // 跳转到注册成功页面
+ Toast.success('提交成功');
+ router.push('/register-success');
+ }
+
+ }).center((err)=>{
+ Toast('注册失败');
+ })
+ .finally(()=>{
+ submitLoadion.value=false
+ // router.push('/register-success');
+ })
+
+ // router.push('/register-success');
+ };
+ </script>
+
+ <style scoped>
+ .register-form {
+ text-align: center;
+ max-width: 400px;
+ margin: 0 auto;
+ padding: 20px;
+ padding-top: 40px;
+ }
+
+ .logo {
+ display: block;
+ margin: 0 auto 20px;
+ width: 100px;
+ }
+
+ h1 {
+ text-align: center;
+ font-size: 20px;
+ margin-bottom: 10px;
+ }
+
+ p {
+ text-align: center;
+ color: #666;
+ margin-bottom: 20px;
+ }
+ </style>
\ No newline at end of file
diff --git a/src/views/registerSuu/index.vue b/src/views/registerSuu/index.vue
new file mode 100644
index 0000000..72fcf5a
--- /dev/null
+++ b/src/views/registerSuu/index.vue
@@ -0,0 +1,17 @@
+<template>
+ <div class="success-container" style="text-align: center;margin-top: 100px;">
+ <van-icon name="checked" class="success-icon" />
+ <h2>注册成功!</h2>
+ <p>您的账户已成功创建,欢迎加入我们!</p>
+ <p>待审核通过后才可以登录系统!</p>
+ <!-- <van-button type="primary" block @click="goToLogin">前往登录</van-button> -->
+ </div>
+ </template>
+
+ <style scoped>
+ .success-icon {
+ font-size: 60px;
+ color: #4caf50;
+ margin-bottom: 20px;
+ }
+ </style>
\ No newline at end of file
--
Gitblit v1.8.0