cloud-web-corejs 1.0.280 → 1.1.0-dev.10

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 (193) hide show
  1. package/package.json +6 -2
  2. package/src/components/VabUpload/image-viewer.vue +442 -442
  3. package/src/components/VabUpload/index.vue +45 -3
  4. package/src/components/VabUpload/mixins.js +174 -34
  5. package/src/components/VabUpload/previewGroup.js +128 -0
  6. package/src/components/VabUpload/view.vue +248 -209
  7. package/src/components/baseTabs/mixins.js +181 -181
  8. package/src/components/bizTab/BizBillActions.vue +129 -0
  9. package/src/components/bizTab/BizTabListPage.vue +391 -0
  10. package/src/components/bizTab/README.md +378 -0
  11. package/src/components/bizTab/billTableUtil.js +48 -0
  12. package/src/components/bizTab/billValidators.js +136 -0
  13. package/src/components/bizTab/bizBillDetailMixin.js +705 -0
  14. package/src/components/bizTab/index.js +24 -0
  15. package/src/components/excelExport/exportFieldDialog.vue +23 -12
  16. package/src/components/excelExport/exportItemConfigUtil.js +30 -0
  17. package/src/components/excelExport/mixins.js +3 -3
  18. package/src/components/excelImport/index.vue +156 -156
  19. package/src/components/jsonImport/index.vue +1 -1
  20. package/src/components/langImport/index.vue +1 -1
  21. package/src/components/mobile/statusTag/mixins.js +1 -61
  22. package/src/components/mobile/wf/addTaskUserdialog.vue +23 -3
  23. package/src/components/mobile/wf/content.vue +1705 -1556
  24. package/src/components/mobile/wf/deleteTaskUserDialog.vue +22 -3
  25. package/src/components/mobile/wf/mixins/wfModifyDialogMixin.js +8 -6
  26. package/src/components/mobile/wf/selectUserDialog.vue +122 -0
  27. package/src/components/mobile/wf/setCandidateDialog.vue +25 -4
  28. package/src/components/mobile/wf/urgingDialog.vue +26 -3
  29. package/src/components/mobile/wf/wfModifyDialog.vue +4 -0
  30. package/src/components/obsUpload/index.vue +1 -1
  31. package/src/components/table/config.js +78 -78
  32. package/src/components/table/index.js +1276 -1276
  33. package/src/components/table/plugins/cell-area/index.js +1055 -0
  34. package/src/components/table/plugins/cell-area/index.scss +77 -0
  35. package/src/components/table/plugins/cell-area/util.js +224 -0
  36. package/src/components/table/tableForm.vue +330 -330
  37. package/src/components/table/tableFormMixin.js +318 -318
  38. package/src/components/table/vxeFilter/index.js +163 -163
  39. package/src/components/table/vxeFilter/mixin.js +316 -316
  40. package/src/components/wf/content.vue +1188 -1188
  41. package/src/components/wf/wf.js +40 -20
  42. package/src/components/wf/wfActionDropdown.vue +1 -1
  43. package/src/components/wf/wfActionItems.js +1 -1
  44. package/src/components/xform/docs/2026-08 xform H5 P0 /345/256/236/347/216/260/350/247/204/346/240/274.md" +528 -0
  45. package/src/components/xform/docs/2026-08 xform H5 P1 /345/256/236/347/216/260/350/247/204/346/240/274.md" +412 -0
  46. package/src/components/xform/docs/2026-08 xform H5 P2 /345/256/236/347/216/260/350/247/204/346/240/274.md" +287 -0
  47. package/src/components/xform/docs/2026-08 xform /347/247/273/345/212/250/347/253/257/345/270/203/345/261/200/345/257/271/351/275/220 bill_setting /346/226/271/346/241/210.md" +400 -0
  48. package/src/components/xform/form-designer/designer.js +51 -52
  49. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +269 -269
  50. package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +18 -2
  51. package/src/components/xform/form-designer/form-widget/container-widget/detail-temp-widget.vue +132 -0
  52. package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +250 -250
  53. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +23 -2
  54. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +30 -1
  55. package/src/components/xform/form-designer/form-widget/dialog/fileReferenceDialog.vue +319 -320
  56. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +365 -365
  57. package/src/components/xform/form-designer/form-widget/dialog/importDialog.vue +185 -185
  58. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +554 -555
  59. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +409 -409
  60. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +150 -132
  61. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +114 -114
  62. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +154 -154
  63. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +47 -1
  64. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +178 -178
  65. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +77 -77
  66. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +6 -0
  67. package/src/components/xform/form-designer/form-widget/field-widget/select-widget.vue +139 -139
  68. package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +1 -1
  69. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +106 -106
  70. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +134 -134
  71. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +3 -2
  72. package/src/components/xform/form-designer/indexMixin.js +35 -1
  73. package/src/components/xform/form-designer/setting-panel/form-setting.vue +39 -39
  74. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +10 -10
  75. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/exportItemColumns-dialog.vue +438 -432
  76. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +2103 -2103
  77. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-temp-edito.vue +90 -0
  78. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +82 -82
  79. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +833 -846
  80. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +8 -8
  81. package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +137 -137
  82. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
  83. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +43 -43
  84. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +43 -43
  85. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +96 -96
  86. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +51 -0
  87. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +42 -42
  88. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +43 -43
  89. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +158 -158
  90. package/src/components/xform/form-designer/setting-panel/property-editor/h5Span-editor.vue +51 -0
  91. package/src/components/xform/form-designer/setting-panel/property-editor/itemStyle-editor.vue +39 -0
  92. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +188 -188
  93. package/src/components/xform/form-designer/setting-panel/property-editor/styleTempClass-editor.vue +51 -0
  94. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +347 -347
  95. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +12 -0
  96. package/src/components/xform/form-designer/toolbar-panel/index.vue +884 -874
  97. package/src/components/xform/form-designer/toolbar-panel/indexMixin.js +14 -0
  98. package/src/components/xform/form-designer/widget-panel/index.vue +11 -7
  99. package/src/components/xform/form-designer/widget-panel/indexMixin.js +30 -6
  100. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +112 -4
  101. package/src/components/xform/form-render/container-item/data-table-mixin.js +151 -93
  102. package/src/components/xform/form-render/container-item/detail-h5-item.vue +204 -34
  103. package/src/components/xform/form-render/container-item/detail-temp-item.vue +110 -0
  104. package/src/components/xform/form-render/container-item/h5-card-pane-item.vue +160 -140
  105. package/src/components/xform/form-render/container-item/list-h5-item.vue +1913 -1699
  106. package/src/components/xform/form-render/index.vue +153 -147
  107. package/src/components/xform/form-render/indexMixin.js +35 -3
  108. package/src/components/xform/lang/en-US.js +14 -0
  109. package/src/components/xform/lang/zh-CN.js +17 -0
  110. package/src/components/xform/mixins/defaultHandle.js +707 -707
  111. package/src/components/xform/styles/h5.scss +2238 -0
  112. package/src/components/xform/utils/textMaskUtil.js +182 -179
  113. package/src/components/xform/utils/treeTableUtil.js +1292 -1265
  114. package/src/components/xform/utils/util.js +56 -11
  115. package/src/directive/append-to-body/index.js +48 -0
  116. package/src/index.js +13 -4
  117. package/src/layout/components/Sidebar/default.vue +1655 -1655
  118. package/src/layout/components/extractedCode/viewDialog.vue +7 -7
  119. package/src/router/index.js +48 -27
  120. package/src/router/modules/customer.js +71 -14
  121. package/src/store/modules/permission.js +17 -18
  122. package/src/utils/assetUrl.js +19 -0
  123. package/src/utils/pdfUtil.js +429 -429
  124. package/src/utils/resolveViewComponent.js +142 -16
  125. package/src/utils/vab.js +1283 -1279
  126. package/src/views/bd/project/branch/bd_branch/edit.vue +145 -0
  127. package/src/views/bd/project/branch/bd_branch/list.vue +72 -0
  128. package/src/views/bd/project/branch/bd_branch/menuKindDialog.vue +106 -0
  129. package/src/views/bd/project/branch/bd_branch/mixins/edit.js +189 -0
  130. package/src/views/bd/project/branch/bd_branch/mixins/list.js +124 -0
  131. package/src/views/bd/project/branch/bd_branch/mixins/menuKindDialog.js +85 -0
  132. package/src/views/bd/project/branch/form_script/list.vue +31 -0
  133. package/src/views/bd/project/branch/form_template/list.vue +30 -0
  134. package/src/views/bd/project/branch/menu_kind/list.vue +31 -0
  135. package/src/views/bd/project/common/form_script/list.vue +16 -0
  136. package/src/views/bd/project/common/form_template/list.vue +15 -0
  137. package/src/views/bd/project/common/menu_kind/list.vue +15 -0
  138. package/src/views/bd/project/core/branchContext.js +100 -0
  139. package/src/views/bd/project/core/branchPage.js +78 -0
  140. package/src/views/bd/project/core/branchPageWrap.vue +225 -0
  141. package/src/views/bd/project/core/branchScope.js +44 -0
  142. package/src/views/bd/project/core/branchSearchPage.js +285 -0
  143. package/src/views/bd/project/core/branchSelect.vue +85 -0
  144. package/src/views/bd/project/core/branchTreeBar.vue +81 -0
  145. package/src/views/bd/project/core/httpBranchPatch.js +58 -0
  146. package/src/views/bd/project/datatable/menu_kind/list.vue +15 -0
  147. package/src/views/bd/project/datatable/table_model/list.vue +15 -0
  148. package/src/views/bd/setting/bd_company_env/dialog.vue +174 -174
  149. package/src/views/bd/setting/form_template/edit.vue +378 -356
  150. package/src/views/bd/setting/form_template/formDesignerDialog.vue +6 -0
  151. package/src/views/bd/setting/form_template/formTemplateType.js +43 -0
  152. package/src/views/bd/setting/form_template/list.vue +304 -303
  153. package/src/views/bd/setting/form_template/mixins/edit.js +344 -280
  154. package/src/views/bd/setting/form_template/mixins/list.js +748 -721
  155. package/src/views/bd/setting/table_model/edit.vue +1066 -1066
  156. package/src/views/bd/setting/table_model/mixins/edit.js +1455 -1455
  157. package/src/views/bd/setting/table_model/mixins/zdDialog.js +148 -148
  158. package/src/views/demo/bizTab/bill/billConfig.js +41 -0
  159. package/src/views/demo/bizTab/bill/detail.vue +436 -0
  160. package/src/views/demo/bizTab/bill/list.vue +288 -0
  161. package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
  162. package/src/views/demo/bizTab/simple/billApi.js +123 -0
  163. package/src/views/demo/bizTab/simple/detail.vue +407 -0
  164. package/src/views/demo/bizTab/simple/list.vue +217 -0
  165. package/src/views/demo/bizTab/standalone/index.vue +121 -0
  166. package/src/views/demo/bizTab/wf/billConfig.js +44 -0
  167. package/src/views/demo/bizTab/wf/detail.vue +661 -0
  168. package/src/views/demo/bizTab/wf/list.vue +242 -0
  169. package/src/views/support/form-dialog-demo/demoPickerDialog.vue +72 -0
  170. package/src/views/support/form-dialog-demo/index.vue +537 -0
  171. package/src/views/user/file_view_ins/list.vue +970 -970
  172. package/src/views/user/form/vform/designer.vue +823 -821
  173. package/src/views/user/home/default.vue +1117 -1117
  174. package/src/views/user/home/default2.vue +1 -1
  175. package/src/views/user/home/index.vue +103 -101
  176. package/src/views/user/home/wjl/content.vue +1569 -0
  177. package/src/views/user/notify_message/dialog.vue +139 -137
  178. package/src/views/user/outLink/cc_form_view.vue +188 -0
  179. package/src/views/user/outLink/form_view.vue +202 -202
  180. package/src/views/user/outLink/index.vue +110 -110
  181. package/src/views/user/outLink/view.vue +3 -3
  182. package/src/views/user/role/edit.vue +632 -632
  183. package/src/views/user/role/list.vue +260 -260
  184. package/src/views/user/wf/iframe/index.vue +51 -51
  185. package/src/views/user/wf/iframe/index2.vue +64 -64
  186. package/src/views/user/wf/wf_manage/list.vue +1112 -1116
  187. package/src/views/user/wf/wf_manage/list2.vue +871 -875
  188. package/src/views/user/wf/wf_manage/wfContentDialog.vue +134 -131
  189. package/src/views/user/wf/wf_obj_config/importItemDialog.vue +1 -1
  190. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-menu-widget.vue +0 -106
  191. package/src/components/xform/form-designer/form-widget/field-widget/tableexportbuttonwidget.vue +0 -99
  192. package/src/components/xform/form-render/container-item/list-h5-item2.vue +0 -1340
  193. package/src/utils/wf.js +0 -766
