@tmagic/form 1.7.0-beta.4 → 1.7.0

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/dist/style.css CHANGED
@@ -269,6 +269,9 @@ fieldset.m-fieldset .m-form-tip {
269
269
  .m-fields-table .el-form-item {
270
270
  margin-bottom: 0;
271
271
  }
272
+ .m-fields-table .tmagic-form-table-drag-target {
273
+ cursor: move;
274
+ }
272
275
 
273
276
  .m-select {
274
277
  width: 100%;
@@ -1,5 +1,5 @@
1
- import { toRaw, defineComponent, createElementBlock, openBlock, createElementVNode, createBlock, createCommentVNode, unref, withCtx, createVNode, inject, ref, computed, watchEffect, watch, resolveComponent, normalizeStyle, normalizeClass, mergeProps, resolveDynamicComponent, Fragment, renderList, createTextVNode, toDisplayString, readonly, withDirectives, vShow, renderSlot, getCurrentInstance, createSlots, onUnmounted, reactive, onBeforeUnmount, vModelText, useTemplateRef, provide, shallowRef, onBeforeMount, nextTick, resolveDirective, withModifiers, Teleport, h } from 'vue';
2
- import { WarningFilled, CaretBottom, CaretRight, Delete, DocumentCopy, CaretTop, Position, Grid, Plus, ArrowUp, ArrowDown, FullScreen } from '@element-plus/icons-vue';
1
+ import { defineComponent, createElementBlock, openBlock, createElementVNode, createBlock, createCommentVNode, unref, withCtx, createVNode, inject, ref, computed, watchEffect, watch, resolveComponent, normalizeStyle, normalizeClass, mergeProps, resolveDynamicComponent, Fragment, renderList, createTextVNode, toDisplayString, toRaw, readonly, withDirectives, vShow, renderSlot, getCurrentInstance, createSlots, onUnmounted, reactive, onBeforeUnmount, vModelText, useTemplateRef, provide, shallowRef, onBeforeMount, nextTick, resolveDirective, withModifiers, Teleport, h } from 'vue';
2
+ import { WarningFilled, CaretBottom, CaretRight, Delete, DocumentCopy, CaretTop, Position, Grid, Plus, Sort, ArrowUp, ArrowDown, FullScreen } from '@element-plus/icons-vue';
3
3
  import { cloneDeep, isEqual, isEmpty, debounce } from 'lodash-es';
4
4
  import { TMagicTooltip, TMagicIcon, TMagicFormItem, TMagicButton, TMagicCheckbox, TMagicCard, TMagicPopover, TMagicInputNumber, TMagicCol, TMagicRow, TMagicSteps, TMagicStep, getDesignConfig, TMagicBadge, TMagicCascader, TMagicCheckboxGroup, TMagicColorPicker, TMagicDatePicker, TMagicForm, TMagicInput, tMagicMessage, tMagicMessageBox, TMagicDialog, TMagicRadioButton, TMagicRadio, TMagicRadioGroup, TMagicSelect, TMagicSwitch, TMagicTimePicker, useZIndex, TMagicTable, TMagicUpload, TMagicPagination, TMagicDrawer, TMagicScrollbar } from '@tmagic/design';
5
5
  import { getValueByKeyPath, setValueByKeyPath, isNumber, asyncLoadJs } from '@tmagic/utils';
@@ -54,12 +54,12 @@ const initValueItem = function(mForm, item, initValue2, value) {
54
54
  return value;
55
55
  }
56
56
  asyncLoadConfig(value, initValue2, item);
57
- if (name && !items && typeof initValue2[name] !== "undefined") {
57
+ if (name && !items && typeof initValue2?.[name] !== "undefined") {
58
58
  if (typeof value[name] === "undefined") {
59
59
  if (type === "number") {
60
60
  value[name] = Number(initValue2[name]);
61
61
  } else {
62
- value[name] = typeof initValue2[name] === "object" ? cloneDeep(initValue2[name]) : initValue2[name];
62
+ value[name] = typeof initValue2[name] === "object" ? initValue2[name] : initValue2[name];
63
63
  }
64
64
  }
65
65
  return value;
@@ -171,12 +171,13 @@ const getRules = function(mForm, rules = [], props) {
171
171
  };
172
172
  const initValue = async (mForm, { initValues, config }) => {
173
173
  if (!Array.isArray(config)) throw new Error("config应该为数组");
174
- let valuesTmp = createValues(mForm, config, toRaw(initValues), {});
174
+ const initValuesCopy = cloneDeep(initValues);
175
+ let valuesTmp = createValues(mForm, config, initValuesCopy, {});
175
176
  const [firstForm] = config;
176
177
  if (firstForm && typeof firstForm.onInitValue === "function") {
177
178
  valuesTmp = await firstForm.onInitValue(mForm, {
178
179
  formValue: valuesTmp,
179
- initValue: initValues
180
+ initValue: initValuesCopy
180
181
  });
181
182
  }
182
183
  return valuesTmp || {};
@@ -185,7 +186,7 @@ const datetimeFormatter = (v, defaultValue = "-", format = "YYYY-MM-DD HH:mm:ss"
185
186
  if (v) {
186
187
  let time;
187
188
  if (["x", "timestamp"].includes(format)) {
188
- time = dayjs(v).valueOf();
189
+ time = dayjs(Number.isNaN(Number(v)) ? v : Number(v)).valueOf();
189
190
  } else if (typeof v === "string" && v.includes("Z") || v.constructor === Date) {
190
191
  dayjs.extend(utc);
191
192
  time = dayjs(v).utcOffset(8).format(format);
@@ -4783,7 +4784,7 @@ const useSelection = (props, emit, tMagicTableRef) => {
4783
4784
  };
4784
4785
  };
4785
4786
 
4786
- const useSortable = (props, emit, tMagicTableRef, modelName) => {
4787
+ const useSortable = (props, emit, tMagicTableRef, modelName, updateKey) => {
4787
4788
  const mForm = inject("mForm");
4788
4789
  let sortable;
4789
4790
  const rowDrop = () => {
@@ -4800,12 +4801,18 @@ const useSortable = (props, emit, tMagicTableRef, modelName) => {
4800
4801
  preventOnFilter: false,
4801
4802
  // 允许选字
4802
4803
  direction: "vertical",
4804
+ handle: props.config.dropSortHandle ? ".tmagic-form-table-drag-target" : void 0,
4803
4805
  onEnd: ({ newIndex, oldIndex }) => {
4804
4806
  if (typeof newIndex === "undefined") return;
4805
4807
  if (typeof oldIndex === "undefined") return;
4806
4808
  const newData = sortArray(props.model[modelName.value], newIndex, oldIndex, props.sortKey);
4807
4809
  emit("change", newData);
4808
4810
  mForm?.$emit("field-change", newData);
4811
+ nextTick(() => {
4812
+ sortable?.destroy();
4813
+ sortable = void 0;
4814
+ updateKey.value += 1;
4815
+ });
4809
4816
  }
4810
4817
  });
4811
4818
  };
@@ -4884,23 +4891,39 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
4884
4891
  renderSlot(_ctx.$slots, "operateCol", {
4885
4892
  scope: { $index: __props.index, row: __props.row }
4886
4893
  }),
4894
+ __props.config.dropSort && __props.config.dropSortHandle ? (openBlock(), createBlock(unref(TMagicTooltip), {
4895
+ key: 0,
4896
+ content: "拖动排序",
4897
+ placement: "left-start"
4898
+ }, {
4899
+ default: withCtx(() => [
4900
+ createVNode(unref(TMagicButton), {
4901
+ size: "small",
4902
+ link: "",
4903
+ class: normalizeClass({ "tmagic-form-table-drag-target": __props.config.dropSortHandle }),
4904
+ icon: __props.config.dropActionButtonIcon || unref(Sort)
4905
+ }, null, 8, ["class", "icon"])
4906
+ ]),
4907
+ _: 1
4908
+ /* STABLE */
4909
+ })) : createCommentVNode("v-if", true),
4887
4910
  withDirectives(createVNode(unref(TMagicButton), {
4888
4911
  size: "small",
4889
4912
  type: "danger",
4890
4913
  link: "",
4891
4914
  title: "删除",
4892
- icon: unref(Delete),
4915
+ icon: __props.config.deleteActionButtonIcon || unref(Delete),
4893
4916
  onClick: _cache[0] || (_cache[0] = ($event) => removeHandler(__props.index + 1 + __props.currentPage * __props.pageSize - 1))
4894
4917
  }, null, 8, ["icon"]), [
4895
4918
  [vShow, showDelete(__props.index + 1 + __props.currentPage * __props.pageSize - 1)]
4896
4919
  ]),
4897
4920
  copyable(__props.index + 1 + __props.currentPage * __props.pageSize - 1) ? (openBlock(), createBlock(unref(TMagicButton), {
4898
- key: 0,
4921
+ key: 1,
4899
4922
  link: "",
4900
4923
  size: "small",
4901
4924
  type: "primary",
4902
4925
  title: "复制",
4903
- icon: unref(DocumentCopy),
4926
+ icon: __props.config.copyActionButtonIcon || unref(DocumentCopy),
4904
4927
  disabled: __props.disabled,
4905
4928
  onClick: _cache[1] || (_cache[1] = ($event) => copyHandler(__props.index + 1 + __props.currentPage * __props.pageSize - 1))
4906
4929
  }, null, 8, ["icon", "disabled"])) : createCommentVNode("v-if", true)
@@ -5087,11 +5110,11 @@ const useTableColumns = (props, emit, currentPage, pageSize, modelName) => {
5087
5110
  if (typeof props.config.fixed === "string" && ["left", "right"].includes(props.config.fixed)) {
5088
5111
  actionFixed = props.config.fixed;
5089
5112
  }
5090
- const actionClumn = {
5113
+ const actionColumn = {
5091
5114
  props: {
5092
5115
  label: "操作",
5093
5116
  fixed: actionFixed,
5094
- width: props.config.operateColWidth || 112,
5117
+ width: props.config.operateColWidth ?? (props.config.dropSortHandle && props.config.dropSort ? 132 : 112),
5095
5118
  align: "center"
5096
5119
  },
5097
5120
  cell: ({ row, $index }) => h(_sfc_main$4, {
@@ -5111,7 +5134,7 @@ const useTableColumns = (props, emit, currentPage, pageSize, modelName) => {
5111
5134
  })
5112
5135
  };
5113
5136
  if (actionFixed !== "right") {
5114
- columns2.push(actionClumn);
5137
+ columns2.push(actionColumn);
5115
5138
  }
5116
5139
  if (props.sort && props.model[modelName.value] && props.model[modelName.value].length > 1) {
5117
5140
  columns2.push({
@@ -5202,7 +5225,7 @@ const useTableColumns = (props, emit, currentPage, pageSize, modelName) => {
5202
5225
  }
5203
5226
  }
5204
5227
  if (actionFixed === "right") {
5205
- columns2.push(actionClumn);
5228
+ columns2.push(actionColumn);
5206
5229
  }
5207
5230
  return columns2;
5208
5231
  });
@@ -5251,13 +5274,13 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
5251
5274
  modelName
5252
5275
  );
5253
5276
  const { nextZIndex } = useZIndex();
5277
+ const updateKey = ref(1);
5254
5278
  const { addable, newHandler } = useAdd(props, emit);
5255
5279
  const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
5256
- useSortable(props, emit, tMagicTableRef, modelName);
5280
+ useSortable(props, emit, tMagicTableRef, modelName, updateKey);
5257
5281
  const { isFullscreen, toggleFullscreen } = useFullscreen();
5258
5282
  const { importable, excelHandler, clearHandler } = useImport(props, emit, newHandler);
5259
5283
  const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
5260
- const updateKey = ref(1);
5261
5284
  const data = computed(() => props.config.pagination ? paginationData.value : props.model[modelName.value]);
5262
5285
  const toggleMode = () => {
5263
5286
  const calcLabelWidth = (label) => {
@@ -5313,7 +5336,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
5313
5336
  createVNode(unref(TMagicTooltip), {
5314
5337
  content: "拖拽可排序",
5315
5338
  placement: "left-start",
5316
- disabled: __props.config.dropSort !== true
5339
+ disabled: __props.config.dropSort !== true || __props.config.dropSortHandle
5317
5340
  }, {
5318
5341
  default: withCtx(() => [
5319
5342
  __props.model[modelName.value] ? (openBlock(), createBlock(unref(TMagicTable), {
@@ -2984,12 +2984,12 @@
2984
2984
  return value;
2985
2985
  }
2986
2986
  asyncLoadConfig(value, initValue2, item);
2987
- if (name && !items && typeof initValue2[name] !== "undefined") {
2987
+ if (name && !items && typeof initValue2?.[name] !== "undefined") {
2988
2988
  if (typeof value[name] === "undefined") {
2989
2989
  if (type === "number") {
2990
2990
  value[name] = Number(initValue2[name]);
2991
2991
  } else {
2992
- value[name] = typeof initValue2[name] === "object" ? cloneDeep(initValue2[name]) : initValue2[name];
2992
+ value[name] = typeof initValue2[name] === "object" ? initValue2[name] : initValue2[name];
2993
2993
  }
2994
2994
  }
2995
2995
  return value;
@@ -3101,12 +3101,13 @@
3101
3101
  };
3102
3102
  const initValue = async (mForm, { initValues, config }) => {
3103
3103
  if (!Array.isArray(config)) throw new Error("config应该为数组");
3104
- let valuesTmp = createValues(mForm, config, vue.toRaw(initValues), {});
3104
+ const initValuesCopy = cloneDeep(initValues);
3105
+ let valuesTmp = createValues(mForm, config, initValuesCopy, {});
3105
3106
  const [firstForm] = config;
3106
3107
  if (firstForm && typeof firstForm.onInitValue === "function") {
3107
3108
  valuesTmp = await firstForm.onInitValue(mForm, {
3108
3109
  formValue: valuesTmp,
3109
- initValue: initValues
3110
+ initValue: initValuesCopy
3110
3111
  });
3111
3112
  }
3112
3113
  return valuesTmp || {};
@@ -3115,7 +3116,7 @@
3115
3116
  if (v) {
3116
3117
  let time;
3117
3118
  if (["x", "timestamp"].includes(format)) {
3118
- time = dayjs(v).valueOf();
3119
+ time = dayjs(Number.isNaN(Number(v)) ? v : Number(v)).valueOf();
3119
3120
  } else if (typeof v === "string" && v.includes("Z") || v.constructor === Date) {
3120
3121
  dayjs.extend(utc);
3121
3122
  time = dayjs(v).utcOffset(8).format(format);
@@ -7713,7 +7714,7 @@
7713
7714
  };
7714
7715
  };
7715
7716
 
7716
- const useSortable = (props, emit, tMagicTableRef, modelName) => {
7717
+ const useSortable = (props, emit, tMagicTableRef, modelName, updateKey) => {
7717
7718
  const mForm = vue.inject("mForm");
7718
7719
  let sortable;
7719
7720
  const rowDrop = () => {
@@ -7730,12 +7731,18 @@
7730
7731
  preventOnFilter: false,
7731
7732
  // 允许选字
7732
7733
  direction: "vertical",
7734
+ handle: props.config.dropSortHandle ? ".tmagic-form-table-drag-target" : void 0,
7733
7735
  onEnd: ({ newIndex, oldIndex }) => {
7734
7736
  if (typeof newIndex === "undefined") return;
7735
7737
  if (typeof oldIndex === "undefined") return;
7736
7738
  const newData = sortArray(props.model[modelName.value], newIndex, oldIndex, props.sortKey);
7737
7739
  emit("change", newData);
7738
7740
  mForm?.$emit("field-change", newData);
7741
+ vue.nextTick(() => {
7742
+ sortable?.destroy();
7743
+ sortable = void 0;
7744
+ updateKey.value += 1;
7745
+ });
7739
7746
  }
7740
7747
  });
7741
7748
  };
@@ -7814,23 +7821,39 @@
7814
7821
  vue.renderSlot(_ctx.$slots, "operateCol", {
7815
7822
  scope: { $index: __props.index, row: __props.row }
7816
7823
  }),
7824
+ __props.config.dropSort && __props.config.dropSortHandle ? (vue.openBlock(), vue.createBlock(vue.unref(design.TMagicTooltip), {
7825
+ key: 0,
7826
+ content: "拖动排序",
7827
+ placement: "left-start"
7828
+ }, {
7829
+ default: vue.withCtx(() => [
7830
+ vue.createVNode(vue.unref(design.TMagicButton), {
7831
+ size: "small",
7832
+ link: "",
7833
+ class: vue.normalizeClass({ "tmagic-form-table-drag-target": __props.config.dropSortHandle }),
7834
+ icon: __props.config.dropActionButtonIcon || vue.unref(iconsVue.Sort)
7835
+ }, null, 8, ["class", "icon"])
7836
+ ]),
7837
+ _: 1
7838
+ /* STABLE */
7839
+ })) : vue.createCommentVNode("v-if", true),
7817
7840
  vue.withDirectives(vue.createVNode(vue.unref(design.TMagicButton), {
7818
7841
  size: "small",
7819
7842
  type: "danger",
7820
7843
  link: "",
7821
7844
  title: "删除",
7822
- icon: vue.unref(iconsVue.Delete),
7845
+ icon: __props.config.deleteActionButtonIcon || vue.unref(iconsVue.Delete),
7823
7846
  onClick: _cache[0] || (_cache[0] = ($event) => removeHandler(__props.index + 1 + __props.currentPage * __props.pageSize - 1))
7824
7847
  }, null, 8, ["icon"]), [
7825
7848
  [vue.vShow, showDelete(__props.index + 1 + __props.currentPage * __props.pageSize - 1)]
7826
7849
  ]),
7827
7850
  copyable(__props.index + 1 + __props.currentPage * __props.pageSize - 1) ? (vue.openBlock(), vue.createBlock(vue.unref(design.TMagicButton), {
7828
- key: 0,
7851
+ key: 1,
7829
7852
  link: "",
7830
7853
  size: "small",
7831
7854
  type: "primary",
7832
7855
  title: "复制",
7833
- icon: vue.unref(iconsVue.DocumentCopy),
7856
+ icon: __props.config.copyActionButtonIcon || vue.unref(iconsVue.DocumentCopy),
7834
7857
  disabled: __props.disabled,
7835
7858
  onClick: _cache[1] || (_cache[1] = ($event) => copyHandler(__props.index + 1 + __props.currentPage * __props.pageSize - 1))
7836
7859
  }, null, 8, ["icon", "disabled"])) : vue.createCommentVNode("v-if", true)
@@ -8017,11 +8040,11 @@
8017
8040
  if (typeof props.config.fixed === "string" && ["left", "right"].includes(props.config.fixed)) {
8018
8041
  actionFixed = props.config.fixed;
8019
8042
  }
8020
- const actionClumn = {
8043
+ const actionColumn = {
8021
8044
  props: {
8022
8045
  label: "操作",
8023
8046
  fixed: actionFixed,
8024
- width: props.config.operateColWidth || 112,
8047
+ width: props.config.operateColWidth ?? (props.config.dropSortHandle && props.config.dropSort ? 132 : 112),
8025
8048
  align: "center"
8026
8049
  },
8027
8050
  cell: ({ row, $index }) => vue.h(_sfc_main$4, {
@@ -8041,7 +8064,7 @@
8041
8064
  })
8042
8065
  };
8043
8066
  if (actionFixed !== "right") {
8044
- columns2.push(actionClumn);
8067
+ columns2.push(actionColumn);
8045
8068
  }
8046
8069
  if (props.sort && props.model[modelName.value] && props.model[modelName.value].length > 1) {
8047
8070
  columns2.push({
@@ -8132,7 +8155,7 @@
8132
8155
  }
8133
8156
  }
8134
8157
  if (actionFixed === "right") {
8135
- columns2.push(actionClumn);
8158
+ columns2.push(actionColumn);
8136
8159
  }
8137
8160
  return columns2;
8138
8161
  });
@@ -8181,13 +8204,13 @@
8181
8204
  modelName
8182
8205
  );
8183
8206
  const { nextZIndex } = design.useZIndex();
8207
+ const updateKey = vue.ref(1);
8184
8208
  const { addable, newHandler } = useAdd(props, emit);
8185
8209
  const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
8186
- useSortable(props, emit, tMagicTableRef, modelName);
8210
+ useSortable(props, emit, tMagicTableRef, modelName, updateKey);
8187
8211
  const { isFullscreen, toggleFullscreen } = useFullscreen();
8188
8212
  const { importable, excelHandler, clearHandler } = useImport(props, emit, newHandler);
8189
8213
  const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
8190
- const updateKey = vue.ref(1);
8191
8214
  const data = vue.computed(() => props.config.pagination ? paginationData.value : props.model[modelName.value]);
8192
8215
  const toggleMode = () => {
8193
8216
  const calcLabelWidth = (label) => {
@@ -8243,7 +8266,7 @@
8243
8266
  vue.createVNode(vue.unref(design.TMagicTooltip), {
8244
8267
  content: "拖拽可排序",
8245
8268
  placement: "left-start",
8246
- disabled: __props.config.dropSort !== true
8269
+ disabled: __props.config.dropSort !== true || __props.config.dropSortHandle
8247
8270
  }, {
8248
8271
  default: vue.withCtx(() => [
8249
8272
  __props.model[modelName.value] ? (vue.openBlock(), vue.createBlock(vue.unref(design.TMagicTable), {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.7.0-beta.4",
2
+ "version": "1.7.0",
3
3
  "name": "@tmagic/form",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -51,9 +51,9 @@
51
51
  "peerDependencies": {
52
52
  "vue": "^3.5.24",
53
53
  "typescript": "^5.9.3",
54
- "@tmagic/design": "1.7.0-beta.4",
55
- "@tmagic/utils": "1.7.0-beta.4",
56
- "@tmagic/form-schema": "1.7.0-beta.4"
54
+ "@tmagic/design": "1.7.0",
55
+ "@tmagic/form-schema": "1.7.0",
56
+ "@tmagic/utils": "1.7.0"
57
57
  },
58
58
  "peerDependenciesMeta": {
59
59
  "typescript": {
@@ -1,12 +1,21 @@
1
1
  <template>
2
2
  <slot name="operateCol" :scope="{ $index: index, row: row }"></slot>
3
+ <TMagicTooltip v-if="config.dropSort && config.dropSortHandle" content="拖动排序" placement="left-start">
4
+ <TMagicButton
5
+ size="small"
6
+ link
7
+ :class="{ 'tmagic-form-table-drag-target': config.dropSortHandle }"
8
+ :icon="config.dropActionButtonIcon || Sort"
9
+ >
10
+ </TMagicButton>
11
+ </TMagicTooltip>
3
12
  <TMagicButton
4
13
  v-show="showDelete(index + 1 + currentPage * pageSize - 1)"
5
14
  size="small"
6
15
  type="danger"
7
16
  link
8
17
  title="删除"
9
- :icon="Delete"
18
+ :icon="config.deleteActionButtonIcon || Delete"
10
19
  @click="removeHandler(index + 1 + currentPage * pageSize - 1)"
11
20
  ></TMagicButton>
12
21
 
@@ -16,7 +25,7 @@
16
25
  size="small"
17
26
  type="primary"
18
27
  title="复制"
19
- :icon="DocumentCopy"
28
+ :icon="config.copyActionButtonIcon || DocumentCopy"
20
29
  :disabled="disabled"
21
30
  @click="copyHandler(index + 1 + currentPage * pageSize - 1)"
22
31
  ></TMagicButton>
@@ -24,10 +33,10 @@
24
33
 
25
34
  <script setup lang="ts">
26
35
  import { inject } from 'vue';
27
- import { Delete, DocumentCopy } from '@element-plus/icons-vue';
36
+ import { Delete, DocumentCopy, Sort } from '@element-plus/icons-vue';
28
37
  import { cloneDeep } from 'lodash-es';
29
38
 
30
- import { TMagicButton } from '@tmagic/design';
39
+ import { TMagicButton, TMagicTooltip } from '@tmagic/design';
31
40
 
32
41
  import type { FormState, TableConfig } from '../schema';
33
42
 
@@ -8,7 +8,11 @@
8
8
  >
9
9
  <div class="m-fields-table" :class="{ 'm-fields-table-item-extra': config.itemExtra }">
10
10
  <span v-if="config.extra" style="color: rgba(0, 0, 0, 0.45)" v-html="config.extra"></span>
11
- <TMagicTooltip content="拖拽可排序" placement="left-start" :disabled="config.dropSort !== true">
11
+ <TMagicTooltip
12
+ content="拖拽可排序"
13
+ placement="left-start"
14
+ :disabled="config.dropSort !== true || config.dropSortHandle"
15
+ >
12
16
  <TMagicTable
13
17
  v-if="model[modelName]"
14
18
  ref="tMagicTable"
@@ -133,16 +137,15 @@ const { pageSize, currentPage, paginationData, handleSizeChange, handleCurrentCh
133
137
  );
134
138
 
135
139
  const { nextZIndex } = useZIndex();
140
+ const updateKey = ref(1);
136
141
 
137
142
  const { addable, newHandler } = useAdd(props, emit);
138
143
  const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
139
- useSortable(props, emit, tMagicTableRef, modelName);
144
+ useSortable(props, emit, tMagicTableRef, modelName, updateKey);
140
145
  const { isFullscreen, toggleFullscreen } = useFullscreen();
141
146
  const { importable, excelHandler, clearHandler } = useImport(props, emit, newHandler);
142
147
  const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
143
148
 
144
- const updateKey = ref(1);
145
-
146
149
  const data = computed(() => (props.config.pagination ? paginationData.value : props.model[modelName.value]));
147
150
 
148
151
  const toggleMode = () => {
@@ -1,4 +1,4 @@
1
- import { inject, type Ref, type ShallowRef, watchEffect } from 'vue';
1
+ import { inject, nextTick, type Ref, type ShallowRef, watchEffect } from 'vue';
2
2
  import Sortable, { type SortableEvent } from 'sortablejs';
3
3
 
4
4
  import { type TMagicTable } from '@tmagic/design';
@@ -13,6 +13,7 @@ export const useSortable = (
13
13
  emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void,
14
14
  tMagicTableRef: ShallowRef<InstanceType<typeof TMagicTable> | null>,
15
15
  modelName: Ref<string | number>,
16
+ updateKey: Ref<number>,
16
17
  ) => {
17
18
  const mForm = inject<FormState | undefined>('mForm');
18
19
 
@@ -29,6 +30,7 @@ export const useSortable = (
29
30
  filter: 'input', // 表单组件选字操作和触发拖拽会冲突,优先保证选字操作
30
31
  preventOnFilter: false, // 允许选字
31
32
  direction: 'vertical',
33
+ handle: props.config.dropSortHandle ? '.tmagic-form-table-drag-target' : undefined,
32
34
  onEnd: ({ newIndex, oldIndex }: SortableEvent) => {
33
35
  if (typeof newIndex === 'undefined') return;
34
36
  if (typeof oldIndex === 'undefined') return;
@@ -36,6 +38,12 @@ export const useSortable = (
36
38
 
37
39
  emit('change', newData);
38
40
  mForm?.$emit('field-change', newData);
41
+
42
+ nextTick(() => {
43
+ sortable?.destroy();
44
+ sortable = undefined;
45
+ updateKey.value += 1;
46
+ });
39
47
  },
40
48
  });
41
49
  };
@@ -107,11 +107,11 @@ export const useTableColumns = (
107
107
  actionFixed = props.config.fixed;
108
108
  }
109
109
 
110
- const actionClumn = {
110
+ const actionColumn = {
111
111
  props: {
112
112
  label: '操作',
113
113
  fixed: actionFixed,
114
- width: props.config.operateColWidth || 112,
114
+ width: props.config.operateColWidth ?? (props.config.dropSortHandle && props.config.dropSort ? 132 : 112),
115
115
  align: 'center',
116
116
  },
117
117
  cell: ({ row, $index }: any) =>
@@ -133,7 +133,7 @@ export const useTableColumns = (
133
133
  };
134
134
 
135
135
  if (actionFixed !== 'right') {
136
- columns.push(actionClumn);
136
+ columns.push(actionColumn);
137
137
  }
138
138
 
139
139
  if (props.sort && props.model[modelName.value] && props.model[modelName.value].length > 1) {
@@ -237,7 +237,7 @@ export const useTableColumns = (
237
237
  }
238
238
 
239
239
  if (actionFixed === 'right') {
240
- columns.push(actionClumn);
240
+ columns.push(actionColumn);
241
241
  }
242
242
 
243
243
  return columns;
@@ -65,4 +65,8 @@
65
65
  .el-form-item {
66
66
  margin-bottom: 0;
67
67
  }
68
+
69
+ .tmagic-form-table-drag-target {
70
+ cursor: move;
71
+ }
68
72
  }
package/src/utils/form.ts CHANGED
@@ -16,7 +16,6 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { toRaw } from 'vue';
20
19
  import dayjs from 'dayjs';
21
20
  import utc from 'dayjs/plugin/utc';
22
21
  import { cloneDeep } from 'lodash-es';
@@ -121,12 +120,12 @@ const initValueItem = function (
121
120
  asyncLoadConfig(value, initValue, item as HtmlField);
122
121
 
123
122
  // 这种情况比较多,提前结束
124
- if (name && !items && typeof initValue[name] !== 'undefined') {
123
+ if (name && !items && typeof initValue?.[name] !== 'undefined') {
125
124
  if (typeof value[name] === 'undefined') {
126
125
  if (type === 'number') {
127
126
  value[name] = Number(initValue[name]);
128
127
  } else {
129
- value[name] = typeof initValue[name] === 'object' ? cloneDeep(initValue[name]) : initValue[name];
128
+ value[name] = typeof initValue[name] === 'object' ? initValue[name] : initValue[name];
130
129
  }
131
130
  }
132
131
 
@@ -281,13 +280,15 @@ export const initValue = async (
281
280
  ) => {
282
281
  if (!Array.isArray(config)) throw new Error('config应该为数组');
283
282
 
284
- let valuesTmp = createValues(mForm, config, toRaw(initValues), {});
283
+ const initValuesCopy = cloneDeep(initValues);
284
+
285
+ let valuesTmp = createValues(mForm, config, initValuesCopy, {});
285
286
 
286
287
  const [firstForm] = config as [ContainerCommonConfig];
287
288
  if (firstForm && typeof firstForm.onInitValue === 'function') {
288
289
  valuesTmp = await firstForm.onInitValue(mForm, {
289
290
  formValue: valuesTmp,
290
- initValue: initValues,
291
+ initValue: initValuesCopy,
291
292
  });
292
293
  }
293
294
 
@@ -302,7 +303,7 @@ export const datetimeFormatter = (
302
303
  if (v) {
303
304
  let time: string | number;
304
305
  if (['x', 'timestamp'].includes(format)) {
305
- time = dayjs(v).valueOf();
306
+ time = dayjs(Number.isNaN(Number(v)) ? v : Number(v)).valueOf();
306
307
  } else if ((typeof v === 'string' && v.includes('Z')) || v.constructor === Date) {
307
308
  dayjs.extend(utc);
308
309
  // UTC字符串时间或Date对象格式化为北京时间