feat: 添加剪贴板功能,更新用户信息展示,优化用户设置界面

This commit is contained in:
2025-12-21 05:00:00 +07:00
parent 7dfc125f66
commit c76933a62a
8 changed files with 60 additions and 15 deletions

4
auto-imports.d.ts vendored
View File

@@ -164,7 +164,7 @@ declare global {
const useBrowserLocation: typeof import('@vueuse/core').useBrowserLocation const useBrowserLocation: typeof import('@vueuse/core').useBrowserLocation
const useCacheSize: typeof import('./src/composables/useCacheSize').useCacheSize const useCacheSize: typeof import('./src/composables/useCacheSize').useCacheSize
const useCached: typeof import('@vueuse/core').useCached const useCached: typeof import('@vueuse/core').useCached
const useClipboard: typeof import('@vueuse/core').useClipboard const useClipboard: typeof import('./src/composables/useColipboard').useClipboard
const useClipboardItems: typeof import('@vueuse/core').useClipboardItems const useClipboardItems: typeof import('@vueuse/core').useClipboardItems
const useCloned: typeof import('@vueuse/core').useCloned const useCloned: typeof import('@vueuse/core').useCloned
const useColorMode: typeof import('@vueuse/core').useColorMode const useColorMode: typeof import('@vueuse/core').useColorMode
@@ -524,7 +524,7 @@ declare module 'vue' {
readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']> readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']>
readonly useCacheSize: UnwrapRef<typeof import('./src/composables/useCacheSize')['useCacheSize']> readonly useCacheSize: UnwrapRef<typeof import('./src/composables/useCacheSize')['useCacheSize']>
readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']> readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']>
readonly useClipboard: UnwrapRef<typeof import('@vueuse/core')['useClipboard']> readonly useClipboard: UnwrapRef<typeof import('./src/composables/useColipboard')['useClipboard']>
readonly useClipboardItems: UnwrapRef<typeof import('@vueuse/core')['useClipboardItems']> readonly useClipboardItems: UnwrapRef<typeof import('@vueuse/core')['useClipboardItems']>
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']> readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']> readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>

View File

@@ -21,6 +21,7 @@
"@capacitor-mlkit/barcode-scanning": "^8.0.0", "@capacitor-mlkit/barcode-scanning": "^8.0.0",
"@capacitor/app": "8.0.0", "@capacitor/app": "8.0.0",
"@capacitor/camera": "^8.0.0", "@capacitor/camera": "^8.0.0",
"@capacitor/clipboard": "^8.0.0",
"@capacitor/core": "8.0.0", "@capacitor/core": "8.0.0",
"@capacitor/haptics": "8.0.0", "@capacitor/haptics": "8.0.0",
"@capacitor/ios": "^8.0.0", "@capacitor/ios": "^8.0.0",
@@ -29,7 +30,7 @@
"@elysiajs/eden": "^1.4.5", "@elysiajs/eden": "^1.4.5",
"@ionic/vue": "^8.7.11", "@ionic/vue": "^8.7.11",
"@ionic/vue-router": "^8.7.11", "@ionic/vue-router": "^8.7.11",
"@riwa/api-types": "http://192.168.1.27:9527/api/riwa-api-types-0.0.39.tgz", "@riwa/api-types": "http://192.168.1.27:9527/api/riwa-api-types-0.0.40.tgz",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "^4.1.18",
"@vee-validate/yup": "^4.15.1", "@vee-validate/yup": "^4.15.1",
"@vueuse/core": "^14.1.0", "@vueuse/core": "^14.1.0",

24
pnpm-lock.yaml generated
View File

