@xjw_/vue2-npm-system 1.0.19 → 1.0.21

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 @@
1
+ <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775015498486" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5570" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M291.5 925.2c-22.1 0-40-17.9-40-40V721.6H128.8c-16.6 0-30-13.4-30-30V384.8c0-59.5 48.3-107.8 107.8-107.8h44.9V138.8c0-22.1 17.9-40 40-40h441c22.1 0 40 17.9 40 40V277h44.9c59.5 0 107.8 48.3 107.8 107.8v306.8c0 16.6-13.4 30-30 30H772.5v163.6c0 22.1-17.9 40-40 40h-441z m418.1-62.9v-217H314.4v217h395.2z m152.7-203.6V384.8c0-24.8-20.1-44.9-44.9-44.9H206.6c-24.8 0-44.9 20.1-44.9 44.9v273.9h89.8v-70.3c0-3.3 2.7-6 6-6h509c3.3 0 6 2.7 6 6v70.3h89.8zM709.6 277V161.7H314.4V277h395.2zM283 467.1c-17.3 0-31.4-14.1-31.4-31.4s14.1-31.4 31.4-31.4h229c17.3 0 31.4 14.1 31.4 31.4s-14.1 31.4-31.4 31.4H283z" p-id="5571"></path></svg>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775015534186" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7365" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 96a15.36 15.36 0 0 1 11.328 4.672l203.648 203.648a16 16 0 0 1 2.56 19.2l-2.56 3.456-45.248 45.248a16 16 0 0 1-19.2 2.56l-3.456-2.56L560 273.216l0.064 446.784a16 16 0 0 1-16 16h-64a16 16 0 0 1-16-16V273.28L364.864 372.224a16 16 0 0 1-22.656 0l-45.248-45.248a16 16 0 0 1 0-22.656l203.648-203.648A16.64 16.64 0 0 1 512 96z" p-id="7366"></path><path d="M142.656 544H72.64l-2.688 0.256a7.488 7.488 0 0 0-5.504 4.416L64 550.976v333.056l0.384 5.952a43.456 43.456 0 0 0 36.416 37.504l6.4 0.512H916.48l5.888-0.32a43.328 43.328 0 0 0 37.376-36.672l0.448-6.528 0.064-332.608L960 549.376a7.232 7.232 0 0 0-4.928-4.928l-2.56-0.384L882.56 544l-2.752 0.256a7.488 7.488 0 0 0-5.44 4.416l-0.448 2.304v282.432l-8.32 7.552H158.656l-8.32-7.552v-281.6l-0.192-2.432a7.232 7.232 0 0 0-4.928-4.928l-2.56-0.384z" p-id="7367"></path></svg>
@@ -0,0 +1,102 @@
1
+ <template>
2
+ <div class="x-pagination">
3
+ <el-pagination
4
+ :current-page="internalCurrentPage"
5
+ :page-size="internalPageSize"
6
+ :total="xTotal"
7
+ :page-sizes="xPageSizes"
8
+ :layout="pagerLayout"
9
+ @current-change="handleCurrentChange"
10
+ @size-change="handleSizeChange"
11
+ />
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ export default {
17
+ name: 'XPagination',
18
+ props: {
19
+ // 当前页码
20
+ xCurrentPage: {
21
+ type: Number,
22
+ default: 1
23
+ },
24
+ // 每页条数
25
+ xPageSize: {
26
+ type: Number,
27
+ default: 20
28
+ },
29
+ // 总条数
30
+ xTotal: {
31
+ type: Number,
32
+ default: 0
33
+ },
34
+ // 分页大小选项
35
+ xPageSizes: {
36
+ type: Array,
37
+ default: () =>[20,50,100,200,500,1000]
38
+ },
39
+ // 分页布局配置
40
+ xLayouts: {
41
+ type: Array,
42
+ default: () => ['total', 'sizes', 'prev', 'pager', 'next', 'jumper']
43
+ }
44
+ },
45
+ data() {
46
+ return {
47
+ internalCurrentPage: this.xCurrentPage,
48
+ internalPageSize: this.xPageSize
49
+ }
50
+ },
51
+ computed: {
52
+ // 将数组布局配置转换为 el-pagination 的 layout 字符串
53
+ pagerLayout() {
54
+ if (!this.xLayouts || !Array.isArray(this.xLayouts)) {
55
+ return 'total, sizes, prev, pager, next, jumper'
56
+ }
57
+ // 将大写的布局名称转换为小写
58
+ return this.xLayouts.map(item => {
59
+ if (typeof item === 'string') {
60
+ return item.toLowerCase()
61
+ }
62
+ return item
63
+ }).join(', ')
64
+ }
65
+ },
66
+ watch: {
67
+ xCurrentPage(val) {
68
+ this.internalCurrentPage = val
69
+ },
70
+ xPageSize(val) {
71
+ this.internalPageSize = val
72
+ }
73
+ },
74
+ methods: {
75
+ // 页码改变
76
+ handleCurrentChange(page) {
77
+ this.internalCurrentPage = page
78
+ this.$emit('update-page', this.internalCurrentPage, this.internalPageSize)
79
+ },
80
+
81
+ // 每页条数改变
82
+ handleSizeChange(size) {
83
+ this.internalPageSize = size
84
+ this.internalCurrentPage = 1
85
+ this.$emit('update-page',this.internalCurrentPage,this.internalPageSize)
86
+ }
87
+ }
88
+ }
89
+ </script>
90
+
91
+ <style lang="scss" scoped>
92
+ ::v-deep {
93
+ .el-pagination {
94
+ display: flex;
95
+ align-items: center;
96
+ height: 44px;
97
+ border: 1px solid #EAEFFE;
98
+ justify-content: flex-end;
99
+ padding: 0 16px 0 0;
100
+ }
101
+ }
102
+ </style>
@@ -0,0 +1,378 @@
1
+ <template>
2
+ <div class="x-report-table">
3
+ <!-- 报表标题和操作按钮 -->
4
+ <div class="report-header">
5
+ <h2 class="report-title">{{ xReportTitle }}</h2>
6
+ <div class="report-actions">
7
+ <div class="h-align-center h-cursor-pointer" @click="printReport">
8
+ <svg-icon icon-class="print" class-name="h-t-primary svg-icon-22" ></svg-icon ><span class="h-ml-8">打印</span>
9
+ </div>
10
+ <div class="h-align-center h-cursor-pointer" @click="handleExport">
11
+ <svg-icon icon-class="upload" class-name="h-t-primary svg-icon-22" ></svg-icon><span class="h-ml-8">导出</span>
12
+ </div>
13
+ </div>
14
+ </div>
15
+
16
+ <!-- 页头信息 -->
17
+ <div class="x-t-4-14-22 h-pb-12" ref="reportHeader">
18
+ <div class="h-flex h-justify-between">
19
+ <div v-if="xOrganizationName">
20
+ <span class="">制表单位:</span>
21
+ <span class="">{{ xOrganizationName }}</span>
22
+ </div>
23
+ <div v-if="xDateRange">
24
+ <span class="">日期范围:</span>
25
+ <span class="">{{ xDateRange }}</span>
26
+ </div>
27
+ <div v-if="xCustomHeader1">
28
+ <span class="">{{ xCustomHeader1Label }}:</span>
29
+ <span class="">{{ xCustomHeader1 }}</span>
30
+ </div>
31
+ <div>
32
+ <span class="">{{ xCustomHeader2Label }}{{xCustomHeader2Label ? ':':''}}</span>
33
+ <span class="">{{ xCustomHeader2 }}</span>
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ <!-- 表格主体 -->
39
+ <div class="report-body">
40
+ <x-vxe-table
41
+ ref="vxeTable"
42
+ :x-sub-height="xSubHeight"
43
+ :x-show-toolbar="xShowToolbar"
44
+ :x-show-pagination="xShowPagination"
45
+ :data="xData"
46
+ :x-is-show-bg="false"
47
+ :x-page-size="xPageSize"
48
+ :x-current-page="xCurrentPage"
49
+ :x-total="xTotal"
50
+ @change-page="handlePageChange"
51
+ >
52
+ <template #buttons>
53
+ <slot name="buttons"></slot>
54
+ </template>
55
+ <slot></slot>
56
+ </x-vxe-table>
57
+ </div>
58
+
59
+ <!-- 页尾信息 -->
60
+ <div class="x-t-4-14-22 h-pt-12" ref="reportFooter">
61
+ <div class="h-flex h-justify-between">
62
+ <div v-if="xAuditorName">
63
+ <span class="">审核人员:</span>
64
+ <span class="">{{ xAuditorName }}</span>
65
+ </div>
66
+ <div v-if="xCreatorName">
67
+ <span class="">制表人员:</span>
68
+ <span class="">{{ xCreatorName }}</span>
69
+ </div>
70
+ <div v-if="xCustomFooterField">
71
+ <span class="">{{ xCustomFooterFieldLabel }}:</span>
72
+ <span class="">{{ xCustomFooterField }}</span>
73
+ </div>
74
+ <div>
75
+ <span class="">打印日期:</span>
76
+ <span class="">{{ formattedPrintDate }}</span>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </template>
82
+
83
+ <script>
84
+ import XVxeTable from './XVxeTable.vue";
85
+ import SvgIcon from "./SvgIcon.vue";
86
+
87
+ export default {
88
+ name: 'XReportTable',
89
+ components: {SvgIcon, XVxeTable},
90
+ props: {
91
+ // 报表标题
92
+ xReportTitle: {
93
+ type: String,
94
+ default: ''
95
+ },
96
+ // 表格数据
97
+ xData: {
98
+ type: Array,
99
+ default: () => []
100
+ },
101
+ // 制表单位
102
+ xOrganizationName: {
103
+ type: String,
104
+ default: ''
105
+ },
106
+ // 日期范围
107
+ xDateRange: {
108
+ type: String,
109
+ default: ''
110
+ },
111
+ // 自定义页头字段
112
+ xCustomHeader1: {
113
+ type: String,
114
+ default: ''
115
+ },
116
+ xCustomHeader1Label: {
117
+ type: String,
118
+ default: ''
119
+ },
120
+ xCustomHeader2: {
121
+ type: String,
122
+ default: ''
123
+ },
124
+ xCustomHeader2Label: {
125
+ type: String,
126
+ default: ''
127
+ },
128
+ // 审核人员
129
+ xAuditorName: {
130
+ type: String,
131
+ default: ''
132
+ },
133
+ // 制表人员
134
+ xCreatorName: {
135
+ type: String,
136
+ default: ''
137
+ },
138
+ // 自定义页尾字段
139
+ xCustomFooterField: {
140
+ type: String,
141
+ default: ''
142
+ },
143
+ xCustomFooterFieldLabel: {
144
+ type: String,
145
+ default: ''
146
+ },
147
+ // 打印日期
148
+ xPrintDate: {
149
+ type: String,
150
+ default: ''
151
+ },
152
+ // 是否显示打印按钮
153
+ xShowPrint: {
154
+ type: Boolean,
155
+ default: true
156
+ },
157
+ // 是否显示导出按钮
158
+ xShowExport: {
159
+ type: Boolean,
160
+ default: true
161
+ },
162
+ xSubHeight: {
163
+ type: String,
164
+ default: '230px'
165
+ },
166
+ xShowToolbar: {
167
+ type: Boolean,
168
+ default: false
169
+ },
170
+ xShowPagination: {
171
+ type: Boolean,
172
+ default: true
173
+ },
174
+ // 分页大小
175
+ xPageSize: {
176
+ type: Number,
177
+ default: 20
178
+ },
179
+ xTotal: {
180
+ type: Number,
181
+ default: 0
182
+ },
183
+ // 当前页码
184
+ xCurrentPage: {
185
+ type: Number,
186
+ default: 1
187
+ },
188
+ // 是否使用回调打印
189
+ xUsePrintCallback: {
190
+ type: Boolean,
191
+ default: false
192
+ },
193
+ },
194
+ data() {
195
+ return {
196
+ currentDate: new Date()
197
+ }
198
+ },
199
+ computed: {
200
+ // 如果没有传入打印日期,使用当前日期
201
+ formattedPrintDate() {
202
+ if (this.xPrintDate) {
203
+ return this.xPrintDate
204
+ }
205
+ const now = new Date()
206
+ const year = now.getFullYear()
207
+ const month = String(now.getMonth() + 1).padStart(2, '0')
208
+ const day = String(now.getDate()).padStart(2, '0')
209
+ return `${year}-${month}-${day}`
210
+ }
211
+ },
212
+ methods: {
213
+ // 处理分页变化
214
+ handlePageChange(page) {
215
+ this.$emit('change-page', page)
216
+ },
217
+ printReport(){
218
+ if (this.xUsePrintCallback) {
219
+ // 如果启用回调,触发父组件事件
220
+ this.$emit('printReport')
221
+ } else {
222
+ // 否则执行默认打印逻辑
223
+ this.handlePrint()
224
+ }
225
+ },
226
+ // 获取 VXE Table 实例
227
+ getTableInstance() {
228
+ // XVxeTable 组件的 ref 是 vxeTable,需要访问其内部的 VXE Table 实例
229
+ if (this.$refs.vxeTable) {
230
+ return this.$refs.vxeTable.$refs.vxeTable
231
+ }
232
+ return null
233
+ },
234
+
235
+ // 打印
236
+ handlePrint() {
237
+ const tableEl = this.getTableInstance()
238
+ if (!tableEl) {
239
+ console.error('VXE Table instance not found')
240
+ this.$message.error('表格组件未加载完成,请稍后再试')
241
+ return
242
+ }
243
+
244
+ // 获取表头和表尾的真实 DOM 元素
245
+ const headerEl = this.$refs.reportHeader
246
+ const footerEl = this.$refs.reportFooter
247
+
248
+ if (!headerEl || !footerEl) {
249
+ console.error('Report header or footer element not found')
250
+ this.$message.error('报表元素未加载完成,请稍后再试')
251
+ return
252
+ }
253
+
254
+ // 克隆节点并保留样式
255
+ const headerHtml = headerEl.innerHTML
256
+ const footerHtml = footerEl.innerHTML
257
+
258
+ // 调用 VXE Table 打印方法
259
+ if (typeof tableEl.print === 'function') {
260
+ tableEl.print({
261
+ sheetName: this.xReportTitle || '报表',
262
+ style: `
263
+ table td, table th {
264
+ border: 1px solid #000!important;
265
+ }
266
+ .table-head{
267
+ text-align: center;
268
+ font-size: 20px;
269
+ line-height: 40px;
270
+ font-weight: bold;
271
+ }
272
+ .table-head-2{
273
+ width: 33%;
274
+ }
275
+ .table-head-1{
276
+ display: flex;
277
+ line-height: 25px;
278
+ }
279
+ .btn-print{
280
+ text-align: center;
281
+ margin-top: 10px;
282
+ }
283
+ .x-t-4-14-22 {
284
+ font-weight: 400;
285
+ font-size: 14px;
286
+ color: #333333;
287
+ line-height: 22px;
288
+ }
289
+ .h-flex {
290
+ display: flex;
291
+ }
292
+ .h-justify-between {
293
+ justify-content: space-between;
294
+ }
295
+ .h-pb-12 {
296
+ padding-bottom: 12px;
297
+ }
298
+ .h-pt-12 {
299
+ padding-top: 12px;
300
+ }`,
301
+ beforePrintMethod: ({ content }) => {
302
+ // 拦截打印之前,返回自定义的 html 内容
303
+ if (this.xReportTitle) {
304
+ return `<div class="table-head">${this.xReportTitle}</div>` + headerHtml + content + footerHtml
305
+ }
306
+ return headerHtml + content + footerHtml
307
+ }
308
+ })
309
+ } else {
310
+ console.error('VXE Table print method not found')
311
+ this.$message.error('打印功能暂不可用')
312
+ }
313
+ },
314
+
315
+ // 导出
316
+ handleExport() {
317
+ this.$emit('export')
318
+ // 可以在这里实现导出逻辑
319
+ },
320
+
321
+ // 清除复选
322
+ clearCheckbox() {
323
+ this.$refs.vxeTable.clearCheckbox()
324
+ },
325
+
326
+ // 清除排序
327
+ clearSort() {
328
+ this.$refs.vxeTable.clearSort()
329
+ }
330
+ }
331
+ }
332
+ </script>
333
+ <style lang="scss" scoped>
334
+ .x-report-table {
335
+ background: #FFFFFF;
336
+ box-shadow: 0px 0px 6px 0px rgba(0,0,0,0.1);
337
+ border-radius: 4px;
338
+ backdrop-filter: blur(2px);
339
+ padding: 20px;
340
+
341
+ .report-header {
342
+ display: flex;
343
+ justify-content: space-between;
344
+ align-items: center;
345
+ padding-bottom: 12px;
346
+
347
+ .report-title {
348
+ margin: 0;
349
+ font-size: 20px;
350
+ font-weight: bold;
351
+ color: #303133;
352
+ text-align: center;
353
+ flex: 1;
354
+ }
355
+
356
+ .report-actions {
357
+ display: flex;
358
+ gap: 20px;
359
+ font-weight: 400;
360
+ font-size: 14px;
361
+ color: #333333;
362
+ line-height: 22px;
363
+ }
364
+ }
365
+ }
366
+ .x-t-4-14-22 {
367
+ font-weight: 400;
368
+ font-size: 14px;
369
+ color: #333333;
370
+ line-height: 22px;
371
+ }
372
+ .table-head {
373
+ text-align: center;
374
+ font-size: 20px;
375
+ line-height: 40px;
376
+ font-weight: bold;
377
+ }
378
+ </style>
@@ -34,9 +34,9 @@
34
34
  </div>
