qidian-vue-ui 2.0.1 → 2.0.3

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,58 +1,58 @@
1
- .qd-service-table[data-v-ae90af38] {
1
+ .qd-service-table[data-v-616e3cad] {
2
2
  height: 100%;
3
3
  display: flex;
4
4
  flex-direction: column;
5
5
  }
6
- .qd-service-table[data-v-ae90af38] > .t-table__content {
6
+ .qd-service-table[data-v-616e3cad] > .t-table__content {
7
7
  flex: 1;
8
8
  }
9
- .qd-service-table[data-v-ae90af38] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
9
+ .qd-service-table[data-v-616e3cad] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
10
10
  margin-left: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
11
11
  }
12
- .qd-service-table[data-v-ae90af38] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
12
+ .qd-service-table[data-v-616e3cad] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
13
13
  width: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
14
14
  }
15
- .qd-service-table[data-v-ae90af38] .t-affix > .t-table__affixed-header-elm-wrap,
16
- .qd-service-table[data-v-ae90af38] .t-affix > .t-table__scrollbar--obvious {
17
- transform: var(--v42be12ab);
15
+ .qd-service-table[data-v-616e3cad] .t-affix > .t-table__affixed-header-elm-wrap,
16
+ .qd-service-table[data-v-616e3cad] .t-affix > .t-table__scrollbar--obvious {
17
+ transform: var(--v17ef397a);
18
18
  }
19
- .qd-service-table--horizontal-bar-static[data-v-ae90af38] .t-table__scrollbar--obvious {
19
+ .qd-service-table--horizontal-bar-static[data-v-616e3cad] .t-table__scrollbar--obvious {
20
20
  visibility: hidden;
21
21
  pointer-events: none;
22
22
  }
23
- .qd-service-table[data-v-ae90af38] .t-table__affixed-header-elm-wrap {
23
+ .qd-service-table[data-v-616e3cad] .t-table__affixed-header-elm-wrap {
24
24
  height: auto !important;
25
25
  }
26
- .qd-service-table[data-v-ae90af38] .t-table__affixed-header-elm {
26
+ .qd-service-table[data-v-616e3cad] .t-table__affixed-header-elm {
27
27
  position: relative;
28
28
  scrollbar-width: none;
29
29
  }
30
- .qd-service-table[data-v-ae90af38] .t-table__affixed-header-elm::-webkit-scrollbar {
30
+ .qd-service-table[data-v-616e3cad] .t-table__affixed-header-elm::-webkit-scrollbar {
31
31
  display: none;
32
32
  width: 0;
33
33
  height: 0;
34
34
  }
35
- .qd-service-table[data-v-ae90af38] .t-table__virtual-scroll-cursor + table {
35
+ .qd-service-table[data-v-616e3cad] .t-table__virtual-scroll-cursor + table {
36
36
  border-collapse: separate;
37
37
  }
38
- .qd-service-table[data-v-ae90af38] .t-table__expanded-row-inner {
38
+ .qd-service-table[data-v-616e3cad] .t-table__expanded-row-inner {
39
39
  position: sticky;
40
40
  left: 0;
41
- width: var(--cf433440) !important;
41
+ width: var(--v61770878) !important;
42
42
  }
43
- .qd-service-table[data-v-ae90af38] .t-table__cell-wrap > *:not(.t-switch):not(.t-tag):not(.t-icon):not(.qd-file-icon) {
43
+ .qd-service-table[data-v-616e3cad] .t-table__cell-wrap > *:not(.t-switch):not(.t-tag):not(.t-icon):not(.qd-file-icon) {
44
44
  width: 100%;
45
45
  }
46
- .qd-service-table[data-v-ae90af38] .qd-service-table__non-editable-col {
46
+ .qd-service-table[data-v-616e3cad] .qd-service-table__non-editable-col {
47
47
  background-color: color-mix(in srgb, var(--td-bg-color-component) 50%, transparent);
48
48
  }
49
- .qd-service-table[data-v-ae90af38] .qd-service-table__non-editable-col:is(
49
+ .qd-service-table[data-v-616e3cad] .qd-service-table__non-editable-col:is(
50
50
  .t-table__cell--fixed-left,
51
51
  .t-table__cell--fixed-right
52
52
  ) {
53
53
  background-color: inherit;
54
54
  background-image: linear-gradient(color-mix(in srgb, var(--td-bg-color-secondarycontainer) 50%, transparent), color-mix(in srgb, var(--td-bg-color-secondarycontainer) 50%, transparent));
55
55
  }
56
- .qd-service-table--disable-horizontal-scroll[data-v-ae90af38] colgroup > col {
56
+ .qd-service-table--disable-horizontal-scroll[data-v-616e3cad] colgroup > col {
57
57
  width: auto !important;
58
58
  }
@@ -2,7 +2,7 @@ import './index.css'
2
2
  import _sfc_main from "./index.vue2.mjs";
3
3
  /* empty css */
4
4
  import _export_sfc from "../../../_virtual/_plugin-vue_export-helper.mjs";
5
- const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-ae90af38"]]);
5
+ const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-616e3cad"]]);
6
6
  export {
7
7
  QdServiceTable as default
8
8
  };
@@ -4,6 +4,7 @@ import { useVModels, useElementSize, useElementBounding, useIntersectionObserver
4
4
  import { useActivated, useTimer, easyCopy, isEmpty, suspectedWrapperPromise, useServicePagination, createExposeProxy, resizeDirective, getScrollEl } from "qidian-shared";
5
5
  import { LoadingIcon, AddRectangleIcon, MinusRectangleIcon } from "tdesign-icons-vue-next";
6
6
  import { EnhancedTable, Table, Empty } from "tdesign-vue-next";
7
+ import { validate } from "tdesign-vue-next/es/form/utils/form-model.mjs";
7
8
  import { useModal } from "../../../hooks/useModal.mjs";
8
9
  import { getTransformOffset } from "../../../utils/tools.mjs";
9
10
  import { useConfig } from "../../config-provider/useConfig.mjs";
@@ -13,6 +14,7 @@ import { qdServiceTableTreeConfig, qdServiceTableProps, getSortParams } from "./
13
14
  import { PROVIDE_FORM_ADD_BEFORE_SUBMIT_QUEUE } from "../../form/config.mjs";
14
15
  import get from "../../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/get.mjs";
15
16
  import QdForm from "../../form/index.vue.mjs";
17
+ import set from "../../../node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/set.mjs";
16
18
  const defaultMinWidth = 80;
17
19
  const defaultVirtualScrollBufferSize = 2;
18
20
  const defaultVirtualScrollUpdateInterval = 16;
@@ -318,8 +320,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
318
320
  emit: __emit
319
321
  }) {
320
322
  useCssVars((_ctx) => ({
321
- "v42be12ab": affixedHeaderTransform.value,
322
- "cf433440": expandedRowWidth.value
323
+ "v17ef397a": affixedHeaderTransform.value,
324
+ "v61770878": expandedRowWidth.value
323
325
  }));
324
326
  const props = __props;
325
327
  const emit = __emit;
@@ -986,6 +988,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
986
988
  if (getQdFormComponentName(formItem.component).includes("upload")) return true;
987
989
  return false;
988
990
  }
991
+ function shouldRenderVirtualFormItem(column, row) {
992
+ if (!resolveFormItemVirtualRender(column)) return false;
993
+ if (column.formItem?.virtualValidateRender !== void 0) return true;
994
+ if (!getQdFormComponentName(column.formItem?.component).includes("upload")) return true;
995
+ const filesModel = column.formItem?.component?.vModelFiles;
996
+ if (typeof filesModel !== "string") return true;
997
+ const files = get(row, filesModel);
998
+ return Array.isArray(files) && files.some((file) => file.status !== "success");
999
+ }
989
1000
  function removeEditingCell(target) {
990
1001
  editingCells.value = editingCells.value.filter((item) => !isSameEditingCell(item, target));
991
1002
  if (!activeEditingCell.value || !isSameEditingCell(activeEditingCell.value, target)) return;
@@ -1144,45 +1155,68 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1144
1155
  row
1145
1156
  });
1146
1157
  }
1147
- function buildRowFormItems(row) {
1148
- return editableColumns.value.filter(({
1149
- column
1150
- }) => (column.formItem || column.edit?.rules) && column.colKey).map(({
1151
- column
1152
- }) => {
1153
- const formItem = column.formItem;
1154
- const label = typeof column.title === "string" ? column.title : "";
1155
- const shouldRender = resolveFormItemVirtualRender(column);
1156
- const {
1157
- component: _,
1158
- ...restFormItem
1159
- } = formItem ?? {};
1160
- const resolved = resolveQdFormItemOptions({
1161
- formItem: {
1162
- ...formItem ?? {},
1163
- rules: formItem?.rules ?? resolveColumnRules(column.edit?.rules, row)
1164
- },
1165
- context: row,
1166
- label,
1167
- t: formT
1168
- });
1169
- return {
1170
- name: column.colKey,
1171
- label,
1172
- ...shouldRender ? formItem ?? {} : restFormItem,
1173
- rules: resolved.rules,
1174
- context: row
1175
- };
1176
- });
1158
+ function buildOffscreenForm(rows, renderVirtualComponents) {
1159
+ const formData = {};
1160
+ const fields = [];
1161
+ const items = [];
1162
+ for (const row of rows) {
1163
+ for (const {
1164
+ column
1165
+ } of editableColumns.value) {
1166
+ if (!column.formItem && !column.edit?.rules || !column.colKey) continue;
1167
+ if (!resolveFormItemIfRender(column, row)) continue;
1168
+ const formItem = column.formItem;
1169
+ const label = typeof column.title === "string" ? column.title : "";
1170
+ const shouldRender = renderVirtualComponents && shouldRenderVirtualFormItem(column, row);
1171
+ const resolved = resolveQdFormItemOptions({
1172
+ formItem: {
1173
+ ...formItem ?? {},
1174
+ rules: formItem?.rules ?? resolveColumnRules(column.edit?.rules, row)
1175
+ },
1176
+ context: row,
1177
+ label,
1178
+ t: formT
1179
+ });
1180
+ if (!resolved.rules.length && !shouldRender) continue;
1181
+ const name = getCellKey(row, column.colKey);
1182
+ Object.defineProperty(formData, name, {
1183
+ configurable: true,
1184
+ enumerable: true,
1185
+ get: () => get(row, column.colKey),
1186
+ set: (value) => set(row, column.colKey, value)
1187
+ });
1188
+ if (resolved.rules.length) fields.push({
1189
+ name,
1190
+ rules: resolved.rules
1191
+ });
1192
+ if (shouldRender) {
1193
+ const submitFormItem = {
1194
+ ...formItem ?? {}
1195
+ };
1196
+ delete submitFormItem.required;
1197
+ delete submitFormItem.rules;
1198
+ items.push({
1199
+ name,
1200
+ label,
1201
+ ...submitFormItem,
1202
+ context: row
1203
+ });
1204
+ }
1205
+ }
1206
+ }
1207
+ return {
1208
+ fields,
1209
+ formData,
1210
+ items
1211
+ };
1177
1212
  }
1178
1213
  function serializeOffscreen(task) {
1179
1214
  const run2 = offscreenChain.then(task, task);
1180
1215
  offscreenChain = run2.then(() => void 0, () => void 0);
1181
1216
  return run2;
1182
1217
  }
1183
- async function mountOffscreenForm(row) {
1218
+ async function mountOffscreenForm(formData, items) {
1184
1219
  unmountOffscreenForm();
1185
- const items = buildRowFormItems(row);
1186
1220
  const container = document.createElement("div");
1187
1221
  container.setAttribute("aria-hidden", "true");
1188
1222
  Object.assign(container.style, {
@@ -1197,7 +1231,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1197
1231
  });
1198
1232
  document.body.appendChild(container);
1199
1233
  const vnode = h(QdForm, {
1200
- data: row,
1234
+ data: formData,
1201
1235
  items
1202
1236
  });
1203
1237
  vnode.appContext = offscreenAppContext;
@@ -1217,139 +1251,120 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1217
1251
  offscreenContainer = null;
1218
1252
  offscreenInstance = null;
1219
1253
  }
1220
- async function validateRowViaOffscreenForm(row) {
1221
- await mountOffscreenForm(row);
1222
- return offscreenInstance.validate({
1223
- showErrorMessage: false
1224
- });
1225
- }
1226
- async function submitRowViaOffscreenForm(row) {
1227
- await mountOffscreenForm(row);
1228
- return offscreenInstance.submit({
1229
- showErrorMessage: false
1230
- });
1231
- }
1232
- function mergeRowValidateResult(result, row, rowResult) {
1233
- if (typeof rowResult !== "object" || !rowResult) return;
1234
- for (const [colKey, errorList] of Object.entries(rowResult)) {
1235
- if (!Array.isArray(errorList) || !errorList.length) continue;
1236
- result[getCellKey(row, colKey)] = errorList;
1237
- }
1254
+ async function validateRowsViaOffscreenRules(rows) {
1255
+ const {
1256
+ fields,
1257
+ formData
1258
+ } = buildOffscreenForm(rows, false);
1259
+ const result = {};
1260
+ await Promise.all(fields.map(async ({
1261
+ name,
1262
+ rules
1263
+ }) => {
1264
+ const ruleResults = await validate(get(formData, name), rules, {
1265
+ formData,
1266
+ name
1267
+ });
1268
+ if (ruleResults.some((item) => item.result !== true)) result[name] = ruleResults;
1269
+ }));
1270
+ return result;
1238
1271
  }
1239
- async function validateTableViaOffscreenForm() {
1272
+ async function runOffscreenBeforeSubmit(rows) {
1273
+ const {
1274
+ formData,
1275
+ items
1276
+ } = buildOffscreenForm(rows, true);
1277
+ if (!items.length) return {
1278
+ success: true,
1279
+ message: ""
1280
+ };
1240
1281
  try {
1241
- const result = {};
1242
- for (const row of data.value) {
1243
- const rowResult = await validateRowViaOffscreenForm(row);
1244
- mergeRowValidateResult(result, row, rowResult);
1245
- }
1246
- return result;
1282
+ await mountOffscreenForm(formData, items);
1283
+ const submitContext = await offscreenInstance.submit({
1284
+ showErrorMessage: false
1285
+ });
1286
+ return {
1287
+ success: submitContext.validateResult === true,
1288
+ message: submitContext.firstError ?? ""
1289
+ };
1247
1290
  } finally {
1248
1291
  unmountOffscreenForm();
1249
1292
  }
1250
1293
  }
1294
+ async function validateTableViaOffscreenForm() {
1295
+ return validateRowsViaOffscreenRules(data.value);
1296
+ }
1251
1297
  async function validateSingleRowViaOffscreenForm(rowValue) {
1252
- try {
1253
- const row = data.value.find((item) => getRowValue(item) === rowValue);
1254
- if (!row) return [];
1255
- const rowResult = await validateRowViaOffscreenForm(row);
1256
- const result = {};
1257
- mergeRowValidateResult(result, row, rowResult);
1258
- return resolveValidationResults(result);
1259
- } finally {
1260
- unmountOffscreenForm();
1261
- }
1298
+ const row = data.value.find((item) => getRowValue(item) === rowValue);
1299
+ if (!row) return [];
1300
+ const result = await validateRowsViaOffscreenRules([row]);
1301
+ return resolveValidationResults(result);
1262
1302
  }
1263
1303
  async function submitTableViaOffscreenForm(params, showErrorMessage) {
1264
- try {
1265
- const result = {};
1266
- for (const row of data.value) {
1267
- const submitContext = await submitRowViaOffscreenForm(row);
1268
- if (submitContext.validateResult === true) continue;
1269
- const rowValidateResult = submitContext.validateResult;
1270
- if (rowValidateResult && typeof rowValidateResult === "object") {
1271
- mergeRowValidateResult(result, row, rowValidateResult);
1272
- continue;
1273
- }
1274
- if (showErrorMessage && submitContext.firstError) msgError(submitContext.firstError);
1275
- return {
1276
- result: {},
1277
- results: [],
1278
- validateResult: false,
1279
- firstError: submitContext.firstError,
1280
- showErrorMessage,
1281
- tableData: easyCopy(data.value)
1282
- };
1283
- }
1284
- const cellResults = resolveValidationResults(result);
1285
- if (cellResults.length) await showFirstValidationError(cellResults, {
1286
- ...params,
1287
- showErrorMessage
1288
- });
1304
+ const queueResult = await runOffscreenBeforeSubmit(data.value);
1305
+ if (!queueResult.success) {
1306
+ if (showErrorMessage && queueResult.message) msgError(queueResult.message);
1289
1307
  return {
1290
- result,
1291
- results: cellResults,
1292
- validateResult: !cellResults.length,
1293
- firstError: getFirstValidationError(cellResults),
1308
+ result: {},
1309
+ results: [],
1310
+ validateResult: false,
1311
+ firstError: queueResult.message,
1294
1312
  showErrorMessage,
1295
1313
  tableData: easyCopy(data.value)
1296
1314
  };
1297
- } finally {
1298
- unmountOffscreenForm();
1299
1315
  }
1316
+ const result = await validateRowsViaOffscreenRules(data.value);
1317
+ const cellResults = resolveValidationResults(result);
1318
+ if (cellResults.length) await showFirstValidationError(cellResults, {
1319
+ ...params,
1320
+ showErrorMessage
1321
+ });
1322
+ return {
1323
+ result,
1324
+ results: cellResults,
1325
+ validateResult: !cellResults.length,
1326
+ firstError: getFirstValidationError(cellResults),
1327
+ showErrorMessage,
1328
+ tableData: easyCopy(data.value)
1329
+ };
1300
1330
  }
1301
1331
  async function submitSingleRowViaOffscreenForm(row, params, showErrorMessage) {
1302
- try {
1303
- if (!row) {
1304
- return {
1305
- result: [],
1306
- trigger: "parent",
1307
- validateResult: false,
1308
- showErrorMessage,
1309
- rowData: void 0
1310
- };
1311
- }
1312
- const submitContext = await submitRowViaOffscreenForm(row);
1313
- const rowData = easyCopy(row);
1314
- if (submitContext.validateResult === true) {
1315
- return {
1316
- result: [],
1317
- trigger: "parent",
1318
- validateResult: true,
1319
- showErrorMessage,
1320
- rowData
1321
- };
1322
- }
1323
- const rowValidateResult = submitContext.validateResult;
1324
- if (rowValidateResult && typeof rowValidateResult === "object") {
1325
- const result = {};
1326
- mergeRowValidateResult(result, row, rowValidateResult);
1327
- const cellResults = resolveValidationResults(result);
1328
- await showFirstValidationError(cellResults, {
1329
- ...params,
1330
- showErrorMessage
1331
- });
1332
- return {
1333
- result: cellResults,
1334
- trigger: "parent",
1335
- validateResult: false,
1336
- firstError: getFirstValidationError(cellResults),
1337
- showErrorMessage,
1338
- rowData
1339
- };
1340
- }
1341
- if (showErrorMessage && submitContext.firstError) msgError(submitContext.firstError);
1332
+ if (!row) {
1342
1333
  return {
1343
1334
  result: [],
1344
1335
  trigger: "parent",
1345
1336
  validateResult: false,
1346
- firstError: submitContext.firstError,
1337
+ showErrorMessage,
1338
+ rowData: void 0
1339
+ };
1340
+ }
1341
+ const queueResult = await runOffscreenBeforeSubmit([row]);
1342
+ const rowData = easyCopy(row);
1343
+ if (!queueResult.success) {
1344
+ if (showErrorMessage && queueResult.message) msgError(queueResult.message);
1345
+ return {
1346
+ result: [],
1347
+ trigger: "parent",
1348
+ validateResult: false,
1349
+ firstError: queueResult.message,
1347
1350
  showErrorMessage,
1348
1351
  rowData
1349
1352
  };
1350
- } finally {
1351
- unmountOffscreenForm();
1352
1353
  }
1354
+ const result = await validateRowsViaOffscreenRules([row]);
1355
+ const cellResults = resolveValidationResults(result);
1356
+ await showFirstValidationError(cellResults, {
1357
+ ...params,
1358
+ showErrorMessage
1359
+ });
1360
+ return {
1361
+ result: cellResults,
1362
+ trigger: "parent",
1363
+ validateResult: !cellResults.length,
1364
+ firstError: getFirstValidationError(cellResults),
1365
+ showErrorMessage,
1366
+ rowData
1367
+ };
1353
1368
  }
1354
1369
  async function validateTableData(params) {
1355
1370
  const result = isVirtualScroll.value ? await serializeOffscreen(() => validateTableViaOffscreenForm()) : (await tableRef.value?.validateTableData())?.result ?? {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qidian-vue-ui",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "基于 TDesign 的 QiDian Vue UI 组件库",
5
5
  "author": "qidian",
6
6
  "license": "MIT",
@@ -130,7 +130,7 @@
130
130
  "vue-codemirror": "^6.1.1",
131
131
  "vue-echarts": "^8.0.1",
132
132
  "vue-stream-markdown": "1.0.1-beta.1",
133
- "qidian-shared": "1.2.2"
133
+ "qidian-shared": "1.2.3"
134
134
  },
135
135
  "scripts": {
136
136
  "clean": "rm -rf dist",