tianheng-ui 0.0.78 → 0.0.80

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.
@@ -0,0 +1,359 @@
1
+ <template>
2
+ <div>
3
+ <!-- 搜索栏 -->
4
+ <search
5
+ v-if="searchConfig.show"
6
+ :data="searchData"
7
+ :options="searchConfig.options"
8
+ @on-search="handleSearchSubmit"
9
+ @on-reset="handleSearchReset"
10
+ />
11
+
12
+ <!-- 菜单栏 -->
13
+ <tools
14
+ v-if="toolsConfig.show"
15
+ :options="toolsConfig.options"
16
+ :disabled="{
17
+ batchDelete: tableSelectionData.length === 0,
18
+ export: tableSelectionData.length === 0
19
+ }"
20
+ @on-click="handleToolsClick"
21
+ />
22
+
23
+ <!-- 表格 -->
24
+ <th-table
25
+ v-if="tableConfig.options.length"
26
+ ref="tableRef"
27
+ :data="tableData"
28
+ :options="tableConfig.options"
29
+ :page-info="tableConfig.pageInfo.options"
30
+ :show-page="tableConfig.pageInfo.show"
31
+ :loading="tableConfig.loading.show"
32
+ :loading-text="tableConfig.loading.text"
33
+ :empty-text="tableConfig.empty.text"
34
+ select-type="single"
35
+ border
36
+ @selection-change="handleSelectionChange"
37
+ @pagination-change="handlePagingChange"
38
+ >
39
+ <template #action="{scope, option }">
40
+ <th-table-action
41
+ :actions="option.actions"
42
+ @on-click="
43
+ (action, callback) => {
44
+ handleActionClick(
45
+ scope.$index,
46
+ scope.row,
47
+ action,
48
+ callback,
49
+ option
50
+ );
51
+ }
52
+ "
53
+ >
54
+ </th-table-action>
55
+ </template>
56
+ </th-table>
57
+
58
+ <!-- 表单 -->
59
+ <th-dialog
60
+ v-model="dialog.show"
61
+ :title="dialog.action.name"
62
+ :modal-append-to-body="false"
63
+ @on-affirm="handleDialogAffirm"
64
+ @on-close="handleDialogClose"
65
+ >
66
+ <th-form-generate
67
+ v-if="formConfig"
68
+ :data="formConfig"
69
+ :value="dialog.data"
70
+ ref="formGenerate"
71
+ >
72
+ </th-form-generate>
73
+ <!-- <span slot="footer">
74
+ <th-table-tools :options="dialogOptions" @on-click="handleToolsClick" />
75
+ </span> -->
76
+ </th-dialog>
77
+ </div>
78
+ </template>
79
+
80
+ <script>
81
+ import Search from "./custom/items/search";
82
+ import Tools from "./custom/items/tools";
83
+ import { toolsItemConfig, formItemConfig } from "./util/index";
84
+ import * as Axios from "./util/axios";
85
+ export default {
86
+ name: "thTableGenerate",
87
+ components: { Search, Tools },
88
+ props: {
89
+ data: {
90
+ type: Object,
91
+ default: () => {
92
+ return {};
93
+ }
94
+ },
95
+ apiConfig: {
96
+ type: Object,
97
+ default: () => {
98
+ return {};
99
+ }
100
+ }
101
+ },
102
+ data() {
103
+ return {
104
+ tableJson: JSON.parse(JSON.stringify(this.data)),
105
+ network: {},
106
+ axios: null,
107
+ searchConfig: { show: false, options: [] },
108
+ searchData: {},
109
+ toolsConfig: { show: false, options: [] },
110
+ tableConfig: { options: [], pageInfo: {} },
111
+ tableData: [],
112
+ tableSelectionData: [],
113
+ dialog: { show: false, data: {}, action: {} },
114
+ formConfig: null
115
+ };
116
+ },
117
+ watch: {
118
+ data(val) {
119
+ this.tableJson = val;
120
+ this.initConfig();
121
+ },
122
+ tableJson: {
123
+ deep: true,
124
+ handler(val) {
125
+ this.$emit("update:data", val);
126
+ }
127
+ }
128
+ },
129
+ created() {
130
+ this.axios = Axios.init(this.apiConfig);
131
+ },
132
+ mounted() {
133
+ this.initConfig();
134
+ },
135
+ methods: {
136
+ initConfig() {
137
+ // 网络请求
138
+ this.network = this.tableJson.network;
139
+
140
+ // 搜索栏
141
+ this.searchConfig = this.tableJson.search;
142
+ if (this.searchConfig.show) {
143
+ this.searchConfig.options.map(item => {
144
+ this.$set(this.searchData, item.prop, item.defaultValue || "");
145
+ });
146
+ }
147
+
148
+ // table
149
+ for (let i = 0; i < this.tableJson.table.options.length; i++) {
150
+ const element = this.tableJson.table.options[i];
151
+ delete element.type;
152
+ }
153
+ if (this.tableJson.table.sequence) {
154
+ this.tableJson.table.options.unshift({ type: "index", label: "序号" });
155
+ }
156
+ const action = { label: "操作", hide: true, slot: "action", actions: [] };
157
+
158
+ // 按position处理按钮,1:公共区,2:行内区
159
+ for (const key in this.tableJson.tools) {
160
+ if (Object.hasOwnProperty.call(this.tableJson.tools, key)) {
161
+ const element = this.tableJson.tools[key];
162
+ if (!element.show) continue;
163
+ if (key === "batchDelete") {
164
+ this.tableJson.table.options.unshift({
165
+ type: "selection",
166
+ label: ""
167
+ });
168
+ }
169
+ const dic = toolsItemConfig(key, element);
170
+ dic.form = element.form;
171
+ if (element.position === 1) {
172
+ this.toolsConfig.show = true;
173
+ this.toolsConfig.options.push(dic);
174
+ } else if (element.position === 2) {
175
+ action.hide = false;
176
+ action.actions.push(dic);
177
+ }
178
+ }
179
+ }
180
+ action.width = action.actions.length * 60 + 20;
181
+ this.tableJson.table.options.push(action);
182
+
183
+ this.tableConfig = this.tableJson.table;
184
+ this.requestListData();
185
+ },
186
+ requestListData() {
187
+ if (!this.network.mounted) return;
188
+ this.tableConfig.loading.show = true;
189
+ const apiInfo = this.network.mounted;
190
+ const params = {
191
+ current: this.tableConfig.pageInfo.options.currentPage,
192
+ size: this.tableConfig.pageInfo.options.pageSize,
193
+ ...this.searchData
194
+ };
195
+ this.axios({
196
+ url: apiInfo.api,
197
+ method: apiInfo.method,
198
+ data: params
199
+ })
200
+ .then(res => {
201
+ const data = res.data.records;
202
+ this.tableData = data;
203
+ this.tableConfig.loading.show = false;
204
+ this.tableConfig.pageInfo.options.total = Number(res.data.total);
205
+ })
206
+ .catch(err => {
207
+ this.tableConfig.loading.show = false;
208
+ });
209
+ },
210
+ requestAddData(data) {
211
+ if (!this.network.add) return;
212
+ this.dialog.action.loading = true;
213
+ const apiInfo = this.network.add;
214
+ this.axios({
215
+ url: apiInfo.api,
216
+ method: apiInfo.method,
217
+ data
218
+ })
219
+ .then(res => {
220
+ this.dialog.action.loading = false;
221
+ this.requestListData();
222
+ })
223
+ .catch(err => {
224
+ this.dialog.action.loading = false;
225
+ });
226
+ },
227
+ requestEditData(data) {
228
+ if (!this.network.edit) return;
229
+ this.dialog.action.loading = true;
230
+ const apiInfo = this.network.edit;
231
+ this.axios({
232
+ url: apiInfo.api,
233
+ method: apiInfo.method,
234
+ data
235
+ })
236
+ .then(res => {
237
+ this.dialog.action.loading = false;
238
+ this.requestListData();
239
+ })
240
+ .catch(err => {
241
+ this.dialog.action.loading = false;
242
+ });
243
+ },
244
+ requestDeleteData(data, callback) {
245
+ if (!this.network.delete) return;
246
+ this.dialog.action.loading = true;
247
+ const apiInfo = this.network.delete;
248
+ this.axios({
249
+ url: apiInfo.api,
250
+ method: apiInfo.method,
251
+ data
252
+ })
253
+ .then(res => {
254
+ callback(true);
255
+ this.dialog.action.loading = false;
256
+ this.requestListData();
257
+ })
258
+ .catch(err => {
259
+ this.dialog.action.loading = false;
260
+ });
261
+ },
262
+ getFormConfig() {
263
+ setTimeout(() => {
264
+ const form = this.dialog.action.form;
265
+ const config = formItemConfig(form.id);
266
+ this.formConfig = config;
267
+ }, 1000);
268
+ },
269
+ handleSearchSubmit(val) {
270
+ console.log("handleSearchSubmit =>", val);
271
+ this.requestListData();
272
+ },
273
+ handleSearchReset(val) {
274
+ console.log("handleSearchReset =>", val);
275
+ },
276
+ handleToolsClick(action) {
277
+ console.log("handleToolsClick =>", action);
278
+ switch (action.act) {
279
+ case "add":
280
+ this.dialog = { show: true, data: {}, action: action };
281
+ this.getFormConfig();
282
+ break;
283
+ case "batchDelete":
284
+ action.loading = true;
285
+ setTimeout(() => {
286
+ action.loading = false;
287
+ this.tableSelectionData = [];
288
+ this.$refs.tableRef.getTable().clearSelection();
289
+ }, 1000);
290
+ break;
291
+ case "export":
292
+ action.loading = true;
293
+ setTimeout(() => {
294
+ action.loading = false;
295
+ this.tableSelectionData = [];
296
+ this.$refs.tableRef.getTable().clearSelection();
297
+ }, 1000);
298
+ break;
299
+ case "import":
300
+ break;
301
+
302
+ default:
303
+ break;
304
+ }
305
+ },
306
+ handlePagingChange(val) {
307
+ console.log("handlePagingChange =>", val);
308
+ this.requestListData()
309
+ },
310
+ handleSelectionChange(val) {
311
+ console.log("handleSelectionChange =>", val);
312
+ this.tableSelectionData = val;
313
+ },
314
+ handleActionClick(index, item, action, callback) {
315
+ console.log("handleActionClick =>", item, action);
316
+ switch (action.act) {
317
+ case "edit":
318
+ this.dialog = { show: true, data: item, action: action };
319
+ this.getFormConfig();
320
+ break;
321
+ case "detail":
322
+ this.dialog = { show: true, data: item, action: action };
323
+ this.getFormConfig();
324
+ break;
325
+ case "delete":
326
+ this.requestDeleteData({ ids: item.id }, callback);
327
+ break;
328
+
329
+ default:
330
+ break;
331
+ }
332
+ },
333
+ handleDialogAffirm(val) {
334
+ this.$refs.formGenerate.getData().then(data => {
335
+ console.log("handleDialogAffirm =>", data);
336
+ switch (this.dialog.action.act) {
337
+ case "add":
338
+ this.requestAddData(data);
339
+ break;
340
+ case "edit":
341
+ this.dialog.data = Object.assign(this.dialog.data, data);
342
+ this.requestEditData(this.dialog.data);
343
+ break;
344
+
345
+ default:
346
+ break;
347
+ }
348
+ this.formConfig = null;
349
+ this.dialog.show = false;
350
+ });
351
+ },
352
+ handleDialogClose() {
353
+ this.formConfig = null;
354
+ }
355
+ }
356
+ };
357
+ </script>
358
+
359
+ <style lang="scss" scoped></style>
@@ -0,0 +1,86 @@
1
+ import axios from "axios";
2
+ import { Notification } from "element-ui";
3
+
4
+ export const init = baseConfig => {
5
+ // 创建axios实例
6
+ const Axios = axios.create({
7
+ baseURL: baseConfig.baseUrl,
8
+ timeout: baseConfig.timeout || 60000 // 请求超时时间
9
+ // withCredentials: true, //允许携带cookie
10
+ });
11
+
12
+ // 添加请求拦截器
13
+ Axios.interceptors.request.use(
14
+ config => {
15
+ config.headers = baseConfig.headers || {
16
+ "Content-Type": "application/json"
17
+ };
18
+ if (baseConfig.token) config.headers["Authorization"] = baseConfig.token;
19
+ return config;
20
+ },
21
+ error => {
22
+ // Do something with request error
23
+ console.log(error); // for debug
24
+ Promise.reject(error);
25
+ }
26
+ );
27
+
28
+ // 添加响应拦截器
29
+ Axios.interceptors.response.use(
30
+ response => {
31
+ const code = response.status;
32
+ if (code < 200 || code > 300) {
33
+ Notification.error({
34
+ title: response.message
35
+ });
36
+ return Promise.reject("error");
37
+ }
38
+
39
+ const dataCode = response.data.code;
40
+ if (dataCode && dataCode !== 200) {
41
+ Notification.error({
42
+ title: response.data.message
43
+ });
44
+ return Promise.reject("error");
45
+ }
46
+
47
+ if (baseConfig.debugger) {
48
+ console.log("\n");
49
+ console.log("request url =>");
50
+ console.log(response.request.responseURL);
51
+ console.log("request res =>", response);
52
+ console.log("\n");
53
+ }
54
+
55
+ return response.data;
56
+ },
57
+ error => {
58
+ let code = 0;
59
+ try {
60
+ code = error.response.data.status;
61
+ } catch (e) {
62
+ if (error.toString().indexOf("Error: timeout") !== -1) {
63
+ Notification.error({
64
+ title: "网络请求超时",
65
+ duration: 5000
66
+ });
67
+ return Promise.reject(error);
68
+ }
69
+ }
70
+ if (code) {
71
+ const errorMsg = error.response.data.message;
72
+ Notification.error({
73
+ title: errorMsg || "未知错误",
74
+ duration: 5000
75
+ });
76
+ } else {
77
+ Notification.error({
78
+ title: "接口请求失败",
79
+ duration: 5000
80
+ });
81
+ }
82
+ return Promise.reject(error);
83
+ }
84
+ );
85
+ return Axios;
86
+ };
@@ -0,0 +1,198 @@
1
+ const toolsConfig = {
2
+ add: {
3
+ act: "add",
4
+ name: "",
5
+ type: "primary",
6
+ icon: "el-icon-plus",
7
+ disabled: false,
8
+ loading: false
9
+ },
10
+ edit: {
11
+ act: "edit",
12
+ name: "",
13
+ type: "text",
14
+ icon: "el-icon-edit",
15
+ disabled: false,
16
+ loading: false
17
+ },
18
+ detail: {
19
+ act: "detail",
20
+ name: "",
21
+ type: "text",
22
+ icon: "el-icon-view",
23
+ disabled: false,
24
+ loading: false
25
+ },
26
+ delete: {
27
+ act: "delete",
28
+ name: "",
29
+ type: "text",
30
+ icon: "el-icon-delete",
31
+ style: "color:#ff4949;",
32
+ disabled: false,
33
+ loading: false
34
+ },
35
+ batchDelete: {
36
+ act: "batchDelete",
37
+ name: "",
38
+ type: "danger",
39
+ icon: "el-icon-delete",
40
+ disabled: false,
41
+ loading: false
42
+ },
43
+ export: {
44
+ act: "export",
45
+ name: "",
46
+ type: "primary",
47
+ icon: "el-icon-download",
48
+ disabled: false,
49
+ loading: false
50
+ },
51
+ import: {
52
+ act: "import",
53
+ name: "",
54
+ type: "primary",
55
+ icon: "el-icon-upload2",
56
+ disabled: false,
57
+ loading: false
58
+ }
59
+ };
60
+
61
+ export const toolsItemConfig = (key, data) => {
62
+ const config = toolsConfig[key] || {};
63
+ config.name = data.name;
64
+ return { ...config };
65
+ };
66
+
67
+ const formConfig = {
68
+ "1": {
69
+ list: [
70
+ {
71
+ name: "栅格布局",
72
+ type: "grid",
73
+ icon: "icon-grid-",
74
+ columns: [
75
+ {
76
+ span: 12,
77
+ list: [
78
+ {
79
+ name: "分类名称",
80
+ type: "input",
81
+ icon: "icon-input",
82
+ options: {
83
+ width: "100%",
84
+ labelWidth: 100,
85
+ isLabelWidth: false,
86
+ defaultValue: "",
87
+ dataType: "string",
88
+ pattern: "",
89
+ placeholder: "",
90
+ maxlength: -1,
91
+ required: true,
92
+ disabled: false,
93
+ readonly: false,
94
+ clearable: false,
95
+ showWordLimit: false,
96
+ showPassword: false,
97
+ prefixIcon: "",
98
+ suffixIcon: "",
99
+ prepend: "",
100
+ append: "",
101
+ hidden: false,
102
+ hideLabel: false
103
+ },
104
+ events: {
105
+ onChange: "",
106
+ onFocus: "",
107
+ onBlur: ""
108
+ },
109
+ rules: [
110
+ {
111
+ type: "string",
112
+ message: "分类名称格式不正确"
113
+ },
114
+ {
115
+ required: true,
116
+ message: "分类名称必须填写"
117
+ }
118
+ ],
119
+ key: "1669798313000_73831",
120
+ model: "name"
121
+ }
122
+ ]
123
+ },
124
+ {
125
+ span: 12,
126
+ list: [
127
+ {
128
+ name: "排序",
129
+ type: "number",
130
+ icon: "icon-number",
131
+ options: {
132
+ width: "100%",
133
+ labelWidth: 100,
134
+ isLabelWidth: false,
135
+ required: false,
136
+ defaultValue: 0,
137
+ min: 0,
138
+ max: 999,
139
+ step: 1,
140
+ disabled: false,
141
+ controlsPosition: true,
142
+ precision: 0,
143
+ hidden: false,
144
+ hideLabel: false
145
+ },
146
+ events: {
147
+ onChange: "",
148
+ onFocus: "",
149
+ onBlur: ""
150
+ },
151
+ key: "1669798320000_2131",
152
+ model: "sort",
153
+ rules: []
154
+ }
155
+ ]
156
+ }
157
+ ],
158
+ options: {
159
+ gutter: 0,
160
+ justify: "start",
161
+ align: "top",
162
+ hideLabel: true
163
+ },
164
+ key: "1669798312000_50523",
165
+ model: "grid_1669798312000_50523",
166
+ rules: []
167
+ }
168
+ ],
169
+ config: {
170
+ ui: "element",
171
+ title: "",
172
+ width: "",
173
+ labelWidth: 100,
174
+ labelPosition: "right",
175
+ labelSuffix: ":",
176
+ size: "small",
177
+ disabled: false,
178
+ hideLabel: false,
179
+ eventScript: [
180
+ {
181
+ key: "mounted",
182
+ name: "mounted",
183
+ func: ""
184
+ },
185
+ {
186
+ key: "refresh",
187
+ name: "refresh",
188
+ func: ""
189
+ }
190
+ ]
191
+ }
192
+ }
193
+ };
194
+
195
+ export const formItemConfig = key => {
196
+ const config = formConfig[key] || {};
197
+ return config;
198
+ };
@@ -86,7 +86,9 @@
86
86
  v-if="tableConfig.table.pageInfo.show"
