Sfoglia il codice sorgente

交易市场平台(供应商)

wwh 3 giorni fa
parent
commit
f0260a3bec

+ 73 - 26
baqing-admin/src/main/java/com/ruoyi/web/modules/diagnosis/support/MedicalResourceValidation.java

@@ -68,9 +68,29 @@ public final class MedicalResourceValidation
68 68
         {
69 69
             row.setTeamMembers(null);
70 70
         }
71
+        blankToNull(row::getIntroduction, row::setIntroduction);
72
+        blankToNull(row::getContactPhone, row::setContactPhone);
73
+        blankToNull(row::getAffiliatedUnit, row::setAffiliatedUnit);
74
+        blankToNull(row::getDetailAddress, row::setDetailAddress);
75
+        blankToNull(row::getServiceArea, row::setServiceArea);
76
+        if (StringUtils.isEmpty(row.getPhotoFileUrl()) && StringUtils.isEmpty(row.getPhotoFilePath()))
77
+        {
78
+            row.setPhotoFileUrl(null);
79
+            row.setPhotoFilePath(null);
80
+        }
71 81
         MedicalResourceMultiValueCodec.encodeLists(row);
72 82
     }
73 83
 
84
+    private static void blankToNull(java.util.function.Supplier<String> getter,
85
+            java.util.function.Consumer<String> setter)
86
+    {
87
+        String v = getter.get();
88
+        if (v != null && v.trim().isEmpty())
89
+        {
90
+            setter.accept(null);
91
+        }
92
+    }
93
+
74 94
     private static void trim(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter)
75 95
     {
76 96
         String v = getter.get();
@@ -90,11 +110,15 @@ public final class MedicalResourceValidation
90 110
         }
91 111
     }
92 112
 
93
-    public static void validateIntroduction(String introduction)
113
+    public static void validateIntroduction(String introduction, boolean required)
94 114
     {
95 115
         if (StringUtils.isEmpty(introduction))
96 116
         {
97
-            throw new ServiceException("请填写介绍");
117
+            if (required)
118
+            {
119
+                throw new ServiceException("请填写介绍");
120
+            }
121
+            return;
98 122
         }
99 123
         if (introduction.length() > MedicalResourceRules.MAX_INTRO_LEN)
100 124
         {
@@ -102,6 +126,11 @@ public final class MedicalResourceValidation
102 126
         }
103 127
     }
104 128
 
129
+    public static void validateIntroduction(String introduction)
130
+    {
131
+        validateIntroduction(introduction, true);
132
+    }
133
+
105 134
     public static void validateContactPhone(String phone, boolean required)
106 135
     {
107 136
         if (StringUtils.isEmpty(phone))
@@ -344,8 +373,16 @@ public final class MedicalResourceValidation
344 373
         }
345 374
     }
346 375
 
347
-    public static void validatePhotoPair(String url, String path)
376
+    public static void validatePhotoPair(String url, String path, boolean required)
348 377
     {
378
+        if (StringUtils.isEmpty(url) && StringUtils.isEmpty(path))
379
+        {
380
+            if (required)
381
+            {
382
+                throw new ServiceException("请上传照片");
383
+            }
384
+            return;
385
+        }
349 386
         if (StringUtils.isEmpty(url) || StringUtils.isEmpty(path))
350 387
         {
351 388
             throw new ServiceException("请上传照片");
@@ -360,6 +397,11 @@ public final class MedicalResourceValidation
360 397
         }
361 398
     }
362 399
 
400
+    public static void validatePhotoPair(String url, String path)
401
+    {
402
+        validatePhotoPair(url, path, true);
403
+    }
404
+
363 405
     public static void validateRemark(String remark)
364 406
     {
365 407
         if (remark != null && remark.length() > MedicalResourceRules.MAX_REMARK_LEN)
@@ -372,11 +414,16 @@ public final class MedicalResourceValidation
372 414
     {
373 415
         trimFieldsForSave(row);
374 416
         validateResourceName(row.getResourceName());
375
-        validateIntroduction(row.getIntroduction());
376
-        validatePhotoPair(row.getPhotoFileUrl(), row.getPhotoFilePath());
377 417
         validateRemark(row.getRemark());
378 418
         String type = row.getResourceType();
379
-        if (MedicalResourceRules.RESOURCE_TYPE_VET.equals(type))
419
+        boolean vet = MedicalResourceRules.RESOURCE_TYPE_VET.equals(type);
420
+        boolean team = MedicalResourceRules.RESOURCE_TYPE_TEAM.equals(type);
421
+        boolean org = MedicalResourceRules.RESOURCE_TYPE_ORG.equals(type);
422
+        boolean equipment = MedicalResourceRules.RESOURCE_TYPE_EQUIPMENT.equals(type);
423
+        boolean optionalPhotoIntro = vet || team || org || equipment;
424
+        validateIntroduction(row.getIntroduction(), !optionalPhotoIntro);
425
+        validatePhotoPair(row.getPhotoFileUrl(), row.getPhotoFilePath(), !optionalPhotoIntro);
426
+        if (vet)
380 427
         {
381 428
             validateVetFields(row);
382 429
         }
@@ -400,24 +447,24 @@ public final class MedicalResourceValidation
400 447
 
401 448
     private static void validateVetFields(BizMedicalResource row)
402 449
     {
403
-        validateContactPhone(row.getContactPhone(), true);
404
-        validateAffiliatedUnit(row.getAffiliatedUnit(), true);
405
-        validateDetailAddress(row.getDetailAddress(), true);
450
+        validateContactPhone(row.getContactPhone(), false);
451
+        validateAffiliatedUnit(row.getAffiliatedUnit(), false);
452
+        validateDetailAddress(row.getDetailAddress(), false);
406 453
         validateConsultModes(row.getConsultModesList(), true);
407
-        validateServiceArea(row.getServiceArea(), true);
408
-        validateFeeStandard(row.getFeeStandard(), true);
409
-        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), true);
410
-        validateServiceWeekdays(row.getServiceWeekdaysList(), true);
454
+        validateServiceArea(row.getServiceArea(), false);
455
+        validateFeeStandard(row.getFeeStandard(), false);
456
+        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), false);
457
+        validateServiceWeekdays(row.getServiceWeekdaysList(), false);
411 458
         row.setMaxDailyAppointments(null);
412 459
     }
413 460
 
414 461
     private static void validateTeamFields(BizMedicalResource row)
415 462
     {
416
-        validateContactPhone(row.getContactPhone(), true);
417
-        validateAffiliatedUnit(row.getAffiliatedUnit(), true);
418
-        validateEstablishDate(row.getEstablishDate(), true);
419
-        validateTeamSize(row.getTeamSize(), true);
420
-        validatePersonInCharge(row.getPersonInCharge(), true);
463
+        validateContactPhone(row.getContactPhone(), false);
464
+        validateAffiliatedUnit(row.getAffiliatedUnit(), false);
465
+        validateEstablishDate(row.getEstablishDate(), false);
466
+        validateTeamSize(row.getTeamSize(), false);
467
+        validatePersonInCharge(row.getPersonInCharge(), false);
421 468
         if (row.getTeamMembers() != null
422 469
                 && row.getTeamMembers().length() > MedicalResourceRules.MAX_TEAM_MEMBERS_LEN)
423 470
         {
@@ -427,19 +474,19 @@ public final class MedicalResourceValidation
427 474
 
428 475
     private static void validateOrgFields(BizMedicalResource row)
429 476
     {
430
-        validateContactPhone(row.getContactPhone(), true);
431
-        validateDetailAddress(row.getDetailAddress(), true);
477
+        validateContactPhone(row.getContactPhone(), false);
478
+        validateDetailAddress(row.getDetailAddress(), false);
432 479
         validateOrgLevel(row.getOrgLevel(), true);
433
-        validatePersonInCharge(row.getPersonInCharge(), true);
434
-        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), true);
435
-        validateServiceWeekdays(row.getServiceWeekdaysList(), true);
436
-        validateMaxDailyAppointments(row.getMaxDailyAppointments(), true);
480
+        validatePersonInCharge(row.getPersonInCharge(), false);
481
+        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), false);
482
+        validateServiceWeekdays(row.getServiceWeekdaysList(), false);
483
+        validateMaxDailyAppointments(row.getMaxDailyAppointments(), false);
437 484
     }
438 485
 
439 486
     private static void validateEquipmentFields(BizMedicalResource row)
440 487
     {
441
-        validateAffiliatedUnit(row.getAffiliatedUnit(), true);
442
-        validateEquipmentModel(row.getEquipmentModel(), true);
488
+        validateAffiliatedUnit(row.getAffiliatedUnit(), false);
489
+        validateEquipmentModel(row.getEquipmentModel(), false);
443 490
     }
444 491
 
445 492
     public static void validateForUpdate(BizMedicalResource db)

+ 55 - 31
baqing-admin/src/main/java/com/ruoyi/web/modules/farming/support/TechResourceValidation.java

@@ -94,11 +94,15 @@ public final class TechResourceValidation
94 94
         }
95 95
     }
96 96
 
97
-    public static void validateTextRequired(String text, String label, int maxLen)
97
+    public static void validateText(String text, String label, int maxLen, boolean required)
98 98
     {
99 99
         if (StringUtils.isEmpty(text))
100 100
         {
101
-            throw new ServiceException("请填写" + label);
101
+            if (required)
102
+            {
103
+                throw new ServiceException("请填写" + label);
104
+            }
105
+            return;
102 106
         }
103 107
         if (text.length() > maxLen)
104 108
         {
@@ -106,6 +110,11 @@ public final class TechResourceValidation
106 110
         }
107 111
     }
