尚医通 (二十五) --------- 医院上传接口

news2025/7/17 4:42:18

目录

  • 一、医院系统模拟接口
    • 1. 服务部署
    • 2. 操作说明
    • 3. 上传接口与回调接口
      • ① 业务术语
      • ② 安全控制
      • ③ 业务接口
      • ④ 平台接口
      • ⑤ 医院接口
  • 二、集成 MongoDB
  • 三、添加医院基础类
  • 四、上传医院
  • 五、参数签名
  • 六、图片 Base64 编码


一、医院系统模拟接口

1. 服务部署

① 找到资源文件夹下面的 hospital-manage 项目,导入 idea

在这里插入图片描述

在这里插入图片描述

② 导入sql,路径:hospital-manage/资源文件/sql/表结构.sql

在这里插入图片描述

在这里插入图片描述

③ 修改 application-dev.yml 文件数据库连接

在这里插入图片描述

④ 启动项目

在这里插入图片描述

2. 操作说明

① 访问项目

浏览器:http://localhost:9998/,如图

在这里插入图片描述
② 医院设置

我们在尚医通管理后台设置的医院信息配置到医院接口模拟系统,如图:

在这里插入图片描述

配置参数:

  • 医院 code:尚医通分配的医院 code
  • 签名 key:尚医通分配的签名 key
  • 统一预约挂号平台基础路径:尚医通接口基础路径

3. 上传接口与回调接口

上传接口包括的相关操作有医院、科室与排班等。

对应的测试数据在:hospital-manage/资源文件/示例数据。

回调接口包括预约下单、更新支付状态和取消预约等。

① 业务术语

医院编号:医院与尚医通合作后,尚医通合提供给医院的唯一标识ID号(hoscode)。

签名密钥:医院与尚医通合作后,尚医通提供给医院,用于接口调用的 MD5 数字签名算法的密码串 (signKey)。

② 安全控制

接口采用数据签名的方式来保证医院与尚医通系统间的身份验证、中间信息传递的完整性,以便进行电子商务安全当中非常重要的交易身份辨识、不可抵赖、防止篡改等功能。

③ 业务接口

传参说明:

