@lark-apaas/coding-template-nestjs-react-fullstack 0.1.36-alpha.20260903095202 → 0.1.36-alpha.20260903185731
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/package.json +1 -1
- package/template/client/src/components/ui/markdown.tsx +43 -0
- package/template/client/src/index.css +0 -1
- package/template/package-lock.json +5783 -13022
- package/template/package.json +5 -68
- package/template/client/src/components/business-ui/README.md +0 -519
- package/template/client/src/components/business-ui/api/chats/queries.ts +0 -39
- package/template/client/src/components/business-ui/api/chats/service.ts +0 -29
- package/template/client/src/components/business-ui/api/departments/queries.ts +0 -42
- package/template/client/src/components/business-ui/api/departments/service.ts +0 -18
- package/template/client/src/components/business-ui/api/files/service.ts +0 -28
- package/template/client/src/components/business-ui/api/user-profiles/queries.ts +0 -42
- package/template/client/src/components/business-ui/api/user-profiles/service.ts +0 -23
- package/template/client/src/components/business-ui/api/users/queries.ts +0 -34
- package/template/client/src/components/business-ui/api/users/service.ts +0 -40
- package/template/client/src/components/business-ui/chat-select/README.md +0 -128
- package/template/client/src/components/business-ui/chat-select/chat-item.tsx +0 -85
- package/template/client/src/components/business-ui/chat-select/chat-select-tag.tsx +0 -83
- package/template/client/src/components/business-ui/chat-select/chat-select.tsx +0 -197
- package/template/client/src/components/business-ui/chat-select/index.tsx +0 -12
- package/template/client/src/components/business-ui/chat-select/types.ts +0 -102
- package/template/client/src/components/business-ui/chat-select/use-chat-value.ts +0 -180
- package/template/client/src/components/business-ui/chat-select/utils.ts +0 -81
- package/template/client/src/components/business-ui/department-select/department-item.tsx +0 -55
- package/template/client/src/components/business-ui/department-select/department-select-field.tsx +0 -86
- package/template/client/src/components/business-ui/department-select/department-select-tag.tsx +0 -56
- package/template/client/src/components/business-ui/department-select/department-select.tsx +0 -168
- package/template/client/src/components/business-ui/department-select/icon-department.tsx +0 -22
- package/template/client/src/components/business-ui/department-select/index.tsx +0 -7
- package/template/client/src/components/business-ui/department-select/types.ts +0 -15
- package/template/client/src/components/business-ui/department-select/utils.ts +0 -17
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-content.tsx +0 -35
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-empty.tsx +0 -28
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-error.tsx +0 -35
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-item.tsx +0 -55
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-list.tsx +0 -174
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-loading.tsx +0 -19
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-search.tsx +0 -31
- package/template/client/src/components/business-ui/entity-combobox/base-combobox-trigger.tsx +0 -281
- package/template/client/src/components/business-ui/entity-combobox/base-combobox.tsx +0 -132
- package/template/client/src/components/business-ui/entity-combobox/context.tsx +0 -19
- package/template/client/src/components/business-ui/entity-combobox/entity-combobox.tsx +0 -145
- package/template/client/src/components/business-ui/entity-combobox/highlight-text.tsx +0 -52
- package/template/client/src/components/business-ui/entity-combobox/hooks.tsx +0 -21
- package/template/client/src/components/business-ui/entity-combobox/index.tsx +0 -31
- package/template/client/src/components/business-ui/entity-combobox/item-pill.tsx +0 -179
- package/template/client/src/components/business-ui/entity-combobox/popover-wrapper.tsx +0 -149
- package/template/client/src/components/business-ui/entity-combobox/search-trigger.tsx +0 -262
- package/template/client/src/components/business-ui/entity-combobox/shared-types.ts +0 -296
- package/template/client/src/components/business-ui/entity-combobox/size-variants.tsx +0 -322
- package/template/client/src/components/business-ui/entity-combobox/types.ts +0 -246
- package/template/client/src/components/business-ui/entity-combobox/use-fetch-data.tsx +0 -81
- package/template/client/src/components/business-ui/entity-combobox/use-infinite-scroll.tsx +0 -99
- package/template/client/src/components/business-ui/entity-combobox/use-popover-outside-click.tsx +0 -32
- package/template/client/src/components/business-ui/form/checkbox-field.tsx +0 -83
- package/template/client/src/components/business-ui/form/context.tsx +0 -38
- package/template/client/src/components/business-ui/form/field-layout.tsx +0 -91
- package/template/client/src/components/business-ui/form/form.tsx +0 -54
- package/template/client/src/components/business-ui/form/hooks/form-context.tsx +0 -4
- package/template/client/src/components/business-ui/form/hooks/form-utils.ts +0 -23
- package/template/client/src/components/business-ui/form/hooks/form.tsx +0 -40
- package/template/client/src/components/business-ui/form/index.tsx +0 -4
- package/template/client/src/components/business-ui/form/input-field.tsx +0 -74
- package/template/client/src/components/business-ui/form/radio-group-field.tsx +0 -138
- package/template/client/src/components/business-ui/form/select-field.tsx +0 -155
- package/template/client/src/components/business-ui/form/switch-field.tsx +0 -66
- package/template/client/src/components/business-ui/form/textarea-field.tsx +0 -72
- package/template/client/src/components/business-ui/form/types.ts +0 -32
- package/template/client/src/components/business-ui/tiptap-editor/README.md +0 -324
- package/template/client/src/components/business-ui/tiptap-editor/components/attachment-toolbar-button.tsx +0 -74
- package/template/client/src/components/business-ui/tiptap-editor/components/blockquote-toolbar-button.tsx +0 -41
- package/template/client/src/components/business-ui/tiptap-editor/components/code-block-toolbar-button.tsx +0 -41
- package/template/client/src/components/business-ui/tiptap-editor/components/color-highlight-toolbar-button.tsx +0 -141
- package/template/client/src/components/business-ui/tiptap-editor/components/heading-toolbar-button.tsx +0 -99
- package/template/client/src/components/business-ui/tiptap-editor/components/horizontal-rule-toolbar-button.tsx +0 -39
- package/template/client/src/components/business-ui/tiptap-editor/components/image-upload-toolbar-button.tsx +0 -65
- package/template/client/src/components/business-ui/tiptap-editor/components/link-edit-form.tsx +0 -127
- package/template/client/src/components/business-ui/tiptap-editor/components/link-hover-toolbar.tsx +0 -380
- package/template/client/src/components/business-ui/tiptap-editor/components/link-toolbar-button.tsx +0 -96
- package/template/client/src/components/business-ui/tiptap-editor/components/list-toolbar-button.tsx +0 -75
- package/template/client/src/components/business-ui/tiptap-editor/components/mark-toolbar-button.tsx +0 -118
- package/template/client/src/components/business-ui/tiptap-editor/components/text-align-toolbar-button.tsx +0 -84
- package/template/client/src/components/business-ui/tiptap-editor/components/undo-redo-toolbar-button.tsx +0 -54
- package/template/client/src/components/business-ui/tiptap-editor/extensions/attachment.tsx +0 -539
- package/template/client/src/components/business-ui/tiptap-editor/extensions/code-block-shiki.tsx +0 -236
- package/template/client/src/components/business-ui/tiptap-editor/extensions/complete-kit.ts +0 -260
- package/template/client/src/components/business-ui/tiptap-editor/extensions/image.tsx +0 -456
- package/template/client/src/components/business-ui/tiptap-editor/hooks/use-tiptap-editor.ts +0 -47
- package/template/client/src/components/business-ui/tiptap-editor/index.ts +0 -38
- package/template/client/src/components/business-ui/tiptap-editor/tiptap-editor-complete.tsx +0 -112
- package/template/client/src/components/business-ui/tiptap-editor/tiptap-editor.tsx +0 -169
- package/template/client/src/components/business-ui/types/user.ts +0 -74
- package/template/client/src/components/business-ui/user-display/index.tsx +0 -2
- package/template/client/src/components/business-ui/user-display/overflow-tooltip-text.tsx +0 -90
- package/template/client/src/components/business-ui/user-display/type.ts +0 -27
- package/template/client/src/components/business-ui/user-display/user-display.tsx +0 -99
- package/template/client/src/components/business-ui/user-display/user-with-avatar.tsx +0 -158
- package/template/client/src/components/business-ui/user-display/utils.ts +0 -37
- package/template/client/src/components/business-ui/user-profile/error-image.tsx +0 -302
- package/template/client/src/components/business-ui/user-profile/user-external-script.ts +0 -73
- package/template/client/src/components/business-ui/user-profile/user-profile.tsx +0 -370
- package/template/client/src/components/business-ui/user-select/index.tsx +0 -28
- package/template/client/src/components/business-ui/user-select/types.ts +0 -109
- package/template/client/src/components/business-ui/user-select/use-user-value.ts +0 -160
- package/template/client/src/components/business-ui/user-select/user-item.tsx +0 -98
- package/template/client/src/components/business-ui/user-select/user-pill.tsx +0 -140
- package/template/client/src/components/business-ui/user-select/user-select-tag.tsx +0 -82
- package/template/client/src/components/business-ui/user-select/user-select.tsx +0 -359
- package/template/client/src/components/business-ui/user-select/utils.tsx +0 -188
- package/template/client/src/components/business-ui/utils/user.ts +0 -72
- package/template/client/src/components/ui/streamdown.tsx +0 -186
- package/template/client/src/lib/shiki.ts +0 -92
package/template/package.json
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"flags": {
|
|
6
6
|
"supportBusinessUser": true,
|
|
7
|
+
"businessUiFromMarket": true,
|
|
7
8
|
"supportScrollReveal": true,
|
|
8
|
-
"supportTiptapAndStreamdown": true,
|
|
9
9
|
"customToaster": true
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
@@ -19,16 +19,12 @@
|
|
|
19
19
|
"build:server": "NODE_ENV=production nest build",
|
|
20
20
|
"build:client": "NODE_ENV=production vite build --config vite.config.ts",
|
|
21
21
|
"start": "NODE_ENV=production node main.js",
|
|
22
|
-
"test": "jest",
|
|
23
|
-
"test:watch": "jest --watch",
|
|
24
|
-
"test:e2e": "jest --config test/e2e/jest.config.js",
|
|
25
22
|
"eslint": "eslint . --quiet",
|
|
26
23
|
"stylelint": "stylelint client/src/**/*.css --quiet",
|
|
27
24
|
"type:check": "concurrently -n \"server,client\" -c \"blue,green\" \"npm run type:check:server\" \"npm run type:check:client\"",
|
|
28
25
|
"type:check:client": "tsc --noEmit --project tsconfig.app.json",
|
|
29
26
|
"type:check:server": "tsc --noEmit --project tsconfig.node.json",
|
|
30
27
|
"lint": "node ./scripts/lint.js",
|
|
31
|
-
"format": "prettier --write \"{server,client,test}/**/*.{js,ts,tsx,json,md}\"",
|
|
32
28
|
"precommit": "node scripts/hooks/run-precommit.js",
|
|
33
29
|
"upgrade": "npx -y @lark-apaas/fullstack-cli sync --disable-gen-openapi"
|
|
34
30
|
},
|
|
@@ -41,7 +37,6 @@
|
|
|
41
37
|
"@nestjs/core": "^10.4.20",
|
|
42
38
|
"@nestjs/platform-express": "^10.4.20",
|
|
43
39
|
"@nestjs/swagger": "^7.4.2",
|
|
44
|
-
"@tanstack/react-form": "^1.27.6",
|
|
45
40
|
"@tanstack/react-query": "^5.90.12",
|
|
46
41
|
"axios": "^1.12.2",
|
|
47
42
|
"cache-manager": "^6.4.3",
|
|
@@ -56,17 +51,11 @@
|
|
|
56
51
|
"tslib": "^2.8.1"
|
|
57
52
|
},
|
|
58
53
|
"devDependencies": {
|
|
59
|
-
"@dnd-kit/core": "^6.3.1",
|
|
60
|
-
"@dnd-kit/modifiers": "^9.0.0",
|
|
61
|
-
"@dnd-kit/sortable": "^10.0.0",
|
|
62
|
-
"@headlessui/react": "^2.2.9",
|
|
63
|
-
"@heroicons/react": "^2.2.0",
|
|
64
54
|
"@hookform/resolvers": "^5.2.2",
|
|
65
55
|
"@lark-apaas/client-toolkit": "^1.2.69",
|
|
66
|
-
"@lark-apaas/coding-preset-vite-react": "1.0.
|
|
56
|
+
"@lark-apaas/coding-preset-vite-react": "^1.0.21",
|
|
67
57
|
"@lark-apaas/fullstack-presets": "^1.1.0",
|
|
68
58
|
"@nestjs/cli": "^10.4.9",
|
|
69
|
-
"@nestjs/testing": "^10.4.20",
|
|
70
59
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
71
60
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
72
61
|
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
|
@@ -93,33 +82,13 @@
|
|
|
93
82
|
"@radix-ui/react-toggle": "^1.1.10",
|
|
94
83
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
95
84
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
96
|
-
"@reduxjs/toolkit": "^2.9.0",
|
|
97
|
-
"@shikijs/langs": "^3.21.0",
|
|
98
|
-
"@shikijs/themes": "^3.21.0",
|
|
99
85
|
"@swc/cli": "^0.5.2",
|
|
100
86
|
"@swc/core": "^1.16.1",
|
|
101
87
|
"@tailwindcss/postcss": "^4.1.13",
|
|
102
88
|
"@tailwindcss/typography": "^0.5.19",
|
|
103
|
-
"@tiptap/core": "^3.14.0",
|
|
104
|
-
"@tiptap/extension-code-block": "^3.15.3",
|
|
105
|
-
"@tiptap/extension-code-block-lowlight": "^3.14.0",
|
|
106
|
-
"@tiptap/extension-color": "^3.14.0",
|
|
107
|
-
"@tiptap/extension-highlight": "^3.14.0",
|
|
108
|
-
"@tiptap/extension-image": "^3.14.0",
|
|
109
|
-
"@tiptap/extension-link": "^3.14.0",
|
|
110
|
-
"@tiptap/extension-placeholder": "^3.14.0",
|
|
111
|
-
"@tiptap/extension-task-item": "^3.15.3",
|
|
112
|
-
"@tiptap/extension-task-list": "^3.15.3",
|
|
113
|
-
"@tiptap/extension-text-align": "^3.14.0",
|
|
114
|
-
"@tiptap/extension-text-style": "^3.14.0",
|
|
115
|
-
"@tiptap/extension-underline": "^3.14.0",
|
|
116
|
-
"@tiptap/pm": "^3.15.3",
|
|
117
|
-
"@tiptap/react": "^3.14.0",
|
|
118
|
-
"@tiptap/starter-kit": "^3.14.0",
|
|
119
89
|
"@types/crypto-js": "^4.2.2",
|
|
120
90
|
"@types/express": "^5.0.3",
|
|
121
91
|
"@types/hbs": "^4.0.5",
|
|
122
|
-
"@types/jest": "^29.5.14",
|
|
123
92
|
"@types/node": "^22.18.6",
|
|
124
93
|
"@types/react": "^19.2.0",
|
|
125
94
|
"@types/react-dom": "^19.2.0",
|
|
@@ -127,79 +96,47 @@
|
|
|
127
96
|
"class-variance-authority": "^0.7.1",
|
|
128
97
|
"clsx": "~2.0.1",
|
|
129
98
|
"cmdk": "^1.1.1",
|
|
130
|
-
"cobe": "^0.6.5",
|
|
131
99
|
"concurrently": "^9.2.1",
|
|
132
|
-
"css-loader": "^7.1.2",
|
|
133
100
|
"date-fns": "^4.1.0",
|
|
134
101
|
"echarts": "~5.6.0",
|
|
135
102
|
"echarts-for-react": "~3.0.2",
|
|
136
103
|
"embla-carousel-react": "^8.6.0",
|
|
137
|
-
"es-toolkit": "^1.43.0",
|
|
138
104
|
"eslint": "^9.35.0",
|
|
139
|
-
"eslint-config-prettier": "^9.1.2",
|
|
140
|
-
"form-data": "^4.0.4",
|
|
141
105
|
"framer-motion": "~11.13.5",
|
|
142
106
|
"gsap": "^3.13.0",
|
|
143
|
-
"html2canvas": "^1.4.1",
|
|
144
107
|
"input-otp": "^1.4.2",
|
|
145
|
-
"jest": "^29.7.0",
|
|
146
|
-
"js-base64": "^3.7.8",
|
|
147
|
-
"jspdf": "^3.0.3",
|
|
148
108
|
"lodash": "^4.17.21",
|
|
149
109
|
"lucide-react": "^0.554.0",
|
|
150
110
|
"nanoid": "^5.1.6",
|
|
151
111
|
"next-themes": "^0.4.6",
|
|
152
|
-
"pinyin-pro": "^3.27.0",
|
|
153
112
|
"postcss": "^8.5.6",
|
|
154
113
|
"postcss-import": "^16.1.1",
|
|
155
|
-
"postcss-loader": "^8.2.0",
|
|
156
|
-
"prettier": "^3.6.2",
|
|
157
|
-
"qrcode.react": "^4.2.0",
|
|
158
|
-
"radix-ui": "^1.4.3",
|
|
159
114
|
"react": "^19.2.0",
|
|
160
|
-
"react-countup": "^6.5.3",
|
|
161
115
|
"react-day-picker": "^9.11.1",
|
|
162
116
|
"react-dom": "^19.2.0",
|
|
163
|
-
"react-dropzone": "^14.3.5",
|
|
164
117
|
"react-error-boundary": "^6.0.0",
|
|
165
118
|
"react-hook-form": "^7.65.0",
|
|
166
|
-
"react-
|
|
167
|
-
"react-refresh": "^0.17.0",
|
|
119
|
+
"react-markdown": "^10.1.0",
|
|
168
120
|
"react-resizable-panels": "^3.0.6",
|
|
169
121
|
"react-router-dom": "^6.30.1",
|
|
170
122
|
"recharts": "^2.15.4",
|
|
123
|
+
"remark-gfm": "^4.0.1",
|
|
171
124
|
"rxjs": "^7.8.2",
|
|
172
|
-
"shiki": "^3.21.0",
|
|
173
125
|
"sonner": "^2.0.7",
|
|
174
|
-
"streamdown": "^1.6.10",
|
|
175
|
-
"style-loader": "^4.0.0",
|
|
176
126
|
"stylelint": "^16.11.0",
|
|
177
127
|
"tailwind-merge": "~3.4.0",
|
|
178
128
|
"tailwindcss": "^4.1.13",
|
|
179
|
-
"ts-jest": "^29.4.3",
|
|
180
|
-
"ts-node": "^10.9.2",
|
|
181
129
|
"tw-animate-css": "^1.3.8",
|
|
182
130
|
"typescript": "^5.9.2",
|
|
183
131
|
"typescript-eslint": "^8.44.0",
|
|
184
132
|
"uuid": "11.0.5",
|
|
185
133
|
"vaul": "^1.1.2",
|
|
186
134
|
"vite": "^8",
|
|
187
|
-
"
|
|
188
|
-
"xlsx-js-style": "^1.2.0",
|
|
189
|
-
"zod": "^3.25.76",
|
|
190
|
-
"zustand": "~5.0.8"
|
|
135
|
+
"zod": "^3.25.76"
|
|
191
136
|
},
|
|
192
137
|
"overrides": {
|
|
193
138
|
"dayjs": "^1.11.15"
|
|
194
139
|
},
|
|
195
|
-
"jest": {
|
|
196
|
-
"preset": "ts-jest",
|
|
197
|
-
"testEnvironment": "node",
|
|
198
|
-
"testMatch": [
|
|
199
|
-
"<rootDir>/server/**/*.spec.ts",
|
|
200
|
-
"<rootDir>/test/unit/**/*.spec.ts"
|
|
201
|
-
]
|
|
202
|
-
},
|
|
203
140
|
"engines": {
|
|
204
141
|
"node": ">=22.0.0",
|
|
205
142
|
"npm": ">=10.0.0"
|
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
# 业务组件文档
|
|
2
|
-
|
|
3
|
-
本文档包含用户选择、部门选择、群组选择、用户展示等业务组件的使用说明。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 目录
|
|
8
|
-
|
|
9
|
-
- [类型统一规范](#类型统一规范)
|
|
10
|
-
- [UserSelect 用户选择组件](#userselect-用户选择组件)
|
|
11
|
-
- [DepartmentSelect 部门选择组件](#departmentselect-部门选择组件)
|
|
12
|
-
- [ChatSelect 群组选择组件](#chatselect-群组选择组件)
|
|
13
|
-
- [UserDisplay 用户展示组件](#userdisplay-用户展示组件)
|
|
14
|
-
- [UserProfile 用户详情组件](#userprofile-用户详情组件)
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## 类型统一规范
|
|
19
|
-
|
|
20
|
-
### 部门类型
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
/** 部门数据结构 */
|
|
24
|
-
interface Department {
|
|
25
|
-
/** 唯一标识:用于 key/去重/选中判断,内部对应 departmentID */
|
|
26
|
-
id: string;
|
|
27
|
-
/** 展示名称:内部优先 zh_cn,其次 en_us */
|
|
28
|
-
name: string;
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### 群组类型
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
/** 群组数据结构 */
|
|
36
|
-
interface Chat {
|
|
37
|
-
/** 唯一标识:对应 chatID */
|
|
38
|
-
id: string;
|
|
39
|
-
/** 群组名称:内部优先 zh_cn,其次 en_us */
|
|
40
|
-
name: string;
|
|
41
|
-
/** 头像:URL 或 16 进制 RGB 颜色 */
|
|
42
|
-
avatar: string;
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## UserSelect 用户选择组件
|
|
49
|
-
|
|
50
|
-
**组件路径**:`@/components/business-ui/user-select`
|
|
51
|
-
|
|
52
|
-
### 功能概述
|
|
53
|
-
|
|
54
|
-
- 用户字段选择组件,用于表单中录入"人员"字段
|
|
55
|
-
- 通过触发器打开弹层,弹层内置搜索功能(始终可用)
|
|
56
|
-
- 仅支持 **ID 模式**:`value/onChange` 只使用用户 `user_id`(string)
|
|
57
|
-
- 组件在 UI 上可展示用户信息(头像/名称),但对外值仅返回/接收 `id`
|
|
58
|
-
- 组件自带用户检索能力,无需额外传搜索接口/数据源
|
|
59
|
-
|
|
60
|
-
### 类型定义
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
|
|
64
|
-
/** 触发器类型 */
|
|
65
|
-
type TriggerType = 'button' | 'search' | 'custom';
|
|
66
|
-
|
|
67
|
-
/** 单选模式 Props */
|
|
68
|
-
interface UserSelectSingleProps {
|
|
69
|
-
/** 当前选中的用户 ID,空值为 null */
|
|
70
|
-
value: string | null;
|
|
71
|
-
/** 选中变化回调 */
|
|
72
|
-
onChange: (value: string | null) => void;
|
|
73
|
-
/** 是否多选,单选时为 false 或不传 */
|
|
74
|
-
multiple?: false;
|
|
75
|
-
/** 触发器类型,仅影响样式,不影响搜索功能 */
|
|
76
|
-
triggerType?: TriggerType;
|
|
77
|
-
/** 是否禁用 */
|
|
78
|
-
disabled?: boolean;
|
|
79
|
-
/** 占位文本 */
|
|
80
|
-
placeholder?: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** 多选模式 Props */
|
|
84
|
-
interface UserSelectMultipleProps {
|
|
85
|
-
/** 当前选中的用户 ID 列表,空值为 [] */
|
|
86
|
-
value: string[];
|
|
87
|
-
/** 选中变化回调 */
|
|
88
|
-
onChange: (value: string[]) => void;
|
|
89
|
-
/** 是否多选,多选时为 true */
|
|
90
|
-
multiple: true;
|
|
91
|
-
/** 触发器类型 */
|
|
92
|
-
triggerType?: TriggerType;
|
|
93
|
-
/** 是否禁用 */
|
|
94
|
-
disabled?: boolean;
|
|
95
|
-
/** 占位文本 */
|
|
96
|
-
placeholder?: string;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
type UserSelectProps = UserSelectSingleProps | UserSelectMultipleProps;
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Props 说明
|
|
103
|
-
|
|
104
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
105
|
-
|------|------|--------|------|
|
|
106
|
-
| `value` | `string \| null` / `string[]` | - | **必填**。单选传 `string \| null`(用户 ID),多选传 `string[]` |
|
|
107
|
-
| `onChange` | `function` | - | **必填**。值变化回调,返回值形态与 `value` 匹配 |
|
|
108
|
-
| `multiple` | `boolean` | `false` | 是否多选 |
|
|
109
|
-
| `triggerType` | `'button' \| 'search' \| 'custom'` | `'button'` | 触发器类型,仅影响样式 |
|
|
110
|
-
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
111
|
-
| `placeholder` | `string` | `'请选择'` | 占位文本 |
|
|
112
|
-
|
|
113
|
-
### 受控规范
|
|
114
|
-
|
|
115
|
-
> ⚠️ **强约束**
|
|
116
|
-
|
|
117
|
-
1. **必须受控**:始终传 `value` + `onChange`
|
|
118
|
-
2. **禁止传**:`undefined` / `User` 对象 / 其他类型
|
|
119
|
-
3. **空值规则**:
|
|
120
|
-
- 单选清空:`null`
|
|
121
|
-
- 多选清空:`[]`
|
|
122
|
-
|
|
123
|
-
### 使用示例
|
|
124
|
-
|
|
125
|
-
```tsx
|
|
126
|
-
import { useState } from 'react';
|
|
127
|
-
import { UserSelect } from '@/components/business-ui/user-select';
|
|
128
|
-
|
|
129
|
-
// 单选
|
|
130
|
-
function SingleSelectExample() {
|
|
131
|
-
const [userId, setUserId] = useState<string | null>(null);
|
|
132
|
-
|
|
133
|
-
return (
|
|
134
|
-
<UserSelect
|
|
135
|
-
value={userId}
|
|
136
|
-
onChange={setUserId}
|
|
137
|
-
placeholder="请选择用户"
|
|
138
|
-
/>
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// 多选
|
|
143
|
-
function MultipleSelectExample() {
|
|
144
|
-
const [userIds, setUserIds] = useState<string[]>([]);
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
<UserSelect
|
|
148
|
-
multiple
|
|
149
|
-
value={userIds}
|
|
150
|
-
onChange={setUserIds}
|
|
151
|
-
placeholder="请选择用户"
|
|
152
|
-
getOptionDisabled={(user) => user.id === 'disabled-id'}
|
|
153
|
-
/>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## DepartmentSelect 部门选择组件
|
|
161
|
-
|
|
162
|
-
**组件路径**:`@/components/business-ui/department-select`
|
|
163
|
-
|
|
164
|
-
### 功能概述
|
|
165
|
-
|
|
166
|
-
- 部门字段选择组件,用于表单中录入"部门/组织"字段
|
|
167
|
-
- 通过触发器打开弹层,弹层内置搜索功能(始终可用)
|
|
168
|
-
- 仅支持**对象模式**(不支持传 ID/string)
|
|
169
|
-
- 选择后自动回显已选部门信息:部门名称(多选以 tag 形式展示)
|
|
170
|
-
- 组件自带部门检索能力,无需额外传搜索接口/数据源
|
|
171
|
-
|
|
172
|
-
### 类型定义
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
|
|
176
|
-
/** 触发器类型 */
|
|
177
|
-
type TriggerType = 'button' | 'search' | 'custom';
|
|
178
|
-
|
|
179
|
-
/** 单选模式 Props */
|
|
180
|
-
interface DepartmentSelectSingleProps {
|
|
181
|
-
/** 当前选中的部门 */
|
|
182
|
-
value: Department | null;
|
|
183
|
-
/** 选中变化回调 */
|
|
184
|
-
onChange: (value: Department | null) => void;
|
|
185
|
-
/** 是否多选,单选时为 false 或不传 */
|
|
186
|
-
multiple?: false;
|
|
187
|
-
/** 触发器类型,仅影响样式,不影响搜索功能 */
|
|
188
|
-
triggerType?: TriggerType;
|
|
189
|
-
/** 是否禁用 */
|
|
190
|
-
disabled?: boolean;
|
|
191
|
-
/** 占位文本 */
|
|
192
|
-
placeholder?: string;
|
|
193
|
-
/** 判断选项是否禁用 */
|
|
194
|
-
getOptionDisabled?: (department: Department) => boolean;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/** 多选模式 Props */
|
|
198
|
-
interface DepartmentSelectMultipleProps {
|
|
199
|
-
/** 当前选中的部门列表 */
|
|
200
|
-
value: Department[];
|
|
201
|
-
/** 选中变化回调 */
|
|
202
|
-
onChange: (value: Department[]) => void;
|
|
203
|
-
/** 是否多选,多选时为 true */
|
|
204
|
-
multiple: true;
|
|
205
|
-
/** 触发器类型 */
|
|
206
|
-
triggerType?: TriggerType;
|
|
207
|
-
/** 是否禁用 */
|
|
208
|
-
disabled?: boolean;
|
|
209
|
-
/** 占位文本 */
|
|
210
|
-
placeholder?: string;
|
|
211
|
-
/** 判断选项是否禁用 */
|
|
212
|
-
getOptionDisabled?: (department: Department) => boolean;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
type DepartmentSelectProps = DepartmentSelectSingleProps | DepartmentSelectMultipleProps;
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Props 说明
|
|
219
|
-
|
|
220
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
221
|
-
|------|------|--------|------|
|
|
222
|
-
| `value` | `Department \| null` / `Department[]` | - | **必填**。单选传 `Department \| null`,多选传 `Department[]` |
|
|
223
|
-
| `onChange` | `function` | - | **必填**。值变化回调,返回值形态与 `value` 匹配 |
|
|
224
|
-
| `multiple` | `boolean` | `false` | 是否多选 |
|
|
225
|
-
| `triggerType` | `'button' \| 'search' \| 'custom'` | `'button'` | 触发器类型,仅影响样式 |
|
|
226
|
-
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
227
|
-
| `placeholder` | `string` | `'请选择部门'` | 占位文本 |
|
|
228
|
-
| `getOptionDisabled` | `(department: Department) => boolean` | - | 判断选项是否禁用,被禁用的已选项 tag 不显示删除按钮 |
|
|
229
|
-
|
|
230
|
-
### 受控规范
|
|
231
|
-
|
|
232
|
-
> ⚠️ **强约束**
|
|
233
|
-
|
|
234
|
-
1. **必须受控**:始终传 `value` + `onChange`
|
|
235
|
-
2. **禁止传**:`undefined` / `string` / `string[]`
|
|
236
|
-
3. **空值规则**:
|
|
237
|
-
- 单选清空:`null`
|
|
238
|
-
- 多选清空:`[]`
|
|
239
|
-
|
|
240
|
-
### 使用示例
|
|
241
|
-
|
|
242
|
-
```tsx
|
|
243
|
-
import { useState } from 'react';
|
|
244
|
-
import { DepartmentSelect, type Department } from '@/components/business-ui/department-select';
|
|
245
|
-
|
|
246
|
-
// 单选
|
|
247
|
-
function SingleSelectExample() {
|
|
248
|
-
const [department, setDepartment] = useState<Department | null>(null);
|
|
249
|
-
|
|
250
|
-
return (
|
|
251
|
-
<DepartmentSelect
|
|
252
|
-
value={department}
|
|
253
|
-
onChange={setDepartment}
|
|
254
|
-
placeholder="请选择部门"
|
|
255
|
-
/>
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// 多选
|
|
260
|
-
function MultipleSelectExample() {
|
|
261
|
-
const [departments, setDepartments] = useState<Department[]>([]);
|
|
262
|
-
|
|
263
|
-
return (
|
|
264
|
-
<DepartmentSelect
|
|
265
|
-
multiple
|
|
266
|
-
value={departments}
|
|
267
|
-
onChange={setDepartments}
|
|
268
|
-
placeholder="请选择部门"
|
|
269
|
-
/>
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## ChatSelect 群组选择组件
|
|
277
|
-
|
|
278
|
-
**组件路径**:`@/components/business-ui/chat-select`
|
|
279
|
-
|
|
280
|
-
### 功能概述
|
|
281
|
-
|
|
282
|
-
- 群组字段选择组件,用于表单中录入"群组"字段
|
|
283
|
-
- 通过触发器打开弹层,弹层内置搜索功能(始终可用)
|
|
284
|
-
- **仅支持 ID 模式**:`value/onChange` 只使用群组 `chatID`(string),该 ID 为飞书群聊 ID
|
|
285
|
-
- 组件在 UI 上可展示群组信息(头像/名称),但对外值仅返回/接收 `chatID`
|
|
286
|
-
- 选择后自动回显已选群组信息:群头像 + 群名称(多选以 tag 形式展示)
|
|
287
|
-
- 组件自带群组检索能力,无需额外传搜索接口/数据源
|
|
288
|
-
|
|
289
|
-
### 类型定义
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
/** 触发器类型 */
|
|
293
|
-
type TriggerType = 'button' | 'search' | 'custom';
|
|
294
|
-
|
|
295
|
-
/** 单选模式 Props */
|
|
296
|
-
interface ChatSelectSingleProps {
|
|
297
|
-
/** 当前选中的群组 ID,空值为 null */
|
|
298
|
-
value: string | null;
|
|
299
|
-
/** 选中变化回调 */
|
|
300
|
-
onChange: (value: string | null) => void;
|
|
301
|
-
/** 是否多选,单选时为 false 或不传 */
|
|
302
|
-
multiple?: false;
|
|
303
|
-
/** 触发器类型,仅影响样式,不影响搜索功能 */
|
|
304
|
-
triggerType?: TriggerType;
|
|
305
|
-
/** 是否禁用 */
|
|
306
|
-
disabled?: boolean;
|
|
307
|
-
/** 占位文本 */
|
|
308
|
-
placeholder?: string;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/** 多选模式 Props */
|
|
312
|
-
interface ChatSelectMultipleProps {
|
|
313
|
-
/** 当前选中的群组 ID 列表,空值为 [] */
|
|
314
|
-
value: string[];
|
|
315
|
-
/** 选中变化回调 */
|
|
316
|
-
onChange: (value: string[]) => void;
|
|
317
|
-
/** 是否多选,多选时为 true */
|
|
318
|
-
multiple: true;
|
|
319
|
-
/** 触发器类型 */
|
|
320
|
-
triggerType?: TriggerType;
|
|
321
|
-
/** 是否禁用 */
|
|
322
|
-
disabled?: boolean;
|
|
323
|
-
/** 占位文本 */
|
|
324
|
-
placeholder?: string;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
type ChatSelectProps = ChatSelectSingleProps | ChatSelectMultipleProps;
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### Props 说明
|
|
331
|
-
|
|
332
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
333
|
-
|------|------|--------|------|
|
|
334
|
-
| `value` | `string \| null` / `string[]` | - | **必填**。单选传 `string \| null`(群组 ID),多选传 `string[]` |
|
|
335
|
-
| `onChange` | `function` | - | **必填**。值变化回调,返回值形态与 `value` 匹配 |
|
|
336
|
-
| `multiple` | `boolean` | `false` | 是否多选 |
|
|
337
|
-
| `triggerType` | `'button' \| 'search' \| 'custom'` | `'button'` | 触发器类型,仅影响样式 |
|
|
338
|
-
| `disabled` | `boolean` | `false` | 是否禁用 |
|
|
339
|
-
| `placeholder` | `string` | `'请选择'` | 占位文本 |
|
|
340
|
-
| `getOptionDisabled` | `(chat) => boolean` | - | 判断选项是否禁用 |
|
|
341
|
-
|
|
342
|
-
### 受控规范
|
|
343
|
-
|
|
344
|
-
> ⚠️ **强约束**
|
|
345
|
-
|
|
346
|
-
1. **必须受控**:始终传 `value` + `onChange`
|
|
347
|
-
2. **禁止传**:`undefined` / 群组对象 / 其他类型
|
|
348
|
-
3. **空值规则**:
|
|
349
|
-
- 单选清空:`null`
|
|
350
|
-
- 多选清空:`[]`
|
|
351
|
-
|
|
352
|
-
### 使用示例
|
|
353
|
-
|
|
354
|
-
```tsx
|
|
355
|
-
import { useState } from 'react';
|
|
356
|
-
import { ChatSelect } from '@/components/business-ui/chat-select';
|
|
357
|
-
|
|
358
|
-
// 单选
|
|
359
|
-
function SingleSelectExample() {
|
|
360
|
-
const [chatId, setChatId] = useState<string | null>(null);
|
|
361
|
-
|
|
362
|
-
return (
|
|
363
|
-
<ChatSelect
|
|
364
|
-
value={chatId}
|
|
365
|
-
onChange={setChatId}
|
|
366
|
-
placeholder="请选择群组"
|
|
367
|
-
/>
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// 多选
|
|
372
|
-
function MultipleSelectExample() {
|
|
373
|
-
const [chatIds, setChatIds] = useState<string[]>([]);
|
|
374
|
-
|
|
375
|
-
return (
|
|
376
|
-
<ChatSelect
|
|
377
|
-
multiple
|
|
378
|
-
value={chatIds}
|
|
379
|
-
onChange={setChatIds}
|
|
380
|
-
placeholder="请选择群组"
|
|
381
|
-
getOptionDisabled={(chat) => chat.id === 'disabled-id'}
|
|
382
|
-
/>
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
---
|
|
388
|
-
|
|
389
|
-
## UserDisplay 用户展示组件
|
|
390
|
-
|
|
391
|
-
**组件路径**:`@/components/business-ui/user-display`
|
|
392
|
-
|
|
393
|
-
### 功能概述
|
|
394
|
-
|
|
395
|
-
- 用于所有用户信息的展示场景
|
|
396
|
-
- 显示用户**头像**和**姓名**
|
|
397
|
-
- 支持单用户和多用户展示
|
|
398
|
-
- 点击用户会弹出 `UserProfile` 卡片
|
|
399
|
-
- 当没有用户的 name 和 avatar 时,只要确保传递了 `user_id` 即可,组件会自动查询用户信息
|
|
400
|
-
|
|
401
|
-
> ⚠️ **注意**:当不传递 `showLabel` 时,组件会同时展示用户头像和姓名。如果只需要头像,需要传递 `showLabel={false}`
|
|
402
|
-
|
|
403
|
-
### 类型定义
|
|
404
|
-
|
|
405
|
-
```typescript
|
|
406
|
-
|
|
407
|
-
/** 头像尺寸 */
|
|
408
|
-
type AvatarSize = 'small' | 'medium' | 'large';
|
|
409
|
-
|
|
410
|
-
/** UserDisplay Props */
|
|
411
|
-
interface IUserDisplayProps {
|
|
412
|
-
/** 用户 ID */
|
|
413
|
-
value?: string[];
|
|
414
|
-
/** 头像尺寸 */
|
|
415
|
-
size?: AvatarSize;
|
|
416
|
-
/** 自定义样式类名 */
|
|
417
|
-
className?: string;
|
|
418
|
-
/** 自定义内联样式 */
|
|
419
|
-
style?: React.CSSProperties;
|
|
420
|
-
/** 是否显示用户姓名,默认 true。设为 false 则只展示头像 */
|
|
421
|
-
showLabel?: boolean;
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### Props 说明
|
|
426
|
-
|
|
427
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
428
|
-
|------|------|--------|------|
|
|
429
|
-
| `value` | `string[]` | - | 用户 ID 数组 |
|
|
430
|
-
| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | 头像尺寸 |
|
|
431
|
-
| `className` | `string` | - | 自定义样式类名 |
|
|
432
|
-
| `style` | `React.CSSProperties` | - | 自定义内联样式 |
|
|
433
|
-
| `showLabel` | `boolean` | `true` | 是否显示用户姓名,设为 `false` 只展示头像 |
|
|
434
|
-
|
|
435
|
-
### 使用示例
|
|
436
|
-
|
|
437
|
-
```tsx
|
|
438
|
-
import { UserDisplay } from '@/components/business-ui/user-display';
|
|
439
|
-
|
|
440
|
-
// 单用户展示 - 使用 ID
|
|
441
|
-
function SingleUserExample() {
|
|
442
|
-
return (
|
|
443
|
-
<UserDisplay
|
|
444
|
-
value={["user-123"]}
|
|
445
|
-
size="small"
|
|
446
|
-
/>
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// 多用户展示 - 使用 ID 数组
|
|
451
|
-
function MultipleUsersExample() {
|
|
452
|
-
const userIds: string[] = ['1', '2', '3'];
|
|
453
|
-
|
|
454
|
-
return (
|
|
455
|
-
<UserDisplay
|
|
456
|
-
value={userIds}
|
|
457
|
-
size="medium"
|
|
458
|
-
className="project-members"
|
|
459
|
-
/>
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// 仅展示头像
|
|
464
|
-
function AvatarOnlyExample() {
|
|
465
|
-
return (
|
|
466
|
-
<UserDisplay
|
|
467
|
-
value={["user-123"]}
|
|
468
|
-
showLabel={false}
|
|
469
|
-
/>
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### 最佳实践
|
|
475
|
-
|
|
476
|
-
- 根据展示场景选择合适的组件尺寸
|
|
477
|
-
- 对于用户信息`user_id`,**禁止直接展示文本**,总是使用 `UserDisplay` 组件展示
|
|
478
|
-
- 对于需要显示完整用户详情的场景,使用 `UserProfile` 组件
|
|
479
|
-
|
|
480
|
-
---
|
|
481
|
-
|
|
482
|
-
## UserProfile 用户详情组件
|
|
483
|
-
|
|
484
|
-
**组件路径**:`@/components/business-ui/user-profile/user-profile`
|
|
485
|
-
|
|
486
|
-
### 功能概述
|
|
487
|
-
|
|
488
|
-
- 用于显示用户详细信息卡片
|
|
489
|
-
- 支持两种显示模式:简单信息卡片和飞书官方用户卡片
|
|
490
|
-
- 自动处理用户状态和类型标识
|
|
491
|
-
- 提供邮箱链接功能
|
|
492
|
-
- 支持错误重试机制
|
|
493
|
-
|
|
494
|
-
### 类型定义
|
|
495
|
-
|
|
496
|
-
```typescript
|
|
497
|
-
/** UserProfile Props */
|
|
498
|
-
interface UserProfileProps {
|
|
499
|
-
/** 用户 ID*/
|
|
500
|
-
value?: string;
|
|
501
|
-
}
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
### Props 说明
|
|
505
|
-
|
|
506
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
507
|
-
|------|------|--------|------|
|
|
508
|
-
| `value` | `string` | - | 用户 ID |
|
|
509
|
-
|
|
510
|
-
### 使用示例
|
|
511
|
-
|
|
512
|
-
```tsx
|
|
513
|
-
import { UserProfile } from '@/components/business-ui/user-profile/user-profile';
|
|
514
|
-
|
|
515
|
-
// 基础用法 - 使用字符串 ID
|
|
516
|
-
function BasicExample() {
|
|
517
|
-
return <UserProfile value="user-123" />;
|
|
518
|
-
}
|
|
519
|
-
```
|