Upload 上传(图片/文件),回显(图片),下载(文件)

1.前端技术:V3 +  Ant Design Vue

2.后端技术:Java

图片上传/回显:

文件上传回显:

表结构:单文件/图片上传为A表对文件C表 (A表field字段 对应 C表id字段)

如图:A表中的 vehicle_driving_license  和 driver_license 存的是C表中的id字段

表结构:多文件/图片上传为A表对文件B表 中的Biz字段,B表中的file_id字段对应C表中的id字段,(B表的 Biz 字段和 file_id 字段是一对多的存在关系)

如图:A表中的 house_type_file_id 和 house_type_balcony_close_file_id 、house_type_balcony_bisect_file_id、house_type_shearwall_file_id 存的是B表中的Biz_id字段,B表中的 field_id 字段对应 C表中的 id 字段,(B表中的Biz_id字段 与 field_id 字段是一对多的关系)

上传:(上传功能不分单个多个)java后台代码(controller):

  @OperationLog@ApiOperation("上传文件")@PostMapping("/upload")public ApiResult<FileInfo> upload(@RequestParam MultipartFile file, HttpServletRequest request) {FileInfo result = null;try {String dir = getUploadDir();File upload = FileServerUtil.upload(file, dir, config.getUploadUuidName());String path = upload.getAbsolutePath().replace("\\", "/").substring(dir.length() - 1);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/upload");requestURL = "/api/file-info/file/";String requestURL2 = "/api/file-info";/*if(requestURL.contains("10.1.140.88")){requestURL = "https://10.1.140.88/api/file";}if(requestURL.contains("djshemei.com")){requestURL = "https://10.1.140.88/api/file";}*/String originalName = file.getOriginalFilename();result = new FileInfo();result.setId(SnowFlakeGenerator.nextId());String contentType = FileServerUtil.getContentType(upload);result.setFileType(contentType);result.setFileName(StrUtil.isBlank(originalName) ? upload.getName() : originalName);result.setFilePath(path);result.setUrlPath(requestURL+result.getId());result.setUrl(requestURL2 + "/" + path);//这个用户应该是这个找登录用户User loginUser = getLoginUser();result.setCreUserId(Long.valueOf(loginUser.getUserId()));result.setCreUserName(loginUser.getUsername());result.setCreateTime(LocalDateTime.now());fileInfoService.save(result);return success(result);} catch (Exception e) {e.printStackTrace();return fail("上传失败", result).setError(e.toString());}}

前端:api代码:

/*** 上传文件*/
export async function uploadFile(file, opt) {const formData = new FormData();formData.append('file', file);const res = await request.post('/community/file-info/upload', formData, opt);if (res.data.code === 0 && res.data.data) {return res.data.data;}return Promise.reject(new Error(res.data.message));
}

在页面引入使用

 <a-row><a-col :span="12"><a-form-item label="行驶证"><ele-image-uploadclass="imagestype":limit="1"v-model:value="form1.vehicleDrivingLicenseField"@upload="onUpload1"@remove="onRemove1"/></a-form-item></a-col><a-col :span="12"><a-form-item label="驾驶证"><ele-image-uploadclass="imagestype":limit="1"v-model:value="form1.driverLicenseField"@upload="onUpload2"@remove="onRemove2"/></a-form-item></a-col></a-row>

使用方法:

  const onUpload1 = ({ file }) => {uploadFile(file).then((data) => {console.log(data, 'data');form1.vehicleDrivingLicenseFieldId1 = data.id;}).catch((e) => {item.status = 'exception';message.error(e.message);});};

数据结构:

  // 图片const form1 = reactive({vehicleDrivingLicenseField: [],vehicleDrivingLicenseFieldId1: '',driverLicenseField: [],driverLicenseFieldId2: ''});

图片回显:java代码 (controller)

 @ApiOperation("查询文件")@GetMapping("/queryFile/{id}")public ApiResult<?> getFileInfoByRoomCar (@PathVariable("id") Long id, HttpServletRequest request ) {List<RoomCar>  roomCarServiceList = roomCarService.list(new QueryWrapper<RoomCar>().eq("car_id", id));if(roomCarServiceList.size() == 0){return success(new ArrayList<>());}else{List<FileInfo> fileIdList = fileInfoService.list(new QueryWrapper<FileInfo>().in("id",  roomCarServiceList.stream().map(RoomCar::getVehicleDrivingLicense).collect(Collectors.toList())));if (fileIdList.size() > 0) {String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/room-car/queryFile/"+id);for (FileInfo record : fileIdList) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/" + record.getFilePath());record.setUrl(requestURL + "/file-info/" + record.getFilePath());}}}List<FileInfo> fileIdList1 = fileInfoService.list(new QueryWrapper<FileInfo>().in("id",  roomCarServiceList.stream().map(RoomCar::getDriverLicense).collect(Collectors.toList())));if (fileIdList1.size() > 0) {String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/room-car/queryFile/"+id);for (FileInfo record : fileIdList1) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/" + record.getFilePath());record.setUrl(requestURL + "/file-info/" + record.getFilePath());}}}HashMap<String, List<FileInfo>> data = new HashMap<>();data.put("vehicleDrivingLicenseField", fileIdList);data.put("driverLicenseField", fileIdList1);return success(data);}}

