wlzboy
2025-11-07 2aebbc9601ab439707f69b08e467808df9f7549c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
package com.ruoyi.system.imagedata;
 
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.config.LegacySystemConfig;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.ImageData;
import com.ruoyi.system.domain.enums.ImageTypeEnum;
import com.ruoyi.system.file.FileUploadResponse;
import com.ruoyi.system.file.IFileUploadService;
import com.ruoyi.system.mapper.ImageDataMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
 
@Service
@DataSource(DataSourceType.SQLSERVER)
public class ImageDataServiceImpl implements IImageDataService {
 
    private static final Logger log = LoggerFactory.getLogger(ImageDataServiceImpl.class);
    @Autowired
    private ImageDataMapper imageDataMapper;
 
    @Autowired
    private IFileUploadService fileUploadService;
 
    @Autowired
    private LegacySystemConfig legacyConfig;
    /**
     * 查询图片数据
     *
     * @param id 图片数据主键
     * @return 图片数据
     */
    @Override
    public ImageData selectImageDataById(Long id) {
        return imageDataMapper.selectImageDataById(id);
    }
 
    /**
     * 查询图片数据列表
     *
     * @param imageData 图片数据
     * @return 图片数据
     */
    @Override
    public List<ImageData> selectImageDataList(ImageData imageData) {
        return imageDataMapper.selectImageDataList(imageData);
    }
 
    /**
     * 新增图片数据
     *
     * @param imageData 图片数据
     * @return 结果
     */
    @Override
    public int insertImageData(ImageData imageData) {
        return imageDataMapper.insertImageData(imageData);
    }
 
    /**
     * 修改图片数据
     *
     * @param imageData 图片数据
     * @return 结果
     */
    @Override
    public int updateImageData(ImageData imageData) {
        return imageDataMapper.updateImageData(imageData);
    }
 
    /**
     * 批量删除图片数据
     *
     * @param ids 需要删除的图片数据主键
     * @return 结果
     */
    @Override
    public int deleteImageDataByIds(Long[] ids) {
        return imageDataMapper.deleteImageDataByIds(ids);
    }
 
    /**
     * 删除图片数据信息
     *
     * @param id 图片数据主键
     * @return 结果
     */
    @Override
    public int deleteImageDataById(Long id) {
        return imageDataMapper.deleteImageDataById(id);
    }
 
    /**
     * 根据调度单ID查询图片数据
     *
     * @param dOrdIDDt 调度单ID
     * @return 图片数据集合
     */
    @Override
    public List<ImageData> selectImageDataByDOrdIDDt(Long dOrdIDDt) {
        return imageDataMapper.selectImageDataByDOrdIDDt(dOrdIDDt);
    }
    /**
     * 生成与旧系统兼容的文件路径
     *
     * @param dispatchOrdID 调度单ID
     * @param mediaId 媒体ID
     * @param isThumbnail 是否为缩略图
     * @return 兼容的文件路径
     */
 
    @Override
    public String generateCompatibleFilePath(Long dispatchOrdID, String mediaId, boolean isThumbnail) {
        try {
            String yearMonth = DateUtils.dateTimeNow("yyyyMM");
            String fileName = dispatchOrdID + "_" + mediaId + ".jpg";
 
            if (isThumbnail) {
                fileName = "s_" + fileName;
            }
 
            return legacyConfig.getFileServerUrl() + "/" + yearMonth + "/" + fileName;
        } catch (Exception e) {
            log.error("生成兼容文件路径失败:{}", e.getMessage());
            return null;
        }
    }
 
    /**
     * 生成与旧系统兼容的访问URL
     *
     * @param dispatchOrdID 调度单ID
     * @param mediaId 媒体ID
     * @param isThumbnail 是否为缩略图
     * @return 兼容的访问URL
     */
    @Override
    public String generateCompatibleUrl(Long dispatchOrdID, String mediaId, boolean isThumbnail) {
        try {
            String yearMonth = DateUtils.dateTimeNow("yyyyMM");
            String fileName = dispatchOrdID + "_" + mediaId + ".jpg";
 
            if (isThumbnail) {
                fileName = "s_" + fileName;
            }
 
            return legacyConfig.getFileServerUrl() + "/" + yearMonth + "/" + fileName;
        } catch (Exception e) {
            log.error("生成兼容URL失败:{}", e.getMessage());
            return null;
        }
    }
    /**
     * 根据服务单ID查询图片数据
     *
     * @param sOrdIDDt 服务单ID
     * @return 图片数据集合
     */
    @Override
    public List<ImageData> selectImageDataBySOrdIDDt(Long sOrdIDDt) {
        return imageDataMapper.selectImageDataBySOrdIDDt(sOrdIDDt);
    }
 
