hookehuyr

chore: 将品牌名称从“美乐爱觉”更新为“生命力教育联盟”

更新所有页面、组件和文档中的品牌名称,包括用户协议、页面标题、分享标题、海报文案等,以反映品牌名称变更
...@@ -12,35 +12,49 @@ ...@@ -12,35 +12,49 @@
12 position="bottom" 12 position="bottom"
13 :style="{ height: '100%' }" 13 :style="{ height: '100%' }"
14 > 14 >
15 - <div class="flex flex-col h-full relative"> 15 + <div class="relative flex h-full flex-col">
16 - <div class="sticky top-0 flex justify-between items-center p-4 border-b border-gray-100 bg-white z-10"> 16 + <div
17 - <h3 class="font-medium text-lg">{{ title }}</h3> 17 + class="sticky top-0 z-10 flex items-center justify-between border-b border-gray-100 bg-white p-4"
18 + >
19 + <h3 class="text-lg font-medium">{{ title }}</h3>
18 <van-icon name="cross" @click="$emit('update:show', false)" class="text-gray-500" /> 20 <van-icon name="cross" @click="$emit('update:show', false)" class="text-gray-500" />
19 </div> 21 </div>
20 22
21 <div class="flex-1 overflow-y-auto p-4 pt-0"> 23 <div class="flex-1 overflow-y-auto p-4 pt-0">
22 <div v-if="type === 'terms'" class="space-y-4 text-gray-600"> 24 <div v-if="type === 'terms'" class="space-y-4 text-gray-600">
23 - <p>欢迎使用美乐爱觉教育!在使用我们的服务之前,请仔细阅读以下用户协议。</p> 25 + <p>欢迎使用生命力教育联盟教育!在使用我们的服务之前,请仔细阅读以下用户协议。</p>
24 26
25 <h5 class="font-medium text-gray-800">1. 服务内容</h5> 27 <h5 class="font-medium text-gray-800">1. 服务内容</h5>
26 - <p>美乐爱觉教育为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。</p> 28 + <p>
29 + 生命力教育联盟教育为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。
30 + </p>
27 31
28 <h5 class="font-medium text-gray-800">2. 用户责任</h5> 32 <h5 class="font-medium text-gray-800">2. 用户责任</h5>
29 - <p>用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。</p> 33 + <p>
34 + 用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。
35 + </p>
30 36
31 <h5 class="font-medium text-gray-800">3. 知识产权</h5> 37 <h5 class="font-medium text-gray-800">3. 知识产权</h5>
32 - <p>本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。</p> 38 + <p>
39 + 本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。
40 + </p>
33 41
34 <h5 class="font-medium text-gray-800">4. 免责声明</h5> 42 <h5 class="font-medium text-gray-800">4. 免责声明</h5>
35 <p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p> 43 <p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p>
36 <h5 class="font-medium text-gray-800">1. 服务内容</h5> 44 <h5 class="font-medium text-gray-800">1. 服务内容</h5>
37 - <p>美乐爱觉教育为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。</p> 45 + <p>
46 + 生命力教育联盟教育为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。
47 + </p>
38 48
39 <h5 class="font-medium text-gray-800">2. 用户责任</h5> 49 <h5 class="font-medium text-gray-800">2. 用户责任</h5>
40 - <p>用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。</p> 50 + <p>
51 + 用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。
52 + </p>
41 53
42 <h5 class="font-medium text-gray-800">3. 知识产权</h5> 54 <h5 class="font-medium text-gray-800">3. 知识产权</h5>
43 - <p>本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。</p> 55 + <p>
56 + 本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。
57 + </p>
44 58
45 <h5 class="font-medium text-gray-800">4. 免责声明</h5> 59 <h5 class="font-medium text-gray-800">4. 免责声明</h5>
46 <p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p> 60 <p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p>
...@@ -50,10 +64,14 @@ ...@@ -50,10 +64,14 @@
50 <p>我们重视您的隐私保护。本隐私政策说明我们如何收集、使用和保护您的个人信息。</p> 64 <p>我们重视您的隐私保护。本隐私政策说明我们如何收集、使用和保护您的个人信息。</p>
51 65
52 <h5 class="font-medium text-gray-800">1. 信息收集</h5> 66 <h5 class="font-medium text-gray-800">1. 信息收集</h5>
53 - <p>我们收集的信息包括但不限于:姓名、联系方式、位置信息等。这些信息用于提供更好的服务体验。</p> 67 + <p>
68 + 我们收集的信息包括但不限于:姓名、联系方式、位置信息等。这些信息用于提供更好的服务体验。
69 + </p>
54 70
55 <h5 class="font-medium text-gray-800">2. 信息使用</h5> 71 <h5 class="font-medium text-gray-800">2. 信息使用</h5>
56 - <p>我们承诺对您的个人信息进行严格保密,不会将其出售、出租或以其他方式泄露给任何第三方。</p> 72 + <p>
73 + 我们承诺对您的个人信息进行严格保密,不会将其出售、出租或以其他方式泄露给任何第三方。
74 + </p>
57 75
58 <h5 class="font-medium text-gray-800">3. 信息安全</h5> 76 <h5 class="font-medium text-gray-800">3. 信息安全</h5>
59 <p>我们采用行业标准的安全措施保护您的个人信息,防止未经授权的访问、使用或泄露。</p> 77 <p>我们采用行业标准的安全措施保护您的个人信息,防止未经授权的访问、使用或泄露。</p>
...@@ -72,19 +90,19 @@ defineProps({ ...@@ -72,19 +90,19 @@ defineProps({
72 show: { 90 show: {
73 type: Boolean, 91 type: Boolean,
74 required: true, 92 required: true,
75 - default: false 93 + default: false,
76 }, 94 },
77 /** 协议类型: 'terms' | 'privacy' */ 95 /** 协议类型: 'terms' | 'privacy' */
78 type: { 96 type: {
79 type: String, 97 type: String,
80 required: true, 98 required: true,
81 - validator: (value) => ['terms', 'privacy'].includes(value) 99 + validator: value => ['terms', 'privacy'].includes(value),
82 }, 100 },
83 /** 弹窗标题 */ 101 /** 弹窗标题 */
84 title: { 102 title: {
85 type: String, 103 type: String,
86 - required: true 104 + required: true,
87 - } 105 + },
88 }) 106 })
89 107
90 defineEmits(['update:show']) 108 defineEmits(['update:show'])
......
...@@ -9,69 +9,81 @@ ...@@ -9,69 +9,81 @@
9 * @Description: 用户协议组件 9 * @Description: 用户协议组件
10 --> 10 -->
11 <template> 11 <template>
12 - <van-popup 12 + <van-popup v-model:show="show" round position="bottom" :style="{ height: '90%' }" teleport="body">
13 - v-model:show="show"
14 - round
15 - position="bottom"
16 - :style="{ height: '90%' }"
17 - teleport="body"
18 - >
19 <div class="p-4"> 13 <div class="p-4">
20 - <div class="text-xl font-bold text-center mb-4">美乐爱觉宇宙用户协议</div> 14 + <div class="mb-4 text-center text-xl font-bold">生命力教育联盟宇宙用户协议</div>
21 - <div class="agreement-content overflow-y-auto h-[calc(100vh*0.8-120px)] px-2"> 15 + <div class="agreement-content h-[calc(100vh*0.8-120px)] overflow-y-auto px-2">
22 - <h2 class="text-lg font-semibold mb-3">1. 协议的范围</h2> 16 + <h2 class="mb-3 text-lg font-semibold">1. 协议的范围</h2>
23 - <p class="mb-4 text-gray-700">欢迎您使用美乐爱觉宇宙平台服务!为使用美乐爱觉宇宙平台服务,您应当阅读并遵守本《用户协议》。请您务必审慎阅读、充分理解各条款内容。</p> 17 + <p class="mb-4 text-gray-700">
18 + 欢迎您使用生命力教育联盟宇宙平台服务!为使用生命力教育联盟宇宙平台服务,您应当阅读并遵守本《用户协议》。请您务必审慎阅读、充分理解各条款内容。
19 + </p>
24 20
25 - <h2 class="text-lg font-semibold mb-3">2. 账号注册</h2> 21 + <h2 class="mb-3 text-lg font-semibold">2. 账号注册</h2>
26 - <p class="mb-4 text-gray-700">您在使用本服务前需要注册一个美乐爱觉宇宙账号。美乐爱觉宇宙账号应当使用手机号码绑定注册,请您使用尚未与美乐爱觉宇宙账号绑定的手机号码,以及未被平台根据本协议封禁的手机号码注册。</p> 22 + <p class="mb-4 text-gray-700">
23 + 您在使用本服务前需要注册一个生命力教育联盟宇宙账号。生命力教育联盟宇宙账号应当使用手机号码绑定注册,请您使用尚未与生命力教育联盟宇宙账号绑定的手机号码,以及未被平台根据本协议封禁的手机号码注册。
24 + </p>
27 25
28 - <h2 class="text-lg font-semibold mb-3">3. 用户个人信息保护</h2> 26 + <h2 class="mb-3 text-lg font-semibold">3. 用户个人信息保护</h2>
29 - <p class="mb-4 text-gray-700">我们非常重视用户个人信息的保护,保护用户个人信息是我们的基本原则之一。我们将会采取合理的措施保护用户的个人信息。除法律法规规定的情形外,未经用户许可我们不会向第三方公开、透露用户个人信息。</p> 27 + <p class="mb-4 text-gray-700">
28 + 我们非常重视用户个人信息的保护,保护用户个人信息是我们的基本原则之一。我们将会采取合理的措施保护用户的个人信息。除法律法规规定的情形外,未经用户许可我们不会向第三方公开、透露用户个人信息。
29 + </p>
30 30
31 - <h2 class="text-lg font-semibold mb-3">4. 内容规范</h2> 31 + <h2 class="mb-3 text-lg font-semibold">4. 内容规范</h2>
32 - <p class="mb-4 text-gray-700">您在使用本服务时需要遵守法律法规、社会主义制度、国家利益、公民合法权益、公共秩序、社会道德风尚和信息真实性等七条底线。</p> 32 + <p class="mb-4 text-gray-700">
33 + 您在使用本服务时需要遵守法律法规、社会主义制度、国家利益、公民合法权益、公共秩序、社会道德风尚和信息真实性等七条底线。
34 + </p>
33 35
34 - <h2 class="text-lg font-semibold mb-3">5. 知识产权</h2> 36 + <h2 class="mb-3 text-lg font-semibold">5. 知识产权</h2>
35 - <p class="mb-4 text-gray-700">美乐爱觉宇宙平台所包含的全部智力成果,包括但不限于平台内容、平台设计、源代码等,均属于平台所有。未经平台许可,任何人不得擅自使用。</p> 37 + <p class="mb-4 text-gray-700">
38 + 生命力教育联盟宇宙平台所包含的全部智力成果,包括但不限于平台内容、平台设计、源代码等,均属于平台所有。未经平台许可,任何人不得擅自使用。
39 + </p>
36 40
37 - <h2 class="text-lg font-semibold mb-3">6. 服务的变更、中断和终止</h2> 41 + <h2 class="mb-3 text-lg font-semibold">6. 服务的变更、中断和终止</h2>
38 - <p class="mb-4 text-gray-700">我们可能会对服务内容进行变更,也可能会中断、中止或终止服务。对于付费服务,我们会在变更前通知您,并向您提供退款等必要的补偿。</p> 42 + <p class="mb-4 text-gray-700">
43 + 我们可能会对服务内容进行变更,也可能会中断、中止或终止服务。对于付费服务,我们会在变更前通知您,并向您提供退款等必要的补偿。
44 + </p>
39 45
40 - <h2 class="text-lg font-semibold mb-3">7. 违约处理</h2> 46 + <h2 class="mb-3 text-lg font-semibold">7. 违约处理</h2>
41 - <p class="mb-4 text-gray-700">如果您违反本协议约定,我们有权视情况采取预先警示、限制或禁止使用全部或部分服务功能、封禁账号等措施。</p> 47 + <p class="mb-4 text-gray-700">
48 + 如果您违反本协议约定,我们有权视情况采取预先警示、限制或禁止使用全部或部分服务功能、封禁账号等措施。
49 + </p>
42 50
43 - <h2 class="text-lg font-semibold mb-3">8. 其他条款</h2> 51 + <h2 class="mb-3 text-lg font-semibold">8. 其他条款</h2>
44 - <p class="mb-4 text-gray-700">本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。如果本协议中任何一条被视为废止、无效或不可执行,应视为可分的且并不影响任何其余条款的有效性和可执行性。</p> 52 + <p class="mb-4 text-gray-700">
53 + 本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。如果本协议中任何一条被视为废止、无效或不可执行,应视为可分的且并不影响任何其余条款的有效性和可执行性。
54 + </p>
45 </div> 55 </div>
46 - <div class="flex justify-center mt-4"> 56 + <div class="mt-4 flex justify-center">
47 - <van-button round type="primary" color="#4CAF50" block @click="handleClose">我已阅读并同意</van-button> 57 + <van-button round type="primary" color="#4CAF50" block @click="handleClose"
58 + >我已阅读并同意</van-button
59 + >
48 </div> 60 </div>
49 </div> 61 </div>
50 </van-popup> 62 </van-popup>
51 </template> 63 </template>
52 64
53 <script setup> 65 <script setup>
54 -import { ref, defineExpose } from 'vue'; 66 +import { ref, defineExpose } from 'vue'
55 67
56 -const show = ref(false); 68 +const show = ref(false)
57 69
58 /** 70 /**
59 * @description 关闭协议弹窗 71 * @description 关闭协议弹窗
60 */ 72 */
61 const handleClose = () => { 73 const handleClose = () => {
62 - show.value = false; 74 + show.value = false
63 -}; 75 +}
64 76
65 /** 77 /**
66 * @description 打开协议弹窗 78 * @description 打开协议弹窗
67 */ 79 */
68 const openAgreement = () => { 80 const openAgreement = () => {
69 - show.value = true; 81 + show.value = true
70 -}; 82 +}
71 83
72 defineExpose({ 84 defineExpose({
73 - openAgreement 85 + openAgreement,
74 -}); 86 +})
75 </script> 87 </script>
76 88
77 <style lang="less" scoped> 89 <style lang="less" scoped>
......
This diff is collapsed. Click to expand it.
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
8 <template> 8 <template>
9 <div class="welcome-content"> 9 <div class="welcome-content">
10 <!-- 标题区域 --> 10 <!-- 标题区域 -->
11 - <div class="mt-20 flex flex-col items-center z-10 w-full px-8"> 11 + <div class="z-10 mt-20 flex w-full flex-col items-center px-8">
12 - <img :src="titleImg" class="w-full max-w-[300px] mb-4 object-contain" alt="美乐爱觉" /> 12 + <img :src="titleImg" class="mb-4 w-full max-w-[300px] object-contain" alt="生命力教育联盟" />
13 </div> 13 </div>
14 14
15 <!-- 功能入口区域 - 水平布局,自动推到底部 --> 15 <!-- 功能入口区域 - 水平布局,自动推到底部 -->
16 - <div class="mt-auto entry-orbit"> 16 + <div class="entry-orbit mt-auto">
17 <div class="orbit-entries"> 17 <div class="orbit-entries">
18 <WelcomeEntryItem 18 <WelcomeEntryItem
19 v-for="entry in entries" 19 v-for="entry in entries"
...@@ -39,7 +39,7 @@ const entries = ref(welcomeEntries) ...@@ -39,7 +39,7 @@ const entries = ref(welcomeEntries)
39 // 导入标题图片 39 // 导入标题图片
40 const titleImg = 'https://cdn.ipadbiz.cn/mlaj/recall/img/title007@2x.png' 40 const titleImg = 'https://cdn.ipadbiz.cn/mlaj/recall/img/title007@2x.png'
41 41
42 -const handleEntryClick = (entry) => { 42 +const handleEntryClick = entry => {
43 if (entry.isExternal) { 43 if (entry.isExternal) {
44 // 外部链接:获取用户ID并拼接 44 // 外部链接:获取用户ID并拼接
45 const currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}') 45 const currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}')
...@@ -103,7 +103,8 @@ const handleEntryClick = (entry) => { ...@@ -103,7 +103,8 @@ const handleEntryClick = (entry) => {
103 103
104 // 动画定义 104 // 动画定义
105 @keyframes float { 105 @keyframes float {
106 - 0%, 100% { 106 + 0%,
107 + 100% {
107 transform: translateY(0); 108 transform: translateY(0);
108 } 109 }
109 50% { 110 50% {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
5 * @FilePath: /mlaj/src/composables/useShare.js 5 * @FilePath: /mlaj/src/composables/useShare.js
6 * @Description: 微信分享相关逻辑 6 * @Description: 微信分享相关逻辑
7 */ 7 */
8 -import wx from 'weixin-js-sdk'; 8 +import wx from 'weixin-js-sdk'
9 9
10 /** 10 /**
11 * @function normalize_image_url 11 * @function normalize_image_url
...@@ -14,15 +14,15 @@ import wx from 'weixin-js-sdk'; ...@@ -14,15 +14,15 @@ import wx from 'weixin-js-sdk';
14 * @returns {string} 处理后的图片地址 14 * @returns {string} 处理后的图片地址
15 */ 15 */
16 function normalize_image_url(src) { 16 function normalize_image_url(src) {
17 - if (!src) return ''; 17 + if (!src) return ''
18 - if (src.includes('cdn.ipadbiz.cn')) { 18 + if (src.includes('cdn.ipadbiz.cn')) {
19 - const compress = 'imageMogr2/thumbnail/200x/strip/quality/70'; 19 + const compress = 'imageMogr2/thumbnail/200x/strip/quality/70'
20 - if (src.includes('?')) { 20 + if (src.includes('?')) {
21 - return src.includes(compress) ? src : `${src}&${compress}`; 21 + return src.includes(compress) ? src : `${src}&${compress}`
22 - }
23 - return `${src}?${compress}`;
24 } 22 }
25 - return src; 23 + return `${src}?${compress}`
24 + }
25 + return src
26 } 26 }
27 27
28 /** 28 /**
...@@ -41,30 +41,30 @@ function normalize_image_url(src) { ...@@ -41,30 +41,30 @@ function normalize_image_url(src) {
41 * @param {string} params.imgUrl 分享图标地址 41 * @param {string} params.imgUrl 分享图标地址
42 * @returns {void} 42 * @returns {void}
43 */ 43 */
44 -export const sharePage = ({ title = '美乐爱觉', desc = '', imgUrl = '' }) => { 44 +export const sharePage = ({ title = '生命力教育联盟', desc = '', imgUrl = '' }) => {
45 - const shareData = { 45 + const shareData = {
46 - title, // 分享标题 46 + title, // 分享标题
47 - desc, // 分享描述 47 + desc, // 分享描述
48 - link: location.origin + location.pathname + location.hash, // 分享链接,需与公众号 JS 安全域名一致 48 + link: location.origin + location.pathname + location.hash, // 分享链接,需与公众号 JS 安全域名一致
49 - imgUrl: normalize_image_url(imgUrl), // 分享图标,按规则追加压缩参数 49 + imgUrl: normalize_image_url(imgUrl), // 分享图标,按规则追加压缩参数
50 - success: function () { 50 + success() {
51 - // 设置成功回调 51 + // 设置成功回调
52 - } 52 + },
53 - } 53 + }
54 54
55 - if (wx && typeof wx.ready === 'function') { 55 + if (wx && typeof wx.ready === 'function') {
56 - wx.ready(() => { 56 + wx.ready(() => {
57 - // 分享好友(微信好友或qq好友) 57 + // 分享好友(微信好友或qq好友)
58 - wx.updateAppMessageShareData(shareData); 58 + wx.updateAppMessageShareData(shareData)
59 - // 分享到朋友圈或qq空间 59 + // 分享到朋友圈或qq空间
60 - wx.updateTimelineShareData(shareData); 60 + wx.updateTimelineShareData(shareData)
61 - // 分享到腾讯微博 61 + // 分享到腾讯微博
62 - if (typeof wx.onMenuShareWeibo === 'function') { 62 + if (typeof wx.onMenuShareWeibo === 'function') {
63 - wx.onMenuShareWeibo(shareData); 63 + wx.onMenuShareWeibo(shareData)
64 - } 64 + }
65 - }); 65 + })
66 - } else { 66 + } else {
67 - // 微信 JSSDK 未初始化或未就绪,分享配置可能不会生效 67 + // 微信 JSSDK 未初始化或未就绪,分享配置可能不会生效
68 - console.warn('微信 JSSDK 未就绪:分享配置可能未生效'); 68 + console.warn('微信 JSSDK 未就绪:分享配置可能未生效')
69 - } 69 + }
70 } 70 }
......
This diff is collapsed. Click to expand it.
...@@ -23,7 +23,7 @@ export const routes = [ ...@@ -23,7 +23,7 @@ export const routes = [
23 path: '/', 23 path: '/',
24 name: 'HomePage', 24 name: 'HomePage',
25 component: () => import('../views/HomePage.vue'), 25 component: () => import('../views/HomePage.vue'),
26 - meta: { title: '美乐爱觉' }, 26 + meta: { title: '生命力教育联盟' },
27 }, 27 },
28 { 28 {
29 path: '/courses', 29 path: '/courses',
...@@ -158,7 +158,7 @@ export const routes = [ ...@@ -158,7 +158,7 @@ export const routes = [
158 path: '/recall/choose', 158 path: '/recall/choose',
159 name: 'ChoosePage', 159 name: 'ChoosePage',
160 component: () => import('../views/recall/ChoosePage.vue'), 160 component: () => import('../views/recall/ChoosePage.vue'),
161 - meta: { title: '美乐爱觉AI星球' }, 161 + meta: { title: '生命力教育联盟AI星球' },
162 }, 162 },
163 { 163 {
164 path: '/checkout', 164 path: '/checkout',
......
This diff is collapsed. Click to expand it.
1 <template> 1 <template>
2 - <div class="min-h-screen flex flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 py-12 px-4 sm:px-6 lg:px-8"> 2 + <div
3 + class="flex min-h-screen flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 px-4 py-12 sm:px-6 lg:px-8"
4 + >
3 <div class="sm:mx-auto sm:w-full sm:max-w-md"> 5 <div class="sm:mx-auto sm:w-full sm:max-w-md">
4 - <h1 class="text-center text-3xl font-bold text-gray-800 mb-2">美乐爱觉教育</h1> 6 + <h1 class="mb-2 text-center text-3xl font-bold text-gray-800">生命力教育联盟教育</h1>
5 <h2 class="text-center text-xl font-medium text-gray-600">重置密码</h2> 7 <h2 class="text-center text-xl font-medium text-gray-600">重置密码</h2>
6 </div> 8 </div>
7 9
8 <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> 10 <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
9 - <FrostedGlass class="py-8 px-6 rounded-lg"> 11 + <FrostedGlass class="rounded-lg px-6 py-8">
10 - <div v-if="error" class="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-md"> 12 + <div
13 + v-if="error"
14 + class="mb-4 rounded-md border border-red-400 bg-red-100 px-4 py-3 text-red-700"
15 + >
11 {{ error }} 16 {{ error }}
12 </div> 17 </div>
13 18
...@@ -25,7 +30,7 @@ ...@@ -25,7 +30,7 @@
25 maxlength="11" 30 maxlength="11"
26 @input="formData.phone = formData.phone.replace(/\D/g, '')" 31 @input="formData.phone = formData.phone.replace(/\D/g, '')"
27 @blur="validatePhone" 32 @blur="validatePhone"
28 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 33 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
29 /> 34 />
30 </div> 35 </div>
31 36
...@@ -40,13 +45,13 @@ ...@@ -40,13 +45,13 @@
40 type="text" 45 type="text"
41 required 46 required
42 maxlength="6" 47 maxlength="6"
43 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 48 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
44 /> 49 />
45 <button 50 <button
46 type="button" 51 type="button"
47 :disabled="countdown > 0 || !isPhoneValid" 52 :disabled="countdown > 0 || !isPhoneValid"
48 @click="sendVerificationCode" 53 @click="sendVerificationCode"
49 - class="mt-1 px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap" 54 + class="mt-1 whitespace-nowrap rounded-md border border-transparent bg-green-600 px-4 py-2 text-sm font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
50 > 55 >
51 {{ countdown > 0 ? `${countdown}秒后重试` : '获取验证码' }} 56 {{ countdown > 0 ? `${countdown}秒后重试` : '获取验证码' }}
52 </button> 57 </button>
...@@ -63,7 +68,7 @@ ...@@ -63,7 +68,7 @@
63 type="password" 68 type="password"
64 required 69 required
65 minlength="6" 70 minlength="6"
66 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 71 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
67 /> 72 />
68 </div> 73 </div>
69 74
...@@ -77,7 +82,7 @@ ...@@ -77,7 +82,7 @@
77 type="password" 82 type="password"
78 required 83 required
79 minlength="6" 84 minlength="6"
80 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 85 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
81 /> 86 />
82 </div> 87 </div>
83 88
...@@ -85,15 +90,15 @@ ...@@ -85,15 +90,15 @@
85 <button 90 <button
86 type="submit" 91 type="submit"
87 :disabled="loading" 92 :disabled="loading"
88 - class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500" 93 + class="flex w-full justify-center rounded-md border border-transparent bg-gradient-to-r from-green-500 to-green-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:from-green-600 hover:to-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2"
89 - :class="{ 'opacity-70 cursor-not-allowed': loading }" 94 + :class="{ 'cursor-not-allowed opacity-70': loading }"
90 > 95 >
91 {{ loading ? '提交中...' : '重置密码' }} 96 {{ loading ? '提交中...' : '重置密码' }}
92 </button> 97 </button>
93 </div> 98 </div>
94 </form> 99 </form>
95 100
96 - <div class="text-center mt-6"> 101 + <div class="mt-6 text-center">
97 <p class="text-sm text-gray-600"> 102 <p class="text-sm text-gray-600">
98 记起密码了? 103 记起密码了?
99 <router-link to="/login" class="font-medium text-green-600 hover:text-green-500"> 104 <router-link to="/login" class="font-medium text-green-600 hover:text-green-500">
...@@ -110,9 +115,9 @@ ...@@ -110,9 +115,9 @@
110 import { ref, reactive } from 'vue' 115 import { ref, reactive } from 'vue'
111 import { useRouter } from 'vue-router' 116 import { useRouter } from 'vue-router'
112 import FrostedGlass from '@/components/effects/FrostedGlass.vue' 117 import FrostedGlass from '@/components/effects/FrostedGlass.vue'
113 -import { smsAPI } from '@/api/common'; 118 +import { smsAPI } from '@/api/common'
114 -import { resetPasswordAPI } from '@/api/users'; 119 +import { resetPasswordAPI } from '@/api/users'
115 -import { showToast } from 'vant'; 120 +import { showToast } from 'vant'
116 121
117 const router = useRouter() 122 const router = useRouter()
118 const error = ref('') 123 const error = ref('')
...@@ -124,7 +129,7 @@ const formData = reactive({ ...@@ -124,7 +129,7 @@ const formData = reactive({
124 phone: '', 129 phone: '',
125 verificationCode: '', 130 verificationCode: '',
126 password: '', 131 password: '',
127 - confirmPassword: '' 132 + confirmPassword: '',
128 }) 133 })
129 134
130 const startCountdown = () => { 135 const startCountdown = () => {
...@@ -187,7 +192,7 @@ const handleSubmit = async () => { ...@@ -187,7 +192,7 @@ const handleSubmit = async () => {
187 const { code } = await resetPasswordAPI({ 192 const { code } = await resetPasswordAPI({
188 mobile: formData.phone, 193 mobile: formData.phone,
189 sms_code: formData.verificationCode, 194 sms_code: formData.verificationCode,
190 - password: formData.password 195 + password: formData.password,
191 }) 196 })
192 197
193 if (code === 1) { 198 if (code === 1) {
...@@ -195,7 +200,6 @@ const handleSubmit = async () => { ...@@ -195,7 +200,6 @@ const handleSubmit = async () => {
195 // 重置成功后跳转到登录页 200 // 重置成功后跳转到登录页
196 router.push('/login') 201 router.push('/login')
197 } 202 }
198 -
199 } catch (err) { 203 } catch (err) {
200 console.error('Reset password error:', err) 204 console.error('Reset password error:', err)
201 error.value = '重置密码失败,请稍后重试' 205 error.value = '重置密码失败,请稍后重试'
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
8 size="10rem" 8 size="10rem"
9 style="margin-bottom: 0.5rem" 9 style="margin-bottom: 0.5rem"
10 /> 10 />
11 - <h1 class="mb-2 text-center text-3xl font-bold text-gray-800">美乐爱觉教育</h1> 11 + <h1 class="mb-2 text-center text-3xl font-bold text-gray-800">生命力教育联盟教育</h1>
12 <!-- <h2 class="text-center text-xl font-medium text-gray-600">欢迎回来</h2> --> 12 <!-- <h2 class="text-center text-xl font-medium text-gray-600">欢迎回来</h2> -->
13 </div> 13 </div>
14 14
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
168 class="cursor-pointer font-medium text-green-600 hover:text-green-500" 168 class="cursor-pointer font-medium text-green-600 hover:text-green-500"
169 @click="userAgreementRef.openAgreement()" 169 @click="userAgreementRef.openAgreement()"
170 > 170 >
171 -美乐爱觉宇宙用户协议》 171 +生命力教育联盟宇宙用户协议》
172 </span> 172 </span>
173 <UserAgreement ref="userAgreementRef" /> 173 <UserAgreement ref="userAgreementRef" />
174 </p> 174 </p>
......
1 <template> 1 <template>
2 - <div class="min-h-screen flex flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 py-12 px-4 sm:px-6 lg:px-8"> 2 + <div
3 + class="flex min-h-screen flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 px-4 py-12 sm:px-6 lg:px-8"
4 + >
3 <div class="sm:mx-auto sm:w-full sm:max-w-md"> 5 <div class="sm:mx-auto sm:w-full sm:max-w-md">
4 - <h1 class="text-center text-3xl font-bold text-gray-800 mb-2">美乐爱觉教育</h1> 6 + <h1 class="mb-2 text-center text-3xl font-bold text-gray-800">生命力教育联盟教育</h1>
5 <h2 class="text-center text-xl font-medium text-gray-600">创建账号</h2> 7 <h2 class="text-center text-xl font-medium text-gray-600">创建账号</h2>
6 </div> 8 </div>
7 9
8 <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> 10 <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
9 - <FrostedGlass class="py-8 px-6 rounded-lg"> 11 + <FrostedGlass class="rounded-lg px-6 py-8">
10 - <div v-if="error" class="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-md"> 12 + <div
13 + v-if="error"
14 + class="mb-4 rounded-md border border-red-400 bg-red-100 px-4 py-3 text-red-700"
15 + >
11 {{ error }} 16 {{ error }}
12 </div> 17 </div>
13 18
...@@ -21,7 +26,7 @@ ...@@ -21,7 +26,7 @@
21 v-model="formData.name" 26 v-model="formData.name"
22 type="text" 27 type="text"
23 required 28 required
24 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 29 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
25 /> 30 />
26 </div> 31 </div>
27 32
...@@ -39,7 +44,7 @@ ...@@ -39,7 +44,7 @@
39 maxlength="11" 44 maxlength="11"
40 @input="formData.phone = formData.phone.replace(/\D/g, '')" 45 @input="formData.phone = formData.phone.replace(/\D/g, '')"
41 @blur="validatePhone" 46 @blur="validatePhone"
42 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 47 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
43 /> 48 />
44 </div> 49 </div>
45 50
...@@ -54,13 +59,13 @@ ...@@ -54,13 +59,13 @@
54 type="text" 59 type="text"
55 required 60 required
56 maxlength="6" 61 maxlength="6"
57 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 62 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
58 /> 63 />
59 <button 64 <button
60 type="button" 65 type="button"
61 :disabled="countdown > 0 || !isPhoneValid" 66 :disabled="countdown > 0 || !isPhoneValid"
62 @click="sendVerificationCode" 67 @click="sendVerificationCode"
63 - class="mt-1 px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap" 68 + class="mt-1 whitespace-nowrap rounded-md border border-transparent bg-green-600 px-4 py-2 text-sm font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
64 > 69 >
65 {{ countdown > 0 ? `${countdown}秒后重试` : '获取验证码' }} 70 {{ countdown > 0 ? `${countdown}秒后重试` : '获取验证码' }}
66 </button> 71 </button>
...@@ -78,7 +83,7 @@ ...@@ -78,7 +83,7 @@
78 autocomplete="new-password" 83 autocomplete="new-password"
79 required 84 required
80 minlength="6" 85 minlength="6"
81 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 86 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
82 /> 87 />
83 </div> 88 </div>
84 89
...@@ -93,7 +98,7 @@ ...@@ -93,7 +98,7 @@
93 autocomplete="new-password" 98 autocomplete="new-password"
94 required 99 required
95 minlength="6" 100 minlength="6"
96 - class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" 101 + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-green-500 focus:outline-none focus:ring-green-500"
97 /> 102 />
98 </div> 103 </div>
99 104
...@@ -105,15 +110,25 @@ ...@@ -105,15 +110,25 @@
105 checked-color="#4caf50" 110 checked-color="#4caf50"
106 class="scale-90" 111 class="scale-90"
107 icon-size="18px" 112 icon-size="18px"
108 - ><span class="text-sm">我已阅读并同意 <a href="#" class="text-green-600 hover:text-green-500" @click.prevent="openTerms">用户协议</a> 和 <a href="#" class="text-green-600 hover:text-green-500" @click.prevent="openPrivacy">隐私政策</a></span></van-checkbox> 113 + ><span class="text-sm"
114 + >我已阅读并同意
115 + <a href="#" class="text-green-600 hover:text-green-500" @click.prevent="openTerms"
116 + >用户协议</a
117 + >
118 +
119 + <a href="#" class="text-green-600 hover:text-green-500" @click.prevent="openPrivacy"
120 + >隐私政策</a
121 + ></span
122 + ></van-checkbox
123 + >
109 </div> 124 </div>
110 125
111 <div> 126 <div>
112 <button 127 <button
113 type="submit" 128 type="submit"
114 :disabled="loading" 129 :disabled="loading"
115 - class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gradient-to-r from-green-500 to-green-600 hover:from-green-600 hover:to-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500" 130 + class="flex w-full justify-center rounded-md border border-transparent bg-gradient-to-r from-green-500 to-green-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:from-green-600 hover:to-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2"
116 - :class="{ 'opacity-70 cursor-not-allowed': loading }" 131 + :class="{ 'cursor-not-allowed opacity-70': loading }"
117 > 132 >
118 {{ loading ? '注册中...' : '立即注册' }} 133 {{ loading ? '注册中...' : '立即注册' }}
119 </button> 134 </button>
...@@ -154,7 +169,7 @@ ...@@ -154,7 +169,7 @@
154 </div> 169 </div>
155 </div> --> 170 </div> -->
156 171
157 - <div class="text-center mt-6"> 172 + <div class="mt-6 text-center">
158 <p class="text-sm text-gray-600"> 173 <p class="text-sm text-gray-600">
159 已有账号? 174 已有账号?
160 <router-link to="/login" class="font-medium text-green-600 hover:text-green-500"> 175 <router-link to="/login" class="font-medium text-green-600 hover:text-green-500">
...@@ -165,16 +180,8 @@ ...@@ -165,16 +180,8 @@
165 </FrostedGlass> 180 </FrostedGlass>
166 </div> 181 </div>
167 182
168 - <TermsPopup 183 + <TermsPopup v-model:show="showTerms" :type="popupType" :title="popupTitle" />
169 - v-model:show="showTerms" 184 + <TermsPopup v-model:show="showPrivacy" :type="popupType" :title="popupTitle" />
170 - :type="popupType"
171 - :title="popupTitle"
172 - />
173 - <TermsPopup
174 - v-model:show="showPrivacy"
175 - :type="popupType"
176 - :title="popupTitle"
177 - />
178 </div> 185 </div>
179 </template> 186 </template>
180 187
...@@ -184,13 +191,13 @@ import { useRoute, useRouter } from 'vue-router' ...@@ -184,13 +191,13 @@ import { useRoute, useRouter } from 'vue-router'
184 import FrostedGlass from '@/components/effects/FrostedGlass.vue' 191 import FrostedGlass from '@/components/effects/FrostedGlass.vue'
185 import TermsPopup from '@/components/common/TermsPopup.vue' 192 import TermsPopup from '@/components/common/TermsPopup.vue'
186 import { useAuth } from '@/contexts/auth' 193 import { useAuth } from '@/contexts/auth'
187 -import { useTitle } from '@vueuse/core'; 194 +import { useTitle } from '@vueuse/core'
188 -import { smsAPI } from '@/api/common'; 195 +import { smsAPI } from '@/api/common'
189 -import { registerAPI } from '@/api/users'; 196 +import { registerAPI } from '@/api/users'
190 -import { showToast } from 'vant'; 197 +import { showToast } from 'vant'
191 198
192 -const $route = useRoute(); 199 +const $route = useRoute()
193 -useTitle($route.meta.title); 200 +useTitle($route.meta.title)
194 201
195 const router = useRouter() 202 const router = useRouter()
196 const { login } = useAuth() 203 const { login } = useAuth()
...@@ -203,7 +210,7 @@ const formData = reactive({ ...@@ -203,7 +210,7 @@ const formData = reactive({
203 verificationCode: '', 210 verificationCode: '',
204 password: '', 211 password: '',
205 confirmPassword: '', 212 confirmPassword: '',
206 - agreeTerms: false 213 + agreeTerms: false,
207 }) 214 })
208 215
209 const startCountdown = () => { 216 const startCountdown = () => {
...@@ -293,7 +300,7 @@ const handleSubmit = async () => { ...@@ -293,7 +300,7 @@ const handleSubmit = async () => {
293 const success = login({ 300 const success = login({
294 name: formData.name, 301 name: formData.name,
295 mobile: formData.phone, 302 mobile: formData.phone,
296 - avatar: '' 303 + avatar: '',
297 }) 304 })
298 if (success) { 305 if (success) {
299 router.push('/') 306 router.push('/')
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.