前端api:

export async function  queryItem(id) {const res = await request.get('/community/decoration-manage/queryFile/' + id);if (res.data.code === 0) {return res.data;}return Promise.reject(new Error(res.data.message));
}

页面引入使用:

 watch(() => props.visible,(visible) => {if (visible) {if (props.data) {assignObject(form, {...props.data});isUpdate.value = true;showFile.value = true;changeRoomType(props.data.roomTypeId);// driverLicense// vehicleDrivingLicensequeryItem(props.data.carId).then((res) => {form1.vehicleDrivingLicenseField =res.data.vehicleDrivingLicenseField;form1.driverLicenseField = res.data.driverLicenseField;}).catch((e) => {message.error(e.message);});loadingData();} else {showFile.value = false;isUpdate.value = false;loadingData();}} else {form1.vehicleDrivingLicenseField = [];form1.driverLicenseField = [];resetFields();}});

 多文件上传跟单文件上传一样的,不一样的是显示的方式:

多文件回显后端 Java代码(controller):

 @ApiOperation("查询文件")@GetMapping("/queryFile/{id}")public ApiResult<?> getFileInfoByRegionalHouseTypeId(@PathVariable("id") Long id, HttpServletRequest request ) {BaseRegionalHouseType mainRec = baseRegionalHouseTypeService.getByIdRel(id);List<FileInfo> house_type_file = new ArrayList<>();List<FileInfo> house_type_balcony_close_file = new ArrayList<>();List<FileInfo> house_type_balcony_bisect_file = new ArrayList<>();List<FileInfo> house_type_shearwall_file = new ArrayList<>();Long bizId;bizId = mainRec.getHouseTypeFileId();if (bizId != null) {house_type_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}bizId = mainRec.getHouseTypeBalconyCloseFileId();if (bizId != null) {house_type_balcony_close_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_balcony_close_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}bizId = mainRec.getHouseTypeBalconyBisectFileId();if (bizId != null) {house_type_balcony_bisect_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_balcony_bisect_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}bizId = mainRec.getHouseTypeShearwallFileId();if (bizId != null) {house_type_shearwall_file = fileInfoService.getfileinfobybiz(bizId);String requestURL = StrUtil.removeSuffix(request.getRequestURL(), "/base-regional-house-type/queryFile/"+id);for (FileInfo record : house_type_shearwall_file) {if (StrUtil.isNotBlank(record.getFilePath())) {record.setDownloadUrl(requestURL + "/file-info/download/" + record.getFilePath());}}}HashMap<String, List<FileInfo>> data = new HashMap<>();data.put("house_type_file", house_type_file);data.put("house_type_balcony_close_file", house_type_balcony_close_file);data.put("house_type_balcony_bisect_file", house_type_balcony_bisect_file);data.put("house_type_shearwall_file", house_type_shearwall_file);return success(data);}

前端api:

export async function  queryHouse(id) {const res = await request.get('/community/base-regional-house-type/queryFile/' + id);if (res.data.code === 0) {return res.data;}return Promise.reject(new Error(res.data.message));
}

页面使用:

<template><ele-modal:width="1200":visible="visible":confirm-loading="loading"title="文件管理":body-style="{ paddingBottom: '8px' }"@update:visible="updateVisible"@ok="save"><div class="ele-body"><a-card :bordered="false"><div class="content"><div class="loudong"><div><divstyle="font-size: 18px; font-weight: 600; margin-bottom: 25px">文件上传</div><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(0)":class="btn == 0 ? 'btnColor' : ''"style="width: 150px">户型图</a-button></a-col></a-row><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(1)":class="btn == 1 ? 'btnColor' : ''"style="width: 150px">封闭阳台方案</a-button></a-col></a-row><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(2)":class="btn == 2 ? 'btnColor' : ''"style="width: 150px">封闭阳台剖面图</a-button></a-col></a-row><a-row type="flex" style="margin: 20px -15px"><a-col :span="24"><a-buttontype="text"@click="typeclick(3)":class="btn == 3 ? 'btnColor' : ''"style="width: 150px">剪力墙标识图</a-button></a-col></a-row></div></div><div class="content-right"><div class="ele-body" style="margin-top: -40px"><div class="content"><div class="content-right"><div class="content-right-header" style="margin-top: 30px"><a-upload:show-upload-list="false":customRequest="onUploadCardf"><a-button type="primary" class="ele-btn-icon"><template #icon><upload-outlined /></template><span>上传</span></a-button></a-upload></div><!-- 表格 --><ele-pro-tableborderedref="tableRef"row-key="id":columns="columns":datasource="datasource":toolkit="false":scroll="{ x: 800 }"><template #bodyCell="{ column, record, index }"><template v-if="column.key === 'action'"><a-space><a:href="record.downloadUrl"target="_blank":disabled="record.downloadUrl != null ? disabled : true">下载</a><a-divider type="vertical" /><a-popconfirmplacement="topRight"title="确定要删除此文件吗?"@confirm="remove(record, index)"><a class="ele-text-danger">删除</a></a-popconfirm></a-space></template></template></ele-pro-table></div></div></div></div></div></a-card><!-- <spbuilding-editv-model:visible="showEdit":data="current"@done="reload"/><bar-code :data="barcodedata" v-model:visible="showBarcode" /> --></div></ele-modal>
</template>
<script setup>import { ref, watch, onMounted } from 'vue';import {getfileinfobybiz,uploadFile,removeFile} from '@/api/system/file-info';import useFormData from '@/utils/use-form-data';import { Form, message } from 'ant-design-vue/es';import { messageLoading } from 'ele-admin-pro/es';import {saveHouse,queryHouse} from '@/api/baseRegionalPark/base-regional-house-type';import { CloudUploadOutlined, FileTextOutlined } from '@ant-design/icons-vue';// import FileUpload from './file-upload.vue';const emit = defineEmits(['done', 'update:visible']);const useForm = Form.useForm;const props = defineProps({data: Object,visible: Boolean});// 表单const { form, resetFields, assignFields } = useFormData({regionalHouseTypeId: '',// 户型图idhouseTypeFileId: '',// 封闭阳台方案idhouseTypeBalconyCloseFileId: '',// 封闭阳台剖面图idhouseTypeBalconyBisectFileId: '',// 剪力墙标识图idhouseTypeShearwallFileId: '',house_type_file: [],house_type_balcony_close_file: [],house_type_balcony_bisect_file: [],house_type_shearwall_file: []});// 按钮颜色const btn = ref(0);// 确定数据const datas = ref({regionalHouseTypeId: '',house_type_file: [],house_type_balcony_close_file: [],house_type_balcony_bisect_file: [],house_type_shearwall_file: [],downloadUrl:"",// 户型图idhouseTypeFileId: '',// 封闭阳台方案idhouseTypeBalconyCloseFileId: '',// 封闭阳台剖面图idhouseTypeBalconyBisectFileId: '',// 剪力墙标识图idhouseTypeShearwallFileId: '',});const typeclick = (type) => {switch (type) {case 0:btn.value = 0;datasource.value = datas.value.house_type_file;        break;case 1:btn.value = 1;datasource.value = datas.value.house_type_balcony_close_file; break;case 2:btn.value = 2;datasource.value = datas.value.house_type_balcony_bisect_file; break;case 3:btn.value = 3;datasource.value = datas.value.house_type_shearwall_file; break;}    };const findPicIds = ref([]);// 表格实例const tableRef = ref(null);// 导入请求状态const loading = ref(false);const isAdmin = ref(false);// 保存按钮const save = () => {saveHouse(datas.value).then((res) => {if (res.code == 0) {message.success('保存成功');emit('done');emit('update:visible', false);} else {message.error(res.msg);}});};// 表格列配置const columns = ref([{title: '序号',key: 'index',width: 48,align: 'center',fixed: 'left',hideInSetting: true,customRender: ({ index }) => index + (tableRef.value?.tableIndex ?? 0)},{title: '文件名',dataIndex: 'fileName'},{title: '文件类型',dataIndex: 'fileType'},{title: '创建人',dataIndex: 'creUserName'},{title: '创建时间',dataIndex: 'createTime'},{title: '操作',key: 'action',width: 160,align: 'center',hideInSetting: true}]);//上传文件const onUploadCardf = (d) => {uploadFile(d.file, {onUploadProgress: (e) => {if (e.lengthComputable) {d.progress = (e.loaded / e.total) * 100;}}}).then((data) => {d.status = 'done';if (btn.value == 0) {        datas.value.house_type_file.push(data);} else if (btn.value == 1) {datas.value.house_type_balcony_close_file.push(data);} else if (btn.value == 2) {datas.value.house_type_balcony_bisect_file.push(data);} else if (btn.value == 3) {datas.value.house_type_shearwall_file.push(data);}message.success('上传成功');}).catch((e) => {message.error(e.message);});};//     /* 删除单个 */const remove = (row, index) => {const hide = message.loading('请求中..', 0);removeFile(row.id).then((msg) => {var arr = [];if(btn.value ==0 ){arr = datas.value.house_type_file.filter((d) => d.id != row.id);datas.value.house_type_file = arr;}if(btn.value ==1 ){arr = datas.value.house_type_balcony_close_file.filter((d) => d.id != row.id);datas.value.house_type_balcony_close_file = arr;}if(btn.value ==2 ){arr = datas.value.house_type_balcony_bisect_file.filter((d) => d.id != row.id);datas.value.house_type_balcony_bisect_file = arr;}if(btn.value ==3 ){arr = datas.value.house_type_shearwall_file.filter((d) => d.id != row.id);datas.value.house_type_shearwall_file = arr;}typeclick(btn.value);hide();message.success(msg);}).catch((e) => {hide();message.error(e.message);});};//   // 表格数据源const datasource = ref([]);/* 更新visible */const updateVisible = (value) => {emit('update:visible', value);};watch(() => props.visible,(visible) => {if (visible) {if (!props.data) {alert('数据为空,请确保传递正确数据');return;}console.log(props.data);datas.value.regionalHouseTypeId = props.data.regionalHouseTypeId;   queryHouse(datas.value.regionalHouseTypeId).then((res) => {datas.value.house_type_file = res.data.house_type_file;datas.value.house_type_balcony_close_file = res.data.house_type_balcony_close_file;datas.value.house_type_balcony_bisect_file = res.data.house_type_balcony_bisect_file;datas.value.house_type_shearwall_file = res.data.house_type_shearwall_file;// 默认选中第一个typeclick(0);});        }});
</script>
<style lang="less" scoped>// .ele-body {//   height: 100%;// }.btnColor {background-color: #f4fbf8;color: #1677ff;}.content {display: flex;.loudong {width: 280px;margin-right: 15px;padding: 15px;// height: 80vh;background: #fff;overflow: auto;box-sizing: border-box;}.search {width: 100%;padding: 20px 10px 0px 20px;background: #f6f5f5;margin-bottom: 5px;}.content-right {flex: 1;}}
</style>

还有一个小细节,java存储文件id的字段一定不要忽略修改的时候传来的null

 

用注解:

@TableField(updateStrategy = FieldStrategy.IGNORED)

就ok啦,暂时先做个笔记,后面有空再慢慢写注解

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OracleXE112、plsqldev1207的安装和基本配置

OracleXE112、plsqldev1207的安装和基本配置 OracleXE112、plsqldev1207的安装和基本配置Oracle安装oracle是什么Oracle两个版本下载安装包 安装OracleXE112_Win64注意&#xff1a;安装到空目录下&#xff1b;输入口令&#xff08;记住啊&#xff01;&#xff09;安装成功&…

【b站咸虾米】ES6 Promise的用法,ES7 async/await异步处理同步化,异步处理进化史

课程地址&#xff1a;【ES6 Promise的用法&#xff0c;ES7 async/await异步处理同步化&#xff0c;异步处理进化史】 https://www.bilibili.com/video/BV1XW4y1v7Md/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 图文地址&#xff1a;https://www.b…

HarmonyOS NEXT应用开发案例——滑动页面信息隐藏与组件位移效果

介绍 在很多应用中&#xff0c;向上滑动"我的"页面&#xff0c;页面顶部会有如下变化效果&#xff1a;一部分信息逐渐隐藏&#xff0c;另一部分信息逐渐显示&#xff0c;同时一些组件会进行缩放或者位置移动。向下滑动时则相反。 效果图预览 使用说明 向上滑动页面…

Django Web架构:全面掌握Django模型字段(上)

Django Web架构 全面掌握Django模型字段&#xff08;上&#xff09; - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article…

网络信息安全:nginx漏洞收集(升级至最新版本)

网络&信息安全&#xff1a;nginx漏洞收集&#xff08;升级至最新版本&#xff09; 一、风险详情1.1 nginx 越界写入漏洞(CVE-2022-41742)1.2 nginx 缓冲区错误漏洞(CVE-2022-41741)1.3 nginx 拒绝服务漏洞&#xff08;CNVD-2018-22806&#xff09; 二、nginx升级步骤 &…

每日一练 | 华为认证真题练习Day194

1、下面是路由器Huawei的部分输出配置&#xff0c;关于该部分配置描迷正确的是: [huawei] bgp 100 [huawei-bgp]peer 12.12.12.2 ip-prefix P1 export [huawei]ip-prefix P1 index 5 deny 10.0.0.0 0 greater-equal 8 less-equal 32 [huawei]ip-prefix P1 index 5 deny 172…

Vue开发环境构建

相关依赖 1.安装Node https://nodejs.org/en/ 验证是否安装 λ node -v v20.10.0 2.安装cnpm镜像 npm install -g cnpm --registryhttps://registry.npm.taobao.org 3.webpack:构建工具 4.开发工具vscode 安装插件&#xff1a;扩展-搜索vetur,vscode-icon,chinese, 搭…

上门预约平台有哪些优势和特点

在着手开发之前&#xff0c;市场调研是不可或缺的步骤。它能帮助我们深入了解当前上门按摩市场的供需状况及竞争态势&#xff0c;进而挖掘潜在用户的真实需求和期望。这些宝贵的信息将成为我们塑造产品特性和锁定目标用户群体的关键。 紧接着&#xff0c;根据市场调研的反馈&am…

Java | Java的输入与输出

文章目录 Java输出1、System.out.println()2、System.out.printf()3、System.out.print() Java输入1、使用Scanner类的对象获取输入&#xff08;1&#xff09;一般类型输入&#xff08;2&#xff09;字符串类型输入&#xff08;3&#xff09;char类型输入 2、使用System.in.rea…

鸿蒙NEXT实战开发:【截屏】

展示全屏截图和屏幕局部截图。通过[screenshot]模块实现屏幕截图 &#xff0c;通过[window]模块实现隐私窗口切换&#xff0c;通过[display]模块查询当前隐私窗口。 效果预览 全屏截图局部截图选择区域局部截图 使用说明&#xff1a; 点击右上角图标打开弹窗&#xff0c;选…

江苏某机场多座超高端智慧公厕上线

作为行业信息化程度最高的智慧机场综合管理系统&#xff0c;能为旅客、航空公司以及机场自身的业务管理提供及时、准确、系统、完整的信息服务&#xff0c;达到信息高度统一、共享、调度严密、管理先进和服务优质的目的。而其中的智慧卫生间建设&#xff0c;更是提升机场旅客服…

企业实施了MES管理系统,为什么还要做数据采集

随着信息技术的迅猛发展&#xff0c;企业对于生产管理的精细化、智能化需求日益增长。MES管理系统作为连接企业计划层与控制层的重要桥梁&#xff0c;已经成为现代制造业不可或缺的核心系统。然而&#xff0c;尽管企业实施了MES管理系统&#xff0c;数据采集工作仍然不可或缺。…

为什么最近黄金回收如此火爆?

龙行龘龘&#xff01;龙年不仅买金热&#xff0c;卖金也大热。近来&#xff0c;黄金回收行业异军突起&#xff0c;成为了市场上的热门话题。无论是街头巷尾的小店&#xff0c;还是网络上的各大平台&#xff0c;黄金回收的广告和宣传都屡见不鲜。那么&#xff0c;为什么最近黄金…

Prometheus Kube-Proxy endpoint connection refused

问题 Kube-Proxy endpoint connection refused 解决方法&#xff1a; $ kubectl edit cm/kube-proxy -n kube-system ## Change frommetricsBindAddress: 127.0.0.1:10249 ### <--- Too secure ## Change tometricsBindAddress: 0.0.0.0:10249 $ kubectl delete pod -l …

python代码性能分析

基准测试可以发现程序变慢了&#xff0c;那么是因为什么原因导致性能变慢的&#xff0c;需要进一步做代码性能分析。python同样提供了性能分析工具。 cProfile cProfile是python默认的性能分析器&#xff0c;他只测量CPU时间&#xff0c;并不关心内存消耗和其他与内存相关联的…

操作教程|使用MeterSphere对恒生UFX系统进行压力测试

恒生UFX&#xff08;United Finance Exchange&#xff0c;统一金融交换&#xff09;系统&#xff08;以下简称为“UFX系统”&#xff09;&#xff0c;是一款帮助证券公司统一管理外部接入客户的系统&#xff0c;该系统整体上覆盖了期货、证券、基金、银行、信托、海外业务等各类…

【实战】K8S集群部署nacos并接入Springcloud项目容器化运维

文章目录 前言Nacos集群搭建Spring cloud配置nacos将Springcloud项目部署在k8s写在最后 前言 相信很多同学都开发过以微服务为架构的系统&#xff0c;开发微服务必不可少要使用注册中心&#xff0c;比如nacos\consul等等。当然在自动化运维流行的今天&#xff0c;我们也会将注…

2024公共管理、工商管理和贸易经济国际学术会议(PABATE2024)

2024公共管理、工商管理和贸易经济国际学术会议(PABATE2024) 一、【会议简介】 2024公共管理、工商管理和贸易经济国际学术会议&#xff08;PABATE2024&#xff09;将于2024年在郑州举行。该会议旨在为公共管理、工商管理和贸易经济领域的学者和从业人员提供一个交流和分享的…

Day22:安全开发-PHP应用留言板功能超全局变量数据库操作第三方插件引用

目录 开发环境 数据导入-mysql架构&库表列 数据库操作-mysqli函数&增删改查 数据接收输出-html混编&超全局变量 第三方插件引用-js传参&函数对象调用 完整源码 思维导图 PHP知识点&#xff1a; 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0…

设计模式之备忘录模式

备忘录模式&#xff08;Memento&#xff09; 定义 在不破坏封装的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态。 使用场景 主要角色 发起人 Originator 需要备份的对象看管人 Caretaker 保存备份的容器备忘录 Memento 备份对象 类图…