108 112
 
113
+    public static void validateTextRequired(String text, String label, int maxLen)
114
+    {
115
+        validateText(text, label, maxLen, true);
116
+    }
117
+
109 118
     public static void validateContactPhone(String phone, boolean required)
110 119
     {
111 120
         if (StringUtils.isEmpty(phone))
@@ -198,15 +207,30 @@ public final class TechResourceValidation
198 207
         }
199 208
     }
200 209
 
201
-    public static void validatePhotoPairRequired(String url, String path)
210
+    public static void validatePhotoPair(String url, String path, boolean required)
202 211
     {
203
-        if (StringUtils.isEmpty(url) || StringUtils.isEmpty(path))
212
+        boolean hasUrl = StringUtils.isNotEmpty(url);
213
+        boolean hasPath = StringUtils.isNotEmpty(path);
214
+        if (!hasUrl && !hasPath)
215
+        {
216
+            if (required)
217
+            {
218
+                throw new ServiceException("请上传照片");
219
+            }
220
+            return;
221
+        }
222
+        if (hasUrl != hasPath)
204 223
         {
205
-            throw new ServiceException("请上传照片");
224
+            throw new ServiceException("照片 url 与 path 须同时填写或同时为空");
206 225
         }
207 226
         validateImagePath(path);
208 227
     }
209 228
 
229
+    public static void validatePhotoPairRequired(String url, String path)
230
+    {
231
+        validatePhotoPair(url, path, true);
232
+    }
233
+
210 234
     public static void validateCoverPairOptional(String url, String path)
211 235
     {
212 236
         boolean hasUrl = StringUtils.isNotEmpty(url);
@@ -291,45 +315,45 @@ public final class TechResourceValidation
291 315
 
292 316
     private static void validateExpert(BizTechResource row)
293 317
     {
294
-        validatePhotoPairRequired(row.getPhotoFileUrl(), row.getPhotoFilePath());
295
-        validateTextRequired(row.getIntroduction(), "专家介绍", TechResourceRules.MAX_INTRO_LEN);
296
-        validateContactPhone(row.getContactPhone(), true);
297
-        validateAffiliatedUnit(row.getAffiliatedUnit(), true);
298
-        validateTextRequired(row.getDetailAddress(), "详细地址", TechResourceRules.MAX_ADDRESS_LEN);
299
-        validateTextRequired(row.getServiceArea(), "服务区域", TechResourceRules.MAX_SERVICE_AREA_LEN);
300
-        validatePositiveAmount(row.getFeeStandard(), "收费标准", true);
301
-        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), true);
302
-        validateServiceWeekdays(row.getServiceWeekdaysList(), true);
318
+        validatePhotoPair(row.getPhotoFileUrl(), row.getPhotoFilePath(), false);
319
+        validateText(row.getIntroduction(), "专家介绍", TechResourceRules.MAX_INTRO_LEN, false);
320
+        validateContactPhone(row.getContactPhone(), false);
321
+        validateAffiliatedUnit(row.getAffiliatedUnit(), false);
322
+        validateText(row.getDetailAddress(), "详细地址", TechResourceRules.MAX_ADDRESS_LEN, false);
323
+        validateText(row.getServiceArea(), "服务区域", TechResourceRules.MAX_SERVICE_AREA_LEN, false);
324
+        validatePositiveAmount(row.getFeeStandard(), "收费标准", false);
325
+        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), false);
326
+        validateServiceWeekdays(row.getServiceWeekdaysList(), false);
303 327
     }
304 328
 
305 329
     private static void validateAchievement(BizTechResource row)
306 330
     {
307 331
         validateCoverPairOptional(row.getCoverFileUrl(), row.getCoverFilePath());
308
-        validateTextRequired(row.getResearchDirection(), "研究方向", TechResourceRules.MAX_DIRECTION_LEN);
309
-        validateTextRequired(row.getAchievementSummary(), "成果摘要", TechResourceRules.MAX_INTRO_LEN);
310
-        validateTextRequired(row.getKeyTechPrinciple(), "关键技术原理", TechResourceRules.MAX_INTRO_LEN);
311
-        validateTextRequired(row.getTechAdvantage(), "技术优势", TechResourceRules.MAX_INTRO_LEN);
312
-        validateTextRequired(row.getCompletionUnit(), "完成单位", TechResourceRules.MAX_UNIT_LEN);
332
+        validateText(row.getResearchDirection(), "研究方向", TechResourceRules.MAX_DIRECTION_LEN, true);
333
+        validateText(row.getAchievementSummary(), "成果摘要", TechResourceRules.MAX_INTRO_LEN, false);
334
+        validateText(row.getKeyTechPrinciple(), "关键技术原理", TechResourceRules.MAX_INTRO_LEN, false);
335
+        validateText(row.getTechAdvantage(), "技术优势", TechResourceRules.MAX_INTRO_LEN, false);
336
+        validateText(row.getCompletionUnit(), "完成单位", TechResourceRules.MAX_UNIT_LEN, false);
313 337
     }
314 338
 
315 339
     private static void validateInstrument(BizTechResource row)
316 340
     {
317
-        validatePhotoPairRequired(row.getPhotoFileUrl(), row.getPhotoFilePath());
318
-        validateTextRequired(row.getIntroduction(), "仪器介绍", TechResourceRules.MAX_INTRO_LEN);
319
-        validateAffiliatedUnit(row.getAffiliatedUnit(), true);
320
-        validateTextRequired(row.getStorageLocation(), "存放地点", TechResourceRules.MAX_ADDRESS_LEN);
321
-        validateTextRequired(row.getReservationProcess(), "预约流程", TechResourceRules.MAX_INTRO_LEN);
322
-        validateTextRequired(row.getPersonInCharge(), "负责人", TechResourceRules.MAX_NAME_LEN_SHORT);
323
-        validateContactPhone(row.getContactPhone(), true);
324
-        validateTextRequired(row.getInstrumentModel(), "仪器型号", TechResourceRules.MAX_MODEL_LEN);
325
-        validatePositiveAmount(row.getBorrowFee(), "借用金额", true);
326
-        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), true);
327
-        validateServiceWeekdays(row.getServiceWeekdaysList(), true);
341
+        validatePhotoPair(row.getPhotoFileUrl(), row.getPhotoFilePath(), false);
342
+        validateText(row.getIntroduction(), "仪器介绍", TechResourceRules.MAX_INTRO_LEN, false);
343
+        validateAffiliatedUnit(row.getAffiliatedUnit(), false);
344
+        validateText(row.getStorageLocation(), "存放地点", TechResourceRules.MAX_ADDRESS_LEN, false);
345
+        validateText(row.getReservationProcess(), "预约流程", TechResourceRules.MAX_INTRO_LEN, false);
346
+        validateText(row.getPersonInCharge(), "负责人", TechResourceRules.MAX_NAME_LEN_SHORT, false);
347
+        validateContactPhone(row.getContactPhone(), false);
348
+        validateText(row.getInstrumentModel(), "仪器型号", TechResourceRules.MAX_MODEL_LEN, false);
349
+        validatePositiveAmount(row.getBorrowFee(), "借用金额", false);
350
+        validateServiceTimeRange(row.getServiceStartTime(), row.getServiceEndTime(), false);
351
+        validateServiceWeekdays(row.getServiceWeekdaysList(), false);
328 352
     }
329 353
 
330 354
     private static void validateVideo(BizTechResource row)
331 355
     {
332
-        validateTextRequired(row.getIntroduction(), "课程简介", TechResourceRules.MAX_INTRO_LEN);
356
+        validateText(row.getIntroduction(), "课程简介", TechResourceRules.MAX_INTRO_LEN, false);
333 357
         if (StringUtils.isEmpty(row.getCourseTopic()))
334 358
         {
335 359
             throw new ServiceException("课程主题不能为空");

+ 3 - 0
baqing-admin/src/test/java/com/ruoyi/web/modules/diagnosis/MedicalResourceTestSamples.java

@@ -79,6 +79,9 @@ public final class MedicalResourceTestSamples
79 79
         row.setDetailAddress("中心街10号");
80 80
         row.setOrgLevel(MedicalResourceRules.ORG_LEVEL_CLINIC);
81 81
         row.setMaxDailyAppointments(50);
82
+        row.setServiceStartTime("08:00");
83
+        row.setServiceEndTime("18:00");
84
+        row.setServiceWeekdaysList(Arrays.asList(1, 2, 3, 4, 5));
82 85
         row.setPublishStatus(MedicalResourceRules.PUBLISH_STATUS_DRAFT);
83 86
         row.setAccountAssigned(MedicalResourceRules.ACCOUNT_ASSIGNED_NO);
84 87
         return row;

+ 169 - 11
baqing-admin/src/test/java/com/ruoyi/web/modules/diagnosis/support/MedicalResourceValidationTest.java

@@ -17,6 +17,34 @@ import com.ruoyi.web.modules.diagnosis.domain.BizMedicalResource;
17 17
 class MedicalResourceValidationTest
18 18
 {
19 19
 
20
+    @Test
21
+    @DisplayName("服务周日选填")
22
+    void serviceWeekdaysOptional()
23
+    {
24
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateServiceWeekdays(null, false));
25
+    }
26
+
27
+    @Test
28
+    @DisplayName("兽医仅姓名与接诊方式可保存")
29
+    void vetOnlyRequiredFields()
30
+    {
31
+        BizMedicalResource row = new BizMedicalResource();
32
+        row.setResourceType(MedicalResourceRules.RESOURCE_TYPE_VET);
33
+        row.setResourceName("测试兽医");
34
+        row.setConsultModesList(Arrays.asList(1));
35
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
36
+    }
37
+
38
+    @Test
39
+    @DisplayName("兽医填写服务时段非法仍失败")
40
+    void vetInvalidServiceTime()
41
+    {
42
+        BizMedicalResource row = MedicalResourceTestSamples.sampleVetDraft();
43
+        row.setServiceStartTime("18:00");
44
+        row.setServiceEndTime("08:00");
45
+        assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
46
+    }
47
+
20 48
     @Test
21 49
     @DisplayName("兽医服务时段")
22 50
     void serviceTimeRange()
@@ -24,10 +52,8 @@ class MedicalResourceValidationTest
24 52
         assertDoesNotThrow(() -> MedicalResourceValidation.validateServiceTimeRange("08:00", "18:00", true));
25 53
         assertThrows(ServiceException.class,
26 54
                 () -> MedicalResourceValidation.validateServiceTimeRange("18:00", "08:00", true));
55
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateServiceTimeRange(null, null, false));
27 56
     }
