@truenewx/tnxvue3 3.4.3 → 3.4.5

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 (47) hide show
  1. package/package.json +12 -6
  2. package/src/bootstrap-vue/dialog/Dialog.vue +22 -10
  3. package/src/element-plus/aj-captcha/api/index.js +2 -2
  4. package/src/element-plus/avatar/Avatar.vue +4 -27
  5. package/src/element-plus/date-picker/DatePicker.vue +8 -9
  6. package/src/element-plus/dialog/Dialog.vue +34 -22
  7. package/src/element-plus/drawer/Drawer.vue +22 -5
  8. package/src/element-plus/edit-table/EditTable.vue +10 -10
  9. package/src/element-plus/enum-select/EnumSelect.vue +30 -30
  10. package/src/element-plus/enum-view/EnumView.vue +1 -3
  11. package/src/element-plus/fetch-cascader/FetchCascader.vue +4 -4
  12. package/src/element-plus/fetch-select/FetchSelect.vue +3 -3
  13. package/src/element-plus/fetch-tags/FetchTags.vue +1 -1
  14. package/src/element-plus/fss-upload/FssUpload.vue +76 -115
  15. package/src/element-plus/fss-view/FssView.vue +28 -30
  16. package/src/element-plus/icon/Icon.vue +3 -0
  17. package/src/element-plus/query-form/QueryForm.vue +3 -3
  18. package/src/element-plus/query-table/QueryTable.vue +12 -12
  19. package/src/element-plus/region-cascader/RegionCascader.vue +3 -3
  20. package/src/element-plus/select/Select.vue +56 -56
  21. package/src/element-plus/submit-form/SubmitForm.vue +5 -5
  22. package/src/element-plus/tnxel-validator.ts +347 -0
  23. package/src/element-plus/tnxel.css +0 -8
  24. package/src/element-plus/tnxel.ts +561 -0
  25. package/src/element-plus/transfer/Transfer.vue +2 -2
  26. package/src/element-plus/upload/Upload.vue +68 -70
  27. package/src/tdesign/desktop/tnxtdd.ts +5 -5
  28. package/src/tdesign/mobile/calendar/Calendar.vue +121 -0
  29. package/src/tdesign/mobile/date-time-picker/DateTimePicker.vue +147 -0
  30. package/src/tdesign/mobile/dialog/Dialog.vue +179 -0
  31. package/src/tdesign/mobile/dialog/DialogContent.vue +13 -0
  32. package/src/tdesign/mobile/drawer/Drawer.vue +176 -0
  33. package/src/tdesign/mobile/drawer/DrawerContent.vue +13 -0
  34. package/src/tdesign/mobile/enum-select/EnumSelect.vue +160 -0
  35. package/src/tdesign/mobile/popup/Popup.vue +106 -0
  36. package/src/tdesign/mobile/region-picker/RegionPicker.vue +223 -0
  37. package/src/tdesign/mobile/select/Select.vue +478 -0
  38. package/src/tdesign/mobile/slide-radio-group/SlideRadioGroup.vue +392 -0
  39. package/src/tdesign/mobile/tnxtdm.css +132 -0
  40. package/src/tdesign/mobile/tnxtdm.ts +310 -7
  41. package/src/tdesign/{foundation/validator.ts → tnxtd-validator.ts} +18 -17
  42. package/src/tdesign/tnxtd.css +66 -0
  43. package/src/tdesign/tnxtd.ts +10 -7
  44. package/src/tnxvue-router.ts +65 -18
  45. package/src/tnxvue.ts +71 -31
  46. package/tsconfig.json +33 -19
  47. package/src/element-plus/tnxel.js +0 -598
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truenewx/tnxvue3",
3
- "version": "3.4.3",
3
+ "version": "3.4.5",
4
4
  "description": "互联网技术解决方案:Vue3扩展支持",
5
5
  "private": false,
6
6
  "type": "module",
@@ -22,24 +22,30 @@
22
22
  "@element-plus/icons-vue": "~2.3.0",
23
23
  "async-validator": "~4.2.0",
24
24
  "bootstrap-vue-next": "~0.40.0",