87
87
  label="分页条数"
88
88
  >
89
- <el-radio-group v-model="tableConfig.table.pageInfo.pageSize">
89
+ <el-radio-group
90
+ v-model="tableConfig.table.pageInfo.options.pageSize"
91
+ >
90
92
  <el-radio-button :label="20">20条</el-radio-button>
91
93
  <el-radio-button :label="50">50条</el-radio-button>
92
94
  <el-radio-button :label="100">100条</el-radio-button>
@@ -221,24 +223,29 @@ export default {
221
223
  },
222
224
  table: {
223
225
  options: [],
224
- sort: {
225
- type: "1",
226
- key: "createTime"
227
- },
228
226
  pageInfo: {
229
227
  show: true,
230
- pageSize: 20
228
+ options: {
229
+ pageCount: 0, // 总页数
230
+ pageSize: 20, // 每页展示的条数
231
+ currentPage: 1, // 当前页码
232
+ total: 0, // 总条数
233
+ sizes: [10, 20, 30, 50, 100]
234
+ }
231
235
  },
232
- sequence: false //序号
236
+ sort: { type: "1", key: "createTime" },
237
+ loading: { show: false, text: "加载中", image: "" },
238
+ empty: { show: true, text: "暂无数据", image: "" },
239
+ sequence: true //是否显示序号
233
240
  },