28
-
29
-    @Test
30
-    @DisplayName("手机号")
31 57
     void contactPhone()
32 58
     {
33 59
         assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateContactPhone("123", true));
@@ -44,26 +70,57 @@ class MedicalResourceValidationTest
44 70
     }
45 71
 
46 72
     @Test
47
-    @DisplayName("设备类型不要求手机")
73
+    @DisplayName("设备不要求手机")
48 74
     void equipmentNoPhone()
49 75
     {
50 76
         BizMedicalResource row = new BizMedicalResource();
51 77
         row.setResourceType(MedicalResourceRules.RESOURCE_TYPE_EQUIPMENT);
52 78
         row.setResourceName("B超仪");
53
-        row.setPhotoFileUrl(MedicalResourceTestSamples.PHOTO_URL);
54
-        row.setPhotoFilePath(MedicalResourceTestSamples.PHOTO_PATH);
55
-        row.setIntroduction("设备介绍");
56
-        row.setAffiliatedUnit("县医院");
57
-        row.setEquipmentModel("A1");
58 79
         assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
59 80
     }
60 81
 
61 82
     @Test
62
-    @DisplayName("兽医缺收费失败")
63
-    void vetMissingFee()
83
+    @DisplayName("设备仅设备名称可保存")
84
+    void equipmentOptionalProfileFields()
85
+    {
86
+        BizMedicalResource row = new BizMedicalResource();
87
+        row.setResourceType(MedicalResourceRules.RESOURCE_TYPE_EQUIPMENT);
88
+        row.setResourceName("B超仪");
89
+        row.setPhotoFileUrl(null);
90
+        row.setPhotoFilePath(null);
91
+        row.setIntroduction(null);
92
+        row.setEquipmentModel(null);
93
+        row.setAffiliatedUnit(null);
94
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
95
+    }
96
+
97
+    @Test
98
+    @DisplayName("设备填写型号超长失败")
99
+    void equipmentInvalidModel()
100
+    {
101
+        BizMedicalResource row = new BizMedicalResource();
102
+        row.setResourceType(MedicalResourceRules.RESOURCE_TYPE_EQUIPMENT);
103
+        row.setResourceName("B超仪");
104
+        row.setEquipmentModel("12345678901");
105
+        assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
106
+    }
107
+
108
+    @Test
109
+    @DisplayName("兽医缺收费可保存")
110
+    void vetMissingFeeAllowed()
64 111
     {
65 112
         BizMedicalResource row = MedicalResourceTestSamples.sampleVetDraft();
66 113
         row.setFeeStandard(null);
114
+        row.setServiceArea(null);
115
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
116
+    }
117
+
118
+    @Test
119
+    @DisplayName("兽医填写收费须为正数")
120
+    void vetInvalidFee()
121
+    {
122
+        BizMedicalResource row = MedicalResourceTestSamples.sampleVetDraft();
123
+        row.setFeeStandard(BigDecimal.ZERO);
67 124
         assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
68 125
     }
69 126
 
@@ -119,6 +176,107 @@ class MedicalResourceValidationTest
119 176
         assertNull(row.getMaxDailyAppointments());
120 177
     }
121 178
 
179
+    @Test
180
+    @DisplayName("兽医仅必填业务字段可保存")
181
+    void vetOptionalProfileFields()
182
+    {
183
+        BizMedicalResource row = MedicalResourceTestSamples.sampleVetDraft();
184
+        row.setPhotoFileUrl(null);
185
+        row.setPhotoFilePath(null);
186
+        row.setIntroduction(null);
187
+        row.setContactPhone(null);
188
+        row.setAffiliatedUnit(null);
189
+        row.setDetailAddress(null);
190
+        row.setServiceArea(null);
191
+        row.setFeeStandard(null);
192
+        row.setServiceStartTime(null);
193
+        row.setServiceEndTime(null);
194
+        row.setServiceWeekdaysList(null);
195
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
196
+    }
197
+
198
+    @Test
199
+    @DisplayName("兽医选填手机号格式仍校验")
200
+    void vetOptionalPhoneFormat()
201
+    {
202
+        BizMedicalResource row = MedicalResourceTestSamples.sampleVetDraft();
203
+        row.setContactPhone("123");
204
+        assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
205
+    }
206
+
207
+    @Test
208
+    @DisplayName("专家团队仅团队名称可保存")
209
+    void teamOptionalProfileFields()
210
+    {
211
+        BizMedicalResource row = MedicalResourceTestSamples.sampleTeamDraft();
212
+        row.setPhotoFileUrl(null);
213
+        row.setPhotoFilePath(null);
214
+        row.setIntroduction(null);
215
+        row.setContactPhone(null);
216
+        row.setAffiliatedUnit(null);
217
+        row.setEstablishDate(null);
218
+        row.setTeamSize(null);
219
+        row.setPersonInCharge(null);
220
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
221
+    }
222
+
223
+    @Test
224
+    @DisplayName("专家团队填写规模须为正整数")
225
+    void teamInvalidSize()
226
+    {
227
+        BizMedicalResource row = MedicalResourceTestSamples.sampleTeamDraft();
228
+        row.setTeamSize(0);
229
+        assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
230
+    }
231
+
232
+    @Test
233
+    @DisplayName("诊疗机构资料选填保留级别")
234
+    void orgOptionalProfileFields()
235
+    {
236
+        BizMedicalResource row = MedicalResourceTestSamples.sampleOrgDraft();
237
+        row.setPhotoFileUrl(null);
238
+        row.setPhotoFilePath(null);
239
+        row.setIntroduction(null);
240
+        row.setDetailAddress(null);
241
+        row.setPersonInCharge(null);
242
+        row.setContactPhone(null);
243
+        row.setMaxDailyAppointments(null);
244
+        row.setServiceStartTime(null);
245
+        row.setServiceEndTime(null);
246
+        row.setServiceWeekdaysList(null);
247
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
248
+    }
249
+
250
+    @Test
251
+    @DisplayName("诊疗机构缺级别失败")
252
+    void orgMissingLevel()
253
+    {
254
+        BizMedicalResource row = new BizMedicalResource();
255
+        row.setResourceType(MedicalResourceRules.RESOURCE_TYPE_ORG);
256
+        row.setResourceName("县动物医院");
257
+        assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
258
+    }
259
+
260
+    @Test
261
+    @DisplayName("诊疗机构名称与级别可保存")
262
+    void orgNameAndLevel()
263
+    {
264
+        BizMedicalResource row = new BizMedicalResource();
265
+        row.setResourceType(MedicalResourceRules.RESOURCE_TYPE_ORG);
266
+        row.setResourceName("县动物医院");
267
+        row.setOrgLevel(MedicalResourceRules.ORG_LEVEL_CLINIC);
268
+        assertDoesNotThrow(() -> MedicalResourceValidation.validateRowForSave(row));
269
+    }
270
+
271
+    @Test
272
+    @DisplayName("诊疗机构填写单日接诊须为正整数")
273
+    void orgInvalidMaxDaily()
274
+    {
275
+        BizMedicalResource row = MedicalResourceTestSamples.sampleOrgDraft();
276
+        row.setMaxDailyAppointments(0);
277
+        assertThrows(ServiceException.class, () -> MedicalResourceValidation.validateRowForSave(row));
278
+    }
279
+
122 280
     @Test
123 281
     @DisplayName("接诊方式至少一项")
124 282
     void consultModes()

+ 130 - 5
baqing-admin/src/test/java/com/ruoyi/web/modules/farming/support/TechResourceValidationTest.java

@@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
4 4
 import static org.junit.jupiter.api.Assertions.assertThrows;
5 5
 
6 6
 import java.math.BigDecimal;
7
-import java.util.Arrays;
8 7
 import org.junit.jupiter.api.DisplayName;
9 8
 import org.junit.jupiter.api.Test;
10 9
 import com.ruoyi.common.exception.ServiceException;
@@ -25,11 +24,39 @@ class TechResourceValidationTest
25 24
     }
26 25
 
27 26
     @Test
28
-    @DisplayName("成果缺摘要失败")
29
-    void achievementMissingSummary()
27
+    @DisplayName("服务周日选填")
28
+    void serviceWeekdaysOptional()
29
+    {
30
+        assertDoesNotThrow(() -> TechResourceValidation.validateServiceWeekdays(null, false));
31
+    }
32
+
33
+    @Test
34
+    @DisplayName("成果缺研究方向失败")
35
+    void achievementMissingDirection()
36
+    {
37
+        BizTechResource row = new BizTechResource();
38
+        row.setResourceType(TechResourceRules.RESOURCE_TYPE_ACHIEVEMENT);
39
+        row.setResourceName("育种新技术成果");
40
+        assertThrows(ServiceException.class, () -> TechResourceValidation.validateRowForSave(row));
41
+    }
42
+
43
+    @Test
44
+    @DisplayName("成果名称与研究方向可保存")
45
+    void achievementNameAndDirection()
46
+    {
47
+        BizTechResource row = new BizTechResource();
48
+        row.setResourceType(TechResourceRules.RESOURCE_TYPE_ACHIEVEMENT);
49
+        row.setResourceName("育种新技术成果");
50
+        row.setResearchDirection("繁育");
51
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(row));
52
+    }
53
+
54
+    @Test
55
+    @DisplayName("成果摘要超长失败")
56
+    void achievementSummaryTooLong()
30 57
     {
31 58
         BizTechResource row = TechResourceTestSamples.sampleAchievementDraft();
32
-        row.setAchievementSummary(null);
59
+        row.setAchievementSummary(repeat('x', 501));
33 60
         assertThrows(ServiceException.class, () -> TechResourceValidation.validateRowForSave(row));
34 61
     }
35 62
 
@@ -42,6 +69,15 @@ class TechResourceValidationTest
42 69
         assertThrows(ServiceException.class, () -> TechResourceValidation.validateRowForSave(row));
43 70
     }
44 71
 
72
+    @Test
73
+    @DisplayName("课程简介选填")
74
+    void videoOptionalIntro()
75
+    {
76
+        BizTechResource row = TechResourceTestSamples.sampleVideoDraft();
77
+        row.setIntroduction(null);
78
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(row));
79
+    }
80
+
45 81
     @Test
46 82
     @DisplayName("借用金额须为正数")
47 83
     void borrowFee()
@@ -50,6 +86,85 @@ class TechResourceValidationTest
50 86
                 () -> TechResourceValidation.validatePositiveAmount(BigDecimal.ZERO, "借用金额", true));
51 87
     }
52 88
 
89
+    @Test
90
+    @DisplayName("专家仅姓名可保存")
91
+    void expertOnlyName()
92
+    {
93
+        BizTechResource row = new BizTechResource();
94
+        row.setResourceType(TechResourceRules.RESOURCE_TYPE_EXPERT);
95
+        row.setResourceName("测试专家");
96
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(row));
97
+    }
98
+
99
+    @Test
100
+    @DisplayName("专家资料选填")
101
+    void expertOptionalProfileFields()
102
+    {
103
+        BizTechResource row = TechResourceTestSamples.sampleExpertDraft();
104
+        row.setPhotoFileUrl(null);
105
+        row.setPhotoFilePath(null);
106
+        row.setIntroduction(null);
107
+        row.setContactPhone(null);
108
+        row.setAffiliatedUnit(null);
109
+        row.setDetailAddress(null);
110
+        row.setServiceArea(null);
111
+        row.setFeeStandard(null);
112
+        row.setServiceStartTime(null);
113
+        row.setServiceEndTime(null);
114
+        row.setServiceWeekdaysList(null);
115
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(row));
116
+    }
117
+
118
+    @Test
119
+    @DisplayName("专家填写服务时段非法仍失败")
120
+    void expertInvalidServiceTime()
121
+    {
122
+        BizTechResource row = TechResourceTestSamples.sampleExpertDraft();
123
+        row.setServiceStartTime("18:00");
124
+        row.setServiceEndTime("08:00");
125
+        assertThrows(ServiceException.class, () -> TechResourceValidation.validateRowForSave(row));
126
+    }
127
+
128
+    @Test
129
+    @DisplayName("专家填写收费须为正数")
130
+    void expertInvalidFee()
131
+    {
132
+        BizTechResource row = TechResourceTestSamples.sampleExpertDraft();
133
+        row.setFeeStandard(BigDecimal.ZERO);
134
+        assertThrows(ServiceException.class, () -> TechResourceValidation.validateRowForSave(row));
135
+    }
136
+
137
+    @Test
138
+    @DisplayName("共享仪器仅名称可保存")
139
+    void instrumentOnlyName()
140
+    {
141
+        BizTechResource row = new BizTechResource();
142
+        row.setResourceType(TechResourceRules.RESOURCE_TYPE_INSTRUMENT);
143
+        row.setResourceName("显微镜");
144
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(row));
145
+    }
146
+
147
+    @Test
148
+    @DisplayName("共享仪器资料选填")
149
+    void instrumentOptionalProfileFields()
150
+    {
151
+        BizTechResource row = TechResourceTestSamples.sampleInstrumentDraft();
152
+        row.setPhotoFileUrl(null);
153
+        row.setPhotoFilePath(null);
154
+        row.setIntroduction(null);
155
+        row.setInstrumentModel(null);
156
+        row.setAffiliatedUnit(null);
157
+        row.setStorageLocation(null);
158
+        row.setReservationProcess(null);
159
+        row.setPersonInCharge(null);
160
+        row.setContactPhone(null);
161
+        row.setBorrowFee(null);
162
+        row.setServiceStartTime(null);
163
+        row.setServiceEndTime(null);
164
+        row.setServiceWeekdaysList(null);
165
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(row));
166
+    }
167
+
53 168
     @Test
54 169
     @DisplayName("类型字段矩阵")
55 170
     void typeMatrix()
@@ -58,7 +173,7 @@ class TechResourceValidationTest
58 173
         assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(achievement));
59 174
         BizTechResource expert = TechResourceTestSamples.sampleExpertDraft();
60 175
         expert.setFeeStandard(null);
61
-        assertThrows(ServiceException.class, () -> TechResourceValidation.validateRowForSave(expert));
176
+        assertDoesNotThrow(() -> TechResourceValidation.validateRowForSave(expert));
62 177
     }
63 178
 
64 179
     @Test
@@ -86,4 +201,14 @@ class TechResourceValidationTest
86 201
         expert.setAccountAssigned(TechResourceRules.ACCOUNT_ASSIGNED_YES);
87 202
         assertThrows(ServiceException.class, () -> TechResourceValidation.validateForAssignAccount(expert));
88 203
     }
204
+
205
+    private static String repeat(char c, int n)
206
+    {
207
+        StringBuilder sb = new StringBuilder(n);
208
+        for (int i = 0; i < n; i++)
209
+        {
210
+            sb.append(c);
211
+        }
212
+        return sb.toString();
213
+    }
89 214
 }

File diff suppressed because it is too large
+ 4 - 4
doc/牧业养殖科技服务/畜牧科技资源管理/畜牧科技资源管理功能需求-草稿.md


+ 39 - 39
doc/牧业养殖科技服务/畜牧科技资源管理/畜牧科技资源管理功能需求.md

@@ -168,7 +168,7 @@ flowchart TD
168 168
 | 初始状态 | **未发布** |
169 169
 | 图片 | 单图;**jpg / jpeg / png**;**≤ 10MB**(专家照片、仪器照片、技术成果封面、课程封面等适用) |
170 170
 | 视频 | 仅视频课程:单文件;**mp4**;**≤ 30MB** |
171
-| 联系方式 | 该类型要求的字段 **必填**,且符合**大陆手机号**格式 |
171
+| 联系方式 | 该类型要求的字段若填写须符合**大陆手机号**格式 |
172 172
 | 文本 | 字数按**字符**计;提交前 trim;空字符串视为未填 |
173 173
 
174 174
 ---
@@ -178,24 +178,24 @@ flowchart TD
178 178
 | 业务字段 | 专家 | 技术成果 | 共享仪器 | 视频课程 |
179 179
 | --- | --- | --- | --- | --- |
180 180
 | 展示名称 | ✓ | ✓ | ✓ | ✓ |
181
-| 主图/照片 | ✓ | — | ✓ | — |
181
+| 主图/照片 | ○ | — | ○ | — |
182 182
 | 封面 | — | ○ | — | ○ |
183
-| 介绍/摘要类长文本 | ✓ | ✓(多项) | ✓ | ✓ |
184
-| 联系方式 | ✓ | — | ✓ | — |
185
-| 隶属单位 | ✓ | — | ✓ | — |
186
-| 详细地址 |  | — | — | — |
187
-| 服务区域 |  | — | — | — |
188
-| 收费标准/借用金额(元/小时,正数) | ✓ | — | ✓ | — |
189
-| 服务时段 / 服务周日 | ✓ | — | ✓ | — |
183
+| 介绍/摘要类长文本 | ○ | ○(多项) | ○ | ○ |
184
+| 联系方式 | ○ | — | ○ | — |
185
+| 隶属单位 | ○ | — | ○ | — |
186
+| 详细地址 |  | — | — | — |
187
+| 服务区域 |  | — | — | — |
188
+| 收费标准/借用金额(元/小时,正数) | ○ | — | ○ | — |
189
+| 服务时段 / 服务周日 | ○ | — | ○ | — |
190 190
 | 研究方向 | — | ✓ | — | — |
