فهرست منبع

feat: add fieldMapToTime prop to FormRenderProps (#4838)

huangxiaomin 6 ماه پیش
والد
کامیت
6b9acf09dc

+ 74 - 2
packages/@core/ui-kit/form-ui/src/components/form-actions.vue

@@ -52,20 +52,92 @@ async function handleSubmit(e: Event) {
   if (!valid) {
     return;
   }
-  await unref(rootProps).handleSubmit?.(toRaw(form.values));
+
+  const values = handleRangeTimeValue(toRaw(form.values));
+  await unref(rootProps).handleSubmit?.(values);
 }
 
 async function handleReset(e: Event) {
   e?.preventDefault();
   e?.stopPropagation();
   const props = unref(rootProps);
+
+  const values = toRaw(form.values);
+  // 清理时间字段
+  props.fieldMapToTime &&
+    props.fieldMapToTime.forEach(([_, [startTimeKey, endTimeKey]]) => {
+      delete values[startTimeKey];
+      delete values[endTimeKey];
+    });
+
   if (isFunction(props.handleReset)) {
-    await props.handleReset?.(form.values);
+    await props.handleReset?.(values);
   } else {
     form.resetForm();
   }
 }
 
+function handleRangeTimeValue(values: Record<string, any>) {
+  const fieldMapToTime = unref(rootProps).fieldMapToTime;
+
+  if (!fieldMapToTime) return values;
+
+  if (!Array.isArray(fieldMapToTime)) {
+    return values;
+  }
+
+  fieldMapToTime.forEach(
+    ([field, [startTimeKey, endTimeKey], format = 'YYYY-MM-DD']) => {
+      if (!values[field]) {
+        delete values[field];
+        return;
+      }
+
+      const [startTime, endTime] = values[field];
+      const [startTimeFormat, endTimeFormat] = Array.isArray(format)
+        ? format
+        : [format, format];
+
+      values[startTimeKey] = startTime
+        ? formatTime(startTime, startTimeFormat)
+        : undefined;
+      values[endTimeKey] = endTime
+        ? formatTime(endTime, endTimeFormat)
+        : undefined;
+
+      delete values[field];
+    },
+  );
+
+  return values;
+}
+
+function formatTime(time: string, format: string): number | string {
+  const date = new Date(time);
+  const timestamp = (date: Date) => Math.floor(date.getTime() / 1000);
+
+  if (format === 'timestamp') return timestamp(date);
+  if (format === 'timestampStartDay')
+    return timestamp(
+      new Date(date.getFullYear(), date.getMonth(), date.getDate()),
+    );
+
+  const padZero = (num: number) => num.toString().padStart(2, '0');
+  const replacements: Record<string, string> = {
+    DD: padZero(date.getDate()),
+    HH: padZero(date.getHours()),
+    MM: padZero(date.getMonth() + 1),
+    mm: padZero(date.getMinutes()),
+    ss: padZero(date.getSeconds()),
+    YYYY: date.getFullYear().toString(),
+  };
+
+  return format.replaceAll(
+    /YYYY|MM|DD|HH|mm|ss/g,
+    (match) => replacements[match] || match,
+  );
+}
+
 watch(
   () => collapsed.value,
   () => {

+ 10 - 0
packages/@core/ui-kit/form-ui/src/types.ts

@@ -206,6 +206,12 @@ export type HandleResetFn = (
   values: Record<string, any>,
 ) => Promise<void> | void;
 
+export type FieldMapToTime = [
+  string,
+  [string, string],
+  ([string, string] | string)?,
+][];
+
 export interface FormSchema<
   T extends BaseFormComponentType = BaseFormComponentType,
 > extends FormCommonConfig {
@@ -266,6 +272,10 @@ export interface FormRenderProps<
    * 组件集合
    */
   componentMap: Record<BaseFormComponentType, Component>;
+  /**
+   * 表单字段映射成时间格式
+   */
+  fieldMapToTime?: FieldMapToTime;
   /**
    * 表单实例
    */

+ 6 - 0
playground/src/views/examples/vxe-table/form.vue

@@ -21,6 +21,7 @@ interface RowType {
 const formOptions: VbenFormProps = {
   // 默认展开
   collapsed: false,
+  fieldMapToTime: [['dateRangePicker', ['startTime', 'endTime'], 'YYYY-MM']],
   schema: [
     {
       component: 'Input',
@@ -62,6 +63,11 @@ const formOptions: VbenFormProps = {
       fieldName: 'datePicker',
       label: 'Date',
     },
+    {
+      component: 'RangePicker',
+      fieldName: 'dateRangePicker',
+      label: 'DateRange',
+    },
   ],
   // 控制表单是否显示折叠按钮
   showCollapseButton: true,