234
241
  tools: {
235
- add: { show: true, name: "新增" },
236
- edit: { show: true, name: "编辑" },
237
- detail: { show: false, name: "查看" },
238
- delete: { show: true, name: "删除" },
239
- batchDelete: { show: false, name: "批量删除" },
240
- export: { show: false, name: "导出" },
241
- import: { show: false, name: "导入" }
242
+ add: { show: true, name: "新增", position: 1 },
243
+ edit: { show: true, name: "编辑", position: 2 },
244
+ detail: { show: true, name: "查看", position: 2 },
245
+ delete: { show: true, name: "删除", position: 2 },
246
+ batchDelete: { show: true, name: "批量删除", position: 1 },
247
+ export: { show: true, name: "导出", position: 1 },
248
+ import: { show: true, name: "导入", position: 1 }
242
249
  }
243
250
  },
244
251
  sortFieldOptions: [{ label: "创建时间", value: "createTime" }]
@@ -118,6 +118,7 @@
118
118
  <th-dialog
119
119
  v-model="dialog.visible"
120
120
  :title="dialog.title"
121
+ :modal-append-to-body="false"
121
122
  @on-affirm="handleDialogAffirm"
122
123
  >
123
124
  <th-code-editor v-model="codeEditorValue"></th-code-editor>