35
35
  <div class="search-form" v-show="showMore">
36
36
  <div class="h-plr-16 h-pt-16 h-pb-16 h-flex">
37
- <!-- <el-form :rules="rules" :model="queryForm" ref="queryForm" inline label-position="top" label-suffix=":" hide-required-asterisk show-message>
38
- </el-form>-->
39
- <slot name="form"></slot>
37
+ <el-form :rules="rules" :model="queryForm" ref="queryForm" inline label-position="top" label-suffix=":" show-message>
38
+ <slot name="form"></slot>
39
+ </el-form>
40
40
  </div>
41
41
  </div>
42
42
  </div>
@@ -63,6 +63,18 @@ export default {
63
63
  placeholder: {
64
64
  type: String,
65
65
  default: '可输入户号/户名/联系电话'
66
+ },
67
+ queryForm: {
68
+ type: Object,
69
+ default: () => {
70
+ return {}
71
+ }
72
+ },
73
+ rules: {
74
+ type: Object,
75
+ default: () => {
76
+ return {}
77
+ }
66
78
  }
67
79
  },
68
80
  data() {
@@ -84,12 +96,41 @@ export default {
84
96
  },
85
97
  methods: {
86
98
  reset() {
99
+ // 重置搜索值
100
+ this.combinedQueries = ''
101
+ this.$emit('input', '')
102
+
103
+ // 重置表单验证状态和值
104
+ if (this.$refs.queryForm) {
105
+ this.$refs.queryForm.resetFields()
106
+ }
107
+
108
+ // 收起更多筛选
109
+ this.showMore = false
110
+
111
+ // 仍然触发事件,让父组件知道发生了重置(可选)
87
112
  this.$emit('data-reset')
88
113
  },
89
114
  // 查询
90
115
  searchParentList() {
91
- this.showMore = false
92
- this.$emit('data-update')
116
+ // 如果有表单验证,先校验
117
+ if (this.queryForm && this.rules && Object.keys(this.rules).length > 0) {
118
+ return new Promise((resolve, reject) => {
119
+ this.$refs.queryForm.validate((valid) => {
120
+ if (valid) {
121
+ this.showMore = false
122
+ this.$emit('data-update')
123
+ resolve(true)
124
+ } else {
125
+ reject(false)
126
+ }
127
+ })
128
+ })
129
+ } else {
130
+ // 没有表单验证,直接执行
131
+ this.showMore = false
132
+ this.$emit('data-update')
133
+ }
93
134
  }
94
135
  }
95
136
  }
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div class="x-vxe-pager">
3
+ <el-pagination
4
+ :current-page="internalCurrentPage"
5
+ :page-size="internalPageSize"
6
+ :total="xTotal"
7
+ :page-sizes="xPageSizes"
8
+ :layout="pagerLayout"
9
+ @current-change="handleCurrentChange"
10
+ @size-change="handleSizeChange"
11
+ v-on="$listeners"
12
+ />
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ export default {
18
+ name: 'XVxePager',
19
+ props: {
20
+ // 代理配置(用于服务端加载)
21
+ xProxyConfig: {
22
+ type: Object,
23
+ default: null
24
+ },
25
+ // 当前页码
26
+ xCurrentPage: {
27
+ type: Number,
28
+ default: 1
29
+ },
30
+ // 每页条数
31
+ xPageSize: {
32
+ type: Number,
33
+ default: 20
34
+ },
35
+ // 总条数
36
+ xTotal: {
37
+ type: Number,
38
+ default: 0
39
+ },
40
+ // 分页大小选项
41
+ xPageSizes: {
42
+ type: Array,
43
+ default: () => [10, 20, 50, 100]
44
+ },
45
+ // 分页布局配置
46
+ xLayouts: {
47
+ type: Array,
48
+ default: () => ['Total', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'Home']
49
+ },
50
+ // 尺寸:large、medium、small、mini
51
+ xSize: {
52
+ type: String,
53
+ default: 'medium'
54
+ },
55
+ // 是否显示加载中
56
+ xLoading: {
57
+ type: Boolean,
58
+ default: false
59
+ }
60
+ },
61
+ data() {
62
+ return {
63
+ internalCurrentPage: this.xCurrentPage,
64
+ internalPageSize: this.xPageSize
65
+ }
66
+ },
67
+ computed: {
68
+ // 将数组布局配置转换为 el-pagination 的 layout 字符串
69
+ pagerLayout() {
70
+ if (Array.isArray(this.xLayouts)) {
71
+ return this.xLayouts.join(', ')
72
+ }
73
+ return this.xLayouts || 'total, sizes, prev, pager, next, jumper'
74
+ }
75
+ },
76
+ watch: {
77
+ xCurrentPage(val) {
78
+ this.internalCurrentPage = val
79
+ },
80
+ xPageSize(val) {
81
+ this.internalPageSize = val
82
+ }
83
+ },
84
+ methods: {
85
+ // 页码改变
86
+ handleCurrentChange(page) {
87
+ this.internalCurrentPage = page
88
+ this.$emit('update-page', this.internalCurrentPage, this.internalPageSize)
89
+ },
90
+
91
+ // 每页条数改变
92
+ handleSizeChange(size) {
93
+ this.internalPageSize = size
94
+ this.internalCurrentPage = 1
95
+ this.$emit('update-page',this.internalCurrentPage,this.internalPageSize)
96
+ }
97
+ }
98
+ }
99
+ </script>
100
+
101
+ <style lang="scss" scoped>
102
+
103
+ </style>