静态资源配置
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Value("${file.save-path}")
private String fileSavePath;
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//映射本地文件夹
registry.addResourceHandler("/images/**").addResourceLocations("file:" + fileSavePath);
super.addResourceHandlers(registry);
}
}
application.yml
file:
save-path: D:\qr_code_duct\qr_code_back\images\
详细说明
由于要展示的图片可能比较大,从后端数据库中获取base64编码明显不可能(base64大部分适用于KB级别的),数据库正常来说也只存放图片的地址,而不是图片的内容。
CREATE TABLE `card_record_image` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`card_record_id` int(11) DEFAULT NULL,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`operator_id` int(11) DEFAULT NULL,
`image_url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `card_record_id` (`card_record_id`),
CONSTRAINT `card_record_image_ibfk_1` FOREIGN KEY (`card_record_id`) REFERENCES `card_record` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4;
public RespondDto saveCardRecord(RequestData requestData) {
// 解析前端传递的数据, 创建CardRecord对象并保存到数据库
CardRecord cardRecord = new CardRecord();
cardRecord.setProductId(requestData.getProductId());
cardRecord.setCurrentLocation(requestData.getCurrentLocation());
cardRecord.setDescription(requestData.getDesc());
cardRecord.setCreateTime(new Date());
cardRecordMapper.insert(cardRecord);
// 保存卡记录图片
List<String> imageList = requestData.getImageList();
List<String> imageUrlList = new ArrayList<>();
for (String base64Image : imageList) {
// 移除可能的前缀信息(如"data:image/jpeg;base64,"),只保留base64编码部分
String base64Data = base64Image.replaceAll("data:image/.*;base64,", "");
// 从 base64 解码成二进制数据
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
// 生成文件名,这里可以根据需要生成唯一的文件名
String fileName = "image_" + UUID.randomUUID() + ".png";
// 构建文件保存路径
// String fileSavePath = "D:" + File.separator + "qr_code_duct" + File.separator + "qr_code_back" + File.separator +"images" +File.separator +fileName;
String fileSavePath = fileProperties.getSavePath() + fileName;
try (FileOutputStream fos = new FileOutputStream(fileSavePath)) {
fos.write(imageBytes);
// 替换为实际的域名和路径
imageUrlList.add("/images/" + fileName);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 保存图片信息到数据库
CardRecordImage cardRecordImage = new CardRecordImage();
cardRecordImage.setCardRecordId(Math.toIntExact(cardRecord.getId()));
// 替换为实际的域名和路径
cardRecordImage.setImageUrl("/images/" + fileName);
cardRecordImage.setCreateTime(new Date());
cardRecordImageMapper.insert(cardRecordImage);
}
return new RespondDto(ResultCode.OK, "保存成功!!");
}
<template>
<div>
<div class="return-button-container">
<el-button size="small" @click="goBack">返回</el-button>
</div>
<el-table :data="cardRecords" style="width: 100%">
<el-table-column prop="productId" label="板卡编号"></el-table-column>
<el-table-column prop="currentLocation" label="记录人"></el-table-column>
<el-table-column label="图片">
<template slot-scope="scope">
<div v-if="Array.isArray(scope.row.images)">
<div v-for="(image, index) in scope.row.images" :key="index">
<img :src="getImageUrl(image.imageUrl)" style="max-width: 100px; max-height: 100px">
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="description" label="说明备注"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
cardRecords: []
};
},
created() {
this.getAllCardRecordsWithImages();
},
methods: {
goBack() {
window.location.href = 'http://localhost:8889/login'
},
getImageUrl(imageUrl) {
return 'http://192.168.**.**:9999' + imageUrl;
},
getAllCardRecordsWithImages() {
this.$request.get('/cardRecord/allWithImages')
.then(res => {
console.log('Response data:', res.data);
if (Array.isArray(res.data) && res.data.length > 0) {
this.cardRecords = res.data.map(item => this.parseData(item));
} else {
console.error('Error fetching card records: Data is empty');
}
})
.catch(error => {
console.error('Error fetching card records:', error);
});
},
parseData(data) {
return {
productId: data.productId,
currentLocation: data.currentLocation,
images: Array.isArray(data.images) ? data.images.map(image => ({
id: image.id,
imageUrl: image.imageUrl
})) : [],
description: data.description
};
}
}
};
</script>
<style scoped>
.return-button-container {
position: absolute;
top: 16px;
right: 16px;
}
</style>