knt-shared 1.2.0 → 1.2.1

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/index.esm.js CHANGED
@@ -656,14 +656,10 @@ const IconFullscreen = Object.assign(_IconFullscreen, {
656
656
  });
657
657
  const _hoisted_1$3 = { class: "basic-upload" };
658
658
  const _hoisted_2$3 = {
659
- key: 0,
660
- class: "upload-card-button"
661
- };
662
- const _hoisted_3$2 = {
663
659
  key: 0,
664
660
  class: "upload-text"
665
661
  };
666
- const _hoisted_4$2 = { class: "upload-tip" };
662
+ const _hoisted_3$2 = { class: "upload-tip" };
667
663
  const _sfc_main$4 = /* @__PURE__ */ defineComponent({
668
664
  ...{
669
665
  name: "BasicUpload",
@@ -672,8 +668,8 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
672
668
  __name: "BasicUpload",
673
669
  props: {
674
670
  modelValue: {},
675
- accept: { default: "" },
676
- maxSize: { default: 10 },
671
+ accept: { default: "image/*" },
672
+ maxSize: { default: 30 },
677
673
  maxCount: { default: 1 },
678
674
  multiple: { type: Boolean, default: false },
679
675
  disabled: { type: Boolean, default: false },
@@ -697,6 +693,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
697
693
  showPreviewButton: { type: Boolean, default: true },
698
694
  showUploadButton: { type: Boolean, default: true },
699
695
  tip: {},
696
+ cardSize: {},
700
697
  imagePreview: { type: Boolean, default: true },
701
698
  imageCrop: { type: Boolean, default: false },
702
699
  imageCompress: { type: Boolean, default: false },
@@ -704,7 +701,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
704
701
  draggable: { type: Boolean, default: false },
705
702
  directory: { type: Boolean, default: false },
706
703
  autoUpload: { type: Boolean, default: true },
707
- resultType: { default: "url" },
704
+ resultType: { default: "fileList" },
708
705
  uploadButtonText: {},
709
706
  uploadButtonType: { default: "primary" }
710
707
  },
@@ -715,6 +712,9 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
715
712
  const uploadRef = ref();
716
713
  const fileListRef = ref([]);
717
714
  const propsRef = ref({});
715
+ const hasShownActionError = ref(false);
716
+ const isInternalUpdate = ref(false);
717
+ const processedFiles = ref(/* @__PURE__ */ new Map());
718
718
  const getProps = computed(() => {
719
719
  return { ...props, ...unref(propsRef) };
720
720
  });
@@ -735,7 +735,15 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
735
735
  showRemoveButton: propsData.showRemoveButton && !propsData.readonly,
736
736
  showUploadButton: !hideUploadButton.value,
737
737
  // 只有在没有自定义预览时才启用 imagePreview
738
- imagePreview: propsData.imagePreview && !propsData.onPreview
738
+ imagePreview: propsData.imagePreview && !propsData.onPreview,
739
+ onRemove: async (fileItem) => {
740
+ if (propsData.onRemove) {
741
+ const canRemove = await propsData.onRemove(fileItem);
742
+ if (!canRemove) return false;
743
+ }
744
+ emit("remove", fileItem);
745
+ return true;
746
+ }
739
747
  };
740
748
  });
741
749
  const validateFileSize = (file) => {
@@ -816,18 +824,46 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
816
824
  action: propsData.action,
817
825
  withCredentials: propsData.withCredentials
818
826
  };
819
- propsData.customRequest(customOptions);
820
- } else {
821
- defaultUpload(options);
827
+ return propsData.customRequest(customOptions);
822
828
  }
829
+ return defaultUpload(options);
830
+ };
831
+ const extractUrlFromResponse = (response) => {
832
+ const urlPaths = ["url", "data.pathUrl", "data.url", "data.path", "pathUrl", "path"];
833
+ for (const path of urlPaths) {
834
+ const value = path.split(".").reduce((obj, key) => obj == null ? void 0 : obj[key], response);
835
+ if (value && typeof value === "string") {
836
+ return value;
837
+ }
838
+ }
839
+ if (response.data && typeof response.data === "string") {
840
+ return response.data;
841
+ }
842
+ return null;
843
+ };
844
+ const isDev = false;
845
+ const logger = {
846
+ debug: (...args) => isDev,
847
+ warn: (...args) => console.warn("[BasicUpload]", ...args),
848
+ error: (...args) => console.error("[BasicUpload]", ...args)
823
849
  };
