jufubao-base 1.0.381 → 1.0.382-beta5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jufubao-base",
3
- "version": "1.0.381",
3
+ "version": "1.0.382-beta5",
4
4
  "private": false,
5
5
  "description": "聚福宝业务组件基础插件包",
6
6
  "main": "index.js",
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+ /**
3
+ * @description 接口配置,
4
+ * 在设置方法名字当时候,别忘记加上【模块名字】:Feed
5
+ * @type {*[]}
6
+ */
7
+ module.exports = [
8
+ {
9
+ //设置方法名字当别忘记加上【模块名字】:Feed
10
+ mapFnName: 'getFeedByIdFilmSquate',
11
+ title: '获取电影广场列表',
12
+ path: '/api/account/film/list-film-square',
13
+ isRule: false,
14
+ params: {
15
+ last_key: ['当前页', 'Number', '必选'],
16
+ page_size: ['每页数量', 'Number', '必选'],
17
+ },
18
+ isConsole: true,
19
+ disabled: true,
20
+ },
21
+
22
+ ];
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @description 当表单组件中有联动操作时候,使用方法进行返回
5
+ */
6
+ export default {
7
+ style: [],
8
+ content: (data) => {
9
+ return [
10
+ {
11
+ label: '背景颜色:',
12
+ ele: 'xd-color',
13
+ valueKey: 'bgColor',
14
+ value: data.bgColor || '',
15
+ placeholder: '请输入占位框背景颜色',
16
+ groupKey:'content',
17
+ },
18
+ ].filter(i=>i)
19
+ },
20
+ advanced: [],
21
+ };
@@ -0,0 +1,474 @@
1
+ <template>
2
+ <view
3
+ class="jfb-base-feed-back"
4
+ @click="handleEditxSelect"
5
+ :class="{ editx : isEditx && active }"
6
+ >
7
+ <!--#ifdef H5-->
8
+ <view
9
+ class="jfb-base-feed-back__edit"
10
+ :class="{ editx : isEditx && active }"
11
+ v-if="isEditx && active"
12
+ >
13
+ <view class="jfb-base-feed-back__edit-icon" @click="delEdit">删除</view>
14
+ </view>
15
+ <!-- #endif -->
16
+ <view class="jfb-base-feed-back__body">
17
+ <!-- 反馈类型 -->
18
+ <view class="jfb-feed-back__section">
19
+ <view class="jfb-feed-back__section-title">反馈类型</view>
20
+ <view class="jfb-feed-back__types">
21
+ <view
22
+ v-for="type in feedbackTypes"
23
+ :key="type.value"
24
+ class="jfb-feed-back__type-btn"
25
+ :class="{ active: selectedType === type.value }"
26
+ @click="selectedType = type.value"
27
+ >
28
+ {{ type.label }}
29
+ </view>
30
+ </view>
31
+ </view>
32
+
33
+ <!-- 反馈内容 -->
34
+ <view class="jfb-feed-back__section">
35
+ <view class="jfb-feed-back__section-title">反馈内容</view>
36
+ <view class="jfb-feed-back__textarea-wrapper">
37
+ <textarea
38
+ class="jfb-feed-back__textarea"
39
+ v-model="feedbackContent"
40
+ placeholder="请输入至少10个字"
41
+ maxlength="100"
42
+ @input="onContentInput"
43
+ />
44
+ <view class="jfb-feed-back__char-count">{{ feedbackContent.length }}/100</view>
45
+ </view>
46
+ </view>
47
+
48
+ <!-- 上传图片 -->
49
+ <view class="jfb-feed-back__section">
50
+ <view class="jfb-feed-back__section-title">上传图片(选填)</view>
51
+ <view class="jfb-feed-back__upload-area">
52
+ <view class="jfb-feed-back__upload-item" @click="chooseImage">
53
+ <xd-font-icon name="camera" class="jfb-feed-back__upload-icon" />
54
+ <view class="jfb-feed-back__upload-text">添加图片</view>
55
+ </view>
56
+ <view
57
+ v-for="(img, index) in uploadImages"
58
+ :key="index"
59
+ class="jfb-feed-back__upload-preview"
60
+ >
61
+ <image :src="img" class="jfb-feed-back__upload-preview-img" mode="aspectFill" />
62
+ <view class="jfb-feed-back__upload-delete" @click="removeImage(index)">
63
+ <xd-font-icon name="close" class="jfb-feed-back__upload-delete-icon" />
64
+ </view>
65
+ </view>
66
+ </view>
67
+ <view class="jfb-feed-back__upload-tip">最多可上传6张图片,每张不超过5MB</view>
68
+ </view>
69
+
70
+ <!-- 联系方式 -->
71
+ <view class="jfb-feed-back__section">
72
+ <view class="jfb-feed-back__section-title">联系方式(选填)</view>
73
+ <input
74
+ class="jfb-feed-back__contact-input"
75
+ v-model="contactInfo"
76
+ placeholder="手机号/邮箱,方便我们联系您"
77
+ />
78
+ </view>
79
+
80
+ <!-- 匿名反馈 -->
81
+ <view class="jfb-feed-back__section jfb-feed-back__section--no-border">
82
+ <view class="jfb-feed-back__anonymous">
83
+ <view class="jfb-feed-back__anonymous-label">
84
+ <xd-font-icon name="anonymous" class="jfb-feed-back__anonymous-icon" />
85
+ <text>匿名反馈</text>
86
+ </view>
87
+ <switch
88
+ class="jfb-feed-back__anonymous-switch"
89
+ :checked="isAnonymous"
90
+ @change="onAnonymousChange"
91
+ color="#e8272c"
92
+ />
93
+ </view>
94
+ </view>
95
+
96
+ <!-- 底部操作栏 -->
97
+ <view class="jfb-feed-back__footer">
98
+ <view class="jfb-feed-back__footer-btn jfb-feed-back__footer-btn--record" @click="goToFeedbackRecord">
99
+ <xd-font-icon name="clock" class="jfb-feed-back__footer-btn-icon" />
100
+ <text>反馈记录</text>
101
+ </view>
102
+ <view class="jfb-feed-back__footer-btn jfb-feed-back__footer-btn--submit" @click="submitFeedback">
103
+ 提交反馈
104
+ </view>
105
+ </view>
106
+ </view>
107
+ </view>
108
+ </template>
109
+
110
+ <script>
111
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon";
112
+ import { jfbRootExec } from "@/utils/xd.event";
113
+ import JfbBaseFeedBackMixin from "./JfbBaseFeedBackMixin";
114
+ import { getContainerPropsValue } from "@/utils/xd.base";
115
+ import componentsMixins from "@/mixins/componentsMixins";
116
+ import extsMixins from "@/mixins/extsMixins";
117
+ export default {
118
+ name: "JfbBaseFeedBack",
119
+ components: {
120
+ XdFontIcon
121
+ },
122
+ mixins: [
123
+ componentsMixins, extsMixins, JfbBaseFeedBackMixin
124
+ ],
125
+ data() {
126
+ return {
127
+ // 反馈类型
128
+ feedbackTypes: [
129
+ { label: '咨询', value: 'consult' },
130
+ { label: '商品问题', value: 'product' },
131
+ { label: '订单问题', value: 'order' },
132
+ { label: '支付问题', value: 'payment' },
133
+ { label: '配送问题', value: 'delivery' },
134
+ { label: '产品建议', value: 'suggestion' },
135
+ { label: '投诉', value: 'complaint' }
136
+ ],
137
+ selectedType: 'consult',
138
+ feedbackContent: '',
139
+ uploadImages: [],
140
+ contactInfo: '',
141
+ isAnonymous: false,
142
+ }
143
+ },
144
+ watch: {
145
+ container(value, oldValue) {
146
+ if (JSON.stringify(value) === JSON.stringify(oldValue)) return;
147
+ if (this.$configProject['isPreview']) this.init(value)
148
+ },
149
+ },
150
+ created() {
151
+ this.init(this.container);
152
+
153
+ //todo
154
+ },
155
+ methods: {
156
+ onJfbLoad(options) {
157
+
158
+ // jfbRootExec('baiduUserLogin', {
159
+
160
+ // vm: this,// data: {
161
+
162
+ // account: 'gaoshiyong',// password: '123456789',// type: 3,// ...options
163
+
164
+ // }
165
+
166
+ // }).then().catch()
167
+ },
168
+ /**
169
+ * @description 监听事件变化
170
+ * @param container {object} 业务组件对象自己
171
+ */
172
+ init(container) {
173
+
174
+ //this.bgcolor = getContainerPropsValue(container, 'content.bgcolor', '#fff');
175
+
176
+ //this.height = getContainerPropsValue(container, 'content.height', 10);
177
+ },
178
+ onJfbScroll(options) {
179
+ console.log('event.onJfbScroll', options)
180
+ },
181
+ onJfbReachBottom(options) {
182
+ console.log('event.onJfbReachBottom', options)
183
+ },
184
+ onJfbShow(options) {
185
+ console.log('event.onJfbShow', options)
186
+ },
187
+ onJfbHide(options) {
188
+ console.log('event.onJfbHide', options)
189
+ },
190
+ onJfbBack(options) {
191
+ console.log('event.onJfbBack', options)
192
+ },
193
+ onJfbUpdate(...data) {
194
+ console.log('event.onJfbUpdate', data)
195
+ },
196
+ onJfbCustomEvent(options) {
197
+ console.log('event.onJfbReachBottom', options)
198
+ },
199
+ // 内容输入
200
+ onContentInput() {
201
+ // 字数限制已在 maxlength 控制
202
+ },
203
+ // 选择图片
204
+ chooseImage() {
205
+ if (this.uploadImages.length >= 6) {
206
+ uni.showToast({ title: '最多上传6张图片', icon: 'none' });
207
+ return;
208
+ }
209
+ uni.chooseImage({
210
+ count: 6 - this.uploadImages.length,
211
+ sizeType: ['compressed'],
212
+ sourceType: ['album', 'camera'],
213
+ success: (res) => {
214
+ this.uploadImages = this.uploadImages.concat(res.tempFilePaths);
215
+ }
216
+ });
217
+ },
218
+ // 删除图片
219
+ removeImage(index) {
220
+ this.uploadImages.splice(index, 1);
221
+ },
222
+ // 匿名反馈切换
223
+ onAnonymousChange(e) {
224
+ this.isAnonymous = e.detail.value;
225
+ },
226
+ // 提交反馈
227
+ submitFeedback() {
228
+ if (!this.selectedType) {
229
+ uni.showToast({ title: '请选择反馈类型', icon: 'none' });
230
+ return;
231
+ }
232
+ if (this.feedbackContent.length < 10) {
233
+ uni.showToast({ title: '请输入至少10个字', icon: 'none' });
234
+ return;
235
+ }
236
+ // TODO: 调用提交接口
237
+ uni.showToast({ title: '提交成功', icon: 'success' });
238
+ },
239
+ // 跳转反馈记录
240
+ goToFeedbackRecord() {
241
+ // TODO: 跳转到反馈记录页面
242
+ console.log('跳转反馈记录');
243
+ }
244
+ }
245
+ }
246
+
247
+ </script>
248
+
249
+ <style scoped lang="less">
250
+ @import "./JfbBaseFeedBackLess.less";
251
+
252
+ .jfb-base-feed-back {
253
+ &__body{
254
+ background: #f5f5f5;
255
+ min-height: 100vh;
256
+ padding-bottom: env(safe-area-inset-bottom);
257
+ }
258
+ }
259
+
260
+ .jfb-feed-back {
261
+ &__section {
262
+ background: #fff;
263
+ padding: 24rpx 30rpx;
264
+ margin-bottom: 16rpx;
265
+
266
+ &--no-border {
267
+ background: transparent;
268
+ margin-bottom: 0;
269
+ }
270
+ }
271
+
272
+ &__section-title {
273
+ font-size: 30rpx;
274
+ color: #333;
275
+ margin-bottom: 24rpx;
276
+ }
277
+
278
+ // 反馈类型
279
+ &__types {
280
+ display: flex;
281
+ flex-wrap: wrap;
282
+ gap: 16rpx;
283
+ }
284
+
285
+ &__type-btn {
286
+ padding: 16rpx 36rpx;
287
+ border: 2rpx solid #e5e5e5;
288
+ border-radius: 12rpx;
289
+ font-size: 28rpx;
290
+ color: #999;
291
+ background: #fff;
292
+ transition: all 0.2s;
293
+
294
+ &.active {
295
+ background: #e8272c;
296
+ border-color: #e8272c;
297
+ color: #fff;
298
+ }
299
+ }
300
+
301
+ // 反馈内容
302
+ &__textarea-wrapper {
303
+ position: relative;
304
+ border: 2rpx solid #e5e5e5;
305
+ border-radius: 12rpx;
306
+ overflow: hidden;
307
+ }
308
+
309
+ &__textarea {
310
+ width: 100%;
311
+ min-height: 200rpx;
312
+ padding: 24rpx;
313
+ font-size: 28rpx;
314
+ color: #333;
315
+ box-sizing: border-box;
316
+ }
317
+
318
+ &__char-count {
319
+ text-align: right;
320
+ padding: 12rpx 24rpx;
321
+ font-size: 24rpx;
322
+ color: #999;
323
+ }
324
+
325
+ // 上传图片
326
+ &__upload-area {
327
+ display: flex;
328
+ flex-wrap: wrap;
329
+ gap: 16rpx;
330
+ }
331
+
332
+ &__upload-item,
333
+ &__upload-preview {
334
+ width: 160rpx;
335
+ height: 160rpx;
336
+ border-radius: 12rpx;
337
+ display: flex;
338
+ flex-direction: column;
339
+ align-items: center;
340
+ justify-content: center;
341
+ }
342
+
343
+ &__upload-item {
344
+ background: #f5f5f5;
345
+ border: 2rpx dashed #e5e5e5;
346
+ }
347
+
348
+ &__upload-icon {
349
+ font-size: 48rpx;
350
+ color: #999;
351
+ margin-bottom: 8rpx;
352
+ }
353
+
354
+ &__upload-text {
355
+ font-size: 24rpx;
356
+ color: #999;
357
+ }
358
+
359
+ &__upload-preview {
360
+ position: relative;
361
+ }
362
+
363
+ &__upload-preview-img {
364
+ width: 100%;
365
+ height: 100%;
366
+ border-radius: 12rpx;
367
+ }
368
+
369
+ &__upload-delete {
370
+ position: absolute;
371
+ top: -12rpx;
372
+ right: -12rpx;
373
+ width: 36rpx;
374
+ height: 36rpx;
375
+ background: rgba(0, 0, 0, 0.5);
376
+ border-radius: 50%;
377
+ display: flex;
378
+ align-items: center;
379
+ justify-content: center;
380
+ }
381
+
382
+ &__upload-delete-icon {
383
+ font-size: 20rpx;
384
+ color: #fff;
385
+ }
386
+
387
+ &__upload-tip {
388
+ font-size: 24rpx;
389
+ color: #999;
390
+ margin-top: 16rpx;
391
+ }
392
+
393
+ // 联系方式
394
+ &__contact-input {
395
+ width: 100%;
396
+ height: 72rpx;
397
+ padding: 0 24rpx;
398
+ border: 2rpx solid #e5e5e5;
399
+ border-radius: 12rpx;
400
+ font-size: 28rpx;
401
+ color: #333;
402
+ box-sizing: border-box;
403
+ }
404
+
405
+ // 匿名反馈
406
+ &__anonymous {
407
+ display: flex;
408
+ align-items: center;
409
+ justify-content: space-between;
410
+ padding: 24rpx 0;
411
+ }
412
+
413
+ &__anonymous-label {
414
+ display: flex;
415
+ align-items: center;
416
+ font-size: 28rpx;
417
+ color: #333;
418
+ }
419
+
420
+ &__anonymous-icon {
421
+ font-size: 32rpx;
422
+ color: #333;
423
+ margin-right: 12rpx;
424
+ }
425
+
426
+ &__anonymous-switch {
427
+ transform: scale(0.8);
428
+ }
429
+
430
+ // 底部操作栏
431
+ &__footer {
432
+ position: fixed;
433
+ bottom: 0;
434
+ left: 0;
435
+ right: 0;
436
+ background: #fff;
437
+ padding: 20rpx 30rpx;
438
+ padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
439
+ display: flex;
440
+ align-items: center;
441
+ gap: 20rpx;
442
+ box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
443
+ }
444
+
445
+ &__footer-btn {
446
+ display: flex;
447
+ align-items: center;
448
+ justify-content: center;
449
+ height: 80rpx;
450
+ border-radius: 40rpx;
451
+ font-size: 28rpx;
452
+ transition: all 0.2s;
453
+
454
+ &--record {
455
+ flex: 0 0 auto;
456
+ padding: 0 32rpx;
457
+ border: 2rpx solid #e8272c;
458
+ color: #e8272c;
459
+ background: #fff;
460
+ }
461
+
462
+ &--submit {
463
+ flex: 1;
464
+ background: #e8272c;
465
+ color: #fff;
466
+ }
467
+
468
+ &-icon {
469
+ margin-right: 8rpx;
470
+ font-size: 28rpx;
471
+ }
472
+ }
473
+ }
474
+ </style>
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @desc 获取绝对路径完整地址
3
+ * @param @path
4
+ **/
5
+ //例如:https://image.jufubao.cn/20220501010108/image/bg/default_gonghui_bg.png
6
+ @basePath: 'business/';
7
+ @doMain: '//sandbox-img.jufubao.cn/';
8
+
9
+ .getBusinessImageUrl(@path, @size: 'size8') {
10
+ @url: "@{doMain}@{basePath}@{path}?x-oss-process=style/@{size}";
11
+ background-image: url(@url);
12
+ }
13
+
14
+ //start
15
+ .jfb-base-feed-back {
16
+ box-sizing: border-box;
17
+
18
+ &__body{
19
+ position: relative;
20
+ overflow: hidden;
21
+ z-index: 2
22
+ }
23
+
24
+ &.editx,&.editx:hover {
25
+ position: relative;
26
+ min-height: unit(100, rpx);
27
+ z-index: 3;
28
+ &::after {
29
+ border: 2rpx dashed blue;
30
+ content: " ";
31
+ position: absolute;
32
+ top:0;
33
+ left:0;
34
+ bottom:0;
35
+ right:0;
36
+ z-index: 4;
37
+ cursor: pointer;
38
+ }
39
+
40
+ }
41
+
42
+
43
+ &__edit {
44
+ cursor: pointer;
45
+ position: absolute;
46
+ right: unit(0, rpx);
47
+ top: unit(-52, rpx);
48
+ height: unit(50, rpx);
49
+ line-height: unit(50, rpx);
50
+ display: flex;
51
+ justify-content: center;
52
+ align-items: center;
53
+ background: rgba(0, 0, 0, .6);
54
+ border-radius: unit(10, rpx);
55
+ box-shadow: 0 0 10px rbga(0, 0, 0, 0.3);
56
+ color: #fff;
57
+ font-size: unit(22, rpx);
58
+
59
+ &-icon{
60
+ padding: 0 unit(20, rpx);
61
+ }
62
+
63
+ &.editx {
64
+ box-sizing: border-box;
65
+
66
+ }
67
+ }
68
+ }
69
+ //end
70
+
71
+
72
+ /**notPreview**/
73
+ .jfb-base-feed-back {
74
+ //&:before {
75
+ //content: " ";
76
+ //display: table;
77
+ //}
78
+ }
79
+ /**endNotPreview**/
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+
4
+ //@AttrImport
5
+ import Attr from "./Attr";
6
+ //@EndAttrImport
7
+
8
+
9
+ export default {
10
+ data() {
11
+ return {
12
+ //#ifdef H5
13
+
14
+ //@AttrData
15
+ Attr:{}, //对外开发编辑属性
16
+ //@EndAttrData
17
+
18
+ // #endif
19
+ cssRoot: 'jfb-base-feed-back'
20
+ }
21
+ },
22
+ created() {
23
+
24
+ //@AttrDataCreated
25
+ this.Attr = this.$xdUniHelper.customClone(Attr);
26
+ //@EndAttrDataCreated
27
+
28
+
29
+ },
30
+ }
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+
5
+ getFeedByIdFilmSquate:{},
6
+ }
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+ /**
3
+ * @description 接口配置,
4
+ * 在设置方法名字当时候,别忘记加上【模块名字】:Feed
5
+ * @type {*[]}
6
+ */
7
+ module.exports = [
8
+ {
9
+ //设置方法名字当别忘记加上【模块名字】:Feed
10
+ mapFnName: 'getFeedByIdFilmSquate',
11
+ title: '获取电影广场列表',
12
+ path: '/api/account/film/list-film-square',
13
+ isRule: false,
14
+ params: {
15
+ last_key: ['当前页', 'Number', '必选'],
16
+ page_size: ['每页数量', 'Number', '必选'],
17
+ },
18
+ isConsole: true,
19
+ disabled: true,
20
+ },
21
+ ];
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @description 当表单组件中有联动操作时候,使用方法进行返回
5
+ */
6
+ export default {
7
+ style: [],
8
+ content: (data) => {
9
+ return [
10
+ {
11
+ label: '背景颜色:',
12
+ ele: 'xd-color',
13
+ valueKey: 'bgColor',
14
+ value: data.bgColor || '',
15
+ placeholder: '请输入占位框背景颜色',
16
+ groupKey:'content',
17
+ },
18
+ ].filter(i=>i)
19
+ },
20
+ advanced: [],
21
+ };
@@ -0,0 +1,566 @@
1
+ <template>
2
+ <view
3
+ class="jfb-base-feed-back-list"
4
+ @click="handleEditxSelect"
5
+ :class="{ editx : isEditx && active }"
6
+ >
7
+ <!--#ifdef H5-->
8
+ <view
9
+ class="jfb-base-feed-back-list__edit"
10
+ :class="{ editx : isEditx && active }"
11
+ v-if="isEditx && active"
12
+ >
13
+ <view class="jfb-base-feed-back-list__edit-icon" @click="delEdit">删除</view>
14
+ </view>
15
+ <!-- #endif -->
16
+ <view class="jfb-base-feed-back-list__body">
17
+ <view class="jfb-feed-back-list__container">
18
+ <view
19
+ v-for="item in feedbackList"
20
+ :key="item.id"
21
+ class="jfb-feed-back-list__item"
22
+ @click="goToDetail(item)"
23
+ >
24
+ <!-- 顶部:类型 + 状态 -->
25
+ <view class="jfb-feed-back-list__item-header">
26
+ <view
27
+ class="jfb-feed-back-list__type-tag"
28
+ :class="getTypeTagClass(item.type)"
29
+ >
30
+ <xd-font-icon :name="getTypeIcon(item.type)" class="jfb-feed-back-list__type-icon" />
31
+ <text>{{ getTypeLabel(item.type) }}</text>
32
+ </view>
33
+ <view class="jfb-feed-back-list__status">
34
+ <text :class="item.status === 'replied' ? 'text-green' : 'text-orange'">
35
+ {{ item.status === 'replied' ? '已回复' : '待回复' }}
36
+ </text>
37
+ </view>
38
+ </view>
39
+
40
+ <!-- 内容摘要 -->
41
+ <view class="jfb-feed-back-list__content">{{ item.content }}</view>
42
+
43
+ <!-- 图片 -->
44
+ <view class="jfb-feed-back-list__images">
45
+ <view
46
+ v-for="(img, index) in (item.images && item.images.length ? item.images : [null])"
47
+ :key="index"
48
+ class="jfb-feed-back-list__image-wrapper"
49
+ >
50
+ <image
51
+ v-if="img"
52
+ :src="img"
53
+ class="jfb-feed-back-list__image"
54
+ mode="aspectFill"
55
+ />
56
+ <view v-else class="jfb-feed-back-list__image-placeholder">
57
+ <xd-font-icon name="image" class="jfb-feed-back-list__image-placeholder-icon" />
58
+ </view>
59
+ </view>
60
+ </view>
61
+
62
+ <!-- 底部:时间 + 查看详情 -->
63
+ <view class="jfb-feed-back-list__item-footer">
64
+ <text class="jfb-feed-back-list__time">{{ item.createTime }}</text>
65
+ <view class="jfb-feed-back-list__detail-link">
66
+ <text>查看详情</text>
67
+ <xd-font-icon name="arrow-right" class="jfb-feed-back-list__detail-icon" />
68
+ </view>
69
+ </view>
70
+ </view>
71
+
72
+ <!-- 空状态 -->
73
+ <view v-if="!loading && feedbackList.length === 0" class="jfb-feed-back-list__empty">
74
+ <xd-font-icon name="empty" class="jfb-feed-back-list__empty-icon" />
75
+ <text>暂无反馈记录</text>
76
+ </view>
77
+
78
+ <!-- 加载状态 -->
79
+ <view v-if="loading" class="jfb-feed-back-list__loading">
80
+ <text>加载中...</text>
81
+ </view>
82
+ <view v-if="noMore && feedbackList.length > 0" class="jfb-feed-back-list__no-more">
83
+ <text>没有更多了</text>
84
+ </view>
85
+ </view>
86
+ </view>
87
+
88
+ <!-- 反馈详情弹框 -->
89
+ <xd-down-drawer
90
+ :show.sync="showDetailModal"
91
+ :z-index="2000"
92
+ @close="closeDetailModal"
93
+ >
94
+ <!-- 弹框头部 -->
95
+ <view class="jfb-feed-back-list__drawer-header">
96
+ <text class="jfb-feed-back-list__drawer-title">反馈详情</text>
97
+ </view>
98
+
99
+ <!-- 弹框内容 -->
100
+ <view class="jfb-feed-back-list__drawer-body">
101
+ <!-- 反馈类型 + 状态 -->
102
+ <view class="jfb-feed-back-list__drawer-row">
103
+ <view class="jfb-feed-back-list__drawer-label">反馈类型</view>
104
+ <view class="jfb-feed-back-list__drawer-type-row">
105
+ <view
106
+ class="jfb-feed-back-list__type-tag"
107
+ :class="getTypeTagClass(detailItem.type)"
108
+ >
109
+ <xd-font-icon :name="getTypeIcon(detailItem.type)" class="jfb-feed-back-list__type-icon" />
110
+ <text>{{ getTypeLabel(detailItem.type) }}</text>
111
+ </view>
112
+ <text :class="detailItem.status === 'replied' ? 'text-green' : 'text-orange'">
113
+ <xd-font-icon
114
+ :name="detailItem.status === 'replied' ? 'check-circle' : 'clock'"
115
+ class="jfb-feed-back-list__drawer-status-icon"
116
+ />
117
+ {{ detailItem.status === 'replied' ? '已回复' : '待回复' }}
118
+ </text>
119
+ </view>
120
+ </view>
121
+
122
+ <!-- 是否匿名 -->
123
+ <view class="jfb-feed-back-list__drawer-row">
124
+ <view class="jfb-feed-back-list__drawer-label">是否匿名</view>
125
+ <view class="jfb-feed-back-list__drawer-anonymous-tag">
126
+ {{ detailItem.isAnonymous ? '匿名' : detailItem.contactInfo || '未留联系方式' }}
127
+ </view>
128
+ </view>
129
+
130
+ <!-- 反馈时间 -->
131
+ <view class="jfb-feed-back-list__drawer-row">
132
+ <view class="jfb-feed-back-list__drawer-label">反馈时间</view>
133
+ <text class="jfb-feed-back-list__drawer-value">{{ detailItem.createTime }}</text>
134
+ </view>
135
+
136
+ <!-- 反馈内容 -->
137
+ <view class="jfb-feed-back-list__drawer-row">
138
+ <view class="jfb-feed-back-list__drawer-label">反馈内容</view>
139
+ <view class="jfb-feed-back-list__drawer-content-box">
140
+ {{ detailItem.content }}
141
+ </view>
142
+ </view>
143
+
144
+ <!-- 图片 -->
145
+ <view v-if="detailItem.images && detailItem.images.length" class="jfb-feed-back-list__drawer-row">
146
+ <view class="jfb-feed-back-list__drawer-images">
147
+ <image
148
+ v-for="(img, index) in detailItem.images"
149
+ :key="index"
150
+ :src="img"
151
+ class="jfb-feed-back-list__drawer-image"
152
+ mode="aspectFill"
153
+ />
154
+ </view>
155
+ </view>
156
+ </view>
157
+ </xd-down-drawer>
158
+ </view>
159
+ </template>
160
+
161
+ <script>
162
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon";
163
+ import { jfbRootExec } from "@/utils/xd.event";
164
+ import JfbBaseFeedBackListMixin from "./JfbBaseFeedBackListMixin";
165
+ import { getContainerPropsValue } from "@/utils/xd.base";
166
+ import componentsMixins from "@/mixins/componentsMixins";
167
+ import extsMixins from "@/mixins/extsMixins";
168
+ export default {
169
+ name: "JfbBaseFeedBackList",
170
+ components: {
171
+ XdFontIcon
172
+ },
173
+ mixins: [
174
+ componentsMixins, extsMixins, JfbBaseFeedBackListMixin
175
+ ],
176
+ data() {
177
+ return {
178
+ feedbackList: [],
179
+ loading: false,
180
+ noMore: false,
181
+ page: 1,
182
+ pageSize: 10,
183
+ showDetailModal: false,
184
+ detailItem: {},
185
+ typeMap: {
186
+ consult: { label: '咨询', icon: 'message' },
187
+ product: { label: '商品问题', icon: 'product' },
188
+ order: { label: '订单问题', icon: 'order' },
189
+ payment: { label: '支付问题', icon: 'payment' },
190
+ delivery: { label: '配送问题', icon: 'delivery' },
191
+ suggestion: { label: '产品建议', icon: 'suggestion' },
192
+ complaint: { label: '投诉', icon: 'complaint' }
193
+ }
194
+ }
195
+ },
196
+ computed: {
197
+ },
198
+ watch: {
199
+ container(value, oldValue) {
200
+ if (JSON.stringify(value) === JSON.stringify(oldValue)) return;
201
+ if (this.$configProject['isPreview']) this.init(value)
202
+ },
203
+ },
204
+ created() {
205
+ this.init(this.container);
206
+ this.fetchFeedbackList();
207
+ },
208
+ methods: {
209
+ // 获取反馈列表
210
+ async fetchFeedbackList() {
211
+ if (this.loading || this.noMore) return;
212
+ this.loading = true;
213
+ try {
214
+ // TODO: 替换为真实接口
215
+ // const res = await this.$api.getFeedbackList({ page: this.page, pageSize: this.pageSize });
216
+ // this.feedbackList = [...this.feedbackList, ...res.data];
217
+ // this.noMore = res.data.length < this.pageSize;
218
+
219
+ // 模拟数据
220
+ this.feedbackList = [...this.feedbackList, ...this.getMockData()];
221
+ this.noMore = this.page >= 3;
222
+ this.page++;
223
+ } catch (e) {
224
+ console.error('获取反馈列表失败', e);
225
+ } finally {
226
+ this.loading = false;
227
+ }
228
+ },
229
+ // 查看详情
230
+ goToDetail(item) {
231
+ this.detailItem = item;
232
+ this.showDetailModal = true;
233
+ },
234
+ // 关闭详情弹框
235
+ closeDetailModal() {
236
+ this.showDetailModal = false;
237
+ },
238
+ // 获取类型标签 class
239
+ getTypeTagClass(type) {
240
+ return `jfb-feed-back-list__type-tag--${type}`;
241
+ },
242
+ // 获取类型图标
243
+ getTypeIcon(type) {
244
+ return (this.typeMap[type] && this.typeMap[type].icon) || 'message';
245
+ },
246
+ // 获取类型文案
247
+ getTypeLabel(type) {
248
+ return (this.typeMap[type] && this.typeMap[type].label) || type;
249
+ },
250
+ // 模拟数据
251
+ getMockData() {
252
+ const types = ['product', 'order', 'delivery', 'suggestion', 'complaint', 'payment'];
253
+ const statuses = ['replied', 'pending'];
254
+ const contents = [
255
+ '订单配送太慢了,希望能加快配送速度,昨天下的单今天还没送到,体验不太好...',
256
+ '商品质量有问题,申请退换货,收到的商品有破损,包装也不完整...',
257
+ '客服态度很好,问题已解决,感谢工作人员的耐心解答...',
258
+ '建议增加更多配送方式,目前只有快递不够方便...'
259
+ ];
260
+ return Array.from({ length: 3 }, (_, i) => ({
261
+ id: Date.now() + i,
262
+ type: types[(this.page - 1 + i) % types.length],
263
+ status: statuses[i % statuses.length],
264
+ content: contents[i % contents.length],
265
+ images: i % 3 === 0 ? ['data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwIiBoZWlnaHQ9IjEyMCIgdmlld0JveD0iMCAwIDEyMCAxMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiIHJ4PSIxMiIgZmlsbD0iI2Y1ZjVmNSIvPjxwYXRoIGQ9Ik00MCA0NUw1MCA2MEw2MCA0NUw3MCA2MEw4MCA0NSIgc3Ryb2tlPSIjY2NjIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz48L3N2Zz4='] : [],
266
+ createTime: '2026-05-01 12:00',
267
+ isAnonymous: i % 2 === 0,
268
+ contactInfo: i % 2 === 0 ? '' : '138****1234'
269
+ }));
270
+ },
271
+ onJfbLoad(options) {
272
+
273
+ // jfbRootExec('baiduUserLogin', {
274
+
275
+ // vm: this,// data: {
276
+
277
+ // account: 'gaoshiyong',// password: '123456789',// type: 3,// ...options
278
+
279
+ // }
280
+
281
+ // }).then().catch()
282
+ },
283
+ /**
284
+ * @description 监听事件变化
285
+ * @param container {object} 业务组件对象自己
286
+ */
287
+ init(container) {
288
+
289
+ //this.bgcolor = getContainerPropsValue(container, 'content.bgcolor', '#fff');
290
+
291
+ //this.height = getContainerPropsValue(container, 'content.height', 10);
292
+ },
293
+ onJfbScroll(options) {
294
+ console.log('event.onJfbScroll', options)
295
+ },
296
+ onJfbReachBottom(options) {
297
+ console.log('event.onJfbReachBottom', options)
298
+ },
299
+ onJfbShow(options) {
300
+ console.log('event.onJfbShow', options)
301
+ },
302
+ onJfbHide(options) {
303
+ console.log('event.onJfbHide', options)
304
+ },
305
+ onJfbBack(options) {
306
+ console.log('event.onJfbBack', options)
307
+ },
308
+ onJfbUpdate(...data) {
309
+ console.log('event.onJfbUpdate', data)
310
+ },
311
+ onJfbCustomEvent(options) {
312
+ console.log('event.onJfbReachBottom', options)
313
+ },
314
+ }
315
+ }
316
+
317
+ </script>
318
+
319
+ <style scoped lang="less">
320
+ @import "./JfbBaseFeedBackListLess.less";
321
+
322
+ .jfb-base-feed-back-list {
323
+ &__body {
324
+ background: #f5f5f5;
325
+ min-height: 100vh;
326
+ }
327
+ }
328
+
329
+ .jfb-feed-back-list {
330
+ &__container {
331
+ padding: 10rpx;
332
+ padding-bottom: calc(10rpx + env(safe-area-inset-bottom));
333
+ }
334
+
335
+ &__item {
336
+ background: #fff;
337
+ border-radius: 10rpx;
338
+ padding: 20rpx;
339
+ margin-bottom: 10rpx;
340
+ }
341
+
342
+ // 顶部:类型 + 状态
343
+ &__item-header {
344
+ display: flex;
345
+ align-items: center;
346
+ justify-content: space-between;
347
+ margin-bottom: 14rpx;
348
+ }
349
+
350
+ &__type-tag {
351
+ display: flex;
352
+ align-items: center;
353
+ padding: 6rpx 14rpx;
354
+ border-radius: 6rpx;
355
+ font-size: 26rpx;
356
+ color: #e8272c;
357
+ background: #fde8e8;
358
+
359
+ &--product,
360
+ &--order,
361
+ &--payment,
362
+ &--delivery,
363
+ &--suggestion,
364
+ &--complaint,
365
+ &--consult {
366
+ background: #fde8e8;
367
+ color: #e8272c;
368
+ }
369
+ }
370
+
371
+ &__type-icon {
372
+ font-size: 26rpx;
373
+ margin-right: 4rpx;
374
+ }
375
+
376
+ &__status {
377
+ font-size: 24rpx;
378
+ }
379
+
380
+ .text-green {
381
+ color: #52c41a;
382
+ }
383
+
384
+ .text-orange {
385
+ color: #fa8c16;
386
+ }
387
+
388
+ // 内容摘要
389
+ &__content {
390
+ font-size: 28rpx;
391
+ color: #333;
392
+ line-height: 1.6;
393
+ margin-bottom: 14rpx;
394
+ overflow: hidden;
395
+ text-overflow: ellipsis;
396
+ display: -webkit-box;
397
+ -webkit-line-clamp: 2;
398
+ line-clamp: 2;
399
+ -webkit-box-orient: vertical;
400
+ }
401
+
402
+ // 图片
403
+ &__images {
404
+ display: flex;
405
+ gap: 10rpx;
406
+ margin-bottom: 14rpx;
407
+ }
408
+
409
+ &__image-wrapper {
410
+ width: 120rpx;
411
+ height: 120rpx;
412
+ border-radius: 8rpx;
413
+ overflow: hidden;
414
+ background: #f5f5f5;
415
+ }
416
+
417
+ &__image {
418
+ width: 100%;
419
+ height: 100%;
420
+ }
421
+
422
+ &__image-placeholder {
423
+ width: 100%;
424
+ height: 100%;
425
+ display: flex;
426
+ align-items: center;
427
+ justify-content: center;
428
+ }
429
+
430
+ &__image-placeholder-icon {
431
+ font-size: 36rpx;
432
+ color: #ddd;
433
+ }
434
+
435
+ // 底部
436
+ &__item-footer {
437
+ display: flex;
438
+ align-items: center;
439
+ justify-content: space-between;
440
+ }
441
+
442
+ &__time {
443
+ font-size: 24rpx;
444
+ color: #999;
445
+ }
446
+
447
+ &__detail-link {
448
+ display: flex;
449
+ align-items: center;
450
+ font-size: 24rpx;
451
+ color: #999;
452
+ }
453
+
454
+ &__detail-icon {
455
+ font-size: 22rpx;
456
+ margin-left: 4rpx;
457
+ }
458
+
459
+ // 空状态
460
+ &__empty {
461
+ display: flex;
462
+ flex-direction: column;
463
+ align-items: center;
464
+ justify-content: center;
465
+ padding: 120rpx 0;
466
+ color: #999;
467
+ font-size: 28rpx;
468
+ }
469
+
470
+ &__empty-icon {
471
+ font-size: 80rpx;
472
+ color: #ccc;
473
+ margin-bottom: 20rpx;
474
+ }
475
+
476
+ // 加载状态
477
+ &__loading,
478
+ &__no-more {
479
+ text-align: center;
480
+ padding: 30rpx 0;
481
+ font-size: 24rpx;
482
+ color: #999;
483
+ }
484
+
485
+ // Drawer 弹框样式
486
+ &__drawer-header {
487
+ display: flex;
488
+ align-items: center;
489
+ justify-content: space-between;
490
+ padding: 30rpx;
491
+ border-bottom: 1rpx solid #f0f0f0;
492
+ }
493
+
494
+ &__drawer-title {
495
+ font-size: 32rpx;
496
+ font-weight: 600;
497
+ color: #333;
498
+ }
499
+
500
+ &__drawer-body {
501
+ padding: 30rpx;
502
+ padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
503
+ }
504
+
505
+ &__drawer-row {
506
+ margin-bottom: 30rpx;
507
+ }
508
+
509
+ &__drawer-row:last-child {
510
+ margin-bottom: 0;
511
+ }
512
+
513
+ &__drawer-label {
514
+ font-size: 26rpx;
515
+ color: #999;
516
+ margin-bottom: 16rpx;
517
+ }
518
+
519
+ &__drawer-type-row {
520
+ display: flex;
521
+ align-items: center;
522
+ gap: 16rpx;
523
+ }
524
+
525
+ &__drawer-status-icon {
526
+ font-size: 26rpx;
527
+ margin-right: 4rpx;
528
+ }
529
+
530
+ &__drawer-anonymous-tag {
531
+ display: inline-block;
532
+ padding: 8rpx 24rpx;
533
+ background: #f5f5f5;
534
+ border-radius: 8rpx;
535
+ font-size: 26rpx;
536
+ color: #666;
537
+ }
538
+
539
+ &__drawer-value {
540
+ font-size: 28rpx;
541
+ color: #333;
542
+ }
543
+
544
+ &__drawer-content-box {
545
+ padding: 20rpx;
546
+ background: #f9f9f9;
547
+ border-radius: 12rpx;
548
+ font-size: 28rpx;
549
+ color: #333;
550
+ line-height: 1.6;
551
+ word-break: break-all;
552
+ }
553
+
554
+ &__drawer-images {
555
+ display: flex;
556
+ flex-wrap: wrap;
557
+ gap: 10rpx;
558
+ }
559
+
560
+ &__drawer-image {
561
+ width: 160rpx;
562
+ height: 160rpx;
563
+ border-radius: 12rpx;
564
+ }
565
+ }
566
+ </style>
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @desc 获取绝对路径完整地址
3
+ * @param @path
4
+ **/
5
+ //例如:https://image.jufubao.cn/20220501010108/image/bg/default_gonghui_bg.png
6
+ @basePath: 'business/';
7
+ @doMain: '//sandbox-img.jufubao.cn/';
8
+
9
+ .getBusinessImageUrl(@path, @size: 'size8') {
10
+ @url: "@{doMain}@{basePath}@{path}?x-oss-process=style/@{size}";
11
+ background-image: url(@url);
12
+ }
13
+
14
+ //start
15
+ .jfb-base-feed-back-list {
16
+ box-sizing: border-box;
17
+
18
+ &__body{
19
+ position: relative;
20
+ overflow: hidden;
21
+ z-index: 2
22
+ }
23
+
24
+ &.editx,&.editx:hover {
25
+ position: relative;
26
+ min-height: unit(100, rpx);
27
+ z-index: 3;
28
+ &::after {
29
+ border: 2rpx dashed blue;
30
+ content: " ";
31
+ position: absolute;
32
+ top:0;
33
+ left:0;
34
+ bottom:0;
35
+ right:0;
36
+ z-index: 4;
37
+ cursor: pointer;
38
+ }
39
+
40
+ }
41
+
42
+
43
+ &__edit {
44
+ cursor: pointer;
45
+ position: absolute;
46
+ right: unit(0, rpx);
47
+ top: unit(-52, rpx);
48
+ height: unit(50, rpx);
49
+ line-height: unit(50, rpx);
50
+ display: flex;
51
+ justify-content: center;
52
+ align-items: center;
53
+ background: rgba(0, 0, 0, .6);
54
+ border-radius: unit(10, rpx);
55
+ box-shadow: 0 0 10px rbga(0, 0, 0, 0.3);
56
+ color: #fff;
57
+ font-size: unit(22, rpx);
58
+
59
+ &-icon{
60
+ padding: 0 unit(20, rpx);
61
+ }
62
+
63
+ &.editx {
64
+ box-sizing: border-box;
65
+
66
+ }
67
+ }
68
+ }
69
+ //end
70
+
71
+
72
+ /**notPreview**/
73
+ .jfb-base-feed-back-list {
74
+ //&:before {
75
+ //content: " ";
76
+ //display: table;
77
+ //}
78
+ }
79
+ /**endNotPreview**/
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+
4
+ //@AttrImport
5
+ import Attr from "./Attr";
6
+ //@EndAttrImport
7
+
8
+
9
+ export default {
10
+ data() {
11
+ return {
12
+ //#ifdef H5
13
+
14
+ //@AttrData
15
+ Attr:{}, //对外开发编辑属性
16
+ //@EndAttrData
17
+
18
+ // #endif
19
+ cssRoot: 'jfb-base-feed-back-list'
20
+ }
21
+ },
22
+ created() {
23
+
24
+ //@AttrDataCreated
25
+ this.Attr = this.$xdUniHelper.customClone(Attr);
26
+ //@EndAttrDataCreated
27
+
28
+
29
+ },
30
+ }
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ getFeedByIdFilmSquate:{},
5
+ }
@@ -1,22 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * @description 第三方库
5
- * @param threePackagePath {String} 第三方库所在项目路径存放路径路
6
- * @param packname {String} 包名字
7
- * @returns {string|*}
8
- */
9
- const getPackagePath = (threePackagePath, packname = 'gxd-commands-bussiness')=>{
10
- if(packname === 'gxd-commands-bussiness') {
11
- return `/Users/shiyonggao/home/root/Base-Jufubao/xd-commands-bussiness/${threePackagePath}`;
12
- }
13
-
14
- if (packname === 'gxd-uni-library-editx') {
15
- return `/Users/shiyonggao/home/root/Base-Jufubao/xd-uni-library-editx/${threePackagePath}`;
16
- }
17
-
18
- };
19
-
20
- module.exports = {
21
- getPackagePath
22
- }