25
- "element-plus": "~2.11.0",
25
+ "element-plus": "~2.13.0",
26
26
  "tdesign-icons-vue-next": "~0.4.0",
27
- "tdesign-mobile-vue": "~1.11.0",
27
+ "tdesign-mobile-vue": "~1.12.0",
28
28
  "tdesign-vue-next": "~1.17.0",
29
29
  "validator": "~13.15.0",
30
30
  "vue": "~3.5.0",
31
31
  "vue-router": "~4.6.0"
32
32
  },
33
33
  "dependencies": {
34
- "@truenewx/tnxcore": "3.4.2",
34
+ "@truenewx/tnxcore": "3.4.4",
35
+ "bootstrap": "5.3.8",
36
+ "cash-dom": "8.1.5",
35
37
  "mitt": "3.0.1"
36
38
  },
37
39
  "devDependencies": {
38
- "@eslint/js": "9.39.1",
40
+ "@eslint/js": "9.39.2",
41
+ "@typescript-eslint/parser": "8.50.0",
42
+ "@typescript-eslint/eslint-plugin": "8.50.0",
39
43
  "@vitejs/plugin-vue": "6.0.1",
40
44
  "eslint": "9.39.1",
41
45
  "eslint-plugin-vue": "10.5.1",
42
46
  "globals": "16.5.0",
47
+ "tsx": "4.21.0",
48
+ "typescript": "5.6.3",
43
49
  "vite": "7.2.2",
44
50
  "vue-eslint-parser": "10.2.0"
45
51
  },
@@ -49,4 +55,4 @@
49
55
  "not dead",
50
56
  "not ie 11"
51
57
  ]
52
- }
58
+ }
@@ -20,9 +20,9 @@
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 || 'light'"
24
- :loading="buttonLoadings[index]"
25
- @click="btnClick(index)"
23
+ :type="button.type || 'light'"
24
+ :loading="buttonLoadings[index]"
25
+ @click="btnClick(index)"
26
26
  >
27
27
  {{ button.caption || button.text }}
28
28
  </TnxbsvButton>
@@ -113,14 +113,26 @@ export default {
113
113
  },
114
114
  btnClick(index) {
115
115
  const button = this.buttons[index];
116
- if (button && typeof button.click === 'function') {
117
- let result = button.click.call(this.$refs.content, this.close);
118
- if (result === 'loading') {
119
- this.buttonLoadings[index] = true;
120
- return;
116
+ if (button) {
117
+ let click = button.click;
118
+ if (typeof click === 'string') {
119
+ if (typeof this.$refs.content[click] === 'function') {
120
+ click = this.$refs.content[click];
121
+ } else {
122
+ console.error(`Method '${click}' not found in component:`, this.$refs.content);
123
+ click = null;
124
+ }
121
125
  }
122
- if (result === false) {
123
- return;
126
+
127
+ if (typeof click === 'function') {
128
+ let result = click.call(this.$refs.content, this.close);
129
+ if (result === 'loading') {
130
+ this.buttonLoadings[index] = true;
131
+ return;
132
+ }
133
+ if (result === false) {
134
+ return;
135
+ }
124
136
  }
125
137
  }
126
138
  this.close();
@@ -1,11 +1,11 @@
1
1
  // 获取验证图片以及token
2
2
  export function reqGet(data) {
3
- return window.tnx.app.rpc.post('/captcha/generate', data);
3
+ return window.tnx.api.post('/captcha/generate', data);
4
4
  }
5
5
 
6
6
  // 滑动或者点选验证
7
7
  export function reqCheck(data) {
8
- return window.tnx.app.rpc.post('/captcha/check', data);
8
+ return window.tnx.api.post('/captcha/check', data);
9
9
  }
10
10
 
11
11
 
@@ -74,33 +74,10 @@ export default {
74
74
  methods: {
75
75
  load() {
76
76
  if (this.url && this.url.startsWith(window.tnx.fss.PROTOCOL)) {
77
- let rpc = window.tnx.app.rpc;
78
- let fssConfig = window.tnx.fss.getClientConfig();
79
- if (this.preview) {
80
- rpc.get(fssConfig.contextUrl + '/meta', {
81
- locationUrl: this.url
82
- }, (meta) => {
83
- this.src = meta.thumbnailReadUrl;
84
- this.previewSrcList = [meta.readUrl];
85
- }, {
86
- app: fssConfig.appName,
87
- error(errors) {
88
- console.error(errors[0].message);
89
- }
90
- });
91
- } else {
92
- rpc.get(fssConfig.contextUrl + '/read/url', {
93
- locationUrl: this.url,
94
- thumbnail: true,
95
- }, (readUrl) => {
96
- this.src = readUrl;
97
- }, {
98
- app: fssConfig.appName,
99
- error(errors) {
100
- console.error(errors[0].message);
101
- }
102
- });
103
- }
77
+ window.tnx.fss.getReadUrl(this.url, true).then(readUrl => {
78
+ this.src = readUrl.thumbnailUrl;
79
+ this.previewSrcList = [readUrl.readUrl];
80
+ });
104
81
  } else {
105
82
  this.src = this.url;
106
83
  }
@@ -1,23 +1,22 @@
1
1
  <template>
2
2
  <div class="tnxel-date-picker d-flex" v-if="permanentable">
3
3
  <el-date-picker :type="type" v-model="model.value" :value-format="format" :editable="editable"
4
- :placeholder="placeholderText" :clearable="empty" :default-value="defaultDate"
5
- :disabled-date="disabledDate" :disabled="disabled || model.permanent"
6
- :class="{'flex-grow-1': !pickerWidth}" :style="{width: pickerWidth}"
7
- @change="emitModelValue"/>
4
+ :placeholder="placeholderText" :clearable="empty" :default-value="defaultDate"
5
+ :disabled-date="disabledDate" :disabled="disabled || model.permanent"
6
+ :class="{'flex-grow-1': !pickerWidth}" :style="{width: pickerWidth}"
7
+ @change="emitModelValue"/>
8
8
  <el-checkbox style="margin-left: 1rem; margin-right: 0.75rem;" v-model="model.permanent"
9
- @change="onPermanentChange">{{ permanentText }}
9
+ @change="onPermanentChange">{{ permanentText }}
10
10
  </el-checkbox>
11
11
  </div>
12
12
  <el-date-picker class="tnxel-date-picker" :type="type" v-model="model.value" :value-format="format"
13
- :editable="editable" :placeholder="placeholderText" :clearable="empty" :default-value="defaultDate"
14
- :disabled-date="disabledDate" :disabled="disabled" :style="{width: pickerWidth}" v-else/>
13
+ :editable="editable" :placeholder="placeholderText" :clearable="empty" :default-value="defaultDate"
14
+ :disabled-date="disabledDate" :disabled="disabled" :style="{width: pickerWidth}" v-else/>
15
15
  </template>
16
16
 
17
17
  <script>
18
18
  import $ from 'cash-dom';
19
-
20
- const util = window.tnx.util;
19
+ import {util} from '../tnxel.ts';
21
20
 
22
21
  export default {
23
22
  name: 'TnxelDatePicker',
@@ -1,19 +1,19 @@
1
1
  <template>
2
2
  <el-dialog class="tnxel-dialog"
3
- :data-v-id="id"
4
- v-model="visible"
5
- destroy-on-close
6
- append-to-body
7
- :modal="options.modal"
8
- :close-on-click-modal="options['close-on-click-modal']"
9
- :close-on-press-escape="options['close-on-press-escape']"
10
- :show-close="options['show-close']"
11
- :center="options.center"
12
- :before-close="beforeClose"
13
- @closed="onClosed">
3
+ :data-v-id="id"
4
+ v-model="visible"
5
+ destroy-on-close
6
+ append-to-body
7
+ :modal="options.modal"
8
+ :close-on-click-modal="options['close-on-click-modal']"
9
+ :close-on-press-escape="options['close-on-press-escape']"
10
+ :show-close="options['show-close']"
11
+ :center="options.center"
12
+ :before-close="beforeClose"
13
+ @closed="onClosed">
14
14
  <template #header>
15
15
  <div class="tnxel-dialog-title" :class="mergeClass({'border-bottom': title})" v-html="title"
16
- v-if="title || options['show-close']"></div>
16
+ v-if="title || options['show-close']"></div>
17
17
  </template>
18
18
  <template v-if="$slots.default">
19
19
  <slot></slot>
@@ -23,7 +23,7 @@
23
23
  <template #footer v-if="buttons && buttons.length">
24
24
  <div class="tnxel-dialog-footer" :class="mergeClass()">
25
25
  <el-button v-for="(button, index) in buttons" :type="button.type" :key="index"
26
- :loading="buttonLoadings[index]" @click="btnClick(index)">{{ button.caption || button.text }}
26
+ :loading="buttonLoadings[index]" @click="btnClick(index)">{{ button.caption || button.text }}
27
27
  </el-button>
28
28
  </div>
29
29
  </template>
@@ -111,7 +111,7 @@ export default {
111
111
  },
112
112
  },
113
113
  mounted() {
114
- window.tnx.app.eventBus.once('tnx.error', options => {
114
+ window.tnx.eventBus.once('tnx.error', options => {
115
115
  this.buttonLoadings = [];
116
116
  });
117
117
  this.$nextTick(() => {
@@ -133,7 +133,7 @@ export default {
133
133
  });
134
134
  },
135
135
  beforeUnmount() {
136
- window.tnx.app.eventBus.off('tnx.error');
136
+ window.tnx.eventBus.off('tnx.error');
137
137
  },
138
138
  methods: {
139
139
  mergeClass(classObject) {
@@ -170,14 +170,26 @@ export default {
170
170
  },
171
171
  btnClick(index) {
172
172
  const button = this.buttons[index];
173
- if (button && typeof button.click === 'function') {
174
- let result = button.click.call(this.$refs.content, this.close);
175
- if (result === 'loading') {
176
- this.buttonLoadings[index] = true;
177
- return;
173
+ if (button) {
174
+ let click = button.click;
175
+ if (typeof click === 'string') {
176
+ if (typeof this.$refs.content[click] === 'function') {
177
+ click = this.$refs.content[click];
178
+ } else {
179
+ console.error(`Method '${click}' not found in component:`, this.$refs.content);
180
+ click = null;
181
+ }
178
182
  }
179
- if (result === false) {
180
- return;
183
+
184
+ if (typeof click === 'function') {
185
+ let result = click.call(this.$refs.content, this.close);
186
+ if (result === 'loading') {
187
+ this.buttonLoadings[index] = true;
188
+ return;
189
+ }
190
+ if (result === false) {
191
+ return;
192
+ }
181
193
  }
182
194
  }
183
195
  this.close();
@@ -23,7 +23,7 @@
23
23
  </div>
24
24
  <div class="tnxel-drawer-footer" v-if="buttons && buttons.length">
25
25
  <el-button v-for="(button, index) in buttons" :type="button.type" :key="index"
26
- @click="btnClick(index)">{{ button.caption || button.text }}
26
+ @click="btnClick(index)">{{ button.caption || button.text }}
27
27
  </el-button>
28
28
  </div>
29
29
  </div>
@@ -31,7 +31,7 @@
31
31
  </template>
32
32
 
33
33
  <script>
34
- const util = window.tnx.util;
34
+ import {util} from '../tnxel.ts';
35
35
 
36
36
  export default {
37
37
  name: 'TnxelDrawer',
@@ -87,9 +87,26 @@ export default {
87
87
  methods: {
88
88
  btnClick(index) {
89
89
  const button = this.buttons[index];
90
- if (button && typeof button.click === 'function') {
91
- if (button.click.call(this.$refs.content, this.close) === false) {
92
- return;
90
+ if (button) {
91
+ let click = button.click;
92
+ if (typeof click === 'string') {
93
+ if (typeof this.$refs.content[click] === 'function') {
94
+ click = this.$refs.content[click];
95
+ } else {
96
+ console.error(`Method '${click}' not found in component:`, this.$refs.content);
97
+ click = null;
98
+ }
99
+ }
100
+
101
+ if (typeof click === 'function') {
102
+ let result = click.call(this.$refs.content, this.close);
103
+ if (result === 'loading') {
104
+ this.buttonLoadings[index] = true;
105
+ return;
106
+ }
107
+ if (result === false) {
108
+ return;
109
+ }
93
110
  }
94
111
  }
95
112
  this.close();
@@ -1,14 +1,14 @@
1
1
  <template>
2
2
  <div class="tnxel-edit-table-container" :id="id">
3
3
  <el-table ref="table"
4
- class="tnxel-edit-table"
5
- :class="{'padding-none': !padding}"
6
- :data="tableDataList"
7
- :row-key="rowKey"
8
- :row-class-name="tableRowClassName"
9
- :highlight-current-row="selectable"
10
- border
11
- @current-change="onSelectRow"
4
+ class="tnxel-edit-table"
5
+ :class="{'padding-none': !padding}"
6
+ :data="tableDataList"
7
+ :row-key="rowKey"
8
+ :row-class-name="tableRowClassName"
9
+ :highlight-current-row="selectable"
10
+ border
11
+ @current-change="onSelectRow"
12
12
  >
13
13
  <template #empty v-if="!tableDataList">
14
14
  <tnxel-icon class="text-placeholder" value="Loading"/>
@@ -172,7 +172,7 @@ export default {
172
172
  initRules() {
173
173
  if (this.rules) {
174
174
  if (typeof this.rules === 'string') {
175
- window.tnx.app.rpc.getMeta(this.rules, this.rulesApp).then(meta => {
175
+ window.tnx.meta.getMeta(this.rules, this.rulesApp).then(meta => {
176
176
  if (this.rulesLoaded) {
177
177
  this.rulesLoaded(meta.$rules);
178
178
  } else {
@@ -269,7 +269,7 @@ export default {
269
269
  let model = {};
270
270
  model[fieldName] = element.value;
271
271
  let successful = true;
272
- window.tnx.app.validator.validate(rules, model).catch(errors => {
272
+ window.tnx.validator.validate(rules, model).catch(errors => {
273
273
  if (errors) {
274
274
  successful = false;
275
275
  let message = '';
@@ -1,37 +1,37 @@
1
1
  <template>
2
- <tnxel-fetch-cascader v-model="model"
3
- url="/api/meta/enums" value-name="key" text-name="caption" index-name="searchIndex"
4
- :disabled="disabled"
5
- :empty="empty"
6
- :filterable="filterable"
7
- :theme="theme"
8
- :params="{
2
+ <tnxel-fetch-cascader v-model="model"
3
+ url="/api/meta/enums" value-name="key" text-name="caption" index-name="searchIndex"
4
+ :disabled="disabled"
5
+ :empty="empty"
6
+ :filterable="filterable"
7
+ :theme="theme"
8
+ :params="{
9
9
  type: type,
10
10
  subtype:subtype,
11
11
  grouped: true,
12
12
  }"
13
- v-if="grouped"/>
14
- <tnxel-select ref="select"
15
- v-model="model"
16
- :id="id"
17
- :selector="selector"
18
- :items="items"
19
- value-name="key" text-name="caption" index-name="searchIndex"
20
- :default-value="defaultValue"
21
- :empty="empty"
22
- :empty-value="emptyValue"
23
- :placeholder="placeholder"
24
- :disabled="disabled"
25
- :filterable="filterable"
26
- :theme="theme"
27
- :size="size"
28
- :tag-click="tagClick"
29
- :change="change"
30
- v-else>
31
- <template #option="{item}" v-if="$slots.option">
32
- <slot name="option" :item="item"></slot>
33
- </template>
34
- </tnxel-select>
13
+ v-if="grouped"/>
14
+ <tnxel-select ref="select"
15
+ v-model="model"
16
+ :id="id"
17
+ :selector="selector"
18
+ :items="items"
19
+ value-name="key" text-name="caption" index-name="searchIndex"
20
+ :default-value="defaultValue"
21
+ :empty="empty"
22
+ :empty-value="emptyValue"
23
+ :placeholder="placeholder"
24
+ :disabled="disabled"
25
+ :filterable="filterable"
26
+ :theme="theme"
27
+ :size="size"
28
+ :tag-click="tagClick"
29
+ :change="change"
30
+ v-else>
31
+ <template #option="{item}" v-if="$slots.option">
32
+ <slot name="option" :item="item"></slot>
33
+ </template>
34
+ </tnxel-select>
35
35
  </template>
36
36
 
37
37
  <script>
@@ -116,7 +116,7 @@ export default {
116
116
  this.initModel();
117
117
  } else {
118
118
  let vm = this;
119
- window.tnx.app.rpc.resolveEnumItems(this.type, this.subtype, {
119
+ window.tnx.meta.resolveEnumItems(this.type, this.subtype, {
120
120
  app: this.app,
121
121
  }).then((items) => {
122
122
  vm.items = items;
@@ -26,9 +26,7 @@ export default {
26
26
  };
27
27
  },
28
28
  mounted() {
29
- window.tnx.app.rpc.resolveEnumType(this.type, this.subtype, {
30
- app: this.app,
31
- }).then(enumType => {
29
+ window.tnx.meta.resolveEnumType(this.type, this.subtype).then(enumType => {
32
30
  this.item = enumType.items.find(item => item.key === this.itemKey);
33
31
  });
34
32
  },
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <el-cascader v-model="model" class="ignore-feedback" :options="items" :props="options"
3
- :placeholder="placeholder" :show-all-levels="showAllLevels" :clearable="empty" :disabled="disabled"
4
- :filterable="filterable" :filter-method="filter" v-if="items"/>
3
+ :placeholder="placeholder" :show-all-levels="showAllLevels" :clearable="empty" :disabled="disabled"
4
+ :filterable="filterable" :filter-method="filter" v-if="items"/>
5
5
  </template>
6
6
 
7
7
  <script>
@@ -47,7 +47,7 @@ export default {
47
47
  change: Function, // 选中值变化后的事件处理函数,由于比element的change事件传递更多参数,所以以prop的形式指定,以尽量节省性能
48
48
  transferItems: {
49
49
  type: Function,
50
- default: function(items) {
50
+ default: function (items) {
51
51
  return items;
52
52
  }
53
53
  },
@@ -121,7 +121,7 @@ export default {
121
121
  return null;
122
122
  },
123
123
  load() {
124
- window.tnx.app.rpc.get(this.url, this.params).then((result) => {
124
+ window.tnx.api.get(this.url, this.params).then((result) => {
125
125
  this.items = this.transferItems(result);
126
126
  this.model = this.getModel();
127
127
  });
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <el-select v-model="model" :loading="loading" :filterable="filterable" remote :remote-method="load"
3
- :placeholder="finalPlaceholder" :disabled="disabled" :title="title" default-first-option>
3
+ :placeholder="finalPlaceholder" :disabled="disabled" :title="title" default-first-option>
4
4
  <el-option class="text-secondary" :value="null" :label="emptyText" v-if="empty"/>
5
5
  <el-option v-for="item in items" :key="item[valueName]" :value="item[valueName]" :label="label(item)"/>
6
6
  <el-option label="还有更多结果..." disabled v-if="more"/>
@@ -15,7 +15,7 @@ export default {
15
15
  url: String,
16
16
  params: { // 构建远程检索请求参数集的函数
17
17
  type: Function,
18
- default: function(keyword) {
18
+ default: function (keyword) {
19
19
  return keyword ? {keyword} : undefined;
20
20
  }
21
21
  },
@@ -122,7 +122,7 @@ export default {
122
122
  if (this.url && this.params) { // 当url或参数函数被设置为null时,不进行取数操作,用于初始条件不满足的情况
123
123
  this.loading = true;
124
124
  let params = this.params(keyword);
125
- window.tnx.app.rpc.get(this.url, params).then(result => {
125
+ window.tnx.api.get(this.url, params).then(result => {
126
126
  this.loading = false;
127
127
  if (Array.isArray(result)) {
128
128
  this.items = result;
@@ -94,7 +94,7 @@ export default {
94
94
  if (this.keyword) {
95
95
  params[this.keywordName] = this.keyword;
96
96
  }
97
- window.tnx.app.rpc.get(this.url, params).then(result => {
97
+ window.tnx.api.get(this.url, params).then(result => {
98
98
  if (result instanceof Array) {
99
99
  this.items = this.format(result);
100
100
  } else if (result.records && result.paged) {