    /**
     * 根据图片类型查询图片数据
     *
     * @param imageType 图片类型
     * @return 图片数据集合
     */
    @Override
    public List<ImageData> selectImageDataByType(Integer imageType) {
        ImageData imageData = new ImageData();
        imageData.setImageType(imageType);
        return imageDataMapper.selectImageDataList(imageData);
    }
 
    /**
     * 标记图片为删除状态
     *
     * @param id 图片数据主键
     * @return 结果
     */
    @Override
    public int markImageDataAsDeleted(Long id) {
        ImageData imageData = new ImageData();
        imageData.setId(id);
        imageData.setImageDel(1); // 1表示已删除
        return imageDataMapper.updateImageData(imageData);
    }
 
 
    /**
     * 微信图片上传处理(原ASP代码转换)
     *
     * @param dispatchOrdID 调度单ID
     * @param serviceOrdID 服务单ID
     * @param oaid OA用户ID
     * @param mediaId 微信媒体ID
     * @param imageType 图片类型
     * @param adminId 当前管理员ID
     * @return 处理结果
     */
 
    public String uploadWxImage(Long dispatchOrdID, Long serviceOrdID, Integer oaid,
                                String mediaId, Integer imageType, Integer adminId) {
        try {
            // 获取图片类型枚举
            ImageTypeEnum imageTypeEnum = ImageTypeEnum.getByCode(imageType);
 
            // 如果有调度单ID,则处理调度单相关图片
            if (dispatchOrdID != null && dispatchOrdID > 0) {
                return processDispatchOrderImage(dispatchOrdID, serviceOrdID, mediaId, imageTypeEnum, adminId);
            }
            // 如果只有OA用户ID,则更新用户头像
            else if (oaid != null && oaid > 0) {
                return updateUserAvatar(oaid, mediaId);
            }
            else {
                return "参数错误:缺少必要的参数";
            }
        } catch (Exception e) {
            return "处理失败:" + e.getMessage();
        }
    }
 
    /**
     * 处理调度单相关图片上传
     */
    private String processDispatchOrderImage(Long dispatchOrdID, Long serviceOrdID,
                                             String mediaId, ImageTypeEnum imageTypeEnum, Integer adminId) {
        try {
            // 生成图片URL路径
            String imageUrl = generateImageUrl(dispatchOrdID, mediaId, false);
            String imageUrls = generateImageUrl(dispatchOrdID, mediaId, true);
 
            // 创建图片数据对象
            ImageData imageData = new ImageData();
            imageData.setDOrdIDDt(dispatchOrdID);
            imageData.setSOrdIDDt(serviceOrdID);
            imageData.setImageType(imageTypeEnum.getCode());
            imageData.setImageUrl(imageUrl);
            imageData.setImageUrls(imageUrls);
            imageData.setUpImageTime(new Date());
            imageData.setUpImageOAid(adminId);
            imageData.setImageDel(0); // 0表示未删除
 
            // 插入图片数据
            int result = imageDataMapper.insertImageData(imageData);
            if (result <= 0) {
                return "图片数据保存失败";
            }
 
 
                return "图片上传成功,ID: " + imageData.getId() + ",类型: " + imageTypeEnum.getDescription();
 
        } catch (Exception e) {
            return "处理调度单图片失败:" + e.getMessage();
        }
    }
 
    /**
     * 更新用户头像
     */
    private String updateUserAvatar(Integer oaid, String mediaId) {
        try {
            // 这里需要调用OA用户服务来更新头像
            // 由于没有OA用户服务的具体实现,这里只是示例
            String avatarUrl = "/upload/" + oaid + "_" + mediaId + ".jpg";
 
            // TODO: 调用OA用户服务更新头像
            // oaUserService.updateAvatar(oaid, avatarUrl);
 
            return "用户头像更新成功";
        } catch (Exception e) {
            return "更新用户头像失败:" + e.getMessage();
        }
    }
 
    /**
     * 生成图片URL
     */
    private String generateImageUrl(Long dispatchOrdID, String mediaId, boolean isThumbnail) {
        Date now = new Date();
        int year = now.getYear() + 1900; // Java的年份需要加1900
        int month = now.getMonth() + 1;  // Java的月份从0开始
 
        String monthStr = String.format("%02d", month);
        String prefix = isThumbnail ? "/upload/" + year + monthStr + "/s_" : "/upload/" + year + monthStr + "/";
 
        return prefix + dispatchOrdID + "_" + mediaId + ".jpg";
    }
 
 
 
 
    /**
     * 保存微信文件到本地(原PHP代码转换)
     *
     * @param filename 文件名
     * @param fileContent 文件内容
     * @return 是否保存成功
     */
    public boolean saveWeixinFile(String filename, byte[] fileContent) {
        FileOutputStream localFile = null;
        try {
            // 确保目录存在
            File file = new File(filename);
            File parentDir = file.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
 
            localFile = new FileOutputStream(filename);
            localFile.write(fileContent);
            localFile.flush();
 
            log.info("成功保存微信文件:{}", filename);
            return true;
        } catch (Exception e) {
            log.error("保存微信文件失败:{}", e.getMessage(), e);
            return false;
        } finally {
            if (localFile != null) {
                try {
                    localFile.close();
                } catch (IOException e) {
                    log.error("关闭文件流失败:{}", e.getMessage());
                }
            }
        }
    }
 
    /**
     * 生成缩略图(原PHP代码转换)
     *
     * @param bigImgPath 原始大图路径
     * @param width 缩略图宽度
     * @param height 缩略图高度(0表示按比例计算)
     * @param smallImgPath 缩略图保存路径
     * @return 是否生成成功
     */
    public boolean createThumbnail(String bigImgPath, int width, int height, String smallImgPath) {
        try {
            // 读取原始图片
            BufferedImage originalImage = ImageIO.read(new File(bigImgPath));
            if (originalImage == null) {
                log.error("无法读取原始图片:{}", bigImgPath);
                return false;
            }
 
            int srcWidth = originalImage.getWidth();
            int srcHeight = originalImage.getHeight();
 
            // 计算缩略图尺寸
            if (height == 0) {
                height = (int) Math.floor((double) width / srcWidth * srcHeight);
            } else if (width == 0) {
                width = (int) Math.floor((double) height / srcHeight * srcWidth);
            }
 
            // 创建缩略图
            BufferedImage thumbnail = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = thumbnail.createGraphics();
 
            // 设置渲染质量
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
            // 绘制缩略图
            g.drawImage(originalImage, 0, 0, width, height, null);
            g.dispose();
 
            // 确保目录存在
            File smallImgFile = new File(smallImgPath);
            File parentDir = smallImgFile.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
 
            // 保存缩略图
            ImageIO.write(thumbnail, "jpg", smallImgFile);
 
            log.info("成功生成缩略图:{} -> {} ({}x{})", bigImgPath, smallImgPath, width, height);
            return true;
        } catch (Exception e) {
            log.error("生成缩略图失败:{}", e.getMessage(), e);
            return false;
        }
    }
 
 
    /**
     * 处理调度单相关图片上传(包含文件URL)
     */
    private String processDispatchOrderImageWithFiles(Long dispatchOrdID, Long serviceOrdID,
                                                      String mediaId, ImageTypeEnum imageTypeEnum,
                                                      Integer adminId, String originalImageUrl, String thumbnailUrl) {
        try {
            // 创建图片数据对象
            ImageData imageData = new ImageData();
            imageData.setDOrdIDDt(dispatchOrdID);
            imageData.setSOrdIDDt(serviceOrdID);
            imageData.setImageType(imageTypeEnum.getCode());
            imageData.setImageUrl(originalImageUrl);
            imageData.setImageUrls(thumbnailUrl);
            imageData.setUpImageTime(new Date());
            imageData.setUpImageOAid(adminId);
            imageData.setImageDel(0); // 0表示未删除
 
            // 插入图片数据
            int result = imageDataMapper.insertImageData(imageData);
            if (result <= 0) {
                return "图片数据保存失败";
            }
 
 
                return "图片上传成功,ID: " + imageData.getId() + ",类型: " + imageTypeEnum.getDescription() +
                        ",原始图片URL: " + originalImageUrl + ",缩略图URL: " + thumbnailUrl;
 
        } catch (Exception e) {
            return "处理调度单图片失败:" + e.getMessage();
        }
    }
 
