@peng_kai/kit 0.3.0-beta.32 → 0.3.0-beta.34

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.
@@ -1,2 +1,2 @@
1
1
  export { default as Settings } from './src/Settings.vue';
2
- export { default as SchemaForm, type IConfigDetail } from './src/SchemaForm.vue';
2
+ export { default as SchemaForm, type IConfigDetail, FormTypes } from './src/SchemaForm.vue';
@@ -4,6 +4,7 @@ import { CheckboxGroup, DatePicker, type DatePickerProps, Form, FormItem, Input,
4
4
  import { computed, toRef } from 'vue';
5
5
  import dayjs from '../../../../libs/dayjs';
6
6
  import { type ItemSchema, useAntdForm } from '../../../../antd';
7
+ import { PictureCardUpload } from '../../../components/upload';
7
8
 
8
9
  export interface IConfigDetail {
9
10
  category_id: number
@@ -19,7 +20,7 @@ export interface IConfigDetail {
19
20
  value: any
20
21
  }
21
22
 
22
- enum FormTypes {
23
+ export enum FormTypes {
23
24
  /** 数字输入框 */
24
25
  NUMBER_INPUT = 0,
25
26
  /** 文本输入框 */
@@ -36,6 +37,8 @@ enum FormTypes {
36
37
  SINGLE_SELECT = 6,
37
38
  /** 多选下拉选择器 */
38
39
  MULTIPLE_SELECT = 7,
40
+ /** 图片上传 */
41
+ IMAGE_UPLOAD = 8,
39
42
  /** 单一日期选择器 */
40
43
  SINGLE_DATE_PICKER = 13,
41
44
  /** 日期范围选择器 */
@@ -81,6 +84,10 @@ const antdPropsResolvers: Record<number, (config: IConfigDetail) => IConfigDetai
81
84
  [FormTypes.MULTIPLE_SELECT](config) {
82
85
  return this[FormTypes.CHECKBOX](config);
83
86
  },
87
+ [FormTypes.IMAGE_UPLOAD](config) {
88
+ config.value = config.value.split(',');
89
+ return config;
90
+ },
84
91
  [FormTypes.SINGLE_DATE_PICKER](config) {
85
92
  const props: DatePickerProps = {};
86
93
 
@@ -130,9 +137,11 @@ const antdValueResolvers: Record<number, (value: any) => any> = {
130
137
  [FormTypes.MULTIPLE_SELECT](value) {
131
138
  if (Array.isArray(value))
132
139
  return value.join(',');
133
-
134
140
  return value;
135
141
  },
142
+ [FormTypes.IMAGE_UPLOAD](value) {
143
+ return value.join(',');
144
+ },
136
145
  [FormTypes.SINGLE_DATE_PICKER](value) {
137
146
  if (dayjs.isDayjs(value))
138
147
  return value.format('YYYY-MM-DD');
@@ -151,9 +160,11 @@ const antdValueResolvers: Record<number, (value: any) => any> = {
151
160
  <script setup lang="ts">
152
161
  const props = withDefaults(defineProps<{
153
162
  formConfig: IConfigDetail[]
163
+ formsOptions?: Partial<Record<FormTypes, any>>;
154
164
  disabled?: boolean
155
165
  }>(), {
156
166
  disabled: false,
167
+ formsOptions: () => ({} as any),
157
168
  });
158
169
 
159
170
  const configList = computed(() => {
@@ -268,6 +279,10 @@ defineExpose({ reset, validate });
268
279
  <Select v-model:value="settingForm.state[item.key]" v-bind="item.options" mode="multiple" />
269
280
  </slot>
270
281
 
282
+ <slot v-else-if="item.form_type === FormTypes.IMAGE_UPLOAD" :name="FormTypes.IMAGE_UPLOAD">
283
+ <PictureCardUpload v-model:urls="settingForm.state[item.key]" useUrl v-bind="{ ...formsOptions[item.form_type], ...item.options}" />
284
+ </slot>
285
+
271
286
  <slot v-else-if="item.form_type === FormTypes.SINGLE_DATE_PICKER" :name="FormTypes.SINGLE_DATE_PICKER">
272
287
  <DatePicker v-model:value="settingForm.state[item.key]" v-bind="item.options" />
273
288
  </slot>
@@ -2,10 +2,10 @@
2
2
  import { Image as AImage, ImagePreviewGroup as AImagePreviewGroup, Upload as AUpload, message } from 'ant-design-vue';
3
3
  import type { UploadProps } from 'ant-design-vue';
4
4
  import type { PreviewGroupPreview } from 'ant-design-vue/es/vc-image/src/PreviewGroup';
5
- import { useVModel } from '@vueuse/core';
6
- import { ref } from 'vue';
5
+ import { ref, customRef, nextTick, triggerRef } from 'vue';
7
6
  import type { AwsS3 } from '../../../../utils/upload';
8
7
  import { createAwsS3Request } from './customRequests';
8
+ import { urlToUploadFile } from './helpers';
9
9
 
10
10
  type UploadFile = Parameters<NonNullable<UploadProps['onPreview']>>['0'];
11
11
  </script>
@@ -13,8 +13,12 @@ type UploadFile = Parameters<NonNullable<UploadProps['onPreview']>>['0'];
13
13
  <script lang="ts" setup>
14
14
  const props = withDefaults(
15
15
  defineProps<{
16
- /** 上传文件的数组 */
16
+ /** 上传图片的数组 */
17
17
  modelValue?: UploadFile[]
18
+ /** 上传图片的 url 数组 */
19
+ urls?: string[]
20
+ /** 是否使用 url 数组 */
21
+ useUrl?: boolean
18
22
  /** awsS3 实例对象 */
19
23
  awsS3: AwsS3
20
24
  /** 根目录 */
@@ -27,6 +31,8 @@ const props = withDefaults(
27
31
  cardSize?: string
28
32
  /** 允许的图片后缀 */
29
33
  allowExts?: string[]
34
+ /** 允许的图片大小,单位为字节 */
35
+ maxSize?: number
30
36
  /** 禁用 */
31
37
  disabled?: boolean
32
38
  }>(),
@@ -36,14 +42,47 @@ const props = withDefaults(
36
42
  rowCount: 'auto-fill',
37
43
  cardSize: '90px',
38
44
  allowExts: () => ['jpg', 'jpeg', 'png', 'gif', 'apng', 'webp', 'svg'],
45
+ maxSize: 1024 * 1024 * 2,
39
46
  disabled: false,
47
+ useUrl: false,
40
48
  },
41
49
  );
42
50
  const emits = defineEmits<{
43
51
  (e: 'update:modelValue', value: UploadFile[]): void
52
+ (e: 'update:urls', value: string[]): void
44
53
  }>();
45
54
 
46
- const fileList = useVModel(props, 'modelValue', emits);
55
+ const fileList = customRef<any>((track, trigger) => {
56
+ let tempValue: any[] = [];
57
+ let isAllDone = true;
58
+ return {
59
+ get() {
60
+ track();
61
+ if (props.useUrl) {
62
+ return isAllDone ? urlToUploadFile(props.urls || []) : tempValue;
63
+ }
64
+ return props.modelValue || [];
65
+ },
66
+ set(v: any) {
67
+ if (props.useUrl) {
68
+ isAllDone = (v || []).every((x: any) => typeof x === 'string' || x.status === 'done');
69
+ if (isAllDone) {
70
+ const urls = (v || []).map((x: any) => typeof x === 'string' ? x : x.response?.url);
71
+ emits('update:urls', urls);
72
+ tempValue = [];
73
+ }
74
+ else {
75
+ tempValue = v;
76
+ }
77
+ }
78
+ else {
79
+ emits('update:modelValue', v);
80
+ }
81
+ trigger();
82
+ }
83
+ }
84
+ })
85
+
47
86
  const preview = ref<PreviewGroupPreview>({
48
87
  visible: false,
49
88
  onVisibleChange(value) {
@@ -54,36 +93,33 @@ const preview = ref<PreviewGroupPreview>({
54
93
  function handlePreview(file: UploadFile) {
55
94
  preview.value.src = file.url || file.thumbUrl;
56
95
  preview.value.visible = true;
57
- preview.value.current = fileList.value?.findIndex(item => preview.value.src === (item.url || item.thumbUrl)) ?? 0;
96
+ preview.value.current = fileList.value?.findIndex((x: any) => preview.value.src === (x.url || x.thumbUrl)) ?? 0;
58
97
  }
59
98
 
60
99
  function beforeUpload(file: UploadFile) {
61
100
  const isImg = props.allowExts.some(item => String(file.type).toLowerCase().includes(item));
62
-
101
+ const isSizeValid = !!(props.maxSize && file.size && file.size <= props.maxSize);
63
102
  if (!isImg)
64
103
  message.error(`${file.name} 不是图片 (${props.allowExts.join(',')})`);
65
-
66
- return isImg;
104
+ if (!isSizeValid)
105
+ message.error(`${file.name} 大小不能超过 ${props.maxSize / 1024 / 1024}MB`);
106
+
107
+ return isImg && isSizeValid;
67
108
  }
68
109
  </script>
69
110
 
70
111
  <template>
71
112
  <div :class="{ 'w-fit': typeof props.rowCount === 'number' }">
72
- <AUpload
73
- v-model:fileList="fileList" class="pic-card-upload" listType="picture-card" multiple :maxCount="$props.maxCount"
74
- :disabled="props.disabled" :beforeUpload="beforeUpload" :customRequest="createAwsS3Request($props.awsS3, $props.rootDir)"
75
- @preview="handlePreview"
76
- >
77
- <i v-if="fileList.length < props.maxCount" class="i-ant-design:plus-outlined text-26px text-$antd-colorTextTertiary" />
113
+ <AUpload v-model:fileList="fileList" class="pic-card-upload" listType="picture-card" multiple
114
+ :maxCount="$props.maxCount" :disabled="props.disabled" :beforeUpload="beforeUpload"
115
+ :customRequest="createAwsS3Request($props.awsS3, $props.rootDir)" @preview="handlePreview">
116
+ <i v-if="fileList.length < props.maxCount"
117
+ class="i-ant-design:plus-outlined text-[26px] text-$antd-colorTextTertiary" />
78
118
  </AUpload>
79
119
 
80
120
  <div style="display: none">
81
121
  <AImagePreviewGroup :preview="preview">
82
- <AImage
83
- v-for="item of fileList"
84
- :key="item.uid"
85
- :src="item.url || item.thumbUrl"
86
- />
122
+ <AImage v-for="item of fileList" :key="item.uid" :src="item.url || item.thumbUrl" />
87
123
  </AImagePreviewGroup>
88
124
  </div>
89
125
  </div>
@@ -117,7 +153,7 @@ function beforeUpload(file: UploadFile) {
117
153
  margin: 0;
118
154
  }
119
155
 
120
- :deep(.ant-upload-list.ant-upload-list-picture-card .ant-upload-list-item::before ) {
156
+ :deep(.ant-upload-list.ant-upload-list-picture-card .ant-upload-list-item::before) {
121
157
  width: 100%;
122
158
  height: 100%;
123
159
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@peng_kai/kit",
3
3
  "type": "module",
4
- "version": "0.3.0-beta.32",
4
+ "version": "0.3.0-beta.34",
5
5
  "description": "",
6
6
  "author": "",
7
7
  "license": "ISC",