所有参数递交的方式必须为 POST,参数值编码为 gb2312。如果采用拼接(如http://localhost?a=1&b=李四) 的形式提交,传参时要对参数值进行 url 编码,尤其是汉字、网址等。采用 Form 表单形式提交则不需要。参数值不要带空格。

验签参数sign生成:

a、组成加密串。所有变量值按照参数名 (不包含sign参数) 升序用 | 连接,最后连接 signKey。

b、加密。采用 32 位 MD5 小写 (编码utf-8) 加密。

c、例:假设接口参数 a=1,b=张三,c=13012345678,指派给商户的签名密钥signKey=1234567890,则加密串如下:1|张三|13012345678|1234567890

d、MD5(32位小写) 加密值核对。

Md5("123456")=e10adc3949ba59abbe56e057f20f883e

所有的字段都使用驼峰形式,如:agent_id 改为 agentId

返回/通知结果:所有接口同步返回

④ 平台接口

A、上传医院

医院的基本信息与规则信息

提交地址:http://localhost/api/hosp/saveHospital

请求参数:变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
hosnamestring50医院名称
hostypestring1医院类型(1:三级甲等,2:三级乙等,3:二级甲等,4:二级乙等,5:一级)
provinceCodestring18省code (国家统计局对应省的code)
cityCodestring50市code (国家统计局对应市的code)
districtCodestring10区code(国家统计局对应区的code)
addressstring20详情地址
logoDatastring11医院logo(转换为base64字符串)
introstring医院简介
routestring255坐车路线
bookingRulestring8000预约规则,json数据
timestamplong时间戳,从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数

bookingRule 例子:

{
	"cycle": "1",
	"releaseTime": "08:30",
	"stopTime": "11:30",
	"quitDay": "-1",
	"quitTime": "15:30",
	"rule": [
		"西院区预约号取号地点:西院区门诊楼一层大厅挂号窗口取号", "东院区预约号取号地点:东院区老门诊楼一层大厅挂号窗口或新门诊楼各楼层挂号/收费窗口取号"
     ]
}

bookingRule 说明:属性说明

  • cycle:预约周期
  • releaseTime:放号时间
  • stopTime:停挂时间
  • quitDay:退号截止天数(如:就诊前一天为-1,当天为0)
  • quitTime:退号时间
  • rule:预约规则,以数组形式传递

同步返回:
结果参数含义:

字段名类型长度必输说明
codestring结果编码。200:请求成功。不等于200:请求失败(message:失败原因)
messagestring100结果描述
datastring5000业务数据

B、上传科室

科室信息:
提交地址:http://localhost/api/hosp/saveDepartment

请求参数:

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
depcodestring50科室编号
depnamestring1科室名称
introstring18科室描述
bigcodestring50大科室编号
bignamestring10大科室名称
addressstring20详情地址
timestamplong时间戳。从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数

同步返回:

结果参数含义

字段名类型长度必输说明
codestring结果编码。200:请求成功;不等于200:请求失败(message:失败原因)
messagestring100结果描述
datastring5000业务数据

C、上传排班

排班信息

提交地址:http://localhost/api/hosp/saveSchedule

请求参数:

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
depcodestring20科室编号
titlestring30职称
docnamestring30医生名称
skillstring300擅长技能
workDatestring10安排日期(yyyy-MM-dd)
workTimeint安排时间 (0:上午 1:下午)
reservedNumberint可预约数
availableNumberint剩余预约数
amountstring5挂号费
statusint排班状态 (-1:停诊 0:停约 1:可约)
hosScheduleIdstring30排班编号 (医院自己的排班主键)
timestamplong时间戳,从1970-01-01 00:00:00算起的毫秒数
signstring32

同步返回 :

结果参数含义

字段名类型长度必输说明
codestring结果编码。200:请求成功,不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

D、查询医院

医院信息

提交地址:http://localhost/api/hosp/hospital/show

请求参数:

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
timestamplong时间戳,从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数。

同步返回:

结果参数含义

字段名类型长度必输说明
codestring结果编码,200:请求成功。不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

E、查询科室

科室信息

提交地址:http://localhost/api/hosp/department/list

请求参数

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
pageNumInt第几页
pageSizeInt每页个数
timestamplong时间戳。从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数。

同步返回

结果参数含义

字段名类型长度必输说明
codestring结果编码,200:请求成功。不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

F、查询排班

医院信息

提交地址:http://localhost/api/hosp/schedule/list

请求参数

变量定义:

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
pageNumInt第几页
pageSizeInt每页个数
timestamplong时间戳,从 1970-01-01 00:00:00 算起的毫秒数
signstring32验签参数

同步返回

结果参数含义:

字段名类型长度必输说明
codestring结果编码,200:请求成功,不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

G、删除科室

删除科室信息

提交地址:http://localhost/api/hosp/department/remove

请求参数

变量定义:

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
depcodestring30科室编号
timestamplong时间戳,从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数

同步返回

结果参数含义:

字段名类型长度必输说明
codestring结果编码 200:请求成功。不等于200:请求失败 (message:失败原因)
messagstring100结果描述
datastring5000业务数据

H、删除排班

删除排班信息

提交地址:http://localhost/api/hosp/schedule/remove

请求参数:

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
hosScheduleIdstrin30排班编号 (医院自己的排班主键)
timestamplong时间戳,从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数

同步返回

结果参数含义

字段名类型长度必输说明
codestring结果编码。200:请求成功,不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

⑤ 医院接口

A、预约下单

医院的基本信息与规则信息

提交地址:${basePath}/order/submitOrder

请求参数:

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
depcodestring20科室编号
hosScheduleIdstring30排班编号 (医院自己的排班主键)
reserveDatestring10安排日期 (yyyy-MM-dd)
reserveTimeint安排时间(0:上午 1:下午)
amountstring5挂号费
namestring20就诊人姓名
sexint就诊人性别
birthdatestring20就诊人出生年月
phonestring11就诊人手机
isMarryint就诊人是否结婚
provinceCodestring50
cityCodestring50市code (国家统计局对应市的code)
districtCodestring10区code (国家统计局对应区的code)
addressstring20就诊人详情地址
contactsNamestring11联系人姓名
contactsCertificatesTypeint联系人证件类型
contactsCertificatesNostring30联系人证件号
contactsPhonestring11联系人手机
isInsureint是否有医保
timestamplong时间戳,从 1970-01-01 00:00:00 算起的毫秒数
signstring32验签参数

同步返回

结果参数含义:

字段名类型长度必输说明
codestring结果编码:200:请求成功,不等于200:请求失败(message:失败原因)
messagestring100结果描述
datastring5000业务数据

data业务数据字段:

字段名类型长度必输说明
hosRecordIdstring预约记录唯一标识 (医院预约记录主键)
numberint预约序号
reservedNumberint排班可预约数
availableNumberint排班剩余预约数
fetchTimestring50取号时间
fetchAddressstring200取号地址

B、更新支付状态
平台支付成功,通过该接口更新医院支付状态

提交地址 :${basePath}/order/updatePayStatus

请求参数 :

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
hosRecordIdstring预约记录唯一标识 (医院预约记录主键)
timestamplong时间戳,从1970-01-01 00:00:00算起的毫秒数
signstring32验签参数

同步返回:

结果参数含义

字段名类型长度必输说明
codestring结果编码,200:请求成功。不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

C、取消预约

平台通过该接口取消预约

提交地址:${basePath}/order/updateCancelStatus

请求参数

变量定义

字段名类型长度必输说明
hoscodestring30给医院分配的唯一标识
hosRecordIdstring预约记录唯一标识 (医院预约记录主键)
timestamplong时间戳,从 1970-01-01 00:00:00 算起的毫秒数
signstring32验签参数

同步返回

结果参数含义

字段名类型长度必输说明
codestring结果编码,200:请求成功,不等于200:请求失败 (message:失败原因)
messagestring100结果描述
datastring5000业务数据

二、集成 MongoDB

A、添加依赖

service-hosp 模块 pom.xml 添加依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

在这里插入图片描述

B、添加配置

在 application.properties 文件添加配置

spring.data.mongodb.uri=mongodb://192.168.38.130:27017/yygh_hosp

说明:改为自己安装 MongoDB 的 IP 地址

这样写也可以:

在这里插入图片描述

三、添加医院基础类

A、添加 model

说明:由于实体对象没有逻辑,我们已经统一导入com.fancy.yygh.model.hosp.Hospital

B、添加 Repository

@Repository
public interface HospitalRepository extends MongoRepository<Hospital,String> {
    
}

在这里插入图片描述

C、添加 service 接口及实现类

添加 com.fancy.yygh.hosp.service.HospitalService 接口

public interface HospitalService {
 
}

添加com.fancy.yygh.hosp.service.impl.HospitalServiceImpl接口实现

package com.fancy.yygh.hosp.service.impl;

@Service
public class HospitalServiceImpl implements HospitalService {

	@Autowired
	private HospitalRepository hospitalRepository;

}

在这里插入图片描述

D、添加 controller

添加 com.fancy.yygh.hosp.api.ApiController

package com.fancy.yygh.hosp.api;

@Api(tags = "医院管理API接口")
@RestController
@RequestMapping("/api/hosp")
public class ApiController {

	@Autowired
	private HospitalService hospitalService;

}

说明:平台对外开发的接口都写在该 Controller 类

在这里插入图片描述

四、上传医院

医院编号是平台分配的,全局唯一,上传医院接口可以多次调用,如果存在相同编号的为更新操作

A、接口数据分析

{
	"hoscode": "1000_0",
	"hosname": "北京协和医院",
	"hostype": "1",
	"provinceCode": "110000",
	"cityCode": "110100",
	"districtCode": "110102",
	"address": "大望路",
	"intro": "北京协和医院是集医疗、教学、科研于一体的大型三级甲等综合医院,是国家卫生计生委...目标而继续努力。",
	"route": "东院区乘车路线:106、...更多乘车路线详见须知。",
	"logoData": "iVBORw0KGgoAAAA...NSUhEUg==",
	"bookingRule": {
		"cycle": "1",
		"releaseTime": "08:30",
		"stopTime": "11:30",
		"quitDay": "-1",
		"quitTime": "15:30",
		"rule": [
			"西院区预约号取号地点:西院区门诊楼一层大厅挂号窗口取号",
			"东院区预约号取号地点:东院区老门诊楼一层大厅挂号窗口或新门诊楼各楼层挂号/收费窗口取号"
		]
    }
}

说明:

  • 数据分为医院基本信息与预约规则信息
  • 医院logo转换为base64字符串
  • 预约规则信息属于医院基本信息的一个属性
  • 预约规则rule,以数组形式传递
  • 数据传递过来我们还要验证签名,只允许平台开通的医院可以上传数据,保证数据安全性

B、添加 service 接口

在 HospitalService 类添加接口

/**
 * 上传医院信息
 * @param paramMap
*/
void save(Map<String, Object> paramMap);

说明:参数使用Map,减少对象封装,有利于签名校验,后续会体验到

在 HospitalServiceImpl 类添加实现

@Override
public void save(Map<String, Object> paramMap) {
	log.info(JSONObject.toJSONString(paramMap));
	Hospital hospital = JSONObject.parseObject(JSONObject.toJSONString(paramMap),Hospital.class);
	//判断是否存在
	Hospital targetHospital = hospitalRepository.getHospitalByHoscode(hospital.getHoscode());
	if(null != targetHospital) {
		hospital.setStatus(targetHospital.getStatus());
		hospital.setCreateTime(targetHospital.getCreateTime());
		hospital.setUpdateTime(new Date());
		hospital.setIsDeleted(0);
		hospitalRepository.save(hospital);
	} else {
		//0:未上线 1:已上线
		hospital.setStatus(0);
		hospital.setCreateTime(new Date());
		hospital.setUpdateTime(new Date());
		hospital.setIsDeleted(0);
		hospitalRepository.save(hospital);
	}
}

说明:

Hospital hospital = JSONObject.parseObject(JSONObject.toJSONString(paramMap),Hospital.class);

Map 转换为 Hospital 对象时,预约规则 bookingRule 为一个对象属性,rule 为一个数组属性,因此在转换时我们要重新对应的 set 方法,不然转换不会成功

public class Hospital extends BaseMongoEntity {

	private static final long serialVersionUID = 1L;
	
	@ApiModelProperty(value = "医院编号")
	private String hoscode;
	
	...
	
	//预约规则
	@ApiModelProperty(value = "预约规则")
	private BookingRule bookingRule;
	
	public void setBookingRule(String bookingRule) {
		this.bookingRule = JSONObject.parseObject(bookingRule, BookingRule.class);
	}

}


public class BookingRule {

	@ApiModelProperty(value = "预约周期")
	private Integer cycle;
	
	...
	
	@ApiModelProperty(value = "预约规则")
	private List<String>rule;
	
	/**
	    *
	    * @param rule
	*/
	public void setRule(String rule) {
		if(!StringUtils.isEmpty(rule)) {
			this.rule = JSONArray.parseArray(rule, String.class);
		}
	}

}

C、添加repository接口

在 HospitalRepository 类添加接口

Hospital getHospitalByHoscode(String hoscode);

D、添加 controller 接口

在 ApiController 类添加接口

@ApiOperation(value = "上传医院")
@PostMapping("saveHospital")
public Result saveHospital(HttpServletRequest request) {
   	Map<String, Object> paramMap = HttpRequestHelper.switchMap(request.getParameterMap());
	hospitalService.save(paramMap);
	return Result.ok();
}

E、添加帮助类

在 service-util 模块添加 HttpRequestHelper 帮助类

package com.fancy.yygh.common.helper;


@Slf4j
public class HttpRequestHelper {

	/**
	*
	* @param paramMap
	* @return
	*/
	public static Map<String, Object> switchMap(Map<String, String[]> paramMap) {
		Map<String, Object> resultMap = new HashMap<>();
		for (Map.Entry<String, String[]> param : paramMap.entrySet()) {
			resultMap.put(param.getKey(), param.getValue()[0]);
		}
		return resultMap;
	}
}

五、参数签名

A、封装签名方法

在 service-util 模块 HttpRequestHelper 类添加方法

public static void main(String[] args) {
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("d", "4");
    paramMap.put("b", "2");
    paramMap.put("c", "3");
    paramMap.put("a", "1");
	paramMap.put("timestamp", getTimestamp());
	log.info(getSign(paramMap, "111111111"));
}


/**
* 请求数据获取签名
* @param paramMap
* @param signKey
* @return
*/
public static String getSign(Map<String, Object> paramMap, String signKey) {
	if(paramMap.containsKey("sign")) {
        paramMap.remove("sign");
    }
    TreeMap<String, Object> sorted = new TreeMap<>(paramMap);
    StringBuilder str = new StringBuilder();
	for (Map.Entry<String, Object> param : sorted.entrySet()) {
        str.append(param.getValue()).append("|");
    }
    str.append(signKey);
	log.info("加密前:"+ str.toString());
    String md5Str = MD5.encrypt(str.toString());
	log.info("加密后:"+ md5Str);
	return md5Str;
}

/**
 * 签名校验
 * @param paramMap
* @param signKey
* @return
*/
public static boolean isSignEquals(Map<String, Object> paramMap, String signKey) {
    String sign = (String)paramMap.get("sign");
    String md5Str = getSign(paramMap, signKey);
	if(!sign.equals(md5Str)) {
		return false;
    }
	return true;
}

/**
 * 获取时间戳
 * @return
*/
public static long getTimestamp() {
	return new Date().getTime();
}

B、上传医院添加签名校验

我们在医院设置的时候,为每个医院生成了医院编码与签名key,因此我在验证签名时要根据医院编码去动态获取签名key,然后再做签名校验

添加获取签名key接口

1,在 HospitalSetService 类添加接口

/**
 * 获取签名key
 * @param hoscode
* @return
*/
String getSignKey(String hoscode);

2,在 HospitalSetServiceImpl 类实现接口

@Override
public String getSignKey(String hoscode) {
	HospitalSet hospitalSet = this.getByHoscode(hoscode);
	if(null == hospitalSet) {
		throw new YyghException(ResultCodeEnum.HOSPITAL_OPEN);
	}
	if(hospitalSet.getStatus().intValue() == 0) {
		throw new YyghException(ResultCodeEnum.HOSPITAL_LOCK);
	}
	return hospitalSet.getSignKey();
}

/**
 * 根据hoscode获取医院设置
 * @param hoscode
* @return
*/
private HospitalSet getByHoscode(String hoscode) {
	return hospitalSetMapper.selectOne(new QueryWrapper<HospitalSet>().eq("hoscode", hoscode));
}

修改 ApiController 类上传医院接口:

修改 ApiController 类上传医院接口

@ApiOperation(value = "上传医院")
@PostMapping("saveHospital")
public Result saveHospital(HttpServletRequest request) {
	Map<String, Object> paramMap = HttpRequestHelper.switchMap(request.getParameterMap());
	//必须参数校验 略
	String hoscode = (String)paramMap.get("hoscode");
	if(StringUtils.isEmpty(hoscode)) {
		throw new YyghException(ResultCodeEnum.PARAM_ERROR);
	}
	//签名校验
	if(!HttpRequestHelper.isSignEquals(paramMap, hospitalSetService.getSignKey(hoscode))) {
		throw new YyghException(ResultCodeEnum.SIGN_ERROR);
	}

	hospitalService.save(paramMap);
	return Result.ok();
}

六、图片 Base64 编码

A、图片 base64 说明

图片的 Base64 编码就是可以将一张图片数据编码成一串字符串,使用该字符串代替图像地址 url

在前端页面中常见的 Base64 图片的引入方式:

<img src="data:image/png;base64,iVBORw0..>

优点

  • Base64 格式的图片是文本格式,占用内存小,转换后的大小比例大概为 1/3,降低了资源服务器的消耗;
  • 网页中使用 Base64 格式的图片时,不用再请求服务器调用图片资源,减少了服务器访问次数。

缺点

  • Base64 格式的文本内容较多,存储在数据库中增大了数据库服务器的压力
  • 网页加载图片虽然不用访问服务器了,但因为 Base64 格式的内容太多,所以加载网页的速度会降低,可能会影响用户的体验。

说明:医院 logo 图片小,因此上传医院 logo 是可以使用Base64 格式保存

B、图片 Base64 工具类

在 common-util 模块添加工具类
添加 com.fancy.yygh.common.util.ImageBase64Util 类

package com.fancy.yygh.common.util;

import org.apache.commons.codec.binary.Base64;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class ImageBase64Util {

	public static void main(String[] args) {
		String imageFile= "D:\\yygh_work\\xh.png";// 待处理的图片
		System.out.println(getImageString(imageFile));
	}
	
	public static String getImageString(String imageFile){
		InputStream is = null;
		try {
			byte[] data = null;
			is = new FileInputStream(new File(imageFile));
			data = new byte[is.available()];
			is.read(data);
			return new String(Base64.encodeBase64(data));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != is) {
				try {
					is.close();
					is = null;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return "";
	}
}

C、上传医院接口修正

图片转换为 Base64 字符串时,该字符串中包含大量的加号“+”,服务器在解析数据时会把加号当成连接符,转换为空格,因此我们要做一下特殊处理

修改 ApiController 类上传接口

@ApiOperation(value = "上传医院")
@PostMapping("saveHospital")
public Result saveHospital(HttpServletRequest request) {
    Map<String, Object> paramMap = HttpRequestHelper.switchMap(request.getParameterMap());
	//必须参数校验 略
	String hoscode = (String)paramMap.get("hoscode");
	if(StringUtils.isEmpty(hoscode)) {
		throw new YyghException(ResultCodeEnum.PARAM_ERROR);
   	}
	//传输过程中“+”转换为了“ ”,因此我们要转换回来
	String logoDataString = (String)paramMap.get("logoData");
	if(!StringUtils.isEmpty(logoDataString)) {
		String logoData = logoDataString.replaceAll("", "+");
		paramMap.put("logoData", logoData);
    }

	//签名校验
	if(!HttpRequestHelper.isSignEquals(paramMap, hospitalSetService.getSignKey(hoscode))) {
		throw new YyghException(ResultCodeEnum.SIGN_ERROR);
    }

	hospitalService.save(paramMap);
	return Result.ok();
}

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

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

相关文章

ArcGIS pro导出地图删除右下角小字制作者服务许可

ArcGIS pro导出地图删除右下角小字制作者服务许可 ArcGIS pro具有强大的制图功能&#xff0c;提供了丰富的底图。 研究者在使用这些底图出图时&#xff0c;发现地图右下角有__制作者名单、服务许可、来源&#xff1f;__ &#xff08;我也不知道它叫什么&#xff09;如下图 就…

【深入浅出Spring6】第六期——手写Spring框架与Spring IoC注解式开发

一、手写Spring框架 $ 准备工作 创建新的模块 myspring我们采用边测试边写框架的方式&#xff0c;所以还需要我们提供待测试的类 一号嘉宾——User类&#xff1a;用于一般类型传值测试 package com.powernode.myspring.bean; /*** author Bonbons* version 1.0*/ public clas…

【面试题】CSS响应式

1. rem是什么&#xff1f; rem&#xff0c;CSS3新增的一个相对单位&#xff08;root em&#xff0c;根em&#xff09;&#xff0c;相对于根元素&#xff0c;常用于响应式布局em&#xff0c;相对长度单位&#xff0c;相对于父元素&#xff0c;不常用px&#xff0c;像素&#xf…

中兴通讯完成基于低频 5G 商用基站的通感融合测试验证

11 月 16 日消息&#xff0c;今年 11 月&#xff0c;在 IMT-2020&#xff08;5G&#xff09;推进组的指导下&#xff0c;中兴通讯使用 4.9GHz 低频 5G 商用基站&#xff0c;完成了室外无人机、车辆和行人感知测试验证以及室内场景下呼吸感知的测试验证。验证结果显示&#xff0…

api-ms-win-crt-runtime-l1-1-0.dll文件加载失败是怎么造成的?怎么修复?

电脑中是含有大量不同类型的软件程序的&#xff0c;这些软件程序为用户们提供了丰富的功能&#xff0c;用户们使用这些软件的时候虽然看上去比较简单&#xff0c;但是电脑系统内部却是会调用大量文件的&#xff0c;在软件执行命令的过程中无论哪个环节出现了问题&#xff0c;都…

DDD系列 实战一 应用设计案例 (golang)

DDD系列 实战一 应用设计案例 (golang) 基于 ddd 的设计思想, 核心领域需要由纯内存对象基础设施的抽象的接口组成 独立于外部框架: 比如 web 框架可以是 gin, 也可以是 beego独立于客户端: 比如客户端可以是 web, 可以是移动端, 也可以是其他服务 rpc 调用独立于基础组件: 比如…

数据结构计算二叉树的深度和节点个数

2022.11.19 计算二叉树的深度和节点个数任务描述相关知识编程要求测试说明C/C代码任务描述 本关任务&#xff1a;给定一棵二叉树&#xff0c;计算该二叉树的深度、总节点个数和叶子节点个数。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.二叉树深度概念…

【Java八股文总结】之类

文章目录Q&#xff1a;一个Java文件中可以有多个类么&#xff08;不含内部类&#xff09;&#xff1f;一、Object类1、Object类的常见方法有哪些&#xff1f;2、 和 equals() 的区别3、HashCode()的作用&#xff1f;4、为什么要有hashCode&#xff1f;5、为什么重写equals()时必…

古人的雅趣

学习古人雅趣&#xff0c;为今日生活增添情趣。 目录 曲水流觞 九月九日重阳节赏菊 中秋赏月 一、曲水流觞 中国古代汉族民间的一种传统习俗&#xff0c;后来发展成为文人墨客诗酒唱酬的一种雅事。 夏历的三月上巳日人们举行祓禊&#xff08;fx&#xff09;仪式之后&#xf…

单流 TCP 100Gbps+ 难题的直观解释

关于 400Gbps 场景的概括&#xff0c;参见&#xff1a;400Gbps 网络面临的挑战 首先定义规则&#xff1a; 画坐标系&#xff0c;横轴为到达时间&#xff0c;纵轴为服务(处理)时间。每到达一个任务在横轴对应时间画一条垂直线。每处理一个任务在纵轴对应时间画一条水平线。任务…

【Linux】文件操作/文件描述符/重定向原理/缓冲区

目录 一.文件的概念 1.什么是内存级文件? 2.什么是磁盘级文件? 3.文件IO的过程 4.linux下, 一切皆文件 二.文件操作(C语言接口) 1.语言级文件接口与系统级文件接口 1).什么是语言级别的文件接口? 2).为什么要有语言级别文件接口, 直接用系统接口不好吗? 3).系统级…

