Commit 322d93db authored by tyyin lan's avatar tyyin lan

feat: 礼包兑换&路由调整&首页样式调整

parent 9e9b2a7f
......@@ -23,6 +23,7 @@
"axios": "^1.7.7",
"clipboardy": "^4.0.0",
"dayjs": "^1.11.13",
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"pinia": "^2.2.2",
"spark-md5": "^3.0.2",
......@@ -34,6 +35,7 @@
"@commitlint/cli": "^19.4.1",
"@commitlint/config-conventional": "^19.4.1",
"@commitlint/types": "^19.0.3",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.16.5",
"@types/spark-md5": "^3.0.4",
"@types/validator": "^13.12.1",
......
......@@ -29,6 +29,9 @@ importers:
dayjs:
specifier: ^1.11.13
version: 1.11.13
lodash-es:
specifier: ^4.17.21
version: 4.17.21
nanoid:
specifier: ^5.0.7
version: 5.0.7
......@@ -57,6 +60,9 @@ importers:
'@commitlint/types':
specifier: ^19.0.3
version: 19.0.3
'@types/lodash-es':
specifier: ^4.17.12
version: 4.17.12
'@types/node':
specifier: ^20.16.5
version: 20.16.5
......@@ -68,10 +74,10 @@ importers:
version: 13.12.1
'@typescript-eslint/parser':
specifier: ^7.18.0
version: 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
version: 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@unocss/eslint-config':
specifier: ^0.61.9
version: 0.61.9(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
version: 0.61.9(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@vitejs/plugin-vue':
specifier: ^4.6.2
version: 4.6.2(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))(vue@3.5.5(typescript@5.5.4))
......@@ -80,16 +86,16 @@ importers:
version: 10.4.20(postcss@8.4.45)
eslint:
specifier: ^9.9.1
version: 9.9.1(jiti@2.0.0-beta.3)
version: 9.9.1(jiti@1.21.6)
eslint-config-prettier:
specifier: ^9.1.0
version: 9.1.0(eslint@9.9.1(jiti@2.0.0-beta.3))
version: 9.1.0(eslint@9.9.1(jiti@1.21.6))
eslint-plugin-prettier:
specifier: ^5.2.1
version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@2.0.0-beta.3)))(eslint@9.9.1(jiti@2.0.0-beta.3))(prettier@3.3.3)
version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)))(eslint@9.9.1(jiti@1.21.6))(prettier@3.3.3)
eslint-plugin-vue:
specifier: ^9.28.0
version: 9.28.0(eslint@9.9.1(jiti@2.0.0-beta.3))
version: 9.28.0(eslint@9.9.1(jiti@1.21.6))
globals:
specifier: ^15.9.0
version: 15.9.0
......@@ -146,7 +152,7 @@ importers:
version: 5.5.4
typescript-eslint:
specifier: ^7.18.0
version: 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
version: 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
unocss:
specifier: ^0.61.9
version: 0.61.9(postcss@8.4.45)(rollup@4.21.2)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))
......@@ -161,10 +167,10 @@ importers:
version: 5.4.3(@types/node@20.16.5)(sass@1.78.0)
vite-plugin-checker:
specifier: ^0.7.2
version: 0.7.2(eslint@9.9.1(jiti@2.0.0-beta.3))(meow@13.2.0)(optionator@0.9.4)(stylelint@16.9.0(typescript@5.5.4))(typescript@5.5.4)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))(vue-tsc@2.0.29(typescript@5.5.4))
version: 0.7.2(eslint@9.9.1(jiti@1.21.6))(optionator@0.9.4)(stylelint@16.9.0(typescript@5.5.4))(typescript@5.5.4)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))(vue-tsc@2.0.29(typescript@5.5.4))
vue-eslint-parser:
specifier: ^9.4.3
version: 9.4.3(eslint@9.9.1(jiti@2.0.0-beta.3))
version: 9.4.3(eslint@9.9.1(jiti@1.21.6))
vue-tsc:
specifier: ~2.0.29
version: 2.0.29(typescript@5.5.4)
......@@ -3527,9 +3533,9 @@ snapshots:
'@esbuild/win32-x64@0.23.1':
optional: true
'@eslint-community/eslint-utils@4.4.0(eslint@9.9.1(jiti@2.0.0-beta.3))':
'@eslint-community/eslint-utils@4.4.0(eslint@9.9.1(jiti@1.21.6))':
dependencies:
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.11.0': {}
......@@ -3702,15 +3708,15 @@ snapshots:
'@types/web-bluetooth@0.0.20': {}
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4))(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)':
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@eslint-community/regexpp': 4.11.0
'@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/type-utils': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/type-utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.18.0
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
......@@ -3720,14 +3726,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)':
'@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.7
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
......@@ -3738,12 +3744,12 @@ snapshots:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0
'@typescript-eslint/type-utils@7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)':
'@typescript-eslint/type-utils@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
debug: 4.3.7
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies:
typescript: 5.5.4
......@@ -3767,13 +3773,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)':
'@typescript-eslint/utils@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@2.0.0-beta.3))
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6))
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
transitivePeerDependencies:
- supports-color
- typescript
......@@ -3822,17 +3828,17 @@ snapshots:
'@unocss/core@0.61.9': {}
'@unocss/eslint-config@0.61.9(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)':
'@unocss/eslint-config@0.61.9(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@unocss/eslint-plugin': 0.61.9(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@unocss/eslint-plugin': 0.61.9(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
transitivePeerDependencies:
- eslint
- supports-color
- typescript
'@unocss/eslint-plugin@0.61.9(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)':
'@unocss/eslint-plugin@0.61.9(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@unocss/config': 0.61.9
'@unocss/core': 0.61.9
magic-string: 0.30.11
......@@ -4467,29 +4473,29 @@ snapshots:
escape-string-regexp@5.0.0: {}
eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@2.0.0-beta.3)):
eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)):
dependencies:
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@2.0.0-beta.3)))(eslint@9.9.1(jiti@2.0.0-beta.3))(prettier@3.3.3):
eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.9.1(jiti@1.21.6)))(eslint@9.9.1(jiti@1.21.6))(prettier@3.3.3):
dependencies:
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
prettier: 3.3.3
prettier-linter-helpers: 1.0.0
synckit: 0.9.1
optionalDependencies:
eslint-config-prettier: 9.1.0(eslint@9.9.1(jiti@2.0.0-beta.3))
eslint-config-prettier: 9.1.0(eslint@9.9.1(jiti@1.21.6))
eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@2.0.0-beta.3)):
eslint-plugin-vue@9.28.0(eslint@9.9.1(jiti@1.21.6)):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@2.0.0-beta.3))
eslint: 9.9.1(jiti@2.0.0-beta.3)
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6))
eslint: 9.9.1(jiti@1.21.6)
globals: 13.24.0
natural-compare: 1.4.0
nth-check: 2.1.1
postcss-selector-parser: 6.1.2
semver: 7.6.3
vue-eslint-parser: 9.4.3(eslint@9.9.1(jiti@2.0.0-beta.3))
vue-eslint-parser: 9.4.3(eslint@9.9.1(jiti@1.21.6))
xml-name-validator: 4.0.0
transitivePeerDependencies:
- supports-color
......@@ -4508,9 +4514,9 @@ snapshots:
eslint-visitor-keys@4.0.0: {}
eslint@9.9.1(jiti@2.0.0-beta.3):
eslint@9.9.1(jiti@1.21.6):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@2.0.0-beta.3))
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.6))
'@eslint-community/regexpp': 4.11.0
'@eslint/config-array': 0.18.0
'@eslint/eslintrc': 3.1.0
......@@ -4545,7 +4551,7 @@ snapshots:
strip-ansi: 6.0.1
text-table: 0.2.0
optionalDependencies:
jiti: 2.0.0-beta.3
jiti: 1.21.6
transitivePeerDependencies:
- supports-color
......@@ -5576,12 +5582,12 @@ snapshots:
type-fest@0.21.3: {}
typescript-eslint@7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4):
typescript-eslint@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4):
dependencies:
'@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4))(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@2.0.0-beta.3))(typescript@5.5.4)
eslint: 9.9.1(jiti@2.0.0-beta.3)
'@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/parser': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
eslint: 9.9.1(jiti@1.21.6)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
......@@ -5715,7 +5721,7 @@ snapshots:
evtd: 0.2.4
vue: 3.5.5(typescript@5.5.4)
vite-plugin-checker@0.7.2(eslint@9.9.1(jiti@2.0.0-beta.3))(meow@13.2.0)(optionator@0.9.4)(stylelint@16.9.0(typescript@5.5.4))(typescript@5.5.4)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))(vue-tsc@2.0.29(typescript@5.5.4)):
vite-plugin-checker@0.7.2(eslint@9.9.1(jiti@1.21.6))(optionator@0.9.4)(stylelint@16.9.0(typescript@5.5.4))(typescript@5.5.4)(vite@5.4.3(@types/node@20.16.5)(sass@1.78.0))(vue-tsc@2.0.29(typescript@5.5.4)):
dependencies:
'@babel/code-frame': 7.24.7
ansi-escapes: 4.3.2
......@@ -5733,8 +5739,7 @@ snapshots:
vscode-languageserver-textdocument: 1.0.12
vscode-uri: 3.0.8
optionalDependencies:
eslint: 9.9.1(jiti@2.0.0-beta.3)
meow: 13.2.0
eslint: 9.9.1(jiti@1.21.6)
optionator: 0.9.4
stylelint: 16.9.0(typescript@5.5.4)
typescript: 5.5.4
......@@ -5782,10 +5787,10 @@ snapshots:
dependencies:
vue: 3.5.5(typescript@5.5.4)
vue-eslint-parser@9.4.3(eslint@9.9.1(jiti@2.0.0-beta.3)):
vue-eslint-parser@9.4.3(eslint@9.9.1(jiti@1.21.6)):
dependencies:
debug: 4.3.7
eslint: 9.9.1(jiti@2.0.0-beta.3)
eslint: 9.9.1(jiti@1.21.6)
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3
espree: 9.6.1
......
import { request } from '@/utils/request'
// 根据ID获取推荐模板信息
export function fetchGiftCodeRedemption<T>(redemptionCode: string) {
return request.post<T>(`/bizRedemptionRest/equityRedeem.json?redemptionCode=${redemptionCode}`)
}
......@@ -24,3 +24,7 @@ export function fetchUniversalCurrency<T>(token?: string) {
},
})
}
export function fetchUserInfo<T>() {
return request.post<T>('/bizMemberInfoRest/indexGetMemberInfo.json')
}
......@@ -4,9 +4,11 @@ import { ref } from 'vue'
import { themeOverrides } from '@/config/theme-config'
import { useResizeObserver } from '@vueuse/core'
import { useDesignSettingStore } from '@/store/modules/design-setting'
import { useUserStore } from './store/modules/user'
// import { NThemeEditor } from 'naive-ui'
const designSettingStore = useDesignSettingStore()
const userStore = useUserStore()
const currentLocale = ref(zhTW)
const currentDateLocale = ref(dateZhTW)
......@@ -33,6 +35,11 @@ useResizeObserver(rootContainer, (entries) => {
designSettingStore.toggleSidebarDisplayStatus('expand')
}
})
;(function () {
if (userStore.isLogin) {
useUserStore().fetchUpdateUserInfo()
}
})()
</script>
<template>
......
......@@ -34,7 +34,7 @@ const modules: Record<string, any> = import.meta.glob(['./modules/**/*.ts', '!./
export const sidebarMenus: any[] = menuFilterSort([...routes])
const router = createRouter({
export const router = createRouter({
history: getHistoryMode(import.meta.env.VITE_ROUTER_MODE),
routes: [...routes, ...baseRoutes],
strict: true,
......
import { type RouteRecordRaw } from 'vue-router'
// import Layout from '@/layout/index.vue'
import Index from '@/views/index/index.vue'
// export default [
// {
// path: '/',
// name: 'Root',
// meta: {
// rank: 1001,
// title: '',
// },
// component: Layout,
// redirect: '/home',
// children: [
// {
// path: '/home',
// name: 'Home',
// meta: {
// rank: 1001,
// title: '首页',
// icon: 'material-symbols:home-outline',
// },
// component: Home,
// },
// ],
// },
// ] as RouteRecordRaw[]
export default [
{
path: '/',
......@@ -39,20 +13,20 @@ export default [
children: [
{
path: '/',
redirect: 'home',
redirect: 'workbench',
},
{
path: 'home',
name: 'Home',
path: 'workbench',
name: 'Workbench',
meta: {
title: '首页',
title: '工作台',
rank: 1001,
},
component: () => import('@/views/home/home.vue'),
component: () => import('@/views/workbench/workbench.vue'),
},
{
path: '/work/videos',
name: 'work-videos',
name: 'WorkVideos',
meta: {
title: '我的作品',
rank: 1001,
......@@ -61,7 +35,7 @@ export default [
},
{
path: '/work/draft',
name: 'work-draft',
name: 'WorkDraft',
meta: {
title: '草稿箱',
rank: 1001,
......
import { defineStore } from 'pinia'
import { ss } from '@/utils/storage'
import { type UserState, type UserInfo, UserStoreStorageKeyEnum } from '../types/user'
import { fetchUserInfo } from '@/apis/user'
function createDefaultUserInfoFactory(): UserInfo {
return {
memberId: null,
account: '',
avatarUrl: '',
nickName: '',
mobilePhone: '',
equityNum: 0,
taskConfigNum: 0,
}
}
......@@ -43,5 +47,11 @@ export const useUserStore = defineStore('user-store', {
this.userInfo = userInfo
ss.set(UserStoreStorageKeyEnum.userInfo, userInfo)
},
fetchUpdateUserInfo() {
fetchUserInfo<UserInfo>().then((res) => {
this.updateUserInfo(res.data)
})
},
},
})
export interface UserInfo {
memberId: number | null
account: string
mobilePhone: string
nickName: string
avatarUrl: string
equityNum: number
taskConfigNum: number
}
export interface UserState {
......
import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios'
import { BASE_URLS } from '@/config/base-url'
import { useUserStore } from '@/store/modules/user'
import { useRouter } from 'vue-router'
import { router } from '@/router/index'
import { debounce } from 'lodash-es'
interface PagingInfoParams {
pageNo: number
......@@ -17,13 +18,21 @@ export interface Response<T> {
const ENV = import.meta.env.VITE_APP_ENV
function handleLogout() {
const router = useRouter()
const handleLogout = debounce(
() => {
const currentRoute = router.currentRoute.value
const currentRoute = router.currentRoute.value
router.replace({ name: 'Login', query: { redirect: encodeURIComponent(currentRoute.fullPath) } })
window.$message.warning('身份已过期,请重新登录')
}
if (currentRoute.name === 'Login') {
return
}
router.replace({ name: 'Login', query: { redirect: encodeURIComponent(currentRoute.fullPath) } })
useUserStore().logout()
window.$message.warning('身份已过期,请重新登录')
},
700,
{ leading: true, trailing: false },
)
const service = axios.create({
baseURL: `${BASE_URLS[ENV]}/api/rest`,
......@@ -59,7 +68,7 @@ service.interceptors.response.use(
// 处理响应错误
if (response && [500, 502].includes(response.status) && window.location.hash === '#/500')
useRouter().push({ name: 'ServerError' })
router.push({ name: 'ServerError' })
return Promise.reject(error)
},
......
......@@ -58,7 +58,7 @@ async function handleGetDigitalHumanDialogueConfig() {
}
})
.catch(() => {
router.replace({ name: 'Home' })
router.replace({ name: 'Workbench' })
})
}
......
<script setup lang="ts">
import { fetchGiftCodeRedemption } from '@/apis/gift-redemption'
import type { FormInst } from 'naive-ui'
import { ref, shallowReadonly, useTemplateRef } from 'vue'
const isShowGiftCodeRedemptionModal = defineModel<boolean>('isShowGiftCodeRedemptionModal', { default: false })
const exchangeInfoFormRef = useTemplateRef<FormInst>('exchangeInfoFormRef')
const exchangeInfoForm = ref({
redemptionCode: '',
})
const exchangeInfoFormRules = shallowReadonly({
redemptionCode: {
required: true,
message: '請填冩禮包碼',
trigger: 'blur',
},
})
const exchangeSubmitBtnLoading = ref(false)
function handleExchangeSubmit() {
exchangeInfoFormRef.value?.validate((errors) => {
if (errors) return ''
exchangeSubmitBtnLoading.value = true
fetchGiftCodeRedemption<{ awardType: string; awardNum: number }>(exchangeInfoForm.value.redemptionCode)
.then((res) => {
setTimeout(() => {
window.$dialog.success({
title: '禮包兌換成功',
content: `兌換內容:${res.data.awardNum}靈荳`,
contentStyle: { fontSize: '14px', marginTop: '20px' },
closable: false,
positiveText: '知道了',
positiveButtonProps: {
type: 'info',
size: 'medium',
},
})
}, 100)
})
.catch(() => {
setTimeout(() => {
window.$dialog.error({
title: '禮包兌換失敗',
content: '請重新兌換或聯繫客服',
contentStyle: { fontSize: '14px', marginTop: '20px' },
closable: false,
positiveText: '知道了',
positiveButtonProps: {
type: 'info',
size: 'medium',
},
})
}, 200)
})
.finally(() => {
exchangeSubmitBtnLoading.value = false
isShowGiftCodeRedemptionModal.value = false
})
})
}
function onModalAfterLeave() {
exchangeInfoFormRef.value?.restoreValidation()
exchangeInfoForm.value.redemptionCode = ''
}
</script>
<template>
<n-modal v-model:show="isShowGiftCodeRedemptionModal" :mask-closable="false" :on-after-leave="onModalAfterLeave">
<n-card
class="!w-[600px]"
title="禮包碼兌換"
:bordered="false"
size="medium"
closable
@close="() => (isShowGiftCodeRedemptionModal = false)"
>
<n-form
ref="exchangeInfoFormRef"
label-placement="left"
label-width="auto"
:model="exchangeInfoForm"
:rules="exchangeInfoFormRules"
>
<n-form-item label="禮包碼" path="redemptionCode">
<n-input v-model:value="exchangeInfoForm.redemptionCode" placeholder="請輸入禮包碼" />
</n-form-item>
</n-form>
<div class="mb-[20px] mt-[16px]">
<h2>兌換説明:</h2>
<div class="mt-[6px] pl-[8px] leading-7">
<div>1、每個禮包碼僅限使用一次;</div>
<div>2、禮包內容和適用條件以活動説明爲準;</div>
<div>3、兌換時,請準確無誤地輸入禮包碼,包括字母大小冩、數字位數;</div>
<div>4、禮包碼一旦兌換成功,獎勵將直接髮放至您的賬戶中,不可轉移給其他賬戶;</div>
<div>5、本活動最終解釋權歸萃想智能雲創所有,如有任何爭議,萃想保留決定權;</div>
<div>6、如遇無法正常兌換或其他問題,請尋求客服幫助。客服聯繫方式:蒐索微信公衆號:萃想AI工坊,後颱留言。</div>
</div>
</div>
<template #footer>
<div class="text-end">
<n-space justify="end">
<n-button @click="() => (isShowGiftCodeRedemptionModal = false)">取消</n-button>
<n-button type="info" :loading="exchangeSubmitBtnLoading" @click="handleExchangeSubmit">確定兌換</n-button>
</n-space>
</div>
</template>
</n-card>
</n-modal>
</template>
<script setup lang="ts">
import { NDropdown } from 'naive-ui'
import { h, ref } from 'vue'
import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import { computed, h, ref, shallowRef } from 'vue'
import { NAvatar } from 'naive-ui'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/store/modules/user'
import { Right, Logout } from '@icon-park/vue-next'
import { Icon } from '@icon-park/vue-next/lib/runtime'
import { onMounted } from 'vue'
import { fetchUniversalCurrency } from '@/apis/user'
import { Logout } from '@icon-park/vue-next'
import { Gift } from '@icon-park/vue-next'
import GiftCodeRedemption from '../components/gift-code-redemption.vue'
const router = useRouter()
const userStore = useUserStore()
const userInfo = userStore.userInfo
const UniversalCurrency = ref()
const options = [
{
key: 'nickName',
type: 'render',
render: renderCustomHeader,
},
{
label: '购买记录',
key: 'purchaseRecord',
icon: renderIcon(Right),
},
{
label: '使用记录',
key: 'usageRecord',
icon: renderIcon(Right),
},
{
type: 'divider',
key: 'd1',
},
const dropdownOptions = shallowRef([
{
label: '退出登录',
key: 'logout',
icon: renderIcon(Logout),
icon: () => h(Logout, { theme: 'outline', size: 12, strokeWidth: 3 }),
},
]
function getUniversalCurrency() {
fetchUniversalCurrency().then((res) => {
if (res.code !== 0) return ''
UniversalCurrency.value = res.data
})
}
])
function renderIcon(icon: Icon) {
return () => {
return h(icon, {
theme: 'outline',
size: 15,
fill: '#333639',
})
}
}
const userInfo = computed(() => userStore.userInfo)
function renderCustomHeader() {
return h('div', [
h('div', { class: 'flex w-[200px]' }, [
h(NAvatar, {
round: true,
class: 'w-[50px] h-[50px] mr-[6px] ml-[15px] mt-[10px]',
src:
userInfo.avatarUrl || 'https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-template/20230103/1672717001352.png',
}),
h('div', { class: 'text-[16px] mt-[20px] ml-[3px]' }, [userInfo.nickName]),
]),
h('div', { class: 'flex items-center justify-between mt-[10px] mb-[8px] ml-[15px]' }, [
h('div', ['灵豆余额']),
h('div', { class: 'flex' }, [
h('span', { class: 'mr-[5px] text-[14px]' }, [UniversalCurrency.value]),
h('img', {
class: 'mr-[9px] w-[16px] h-[16px] mt-[1px] ml-[5px]',
src: new URL('@/assets/images/icon-universalcurrency.png', import.meta.url).href,
}),
]),
]),
])
}
async function handleSelect(key: string | number) {
if (key === 'purchaseRecord') {
console.log('购买记录')
} else if (key === 'usageRecord') {
console.log('使用记录')
} else if (key === 'logout') {
await userStore.logout()
router.replace({ name: 'Login' })
window.$message.success('成功退出登錄')
return
const isShowGiftCodeRedemptionModal = ref(false)
function handleDropdownSelect(key: string | number) {
switch (key) {
case 'logout':
userStore.logout()
router.replace({ name: 'Login' })
window.$message.success('已退出登錄')
break
}
}
onMounted(() => {
getUniversalCurrency()
})
</script>
<template>
<header class="flex h-[56px] justify-between">
<div class="font-600 flex items-center pl-4 text-xl">萃想智能云创</div>
<div class="flex items-center pr-4">
<div class="mx-6">
<div class="mx-3">
<n-button
class="!rounded-[6px]"
color="#fff"
text-color="#151b26"
@click="() => (isShowGiftCodeRedemptionModal = true)"
>
<template #icon><Gift theme="outline" size="14" fill="#333" :stroke-width="3" /></template>
<span class="text-[14px]">禮包碼兌換</span>
</n-button>
</div>
<!-- <div class="mx-3">
<n-button class="!rounded-[6px]" color="#ffecd4" text-color="#151b26">
<template #icon><CustomIcon class="text-lg" icon="mingcute:pig-money-line" /></template>
<span class="text-[14px]">充值</span>
</n-button>
</div> -->
<div class="ml-3 flex items-center justify-center">
<NDropdown :options="dropdownOptions" trigger="hover" class="dropdown-style" @select="handleDropdownSelect">
<NAvatar
class="cursor-pointer"
round
size="small"
object-fit="cover"
:src="
userInfo.avatarUrl ||
'https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-template/20230103/1672717001352.png'
"
/>
</NDropdown>
</div>
<NDropdown :options="options" trigger="hover" class="dropdown-style" @select="handleSelect">
<NAvatar
class="cursor-pointer"
round
size="small"
object-fit="cover"
src="https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-template/20230103/1672717001352.png"
/>
</NDropdown>
</div>
</header>
<GiftCodeRedemption v-model:is-show-gift-code-redemption-modal="isShowGiftCodeRedemptionModal" />
</template>
......@@ -5,7 +5,7 @@ import MainContent from './main-content.vue'
</script>
<template>
<div class="h-screen bg-[#f3f4fb]">
<div class="h-screen min-w-[1280px] bg-[#f3f4fb]">
<div class="mx-auto h-full max-w-[1440px]">
<n-layout content-class="layout-wrapper-content" class="h-full !bg-transparent">
<n-layout-header class="mb-[16px] !bg-transparent">
......
<script setup lang="ts">
import { shallowReadonly } from 'vue'
import { h, ref, shallowReadonly, watchEffect } from 'vue'
import type { MenuOption } from 'naive-ui'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { Workbench, DocumentFolder, Inbox, CommentOne } from '@icon-park/vue-next'
const router = useRouter()
const route = useRoute()
function iconConfigFactory(): any {
return { theme: 'outline', size: 14, strokeWidth: 3 }
}
const menuOptions = shallowReadonly<MenuOption[]>([
{
type: 'group',
label: '视频',
key: 'videos',
key: 'Videos',
children: [
{
label: '工作颱',
key: 'home',
onClick: () => router.push({ name: 'Home' }),
key: 'Workbench',
icon: () => h(Workbench, { ...iconConfigFactory() }),
},
{
label: '我的作品',
key: 'opus',
onClick: () => router.push({ name: 'work-videos' }),
key: 'WorkVideos',
icon: () => h(DocumentFolder, { ...iconConfigFactory() }),
},
{
label: '草稿箱',
key: 'draft',
onClick: () => router.push({ name: 'work-draft' }),
key: 'WorkDraft',
icon: () => h(Inbox, { ...iconConfigFactory() }),
},
],
},
{
type: 'group',
label: '對話',
key: 'dialogue',
key: 'Dialogue',
children: [
{
label: '我的對話',
key: 'dialogueList',
onClick: () => router.push({ name: 'DialogueList' }),
key: 'DialogueList',
icon: () => h(CommentOne, { ...iconConfigFactory() }),
},
],
},
])
const currentMenuValue = ref('')
watchEffect(() => {
currentMenuValue.value = route.name as string
})
function onMenuValueChange(key: string) {
router.push({ name: key })
}
</script>
<template>
<section class="h-full pr-[24px]">
<div class="h-full rounded-[16px] bg-white p-[16px]">
<n-menu :options="menuOptions" />
<section class="h-full overflow-hidden pr-[24px]">
<div class="h-full overflow-auto rounded-[16px] bg-white py-[16px] pl-[16px]">
<n-scrollbar>
<div class="pr-[16px]">
<n-menu :value="currentMenuValue" :options="menuOptions" :indent="12" :on-update:value="onMenuValueChange" />
</div>
</n-scrollbar>
</div>
</section>
</template>
......@@ -227,10 +227,13 @@ function handleLoginSubmit(method: LoginMethod) {
memberId: res.data.memberId,
mobilePhone: res.data.mobilePhone,
nickName: res.data.nickName,
account: res.data.account,
equityNum: res.data.equityNum,
taskConfigNum: res.data.taskConfigNum,
})
const redirectUrl = decodeURIComponent((route.query.redirect as string) || '')
router.replace({ path: redirectUrl ? redirectUrl : '/home' })
router.replace({ path: redirectUrl ? redirectUrl : '/workbench' })
window.$message.success('登錄成功')
......
export function splitTextIntoParagraphs(text: string): string[] {
const minLength = 100
const maxLength = 150
const paragraphs: string[] = []
let start = 0
while (start < text.length) {
let end = start + maxLength
if (end >= text.length) {
paragraphs.push(text.slice(start))
break
}
while (end > start + minLength && text[end] !== ' ' && text[end] !== '.') {
end--
}
if (end === start + minLength) {
end = start + maxLength
}
paragraphs.push(text.slice(start, end).trim())
start = end
}
return paragraphs
}
export function splitArticle(article: string): string[] {
const sentences = article.match(/[^。!?\n]+[。!?]/g) || []
const result: string[] = []
let currentParagraph = ''
for (const sentence of sentences) {
if (currentParagraph.length + sentence.length > 150) {
if (currentParagraph.length >= 100) {
result.push(currentParagraph.trim())
currentParagraph = sentence
} else {
currentParagraph += sentence
}
} else {
currentParagraph += sentence
}
}
if (currentParagraph.length > 0) {
result.push(currentParagraph.trim())
}
return result
}
<script setup lang="ts">
import { fetchUniversalCurrency } from '@/apis/user'
import { useUserStore } from '@/store/modules/user'
import { Right } from '@icon-park/vue-next'
import { onMounted, ref } from 'vue'
import { computed, ref } from 'vue'
import CreateDigitalHumanDialogueModal, {
DigitalHumanDialogueForm,
} from '@/views/dialogue-detail/components/create-digital-human-dialogue-modal.vue'
......@@ -11,29 +9,14 @@ import { DigitalHumanDialogueConfig } from '@/store/types/digital-human-dialogue
import { fetchSaveDigitalHumanDialogueConfig } from '@/apis/digital-human-dialogue'
import { useRouter } from 'vue-router'
const UniversalCurrency = ref()
const userStore = useUserStore()
const userInfo = userStore.userInfo
const userInfo = computed(() => userStore.userInfo)
function handleGoToCreation() {
console.log('立即创作')
}
function getUniversalCurrency() {
fetchUniversalCurrency().then((res) => {
if (res.code !== 0) return ''
UniversalCurrency.value = res.data
})
}
function handleRechargeCurrency() {
console.log('充值')
}
onMounted(() => {
getUniversalCurrency()
})
const digitalHumanDialogueStore = useDigitalHumanDialogueStore()
const router = useRouter()
......@@ -99,43 +82,33 @@ async function handleCreateDigitalHumanDialogue(digitalHumanDialogueForm: Digita
<img src="@/assets/videoSlide.png" alt="數字人生成" />
</div>
</div>
<div class="border-1 ml-[20px] h-[173px] w-[325px] rounded-[20px] bg-[#ffffff] text-[14px]">
<div>
<div class="flex text-[16px]">
<div class="ml-[20px] mt-[16px] h-[56px] w-[56px] overflow-hidden rounded-full">
<n-avatar
round
:size="56"
:src="
userInfo.avatarUrl ||
'https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-template/20230103/1672717001352.png'
"
/>
</div>
<div class="ml-[14px] mt-[30px]">{{ userInfo.nickName }}</div>
<div class="flex items-center px-[26px] py-[20px]">
<n-avatar
round
object-fit="cover"
size="large"
:src="
userInfo.avatarUrl ||
'https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-template/20230103/1672717001352.png'
"
/>
<div class="ml-[10px] flex-1 truncate text-[18px]">{{ userInfo.account || '-' }}</div>
</div>
<div class="flex items-center">
<div class="flex flex-1 flex-col items-center text-[16px]">
<div class="font-600 mb-2 truncate text-[18px]">{{ userInfo.taskConfigNum || '-' }}</div>
<div>創作</div>
</div>
<div class="mt-[25px] flex">
<div class="mr-[50px]">
<div class="ml-[70px] text-center text-[16px] text-[#101010]">12</div>
<div class="ml-[72px] mt-[6px]">創作</div>
</div>
<div class="h-[45px] w-[1px] bg-[#BBBBBB]"></div>
<div class="flex">
<div class="ml-[56px]">
<div class="text-center text-[16px] text-[#101010]">{{ UniversalCurrency }}</div>
<div class="mt-[6px]">餘額</div>
</div>
<div
class="ml-[15px] h-[24px] cursor-pointer leading-[24px] text-[#036CFD]"
@click="handleRechargeCurrency"
>
充值
</div>
<div class="mt-[5px] cursor-pointer">
<Right theme="outline" size="15" fill="#036CFD" />
</div>
</div>
<div class="h-[34px] w-[2px] bg-[#bbb]"></div>
<div class="flex flex-1 flex-col items-center text-[16px]">
<div class="font-600 mb-2 truncate text-[18px]">{{ userInfo.equityNum || '-' }}</div>
<div>餘額</div>
</div>
</div>
</div>
......
<script setup lang="ts">
// import { fetchRecentCreationList } from '@/apis/drafts'
// import { useUserStore } from '@/store/modules/user'
import { Right } from '@icon-park/vue-next'
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
// const userStore = useUserStore()
// const token = userStore.token
onMounted(() => {
// getRecentCreationList()
})
function handleGoToDrafts() {
router.push('/work/draft')
}
// function getRecentCreationList() {
// fetchRecentCreationList(token).then((res) => {
// if (res.code !== 0) return ''
// console.log(res)
// })
// }
</script>
<template>
<div class="rounded-[16px] bg-white px-[24px] pt-[24px]">
<div class="mb-[16px] flex justify-between text-[18px] text-[#000]">
<div>最近創作</div>
<div class="flex h-[22px] cursor-pointer items-center text-[14px] text-[#5b647a]" @click="handleGoToDrafts">
<div>查看全部</div>
<Right theme="outline" size="16" fill="#5b647a" />
</div>
</div>
<div class="overflow-y-auto text-nowrap">
<n-scrollbar :x-scrollable="true">
<div v-for="item in 7" :key="item" class="mr-[10px] inline-block pb-[16px] text-center">
<div
class="relative mb-[12px] h-[145px] w-[145px] cursor-pointer overflow-hidden rounded-[12px] bg-[#f3f4fb]"
>
<img
class="z-1 relative h-full w-full object-contain transition-[scale] duration-300 ease-in-out hover:scale-110"
src="https://meta-human-editor-prd.cdn.bcebos.com/2024-04-17T16:53:29.223639/sd-qdmv5bsghiyx1xb9z_1713344008761.png?x-bce-process=image/format,f_auto/resize,w_500/quality,q_90"
alt="cover-image"
/>
<img
class="absolute left-0 top-0 h-full w-full object-cover blur-[32px]"
src="https://meta-human-editor-prd.cdn.bcebos.com/2024-04-17T16:53:29.223639/sd-qdmv5bsghiyx1xb9z_1713344008761.png?x-bce-process=image/format,f_auto/resize,w_500/quality,q_90"
alt="cover-image"
/>
<div
class="absolute bottom-[8px] left-[8px] z-10 rounded-[4px] bg-[rgba(0,0,0,.5)] px-[6px] py-[2px] text-[12px] text-[#fff]"
>
精品视频
</div>
</div>
<n-ellipsis class="!max-w-[150px] cursor-default text-[#151b26]">金融课程2024-09-11 09:48:41</n-ellipsis>
</div>
</n-scrollbar>
</div>
</div>
</template>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment