@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
@@ -1,32 +1,32 @@
1
1
  <template>
2
- <tnxel-alert type="error" v-if="errors">
3
- <div v-for="(error, index) of errors" :key="index">{{ error.message }}</div>
4
- </tnxel-alert>
5
- <tnxel-upload ref="upload"
6
- :app="app"
7
- :action="action"
8
- :upload-options="uploadOptions"
9
- :file-list="fileList"
10
- :width="width" :height="height"
11
- :center="center"
12
- :trigger-icon="triggerIcon" :trigger-icon-size="triggerIconSize" :trigger-text="triggerText"
13
- :tip="tip"
14
- :show-file-list="showFileList"
15
- :data="params"
16
- :before-upload="beforeUpload"
17
- :on-upload="onUpload"
18
- :on-progress="onProgress"
19
- :on-success="_onSuccess"
20
- :on-error="onError"
21
- :on-removed="_onRemove"
22
- :handle-errors="handleErrors"
23
- :file-icon="fileIcon"
24
- :disabled="disabled"
25
- v-else>
26
- <template #trigger v-if="$slots.trigger">
27
- <slot name="trigger"></slot>
28
- </template>
29
- </tnxel-upload>
2
+ <tnxel-alert type="error" v-if="errors">
3
+ <div v-for="(error, index) of errors" :key="index">{{ error.message }}</div>
4
+ </tnxel-alert>
5
+ <tnxel-upload ref="upload"
6
+ :app="app"
7
+ :action="action"
8
+ :upload-options="uploadLimit"
9
+ :file-list="fileList"
10
+ :width="width" :height="height"
11
+ :center="center"
12
+ :trigger-icon="triggerIcon" :trigger-icon-size="triggerIconSize" :trigger-text="triggerText"
13
+ :tip="tip"
14
+ :show-file-list="showFileList"
15
+ :data="params"
16
+ :before-upload="beforeUpload"
17
+ :on-upload="onUpload"
18
+ :on-progress="onProgress"
19
+ :on-success="_onSuccess"
20
+ :on-error="onError"
21
+ :on-removed="_onRemove"
22
+ :handle-errors="handleErrors"
23
+ :file-icon="fileIcon"
24
+ :disabled="disabled"
25
+ v-else>
26
+ <template #trigger v-if="$slots.trigger">
27
+ <slot name="trigger"></slot>
28
+ </template>
29
+ </tnxel-upload>
30
30
  </template>
31
31
 
32
32
  <script>
@@ -88,9 +88,9 @@ export default {
88
88
  const tnx = window.tnx;
89
89
  return {
90
90
  tnx: tnx,
91
- action: tnx.fss.getUploadUrl(this.type, this.scope),
91
+ action: tnx.fss.getUploadUrl(this.type, this.scope, this.app),
92
92
  params: {},
93
- uploadOptions: {},
93
+ uploadLimit: {},
94
94
  fileList: [],
95
95
  errors: null,
96
96
  };
@@ -141,75 +141,53 @@ export default {
141
141
  }
142
142
  return false;
143
143
  },
