amis 1.8.0-beta.13 → 1.8.0-beta.15

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 (84) hide show
  1. package/lib/WithStore.js +1 -1
  2. package/lib/WithStore.js.map +2 -2
  3. package/lib/components/DatePicker.js +3 -1
  4. package/lib/components/DatePicker.js.map +2 -2
  5. package/lib/components/Tree.js +3 -1
  6. package/lib/components/Tree.js.map +2 -2
  7. package/lib/helper.css +1 -1
  8. package/lib/helper.css.map +1 -1
  9. package/lib/index.js +1 -1
  10. package/lib/renderers/Date.js +6 -1
  11. package/lib/renderers/Date.js.map +2 -2
  12. package/lib/renderers/Form/TreeSelect.js.map +2 -2
  13. package/lib/renderers/Nav.d.ts +21 -20
  14. package/lib/renderers/Nav.js +8 -1
  15. package/lib/renderers/Nav.js.map +2 -2
  16. package/lib/renderers/Page.js +1 -1
  17. package/lib/renderers/Page.js.map +2 -2
  18. package/lib/renderers/Service.js +1 -1
  19. package/lib/renderers/Service.js.map +2 -2
  20. package/lib/renderers/Table/exportExcel.d.ts +6 -0
  21. package/lib/renderers/Table/exportExcel.js +288 -0
  22. package/lib/renderers/Table/exportExcel.js.map +13 -0
  23. package/lib/renderers/Table/index.d.ts +1 -1
  24. package/lib/renderers/Table/index.js +4 -251
  25. package/lib/renderers/Table/index.js.map +2 -2
  26. package/lib/themes/ang-ie11.css +18 -15
  27. package/lib/themes/ang.css +4 -0
  28. package/lib/themes/ang.css.map +1 -1
  29. package/lib/themes/antd-ie11.css +18 -15
  30. package/lib/themes/antd.css +4 -0
  31. package/lib/themes/antd.css.map +1 -1
  32. package/lib/themes/cxd-ie11.css +3 -0
  33. package/lib/themes/cxd.css +4 -0
  34. package/lib/themes/cxd.css.map +1 -1
  35. package/lib/themes/dark-ie11.css +18 -15
  36. package/lib/themes/dark.css +4 -0
  37. package/lib/themes/dark.css.map +1 -1
  38. package/lib/themes/default-ie11.css +3 -0
  39. package/lib/themes/default.css +4 -0
  40. package/lib/themes/default.css.map +1 -1
  41. package/lib/utils/api.js +28 -6
  42. package/lib/utils/api.js.map +2 -2
  43. package/package.json +1 -1
  44. package/scss/_properties.scss +1 -0
  45. package/scss/components/form/_date.scss +1 -0
  46. package/scss/helper/layout/_display.scss +1 -1
  47. package/sdk/ang-ie11.css +19 -15
  48. package/sdk/ang.css +5 -0
  49. package/sdk/antd-ie11.css +19 -15
  50. package/sdk/antd.css +5 -0
  51. package/sdk/barcode.js +51 -51
  52. package/sdk/charts.js +14 -14
  53. package/sdk/codemirror.js +7 -7
  54. package/sdk/color-picker.js +65 -65
  55. package/sdk/cropperjs.js +2 -2
  56. package/sdk/cxd-ie11.css +4 -0
  57. package/sdk/cxd.css +5 -0
  58. package/sdk/dark-ie11.css +19 -15
  59. package/sdk/dark.css +5 -0
  60. package/sdk/exceljs.js +1 -1
  61. package/sdk/helper.css +1 -1
  62. package/sdk/helper.css.map +1 -1
  63. package/sdk/markdown.js +69 -69
  64. package/sdk/papaparse.js +1 -1
  65. package/sdk/renderers/Form/CityDB.js +1 -1
  66. package/sdk/rest.js +17 -17
  67. package/sdk/rich-text.js +62 -62
  68. package/sdk/sdk-ie11.css +4 -0
  69. package/sdk/sdk.css +5 -0
  70. package/sdk/sdk.js +1269 -1267
  71. package/sdk/thirds/hls.js/hls.js +1 -1
  72. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  73. package/sdk/tinymce.js +57 -57
  74. package/src/WithStore.tsx +1 -1
  75. package/src/components/DatePicker.tsx +2 -1
  76. package/src/components/Tree.tsx +3 -1
  77. package/src/renderers/Date.tsx +14 -1
  78. package/src/renderers/Form/TreeSelect.tsx +15 -12
  79. package/src/renderers/Nav.tsx +7 -1
  80. package/src/renderers/Page.tsx +9 -2
  81. package/src/renderers/Service.tsx +8 -2
  82. package/src/renderers/Table/exportExcel.ts +289 -0
  83. package/src/renderers/Table/index.tsx +5 -252
  84. package/src/utils/api.ts +36 -10