    /**
     * 更新用户头像(包含文件URL)
     */
    private String updateUserAvatarWithFile(Integer oaid, String mediaId, String imageUrl) {
        try {
            // 这里需要调用OA用户服务来更新头像
            // TODO: 调用OA用户服务更新头像
            // oaUserService.updateAvatar(oaid, imageUrl);
 
            return "用户头像更新成功,URL:" + imageUrl;
        } catch (Exception e) {
            return "更新用户头像失败:" + e.getMessage();
        }
    }
 
    /**
     * 检查文件兼容性(确保与旧系统兼容)
     *
     * @param filePath 文件路径
     * @return 兼容性检查结果
     */
    public String checkFileCompatibility(String filePath) {
        try {
            File file = new File(filePath);
 
            if (!file.exists()) {
                return "文件不存在:" + filePath;
            }
 
            // 检查文件命名是否符合旧系统规范
            String fileName = file.getName();
            if (!fileName.matches("^(\\d+|[A-Z]+)_[A-Za-z0-9_]+\\.jpg$")) {
                return "文件命名不符合旧系统规范:" + fileName;
            }
 
            // 检查目录结构是否符合旧系统规范
            String parentDir = file.getParentFile().getName();
            if (!parentDir.matches("^\\d{6}$")) { // 年月格式:202412
                return "目录结构不符合旧系统规范:" + parentDir;
            }
 
            return "文件兼容性检查通过:" + filePath;
        } catch (Exception e) {
            return "兼容性检查失败:" + e.getMessage();
        }
    }
 
    /**
     * 验证URL格式是否与旧系统兼容
     *
     * @param url 图片URL
     * @return 是否兼容
     */
    public boolean isUrlCompatible(String url) {
        try {
            // 检查URL格式是否符合旧系统规范
            // 旧系统格式:/upload/年月/文件名.jpg
            return url.matches("^/upload/\\d{6}/[A-Za-z0-9_]+\\.jpg$");
        } catch (Exception e) {
            log.error("URL兼容性检查失败:{}", e.getMessage());
            return false;
        }
    }
 
 
 
    /**
     * 通过图片URL上传处理(允许直接传入图片URL)
     *
     * @param dispatchOrdID 调度单ID
     * @param serviceOrdID 服务单ID
     * @param oaid OA用户ID
     * @param imageUrl 图片URL
     * @param thumbnailUrl 缩略图URL(可选)
     * @param imageType 图片类型
     * @param adminId 当前管理员ID
     * @return 处理结果
     */
    @Override
 
    public String uploadImageByUrl(Long dispatchOrdID, Long serviceOrdID, Integer oaid,
                                   String imageUrl, String thumbnailUrl, Integer imageType, Integer adminId) {
        try {
            // 验证参数
            if (imageUrl == null || imageUrl.trim().isEmpty()) {
                return "图片URL不能为空";
            }
 
            // 处理业务逻辑
            if (dispatchOrdID != null && dispatchOrdID > 0) {
                // 调度单相关图片
                ImageTypeEnum imageTypeEnum = ImageTypeEnum.getByCode(imageType);
                return processDispatchOrderImageWithFiles(dispatchOrdID, serviceOrdID, null,
                        imageTypeEnum, adminId, imageUrl, thumbnailUrl);
            } else if (oaid != null && oaid > 0) {
                // OA用户头像
                return updateUserAvatarWithFile(oaid, null, imageUrl);
            } else {
                return "参数错误:缺少必要的参数(调度单ID或OA用户ID)";
            }
        } catch (Exception e) {
            log.error("通过URL上传图片失败:{}", e.getMessage(), e);
            return "处理失败:" + e.getMessage();
        }
    }
 