144
- _initialize() {
145
- const vm = this;
146
- let fssConfig = vm.tnx.fss.getClientConfig(this.app);
147
- vm.tnx.app.rpc.ensureLogined({
148
- app: window.tnx.componentDefaultApp || fssConfig.appName,
149
- toLogin(loginFormUrl, originalUrl, originalMethod) {
150
- return true;
151
- }
152
- }).then(() => {
153
- let locationUrls;
154
- if (vm.modelValue) {
155
- locationUrls = Array.isArray(vm.modelValue) ? vm.modelValue : [vm.modelValue];
156
- } else {
157
- locationUrls = [];
158
- }
159
- if (locationUrls.length) {
160
- vm.tnx.app.rpc.get(fssConfig.contextUrl + '/metas', {
161
- locationUrls: locationUrls
162
- }, {
163
- app: fssConfig.appName
164
- }).then(metas => {
165
- let fileList = [];
166
- metas.forEach(meta => {
167
- if (meta) {
168
- fileList.push({
169
- name: meta.name,
170
- url: vm._getFullReadUrl(meta.thumbnailReadUrl || meta.readUrl),
171
- previewUrl: vm.tnx.fss.getClientConfig().baseUrl + meta.downloadUrl,
172
- locationUrl: meta.locationUrl,
173
- });
174
- }
175
- });
176
- vm.fileList = fileList;
177
- vm.$nextTick(() => {
178
- vm._loadUploadOptions();
144
+ async _initialize() {
145
+ await this.tnx.auth.ensureLogined();
146
+ let locationUrls;
147
+ if (this.modelValue) {
148
+ locationUrls = Array.isArray(this.modelValue) ? this.modelValue : [this.modelValue];
149
+ } else {
150
+ locationUrls = [];
151
+ }
152
+ if (locationUrls.length) {
153
+ this.fileList = [];
154
+ for (let locationUrl of locationUrls) {
155
+ let readUrl = await this.tnx.fss.getReadUrl(locationUrl, true);
156
+ if (readUrl) {
157
+ this.fileList.push({
158
+ url: readUrl.thumbnailUrl,
159
+ previewUrl: readUrl.readUrl,
160
+ locationUrl: locationUrl,
179
161
  });
180
- });
181
- } else {
182
- vm.fileList = [];
183
- vm.$nextTick(() => {
184
- vm._loadUploadOptions();
185
- });
162
+ }
186
163
  }
187
- });
164
+ await this.$nextTick();
165
+ this._loadUploadOptions();
166
+ } else {
167
+ this.fileList = [];
168
+ await this.$nextTick();
169
+ this._loadUploadOptions();
170
+ }
188
171
  },
189
172
  _loadUploadOptions() {
190
173
  // 上传限制为空才执行加载,避免多次重复加载
191
- if (Object.keys(this.uploadOptions).length === 0) {
174
+ if (Object.keys(this.uploadLimit).length === 0) {
192
175
  this.errors = null;
193
176
  let vm = this;
194
- vm.tnx.fss.loadUploadOptions(this.type, {
195
- app: vm.app,
196
- error: function (errors) {
197
- vm.errors = errors;
198
- }
199
- }).then(uploadOptions => {
177
+ this.tnx.fss.getUploadLimit(this.type).then(uploadLimit => {
200
178
  if (vm.extension) {
201
179
  let extensions = Array.isArray(vm.extension) ? vm.extension : [vm.extension];
202
180
  let acceptedExtensions = [];
203
- if (uploadOptions.extensionsRejected) { // 服务端上传限制扩展名为排除模式
181
+ if (uploadLimit.extensionsRejected) { // 服务端上传限制扩展名为排除模式
204
182
  for (let extension of extensions) {
205
- if (!uploadOptions.extensions.contains(extension)) { // 取未被排除的
183
+ if (!uploadLimit.extensions.contains(extension)) { // 取未被排除的
206
184
  acceptedExtensions.push(extension);
207
185
  }
208
186
  }
209
187
  } else { // 服务端上传限制扩展名为包含模式
210
- if (uploadOptions.extensions.length) {
188
+ if (uploadLimit.extensions.length) {
211
189
  for (let extension of extensions) {
212
- if (uploadOptions.extensions.contains(extension)) { // 取被包含的
190
+ if (uploadLimit.extensions.contains(extension)) { // 取被包含的
213
191
  acceptedExtensions.push(extension);
214
192
  }
215
193
  }
@@ -220,11 +198,11 @@ export default {
220
198
  }
221
199
  }
222
200
  if (acceptedExtensions.length) { // 接受的扩展名清单不为空,则替代服务端配置中的扩展名限制
223
- uploadOptions.extensionsRejected = false;
224
- uploadOptions.extensions = acceptedExtensions;
201
+ uploadLimit.extensionsRejected = false;
202
+ uploadLimit.extensions = acceptedExtensions;
225
203
  }
226
204
  }
227
- vm.uploadOptions = uploadOptions;
205
+ vm.uploadLimit = uploadLimit;
228
206
  });
229
207
  }
230
208
  },
@@ -236,12 +214,12 @@ export default {
236
214
  },
237
215
  _onSuccess(result, file, fileList) {
238
216
  if (result) {
239
- file.locationUrl = result.locationUrl;
217
+ file.locationUrl = result.storageUrl;
240
218
  file.readUrl = result.readUrl;
241
- file.downloadUrl = result.downloadUrl;
219
+ file.downloadUrl = result.readUrl;
242
220
  // 构建Upload组件用到的文件字段
243
221
  file.url = result.readUrl;
244
- file.previewUrl = this.tnx.fss.getClientConfig().baseUrl + result.downloadUrl;
222
+ file.previewUrl = result.readUrl;
245
223
 
246
224
  this.fileList = fileList;
247
225
  this.emitInput();
@@ -272,9 +250,6 @@ export default {
272
250
  return;
273
251
  }
274
252
  }
275
- if (this.uploadOptions.number === 1) {
276
- locationUrls = locationUrls[0];
277
- }
278
253
  this.$emit('update:modelValue', locationUrls);
279
254
  },
280
255
  size() {
@@ -283,38 +258,24 @@ export default {
283
258
  /**
284
259
  * 校验上传是否已经全部完成
285
260
  * @param reject 没有完成上传时的处理函数,传入文件对象参数
286
- * @returns 文件存储路径或其数组,有上传未完成时返回false
287
261
  */
288
262
  validateUploaded(reject) {
289
- if (this.uploadOptions.number > 1) {
290
- const locationUrls = [];
291
- for (let file of this.uploadingFiles) {
292
- if (file.locationUrl) {
293
- locationUrls.push(file.locationUrl);
294
- } else {
295
- this._doValidateUploadedReject(reject, file);
296
- return false;
297
- }
298
- }
299
- return locationUrls;
300
- } else if (this.uploadingFiles.length) {
301
- let file = this.uploadingFiles[0];
302
- if (file) {
303
- if (file.locationUrl) {
304
- return file.locationUrl;
305
- } else {
306
- this._doValidateUploadedReject(reject, file);
307
- return false;
308
- }
263
+ const locationUrls = [];
264
+ for (let file of this.uploadingFiles) {
265
+ if (file.locationUrl) {
266
+ locationUrls.push(file.locationUrl);
267
+ } else {
268
+ this._doValidateUploadedReject(reject, file);
269
+ return false;
309
270
  }
310
271
  }
311
- return null;
272
+ return locationUrls;
312
273
  },
313
274
  _doValidateUploadedReject(reject, file) {
314
275
  if (typeof reject === 'function') {
315
276
  reject(file);
316
277
  } else {
317
- this.tnx.alert('文件"' + file.name + '"还未上传完毕,请稍候').then(() => {
278
+ this.tnx.alert('文件"' + file.name + '"还未上传完毕,请稍候', {title: '提示'}).then(() => {
318
279
  if (reject && typeof reject.disable === 'function') {
319
280
  reject.disable(false);
320
281
  }
@@ -1,31 +1,32 @@
1
1
  <template>
2
- <div class="tnxel-fss-view">
3
- <template v-if="readUrl">
4
- <span class="text-muted" v-if="denied">没有权限查看该文件</span>
5
- <template v-else-if="thumbnailIconValue">
6
- <tnxel-button type="primary" link :icon="thumbnailIconValue" :title="$attrs.title || meta.name"
7
- @click="toPreview"/>
8
- <el-image-viewer :url-list="[previewUrl]" teleported @close="imagePreviewing = false"
9
- v-if="imagePreviewing"/>
10
- </template>
11
- <el-image :src="thumbnailReadUrl" :preview-src-list="previewUrl ? [previewUrl] : undefined" fit="contain"
12
- preview-teleported :style="{width: imageWidth, height: imageHeight}" v-else-if="imageable && thumbnail">
13
- <template #error>
14
- <div class="text-muted h-100 flex-center">
15
- <i class="el-icon-picture-outline"/>
16
- </div>
17
- </template>
18
- </el-image>
19
- <template v-else>
20
- <a class="overflow-ellipsis" :href="downloadUrl" target="_blank" :title="'下载 ' + meta.name">
21
- {{ meta.name }}
22
- </a>
23
- <a class="preview" :href="previewUrl" target="_blank" :title="'预览 ' + meta.name"
24
- v-if="previewUrl">预览</a>
2
+ <div class="tnxel-fss-view">
3
+ <template v-if="readUrl">
4
+ <span class="text-muted" v-if="denied">没有权限查看该文件</span>
5
+ <template v-else-if="thumbnailIconValue">
6
+ <tnxel-button type="primary" link :icon="thumbnailIconValue" :title="$attrs.title || meta.name"
7
+ @click="toPreview"/>
8
+ <el-image-viewer :url-list="[previewUrl]" teleported @close="imagePreviewing = false"
9
+ v-if="imagePreviewing"/>
10
+ </template>
11
+ <el-image :src="thumbnailReadUrl" :preview-src-list="previewUrl ? [previewUrl] : undefined" fit="contain"
12
+ preview-teleported :style="{width: imageWidth, height: imageHeight}"
13
+ v-else-if="imageable && thumbnail">
14
+ <template #error>
15
+ <div class="text-muted h-100 flex-center">
16
+ <i class="el-icon-picture-outline"/>
17
+ </div>
25
18
  </template>
19
+ </el-image>
20
+ <template v-else>
21
+ <a class="overflow-ellipsis" :href="downloadUrl" target="_blank" :title="'下载 ' + meta.name">
22
+ {{ meta.name }}
23
+ </a>
24
+ <a class="preview" :href="previewUrl" target="_blank" :title="'预览 ' + meta.name"
25
+ v-if="previewUrl">预览</a>
26
26
  </template>
27
- <tnxel-icon class="text-muted" value="Loading" v-else/>
28
- </div>
27
+ </template>
28
+ <tnxel-icon class="text-muted" value="Loading" v-else/>
29
+ </div>
29
30
  </template>
30
31
 
31
32
  <script>
@@ -103,10 +104,7 @@ export default {
103
104
  return height;
104
105
  },
105
106
  downloadUrl() {
106
- let baseUrl = window.tnx.app.rpc.getDefaultBaseUrl();
107
- if (this.app) {
108
- baseUrl = window.tnx.app.rpc.getBaseUrl(this.app);
109
- }
107
+ let baseUrl = window.tnx.api.getBaseUrl(this.app);
110
108
  return baseUrl + this.meta.downloadUrl;
111
109
  },
112
110
  previewUrl() {
@@ -154,7 +152,7 @@ export default {
154
152
  methods: {
155
153
  load() {
156
154
  if (this.loadable) {
157
- let rpc = window.tnx.app.rpc;
155
+ let rpc = window.tnx.api;
158
156
  let fssConfig = window.tnx.fss.getClientConfig(this.app);
159
157
  let vm = this;
160
158
  rpc.get(fssConfig.contextUrl + '/meta', {
@@ -69,6 +69,7 @@
69
69
  <Switch v-else-if="value === 'Switch'"/>
70
70
  <Tools v-else-if="value === 'Tools'"/>
71
71
  <Top v-else-if="value === 'Top'"/>
72
+ <Upload v-else-if="value === 'Upload'"/>
72
73
  <User v-else-if="value === 'User'"/>
73
74
  <UserFilled v-else-if="value === 'UserFilled'"/>
74
75
  <View v-else-if="value === 'View'"/>
@@ -148,6 +149,7 @@ import {
148
149
  Switch,
149
150
  Tools,
150
151
  Top,
152
+ Upload,
151
153
  User,
152
154
  UserFilled,
153
155
  View,
@@ -225,6 +227,7 @@ const components = {
225
227
  Switch,
226
228
  Tools,
227
229
  Top,
230
+ Upload,
228
231
  User,
229
232
  UserFilled,
230
233
  View,
@@ -12,7 +12,7 @@
12
12
  </template>
13
13
 
14
14
  <script>
15
- import {ObjectUtil} from '@truenewx/tnxcore/src/tnxcore-util';
15
+ import {util} from '../tnxel.ts';
16
16
  import Button from '../button/Button.vue';
17
17
 
18
18
  export default {
@@ -119,8 +119,8 @@ export default {
119
119
  return;
120
120
  }
121
121
  } else {
122
- ObjectUtil.clear(this.params, ['pageSize', 'pageNo', 'ignoring', 'orderBy']);
123
- if (ObjectUtil.isNotNull(this.params.pageNo)) {
122
+ util.object.clear(this.params, ['pageSize', 'pageNo', 'ignoring', 'orderBy']);
123
+ if (util.object.isNotNull(this.params.pageNo)) {
124
124
  this.params.pageNo = 1;
125
125
  }
126
126
  }
@@ -1,20 +1,20 @@
1
1
  <template>
2
2
  <div class="tnxel-query-table" :id="id" :class="{selectable: selectable}">
3
3
  <el-table ref="table" :data="records" scrollbar-always-on
4
- :size="size" :border="border" :stripe="stripe" :max-height="tableMaxHeight"
5
- @sort-change="sort" :default-sort="defaultSort" :key="tableKey"
6
- :default-expand-all="defaultExpandAll" :span-method="spanMethod"
7
- :row-class-name="rowClassName" @cell-click="selectRow" v-loading="records === null">
4
+ :size="size" :border="border" :stripe="stripe" :max-height="tableMaxHeight"
5
+ @sort-change="sort" :default-sort="defaultSort" :key="tableKey"
6
+ :default-expand-all="defaultExpandAll" :span-method="spanMethod"
7
+ :row-class-name="rowClassName" @cell-click="selectRow" v-loading="records === null">
8
8
  <el-table-column header-align="center" align="center" :width="selectable === 'all' ? 40 : 54"
9
- v-if="selectable">
9
+ v-if="selectable">
10
10
  <template #header>
11
11
  <el-checkbox :model-value="pageAllSelected" :indeterminate="allSelectedIndeterminate"
12
- @change="selectAll" v-if="selectable === 'all'"/>
12
+ @change="selectAll" v-if="selectable === 'all'"/>
13
13
  <span v-else>选择</span>
14
14
  </template>
15
15
  <template #default="scope">
16
16
  <el-checkbox v-model="pageSelectedIndexes[scope.$index]" @change="selectPageToAll"
17
- v-if="selectable === 'multi' || selectable === 'all'"/>
17
+ v-if="selectable === 'multi' || selectable === 'all'"/>
18
18
  </template>
19
19
  </el-table-column>
20
20
  <slot></slot>
@@ -30,10 +30,10 @@
30
30
  </template>
31
31
  <template #append v-if="records && records.length && paged && typeof paged.total !== 'number'">
32
32
  <tnxel-button class="py-0 px-1 mx-2 border-0" icon="Top" tooltip="回到顶部" plain
33
- @click="scrollToTop"/>
33
+ @click="scrollToTop"/>
34
34
  <tnxel-icon class="text-secondary" value="Loading" :size="18" v-if="querying"/>
35
35
  <el-button type="primary" link class="m-0" @click="onPagedChange(paged.pageNo + 1)"
36
- v-else-if="paged.morePage">
36
+ v-else-if="paged.morePage">
37
37
  加载更多
38
38
  </el-button>
39
39
  <el-button type="info" link v-else>已没有更多</el-button>
@@ -41,9 +41,9 @@
41
41
  </template>
42
42
  </el-table>
43
43
  <slot name="paged" :paged="paged" :show="showPaged" :query="query"
44
- v-if="params.pageSize > 0 && paged && typeof paged.total === 'number'">
44
+ v-if="params.pageSize > 0 && paged && typeof paged.total === 'number'">
45
45
  <tnxel-paged :value="paged" :change="onPagedChange" :align="pagedAlign"
46
- :page-sizes="pagedSizes" :layout="pagedLayout" v-if="showPaged"/>
46
+ :page-sizes="pagedSizes" :layout="pagedLayout" v-if="showPaged"/>
47
47
  </slot>
48
48
  </div>
49
49
  </template>
@@ -274,7 +274,7 @@ export default {
274
274
  this.records = null;
275
275
  this.paged = null;
276
276
  }
277
- window.tnx.app.rpc.get(this.url, this.params).then(result => {
277
+ window.tnx.api.get(this.url, this.params).then(result => {
278
278
  this.querying = false;
279
279
  if (Array.isArray(result)) {
280
280
  this.records = this.format(result);
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <el-cascader v-model="model" class="ignore-feedback" :options="region.subs" :props="options"
3
- :placeholder="placeholder" :disabled="disabled" :clearable="empty"/>
2
+ <el-cascader v-model="model" class="ignore-feedback" :options="region.subs" :props="options"
3
+ :placeholder="placeholder" :disabled="disabled" :clearable="empty"/>
4
4
  </template>
5
5
 
6
6
  <script>
@@ -60,7 +60,7 @@ export default {
60
60
  }
61
61
  },
62
62
  created() {
63
- window.tnx.app.rpc.loadRegion(this.scope, parseInt(this.maxLevel), {
63
+ window.tnx.meta.loadRegion(this.scope, parseInt(this.maxLevel), {
64
64
  app: this.app,
65
65
  }).then((region) => {
66
66
  this.region = region;