191
-| 关键技术原理 / 技术优势 | — |  | — | — |
192
-| 完成单位 | — |  | — | — |
193
-| 仪器型号 | — | — |  | — |
194
-| 存放地点 / 预约流程 / 负责人 | — | — |  | — |
191
+| 关键技术原理 / 技术优势 | — |  | — | — |
192
+| 完成单位 | — |  | — | — |
193
+| 仪器型号 | — | — |  | — |
194
+| 存放地点 / 预约流程 / 负责人 | — | — |  | — |
195 195
 | 课程主题 | — | — | — | ✓ |
196 196
 | 视频文件 | — | — | — | ✓ |
197 197
 
198
-> **○** 表示选填;**✓** 表示该类型下必填(若列有对应字段)。
198
+> **○** 表示选填;**✓** 表示该类型下必填(若列有对应字段)。各类型资料类字段见 **§5.4**~**§5.7**。
199 199
 
200 200
 ---
201 201
 
@@ -204,15 +204,15 @@ flowchart TD
204 204
 | 字段 | 规则 |
205 205
 | --- | --- |
206 206
 | 专家姓名 | **必填**;**1~10** 字 |
207
-| 专家照片 | **必填**;**§5.2** 图片规则 |
208
-| 专家介绍 | **必填**;**1~500** 字;宜包含资质、从业年限、专业领域、研究方向、技术特长等 |
209
-| 联系方式 | **必填**;手机号 |
210
-| 隶属单位 | **必填**;**1~20** 字 |
211
-| 详细地址 | **必填**;**1~100** 字 |
212
-| 服务区域 | **必填**;**1~100** 字 |
213
-| 收费标准 | **必填**;**正数**;单位 **元/小时** |
214
-| 服务时段 | **必填**;**HH:mm** 起止;结束时间 **≥** 开始时间 |
215
-| 服务周日 | **必填**;**多选** 周一至周日;至少选一天 |
207
+| 专家照片 | **选填**;若上传须符合 **§5.2** 图片规则 |
208
+| 专家介绍 | **选填**;若有内容 **≤500** 字;宜包含资质、从业年限、专业领域、研究方向、技术特长等 |
209
+| 联系方式 | **选填**;若填写须为大陆手机号 |
210
+| 隶属单位 | **选填**;若有内容 **≤20** 字 |
211
+| 详细地址 | **选填**;若有内容 **≤100** 字 |
212
+| 服务区域 | **选填**;若有内容 **≤100** 字 |
213
+| 收费标准 | **选填**;若填写须为**正数**;单位 **元/小时** |
214
+| 服务时段 | **选填**;若填写须为 **HH:mm** 起止;结束时间 **≥** 开始时间 |
215
+| 服务周日 | **选填**;**多选** 周一至周日 |
216 216
 
217 217
 ---
218 218
 
@@ -222,10 +222,10 @@ flowchart TD
222 222
 | --- | --- |
223 223
 | 成果名称 | **必填**;**1~20** 字 |
224 224
 | 研究方向 | **必填**;**可输入下拉**;预设:**繁育、饲养、防疫、粪污处理**;可输入其他方向;**1~20** 字 |
225
-| 成果摘要 | **必填**;**1~500** 字 |
226
-| 关键技术原理 | **必填**;**1~500** 字 |
227
-| 技术优势 | **必填**;**1~500** 字 |
228
-| 完成单位 | **必填**;**1~20** 字 |
225
+| 成果摘要 | **选填**;若有内容 **≤500** 字 |
226
+| 关键技术原理 | **选填**;若有内容 **≤500** 字 |
227
+| 技术优势 | **选填**;若有内容 **≤500** 字 |
228
+| 完成单位 | **选填**;若有内容 **≤20** 字 |
229 229
 | 封面 | **选填**;**§5.2** 图片规则 |
230 230
 
231 231
 ---
@@ -235,17 +235,17 @@ flowchart TD
235 235
 | 字段 | 规则 |
236 236
 | --- | --- |
237 237
 | 仪器名称 | **必填**;**1~10** 字 |
238
-| 仪器型号 | **必填**;**1~10** 字 |
239
-| 仪器照片 | **必填**;**§5.2** 图片规则 |
240
-| 仪器介绍 | **必填**;**1~500** 字 |
241
-| 隶属单位 | **必填**;**1~20** 字 |
242
-| 存放地点 | **必填**;**1~100** 字 |
243
-| 预约流程 | **必填**;**1~500** 字 |
244
-| 负责人 | **必填**;**1~10** 字 |
245
-| 联系方式 | **必填**;手机号 |
246
-| 借用金额 | **必填**;**正数**;单位 **元/小时** |
247
-| 服务时段 | **必填**;**HH:mm** 起止;结束时间 **≥** 开始时间 |
248
-| 服务周日 | **必填**;**多选** 周一至周日;至少选一天 |
238
+| 仪器型号 | **选填**;若有内容 **≤10** 字 |
239
+| 仪器照片 | **选填**;若上传须符合 **§5.2** 图片规则 |
240
+| 仪器介绍 | **选填**;若有内容 **≤500** 字 |
241
+| 隶属单位 | **选填**;若有内容 **≤20** 字 |
242
+| 存放地点 | **选填**;若有内容 **≤100** 字 |
243
+| 预约流程 | **选填**;若有内容 **≤500** 字 |
244
+| 负责人 | **选填**;若有内容 **≤10** 字 |
245
+| 联系方式 | **选填**;若填写须为大陆手机号 |
246
+| 借用金额 | **选填**;若填写须为**正数**;单位 **元/小时** |
247
+| 服务时段 | **选填**;若填写须为 **HH:mm** 起止;结束时间 **≥** 开始时间 |
248
+| 服务周日 | **选填**;**多选** 周一至周日 |
249 249
 
250 250
 ---
251 251
 
@@ -254,7 +254,7 @@ flowchart TD
254 254
 | 字段 | 规则 |
255 255
 | --- | --- |
256 256
 | 课程标题 | **必填**;**1~20** 字 |
257
-| 课程简介 | **必填**;**1~500** 字 |
257
+| 课程简介 | **选填**;若有内容 **≤500** 字 |
258 258
 | 课程主题 | **必填**;**下拉单选**;选项来自 `GET /category/informationCategory/children?parentCode=005&categoryType=8`(展示 `name`,落库 `code`,如 `005001` 基础养殖) |
259 259
 | 视频文件 | **必填**;**§5.2** 视频规则 |
260 260
 | 封面 | **选填**;**§5.2** 图片规则 |

+ 9 - 8
doc/牧业养殖科技服务/畜牧科技资源管理/畜牧科技资源管理技术方案.md