package/src/utils/vab.js CHANGED
@@ -1,1279 +1,1283 @@
1
- /**version-1.0*/
2
- let install = {};
3
-
4
- import request from "./request";
5
- import * as lodash from "lodash";
6
- import { Loading, Message, MessageBox, Notification, Form } from "element-ui";
7
- import store from "../store";
8
- import ElImageViewer from "../components/VabUpload/image-viewer";
9
-
10
- import { getToken } from "./auth";
11
- import XEUtils from "xe-utils";
12
-
13
- import prefixConfig from "@/prefixConfig.js";
14
- import moment from "moment";
15
- import { openView } from "./repeatOpen";
16
-
17
- let imFun = {
18
- request,
19
- lodash,
20
- Loading,
21
- Message,
22
- MessageBox,
23
- Notification,
24
- Form,
25
- store,
26
- getToken,
27
- prefixConfig,
28
- };
29
-
30
- function reqImg(a) {
31
- return require("@/resources/images/" + a);
32
- }
33
-
34
- const FILE_ICON_NAME_MAP = {
35
- word: "ico-wrod.svg",
36
- excel: "ico-excel.svg",
37
- ppt: "ico-ppt.svg",
38
- pdf: "ico-pdf.svg",
39
- picture: "ico-photo.svg",
40
- video: "ico-video.svg",
41
- audio: "ico-music.svg",
42
- html: "ico-html.svg",
43
- txt: "ico-txt.svg",
44
- java: "ico-java.svg",
45
- vue: "ico-vue.svg",
46
- ftl: "ico-ftl.svg",
47
- xml: "ico-xml.svg",
48
- flash: "ico-flash.svg",
49
- zip: "ico-yasuobao.svg",
50
- exe: "ico-ext.svg",
51
- psd: "ico-psd.svg",
52
- folder: "ico-wenjianjia.svg",
53
- other: "ico-default_wenjian.svg",
54
- };
55
-
56
- const FILE_ICON_TYPE_MAP = {
57
- doc: "word",
58
- docx: "word",
59
- xls: "excel",
60
- xlsx: "excel",
61
- ppt: "ppt",
62
- pptx: "ppt",
63
- pdf: "pdf",
64
- jpg: "picture",
65
- jpeg: "picture",
66
- png: "picture",
67
- gif: "picture",
68
- mp3: "video",
69
- mp4: "video",
70
- mpg: "video",
71
- mkv: "video",
72
- rmvb: "video",
73
- avi: "video",
74
- mov: "video",
75
- wav: "audio",
76
- html: "html",
77
- htm: "html",
78
- txt: "txt",
79
- java: "java",
80
- vue: "vue",
81
- ftl: "ftl",
82
- xml: "xml",
83
- swf: "flash",
84
- zip: "zip",
85
- rar: "zip",
86
- "7z": "zip",
87
- // exe: 'exe',
88
- psd: "psd",
89
- };
90
-
91
- let typeList = [
92
- "doc",
93
- "docx",
94
- "xls",
95
- "xlsx",
96
- "ppt",
97
- "pptx",
98
- "csv",
99
- "wps",
100
- "dps",
101
- "et",
102
- "ett",
103
- "wpt",
104
- "vsd",
105
- "vsdx",
106
- "wmf",
107
- "emf",
108
- "psd",
109
- "eps",
110
- "pdf",
111
- "xmind",
112
- "obj",
113
- "3ds",
114
- "stl",
115
- "ply",
116
- "gltf",
117
- "glb",
118
- "off",
119
- "3dm",
120
- "fbx",
121
- "dae",
122
- "wrl",
123
- "3mf",
124
- "ifc",
125
- "brep",
126
- "step",
127
- "iges",
128
- "fcstd",
129
- "bim",
130
- "dwg",
131
- "dxf",
132
- "dwf",
133
- "iges",
134
- "igs",
135
- "dwt",
136
- "dng",
137
- "ifc",
138
- "dwfx",
139
- "stl",
140
- "cf2",
141
- "plt",
142
- "txt",
143
- "xml",
144
- "md",
145
- "java",
146
- "php",
147
- "py",
148
- "js",
149
- "css",
150
- "zip",
151
- "rar",
152
- "jar",
153
- "tar",
154
- "gzip",
155
- "7z",
156
- "mp3",
157
- "wav",
158
- "mp4",
159
- "flv",
160
- "avi",
161
- "mov",
162
- "rm",
163
- "mkv",
164
- "mpeg",
165
- "mpg",
166
- "rmvb",
167
- "wmv",
168
- "3gp",
169
- "swf",
170
- "drawio",
171
- "tif",
172
- "tiff",
173
- "jfif",
174
- "webp",
175
- "tga",
176
- "svg",
177
- "vue",
178
- "ftl",
179
- ];
180
-
181
- const accessToken = imFun.store.getters["user/token"];
182
-
183
- const loadingText = "";
184
- const messageDuration = 3000;
185
-
186
- install = (Vue, opts = {}) => {
187
- /**http请求*/
188
- let $http = async function (option) {
189
- option = option || {};
190
- if (!option.loadingTarget && this.$el) {
191
- option.loadingTarget = this.$el;
192
- }
193
- if (!option.vueTarget) {
194
- option.vueTarget = this;
195
- }
196
- if (option.sync === false) {
197
- return await imFun.request(option);
198
- } else {
199
- return imFun.request(option);
200
- }
201
- };
202
-
203
- Vue.prototype.$commonHttp = function (opts) {
204
- let defaultOption = {
205
- addCreateInfo: true,
206
- queryCreateInfo: window.$vueRoot.$store.getters.queryCreateInfo || "0",
207
- };
208
- let option = Object.assign({}, defaultOption, opts);
209
- if (opts.addCreateInfo === null || opts.addCreateInfo === undefined) {
210
- option.addCreateInfo = defaultOption.addCreateInfo;
211
- }
212
- if (
213
- opts.queryCreateInfo === null ||
214
- opts.queryCreateInfo === undefined ||
215
- opts.queryCreateInfo === true
216
- ) {
217
- option.queryCreateInfo = defaultOption.queryCreateInfo;
218
- }
219
- if (opts.queryCreateInfo === false) {
220
- option.queryCreateInfo = "0";
221
- }
222
- return this.$http(option);
223
- };
224
-
225
- Object.assign($http, imFun.request);
226
- $http.prototype = imFun.request.prototype;
227
- Vue.prototype.$http = $http;
228
-
229
- /* 通用打开菜单/路由:开关开启时以独立标签重复打开,否则按原逻辑跳转
230
- * 用法:this.$openView('/path') 或 this.$openView({ path, query }[, route]) */
231
- Vue.prototype.$openView = function (location, route) {
232
- return openView(this.$router, location, route);
233
- };
234
-
235
- /* 全局accessToken */
236
- Vue.prototype.$baseAccessToken = () => {
237
- return accessToken || imFun.getToken();
238
- };
239
-
240
- /* 全局加载层 */
241
- Vue.prototype.$baseLoading = function (option) {
242
- let d = this.$el;
243
- let loading;
244
- option = option || {};
245
- if (!option.index) {
246
- let opts = {
247
- lock: true,
248
- background: "hsla(0,0%,100%,.8)",
249
- target: d,
250
- };
251
- Object.assign(opts, option);
252
- loading = imFun.Loading.service(opts);
253
- } else {
254
- let opts = {
255
- lock: true,
256
- spinner: "vab-loading-type" + option.index,
257
- background: "hsla(0,0%,100%,.8)",
258
- target: d,
259
- };
260
- Object.assign(opts, option);
261
- loading = imFun.Loading.service(opts);
262
- }
263
- return loading;
264
- };
265
- /* 全局多彩加载层 */
266
- Vue.prototype.$baseColorfullLoading = function (index, text) {
267
- let loading;
268
- if (!index) {
269
- loading = imFun.Loading.service({
270
- lock: true,
271
- text: text || loadingText,
272
- spinner: "dots-loader",
273
- background: "hsla(0,0%,100%,.8)",
274
- target: this.target,
275
- fullscreen: true,
276
- });
277
- } else {
278
- switch (index) {
279
- case 1:
280
- index = "dots";
281
- break;
282
- case 2:
283
- index = "gauge";
284
- break;
285
- case 3:
286
- index = "inner-circles";
287
- break;
288
- case 4:
289
- index = "plus";
290
- break;
291
- }
292
- loading = imFun.Loading.service({
293
- lock: true,
294
- text: text || loadingText,
295
- spinner: index + "-loader",
296
- background: "hsla(0,0%,100%,.8)",
297
- target: this.target,
298
- });
299
- }
300
- return loading;
301
- };
302
- /* 全局Message */
303
- Vue.prototype.$baseMessage = ({ message, type, onClose }) => {
304
- imFun.Message({
305
- offset: 60,
306
- showClose: true,
307
- message: message,
308
- type: type,
309
- dangerouslyUseHTMLString: true,
310
- duration: messageDuration,
311
- onClose: onClose,
312
- });
313
- };
314
-
315
- /* 全局Alert */
316
- Vue.prototype.$baseAlert = function (content, title, callback) {
317
- imFun.MessageBox.alert(content, title || "提示", {
318
- confirmButtonText: "确定",
319
- dangerouslyUseHTMLString: true,
320
- target: this.$el,
321
- confirmButtonClass: "icondui",
322
- customClass: "dialog-style",
323
- callback: (action) => {
324
- if (callback) {
325
- callback();
326
- }
327
- },
328
- });
329
- };
330
-
331
- /* 全局Confirm */
332
- Vue.prototype.$baseConfirm = function (content, title) {
333
- return imFun.MessageBox.confirm(content, title || "提示", {
334
- confirmButtonText: "确定",
335
- cancelButtonText: "取消",
336
- closeOnClickModal: false,
337
- type: "warning",
338
- customClass: "dialog-style",
339
- cancelButtonClass: "iconguanbi",
340
- confirmButtonClass: "icondui",
341
- });
342
- };
343
-
344
- /* 全局Notification */
345
- Vue.prototype.$baseNotify = (message, title, type, position) => {
346
- imFun.Notification({
347
- title: title,
348
- message: message,
349
- position: position || "top-right",
350
- type: type || "success",
351
- duration: messageDuration,
352
- });
353
- };
354
-
355
- /* 全局TableHeight */
356
- Vue.prototype.$baseTableHeight = (formType) => {
357
- let height = window.innerHeight;
358
- let paddingHeight = 400;
359
- const formHeight = 50;
360
-
361
- if (true) {
362
- paddingHeight = 365;
363
- }
364
-
365
- if ("number" === typeof formType) {
366
- height = height - paddingHeight - formHeight * formType;
367
- } else {
368
- height = height - paddingHeight;
369
- }
370
- return height;
371
- };
372
-
373
- /* 全局map图层 */
374
- Vue.prototype.$baseMap = () => {
375
- return new maptalks.Map("map", {
376
- center: [116.41348403785, 39.910843952376],
377
- zoom: 12,
378
- minZoom: 1,
379
- maxZoom: 19,
380
- spatialReference: {
381
- projection: "baidu",
382
- },
383
- attribution: {
384
- content: "© vue-admin-beautiful",
385
- },
386
- baseLayer: new maptalks.TileLayer("base", {
387
- cssFilter: "sepia(100%) invert(90%)",
388
- urlTemplate:
389
- "http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1",
390
- subdomains: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
391
- attribution:
392
- '&copy; <a target="_blank" href="http://map.baidu.com">Baidu</a>',
393
- }),
394
- });
395
- };
396
-
397
- /* 全局lodash */
398
- Vue.prototype.$baseLodash = imFun.lodash;
399
- /* 全局事件总线 */
400
- Vue.prototype.$baseEventBus = new Vue();
401
-
402
- Vue.prototype.$commonFileUtil = {
403
- // 文件类型获取与判断接口
404
- getFileSuffix: function (name) {
405
- let i = name.lastIndexOf(".");
406
- if (i < 0) {
407
- // 默认是文本类型
408
- return "";
409
- }
410
- let suffix = name.substring(i + 1, name.length).toLowerCase();
411
- return suffix;
412
- },
413
- isBinary: function (suffix) {
414
- if (!suffix || suffix === "") {
415
- return false;
416
- }
417
- let fileTypeMap = {
418
- bin: true,
419
- exe: true,
420
- dll: true,
421
- so: true,
422
- lib: true,
423
- war: true,
424
- jar: true,
425
- };
426
- let type = fileTypeMap[suffix];
427
- if (undefined === type) {
428
- return false;
429
- }
430
- return true;
431
- },
432
- isPicture: function (suffix) {
433
- if (!suffix || suffix === "") {
434
- return false;
435
- }
436
-
437
- let fileTypeMap = {
438
- jpg: true,
439
- jpeg: true,
440
- png: true,
441
- gif: true,
442
- bmp: true,
443
- mpg: true,
444
- webp: true,
445
- };
446
-
447
- let type = fileTypeMap[suffix];
448
- if (undefined === type) {
449
- return false;
450
- }
451
-
452
- return true;
453
- },
454
- isVideo: function (suffix) {
455
- if (!suffix || suffix === "") {
456
- return false;
457
- }
458
- let fileTypeMap = {
459
- avi: true,
460
- mov: true,
461
- mpeg: true,
462
- mpg: true,
463
- mp4: true,
464
- rmvb: true,
465
- asf: true,
466
- flv: true,
467
- ogg: true,
468
- };
469
-
470
- let type = fileTypeMap[suffix];
471
- if (undefined === type) {
472
- return false;
473
- }
474
-
475
- return true;
476
- },
477
- isText: function (suffix) {
478
- if (!suffix || suffix === "") {
479
- return false;
480
- }
481
- let fileTypeMap = {
482
- txt: true,
483
- log: true,
484
- md: true,
485
- py: true,
486
- java: true,
487
- cpp: true,
488
- hpp: true,
489
- c: true,
490
- h: true,
491
- json: true,
492
- xml: true,
493
- html: true,
494
- sql: true,
495
- js: true,
496
- css: true,
497
- jsp: true,
498
- php: true,
499
- properties: true,
500
- conf: true,
501
- out: true,
502
- sh: true,
503
- bat: true,
504
- msg: true,
505
- cmake: true,
506
- yaml: true,
507
- yml: true,
508
- };
509
-
510
- let type = fileTypeMap[suffix];
511
- if (undefined === type) {
512
- return false;
513
- }
514
-
515
- return true;
516
- },
517
- isZip: function (suffix) {
518
- if (!suffix || suffix === "") {
519
- return false;
520
- }
521
- let fileTypeMap = {
522
- zip: true,
523
- war: true,
524
- rar: true,
525
- "7z": true,
526
- gz: true,
527
- tgz: true,
528
- xz: true,
529
- txz: true,
530
- bz2: true,
531
- tbz2: true,
532
- tar: true,
533
- };
534
-
535
- let type = fileTypeMap[suffix];
536
- if (undefined === type) {
537
- return false;
538
- }
539
-
540
- return true;
541
- },
542
- isOffice: function (suffix) {
543
- if (!suffix || suffix === "") {
544
- return false;
545
- }
546
- let fileTypeMap = {
547
- doc: true,
548
- docx: true,
549
- ppt: true,
550
- pptx: true,
551
- xls: true,
552
- xlsx: true,
553
- };
554
-
555
- let type = fileTypeMap[suffix];
556
- if (undefined === type) {
557
- return false;
558
- }
559
-
560
- return true;
561
- },
562
- isPdf: function (suffix) {
563
- if (!suffix || suffix === "") {
564
- return false;
565
- }
566
- let fileTypeMap = {
567
- pdf: true,
568
- };
569
-
570
- let type = fileTypeMap[suffix];
571
- if (undefined === type) {
572
- return false;
573
- }
574
-
575
- return true;
576
- },
577
- isPictureFile: function (fileName) {
578
- if (!fileName) return false;
579
- let typeStr = Object.prototype.toString.call(fileName);
580
- let suffix = null;
581
- if (typeStr === "[object Object]") {
582
- suffix = this.getFileSuffix(fileName.name);
583
- } else {
584
- suffix = this.getFileSuffix(fileName);
585
- }
586
- return this.isPicture(suffix);
587
- },
588
- isTextFile: function (fileName) {
589
- let suffix = this.getFileSuffix(fileName);
590
- return this.isText(suffix);
591
- },
592
- getShowUrl(url, showImagePreview) {
593
- let index = url.lastIndexOf("/");
594
- let filename;
595
- if (index >= 0) {
596
- filename = url.substring(url.lastIndexOf("/") + 1);
597
- } else {
598
- filename = url;
599
- }
600
-
601
- if (this.isPictureFile(filename) && showImagePreview !== false) {
602
- return url;
603
- } else {
604
- return this.getFileIconRequire(filename);
605
- }
606
- },
607
- resolveFileIconName: function (name, showType) {
608
- let iconType = this.getDiyFileIconType(name) || "other";
609
- if (showType) {
610
- iconType = showType;
611
- }
612
- return FILE_ICON_NAME_MAP[iconType];
613
- },
614
- getFileIconRequire: function (name, showType) {
615
- return reqImg(this.resolveFileIconName(name, showType));
616
- },
617
- getFileIconPath: function (name, showType) {
618
- return "/resources/images/" + this.resolveFileIconName(name, showType);
619
- },
620
- getDiyFileIconType: function (name) {
621
- let suffix = this.getFileSuffix(name);
622
- if (suffix === "") {
623
- // 默认是文本类型
624
- return "";
625
- }
626
-
627
- let iconType = FILE_ICON_TYPE_MAP[suffix];
628
- if (undefined === iconType) {
629
- return "";
630
- }
631
- return iconType;
632
- },
633
- getFileExtension(urlString) {
634
- if (!urlString) return null;
635
- const url = new URL(urlString);
636
- // 获取路径部分,例如 "/images/photo.jpg"
637
- const pathname = url.pathname;
638
-
639
- // 使用 lastIndexOf 找到最后一个点的位置
640
- const lastDotIndex = pathname.lastIndexOf(".");
641
-
642
- // 如果没有点,或者点在最后一位(即没有后缀),返回空字符串
643
- if (lastDotIndex === -1 || lastDotIndex === pathname.length - 1) {
644
- return "";
645
- }
646
-
647
- // 截取点之后的部分
648
- return pathname.slice(lastDotIndex + 1).toLowerCase();
649
- },
650
- downloadFile: function () {
651
- let filePath, name;
652
- let opts;
653
- if (typeof arguments[0] === "string") {
654
- filePath = arguments[0];
655
- name = arguments[1];
656
- } else {
657
- opts = arguments[0];
658
- filePath = opts.filePath;
659
- name = opts.name;
660
- }
661
- if (filePath) {
662
- let url = null;
663
- if (filePath.indexOf("?") >= 0) {
664
- url = filePath + "&_d=true";
665
- } else {
666
- url = filePath + "?_d=true";
667
- }
668
- if (name) {
669
- let fileSuffix = this.getFileExtension(filePath);
670
- if (fileSuffix && !name.endsWith("." + fileSuffix)) {
671
- name = name + "." + fileSuffix;
672
- }
673
-
674
- url += "&_n=" + encodeURIComponent(name);
675
- }
676
- // window.open(url);
677
- openInNewTab(url);
678
- }
679
- },
680
- isPreviewFile(fileName) {
681
- let fileSuffix = this.getFileSuffix(fileName);
682
- return typeList.includes(fileSuffix);
683
- },
684
- };
685
-
686
- Vue.prototype.$openFilePreview = function () {
687
- let filePath;
688
- let opts;
689
- if (typeof arguments[0] === "string") {
690
- filePath = arguments[0];
691
- } else {
692
- let attachment = arguments[0];
693
- filePath = attachment.domain + attachment.url;
694
- }
695
- let fileSuffix = this.$commonFileUtil.getFileSuffix(filePath);
696
- if (!typeList.includes(fileSuffix)) {
697
- return;
698
- }
699
-
700
- this.$http({
701
- url: USER_PREFIX + "/sf_common/getFilePreviewUrl",
702
- method: `post`,
703
- data: {
704
- url: filePath,
705
- },
706
- isLoading: true,
707
- success: (res) => {
708
- if (res.objx) {
709
- openInNewTab(res.objx);
710
- }
711
- },
712
- });
713
- };
714
-
715
- function openInNewTab(url) {
716
- if (!url) return;
717
- let a = document.createElement("a");
718
- a.href = url;
719
- a.target = "_blank";
720
- document.body.appendChild(a);
721
- a.click();
722
- document.body.removeChild(a);
723
- }
724
-
725
- Vue.prototype.$getFilePreviewUrl = async function (obj, callback) {
726
- let filePath;
727
- let opts;
728
- if (typeof obj === "string") {
729
- filePath = obj;
730
- } else {
731
- let attachment = obj;
732
- filePath = attachment.domain + attachment.url;
733
- }
734
- let fileSuffix = this.$commonFileUtil.getFileSuffix(filePath);
735
- /*if (!typeList.includes(fileSuffix)) {
736
- return;
737
- }*/
738
-
739
- return this.$http({
740
- url: USER_PREFIX + "/sf_common/getFilePreviewUrl",
741
- method: `post`,
742
- data: {
743
- url: filePath,
744
- },
745
- isLoading: true,
746
- success: (res) => {
747
- callback && callback(res.objx);
748
- },
749
- });
750
- };
751
-
752
- Vue.prototype.$baseFilePreview = function (attachment, index) {
753
- let that = this;
754
- let openImagePreView = function (attachments, index) {
755
- let pictureIndex = -1;
756
- let pictureDtoList = [];
757
- index = index || 0;
758
- attachments.forEach((item, i) => {
759
- let typeStr = Object.prototype.toString.call(item);
760
- if (typeStr === "[object Object]") {
761
- if (that.$commonFileUtil.isPictureFile(item.url)) {
762
- if (i <= index) {
763
- pictureIndex++;
764
- }
765
- pictureDtoList.push(item.domain + item.url);
766
- }
767
- } else {
768
- if (that.$commonFileUtil.isPictureFile(item)) {
769
- if (i <= index) {
770
- pictureIndex++;
771
- }
772
- pictureDtoList.push(item);
773
- }
774
- }
775
- });
776
-
777
- let a = Vue.extend(ElImageViewer);
778
- let instance = new a({
779
- propsData: {
780
- onClose: () => {
781
- dom.remove();
782
- },
783
- initialIndex: pictureIndex,
784
- urlList: pictureDtoList,
785
- },
786
- });
787
- let dom = instance.$mount().$el;
788
- document.body.append(dom);
789
- };
790
- let openPreview = function (attachment, index) {
791
- if (Array.isArray(attachment)) {
792
- let currentFile = attachment[index];
793
- let typeStr = Object.prototype.toString.call(currentFile);
794
- let url =
795
- typeStr === "[object Object]"
796
- ? currentFile.domain + currentFile.url
797
- : currentFile;
798
- if (that.$commonFileUtil.isPictureFile(url)) {
799
- openImagePreView(attachment, index);
800
- } else if (that.$commonFileUtil.isPreviewFile(url)) {
801
- that.$openFilePreview(url);
802
- }
803
- } else {
804
- let typeStr = Object.prototype.toString.call(attachment);
805
- let url =
806
- typeStr === "[object Object]"
807
- ? attachment.domain + attachment.url
808
- : attachment;
809
- if (that.$commonFileUtil.isPictureFile(url)) {
810
- openImagePreView([url], 0);
811
- } else if (that.$commonFileUtil.isPreviewFile(url)) {
812
- that.$openFilePreview(url);
813
- }
814
- }
815
- };
816
- openPreview(attachment, index);
817
- };
818
-
819
- Vue.prototype.$openEditView = function (key) {
820
- this[key] = false;
821
- setTimeout(() => {
822
- this[key] = true;
823
- }, 200);
824
- };
825
-
826
- Vue.prototype.$baseReload = function (param) {
827
- this.$emit("reload", this, param);
828
- };
829
-
830
- Vue.prototype.$reloadHandle = function (target, param) {
831
- let visibleKey = target.$attrs["visible-key"] || "showEdit";
832
- let parentTarget = target.$attrs["parent-target"] || target.$parent;
833
- let originTarget = parentTarget.$refs._viewDialog ? parentTarget : target;
834
- let updateParam =
835
- param !== null &&
836
- param !== undefined &&
837
- param.updateParam !== null &&
838
- param.updateParam !== undefined
839
- ? param.updateParam
840
- : {};
841
- for (let key in updateParam) {
842
- originTarget.$emit("update:" + key, updateParam[key]);
843
- }
844
- parentTarget[visibleKey] = false;
845
- return new Promise((resolve) => {
846
- setTimeout(() => {
847
- parentTarget[visibleKey] = true;
848
- parentTarget.$nextTick(resolve);
849
- }, 200);
850
- });
851
- };
852
-
853
- Vue.prototype.$baseStartPickerOptions = function (value, type) {
854
- return {
855
- disabledDate: (time) => {
856
- if (value !== null && value !== undefined && value !== "") {
857
- let date = new Date(value.replace(/-/g, "/"));
858
- if (!type || type === "date") {
859
- date.setDate(date.getDate() + 1);
860
- return time.getTime() >= date.getTime();
861
- } else if (type === "year") {
862
- return time.getYear() > date.getYear();
863
- } else if (type === "month") {
864
- date.setMonth(date.getMonth() + 1);
865
- return time.getTime() >= date.getTime();
866
- }
867
- } else {
868
- return false;
869
- }
870
- },
871
- };
872
- };
873
-
874
- Vue.prototype.$baseEndPickerOptions = function (value, format) {
875
- return {
876
- disabledDate: (time) => {
877
- if (value !== null && value !== undefined && value !== "") {
878
- let date = new Date(value.replace(/-/g, "/"));
879
- return time.getTime() < date.getTime();
880
- } else {
881
- return false;
882
- }
883
- },
884
- };
885
- };
886
-
887
- //除法
888
- function baseDiv() {
889
- let value = 0;
890
- if (arguments.length) {
891
- value = arguments[0];
892
- for (let i = 1; i < arguments.length; i++) {
893
- value = XEUtils.divide(value, arguments[i]);
894
- }
895
- }
896
- return value;
897
- }
898
-
899
- //乘法
900
- function baseMul() {
901
- let value = 0;
902
- if (arguments.length) {
903
- value = arguments[0];
904
- for (let i = 1; i < arguments.length; i++) {
905
- value = XEUtils.multiply(value, arguments[i]);
906
- }
907
- }
908
- return value;
909
- }
910
-
911
- //加法
912
- function baseAdd() {
913
- let value = 0;
914
- if (arguments.length) {
915
- value = arguments[0];
916
- for (let i = 1; i < arguments.length; i++) {
917
- value = XEUtils.add(value, arguments[i]);
918
- }
919
- }
920
- return value;
921
- }
922
-
923
- //减法
924
- function baseSub() {
925
- let value = 0;
926
- if (arguments.length) {
927
- value = arguments[0];
928
- for (let i = 1; i < arguments.length; i++) {
929
- value = XEUtils.subtract(value, arguments[i]);
930
- }
931
- }
932
- return value;
933
- }
934
-
935
- Vue.prototype.$baseAdd = baseAdd;
936
- Vue.prototype.$baseSub = baseSub;
937
- Vue.prototype.$baseMul = baseMul;
938
- Vue.prototype.$baseDiv = baseDiv;
939
-
940
- /**
941
- * 格式化数字为带千分位的字符串。
942
- *
943
- * @param {string | number} value - 输入值
944
- * @param {Object} [options={}] - 配置
945
- * @param {boolean} [options.fixed=false] -
946
- * - `true`: 启用定点精度处理 —— 使用 toFixed(digits) 四舍五入并补零到指定小数位。
947
- * - `false`(默认): 保留原始小数形式(不四舍五入、不补零、保留尾随零)。
948
- * @param {number} [options.digits=2] - 小数位数(仅在 fixed: true 时生效)
949
- * @param {string} [options.thousandsSeparator=','] - 千分位分隔符(始终生效)
950
- * @param {string} [options.decimalSeparator='.'] - 小数点符号
951
- * @returns {string}
952
- *
953
- * @example
954
- * // 默认:保留原始小数
955
- * formatNumber(0.2); // "0.2"
956
- * formatNumber("0.2000"); // "0.2000"
957
- *
958
- * // 启用定点精度处理
959
- * formatNumber(0.2, { fixed: true }); // "0.20"
960
- * formatNumber("123.456", { fixed: true, digits: 1 }); // "123.5"
961
- * formatNumber(1000, { fixed: true, digits: 0 }); // "1,000"
962
- */
963
- function formatNumber(value, options = {}) {
964
- if (value === null || value === undefined || value === "") {
965
- return "";
966
- }
967
-
968
- const {
969
- fixed = false,
970
- digits = 2,
971
- thousandsSeparator = ",",
972
- decimalSeparator = ".",
973
- } = options;
974
-
975
- const isNumber = typeof value === "number";
976
- let str = String(value).trim();
977
-
978
- // Normalize ".123" → "0.123"
979
- if (str.charCodeAt(0) === 46) {
980
- str = "0" + str;
981
- } else if (str.startsWith("-.")) {
982
- str = "-0." + str.slice(2);
983
- }
984
-
985
- let intPart, decPart, isNegative;
986
-
987
- if (fixed) {
988
- // ✅ 启用精度处理:toFixed + 补零
989
- const num = isNumber ? value : parseFloat(str);
990
- if (num !== num) return str;
991
-
992
- const fixedStr = num.toFixed(digits);
993
- const dotIndex = fixedStr.indexOf(".");
994
- intPart = dotIndex === -1 ? fixedStr : fixedStr.slice(0, dotIndex);
995
- decPart = dotIndex === -1 ? "" : fixedStr.slice(dotIndex + 1);
996
- isNegative = intPart.charCodeAt(0) === 45;
997
- if (isNegative) intPart = intPart.slice(1);
998
- } else {
999
- // 保留原始小数
1000
- let s = str;
1001
- isNegative = s.charCodeAt(0) === 45;
1002
- if (isNegative) s = s.slice(1);
1003
-
1004
- const dotIndex = s.indexOf(".");
1005
- intPart = dotIndex === -1 ? s : s.slice(0, dotIndex);
1006
- decPart = dotIndex === -1 ? "" : s.slice(dotIndex + 1);
1007
-
1008
- if (intPart === "") intPart = "0";
1009
- if (!/^\d+$/.test(intPart)) return str;
1010
- }
1011
-
1012
- // 千分位(始终应用)
1013
- let fmtInt = intPart;
1014
- if (intPart !== "0") {
1015
- let out = "";
1016
- for (let i = intPart.length - 1, c = 0; i >= 0; i--, c++) {
1017
- if (c > 0 && c % 3 === 0) out = thousandsSeparator + out;
1018
- out = intPart[i] + out;
1019
- }
1020
- fmtInt = out;
1021
- }
1022
-
1023
- // 拼接
1024
- let result = isNegative ? "-" + fmtInt : fmtInt;
1025
- if (decPart) {
1026
- result += decimalSeparator + decPart;
1027
- } else if (fixed && digits > 0) {
1028
- result += decimalSeparator + "0".repeat(digits);
1029
- }
1030
-
1031
- return result;
1032
- }
1033
- Vue.prototype.$formatNumber = formatNumber;
1034
-
1035
- /**
1036
- * 生成一个符合 RFC4122 标准的随机 UUID (v4)
1037
- * @returns {string} 格式为 "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx" 的 UUID 字符串
1038
- */
1039
- function generateUUID() {
1040
- const buf = new Uint8Array(16);
1041
- crypto.getRandomValues(buf);
1042
- buf[6] = (buf[6] & 0x0f) | 0x40; // version 4
1043
- buf[8] = (buf[8] & 0x3f) | 0x80; // variant RFC4122
1044
- const hex = Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join(
1045
- ""
1046
- );
1047
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(
1048
- 12,
1049
- 16
1050
- )}-${hex.slice(16, 20)}-${hex.slice(20)}`;
1051
- }
1052
- Vue.prototype.$generateUUID = generateUUID;
1053
-
1054
- //数字精确位数
1055
- Vue.prototype.$currency = function (value, priceScale, priceRoundType) {
1056
- if (value !== null && value !== undefined) {
1057
- if (priceScale === null || priceScale === undefined) {
1058
- priceScale = 2;
1059
- }
1060
- if (priceRoundType === null || priceRoundType === undefined) {
1061
- priceRoundType = "roundHalfUp";
1062
- }
1063
- let price;
1064
- if (priceRoundType === "roundHalfUp") {
1065
- price = (
1066
- Math.round(value * Math.pow(10, priceScale)) /
1067
- Math.pow(10, priceScale)
1068
- ).toFixed(priceScale);
1069
- } else if (priceRoundType === "roundUp") {
1070
- price = (
1071
- Math.ceil(value * Math.pow(10, priceScale)) / Math.pow(10, priceScale)
1072
- ).toFixed(priceScale);
1073
- } else {
1074
- price = (
1075
- Math.floor(value * Math.pow(10, priceScale)) /
1076
- Math.pow(10, priceScale)
1077
- ).toFixed(priceScale);
1078
- }
1079
- return price;
1080
- }
1081
- };
1082
-
1083
- Vue.prototype.$getBaseDicts = async function (option) {
1084
- let isLoading = option.isLoading || false;
1085
- return this.$http({
1086
- url: USER_PREFIX + "/common_attribute/listItems",
1087
- method: `post`,
1088
- data: {
1089
- code: option.code,
1090
- enabled: true,
1091
- forCompany: true,
1092
- ...option.data,
1093
- },
1094
- isLoading: isLoading,
1095
- modalStrictly: true,
1096
- success: (res) => {
1097
- let dicts = res.objx || [];
1098
- let dictMap = {};
1099
- for (let item of dicts) {
1100
- dictMap[item.sn] = item.value;
1101
- }
1102
- /* dicts.forEach((item) => {
1103
- dictMap[item.sn] = item.value;
1104
- }); */
1105
- option.success &&
1106
- option.success({
1107
- dicts,
1108
- dictMap,
1109
- });
1110
- },
1111
- });
1112
- };
1113
-
1114
- imFun.Form.methods.$baseValidate = function (callback, opt) {
1115
- let that = this;
1116
- that.validate((valid, obj, c, d) => {
1117
- if (!valid && (!opt || opt.errorTip !== false)) {
1118
- this.$message({
1119
- message: this.$t2("必填项不能为空", "system.message.required"),
1120
- type: "error",
1121
- duration: 2000,
1122
- });
1123
- }
1124
- scrollToFirstError(that);
1125
- callback(valid, obj);
1126
- });
1127
- };
1128
-
1129
- function scrollToFirstError(formTarget) {
1130
- // 获取第一个验证失败的字段
1131
- // let formTarget = this.$refs['renderForm'];
1132
- const firstErrorField = Object.keys(formTarget.fields).find((key) => {
1133
- return formTarget.fields[key].validateState === "error";
1134
- });
1135
-
1136
- if (firstErrorField) {
1137
- const field = formTarget.fields[firstErrorField];
1138
-
1139
- let dom = field.$el;
1140
- if (dom) {
1141
- // 滚动到该字段位置
1142
- dom.scrollIntoView({
1143
- behavior: "smooth",
1144
- block: "center",
1145
- });
1146
-
1147
- // 添加高亮效果
1148
- dom.classList.add("highlight");
1149
-
1150
- // 3秒后移除高亮效果
1151
- setTimeout(() => {
1152
- dom.classList.remove("highlight");
1153
- }, 3000);
1154
- }
1155
- }
1156
- }
1157
-
1158
- Vue.prototype.$getBillInfo = async function (option) {
1159
- let defaultOption = {
1160
- url: null,
1161
- method: `post`,
1162
- data: {},
1163
- isLoading: true,
1164
- modalStrictly: true,
1165
- success: null,
1166
- };
1167
- let opt = Object.assign({}, defaultOption, option);
1168
- delete opt.wfConfig;
1169
- return this.$http({
1170
- ...opt,
1171
- success: (res, response) => {
1172
- option.success && option.success(res, response);
1173
- },
1174
- });
1175
- };
1176
-
1177
- Vue.prototype.$downloadByFileWhole = function (fileWhole, fileName) {
1178
- let that = this;
1179
- if (!fileWhole) {
1180
- this.$baseAlert("凭证信息不存在");
1181
- return;
1182
- }
1183
- let getDownloadDomian = function (callback) {
1184
- that.$http({
1185
- method: "post",
1186
- url: USER_PREFIX + "/common/fileDownloadUrl",
1187
- data: {},
1188
- isLoading: true,
1189
- success: (res) => {
1190
- callback(res.objx);
1191
- },
1192
- });
1193
- };
1194
- getDownloadDomian((domain) => {
1195
- if (fileName) {
1196
- fileWhole.fileName = fileName;
1197
- }
1198
- that.$http({
1199
- method: "post",
1200
- url: domain + "/docfile/download",
1201
- data: fileWhole,
1202
- isLoading: true,
1203
- success: (res) => {
1204
- // window.open(res.objx.url);
1205
- let url = res.objx.url;
1206
- openInNewTab(url);
1207
- },
1208
- });
1209
- });
1210
- };
1211
-
1212
- let isDef = function (value) {
1213
- return value !== undefined && value !== null;
1214
- };
1215
-
1216
- Vue.prototype.$t2 = function (defaultValue, path, values) {
1217
- let that = window.$vueRoot;
1218
- if (!that.hasOwnProperty("_i18n")) {
1219
- return defaultValue;
1220
- }
1221
- const i18n = that.$i18n;
1222
- path = path || defaultValue;
1223
- return i18n.te(path) ? i18n.t(path, values) : defaultValue;
1224
- };
1225
-
1226
- Vue.prototype.$t1 = function (path, values) {
1227
- let that = window.$vueRoot;
1228
- if (!that.hasOwnProperty("_i18n")) {
1229
- return path;
1230
- }
1231
- let lang = that.$i18n.locale;
1232
- const i18n = that.$i18n;
1233
- if (lang === "zh") {
1234
- let val = i18n._t(path, lang, { zh: { [path]: path } }, null, values);
1235
- return val;
1236
- } else {
1237
- if (!i18n.te(path)) {
1238
- return i18n._t(path, lang, { zh: { [path]: path } }, null, values);
1239
- } else {
1240
- return (
1241
- i18n.t(path, values) ||
1242
- i18n._t(path, lang, { zh: { [path]: path } }, null, values)
1243
- );
1244
- }
1245
- }
1246
- };
1247
-
1248
- Vue.prototype.$i18nVal = function (zhValue, enValue) {
1249
- let that = window.$vueRoot;
1250
- if (!that.hasOwnProperty("_i18n")) {
1251
- return zhValue;
1252
- }
1253
- let $i18n = that.$i18n;
1254
- let value = zhValue;
1255
- if ($i18n.locale === "zh") {
1256
- value = zhValue;
1257
- } else if ($i18n.locale === "en") {
1258
- value = enValue;
1259
- }
1260
- return value;
1261
- };
1262
-
1263
- Vue.prototype.$utcToLocal = function (utcTime) {
1264
- if (!utcTime) return utcTime;
1265
- let offsetHours = this.$store.getters.utcTransformOffset; // 时区偏移量,单位:小时
1266
- if (!offsetHours || offsetHours === 0) return utcTime;
1267
- let localTime = moment(utcTime).add(offsetHours, "hours");
1268
- return localTime.format("YYYY-MM-DD HH:mm:ss");
1269
- };
1270
-
1271
- Vue.prototype.$window = window;
1272
- };
1273
-
1274
- window && Object.assign(window, imFun.prefixConfig);
1275
- if (typeof window !== "undefined" && window.Vue) {
1276
- install(window.Vue);
1277
- }
1278
-
1279
- export default install;
1
+ /**version-1.0*/
2
+ let install = {};
3
+
4
+ import request from "./request";
5
+ import * as lodash from "lodash";
6
+ import { Loading, Message, MessageBox, Notification, Form } from "element-ui";
7
+ import store from "../store";
8
+ import ElImageViewer from "../components/VabUpload/image-viewer";
9
+
10
+ import { getToken } from "./auth";
11
+ import XEUtils from "xe-utils";
12
+
13
+ import prefixConfig from "@/prefixConfig.js";
14
+ import moment from "moment";
15
+ import { openView } from "./repeatOpen";
16
+ import { assetUrl } from "./assetUrl";
17
+
18
+ let imFun = {
19
+ request,
20
+ lodash,
21
+ Loading,
22
+ Message,
23
+ MessageBox,
24
+ Notification,
25
+ Form,
26
+ store,
27
+ getToken,
28
+ prefixConfig,
29
+ };
30
+
31
+ function reqImg(a) {
32
+ /* webpack5 下 require 返回的是无原型的 Module 对象,直接当 src 用会崩,统一取真实 URL */
33
+ return assetUrl(require("@/resources/images/" + a));
34
+ }
35
+
36
+ const FILE_ICON_NAME_MAP = {
37
+ word: "ico-wrod.svg",
38
+ excel: "ico-excel.svg",
39
+ ppt: "ico-ppt.svg",
40
+ pdf: "ico-pdf.svg",
41
+ picture: "ico-photo.svg",
42
+ video: "ico-video.svg",
43
+ audio: "ico-music.svg",
44
+ html: "ico-html.svg",
45
+ txt: "ico-txt.svg",
46
+ java: "ico-java.svg",
47
+ vue: "ico-vue.svg",
48
+ ftl: "ico-ftl.svg",
49
+ xml: "ico-xml.svg",
50
+ flash: "ico-flash.svg",
51
+ zip: "ico-yasuobao.svg",
52
+ exe: "ico-ext.svg",
53
+ psd: "ico-psd.svg",
54
+ folder: "ico-wenjianjia.svg",
55
+ other: "ico-default_wenjian.svg",
56
+ };
57
+
58
+ const FILE_ICON_TYPE_MAP = {
59
+ doc: "word",
60
+ docx: "word",
61
+ xls: "excel",
62
+ xlsx: "excel",
63
+ ppt: "ppt",
64
+ pptx: "ppt",
65
+ pdf: "pdf",
66
+ jpg: "picture",
67
+ jpeg: "picture",
68
+ png: "picture",
69
+ gif: "picture",
70
+ mp3: "video",
71
+ mp4: "video",
72
+ mpg: "video",
73
+ mkv: "video",
74
+ rmvb: "video",
75
+ avi: "video",
76
+ mov: "video",
77
+ wav: "audio",
78
+ html: "html",
79
+ htm: "html",
80
+ txt: "txt",
81
+ java: "java",
82
+ vue: "vue",
83
+ ftl: "ftl",
84
+ xml: "xml",
85
+ swf: "flash",
86
+ zip: "zip",
87
+ rar: "zip",
88
+ "7z": "zip",
89
+ // exe: 'exe',
90
+ psd: "psd",
91
+ };
92
+
93
+ let typeList = [
94
+ "doc",
95
+ "docx",
96
+ "xls",
97
+ "xlsx",
98
+ "ppt",
99
+ "pptx",
100
+ "csv",
101
+ "wps",
102
+ "dps",
103
+ "et",
104
+ "ett",
105
+ "wpt",
106
+ "vsd",
107
+ "vsdx",
108
+ "wmf",
109
+ "emf",
110
+ "psd",
111
+ "eps",
112
+ "pdf",
113
+ "xmind",
114
+ "obj",
115
+ "3ds",
116
+ "stl",
117
+ "ply",
118
+ "gltf",
119
+ "glb",
120
+ "off",
121
+ "3dm",
122
+ "fbx",
123
+ "dae",
124
+ "wrl",
125
+ "3mf",
126
+ "ifc",
127
+ "brep",
128
+ "step",
129
+ "iges",
130
+ "fcstd",
131
+ "bim",
132
+ "dwg",
133
+ "dxf",
134
+ "dwf",
135
+ "iges",
136
+ "igs",
137
+ "dwt",
138
+ "dng",
139
+ "ifc",
140
+ "dwfx",
141
+ "stl",
142
+ "cf2",
143
+ "plt",
144
+ "txt",
145
+ "xml",
146
+ "md",
147
+ "java",
148
+ "php",
149
+ "py",
150
+ "js",
151
+ "css",
152
+ "zip",
153
+ "rar",
154
+ "jar",
155
+ "tar",
156
+ "gzip",
157
+ "7z",
158
+ "mp3",
159
+ "wav",
160
+ "mp4",
161
+ "flv",
162
+ "avi",
163
+ "mov",
164
+ "rm",
165
+ "mkv",
166
+ "mpeg",
167
+ "mpg",
168
+ "rmvb",
169
+ "wmv",
170
+ "3gp",
171
+ "swf",
172
+ "drawio",
173
+ "tif",
174
+ "tiff",
175
+ "jfif",
176
+ "webp",
177
+ "tga",
178
+ "svg",
179
+ "vue",
180
+ "ftl",
181
+ ];
182
+
183
+ const accessToken = imFun.store.getters["user/token"];
184
+
185
+ const loadingText = "";
186
+ const messageDuration = 3000;
187
+
188
+ install = (Vue, opts = {}) => {
189
+ /**http请求*/
190
+ let $http = async function (option) {
191
+ option = option || {};
192
+ if (!option.loadingTarget && this.$el) {
193
+ option.loadingTarget = this.$el;
194
+ }
195
+ if (!option.vueTarget) {
196
+ option.vueTarget = this;
197
+ }
198
+ if (option.sync === false) {
199
+ return await imFun.request(option);
200
+ } else {
201
+ return imFun.request(option);
202
+ }
203
+ };
204
+
205
+ Vue.prototype.$commonHttp = function (opts) {
206
+ let defaultOption = {
207
+ addCreateInfo: true,
208
+ queryCreateInfo: window.$vueRoot.$store.getters.queryCreateInfo || "0",
209
+ };
210
+ let option = Object.assign({}, defaultOption, opts);
211
+ if (opts.addCreateInfo === null || opts.addCreateInfo === undefined) {
212
+ option.addCreateInfo = defaultOption.addCreateInfo;
213
+ }
214
+ if (
215
+ opts.queryCreateInfo === null ||
216
+ opts.queryCreateInfo === undefined ||
217
+ opts.queryCreateInfo === true
218
+ ) {
219
+ option.queryCreateInfo = defaultOption.queryCreateInfo;
220
+ }
221
+ if (opts.queryCreateInfo === false) {
222
+ option.queryCreateInfo = "0";
223
+ }
224
+ return this.$http(option);
225
+ };
226
+
227
+ Object.assign($http, imFun.request);
228
+ $http.prototype = imFun.request.prototype;
229
+ Vue.prototype.$http = $http;
230
+
231
+ /* 通用打开菜单/路由:开关开启时以独立标签重复打开,否则按原逻辑跳转
232
+ * 用法:this.$openView('/path') 或 this.$openView({ path, query }[, route]) */
233
+ Vue.prototype.$openView = function (location, route) {
234
+ return openView(this.$router, location, route);
235
+ };
236
+
237
+ /* 全局accessToken */
238
+ Vue.prototype.$baseAccessToken = () => {
239
+ return accessToken || imFun.getToken();
240
+ };
241
+
242
+ /* 全局加载层 */
243
+ Vue.prototype.$baseLoading = function (option) {
244
+ let d = this.$el;
245
+ let loading;
246
+ option = option || {};
247
+ if (!option.index) {
248
+ let opts = {
249
+ lock: true,
250
+ background: "hsla(0,0%,100%,.8)",
251
+ target: d,
252
+ };
253
+ Object.assign(opts, option);
254
+ loading = imFun.Loading.service(opts);
255
+ } else {
256
+ let opts = {
257
+ lock: true,
258
+ spinner: "vab-loading-type" + option.index,
259
+ background: "hsla(0,0%,100%,.8)",
260
+ target: d,
261
+ };
262
+ Object.assign(opts, option);
263
+ loading = imFun.Loading.service(opts);
264
+ }
265
+ return loading;
266
+ };
267
+ /* 全局多彩加载层 */
268
+ Vue.prototype.$baseColorfullLoading = function (index, text) {
269
+ let loading;
270
+ if (!index) {
271
+ loading = imFun.Loading.service({
272
+ lock: true,
273
+ text: text || loadingText,
274
+ spinner: "dots-loader",
275
+ background: "hsla(0,0%,100%,.8)",
276
+ target: this.target,
277
+ fullscreen: true,
278
+ });
279
+ } else {
280
+ switch (index) {
281
+ case 1:
282
+ index = "dots";
283
+ break;
284
+ case 2:
285
+ index = "gauge";
286
+ break;
287
+ case 3:
288
+ index = "inner-circles";
289
+ break;
290
+ case 4:
291
+ index = "plus";
292
+ break;
293
+ }
294
+ loading = imFun.Loading.service({
295
+ lock: true,
296
+ text: text || loadingText,
297
+ spinner: index + "-loader",
298
+ background: "hsla(0,0%,100%,.8)",
299
+ target: this.target,
300
+ });
301
+ }
302
+ return loading;
303
+ };
304
+ /* 全局Message */
305
+ Vue.prototype.$baseMessage = ({ message, type, onClose }) => {
306
+ imFun.Message({
307
+ offset: 60,
308
+ showClose: true,
309
+ message: message,
310
+ type: type,
311
+ dangerouslyUseHTMLString: true,
312
+ duration: messageDuration,
313
+ onClose: onClose,
314
+ });
315
+ };
316
+
317
+ /* 全局Alert */
318
+ Vue.prototype.$baseAlert = function (content, title, callback) {
319
+ imFun.MessageBox.alert(content, title || "提示", {
320
+ confirmButtonText: "确定",
321
+ dangerouslyUseHTMLString: true,
322
+ target: this.$el,
323
+ confirmButtonClass: "icondui",
324
+ customClass: "dialog-style",
325
+ callback: (action) => {
326
+ if (callback) {
327
+ callback();
328
+ }
329
+ },
330
+ });
331
+ };
332
+
333
+ /* 全局Confirm */
334
+ Vue.prototype.$baseConfirm = function (content, title) {
335
+ return imFun.MessageBox.confirm(content, title || "提示", {
336
+ confirmButtonText: "确定",
337
+ cancelButtonText: "取消",
338
+ closeOnClickModal: false,
339
+ type: "warning",
340
+ customClass: "dialog-style",
341
+ cancelButtonClass: "iconguanbi",
342
+ confirmButtonClass: "icondui",
343
+ });
344
+ };
345
+
346
+ /* 全局Notification */
347
+ Vue.prototype.$baseNotify = (message, title, type, position) => {
348
+ imFun.Notification({
349
+ title: title,
350
+ message: message,
351
+ position: position || "top-right",
352
+ type: type || "success",
353
+ duration: messageDuration,
354
+ });
355
+ };
356
+
357
+ /* 全局TableHeight */
358
+ Vue.prototype.$baseTableHeight = (formType) => {
359
+ let height = window.innerHeight;
360
+ let paddingHeight = 400;
361
+ const formHeight = 50;
362
+
363
+ if (true) {
364
+ paddingHeight = 365;
365
+ }
366
+
367
+ if ("number" === typeof formType) {
368
+ height = height - paddingHeight - formHeight * formType;
369
+ } else {
370
+ height = height - paddingHeight;
371
+ }
372
+ return height;
373
+ };
374
+
375
+ /* 全局map图层 */
376
+ Vue.prototype.$baseMap = () => {
377
+ return new maptalks.Map("map", {
378
+ center: [116.41348403785, 39.910843952376],
379
+ zoom: 12,
380
+ minZoom: 1,
381
+ maxZoom: 19,
382
+ spatialReference: {
383
+ projection: "baidu",
384
+ },
385
+ attribution: {
386
+ content: "&copy; vue-admin-beautiful",
387
+ },
388
+ baseLayer: new maptalks.TileLayer("base", {
389
+ cssFilter: "sepia(100%) invert(90%)",
390
+ urlTemplate:
391
+ "http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1",
392
+ subdomains: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
393
+ attribution:
394
+ '&copy; <a target="_blank" href="http://map.baidu.com">Baidu</a>',
395
+ }),
396
+ });
397
+ };
398
+
399
+ /* 全局lodash */
400
+ Vue.prototype.$baseLodash = imFun.lodash;
401
+ /* 全局事件总线 */
402
+ Vue.prototype.$baseEventBus = new Vue();
403
+ /* 模板里 :src="$assetUrl(require(...))" 用,见 utils/assetUrl.js */
404
+ Vue.prototype.$assetUrl = assetUrl;
405
+
406
+ Vue.prototype.$commonFileUtil = {
407
+ // 文件类型获取与判断接口
408
+ getFileSuffix: function (name) {
409
+ let i = name.lastIndexOf(".");
410
+ if (i < 0) {
411
+ // 默认是文本类型
412
+ return "";
413
+ }
414
+ let suffix = name.substring(i + 1, name.length).toLowerCase();
415
+ return suffix;
416
+ },
417
+ isBinary: function (suffix) {
418
+ if (!suffix || suffix === "") {
419
+ return false;
420
+ }
421
+ let fileTypeMap = {
422
+ bin: true,
423
+ exe: true,
424
+ dll: true,
425
+ so: true,
426
+ lib: true,
427
+ war: true,
428
+ jar: true,
429
+ };
430
+ let type = fileTypeMap[suffix];
431
+ if (undefined === type) {
432
+ return false;
433
+ }
434
+ return true;
435
+ },
436
+ isPicture: function (suffix) {
437
+ if (!suffix || suffix === "") {
438
+ return false;
439
+ }
440
+
441
+ let fileTypeMap = {
442
+ jpg: true,
443
+ jpeg: true,
444
+ png: true,
445
+ gif: true,
446
+ bmp: true,
447
+ mpg: true,
448
+ webp: true,
449
+ };
450
+
451
+ let type = fileTypeMap[suffix];
452
+ if (undefined === type) {
453
+ return false;
454
+ }
455
+
456
+ return true;
457
+ },
458
+ isVideo: function (suffix) {
459
+ if (!suffix || suffix === "") {
460
+ return false;
461
+ }
462
+ let fileTypeMap = {
463
+ avi: true,
464
+ mov: true,
465
+ mpeg: true,
466
+ mpg: true,
467
+ mp4: true,
468
+ rmvb: true,
469
+ asf: true,
470
+ flv: true,
471
+ ogg: true,
472
+ };
473
+
474
+ let type = fileTypeMap[suffix];
475
+ if (undefined === type) {
476
+ return false;
477
+ }
478
+
479
+ return true;
480
+ },
481
+ isText: function (suffix) {
482
+ if (!suffix || suffix === "") {
483
+ return false;
484
+ }
485
+ let fileTypeMap = {
486
+ txt: true,
487
+ log: true,
488
+ md: true,
489
+ py: true,
490
+ java: true,
491
+ cpp: true,
492
+ hpp: true,
493
+ c: true,
494
+ h: true,
495
+ json: true,
496
+ xml: true,
497
+ html: true,
498
+ sql: true,
499
+ js: true,
500
+ css: true,
501
+ jsp: true,
502
+ php: true,
503
+ properties: true,
504
+ conf: true,
505
+ out: true,
506
+ sh: true,
507
+ bat: true,
508
+ msg: true,
509
+ cmake: true,
510
+ yaml: true,
511
+ yml: true,
512
+ };
513
+
514
+ let type = fileTypeMap[suffix];
515
+ if (undefined === type) {
516
+ return false;
517
+ }
518
+
519
+ return true;
520
+ },
521
+ isZip: function (suffix) {
522
+ if (!suffix || suffix === "") {
523
+ return false;
524
+ }
525
+ let fileTypeMap = {
526
+ zip: true,
527
+ war: true,
528
+ rar: true,
529
+ "7z": true,
530
+ gz: true,
531
+ tgz: true,
532
+ xz: true,
533
+ txz: true,
534
+ bz2: true,
535
+ tbz2: true,
536
+ tar: true,
537
+ };
538
+
539
+ let type = fileTypeMap[suffix];
540
+ if (undefined === type) {
541
+ return false;
542
+ }
543
+
544
+ return true;
545
+ },
546
+ isOffice: function (suffix) {
547
+ if (!suffix || suffix === "") {
548
+ return false;
549
+ }
550
+ let fileTypeMap = {
551
+ doc: true,
552
+ docx: true,
553
+ ppt: true,
554
+ pptx: true,
555
+ xls: true,
556
+ xlsx: true,
557
+ };
558
+
559
+ let type = fileTypeMap[suffix];
560
+ if (undefined === type) {
561
+ return false;
562
+ }
563
+
564
+ return true;
565
+ },
566
+ isPdf: function (suffix) {
567
+ if (!suffix || suffix === "") {
568
+ return false;
569
+ }
570
+ let fileTypeMap = {
571
+ pdf: true,
572
+ };
573
+
574
+ let type = fileTypeMap[suffix];
575
+ if (undefined === type) {
576
+ return false;
577
+ }
578
+
579
+ return true;
580
+ },
581
+ isPictureFile: function (fileName) {
582
+ if (!fileName) return false;
583
+ let typeStr = Object.prototype.toString.call(fileName);
584
+ let suffix = null;
585
+ if (typeStr === "[object Object]") {
586
+ suffix = this.getFileSuffix(fileName.name);
587
+ } else {
588
+ suffix = this.getFileSuffix(fileName);
589
+ }
590
+ return this.isPicture(suffix);
591
+ },
592
+ isTextFile: function (fileName) {
593
+ let suffix = this.getFileSuffix(fileName);
594
+ return this.isText(suffix);
595
+ },
596
+ getShowUrl(url, showImagePreview) {
597
+ let index = url.lastIndexOf("/");
598
+ let filename;
599
+ if (index >= 0) {
600
+ filename = url.substring(url.lastIndexOf("/") + 1);
601
+ } else {
602
+ filename = url;
603
+ }
604
+
605
+ if (this.isPictureFile(filename) && showImagePreview !== false) {
606
+ return url;
607
+ } else {
608
+ return this.getFileIconRequire(filename);
609
+ }
610
+ },
611
+ resolveFileIconName: function (name, showType) {
612
+ let iconType = this.getDiyFileIconType(name) || "other";
613
+ if (showType) {
614
+ iconType = showType;
615
+ }
616
+ return FILE_ICON_NAME_MAP[iconType];
617
+ },
618
+ getFileIconRequire: function (name, showType) {
619
+ return reqImg(this.resolveFileIconName(name, showType));
620
+ },
621
+ getFileIconPath: function (name, showType) {
622
+ return "/resources/images/" + this.resolveFileIconName(name, showType);
623
+ },
624
+ getDiyFileIconType: function (name) {
625
+ let suffix = this.getFileSuffix(name);
626
+ if (suffix === "") {
627
+ // 默认是文本类型
628
+ return "";
629
+ }
630
+
631
+ let iconType = FILE_ICON_TYPE_MAP[suffix];
632
+ if (undefined === iconType) {
633
+ return "";
634
+ }
635
+ return iconType;
636
+ },
637
+ getFileExtension(urlString) {
638
+ if (!urlString) return null;
639
+ const url = new URL(urlString);
640
+ // 获取路径部分,例如 "/images/photo.jpg"
641
+ const pathname = url.pathname;
642
+
643
+ // 使用 lastIndexOf 找到最后一个点的位置
644
+ const lastDotIndex = pathname.lastIndexOf(".");
645
+
646
+ // 如果没有点,或者点在最后一位(即没有后缀),返回空字符串
647
+ if (lastDotIndex === -1 || lastDotIndex === pathname.length - 1) {
648
+ return "";
649
+ }
650
+
651
+ // 截取点之后的部分
652
+ return pathname.slice(lastDotIndex + 1).toLowerCase();
653
+ },
654
+ downloadFile: function () {
655
+ let filePath, name;
656
+ let opts;
657
+ if (typeof arguments[0] === "string") {
658
+ filePath = arguments[0];
659
+ name = arguments[1];
660
+ } else {
661
+ opts = arguments[0];
662
+ filePath = opts.filePath;
663
+ name = opts.name;
664
+ }
665
+ if (filePath) {
666
+ let url = null;
667
+ if (filePath.indexOf("?") >= 0) {
668
+ url = filePath + "&_d=true";
669
+ } else {
670
+ url = filePath + "?_d=true";
671
+ }
672
+ if (name) {
673
+ let fileSuffix = this.getFileExtension(filePath);
674
+ if (fileSuffix && !name.endsWith("." + fileSuffix)) {
675
+ name = name + "." + fileSuffix;
676
+ }
677
+
678
+ url += "&_n=" + encodeURIComponent(name);
679
+ }
680
+ // window.open(url);
681
+ openInNewTab(url);
682
+ }
683
+ },
684
+ isPreviewFile(fileName) {
685
+ let fileSuffix = this.getFileSuffix(fileName);
686
+ return typeList.includes(fileSuffix);
687
+ },
688
+ };
689
+
690
+ Vue.prototype.$openFilePreview = function () {
691
+ let filePath;
692
+ let opts;
693
+ if (typeof arguments[0] === "string") {
694
+ filePath = arguments[0];
695
+ } else {
696
+ let attachment = arguments[0];
697
+ filePath = attachment.domain + attachment.url;
698
+ }
699
+ let fileSuffix = this.$commonFileUtil.getFileSuffix(filePath);
700
+ if (!typeList.includes(fileSuffix)) {
701
+ return;
702
+ }
703
+
704
+ this.$http({
705
+ url: USER_PREFIX + "/sf_common/getFilePreviewUrl",
706
+ method: `post`,
707
+ data: {
708
+ url: filePath,
709
+ },
710
+ isLoading: true,
711
+ success: (res) => {
712
+ if (res.objx) {
713
+ openInNewTab(res.objx);
714
+ }
715
+ },
716
+ });
717
+ };
718
+
719
+ function openInNewTab(url) {
720
+ if (!url) return;
721
+ let a = document.createElement("a");
722
+ a.href = url;
723
+ a.target = "_blank";
724
+ document.body.appendChild(a);
725
+ a.click();
726
+ document.body.removeChild(a);
727
+ }
728
+
729
+ Vue.prototype.$getFilePreviewUrl = async function (obj, callback) {
730
+ let filePath;
731
+ let opts;
732
+ if (typeof obj === "string") {
733
+ filePath = obj;
734
+ } else {
735
+ let attachment = obj;
736
+ filePath = attachment.domain + attachment.url;
737
+ }
738
+ let fileSuffix = this.$commonFileUtil.getFileSuffix(filePath);
739
+ /*if (!typeList.includes(fileSuffix)) {
740
+ return;
741
+ }*/
742
+
743
+ return this.$http({
744
+ url: USER_PREFIX + "/sf_common/getFilePreviewUrl",
745
+ method: `post`,
746
+ data: {
747
+ url: filePath,
748
+ },
749
+ isLoading: true,
750
+ success: (res) => {
751
+ callback && callback(res.objx);
752
+ },
753
+ });
754
+ };
755
+
756
+ Vue.prototype.$baseFilePreview = function (attachment, index) {
757
+ let that = this;
758
+ let openImagePreView = function (attachments, index) {
759
+ let pictureIndex = -1;
760
+ let pictureDtoList = [];
761
+ index = index || 0;
762
+ attachments.forEach((item, i) => {
763
+ let typeStr = Object.prototype.toString.call(item);
764
+ if (typeStr === "[object Object]") {
765
+ if (that.$commonFileUtil.isPictureFile(item.url)) {
766
+ if (i <= index) {
767
+ pictureIndex++;
768
+ }
769
+ pictureDtoList.push(item.domain + item.url);
770
+ }
771
+ } else {
772
+ if (that.$commonFileUtil.isPictureFile(item)) {
773
+ if (i <= index) {
774
+ pictureIndex++;
775
+ }
776
+ pictureDtoList.push(item);
777
+ }
778
+ }
779
+ });
780
+
781
+ let a = Vue.extend(ElImageViewer);
782
+ let instance = new a({
783
+ propsData: {
784
+ onClose: () => {
785
+ dom.remove();
786
+ },
787
+ initialIndex: pictureIndex,
788
+ urlList: pictureDtoList,
789
+ },
790
+ });
791
+ let dom = instance.$mount().$el;
792
+ document.body.append(dom);
793
+ };
794
+ let openPreview = function (attachment, index) {
795
+ if (Array.isArray(attachment)) {
796
+ let currentFile = attachment[index];
797
+ let typeStr = Object.prototype.toString.call(currentFile);
798
+ let url =
799
+ typeStr === "[object Object]"
800
+ ? currentFile.domain + currentFile.url
801
+ : currentFile;
802
+ if (that.$commonFileUtil.isPictureFile(url)) {
803
+ openImagePreView(attachment, index);
804
+ } else if (that.$commonFileUtil.isPreviewFile(url)) {
805
+ that.$openFilePreview(url);
806
+ }
807
+ } else {
808
+ let typeStr = Object.prototype.toString.call(attachment);
809
+ let url =
810
+ typeStr === "[object Object]"
811
+ ? attachment.domain + attachment.url
812
+ : attachment;
813
+ if (that.$commonFileUtil.isPictureFile(url)) {
814
+ openImagePreView([url], 0);
815
+ } else if (that.$commonFileUtil.isPreviewFile(url)) {
816
+ that.$openFilePreview(url);
817
+ }
818
+ }
819
+ };
820
+ openPreview(attachment, index);
821
+ };
822
+
823
+ Vue.prototype.$openEditView = function (key) {
824
+ this[key] = false;
825
+ setTimeout(() => {
826
+ this[key] = true;
827
+ }, 200);
828
+ };
829
+
830
+ Vue.prototype.$baseReload = function (param) {
831
+ this.$emit("reload", this, param);
832
+ };
833
+
834
+ Vue.prototype.$reloadHandle = function (target, param) {
835
+ let visibleKey = target.$attrs["visible-key"] || "showEdit";
836
+ let parentTarget = target.$attrs["parent-target"] || target.$parent;
837
+ let originTarget = parentTarget.$refs._viewDialog ? parentTarget : target;
838
+ let updateParam =
839
+ param !== null &&
840
+ param !== undefined &&
841
+ param.updateParam !== null &&
842
+ param.updateParam !== undefined
843
+ ? param.updateParam
844
+ : {};
845
+ for (let key in updateParam) {
846
+ originTarget.$emit("update:" + key, updateParam[key]);
847
+ }
848
+ parentTarget[visibleKey] = false;
849
+ return new Promise((resolve) => {
850
+ setTimeout(() => {
851
+ parentTarget[visibleKey] = true;
852
+ parentTarget.$nextTick(resolve);
853
+ }, 200);
854
+ });
855
+ };
856
+
857
+ Vue.prototype.$baseStartPickerOptions = function (value, type) {
858
+ return {
859
+ disabledDate: (time) => {
860
+ if (value !== null && value !== undefined && value !== "") {
861
+ let date = new Date(value.replace(/-/g, "/"));
862
+ if (!type || type === "date") {
863
+ date.setDate(date.getDate() + 1);
864
+ return time.getTime() >= date.getTime();
865
+ } else if (type === "year") {
866
+ return time.getYear() > date.getYear();
867
+ } else if (type === "month") {
868
+ date.setMonth(date.getMonth() + 1);
869
+ return time.getTime() >= date.getTime();
870
+ }
871
+ } else {
872
+ return false;
873
+ }
874
+ },
875
+ };
876
+ };
877
+
878
+ Vue.prototype.$baseEndPickerOptions = function (value, format) {
879
+ return {
880
+ disabledDate: (time) => {
881
+ if (value !== null && value !== undefined && value !== "") {
882
+ let date = new Date(value.replace(/-/g, "/"));
883
+ return time.getTime() < date.getTime();
884
+ } else {
885
+ return false;
886
+ }
887
+ },
888
+ };
889
+ };
890
+
891
+ //除法
892
+ function baseDiv() {
893
+ let value = 0;
894
+ if (arguments.length) {
895
+ value = arguments[0];
896
+ for (let i = 1; i < arguments.length; i++) {
897
+ value = XEUtils.divide(value, arguments[i]);
898
+ }
899
+ }
900
+ return value;
901
+ }
902
+
903
+ //乘法
904
+ function baseMul() {
905
+ let value = 0;
906
+ if (arguments.length) {
907
+ value = arguments[0];
908
+ for (let i = 1; i < arguments.length; i++) {
909
+ value = XEUtils.multiply(value, arguments[i]);
910
+ }
911
+ }
912
+ return value;
913
+ }
914
+
915
+ //加法
916
+ function baseAdd() {
917
+ let value = 0;
918
+ if (arguments.length) {
919
+ value = arguments[0];
920
+ for (let i = 1; i < arguments.length; i++) {
921
+ value = XEUtils.add(value, arguments[i]);
922
+ }
923
+ }
924
+ return value;
925
+ }
926
+
927
+ //减法
928
+ function baseSub() {
929
+ let value = 0;
930
+ if (arguments.length) {
931
+ value = arguments[0];
932
+ for (let i = 1; i < arguments.length; i++) {
933
+ value = XEUtils.subtract(value, arguments[i]);
934
+ }
935
+ }
936
+ return value;
937
+ }
938
+
939
+ Vue.prototype.$baseAdd = baseAdd;
940
+ Vue.prototype.$baseSub = baseSub;
941
+ Vue.prototype.$baseMul = baseMul;
942
+ Vue.prototype.$baseDiv = baseDiv;
943
+
944
+ /**
945
+ * 格式化数字为带千分位的字符串。
946
+ *
947
+ * @param {string | number} value - 输入值
948
+ * @param {Object} [options={}] - 配置
949
+ * @param {boolean} [options.fixed=false] -
950
+ * - `true`: 启用定点精度处理 —— 使用 toFixed(digits) 四舍五入并补零到指定小数位。
951
+ * - `false`(默认): 保留原始小数形式(不四舍五入、不补零、保留尾随零)。
952
+ * @param {number} [options.digits=2] - 小数位数(仅在 fixed: true 时生效)
953
+ * @param {string} [options.thousandsSeparator=','] - 千分位分隔符(始终生效)
954
+ * @param {string} [options.decimalSeparator='.'] - 小数点符号
955
+ * @returns {string}
956
+ *
957
+ * @example
958
+ * // 默认:保留原始小数
959
+ * formatNumber(0.2); // "0.2"
960
+ * formatNumber("0.2000"); // "0.2000"
961
+ *
962
+ * // 启用定点精度处理
963
+ * formatNumber(0.2, { fixed: true }); // "0.20"
964
+ * formatNumber("123.456", { fixed: true, digits: 1 }); // "123.5"
965
+ * formatNumber(1000, { fixed: true, digits: 0 }); // "1,000"
966
+ */
967
+ function formatNumber(value, options = {}) {
968
+ if (value === null || value === undefined || value === "") {
969
+ return "";
970
+ }
971
+
972
+ const {
973
+ fixed = false,
974
+ digits = 2,
975
+ thousandsSeparator = ",",
976
+ decimalSeparator = ".",
977
+ } = options;
978
+
979
+ const isNumber = typeof value === "number";
980
+ let str = String(value).trim();
981
+
982
+ // Normalize ".123" "0.123"
983
+ if (str.charCodeAt(0) === 46) {
984
+ str = "0" + str;
985
+ } else if (str.startsWith("-.")) {
986
+ str = "-0." + str.slice(2);
987
+ }
988
+
989
+ let intPart, decPart, isNegative;
990
+
991
+ if (fixed) {
992
+ // 启用精度处理:toFixed + 补零
993
+ const num = isNumber ? value : parseFloat(str);
994
+ if (num !== num) return str;
995
+
996
+ const fixedStr = num.toFixed(digits);
997
+ const dotIndex = fixedStr.indexOf(".");
998
+ intPart = dotIndex === -1 ? fixedStr : fixedStr.slice(0, dotIndex);
999
+ decPart = dotIndex === -1 ? "" : fixedStr.slice(dotIndex + 1);
1000
+ isNegative = intPart.charCodeAt(0) === 45;
1001
+ if (isNegative) intPart = intPart.slice(1);
1002
+ } else {
1003
+ // 保留原始小数
1004
+ let s = str;
1005
+ isNegative = s.charCodeAt(0) === 45;
1006
+ if (isNegative) s = s.slice(1);
1007
+
1008
+ const dotIndex = s.indexOf(".");
1009
+ intPart = dotIndex === -1 ? s : s.slice(0, dotIndex);
1010
+ decPart = dotIndex === -1 ? "" : s.slice(dotIndex + 1);
1011
+
1012
+ if (intPart === "") intPart = "0";
1013
+ if (!/^\d+$/.test(intPart)) return str;
1014
+ }
1015
+
1016
+ // 千分位(始终应用)
1017
+ let fmtInt = intPart;
1018
+ if (intPart !== "0") {
1019
+ let out = "";
1020
+ for (let i = intPart.length - 1, c = 0; i >= 0; i--, c++) {
1021
+ if (c > 0 && c % 3 === 0) out = thousandsSeparator + out;
1022
+ out = intPart[i] + out;
1023
+ }
1024
+ fmtInt = out;
1025
+ }
1026
+
1027
+ // 拼接
1028
+ let result = isNegative ? "-" + fmtInt : fmtInt;
1029
+ if (decPart) {
1030
+ result += decimalSeparator + decPart;
1031
+ } else if (fixed && digits > 0) {
1032
+ result += decimalSeparator + "0".repeat(digits);
1033
+ }
1034
+
1035
+ return result;
1036
+ }
1037
+ Vue.prototype.$formatNumber = formatNumber;
1038
+
1039
+ /**
1040
+ * 生成一个符合 RFC4122 标准的随机 UUID (v4)
1041
+ * @returns {string} 格式为 "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx" 的 UUID 字符串
1042
+ */
1043
+ function generateUUID() {
1044
+ const buf = new Uint8Array(16);
1045
+ crypto.getRandomValues(buf);
1046
+ buf[6] = (buf[6] & 0x0f) | 0x40; // version 4
1047
+ buf[8] = (buf[8] & 0x3f) | 0x80; // variant RFC4122
1048
+ const hex = Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join(
1049
+ ""
1050
+ );
1051
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(
1052
+ 12,
1053
+ 16
1054
+ )}-${hex.slice(16, 20)}-${hex.slice(20)}`;
1055
+ }
1056
+ Vue.prototype.$generateUUID = generateUUID;
1057
+
1058
+ //数字精确位数
1059
+ Vue.prototype.$currency = function (value, priceScale, priceRoundType) {
1060
+ if (value !== null && value !== undefined) {
1061
+ if (priceScale === null || priceScale === undefined) {
1062
+ priceScale = 2;
1063
+ }
1064
+ if (priceRoundType === null || priceRoundType === undefined) {
1065
+ priceRoundType = "roundHalfUp";
1066
+ }
1067
+ let price;
1068
+ if (priceRoundType === "roundHalfUp") {
1069
+ price = (
1070
+ Math.round(value * Math.pow(10, priceScale)) /
1071
+ Math.pow(10, priceScale)
1072
+ ).toFixed(priceScale);
1073
+ } else if (priceRoundType === "roundUp") {
1074
+ price = (
1075
+ Math.ceil(value * Math.pow(10, priceScale)) / Math.pow(10, priceScale)
1076
+ ).toFixed(priceScale);
1077
+ } else {
1078
+ price = (
1079
+ Math.floor(value * Math.pow(10, priceScale)) /
1080
+ Math.pow(10, priceScale)
1081
+ ).toFixed(priceScale);
1082
+ }
1083
+ return price;
1084
+ }
1085
+ };
1086
+
1087
+ Vue.prototype.$getBaseDicts = async function (option) {
1088
+ let isLoading = option.isLoading || false;
1089
+ return this.$http({
1090
+ url: USER_PREFIX + "/common_attribute/listItems",
1091
+ method: `post`,
1092
+ data: {
1093
+ code: option.code,
1094
+ enabled: true,
1095
+ forCompany: true,
1096
+ ...option.data,
1097
+ },
1098
+ isLoading: isLoading,
1099
+ modalStrictly: true,
1100
+ success: (res) => {
1101
+ let dicts = res.objx || [];
1102
+ let dictMap = {};
1103
+ for (let item of dicts) {
1104
+ dictMap[item.sn] = item.value;
1105
+ }
1106
+ /* dicts.forEach((item) => {
1107
+ dictMap[item.sn] = item.value;
1108
+ }); */
1109
+ option.success &&
1110
+ option.success({
1111
+ dicts,
1112
+ dictMap,
1113
+ });
1114
+ },
1115
+ });
1116
+ };
1117
+
1118
+ imFun.Form.methods.$baseValidate = function (callback, opt) {
1119
+ let that = this;
1120
+ that.validate((valid, obj, c, d) => {
1121
+ if (!valid && (!opt || opt.errorTip !== false)) {
1122
+ this.$message({
1123
+ message: this.$t2("必填项不能为空", "system.message.required"),
1124
+ type: "error",
1125
+ duration: 2000,
1126
+ });
1127
+ }
1128
+ scrollToFirstError(that);
1129
+ callback(valid, obj);
1130
+ });
1131
+ };
1132
+
1133
+ function scrollToFirstError(formTarget) {
1134
+ // 获取第一个验证失败的字段
1135
+ // let formTarget = this.$refs['renderForm'];
1136
+ const firstErrorField = Object.keys(formTarget.fields).find((key) => {
1137
+ return formTarget.fields[key].validateState === "error";
1138
+ });
1139
+
1140
+ if (firstErrorField) {
1141
+ const field = formTarget.fields[firstErrorField];
1142
+
1143
+ let dom = field.$el;
1144
+ if (dom) {
1145
+ // 滚动到该字段位置
1146
+ dom.scrollIntoView({
1147
+ behavior: "smooth",
1148
+ block: "center",
1149
+ });
1150
+
1151
+ // 添加高亮效果
1152
+ dom.classList.add("highlight");
1153
+
1154
+ // 3秒后移除高亮效果
1155
+ setTimeout(() => {
1156
+ dom.classList.remove("highlight");
1157
+ }, 3000);
1158
+ }
1159
+ }
1160
+ }
1161
+
1162
+ Vue.prototype.$getBillInfo = async function (option) {
1163
+ let defaultOption = {
1164
+ url: null,
1165
+ method: `post`,
1166
+ data: {},
1167
+ isLoading: true,
1168
+ modalStrictly: true,
1169
+ success: null,
1170
+ };
1171
+ let opt = Object.assign({}, defaultOption, option);
1172
+ delete opt.wfConfig;
1173
+ return this.$http({
1174
+ ...opt,
1175
+ success: (res, response) => {
1176
+ option.success && option.success(res, response);
1177
+ },
1178
+ });
1179
+ };
1180
+
1181
+ Vue.prototype.$downloadByFileWhole = function (fileWhole, fileName) {
1182
+ let that = this;
1183
+ if (!fileWhole) {
1184
+ this.$baseAlert("凭证信息不存在");
1185
+ return;
1186
+ }
1187
+ let getDownloadDomian = function (callback) {
1188
+ that.$http({
1189
+ method: "post",
1190
+ url: USER_PREFIX + "/common/fileDownloadUrl",
1191
+ data: {},
1192
+ isLoading: true,
1193
+ success: (res) => {
1194
+ callback(res.objx);
1195
+ },
1196
+ });
1197
+ };
1198
+ getDownloadDomian((domain) => {
1199
+ if (fileName) {
1200
+ fileWhole.fileName = fileName;
1201
+ }
1202
+ that.$http({
1203
+ method: "post",
1204
+ url: domain + "/docfile/download",
1205
+ data: fileWhole,
1206
+ isLoading: true,
1207
+ success: (res) => {
1208
+ // window.open(res.objx.url);
1209
+ let url = res.objx.url;
1210
+ openInNewTab(url);
1211
+ },
1212
+ });
1213
+ });
1214
+ };
1215
+
1216
+ let isDef = function (value) {
1217
+ return value !== undefined && value !== null;
1218
+ };
1219
+
1220
+ Vue.prototype.$t2 = function (defaultValue, path, values) {
1221
+ let that = window.$vueRoot;
1222
+ if (!that.hasOwnProperty("_i18n")) {
1223
+ return defaultValue;
1224
+ }
1225
+ const i18n = that.$i18n;
1226
+ path = path || defaultValue;
1227
+ return i18n.te(path) ? i18n.t(path, values) : defaultValue;
1228
+ };
1229
+
1230
+ Vue.prototype.$t1 = function (path, values) {
1231
+ let that = window.$vueRoot;
1232
+ if (!that.hasOwnProperty("_i18n")) {
1233
+ return path;
1234
+ }
1235
+ let lang = that.$i18n.locale;
1236
+ const i18n = that.$i18n;
1237
+ if (lang === "zh") {
1238
+ let val = i18n._t(path, lang, { zh: { [path]: path } }, null, values);
1239
+ return val;
1240
+ } else {
1241
+ if (!i18n.te(path)) {
1242
+ return i18n._t(path, lang, { zh: { [path]: path } }, null, values);
1243
+ } else {
1244
+ return (
1245
+ i18n.t(path, values) ||
1246
+ i18n._t(path, lang, { zh: { [path]: path } }, null, values)
1247
+ );
1248
+ }
1249
+ }
1250
+ };
1251
+
1252
+ Vue.prototype.$i18nVal = function (zhValue, enValue) {
1253
+ let that = window.$vueRoot;
1254
+ if (!that.hasOwnProperty("_i18n")) {
1255
+ return zhValue;
1256
+ }
1257
+ let $i18n = that.$i18n;
1258
+ let value = zhValue;
1259
+ if ($i18n.locale === "zh") {
1260
+ value = zhValue;
1261
+ } else if ($i18n.locale === "en") {
1262
+ value = enValue;
1263
+ }
1264
+ return value;
1265
+ };
1266
+
1267
+ Vue.prototype.$utcToLocal = function (utcTime) {
1268
+ if (!utcTime) return utcTime;
1269
+ let offsetHours = this.$store.getters.utcTransformOffset; // 时区偏移量,单位:小时
1270
+ if (!offsetHours || offsetHours === 0) return utcTime;
1271
+ let localTime = moment(utcTime).add(offsetHours, "hours");
1272
+ return localTime.format("YYYY-MM-DD HH:mm:ss");
1273
+ };
1274
+
1275
+ Vue.prototype.$window = window;
1276
+ };
1277
+
1278
+ window && Object.assign(window, imFun.prefixConfig);
1279
+ if (typeof window !== "undefined" && window.Vue) {
1280
+ install(window.Vue);
1281
+ }
1282
+
1283
+ export default install;