From cc31d303d12f9c7cd2c4574351b67db04069ae0d Mon Sep 17 00:00:00 2001
From: hejianhao <15708179461@qq.com>
Date: 星期五, 28 八月 2026 15:46:30 +0800
Subject: [PATCH] 828优化功能新需求
---
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/vo/ClinicListItemVO.java | 1
traditionalApp/pages/home/home.vue | 5
tcm-training-admin/src/pages/member/clinic/index.tsx | 12 +
traditionalApp/pages/mine/mine.vue | 25 -
tcm-training-admin/src/app.tsx | 13 +
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/mapper/ClinicQueryMapper.java | 2
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/row/ClinicListRow.java | 1
tcm-training-admin-backend/src/main/resources/mapper/ClinicQueryMapper.xml | 9
tcm-training-admin/config/routes.ts | 182 ++++++++--------
traditionalApp/pages/login/login.vue | 6
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/controller/ClinicController.java | 6
traditionalApp/App.vue | 8
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterRegionService.java | 10
tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/register/service/AppRegisterRegionServiceTest.java | 24 ++
traditionalApp/config/index.js | 1
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java | 34 +-
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/bootstrap/DataInitializer.java | 2
/dev/null | 199 ------------------
tcm-training-admin/src/pages/live/broadcast/index.tsx | 2
traditionalApp/pages/articleDetail/articleDetail.vue | 3
traditionalApp/pages/good/projectDetail.vue | 4
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java | 64 -----
traditionalApp/manifest.json | 4
23 files changed, 216 insertions(+), 401 deletions(-)
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterRegionService.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterRegionService.java
index 2d587a6..67902d8 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterRegionService.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterRegionService.java
@@ -101,6 +101,9 @@
}
List<AppRegisterRegionPickerOptionVO> currentDistrictOptions = new ArrayList<AppRegisterRegionPickerOptionVO>(districts.size());
for (SysRegion district : districts) {
+ if (shouldHideInAppPicker(district)) {
+ continue;
+ }
currentDistrictOptions.add(toPickerOption(district, 3));
}
currentAreaOptions.add(currentDistrictOptions);
@@ -117,6 +120,13 @@
}
/**
+ * APP 地区选择器不展示行政区划占位节点。
+ */
+ private boolean shouldHideInAppPicker(SysRegion region) {
+ return region.getName() != null && region.getName().contains("市辖区");
+ }
+
+ /**
* 将海诊通诊所地区编码或名称归一化为本地三级行政区划。
*/
public RegionSelection resolveRegionSelection(String provinceCode,
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java
index 0640522..edec2fc 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/register/service/AppRegisterService.java
@@ -184,6 +184,9 @@
clinic.setBusinessLicenseUrl(trimToNull(request.getBusinessLicenseUrl()));
clinic.setInviteCode(generateInviteCode());
clinic.setStatus(1);
+
+ clinic.setAgentId(4L); // 绑定到默认的省代上面
+
clinicMapper.insert(clinic);
AppUser user = new AppUser();
@@ -194,19 +197,24 @@
user.setClinicId(clinic.getId());
userMapper.insert(user);
-// Integer provinceCode = parseRegionCode(clinic.getProvinceCode(), "省编码");
-// Integer cityCode = parseRegionCode(clinic.getCityCode(), "市编码");
-// Integer areaCode = parseRegionCode(clinic.getDistrictCode(), "区县编码");
-// log.info("调用微赞创建门店,入参 title={}, provinceCode={}, cityCode={}, areaCode={}, address={}, telephone={}",
-// clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
-// try {
-// JsonNode vzanResponse = vzanHttpUtil.createStore(clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
-// log.info("微赞创建门店成功,出参={}", vzanResponse);
-// } catch (RuntimeException ex) {
-// log.error("微赞创建门店失败,本地事务将回滚,入参 title={}, provinceCode={}, cityCode={}, areaCode={}, address={}, telephone={}",
-// clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone(), ex);
-// throw new IllegalStateException("微赞创建门店失败", ex);
-// }
+ Integer provinceCode = parseRegionCode(clinic.getProvinceCode(), "省编码");
+ Integer cityCode = parseRegionCode(clinic.getCityCode(), "市编码");
+ Integer areaCode = parseRegionCode(clinic.getDistrictCode(), "区县编码");
+ log.info("调用微赞创建门店,入参 title={}, provinceCode={}, cityCode={}, areaCode={}, address={}, telephone={}"
+ , clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
+ try {
+ JsonNode vzanResponse = vzanHttpUtil.createStore(clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
+ log.info("微赞创建门店成功,出参={}", vzanResponse);
+ // 注册阶段暂未绑定区域代理,parentMobile 传空,由微赞按一级代理处理。
+ log.info("调用微赞创建一级代理,入参 agentMobile={}, agentName={}, levelCode=1, storeName={}, parentMobile=18510939636",
+ clinic.getContactPhone(), clinic.getName(), clinic.getName());
+ JsonNode vzanAgentResponse = vzanHttpUtil.createAgent(
+ clinic.getContactPhone(), clinic.getName(), 1, "18510939636", clinic.getName());
+ log.info("微赞创建一级代理成功,出参={}", vzanAgentResponse);
+ } catch (RuntimeException ex) {
+ log.error("微赞创建门店或一级代理失败,本地事务将回滚,clinicId={}", clinic.getId(), ex);
+ throw new IllegalStateException("微赞门店或一级代理创建失败", ex);
+ }
clearDraft(request.getRegisterTicket());
return createLoginResponse(user);
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/bootstrap/DataInitializer.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/bootstrap/DataInitializer.java
index eb01d3a..2313f84 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/bootstrap/DataInitializer.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/bootstrap/DataInitializer.java
@@ -20,7 +20,7 @@
import java.util.ArrayList;
import java.util.List;
-@Component
+//@Component
public class DataInitializer implements ApplicationRunner {
private final SysUserService sysUserService;
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/controller/ClinicController.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/controller/ClinicController.java
index 8aeec32..8f6baa8 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/controller/ClinicController.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/controller/ClinicController.java
@@ -44,10 +44,11 @@
@RequestParam(required = false) String regionCode,
@RequestParam(required = false) String name,
@RequestParam(required = false) String phone,
+ @RequestParam(required = false) String agentName,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime createdFrom,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime createdTo,
@RequestParam(required = false) Integer status) {
- return ApiResponse.ok(clinicAppService.page(page, pageSize, regionCode, name, phone, createdFrom, createdTo, status));
+ return ApiResponse.ok(clinicAppService.page(page, pageSize, regionCode, name, phone, agentName, createdFrom, createdTo, status));
}
@GetMapping("/clinics/clinic-import-template")
@@ -65,10 +66,11 @@
@RequestParam(required = false) String regionCode,
@RequestParam(required = false) String name,
@RequestParam(required = false) String phone,
+ @RequestParam(required = false) String agentName,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime createdFrom,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime createdTo,
@RequestParam(required = false) Integer status) throws IOException {
- clinicAppService.export(regionCode, name, phone, createdFrom, createdTo, status, response);
+ clinicAppService.export(regionCode, name, phone, agentName, createdFrom, createdTo, status, response);
}
@GetMapping("/clinics/regions")
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/mapper/ClinicQueryMapper.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/mapper/ClinicQueryMapper.java
index 6d5e009..1880b5f 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/mapper/ClinicQueryMapper.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/mapper/ClinicQueryMapper.java
@@ -18,6 +18,7 @@
@Param("regionCode") String regionCode,
@Param("name") String name,
@Param("phone") String phone,
+ @Param("agentName") String agentName,
@Param("createdFrom") LocalDateTime createdFrom,
@Param("createdTo") LocalDateTime createdTo,
@Param("status") Integer status);
@@ -25,6 +26,7 @@
List<ClinicListRow> selectClinicList(@Param("regionCode") String regionCode,
@Param("name") String name,
@Param("phone") String phone,
+ @Param("agentName") String agentName,
@Param("createdFrom") LocalDateTime createdFrom,
@Param("createdTo") LocalDateTime createdTo,
@Param("status") Integer status);
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/row/ClinicListRow.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/row/ClinicListRow.java
index 64fa430..5d65cdd 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/row/ClinicListRow.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/row/ClinicListRow.java
@@ -16,6 +16,7 @@
private String phone;
private String regionName;
private Integer status;
+ private String agentName;
private Integer userCount;
private LocalDateTime createdAt;
private String businessLicenseUrl;
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java
index 5aecb91..f62d381 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/service/ClinicAppService.java
@@ -4,7 +4,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fasterxml.jackson.databind.JsonNode;
import com.tcm.training.admin.agent.entity.AgentRegion;
import com.tcm.training.admin.agent.entity.ProvincialAgent;
import com.tcm.training.admin.agent.excel.ClinicAgentImportRow;
@@ -29,7 +28,6 @@
import com.tcm.training.admin.member.vo.ClinicDetailVO;
import com.tcm.training.admin.member.vo.ClinicListItemVO;
import com.tcm.training.admin.member.vo.ClinicRegionOptionVO;
-import com.tcm.training.admin.utils.VzanHttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
@@ -54,7 +52,6 @@
private final ProvincialAgentMapper provincialAgentMapper;
private final UserMapper userMapper;
private final SysRegionMapper sysRegionMapper;
- private final VzanHttpUtil vzanHttpUtil;
private final DataSourceTransactionManager transactionManager;
public ClinicAppService(ClinicQueryMapper clinicQueryMapper,
@@ -62,14 +59,12 @@
ProvincialAgentMapper provincialAgentMapper,
UserMapper userMapper,
SysRegionMapper sysRegionMapper,
- VzanHttpUtil vzanHttpUtil,
DataSourceTransactionManager transactionManager) {
this.clinicQueryMapper = clinicQueryMapper;
this.clinicMapper = clinicMapper;
this.provincialAgentMapper = provincialAgentMapper;
this.userMapper = userMapper;
this.sysRegionMapper = sysRegionMapper;
- this.vzanHttpUtil = vzanHttpUtil;
this.transactionManager = transactionManager;
}
@@ -78,6 +73,7 @@
String regionCode,
String name,
String phone,
+ String agentName,
LocalDateTime createdFrom,
LocalDateTime createdTo,
Integer status) {
@@ -86,6 +82,7 @@
trimToNull(regionCode),
trimToNull(name),
trimToNull(phone),
+ trimToNull(agentName),
createdFrom,
createdTo,
status
@@ -177,6 +174,7 @@
public void export(String regionCode,
String name,
String phone,
+ String agentName,
LocalDateTime createdFrom,
LocalDateTime createdTo,
Integer status,
@@ -190,6 +188,7 @@
trimToNull(regionCode),
trimToNull(name),
trimToNull(phone),
+ trimToNull(agentName),
createdFrom,
createdTo,
status
@@ -307,61 +306,7 @@
throw e;
}
- if (request.getAgentId() == null) {
- return detail(id);
- }
-
- // 事务提交后,调用微赞接口(不回滚本地事务)
- try {
- Clinic clinic = clinicMapper.selectById(id);
-
- // 调用微赞创建门店
- Integer provinceCode = parseRegionCode(clinic.getProvinceCode(), "省编码");
- Integer cityCode = parseRegionCode(clinic.getCityCode(), "市编码");
- Integer areaCode = parseRegionCode(clinic.getDistrictCode(), "区县编码");
- log.info("调用微赞创建门店,入参 title={}, provinceCode={}, cityCode={}, areaCode={}, address={}, telephone={}",
- clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
- JsonNode vzanStoreResponse = vzanHttpUtil.createStore(clinic.getName(), provinceCode, cityCode, areaCode, clinic.getAddress(), clinic.getContactPhone());
- log.info("微赞创建门店成功,出参={}", vzanStoreResponse);
-
- // 查询代理信息获取parentMobile
- ProvincialAgent agent = provincialAgentMapper.selectById(request.getAgentId());
-
- String parentMobile = agent.getContactInfo();
- if (parentMobile == null || parentMobile.trim().isEmpty()) {
- throw new IllegalArgumentException("代理联系方式为空,agentId=" + request.getAgentId());
- }
-
- // 调用微赞创建代理
- log.info("调用微赞创建代理,入参 agentMobile={}, agentName={}, levelCode=1, storeName={}, parentMobile={}",
- clinic.getContactPhone(), clinic.getName(), clinic.getName(), parentMobile);
- JsonNode vzanAgentResponse = vzanHttpUtil.createAgent(
- clinic.getContactPhone(), // agentMobile传门店的手机号
- clinic.getName(), // agentName传门店的名称
- 1, // levelCode传1
- parentMobile, // parentMobile传代理的contact_info
- clinic.getName() // storeName传门店的name
- );
- log.info("微赞创建代理成功,出参={}", vzanAgentResponse);
-
- } catch (Exception e) {
- // 捕获微赞接口异常,不回滚本地事务
- log.error("调用微赞接口失败,但本地数据已保存成功,clinicId={}", id, e);
- throw new IllegalStateException("调用微赞失败", e);
- }
-
return detail(id);
- }
-
- private Integer parseRegionCode(String code, String fieldName) {
- if (code == null || code.trim().isEmpty()) {
- throw new IllegalArgumentException(fieldName + "不能为空");
- }
- try {
- return Integer.parseInt(code);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(fieldName + "格式错误: " + code);
- }
}
private void addCode(Set<String> codes, String code) {
@@ -432,6 +377,7 @@
item.setPhone(row.getPhone() == null ? "-" : PhoneMasker.mask(row.getPhone()));
item.setRegionName(defaultText(row.getRegionName()));
item.setStatus(row.getStatus());
+ item.setAgentName(defaultText(row.getAgentName()));
item.setUserCount(row.getUserCount() == null ? 0 : row.getUserCount());
item.setCreatedAt(row.getCreatedAt());
item.setBusinessLicenseUrl(trimToNull(row.getBusinessLicenseUrl()));
diff --git a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/vo/ClinicListItemVO.java b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/vo/ClinicListItemVO.java
index db7b9de..708d38f 100644
--- a/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/vo/ClinicListItemVO.java
+++ b/tcm-training-admin-backend/src/main/java/com/tcm/training/admin/member/vo/ClinicListItemVO.java
@@ -16,6 +16,7 @@
private String phone;
private String regionName;
private Integer status;
+ private String agentName;
private Integer userCount;
private LocalDateTime createdAt;
private String businessLicenseUrl;
diff --git a/tcm-training-admin-backend/src/main/resources/mapper/ClinicQueryMapper.xml b/tcm-training-admin-backend/src/main/resources/mapper/ClinicQueryMapper.xml
index 848abd3..0ccde7d 100644
--- a/tcm-training-admin-backend/src/main/resources/mapper/ClinicQueryMapper.xml
+++ b/tcm-training-admin-backend/src/main/resources/mapper/ClinicQueryMapper.xml
@@ -18,6 +18,9 @@
<if test="phone != null and phone.trim() != ''">
AND c.contact_phone LIKE CONCAT('%', #{phone}, '%')
</if>
+ <if test="agentName != null and agentName.trim() != ''">
+ AND pa.agent_name LIKE CONCAT('%', #{agentName}, '%')
+ </if>
<if test="createdFrom != null">
AND c.created_at >= #{createdFrom}
</if>
@@ -44,10 +47,12 @@
ELSE NULL
END AS regionName,
c.status,
+ pa.agent_name AS agentName,
COUNT(u.id) AS userCount,
c.created_at AS createdAt,
c.business_license_url AS businessLicenseUrl
FROM tcm_clinic c
+ LEFT JOIN tcm_provincial_agent pa ON pa.id = c.agent_id AND pa.deleted = 0
LEFT JOIN tcm_app_user u ON u.clinic_id = c.id AND u.deleted = 0
<include refid="ClinicWhere"/>
GROUP BY
@@ -58,6 +63,7 @@
c.city_name,
c.district_name,
c.status,
+ pa.agent_name,
c.created_at,
c.business_license_url
ORDER BY c.id DESC
@@ -78,10 +84,12 @@
ELSE NULL
END AS regionName,
c.status,
+ pa.agent_name AS agentName,
COUNT(u.id) AS userCount,
c.created_at AS createdAt,
c.business_license_url AS businessLicenseUrl
FROM tcm_clinic c
+ LEFT JOIN tcm_provincial_agent pa ON pa.id = c.agent_id AND pa.deleted = 0
LEFT JOIN tcm_app_user u ON u.clinic_id = c.id AND u.deleted = 0
<include refid="ClinicWhere"/>
GROUP BY
@@ -92,6 +100,7 @@
c.city_name,
c.district_name,
c.status,
+ pa.agent_name,
c.created_at,
c.business_license_url
ORDER BY c.id DESC
diff --git a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/register/service/AppRegisterRegionServiceTest.java b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/register/service/AppRegisterRegionServiceTest.java
index c6449c6..ba020b2 100644
--- a/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/register/service/AppRegisterRegionServiceTest.java
+++ b/tcm-training-admin-backend/src/test/java/com/tcm/training/admin/app/register/service/AppRegisterRegionServiceTest.java
@@ -2,6 +2,7 @@
import com.tcm.training.admin.app.register.entity.SysRegion;
import com.tcm.training.admin.app.register.mapper.SysRegionMapper;
+import com.tcm.training.admin.app.register.vo.AppRegisterRegionDatasetVO;
import com.tcm.training.admin.app.register.vo.AppRegisterRegionOptionVO;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -9,6 +10,7 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -52,6 +54,28 @@
}
/**
+ * APP 完整地区数据集应过滤区县层级的市辖区占位节点。
+ */
+ @Test
+ void buildRegionDatasetShouldHideMunicipalDistrictPlaceholder() {
+ SysRegion province = buildRegion(1L, "江西省", "360000", 0L);
+ SysRegion city = buildRegion(2L, "吉安市", "360800", 1L);
+ SysRegion placeholder = buildRegion(3L, "吉安市市辖区", "360801", 2L);
+ SysRegion district = buildRegion(4L, "吉州区", "360802", 2L);
+ when(sysRegionMapper.selectAllOrdered()).thenReturn(
+ Arrays.asList(province, city, placeholder, district)
+ );
+
+ AppRegisterRegionDatasetVO dataset = appRegisterRegionService.buildRegionDataset();
+
+ assertEquals(1, dataset.getAreas().size());
+ assertEquals(1, dataset.getAreas().get(0).size());
+ assertEquals(1, dataset.getAreas().get(0).get(0).size());
+ assertEquals("吉州区", dataset.getAreas().get(0).get(0).get(0).getLabel());
+ assertEquals("360802", dataset.getAreas().get(0).get(0).get(0).getValue());
+ }
+
+ /**
* 海诊通仅返回地区名称时,应通过 sys_region 解析出完整编码。
*/
@Test
diff --git a/tcm-training-admin/admin.zip b/tcm-training-admin/admin.zip
deleted file mode 100644
index 6ad07d0..0000000
--- a/tcm-training-admin/admin.zip
+++ /dev/null
Binary files differ
diff --git a/tcm-training-admin/config/routes.ts b/tcm-training-admin/config/routes.ts
index 484ca6e..8b51e35 100644
--- a/tcm-training-admin/config/routes.ts
+++ b/tcm-training-admin/config/routes.ts
@@ -192,22 +192,28 @@
component: './member/user/redirect',
},
{
- name: '用户管理',
- path: '/member/user/manage',
- access: 'member:user:view',
- component: './member/user',
+ name: '省代用户',
+ path: '/member/user/agent',
+ access: 'member:agent:view',
+ component: './member/agent',
},
{
- name: '诊所管理',
+ name: '诊所用户',
path: '/member/user/clinic',
access: 'member:clinic:view',
component: './member/clinic',
},
{
- name: '省代理管理',
- path: '/member/user/agent',
- access: 'member:agent:view',
- component: './member/agent',
+ name: '普通用户',
+ path: '/member/user/manage',
+ access: 'member:user:view',
+ component: './member/user',
+ },
+ {
+ name: '会员用户',
+ path: '/member/user/member-users',
+ access: 'member:user:member:view',
+ component: './member/user/member-users',
},
{
name: '编辑诊所',
@@ -222,12 +228,6 @@
hideInMenu: true,
access: 'member:clinic:view',
component: './member/clinic/detail',
- },
- {
- name: '会员用户',
- path: '/member/user/member-users',
- access: 'member:user:member:view',
- component: './member/user/member-users',
},
{
name: '会员用户详情',
@@ -273,26 +273,21 @@
},
{
path: '/live',
- name: '课程与学习',
+ name: '内容',
icon: 'read',
access: 'canViewLiveModule',
routes: [
{
path: '/live',
- redirect: '/live/course',
+ redirect: '/live/course/broadcast',
},
{
path: '/live/expert',
redirect: '/live/course/expert',
},
{
- path: '/live/course',
- name: '课程管理',
+ name: '类直播',
routes: [
- {
- path: '/live/course',
- redirect: '/live/course/broadcast',
- },
{
name: '养生直播',
path: '/live/course/broadcast',
@@ -314,36 +309,67 @@
component: './live/broadcast/edit',
},
{
- name: '微赞直播间设置',
- path: '/live/course/live-room-setting',
- access: 'live:room-setting:view',
- component: './live/live-room-setting',
- }, {
- name: '直播预约记录',
+ name: '预约记录',
path: '/live/course/reserve-records',
access: 'live:reserve:view',
component: './live/reserve-records',
},
{
- name: '直播观看记录',
+ name: '观看记录',
path: '/live/course/watch-records',
access: 'live:watch:view',
component: './live/watch-records',
},
{
- name: '分类管理',
+ name: '直播预约记录跳转',
+ path: '/live/course/broadcast/:courseId/sessions/:sessionId/reserves',
+ hideInMenu: true,
+ access: 'live:reserve:view',
+ component: './live/record-redirect',
+ },
+ {
+ name: '直播观看记录跳转',
+ path: '/live/course/broadcast/:courseId/sessions/:sessionId/watch-records',
+ hideInMenu: true,
+ access: 'live:watch:view',
+ component: './live/record-redirect',
+ },
+ ],
+ },
+ {
+ name: '微赞直播',
+ routes: [
+ {
+ name: '直播设置',
+ path: '/live/course/live-room-setting',
+ access: 'live:room-setting:view',
+ component: './live/live-room-setting',
+ },
+ ],
+ },
+ {
+ name: '课程',
+ routes: [
+ {
+ name: '添加分类',
path: '/live/course/category',
access: 'live:category:view',
component: './live/category',
},
{
- name: '养生课程',
+ name: '添加专家',
+ path: '/live/course/expert',
+ access: 'live:expert:view',
+ component: './live/expert',
+ },
+ {
+ name: '添加课堂',
path: '/live/course/health',
access: 'live:health-course:view',
component: './live/health',
},
{
- name: '视频与课程资源管理',
+ name: '添加视频',
path: '/live/course/video-resources',
access: 'live:health-course:view',
component: './live/video-resources',
@@ -397,61 +423,11 @@
access: 'live:health-course:video:edit',
component: './live/health/video-manage',
},
- {
- name: '直播预约记录跳转',
- path: '/live/course/broadcast/:courseId/sessions/:sessionId/reserves',
- hideInMenu: true,
- access: 'live:reserve:view',
- component: './live/record-redirect',
- },
- {
- name: '直播观看记录跳转',
- path: '/live/course/broadcast/:courseId/sessions/:sessionId/watch-records',
- hideInMenu: true,
- access: 'live:watch:view',
- component: './live/record-redirect',
- },
- {
- name: '授课专家管理',
- path: '/live/course/expert',
- access: 'live:expert:view',
- component: './live/expert',
- },
- {
- path: '/live/course/project-introduction/create',
- hideInMenu: true,
- redirect: '/live/promotion/project-introduction/create',
- },
- {
- path: '/live/course/project-introduction',
- hideInMenu: true,
- redirect: '/live/promotion/project-introduction',
- },
- {
- path: '/live/course/project-introduction-password',
- hideInMenu: true,
- redirect: '/live/promotion/project-introduction-password',
- },
- {
- path: '/live/course/health-popularization/create',
- hideInMenu: true,
- redirect: '/live/promotion/health-popularization/create',
- },
- {
- path: '/live/course/health-popularization',
- hideInMenu: true,
- redirect: '/live/promotion/health-popularization',
- },
],
},
{
- path: '/live/promotion',
- name: '宣传知识',
+ name: '科普',
routes: [
- {
- path: '/live/promotion',
- redirect: '/live/promotion/project-introduction',
- },
{
name: '健康知识',
path: '/live/promotion/health-popularization',
@@ -492,6 +468,17 @@
access: 'live:health-promotion:edit',
component: './live/health-promotion/manage',
},
+ ],
+ },
+ {
+ name: '项目',
+ routes: [
+ {
+ name: '项目密码',
+ path: '/live/promotion/project-introduction-password',
+ access: 'live:project-introduction:view',
+ component: './live/project-introduction-password',
+ },
{
name: '项目介绍',
path: '/live/promotion/project-introduction',
@@ -513,10 +500,29 @@
component: './live/project-introduction/manage',
},
{
- name: '项目介绍密码',
- path: '/live/promotion/project-introduction-password',
- access: 'live:project-introduction:view',
- component: './live/project-introduction-password',
+ path: '/live/course/project-introduction/create',
+ hideInMenu: true,
+ redirect: '/live/promotion/project-introduction/create',
+ },
+ {
+ path: '/live/course/project-introduction',
+ hideInMenu: true,
+ redirect: '/live/promotion/project-introduction',
+ },
+ {
+ path: '/live/course/project-introduction-password',
+ hideInMenu: true,
+ redirect: '/live/promotion/project-introduction-password',
+ },
+ {
+ path: '/live/course/health-popularization/create',
+ hideInMenu: true,
+ redirect: '/live/promotion/health-popularization/create',
+ },
+ {
+ path: '/live/course/health-popularization',
+ hideInMenu: true,
+ redirect: '/live/promotion/health-popularization',
},
],
},
diff --git a/tcm-training-admin/src/app.tsx b/tcm-training-admin/src/app.tsx
index f0c27c3..f60de8d 100644
--- a/tcm-training-admin/src/app.tsx
+++ b/tcm-training-admin/src/app.tsx
@@ -1,4 +1,4 @@
-import type { Settings as LayoutSettings } from '@ant-design/pro-components';
+import type { MenuDataItem, Settings as LayoutSettings } from '@ant-design/pro-components';
import { SettingDrawer } from '@ant-design/pro-components';
import type { RunTimeLayoutConfig } from '@umijs/max';
import { history } from '@umijs/max';
@@ -26,6 +26,16 @@
loading?: boolean;
};
+const ensureMenuKeys = (menuData: MenuDataItem[], parentKey = 'menu'): MenuDataItem[] =>
+ menuData.map((item, index) => {
+ const key = item.key || item.path || `${parentKey}-${String(item.name || index)}`;
+
+ return {
+ ...item,
+ key,
+ children: item.children ? ensureMenuKeys(item.children, String(key)) : item.children,
+ };
+ });
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
@@ -79,6 +89,7 @@
);
},
...initialState?.settings,
+ menuDataRender: ensureMenuKeys,
pageTitleRender: () => '管理后台',
};
};
diff --git a/tcm-training-admin/src/pages/live/broadcast/index.tsx b/tcm-training-admin/src/pages/live/broadcast/index.tsx
index 1cae71c..54d541e 100644
--- a/tcm-training-admin/src/pages/live/broadcast/index.tsx
+++ b/tcm-training-admin/src/pages/live/broadcast/index.tsx
@@ -170,7 +170,7 @@
<Space size={16} className="live-broadcast-table__actions">
{canDetail ? (
<button type="button" onClick={() => history.push(`/live/course/broadcast/${record.id}`)}>
- 详情
+ 类直播
</button>
) : null}
{canEdit ? (
diff --git a/tcm-training-admin/src/pages/member/clinic/index.tsx b/tcm-training-admin/src/pages/member/clinic/index.tsx
index 321c11d..2690f29 100644
--- a/tcm-training-admin/src/pages/member/clinic/index.tsx
+++ b/tcm-training-admin/src/pages/member/clinic/index.tsx
@@ -12,6 +12,7 @@
regionCode?: string[];
name?: string;
phone?: string;
+ agentName?: string;
status?: number;
createdRange?: Dayjs[];
};
@@ -22,6 +23,7 @@
phone?: string;
regionName?: string;
status: number;
+ agentName?: string;
userCount: number;
createdAt: string;
businessLicenseUrl?: string;
@@ -34,6 +36,7 @@
regionCode: getSelectedRegionCode(values.regionCode),
name: values.name?.trim() || undefined,
phone: values.phone?.trim() || undefined,
+ agentName: values.agentName?.trim() || undefined,
status: values.status,
createdFrom: values.createdRange?.[0]
? dayjs(values.createdRange[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss')
@@ -145,6 +148,12 @@
render: (value) => (value === 1 ? '启用' : value === 2 ? '注销' : '禁用'),
},
{
+ title: '省代',
+ dataIndex: 'agentName',
+ width: 140,
+ render: (value) => value || '-',
+ },
+ {
title: '注册时间',
dataIndex: 'createdAt',
width: 180,
@@ -197,6 +206,9 @@
]}
/>
</Form.Item>
+ <Form.Item label="省代" name="agentName">
+ <Input placeholder="请输入" allowClear />
+ </Form.Item>
<Form.Item label="注册时间" name="createdRange">
<DatePicker.RangePicker className="member-clinic-search-form__range" />
</Form.Item>
diff --git a/traditionalApp/App.vue b/traditionalApp/App.vue
index b0e150a..b8d3dfa 100644
--- a/traditionalApp/App.vue
+++ b/traditionalApp/App.vue
@@ -11,10 +11,6 @@
import { cacheInviteCode } from '@/utils/invite-cache.js'
import { initJPushLifecycle } from '@/utils/push.js'
import {
- checkAppVersionUpdate,
- resumeForceUpdatePrompt
- } from '@/utils/app-version.js'
- import {
getOpeninstallInstallData,
initOpeninstall,
registerOpeninstallWakeUp
@@ -30,7 +26,6 @@
initOpeninstall()
registerOpeninstallWakeUp(handleOpeninstallPayload)
getOpeninstallInstallData(handleOpeninstallPayload)
- checkAppVersionUpdate()
// #endif
})
@@ -39,9 +34,6 @@
*/
onShow(() => {
handleOpenByScheme()
- // #ifdef APP-PLUS
- resumeForceUpdatePrompt()
- // #endif
})
/**
diff --git a/traditionalApp/config/index.js b/traditionalApp/config/index.js
index 968c0f7..d89ad39 100644
--- a/traditionalApp/config/index.js
+++ b/traditionalApp/config/index.js
@@ -2,7 +2,6 @@
// BASE_URL: 'http://221.182.45.100:48080',
BASE_URL: 'https://haizhentong.com',
OPENINSTALL_URL: 'https://m.malink.cn/s/7bIzeu',
- APP_STORE_URL: '',
uploadUrl: "https://haizhentong.com/api/open/file/upload",
imageUrl: 'http://221.182.45.100:11224/images/'
};
diff --git a/traditionalApp/manifest.json b/traditionalApp/manifest.json
index 216a56a..e9d19f7 100644
--- a/traditionalApp/manifest.json
+++ b/traditionalApp/manifest.json
@@ -3,8 +3,8 @@
"name" : "海诊康道",
"appid" : "__UNI__7B5B0CA",
"description" : "",
- "versionName" : "1.0.23",
- "versionCode" : 122,
+ "versionName" : "1.0.0",
+ "versionCode" : 100,
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
diff --git a/traditionalApp/pages/articleDetail/articleDetail.vue b/traditionalApp/pages/articleDetail/articleDetail.vue
index 90597c9..8028439 100644
--- a/traditionalApp/pages/articleDetail/articleDetail.vue
+++ b/traditionalApp/pages/articleDetail/articleDetail.vue
@@ -21,7 +21,7 @@
<!-- 内容区域 -->
<view class="content-area">
- <text class="content-title">{{ detail.title || '健康科普详情' }}</text>
+ <text v-if="isVideoType" class="content-title">{{ detail.title || '健康科普详情' }}</text>
<text v-if="isVideoType && videoSubtitle" class="content-subtitle">{{ videoSubtitle }}</text>
<rich-text v-if="!isVideoType" :nodes="contentNodes" class="rich-content"></rich-text>
<view v-if="loading" class="status-text">加载中...</view>
@@ -288,7 +288,6 @@
}
.rich-content {
- margin-top: 24rpx;
width: 100%;
font-size: 28rpx;
line-height: 1.8;
diff --git a/traditionalApp/pages/good/projectDetail.vue b/traditionalApp/pages/good/projectDetail.vue
index dfd2943..dac4129 100644
--- a/traditionalApp/pages/good/projectDetail.vue
+++ b/traditionalApp/pages/good/projectDetail.vue
@@ -6,7 +6,7 @@
<!-- 导航栏 -->
<view class="nav-bar">
<image class="back-icon" src="/static/image/home/left.png" mode="aspectFit" @tap="goBack"></image>
- <text class="nav-title">{{ detail.title || '详情' }}</text>
+ <text class="nav-title">详情</text>
<view class="nav-right-placeholder"></view>
</view>
@@ -34,8 +34,6 @@
<!-- 图文内容 -->
<view v-if="detail.contentType === 1">
- <!-- 标题 -->
- <view class="detail-title">{{ detail.title }}</view>
<!-- 内容 -->
<view v-if="detail.content" class="html-content">
<rich-text :nodes="detail.content"></rich-text>
diff --git a/traditionalApp/pages/home/home.vue b/traditionalApp/pages/home/home.vue
index 5648996..5faddfe 100644
--- a/traditionalApp/pages/home/home.vue
+++ b/traditionalApp/pages/home/home.vue
@@ -376,7 +376,7 @@
const userAgent = res?.data?.ua?.trim();
console.log('[goWeiZanLive] 解析目标URL:', targetUrl);
- if (res?.code !== 0 || !targetUrl || !userAgent) {
+ if (res?.code !== 0 || !targetUrl) {
console.log('[goWeiZanLive] 获取跳转地址失败,code:', res?.code, 'msg:', res?.msg);
uni.showToast({ title: res?.msg || '获取直播间地址失败', icon: 'none' });
return;
@@ -1091,12 +1091,14 @@
.course-info {
flex: 1;
+ min-width: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
.course-top {
display: flex;
+ min-width: 0;
align-items: center;
margin-top: 4rpx;
@@ -1114,6 +1116,7 @@
font-weight: bold;
color: #333;
flex: 1;
+ min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
diff --git a/traditionalApp/pages/login/login.vue b/traditionalApp/pages/login/login.vue
index 67c2a4d..2e5b0d1 100644
--- a/traditionalApp/pages/login/login.vue
+++ b/traditionalApp/pages/login/login.vue
@@ -166,13 +166,9 @@
})
/**
- * 关闭登录页,优先返回上一页,没有页面栈时回首页。
+ * 关闭登录页统一回到首页,避免从需要登录的 tabbar 页面返回后再次触发登录拦截。
*/
const handleClose = () => {
- if (getCurrentPages().length > 1) {
- uni.navigateBack()
- return
- }
uni.switchTab({
url: '/pages/home/home'
})
diff --git a/traditionalApp/pages/mine/mine.vue b/traditionalApp/pages/mine/mine.vue
index f057f8a..fd05866 100644
--- a/traditionalApp/pages/mine/mine.vue
+++ b/traditionalApp/pages/mine/mine.vue
@@ -36,7 +36,7 @@
</view>
<view class="list-section card-box">
- <view class="list-item" v-for="(item, index) in bottomMenuList" :key="`${item.title}-${index}`" @tap="goPage(item)">
+ <view class="list-item" v-for="(item, index) in bottomMenuList" :key="`${item.title}-${index}`" @tap="handleBottomMenuClick(item)">
<view class="list-left">
<image class="list-icon" :class="item.iconClass" :src="item.icon" mode="aspectFit"></image>
<text class="list-title">{{ item.title }}</text>
@@ -55,7 +55,6 @@
import { onLoad, onShow } from '@dcloudio/uni-app'
import { getNoticeList } from '../notice/service'
import { getUserCenter } from './service'
-import { getRuntimeVersionName } from '@/utils/app-version.js'
import { hasStoredSession } from '@/utils/auth-session.js'
import manifestConfig from '../../manifest.json'
@@ -104,7 +103,7 @@
const statusBarHeight = ref(0)
const unreadNoticeTotal = ref(0)
const manifestVersionName = String(manifestConfig.versionName || '')
-const appVersionText = ref(manifestVersionName)
+const appVersionText = manifestVersionName
const userCenter = ref<UserCenterData>(createDefaultUserCenter())
const userRole = computed<UserRole>(() => {
return isDoctorLikeUser(userCenter.value) ? 'doctor' : 'personal'
@@ -216,7 +215,6 @@
onLoad(() => {
const systemInfo = uni.getSystemInfoSync()
statusBarHeight.value = systemInfo.statusBarHeight || 20
- resolveAppVersion()
syncCachedUserInfo()
})
@@ -384,6 +382,13 @@
}
/**
+ * 处理底部普通菜单跳转。
+ */
+async function handleBottomMenuClick(item: MenuItem) {
+ goPage(item)
+}
+
+/**
* 统一跳转个人中心相关页面。
*/
function goPage(target: string | MenuItem) {
@@ -413,17 +418,6 @@
url: '/pages/login/login',
})
}, 200)
-}
-
-/**
- * APP 环境读取当前安装包版本,非 APP 环境使用 manifest 版本兜底。
- */
-function resolveAppVersion() {
- getRuntimeVersionName(manifestVersionName).then((versionName) => {
- appVersionText.value = versionName || manifestVersionName
- }).catch(() => {
- appVersionText.value = manifestVersionName
- })
}
/**
@@ -710,6 +704,7 @@
color: #1A1A1A;
margin-left: 22rpx;
}
+
}
}
}
diff --git a/traditionalApp/utils/app-version.js b/traditionalApp/utils/app-version.js
deleted file mode 100644
index 308eafa..0000000
--- a/traditionalApp/utils/app-version.js
+++ /dev/null
@@ -1,199 +0,0 @@
-import config from '@/config/index.js'
-
-const CHECK_VERSION_URL = '/api/app/version/check'
-let checkingVersion = false
-let updatePopupVisible = false
-let latestUpdateInfo = null
-
-/**
- * 检查 APP 是否存在管理后台配置的新版本。
- */
-export function checkAppVersionUpdate() {
- // #ifndef APP-PLUS
- return
- // #endif
- if (checkingVersion) {
- return
- }
- checkingVersion = true
- resolveRuntimeVersionInfo()
- .then((runtimeInfo) => requestVersionCheck(runtimeInfo))
- .then((payload) => {
- const updateInfo = payload && payload.code === 0 ? payload.data : null
- if (!updateInfo || updateInfo.hasUpdate !== true) {
- return
- }
- const downloadUrl = resolveUpdateUrl(updateInfo)
- if (!downloadUrl) {
- return
- }
- showUpdateModal(Object.assign({}, updateInfo, {
- downloadUrl
- }))
- })
- .catch(() => {
- })
- .finally(() => {
- checkingVersion = false
- })
-}
-
-/**
- * 读取 APP 原生版本信息,优先使用 manifest 中的 versionCode。
- */
-function resolveRuntimeVersionInfo() {
- return new Promise((resolve) => {
- const fallbackInfo = {
- platform: resolvePlatform(),
- versionCode: 0,
- versionName: ''
- }
- if (typeof plus === 'undefined' || !plus.runtime || typeof plus.runtime.getProperty !== 'function') {
- resolve(fallbackInfo)
- return
- }
- plus.runtime.getProperty(plus.runtime.appid, (info) => {
- resolve({
- platform: resolvePlatform(),
- versionCode: normalizeVersionCode(info && info.versionCode),
- versionName: normalizeText(info && info.version)
- })
- })
- })
-}
-
-/**
- * 读取当前安装 APP 的展示版本号。
- */
-export function getRuntimeVersionName(fallbackVersionName = '') {
- return resolveRuntimeVersionInfo().then((runtimeInfo) => {
- return normalizeText(runtimeInfo.versionName) || normalizeText(fallbackVersionName)
- })
-}
-
-/**
- * 将当前运行平台转换为后端版本检查平台值。
- */
-function resolvePlatform() {
- const platform = normalizeText(uni.getSystemInfoSync().platform).toLowerCase()
- return platform === 'ios' ? 'IOS' : 'ANDROID'
-}
-
-/**
- * 请求后端版本检查接口。
- */
-function requestVersionCheck(runtimeInfo) {
- return new Promise((resolve, reject) => {
- uni.request({
- url: `${config.BASE_URL}${CHECK_VERSION_URL}`,
- method: 'GET',
- data: {
- platform: runtimeInfo.platform,
- currentVersionCode: runtimeInfo.versionCode,
- currentVersionNo: runtimeInfo.versionName
- },
- header: {
- 'content-type': 'application/json'
- },
- success: (res) => {
- resolve(res.data || {})
- },
- fail: reject
- })
- })
-}
-
-/**
- * 解析当前平台可用的更新地址,iOS 只允许跳转 App Store。
- */
-function resolveUpdateUrl(updateInfo) {
- if (isIosPlatform()) {
- return normalizeText(config.APP_STORE_URL)
- }
- return normalizeText(updateInfo.downloadUrl)
-}
-
-/**
- * 展示版本更新弹窗,强制更新时禁止跳过。
- */
-function showUpdateModal(updateInfo) {
- latestUpdateInfo = updateInfo
- if (updatePopupVisible) {
- return
- }
- updatePopupVisible = true
- const forceUpdate = updateInfo.forceUpdate === true
- let confirmed = false
- uni.showModal({
- title: forceUpdate ? '发现新版本,请立即更新' : '发现新版本',
- content: buildUpdateContent(updateInfo),
- showCancel: !forceUpdate,
- cancelText: '暂不更新',
- confirmText: '立即更新',
- success: (modalResult) => {
- if (modalResult.confirm) {
- confirmed = true
- openDownloadUrl(updateInfo.downloadUrl)
- return
- }
- },
- complete: () => {
- updatePopupVisible = false
- if (forceUpdate && !confirmed) {
- setTimeout(() => {
- showUpdateModal(updateInfo)
- }, 100)
- }
- }
- })
-}
-
-/**
- * 拼接更新提示内容,确保后台更新说明能直接展示给用户。
- */
-function buildUpdateContent(updateInfo) {
- const versionNo = normalizeText(updateInfo.latestVersionNo)
- const updateNotice = normalizeText(updateInfo.updateNotice) || '请更新到最新版本后继续使用。'
- return versionNo ? `最新版本:${versionNo}\n${updateNotice}` : updateNotice
-}
-
-/**
- * 打开后台配置的安装包或下载地址。
- */
-function openDownloadUrl(downloadUrl) {
- if (!downloadUrl) {
- return
- }
- plus.runtime.openURL(downloadUrl)
-}
-
-/**
- * APP 回到前台时,强制更新场景需要继续拦截用户使用旧版本。
- */
-export function resumeForceUpdatePrompt() {
- if (latestUpdateInfo && latestUpdateInfo.forceUpdate === true && !updatePopupVisible) {
- showUpdateModal(latestUpdateInfo)
- }
-}
-
-/**
- * 判断当前是否为 iOS APP。
- */
-function isIosPlatform() {
- return resolvePlatform() === 'IOS'
-}
-
-/**
- * 规范化可选字符串。
- */
-function normalizeText(value) {
- return String(value || '').trim()
-}
-
-/**
- * 规范化原生 versionCode,避免异常值传到后端。
- */
-function normalizeVersionCode(value) {
- const versionCode = Number(value || 0)
- return Number.isFinite(versionCode) && versionCode >= 0 ? versionCode : 0
-}
--
Gitblit v1.7.1