    /**
     * 通过图片URL上传处理(简化版本,自动生成缩略图URL)
     *
     * @param dispatchOrdID 调度单ID
     * @param serviceOrdID 服务单ID
     * @param oaid OA用户ID
     * @param imageUrl 图片URL
     * @param imageType 图片类型
     * @param adminId 当前管理员ID
     * @return 处理结果
     */
    @Override
 
    public String uploadImageByUrlSimple(Long dispatchOrdID, Long serviceOrdID, Integer oaid,
                                         String imageUrl, Integer imageType, Integer adminId) {
        try {
            // 验证参数
            if (imageUrl == null || imageUrl.trim().isEmpty()) {
                return "图片URL不能为空";
            }
 
            // 自动生成缩略图URL(如果原图URL包含文件名)
            String thumbnailUrl = null;
            if (imageUrl.contains("/")) {
                String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
                if (fileName.contains(".")) {
                    String nameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."));
                    String extension = fileName.substring(fileName.lastIndexOf("."));
                    String thumbnailFileName = "s_" + nameWithoutExt + extension;
                    thumbnailUrl = imageUrl.substring(0, imageUrl.lastIndexOf("/") + 1) + thumbnailFileName;
                }
            }
 
            // 调用完整版本的方法
            return uploadImageByUrl(dispatchOrdID, serviceOrdID, oaid, imageUrl, thumbnailUrl, imageType, adminId);
        } catch (Exception e) {
            log.error("通过URL上传图片(简化版)失败:{}", e.getMessage(), e);
            return "处理失败:" + e.getMessage();
        }
    }
 
    @Override
    public String uploadWxImageWithDownload(String accessToken, String mediaId, Long dispatchOrdID, Integer oaid, Integer imageType, Integer adminId) {
        try {
            // 确定目标路径
            String targetPath;
            if (dispatchOrdID != null && dispatchOrdID > 0) {
                // 调度单相关图片:按年月组织目录
                String yearMonth = DateUtils.dateTimeNow("yyyyMM");
                targetPath = yearMonth + "/" + dispatchOrdID;
            } else if (oaid != null && oaid > 0) {
                // OA用户头像
                targetPath = "avatar/" + oaid;
            } else {
                return "参数错误:缺少必要的参数";
            }
 
            // 使用文件上传服务从微信下载并上传文件
            FileUploadResponse uploadResponse = fileUploadService.uploadFromWechat(accessToken, mediaId, targetPath);
            if (!uploadResponse.isSuccess()) {
                return "文件上传失败:" + uploadResponse.getMessage();
            }
 
            // 获取上传后的文件路径
            String originalImageUrl = uploadResponse.getFilePath();
            String thumbnailUrl = uploadResponse.getThumbnailPath();
 
            // 处理业务逻辑
            if (dispatchOrdID != null && dispatchOrdID > 0) {
                return processDispatchOrderImageWithFiles(dispatchOrdID, null, mediaId,
                        ImageTypeEnum.getByCode(imageType), adminId, originalImageUrl, thumbnailUrl);
            } else if (oaid != null && oaid > 0) {
                return updateUserAvatarWithFile(oaid, mediaId, originalImageUrl);
            }
 
            return "图片上传成功,文件路径:" + originalImageUrl;
        } catch (Exception e) {
            log.error("微信图片上传处理失败:{}", e.getMessage(), e);
            return "处理失败:" + e.getMessage();
        }
    }
 
    /**
     * 根据调度单ID和图片类型查询图片数据
     *
     * @param dispatchOrdID 调度单ID
     * @param imageType 图片类型
     * @return 图片数据集合
     */
    @Override
    public List<ImageData> selectImageDataByDOrdIDDtAndType(Long dispatchOrdID, Integer imageType) {
        // 创建查询条件
        ImageData imageData = new ImageData();
        imageData.setDOrdIDDt(dispatchOrdID);
        imageData.setImageType(imageType);
 
        // 查询图片数据
        return imageDataMapper.selectImageDataList(imageData);
    }
 
}