824
850
  const defaultUpload = (options) => {
825
851
  const propsData = unref(getProps);
826
852
  const { fileItem, onProgress, onSuccess, onError } = options;
827
853
  if (!propsData.action) {
828
- Message.error("请配置上传地址 action");
854
+ if (!hasShownActionError.value) {
855
+ Message.error("请配置上传地址 action");
856
+ hasShownActionError.value = true;
857
+ setTimeout(() => {
858
+ hasShownActionError.value = false;
859
+ }, 3e3);
860
+ }
829
861
  onError(new Error("上传地址未配置"));
830
- return;
862
+ return {
863
+ abort() {
864
+ xhr.abort();
865
+ }
866
+ };
831
867
  }
832
868
  const formData = new FormData();
833
869
  formData.append(propsData.name || "file", fileItem.file);
@@ -847,15 +883,31 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
847
883
  if (xhr.status >= 200 && xhr.status < 300) {
848
884
  try {
849
885
  const response = JSON.parse(xhr.responseText);
850
- onSuccess(response);
886
+ const { code, message, data } = response;
887
+ if (code !== 200) {
888
+ const errorMsg = message ? `上传失败: ${message}` : "上传失败";
889
+ onError(new Error(errorMsg));
890
+ Message.error(errorMsg);
891
+ return;
892
+ }
893
+ const extractedUrl = extractUrlFromResponse(response);
894
+ const normalizedResponse = extractedUrl ? { url: extractedUrl, name: fileItem.name, ...data } : response;
895
+ if (!extractedUrl) {
896
+ logger.warn("响应中未找到 URL 字段,可能导致上传状态异常");
897
+ }
898
+ Message.success(`${fileItem.name} 上传成功`);
899
+ onSuccess(normalizedResponse);
851
900
  } catch (error) {
852
- onSuccess(xhr.responseText);
901
+ onSuccess({ data: xhr.responseText });
853
902
  }
854
903
  } else {
855
- onError(new Error(`上传失败: ${xhr.status}`));
904
+ const errorMsg = `上传失败: HTTP ${xhr.status}`;
905
+ Message.error(errorMsg);
906
+ onError(new Error(errorMsg));
856
907
  }
857
908
  });
858
909
  xhr.addEventListener("error", () => {
910
+ logger.error("上传网络错误");
859
911
  onError(new Error("网络错误"));
860
912
  });
861
913
  xhr.addEventListener("abort", () => {
@@ -871,32 +923,42 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
871
923
  xhr.withCredentials = true;
872
924
  }
873
925
  xhr.send(formData);
926
+ return {
927
+ abort() {
928
+ xhr.abort();
929
+ }
930
+ };
874
931
  };
