优化
This commit is contained in:
@@ -18,7 +18,7 @@ export default {
|
|||||||
pleaseInputName: 'Please input the name',
|
pleaseInputName: 'Please input the name',
|
||||||
nameLengthError: 'Name length must be between {min} and {max} characters',
|
nameLengthError: 'Name length must be between {min} and {max} characters',
|
||||||
passwordSpecial: 'Must contain special 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',
|
pleaseInputEmail: 'Please input the email',
|
||||||
emailFormatError: 'Please input the email again',
|
emailFormatError: 'Please input the email again',
|
||||||
pleaseInputPassword: 'Please input the password',
|
pleaseInputPassword: 'Please input the password',
|
||||||
@@ -355,7 +355,7 @@ export default {
|
|||||||
Offices: "Offices",
|
Offices: "Offices",
|
||||||
JoinWithUs: "Join with Us",
|
JoinWithUs: "Join with Us",
|
||||||
},
|
},
|
||||||
addShoppingCart:{
|
addShoppingCart: {
|
||||||
title: 'Added to your Shopping Cart',
|
title: 'Added to your Shopping Cart',
|
||||||
statement: 'Digital Assets Only. No physical product included.',
|
statement: 'Digital Assets Only. No physical product included.',
|
||||||
button: 'Set Shopping Cart'
|
button: 'Set Shopping Cart'
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default {
|
|||||||
pleaseInputName: '请输入姓名',
|
pleaseInputName: '请输入姓名',
|
||||||
nameLengthError: '姓名长度必须在 {min} 到 {max} 个字符之间',
|
nameLengthError: '姓名长度必须在 {min} 到 {max} 个字符之间',
|
||||||
passwordSpecial: '必须包含特殊符号',
|
passwordSpecial: '必须包含特殊符号',
|
||||||
passwordCase: '大小写字母与数字混合组合',
|
passwordCase: '字母和数字组合',
|
||||||
pleaseInputEmail: '请输入邮箱',
|
pleaseInputEmail: '请输入邮箱',
|
||||||
emailFormatError: '请输入正确的邮箱',
|
emailFormatError: '请输入正确的邮箱',
|
||||||
pleaseInputPassword: '请输入密码',
|
pleaseInputPassword: '请输入密码',
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useGlobalStore } from '@/stores/global'
|
|||||||
import { getUserLanguage } from '@/api/user'
|
import { getUserLanguage } from '@/api/user'
|
||||||
import { fetchAllUnreadMessage } from '@/api/notification'
|
import { fetchAllUnreadMessage } from '@/api/notification'
|
||||||
import i18n from '@/lang/index'
|
import i18n from '@/lang/index'
|
||||||
|
import myEvent from '@/utils/myEvent'
|
||||||
|
|
||||||
// 语言映射:后端格式 -> i18n 格式
|
// 语言映射:后端格式 -> i18n 格式
|
||||||
const backendToI18nLanguage: Record<string, string> = {
|
const backendToI18nLanguage: Record<string, string> = {
|
||||||
@@ -19,6 +20,8 @@ let languageSynced = false
|
|||||||
* 1. 设置路由的meta属性为{ cache: true },表示需要缓存
|
* 1. 设置路由的meta属性为{ cache: true },表示需要缓存
|
||||||
* 2. App.vue中使用RouteCache组件,通过路由的name来进行匹配
|
* 2. App.vue中使用RouteCache组件,通过路由的name来进行匹配
|
||||||
* 3. 路由的name默认是文件名,如果文件名与name不一致,通过defineOptions({ name: 'componentName' })来设置
|
* 3. 路由的name默认是文件名,如果文件名与name不一致,通过defineOptions({ name: 'componentName' })来设置
|
||||||
|
*
|
||||||
|
* 需要登录路由: meta={ login:true }
|
||||||
*/
|
*/
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
routes: [
|
routes: [
|
||||||
@@ -62,7 +65,8 @@ const router = createRouter({
|
|||||||
{
|
{
|
||||||
path: '/shoppingCart', // 购物车
|
path: '/shoppingCart', // 购物车
|
||||||
name: 'shoppingCart',
|
name: 'shoppingCart',
|
||||||
component: () => import('@/views/shoppingCart/index.vue')
|
component: () => import('@/views/shoppingCart/index.vue'),
|
||||||
|
meta: { login: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/notifications',
|
path: '/notifications',
|
||||||
@@ -94,6 +98,9 @@ const router = createRouter({
|
|||||||
})
|
})
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
|
if(to.meta?.login && !useUserInfoStore().state.token) {
|
||||||
|
myEvent.emit('openLoginDialog')
|
||||||
|
}
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
> section {
|
> section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
min-height: 50vw;
|
||||||
}
|
}
|
||||||
> section.bgw {
|
> section.bgw {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -40,5 +41,8 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
> .section-footer {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -78,6 +78,7 @@
|
|||||||
> div {
|
> div {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border: 0.1rem solid #979797;
|
border: 0.1rem solid #979797;
|
||||||
|
background-color: #fff;
|
||||||
> img {
|
> img {
|
||||||
width: 27.4rem;
|
width: 27.4rem;
|
||||||
height: 34.6rem;
|
height: 34.6rem;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="digital-items2 bgw">
|
<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="content">
|
||||||
<div class="tip" v-html="$t('Home.DigitalItemsTip2')"></div>
|
<div class="tip" v-html="$t('Home.DigitalItemsTip2')"></div>
|
||||||
<div class="list">
|
<div class="list">
|
||||||
@@ -65,6 +65,7 @@
|
|||||||
> div {
|
> div {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border: 0.1rem solid #979797;
|
border: 0.1rem solid #979797;
|
||||||
|
background-color: #fff;
|
||||||
> img {
|
> img {
|
||||||
width: 27.4rem;
|
width: 27.4rem;
|
||||||
height: 34.6rem;
|
height: 34.6rem;
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
<span>{{ $t('Login.passwordLengthError', { min: 6, max: 20 }) }}</span>
|
<span>{{ $t('Login.passwordLengthError', { min: 6, max: 20 }) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<!-- <div>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<CloseBold v-if="validateSpecial(value)" />
|
<CloseBold v-if="validateSpecial(value)" />
|
||||||
<Select v-else />
|
<Select v-else />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>{{ $t('Login.passwordSpecial') }}</span>
|
<span>{{ $t('Login.passwordSpecial') }}</span>
|
||||||
</div>
|
</div> -->
|
||||||
<div>
|
<div>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<CloseBold v-if="validateCase(value)" />
|
<CloseBold v-if="validateCase(value)" />
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border-radius: 1.5rem;
|
// border-radius: 1.5rem;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
|
|||||||
@@ -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 validateLength = (v, min = 6, max = 20) => (v.length < 6 || v.length > 20);
|
||||||
//检查特殊字符
|
//检查特殊字符
|
||||||
export const validateSpecial = (v) => (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(v));
|
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) => {
|
export const validatePass = (rule, value, callback) => {
|
||||||
var str = ''
|
var str = ''
|
||||||
if (validateLength(value)) {
|
if (validateLength(value)) {
|
||||||
str = t('Login.passwordLengthError', { min: 6, max: 20 })
|
str = t('Login.passwordLengthError', { min: 6, max: 20 })
|
||||||
} else if (validateSpecial(value)) {
|
// } else if (validateSpecial(value)) {
|
||||||
str = t('Login.passwordSpecial')
|
// str = t('Login.passwordSpecial')
|
||||||
} else if (validateCase(value)) {
|
} else if (validateCase(value)) {
|
||||||
str = t('Login.passwordCase')
|
str = t('Login.passwordCase')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-header" id="main-header">
|
<div class="main-header" id="main-header">
|
||||||
<div class="left">
|
<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>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<div
|
<div
|
||||||
@@ -14,7 +18,7 @@
|
|||||||
? activePath === v.path
|
? activePath === v.path
|
||||||
: new RegExp(`^${v.path}`).test(activePath)
|
: new RegExp(`^${v.path}`).test(activePath)
|
||||||
}"
|
}"
|
||||||
@click="onNavItemClick(v.path)"
|
@click="onNavItemClick(v)"
|
||||||
>
|
>
|
||||||
<span>{{ $t(v.name) }}</span>
|
<span>{{ $t(v.name) }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -25,7 +29,7 @@
|
|||||||
v-for="v in navList2"
|
v-for="v in navList2"
|
||||||
:key="v.path"
|
:key="v.path"
|
||||||
:class="{ active: new RegExp(`^${v.path}`).test(activePath) }"
|
: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" />
|
<svg-icon :name="activePath === v.path ? v.active_icon : v.icon" size="22" />
|
||||||
</div>
|
</div>
|
||||||
@@ -129,10 +133,15 @@
|
|||||||
{
|
{
|
||||||
icon: 'cart_0',
|
icon: 'cart_0',
|
||||||
active_icon: 'cart_1',
|
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
|
if (path === activePath.value) return
|
||||||
router.push(path)
|
router.push(path)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span class="icon"><svg-icon name="card" size="20" /></span>
|
<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>
|
</div>
|
||||||
<template v-if="!query.paymentId">
|
<template v-if="!query.paymentId">
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
You'll be redirected to a Paypal popup to log in and confirm. No card details
|
You'll be redirected to a Stripe popup to log in and confirm. No card details
|
||||||
are shared with Stylish Parade — PayPal handles all payment security.
|
are shared with Stylish Parade — Stripe handles all payment security.
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button custom="black" @click="onPayWith">
|
<button custom="black" @click="onPayWith">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<span class="text">{{ $t('ShoppingCart.brands') }}</span>
|
<span class="text">{{ $t('ShoppingCart.brands') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="brands-item" v-for="v in brandsList" :key="v.brand">
|
<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 class="value"
|
||||||
><span>{{ v.children.length }}</span
|
><span>{{ v.children.length }}</span
|
||||||
>{{ $t('ShoppingCart.item') }}</span
|
>{{ $t('ShoppingCart.item') }}</span
|
||||||
@@ -51,6 +51,7 @@
|
|||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
arr.push({
|
arr.push({
|
||||||
brand: v.brand,
|
brand: v.brand,
|
||||||
|
id: v.sellerId,
|
||||||
children: [v]
|
children: [v]
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -68,6 +69,12 @@
|
|||||||
query: { list }
|
query: { list }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const handleBrandClick = (id) => {
|
||||||
|
router.push({
|
||||||
|
name: 'brandDetail',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@@ -124,6 +131,8 @@
|
|||||||
> .label {
|
> .label {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
color: #585858;
|
color: #585858;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
> .value {
|
> .value {
|
||||||
color: #808080;
|
color: #808080;
|
||||||
|
|||||||
@@ -319,6 +319,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
> .text {
|
> .text {
|
||||||
font-family: KaiseiOpti-Bold;
|
font-family: KaiseiOpti-Bold;
|
||||||
font-size: var(--sc-list-title-font-size, 4rem);
|
font-size: var(--sc-list-title-font-size, 4rem);
|
||||||
@@ -420,7 +421,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sc-list:deep(.el-select) {
|
.sc-list:deep(.el-select) {
|
||||||
width: 15rem;
|
width: 18rem;
|
||||||
--el-border-radius-base: 0;
|
--el-border-radius-base: 0;
|
||||||
--el-select-input-color: rgba(0, 0, 0, 0.5);
|
--el-select-input-color: rgba(0, 0, 0, 0.5);
|
||||||
--el-select-input-font-size: 1rem;
|
--el-select-input-font-size: 1rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user