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