@truenewx/tnxvue3 2.6.0
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.
- package/README.md +3 -0
- package/package.json +76 -0
- package/sample/App.vue +19 -0
- package/sample/main.js +11 -0
- package/sample/pages/index.vue +79 -0
- package/sample/pages/info.vue +28 -0
- package/sample/tnx.js +31 -0
- package/src/aj-captcha/Verify/VerifyPoints.vue +258 -0
- package/src/aj-captcha/Verify/VerifySlide.vue +379 -0
- package/src/aj-captcha/Verify.vue +375 -0
- package/src/aj-captcha/api/index.js +19 -0
- package/src/aj-captcha/utils/ase.js +11 -0
- package/src/aj-captcha/utils/util.js +35 -0
- package/src/ant-design/tnxad-theme.css +5 -0
- package/src/ant-design/tnxad.css +8 -0
- package/src/ant-design/tnxad.js +23 -0
- package/src/element-plus/alert/Alert.vue +112 -0
- package/src/element-plus/avatar/Avatar.vue +124 -0
- package/src/element-plus/button/Button.vue +184 -0
- package/src/element-plus/check-icon/CheckIcon.vue +61 -0
- package/src/element-plus/close-error-button/CloseErrorButton.vue +45 -0
- package/src/element-plus/curd/Curd.vue +224 -0
- package/src/element-plus/date-picker/DatePicker.vue +206 -0
- package/src/element-plus/date-range/DateRange.vue +78 -0
- package/src/element-plus/datetime-picker/DateTimePicker.vue +129 -0
- package/src/element-plus/detail-form/DetailForm.vue +88 -0
- package/src/element-plus/dialog/Dialog.vue +259 -0
- package/src/element-plus/dialog/DialogContent.vue +13 -0
- package/src/element-plus/drawer/Drawer.vue +175 -0
- package/src/element-plus/dropdown-item/DropdownItem.vue +30 -0
- package/src/element-plus/enum-select/EnumSelect.vue +125 -0
- package/src/element-plus/fetch-cascader/FetchCascader.vue +138 -0
- package/src/element-plus/fetch-select/FetchSelect.vue +166 -0
- package/src/element-plus/fetch-tags/FetchTags.vue +122 -0
- package/src/element-plus/fss-upload/FssUpload.vue +306 -0
- package/src/element-plus/fss-view/FssView.vue +163 -0
- package/src/element-plus/icon/Icon.vue +221 -0
- package/src/element-plus/input-number/InputNumber.vue +150 -0
- package/src/element-plus/paged/Paged.vue +76 -0
- package/src/element-plus/permission-tree/PermissionTree.vue +184 -0
- package/src/element-plus/query-form/QueryForm.vue +138 -0
- package/src/element-plus/query-table/QueryTable.vue +402 -0
- package/src/element-plus/region-cascader/RegionCascader.vue +108 -0
- package/src/element-plus/select/Select.vue +446 -0
- package/src/element-plus/slider/Slider.vue +88 -0
- package/src/element-plus/steps-nav/StepsNav.vue +57 -0
- package/src/element-plus/submit-form/SubmitForm.vue +236 -0
- package/src/element-plus/table-column/TableColumn.vue +32 -0
- package/src/element-plus/tabs/Tabs.vue +93 -0
- package/src/element-plus/tnxel.css +890 -0
- package/src/element-plus/tnxel.js +528 -0
- package/src/element-plus/transfer/Transfer.vue +117 -0
- package/src/element-plus/upload/Upload.vue +856 -0
- package/src/percent/Percent.vue +12 -0
- package/src/text/Text.vue +33 -0
- package/src/tnxvue-cli.js +64 -0
- package/src/tnxvue-router.js +161 -0
- package/src/tnxvue-validator.js +365 -0
- package/src/tnxvue.css +12 -0
- package/src/tnxvue.js +343 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
// tnxel.js
|
|
2
|
+
/**
|
|
3
|
+
* 基于ElementPlus的扩展支持
|
|
4
|
+
*/
|
|
5
|
+
import ElementPlus, {ElLoading, ElMessage, ElMessageBox} from 'element-plus';
|
|
6
|
+
import ElementPlus_zh_CN from 'element-plus/es/locale/lang/zh-cn';
|
|
7
|
+
import tnxbs from '@truenewx/tnxcore/src/tnxbs'; // 二次封装组件中使用了Bootstrap的基础样式
|
|
8
|
+
import tnxvue from '../tnxvue.js';
|
|
9
|
+
|
|
10
|
+
import Avatar from './avatar/Avatar.vue';
|
|
11
|
+
import Alert from './alert/Alert.vue';
|
|
12
|
+
import Button from './button/Button.vue';
|
|
13
|
+
import CheckIcon from './check-icon/CheckIcon.vue';
|
|
14
|
+
import CloseErrorButton from './close-error-button/CloseErrorButton.vue';
|
|
15
|
+
import Curd from './curd/Curd.vue';
|
|
16
|
+
import DatePicker from './date-picker/DatePicker.vue';
|
|
17
|
+
import DateRange from './date-range/DateRange.vue';
|
|
18
|
+
import DateTimePicker from './datetime-picker/DateTimePicker.vue';
|
|
19
|
+
import DetailForm from './detail-form/DetailForm.vue';
|
|
20
|
+
import Dialog from './dialog/Dialog.vue';
|
|
21
|
+
import Drawer from './drawer/Drawer.vue';
|
|
22
|
+
import DropdownItem from './dropdown-item/DropdownItem.vue';
|
|
23
|
+
import EnumSelect from './enum-select/EnumSelect.vue';
|
|
24
|
+
import FetchCascader from './fetch-cascader/FetchCascader.vue';
|
|
25
|
+
import FetchSelect from './fetch-select/FetchSelect.vue';
|
|
26
|
+
import FetchTags from './fetch-tags/FetchTags.vue';
|
|
27
|
+
import FssUpload from './fss-upload/FssUpload.vue';
|
|
28
|
+
import FssView from './fss-view/FssView.vue';
|
|
29
|
+
import Icon from './icon/Icon.vue';
|
|
30
|
+
import InputNumber from './input-number/InputNumber.vue';
|
|
31
|
+
import Paged from './paged/Paged.vue';
|
|
32
|
+
import PermissionTree from './permission-tree/PermissionTree.vue';
|
|
33
|
+
import QueryForm from './query-form/QueryForm.vue';
|
|
34
|
+
import QueryTable from './query-table/QueryTable.vue';
|
|
35
|
+
import RegionCascader from './region-cascader/RegionCascader.vue';
|
|
36
|
+
import Select from './select/Select.vue';
|
|
37
|
+
import Slider from './slider/Slider.vue';
|
|
38
|
+
import StepsNav from './steps-nav/StepsNav.vue';
|
|
39
|
+
import SubmitForm from './submit-form/SubmitForm.vue';
|
|
40
|
+
import TabColumn from './table-column/TableColumn.vue';
|
|
41
|
+
import Tabs from './tabs/Tabs.vue';
|
|
42
|
+
import Transfer from './transfer/Transfer.vue';
|
|
43
|
+
import Upload from './upload/Upload.vue';
|
|
44
|
+
|
|
45
|
+
import './tnxel.css';
|
|
46
|
+
|
|
47
|
+
const $ = tnxbs.libs.$;
|
|
48
|
+
|
|
49
|
+
const components = Object.assign({}, tnxvue.components, {
|
|
50
|
+
Avatar,
|
|
51
|
+
Alert,
|
|
52
|
+
Button,
|
|
53
|
+
CheckIcon,
|
|
54
|
+
CloseErrorButton,
|
|
55
|
+
Curd,
|
|
56
|
+
DatePicker,
|
|
57
|
+
DateRange,
|
|
58
|
+
DateTimePicker,
|
|
59
|
+
DetailForm,
|
|
60
|
+
Dialog,
|
|
61
|
+
Drawer,
|
|
62
|
+
DropdownItem,
|
|
63
|
+
EnumSelect,
|
|
64
|
+
FetchCascader,
|
|
65
|
+
FetchSelect,
|
|
66
|
+
FetchTags,
|
|
67
|
+
FssUpload,
|
|
68
|
+
FssView,
|
|
69
|
+
Icon,
|
|
70
|
+
InputNumber,
|
|
71
|
+
Paged,
|
|
72
|
+
PermissionTree,
|
|
73
|
+
QueryForm,
|
|
74
|
+
QueryTable,
|
|
75
|
+
RegionCascader,
|
|
76
|
+
Select,
|
|
77
|
+
Slider,
|
|
78
|
+
StepsNav,
|
|
79
|
+
SubmitForm,
|
|
80
|
+
TabColumn,
|
|
81
|
+
Tabs,
|
|
82
|
+
Transfer,
|
|
83
|
+
Upload,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const dialogContainerClass = 'tnxel-dialog-container';
|
|
87
|
+
const drawerContainerClass = 'tnxel-drawer-container';
|
|
88
|
+
|
|
89
|
+
const tnxel = Object.assign({}, tnxbs, tnxvue, {
|
|
90
|
+
libs: Object.assign({}, tnxbs.libs, tnxvue.libs, {ElementPlus}),
|
|
91
|
+
components,
|
|
92
|
+
_dialogs: [], // 对话框堆栈
|
|
93
|
+
dialog(content, title, buttons, options, contentProps) {
|
|
94
|
+
this._closeMessage();
|
|
95
|
+
|
|
96
|
+
let componentOptions = {};
|
|
97
|
+
if (this.util.isComponent(content)) {
|
|
98
|
+
componentOptions.components = {
|
|
99
|
+
'tnxel-dialog-content': content
|
|
100
|
+
};
|
|
101
|
+
content = null;
|
|
102
|
+
}
|
|
103
|
+
let componentDefinition = Object.assign({}, Dialog, componentOptions);
|
|
104
|
+
|
|
105
|
+
const dialogId = 'dialog-' + (new Date().getTime());
|
|
106
|
+
$('body').append('<div class="' + dialogContainerClass + '" id="' + dialogId + '"></div>');
|
|
107
|
+
if (!(buttons instanceof Array)) {
|
|
108
|
+
buttons = [];
|
|
109
|
+
}
|
|
110
|
+
const containerSelector = '.' + dialogContainerClass + '#' + dialogId;
|
|
111
|
+
options = options || {};
|
|
112
|
+
const dialogVm = window.tnx.createVueInstance(componentDefinition, null, {
|
|
113
|
+
modelValue: true,
|
|
114
|
+
container: containerSelector,
|
|
115
|
+
title: title,
|
|
116
|
+
content: content,
|
|
117
|
+
contentProps: contentProps,
|
|
118
|
+
buttons: buttons,
|
|
119
|
+
theme: options.theme,
|
|
120
|
+
}).mount(containerSelector);
|
|
121
|
+
dialogVm.options = Object.assign(dialogVm.options || {}, options);
|
|
122
|
+
dialogVm.options.onClosed = this.util.function.around(dialogVm.options.onClosed, function (onClosed) {
|
|
123
|
+
let $container = $(containerSelector);
|
|
124
|
+
$container.next('.el-overlay').remove();
|
|
125
|
+
$container.remove();
|
|
126
|
+
if (onClosed) {
|
|
127
|
+
onClosed.call(dialogVm);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
this._dialogs.push(dialogVm);
|
|
131
|
+
return dialogVm;
|
|
132
|
+
},
|
|
133
|
+
closeDialog(all, callback) {
|
|
134
|
+
if (typeof all === 'function') {
|
|
135
|
+
callback = all;
|
|
136
|
+
all = false;
|
|
137
|
+
}
|
|
138
|
+
if (this._dialogs.length) {
|
|
139
|
+
let dialog = this._dialogs.pop();
|
|
140
|
+
while (dialog) {
|
|
141
|
+
dialog.close(callback);
|
|
142
|
+
if (all) {
|
|
143
|
+
dialog = this._dialogs.pop();
|
|
144
|
+
} else {
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
_drawers: [], // 抽屉堆栈
|
|
151
|
+
drawer(content, title, buttons, options, contentProps) {
|
|
152
|
+
this._closeMessage();
|
|
153
|
+
|
|
154
|
+
let componentOptions = {};
|
|
155
|
+
if (this.util.isComponent(content)) {
|
|
156
|
+
componentOptions.components = {
|
|
157
|
+
'tnxel-drawer-content': content
|
|
158
|
+
};
|
|
159
|
+
content = null;
|
|
160
|
+
}
|
|
161
|
+
let componentDefinition = Object.assign({}, Drawer, componentOptions);
|
|
162
|
+
|
|
163
|
+
const drawerId = 'drawer-' + (new Date().getTime());
|
|
164
|
+
$('body').append('<div class="' + drawerContainerClass + '" id="' + drawerId + '"></div>');
|
|
165
|
+
if (!(buttons instanceof Array)) {
|
|
166
|
+
buttons = [];
|
|
167
|
+
}
|
|
168
|
+
const containerSelector = '.' + drawerContainerClass + '#' + drawerId;
|
|
169
|
+
options = options || {};
|
|
170
|
+
const drawerVm = window.tnx.createVueInstance(componentDefinition, null, {
|
|
171
|
+
content: content,
|
|
172
|
+
title: title,
|
|
173
|
+
contentProps: contentProps,
|
|
174
|
+
buttons: buttons,
|
|
175
|
+
theme: options.theme,
|
|
176
|
+
}).mount(containerSelector);
|
|
177
|
+
drawerVm.id = drawerId;
|
|
178
|
+
drawerVm.options = Object.assign(drawerVm.options || {}, options);
|
|
179
|
+
drawerVm.options.onClosed = this.util.function.around(drawerVm.options.onClosed, function (onClosed) {
|
|
180
|
+
let $container = $(containerSelector);
|
|
181
|
+
$container.next('.el-overlay').remove();
|
|
182
|
+
$container.remove();
|
|
183
|
+
if (onClosed) {
|
|
184
|
+
onClosed.call(drawerVm);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
this._drawers.push(drawerVm);
|
|
188
|
+
return drawerVm;
|
|
189
|
+
},
|
|
190
|
+
closeDrawer(all, callback) {
|
|
191
|
+
if (typeof all === 'function') {
|
|
192
|
+
callback = all;
|
|
193
|
+
all = false;
|
|
194
|
+
}
|
|
195
|
+
if (this._drawers.length) {
|
|
196
|
+
let drawer = this._drawers.pop();
|
|
197
|
+
while (drawer) {
|
|
198
|
+
drawer.close(callback);
|
|
199
|
+
if (all) {
|
|
200
|
+
drawer = this._drawers.pop();
|
|
201
|
+
} else {
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
_closeMessage() {
|
|
208
|
+
ElMessage.closeAll();
|
|
209
|
+
this.closeLoading();
|
|
210
|
+
},
|
|
211
|
+
_handleZIndex(selector) {
|
|
212
|
+
const util = this.util;
|
|
213
|
+
setTimeout(function () {
|
|
214
|
+
const topZIndex = util.dom.minTopZIndex(2);
|
|
215
|
+
const element = $(selector);
|
|
216
|
+
const zIndex = Number(element.css('zIndex'));
|
|
217
|
+
if (isNaN(zIndex) || topZIndex > zIndex) {
|
|
218
|
+
element.css('zIndex', topZIndex);
|
|
219
|
+
const modal = element.next();
|
|
220
|
+
if (modal.is('.v-modal')) {
|
|
221
|
+
modal.css('zIndex', topZIndex - 1);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
alert(message, title, callback, options) {
|
|
227
|
+
if (typeof title === 'function') {
|
|
228
|
+
options = callback;
|
|
229
|
+
callback = title;
|
|
230
|
+
title = '提示';
|
|
231
|
+
}
|
|
232
|
+
options = Object.assign({
|
|
233
|
+
dangerouslyUseHTMLString: true,
|
|
234
|
+
type: 'warning',
|
|
235
|
+
confirmButtonText: '确定',
|
|
236
|
+
}, options);
|
|
237
|
+
ElMessageBox.alert(message, title, options).then(callback);
|
|
238
|
+
this._handleZIndex('.el-message-box__wrapper:last');
|
|
239
|
+
},
|
|
240
|
+
success(message, callback, options) {
|
|
241
|
+
options = Object.assign({
|
|
242
|
+
dangerouslyUseHTMLString: true,
|
|
243
|
+
}, options, {
|
|
244
|
+
type: 'success',
|
|
245
|
+
confirmButtonText: '确定',
|
|
246
|
+
});
|
|
247
|
+
ElMessageBox.alert(message, '成功', options).then(callback);
|
|
248
|
+
this._handleZIndex('.el-message-box__wrapper:last');
|
|
249
|
+
},
|
|
250
|
+
error(message, callback, options) {
|
|
251
|
+
options = Object.assign({
|
|
252
|
+
dangerouslyUseHTMLString: true,
|
|
253
|
+
}, options, {
|
|
254
|
+
type: 'error',
|
|
255
|
+
confirmButtonText: '确定',
|
|
256
|
+
});
|
|
257
|
+
ElMessageBox.alert(message, '错误', options).then(callback);
|
|
258
|
+
this._handleZIndex('.el-message-box__wrapper:last');
|
|
259
|
+
},
|
|
260
|
+
confirm(message, title, callback, options) {
|
|
261
|
+
if (typeof title === 'function') {
|
|
262
|
+
options = callback;
|
|
263
|
+
callback = title;
|
|
264
|
+
title = '确认';
|
|
265
|
+
}
|
|
266
|
+
options = Object.assign({
|
|
267
|
+
type: 'question',
|
|
268
|
+
confirmButtonText: '确定',
|
|
269
|
+
cancelButtonText: '取消',
|
|
270
|
+
}, options, {
|
|
271
|
+
dangerouslyUseHTMLString: true,
|
|
272
|
+
distinguishCancelAndClose: true,
|
|
273
|
+
});
|
|
274
|
+
if (options.type === 'question') {
|
|
275
|
+
options.type = 'info';
|
|
276
|
+
options.icon = Icon.components.QuestionFilled;
|
|
277
|
+
}
|
|
278
|
+
if (options.reverse) {
|
|
279
|
+
options.customClass = 'reverse';
|
|
280
|
+
let buttonText = options.confirmButtonText;
|
|
281
|
+
options.confirmButtonText = options.cancelButtonText;
|
|
282
|
+
options.cancelButtonText = buttonText;
|
|
283
|
+
}
|
|
284
|
+
if (typeof callback === 'function') {
|
|
285
|
+
options.callback = function (action) {
|
|
286
|
+
let yes = undefined;
|
|
287
|
+
if (action === 'confirm') {
|
|
288
|
+
yes = options.reverse ? false : true;
|
|
289
|
+
} else if (action === 'cancel') {
|
|
290
|
+
yes = options.reverse ? true : false;
|
|
291
|
+
}
|
|
292
|
+
callback(yes);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
ElMessageBox.confirm(message, title, options);
|
|
296
|
+
this._handleZIndex('.el-message-box__wrapper:last');
|
|
297
|
+
},
|
|
298
|
+
toast(message, timeout, callback, options) {
|
|
299
|
+
if (typeof timeout === 'function') {
|
|
300
|
+
options = callback;
|
|
301
|
+
callback = timeout;
|
|
302
|
+
timeout = undefined;
|
|
303
|
+
}
|
|
304
|
+
options = Object.assign({
|
|
305
|
+
type: 'success', // 默认为成功主题,可更改为其它主题
|
|
306
|
+
offset: this.util.dom.getDocHeight() * 0.4,
|
|
307
|
+
dangerouslyUseHTMLString: true,
|
|
308
|
+
}, options, {
|
|
309
|
+
center: true, // 因为是竖向排列,所以必须居中
|
|
310
|
+
showClose: false,
|
|
311
|
+
message: message,
|
|
312
|
+
duration: timeout || 1500,
|
|
313
|
+
customClass: 'tnxel-toast',
|
|
314
|
+
onClose: callback,
|
|
315
|
+
});
|
|
316
|
+
this._closeMessage();
|
|
317
|
+
ElMessage(options);
|
|
318
|
+
this._handleZIndex('.el-message:last');
|
|
319
|
+
},
|
|
320
|
+
showLoading(message, options) {
|
|
321
|
+
if (typeof message !== 'string') {
|
|
322
|
+
options = message;
|
|
323
|
+
message = undefined;
|
|
324
|
+
}
|
|
325
|
+
options = Object.assign({
|
|
326
|
+
dangerouslyUseHTMLString: true,
|
|
327
|
+
}, options, {
|
|
328
|
+
text: message,
|
|
329
|
+
});
|
|
330
|
+
this._closeMessage();
|
|
331
|
+
window.tnx.loadingInstance = ElLoading.service(options);
|
|
332
|
+
this._handleZIndex('.el-loading-mask');
|
|
333
|
+
return window.tnx.loadingInstance;
|
|
334
|
+
},
|
|
335
|
+
closeLoading() {
|
|
336
|
+
if (window.tnx.loadingInstance) { // 确保绝对的单例
|
|
337
|
+
window.tnx.loadingInstance.close();
|
|
338
|
+
window.tnx.loadingInstance = undefined;
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
hideLoading() {
|
|
342
|
+
this.closeLoading();
|
|
343
|
+
},
|
|
344
|
+
validateUploaded(vm, reject) {
|
|
345
|
+
let result = true;
|
|
346
|
+
let formRef = null;
|
|
347
|
+
let refKeys = Object.keys(vm.$refs);
|
|
348
|
+
for (let refKey of refKeys) {
|
|
349
|
+
let refObj = vm.$refs[refKey];
|
|
350
|
+
if (Array.isArray(refObj)) {
|
|
351
|
+
for (let ref of refObj) {
|
|
352
|
+
if (typeof ref.validateUploaded === 'function') {
|
|
353
|
+
if (ref.validateUploaded(reject) === false) {
|
|
354
|
+
result = false;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
} else if (refObj.$el.tagName === 'FORM' && typeof refObj.disable === 'function') {
|
|
360
|
+
formRef = refObj;
|
|
361
|
+
} else {
|
|
362
|
+
if (typeof refObj.validateUploaded === 'function') {
|
|
363
|
+
if (refObj.validateUploaded(reject) === false) {
|
|
364
|
+
result = false;
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (!result && formRef) {
|
|
371
|
+
formRef.disable(false);
|
|
372
|
+
}
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
tnxel.install = tnxel.util.function.around(tnxel.install, function (install, vm) {
|
|
378
|
+
vm.use(ElementPlus, {
|
|
379
|
+
locale: ElementPlus_zh_CN,
|
|
380
|
+
});
|
|
381
|
+
install.call(window.tnx, vm);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
tnxel.router.beforeLeave = tnxel.util.function.around(tnxel.router.beforeLeave, function (beforeLeave, router, from) {
|
|
385
|
+
// 页面跳转前关闭当前页面中可能存在的所有消息框和对话框
|
|
386
|
+
window.tnx._closeMessage();
|
|
387
|
+
window.tnx.closeDialog(true);
|
|
388
|
+
beforeLeave.call(window.tnx.router, router, from);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
tnxel.date = {
|
|
392
|
+
formatDateTime: function (row, column, cellValue) {
|
|
393
|
+
if (cellValue) {
|
|
394
|
+
return new Date(cellValue).formatDateTime();
|
|
395
|
+
}
|
|
396
|
+
return undefined;
|
|
397
|
+
},
|
|
398
|
+
formatDate: function (row, column, cellValue) {
|
|
399
|
+
if (cellValue) {
|
|
400
|
+
return new Date(cellValue).formatDate();
|
|
401
|
+
}
|
|
402
|
+
return undefined;
|
|
403
|
+
},
|
|
404
|
+
formatTime: function (row, column, cellValue) {
|
|
405
|
+
if (typeof cellValue === 'number') {
|
|
406
|
+
cellValue = new Date(cellValue);
|
|
407
|
+
}
|
|
408
|
+
if (cellValue instanceof Date) {
|
|
409
|
+
cellValue = cellValue.formatTime();
|
|
410
|
+
}
|
|
411
|
+
if (typeof cellValue === 'string') {
|
|
412
|
+
return cellValue;
|
|
413
|
+
}
|
|
414
|
+
return undefined;
|
|
415
|
+
},
|
|
416
|
+
formatTimeMinute: function (row, column, cellValue) {
|
|
417
|
+
if (typeof cellValue === 'number') {
|
|
418
|
+
cellValue = new Date(cellValue);
|
|
419
|
+
}
|
|
420
|
+
if (cellValue instanceof Date) {
|
|
421
|
+
cellValue = cellValue.formatTimeMinute();
|
|
422
|
+
}
|
|
423
|
+
if (typeof cellValue === 'string') {
|
|
424
|
+
let array = cellValue.split(':');
|
|
425
|
+
if (array.length > 1) {
|
|
426
|
+
return array[0] + ':' + array[1];
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return undefined;
|
|
430
|
+
},
|
|
431
|
+
formatDateMinute: function (row, column, cellValue) {
|
|
432
|
+
if (cellValue) {
|
|
433
|
+
return new Date(cellValue).formatDateMinute();
|
|
434
|
+
}
|
|
435
|
+
return undefined;
|
|
436
|
+
},
|
|
437
|
+
formatDateMonth: function (row, column, cellValue) {
|
|
438
|
+
if (cellValue) {
|
|
439
|
+
return new Date(cellValue).formatDateMonth();
|
|
440
|
+
}
|
|
441
|
+
return undefined;
|
|
442
|
+
},
|
|
443
|
+
formatPermanentableDate: function (row, column, cellValue) {
|
|
444
|
+
if (Array.isArray(cellValue)) {
|
|
445
|
+
cellValue = cellValue[column];
|
|
446
|
+
}
|
|
447
|
+
return tnxvue.util.date.formatPermanentableDate(cellValue);
|
|
448
|
+
},
|
|
449
|
+
/**
|
|
450
|
+
* 将Java标准的日期格式转换为Day.js的日期格式
|
|
451
|
+
* @param format Java标准的日期格式
|
|
452
|
+
* @returns {String} Day.js的日期格式
|
|
453
|
+
*/
|
|
454
|
+
toDayJsDateFormat(format) {
|
|
455
|
+
return format.replaceAll('y', 'Y').replaceAll('d', 'D');
|
|
456
|
+
},
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
tnxel.number = {
|
|
460
|
+
formatPercent: function (row, column, cellValue) {
|
|
461
|
+
if (typeof cellValue !== 'number') {
|
|
462
|
+
cellValue = parseFloat(cellValue);
|
|
463
|
+
}
|
|
464
|
+
if (!isNaN(cellValue)) {
|
|
465
|
+
return cellValue.toPercent();
|
|
466
|
+
}
|
|
467
|
+
return undefined;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
tnxel.boolean = {
|
|
472
|
+
items: {
|
|
473
|
+
getText(type, value) {
|
|
474
|
+
let items = this[type];
|
|
475
|
+
if (Array.isArray(items)) {
|
|
476
|
+
for (let item of items) {
|
|
477
|
+
if (item.value === value) {
|
|
478
|
+
return item.text;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return undefined;
|
|
483
|
+
},
|
|
484
|
+
has: [{
|
|
485
|
+
value: true,
|
|
486
|
+
text: '有',
|
|
487
|
+
}, {
|
|
488
|
+
value: false,
|
|
489
|
+
text: '无',
|
|
490
|
+
}]
|
|
491
|
+
},
|
|
492
|
+
format: function (row, column, cellValue) {
|
|
493
|
+
if (typeof cellValue === 'boolean') {
|
|
494
|
+
cellValue = cellValue.toText();
|
|
495
|
+
}
|
|
496
|
+
return cellValue;
|
|
497
|
+
},
|
|
498
|
+
formatHas: function (row, column, cellValue) {
|
|
499
|
+
if (typeof cellValue === 'boolean') {
|
|
500
|
+
cellValue = tnxel.boolean.items.getText('has', cellValue);
|
|
501
|
+
}
|
|
502
|
+
return cellValue;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
tnxel.table = {}
|
|
507
|
+
|
|
508
|
+
const rpc = tnxel.app.rpc;
|
|
509
|
+
rpc.handleErrors = tnxel.util.function.around(rpc.handleErrors, function (handleErrors, errors, options) {
|
|
510
|
+
if (options && options.form) {
|
|
511
|
+
let forms;
|
|
512
|
+
if (Array.isArray(options.form)) {
|
|
513
|
+
forms = options.form;
|
|
514
|
+
} else {
|
|
515
|
+
forms = [options.form];
|
|
516
|
+
}
|
|
517
|
+
forms.forEach(form => {
|
|
518
|
+
if (typeof form.disable === 'function') {
|
|
519
|
+
form.disable(false);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
return handleErrors.call(rpc, errors, options);
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
window.tnx = tnxel;
|
|
527
|
+
|
|
528
|
+
export default tnxel;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-transfer class="tnxel-transfer" v-model="selected" :data="selectable" :titles="titles"
|
|
3
|
+
:filterable="filterable" :filter-method="filter" :filter-placeholder="placeholder"/>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script>
|
|
7
|
+
export default {
|
|
8
|
+
name: 'TnxelTransfer',
|
|
9
|
+
props: {
|
|
10
|
+
modelValue: {
|
|
11
|
+
type: Array,
|
|
12
|
+
default() {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
url: {
|
|
17
|
+
type: String,
|
|
18
|
+
required: true,
|
|
19
|
+
},
|
|
20
|
+
params: [Object, Array],
|
|
21
|
+
title: {
|
|
22
|
+
type: [String, Array]
|
|
23
|
+
},
|
|
24
|
+
filterable: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
default: true,
|
|
27
|
+
},
|
|
28
|
+
placeholder: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: () => '输入关键字进行筛选',
|
|
31
|
+
},
|
|
32
|
+
keyName: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: () => 'id',
|
|
35
|
+
},
|
|
36
|
+
labelName: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: () => 'caption',
|
|
39
|
+
},
|
|
40
|
+
indexName: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: () => 'index',
|
|
43
|
+
},
|
|
44
|
+
formatter: Function,
|
|
45
|
+
},
|
|
46
|
+
emits: ['update:modelValue'],
|
|
47
|
+
data() {
|
|
48
|
+
return {
|
|
49
|
+
selectable: [],
|
|
50
|
+
selected: this.modelValue,
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
computed: {
|
|
54
|
+
titles() {
|
|
55
|
+
if (typeof this.title === 'string') {
|
|
56
|
+
return ['可选' + this.title, '已选' + this.title];
|
|
57
|
+
}
|
|
58
|
+
return this.title;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
created() {
|
|
62
|
+
let vm = this;
|
|
63
|
+
let params;
|
|
64
|
+
if (typeof this.params === 'function') {
|
|
65
|
+
params = this.params();
|
|
66
|
+
} else {
|
|
67
|
+
params = this.params;
|
|
68
|
+
}
|
|
69
|
+
window.tnx.app.rpc.get(this.url, params, function(list) {
|
|
70
|
+
vm.selectable = [];
|
|
71
|
+
list.forEach(item => {
|
|
72
|
+
if (vm.formatter) {
|
|
73
|
+
vm.formatter(item);
|
|
74
|
+
}
|
|
75
|
+
vm.selectable.push({
|
|
76
|
+
key: item[vm.keyName],
|
|
77
|
+
label: item[vm.labelName],
|
|
78
|
+
index: item[vm.indexName],
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
watch: {
|
|
84
|
+
modelValue(value) {
|
|
85
|
+
this.selected = value;
|
|
86
|
+
},
|
|
87
|
+
selected(value) {
|
|
88
|
+
this.$emit('update:modelValue', value);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
methods: {
|
|
92
|
+
filter(keyword, item) {
|
|
93
|
+
return (item.label && item.label.contains(keyword)) || (item.index && item.index.contains(keyword));
|
|
94
|
+
},
|
|
95
|
+
getSelectableItems() {
|
|
96
|
+
return this.selectable;
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
</script>
|
|
101
|
+
|
|
102
|
+
<style>
|
|
103
|
+
.tnxel-transfer {
|
|
104
|
+
display: flex;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.tnxel-transfer .el-transfer__buttons {
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
justify-content: center;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.tnxel-transfer .el-transfer__buttons .el-button + .el-button {
|
|
114
|
+
margin-left: 0;
|
|
115
|
+
margin-top: 10px;
|
|
116
|
+
}
|
|
117
|
+
</style>
|