@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.
Files changed (60) hide show
  1. package/README.md +3 -0
  2. package/package.json +76 -0
  3. package/sample/App.vue +19 -0
  4. package/sample/main.js +11 -0
  5. package/sample/pages/index.vue +79 -0
  6. package/sample/pages/info.vue +28 -0
  7. package/sample/tnx.js +31 -0
  8. package/src/aj-captcha/Verify/VerifyPoints.vue +258 -0
  9. package/src/aj-captcha/Verify/VerifySlide.vue +379 -0
  10. package/src/aj-captcha/Verify.vue +375 -0
  11. package/src/aj-captcha/api/index.js +19 -0
  12. package/src/aj-captcha/utils/ase.js +11 -0
  13. package/src/aj-captcha/utils/util.js +35 -0
  14. package/src/ant-design/tnxad-theme.css +5 -0
  15. package/src/ant-design/tnxad.css +8 -0
  16. package/src/ant-design/tnxad.js +23 -0
  17. package/src/element-plus/alert/Alert.vue +112 -0
  18. package/src/element-plus/avatar/Avatar.vue +124 -0
  19. package/src/element-plus/button/Button.vue +184 -0
  20. package/src/element-plus/check-icon/CheckIcon.vue +61 -0
  21. package/src/element-plus/close-error-button/CloseErrorButton.vue +45 -0
  22. package/src/element-plus/curd/Curd.vue +224 -0
  23. package/src/element-plus/date-picker/DatePicker.vue +206 -0
  24. package/src/element-plus/date-range/DateRange.vue +78 -0
  25. package/src/element-plus/datetime-picker/DateTimePicker.vue +129 -0
  26. package/src/element-plus/detail-form/DetailForm.vue +88 -0
  27. package/src/element-plus/dialog/Dialog.vue +259 -0
  28. package/src/element-plus/dialog/DialogContent.vue +13 -0
  29. package/src/element-plus/drawer/Drawer.vue +175 -0
  30. package/src/element-plus/dropdown-item/DropdownItem.vue +30 -0
  31. package/src/element-plus/enum-select/EnumSelect.vue +125 -0
  32. package/src/element-plus/fetch-cascader/FetchCascader.vue +138 -0
  33. package/src/element-plus/fetch-select/FetchSelect.vue +166 -0
  34. package/src/element-plus/fetch-tags/FetchTags.vue +122 -0
  35. package/src/element-plus/fss-upload/FssUpload.vue +306 -0
  36. package/src/element-plus/fss-view/FssView.vue +163 -0
  37. package/src/element-plus/icon/Icon.vue +221 -0
  38. package/src/element-plus/input-number/InputNumber.vue +150 -0
  39. package/src/element-plus/paged/Paged.vue +76 -0
  40. package/src/element-plus/permission-tree/PermissionTree.vue +184 -0
  41. package/src/element-plus/query-form/QueryForm.vue +138 -0
  42. package/src/element-plus/query-table/QueryTable.vue +402 -0
  43. package/src/element-plus/region-cascader/RegionCascader.vue +108 -0
  44. package/src/element-plus/select/Select.vue +446 -0
  45. package/src/element-plus/slider/Slider.vue +88 -0
  46. package/src/element-plus/steps-nav/StepsNav.vue +57 -0
  47. package/src/element-plus/submit-form/SubmitForm.vue +236 -0
  48. package/src/element-plus/table-column/TableColumn.vue +32 -0
  49. package/src/element-plus/tabs/Tabs.vue +93 -0
  50. package/src/element-plus/tnxel.css +890 -0
  51. package/src/element-plus/tnxel.js +528 -0
  52. package/src/element-plus/transfer/Transfer.vue +117 -0
  53. package/src/element-plus/upload/Upload.vue +856 -0
  54. package/src/percent/Percent.vue +12 -0
  55. package/src/text/Text.vue +33 -0
  56. package/src/tnxvue-cli.js +64 -0
  57. package/src/tnxvue-router.js +161 -0
  58. package/src/tnxvue-validator.js +365 -0
  59. package/src/tnxvue.css +12 -0
  60. package/src/tnxvue.js +343 -0
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # tnxvue3
2
+
3
+ 互联网技术解决方案:Vue3扩展支持
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@truenewx/tnxvue3",
3
+ "version": "2.6.0",
4
+ "description": "互联网技术解决方案:Vue3扩展支持",
5
+ "private": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "main": "sample/main.js",
10
+ "keywords": [
11
+ "truenewx",
12
+ "tnxvue3",
13
+ "tnx"
14
+ ],
15
+ "author": "truenewx",
16
+ "license": "Apache-2.0",
17
+ "scripts": {
18
+ "serve": "vue-cli-service serve",
19
+ "build": "vue-cli-service build"
20
+ },
21
+ "dependencies": {
22
+ "@truenewx/tnxcore": "2.6.1",
23
+ "@element-plus/icons-vue": "2.1.0",
24
+ "ant-design-vue": "3.2.20",
25
+ "async-validator": "4.2.5",
26
+ "crypto-js": "4.1.1",
27
+ "element-plus": "2.3.4",
28
+ "mitt": "3.0.0",
29
+ "vue": "3.2.47",
30
+ "vue-router": "4.1.6"
31
+ },
32
+ "devDependencies": {
33
+ "@babel/core": "7.21.8",
34
+ "@babel/eslint-parser": "7.21.8",
35
+ "@vue/cli-plugin-babel": "5.0.8",
36
+ "@vue/cli-plugin-eslint": "5.0.8",
37
+ "@vue/cli-service": "5.0.8",
38
+ "eslint": "7.32.0",
39
+ "eslint-plugin-vue": "8.7.1",
40
+ "copy-webpack-plugin": "11.0.0",
41
+ "terser-webpack-plugin": "5.3.7"
42
+ },
43
+ "eslintConfig": {
44
+ "root": true,
45
+ "env": {
46
+ "node": true
47
+ },
48
+ "extends": [
49
+ "plugin:vue/vue3-essential",
50
+ "eslint:recommended"
51
+ ],
52
+ "parserOptions": {
53
+ "parser": "@babel/eslint-parser"
54
+ },
55
+ "rules": {
56
+ "eqeqeq": "warn",
57
+ "no-unused-vars": [
58
+ "warn",
59
+ {
60
+ "vars": "local",
61
+ "args": "none"
62
+ }
63
+ ],
64
+ "no-undef": "warn",
65
+ "no-useless-escape": "warn",
66
+ "vue/no-v-model-argument": "off",
67
+ "vue/multi-word-component-names": "off"
68
+ }
69
+ },
70
+ "browserslist": [
71
+ "> 1%",
72
+ "last 2 versions",
73
+ "not dead",
74
+ "not ie 11"
75
+ ]
76
+ }
package/sample/App.vue ADDED
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div id="app">
3
+ <page-index/>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import index from './pages/index.vue';
9
+
10
+ export default {
11
+ name: 'App',
12
+ components: {
13
+ 'page-index': index,
14
+ },
15
+ data() {
16
+ return {}
17
+ }
18
+ }
19
+ </script>
package/sample/main.js ADDED
@@ -0,0 +1,11 @@
1
+ import '../../core/tnxcore.css';
2
+ import 'bootstrap/dist/css/bootstrap-reboot.min.css';
3
+ import 'bootstrap/dist/css/bootstrap-grid.min.css';
4
+ import 'bootstrap/dist/css/bootstrap-utilities.min.css';
5
+ import '../src/tnxvue.css';
6
+ import 'element-plus/dist/index.css';
7
+ import '../src/element-plus/tnxel.css';
8
+ import tnx from './tnx';
9
+ import App from './App.vue';
10
+
11
+ tnx.createVueInstance(App).mount('#app');
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div class="container-xl mx-auto flex-h-center">
3
+ <div class="text-center">
4
+ <h1>{{ title }}</h1>
5
+ <p>首页</p>
6
+ <el-space wrap>
7
+ <el-button @click="showAlert">Alert</el-button>
8
+ <el-button @click="showSuccess">Success</el-button>
9
+ <el-button @click="showError">Error</el-button>
10
+ <el-button @click="showConfirm">Confirm</el-button>
11
+ <el-button @click="showToast">Toast</el-button>
12
+ <el-button @click="showLoading">Loading</el-button>
13
+ <el-button @click="showOpen">Open</el-button>
14
+ </el-space>
15
+ <div class="mt-5">
16
+ <tnxel-fss-upload type="UserHeadImage" v-model="storageUrl"/>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <script>
23
+ import {app, tnx} from '../tnx.js';
24
+ import info from './info.vue';
25
+
26
+ export default {
27
+ components: {
28
+ 'tnxel-fss-upload': tnx.components.FssUpload,
29
+ },
30
+ data() {
31
+ return {
32
+ title: process.env.VUE_APP_TITLE,
33
+ storageUrl: null,
34
+ };
35
+ },
36
+ created() {
37
+ app.rpc.loadConfig(process.env.VUE_APP_API_BASE_URL);
38
+ },
39
+ methods: {
40
+ showAlert() {
41
+ tnx.alert('Hello World', function() {
42
+ console.info('Alerted');
43
+ });
44
+ },
45
+ showSuccess() {
46
+ tnx.success('提交成功,请等待组织管理员为你分配角色,获得组织角色后方可使用组织功能。', function() {
47
+ console.info('Successed');
48
+ });
49
+ },
50
+ showError() {
51
+ tnx.error('Hello World', function() {
52
+ console.info('Errored');
53
+ });
54
+ },
55
+ showConfirm() {
56
+ tnx.confirm('Hello World', function(yes) {
57
+ console.info(yes);
58
+ });
59
+ },
60
+ showToast() {
61
+ tnx.toast('操作成功', 200000, function() {
62
+ console.info('Toast closed.');
63
+ });
64
+ },
65
+ showLoading() {
66
+ tnx.showLoading('加载中');
67
+ setTimeout(function() {
68
+ tnx.closeLoading();
69
+ }, 2000);
70
+ },
71
+ showOpen() {
72
+ tnx.open(info, {
73
+ param: '- from params',
74
+ opener: this,
75
+ });
76
+ },
77
+ }
78
+ }
79
+ </script>
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div>
3
+ <p>Component: Hello World {{ param }}</p>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ props: ['param', 'opener'],
10
+ data() {
11
+ return {
12
+ abc: 'abc',
13
+ };
14
+ },
15
+ methods: {
16
+ dialog() {
17
+ return {
18
+ title: '组件',
19
+ type: 'confirm',
20
+ click: this.toSubmit
21
+ }
22
+ },
23
+ toSubmit(yes, close) {
24
+ console.info(this.abc + ': ' + yes);
25
+ }
26
+ }
27
+ }
28
+ </script>
package/sample/tnx.js ADDED
@@ -0,0 +1,31 @@
1
+ // tnx.js
2
+ import tnxel from '../src/element-plus/tnxel';
3
+
4
+ export const tnx = tnxel;
5
+ export const util = tnx.util;
6
+ export const app = tnx.app;
7
+
8
+ app.rpc.toLogin = function (loginFormUrl, originalUrl) {
9
+ if (loginFormUrl) {
10
+ let alertable = originalUrl !== undefined;
11
+ const username = process.env.VUE_APP_LOGIN_USERNAME;
12
+ const password = process.env.VUE_APP_LOGIN_PASSWORD;
13
+ if (username && password) { // 将默认用户名密码插入到参数清单头部,以免被其它参数中的#影响而被忽略
14
+ const index = loginFormUrl.indexOf('?') + 1;
15
+ loginFormUrl = loginFormUrl.substr(0, index) + 'username=' + username + '&password='
16
+ + password + '&' + loginFormUrl.substr(index);
17
+ alertable = false;
18
+ }
19
+ if (alertable) {
20
+ tnx.alert('尚未登录或登录会话已过期,需重新登录', function () {
21
+ window.location.href = loginFormUrl;
22
+ });
23
+ } else {
24
+ window.location.href = loginFormUrl;
25
+ }
26
+ return true;
27
+ }
28
+ return false;
29
+ }
30
+
31
+ export default tnx;
@@ -0,0 +1,258 @@
1
+ <template>
2
+ <div style="position: relative">
3
+ <div class="verify-img-out">
4
+ <div class="verify-img-panel" :style="{'height': setSize.imgHeight,
5
+ 'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
6
+ 'margin-bottom': vSpace + 'px'}"
7
+ >
8
+ <div class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
9
+ <el-icon :size="16">
10
+ <icon-refresh/>
11
+ </el-icon>
12
+ </div>
13
+ <img :src="'data:image/png;base64,'+pointBackImgBase"
14
+ ref="canvas"
15
+ alt="" style="width:100%;height:100%;display:block"
16
+ @click="bindingClick?canvasClick($event):undefined">
17
+
18
+ <div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area bg-success"
19
+ :style="{
20
+ color:'#fff',
21
+ 'z-index':9999,
22
+ width:'20px',
23
+ height:'20px',
24
+ 'text-align':'center',
25
+ 'line-height':'20px',
26
+ 'border-radius': '50%',
27
+ position:'absolute',
28
+ top:parseInt(tempPoint.y-10) + 'px',
29
+ left:parseInt(tempPoint.x-10) + 'px'
30
+ }">
31
+ {{ index + 1 }}
32
+ </div>
33
+ </div>
34
+ </div>
35
+ <!-- 'height': this.barSize.height, -->
36
+ <div class="verify-bar-area" :class="barAreaClass"
37
+ :style="{'line-height':this.barSize.height}">
38
+ <span class="verify-msg">{{ text }}</span>
39
+ </div>
40
+ </div>
41
+ </template>
42
+ <script type="text/babel">
43
+ /**
44
+ * VerifyPoints
45
+ * @description 点选
46
+ * */
47
+ import {resetSize} from '../utils/util';
48
+ import {aesEncrypt} from '../utils/ase';
49
+ import {reqCheck, reqGet} from '../api';
50
+ import {getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs} from 'vue';
51
+ import {Refresh} from '@element-plus/icons-vue';
52
+
53
+ export default {
54
+ name: 'VerifyPoints',
55
+ components: {
56
+ 'icon-refresh': Refresh,
57
+ },
58
+ props: {
59
+ //弹出式pop,固定fixed
60
+ mode: {
61
+ type: String,
62
+ default: 'fixed'
63
+ },
64
+ captchaType: {
65
+ type: String,
66
+ },
67
+ //间隔
68
+ vSpace: {
69
+ type: Number,
70
+ default: 5
71
+ },
72
+ imgSize: {
73
+ type: Object,
74
+ default() {
75
+ return {
76
+ width: '310px',
77
+ height: '155px'
78
+ }
79
+ }
80
+ },
81
+ barSize: {
82
+ type: Object,
83
+ default() {
84
+ return {
85
+ width: '310px',
86
+ height: '40px'
87
+ }
88
+ }
89
+ }
90
+ },
91
+ setup(props, context) {
92
+ const {mode, captchaType, vSpace, imgSize, barSize} = toRefs(props)
93
+ const {proxy} = getCurrentInstance();
94
+ let secretKey = ref(''), //后端返回的ase加密秘钥
95
+ checkNum = ref(3), //默认需要点击的字数
96
+ fontPos = reactive([]), //选中的坐标信息
97
+ checkPosArr = reactive([]), //用户点击的坐标
98
+ num = ref(1), //点击的记数
99
+ pointBackImgBase = ref(''), //后端获取到的背景图片
100
+ poinTextList = reactive([]), //后端返回的点击字体顺序
101
+ backToken = ref(''), //后端返回的token值
102
+ setSize = reactive({
103
+ imgHeight: 0,
104
+ imgWidth: 0,
105
+ barHeight: 0,
106
+ barWidth: 0
107
+ }),
108
+ tempPoints = reactive([]),
109
+ text = ref(''),
110
+ barAreaClass = ref('text-secondary'),
111
+ showRefresh = ref(true),
112
+ bindingClick = ref(true)
113
+
114
+
115
+ const init = () => {
116
+ //加载页面
117
+ fontPos.splice(0, fontPos.length)
118
+ checkPosArr.splice(0, checkPosArr.length)
119
+ num.value = 1
120
+ getPictrue();
121
+ nextTick(() => {
122
+ let {imgHeight, imgWidth, barHeight, barWidth} = resetSize(proxy)
123
+ setSize.imgHeight = imgHeight
124
+ setSize.imgWidth = imgWidth
125
+ setSize.barHeight = barHeight
126
+ setSize.barWidth = barWidth
127
+ proxy.$parent.$emit('ready', proxy)
128
+ })
129
+ }
130
+ onMounted(() => {
131
+ // 禁止拖拽
132
+ init()
133
+ proxy.$el.onselectstart = function () {
134
+ return false
135
+ }
136
+ })
137
+ const canvas = ref(null)
138
+ const canvasClick = (e) => {
139
+ checkPosArr.push(getMousePos(canvas, e));
140
+ if (num.value === checkNum.value) {
141
+ num.value = createPoint(getMousePos(canvas, e));
142
+ //按比例转换坐标值
143
+ let arr = pointTransfrom(checkPosArr, setSize)
144
+ checkPosArr.length = 0
145
+ checkPosArr.push(...arr);
146
+ //等创建坐标执行完
147
+ setTimeout(() => {
148
+ // let flag = this.comparePos(this.fontPos, this.checkPosArr);
149
+ //发送后端请求
150
+ let captchaVerification = secretKey.value ? aesEncrypt(
151
+ backToken.value + '---' + JSON.stringify(checkPosArr),
152
+ secretKey.value) : backToken.value + '---' + JSON.stringify(checkPosArr)
153
+ let data = {
154
+ captchaType: captchaType.value,
155
+ "pointJson": secretKey.value ? aesEncrypt(JSON.stringify(checkPosArr),
156
+ secretKey.value) : JSON.stringify(checkPosArr),
157
+ "token": backToken.value
158
+ }
159
+ reqCheck(data).then(res => {
160
+ if (res.repCode === "0000") {
161
+ barAreaClass.value = 'text-success border-success';
162
+ text.value = '验证成功'
163
+ bindingClick.value = false
164
+ if (mode.value == 'pop') {
165
+ setTimeout(() => {
166
+ proxy.$parent.clickShow = false;
167
+ refresh();
168
+ }, 1500)
169
+ }
170
+ proxy.$parent.$emit('success', {captchaVerification})
171
+ } else {
172
+ proxy.$parent.$emit('error', proxy)
173
+ barAreaClass.value = 'text-danger border-danger';
174
+ text.value = '验证失败'
175
+ setTimeout(() => {
176
+ refresh();
177
+ }, 700);
178
+ }
179
+ })
180
+ }, 400);
181
+ }
182
+ if (num.value < checkNum.value) {
183
+ num.value = createPoint(getMousePos(canvas, e));
184
+ }
185
+ }
186
+ //获取坐标
187
+ const getMousePos = function (obj, e) {
188
+ let x = e.offsetX
189
+ let y = e.offsetY
190
+ return {x, y}
191
+ }
192
+ //创建坐标点
193
+ const createPoint = function (pos) {
194
+ tempPoints.push(Object.assign({}, pos))
195
+ return num.value + 1;
196
+ }
197
+ const refresh = function () {
198
+ tempPoints.splice(0, tempPoints.length);
199
+ barAreaClass.value = 'text-secondary';
200
+ bindingClick.value = true
201
+ fontPos.splice(0, fontPos.length)
202
+ checkPosArr.splice(0, checkPosArr.length)
203
+ num.value = 1
204
+ getPictrue();
205
+ text.value = '验证失败'
206
+ showRefresh.value = true
207
+ }
208
+
209
+ // 请求背景图片和验证图片
210
+ function getPictrue() {
211
+ let data = {
212
+ captchaType: captchaType.value
213
+ }
214
+ reqGet(data).then(res => {
215
+ if (res.repCode === "0000") {
216
+ pointBackImgBase.value = res.repData.originalImageBase64
217
+ backToken.value = res.repData.token
218
+ secretKey.value = res.repData.secretKey
219
+ poinTextList.value = res.repData.wordList
220
+ text.value = '请依次点击【' + poinTextList.value.join("、") + '】'
221
+ } else {
222
+ text.value = res.repMsg;
223
+ }
224
+ })
225
+ }
226
+
227
+ //坐标转换函数
228
+ const pointTransfrom = function (pointArr, imgSize) {
229
+ let newPointArr = pointArr.map(p => {
230
+ let x = Math.round(310 * p.x / parseInt(imgSize.imgWidth))
231
+ let y = Math.round(155 * p.y / parseInt(imgSize.imgHeight))
232
+ return {x, y}
233
+ })
234
+ return newPointArr
235
+ }
236
+ return {
237
+ secretKey,
238
+ checkNum,
239
+ fontPos,
240
+ checkPosArr,
241
+ num,
242
+ pointBackImgBase,
243
+ poinTextList,
244
+ backToken,
245
+ setSize,
246
+ tempPoints,
247
+ text,
248
+ barAreaClass,
249
+ showRefresh,
250
+ bindingClick,
251
+ init,
252
+ canvas,
253
+ canvasClick,
254
+ getMousePos, createPoint, refresh, getPictrue, pointTransfrom
255
+ }
256
+ },
257
+ }
258
+ </script>