zjk
2026-09-29 54dcf0a82e7490fa58b1c056d5c0b9cb739c2931
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package com.tcm.training.admin.system.service;
 
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tcm.training.admin.common.PageResponse;
import com.tcm.training.admin.member.entity.AppUser;
import com.tcm.training.admin.member.mapper.UserMapper;
import com.tcm.training.admin.system.dto.UserFeedbackSubmitRequest;
import com.tcm.training.admin.system.entity.UserFeedback;
import com.tcm.training.admin.system.mapper.UserFeedbackMapper;
import com.tcm.training.admin.system.mapper.UserFeedbackQueryMapper;
import com.tcm.training.admin.system.vo.UserFeedbackListItemVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.regex.Pattern;
 
@Service
public class UserFeedbackAppService {
 
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1\\d{10}$");
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
 
    private final UserFeedbackMapper userFeedbackMapper;
    private final UserFeedbackQueryMapper userFeedbackQueryMapper;
    private final UserMapper userMapper;
 
    public UserFeedbackAppService(UserFeedbackMapper userFeedbackMapper,
                                  UserFeedbackQueryMapper userFeedbackQueryMapper,
                                  UserMapper userMapper) {
        this.userFeedbackMapper = userFeedbackMapper;
        this.userFeedbackQueryMapper = userFeedbackQueryMapper;
        this.userMapper = userMapper;
    }
 
    public PageResponse<UserFeedbackListItemVO> page(int page, int pageSize, String content) {
        IPage<UserFeedbackListItemVO> result = userFeedbackQueryMapper.selectUserFeedbackPage(
                new Page<UserFeedbackListItemVO>(page, pageSize),
                trimToNull(content)
        );
        return PageResponse.of(result.getRecords(), result.getTotal(), result.getCurrent(), result.getSize());
    }
 
    @Transactional
    public void submit(Long appUserId, UserFeedbackSubmitRequest request) {
        requireAppUser(appUserId);
 
        UserFeedback item = new UserFeedback();
        item.setAppUserId(appUserId);
        item.setContent(normalizeContent(request.getContent()));
        item.setContact(normalizeContact(request.getContact()));
        item.setDeleted(0);
        userFeedbackMapper.insert(item);
    }
 
    private void requireAppUser(Long appUserId) {
        AppUser user = userMapper.selectById(appUserId);
        if (user == null || (user.getDeleted() != null && user.getDeleted() == 1)) {
            throw new IllegalArgumentException("用户不存在");
        }
    }
 
    private String normalizeContent(String content) {
        String trimmed = trimToNull(content);
        if (trimmed == null) {
            throw new IllegalArgumentException("请输入问题和意见");
        }
        return trimmed;
    }
 
    private String normalizeContact(String contact) {
        String trimmed = trimToNull(contact);
        if (trimmed == null) {
            return null;
        }
        if (!PHONE_PATTERN.matcher(trimmed).matches() && !EMAIL_PATTERN.matcher(trimmed).matches()) {
            throw new IllegalArgumentException("请输入正确的手机号或邮箱");
        }
        return trimmed;
    }
 
    private String trimToNull(String value) {
        if (value == null) {
            return null;
        }
        String trimmed = value.trim();
        return trimmed.isEmpty() ? null : trimmed;
    }
}