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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package com.tcm.training.admin.app.clinic.service;
 
import com.tcm.training.admin.app.auth.service.AppAuthSessionService;
import com.tcm.training.admin.app.clinic.dto.AppClinicInfoUpdateRequest;
import com.tcm.training.admin.app.clinic.vo.AppClinicInfoVO;
import com.tcm.training.admin.live.entity.Clinic;
import com.tcm.training.admin.live.mapper.ClinicMapper;
import com.tcm.training.admin.member.entity.AppUser;
import com.tcm.training.admin.member.mapper.UserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
/**
 * APP 诊所信息服务。
 */
@Service
public class AppClinicInfoService {
 
    private static final int USER_TYPE_DOCTOR = 1;
    private static final int USER_STATUS_ENABLED = 1;
 
    private final AppAuthSessionService appAuthSessionService;
    private final UserMapper userMapper;
    private final ClinicMapper clinicMapper;
 
    /**
     * 注入 APP 诊所信息所需依赖。
     */
    public AppClinicInfoService(AppAuthSessionService appAuthSessionService,
                                UserMapper userMapper,
                                ClinicMapper clinicMapper) {
        this.appAuthSessionService = appAuthSessionService;
        this.userMapper = userMapper;
        this.clinicMapper = clinicMapper;
    }
 
    /**
     * 获取当前登录医生所属诊所详情。
     */
    public AppClinicInfoVO detail() {
        Clinic clinic = requireOwnedClinic();
        return toClinicInfo(clinic);
    }
 
    /**
     * 更新当前登录医生所属诊所信息。
     */
    @Transactional
    public AppClinicInfoVO update(AppClinicInfoUpdateRequest request) {
        Clinic clinic = requireOwnedClinic();
        clinic.setName(trimRequired(request.getInstitutionName(), "请输入诊所名称"));
        clinic.setProvinceCode(trimRequired(request.getProvinceCode(), "请选择省份"));
        clinic.setProvinceName(trimRequired(request.getProvinceName(), "请选择省份"));
        clinic.setCityCode(trimRequired(request.getCityCode(), "请选择城市"));
        clinic.setCityName(trimRequired(request.getCityName(), "请选择城市"));
        clinic.setDistrictCode(trimRequired(request.getDistrictCode(), "请选择区县"));
        clinic.setDistrictName(trimRequired(request.getDistrictName(), "请选择区县"));
        clinic.setAddress(trimRequired(request.getDetailAddress(), "请输入详细地址"));
        // 营业执照在诊所信息页允许为空,方便用户先完善基础资料再补传附件。
        clinic.setBusinessLicenseUrl(trimToNull(request.getBusinessLicenseUrl()));
        clinicMapper.updateById(clinic);
        return toClinicInfo(clinic);
    }
 
    /**
     * 校验当前登录用户为启用中的医生并已绑定诊所。
     */
    private Clinic requireOwnedClinic() {
        Long userId = appAuthSessionService.requireLoginUserId();
        AppUser user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == null || user.getDeleted().intValue() != 0) {
            throw new IllegalArgumentException("用户不存在");
        }
        if (user.getStatus() == null || user.getStatus().intValue() != USER_STATUS_ENABLED) {
            throw new IllegalArgumentException("用户已禁用");
        }
        if (user.getType() == null || user.getType().intValue() != USER_TYPE_DOCTOR) {
            throw new IllegalArgumentException("当前用户无权查看诊所信息");
        }
        if (user.getClinicId() == null) {
            throw new IllegalArgumentException("当前账号未绑定诊所");
        }
        Clinic clinic = clinicMapper.selectById(user.getClinicId());
        if (clinic == null || clinic.getDeleted() == null || clinic.getDeleted().intValue() != 0) {
            throw new IllegalArgumentException("诊所不存在");
        }
        return clinic;
    }
 
    /**
     * 将诊所实体转换为 APP 诊所信息响应结构。
     */
    private AppClinicInfoVO toClinicInfo(Clinic clinic) {
        AppClinicInfoVO result = new AppClinicInfoVO();
        result.setClinicId(clinic.getId());
        result.setInstitutionName(trimToEmpty(clinic.getName()));
        result.setProvinceCode(trimToEmpty(clinic.getProvinceCode()));
        result.setProvinceName(trimToEmpty(clinic.getProvinceName()));
        result.setCityCode(trimToEmpty(clinic.getCityCode()));
        result.setCityName(trimToEmpty(clinic.getCityName()));
        result.setDistrictCode(trimToEmpty(clinic.getDistrictCode()));
        result.setDistrictName(trimToEmpty(clinic.getDistrictName()));
        result.setRegionText(buildRegionText(clinic));
        result.setDetailAddress(trimToEmpty(clinic.getAddress()));
        result.setBusinessLicenseUrl(trimToEmpty(clinic.getBusinessLicenseUrl()));
        return result;
    }
 
    /**
     * 将省市区名称拼接成页面直接可展示的地区文案。
     */
    private String buildRegionText(Clinic clinic) {
        StringBuilder builder = new StringBuilder();
        appendText(builder, clinic == null ? null : clinic.getProvinceName());
        appendText(builder, clinic == null ? null : clinic.getCityName());
        appendText(builder, clinic == null ? null : clinic.getDistrictName());
        return builder.toString().trim();
    }
 
    /**
     * 将文本安全追加到地区名称拼接器中。
     */
    private void appendText(StringBuilder builder, String value) {
        String normalized = trimToNull(value);
        if (normalized == null) {
            return;
        }
        if (builder.length() > 0) {
            builder.append(' ');
        }
        builder.append(normalized);
    }
 
    /**
     * 将必填文本归一化,并在空值时抛出业务错误。
     */
    private String trimRequired(String value, String message) {
        String normalized = trimToNull(value);
        if (normalized == null) {
            throw new IllegalArgumentException(message);
        }
        return normalized;
    }
 
    /**
     * 将空白文本统一归一化为 null。
     */
    private String trimToNull(String value) {
        if (value == null) {
            return null;
        }
        String trimmed = value.trim();
        return trimmed.isEmpty() ? null : trimmed;
    }
 
    /**
     * 将可空文本统一转换为空字符串。
     */
    private String trimToEmpty(String value) {
        String normalized = trimToNull(value);
        return normalized == null ? "" : normalized;
    }
}