This commit is contained in:
李志鹏
2026-06-01 11:18:35 +08:00
parent ad0f4f65e5
commit bf5c27d857
12 changed files with 54 additions and 22 deletions

View File

@@ -18,7 +18,7 @@ export default {
pleaseInputName: 'Please input the name',
nameLengthError: 'Name length must be between {min} and {max} characters',
passwordSpecial: 'Must contain special characters',
passwordCase: 'Mix of uppercase, lowercase and numbers',
passwordCase: 'A combination of numbers and letters',
pleaseInputEmail: 'Please input the email',
emailFormatError: 'Please input the email again',
pleaseInputPassword: 'Please input the password',
@@ -355,7 +355,7 @@ export default {
Offices: "Offices",
JoinWithUs: "Join with Us",
},
addShoppingCart:{
addShoppingCart: {
title: 'Added to your Shopping Cart',
statement: 'Digital Assets Only. No physical product included.',
button: 'Set Shopping Cart'

View File

@@ -18,7 +18,7 @@ export default {
pleaseInputName: '请输入姓名',
nameLengthError: '姓名长度必须在 {min} 到 {max} 个字符之间',
passwordSpecial: '必须包含特殊符号',
passwordCase: '大小写字母数字混合组合',
passwordCase: '字母数字组合',
pleaseInputEmail: '请输入邮箱',
emailFormatError: '请输入正确的邮箱',
pleaseInputPassword: '请输入密码',

View File

@@ -4,6 +4,7 @@ import { useGlobalStore } from '@/stores/global'
import { getUserLanguage } from '@/api/user'
import { fetchAllUnreadMessage } from '@/api/notification'
import i18n from '@/lang/index'
import myEvent from '@/utils/myEvent'
// 语言映射:后端格式 -> i18n 格式
const backendToI18nLanguage: Record<string, string> = {
@@ -19,6 +20,8 @@ let languageSynced = false
* 1. 设置路由的meta属性为{ cache: true },表示需要缓存
* 2. App.vue中使用RouteCache组件通过路由的name来进行匹配
* 3. 路由的name默认是文件名,如果文件名与name不一致,通过defineOptions({ name: 'componentName' })来设置
*
* 需要登录路由: meta={ login:true }
*/
const router = createRouter({
routes: [
@@ -62,7 +65,8 @@ const router = createRouter({
{
path: '/shoppingCart', // 购物车
name: 'shoppingCart',
component: () => import('@/views/shoppingCart/index.vue')
component: () => import('@/views/shoppingCart/index.vue'),
meta: { login: true }
},
{
path: '/notifications',
@@ -94,6 +98,9 @@ const router = createRouter({
})
router.beforeEach((to, from, next) => {
if(to.meta?.login && !useUserInfoStore().state.token) {
myEvent.emit('openLoginDialog')
}
next()
})

View File

@@ -28,6 +28,7 @@
> section {
width: 100%;
height: auto;
min-height: 50vw;
}
> section.bgw {
position: relative;
@@ -40,5 +41,8 @@
position: absolute;
}
}
> .section-footer {
min-height: 0;
}
}
</style>

View File

@@ -78,6 +78,7 @@
> div {
padding: 1rem;
border: 0.1rem solid #979797;
background-color: #fff;
> img {
width: 27.4rem;
height: 34.6rem;

View File

@@ -1,6 +1,6 @@
<template>
<section class="digital-items2 bgw">
<img src="@/assets/images/home/digital-items-1.jpg" class="bg" />
<img src="@/assets/images/home/digital-items-2.jpg" class="bg" />
<div class="content">
<div class="tip" v-html="$t('Home.DigitalItemsTip2')"></div>
<div class="list">
@@ -65,6 +65,7 @@
> div {
padding: 1rem;
border: 0.1rem solid #979797;
background-color: #fff;
> img {
width: 27.4rem;
height: 34.6rem;

View File

@@ -7,13 +7,13 @@
</el-icon>
<span>{{ $t('Login.passwordLengthError', { min: 6, max: 20 }) }}</span>
</div>
<div>
<!-- <div>
<el-icon>
<CloseBold v-if="validateSpecial(value)" />
<Select v-else />
</el-icon>
<span>{{ $t('Login.passwordSpecial') }}</span>
</div>
</div> -->
<div>
<el-icon>
<CloseBold v-if="validateCase(value)" />
@@ -42,7 +42,7 @@
color: #fff;
font-size: 1.1rem;
padding: 1.5rem;
border-radius: 1.5rem;
// border-radius: 1.5rem;
line-height: normal;
> div {

View File

@@ -23,15 +23,15 @@ export const validateEmail = (rule, value, callback) => {
export const validateLength = (v, min = 6, max = 20) => (v.length < 6 || v.length > 20);
//检查特殊字符
export const validateSpecial = (v) => (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(v));
//检查大小写字母和数字
export const validateCase = (v) => (!/[a-z]/.test(v) || !/[A-Z]/.test(v) || !/\d/.test(v));
//检查字母和数字
export const validateCase = (v) => (!/[A-z]/.test(v) || !/\d/.test(v));
// 检查密码
export const validatePass = (rule, value, callback) => {
var str = ''
if (validateLength(value)) {
str = t('Login.passwordLengthError', { min: 6, max: 20 })
} else if (validateSpecial(value)) {
str = t('Login.passwordSpecial')
// } else if (validateSpecial(value)) {
// str = t('Login.passwordSpecial')
} else if (validateCase(value)) {
str = t('Login.passwordCase')
}

View File

@@ -1,7 +1,11 @@
<template>
<div class="main-header" id="main-header">
<div class="left">
<img class="logo" src="@/assets/images/logo.png" @click="onNavItemClick('/')" />
<img
class="logo"
src="@/assets/images/logo.png"
@click="onNavItemClick({ path: '/' })"
/>
</div>
<div class="center">
<div
@@ -14,7 +18,7 @@
? activePath === v.path
: new RegExp(`^${v.path}`).test(activePath)
}"
@click="onNavItemClick(v.path)"
@click="onNavItemClick(v)"
>
<span>{{ $t(v.name) }}</span>
</div>
@@ -25,7 +29,7 @@
v-for="v in navList2"
:key="v.path"
:class="{ active: new RegExp(`^${v.path}`).test(activePath) }"
@click="onNavItemClick(v.path)"
@click="onNavItemClick(v)"
>
<svg-icon :name="activePath === v.path ? v.active_icon : v.icon" size="22" />
</div>
@@ -129,10 +133,15 @@
{
icon: 'cart_0',
active_icon: 'cart_1',
path: '/shoppingCart'
path: '/shoppingCart',
login: true
}
])
const onNavItemClick = (path: string) => {
const onNavItemClick = (v: any) => {
const path = v.path
if (v.login && !userInfoStore.state.token) {
return onLogin()
}
if (path === activePath.value) return
router.push(path)
}

View File

@@ -23,12 +23,12 @@
</div>
<div class="title">
<span class="icon"><svg-icon name="card" size="20" /></span>
<span class="text">Pay with Paypal</span>
<span class="text">Pay with Stripe</span>
</div>
<template v-if="!query.paymentId">
<div class="tip">
You'll be redirected to a Paypal popup to log in and confirm. No card details
are shared with Stylish Parade — PayPal handles all payment security.
You'll be redirected to a Stripe popup to log in and confirm. No card details
are shared with Stylish Parade — Stripe handles all payment security.
</div>
<div class="buttons">
<button custom="black" @click="onPayWith">

View File

@@ -11,7 +11,7 @@
<span class="text">{{ $t('ShoppingCart.brands') }}</span>
</div>
<div class="brands-item" v-for="v in brandsList" :key="v.brand">
<span class="label">{{ v.brand }}</span>
<span class="label" @click="handleBrandClick(v.id)">{{ v.brand }}</span>
<span class="value"
><span>{{ v.children.length }}</span
>{{ $t('ShoppingCart.item') }}</span
@@ -51,6 +51,7 @@
if (index === -1) {
arr.push({
brand: v.brand,
id: v.sellerId,
children: [v]
})
} else {
@@ -68,6 +69,12 @@
query: { list }
})
}
const handleBrandClick = (id) => {
router.push({
name: 'brandDetail',
params: { id }
})
}
</script>
<style lang="less" scoped>
@@ -124,6 +131,8 @@
> .label {
text-decoration: underline;
color: #585858;
cursor: pointer;
user-select: none;
}
> .value {
color: #808080;

View File

@@ -319,6 +319,7 @@
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
> .text {
font-family: KaiseiOpti-Bold;
font-size: var(--sc-list-title-font-size, 4rem);
@@ -420,7 +421,7 @@
}
}
.sc-list:deep(.el-select) {
width: 15rem;
width: 18rem;
--el-border-radius-base: 0;
--el-select-input-color: rgba(0, 0, 0, 0.5);
--el-select-input-font-size: 1rem;