xt-element-ui 2.2.2 → 2.2.4

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 (153) hide show
  1. package/README.md +140 -192
  2. package/docs/README.md +162 -81
  3. package/docs/components/base/theme.md +248 -0
  4. package/docs/components/base/xt-button.md +11 -4
  5. package/docs/components/base/xt-card.md +5 -11
  6. package/docs/components/base/xt-config-provider.md +2 -0
  7. package/docs/components/base/xt-flow.md +404 -0
  8. package/docs/components/base/xt-list.md +1 -1
  9. package/docs/components/base/xt-multi.md +5 -5
  10. package/docs/components/base/xt-scroll-arrow.md +87 -1
  11. package/docs/components/base/xt-scroll.md +237 -0
  12. package/docs/components/business/xt-chart.md +1 -0
  13. package/docs/components/utils/config.md +18 -4
  14. package/docs/components/utils/theme.md +280 -183
  15. package/lib/index.common.1.js +4 -26
  16. package/lib/index.common.2.js +1 -1
  17. package/lib/index.common.js +4577 -109925
  18. package/lib/index.css +1 -1
  19. package/lib/index.umd.1.js +4 -26
  20. package/lib/index.umd.2.js +1 -1
  21. package/lib/index.umd.js +4583 -109930
  22. package/lib/index.umd.min.1.js +1 -1
  23. package/lib/index.umd.min.js +1 -1
  24. package/lib/theme/element-overrides.css +607 -0
  25. package/lib/theme/element-vars.css +280 -0
  26. package/lib/xt-badge/xt-badge.common.js +1 -1
  27. package/lib/xt-badge/xt-badge.css +1 -1
  28. package/lib/xt-badge/xt-badge.umd.js +1 -1
  29. package/lib/xt-button/xt-button.common.js +13 -8
  30. package/lib/xt-button/xt-button.css +1 -1
  31. package/lib/xt-button/xt-button.umd.js +13 -8
  32. package/lib/xt-button/xt-button.umd.min.js +1 -1
  33. package/lib/xt-card/xt-card.common.js +5 -5
  34. package/lib/xt-card/xt-card.umd.js +5 -5
  35. package/lib/xt-card/xt-card.umd.min.js +1 -1
  36. package/lib/xt-card-item/xt-card-item.common.js +4 -4
  37. package/lib/xt-card-item/xt-card-item.umd.js +4 -4
  38. package/lib/xt-card-item/xt-card-item.umd.min.js +1 -1
  39. package/lib/xt-chart/xt-chart.common.js +1969 -108924
  40. package/lib/xt-chart/xt-chart.css +1 -1
  41. package/lib/xt-chart/xt-chart.umd.js +1975 -108929
  42. package/lib/xt-chart/xt-chart.umd.min.js +1 -1
  43. package/lib/xt-config-provider/xt-config-provider.common.js +561 -107504
  44. package/lib/xt-config-provider/xt-config-provider.css +1 -1
  45. package/lib/xt-config-provider/xt-config-provider.umd.js +567 -107509
  46. package/lib/xt-config-provider/xt-config-provider.umd.min.js +1 -1
  47. package/lib/xt-date-picker/xt-date-picker.common.1.js +4 -26
  48. package/lib/xt-date-picker/xt-date-picker.common.2.js +1 -1
  49. package/lib/xt-date-picker/xt-date-picker.common.js +1 -47
  50. package/lib/xt-date-picker/xt-date-picker.css +1 -1
  51. package/lib/xt-date-picker/xt-date-picker.umd.1.js +4 -26
  52. package/lib/xt-date-picker/xt-date-picker.umd.2.js +1 -1
  53. package/lib/xt-date-picker/xt-date-picker.umd.js +1 -47
  54. package/lib/xt-date-picker/xt-date-picker.umd.min.1.js +1 -1
  55. package/lib/xt-date-picker/xt-date-picker.umd.min.js +1 -1
  56. package/lib/xt-flex-box/xt-flex-box.common.js +1 -1
  57. package/lib/xt-flex-box/xt-flex-box.umd.js +1 -1
  58. package/lib/xt-flow/demo.html +10 -0
  59. package/lib/xt-flow/index.js +1 -0
  60. package/lib/xt-flow/xt-flow.common.js +638 -0
  61. package/lib/xt-flow/xt-flow.css +1 -0
  62. package/lib/xt-flow/xt-flow.umd.js +648 -0
  63. package/lib/xt-flow/xt-flow.umd.min.js +1 -0
  64. package/lib/xt-form-schema/xt-form-schema.common.js +1 -1
  65. package/lib/xt-form-schema/xt-form-schema.umd.js +1 -1
  66. package/lib/xt-grid-box/xt-grid-box.common.js +1 -1
  67. package/lib/xt-grid-box/xt-grid-box.umd.js +1 -1
  68. package/lib/xt-grid-item/xt-grid-item.common.js +1 -1
  69. package/lib/xt-grid-item/xt-grid-item.umd.js +1 -1
  70. package/lib/xt-icon/xt-icon.common.js +1 -1
  71. package/lib/xt-icon/xt-icon.umd.js +1 -1
  72. package/lib/xt-input/xt-input.common.js +1 -1
  73. package/lib/xt-input/xt-input.umd.js +1 -1
  74. package/lib/xt-list/xt-list.common.js +457 -118
  75. package/lib/xt-list/xt-list.css +1 -1
  76. package/lib/xt-list/xt-list.umd.js +457 -118
  77. package/lib/xt-list/xt-list.umd.min.js +1 -1
  78. package/lib/xt-map/xt-map.common.js +1 -1
  79. package/lib/xt-map/xt-map.umd.js +1 -1
  80. package/lib/xt-map-provider/xt-map-provider.common.js +1 -1
  81. package/lib/xt-map-provider/xt-map-provider.umd.js +1 -1
  82. package/lib/xt-page/xt-page.common.js +1 -1
  83. package/lib/xt-page/xt-page.umd.js +1 -1
  84. package/lib/xt-progress/xt-progress.common.js +1 -1
  85. package/lib/xt-progress/xt-progress.umd.js +1 -1
  86. package/lib/xt-scroll/demo.html +10 -0
  87. package/lib/xt-scroll/index.js +1 -0
  88. package/lib/xt-scroll/xt-scroll.common.js +551 -0
  89. package/lib/xt-scroll/xt-scroll.css +1 -0
  90. package/lib/xt-scroll/xt-scroll.umd.js +561 -0
  91. package/lib/xt-scroll/xt-scroll.umd.min.js +1 -0
  92. package/lib/xt-scroll-arrow/xt-scroll-arrow.common.js +591 -170
  93. package/lib/xt-scroll-arrow/xt-scroll-arrow.css +1 -1
  94. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.js +591 -170
  95. package/lib/xt-scroll-arrow/xt-scroll-arrow.umd.min.js +1 -1
  96. package/lib/xt-select-tree/xt-select-tree.common.js +1 -1
  97. package/lib/xt-select-tree/xt-select-tree.umd.js +1 -1
  98. package/lib/xt-step-price/xt-step-price.common.js +2 -2
  99. package/lib/xt-step-price/xt-step-price.umd.js +2 -2
  100. package/lib/xt-step-price-item/xt-step-price-item.common.js +1 -1
  101. package/lib/xt-step-price-item/xt-step-price-item.umd.js +1 -1
  102. package/lib/xt-tab-pane/xt-tab-pane.common.js +1 -1
  103. package/lib/xt-tab-pane/xt-tab-pane.umd.js +1 -1
  104. package/lib/xt-table/xt-table.common.js +2 -2
  105. package/lib/xt-table/xt-table.umd.js +2 -2
  106. package/lib/xt-tabs/xt-tabs.common.js +1 -1
  107. package/lib/xt-tabs/xt-tabs.umd.js +1 -1
  108. package/lib/xt-text/xt-text.common.js +1 -1
  109. package/lib/xt-text/xt-text.css +1 -1
  110. package/lib/xt-text/xt-text.umd.js +1 -1
  111. package/lib/xt-time/xt-time.common.js +1 -1
  112. package/lib/xt-time/xt-time.umd.js +1 -1
  113. package/lib/xt-transfer-tree/xt-transfer-tree.common.js +1 -1
  114. package/lib/xt-transfer-tree/xt-transfer-tree.umd.js +1 -1
  115. package/lib/xt-upload/xt-upload.common.js +11 -11
  116. package/lib/xt-upload/xt-upload.umd.js +12 -12
  117. package/lib/xt-upload/xt-upload.umd.min.js +1 -1
  118. package/package.json +6 -5
  119. package/src/components/index.scss +7 -1
  120. package/src/components/theme/element-overrides.css +607 -0
  121. package/src/components/theme/element-vars.css +280 -0
  122. package/src/components/theme/iframe-injector.js +502 -0
  123. package/src/components/theme/index.js +64 -0
  124. package/src/components/xt-badge/style/index.scss +6 -6
  125. package/src/components/xt-button/index.vue +11 -6
  126. package/src/components/xt-button/style/index.scss +7 -5
  127. package/src/components/xt-card/index.vue +3 -3
  128. package/src/components/xt-card-item/index.vue +2 -2
  129. package/src/components/xt-chart/XtMulti.vue +8 -18
  130. package/src/components/xt-chart/XtPie.vue +1 -0
  131. package/src/components/xt-chart/utils.js +84 -50
  132. package/src/components/xt-config-provider/index.vue +56 -54
  133. package/src/components/xt-config-provider/style/index.scss +0 -11
  134. package/src/components/xt-date-picker/component/RangeDate.vue +1 -29
  135. package/src/components/xt-date-picker/style/index.scss +79 -54
  136. package/src/components/xt-flow/flowable-parser.js +244 -0
  137. package/src/components/xt-flow/index.js +8 -0
  138. package/src/components/xt-flow/index.vue +226 -0
  139. package/src/components/xt-flow/style/index.scss +359 -0
  140. package/src/components/xt-list/index.vue +23 -12
  141. package/src/components/xt-scroll/index.js +9 -0
  142. package/src/components/xt-scroll/index.vue +363 -0
  143. package/src/components/xt-scroll/style/index.scss +107 -0
  144. package/src/components/xt-scroll-arrow/index.vue +200 -83
  145. package/src/components/xt-scroll-arrow/style/index.scss +16 -5
  146. package/src/components/xt-text/style/index.scss +6 -6
  147. package/src/index.js +15 -13
  148. package/src/styles/css-variables.scss +73 -1
  149. package/src/utils/color.js +105 -0
  150. package/src/utils/index.js +456 -468
  151. package/src/utils/theme-vars.js +134 -0
  152. package/lib/css/1.87a493be.css +0 -1
  153. package/lib/xt-date-picker/css/1.87a493be.css +0 -1