@@ -59,6 +59,9 @@ import ColumnToggler from './ColumnToggler';
59
59
  import {BadgeSchema} from '../../components/Badge';
60
60
  import offset from '../../utils/offset';
61
61
  import {getStyleNumber} from '../../utils/dom';
62
+ import {DateSchema} from '../Date';
63
+ import moment from 'moment';
64
+ import {exportExcel} from './exportExcel';
62
65
 
63
66
  /**
64
67
  * 表格列,不指定类型时默认为文本类型。
@@ -367,25 +370,13 @@ export interface TableProps extends RendererProps {
367
370
  itemBadge?: BadgeSchema;
368
371
  }
369
372
 
370
- type ExportExcelToolbar = SchemaNode & {
373
+ export type ExportExcelToolbar = SchemaNode & {
371
374
  api?: SchemaApi;
372
375
  columns?: string[];
373
376
  exportColumns?: any[];
374
377
  filename?: string;
375
378
  };
376
379
 
377
- /**
378
- * 将 url 转成绝对地址
379
- */
380
- const getAbsoluteUrl = (function () {
381
- let link: HTMLAnchorElement;
382
- return function (url: string) {
383
- if (!link) link = document.createElement('a');
384
- link.href = url;
385
- return link.href;
386
- };
387
- })();
388
-
389
380
  export default class Table extends React.Component<TableProps, object> {
390
381
  static propsList: Array<string> = [
391
382
  'header',
@@ -2281,245 +2272,7 @@ export default class Table extends React.Component<TableProps, object> {
2281
2272
  {
2282
2273
  onAction: () => {
2283
2274
  import('exceljs').then(async (ExcelJS: any) => {
2284
- let rows = [];
2285
- let tmpStore;
2286
- let filename = 'data';
2287
- // 支持配置 api 远程获取
2288
- if (typeof toolbar === 'object' && toolbar.api) {
2289
- const res = await env.fetcher(toolbar.api, data);
2290
- if (!res.data) {
2291
- env.notify('warning', __('placeholder.noData'));
2292
- return;
2293
- }
2294
- if (Array.isArray(res.data)) {
2295
- rows = res.data;
2296
- } else {
2297
- rows = res.data.rows || res.data.items;
2298
- }
2299
- // 因为很多方法是 store 里的,所以需要构建 store 来处理
2300
- tmpStore = TableStore.create(getSnapshot(store));
2301
- tmpStore.initRows(rows);
2302
- rows = tmpStore.rows;
2303
- } else {
2304
- rows = store.rows;
2305
- }
2306
-
2307
- if (typeof toolbar === 'object' && toolbar.filename) {
2308
- filename = filter(toolbar.filename, data, '| raw');
2309
- }
2310
-
2311
- if (rows.length === 0) {
2312
- env.notify('warning', __('placeholder.noData'));
2313
- return;
2314
- }
2315
-
2316
- const workbook = new ExcelJS.Workbook();
2317
- const worksheet = workbook.addWorksheet('sheet', {
2318
- properties: {defaultColWidth: 15}
2319
- });
2320
- worksheet.views = [{state: 'frozen', xSplit: 0, ySplit: 1}];
2321
-
2322
- let exportColumnNames = toolbar.columns;
2323
-
2324
- if (isPureVariable(exportColumnNames)) {
2325
- exportColumnNames = resolveVariableAndFilter(
2326
- exportColumnNames,
2327
- data,
2328
- '| raw'
2329
- );
2330
- }
2331
-
2332
- // 自定义导出列配置
2333
- if (toolbar.exportColumns && Array.isArray(toolbar.exportColumns)) {
2334
- columns = toolbar.exportColumns;
2335
- }
2336
-
2337
- const filteredColumns = exportColumnNames
2338
- ? columns.filter(column => {
2339
- const filterColumnsNames = exportColumnNames!;
2340
- if (
2341
- column.name &&
2342
- filterColumnsNames.indexOf(column.name) !== -1
2343
- ) {
2344
- return true;
2345
- }
2346
- return false;
2347
- })
2348
- : columns;
2349
-
2350
- const firstRowLabels = filteredColumns.map(column => {
2351
- return column.label;
2352
- });
2353
- const firstRow = worksheet.getRow(1);
2354
- firstRow.values = firstRowLabels;
2355
- worksheet.autoFilter = {
2356
- from: {
2357
- row: 1,
2358
- column: 1
2359
- },
2360
- to: {
2361
- row: 1,
2362
- column: firstRowLabels.length
2363
- }
2364
- };
2365
- // 用于 mapping source 的情况
2366
- const remoteMappingCache: any = {};
2367
- // 数据从第二行开始
2368
- let rowIndex = 1;
2369
- for (const row of rows) {
2370
- rowIndex += 1;
2371
- const sheetRow = worksheet.getRow(rowIndex);
2372
- let columIndex = 0;
2373
- for (const column of filteredColumns) {
2374
- columIndex += 1;
2375
- const name = column.name!;
2376
- const value = getVariable(row.data, name);
2377
- if (
2378
- typeof value === 'undefined' &&
2379
- !(column as TplSchema).tpl
2380
- ) {
2381
- continue;
2382
- }
2383
- // 处理合并单元格
2384
- if (name in row.rowSpans) {
2385
- if (row.rowSpans[name] === 0) {
2386
- continue;
2387
- } else {
2388
- // start row, start column, end row, end column
2389
- worksheet.mergeCells(
2390
- rowIndex,
2391
- columIndex,
2392
- rowIndex + row.rowSpans[name] - 1,
2393
- columIndex
2394
- );
2395
- }
2396
- }
2397
-
2398
- const type = (column as BaseSchema).type || 'plain';
2399
- if (type === 'image' && value) {
2400
- try {
2401
- const imageData = await toDataURL(value);
2402
- const imageDimensions = await getImageDimensions(imageData);
2403
- let imageWidth = imageDimensions.width;
2404
- let imageHeight = imageDimensions.height;
2405
- // 限制一下图片高宽
2406
- const imageMaxSize = 100;
2407
- if (imageWidth > imageHeight) {
2408
- if (imageWidth > imageMaxSize) {
2409
- imageHeight = (imageMaxSize * imageHeight) / imageWidth;
2410
- imageWidth = imageMaxSize;
2411
- }
2412
- } else {
2413
- if (imageHeight > imageMaxSize) {
2414
- imageWidth = (imageMaxSize * imageWidth) / imageHeight;
2415
- imageHeight = imageMaxSize;
2416
- }
2417
- }
2418
- const imageMatch = imageData.match(/data:image\/(.*);/);
2419
- let imageExt = 'png';
2420
- if (imageMatch) {
2421
- imageExt = imageMatch[1];
2422
- }
2423
- // 目前 excel 只支持这些格式,所以其它格式直接输出 url
2424
- if (
2425
- imageExt != 'png' &&
2426
- imageExt != 'jpeg' &&
2427
- imageExt != 'gif'
2428
- ) {
2429
- sheetRow.getCell(columIndex).value = value;
2430
- continue;
2431
- }
2432
- const imageId = workbook.addImage({
2433
- base64: imageData,
2434
- extension: imageExt
2435
- });
2436
- const linkURL = getAbsoluteUrl(value);
2437
- worksheet.addImage(imageId, {
2438
- // 这里坐标位置是从 0 开始的,所以要减一
2439
- tl: {col: columIndex - 1, row: rowIndex - 1},
2440
- ext: {
2441
- width: imageWidth,
2442
- height: imageHeight
2443
- },
2444
- hyperlinks: {
2445
- tooltip: linkURL
2446
- }
2447
- });
2448
- } catch (e) {
2449
- console.warn(e.stack);
2450
- }
2451
- } else if (type == 'link') {
2452
- const linkURL = getAbsoluteUrl(value);
2453
- sheetRow.getCell(columIndex).value = {
2454
- text: value,
2455
- hyperlink: linkURL
2456
- };
2457
- } else if (type === 'mapping') {
2458
- // 拷贝自 Mapping.tsx
2459
- let map = (column as MappingSchema).map;
2460
- const source = (column as MappingSchema).source;
2461
- if (source) {
2462
- let sourceValue = source;
2463
- if (isPureVariable(source)) {
2464
- sourceValue = resolveVariableAndFilter(
2465
- source as string,
2466
- data,
2467
- '| raw'
2468
- );
2469
- }
2470
-
2471
- const mapKey = JSON.stringify(source);
2472
- if (mapKey in remoteMappingCache) {
2473
- map = remoteMappingCache[mapKey];
2474
- } else {
2475
- const res = await env.fetcher(sourceValue, data);
2476
- if (res.data) {
2477
- remoteMappingCache[mapKey] = res.data;
2478
- map = res.data;
2479
- }
2480
- }
2481
- }
2482
-
2483
- if (
2484
- typeof value !== 'undefined' &&
2485
- map &&
2486
- (map[value] ?? map['*'])
2487
- ) {
2488
- const viewValue =
2489
- map[value] ??
2490
- (value === true && map['1']
2491
- ? map['1']
2492
- : value === false && map['0']
2493
- ? map['0']
2494
- : map['*']); // 兼容平台旧用法:即 value 为 true 时映射 1 ,为 false 时映射 0
2495
- sheetRow.getCell(columIndex).value =
2496
- removeHTMLTag(viewValue);
2497
- } else {
2498
- sheetRow.getCell(columIndex).value = removeHTMLTag(value);
2499
- }
2500
- } else {
2501
- if ((column as TplSchema).tpl) {
2502
- sheetRow.getCell(columIndex).value = removeHTMLTag(
2503
- filter(
2504
- (column as TplSchema).tpl,
2505
- createObject(data, row.data)
2506
- )
2507
- );
2508
- } else {
2509
- sheetRow.getCell(columIndex).value = value;
2510
- }
2511
- }
2512
- }
2513
- }
2514
-
2515
- const buffer = await workbook.xlsx.writeBuffer();
2516
-
2517
- if (buffer) {
2518
- var blob = new Blob([buffer], {
2519
- type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
2520
- });
2521
- saveAs(blob, filename + '.xlsx');
2522
- }
2275
+ exportExcel(ExcelJS, this.props, toolbar);
2523
2276
  });
2524
2277
  }
2525
2278
  }
package/src/utils/api.ts CHANGED
@@ -12,10 +12,12 @@ import {
12
12
  cloneObject,
13
13
  createObject,
14
14
  qsparse,
15
- uuid
15
+ uuid,
16
+ JSONTraverse
16
17
  } from './helper';
17
18
  import isPlainObject from 'lodash/isPlainObject';
18
19
  import {debug} from './debug';
20
+ import {evaluate, parse} from 'amis-formula';
19
21
 
20
22
  const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head|jsonp):/i;
21
23
 
@@ -94,24 +96,48 @@ export function buildApi(
94
96
  }
95
97
 
96
98
  const raw = (api.url = api.url || '');
97
- const idx = api.url.indexOf('?');
99
+ const ast: any = parse(api.url);
100
+ const url = ast.body
101
+ .map((item: any, index: number) => {
102
+ return item.type === 'raw' ? item.value : `__expression__${index}__`;
103
+ })
104
+ .join('');
105
+
106
+ const idx = url.indexOf('?');
107
+ let replaceExpression = (fragment: string) => {
108
+ return fragment.replace(
109
+ /__expression__(\d+)__/g,
110
+ (_: any, index: string) => {
111
+ return evaluate(ast.body[index], data, {
112
+ defaultFilter: 'url_encode'
113
+ });
114
+ }
115
+ );
116
+ };
98
117
 
99
118
  if (~idx) {
100
- const hashIdx = api.url.indexOf('#');
119
+ const hashIdx = url.indexOf('#');
101
120
  const params = qsparse(
102
- api.url.substring(
103
- idx + 1,
104
- ~hashIdx && hashIdx > idx ? hashIdx : undefined
105
- )
121
+ url.substring(idx + 1, ~hashIdx && hashIdx > idx ? hashIdx : undefined)
106
122
  );
123
+
124
+ // 将里面的表达式运算完
125
+ JSONTraverse(params, (value: any, key: string | number, host: any) => {
126
+ if (typeof value === 'string' && /^__expression__(\d+)__$/.test(value)) {
127
+ host[key] = evaluate(ast.body[RegExp.$1].body, data);
128
+ }
129
+ });
130
+
107
131
  api.url =
108
- tokenize(api.url.substring(0, idx + 1), data, '| url_encode') +
132
+ replaceExpression(url.substring(0, idx + 1)) +
109
133
  qsstringify(
110
134
  (api.query = dataMapping(params, data, undefined, api.convertKeyToPath))
111
135
  ) +
112
- (~hashIdx && hashIdx > idx ? api.url.substring(hashIdx) : '');
136
+ (~hashIdx && hashIdx > idx
137
+ ? replaceExpression(url.substring(hashIdx))
138
+ : '');
113
139
  } else {
114
- api.url = tokenize(api.url, data, '| url_encode');
140
+ api.url = replaceExpression(url);
115
141
  }
116
142
 
117
143
  if (ignoreData) {