foucui 1.0.1 → 1.0.2

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.
Files changed (234) hide show
  1. package/dist/components/QiuCanvasKit/QiuCanvasEditor.vue.d.ts +3 -1
  2. package/dist/components/QiuCanvasKit/components/DataModulesPanel.vue.d.ts +1 -0
  3. package/dist/components/QiuTable/index.vue.d.ts +12 -12
  4. package/dist/foucui.css +1 -1
  5. package/dist/foucui.js +7476 -7373
  6. package/dist/foucui.umd.cjs +19 -19
  7. package/package.json +23 -13
  8. package/components/QiuAffix/index.vue +0 -186
  9. package/components/QiuAlert/index.vue +0 -208
  10. package/components/QiuAnchor/context.ts +0 -18
  11. package/components/QiuAnchor/index.vue +0 -180
  12. package/components/QiuAnchorLink/index.vue +0 -67
  13. package/components/QiuApp/index.vue +0 -9
  14. package/components/QiuAutocomplete/index.vue +0 -408
  15. package/components/QiuAvatar/index.vue +0 -140
  16. package/components/QiuBacktop/index.vue +0 -121
  17. package/components/QiuBadge/api/index.ts +0 -389
  18. package/components/QiuBadge/components/BadgeImagePickerDialog.vue +0 -243
  19. package/components/QiuBadge/components/BadgeLibraryManagerDialog.vue +0 -30
  20. package/components/QiuBadge/components/BadgeLibraryPanel.vue +0 -182
  21. package/components/QiuBadge/composables/useTableHostHeight.ts +0 -53
  22. package/components/QiuBadge/index.ts +0 -18
  23. package/components/QiuBadge/shared/BadgeTemplateRenderer.vue +0 -32
  24. package/components/QiuBadge/shared/assetUrl.ts +0 -26
  25. package/components/QiuBadge/shared/badgeTemplate.ts +0 -309
  26. package/components/QiuBadge/utils/chinaAreaData.ts +0 -44
  27. package/components/QiuBadge/utils/hostRegion.ts +0 -22
  28. package/components/QiuBadge/utils/pca-code.json +0 -1
  29. package/components/QiuBadge/utils/pdfFromElement.ts +0 -348
  30. package/components/QiuBadge/views/BadgeLibraryView.vue +0 -32
  31. package/components/QiuBadge/views/BadgeManageView.vue +0 -1364
  32. package/components/QiuBadge/views/BadgeTemplateEditorView.vue +0 -10
  33. package/components/QiuBadge/views/BadgeTemplateListView.vue +0 -229
  34. package/components/QiuBadge/views/DeskLabelTemplateListView.vue +0 -227
  35. package/components/QiuBadge/views/DeskLabelView.vue +0 -683
  36. package/components/QiuBadgeDot/index.vue +0 -87
  37. package/components/QiuButton/index.vue +0 -247
  38. package/components/QiuButtonGroup/index.vue +0 -63
  39. package/components/QiuCanvasKit/QiuCanvasEditor.vue +0 -5503
  40. package/components/QiuCanvasKit/QiuCanvasRenderer.vue +0 -348
  41. package/components/QiuCanvasKit/assetUrl.ts +0 -11
  42. package/components/QiuCanvasKit/components/DataModulesPanel.vue +0 -352
  43. package/components/QiuCanvasKit/export/html.ts +0 -132
  44. package/components/QiuCanvasKit/export/pdf.ts +0 -48
  45. package/components/QiuCanvasKit/export/png.ts +0 -50
  46. package/components/QiuCanvasKit/index.ts +0 -20
  47. package/components/QiuCanvasKit/modules/badgeCompat.ts +0 -84
  48. package/components/QiuCanvasKit/modules/dataRegistry.ts +0 -207
  49. package/components/QiuCanvasKit/modules/merge.ts +0 -71
  50. package/components/QiuCanvasKit/presets/badge.ts +0 -67
  51. package/components/QiuCanvasKit/presets/banner.ts +0 -79
  52. package/components/QiuCanvasKit/types.ts +0 -138
  53. package/components/QiuCard/index.vue +0 -104
  54. package/components/QiuCarousel/context.ts +0 -16
  55. package/components/QiuCarousel/index.vue +0 -343
  56. package/components/QiuCarouselItem/index.vue +0 -47
  57. package/components/QiuCascader/index.vue +0 -879
  58. package/components/QiuCascader/types.ts +0 -48
  59. package/components/QiuCheckbox/QiuCheckboxGroup.vue +0 -78
  60. package/components/QiuCheckbox/index.vue +0 -231
  61. package/components/QiuCheckbox/types.ts +0 -8
  62. package/components/QiuCode/index.vue +0 -64
  63. package/components/QiuCol/col.scss +0 -55
  64. package/components/QiuCol/index.vue +0 -64
  65. package/components/QiuCollapse/context.ts +0 -10
  66. package/components/QiuCollapse/index.vue +0 -70
  67. package/components/QiuCollapseItem/index.vue +0 -167
  68. package/components/QiuColorField/index.vue +0 -296
  69. package/components/QiuColorPicker/README.md +0 -118
  70. package/components/QiuColorPicker/index.vue +0 -60
  71. package/components/QiuColorfulCard/index.vue +0 -101
  72. package/components/QiuCombobox/index.vue +0 -277
  73. package/components/QiuConfigProvider/index.vue +0 -31
  74. package/components/QiuContextMenu/index.vue +0 -209
  75. package/components/QiuDate/index.vue +0 -1134
  76. package/components/QiuDescriptions/context.ts +0 -20
  77. package/components/QiuDescriptions/index.vue +0 -115
  78. package/components/QiuDescriptionsItem/index.vue +0 -103
  79. package/components/QiuDialog/index.vue +0 -828
  80. package/components/QiuDigitalCard/index.vue +0 -159
  81. package/components/QiuDivider/index.vue +0 -185
  82. package/components/QiuDot/index.vue +0 -83
  83. package/components/QiuDrawer/index.vue +0 -350
  84. package/components/QiuDropdown/QiuDropdownItem.vue +0 -74
  85. package/components/QiuDropdown/QiuDropdownMenu.vue +0 -22
  86. package/components/QiuDropdown/context.ts +0 -9
  87. package/components/QiuDropdown/index.vue +0 -189
  88. package/components/QiuEmpty/index.vue +0 -73
  89. package/components/QiuForm/index.vue +0 -172
  90. package/components/QiuForm/types.ts +0 -39
  91. package/components/QiuFormItem/index.vue +0 -276
  92. package/components/QiuFullscreen/index.vue +0 -11
  93. package/components/QiuGrid/index.vue +0 -408
  94. package/components/QiuHoverCard/index.vue +0 -192
  95. package/components/QiuIcon/index.vue +0 -117
  96. package/components/QiuIconPicker/iconify.libraries.ts +0 -182
  97. package/components/QiuIconPicker/icons.catalog.ts +0 -3072
  98. package/components/QiuIconPicker/index.vue +0 -488
  99. package/components/QiuImage/index.vue +0 -177
  100. package/components/QiuInput/index.vue +0 -328
  101. package/components/QiuInputNumber/index.vue +0 -295
  102. package/components/QiuInputOtp/index.vue +0 -190
  103. package/components/QiuKbd/index.vue +0 -57
  104. package/components/QiuLayoutContainer/index.vue +0 -50
  105. package/components/QiuLinkPreview/index.vue +0 -224
  106. package/components/QiuLoading/index.ts +0 -176
  107. package/components/QiuLoading/spinner.vue +0 -820
  108. package/components/QiuLoading/types.ts +0 -44
  109. package/components/QiuMention/index.vue +0 -299
  110. package/components/QiuMenu/QiuMenuRoot.vue +0 -241
  111. package/components/QiuMenu/components/QiuMenuItem.vue +0 -340
  112. package/components/QiuMenu/components/QiuSubMenu.vue +0 -504
  113. package/components/QiuMenu/context.ts +0 -21
  114. package/components/QiuMenu/index.vue +0 -43
  115. package/components/QiuMenuNav/QiuMenuNavItem.vue +0 -100
  116. package/components/QiuMenuNav/QiuMenuNavSub.vue +0 -120
  117. package/components/QiuMenuNav/context.ts +0 -14
  118. package/components/QiuMenuNav/index.vue +0 -148
  119. package/components/QiuMsg/QiuMsgItem.vue +0 -180
  120. package/components/QiuMsg/index.ts +0 -158
  121. package/components/QiuMsg/types.ts +0 -23
  122. package/components/QiuMsgBox/index.ts +0 -147
  123. package/components/QiuNotification/QiuNotificationItem.vue +0 -168
  124. package/components/QiuNotification/index.ts +0 -155
  125. package/components/QiuNotification/types.ts +0 -14
  126. package/components/QiuPage/index.vue +0 -12
  127. package/components/QiuPageHeader/index.vue +0 -115
  128. package/components/QiuPageMain/index.vue +0 -78
  129. package/components/QiuPagination/index.vue +0 -421
  130. package/components/QiuPasswordStrength/index.vue +0 -101
  131. package/components/QiuPopconfirm/index.vue +0 -196
  132. package/components/QiuPopover/index.vue +0 -277
  133. package/components/QiuProgress/index.vue +0 -235
  134. package/components/QiuQrcode/index.vue +0 -302
  135. package/components/QiuQueryForm/components/QiuQueryFormBottomPanel.vue +0 -13
  136. package/components/QiuQueryForm/components/QiuQueryFormLeftPanel.vue +0 -37
  137. package/components/QiuQueryForm/components/QiuQueryFormRightPanel.vue +0 -37
  138. package/components/QiuQueryForm/components/QiuQueryFormTopPanel.vue +0 -13
  139. package/components/QiuQueryForm/index.vue +0 -117
  140. package/components/QiuRadio/QiuRadioGroup.vue +0 -75
  141. package/components/QiuRadio/index.vue +0 -191
  142. package/components/QiuRadio/types.ts +0 -9
  143. package/components/QiuRate/index.vue +0 -184
  144. package/components/QiuRefresh/index.vue +0 -32
  145. package/components/QiuResult/index.vue +0 -103
  146. package/components/QiuRow/index.vue +0 -60
  147. package/components/QiuRow/types.ts +0 -5
  148. package/components/QiuScrollbar/index.vue +0 -107
  149. package/components/QiuSearchBar/index.vue +0 -154
  150. package/components/QiuSegmented/index.vue +0 -120
  151. package/components/QiuSelect/QiuOption.vue +0 -93
  152. package/components/QiuSelect/index.vue +0 -452
  153. package/components/QiuSelect/types.ts +0 -15
  154. package/components/QiuSkeleton/index.vue +0 -78
  155. package/components/QiuSlider/index.vue +0 -266
  156. package/components/QiuSpace/index.vue +0 -95
  157. package/components/QiuSparkline/index.vue +0 -92
  158. package/components/QiuStatistic/index.vue +0 -4
  159. package/components/QiuStatistics/index.vue +0 -123
  160. package/components/QiuStep/index.vue +0 -220
  161. package/components/QiuSteps/context.ts +0 -25
  162. package/components/QiuSteps/index.vue +0 -84
  163. package/components/QiuSwitch/index.vue +0 -145
  164. package/components/QiuTabBar/index.vue +0 -218
  165. package/components/QiuTabBar/types.ts +0 -19
  166. package/components/QiuTabPane/index.vue +0 -82
  167. package/components/QiuTable/columns.ts +0 -16
  168. package/components/QiuTable/export.ts +0 -102
  169. package/components/QiuTable/index.ts +0 -24
  170. package/components/QiuTable/index.vue +0 -3503
  171. package/components/QiuTable/registry.ts +0 -75
  172. package/components/QiuTable/styles/table.scss +0 -1230
  173. package/components/QiuTable/types.ts +0 -413
  174. package/components/QiuTable/useArea.ts +0 -202
  175. package/components/QiuTable/useColumns.ts +0 -325
  176. package/components/QiuTable/useEdit.ts +0 -136
  177. package/components/QiuTable/useExtras.ts +0 -115
  178. package/components/QiuTable/useHistory.ts +0 -77
  179. package/components/QiuTable/useMerge.ts +0 -105
  180. package/components/QiuTable/useResize.ts +0 -86
  181. package/components/QiuTable/useScrollSync.ts +0 -152
  182. package/components/QiuTable/useVirtual.ts +0 -97
  183. package/components/QiuTable/utils.ts +0 -165
  184. package/components/QiuTableColumn/index.vue +0 -101
  185. package/components/QiuTag/index.vue +0 -143
  186. package/components/QiuText/index.vue +0 -99
  187. package/components/QiuTime/index.vue +0 -548
  188. package/components/QiuTimeAgo/index.vue +0 -103
  189. package/components/QiuTimeline/index.vue +0 -54
  190. package/components/QiuTimelineItem/index.vue +0 -140
  191. package/components/QiuTips/index.vue +0 -323
  192. package/components/QiuTooltip/index.vue +0 -237
  193. package/components/QiuTransfer/index.vue +0 -277
  194. package/components/QiuTree/QiuTreeNode.vue +0 -146
  195. package/components/QiuTree/index.vue +0 -143
  196. package/components/QiuTree/types.ts +0 -30
  197. package/components/QiuTreeSelect/index.vue +0 -259
  198. package/components/QiuTrend/index.vue +0 -92
  199. package/components/QiuUpload/index.vue +0 -628
  200. package/components/QiuUploadCrop/index.vue +0 -1267
  201. package/components/QiuWatermark/index.vue +0 -121
  202. package/components/useBodyScrollLock.ts +0 -28
  203. package/dist/components/QiuBadge/utils/pca-code.json.d.ts +0 -3
  204. package/plugins/qiu.ts +0 -83
  205. package/plugins/shortcuts.ts +0 -69
  206. package/src/bridge/@/api/media.ts +0 -8
  207. package/src/bridge/@/api/notice.ts +0 -5
  208. package/src/bridge/@/config/index.ts +0 -38
  209. package/src/bridge/@/config/media.config.ts +0 -37
  210. package/src/bridge/@/config/security.config.ts +0 -8
  211. package/src/bridge/@/i18n/index.ts +0 -6
  212. package/src/bridge/@/store/modules/bing.ts +0 -9
  213. package/src/bridge/@/store/modules/errorLog.ts +0 -9
  214. package/src/bridge/@/store/modules/media.ts +0 -10
  215. package/src/bridge/@/store/modules/routes.ts +0 -10
  216. package/src/bridge/@/store/modules/settings.ts +0 -9
  217. package/src/bridge/@/store/modules/tabs.ts +0 -9
  218. package/src/bridge/@/store/modules/user.ts +0 -9
  219. package/src/bridge/@/utils/convertToCamelCase.ts +0 -11
  220. package/src/bridge/@/utils/index.ts +0 -9
  221. package/src/bridge/@/utils/pageTitle.ts +0 -4
  222. package/src/bridge/@/utils/routes.ts +0 -14
  223. package/src/bridge/@/utils/validate.ts +0 -17
  224. package/src/bridge/@qiu/plugins/shortcuts.ts +0 -3
  225. package/src/i18n.ts +0 -8
  226. package/src/icons/qiu-logo.svg +0 -1
  227. package/styles/dark.scss +0 -194
  228. package/styles/normalize.css +0 -349
  229. package/styles/plain.scss +0 -423
  230. package/styles/qiu-tokens.scss +0 -40
  231. package/styles/qiu.scss +0 -1149
  232. package/styles/technology.scss +0 -452
  233. package/styles/var.scss +0 -382
  234. package/styles/variables.scss +0 -77
