diff --git a/src/api/user.ts b/src/api/user.ts index ae2967d..815fac8 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -1,34 +1,110 @@ import request from '@/utils/request' export interface WardrobeItem { - buyerId: number - categories: string[] - designFor: 'female' | 'male' | 'all' - page: number - size: number + buyerId: number + categories: string[] + designFor: 'female' | 'male' | 'all' + page: number + size: number } +// 获取我的衣橱assets export const fetchMyWardrobe = (data: WardrobeItem): Promise => { - return request({ - url: '/buyer/buyer/order/assets/page', - method: 'post', - data - }) + return request({ + url: '/buyer/buyer/order/assets/page', + method: 'post', + data + }) } export interface OrderItem { - status?: number // 0未支付 1已支付 2已取消 不传查全部 - page: number - size: number + status?: number // 0未支付 1已支付 2已取消 不传查全部 + page: number + size: number } export interface OrdersPageResponse { - content: any[] + content: any[] +} +// 获取我的衣橱 orders +export const fetchMyOrders = (data: OrderItem): Promise => { + return request({ + url: '/buyer/buyer/order/page', + method: 'get', + params: data + }) } -export const fetchMyOrders = (data: OrderItem): Promise => { - return request({ - url: '/buyer/buyer/order/page', - method: 'get', - params: data - }) +export interface Download { + ids: string[] +} +// 下载资源 +export const fetchDownloadItemsByGet = (params: Download): Promise => { + return request({ + url: '/buyer/listing/mall/main-product/download', + method: 'get', + responseType: 'blob', + params, + paramsSerializer: (p: any) => { + const usp = new URLSearchParams() + if (p && p.ids && Array.isArray(p.ids)) { + p.ids.forEach((id: any) => usp.append('ids', String(id))) + } else if (p) { + Object.keys(p).forEach((k) => { + const v = (p as any)[k] + if (Array.isArray(v)) { + v.forEach((x) => usp.append(k, String(x))) + } else if (v !== undefined && v !== null) { + usp.append(k, String(v)) + } + }) + } + return usp.toString() + } + }) +} + +// 获取用户信息 +export const fetchUserProfile = (): Promise => { + return request({ + url: '/buyer/profile/getProfile', + method: 'post' + }) +} + +// 设置用户信息 +export interface UserProfile { + firstName: string + lastName: string + username: string + roles: string[] + region: string + language: string + email: string + oldPassword?: string + newPassword?: string + verifyCode?: string +} +export const updateUserProfile = (data: UserProfile): Promise => { + return request({ + url: '/buyer/profile/setProfile', + method: 'post', + data + }) +} + +// 获取设置页验证码 +export const fetchVerifyCode = (): Promise => { + return request({ + url: '/buyer/profile/sendEmailChangeCode', + method: 'post' + }) +} + +// 验证设置页验证码 +export const verifyEmailCode = (verifyCode: string): Promise => { + return request({ + url: '/buyer/profile/verifyEmailChangeCode', + method: 'post', + data: { verifyCode } + }) } diff --git a/src/lang/en.ts b/src/lang/en.ts index c87d293..d145070 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -46,18 +46,21 @@ export default { submit: 'Submit', enterNewPassword: 'Enter a new password for
{email}', passwordsDoNotMatch: 'Passwords do not match', - logOffTip: 'Are you sure to log off?', + logOffTip: 'Are you sure to log off?' }, RegisterSuccess: { title1: 'Welcome to Stylish Parade!', title2: 'Please switch to the Login tab to log in.', title3: 'What awaits you in Stylish Parade', item1title: 'Behind the design', - item1tip: 'Discover how designers bring ideas to life with AiDA — from first sketch to final look.', + item1tip: + 'Discover how designers bring ideas to life with AiDA — from first sketch to final look.', item2title: 'Creative digital works', - item2tip: 'Unlock a growing library of inspiring digital works to refresh your creative mind.', + item2tip: + 'Unlock a growing library of inspiring digital works to refresh your creative mind.', item3title: 'A fashion community', - item3tip: 'Join a space where fashion speaks — exchange ideas and connect with creators worldwide.', + item3tip: + 'Join a space where fashion speaks — exchange ideas and connect with creators worldwide.' }, Settings: { title: 'Settings', @@ -73,7 +76,7 @@ export default { usernamePlaceholder: 'Username', usernameTip: 'Your public username on Stylish Parade.', role: 'ROLE', - roleTip: 'Select up to 2 labels that suit you.', + roleTip: 'Select up to 2 labels that suit you.' }, security: { title: 'Security', @@ -104,6 +107,7 @@ export default { discard: 'DISCARD', edit: 'EDIT', saveChange: 'SAVE CHANGE', + verifyEmail: 'VERIFY EMAIL', saving: 'SAVING...' }, dialog: { @@ -114,7 +118,7 @@ export default { resendCodeIn: 'Resend Code in {time}' }, messages: { - enterNewEmailFirst: 'Please enter your new email address first', + enterNewEmailFirst: 'Please enter your email address first', invalidEmail: 'Please enter a valid email address', sameEmail: 'Please enter a different email address', alreadyVerified: 'This email has already been verified', @@ -122,6 +126,11 @@ export default { enterVerificationCode: 'Please enter the 6-digit verification code', verificationCompleted: 'Email verification completed', verifyEmailBeforeSave: 'Please verify your new email before saving', + currentPasswordRequired: 'Please enter your current password', + passwordLengthError: 'Password length must be between {min} and {max} characters', + passwordSpecial: 'Password must contain special characters', + passwordCase: 'Password must include upper/lowercase letters and numbers', + passwordNotSameAsOld: 'New password cannot be the same as current password', settingsUpdated: 'Settings updated' }, roles: { @@ -139,7 +148,7 @@ export default { }, languages: { english: 'English', - chinese: 'Chinese', + chinese: 'Chinese' }, regions: { hongKongSar: 'Hong Kong SAR', @@ -152,7 +161,7 @@ export default { title: 'My Wardrobe', subtitle: 'Your digital pieces, all in one place', common: { - all: 'All', + all: 'All' }, tabs: { ariaLabel: 'Wardrobe tabs', @@ -226,33 +235,33 @@ export default { info3: 'This architecture is designed to elevate your exposure through profound "propositional expression," ensuring that soulful, story-driven designs achieve higher market premiums and superior sales conversion.' } }, - footer:{ + footer: { About: 'About', PrivacyPolicy: 'Privacy Policy', TermsOfUse: 'Terms of Use', Disclaimer: 'Disclaimer', - SiteMap: 'Site Map', + SiteMap: 'Site Map' }, - brand:{ + brand: { title: 'Brand', description: "Every brand, every story — discover who's behind the collections.", search: 'Search brand', noFound: 'Brand No Found', noFoundTip: 'Try using another keywords.', searchHistory: 'Searching History', - brandItem:{ - viewProfile: 'View Profile', + brandItem: { + viewProfile: 'View Profile' } }, - brandDetail:{ + brandDetail: { addShoppingTip: 'Please log in first.', merchantInfo: { Contact: 'Contact', - About: 'About', + About: 'About' }, - All: 'All', + All: 'All' }, - digitalItem:{ + digitalItem: { BestSelling: 'Best Selling', Price: 'Price: Low to High', SelectedFirst: 'Selected First', @@ -267,11 +276,11 @@ export default { Filters: 'Filters', Clear: 'Clear', Categories: 'Categories', - Gender: 'Gender', + Gender: 'Gender' } }, checked: { - All: 'All', + All: 'All' }, MainHeader: { Home: 'Home', @@ -281,7 +290,7 @@ export default { HiName: 'Hi, {name}', MyWardrobe: 'My Wardrobe', Notifications: 'Notifications', - Settings: 'Settings', + Settings: 'Settings' }, ShoppingCart: { title: 'Shopping Cart', @@ -300,9 +309,9 @@ export default { selected: 'Selected', brands: 'Brands', item: 'item', - checkoutSelected: 'Checkout Selected', + checkoutSelected: 'Checkout Selected' }, - digitalDetail:{ + digitalDetail: { Sketch: 'Sketch', Illustration: 'Illustration', Product: 'Product Image', @@ -311,9 +320,10 @@ export default { ReleaseIn: 'Release in', CopyrightLicenseNotice: 'Copyright & License Notice', LicenseIncludedInAsset: 'License Included in Asset', - LicenseIncludedInAssetInfo: 'All products on this platform are digital assets, not physical goods. Purchase grants a usage license only; copyright and intellectual property rights remain with the original creator, unless otherwise stated.', + LicenseIncludedInAssetInfo: + 'All products on this platform are digital assets, not physical goods. Purchase grants a usage license only; copyright and intellectual property rights remain with the original creator, unless otherwise stated.', BuyNow: 'Buy Now', - AddToCart: 'Add to Cart', + AddToCart: 'Add to Cart' }, Home: { IndexTitle: 'We’re Seeking
Fashion Voice
Worth Featuring.', @@ -348,6 +358,22 @@ export default { addShoppingCart:{ title: 'Added to your Shopping Cart', statement: 'Digital Assets Only. No physical product included.', - button: 'Set Shopping Cart', + button: 'Set Shopping Cart' + }, + area: { + chinaMainland: 'China Mainland', + hongKongSar: 'Hong Kong SAR', + macauSar: 'Macau SAR', + taiwan: 'Taiwan', + japan: 'Japan', + southKorea: 'South Korea', + singapore: 'Singapore', + unitedStates: 'United States', + unitedKingdom: 'United Kingdom', + france: 'France', + italy: 'Italy', + germany: 'Germany', + australia: 'Australia', + canada: 'Canada' } -} \ No newline at end of file +} diff --git a/src/lang/zh-cn.ts b/src/lang/zh-cn.ts index e031cf3..b0c5200 100644 --- a/src/lang/zh-cn.ts +++ b/src/lang/zh-cn.ts @@ -46,7 +46,7 @@ export default { submit: '提交', enterNewPassword: '请输入新密码
{email}', passwordsDoNotMatch: '两次输入密码不一致', - logOffTip: '确定退出登录吗?', + logOffTip: '确定退出登录吗?' }, RegisterSuccess: { title1: '欢迎来到 Stylish Parade!', @@ -57,7 +57,7 @@ export default { item2title: '创意数字作品', item2tip: '解锁一个增长的数字作品库,刷新你的创意。', item3title: '时尚社区', - item3tip: '加入一个全球的时尚社区,与设计师分享创意。', + item3tip: '加入一个全球的时尚社区,与设计师分享创意。' }, Settings: { title: '设置', @@ -73,7 +73,7 @@ export default { usernamePlaceholder: '请输入用户名', usernameTip: '这是你在 Stylish Parade 上公开显示的用户名。', role: '身份标签', - roleTip: '最多选择 2 个符合你的标签。', + roleTip: '最多选择 2 个符合你的标签。' }, security: { title: '安全', @@ -104,6 +104,7 @@ export default { discard: '放弃', edit: '编辑', saveChange: '保存更改', + verifyEmail: '验证邮箱', saving: '保存中...' }, dialog: { @@ -122,6 +123,11 @@ export default { enterVerificationCode: '请输入 6 位验证码', verificationCompleted: '邮箱验证完成', verifyEmailBeforeSave: '请先完成新邮箱验证再保存', + currentPasswordRequired: '请输入当前密码', + passwordLengthError: '密码长度必须在 {min} 到 {max} 个字符之间', + passwordSpecial: '密码必须包含特殊符号', + passwordCase: '密码必须包含大小写字母和数字', + passwordNotSameAsOld: '新密码不能与旧密码相同', settingsUpdated: '设置已更新' }, roles: { @@ -139,7 +145,7 @@ export default { }, languages: { english: '英文', - chinese: '中文', + chinese: '中文' }, regions: { hongKongSar: '中国香港特别行政区', @@ -152,7 +158,7 @@ export default { title: '我的衣橱', subtitle: '你的数字单品尽在此处', common: { - all: '全部', + all: '全部' }, tabs: { ariaLabel: '衣橱标签页', @@ -216,62 +222,62 @@ export default { }, collectionStory: { back: '返回首页', - title: "我们在寻找", - description: "值得被听见的时尚之声", - button: "如有兴趣,请联系我们", + title: '我们在寻找', + description: '值得被听见的时尚之声', + button: '如有兴趣,请联系我们', joinUs: { title: '加入我们的设计师社区,', - info: "加入我们的远见者社区,发表你的系列故事。", - info2: "我们目前正在寻找深度整合 AiDA 创意工作流程的系列作品,特别是那些通过强大的核心理念和富有感染力的灵感而产生共鸣的作品。", - info3: "这一架构旨在通过深刻的‘命题式表达’提升你的曝光度,确保那些有灵魂、由故事驱动的设计能获得更高的市场溢价和卓越的销售转化率。" + info: '加入我们的远见者社区,发表你的系列故事。', + info2: '我们目前正在寻找深度整合 AiDA 创意工作流程的系列作品,特别是那些通过强大的核心理念和富有感染力的灵感而产生共鸣的作品。', + info3: '这一架构旨在通过深刻的‘命题式表达’提升你的曝光度,确保那些有灵魂、由故事驱动的设计能获得更高的市场溢价和卓越的销售转化率。' } }, - footer:{ + footer: { About: '关于我们', PrivacyPolicy: '隐私政策', TermsOfUse: '条款与条件', Disclaimer: '免责声明', - SiteMap: '地图', + SiteMap: '地图' }, - brand:{ - title: "品牌", - description: "每一个品牌,每一个故事 — 发现系列作品背后的缔造者。", - search: "搜索品牌", - noFound: "未找到品牌", - noFoundTip: "请尝试使用其他关键词。", - searchHistory: "搜索历史", + brand: { + title: '品牌', + description: '每一个品牌,每一个故事 — 发现系列作品背后的缔造者。', + search: '搜索品牌', + noFound: '未找到品牌', + noFoundTip: '请尝试使用其他关键词。', + searchHistory: '搜索历史', brandItem: { - viewProfile: "查看简介" + viewProfile: '查看简介' } }, - brandDetail:{ - addShoppingTip: "请先登录。", + brandDetail: { + addShoppingTip: '请先登录。', merchantInfo: { - Contact: "联系方式", - About: "关于我们" + Contact: '联系方式', + About: '关于我们' }, - All: "全部" + All: '全部' }, digitalItem: { - BestSelling: "畅销优先", - Price: "价格:从低到高", - SelectedFirst: "已选优先", - DateAdded: "添加日期", - NewestFirst: "最新优先", - title: "数字藏品", - info: "收藏于个人档案中的虚拟时装作品", - sortBy: "排序方式", - noData: "暂无数字藏品", - noDataTip: "请尝试调整筛选条件或刷新页面。", + BestSelling: '畅销优先', + Price: '价格:从低到高', + SelectedFirst: '已选优先', + DateAdded: '添加日期', + NewestFirst: '最新优先', + title: '数字藏品', + info: '收藏于个人档案中的虚拟时装作品', + sortBy: '排序方式', + noData: '暂无数字藏品', + noDataTip: '请尝试调整筛选条件或刷新页面。', MerchantInfo: { - Filters: "筛选", - Clear: "清空", - Categories: "分类", - Gender: "适用性别" + Filters: '筛选', + Clear: '清空', + Categories: '分类', + Gender: '适用性别' } }, checked: { - All: "全部" + All: '全部' }, MainHeader: { Home: '首页', @@ -281,7 +287,7 @@ export default { HiName: '你好,{name}', MyWardrobe: '我的衣橱', Notifications: '通知', - Settings: '设置', + Settings: '设置' }, ShoppingCart: { title: '购物车', @@ -300,54 +306,80 @@ export default { selected: '已选', brands: '品牌', item: '数字藏品', - checkoutSelected: '结账', + checkoutSelected: '结账' }, - digitalDetail:{ - Sketch: "草图", - Illustration: "插画", - Product: "产品", - EditorialVisual: "编辑视觉", - Back: "返回", - ReleaseIn: "发布于", - CopyrightLicenseNotice: "版权与许可声明", - LicenseIncludedInAsset: "资产包含许可", - LicenseIncludedInAssetInfo: "本平台所有产品均为数字资产,非实物商品。购买仅授予使用许可;版权及知识产权仍归原作者所有,除非另有说明。", - BuyNow: "立即购买", - AddToCart: "加入购物车" + digitalDetail: { + Sketch: '草图', + Illustration: '插画', + Product: '产品', + EditorialVisual: '编辑视觉', + Back: '返回', + ReleaseIn: '发布于', + CopyrightLicenseNotice: '版权与许可声明', + LicenseIncludedInAsset: '资产包含许可', + LicenseIncludedInAssetInfo: + '本平台所有产品均为数字资产,非实物商品。购买仅授予使用许可;版权及知识产权仍归原作者所有,除非另有说明。', + BuyNow: '立即购买', + AddToCart: '加入购物车' + }, + addShoppingCart: { + title: '已添加到您的购物车', + statement: '仅限数字资产。不包含实体产品。', + button: '去购物车' + }, + area: { + chinaMainland: '中国大陆', + hongKongSar: '中国香港特别行政区', + macauSar: '中国澳门特别行政区', + taiwan: '中国台湾', + japan: '日本', + southKorea: '韩国', + singapore: '新加坡', + unitedStates: '美国', + unitedKingdom: '英国', + france: '法国', + italy: '意大利', + germany: '德国', + australia: '澳大利亚', + canada: '加拿大' }, Home: { IndexTitle: '我们正在寻
找值得推广
的时尚之声。', - IndexTip: '通过了解每件作品背后的故事来探索其收藏品。这是一个精心打造的场所,将设计师、故事和时尚商业紧密相连。', + IndexTip: + '通过了解每件作品背后的故事来探索其收藏品。这是一个精心打造的场所,将设计师、故事和时尚商业紧密相连。', DesignerTitle: '设计师社区', DesignerTip: '发现 AiDA 创意社区的设计师。
每月我们都会展示他们最杰出的作品。', SearchBrands: '搜索品牌', AidaTitle: '使用 AiDA 设计', - AidaTip: '在这个平台上,每一件服装都是设计师创意在 AiDA 软件中绽放的成果。AiDA 是一款能激发您的创造力的工具,它从不掩盖您的才华。让您的创意尽情绽放吧。', + AidaTip: + '在这个平台上,每一件服装都是设计师创意在 AiDA 软件中绽放的成果。AiDA 是一款能激发您的创造力的工具,它从不掩盖您的才华。让您的创意尽情绽放吧。', TryNow: '立即试用', DigitalItems: '数字藏品', - DigitalItemsTip1: 'AiDA 能够捕捉您最激昂的想法,并将其转化为生动的形象。
“数字愿景”一个充满创造力碰撞与发展的虚拟世界。', - DigitalItemsTip2: 'AiDA 风格的创新,打造出实用性强的日常服饰,这些服饰能够经久耐用。
你的衣橱与现代时尚的节奏保持同步。', + DigitalItemsTip1: + 'AiDA 能够捕捉您最激昂的想法,并将其转化为生动的形象。
“数字愿景”一个充满创造力碰撞与发展的虚拟世界。', + DigitalItemsTip2: + 'AiDA 风格的创新,打造出实用性强的日常服饰,这些服饰能够经久耐用。
你的衣橱与现代时尚的节奏保持同步。', FooterTip: 'Stylish Parade 是一个为设计师提供的商业平台,它作为 AiDA 商业的商业扩展。', FooterAidaTip: '使用 AiDA 设计', - Help: "帮助", - FAQ: "常见问题", - MyAccount: "我的账户", - MyOrders: "我的订单", - PaymentInvoices: "支付发票", - CopyrightLicense: "版权与许可声明", - Polices: "政策", - Legal: "法律", - PrivacyPolicy: "隐私政策", - CookiesSettings: "Cookie 设置", - PurchaseConditions: "购买条件", - Company: "公司", - AboutUs: "关于我们", - Offices: "办公室", - JoinWithUs: "加入我们", + Help: '帮助', + FAQ: '常见问题', + MyAccount: '我的账户', + MyOrders: '我的订单', + PaymentInvoices: '支付发票', + CopyrightLicense: '版权与许可声明', + Polices: '政策', + Legal: '法律', + PrivacyPolicy: '隐私政策', + CookiesSettings: 'Cookie 设置', + PurchaseConditions: '购买条件', + Company: '公司', + AboutUs: '关于我们', + Offices: '办公室', + JoinWithUs: '加入我们' }, - addShoppingCart:{ - title: "已添加到您的购物车", - statement: "仅限数字资产。不包含实体产品。", - button: "去购物车" + addShoppingCart: { + title: '已添加到您的购物车', + statement: '仅限数字资产。不包含实体产品。', + button: '去购物车' } } diff --git a/src/utils/area.ts b/src/utils/area.ts new file mode 100644 index 0000000..a761010 --- /dev/null +++ b/src/utils/area.ts @@ -0,0 +1,86 @@ +export default [ + { + key: 'chinaMainland', + name: 'China Mainland', + label: 'China Mainland', + value: 'China Mainland' + }, + { + key: 'hongKongSar', + name: 'Hong Kong SAR', + label: 'Hong Kong SAR', + value: 'Hong Kong SAR' + }, + { + key: 'macauSar', + name: 'Macau SAR', + label: 'Macau SAR', + value: 'Macau SAR' + }, + { + key: 'taiwan', + name: 'Taiwan', + label: 'Taiwan', + value: 'Taiwan' + }, + { + key: 'japan', + name: 'Japan', + label: 'Japan', + value: 'Japan' + }, + { + key: 'southKorea', + name: 'South Korea', + label: 'South Korea', + value: 'South Korea' + }, + { + key: 'singapore', + name: 'Singapore', + label: 'Singapore', + value: 'Singapore' + }, + { + key: 'unitedStates', + name: 'United States', + label: 'United States', + value: 'United States' + }, + { + key: 'unitedKingdom', + name: 'United Kingdom', + label: 'United Kingdom', + value: 'United Kingdom' + }, + { + key: 'france', + name: 'France', + label: 'France', + value: 'France' + }, + { + key: 'italy', + name: 'Italy', + label: 'Italy', + value: 'Italy' + }, + { + key: 'germany', + name: 'Germany', + label: 'Germany', + value: 'Germany' + }, + { + key: 'australia', + name: 'Australia', + label: 'Australia', + value: 'Australia' + }, + { + key: 'canada', + name: 'Canada', + label: 'Canada', + value: 'Canada' + } +] diff --git a/src/utils/request.ts b/src/utils/request.ts index 6eef519..c0240df 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -65,6 +65,16 @@ service.interceptors.response.use( if (response.config.url.includes('llm/streamChat')) { return response } + // 如果是二进制下载(blob/arraybuffer),直接返回原始 response 以便调用方处理文件 + if ( + response.config.responseType === 'blob' || + response.config.responseType === 'arraybuffer' || + response.headers['content-type'] === 'application/octet-stream' + ) { + removePending(response.config) + if (response.config.loading) closeLoading() + return response + } // 已完成请求的删除请求中数组 removePending(response.config) diff --git a/src/views/setting/components/RegionSection.vue b/src/views/setting/components/RegionSection.vue index c640893..f1e9bfb 100644 --- a/src/views/setting/components/RegionSection.vue +++ b/src/views/setting/components/RegionSection.vue @@ -27,7 +27,7 @@
{{ t('Settings.region.region') }}
- {{ displayRegionLabel }} + {{ t(`area.${displayRegionLabel}`) }}
diff --git a/src/views/setting/components/SecuritySection.vue b/src/views/setting/components/SecuritySection.vue index 2d6d865..6c73d08 100644 --- a/src/views/setting/components/SecuritySection.vue +++ b/src/views/setting/components/SecuritySection.vue @@ -23,18 +23,18 @@ :placeholder="t('Settings.security.newEmailPlaceholder')" @update:model-value="emit('update:newEmail', String($event))" /> - + -->
-
+
diff --git a/src/views/setting/components/SettingsActions.vue b/src/views/setting/components/SettingsActions.vue index d4fa7a5..69ed412 100644 --- a/src/views/setting/components/SettingsActions.vue +++ b/src/views/setting/components/SettingsActions.vue @@ -1,7 +1,10 @@