@truenewx/tnxvue3 3.0.10 → 3.0.12
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/index.html +12 -0
- package/package.json +9 -19
- package/src/bootstrap-vue/button/Button.vue +1 -1
- package/src/bootstrap-vue/cascader/Cascader.vue +1 -1
- package/src/bootstrap-vue/dialog/Dialog.vue +1 -1
- package/src/bootstrap-vue/progress/Progress.vue +58 -0
- package/src/bootstrap-vue/tnxbsv.css +4 -0
- package/src/bootstrap-vue/tnxbsv.js +6 -1
- package/src/bootstrap-vue/upload/Upload.vue +173 -0
- package/src/element-plus/fss-view/FssView.vue +1 -1
- package/src/tnxvue.js +1 -1
- package/src/tnxvue-cli.js +0 -64
package/index.html
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>tnxvue3</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="./sample/main.js"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truenewx/tnxvue3",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.12",
|
|
4
4
|
"description": "互联网技术解决方案:Vue3扩展支持",
|
|
5
5
|
"private": false,
|
|
6
|
-
"
|
|
7
|
-
"access": "public"
|
|
8
|
-
},
|
|
6
|
+
"type": "module",
|
|
9
7
|
"main": "src/tnxvue.js",
|
|
10
8
|
"keywords": [
|
|
11
9
|
"truenewx",
|
|
@@ -15,8 +13,9 @@
|
|
|
15
13
|
"author": "truenewx",
|
|
16
14
|
"license": "Apache-2.0",
|
|
17
15
|
"scripts": {
|
|
18
|
-
"
|
|
19
|
-
"build": "
|
|
16
|
+
"dev": "vite",
|
|
17
|
+
"build": "vite build",
|
|
18
|
+
"preview": "vite preview"
|
|
20
19
|
},
|
|
21
20
|
"peerDependencies": {
|
|
22
21
|
"element-plus": "~2.8.0",
|
|
@@ -25,22 +24,16 @@
|
|
|
25
24
|
"vue-router": "~4.4.0"
|
|
26
25
|
},
|
|
27
26
|
"dependencies": {
|
|
28
|
-
"@truenewx/tnxcore": "3.0.
|
|
27
|
+
"@truenewx/tnxcore": "3.0.10",
|
|
29
28
|
"@element-plus/icons-vue": "2.3.1",
|
|
30
29
|
"async-validator": "4.2.5",
|
|
31
30
|
"mitt": "3.0.1"
|
|
32
31
|
},
|
|
33
32
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"
|
|
36
|
-
"@babel/preset-env": "7.22.5",
|
|
37
|
-
"@vue/cli-plugin-babel": "5.0.8",
|
|
38
|
-
"@vue/cli-plugin-eslint": "5.0.8",
|
|
39
|
-
"@vue/cli-service": "5.0.8",
|
|
33
|
+
"@vitejs/plugin-vue": "5.2.1",
|
|
34
|
+
"vite": "6.2.0",
|
|
40
35
|
"eslint": "7.32.0",
|
|
41
|
-
"eslint-plugin-vue": "8.7.1"
|
|
42
|
-
"copy-webpack-plugin": "11.0.0",
|
|
43
|
-
"terser-webpack-plugin": "5.3.7"
|
|
36
|
+
"eslint-plugin-vue": "8.7.1"
|
|
44
37
|
},
|
|
45
38
|
"eslintConfig": {
|
|
46
39
|
"root": true,
|
|
@@ -51,9 +44,6 @@
|
|
|
51
44
|
"plugin:vue/vue3-essential",
|
|
52
45
|
"eslint:recommended"
|
|
53
46
|
],
|
|
54
|
-
"parserOptions": {
|
|
55
|
-
"parser": "@babel/eslint-parser"
|
|
56
|
-
},
|
|
57
47
|
"rules": {
|
|
58
48
|
"eqeqeq": "warn",
|
|
59
49
|
"no-unused-vars": [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<BButton class="tnxbsv-button" :variant="type || '
|
|
2
|
+
<BButton class="tnxbsv-button" :variant="type || 'light'" :loading="loading" :disabled="loading">
|
|
3
3
|
<i class="me-1" :class="icon" v-if="icon"></i>
|
|
4
4
|
<div>
|
|
5
5
|
<slot></slot>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
@focus="handleFocus"
|
|
11
11
|
/>
|
|
12
12
|
<template #append>
|
|
13
|
-
<BButton variant="
|
|
13
|
+
<BButton variant="light" class="btn-append">
|
|
14
14
|
<i v-if="clearable && !disabled && modelValue"
|
|
15
15
|
class="bi bi-x-circle me-1"
|
|
16
16
|
@click.stop="clearValue">
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<component ref="content" :is="content" v-bind="contentProps" v-else></component>
|
|
21
21
|
<template #footer>
|
|
22
22
|
<TnxbsvButton v-for="(button, index) in buttons" :key="index"
|
|
23
|
-
:type="button.type"
|
|
23
|
+
:type="button.type || 'light'"
|
|
24
24
|
:loading="buttonLoadings[index]"
|
|
25
25
|
@click="btnClick(index)"
|
|
26
26
|
>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tnxbs-progress">
|
|
3
|
+
<BProgress :variant="type" :key="type" :value="value" :max="max" :show-value="showValue">
|
|
4
|
+
<div class="progress-bar" :style="{width: percent}">
|
|
5
|
+
{{ showProgress ? percent : '' }}
|
|
6
|
+
</div>
|
|
7
|
+
</BProgress>
|
|
8
|
+
<span class="tnxbs-progress-value" v-if="showValue">{{ value }}/{{ max }}</span>
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
import {BProgress} from 'bootstrap-vue-next';
|
|
14
|
+
|
|
15
|
+
export default {
|
|
16
|
+
name: 'TnxbsvProgress',
|
|
17
|
+
components: {BProgress},
|
|
18
|
+
props: {
|
|
19
|
+
type: String,
|
|
20
|
+
value: {
|
|
21
|
+
type: Number,
|
|
22
|
+
default: 0
|
|
23
|
+
},
|
|
24
|
+
max: Number,
|
|
25
|
+
precision: {
|
|
26
|
+
type: Number,
|
|
27
|
+
default: 0,
|
|
28
|
+
},
|
|
29
|
+
showValue: Boolean,
|
|
30
|
+
showProgress: Boolean,
|
|
31
|
+
},
|
|
32
|
+
data() {
|
|
33
|
+
return {};
|
|
34
|
+
},
|
|
35
|
+
computed: {
|
|
36
|
+
percent() {
|
|
37
|
+
return (this.value / this.max).toPercent(this.precision);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
methods: {}
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
.tnxbs-progress {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.tnxbs-progress .progress {
|
|
51
|
+
flex-grow: 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.tnxbs-progress .tnxbs-progress-value {
|
|
55
|
+
margin-left: 0.5rem;
|
|
56
|
+
color: var(--bs-body-color);
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -15,12 +15,14 @@ import FormGroup from './form/FormGroup.vue';
|
|
|
15
15
|
import LoadingIcon from './loading-icon/LoadingIcon.vue';
|
|
16
16
|
import LoadingOverlay from './loading-overlay/LoadingOverlay.vue';
|
|
17
17
|
import Paged from './paged/Paged.vue';
|
|
18
|
+
import Progress from './progress/Progress.vue';
|
|
18
19
|
import QueryForm from './query-form/QueryForm.vue';
|
|
19
20
|
import QueryTable from './query-table/QueryTable.vue';
|
|
20
21
|
import RegionCascader from './region-cascader/RegionCascader.vue';
|
|
21
22
|
import Select from './select/Select.vue';
|
|
22
23
|
import SubmitForm from './submit-form/SubmitForm.vue';
|
|
23
24
|
import TagsInput from './tags-input/TagsInput.vue';
|
|
25
|
+
import Upload from './upload/Upload.vue';
|
|
24
26
|
|
|
25
27
|
export const build = tnxvue.build;
|
|
26
28
|
|
|
@@ -34,12 +36,14 @@ export default build('tnxbsv', () => {
|
|
|
34
36
|
FormGroup,
|
|
35
37
|
LoadingIcon,
|
|
36
38
|
Paged,
|
|
39
|
+
Progress,
|
|
37
40
|
QueryForm,
|
|
38
41
|
QueryTable,
|
|
39
42
|
RegionCascader,
|
|
40
43
|
Select,
|
|
41
44
|
SubmitForm,
|
|
42
45
|
TagsInput,
|
|
46
|
+
Upload,
|
|
43
47
|
});
|
|
44
48
|
|
|
45
49
|
const tnxbsv = Object.assign({}, tnxjq, tnxvue, {
|
|
@@ -51,7 +55,7 @@ export default build('tnxbsv', () => {
|
|
|
51
55
|
let id = new Date().getTime();
|
|
52
56
|
let containerId = 'dialog-container-' + id;
|
|
53
57
|
let componentDefinition = Object.assign({}, Dialog,);
|
|
54
|
-
let
|
|
58
|
+
let rootProps = Object.assign({}, options, {
|
|
55
59
|
modelValue: true,
|
|
56
60
|
id: id,
|
|
57
61
|
container: '#' + containerId,
|
|
@@ -60,6 +64,7 @@ export default build('tnxbsv', () => {
|
|
|
60
64
|
contentProps,
|
|
61
65
|
buttons,
|
|
62
66
|
});
|
|
67
|
+
let dialogVm = window.tnx.createVueInstance(componentDefinition, null, rootProps);
|
|
63
68
|
const dialogContainer = document.createElement('div');
|
|
64
69
|
dialogContainer.className = 'tnxbsv-dialog-container';
|
|
65
70
|
dialogContainer.id = containerId;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tnxbsv-upload">
|
|
3
|
+
<BOverlay :show="uploading" spinner-variant="primary" spinner-small>
|
|
4
|
+
<BInputGroup>
|
|
5
|
+
<BFormInput :value="file?.name" :placeholder="placeholder" tabindex="-1" readonly/>
|
|
6
|
+
<template #append>
|
|
7
|
+
<div class="input-group-append">
|
|
8
|
+
<i class="bi bi-x-circle icon-clear" @click="clear" v-if="empty"/>
|
|
9
|
+
<BButton :variant="buttonType" @click="toSelect">{{ buttonText }}</BButton>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
</BInputGroup>
|
|
13
|
+
<BFormFile class="d-none" v-model="file" :accept="uploadOptions.extensions || accept"/>
|
|
14
|
+
</BOverlay>
|
|
15
|
+
<div class="tnxbsv-upload-error" v-if="errorMessage">{{ errorMessage }}</div>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
import {BOverlay, BInputGroup, BFormInput, BButton, BFormFile} from 'bootstrap-vue-next';
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
name: 'TnxbsvUpload',
|
|
24
|
+
components: {BOverlay, BInputGroup, BFormInput, BButton, BFormFile,},
|
|
25
|
+
props: {
|
|
26
|
+
app: String, // 上传目标应用名称
|
|
27
|
+
action: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
accept: [String, Array],
|
|
32
|
+
uploadOptions: {
|
|
33
|
+
type: Object,
|
|
34
|
+
default: () => ({}),
|
|
35
|
+
},
|
|
36
|
+
placeholder: String,
|
|
37
|
+
buttonType: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: 'light',
|
|
40
|
+
},
|
|
41
|
+
buttonText: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: '选择文件',
|
|
44
|
+
},
|
|
45
|
+
empty: Boolean,
|
|
46
|
+
beforeUpload: Function,
|
|
47
|
+
onSuccess: Function,
|
|
48
|
+
onError: Function,
|
|
49
|
+
},
|
|
50
|
+
data() {
|
|
51
|
+
return {
|
|
52
|
+
file: null,
|
|
53
|
+
uploading: false,
|
|
54
|
+
errorMessage: null,
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
computed: {
|
|
58
|
+
actionUrl() {
|
|
59
|
+
let baseUrl;
|
|
60
|
+
if (this.app) {
|
|
61
|
+
baseUrl = window.tnx.app.rpc.getBaseUrl(this.app);
|
|
62
|
+
}
|
|
63
|
+
baseUrl = baseUrl || window.tnx.app.rpc.getDefaultBaseUrl();
|
|
64
|
+
return baseUrl + this.action;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
watch: {
|
|
68
|
+
file(newFile, oldFile) {
|
|
69
|
+
if (newFile) {
|
|
70
|
+
if (!newFile.handled) {
|
|
71
|
+
this.uploadFile();
|
|
72
|
+
}
|
|
73
|
+
} else if (!oldFile.handled) {
|
|
74
|
+
oldFile.handled = true;
|
|
75
|
+
this.file = oldFile;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
mounted() {
|
|
80
|
+
this.file = null;
|
|
81
|
+
this.uploading = false;
|
|
82
|
+
this.errorMessage = null;
|
|
83
|
+
},
|
|
84
|
+
methods: {
|
|
85
|
+
toSelect() {
|
|
86
|
+
const $ = window.tnx.libs.$;
|
|
87
|
+
$('.tnxbsv-upload input[type="file"]').trigger('click')
|
|
88
|
+
},
|
|
89
|
+
clear() {
|
|
90
|
+
this.file.handled = true;
|
|
91
|
+
this.$nextTick(() => {
|
|
92
|
+
this.file = null;
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
uploadFile() {
|
|
96
|
+
if (this.file) {
|
|
97
|
+
if (this.beforeUpload && this.beforeUpload(this.file) === false) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const formData = new FormData();
|
|
101
|
+
formData.append('file', this.file);
|
|
102
|
+
this.uploading = true;
|
|
103
|
+
this.errorMessage = null;
|
|
104
|
+
|
|
105
|
+
window.tnx.app.rpc.request(this.actionUrl, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
body: formData,
|
|
108
|
+
timeout: 0, // 文件上传不设置超时
|
|
109
|
+
app: this.app, // 指定目标应用
|
|
110
|
+
success: result => {
|
|
111
|
+
if (this.onSuccess) {
|
|
112
|
+
this.onSuccess(result);
|
|
113
|
+
} else {
|
|
114
|
+
console.log('文件上传成功:', result);
|
|
115
|
+
}
|
|
116
|
+
this.uploading = false;
|
|
117
|
+
},
|
|
118
|
+
error: error => {
|
|
119
|
+
this.uploading = false;
|
|
120
|
+
if (this.onError && this.onError(error) === false) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.errorMessage = error.message;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style>
|
|
133
|
+
.tnxbsv-upload input:focus {
|
|
134
|
+
outline: none;
|
|
135
|
+
box-shadow: none;
|
|
136
|
+
border-color: var(--bs-border-color);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.tnxbsv-upload .input-group-append {
|
|
140
|
+
position: relative;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.tnxbsv-upload .input-group-append .icon-clear {
|
|
144
|
+
position: absolute;
|
|
145
|
+
right: calc(100% + 0.75rem);
|
|
146
|
+
top: 50%;
|
|
147
|
+
transform: translateY(-50%);
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
z-index: 10;
|
|
150
|
+
color: var(--bs-tertiary-color);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.tnxbsv-upload .input-group-append .icon-clear:hover {
|
|
154
|
+
color: var(--bs-secondary-color);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.tnxbsv-upload .input-group-append .btn {
|
|
158
|
+
border-top-left-radius: 0;
|
|
159
|
+
border-bottom-left-radius: 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.tnxbsv-upload-error {
|
|
163
|
+
margin-top: 0.25rem;
|
|
164
|
+
color: var(--bs-danger);
|
|
165
|
+
font-size: 87.5%;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.tnxbsv-upload-placeholder {
|
|
169
|
+
margin-top: 0.25rem;
|
|
170
|
+
color: var(--bs-tertiary-color);
|
|
171
|
+
font-size: 87.5%;
|
|
172
|
+
}
|
|
173
|
+
</style>
|
|
@@ -103,7 +103,7 @@ export default {
|
|
|
103
103
|
return height;
|
|
104
104
|
},
|
|
105
105
|
downloadUrl() {
|
|
106
|
-
let baseUrl =
|
|
106
|
+
let baseUrl = window.tnx.app.rpc.getDefaultBaseUrl();
|
|
107
107
|
if (this.app) {
|
|
108
108
|
baseUrl = window.tnx.app.rpc.getBaseUrl(this.app);
|
|
109
109
|
}
|
package/src/tnxvue.js
CHANGED
package/src/tnxvue-cli.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// tnxvue-cli.js
|
|
2
|
-
const TerserPlugin = require('terser-webpack-plugin');
|
|
3
|
-
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
4
|
-
|
|
5
|
-
module.exports = {
|
|
6
|
-
uglify(config, options) {
|
|
7
|
-
Object.assign(config, {
|
|
8
|
-
optimization: {
|
|
9
|
-
minimizer: [new TerserPlugin({
|
|
10
|
-
terserOptions: Object.assign({
|
|
11
|
-
compress: {
|
|
12
|
-
warnings: false,
|
|
13
|
-
drop_console: false,
|
|
14
|
-
drop_debugger: true,
|
|
15
|
-
}
|
|
16
|
-
}, options)
|
|
17
|
-
})]
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
},
|
|
21
|
-
copy(config, dependencies, libs, patterns) {
|
|
22
|
-
let pluginPatterns = [];
|
|
23
|
-
for (let lib of libs) {
|
|
24
|
-
let from = lib.path;
|
|
25
|
-
let to = 'libs/js/' + lib.name;
|
|
26
|
-
if (config.mode === 'production') {
|
|
27
|
-
let version = dependencies[lib.name];
|
|
28
|
-
if (version) {
|
|
29
|
-
to += '-' + version;
|
|
30
|
-
}
|
|
31
|
-
from += lib.prod;
|
|
32
|
-
to += lib.prod;
|
|
33
|
-
}
|
|
34
|
-
if (!from.endsWith('/')) {
|
|
35
|
-
from += '.js';
|
|
36
|
-
}
|
|
37
|
-
if (!to.endsWith('/')) {
|
|
38
|
-
to += '.js';
|
|
39
|
-
}
|
|
40
|
-
pluginPatterns.push({
|
|
41
|
-
from: './node_modules/' + from,
|
|
42
|
-
to: './' + to,
|
|
43
|
-
});
|
|
44
|
-
let globalVarName = config.externals[lib.name];
|
|
45
|
-
if (globalVarName) {
|
|
46
|
-
let baseUrl = process.env.VUE_APP_VIEW_BASE_URL;
|
|
47
|
-
if (!baseUrl.endsWith('/')) {
|
|
48
|
-
baseUrl += '/';
|
|
49
|
-
}
|
|
50
|
-
process.env['VUE_APP_LIBS_' + globalVarName] = baseUrl + to;
|
|
51
|
-
}
|
|
52
|
-
if (lib.map) {
|
|
53
|
-
pluginPatterns.push({
|
|
54
|
-
from: './node_modules/' + lib.path + lib.map,
|
|
55
|
-
to: './libs/js/',
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (patterns && patterns.length) {
|
|
60
|
-
pluginPatterns = pluginPatterns.concat(patterns);
|
|
61
|
-
}
|
|
62
|
-
config.plugins.push(new CopyWebpackPlugin({patterns: pluginPatterns}));
|
|
63
|
-
},
|
|
64
|
-
}
|