@@ -1,243 +0,0 @@
1
- <template>
2
- <qiu-dialog
3
- v-model="visibleInner"
4
- title="添加图片"
5
- width="720px"
6
- destroy-on-close
7
- class="badge-img-picker-dlg"
8
- @opened="load"
9
- >
10
- <qiu-tab-bar v-model="tab">
11
- <qiu-tab-pane label="图片库" name="lib">
12
- <p class="dlg-hint">双击缩略图插入到画布;删除后模板里若仍引用该地址将无法显示。</p>
13
- <div v-qiu-loading="loading" class="lib-grid">
14
- <div
15
- v-for="it in list"
16
- :key="it.id"
17
- class="lib-cell"
18
- @dblclick="pick(it)"
19
- >
20
- <img :src="fullUrl(it.url)" alt="" class="thumb" loading="lazy" />
21
- <div class="meta" :title="it.orig_name">{{ it.orig_name || '未命名' }}</div>
22
- <qiu-button type="danger" link size="small" class="del" @click.stop="remove(it)">删除</qiu-button>
23
- </div>
24
- </div>
25
- <qiu-empty v-if="!loading && !list.length" description="暂无图片,可到「上传本地文件」添加" />
26
- </qiu-tab-pane>
27
- <qiu-tab-pane label="上传本地文件" name="up">
28
- <p class="dlg-hint">上传后会写入图片库,并自动插入当前画布;可多选文件或一次拖拽多张。</p>
29
- <div
30
- class="upload-drop"
31
- @dragover.prevent
32
- @drop.prevent="onDrop"
33
- @click="fileInputRef?.click()"
34
- >
35
- <qiu-icon icon="upload-cloud-2-line" class="upload-ico" />
36
- <div class="upload-text">拖到此处,或 <em>点击选择多个文件</em></div>
37
- <div class="upload-sub">支持 JPG / PNG / GIF / WebP / BMP,单文件不超过 8MB</div>
38
- <input
39
- ref="fileInputRef"
40
- type="file"
41
- multiple
42
- accept="image/jpeg,image/png,image/gif,image/webp,image/bmp"
43
- class="upload-input"
44
- @change="onFileInput"
45
- />
46
- </div>
47
- </qiu-tab-pane>
48
- </qiu-tab-bar>
49
-
50
- <qiu-dialog v-model="deleteConfirmVisible" title="删除确认" width="400px" append-to-body>
51
- <p>确定删除「{{ deleteTarget?.orig_name || '该图片' }}」?</p>
52
- <template #footer>
53
- <qiu-button @click="deleteConfirmVisible = false">取消</qiu-button>
54
- <qiu-button type="danger" @click="doRemove">删除</qiu-button>
55
- </template>
56
- </qiu-dialog>
57
- </qiu-dialog>
58
- </template>
59
-
60
- <script setup lang="ts">
61
- import { ref, watch, computed } from 'vue'
62
- import { qiuMsg } from '../../QiuMsg'
63
- import { getBadgeLibraryImages, uploadBadgeLibraryImage, deleteBadgeLibraryImage } from '../api/index'
64
- import { resolveAssetUrl } from '../shared/assetUrl'
65
-
66
- const props = withDefaults(
67
- defineProps<{ modelValue: boolean; defaultTab?: 'lib' | 'up' }>(),
68
- { defaultTab: 'lib' }
69
- )
70
- const emit = defineEmits<{ 'update:modelValue': [boolean]; pick: [string] }>()
71
-
72
- const visibleInner = computed({
73
- get: () => props.modelValue,
74
- set: (v: boolean) => emit('update:modelValue', v),
75
- })
76
-
77
- const tab = ref('lib')
78
- const loading = ref(false)
79
- const list = ref<any[]>([])
80
- const fileInputRef = ref<HTMLInputElement | null>(null)
81
- const deleteConfirmVisible = ref(false)
82
- const deleteTarget = ref<{ id: number; orig_name?: string } | null>(null)
83
-
84
- function fullUrl(path: string) {
85
- return resolveAssetUrl(path)
86
- }
87
-
88
- async function load() {
89
- loading.value = true
90
- try {
91
- const res: any = await getBadgeLibraryImages({ page: 1, page_size: 120 })
92
- list.value = res.data?.list ?? []
93
- } catch {
94
- list.value = []
95
- } finally {
96
- loading.value = false
97
- }
98
- }
99
-
100
- watch(
101
- () => props.modelValue,
102
- (v) => {
103
- if (v) tab.value = props.defaultTab
104
- }
105
- )
106
-
107
- function pick(it: { url: string }) {
108
- if (!it?.url) return
109
- emit('pick', resolveAssetUrl(it.url))
110
- visibleInner.value = false
111
- }
112
-
113
- function remove(it: { id: number; orig_name?: string }) {
114
- deleteTarget.value = it
115
- deleteConfirmVisible.value = true
116
- }
117
-
118
- async function doRemove() {
119
- const it = deleteTarget.value
120
- if (!it) return
121
- deleteConfirmVisible.value = false
122
- try {
123
- await deleteBadgeLibraryImage(Number(it.id))
124
- qiuMsg.success('已删除')
125
- await load()
126
- } catch {
127
- /* 拦截器 */
128
- }
129
- }
130
-
131
- const MAX_BADGE_UPLOAD_MB = 8
132
-
133
- async function uploadFiles(files: FileList | File[]) {
134
- for (const file of Array.from(files)) {
135
- const mb = file.size / (1024 * 1024)
136
- if (mb > MAX_BADGE_UPLOAD_MB) {
137
- qiuMsg.error(`「${file.name}」超过 ${MAX_BADGE_UPLOAD_MB}MB,已跳过`)
138
- continue
139
- }
140
- try {
141
- const res: any = await uploadBadgeLibraryImage(file)
142
- const url = res?.data?.url
143
- if (!url) {
144
- qiuMsg.error(`「${file.name}」上传失败`)
145
- continue
146
- }
147
- emit('pick', resolveAssetUrl(url))
148
- await load()
149
- } catch {
150
- /* 拦截器已提示 */
151
- }
152
- }
153
- }
154
-
155
- function onFileInput(e: Event) {
156
- const input = e.target as HTMLInputElement
157
- if (input.files?.length) uploadFiles(input.files)
158
- input.value = ''
159
- }
160
-
161
- function onDrop(e: DragEvent) {
162
- if (e.dataTransfer?.files?.length) uploadFiles(e.dataTransfer.files)
163
- }
164
- </script>
165
-
166
- <style scoped>
167
- .dlg-hint {
168
- font-size: 13px;
169
- color: #909399;
170
- margin: 0 0 12px;
171
- line-height: 1.5;
172
- }
173
- .lib-grid {
174
- display: grid;
175
- grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
176
- gap: 12px;
177
- max-height: 420px;
178
- overflow-y: auto;
179
- padding: 4px 0;
180
- }
181
- .lib-cell {
182
- border: 1px solid #ebeef5;
183
- border-radius: 8px;
184
- padding: 8px;
185
- cursor: pointer;
186
- transition: border-color 0.15s, box-shadow 0.15s;
187
- position: relative;
188
- }
189
- .lib-cell:hover {
190
- border-color: #409eff;
191
- box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
192
- }
193
- .thumb {
194
- width: 100%;
195
- height: 100px;
196
- object-fit: contain;
197
- background: #f5f7fa;
198
- border-radius: 4px;
199
- }
200
- .meta {
201
- font-size: 11px;
202
- color: #606266;
203
- margin-top: 6px;
204
- overflow: hidden;
205
- text-overflow: ellipsis;
206
- white-space: nowrap;
207
- }
208
- .del {
209
- margin-top: 4px;
210
- }
211
- .upload-drop {
212
- padding: 40px 20px;
213
- text-align: center;
214
- cursor: pointer;
215
- border: 1px dashed #dcdfe6;
216
- border-radius: 8px;
217
- background: #fafafa;
218
- }
219
- .upload-drop:hover {
220
- border-color: #409eff;
221
- }
222
- .upload-input {
223
- display: none;
224
- }
225
- .upload-ico {
226
- font-size: 48px;
227
- color: #c0c4cc;
228
- margin-bottom: 8px;
229
- }
230
- .upload-text {
231
- font-size: 14px;
232
- color: #606266;
233
- }
234
- .upload-text em {
235
- color: #409eff;
236
- font-style: normal;
237
- }
238
- .upload-sub {
239
- font-size: 12px;
240
- color: #909399;
241
- margin-top: 8px;
242
- }
243
- </style>
@@ -1,30 +0,0 @@
1
- <template>
2
- <qiu-dialog
3
- :model-value="modelValue"
4
- title="证件图片库"
5
- width="min(920px, 94vw)"
6
- class="badge-library-manager-dialog"
7
- append-to-body
8
- destroy-on-close
9
- @update:model-value="$emit('update:modelValue', $event)"
10
- >
11
- <p class="dlg-tip">管理模板编辑中上传的图片;删除后已保存模板里若仍引用该地址将无法显示。</p>
12
- <BadgeLibraryPanel v-if="modelValue" />
13
- </qiu-dialog>
14
- </template>
15
-
16
- <script setup lang="ts">
17
- import BadgeLibraryPanel from './BadgeLibraryPanel.vue'
18
-
19
- defineProps<{ modelValue: boolean }>()
20
- defineEmits<{ 'update:modelValue': [boolean] }>()
21
- </script>
22
-
23
- <style scoped>
24
- .dlg-tip {
25
- margin: 0 0 14px;
26
- font-size: 13px;
27
- color: #909399;
28
- line-height: 1.5;
29
- }
30
- </style>
@@ -1,182 +0,0 @@
1
- <template>
2
- <div class="badge-library-panel">
3
- <qiu-card shadow="never" class="toolbar-card">
4
- <label class="upload-btn">
5
- <input
6
- type="file"
7
- accept="image/jpeg,image/png,image/gif,image/webp,image/bmp"
8
- class="upload-input"
9
- @change="onFileChange"
10
- />
11
- <qiu-button type="primary" tag="span">上传图片</qiu-button>
12
- </label>
13
- <span class="hint">上传后可在模板编辑器的「图片库」中选用。</span>
14
- </qiu-card>
15
-
16
- <qiu-card v-qiu-loading="loading" shadow="never">
17
- <div class="lib-grid">
18
- <div v-for="it in list" :key="it.id" class="lib-cell">
19
- <img :src="fullUrl(it.url)" alt="" class="thumb" loading="lazy" />
20
- <div class="meta" :title="it.orig_name">{{ it.orig_name || '未命名' }}</div>
21
- <div class="sub">{{ formatSize(it.size) }} · {{ it.create_time }}</div>
22
- <qiu-button type="danger" link size="small" @click="remove(it)">删除</qiu-button>
23
- </div>
24
- </div>
25
- <qiu-empty v-if="!loading && !list.length" description="暂无图片" />
26
- <div v-if="total > pageSize" class="pager">
27
- <qiu-pagination
28
- v-model:current-page="page"
29
- :page-size="pageSize"
30
- layout="total, prev, pager, next"
31
- :total="total"
32
- @current-change="load"
33
- />
34
- </div>
35
- </qiu-card>
36
-
37
- <qiu-dialog v-model="deleteConfirmVisible" title="删除确认" width="400px">
38
- <p>确定删除「{{ deleteTarget?.orig_name || '该图片' }}」?</p>
39
- <template #footer>
40
- <qiu-button @click="deleteConfirmVisible = false">取消</qiu-button>
41
- <qiu-button type="danger" @click="doRemove">删除</qiu-button>
42
- </template>
43
- </qiu-dialog>
44
- </div>
45
- </template>
46
-
47
- <script setup lang="ts">
48
- import { ref, onMounted } from 'vue'
49
- import { qiuMsg } from '../../QiuMsg'
50
- import { getBadgeLibraryImages, uploadBadgeLibraryImage, deleteBadgeLibraryImage } from '../api/index'
51
- import { resolveAssetUrl } from '../shared/assetUrl'
52
-
53
- const loading = ref(false)
54
- const list = ref<any[]>([])
55
- const total = ref(0)
56
- const page = ref(1)
57
- const pageSize = ref(40)
58
- const deleteConfirmVisible = ref(false)
59
- const deleteTarget = ref<{ id: number; orig_name?: string } | null>(null)
60
-
61
- function fullUrl(path: string) {
62
- return resolveAssetUrl(path)
63
- }
64
-
65
- function formatSize(n: unknown) {
66
- const b = Number(n) || 0
67
- if (b < 1024) return `${b} B`
68
- if (b < 1024 * 1024) return `${(b / 1024).toFixed(1)} KB`
69
- return `${(b / 1024 / 1024).toFixed(2)} MB`
70
- }
71
-
72
- async function load() {
73
- loading.value = true
74
- try {
75
- const res: any = await getBadgeLibraryImages({ page: page.value, page_size: pageSize.value })
76
- list.value = res.data?.list ?? []
77
- total.value = Number(res.data?.total ?? 0)
78
- } catch {
79
- list.value = []
80
- total.value = 0
81
- } finally {
82
- loading.value = false
83
- }
84
- }
85
-
86
- async function onFileChange(e: Event) {
87
- const input = e.target as HTMLInputElement
88
- const file = input.files?.[0]
89
- input.value = ''
90
- if (!file) return
91
- try {
92
- await uploadBadgeLibraryImage(file)
93
- qiuMsg.success('已上传')
94
- page.value = 1
95
- await load()
96
- } catch {
97
- /* */
98
- }
99
- }
100
-
101
- function remove(it: { id: number; orig_name?: string }) {
102
- deleteTarget.value = it
103
- deleteConfirmVisible.value = true
104
- }
105
-
106
- async function doRemove() {
107
- const it = deleteTarget.value
108
- if (!it) return
109
- deleteConfirmVisible.value = false
110
- try {
111
- await deleteBadgeLibraryImage(Number(it.id))
112
- qiuMsg.success('已删除')
113
- await load()
114
- } catch {
115
- /* */
116
- }
117
- }
118
-
119
- onMounted(() => load())
120
-
121
- defineExpose({ load })
122
- </script>
123
-
124
- <style scoped>
125
- .badge-library-panel .toolbar-card {
126
- margin-bottom: 16px;
127
- display: flex;
128
- align-items: center;
129
- gap: 16px;
130
- flex-wrap: wrap;
131
- }
132
- .upload-btn {
133
- position: relative;
134
- display: inline-flex;
135
- cursor: pointer;
136
- }
137
- .upload-input {
138
- position: absolute;
139
- width: 0;
140
- height: 0;
141
- opacity: 0;
142
- pointer-events: none;
143
- }
144
- .hint {
145
- font-size: 13px;
146
- color: #909399;
147
- }
148
- .lib-grid {
149
- display: grid;
150
- grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
151
- gap: 12px;
152
- }
153
- .lib-cell {
154
- border: 1px solid #ebeef5;
155
- border-radius: 8px;
156
- padding: 10px;
157
- }
158
- .thumb {
159
- width: 100%;
160
- height: 120px;
161
- object-fit: contain;
162
- background: #f5f7fa;
163
- border-radius: 6px;
164
- }
165
- .meta {
166
- font-size: 13px;
167
- margin-top: 8px;
168
- overflow: hidden;
169
- text-overflow: ellipsis;
170
- white-space: nowrap;
171
- }
172
- .sub {
173
- font-size: 12px;
174
- color: #909399;
175
- margin: 4px 0 8px;
176
- }
177
- .pager {
178
- margin-top: 16px;
179
- display: flex;
180
- justify-content: flex-end;
181
- }
182
- </style>
@@ -1,53 +0,0 @@
1
- import { ref, watch, onUnmounted, nextTick } from 'vue'
2
-
3
- /** 测量容器高度供 qiu-table 的 `height` 使用,使表格占满剩余区域。
4
- * 使用 ResizeObserver(宿主为表格外层 div,非表格根节点)+ window resize,避免仅靠窗口尺寸遗漏侧栏折叠等变化。 */
5
- export function useTableHostHeight(minHeight = 160) {
6
- const hostRef = ref<HTMLElement | null>(null)
7
- const tableHeight = ref(Math.max(minHeight, 200))
8
- let raf = 0
9
- let ro: ResizeObserver | null = null
10
- let removeWindowListener: (() => void) | null = null
11
-
12
- const measure = () => {
13
- const el = hostRef.value
14
- if (!el) return
15
- cancelAnimationFrame(raf)
16
- raf = requestAnimationFrame(() => {
17
- const h = Math.floor(el.getBoundingClientRect().height)
18
- const next = Math.max(minHeight, h)
19
- if (Math.abs(next - tableHeight.value) > 1) {
20
- tableHeight.value = next
21
- }
22
- })
23
- }
24
-
25
- const cleanup = () => {
26
- removeWindowListener?.()
27
- removeWindowListener = null
28
- ro?.disconnect()
29
- ro = null
30
- }
31
-
32
- watch(
33
- hostRef,
34
- (el) => {
35
- cleanup()
36
- if (!el) return
37
- nextTick(() => measure())
38
- const onWinResize = () => measure()
39
- window.addEventListener('resize', onWinResize, { passive: true })
40
- removeWindowListener = () => window.removeEventListener('resize', onWinResize)
41
- ro = new ResizeObserver(() => measure())
42
- ro.observe(el)
43
- },
44
- { flush: 'post' }
45
- )
46
-
47
- onUnmounted(() => {
48
- cleanup()
49
- cancelAnimationFrame(raf)
50
- })
51
-
52
- return { hostRef, tableHeight, recalcTableHeight: measure }
53
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * QiuBadge — 证件 / 桌签制作插件
3
- * 源码迁自 zhihui web-admin + shared,先落地再调。
4
- */
5
- /** 编辑器真源在 QiuCanvasKit;此入口保持兼容 */
6
- export { default as QiuBadgeTemplateEditor } from '../QiuCanvasKit/QiuCanvasEditor.vue'
7
- export { default as QiuBadgeTemplateList } from './views/BadgeTemplateListView.vue'
8
- export { default as QiuBadgeManage } from './views/BadgeManageView.vue'
9
- export { default as QiuBadgeLibrary } from './views/BadgeLibraryView.vue'
10
- export { default as QiuDeskLabel } from './views/DeskLabelView.vue'
11
- export { default as QiuDeskLabelTemplateList } from './views/DeskLabelTemplateListView.vue'
12
- export { default as QiuBadgeTemplateRenderer } from './shared/BadgeTemplateRenderer.vue'
13
- export { default as QiuBadgeImagePickerDialog } from './components/BadgeImagePickerDialog.vue'
14
- export { default as QiuBadgeLibraryManagerDialog } from './components/BadgeLibraryManagerDialog.vue'
15
- export { default as QiuBadgeLibraryPanel } from './components/BadgeLibraryPanel.vue'
16
- export * from './shared/badgeTemplate'
17
- export * from './shared/assetUrl'
18
- export * as QiuBadgeApi from './api/index'
@@ -1,32 +0,0 @@
1
- <script setup lang="ts">
2
- /**
3
- * 兼容旧名:委托 QiuCanvasRenderer
4
- * @author qiuye
5
- * @email yjk150@qq.com
6
- * @date 2026-08-16
7
- */
8
- import QiuCanvasRenderer from '../../QiuCanvasKit/QiuCanvasRenderer.vue'
9
- import type { BadgeTemplateDoc } from './badgeTemplate'
10
- import type { MergeContext } from '../../QiuCanvasKit/types'
11
-
12
- defineOptions({ name: 'QiuBadgeTemplateRenderer' })
13
-
14
- withDefaults(
15
- defineProps<{
16
- doc: BadgeTemplateDoc | null
17
- mergeData?: MergeContext | Record<string, string>
18
- screenScale?: number
19
- enableLinks?: boolean
20
- }>(),
21
- { screenScale: 1, mergeData: () => ({}), enableLinks: false }
22
- )
23
- </script>
24
-
25
- <template>
26
- <QiuCanvasRenderer
27
- :doc="(doc as any)"
28
- :merge-data="mergeData"
29
- :screen-scale="screenScale"
30
- :enable-links="enableLinks"
31
- />
32
- </template>
@@ -1,26 +0,0 @@
1
- export function resolveAssetUrl(src: string | null | undefined): string {
2
- const value = String(src || '').trim()
3
- if (!value) return ''
4
- if (/^data:/i.test(value) || /^blob:/i.test(value)) return value
5
- if (/^(https?:)?\/\//i.test(value)) {
6
- try {
7
- const parsed = new URL(value, window.location.origin)
8
- if (parsed.pathname.startsWith('/uploads/')) {
9
- // Always prefer same-origin uploads path so html2canvas/jsPDF can render images
10
- // without being blocked by cross-origin resource restrictions in production.
11
- return `${parsed.pathname}${parsed.search}${parsed.hash}`
12
- }
13
- } catch {}
14
- return value
15
- }
16
- if (value.startsWith('/uploads/')) {
17
- return value
18
- }
19
-
20
- const raw = import.meta.env.VITE_API_BASE_URL
21
- const apiBase = typeof raw === 'string' ? raw.trim().replace(/\/$/, '') : ''
22
- if (!apiBase) return value.startsWith('/') ? value : `/${value}`
23
-
24
- const staticBase = apiBase.replace(/\/api$/i, '')
25
- return `${staticBase}${value.startsWith('/') ? value : `/${value}`}`
26
- }