老系统如何重构之最全总结

目录 1. 重构的概念 1.1 重构的定义 1.2 重构的分类 2 为什么重构 3 如何重构 3.1 说服业务方 3.2 确定重构的目标 3.3 老系统的熟悉与梳理 3.4 数据库的重构 3.5 前后端的系统重构 3.6 数据迁移与检查 3.7 系统检查联调测试 3.8 系统切换 1. 重构的概念 1.1 重构…

DlhSoft Gantt Chart Hyper Library for HTML5 Standard Edition

DlhSoft Gantt Chart Hyper Library 甘特图超级库包括一组交互式计划组件&#xff0c;可用于使用纯 JavaScript、TypeScript 或 Angular、React 或 Vue 等框架构建的启用时间线的应用程序 基于 JavaScript 的甘特图 可定制的网格列、汇总的工作分解结构、带有可拖动条和依赖线…

静态HTML网页设计作品 DIV布局家乡介绍网页模板代码---(太原 10页带本地存储登录注册 js表单校验)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 家乡旅游景点 | 家乡民生变化 | 介绍自己的家乡 | 我的家乡 | 家乡主题 | HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&#xff1a;样式 在…

基于ssm jsp超市在线销售平台的设计与实现

近年来&#xff0c;网络信息技术的迅猛发展&#xff0c;互联网逐渐渗透到人们日常生活中的方 方面面&#xff0c;而给我们的生活带来巨大变化的电子商务正在以前所未有的速度蓬勃发 展&#xff0c;电子商务也成为网络研究与应用的热点之一。网上商店是电子商务的重要方 面&…

