@nokecy/qc-ui 1.1.75 → 1.1.78

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.
Files changed (65) hide show
  1. package/dist/cjs/exportButton/exportAction.d.ts +74 -0
  2. package/dist/cjs/exportButton/exportAction.js +199 -0
  3. package/dist/cjs/exportButton/index.d.ts +39 -0
  4. package/dist/cjs/exportButton/index.js +295 -0
  5. package/dist/cjs/importModal/index.d.ts +9 -0
  6. package/dist/cjs/importModal/index.js +46 -8
  7. package/dist/cjs/index.d.ts +4 -0
  8. package/dist/cjs/index.js +66 -0
  9. package/dist/cjs/standardList/StandardAgGridPlus.d.ts +58 -0
  10. package/dist/cjs/standardList/StandardAgGridPlus.js +698 -0
  11. package/dist/cjs/standardList/dateFormat.d.ts +16 -0
  12. package/dist/cjs/standardList/dateFormat.js +56 -0
  13. package/dist/cjs/standardList/emptyState.d.ts +36 -0
  14. package/dist/cjs/standardList/emptyState.js +89 -0
  15. package/dist/cjs/standardList/enumColumns.d.ts +31 -0
  16. package/dist/cjs/standardList/enumColumns.js +87 -0
  17. package/dist/cjs/standardList/gridColumnDefs.d.ts +33 -0
  18. package/dist/cjs/standardList/gridColumnDefs.js +61 -0
  19. package/dist/cjs/standardList/groupedHeaders.d.ts +28 -0
  20. package/dist/cjs/standardList/groupedHeaders.js +84 -0
  21. package/dist/cjs/standardList/groupedHeaders.less +29 -0
  22. package/dist/cjs/standardList/index.d.ts +20 -0
  23. package/dist/cjs/standardList/index.js +176 -0
  24. package/dist/cjs/standardList/listDateDisplay.d.ts +9 -0
  25. package/dist/cjs/standardList/listDateDisplay.js +64 -0
  26. package/dist/cjs/standardList/listDefaultSort.d.ts +38 -0
  27. package/dist/cjs/standardList/listDefaultSort.js +139 -0
  28. package/dist/cjs/standardList/listRefresh.d.ts +25 -0
  29. package/dist/cjs/standardList/listRefresh.js +53 -0
  30. package/dist/cjs/utils/download.d.ts +6 -0
  31. package/dist/cjs/utils/download.js +23 -0
  32. package/dist/esm/exportButton/exportAction.d.ts +74 -0
  33. package/dist/esm/exportButton/exportAction.js +193 -0
  34. package/dist/esm/exportButton/index.d.ts +39 -0
  35. package/dist/esm/exportButton/index.js +259 -0
  36. package/dist/esm/importModal/index.d.ts +9 -0
  37. package/dist/esm/importModal/index.js +46 -8
  38. package/dist/esm/index.d.ts +4 -0
  39. package/dist/esm/index.js +3 -0
  40. package/dist/esm/standardList/StandardAgGridPlus.d.ts +58 -0
  41. package/dist/esm/standardList/StandardAgGridPlus.js +691 -0
  42. package/dist/esm/standardList/dateFormat.d.ts +16 -0
  43. package/dist/esm/standardList/dateFormat.js +50 -0
  44. package/dist/esm/standardList/emptyState.d.ts +36 -0
  45. package/dist/esm/standardList/emptyState.js +83 -0
  46. package/dist/esm/standardList/enumColumns.d.ts +31 -0
  47. package/dist/esm/standardList/enumColumns.js +82 -0
  48. package/dist/esm/standardList/gridColumnDefs.d.ts +33 -0
  49. package/dist/esm/standardList/gridColumnDefs.js +55 -0
  50. package/dist/esm/standardList/groupedHeaders.d.ts +28 -0
  51. package/dist/esm/standardList/groupedHeaders.js +78 -0
  52. package/dist/esm/standardList/groupedHeaders.less +29 -0
  53. package/dist/esm/standardList/index.d.ts +20 -0
  54. package/dist/esm/standardList/index.js +15 -0
  55. package/dist/esm/standardList/listDateDisplay.d.ts +9 -0
  56. package/dist/esm/standardList/listDateDisplay.js +58 -0
  57. package/dist/esm/standardList/listDefaultSort.d.ts +38 -0
  58. package/dist/esm/standardList/listDefaultSort.js +133 -0
  59. package/dist/esm/standardList/listRefresh.d.ts +25 -0
  60. package/dist/esm/standardList/listRefresh.js +47 -0
  61. package/dist/esm/utils/download.d.ts +6 -0
  62. package/dist/esm/utils/download.js +17 -0
  63. package/dist/umd/qc-ui.min.css +1 -1
  64. package/dist/umd/qc-ui.min.js +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ /**
2
+ * 导出按钮的行为决策与地址构造。
3
+ *
4
+ * 抽成纯函数是为了能直接测:这里的分支决定了「现场点导出会发生什么」,
5
+ * 而它最容易出问题的两个场景——模板没配、模板接口挂了——在页面里很难复现。
6
+ *
7
+ * @author nokecy
8
+ */
9
+ /** 导出模板服务的接口地址:可用模板列表与按模板渲染文件。默认指向 MES 后端的 export-template 服务,其他后端可在 ExportButton 上覆盖。 */
10
+ export interface ExportTemplateApi {
11
+ /** 按页面标识取可用模板(GET,参数 gridKey) */
12
+ options: string;
13
+ /** 按模板渲染并下载(GET,参数 TemplateId、Filter) */
14
+ render: string;
15
+ }
16
+ /** 默认的导出模板服务地址。 */
17
+ export declare const DEFAULT_EXPORT_TEMPLATE_API: ExportTemplateApi;
18
+ /** 后端 `export-template/options` 返回的模板项 */
19
+ export interface ExportTemplateOption {
20
+ id: string;
21
+ name: string;
22
+ isDefault: boolean;
23
+ }
24
+ /** 导出按钮该以什么形态出现 */
25
+ export type ExportAction =
26
+ /** 没有可用模板:走页面自带的旧导出入口 */
27
+ {
28
+ kind: 'legacy';
29
+ }
30
+ /** 只有一个模板:按钮直接导 */
31
+ | {
32
+ kind: 'single';
33
+ template: ExportTemplateOption;
34
+ }
35
+ /** 多个模板:下拉选择 */
36
+ | {
37
+ kind: 'menu';
38
+ templates: ExportTemplateOption[];
39
+ defaultTemplate: ExportTemplateOption;
40
+ };
41
+ /**
42
+ * 根据可用模板决定导出按钮的行为。
43
+ *
44
+ * 传 null / undefined 表示「没拿到模板列表」(接口失败或还没加载),
45
+ * 与「确实一个模板都没配」一样回落到旧导出——模板服务出问题不该让现场导不出数据。
46
+ */
47
+ export declare const resolveExportAction: (templates: ExportTemplateOption[] | null | undefined) => ExportAction;
48
+ /**
49
+ * 导出接口地址。这里已经把参数百分号编码好了(Gridify 的值里可能有 `&` `#` `+`,不编会截断 query string)。
50
+ *
51
+ * <b>因此下载不能走 `downloadBlob`</b>:它内部还会 `encodeURI(url)` 再编一次,
52
+ * `%` 被转义成 `%25`(`boxCode%3D*BOX001` → `boxCode%253D*BOX001`),
53
+ * 后端解析不出筛选串——现场表现是「在列表上筛完点导出,导出的是全量」。
54
+ * 见本目录 index.tsx 里的 `download`。
55
+ */
56
+ export declare const buildExportUrl: (templateId: string, filter?: string | null, renderUrl?: string) => string;
57
+ /**
58
+ * 从响应头取导出文件名。
59
+ *
60
+ * 文件名是运维在模板上配的(可带 {date} 之类的占位),只有服务端知道最终值;
61
+ * 客户端自己起名会让那项配置永远不生效。头里取不到就用兜底名。
62
+ *
63
+ * 后端用 `filename*=UTF-8''xxx`(RFC 5987)传中文名,老式 `filename="xxx"` 也认。
64
+ */
65
+ export declare const resolveFileName: (contentDisposition: string | undefined | null, fallback: string) => string;
66
+ /**
67
+ * 从导出失败的异常里取出给人看的错误信息。
68
+ *
69
+ * 导出请求是 `responseType: 'blob'`,后端返回的 JSON 错误体也会被 axios 当成 blob 收下,
70
+ * `e.response.data.error.message` 这条路永远取不到东西——现场看到的是 axios 自己的
71
+ * "Request failed with status code 500",既不知道是数据太多超时还是模板配错。
72
+ * 所以先把 blob 读回来解析一次。
73
+ */
74
+ export declare const resolveExportError: (error: any) => Promise<string>;
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.resolveFileName = exports.resolveExportError = exports.resolveExportAction = exports.buildExportUrl = exports.DEFAULT_EXPORT_TEMPLATE_API = void 0;
8
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
9
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
10
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
11
+ /**
12
+ * 导出按钮的行为决策与地址构造。
13
+ *
14
+ * 抽成纯函数是为了能直接测:这里的分支决定了「现场点导出会发生什么」,
15
+ * 而它最容易出问题的两个场景——模板没配、模板接口挂了——在页面里很难复现。
16
+ *
17
+ * @author nokecy
18
+ */
19
+
20
+ /** 导出模板服务的接口地址:可用模板列表与按模板渲染文件。默认指向 MES 后端的 export-template 服务,其他后端可在 ExportButton 上覆盖。 */
21
+
22
+ /** 默认的导出模板服务地址。 */
23
+ var DEFAULT_EXPORT_TEMPLATE_API = exports.DEFAULT_EXPORT_TEMPLATE_API = {
24
+ options: '/api/mes/export-template/options',
25
+ render: '/api/mes/export-template/render'
26
+ };
27
+
28
+ /** 后端 `export-template/options` 返回的模板项 */
29
+
30
+ /** 导出按钮该以什么形态出现 */
31
+
32
+ /**
33
+ * 根据可用模板决定导出按钮的行为。
34
+ *
35
+ * 传 null / undefined 表示「没拿到模板列表」(接口失败或还没加载),
36
+ * 与「确实一个模板都没配」一样回落到旧导出——模板服务出问题不该让现场导不出数据。
37
+ */
38
+ var resolveExportAction = exports.resolveExportAction = function resolveExportAction(templates) {
39
+ var _templates$find;
40
+ if (!templates || templates.length === 0) {
41
+ return {
42
+ kind: 'legacy'
43
+ };
44
+ }
45
+ if (templates.length === 1) {
46
+ return {
47
+ kind: 'single',
48
+ template: templates[0]
49
+ };
50
+ }
51
+
52
+ // 后端已按「默认优先、其次按名称」排序,所以取不到 isDefault 时用首个兜底,
53
+ // 不让默认项落空导致下拉没有选中态。
54
+ var defaultTemplate = (_templates$find = templates.find(function (item) {
55
+ return item.isDefault;
56
+ })) !== null && _templates$find !== void 0 ? _templates$find : templates[0];
57
+ return {
58
+ kind: 'menu',
59
+ templates: templates,
60
+ defaultTemplate: defaultTemplate
61
+ };
62
+ };
63
+
64
+ /**
65
+ * 导出接口地址。这里已经把参数百分号编码好了(Gridify 的值里可能有 `&` `#` `+`,不编会截断 query string)。
66
+ *
67
+ * <b>因此下载不能走 `downloadBlob`</b>:它内部还会 `encodeURI(url)` 再编一次,
68
+ * `%` 被转义成 `%25`(`boxCode%3D*BOX001` → `boxCode%253D*BOX001`),
69
+ * 后端解析不出筛选串——现场表现是「在列表上筛完点导出,导出的是全量」。
70
+ * 见本目录 index.tsx 里的 `download`。
71
+ */
72
+ var buildExportUrl = exports.buildExportUrl = function buildExportUrl(templateId, filter) {
73
+ var renderUrl = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_EXPORT_TEMPLATE_API.render;
74
+ var params = new URLSearchParams();
75
+ params.set('TemplateId', templateId);
76
+
77
+ // 空筛选串不拼参数:拼上 Filter= 会让后端把空串当成一个筛选串去解析
78
+ if (filter) {
79
+ params.set('Filter', filter);
80
+ }
81
+ return "".concat(renderUrl, "?").concat(params.toString());
82
+ };
83
+
84
+ /**
85
+ * 从响应头取导出文件名。
86
+ *
87
+ * 文件名是运维在模板上配的(可带 {date} 之类的占位),只有服务端知道最终值;
88
+ * 客户端自己起名会让那项配置永远不生效。头里取不到就用兜底名。
89
+ *
90
+ * 后端用 `filename*=UTF-8''xxx`(RFC 5987)传中文名,老式 `filename="xxx"` 也认。
91
+ */
92
+ var resolveFileName = exports.resolveFileName = function resolveFileName(contentDisposition, fallback) {
93
+ var withExtension = function withExtension(name) {
94
+ return /\.xlsx$/i.test(name) ? name : "".concat(name, ".xlsx");
95
+ };
96
+ if (!contentDisposition) return withExtension(fallback);
97
+ var star = /filename\*=(?:UTF-8'')?([^;]+)/i.exec(contentDisposition);
98
+ if (star !== null && star !== void 0 && star[1]) {
99
+ try {
100
+ return withExtension(decodeURIComponent(star[1].trim().replace(/^"|"$/g, '')));
101
+ } catch (_unused) {
102
+ // 头里的编码坏了不该让整个下载失败,退回兜底名
103
+ }
104
+ }
105
+ var plain = /filename="?([^";]+)"?/i.exec(contentDisposition);
106
+ if (plain !== null && plain !== void 0 && plain[1]) return withExtension(plain[1].trim());
107
+ return withExtension(fallback);
108
+ };
109
+ var readBlobText = function readBlobText(blob) {
110
+ if (typeof blob.text === 'function') return blob.text();
111
+ // 个别环境(旧浏览器、jsdom)的 Blob 没有 text(),用 FileReader 兜底
112
+ return new Promise(function (resolve, reject) {
113
+ var reader = new FileReader();
114
+ reader.onload = function () {
115
+ var _reader$result;
116
+ return resolve(String((_reader$result = reader.result) !== null && _reader$result !== void 0 ? _reader$result : ''));
117
+ };
118
+ reader.onerror = function () {
119
+ return reject(reader.error);
120
+ };
121
+ reader.readAsText(blob);
122
+ });
123
+ };
124
+
125
+ /**
126
+ * 从导出失败的异常里取出给人看的错误信息。
127
+ *
128
+ * 导出请求是 `responseType: 'blob'`,后端返回的 JSON 错误体也会被 axios 当成 blob 收下,
129
+ * `e.response.data.error.message` 这条路永远取不到东西——现场看到的是 axios 自己的
130
+ * "Request failed with status code 500",既不知道是数据太多超时还是模板配错。
131
+ * 所以先把 blob 读回来解析一次。
132
+ */
133
+ var resolveExportError = exports.resolveExportError = /*#__PURE__*/function () {
134
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(error) {
135
+ var _error$response, _data$error;
136
+ var data, _JSON$parse, message;
137
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
138
+ while (1) switch (_context.prev = _context.next) {
139
+ case 0:
140
+ data = error === null || error === void 0 || (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data;
141
+ if (!(typeof Blob !== 'undefined' && data instanceof Blob)) {
142
+ _context.next = 26;
143
+ break;
144
+ }
145
+ _context.prev = 2;
146
+ _context.t2 = JSON;
147
+ _context.next = 6;
148
+ return readBlobText(data);
149
+ case 6:
150
+ _context.t3 = _context.sent;
151
+ _context.t4 = _JSON$parse = _context.t2.parse.call(_context.t2, _context.t3);
152
+ _context.t1 = _context.t4 === null;
153
+ if (_context.t1) {
154
+ _context.next = 11;
155
+ break;
156
+ }
157
+ _context.t1 = _JSON$parse === void 0;
158
+ case 11:
159
+ _context.t0 = _context.t1;
160
+ if (_context.t0) {
161
+ _context.next = 14;
162
+ break;
163
+ }
164
+ _context.t0 = (_JSON$parse = _JSON$parse.error) === null || _JSON$parse === void 0;
165
+ case 14:
166
+ if (!_context.t0) {
167
+ _context.next = 18;
168
+ break;
169
+ }
170
+ _context.t5 = void 0;
171
+ _context.next = 19;
172
+ break;
173
+ case 18:
174
+ _context.t5 = _JSON$parse.message;
175
+ case 19:
176
+ message = _context.t5;
177
+ if (!message) {
178
+ _context.next = 22;
179
+ break;
180
+ }
181
+ return _context.abrupt("return", message);
182
+ case 22:
183
+ _context.next = 26;
184
+ break;
185
+ case 24:
186
+ _context.prev = 24;
187
+ _context.t6 = _context["catch"](2);
188
+ case 26:
189
+ return _context.abrupt("return", (data === null || data === void 0 || (_data$error = data.error) === null || _data$error === void 0 ? void 0 : _data$error.message) || (error === null || error === void 0 ? void 0 : error.message) || '导出失败');
190
+ case 27:
191
+ case "end":
192
+ return _context.stop();
193
+ }
194
+ }, _callee, null, [[2, 24]]);
195
+ }));
196
+ return function resolveExportError(_x) {
197
+ return _ref.apply(this, arguments);
198
+ };
199
+ }();
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { buildExportUrl, DEFAULT_EXPORT_TEMPLATE_API, resolveExportAction, resolveExportError, resolveFileName, type ExportTemplateApi, type ExportTemplateOption } from './exportAction';
3
+ /**
4
+ * 列表页统一导出按钮。
5
+ *
6
+ * <p>导出格式由运维在「导出模板」里配,页面这边只提供 gridKey 和当前筛选条件。
7
+ * 一个页面配了几份模板(各客户各一份),这里就出下拉让人挑。</p>
8
+ *
9
+ * <p><b>没有模板时走 `legacy`</b>——即页面原来那个硬编码的导出接口。
10
+ * 老导出接口保留并存,模板配好之前现场照常能导;模板接口挂了也走这条路。
11
+ * 三种形态(老接口 / 单模板 / 多模板)长得一样,只有多模板时右边多一个下拉箭头,
12
+ * 所以运维配不配模板,操作员那边看到的都是同一个按钮。</p>
13
+ *
14
+ * @author nokecy
15
+ */
16
+ export interface ExportButtonProps {
17
+ /**
18
+ * 发请求的函数,约定与 umi 的 `request` 一致:`request(url, { method, params, responseType, getResponse, skipErrorHandler })`,
19
+ * 传 `getResponse: true` 时返回 `{ data, headers }`。宿主在这里带上自己的鉴权、网关前缀与错误处理。
20
+ */
21
+ request: (url: string, options?: Record<string, any>) => Promise<any>;
22
+ /** 导出模板服务的接口地址,默认 MES 后端的 `/api/mes/export-template/{options,render}` */
23
+ templateApi?: ExportTemplateApi;
24
+ /** 页面标识,取自 `getGridKey(...)`,与导出模板上配的「适用页面」对应 */
25
+ gridKey: string;
26
+ /** 列表当前的 Gridify 筛选串,原样透传给后端 */
27
+ filter?: string;
28
+ /** 没有可用模板时导什么:页面原有导出接口的地址,以及响应头没给文件名时的兜底名 */
29
+ legacy?: {
30
+ url: string;
31
+ fileName: string;
32
+ };
33
+ /** 按钮文字,默认「导出」 */
34
+ children?: React.ReactNode;
35
+ }
36
+ declare const ExportButton: React.FC<ExportButtonProps>;
37
+ export default ExportButton;
38
+ export { buildExportUrl, DEFAULT_EXPORT_TEMPLATE_API, resolveExportAction, resolveExportError, resolveFileName };
39
+ export type { ExportTemplateApi, ExportTemplateOption };
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "DEFAULT_EXPORT_TEMPLATE_API", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _exportAction.DEFAULT_EXPORT_TEMPLATE_API;
11
+ }
12
+ });
13
+ Object.defineProperty(exports, "buildExportUrl", {
14
+ enumerable: true,
15
+ get: function get() {
16
+ return _exportAction.buildExportUrl;
17
+ }
18
+ });
19
+ exports.default = void 0;
20
+ Object.defineProperty(exports, "resolveExportAction", {
21
+ enumerable: true,
22
+ get: function get() {
23
+ return _exportAction.resolveExportAction;
24
+ }
25
+ });
26
+ Object.defineProperty(exports, "resolveExportError", {
27
+ enumerable: true,
28
+ get: function get() {
29
+ return _exportAction.resolveExportError;
30
+ }
31
+ });
32
+ Object.defineProperty(exports, "resolveFileName", {
33
+ enumerable: true,
34
+ get: function get() {
35
+ return _exportAction.resolveFileName;
36
+ }
37
+ });
38
+ var _download = require("../utils/download");
39
+ var _icons = require("@ant-design/icons");
40
+ var _ahooks = require("ahooks");
41
+ var _antd = require("antd");
42
+ var _react = _interopRequireWildcard(require("react"));
43
+ var _exportAction = require("./exportAction");
44
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
45
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
46
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
47
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
48
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
49
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
50
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
51
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
52
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
53
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
54
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
55
+ /**
56
+ * 列表页统一导出按钮。
57
+ *
58
+ * <p>导出格式由运维在「导出模板」里配,页面这边只提供 gridKey 和当前筛选条件。
59
+ * 一个页面配了几份模板(各客户各一份),这里就出下拉让人挑。</p>
60
+ *
61
+ * <p><b>没有模板时走 `legacy`</b>——即页面原来那个硬编码的导出接口。
62
+ * 老导出接口保留并存,模板配好之前现场照常能导;模板接口挂了也走这条路。
63
+ * 三种形态(老接口 / 单模板 / 多模板)长得一样,只有多模板时右边多一个下拉箭头,
64
+ * 所以运维配不配模板,操作员那边看到的都是同一个按钮。</p>
65
+ *
66
+ * @author nokecy
67
+ */
68
+
69
+ var ExportButton = function ExportButton(_ref) {
70
+ var request = _ref.request,
71
+ _ref$templateApi = _ref.templateApi,
72
+ templateApi = _ref$templateApi === void 0 ? _exportAction.DEFAULT_EXPORT_TEMPLATE_API : _ref$templateApi,
73
+ gridKey = _ref.gridKey,
74
+ filter = _ref.filter,
75
+ legacy = _ref.legacy,
76
+ _ref$children = _ref.children,
77
+ children = _ref$children === void 0 ? '导出' : _ref$children;
78
+ var _useRequest = (0, _ahooks.useRequest)(function () {
79
+ return request(templateApi.options, {
80
+ method: 'GET',
81
+ params: {
82
+ gridKey: gridKey
83
+ },
84
+ // 模板服务不可用不该在列表页弹一堆报错——拿不到就当没配模板,走 legacy
85
+ skipErrorHandler: true
86
+ }).catch(function () {
87
+ return null;
88
+ });
89
+ }, {
90
+ refreshDeps: [gridKey]
91
+ }),
92
+ data = _useRequest.data;
93
+ var action = (0, _react.useMemo)(function () {
94
+ return (0, _exportAction.resolveExportAction)(data);
95
+ }, [data]);
96
+ var _useState = (0, _react.useState)(false),
97
+ _useState2 = _slicedToArray(_useState, 2),
98
+ exporting = _useState2[0],
99
+ setExporting = _useState2[1];
100
+
101
+ /**
102
+ * 跑一次导出,全程给反馈。
103
+ *
104
+ * 十万行的导出服务端要跑几十秒,原先从点下去到文件落地界面上没有任何变化,
105
+ * 现场的反应就是「点了没反应」,然后连点——每点一次服务端多跑一遍全量查询。
106
+ * 这里同时做三件事:按钮转圈(antd 的 loading 态本身就吞掉后续点击,顺带防重)、
107
+ * 挂一条不自动消失的提示(等了几十秒的人多半已经在看别处,按钮上那圈他看不见)、
108
+ * 结束时明确说成了还是败了。
109
+ */
110
+ var runExport = /*#__PURE__*/function () {
111
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(task) {
112
+ var hideTip;
113
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
114
+ while (1) switch (_context.prev = _context.next) {
115
+ case 0:
116
+ if (!exporting) {
117
+ _context.next = 2;
118
+ break;
119
+ }
120
+ return _context.abrupt("return");
121
+ case 2:
122
+ setExporting(true);
123
+ hideTip = _antd.message.loading('正在生成导出文件,请稍候…', 0);
124
+ _context.prev = 4;
125
+ _context.next = 7;
126
+ return task();
127
+ case 7:
128
+ _antd.message.success('导出完成');
129
+ _context.next = 17;
130
+ break;
131
+ case 10:
132
+ _context.prev = 10;
133
+ _context.t0 = _context["catch"](4);
134
+ _context.t1 = _antd.message;
135
+ _context.next = 15;
136
+ return (0, _exportAction.resolveExportError)(_context.t0);
137
+ case 15:
138
+ _context.t2 = _context.sent;
139
+ _context.t1.error.call(_context.t1, _context.t2);
140
+ case 17:
141
+ _context.prev = 17;
142
+ hideTip();
143
+ setExporting(false);
144
+ return _context.finish(17);
145
+ case 21:
146
+ case "end":
147
+ return _context.stop();
148
+ }
149
+ }, _callee, null, [[4, 10, 17, 21]]);
150
+ }));
151
+ return function runExport(_x) {
152
+ return _ref2.apply(this, arguments);
153
+ };
154
+ }();
155
+
156
+ /**
157
+ * 按模板导出。
158
+ *
159
+ * 没用公共的 `downloadBlob`,两个原因:
160
+ * ① 它会对已经编码好的 URL 再 `encodeURI` 一次,筛选串里的 `%` 被二次转义,导出就丢筛选;
161
+ * ② 它要求调用方自己起文件名,而文件名是运维在模板上配的(支持 {date} 之类),
162
+ * 只能从响应头里取,写死模板名会让那项配置永远不生效。
163
+ */
164
+ var download = function download(templateId, fallbackName) {
165
+ return runExport( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
166
+ var _headers, _data;
167
+ var response, headers;
168
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
169
+ while (1) switch (_context2.prev = _context2.next) {
170
+ case 0:
171
+ _context2.next = 2;
172
+ return request((0, _exportAction.buildExportUrl)(templateId, filter, templateApi.render), {
173
+ method: 'GET',
174
+ responseType: 'blob',
175
+ getResponse: true,
176
+ skipErrorHandler: true
177
+ });
178
+ case 2:
179
+ response = _context2.sent;
180
+ headers = (_headers = response === null || response === void 0 ? void 0 : response.headers) !== null && _headers !== void 0 ? _headers : {};
181
+ (0, _download.saveAs)((_data = response === null || response === void 0 ? void 0 : response.data) !== null && _data !== void 0 ? _data : response, (0, _exportAction.resolveFileName)(headers['content-disposition'], fallbackName));
182
+ case 5:
183
+ case "end":
184
+ return _context2.stop();
185
+ }
186
+ }, _callee2);
187
+ })));
188
+ };
189
+
190
+ /**
191
+ * 走页面原有的老导出接口。
192
+ *
193
+ * 等价于 `downloadBlob`(老接口的 url 里筛选串没编码,同样靠 `encodeURI` 补),
194
+ * 只是加了 `skipErrorHandler`:错误统一由 `runExport` 报一次,
195
+ * 否则 umi 的全局处理器先弹一次、这里再弹一次。
196
+ */
197
+ var downloadLegacy = function downloadLegacy(target) {
198
+ return runExport( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
199
+ var blob;
200
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
201
+ while (1) switch (_context3.prev = _context3.next) {
202
+ case 0:
203
+ _context3.next = 2;
204
+ return request(encodeURI(target.url), {
205
+ method: 'GET',
206
+ responseType: 'blob',
207
+ skipErrorHandler: true
208
+ });
209
+ case 2:
210
+ blob = _context3.sent;
211
+ (0, _download.saveAs)(blob, target.fileName);
212
+ case 4:
213
+ case "end":
214
+ return _context3.stop();
215
+ }
216
+ }, _callee3);
217
+ })));
218
+ };
219
+ if (action.kind === 'legacy') {
220
+ if (!legacy) return null;
221
+ return /*#__PURE__*/_react.default.createElement(_antd.Tooltip, {
222
+ title: "\u6309\u7CFB\u7EDF\u9ED8\u8BA4\u683C\u5F0F\u5BFC\u51FA\u5F53\u524D\u7B5B\u9009\u7ED3\u679C"
223
+ }, /*#__PURE__*/_react.default.createElement(_antd.Button, {
224
+ type: "primary",
225
+ icon: /*#__PURE__*/_react.default.createElement(_icons.DownloadOutlined, null),
226
+ loading: exporting,
227
+ onClick: function onClick() {
228
+ return void downloadLegacy(legacy);
229
+ }
230
+ }, children));
231
+ }
232
+ if (action.kind === 'single') {
233
+ var template = action.template;
234
+ return /*#__PURE__*/_react.default.createElement(_antd.Tooltip, {
235
+ title: "\u6309\u6A21\u677F\u300C".concat(template.name, "\u300D\u5BFC\u51FA\u5F53\u524D\u7B5B\u9009\u7ED3\u679C")
236
+ }, /*#__PURE__*/_react.default.createElement(_antd.Button, {
237
+ type: "primary",
238
+ icon: /*#__PURE__*/_react.default.createElement(_icons.DownloadOutlined, null),
239
+ loading: exporting,
240
+ onClick: function onClick() {
241
+ return void download(template.id, template.name);
242
+ }
243
+ }, children));
244
+ }
245
+ var templates = action.templates,
246
+ defaultTemplate = action.defaultTemplate;
247
+ return /*#__PURE__*/_react.default.createElement(_antd.Dropdown.Button, {
248
+ type: "primary",
249
+ loading: exporting
250
+ // 导出期间把下拉的 trigger 置空:光有 loading 只拦得住主按钮,下拉照样能展开,
251
+ // 点进去的模板会被上面那道并发守卫静默吃掉——又成了「点了没反应」。
252
+ // 这里不用 disabled,那会把主按钮一起变灰,跟另外两种形态导出中的样子对不上。
253
+ ,
254
+ trigger: exporting ? [] : undefined
255
+ // Dropdown.Button 的 icon 给的是右边那半,正好用来做「这里能展开」的指示;
256
+ // 左边主按钮不吃 icon,只能在 buttonsRender 里补。
257
+ ,
258
+ icon: /*#__PURE__*/_react.default.createElement(_icons.DownOutlined, null),
259
+ onClick: function onClick() {
260
+ return void download(defaultTemplate.id, defaultTemplate.name);
261
+ },
262
+ menu: {
263
+ items: templates.map(function (item) {
264
+ return {
265
+ key: item.id,
266
+ // 标出默认项,让人对得上主按钮直接导的是哪一份
267
+ label: item.id === defaultTemplate.id ? "".concat(item.name, "\uFF08\u9ED8\u8BA4\uFF09") : item.name,
268
+ onClick: function onClick() {
269
+ return void download(item.id, item.name);
270
+ }
271
+ };
272
+ })
273
+ }
274
+ // Tooltip 包在主按钮上而不是整个 Dropdown.Button 外面:DropdownButton 是普通函数组件、
275
+ // 没有 forwardRef,Tooltip 拿不到它的 DOM(React 会报 refs 警告,气泡定位也不准)。
276
+ ,
277
+ buttonsRender: function buttonsRender(_ref5) {
278
+ var _ref6 = _slicedToArray(_ref5, 2),
279
+ mainButton = _ref6[0],
280
+ arrowButton = _ref6[1];
281
+ return [/*#__PURE__*/_react.default.createElement(_antd.Tooltip, {
282
+ key: "main",
283
+ title: "\u6309\u6A21\u677F\u300C".concat(defaultTemplate.name, "\u300D\u5BFC\u51FA\uFF1B\u70B9\u53F3\u4FA7\u7BAD\u5934\u53EF\u6362\u5176\u5B83\u683C\u5F0F")
284
+ }, /*#__PURE__*/_react.default.cloneElement(mainButton, {
285
+ icon: /*#__PURE__*/_react.default.createElement(_icons.DownloadOutlined, null)
286
+ })),
287
+ /*#__PURE__*/
288
+ // 右半边 antd 不给传 disabled,导出期间它看着能点其实点不开,得自己补上
289
+ _react.default.cloneElement(arrowButton, {
290
+ disabled: exporting
291
+ })];
292
+ }
293
+ }, children);
294
+ };
295
+ var _default = exports.default = ExportButton;
@@ -18,6 +18,15 @@ export interface ImportModalProps {
18
18
  serverUrl?: () => string;
19
19
  /** 按钮属性 */
20
20
  buttonProps?: any;
21
+ /**
22
+ * 发上传请求的函数,约定与 umi 的 `request` 一致:`request(url, { method, data, headers, skipErrorHandler, onUploadProgress })`。
23
+ * 传入后上传改走它(宿主在这里带上自己的鉴权与网关前缀);不传则由 antd Upload 直接请求 `action`。
24
+ */
25
+ request?: (url: string, options?: Record<string, any>) => Promise<any>;
26
+ /** 上传请求的方法,仅配合 `request` 使用,默认 POST */
27
+ method?: string;
28
+ /** 上传请求成功后的回调,参数是接口响应(早于「导入成功」提示);仅配合 `request` 使用 */
29
+ onRealSuccess?: (response: any) => void;
21
30
  }
22
31
  /**
23
32
  * 通用导入弹出框