@@ -20,6 +20,9 @@ importers:
'@capacitor/camera': '@capacitor/camera':
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.0) version: 8.0.0(@capacitor/core@8.0.0)
'@capacitor/clipboard':
specifier: ^8.0.0
version: 8.0.0(@capacitor/core@8.0.0)
'@capacitor/core': '@capacitor/core':
specifier: 8.0.0 specifier: 8.0.0
version: 8.0.0 version: 8.0.0
@@ -45,8 +48,8 @@ importers:
specifier: ^8.7.11 specifier: ^8.7.11
version: 8.7.11(@stencil/core@4.39.0)(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) version: 8.7.11(@stencil/core@4.39.0)(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@riwa/api-types': '@riwa/api-types':
specifier: http://192.168.1.27:9527/api/riwa-api-types-0.0.39.tgz specifier: http://192.168.1.27:9527/api/riwa-api-types-0.0.40.tgz
version: http://192.168.1.27:9527/api/riwa-api-types-0.0.39.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))) version: http://192.168.1.27:9527/api/riwa-api-types-0.0.40.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: ^4.1.18 specifier: ^4.1.18
version: 4.1.18(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2)) version: 4.1.18(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))
@@ -826,6 +829,11 @@ packages:
engines: {node: '>=22.0.0'} engines: {node: '>=22.0.0'}
hasBin: true hasBin: true
'@capacitor/clipboard@8.0.0':
resolution: {integrity: sha512-nRgx07ThaoxOaTObZo/G39se9wA3oVgP0ooNO539P1TOZzWObwuXWObZgvaRJNpJfHVYcNe45Ylb8nlYl7VleA==}
peerDependencies:
'@capacitor/core': '>=8.0.0'
'@capacitor/core@8.0.0': '@capacitor/core@8.0.0':
resolution: {integrity: sha512-250HTVd/W/KdMygoqaedisvNbHbpbQTN2Hy/8ZYGm1nAqE0Fx7sGss4l0nDg33STxEdDhtVRoL2fIaaiukKseA==} resolution: {integrity: sha512-250HTVd/W/KdMygoqaedisvNbHbpbQTN2Hy/8ZYGm1nAqE0Fx7sGss4l0nDg33STxEdDhtVRoL2fIaaiukKseA==}
@@ -1327,9 +1335,9 @@ packages:
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
'@riwa/api-types@http://192.168.1.27:9527/api/riwa-api-types-0.0.39.tgz': '@riwa/api-types@http://192.168.1.27:9527/api/riwa-api-types-0.0.40.tgz':
resolution: {tarball: http://192.168.1.27:9527/api/riwa-api-types-0.0.39.tgz} resolution: {tarball: http://192.168.1.27:9527/api/riwa-api-types-0.0.40.tgz}
version: 0.0.39 version: 0.0.40
peerDependencies: peerDependencies:
'@elysiajs/eden': ^1.4.5 '@elysiajs/eden': ^1.4.5
@@ -5826,6 +5834,10 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@capacitor/clipboard@8.0.0(@capacitor/core@8.0.0)':
dependencies:
'@capacitor/core': 8.0.0
'@capacitor/core@8.0.0': '@capacitor/core@8.0.0':
dependencies: dependencies:
tslib: 2.8.1 tslib: 2.8.1
@@ -6410,7 +6422,7 @@ snapshots:
'@pkgr/core@0.2.9': {} '@pkgr/core@0.2.9': {}
'@riwa/api-types@http://192.168.1.27:9527/api/riwa-api-types-0.0.39.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))': '@riwa/api-types@http://192.168.1.27:9527/api/riwa-api-types-0.0.40.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))':
dependencies: dependencies:
'@elysiajs/eden': 1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)) '@elysiajs/eden': 1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))

View File

@@ -0,0 +1,16 @@
import { Clipboard } from "@capacitor/clipboard";
export function useClipboard() {
function writeText(text: string): Promise<void> {
return Clipboard.write({ string: text });
}
function readText() {
return Clipboard.read().then(result => result);
}
return {
writeText,
readText,
};
}

View File

@@ -1,6 +1,5 @@
import type { UserData, UserProfileData } from "@/api/types"; import type { UserData, UserProfileData } from "@/api/types";
import { client, safeClient } from "@/api"; import { client, safeClient } from "@/api";
import { authClient } from "@/auth";
interface State { interface State {
user: UserData | null; user: UserData | null;

View File

@@ -17,6 +17,7 @@ async function handleSignInEmail(value: EmailVerifyClient) {
}); });
if (data?.token) { if (data?.token) {
userStore.setToken(data.token); userStore.setToken(data.token);
userStore.updateProfile();
useNavigateToRedirect(route.query.redirect as string); useNavigateToRedirect(route.query.redirect as string);
} }
} }
@@ -29,6 +30,7 @@ async function handleSignInPhoneNumber(value: PhoneNumberVerifyClient) {
}); });
if (data?.token) { if (data?.token) {
userStore.setToken(data.token); userStore.setToken(data.token);
userStore.updateProfile();
useNavigateToRedirect(route.query.redirect as string); useNavigateToRedirect(route.query.redirect as string);
} }
} }

View File

@@ -1,5 +1,5 @@
<script lang='ts' setup> <script lang='ts' setup>
import { alertController } from "@ionic/vue"; import { alertController, toastController } from "@ionic/vue";
import { arrowBackOutline } from "ionicons/icons"; import { arrowBackOutline } from "ionicons/icons";
import TdesignCopy from "~icons/tdesign/copy"; import TdesignCopy from "~icons/tdesign/copy";
import { authClient } from "@/auth"; import { authClient } from "@/auth";
@@ -31,6 +31,21 @@ async function handleSignOut() {
await alert.present(); await alert.present();
} }
const { writeText } = useClipboard();
function handleCopyUid() {
if (userProfile.value?.uid) {
writeText(userProfile.value.uid);
toastController
.create({
message: "UID copied to clipboard",
duration: 2000,
position: "bottom",
})
.then(toast => toast.present());
}
}
</script> </script>
<template> <template>
@@ -62,8 +77,8 @@ async function handleSignOut() {
UID UID
</div> </div>
</div> </div>
<div class="end"> <div class="end" @click="handleCopyUid">
<div>54213213</div> <div>{{ userProfile?.uid }}</div>
<TdesignCopy /> <TdesignCopy />
</div> </div>
</div> </div>

View File

@@ -2,7 +2,7 @@
import { chevronForwardOutline, copyOutline, qrCodeOutline } from "ionicons/icons"; import { chevronForwardOutline, copyOutline, qrCodeOutline } from "ionicons/icons";
const userStore = useUserStore(); const userStore = useUserStore();
const { user } = storeToRefs(userStore); const { user, userProfile } = storeToRefs(userStore);
</script> </script>
<template> <template>
@@ -14,7 +14,7 @@ const { user } = storeToRefs(userStore);
{{ user?.email }} {{ user?.email }}
</div> </div>
<div class="user-uid mt-1 text-xs text-text-100"> <div class="user-uid mt-1 text-xs text-text-100">
UID: 95223143 UID: {{ userProfile?.uid }}
</div> </div>
</div> </div>
</div> </div>