@@ -0,0 +1,638 @@
1
+ module.exports =
2
+ /******/ (function(modules) { // webpackBootstrap
3
+ /******/ // The module cache
4
+ /******/ var installedModules = {};
5
+ /******/
6
+ /******/ // The require function
7
+ /******/ function __webpack_require__(moduleId) {
8
+ /******/
9
+ /******/ // Check if module is in cache
10
+ /******/ if(installedModules[moduleId]) {
11
+ /******/ return installedModules[moduleId].exports;
12
+ /******/ }
13
+ /******/ // Create a new module (and put it into the cache)
14
+ /******/ var module = installedModules[moduleId] = {
15
+ /******/ i: moduleId,
16
+ /******/ l: false,
17
+ /******/ exports: {}
18
+ /******/ };
19
+ /******/
20
+ /******/ // Execute the module function
21
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22
+ /******/
23
+ /******/ // Flag the module as loaded
24
+ /******/ module.l = true;
25
+ /******/
26
+ /******/ // Return the exports of the module
27
+ /******/ return module.exports;
28
+ /******/ }
29
+ /******/
30
+ /******/
31
+ /******/ // expose the modules object (__webpack_modules__)
32
+ /******/ __webpack_require__.m = modules;
33
+ /******/
34
+ /******/ // expose the module cache
35
+ /******/ __webpack_require__.c = installedModules;
36
+ /******/
37
+ /******/ // define getter function for harmony exports
38
+ /******/ __webpack_require__.d = function(exports, name, getter) {
39
+ /******/ if(!__webpack_require__.o(exports, name)) {
40
+ /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41
+ /******/ }
42
+ /******/ };
43
+ /******/
44
+ /******/ // define __esModule on exports
45
+ /******/ __webpack_require__.r = function(exports) {
46
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48
+ /******/ }
49
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
50
+ /******/ };
51
+ /******/
52
+ /******/ // create a fake namespace object
53
+ /******/ // mode & 1: value is a module id, require it
54
+ /******/ // mode & 2: merge all properties of value into the ns
55
+ /******/ // mode & 4: return value when already ns object
56
+ /******/ // mode & 8|1: behave like require
57
+ /******/ __webpack_require__.t = function(value, mode) {
58
+ /******/ if(mode & 1) value = __webpack_require__(value);
59
+ /******/ if(mode & 8) return value;
60
+ /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61
+ /******/ var ns = Object.create(null);
62
+ /******/ __webpack_require__.r(ns);
63
+ /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64
+ /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65
+ /******/ return ns;
66
+ /******/ };
67
+ /******/
68
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
69
+ /******/ __webpack_require__.n = function(module) {
70
+ /******/ var getter = module && module.__esModule ?
71
+ /******/ function getDefault() { return module['default']; } :
72
+ /******/ function getModuleExports() { return module; };
73
+ /******/ __webpack_require__.d(getter, 'a', getter);
74
+ /******/ return getter;
75
+ /******/ };
76
+ /******/
77
+ /******/ // Object.prototype.hasOwnProperty.call
78
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79
+ /******/
80
+ /******/ // __webpack_public_path__
81
+ /******/ __webpack_require__.p = "";
82
+ /******/
83
+ /******/
84
+ /******/ // Load entry module and return exports
85
+ /******/ return __webpack_require__(__webpack_require__.s = "fb15");
86
+ /******/ })
87
+ /************************************************************************/
88
+ /******/ ({
89
+
90
+ /***/ "fb15":
91
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
92
+
93
+ "use strict";
94
+ // ESM COMPAT FLAG
95
+ __webpack_require__.r(__webpack_exports__);
96
+
97
+ // CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
98
+ // This file is imported into lib/wc client bundles.
99
+
100
+ if (typeof window !== 'undefined') {
101
+ var currentScript = window.document.currentScript
102
+ if (false) { var getCurrentScript; }
103
+
104
+ var src = currentScript && currentScript.src.match(/(.+\/)[^/]+\.js(\?.*)?$/)
105
+ if (src) {
106
+ __webpack_require__.p = src[1] // eslint-disable-line
107
+ }
108
+ }
109
+
110
+ // Indicate to webpack that this file can be concatenated
111
+ /* harmony default export */ var setPublicPath = (null);
112
+
113
+ // EXTERNAL MODULE: ./src/components/xt-flow/style/index.scss
114
+ var style = __webpack_require__("fdbd");
115
+
116
+ // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"1d9e3ae5-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??ref--5!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/xt-flow/index.vue?vue&type=template&id=05a25f5f
117
+ var render = function render(){var _vm=this,_c=_vm._self._c;return _c('div',{staticClass:"xt-flow",class:_vm.rootClasses},[_vm._l((_vm.displayNodes),function(node,index){return _c('div',{key:node.id || index,staticClass:"xt-flow__node",class:_vm.nodeClasses(node, index)},[_c('div',{staticClass:"xt-flow__timeline"},[_c('div',{staticClass:"xt-flow__icon",class:`xt-flow__icon--${node.status}`},[_vm._t("node-avatar",function(){return [_c('span',{staticClass:"xt-flow__icon-dot"})]},{"node":node,"index":index})],2),(index < _vm.displayNodes.length - 1)?_c('div',{staticClass:"xt-flow__line",class:[
118
+ `xt-flow__line--${node.status}`,
119
+ { 'xt-flow__line--dashed': node.status === 'rejected' }
120
+ ]}):_vm._e()]),_c('div',{staticClass:"xt-flow__body"},[_c('div',{staticClass:"xt-flow__header"},[_c('span',{staticClass:"xt-flow__title"},[_vm._t("node",function(){return [_vm._v(" "+_vm._s(node.name || node.title)+" ")]},{"node":node,"index":index})],2),_c('span',{staticClass:"xt-flow__status",class:`xt-flow__status--${node.status}`},[_vm._v(" "+_vm._s(_vm.statusText(node.status))+" ")])]),_c('div',{staticClass:"xt-flow__meta"},[(node.assignee)?[_c('span',{staticClass:"xt-flow__assignee"},[_vm._t("assignee",function(){return [_c('span',{staticClass:"xt-flow__assignee-icon"},[_vm._v("👤")]),_vm._v(" "+_vm._s(node.assignee)+" ")]},{"node":node,"index":index})],2)]:_vm._e(),(node.createTime || node.endTime)?[_c('span',{staticClass:"xt-flow__time"},[_vm._v(" "+_vm._s(_vm.formatTime(node))+" ")])]:_vm._e(),(node.duration)?[_c('span',{staticClass:"xt-flow__duration"},[_vm._v(" "+_vm._s(node.duration)+" ")])]:_vm._e()],2),(node.comment || node.description)?_c('div',{staticClass:"xt-flow__desc"},[_vm._t("node-desc",function(){return [(node.status === 'rejected' && node.comment)?[_c('span',{staticClass:"xt-flow__desc-label"},[_vm._v("驳回原因:")])]:(node.comment)?[_c('span',{staticClass:"xt-flow__desc-label"},[_vm._v("审批意见:")])]:_vm._e(),_vm._v(" "+_vm._s(node.comment || node.description)+" ")]},{"node":node,"index":index})],2):_vm._e(),(_vm.$scopedSlots['node-action'])?_c('div',{staticClass:"xt-flow__actions"},[_vm._t("node-action",null,{"node":node,"index":index})],2):_vm._e()])])}),(_vm.isCollapsible && _vm.collapsed)?_c('div',{staticClass:"xt-flow__collapse",on:{"click":_vm.toggleCollapse}},[_vm._t("expand-trigger",function(){return [_c('span',{staticClass:"xt-flow__collapse-text"},[_vm._v(" 展开全部 "+_vm._s(_vm.totalCount)+" 条审批记录 "),_c('span',{staticClass:"xt-flow__collapse-arrow"},[_vm._v("▼")])])]})],2):_vm._e(),(_vm.isCollapsible && !_vm.collapsed)?_c('div',{staticClass:"xt-flow__collapse",on:{"click":_vm.toggleCollapse}},[_vm._t("collapse-trigger",function(){return [_vm._m(0)]})],2):_vm._e()],2)
121
+ }
122
+ var staticRenderFns = [function (){var _vm=this,_c=_vm._self._c;return _c('span',{staticClass:"xt-flow__collapse-text"},[_vm._v(" 收起 "),_c('span',{staticClass:"xt-flow__collapse-arrow xt-flow__collapse-arrow--up"},[_vm._v("▲")])])
123
+ }]
124
+
125
+
126
+ // CONCATENATED MODULE: ./src/components/xt-flow/index.vue?vue&type=template&id=05a25f5f
127
+
128
+ // CONCATENATED MODULE: ./src/components/xt-flow/flowable-parser.js
129
+ /**
130
+ * Flowable 工作流数据格式化工具
131
+ *
132
+ * 原生 Flowable 数据格式示例:
133
+ * {
134
+ * "id": "75001",
135
+ * "processInstanceId": "25001",
136
+ * "taskId": "50001",
137
+ * "taskName": "部门经理审批",
138
+ * "assignee": "张三",
139
+ * "startTime": "2024-01-01T10:00:00",
140
+ * "endTime": "2024-01-01T10:30:00",
141
+ * "deleteReason": null,
142
+ * "type": "startEvent" | "userTask" | "endEvent"
143
+ * }
144
+ *
145
+ * 历史任务(HistoricTaskInstance):
146
+ * {
147
+ * "id": "50001",
148
+ * "name": "部门经理审批",
149
+ * "assignee": "张三",
150
+ * "startTime": "2024-01-01T10:00:00",
151
+ * "endTime": "2024-01-01T10:30:00",
152
+ * "deleteReason": "rejected",
153
+ * "durationInMillis": 1800000
154
+ * }
155
+ */
156
+
157
+ // 默认待办节点
158
+ const DEFAULT_PENDING_NODE = {
159
+ status: 'pending',
160
+ name: '待处理',
161
+ assignee: '--',
162
+ createTime: null,
163
+ comment: '等待审批中...'
164
+ }
165
+
166
+ /**
167
+ * 解析 Flowable 原始数据为 xt-flow 组件格式
168
+ * @param {Array} rawData - Flowable 返回的原始数据
169
+ * @param {Object} options
170
+ * @param {Object} options.pendingNode - 自定义待办节点数据
171
+ * @param {Boolean} options.autoPending - 是否自动追加待办节点(默认 true)
172
+ * @returns {Array} 标准化后的节点数组
173
+ */
174
+ function parseFlowData(rawData, options = {}) {
175
+ const { pendingNode = null, autoPending = true } = options
176
+
177
+ if (!rawData || !rawData.length) {
178
+ return []
179
+ }
180
+
181
+ const nodes = rawData
182
+ .filter((item) => {
183
+ // 过滤掉 startEvent 和无效数据
184
+ if (item.type === 'startEvent') return false
185
+ // 过滤掉没有任务名称的节点
186
+ if (!item.name && !item.taskName && !item.activityName) return false
187
+ return true
188
+ })
189
+ .map((item) => {
190
+ const node = {
191
+ id: item.id || item.taskId || '',
192
+ name: item.name || item.taskName || item.activityName || '',
193
+ assignee: item.assignee || '',
194
+ createTime: item.startTime || item.createTime || '',
195
+ endTime: item.endTime || '',
196
+ status: inferStatus(item),
197
+ comment: item.comment || item.deleteReason || '',
198
+ duration: formatDuration(item.durationInMillis || item.duration),
199
+ // 保留原始数据用于插槽扩展
200
+ raw: item
201
+ }
202
+ return node
203
+ })
204
+
205
+ // 自动追加待办节点
206
+ if (autoPending && nodes.length > 0) {
207
+ const lastNode = nodes[nodes.length - 1]
208
+ // 如果最后一个节点不是 pending 状态,追加待办节点
209
+ if (lastNode.status !== 'pending') {
210
+ const pending = pendingNode || DEFAULT_PENDING_NODE
211
+ nodes.push({
212
+ id: 'pending',
213
+ name: pending.name || '待处理',
214
+ assignee: pending.assignee || '--',
215
+ createTime: pending.createTime || null,
216
+ endTime: null,
217
+ status: 'pending',
218
+ comment: pending.comment || '',
219
+ duration: '',
220
+ raw: pending
221
+ })
222
+ }
223
+ }
224
+
225
+ return nodes
226
+ }
227
+
228
+ /**
229
+ * 推断节点状态
230
+ * @param {Object} item - Flowable 原始数据项
231
+ * @returns {String} 状态值
232
+ */
233
+ function inferStatus(item) {
234
+ const deleteReason = (item.deleteReason || '').toLowerCase()
235
+
236
+ // 根据 deleteReason 判断
237
+ if (deleteReason.includes('reject') || deleteReason.includes('驳回')) {
238
+ return 'rejected'
239
+ }
240
+ if (deleteReason.includes('delegate') || deleteReason.includes('委托')) {
241
+ return 'delegated'
242
+ }
243
+ if (deleteReason.includes('transfer') || deleteReason.includes('转办')) {
244
+ return 'transferred'
245
+ }
246
+ if (deleteReason.includes('revoke') || deleteReason.includes('撤回') || deleteReason.includes('recall')) {
247
+ return 'recalled'
248
+ }
249
+ if (deleteReason.includes('cancel') || deleteReason.includes('取消')) {
250
+ return 'cancelled'
251
+ }
252
+
253
+ // 有结束时间且无驳回原因 → 通过
254
+ if (item.endTime && !item.deleteReason) {
255
+ return 'approved'
256
+ }
257
+
258
+ // 无结束时间 → 待办中
259
+ if (!item.endTime) {
260
+ return 'pending'
261
+ }
262
+
263
+ return 'approved'
264
+ }
265
+
266
+ /**
267
+ * 格式化时长
268
+ * @param {Number} millis - 毫秒数
269
+ * @returns {String} 格式化后的时长
270
+ */
271
+ function formatDuration(millis) {
272
+ if (!millis && millis !== 0) return ''
273
+
274
+ const totalSeconds = Math.floor(millis / 1000)
275
+ if (totalSeconds < 60) {
276
+ return `${totalSeconds}秒`
277
+ }
278
+
279
+ const minutes = Math.floor(totalSeconds / 60)
280
+ if (minutes < 60) {
281
+ return `${minutes}分钟`
282
+ }
283
+
284
+ const hours = Math.floor(minutes / 60)
285
+ const remainMinutes = minutes % 60
286
+ if (hours < 24) {
287
+ return remainMinutes > 0 ? `${hours}小时${remainMinutes}分钟` : `${hours}小时`
288
+ }
289
+
290
+ const days = Math.floor(hours / 24)
291
+ const remainHours = hours % 24
292
+ return remainHours > 0 ? `${days}天${remainHours}小时` : `${days}天`
293
+ }
294
+
295
+ /**
296
+ * 格式化时间字符串
297
+ * @param {String} timeStr - 时间字符串
298
+ * @param {String} format - 格式
299
+ * @returns {String} 格式化后的时间
300
+ */
301
+ function formatFlowTime(timeStr, format) {
302
+ if (!timeStr) return ''
303
+
304
+ try {
305
+ const d = new Date(timeStr)
306
+ if (isNaN(d.getTime())) return timeStr
307
+
308
+ const year = d.getFullYear()
309
+ const month = String(d.getMonth() + 1).padStart(2, '0')
310
+ const day = String(d.getDate()).padStart(2, '0')
311
+ const hour = String(d.getHours()).padStart(2, '0')
312
+ const minute = String(d.getMinutes()).padStart(2, '0')
313
+ const second = String(d.getSeconds()).padStart(2, '0')
314
+
315
+ return format
316
+ .replace('YYYY', year)
317
+ .replace('MM', month)
318
+ .replace('DD', day)
319
+ .replace('HH', hour)
320
+ .replace('mm', minute)
321
+ .replace('ss', second)
322
+ } catch (e) {
323
+ return timeStr
324
+ }
325
+ }
326
+
327
+ /**
328
+ * 生成模拟审批链数据(用于开发和演示)
329
+ * @param {Number} count - 节点数量
330
+ * @returns {Array} 模拟数据
331
+ */
332
+ function createMockFlowData(count = 7) {
333
+ const statuses = ['approved', 'approved', 'approved', 'rejected', 'pending', 'transferred', 'approved']
334
+ const names = [
335
+ '提交申请', '直属领导审批', '部门经理审批',
336
+ '总监审批', 'HR 审批', '总经理审批', '流程结束'
337
+ ]
338
+ const assignees = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九']
339
+ const comments = [
340
+ '', '同意', '同意', '驳回:请补充材料后重新提交',
341
+ '', '', '同意'
342
+ ]
343
+
344
+ const now = new Date()
345
+ const result = []
346
+
347
+ for (let i = 0; i < Math.min(count, names.length); i++) {
348
+ const startTime = new Date(now.getTime() - (count - i) * 3600000)
349
+ const endTime = statuses[i] === 'pending'
350
+ ? null
351
+ : new Date(startTime.getTime() + 1800000)
352
+
353
+ result.push({
354
+ id: `flow-${i + 1}`,
355
+ name: names[i],
356
+ assignee: assignees[i],
357
+ status: statuses[i],
358
+ createTime: startTime.toISOString(),
359
+ endTime: endTime ? endTime.toISOString() : null,
360
+ comment: comments[i],
361
+ duration: endTime ? '30分钟' : ''
362
+ })
363
+ }
364
+
365
+ return result
366
+ }
367
+
368
+ /* harmony default export */ var flowable_parser = ({
369
+ parseFlowData,
370
+ formatFlowTime,
371
+ createMockFlowData
372
+ });
373
+ // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/xt-flow/index.vue?vue&type=script&lang=js
374
+
375
+
376
+
377
+ /* harmony default export */ var xt_flowvue_type_script_lang_js = ({
378
+ name: 'XtFlow',
379
+
380
+ props: {
381
+ // 数据源:数组格式,支持 Flowable 原始格式或自定义格式
382
+ data: {
383
+ type: Array,
384
+ default: () => []
385
+ },
386
+ // 是否自动折叠长审批链
387
+ collapse: {
388
+ type: Boolean,
389
+ default: true
390
+ },
391
+ // 折叠前可见节点数
392
+ collapseCount: {
393
+ type: Number,
394
+ default: 5
395
+ },
396
+ // 圆角风格:square 方形 / round 圆形
397
+ rounded: {
398
+ type: String,
399
+ default: 'square',
400
+ validator: (val) => ['square', 'round'].includes(val)
401
+ },
402
+ // 数据格式:flowable 原生 / custom 自定义
403
+ format: {
404
+ type: String,
405
+ default: 'flowable',
406
+ validator: (val) => ['flowable', 'custom'].includes(val)
407
+ },
408
+ // 时间格式(仅在 format='flowable' 时生效)
409
+ timeFormat: {
410
+ type: String,
411
+ default: 'YYYY-MM-DD HH:mm:ss'
412
+ },
413
+ // 自定义状态文本映射
414
+ statusMap: {
415
+ type: Object,
416
+ default: () => ({
417
+ approved: '已通过',
418
+ rejected: '已驳回',
419
+ pending: '待审批',
420
+ transferred: '已转办',
421
+ delegated: '已委托',
422
+ recalled: '已撤回',
423
+ started: '已发起',
424
+ cancelled: '已取消'
425
+ })
426
+ }
427
+ },
428
+
429
+ data() {
430
+ return {
431
+ collapsed: true
432
+ }
433
+ },
434
+
435
+ computed: {
436
+ rootClasses() {
437
+ return [
438
+ `xt-flow--${this.rounded}`
439
+ ]
440
+ },
441
+
442
+ parsedData() {
443
+ if (this.format === 'flowable') {
444
+ return parseFlowData(this.data)
445
+ }
446
+ return this.data
447
+ },
448
+
449
+ totalCount() {
450
+ return this.parsedData.length
451
+ },
452
+
453
+ isCollapsible() {
454
+ return this.collapse && this.totalCount > this.collapseCount
455
+ },
456
+
457
+ displayNodes() {
458
+ if (!this.isCollapsible || !this.collapsed) {
459
+ return this.parsedData
460
+ }
461
+ return this.parsedData.slice(0, this.collapseCount)
462
+ }
463
+ },
464
+
465
+ methods: {
466
+ nodeClasses(node, index) {
467
+ return [
468
+ `xt-flow__node--${node.status}`,
469
+ {
470
+ 'xt-flow__node--last': index === this.displayNodes.length - 1,
471
+ 'xt-flow__node--first': index === 0
472
+ }
473
+ ]
474
+ },
475
+
476
+ statusText(status) {
477
+ return this.statusMap[status] || status
478
+ },
479
+
480
+ formatTime(node) {
481
+ if (this.format === 'flowable') {
482
+ return formatFlowTime(node.createTime || node.endTime, this.timeFormat)
483
+ }
484
+ return node.createTime || node.endTime || ''
485
+ },
486
+
487
+ toggleCollapse() {
488
+ this.collapsed = !this.collapsed
489
+ }
490
+ }
491
+ });
492
+
493
+ // CONCATENATED MODULE: ./src/components/xt-flow/index.vue?vue&type=script&lang=js
494
+ /* harmony default export */ var components_xt_flowvue_type_script_lang_js = (xt_flowvue_type_script_lang_js);
495
+ // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
496
+ /* globals __VUE_SSR_CONTEXT__ */
497
+
498
+ // IMPORTANT: Do NOT use ES2015 features in this file (except for modules).
499
+ // This module is a runtime utility for cleaner component module output and will
500
+ // be included in the final webpack user bundle.
501
+
502
+ function normalizeComponent(
503
+ scriptExports,
504
+ render,
505
+ staticRenderFns,
506
+ functionalTemplate,
507
+ injectStyles,
508
+ scopeId,
509
+ moduleIdentifier /* server only */,
510
+ shadowMode /* vue-cli only */
511
+ ) {
512
+ // Vue.extend constructor export interop
513
+ var options =
514
+ typeof scriptExports === 'function' ? scriptExports.options : scriptExports
515
+
516
+ // render functions
517
+ if (render) {
518
+ options.render = render
519
+ options.staticRenderFns = staticRenderFns
520
+ options._compiled = true
521
+ }
522
+
523
+ // functional template
524
+ if (functionalTemplate) {
525
+ options.functional = true
526
+ }
527
+
528
+ // scopedId
529
+ if (scopeId) {
530
+ options._scopeId = 'data-v-' + scopeId
531
+ }
532
+
533
+ var hook
534
+ if (moduleIdentifier) {
535
+ // server build
536
+ hook = function (context) {
537
+ // 2.3 injection
538
+ context =
539
+ context || // cached call
540
+ (this.$vnode && this.$vnode.ssrContext) || // stateful
541
+ (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
542
+ // 2.2 with runInNewContext: true
543
+ if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
544
+ context = __VUE_SSR_CONTEXT__
545
+ }
546
+ // inject component styles
547
+ if (injectStyles) {
548
+ injectStyles.call(this, context)
549
+ }
550
+ // register component module identifier for async chunk inferrence
551
+ if (context && context._registeredComponents) {
552
+ context._registeredComponents.add(moduleIdentifier)
553
+ }
554
+ }
555
+ // used by ssr in case component is cached and beforeCreate
556
+ // never gets called
557
+ options._ssrRegister = hook
558
+ } else if (injectStyles) {
559
+ hook = shadowMode
560
+ ? function () {
561
+ injectStyles.call(
562
+ this,
563
+ (options.functional ? this.parent : this).$root.$options.shadowRoot
564
+ )
565
+ }
566
+ : injectStyles
567
+ }
568
+
569
+ if (hook) {
570
+ if (options.functional) {
571
+ // for template-only hot-reload because in that case the render fn doesn't
572
+ // go through the normalizer
573
+ options._injectStyles = hook
574
+ // register for functional component in vue file
575
+ var originalRender = options.render
576
+ options.render = function renderWithStyleInjection(h, context) {
577
+ hook.call(context)
578
+ return originalRender(h, context)
579
+ }
580
+ } else {
581
+ // inject component registration as beforeCreate hook
582
+ var existing = options.beforeCreate
583
+ options.beforeCreate = existing ? [].concat(existing, hook) : [hook]
584
+ }
585
+ }
586
+
587
+ return {
588
+ exports: scriptExports,
589
+ options: options
590
+ }
591
+ }
592
+
593
+ // CONCATENATED MODULE: ./src/components/xt-flow/index.vue
594
+
595
+
596
+
597
+
598
+
599
+ /* normalize component */
600
+
601
+ var component = normalizeComponent(
602
+ components_xt_flowvue_type_script_lang_js,
603
+ render,
604
+ staticRenderFns,
605
+ false,
606
+ null,
607
+ null,
608
+ null
609
+
610
+ )
611
+
612
+ /* harmony default export */ var xt_flow = (component.exports);
613
+ // CONCATENATED MODULE: ./src/components/xt-flow/index.js
614
+
615
+
616
+
617
+ xt_flow.install = function(Vue) {
618
+ Vue.component(xt_flow.name, xt_flow)
619
+ }
620
+
621
+ /* harmony default export */ var components_xt_flow = (xt_flow);
622
+ // CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js
623
+
624
+
625
+ /* harmony default export */ var entry_lib = __webpack_exports__["default"] = (components_xt_flow);
626
+
627
+
628
+
629
+ /***/ }),
630
+
631
+ /***/ "fdbd":
632
+ /***/ (function(module, exports, __webpack_require__) {
633
+
634
+ // extracted by mini-css-extract-plugin
635
+
636
+ /***/ })
637
+
638
+ /******/ });
@@ -0,0 +1 @@
1
+ .xt-flow{position:relative;padding:var(--xt-spacing-md,16px) 0}.xt-flow__node{display:flex;align-items:flex-start;padding-bottom:0;position:relative}.xt-flow__node:last-child .xt-flow__line{display:none}.xt-flow__timeline{flex-direction:column;width:40px;margin-right:var(--xt-spacing-sm,12px)}.xt-flow__icon,.xt-flow__timeline{display:flex;align-items:center;flex-shrink:0}.xt-flow__icon{width:24px;height:24px;border-radius:50%;justify-content:center;z-index:1;transition:background var(--xt-transition-duration-fast,.2s) ease}.xt-flow__icon-dot{width:10px;height:10px;border-radius:50%;display:block}.xt-flow__icon--approved{background:var(--xt-color-primary-light-9,#e8f4ff)}.xt-flow__icon--approved .xt-flow__icon-dot{background:var(--xt-color-primary,#1890ff)}.xt-flow__icon--rejected{background:var(--xt-color-danger-light-9,#fef0f0)}.xt-flow__icon--rejected .xt-flow__icon-dot{background:var(--xt-color-danger,#f56c6c)}.xt-flow__icon--pending{background:var(--xt-color-warning-light-9,#fdf6ec)}.xt-flow__icon--pending .xt-flow__icon-dot{background:var(--xt-color-warning,#e6a23c);animation:xt-flow-pulse 1.5s ease-in-out infinite}.xt-flow__icon--delegated,.xt-flow__icon--transferred{background:var(--xt-color-info-light-9,#f4f4f5)}.xt-flow__icon--delegated .xt-flow__icon-dot,.xt-flow__icon--transferred .xt-flow__icon-dot{background:var(--xt-color-info,#909399)}.xt-flow__icon--cancelled,.xt-flow__icon--recalled{background:var(--xt-fill-color-light,#f5f7fa)}.xt-flow__icon--cancelled .xt-flow__icon-dot,.xt-flow__icon--recalled .xt-flow__icon-dot{background:var(--xt-text-color-secondary,#909399)}.xt-flow__icon--started{background:var(--xt-color-primary-light-9,#e8f4ff)}.xt-flow__icon--started .xt-flow__icon-dot{background:var(--xt-color-primary,#1890ff)}@keyframes xt-flow-pulse{0%,to{opacity:1}50%{opacity:.4}}.xt-flow__line{width:2px;flex:1;min-height:32px;background:var(--xt-border-color-light,#e4e7ed);margin:4px 0;transition:background var(--xt-transition-duration-fast,.2s) ease}.xt-flow__line--approved{background:var(--xt-color-primary-light-5,#8cc8ff)}.xt-flow__line--dashed,.xt-flow__line--rejected{background:repeating-linear-gradient(180deg,var(--xt-color-danger,#f56c6c) 0,var(--xt-color-danger,#f56c6c) 4px,transparent 0,transparent 8px)}.xt-flow__line--pending{background:repeating-linear-gradient(180deg,var(--xt-border-color,#dcdfe6) 0,var(--xt-border-color,#dcdfe6) 3px,transparent 0,transparent 6px)}.xt-flow__line--delegated,.xt-flow__line--transferred{background:var(--xt-border-color,#dcdfe6)}.xt-flow__line--cancelled,.xt-flow__line--recalled{background:var(--xt-border-color-lighter,#ebeef5)}.xt-flow__body{flex:1;min-width:0;padding-bottom:var(--xt-spacing-md,16px);border-radius:var(--xt-border-radius-small,4px);transition:background var(--xt-transition-duration-fast,.2s) ease}.xt-flow__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.xt-flow__title{font-size:calc(14px + var(--xt-font-size-increment, 0px));font-weight:var(--xt-font-weight-primary,500);color:var(--xt-text-color-primary,#303133);line-height:1.4;word-break:break-all}.xt-flow__status{flex-shrink:0;font-size:calc(12px + var(--xt-font-size-increment, 0px));padding:1px 8px;border-radius:var(--xt-border-radius-mini,2px);margin-left:var(--xt-spacing-xs,8px);line-height:20px;white-space:nowrap}.xt-flow__status--approved{color:var(--xt-color-primary,#1890ff);background:var(--xt-color-primary-light-9,#e8f4ff)}.xt-flow__status--rejected{color:var(--xt-color-danger,#f56c6c);background:var(--xt-color-danger-light-9,#fef0f0)}.xt-flow__status--pending{color:var(--xt-color-warning,#e6a23c);background:var(--xt-color-warning-light-9,#fdf6ec)}.xt-flow__status--delegated,.xt-flow__status--transferred{color:var(--xt-color-info,#909399);background:var(--xt-color-info-light-9,#f4f4f5)}.xt-flow__status--cancelled,.xt-flow__status--recalled{color:var(--xt-text-color-secondary,#909399);background:var(--xt-fill-color-light,#f5f7fa)}.xt-flow__status--started{color:var(--xt-color-primary,#1890ff);background:var(--xt-color-primary-light-9,#e8f4ff)}.xt-flow__meta{display:flex;align-items:center;flex-wrap:wrap;gap:var(--xt-spacing-xs,8px);font-size:calc(12px + var(--xt-font-size-increment, 0px));color:var(--xt-text-color-secondary,#909399);line-height:1.5}.xt-flow__assignee{display:inline-flex;align-items:center;gap:2px}.xt-flow__assignee-icon{font-size:12px}.xt-flow__duration,.xt-flow__time{color:var(--xt-text-color-placeholder,#a8abb2)}.xt-flow__desc{margin-top:6px;padding:var(--xt-spacing-xs,8px);font-size:calc(13px + var(--xt-font-size-increment, 0px));color:var(--xt-text-color-regular,#606266);background:var(--xt-fill-color-light,#f5f7fa);border-radius:var(--xt-border-radius-small,4px);line-height:1.6;word-break:break-all}.xt-flow__desc-label{font-weight:var(--xt-font-weight-primary,500);color:var(--xt-text-color-primary,#303133)}.xt-flow__actions{margin-top:8px;display:flex;gap:var(--xt-spacing-xs,8px);flex-wrap:wrap}.xt-flow__collapse{display:flex;align-items:center;justify-content:center;padding:var(--xt-spacing-sm,12px) 0;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:color var(--xt-transition-duration-fast,.2s) ease}.xt-flow__collapse:hover .xt-flow__collapse-text{color:var(--xt-color-primary,#1890ff)}.xt-flow__collapse-text{font-size:calc(13px + var(--xt-font-size-increment, 0px));color:var(--xt-text-color-secondary,#909399);display:inline-flex;align-items:center;gap:4px;transition:color var(--xt-transition-duration-fast,.2s) ease}.xt-flow__collapse-arrow{font-size:10px}.xt-flow__collapse-arrow--up{transform:rotate(0deg)}.xt-flow--square .xt-flow__icon{border-radius:4px}.xt-flow--square .xt-flow__icon-dot{border-radius:2px}.xt-flow--round .xt-flow__icon,.xt-flow--round .xt-flow__icon-dot{border-radius:50%}