【干货】教你在十分钟内编译一个Linux内核,并在虚拟机里运行!

前言 这篇文章将会简单的介绍如何在Linux系统上面&#xff0c;编译一个5.19的内核&#xff0c;然后在QEMU虚拟机中运行。 下载Linux内核源码 首先&#xff0c;我们需要下载Linux的代码&#xff1a; https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.19.10.t…

使用vue互联QQ音乐完成网站音乐播放器

&#x1f3b6; 文章简介&#xff1a;使用vue互联QQ音乐完成网站音乐播放器 &#x1f4a1; 创作目的&#xff1a;记录使用APlayer播放器MetingJs实现 在线播放qq音乐、网易云音…等平台的音乐 ☀️ 今日天气&#xff1a;2022-11-19 小雨多云 天空灰蒙蒙的 &#x1f972; &#x…

还在付费使用 XShell?我选择这款超牛逼的 SSH 客户端,完全免费

分享过FinallShell这款SSH客户端&#xff0c;也是xiaoz目前常用的SSH客户端工具&#xff0c;FinalShell使用起来方便顺手&#xff0c;但令我不爽的是tab数量变多的时候FinalShell越来越卡&#xff0c;而且内存占用也比较高。 最近发现一款使用使用C语言开发的跨平台SSH客户端W…

【无人机】基于Matlab的四旋翼无人机控制仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

uni-app —— 下拉刷新 上拉加载

文章目录 前言一、下拉刷新 1.开启下拉刷新2.监听下拉刷新3.关闭下拉刷新二、上拉加载总结一、下拉刷新 1. 开启下拉刷新 在uni-app中有两种方式开启下拉刷新 需要在 ​​pages.json ​​​ 里&#xff0c;找到的当前页面的pages节点&#xff0c;并在​​style​​​ 选项中开…