diff --git a/package-lock.json b/package-lock.json index dddcc45..a493c7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "hasInstallScript": true, "dependencies": { "axios": "^1.3.6", + "crypto-js": "^4.2.0", "gsap": "^3.13.0", "markdown-it": "^14.1.0", "normalize.css": "^8.0.1", @@ -22,6 +23,7 @@ }, "devDependencies": { "@rushstack/eslint-patch": "^1.2.0", + "@types/crypto-js": "^4.2.2", "@types/node": "^18.16.0", "@vant/auto-import-resolver": "^1.3.0", "@vitejs/plugin-vue": "^4.0.0", @@ -654,6 +656,13 @@ "node": ">=10.13.0" } }, + "node_modules/@types/crypto-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz", + "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz", @@ -2104,6 +2113,12 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, "node_modules/css-select": { "version": "4.3.0", "resolved": "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz", @@ -8935,6 +8950,12 @@ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "dev": true }, + "@types/crypto-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz", + "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==", + "dev": true + }, "@types/estree": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.1.tgz", @@ -10039,6 +10060,11 @@ "which": "^2.0.1" } }, + "crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, "css-select": { "version": "4.3.0", "resolved": "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz", diff --git a/package.json b/package.json index 6abf0ff..931f726 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "axios": "^1.3.6", + "crypto-js": "^4.2.0", "gsap": "^3.13.0", "markdown-it": "^14.1.0", "normalize.css": "^8.0.1", @@ -26,6 +27,7 @@ }, "devDependencies": { "@rushstack/eslint-patch": "^1.2.0", + "@types/crypto-js": "^4.2.2", "@types/node": "^18.16.0", "@vant/auto-import-resolver": "^1.3.0", "@vitejs/plugin-vue": "^4.0.0", diff --git a/src/router/index.ts b/src/router/index.ts index 1ddc069..ce5cba2 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,13 +1,38 @@ import { createRouter, createWebHistory } from 'vue-router' +import { useGenerateStore } from '@/stores/modules/generate' +const VerifyIDs = (num: number) => { + const ids = [ + !!useGenerateStore().customerId, + !!useGenerateStore().visitRecordId, + !!useGenerateStore().styleId, + // !!useGenerateStore().modelPhotoId, + true, + !!useGenerateStore().originalTryOnId, + ]; + return ids.splice(0, num).every(id => id) ? true : "/stylist/customer"; +} /** * 路由缓存机制: * 1. 设置路由的meta属性为{ cache: true },表示需要缓存 * 2. App.vue中使用RouteCache组件,通过路由的name来进行匹配 * 3. 路由的name默认是文件名,如果文件名与name不一致,通过defineOptions({ name: 'componentName' })来设置 + * + * 自定义验证规则: + * meta:{ verify: ()=> boolean || string } + * 1. boolean true 跳转 false 不跳转 + * 2. string 跳转的路由path */ - +/** 验证id + * @param num 验证id的数量1-5 + * 1. 顾客id + * 2. 进店记录id + * 3. 服装id + * 4. 模特照片id + * 5. 原始试穿id-优先AI魔改 + * @returns boolean + */ const router = createRouter({ history: createWebHistory('/'), // history: createWebHistory(import.meta.env.VITE_APP_URL), @@ -45,22 +70,25 @@ const router = createRouter({ { path: 'index', name: 'index', - component: () => import('@/views/stylist/index.vue') + component: () => import('@/views/stylist/index.vue'), + meta: { verify: ()=> VerifyIDs(2) } }, { path: 'sex', name: 'sex', - component: () => import('@/views/stylist/sex.vue') + component: () => import('@/views/stylist/sex.vue'), + meta: { verify: ()=> VerifyIDs(2) } }, { path: 'dressfor', name: 'dressfor', - component: () => import('@/views/stylist/dressfor.vue') + component: () => import('@/views/stylist/dressfor.vue'), + meta: { verify: ()=> VerifyIDs(2) } }, { path: 'customer', name: 'customer', - component: () => import('@/views/stylist/customer.vue') + component: () => import('@/views/stylist/customer.vue'), } ] }, @@ -68,7 +96,7 @@ const router = createRouter({ path: '/asistant', name: 'asistant', component: () => import('../views/asistant/index.vue'), - meta: { cache: true } + meta: { cache: true, verify: ()=> VerifyIDs(2) } }, { path: '/workshop', @@ -83,57 +111,67 @@ const router = createRouter({ path: '/workshop/selectStyle', name: 'SelectStyle', component: () => import('../views/Workshop/selectStyle.vue'), + meta: { verify: ()=> VerifyIDs(2) } }, { path: '/workshop/selectModel', name: 'SelectModel', - component: () => import('../views/Workshop/selectModel.vue') + component: () => import('../views/Workshop/selectModel.vue'), + meta: { verify: ()=> VerifyIDs(3) } }, { path: '/workshop/product', name: 'Product', - component: () => import('../views/Workshop/product.vue') + component: () => import('../views/Workshop/product.vue'), + meta: { verify: ()=> VerifyIDs(4) } }, { // 上传照片1 path: '/workshop/uploadFace', name: 'uploadFace', - component: () => import('../views/Workshop/uploadFace1.vue') + component: () => import('../views/Workshop/uploadFace1.vue'), + meta: { verify: ()=> VerifyIDs(5) } }, { // 上传照片2 path: '/workshop/uploadFace2', name: 'uploadFace2', - component: () => import('../views/Workshop/uploadFace2.vue') + component: () => import('../views/Workshop/uploadFace2.vue'), + meta: { verify: ()=> VerifyIDs(5) } }, { // 自定义创作 path: '/workshop/customize', name: 'customize', - component: () => import('../views/Workshop/customize.vue') + component: () => import('../views/Workshop/customize.vue'), + meta: { verify: ()=> VerifyIDs(5) } }, { // library path: '/workshop/library', name: 'library', - component: () => import('../views/Workshop/library.vue') + component: () => import('../views/Workshop/library.vue'), + meta: { verify: ()=> VerifyIDs(2) } }, { path: '/workshop/profile', name: 'profile', - component: () => import('../views/Workshop/profile.vue') + component: () => import('../views/Workshop/profile.vue'), + meta: { verify: ()=> VerifyIDs(1) } }, { // creation path: '/workshop/creation', name: 'creation', - component: () => import('../views/Workshop/creation/index.vue') + component: () => import('../views/Workshop/creation/index.vue'), + meta: { verify: ()=> VerifyIDs(2) } }, { // 完成创建 path: '/workshop/end', name: 'end', - component: () => import('../views/Workshop/end.vue') + component: () => import('../views/Workshop/end.vue'), + meta: { verify: ()=> VerifyIDs(2) } } ] } diff --git a/src/router/router-config.ts b/src/router/router-config.ts index 3fdf1ac..e9379b0 100644 --- a/src/router/router-config.ts +++ b/src/router/router-config.ts @@ -5,10 +5,22 @@ const whiteList = ['/login'] console.log(whiteList) router.beforeEach((to, from, next) => { - next() + requestAnimationFrame(() => { + const verify = to.meta?.verify; + if (typeof verify === 'function') { + const res = verify() + if (res === false) { + return next(false) + } else if (typeof res === 'string') { + console.log(res) + return next({ path: res }) + } + } + next() + }) }) router.afterEach(() => { - // finish progress bar - // NProgress.done() + // finish progress bar + // NProgress.done() }) diff --git a/src/stores/modules/generate.ts b/src/stores/modules/generate.ts index 68ac9cd..f62a40f 100644 --- a/src/stores/modules/generate.ts +++ b/src/stores/modules/generate.ts @@ -1,7 +1,6 @@ // 每一个存储的模块,命名规则use开头,store结尾 import { defineStore } from 'pinia' import MyEvent from '@/utils/myEvent' -import { uploadCustomerPhoto } from '@/api/workshop' MyEvent.add('clear-generate-state', () => useGenerateStore().clearGenerateData()) export const useGenerateStore = defineStore({ diff --git a/src/utils/tools.ts b/src/utils/tools.ts index 69b2286..65a05ec 100644 --- a/src/utils/tools.ts +++ b/src/utils/tools.ts @@ -1,3 +1,5 @@ +import CryptoJS from 'crypto-js' + function getUniversalZoomLevel() { // 现代浏览器方案 if (window.visualViewport) { @@ -146,3 +148,12 @@ export async function DownloadImages(list: Array<{ url: string, name?: string }> } typeof onSuccess === "function" && onSuccess(successCount, errCount); } + +/** + * MD5加密密码 + * @param password 原始密码 + * @returns MD5加密后的密码 + */ +export function encryptPassword(password: string): string { + return CryptoJS.MD5(password).toString() +} \ No newline at end of file diff --git a/src/views/Workshop/creation/creation-list.vue b/src/views/Workshop/creation/creation-list.vue index f6ff35b..8f9cbff 100644 --- a/src/views/Workshop/creation/creation-list.vue +++ b/src/views/Workshop/creation/creation-list.vue @@ -281,6 +281,7 @@ display: flex; align-items: center; justify-content: center; + background-color: #fff; } } > .icon-selected { diff --git a/src/views/Workshop/customize.vue b/src/views/Workshop/customize.vue index 3e0115b..0cf10aa 100644 --- a/src/views/Workshop/customize.vue +++ b/src/views/Workshop/customize.vue @@ -220,6 +220,7 @@ border: 0.24rem solid #000; display: flex; align-items: center; + background-color: #fff; > .icon { margin: 0 1.8rem; } @@ -246,6 +247,7 @@ display: flex; align-items: center; justify-content: center; + background-color: #fff; } } } diff --git a/src/views/Workshop/product.vue b/src/views/Workshop/product.vue index d004bab..f158ef3 100644 --- a/src/views/Workshop/product.vue +++ b/src/views/Workshop/product.vue @@ -179,6 +179,7 @@ const { isLoading } = toRefs(data); width: 100%; height: 100%; object-fit: contain; + display: block; } > .operation{ position: absolute; diff --git a/src/views/asistant/components/InputArea.vue b/src/views/asistant/components/InputArea.vue index a9ea235..78b75a4 100644 --- a/src/views/asistant/components/InputArea.vue +++ b/src/views/asistant/components/InputArea.vue @@ -196,7 +196,9 @@ const startRecording = () => { if (!speechRecognition) { // 检查浏览器支持 if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) { - alert('您的浏览器不支持语音识别功能') + // alert('您的浏览器不支持语音识别功能') + showToast('Your browser does not support speech recognition, please try again with another browser') + isRecording.value = false return } @@ -244,7 +246,7 @@ const startRecording = () => { // 显示临时结果(可选) if (interimTranscript) { - console.log('临时识别结果:', interimTranscript) + console.log('语音转文字识别中:', interimTranscript) } } @@ -261,6 +263,7 @@ const startRecording = () => { console.error('语音识别错误:', event.error) isRecording.value = false // alert('语音识别失败,请重试') + showToast('Speech recognition failed, please try again') showToast(event.error) } diff --git a/src/views/login/LoginPage.vue b/src/views/login/LoginPage.vue index d7fb2dd..6ddb689 100644 --- a/src/views/login/LoginPage.vue +++ b/src/views/login/LoginPage.vue @@ -50,6 +50,7 @@ import { useUserInfoStore } from '@/stores' import { showToast } from 'vant' import { google } from '@/assets/base64' import { fetchRegisterOrLogin } from '@/api/login' +import { encryptPassword } from '@/utils/tools' const router = useRouter() const userInfoStore = useUserInfoStore() @@ -109,7 +110,8 @@ const handleLogin = async () => { isLoading.value = true - fetchRegisterOrLogin({ ...formData, operationType: 'LOGIN' }).then((response) => { + const encryptedPassword = encryptPassword(formData.password) + fetchRegisterOrLogin({ ...formData, password: encryptedPassword, operationType: 'LOGIN' }).then((response) => { console.log('登录成功', response) userInfoStore.setToken(response.token) userInfoStore.setUserInfo(response.user) diff --git a/src/views/login/ResetPage.vue b/src/views/login/ResetPage.vue index 3561a50..c8ad072 100644 --- a/src/views/login/ResetPage.vue +++ b/src/views/login/ResetPage.vue @@ -22,7 +22,6 @@ v-else-if="step === 'verify'" :ct="emailCode" @nextStep="handleCheckVerifyCode" - @resend="handleSendVerifyCode" /> @@ -42,7 +41,8 @@ import Mail from './components/Mail.vue' import Verify from './components/Verify.vue' import Password from './components/Password.vue' import { showToast } from 'vant' -import { precheckEmail, resetPassword } from '@/api/login' +import { resetPassword } from '@/api/login' +import { encryptPassword } from '@/utils/tools' const router = useRouter() const step = ref<'mail' | 'verify' | 'password'>('mail') @@ -79,10 +79,8 @@ const handleSendVerifyCode = (data: any) => { if (data?.email) { fromData.value.email = data?.email } - precheckEmail({ email: fromData.value.email }).then(() => { - showToast('the verification code has been sent to your email') - handleStep('verify') - }) + // 只切换步骤,验证码的发送由 Verify 组件负责 + handleStep('verify') } const handleCheckVerifyCode = (data: any) => { @@ -92,7 +90,7 @@ const handleCheckVerifyCode = (data: any) => { } const handleSuccess = (data: any) => { - fromData.value.password = data.password + fromData.value.password = encryptPassword(data.password) resetPassword(fromData.value).then((res) => { // console.log('res', res) showToast('the password has been reset') diff --git a/src/views/login/SignupPage.vue b/src/views/login/SignupPage.vue index cb368c3..e1ef9cc 100644 --- a/src/views/login/SignupPage.vue +++ b/src/views/login/SignupPage.vue @@ -56,6 +56,7 @@ import { useRouter } from 'vue-router' import { showToast } from 'vant' import { google } from '@/assets/base64' import { fetchRegisterOrLogin } from '@/api/login' +import { encryptPassword } from '@/utils/tools' const router = useRouter() @@ -121,7 +122,8 @@ const handleConfirm = async () => { isLoading.value = true - fetchRegisterOrLogin({ ...formData, operationType: 'REGISTER' }) + const encryptedPassword = encryptPassword(formData.password) + fetchRegisterOrLogin({ ...formData, password: encryptedPassword, operationType: 'REGISTER' }) .then((res) => { console.log('res', res) showToast('register success') diff --git a/src/views/login/components/Verify.vue b/src/views/login/components/Verify.vue index 8305b0f..ca2f411 100644 --- a/src/views/login/components/Verify.vue +++ b/src/views/login/components/Verify.vue @@ -31,8 +31,10 @@
Confirm