875
932
  const handleChange = (fileList, currentFile) => {
933
+ if (isInternalUpdate.value) return;
934
+ const oldLength = fileListRef.value.length;
935
+ const newLength = fileList.length;
876
936
  fileListRef.value = fileList;
877
937
  emit("change", fileList);
878
- if (currentFile.status === "done") {
879
- Message.success(`${currentFile.name} 上传成功`);
938
+ const isRemove = newLength < oldLength;
939
+ const fileKey = currentFile.uid;
940
+ const lastStatus = processedFiles.value.get(fileKey);
941
+ if (currentFile.status === "done" && lastStatus !== "done" && !isRemove) {
942
+ processedFiles.value.set(fileKey, "done");
880
943
  emit("success", currentFile.response, currentFile);
881
- if (getProps.value.onSuccess) {
882
- getProps.value.onSuccess(currentFile.response, currentFile);
883
- }
884
- } else if (currentFile.status === "error") {
885
- Message.error(`${currentFile.name} 上传失败`);
944
+ } else if (currentFile.status === "error" && lastStatus !== "error") {
945
+ processedFiles.value.set(fileKey, "error");
886
946
  const error = new Error("上传失败");
887
947
  emit("error", error, currentFile);
888
- if (getProps.value.onError) {
889
- getProps.value.onError(error, currentFile);
890
- }
948
+ }
949
+ if (isRemove) {
950
+ const fileUids = new Set(fileList.map((f) => f.uid));
951
+ processedFiles.value.forEach((_, uid) => {
952
+ if (!fileUids.has(uid)) {
953
+ processedFiles.value.delete(uid);
954
+ }
955
+ });
891
956
  }
892
957
  updateModelValue(fileList);
893
958
  };
894
959
  const handleProgress = (currentFile, event) => {
895
960
  const percent = currentFile.percent || 0;
896
961
  emit("progress", percent, currentFile);
897
- if (getProps.value.onProgress) {
898
- getProps.value.onProgress(percent, currentFile);
899
- }
900
962
  };
901
963
  const handlePreview = (fileItem) => {
902
964
  const propsData = unref(getProps);
@@ -908,6 +970,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
908
970
  const updateModelValue = (fileList) => {
909
971
  var _a;
910
972
  const propsData = unref(getProps);
973
+ isInternalUpdate.value = true;
911
974
  switch (propsData.resultType) {
912
975
  case "fileList":
913
976
  emit("update:modelValue", fileList);
@@ -928,6 +991,11 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
928
991
  default:
929
992
  emit("update:modelValue", fileList);
930
993
  }
994
+ nextTick(() => {
995
+ setTimeout(() => {
996
+ isInternalUpdate.value = false;
997
+ }, 50);
998
+ });
931
999
  };
932
1000
  const parseModelValue = (value) => {
933
1001
  if (!value) return [];
@@ -963,6 +1031,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
963
1031
  };
964
1032
  const clearFiles = () => {
965
1033
  fileListRef.value = [];
1034
+ processedFiles.value.clear();
966
1035
  emit("update:modelValue", []);
967
1036
  emit("change", []);
968
1037
  };
@@ -985,18 +1054,14 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
985
1054
  updateModelValue(fileListRef.value);
986
1055
  };
987
1056
  const removeFile = (fileItem) => {
988
- const index = fileListRef.value.findIndex(
989
- (item) => item.uid === fileItem.uid
990
- );
1057
+ const index = fileListRef.value.findIndex((item) => item.uid === fileItem.uid);
991
1058
  if (index !== -1) {
992
1059
  fileListRef.value.splice(index, 1);
993
1060
  updateModelValue(fileListRef.value);
994
1061
  }
995
1062
  };
996
1063
  const updateFile = (fileItem) => {
997
- const index = fileListRef.value.findIndex(
998
- (item) => item.uid === fileItem.uid
999
- );
1064
+ const index = fileListRef.value.findIndex((item) => item.uid === fileItem.uid);
1000
1065
  if (index !== -1) {
1001
1066
  fileListRef.value[index] = { ...fileListRef.value[index], ...fileItem };
1002
1067
  updateModelValue(fileListRef.value);
@@ -1016,7 +1081,8 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1016
1081
  });
1017
1082
  watch(
1018
1083
  () => props.modelValue,
1019
- (val) => {
1084
+ (val, oldVal) => {
1085
+ if (isInternalUpdate.value) return;
1020
1086
  fileListRef.value = parseModelValue(val);
1021
1087
  },
1022
1088
  { immediate: true }
@@ -1047,8 +1113,8 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1047
1113
  }, getBindValue.value, {
1048
1114
  "file-list": fileListRef.value,
1049
1115
  "custom-request": handleCustomRequest,
1050
- "before-upload": handleBeforeUpload,
1051
1116
  onChange: handleChange,
1117
+ onBeforeUpload: handleBeforeUpload,
1052
1118
  onProgress: handleProgress,
1053
1119
  onPreview: handlePreview
1054
1120
  }), createSlots({ _: 2 }, [
@@ -1056,10 +1122,17 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1056
1122
  name: "upload-button",
1057
1123
  fn: withCtx(() => [
1058
1124
  renderSlot(_ctx.$slots, "upload-button", {}, () => [
1059
- getProps.value.listType === "picture-card" ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
1125
+ getProps.value.listType === "picture-card" ? (openBlock(), createElementBlock("div", {
1126
+ key: 0,
1127
+ class: "upload-card-button",
1128
+ style: normalizeStyle({
1129
+ width: `${getProps.value.cardSize || 80}px`,
1130
+ height: `${getProps.value.cardSize || 80}px`
1131
+ })
1132
+ }, [
1060
1133
  createVNode(unref(IconPlus), { size: 16 }),
1061
- getProps.value.uploadButtonText ? (openBlock(), createElementBlock("div", _hoisted_3$2, toDisplayString(getProps.value.uploadButtonText), 1)) : createCommentVNode("", true)
1062
- ])) : (openBlock(), createBlock(_component_a_button, {
1134
+ getProps.value.uploadButtonText ? (openBlock(), createElementBlock("div", _hoisted_2$3, toDisplayString(getProps.value.uploadButtonText), 1)) : createCommentVNode("", true)
1135
+ ], 4)) : (openBlock(), createBlock(_component_a_button, {
1063
1136
  key: 1,
1064
1137
  type: getProps.value.uploadButtonType || "primary"
1065
1138
  }, {
@@ -1086,7 +1159,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1086
1159
  name: "tip",
1087
1160
  fn: withCtx(() => [
1088
1161
  renderSlot(_ctx.$slots, "tip", {}, () => [
1089
- createElementVNode("div", _hoisted_4$2, toDisplayString(getProps.value.tip), 1)
1162
+ createElementVNode("div", _hoisted_3$2, toDisplayString(getProps.value.tip), 1)
1090
1163
  ], true)
1091
1164
  ]),
1092
1165
  key: "2"
@@ -1110,7 +1183,7 @@ const _export_sfc = (sfc, props) => {
1110
1183
  }
1111
1184
  return target;
1112
1185
  };
1113
- const BasicUpload = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-179e6d71"]]);
1186
+ const BasicUpload = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-10587859"]]);
1114
1187
  const componentMap = {
1115
1188
  Input,
1116
1189
  InputNumber,
@@ -2114,7 +2187,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2114
2187
  const indexColumn = {
2115
2188
  title: "序号",
2116
2189
  dataIndex: "__index__",
2117
- width: 80,
2190
+ width: 60,
2118
2191
  align: "center",
2119
2192
  fixed: "left",
2120
2193
  slotName: "__index__",
@@ -2995,7 +3068,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2995
3068
  };
2996
3069
  }
2997
3070
  });
2998
- const BasicTable = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-f0b71ff8"]]);
3071
+ const BasicTable = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-04667d35"]]);
2999
3072
  function useTable(options = {}) {
3000
3073
  const tableRef = ref(null);
3001
3074
  const formRef = ref(null);