@@ -159,16 +159,17 @@ CREATE TABLE `biz_tech_resource` (
159 159
 | 字段 | 专家(004005) | 技术成果(004006) | 共享仪器(004007) | 视频课程(004008) |
160 160
 | --- | --- | --- | --- | --- |
161 161
 | `resource_name` | ✓ | ✓ | ✓ | ✓ |
162
-| `photo_*` | ✓ | — | ✓ | — |
162
+| `photo_*` | ○ | — | ○ | — |
163 163
 | `cover_*` | — | ○ | — | ○ |
164 164
 | `video_*` | — | — | — | ✓ |
165
-| `introduction` | ✓ | — | ✓ | ✓ |
166
-| `achievement_summary` / `key_tech_principle` / `tech_advantage` | — | ✓ | — | — |
167
-| `research_direction` / `completion_unit` | — | ✓ | — | — |
168
-| `contact_phone` | ✓ | — | ✓ | — |
169
-| `affiliated_unit` | ✓ | — | ✓ | — |
170
-| `detail_address` / `service_area` / `fee_standard` | ✓ | — | — | — |
171
-| `service_*` / `borrow_fee` / `instrument_model` / `storage_location` / `reservation_process` / `person_in_charge` | — | — | ✓ | — |
165
+| `introduction` | ○ | — | ○ | ○ |
166
+| `achievement_summary` / `key_tech_principle` / `tech_advantage` | — | ○ | — | — |
167
+| `research_direction` / `completion_unit` | — | ✓/○ | — | — |
168
+| `contact_phone` | ○ | — | ○ | — |
169
+| `affiliated_unit` | ○ | — | ○ | — |
170
+| `detail_address` / `service_area` / `fee_standard` | ○ | — | — | — |
171
+| `service_start_time` / `service_end_time` / `service_weekdays` | ○ | — | ○ | — |
172
+| `borrow_fee` / `instrument_model` / `storage_location` / `reservation_process` / `person_in_charge` | — | — | ○ | — |
172 173
 | `course_topic` | — | — | — | ✓ |
173 174
 
174 175
 > **○** 选填;**✓** 该类型必填(应用层)。

+ 12 - 7
doc/牧业养殖科技服务/畜牧科技资源管理/畜牧科技资源管理测试用例.md

@@ -34,9 +34,14 @@
34 34
 | ZCZX-KJZYGL-UT-002 | 参数校验 | 手机号 | 单元测试 | JUnit5 | §5.2 | 无 | `123`;`13800138000` | 非法失败;合法通过 |
35 35
 | ZCZX-KJZYGL-UT-003 | 参数校验 | 名称长度 | 单元测试 | JUnit5 | §5.4~5.7 | 无 | 专家名 11 字;成果名 21 字;仪器名 10 字 | 超限失败;合法通过 |
36 36
 | ZCZX-KJZYGL-UT-004 | 参数校验 | 收费标准/借用金额 | 单元测试 | JUnit5 | §5.4、§5.6 | 无 | `feeStandard`/`borrowFee` 为 0、负数、正数 | 非正数失败;正数通过 |
37
-| ZCZX-KJZYGL-UT-005 | 参数校验 | 服务周日 | 单元测试 | JUnit5 | §5.4 | 无 | 空数组;`[1]` | 空失败;至少一天通过 |
37
+| ZCZX-KJZYGL-UT-005 | 参数校验 | 服务周日 | 单元测试 | JUnit5 | §5.4 | 无 | `required=true` 时空数组失败;`required=false` 时通过 | 与必填开关一致 |
38 38
 | ZCZX-KJZYGL-UT-006 | 参数校验 | 技术成果三项长文本 | 单元测试 | JUnit5 | §5.5 | 无 | 摘要/原理/优势 501 字;合法 500 字 | 超长失败;通过 |
39
-| ZCZX-KJZYGL-UT-007 | 参数校验 | 类型字段矩阵 | 单元测试 | JUnit5 | §5.3、§2.1 | 无 | 成果带 `contactPhone`;专家缺 `feeStandard`;课程缺 `videoFilePath` | 分别失败;矩阵通过 |
39
+| ZCZX-KJZYGL-UT-006a | 参数校验 | 成果缺研究方向 | 单元测试 | JUnit5 | §5.5 | 无 | 仅成果名称 | 失败 |
40
+| ZCZX-KJZYGL-UT-006a2 | 参数校验 | 成果名称与方向 | 单元测试 | JUnit5 | §5.5 | 无 | 成果名称+研究方向 | 通过 |
41
+| ZCZX-KJZYGL-UT-006b | 参数校验 | 专家资料选填 | 单元测试 | JUnit5 | §5.4 | 无 | 仅专家姓名 | 通过 |
42
+| ZCZX-KJZYGL-UT-006c | 参数校验 | 仪器资料选填 | 单元测试 | JUnit5 | §5.6 | 无 | 仅仪器名称 | 通过 |
43
+| ZCZX-KJZYGL-UT-006d | 参数校验 | 课程简介选填 | 单元测试 | JUnit5 | §5.7 | 无 | 标题+主题+视频;无简介 | 通过 |
44
+| ZCZX-KJZYGL-UT-007 | 参数校验 | 类型字段矩阵 | 单元测试 | JUnit5 | §5.3、§2.1 | 无 | 成果带 `contactPhone`;专家缺 `feeStandard`;课程缺 `videoFilePath` | 专家/成果通过;课程缺视频失败 |
40 45
 | ZCZX-KJZYGL-UT-008 | 参数校验 | 图片/视频路径 | 单元测试 | JUnit5 | §5.2 | 无 | 非 `/profile`;jpg 图;mp4 视频 | 非法失败;合法通过 |
41 46
 | ZCZX-KJZYGL-UT-009 | 发布态 | 已发布不可改 | 单元测试 | JUnit5 | §5.8、§6 | `publish_status=1` | `validateForUpdate` | 失败 |
42 47
 | ZCZX-KJZYGL-UT-010 | 发布态 | 仅已发布可下架 | 单元测试 | JUnit5 | §5.11 | 未发布/已发布 | `validateOffline` | 仅已发布通过 |
@@ -67,11 +72,11 @@
67 72
 | ZCZX-KJZYGL-API-004 | 列表 | 已下架筛选 | 接口测试 | Postman | §2.4 | 有 Y2 | `publishStatus=2` | 含 Y2 |
68 73
 | ZCZX-KJZYGL-API-005 | 列表 | 不含已删除 | 接口测试 | Postman | §2.5 | 某 id 已删 | `GET /list` | 无该 id |
69 74
 | ZCZX-KJZYGL-API-006 | 列表 | 缺 resourceType | 接口测试 | Postman | §3.1 | 已登录 | 不传 `resourceType` | 参数错误或空列表 |
70
-| ZCZX-KJZYGL-API-007 | 新增 | 专家 | 接口测试 | Postman | §5.4 | 已上传照片 | `POST` 专家 Body | `code=200`;未发布 |
71
-| ZCZX-KJZYGL-API-008 | 新增 | 技术成果 | 接口测试 | Postman | §5.5 | 已登录 | `POST` `resourceType=004006` 合法字段 | 成功;无 `photo_*` 必填 |
72
-| ZCZX-KJZYGL-API-009 | 新增 | 共享仪器 | 接口测试 | Postman | §5.6 | 已上传照片 | `POST` `resourceType=004007` | 成功;含 `borrowFee`、预约流程 |
73
-| ZCZX-KJZYGL-API-010 | 新增 | 视频课程 | 接口测试 | Postman | §5.7 | 已上传 mp4 | `POST` `resourceType=004008` | 成功;含 `videoFileUrl` |
74
-| ZCZX-KJZYGL-API-011 | 新增 | 成果缺摘要 | 接口测试 | Postman | §5.5 | 已登录 | 缺 `achievementSummary` | 失败 |
75
+| ZCZX-KJZYGL-API-007 | 新增 | 专家 | 接口测试 | Postman | §5.4 | 已登录 | `POST` 专家 Body;仅专家姓名 | `code=200`;资料字段可省略 |
76
+| ZCZX-KJZYGL-API-008 | 新增 | 技术成果 | 接口测试 | Postman | §5.5 | 已登录 | `POST` `resourceType=004006`;成果名称+研究方向 | 成功;摘要/原理/优势/完成单位可省略 |
77
+| ZCZX-KJZYGL-API-009 | 新增 | 共享仪器 | 接口测试 | Postman | §5.6 | 已登录 | `POST` `resourceType=004007`;仅仪器名称 | 成功;照片/型号/服务时段等可省略 |
78
+| ZCZX-KJZYGL-API-010 | 新增 | 视频课程 | 接口测试 | Postman | §5.7 | 已上传 mp4 | `POST` `resourceType=004008`;无简介 | 成功;含 `videoFileUrl`、课程主题 |
79
+| ZCZX-KJZYGL-API-011 | 新增 | 专家服务时段非法 | 接口测试 | Postman | §5.4 | 已登录 | `serviceEndTime` 早于 `serviceStartTime` | 失败 |
75 80
 | ZCZX-KJZYGL-API-012 | 新增 | 课程缺视频 | 接口测试 | Postman | §5.7 | 已登录 | 缺 `videoFilePath` | 失败 |
76 81
 | ZCZX-KJZYGL-API-013 | 新增 | 手机号非法 | 接口测试 | Postman | §5.2 | 专家/仪器 | `contactPhone=123` | `msg` 含联系方式 |
77 82
 | ZCZX-KJZYGL-API-014 | 详情 | 有效 id | 接口测试 | Postman | §5.9 | 有 Z1 | `GET /{id}` | 全字段;`serviceWeekdays` 为数组 |

File diff suppressed because it is too large
+ 4 - 4
doc/牧业疫病诊疗服务/畜牧医疗资源管理/畜牧医疗资源管理功能需求-草稿.md


+ 44 - 37
doc/牧业疫病诊疗服务/畜牧医疗资源管理/畜牧医疗资源管理功能需求.md

@@ -166,8 +166,8 @@ flowchart TD
166 166
 | --- | --- |
167 167
 | 资源类型 | **必选**;决定表单字段;保存后**不可改** |
168 168
 | 初始状态 | **未发布** |
169
-| 照片 | **填**;**单图**;**jpg / jpeg / png**;**≤ 10MB** |
170
-| 联系方式 | 该类型要求的字段均 **必填** + **大陆手机号**校验 |
169
+| 照片 | **填**;**单图**;**jpg / jpeg / png**;**≤ 10MB** |
170
+| 联系方式 | 该类型要求的字段均 **必填** + **大陆手机号**校验(**兽医人员选填**,填写时校验格式) |
171 171
 | 文本 | 字数按**字符**计;trim 后校验 |
172 172
 
173 173
 ---
@@ -177,20 +177,23 @@ flowchart TD
177 177
 | 业务字段 | 兽医 | 团队 | 机构 | 设备 |
178 178
 | --- | --- | --- | --- | --- |
179 179
 | 展示名称 | ✓ | ✓ | ✓ | ✓ |
180
-| 照片 / 介绍 | ✓ | ✓ | ✓ | ✓ |
181
-| 联系方式 | ✓ | ✓ | ✓ | — |
182
-| 隶属单位 | ✓ | ✓ | — | ✓ |
183
-| 详细地址 | ✓ | — | ✓ | — |
180
+| 照片 | ○ | ○ | ○ | ○ |
181
+| 介绍 | ○ | ○ | ○ | ○ |
182
+| 联系方式 | ○ | ○ | ○ | — |
183
+| 隶属单位 | ○ | ○ | — | ○ |
184
+| 详细地址 | ○ | — | ○ | — |
184 185
 | 接诊方式(多选) | ✓ | — | — | — |
185
-| 服务区域 |  | — | — | — |
186
-| 收费标准(元/小时,正数) |  | — | — | — |
187
-| 服务时段 / 服务周日 | ✓ | — | ✓ | — |
188
-| 单日最大接诊人数 | — | — |  | — |
189
-| 成立时间 / 团队规模 | — |  | — | — |
190
-| 团队成员(选填) | — |  | — | — |
191
-| 负责人 | — | ✓ | ✓ | — |
186
+| 服务区域 |  | — | — | — |
187
+| 收费标准(元/小时,正数) |  | — | — | — |
188
+| 服务时段 / 服务周日 | ○ | — | ○ | — |
189
+| 单日最大接诊人数 | — | — |  | — |
190
+| 成立时间 / 团队规模 | — | ○/○ | — | — |
191
+| 团队成员(选填) | — |  | — | — |
192
+| 负责人 | — | ○ | ○ | — |
192 193
 | 机构级别(单选) | — | — | ✓ | — |
193
-| 设备型号 | — | — | — | ✓ |
194
+| 设备型号 | — | — | — | ○ |
195
+
196
+> **○** 表示选填;**✓** 表示该类型下必填(若列有对应字段)。各类型资料类字段见 **§5.4**~**§5.7**。
194 197
 
195 198
 ---
196 199
 
@@ -199,16 +202,16 @@ flowchart TD
199 202
 | 字段 | 规则 |
200 203
 | --- | --- |
201 204
 | 兽医姓名 | **必填**;**1~10** 字 |
202
-| 兽医照片 | **必填**;**§5.2** |
203
-| 兽医介绍 | **必填**;**1~500** 字 |
204
-| 联系方式 | **必填**;手机号 |
205
-| 隶属单位 | **必填**;**1~20** 字 |
206
-| 详细地址 | **必填**;**1~100** 字 |
205
+| 兽医照片 | **选填**;若上传须符合 **§5.2** 图片规则 |
206
+| 兽医介绍 | **选填**;若有内容 **≤500** 字 |
207
+| 联系方式 | **选填**;若填写须为大陆手机号 |
208
+| 隶属单位 | **选填**;若有内容 **≤20** 字 |
209
+| 详细地址 | **选填**;若有内容 **≤100** 字 |
207 210
 | 接诊方式 | **必填**;**多选**至少一项:定点接诊、上门接诊、在线接诊 |
208
-| 服务区域 | **必填**;**1~100** 字 |
209
-| 收费标准 | **必填**;**正数**;**元/小时** |
210
-| 服务时段 | **必填**;**HH:mm** 起止;结束 **≥** 开始 |
211
-| 服务周日 | **必填**;**多选** 周一至周日;至少一天 |
211
+| 服务区域 | **选填**;若有内容 **≤100** 字 |
212
+| 收费标准 | **选填**;若填写须为**正数**;单位 **元/小时** |
213
+| 服务时段 | **选填**;若填写须为 **HH:mm** 起止;结束 **≥** 开始 |
214
+| 服务周日 | **选填**;**多选** 周一至周日 |
212 215
 
213 216
 ---
214 217
 
@@ -217,12 +220,14 @@ flowchart TD
217 220
 | 字段 | 规则 |
218 221
 | --- | --- |
219 222
 | 团队名称 | **必填**;**1~10** 字 |
220
-| 团队照片 / 介绍 | **必填**;介绍 **1~500** 字 |
221
-| 成立时间 | **必填**;**YYYY-MM-DD**;不宜为未来日期 |
222
-| 团队规模 | **必填**;**正整数**;单位 **人** |
223
+| 团队照片 | **选填**;若上传须符合 **§5.2** 图片规则 |
224
+| 团队介绍 | **选填**;若有内容 **≤500** 字 |
225
+| 成立时间 | **选填**;若填写须为 **YYYY-MM-DD**;不宜为未来日期 |
226
+| 团队规模 | **选填**;若填写须为**正整数**;单位 **人** |
223 227
 | 团队成员 | **选填**;≤ **500** 字 |
224
-| 团队负责人 | **必填**;**1~10** 字 |
225
-| 联系方式 / 隶属单位 | **必填**;手机号;单位 **1~20** 字 |
228
+| 团队负责人 | **选填**;若有内容 **≤10** 字 |
229
+| 联系方式 | **选填**;若填写须为大陆手机号 |
230
+| 隶属单位 | **选填**;若有内容 **≤20** 字 |
226 231
 
227 232
 ---
228 233
 
@@ -231,13 +236,14 @@ flowchart TD
231 236
 | 字段 | 规则 |
232 237
 | --- | --- |
233 238
 | 机构名称 | **必填**;**1~10** 字 |
234
-| 机构照片 / 介绍 | **必填**;介绍 **1~500** 字 |
239
+| 机构照片 | **选填**;若上传须符合 **§5.2** 图片规则 |
240
+| 机构介绍 | **选填**;若有内容 **≤500** 字 |
235 241
 | 机构级别 | **必填**;**单选**:动物诊所、动物医院 |
236
-| 详细地址 | **必填**;**1~100** 字 |
237
-| 负责人 | **必填**;**1~10** 字 |
238
-| 联系方式 | **必填**;手机号 |
239
-| 服务时段 / 服务周日 | **必填**;规则同兽医 **§5.4** 中「服务时段」「服务周日」 |
240
-| 单日最大接诊人数 | **必填**;**正整数**;单位 **人**(供预约模块判断,本模块不执行预约) |
242
+| 详细地址 | **选填**;若有内容 **≤100** 字 |
243
+| 负责人 | **选填**;若有内容 **≤10** 字 |
244
+| 联系方式 | **选填**;若填写须为大陆手机号 |
245
+| 服务时段 / 服务周日 | **选填**;若填写规则同兽医 **§5.4** 中「服务时段」「服务周日」 |
246
+| 单日最大接诊人数 | **选填**;若填写须为**正整数**;单位 **人**(供预约模块判断,本模块不执行预约) |
241 247
 
242 248
 ---
243 249
 
@@ -246,9 +252,10 @@ flowchart TD
246 252
 | 字段 | 规则 |
247 253
 | --- | --- |
248 254
 | 设备名称 | **必填**;**1~10** 字 |
249
-| 设备型号 | **必填**;**1~10** 字 |
250
-| 设备照片 / 介绍 | **必填**;介绍 **1~500** 字 |
251
-| 隶属单位 | **必填**;**1~20** 字 |
255
+| 设备型号 | **选填**;若有内容 **≤10** 字 |
256
+| 设备照片 | **选填**;若上传须符合 **§5.2** 图片规则 |
257
+| 设备介绍 | **选填**;若有内容 **≤500** 字 |
258
+| 隶属单位 | **选填**;若有内容 **≤20** 字 |
252 259
 
253 260
 ---
254 261
 

+ 13 - 13
doc/牧业疫病诊疗服务/畜牧医疗资源管理/畜牧医疗资源管理技术方案.md

@@ -94,9 +94,9 @@ CREATE TABLE `biz_medical_resource` (
94 94
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
95 95
   `resource_type` varchar(32) NOT NULL COMMENT '资讯类别编码(parentCode=004,categoryType=6)',
96 96
   `resource_name` varchar(32) NOT NULL COMMENT '资源名称',
97
-  `photo_file_url` varchar(512) NOT NULL COMMENT '照片URL',
98
-  `photo_file_path` varchar(512) NOT NULL COMMENT '照片路径',
99
-  `introduction` varchar(500) NOT NULL COMMENT '介绍',
97
+  `photo_file_url` varchar(512) DEFAULT NULL COMMENT '照片URL',
98
+  `photo_file_path` varchar(512) DEFAULT NULL COMMENT '照片路径',
99
+  `introduction` varchar(500) DEFAULT NULL COMMENT '介绍',
100 100
   `contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
101 101
   `affiliated_unit` varchar(64) DEFAULT NULL COMMENT '隶属单位',
102 102
   `detail_address` varchar(200) DEFAULT NULL COMMENT '详细地址',
@@ -149,17 +149,17 @@ CREATE TABLE `biz_medical_resource` (
149 149
 
150 150
 | 字段 | 兽医(1) | 团队(2) | 机构(3) | 设备(4) |
151 151
 | --- | --- | --- | --- | --- |
152
-| `resource_name` / `photo_*` / `introduction` | ✓ | ✓ | ✓ | ✓ |
153
-| `contact_phone` | ✓ | ✓ | ✓ | — |
154
-| `affiliated_unit` | ✓ | ✓ | — | ✓ |
155
-| `detail_address` | ✓ | — | ✓ | — |
156
-| `consult_modes` / `service_area` / `fee_standard` | ✓ | — | — | — |
157
-| `service_start_time` / `service_end_time` / `service_weekdays` | ✓ | — | ✓ | — |
158
-| `max_daily_appointments` | — | — |  | — |
159
-| `establish_date` / `team_size` / `team_members` | — |  | — | — |
160
-| `person_in_charge` | — | ✓ | ✓ | — |
152
+| `resource_name` / `photo_*` / `introduction` | ○/○/○ | ○/○/○ | ○/○/○ | ○/○/○ |
153
+| `contact_phone` | ○ | ○ | ○ | — |
154
+| `affiliated_unit` | ○ | ○ | — | ○ |
155
+| `detail_address` | ○ | — | ○ | — |
156
+| `consult_modes` / `service_area` / `fee_standard` | ✓/○/○ | — | — | — |
157
+| `service_start_time` / `service_end_time` / `service_weekdays` | ○ | — | ○ | — |
158
+| `max_daily_appointments` | — | — |  | — |
159
+| `establish_date` / `team_size` / `team_members` | — | ○/○/○ | — | — |
160
+| `person_in_charge` | — | ○ | ○ | — |
161 161
 | `org_level` | — | — | ✓ | — |
162
-| `equipment_model` | — | — | — |  |
162
+| `equipment_model` | — | — | — |  |
163 163
 
164 164
 ### 2.2 资源类型 `resource_type`
165 165
 

+ 13 - 5
doc/牧业疫病诊疗服务/畜牧医疗资源管理/畜牧医疗资源管理测试用例.md

@@ -16,7 +16,7 @@
16 16
 
17 17
 **兽医合法 Body 片段**:`resourceType=004001`,`resourceName=测试兽医`,`introduction=简介`,`contactPhone=13800138000`,`affiliatedUnit=县畜牧局`,`detailAddress=某某路1号`,`consultModes=[1,2]`,`serviceArea=全县`,`feeStandard=100`,`serviceStartTime=08:00`,`serviceEndTime=18:00`,`serviceWeekdays=[1,2,3,4,5]`,`photoFileUrl`/`photoFilePath` 来自上传接口(**不含** `maxDailyAppointments`)。
18 18
 
19
-**机构合法 Body 片段**(在兽医片段基础上改 `resourceType=004003`,去掉兽医专属字段,增加):`orgLevel=1`,`personInCharge=负责人`,`maxDailyAppointments=30`,服务时段/服务周日同兽医
19
+**机构合法 Body 片段**(`resourceType=004003`):`resourceName`、`orgLevel` 必填;`personInCharge`、`maxDailyAppointments`、照片/介绍/地址/手机/服务时段等为选填
20 20
 
21 21
 **界面(UI)测试**:**Playwright** + **Chromium**(`channel: 'chrome'` 使用本机 **Google Chrome**)。
22 22
 
@@ -30,8 +30,16 @@
30 30
 | ZCZX-XMZYGL-UT-002 | 参数校验 | 手机号 | 单元测试 | JUnit5 | §5.2 | 无 | 非法号、合法 11 位 | 非法失败;`13800138000` 通过 |
31 31
 | ZCZX-XMZYGL-UT-003 | 参数校验 | 名称/介绍长度 | 单元测试 | JUnit5 | §5.4~5.7 | 无 | 名称 0/11 字;介绍 501 字 | 超限失败;1~10/500 通过 |
32 32
 | ZCZX-XMZYGL-UT-004 | 参数校验 | 收费标准 | 单元测试 | JUnit5 | §5.4 | 无 | 0、负数、正数 | 非正数失败;`100` 通过 |
33
-| ZCZX-XMZYGL-UT-005 | 参数校验 | 接诊方式/服务周日 | 单元测试 | JUnit5 | §5.4 | 无 | 空数组;至少一项 | 空失败;`[1]` 通过 |
34
-| ZCZX-XMZYGL-UT-006 | 参数校验 | 团队成立时间 | 单元测试 | JUnit5 | §5.5 | 无 | 未来日期;合法过去日期 | 未来失败(若启用);合法通过 |
33
+| ZCZX-XMZYGL-UT-005 | 参数校验 | 接诊方式/服务周日 | 单元测试 | JUnit5 | §5.4 | 无 | 接诊方式空数组失败;`required=false` 时服务周日空通过 | 与必填开关一致 |
34
+| ZCZX-XMZYGL-UT-005a | 参数校验 | 兽医资料选填 | 单元测试 | JUnit5 | §5.4 | 无 | 无照片/介绍/手机/单位/地址/服务区域/收费,保留接诊等必填 | 通过 |
35
+| ZCZX-XMZYGL-UT-005c | 参数校验 | 兽医收费选填 | 单元测试 | JUnit5 | §5.4 | `feeStandard=null` | `validateRowForSave` | 通过;填 0 仍失败 |
36
+| ZCZX-XMZYGL-UT-005b | 参数校验 | 兽医手机格式 | 单元测试 | JUnit5 | §5.4 | 填非法手机 | `validateRowForSave` | 失败 |
37
+| ZCZX-XMZYGL-UT-006 | 参数校验 | 团队成立时间 | 单元测试 | JUnit5 | §5.5 | 无 | 未来日期;合法过去日期 | 未来失败(若填写);未填通过 |
38
+| ZCZX-XMZYGL-UT-006b | 参数校验 | 团队资料选填 | 单元测试 | JUnit5 | §5.5 | 无 | 仅团队名称,其余资料字段空 | 通过 |
39
+| ZCZX-XMZYGL-UT-006c | 参数校验 | 机构资料选填 | 单元测试 | JUnit5 | §5.6 | 无 | 机构名称+机构级别;其余资料字段空 | 通过 |
40
+| ZCZX-XMZYGL-UT-006d | 参数校验 | 机构单日接诊 | 单元测试 | JUnit5 | §5.6 | 无 | 填 0 或负数 | 失败;正整数或未填通过 |
41
+| ZCZX-XMZYGL-UT-006e | 参数校验 | 设备资料选填 | 单元测试 | JUnit5 | §5.7 | 无 | 仅设备名称,照片/介绍/型号/隶属单位空 | 通过 |
42
+| ZCZX-XMZYGL-UT-006f | 参数校验 | 设备型号长度 | 单元测试 | JUnit5 | §5.7 | 无 | 型号 11 字 | 失败 |
35 43
 | ZCZX-XMZYGL-UT-007 | 参数校验 | 类型字段矩阵 | 单元测试 | JUnit5 | §5.3、§2.1 | 无 | 设备行带 `contactPhone`;兽医缺 `feeStandard` | 设备校验不要求手机;兽医缺收费失败 |
36 44
 | ZCZX-XMZYGL-UT-007a | 参数校验 | 兽医单日接诊 | 单元测试 | JUnit5 | §5.3、草稿 §2 | 无 | 合法兽医不传 `maxDailyAppointments`;传入 20 后 `validateRowForSave` | 均通过;后者保存对象 `maxDailyAppointments` 为 `null` |
37 45
 | ZCZX-XMZYGL-UT-008 | 参数校验 | 照片路径 | 单元测试 | JUnit5 | §5.2 | 无 | 非 `/profile` 前缀;jpg 路径 | 非法路径失败;合法通过 |
@@ -64,8 +72,8 @@
64 72
 | ZCZX-XMZYGL-API-006 | 列表 | 缺 resourceType | 接口测试 | Postman | §3.1 | 已登录 | 不传 `resourceType` | 参数错误或空列表(以实现为准) |
65 73
 | ZCZX-XMZYGL-API-007 | 新增 | 兽医全字段 | 接口测试 | Postman | §5.4 | 已登录;已上传照片 | `POST` 合法兽医 Body | `code=200`;`publishStatus` 对应未发布 |
66 74
 | ZCZX-XMZYGL-API-008 | 新增 | 专家团队 | 接口测试 | Postman | §5.5 | 已登录 | `POST` `resourceType=004002` 合法字段 | 成功;无兽医专属字段必填 |
67
-| ZCZX-XMZYGL-API-009 | 新增 | 诊疗机构 | 接口测试 | Postman | §5.6 | 已登录 | `POST` `resourceType=004003` | 成功;含服务时段等 |
68
-| ZCZX-XMZYGL-API-010 | 新增 | 医疗设备 | 接口测试 | Postman | §5.7 | 已登录 | `POST` `resourceType=004004` | 成功;无 `contactPhone` |
75
+| ZCZX-XMZYGL-API-009 | 新增 | 诊疗机构 | 接口测试 | Postman | §5.6 | 已登录 | `POST` `resourceType=004003`;机构名称+机构级别 | 成功;照片/介绍/服务时段等可省略 |
76
+| ZCZX-XMZYGL-API-010 | 新增 | 医疗设备 | 接口测试 | Postman | §5.7 | 已登录 | `POST` `resourceType=004004`;仅设备名称 | 成功;照片/介绍/型号/隶属单位可省略 |
69 77
 | ZCZX-XMZYGL-API-011 | 新增 | 手机号非法 | 接口测试 | Postman | §5.2 | 已登录 | `contactPhone=123` | `code≠200`;`msg` 含联系方式 |
70 78
 | ZCZX-XMZYGL-API-012 | 新增 | 介绍仅空白 | 接口测试 | Postman | §5.2 | 已登录 | `introduction="   "` | 失败 |
71 79
 | ZCZX-XMZYGL-API-013 | 新增 | 服务时段非法 | 接口测试 | Postman | §5.4 | 已登录 | `serviceEndTime` 早于 `serviceStartTime` | 失败 |

+ 3 - 3
sql/biz_medical_resource.sql

@@ -5,9 +5,9 @@ CREATE TABLE IF NOT EXISTS `biz_medical_resource` (
5 5
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
6 6
   `resource_type` varchar(32) NOT NULL COMMENT '资讯类别编码(parentCode=004,categoryType=6)',
7 7
   `resource_name` varchar(32) NOT NULL COMMENT '资源名称',
8
-  `photo_file_url` varchar(512) NOT NULL COMMENT '照片URL',
9
-  `photo_file_path` varchar(512) NOT NULL COMMENT '照片路径',
10
-  `introduction` varchar(500) NOT NULL COMMENT '介绍',
8
+  `photo_file_url` varchar(512) DEFAULT NULL COMMENT '照片URL',
9
+  `photo_file_path` varchar(512) DEFAULT NULL COMMENT '照片路径',
10
+  `introduction` varchar(500) DEFAULT NULL COMMENT '介绍',
11 11
   `contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
12 12
   `affiliated_unit` varchar(64) DEFAULT NULL COMMENT '隶属单位',
13 13
   `detail_address` varchar(200) DEFAULT NULL COMMENT '详细地址',