softleader-nuxt-core 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -15
- package/bin/init.mjs +155 -0
- package/components/uiInterface/IAlert.vue +1 -1
- package/composables/useApiRegistry.ts +30 -0
- package/core/repositories/index.ts +9 -0
- package/package.json +4 -2
- package/plugins/api.ts +24 -16
- package/.eslintrc.cjs +0 -25
- package/.prettierrc +0 -10
- package/repositories/index.ts +0 -20
- package/repositories/modules/auth.ts +0 -30
- package/repositories/modules/user.ts +0 -101
package/README.md
CHANGED
|
@@ -1,27 +1,68 @@
|
|
|
1
|
-
# Nuxt Core Layer
|
|
1
|
+
# Nuxt Core Layer (`softleader-nuxt-core`)
|
|
2
2
|
|
|
3
|
-
這是 Nuxt 3 Core Layer
|
|
3
|
+
這是 Nuxt 3 Core Layer,提供可重用的基礎架構、元件和工具,協助開發團隊快速建立一致且高品質的 Nuxt 3 應用。
|
|
4
4
|
|
|
5
5
|
## 包含內容
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- 基礎 Layout
|
|
7
|
+
- 設計系統元件
|
|
8
|
+
- 基礎 Layout 與路由設定
|
|
9
9
|
- 全域樣式與設計 Tokens
|
|
10
|
-
- 共用 Composables
|
|
11
|
-
-
|
|
10
|
+
- 共用 Composables 與 Utils
|
|
11
|
+
- 統一的開發工具配置(搭配 Nuxt 3 Eslint 等)
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## 使用情境一:在既有專案中使用 (Layer 繼承)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
如果你已經有一個 Nuxt 3 專案,你可以直接將此 Layer 擴展進你的專案中,藉此享有所有組件、功能和設定。
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
1. **安裝依賴**
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install softleader-nuxt-core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. **配置 `nuxt.config.ts`**
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
export default defineNuxtConfig({
|
|
27
|
+
extends: ["softleader-nuxt-core"],
|
|
28
|
+
// ... 其他你的專案設定
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
3. **啟用 ESLint / Prettier (選用)**
|
|
33
|
+
由於此專案依賴 `@nuxt/eslint-config`,建議你的專案也在根目錄設定對應的 Eslint 配置:
|
|
34
|
+
```bash
|
|
35
|
+
npm i -D @nuxt/eslint-config eslint
|
|
36
|
+
```
|
|
37
|
+
並在你的 `eslint.config.mjs` 中繼承 Nuxt 預設配置。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 使用情境二:快速建立全新專案 (Scaffolding CLI)
|
|
42
|
+
|
|
43
|
+
如果你想在一個新的(或空的)資料夾內建立完整包含 `softleader-nuxt-core` 的專案,我們提供了一個內建的命令列工具。
|
|
23
44
|
|
|
24
|
-
|
|
45
|
+
1. **透過 npx 執行初始化腳本**
|
|
46
|
+
你可以直接使用 `npx` 搭配套件名稱,並指定你的專案名稱(例如 `my-new-app`):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx softleader-nuxt-core init my-new-app
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2. **進入專案並啟動**
|
|
53
|
+
指令執行完成後,請進入生成的專案資料夾並啟動開發伺服器:
|
|
54
|
+
```bash
|
|
55
|
+
cd my-new-app
|
|
56
|
+
npm install # 若 CLI 尚未安裝完畢
|
|
57
|
+
npm run dev
|
|
58
|
+
```
|
|
59
|
+
這會自動生成 `package.json`、`app.vue`、`nuxt.config.ts` 等必要檔案,並且已經預先設定好 `extends: ['softleader-nuxt-core']`。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 開發 Core Layer 說明
|
|
64
|
+
|
|
65
|
+
若你是 `softleader-nuxt-core` 的開發者:
|
|
25
66
|
|
|
26
67
|
```bash
|
|
27
68
|
# 安裝依賴
|
|
@@ -33,3 +74,18 @@ npm run lint
|
|
|
33
74
|
# 型別檢查
|
|
34
75
|
npm run typecheck
|
|
35
76
|
```
|
|
77
|
+
|
|
78
|
+
### 發布至 npm
|
|
79
|
+
|
|
80
|
+
為了讓其他開發者能透過 `npx` 使用此腳本或載入此 Layer,您必須將本專案發布到 npm registry。
|
|
81
|
+
|
|
82
|
+
1. **更新版本號**:確保 `package.json` 中的 `version` 已更新。
|
|
83
|
+
2. **登入 npm** (若尚未登入):
|
|
84
|
+
```bash
|
|
85
|
+
npm login
|
|
86
|
+
```
|
|
87
|
+
3. **發布套件**:
|
|
88
|
+
```bash
|
|
89
|
+
npm publish
|
|
90
|
+
```
|
|
91
|
+
_(若是發布到公司私有 registry,請確認 `.npmrc` 中有設定正確的 registry url)_
|
package/bin/init.mjs
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
import { execSync } from 'node:child_process'
|
|
7
|
+
import { parseArgs } from 'node:util'
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
10
|
+
const __dirname = path.dirname(__filename)
|
|
11
|
+
|
|
12
|
+
const options = {
|
|
13
|
+
help: {
|
|
14
|
+
type: 'boolean',
|
|
15
|
+
short: 'h'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { values, positionals } = parseArgs({ options, allowPositionals: true })
|
|
20
|
+
|
|
21
|
+
if (values.help) {
|
|
22
|
+
console.log(`
|
|
23
|
+
用法 (Usage): npx softleader-nuxt-core init [project-name]
|
|
24
|
+
|
|
25
|
+
參數 (Arguments):
|
|
26
|
+
[project-name] 要建立的專案資料夾名稱 (預設: my-nuxt-app)
|
|
27
|
+
|
|
28
|
+
選項 (Options):
|
|
29
|
+
-h, --help 顯示此幫助訊息
|
|
30
|
+
`)
|
|
31
|
+
process.exit(0)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 取得專案名稱,預設為 my-nuxt-app
|
|
35
|
+
const projectName = positionals[0] || 'my-nuxt-app'
|
|
36
|
+
// 解析出目標資料夾的絕對路徑
|
|
37
|
+
const targetDir = path.resolve(process.cwd(), projectName)
|
|
38
|
+
// 產生合法的 npm package name (轉小寫並移除非英數字元)
|
|
39
|
+
const packageName = path.basename(targetDir).toLowerCase().replace(/[^a-z0-9-]/g, '') || 'my-nuxt-app'
|
|
40
|
+
|
|
41
|
+
// 檢查資料夾是否已存在
|
|
42
|
+
if (fs.existsSync(targetDir)) {
|
|
43
|
+
console.error(`錯誤 (Error): 目錄 "${projectName}" 已經存在。`)
|
|
44
|
+
process.exit(1)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log(`開始在 ${targetDir} 建立 Nuxt 3 專案...`)
|
|
48
|
+
|
|
49
|
+
// 1. 建立目標資料夾
|
|
50
|
+
fs.mkdirSync(targetDir, { recursive: true })
|
|
51
|
+
|
|
52
|
+
// 2. 建立 package.json
|
|
53
|
+
const packageJson = {
|
|
54
|
+
name: packageName,
|
|
55
|
+
version: "1.0.0",
|
|
56
|
+
private: true,
|
|
57
|
+
type: "module",
|
|
58
|
+
scripts: {
|
|
59
|
+
"build": "nuxt build",
|
|
60
|
+
"dev": "nuxt dev",
|
|
61
|
+
"generate": "nuxt generate",
|
|
62
|
+
"preview": "nuxt preview",
|
|
63
|
+
"postinstall": "nuxt prepare"
|
|
64
|
+
},
|
|
65
|
+
dependencies: {
|
|
66
|
+
"softleader-nuxt-core": "latest"
|
|
67
|
+
},
|
|
68
|
+
devDependencies: {
|
|
69
|
+
"nuxt": "^3.15.4",
|
|
70
|
+
"vue": "latest",
|
|
71
|
+
"vue-router": "latest"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fs.writeFileSync(
|
|
76
|
+
path.join(targetDir, 'package.json'),
|
|
77
|
+
JSON.stringify(packageJson, null, 2)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
// 3. 建立 nuxt.config.ts (預設繼承 softleader-nuxt-core Layer)
|
|
81
|
+
const nuxtConfigTs = `// https://nuxt.com/docs/api/configuration/nuxt-config
|
|
82
|
+
export default defineNuxtConfig({
|
|
83
|
+
extends: ['softleader-nuxt-core'],
|
|
84
|
+
compatibilityDate: '2024-04-03',
|
|
85
|
+
devtools: { enabled: true }
|
|
86
|
+
})
|
|
87
|
+
`
|
|
88
|
+
fs.writeFileSync(path.join(targetDir, 'nuxt.config.ts'), nuxtConfigTs)
|
|
89
|
+
|
|
90
|
+
// 4. 建立基礎的 app.vue
|
|
91
|
+
const appVue = `<template>
|
|
92
|
+
<NuxtLayout>
|
|
93
|
+
<NuxtPage />
|
|
94
|
+
</NuxtLayout>
|
|
95
|
+
</template>
|
|
96
|
+
`
|
|
97
|
+
fs.writeFileSync(path.join(targetDir, 'app.vue'), appVue)
|
|
98
|
+
|
|
99
|
+
// 5. 建立範例頁面 pages/index.vue
|
|
100
|
+
const pagesDir = path.join(targetDir, 'pages')
|
|
101
|
+
fs.mkdirSync(pagesDir)
|
|
102
|
+
const indexVue = `<template>
|
|
103
|
+
<IStack vertical justify="center" align="center" class="min-h-screen bg-gray-50 p-6">
|
|
104
|
+
<ICard class="w-full max-w-2xl px-8 py-10 text-center shadow-lg rounded-2xl">
|
|
105
|
+
<IIcon name="heroicons:rocket-launch" class="text-6xl text-primary-500 mb-6 mx-auto" />
|
|
106
|
+
<h1 class="text-3xl font-bold text-gray-800 mb-4">歡迎使用 Softleader Nuxt Core!</h1>
|
|
107
|
+
<p class="text-gray-600 mb-8 leading-relaxed">
|
|
108
|
+
您的專案已經成功建立。現在你可以直接使用 Layer 內建的設計系統元件,加速你的開發流程。
|
|
109
|
+
</p>
|
|
110
|
+
|
|
111
|
+
<IAlert type="success" show-icon class="mb-8 text-left">
|
|
112
|
+
<strong>準備就緒!</strong> 嘗試編輯 <code>pages/index.vue</code> 來查看熱更新效果。
|
|
113
|
+
</IAlert>
|
|
114
|
+
|
|
115
|
+
<IStack gap="4" justify="center">
|
|
116
|
+
<IButton type="primary" size="large" href="https://nuxt.com/docs" target="_blank">
|
|
117
|
+
<IIcon name="heroicons:book-open" class="mr-2" />
|
|
118
|
+
Nuxt 官方文件
|
|
119
|
+
</IButton>
|
|
120
|
+
<IButton variant="outlined" size="large" href="https://github.com" target="_blank">
|
|
121
|
+
<IIcon name="bx:bxl-github" class="mr-2" />
|
|
122
|
+
元件庫指南
|
|
123
|
+
</IButton>
|
|
124
|
+
</IStack>
|
|
125
|
+
</ICard>
|
|
126
|
+
</IStack>
|
|
127
|
+
</template>
|
|
128
|
+
`
|
|
129
|
+
fs.writeFileSync(path.join(pagesDir, 'index.vue'), indexVue)
|
|
130
|
+
|
|
131
|
+
// 6. 建立 tsconfig.json 以支援 TypeScript 型別檢查
|
|
132
|
+
const tsconfig = `{
|
|
133
|
+
"extends": "./.nuxt/tsconfig.json"
|
|
134
|
+
}
|
|
135
|
+
`
|
|
136
|
+
fs.writeFileSync(path.join(targetDir, 'tsconfig.json'), tsconfig)
|
|
137
|
+
|
|
138
|
+
// 7. 初始化 Git 儲存庫並安裝 npm 依賴
|
|
139
|
+
try {
|
|
140
|
+
console.log('正在安裝依賴,這可能需要一點時間 (Installing dependencies)...')
|
|
141
|
+
execSync('npm install', { cwd: targetDir, stdio: 'inherit' })
|
|
142
|
+
|
|
143
|
+
console.log('正在初始化 Git 儲存庫 (Initializing git repository)...')
|
|
144
|
+
execSync('git init', { cwd: targetDir, stdio: 'ignore' })
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.log('警告 (Warning): 自動安裝指令執行失敗。您可能需要手動進入資料夾執行 npm install。')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
console.log(`
|
|
150
|
+
專案 "${projectName}" 已準備就緒!
|
|
151
|
+
|
|
152
|
+
下一步 (Next steps):
|
|
153
|
+
cd ${projectName}
|
|
154
|
+
npm run dev
|
|
155
|
+
`)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* API Registry (擴充運作模式)
|
|
5
|
+
*
|
|
6
|
+
* 讓外部專案可以動態註冊自己的 Repository 到 $api 中
|
|
7
|
+
*/
|
|
8
|
+
class ApiRegistry {
|
|
9
|
+
private repositories: Record<string, any> = {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 註冊 Repository
|
|
13
|
+
* @param name 模組名稱 (例如 'order')
|
|
14
|
+
* @param repository 實作物件
|
|
15
|
+
*/
|
|
16
|
+
register(name: string, repository: any) {
|
|
17
|
+
this.repositories[name] = repository
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 取得所有已註冊的 Repositories
|
|
22
|
+
*/
|
|
23
|
+
getExports() {
|
|
24
|
+
return this.repositories
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const registry = new ApiRegistry()
|
|
29
|
+
|
|
30
|
+
export const useApiRegistry = () => registry
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "softleader-nuxt-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Nuxt 3 Core Layer - 可重用的基礎架構",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"layouts",
|
|
14
14
|
"modules",
|
|
15
15
|
"plugins",
|
|
16
|
-
"repositories",
|
|
17
16
|
"router",
|
|
18
17
|
"scripts",
|
|
19
18
|
"styles",
|
|
@@ -30,6 +29,9 @@
|
|
|
30
29
|
".": "./nuxt.config.ts",
|
|
31
30
|
"./utils/scanner": "./router/routes-scanner.ts"
|
|
32
31
|
},
|
|
32
|
+
"bin": {
|
|
33
|
+
"softleader-nuxt-core": "./bin/init.mjs"
|
|
34
|
+
},
|
|
33
35
|
"scripts": {
|
|
34
36
|
"lint": "eslint .",
|
|
35
37
|
"lint:fix": "eslint . --fix",
|
package/plugins/api.ts
CHANGED
|
@@ -1,27 +1,35 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useApiRegistry } from '../composables/useApiRegistry'
|
|
2
|
+
import repositories from '../core/repositories'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* API Plugin (整合層)
|
|
5
|
+
* API Plugin (整合層 - Registry 模式)
|
|
5
6
|
*
|
|
6
7
|
* 職責:
|
|
7
|
-
* 1.
|
|
8
|
-
* 2.
|
|
9
|
-
*
|
|
10
|
-
* 使用範例:
|
|
11
|
-
* ```ts
|
|
12
|
-
* const { $api } = useNuxtApp()
|
|
13
|
-
*
|
|
14
|
-
* // 呼叫 User 模組
|
|
15
|
-
* const { data: users } = await $api.user.getUsers()
|
|
16
|
-
*
|
|
17
|
-
* // 呼叫 Order 模組
|
|
18
|
-
* const { data: order } = await $api.order.getOrderById(1)
|
|
19
|
-
* ```
|
|
8
|
+
* 1. 初始化 API Registry
|
|
9
|
+
* 2. 預註冊 Core 層提供的基礎 Repositories
|
|
10
|
+
* 3. 提供全域唯一的存取點 $api
|
|
20
11
|
*/
|
|
21
12
|
export default defineNuxtPlugin(() => {
|
|
13
|
+
const registry = useApiRegistry()
|
|
14
|
+
|
|
15
|
+
// 1. 預註冊 Core 層的 Repositories
|
|
16
|
+
if (repositories) {
|
|
17
|
+
Object.entries(repositories).forEach(([name, repo]) => {
|
|
18
|
+
registry.register(name, repo)
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 2. 建立一個 Proxy 物件,讓 $api 可以動態存取註冊進來的內容
|
|
23
|
+
// 這解決了「App 層註冊的內容,在 Core 層也能透過 $api 存取」的問題
|
|
24
|
+
const apiProxy = new Proxy({}, {
|
|
25
|
+
get(target, prop: string) {
|
|
26
|
+
return registry.getExports()[prop]
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
22
30
|
return {
|
|
23
31
|
provide: {
|
|
24
|
-
api:
|
|
32
|
+
api: apiProxy
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
35
|
})
|
package/.eslintrc.cjs
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
root: true,
|
|
3
|
-
env: {
|
|
4
|
-
browser: true,
|
|
5
|
-
node: true,
|
|
6
|
-
es2022: true
|
|
7
|
-
},
|
|
8
|
-
extends: [
|
|
9
|
-
'@nuxt/eslint-config',
|
|
10
|
-
'plugin:@typescript-eslint/recommended'
|
|
11
|
-
],
|
|
12
|
-
parser: '@typescript-eslint/parser',
|
|
13
|
-
parserOptions: {
|
|
14
|
-
ecmaVersion: 2022,
|
|
15
|
-
sourceType: 'module'
|
|
16
|
-
},
|
|
17
|
-
plugins: ['@typescript-eslint'],
|
|
18
|
-
rules: {
|
|
19
|
-
// 自訂規則
|
|
20
|
-
'vue/multi-word-component-names': 'off',
|
|
21
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
22
|
-
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
23
|
-
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
|
24
|
-
}
|
|
25
|
-
}
|
package/.prettierrc
DELETED
package/repositories/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import user from './modules/user'
|
|
2
|
-
import auth from './modules/auth'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Repository Index (資料層)
|
|
7
|
-
*
|
|
8
|
-
* 職責:
|
|
9
|
-
* 1. 自動掃描 modules 資料夾下的所有檔案
|
|
10
|
-
* 2. 將它們打包成一個大物件匯出
|
|
11
|
-
* 3. 不依賴 Nuxt,純粹的資料定義
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const repositories = {
|
|
15
|
-
user,
|
|
16
|
-
auth,
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default repositories
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import type { UseFetchOptions } from 'nuxt/app'
|
|
3
|
-
|
|
4
|
-
// 定義 Client,指向 /auth (假設後端路由是 /api/auth)
|
|
5
|
-
const api = useClient('/auth')
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
/**
|
|
9
|
-
* 使用者登入
|
|
10
|
-
* @param credentials { username, password }
|
|
11
|
-
* @param options
|
|
12
|
-
*/
|
|
13
|
-
login(credentials: any, options: UseFetchOptions<any> = {}) {
|
|
14
|
-
return api.post('/login', credentials, options)
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 使用者登出 (如果有的話)
|
|
19
|
-
*/
|
|
20
|
-
logout() {
|
|
21
|
-
return api.post('/logout')
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 取得當前使用者資訊 (Session/Me)
|
|
26
|
-
*/
|
|
27
|
-
getProfile() {
|
|
28
|
-
return api.get('/me')
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import type { UseFetchOptions } from 'nuxt/app'
|
|
3
|
-
import type { UserListResponse } from '../../types/api'
|
|
4
|
-
|
|
5
|
-
type MaybeRef<T> = T | Ref<T>
|
|
6
|
-
|
|
7
|
-
interface UserQueryParams {
|
|
8
|
-
page?: MaybeRef<number>
|
|
9
|
-
itemsPerPage?: MaybeRef<number>
|
|
10
|
-
q?: MaybeRef<string>
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// 1. 定義 Client
|
|
14
|
-
const api = useClient('/users')
|
|
15
|
-
|
|
16
|
-
export default {
|
|
17
|
-
/**
|
|
18
|
-
* 取得使用者列表
|
|
19
|
-
* @param params - 查詢參數 (如分頁、搜尋關鍵字)
|
|
20
|
-
* @param options - 其他 Fetch 選項
|
|
21
|
-
* @returns List of users
|
|
22
|
-
*/
|
|
23
|
-
getUsers(params: UserQueryParams = {}, options: UseFetchOptions<UserListResponse> = {}) {
|
|
24
|
-
return api.get<UserListResponse>('/', {
|
|
25
|
-
query: params,
|
|
26
|
-
...options
|
|
27
|
-
})
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 根據 ID 取得單一使用者
|
|
32
|
-
* @param id - 使用者 ID
|
|
33
|
-
* @returns User detail
|
|
34
|
-
*/
|
|
35
|
-
getUserById(id: MaybeRef<number>) {
|
|
36
|
-
return api.get<any>(`/${unref(id)}`)
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* [範例] 建立使用者
|
|
41
|
-
* @param userData - 使用者資料物件
|
|
42
|
-
* @returns Created user data
|
|
43
|
-
*/
|
|
44
|
-
createUser(userData: any) {
|
|
45
|
-
return api.post('/', userData)
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* [範例] 搜尋使用者
|
|
50
|
-
* @param keyword - 搜尋關鍵字
|
|
51
|
-
* @returns Search results
|
|
52
|
-
*/
|
|
53
|
-
searchUsers(keyword: Ref<string>) {
|
|
54
|
-
return api.get('/search', {
|
|
55
|
-
query: { q: keyword },
|
|
56
|
-
watch: [keyword]
|
|
57
|
-
})
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* [範例] 更新使用者
|
|
62
|
-
* @param id - 使用者 ID
|
|
63
|
-
* @param userData - 更新的使用者資料
|
|
64
|
-
* @returns Updated user data
|
|
65
|
-
*/
|
|
66
|
-
updateUser(id: number, userData: any) {
|
|
67
|
-
return api.put(`/${id}`, userData)
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* [範例] 刪除使用者
|
|
72
|
-
* @param id - 使用者 ID
|
|
73
|
-
* @returns Deletion result
|
|
74
|
-
*/
|
|
75
|
-
deleteUser(id: number) {
|
|
76
|
-
return api.delete(`/${id}`)
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* [範例] 取得大量資料 (延遲載入)
|
|
81
|
-
* @returns Heavy data report
|
|
82
|
-
*/
|
|
83
|
-
getHeavyData() {
|
|
84
|
-
// 注意:這裡是 /heavy-report,因為 api base 是 /users
|
|
85
|
-
// 假設 heavy-report 也是在 /users 下,否則需另外處理
|
|
86
|
-
// 原始碼是 useApi('/heavy-report'),這可能不在 /users 下
|
|
87
|
-
// 為了安全,這裡假設它是獨立的
|
|
88
|
-
// 如果是獨立的,應該用 useApi 或另外一個 useClient
|
|
89
|
-
// 這裡我判斷它可能是 /users/heavy-report 的筆誤,或者真的是 root level
|
|
90
|
-
// 為了保持功能,我這裡用 root client 處理 (假設它不是 users/*)
|
|
91
|
-
// 但原檔放在 user.ts 卻叫 /heavy-report 有點怪
|
|
92
|
-
// 我先維持原路徑:/heavy-report (不接在 /users 後面)
|
|
93
|
-
|
|
94
|
-
// 這裡特別展示:如何在 policy 模式下呼叫「外面」的 API
|
|
95
|
-
// 方法 1: 使用 useApi
|
|
96
|
-
// return useApi('/heavy-report', { lazy: true })
|
|
97
|
-
|
|
98
|
-
// 方法 2 (如果它其實是 user 報表):
|
|
99
|
-
return useApi('/heavy-report', { lazy: true })
|
|
100
|
-
}
|
|
101
|
-
}
|