新入工作微信群打招呼给别人打招呼然后别人回复了两条信息,上一条怎么查看?


提交成功是否继续回答问题?
手机回答更方便,互动更有趣,下载APP
展开全部微信有打招呼的功能,自己一方和陌生人一方都可以打招呼。那么如何查看曾经打过招呼的人的招呼记录呢?查看是否有回复等。工具/原料微信客户端方法/步骤1首先打开微信客户端,选择-发现-附近的人。2然后,选择右上角三点图案。3接着,点开附近打招呼的人。4由于人气旺盛,附近打招呼的人太多,可以一一查看曾近打过招呼的人的信息。5任意点开一个人,还可以查看到招呼记录,说了什么话等。并且可以持续打招呼已赞过已踩过你对这个回答的评价是?评论
收起推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
下载百度知道APP,抢鲜体验使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。扫描二维码下载
×个人、企业类侵权投诉
违法有害信息,请在下方选择后提交
类别色情低俗
涉嫌违法犯罪
时政信息不实
垃圾广告
低质灌水
我们会通过消息、邮箱等方式尽快将举报结果通知您。说明
做任务开宝箱累计完成0
个任务
10任务
50任务
100任务
200任务
任务列表加载中...
}
一、mysql函数创建用户并且授权CREATE USER 'testroot'@'%' IDENTIFIED BY 'testpassword'; GRANT ALL ON test.* TO 'testroot'@'%'; count查询status为1,2的数量select count(case when status = '1' then 1 end) as count1,count(case when status = '2' then 1 end) as count2 from tb group_concatgroup_concat函数常用于select 语句中,下面我们通过一张表来讲解group_concat函数的用法。以下为表exam内容|id subject student|teacher|score --------------------------------------- 1 数学 小红 王老师 80 2 数学 小李 王老师 80 3 数学 小王 王老师 70 4 数学 小张 王老师 90 5 数学 小赵 王老师 70 6 数学 小孙 王老师 80 7 数学 小钱 王老师 90 8 数学 小高 王老师 70 9 数学 小秦 王老师 80 10 数学 小马 王老师 90 11 数学 小朱 王老师 90 12 语文 小高 李老师 70 15 语文 小秦 李老师 70 18 语文 小马 李老师 80 21 语文 小朱 李老师 90 24 语文 小钱 李老师 90 我们希望按分数score进行分组,并查看分组后的学生姓名,就可以用group_concat实现。执行sql:select score,group_concat(student) from exam group by score; 执行结果为:|score group_concat(student) ------------------------------------- 70 小王,小赵,小高,小高,小秦 80 小红,小李,小孙,小秦,小马 90 小张,小钱,小马,小朱,小朱,小钱 在70分这一行有两条小高的记录,90分这一行有两条小钱和小朱的记录,如果我们需要去重,则需要给函数中加一个distinct参数:select score,group_concat(distinct student) from exam group by score; 执行结果为:|score group_concat(student) --------------------------------- 70 小王,小赵,小高,小秦 80 小红,小李,小孙,小秦,小马 90 小张,小钱,小马,小朱 这样group_concat每行数据的结果中就没有了重复值,但是在数据中的分隔符为默认的逗号’,',如果想修改默认的分隔符,只需要在上述指令中稍作修改:select score,group_concat(distinct student separator '%') from exam group by score; 执行结果:|score group_concat(student) --------------------------------- 70 小王%小秦%小赵%小高 80 小孙%小李%小秦%小红%小马 90 小张%小朱%小钱%小马 any_value1.MySQL5.7之后,sql_mode中ONLY_FULL_GROUP_BY模式默认设置为打开状态。2.ONLY_FULL_GROUP_BY的语义就是确定select target list中的所有列的值都是明确语义,简单的说来,在此模式下,target list中的值要么是来自于聚合函数(sum、avg、max等)的结果,要么是来自于group by list中的表达式的值3.MySQL提供了any_value()函数来抑制ONLY_FULL_GROUP_BY值被拒绝4.any_value()会选择被分到同一组的数据里第一条数据的指定列值作为返回数据例子:student_score表:+----+-----------+--------+-------+-----------------+ id username course score class +----+-----------+--------+-------+-----------------+ 1 小王 英语 15 三年级一班 2 小李 英语 10 三年级一班 3 小艾 数学 5 三年级一班 4 小星 数学 52 三年级二班 5 蔡国 数学 100 三年级二班 6 诸葛里 英语 89 三年级二班 7 东方曜 数学 100 三年级二班 8 小赵 数学 100 三年级一班 +----+-----------+--------+-------+-----------------+查询SELECT class,any_value(username) FROM student_score group by class; 正确查询SELECT class,any_value(username) FROM student_score group by class; 查询结果+-----------------+---------------------+ class any_value(username) +-----------------+---------------------+ 三年级一班 小王 三年级二班 小星 +-----------------+---------------------+ concat/concat_ws-将多个字符串连接成为一个字符串concat返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。以sudent_score表为例,concat_ws进行分select concat(id,name) as string,concat_ws(',',id,name) as string2 from student_score; 查询结果+--------+---------+ string string2 +--------+---------+ 1li 1,li 2li 2,li 3x 3,x +--------+---------+ case-类似于switch case用法SELECT CASEWHEN THEN WHEN THEN ELSE END FROM 例子:SELECTTitle,'Price Range' =CASEWHEN price IS NULL THEN 'Unpriced'WHEN price < 10 THEN 'Bargain'WHEN price BETWEEN 10 and 20 THEN 'Average'ELSE 'Gift to impress relatives'END FROM titles ORDER BY price json_unquote与json_extractjson_unquote 去除json字符串的引号,将值转成string类型json_extract截取数据库中指定字段中存储的json数据中的某个字段对应的值使用例子-- 表 tb_json, json字段 content select json_unquote(json_extract( tj.content, '$.list' )) from tb_json tj; 查询5分钟内的数据select * from tb_order where is_deleted = 0 and create_time <= date_sub(now(),interval 5 minute) 查询本月数据select count(*) from tb_parking_lot_data where parking_name = '十四都游客服务中心' and date_format( create_time, '%Y-%m') = date_format('2022-09-18 12:44:34', '%Y-%m') and total = used and status =1 and is_deleted=0;select count(*) from tb_parking_lot_data where date_format( create_time, '%Y-%m') = date_format(now(), '%Y-%m') and status =1 and is_deleted=0; 查询上月数据select count(*) from tb_parking_lot_data where period_diff(date_format(now(),'%Y-%m' ),date_format( create_time,'%Y-%m')) =1 and status =1 and is_deleted=0; 查询每天每小时的数据select hour(create_time) as hour , count(*) as count from tb_parking_lot_data where create_time >'2022-10-18' and create_time<'2022-10-18 239:59' group by hour(create_time); 查询最近七天每天的数据select DATE_FORMAT( "update_time", '%Y-%m-%d' ) days,count(*) count from( select * from tbWHERE DATE_SUB( CURDATE( ), INTERVAL 7 DAY ) <= date( "update_time") ) as tb GROUP BY days; 查询一周内数据(周一到周日)select * from tb_pairing_support_log tpsl where is_deleted = 0 and yearweek(date_format(create_time,'%Y-%m-%D'),1) = yearweek(date_format(now(),'%Y-%m-%D'),1); 查询重复数据-- 查询手机号,姓名, 角色重复的信息 select * from blade_user b where (b.account,b.real_name,b.role_id) in (select account,real_name,role_id from blade_userwhere is_deleted = 0group by account,real_name,role_id having count(*) > 1 ) String TO Date-- start_time_str: 20221010 => 2022-10-10 update tb_waicao_workshop set start_time = str_to_date(start_time_str,'%Y%m%d') where start_time_str is not null; 根据身份证号设置省份update tb_screen_rent_people ts set ts.province = (selectcase left(ts.id_number,2)when '11' then '北京市'when '12' then '天津市'when '13' then '河北省'when '14' then '山西省'when '15' then '内蒙古自治区'when '21' then '辽宁省'when '22' then '吉林省'when '23' then '黑龙江省'when '31' then '上海市'when '32' then '江苏省'when '33' then '浙江省'when '34' then '安徽省'when '35' then '福建省'when '36' then '江西省'when '37' then '山东省'when '41' then '河南省'when '42' then '湖北省'when '43' then '湖南省'when '44' then '广东省'when '45' then '广西壮族自治区'when '46' then '海南省'when '50' then '重庆市'when '51' then '四川省'when '52' then '贵州省'when '53' then '云南省'when '54' then '西藏自治区'when '61' then '陕西省'when '62' then '甘肃省'when '63' then '青海省'when '64' then '宁夏回族自治区'when '65' then '新疆维吾尔自治区'when '71' then '台湾省'when '81' then '香港特别行政区'when '82' then '澳门特别行政区'else '未知'end ) where ts.id_number is not null; 二、mybatis标签XMl 大于小于大于等于= ]]> 小于等于 likeand village_name like concat(concat('%', #{accountInfo.villageName}),'%') wherewhere标签的作用类似于动态sql中的set标签,主要用来简化sql语句中where条件,使得MyBatis 自动判断是否需要加where语句,并且避免在查询条件开头强制添加类似WHERE state = 'ACTIVE'语句之后,才可以添加if标签。使用案例如下所示:   案例解析:按照标准写法,第一个标签内应该不写 and,但是,即便写了and也不会报错,因为where标签自动地帮助我们移除了第一个and关键字。温馨提示,第二个之后的标签内,必须有 and 关键字。where标签只有在一个以上的if条件有值的情况下,才去主动添加WHERE子句。而且,若紧邻where关键字的内容是“AND”或“OR”开头,则where标签自动把它们去除。例如,在上述SQL中,如果只有查询条件id的值为null,那么控制台打印出来的SQL为:select * from user where name="xx" and gender="yy"; if如果条件成立就附加之间的sql语句,如果条件不成立就不附加之间的sql语句。foreach示例public List queryUserByIdsList(List list); SELECT project_name FROM project WHERE project_id IN#{item} 三、JAVA/SpringBoot获取从今天起(包括今天)的七天日期List dateList = new ArrayList<>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); for (int i = 0; i < 7; i++) {Date date = DateUtils.addDays(new Date(), i);String formatDate = sdf.format(date);dateList.add(formatDate); } 获取年月日Date birthday = one.getBirthday(); Calendar calendar = Calendar.getInstance(); calendar.setTime(birthday); // 出生年份 int birthDayYear = calendar.get(Calendar.YEAR); java8-stream流链接:https://www.runoob.com/java/java8-streams.html遍历personList.stream().forEach(person -> {if(person.getAge() > 11){person.setId(0L);} }); 排序-sorted// 默认升序, reversed() 倒序 List sortList = personList.stream().limit(1).sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList()); 过滤-filter// 过滤数据集-获取集合中年龄小于11岁的数据 List personList2 = personList.stream().filter(person -> person.getAge() < 11).collect(Collectors.toList()); 获取指定数量-limit// 获取排序后的前两个数据 List sortList = personList.stream().sorted(Comparator.comparing(Person::getAge).reversed()).limit(2).collect(Collectors.toList());System.out.println(sortList); XXXWrapper-返回视图层所需的字段例子:/*** 包装类,返回视图层所需的字段** @author Chill*/ public class DeptWrapper extends BaseEntityWrapper {private static IDeptService deptService;static {deptService = SpringUtil.getBean(IDeptService.class);}public static DeptWrapper build() {return new DeptWrapper();}/*** 单个dept -> deptVo*/@Overridepublic DeptVO entityVO(Dept dept) {DeptVO deptVO = BeanUtil.copy(dept, DeptVO.class);if (Func.equals(dept.getParentId(), CommonConstant.TOP_PARENT_ID)) {deptVO.setParentName(CommonConstant.TOP_PARENT_NAME);} else {Dept parent = deptService.getById(dept.getParentId());deptVO.setParentName(parent.getDeptName());}return deptVO;}/*** 多个dept -> 多个deptVo*/public List listNodeVO(List list) {List collect = list.stream().map(dept -> BeanUtil.copy(dept, DeptVO.class)).collect(Collectors.toList());return ForestNodeMerger.merge(collect);}/*** 多个dept -> 多个deptVo*/public List listNodeVO(List list) {List collect = list.stream().map(this::entityVO).collect(Collectors.toList());return ForestNodeMerger.merge(collect);}} 在视图层进行转换1.单个情况 /*** 详情*/@GetMapping("/detail")@ApiOperationSupport(order = 1)@ApiOperation(value = "详情", notes = "传入role")public R detail(Role role) {Role detail = roleService.getOne(Condition.getQueryWrapper(role),false);return R.data(RoleWrapper.build().entityVO(detail));} 2.多个情况 /*** 详情*/@GetMapping("/detail")@ApiOperationSupport(order = 1)@ApiOperation(value = "详情", notes = "传入role")public R detail(Role role) {Role detail = roleService.getOne(Condition.getQueryWrapper(role),false);return R.data(RoleWrapper.build().entityVO(detail));} 3.分页情况-XXXWrapper.build().pageVO(pages) /*** 分页 党建活动详情*/@GetMapping("/list")@ApiOperationSupport(order = 2)@ApiOperation(value = "分页 党建活动列表", notes = "传入partyActivityInfo")public R> list(ActivityInfo partyActivityInfo, Query query) {IPage pages = partyActivityInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(partyActivityInfo));return R.data(PartyActivityInfoWrapper.build().pageVO(pages));} 增删改查增/改Controller /*** 新增或修改*/@PostMapping("/submit")@ApiOperationSupport(order = 4)@ApiOperation(value = "新增或修改", notes = "传入dept")public R submit(@Valid @RequestBody Dept dept) {if(dept == null){throw new ServiceException("部门信息不能为空");}// 如果需要一些其他步骤,这样做,否则直接:deptService.saveOrUpdate(dept)return R.status(deptService.submit(dept));} ServerImpl @Overridepublic boolean submit(Dept dept) {CacheUtil.clear(CacheUtil.SYS_CACHE);// 检验**return saveOrUpdate(dept);} 删根据多个id删除Controller /*** 删除 岗位表*/@PostMapping("/remove")@ApiOperationSupport(order = 7)@ApiOperation(value = "逻辑删除", notes = "传入ids")public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {// 如果需要一些其他步骤,这样做,否则直接:return R.status(postService.deleteLogic(Func.toLongList(ids)));return R.status(deptService.removeActivityInfo(ids));} ServerImpl@Overridepublic boolean removeActivityInfo(String ids) {// 检验ids非空if (!StringUtil.isBlank(ids)) {// 检验***}return this.deleteLogic(Func.toLongList(ids));} 查查详情 /*** 1.根据id查询详情*/@GetMapping("/detail")@ApiOperationSupport(order = 1)@ApiOperation(value = "详情", notes = "传入region")public R detail(@valid Region region) {if(Func.isEmpty(activityInfo) null == region.getId()){throw new ServiceException("id不能为空");}Region detail = regionService.getById(region.getId());return R.data(RegionWrapper.build().entityVO(detail));} /*** 1.根据传参查询详情*/@GetMapping("/detail")@ApiOperationSupport(order = 1)@ApiOperation(value = "详情", notes = "传入region")public R detail(@valid Region region) {if(Func.isEmpty(activityInfo)){throw new ServiceException("传入参数不能为空");}Region detail = regionService.getOne(Condition.getQueryWrapper(region));return R.data(RegionWrapper.build().entityVO(detail));} 分页查询根据传入类型的具体非空参数进行查询 /*** 分页-活动列表*/@GetMapping("/list")@ApiOperationSupport(order = 5)@ApiOperation(value = "活动列表", notes = "传入activityInfo")public R> list(Query query,ActivityInfo activityInfo) {IPage page = activityInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(activityInfo));return R.data(page);} 根据名称模糊查询,分页IPage page = activityInfoService.page(Condition.getPage(query), Wrappers.lambdaQuery(ActivityInfo.class).like(ActivityInfo::getName,"123"));return R.data(page); 根据名称模糊查询,按照时间排序,分页IPage page = activityInfoService.page(Condition.getPage(query), Wrappers.lambdaQuery(ActivityInfo.class).like(ActivityInfo::getName,"123").orderByDesc(ActivityInfo::getActivityStartTime));return R.data(page); 自定义分页查询controller /*** 自定义分页*/@GetMapping("/page")@ApiOperation(value = "分页", notes = "传入tenant")public R> page(Tenant tenant, Query query) {IPage pages = tenantService.selectTenantPage(Condition.getPage(query), tenant);return R.data(pages);} ServiceImpl @Overridepublic IPage selectTenantPage(IPage page, Tenant tenant) {return page.setRecords(baseMapper.selectTenantPage(page, tenant));} MapperList selectTenantPage(IPage page,@Param("tenant") Tenant tenant); Mapper.xml 防止用户多次点击 String key = "Publish:"+ + AuthUtil.getUserId();Long increment = redisTemplate.opsForValue().increment(key, 1L);redisTemplate.expire(key, 2, TimeUnit.SECONDS);if (increment > 1L) {throw new ServiceException("请勿点击过快");} 通过图片URL下载图片到本地package com.spring.cache.utils;import org.springframework.stereotype.Component;import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.UUID;@Component public class FileUtils {private final static String serverPath = "/sqt-workspace/images/";/*** 通过URL将图片存入本地* @param pictureUrl* @return*/public static String getFile(String pictureUrl) throws IOException {URL url = new URL(pictureUrl);HttpURLConnection connection = (HttpURLConnection)url.openConnection();//设置请求方式connection.setRequestMethod("GET");//设置超时时间connection.setConnectTimeout(10*1000);//输入流InputStream stream = null;//输出流,图片输出的目的文件BufferedOutputStream fos = null;String pictureHostUrl = null;try {stream = connection.getInputStream();int len = 0;byte[] test = new byte[1024];//如果没有文件夹则创建File file = new File(serverPath);if (!file.exists()){file.mkdirs();}//设置图片名称String fileName = UUID.randomUUID() + ".png";pictureHostUrl = serverPath + fileName;fos = new BufferedOutputStream(new FileOutputStream(pictureHostUrl));//以流的方式上传while ((len = stream.read(test)) !=-1){fos.write(test,0,len);}} catch (Exception e) {e.printStackTrace();} finally {//关闭流,不然消耗资源if(stream != null){stream.close();}if(fos != null){fos.close();}}return pictureHostUrl;}public static boolean deletedFile(String pictureHostUrl) throws IOException {File file = new File(pictureHostUrl);if (file.exists()){return file.delete();}return true;}// public static void main(String[] args) throws IOException { // String pictureUrl = "https://meiyun-mng.oss-cn-hangzhou.aliyuncs.com/images/C76AA016-2604-4745-858F-DF4421366A39.png"; // String filePath = FileUtils.getFile(pictureUrl); // System.out.println(filePath); // boolean b = FileUtils.deletedFile(filePath); // System.out.println(b); // } } 配置类获取yaml配置@Data @Component @ConfigurationProperties(prefix = "spring.redis") public class RedissonProperties {private String host;private String port;private String password;private MySentinelProperties sentinel;private Integer database;} MQTT1. 导入依赖 org.eclipse.pahoorg.eclipse.paho.client.mqttv31.1.0 2. 编写回调类@Component @Slf4j public class DaLingMqtt implements MqttCallback {@Autowiredprivate ComponentService componentService;//地址端口private static final String HOST = "tcp://113.214.34.43:1883";//订阅的主题信息private static final String TOPIC = "root/cloxtec/dev_send/team_0";//用户名public static final String NAME = "";//密码public static final String PASSWORD = "";//生成当前客户端idpublic String CLIENTID = String.valueOf(System.currentTimeMillis());private MqttClient client;private MqttConnectOptions options;// @PostConstructpublic void result() {try {log.info("DaLingMqtt 准备连接");//保存连接MQTT的客户端id 默认内存保存client = new MqttClient(HOST, CLIENTID, new MemoryPersistence());//MQtt连接设置options = new MqttConnectOptions();// 设置是否清空Session true设置为true表示每次连接到服务器都以新的身份连接options.setCleanSession(true);// 设置超时时间 单位为秒options.setConnectionTimeout(10);//设置心跳间隔来判断客户端是否在线options.setKeepAliveInterval(60);options.setAutomaticReconnect(false);// 设置回调client.setCallback(this);client.connect(options);//开始订阅消息//消息级别int Qos = 1;client.subscribe(TOPIC, Qos);log.info("DaLingMqtt 连接成功");} catch (Exception e) {log.info("ReportMqtt客户端连接异常,异常信息:" + e);}}@Overridepublic void connectionLost(Throwable throwable) {try {log.info("程序出现异常,DReportMqtt断线!正在重新连接...:");client.close();this.result();log.info("ReportMqtt重新连接成功");} catch (MqttException e) {log.info(e.getMessage());}}@Overridepublic void messageArrived(String topic, MqttMessage message) {log.info("获取接收消息主题:" + topic);log.info("获取接收消息级别Qos:" + message.getQos());String payload = new String(message.getPayload());log.info("获取接收的MQTT消息:>>>>>"+payload);//进行数据格式转换JSONObject json = JSONObject.parseObject(payload);}@Overridepublic void deliveryComplete(IMqttDeliveryToken token) {log.info("消息发送成功");} } 3. 服务启动时连接@SpringCloudApplication @ServletComponentScan @EnableBladeFeign @EnableFeignClients(basePackages = "cn.beadata") @EnableCaching @MapperScan({"cn.beadata.screendata.mapper","cn.beadata.mapper","cn.beadata.third.api.shaoxing.xinchang.mapper"}) public class BulletsFlyApplication {public static void main(String[] args) {new Thread(()->{DaLingMqtt daLingMqtt = new DaLingMqtt();daLingMqtt.result();}).start();BladeApplication.run(BulletsFlyConstant.APPLICATION_BULLETS_FLY_NAME, BulletsFlyApplication.class, args);}} Enumpublic enum ContentPublishTypeEnum {Deleted(0,"删除"),Published(1,"发布"),Saved(2,"保存未发布"),Disable(3,"禁用"),;private Integer status;private String desc;public Integer getStatus() {return this.status;}ContentPublishTypeEnum(Integer status,String desc) {this.desc = desc;this.status = status;} } websocket1. 导入依赖由于websocket依赖包和SpringBoot内置的存在冲突,所以使用exclusions避开web包 org.springframework.bootspring-boot-starter-websocketorg.springframework.bootspring-boot-starter-web 2. 编写配置类import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** @author litongyin* @date 2023/1/30 18:18*/ @Configuration public class WebSocketConfig {/*** 注入ServerEndpointExporter,* 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();} } 3. 编写websocket服务端@Component @Slf4j @ServerEndpoint("/websocket/{userId}") // 接口路径 ws://localhost:xxxx/websocket/userId; public class WebSocketServer {//与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;/*** 用户ID*/private String userId;// 用来存在线连接用户信息private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();/*** 链接成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam(value="userId")String userId) {try {this.session = session;this.userId = userId;webSocketMap.put(userId,this);log.info("【websocket消息】userId: "+userId+" 连接成功,目前总数为:"+webSocketMap.size());} catch (Exception e) {}}/*** 链接关闭调用的方法*/@OnClosepublic void onClose() {try {webSocketMap.remove(userId);log.info("【websocket消息】userId: "+userId+" 连接断开,目前总数为:"+webSocketMap.size());} catch (Exception e) {}}/*** 收到客户端消息后调用的方法** @param message*/@OnMessagepublic void onMessage(String message) {log.info("【websocket消息】userId: "+userId+" 收到客户端消息: "+message);}/** 发送错误时的处理* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("【websocket消息】userId: "+userId+" 用户错误,原因:"+error.getMessage());error.printStackTrace();}// 此为单点消息@SneakyThrowspublic void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 通过userId向客户端发送消息*/public void sendMessage(String userIdsStr, String message) throws IOException {log.info("【websocket消息】userIds: "+userIdsStr);log.info("【websocket消息】向客户端发送消息: "+message);String[] userIds = userIdsStr.split(",");for (String userId : userIds) {if(StrUtil.isNotBlank(userId) && webSocketMap.containsKey(userId)){webSocketMap.get(userId).sendMessage(message);}else{log.error("用户{}不在线",userId);}}}// 此为广播消息public void sendAllMessage(String message) throws IOException {log.info("【websocket消息】广播消息: "+message);if(StrUtil.isNotBlank(userId) && webSocketMap.containsKey(userId)){webSocketMap.get(userId).sendMessage(message);}else{log.info("用户{}不在线",userId);}}} 六、BladeX多租户的数据隔离-tenant_idbladeX框架提供了使用租户id字段来实现同一张数据表中不同租户数据的增删改查。BladeX 框架将访问的用户对象封装成了BladeUser对象,直接在Controller层引用即可。BladeUser(clientId=saber, userId=1123598821738675201, tenantId=000000, deptId=1123598813738675201, userName=admin, account=admin, roleId=1123598816738675201, roleName=administrator ) 例子:管理员角色能查询所有用户,其他租户只能查询到tenant_id相同的用户/*** 用户列表*/@GetMapping("/list")@ApiImplicitParams({@ApiImplicitParam(name = "account", value = "账号名", paramType = "query", dataType = "string"),@ApiImplicitParam(name = "realName", value = "姓名", paramType = "query", dataType = "string")})@ApiOperationSupport(order = 3)@ApiOperation(value = "列表", notes = "传入account和realName")public R> list(@ApiIgnore @RequestParam Map user, Query query, BladeUser bladeUser) {System.out.println("======user:"+user);System.out.println("======query:"+query);System.out.println("======bladeUser:"+bladeUser);QueryWrapper queryWrapper = Condition.getQueryWrapper(user, User.class);IPage pages = userService.page(Condition.getPage(query), (!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)) ? queryWrapper.lambda().eq(User::getTenantId, bladeUser.getTenantId()) : queryWrapper);return R.data(UserWrapper.build().pageVO(pages));} 常见工具类工具类包位置:org.springblade.core.tool.utilsCommonUtils - 脱敏工具RedisUtil - 缓存工具Func - 判断对象是否为空SpringUtil - 根据类创建对象多数据源配置1.导入依赖 com.baomidoudynamic-datasource-spring-boot-starter2.5.6 2.修改配置文件spring:autoconfigure:exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfiguredatasource:dynamic:#设置默认的数据源或者数据源组,默认值即为screenprimary: bulletsflydatasource:# 默认数据源bulletsfly:url: ${meiyun.datasource.bulletsfly.url}username: ${meiyun.datasource.bulletsfly.username}password: ${meiyun.datasource.bulletsfly.password}# 第二个数据源crm:url: ${meiyun.datasource.crm.url}username: ${meiyun.datasource.crm.username}password: ${meiyun.datasource.crm.password} 3.在mapper上指定数据源(与配置文件中的数据源名称相同)@DS("crm") @Mapper public interface ContractOrderMapper extends BaseMapper { } Redisson-分布式事务1.单机模式-配置类 @Value("${spring.redis.password}")private String password;@Value("${meiyun.lock.address}")private String address;@Value("${spring.redis.database}")private Integer database;@Beanpublic RedissonClient redissonClient(){Config config = new Config();String address = this.address;address = ((address.startsWith("redis://") ) ? address : "redis://"+address);SingleServerConfig serverConfig = config.useSingleServer().setAddress(address).setClientName("Single").setDatabase(this.database);if(StringUtils.isNotBlank(this.password)) {serverConfig.setPassword(this.password);}return Redisson.create(config);} 2.哨兵模式-配置类/*** @author litongyin* @date 2022/11/28 10:17*/ @Configuration public class CacheConfig {@Value("${spring.redis.password}")private String password;@Value("${spring.redis.sentinel.nodes}")private String address;@Value("${spring.redis.sentinel.master}")private String master;@Value("${spring.redis.database}")private Integer database;@Beanpublic RedissonClient redissonClient(){Config config = new Config();String[] adds = address.split(",");for (int i = 0; i < adds.length; i++) {StringBuilder stringBuilder = new StringBuilder("redis://");adds[i] = stringBuilder.append(adds[i]).toString();}SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(adds).setMasterName(master).setDatabase(database);serverConfig.setPassword(password);return Redisson.create(config);} }3.不同环境下的代码@Data @Component @ConfigurationProperties(prefix = "spring.redis") public class RedissonProperties {private String host;private String port;private String password;private MySentinelProperties sentinel;private Integer database;} @Configuration public class CacheConfig {@Value("${meiyun.lock.active}")private String lockActive;@Autowiredprivate RedissonProperties redissonProperties;@Beanpublic RedissonClient redissonClient(){Config config = new Config();if(!"prod".equals(lockActive)){ // 测试或开发String address = redissonProperties.getHost()+":"+redissonProperties.getPort();address = ((address.startsWith("redis://") ) ? address : "redis://"+address);SingleServerConfig serverConfig = config.useSingleServer().setAddress(address).setClientName("Single").setDatabase(redissonProperties.getDatabase());if(StringUtils.isNotBlank(redissonProperties.getPassword())) {serverConfig.setPassword(redissonProperties.getPassword());}} else { // 生产MySentinelProperties sentinel = redissonProperties.getSentinel();String[] adds = sentinel.getNodes().split(",");for (int i = 0; i < adds.length; i++) {StringBuilder stringBuilder = new StringBuilder("redis://");adds[i] = stringBuilder.append(adds[i]).toString();}SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(adds).setMasterName(sentinel.getMaster()).setDatabase(redissonProperties.getDatabase());serverConfig.setPassword(redissonProperties.getPassword());}return Redisson.create(config);} } 4.使用 String key = CacheNameConstant.COUPON_LOCK +userCouponReq.getCouponNo();RLock rLock = redissonClient.getLock(key);try {rLock.lock();XXX}catch (Exception e){e.printStackTrace();}finally {rLock.unlock();} 参数校验public class LoginCheck {public static void check(LoginReq loginReq){Assert.notNull(loginReq,"请求信息不能为空");Assert.notNull(loginReq.getUserType(),"用户类型不能为空");Assert.hasText(loginReq.getSourceType(),"来源类型不能为空");Assert.isTrue(Arrays.asList(UserTypeEnum.USER,UserTypeEnum.MERCHANT).contains(loginReq.getUserType()),"用户类型不正确");Assert.isTrue(Arrays.asList(SourceTypeEnum.WECHAT.name(),SourceTypeEnum.ALIPAY.name()).contains(loginReq.getSourceType()),"来源类型不正确");} } 微信servicepublic interface WxService {public Map code2session(final String code, String tenantId);/*** 获取code2session** @param code* @return*/Map code2session(final String code) ;Map code2sessionBy(String code, String tenantIdHead);/*** 获取AccessToken** @return*/String getAccessToken() ;/*** 检查文本内容是否涉敏* @param content* @return*/boolean checkText(String content);/*** 检查图片内容是否涉敏* @param inputStream* @return*/boolean checkImg(InputStream inputStream);/*** 检查内容* @param content* @param imgUrls* @return*/boolean checkContent(String content,String imgUrls);/*** 解密手机号* @param sessionKey* @param encryptedData* @param iv* @return*/String decryptPhone(String sessionKey, String encryptedData, String iv);String getUserPhoneNumber(String tenantId,String code); } @Service @Slf4j public class WxServiceImpl implements WxService {private static final Logger logger = LoggerFactory.getLogger(WxServiceImpl.class);/*** 微信accessToken存储*/private static ConcurrentHashMap ACCESSTOKEN_MAP = new ConcurrentHashMap<>();/*** 微信accessToken过期时间(ms)*/private static ConcurrentHashMap ACCESSTOKEN_STRDATE_MAP = new ConcurrentHashMap<>();@Autowiredprivate WeChatConf weChatConf;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate SaasService saasService;@Value("${wechat.get-user-phone-number}")private String GET_USER_PHONE_NUMBER;@Overridepublic Map code2session(final String code, String tenantId) {HashMap map = new HashMap<>();map.put("appid", saasService.getAppIdByTenant(tenantId));map.put("secret", saasService.getAppSecretByTenant(tenantId));map.put("js_code", code);Map resMap = code2session(map);log.info("授权获取到的map:" + resMap);return resMap;}/*** 获取code2session** @param code* @return*/@Overridepublic Map code2session(final String code) {HashMap map = new HashMap<>();String tenantId = AuthUtil.getTenantId();map.put("appid", saasService.getAppIdByTenant(tenantId));map.put("secret", saasService.getAppSecretByTenant(tenantId));map.put("js_code", code);Map resMap = code2session(map);return resMap;}@Overridepublic Map code2sessionBy(String code, String tenantId) {HashMap map = new HashMap<>();map.put("appid", saasService.getAppIdByTenant(tenantId));map.put("secret", saasService.getAppSecretByTenant(tenantId));map.put("js_code", code);Map resMap = code2session(map);return resMap;}/*** 获取openId** @param map* @return*/private Map code2session(final Map map) {map.put("grant_type", "authorization_code");final String response = HttpUtil.doPost(weChatConf.getGetOpenidUrl(), map);try {final JSONObject myJsonObject = JSONObject.parseObject(response);logger.info("WxServiceImpl.code2session res=" + myJsonObject.toJSONString());return myJsonObject;} catch (Exception e) {logger.error("WxServiceImpl.code2session response=" + response);throw ServiceException.ofResultEnum(ResultEnum.ERROR_GET_OPENID_FALT);}}/*** 获取AccessToken** @return*/private String accessToken() {String tenantId = AuthUtil.getTenantId();if (null==tenantId ""==tenantId){tenantId= cn.beadata.mct.cms.utils.AuthUtil.getTenantId();}String accessTokenUri = weChatConf.getGetAccesstokenPath() + "&appid=" + saasService.getAppIdByTenant(tenantId)+ "&secret=" + saasService.getAppSecretByTenant(tenantId);logger.info("Enter GetAccessTokenUtil.getAccessToken accessTokenUri" + accessTokenUri);final String response = HttpUtil.doPost(accessTokenUri, null);try {final JSONObject accessTokenObject = JSONObject.parseObject(response);logger.info("Exit GetAccessTokenUtil.getAccessToken response=" + accessTokenObject);final String accessToken = accessTokenObject.get("access_token") == null ? null : accessTokenObject.get("access_token").toString();if (StringUtils.isEmpty(accessToken)) {throw ServiceException.ofResultEnum(ResultEnum.ERROR_GET_ACCESSTOKEN_FALT);}logger.info("Exit GetAccessTokenUtil.getAccessToken accessToken=" + accessToken);return accessToken;} catch (Exception e) {logger.error("Exit GetAccessTokenUtil.getAccessToken response=", response);throw ServiceException.ofResultEnum(ResultEnum.ERROR_GET_ACCESSTOKEN_FALT);}}private String getAccessToken(String tenantId) {if (null==tenantId ""==tenantId){tenantId= cn.beadata.mct.cms.utils.AuthUtil.getTenantId();}String accessTokenUri = weChatConf.getGetAccesstokenPath() + "&appid=" + saasService.getAppIdByTenant(tenantId)+ "&secret=" + saasService.getAppSecretByTenant(tenantId);logger.info("Enter GetAccessTokenUtil.getAccessToken accessTokenUri" + accessTokenUri);final String response = HttpUtil.doPost(accessTokenUri, null);try {final JSONObject accessTokenObject = JSONObject.parseObject(response);logger.info("Exit GetAccessTokenUtil.getAccessToken response=" + accessTokenObject);final String accessToken = accessTokenObject.get("access_token") == null ? null : accessTokenObject.get("access_token").toString();if (StringUtils.isEmpty(accessToken)) {throw ServiceException.ofResultEnum(ResultEnum.ERROR_GET_ACCESSTOKEN_FALT);}logger.info("Exit GetAccessTokenUtil.getAccessToken accessToken=" + accessToken);return accessToken;} catch (Exception e) {logger.error("Exit GetAccessTokenUtil.getAccessToken response=", response);throw ServiceException.ofResultEnum(ResultEnum.ERROR_GET_ACCESSTOKEN_FALT);}}/*** 获取AccessToken** @return*/@Overridepublic String getAccessToken() {final long millisecond = System.currentTimeMillis();String tenantId = AuthUtil.getTenantId();if (null==tenantId ""==tenantId) {tenantId= cn.beadata.mct.cms.utils.AuthUtil.getTenantId();}if ((millisecond - ACCESSTOKEN_STRDATE_MAP.getOrDefault(tenantId,0L)) >= weChatConf.getWxAccesstokenTimeout()) {final String accessToken = accessToken();ACCESSTOKEN_MAP.put(tenantId,accessToken);ACCESSTOKEN_STRDATE_MAP.put(tenantId,millisecond);return accessToken;} else {return ACCESSTOKEN_MAP.get(tenantId);}}/*** 检查文本内容是否涉敏** @param content* @return*/@Overridepublic boolean checkText(String content) {String checkUrl = weChatConf.getMsgCheckUrl();String accessToken = this.getAccessToken();checkUrl = checkUrl + "?access_token=" + accessToken;JSONObject body = new JSONObject();body.put("content", content);HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntity request = new HttpEntity<>(body, headers);JSONObject resJson = restTemplate.postForObject(checkUrl, request, JSONObject.class);Integer errcode = Integer.valueOf(String.valueOf(resJson.get("errcode")));if (errcode == 0) {return true;} else if (errcode == 87014) {return false;}logger.warn("checkContent failed , accessToken : {} , content : {} , error : {}", accessToken, content, resJson.toJSONString());throw ServiceException.ofResultEnum(ResultEnum.SENSITIVE_CONTENT_CHECK_FAILED);}/*** 检查图片内容是否涉敏** @param inputStream* @return*/@Overridepublic boolean checkImg(InputStream inputStream) {String checkUrl = weChatConf.getImgCheckUrl();String accessToken = this.getAccessToken();checkUrl = checkUrl + "?access_token=" + accessToken;HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.MULTIPART_FORM_DATA);HttpHeaders partHeaders = new HttpHeaders();partHeaders.setContentDispositionFormData("media", "media");HttpEntity part = new HttpEntity<>(new InputStreamResource(inputStream), partHeaders);MultiValueMap multiValueMap = new LinkedMultiValueMap<>();multiValueMap.add("media", part);HttpEntity> request = new HttpEntity<>(multiValueMap, headers);JSONObject resJson = restTemplate.postForObject(checkUrl, request, JSONObject.class);Integer errcode = Integer.valueOf(String.valueOf(resJson.get("errcode")));if (errcode == 0) {return true;} else if (errcode == 87014) {return false;}logger.warn("checkContent failed , accessToken : {} , error : {}", accessToken, resJson.toJSONString());throw ServiceException.ofResultEnum(ResultEnum.SENSITIVE_CONTENT_CHECK_FAILED);}/*** 检查内容** @param content* @param imgUrls* @return*/@Overridepublic boolean checkContent(String content, String imgUrls) {boolean checked = true;if (checked && !StringUtils.isBlank(content)) {checked = this.checkText(content);}if (checked && !StringUtils.isBlank(imgUrls)) {String[] imgs = imgUrls.split(",");for (String img : imgs) {if (checked) {ResponseEntity responseEntity = restTemplate.exchange(img, HttpMethod.GET, HttpEntity.EMPTY, byte[].class);ByteArrayInputStream bais = new ByteArrayInputStream(responseEntity.getBody());checked = this.checkImg(bais);}}}return checked;}/*** 解密手机号** @param sessionKey* @param encryptedData* @param iv* @return*/@Overridepublic String decryptPhone(String sessionKey, String encryptedData, String iv) {logger.info("sessionKey: {}",sessionKey);logger.info("encryptedData: {}",encryptedData);logger.info("iv: {}",iv);byte[] dataByte = Base64.decode(encryptedData);byte[] keyByte = Base64.decode(sessionKey);byte[] ivByte = Base64.decode(iv);try {// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要int base = 16;if (keyByte.length % base != 0) {int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);byte[] temp = new byte[groups * base];Arrays.fill(temp, (byte) 0);System.arraycopy(keyByte, 0, temp, 0, keyByte.length);keyByte = temp;}// 初始化Security.addProvider(new BouncyCastleProvider());Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");parameters.init(new IvParameterSpec(ivByte));cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化byte[] resultByte = cipher.doFinal(dataByte);if (null != resultByte && resultByte.length > 0) {String result = new String(resultByte, "UTF-8");JSONObject jsonObject = JSONObject.parseObject(result);logger.info("decryptedData: {}",jsonObject.toJSONString());return String.valueOf(jsonObject.get("phoneNumber"));}} catch (Exception e) {logger.warn("decryptPhone failed",e);throw ServiceException.ofResultEnum(ResultEnum.ERROR_GET_PHONE_FALT);}return null;}@Overridepublic String getUserPhoneNumber(String tenantId,String code) {String accessToken = getAccessToken(tenantId);String userPhoneNumberUri = GET_USER_PHONE_NUMBER + "?access_token=" + accessToken;Map param = new HashMap<>();param.put("code", code);log.info("Enter GET_USER_PHONE_NUMBER.getPhone userPhoneNumberUri" + userPhoneNumberUri + "param: " + code);JSONObject phoneNumberObject = HttpRequest.post(userPhoneNumberUri).bodyJson(param).execute().onSuccess(responseSpec -> JSONObject.parseObject(responseSpec.asString()));try {log.info("Exit GetPhoneNumberUtil.getUserPhoneNumber response=" + phoneNumberObject);final String phone = phoneNumberObject.getJSONObject("phone_info").getString("purePhoneNumber");if (Func.isEmpty(phone)) {throw new org.springblade.core.log.exception.ServiceException(ResultEnum.ERROR_GET_PHONE_FALT.MSG());}log.info("Exit GetPhoneNumberUtil.getUserPhoneNumber accessToken=" + phone);return phone;} catch (Exception e) {log.error("Exit GetPhoneNumberUtil.getUserPhoneNumber response=", phoneNumberObject.toJSONString());throw new org.springblade.core.log.exception.ServiceException(ResultEnum.ERROR_GET_PHONE_FALT.MSG());}}} 七、工具类1. http工具类-后端访问接口获取数据依赖 org.apache.httpcomponentshttpclient4.5.2org.apache.httpcomponentshttpcore4.4.5 代码package com.spring.cache.utils;import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils;import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map;@Slf4j public class HttpUtil {public static String sendGet(String url, Map params,Map headerMap) throws URISyntaxException, IOException {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();// 定义请求的参数URIBuilder uriBuilder = new URIBuilder(url);if (params != null) {for (String key : params.keySet()) {uriBuilder.setParameter(key, params.get(key).toString());}}// 创建http GET请求HttpGet httpGet = new HttpGet(uriBuilder.build());//header对象if (headerMap != null) {for (String key : headerMap.keySet()) {httpGet.setHeader(key, headerMap.get(key).toString());}}//response 对象CloseableHttpResponse response = httpclient.execute(httpGet);String content = getResult(response);close(response, httpclient);return content;}public static String sendPost(String url, Map params,Map headerMap) throws IOException {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();// 创建http POST请求HttpPost httpPost = new HttpPost(url);if (params != null && params.size() > 0) {List parameters = new ArrayList<>(0);for (String key : params.keySet()) {parameters.add(new BasicNameValuePair(key, params.get(key).toString()));}// 构造一个form表单式的实体UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);// 将请求实体设置到httpPost对象中httpPost.setEntity(formEntity);}//伪装浏览器httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");//header对象if (headerMap != null) {for (String key : headerMap.keySet()) {httpPost.setHeader(key, headerMap.get(key).toString());}}CloseableHttpResponse response = httpclient.execute(httpPost);// 判断返回状态是否为200String content = getResult(response);close(response, httpclient);return content;}public static String sendPost(String url, JSONObject json) throws IOException {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();// 创建http POST请求HttpPost httpPost = new HttpPost(url);StringEntity s = new StringEntity(json.toString());s.setContentEncoding("UTF-8");//发送json数据需要设置contentTypes.setContentType("application/json");log.info("请求体body的数据:===================="+s);httpPost.setEntity(s);CloseableHttpResponse response = httpclient.execute(httpPost);// 判断返回状态是否为200String content = getResult(response);close(response, httpclient);return content;}public static String sendPost(String url, String json,Map headerMap) throws IOException {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建请求内容StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);httpPost.setEntity(entity);//header对象if (headerMap != null) {for (String key : headerMap.keySet()) {httpPost.setHeader(key, headerMap.get(key).toString());}}// 执行http请求CloseableHttpResponse response = httpclient.execute(httpPost);String content = getResult(response);close(response, httpclient);return content;}public static void close(CloseableHttpResponse response, CloseableHttpClient httpclient) throws IOException {if (response != null) {response.close();}httpclient.close();}public static String getResult(CloseableHttpResponse response) throws IOException {String content = "";if (response != null && response.getStatusLine().getStatusCode() == 200) {content = EntityUtils.toString(response.getEntity(), "UTF-8");}return content;}public static String sendPost(String url, Map params) throws IOException {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();// 创建http POST请求HttpPost httpPost = new HttpPost(url);if (params != null && params.size() > 0) {List parameters = new ArrayList<>(0);for (String key : params.keySet()) {parameters.add(new BasicNameValuePair(key, params.get(key).toString()));}// 构造一个form表单式的实体UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);// 将请求实体设置到httpPost对象中httpPost.setEntity(formEntity);}//伪装浏览器httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");CloseableHttpResponse response = httpclient.execute(httpPost);if (response != null && response.getStatusLine().getStatusCode() == 200) {return EntityUtils.toString(response.getEntity(), "UTF-8");}return "";}}测试@RestController public class PersonController {@Autowiredprivate PersonService personService;// 1. Get请求-路径参数@GetMapping("/findById/{id}")public Person findById(@PathVariable long id){return personService.findById(id);}//2. Get请求-请求参数@GetMapping("/findById")public Person findById2(@RequestParam long id){return personService.findById(id);}//3. Get请求-请求体Json格式@PostMapping("/save")public boolean save(@RequestBody Person person){return personService.save(person);}//4. Post请求-form表单格式@PostMapping("/saveForm")public boolean save2(Person person){return personService.save(person);} } @Testvoid http() throws URISyntaxException, IOException {// 1. Get请求-路径参数(127.0.0.1:8080/findById/1)String s = HttpUtil.sendGet("http://127.0.0.1:8080/findById/1", null, null);System.out.println(s);//2. Get请求-请求参数(127.0.0.1:8080/findById/?id=1)Map map = new HashMap<>();map.put("id",1);String s1 = HttpUtil.sendGet("http://127.0.0.1:8080/findById/", map, null);System.out.println(s1);//3. POST请求-请求体Json格式JSONObject jsonObject = new JSONObject();jsonObject.put("name","li");jsonObject.put("age",250);String s2 = HttpUtil.sendPost("http://127.0.0.1:8080/save", jsonObject);System.out.println(s2);//4. Post请求-form表单格式Map map1 = new HashMap();map1.put("name","li");map1.put("age",250);String s3 = HttpUtil.sendPost("http://127.0.0.1:8080/saveForm", map1);System.out.println(s3);} 八、前端小程序引入Vconsole安装npm install vconsole 在main.js中引入import VConsole from 'vconsole';const vConsole = new VConsole(); [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BjliFyub-1674872708156)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220922110829175.png)]Uniapp小程序去除导航栏"navigationStyle":"custom" Css实现省略号…及悬浮层显示全部内容的方法:https://blog.csdn.net/weixin_53791978/article/details/122483191微信小程序跳转h51.微信开放平台设置开放地址(https//域名)2.运维在nginx下放置文件3.微信端代码let url = "https://partybuildh5-test.beadata.cn/#/mainPageAnder?loginType=weiXin&token="+getUserInfo().tongong_token console.log("准备跳转智慧党建页面,url:",url) uni.navigateTo({url: "/pagesC/partyBuiding/index?url="+encodeURIComponent(url) }); 4.h5端代码 微信小程序内嵌h5打电话 Vue修改代理请求devServer: {open: true,proxy: {'/blade-party-admin': {// target: 'https://partybuildh5.beadata.cn',// target: 'http://47.98.213.13:8200',target: 'http://47.98.213.13:18202/api', // lilogLevel: 'debug', // 控制台查看代理后请求changeOrigin: true,pathRewrite:{ //重写请求路径'/blade-party-admin' : '/blade-party-admin-wugen' }}}} Ant Design表单控件 Uniappvscode运行微信小程序npm run dev:mp-weixin Vue-websocket1.导入依赖npm install websocket 2.编写api(/api/socket.js)import {setStore, getStore} from '@/util/store'var websock = null; var global_callback = null;function getWebIP(){var curIP = "ws://localhost:8084/websocket/";return curIP; }function initWebSocket(userId){ //初始化weosocket//ws地址var wsuri = getWebIP()+userId;console.log("【websocket消息】 连接url:"+wsuri)websock = new WebSocket(wsuri);websock.onmessage = function(e){websocketonmessage(e);} websock.onclose = function(e){websocketclose(e);}websock.onopen = function () {websocketOpen();}//连接发生错误的回调方法websock.onerror = function () {console.log("【websocket消息】连接异常");} }// 实际调用的方法 function sendSock(agentData,callback){ global_callback = callback;if (websock.readyState === websock.OPEN) {//若是ws开启状态websocketsend(agentData)}else if (websock.readyState === websock.CONNECTING) {// 若是 正在开启状态,则等待1s后重新调用setTimeout(function () {sendSock(agentData,callback);}, 1000);}else {// 若未开启 ,则等待1s后重新调用setTimeout(function () {sendSock(agentData,callback);}, 1000);} }//数据接收 function websocketonmessage(e){ console.log("【websocket消息】接收信息: ",e.data)var data = JSON.parse(e.data)console.log("【websocket消息】接收信息: data: ",data)global_callback(JSON.parse(e.data)); }//数据发送 function websocketsend(agentData){console.log("【websocket消息】发送信息: ",agentData);websock.send(JSON.stringify(agentData)); }//关闭 function websocketclose(e){ console.log("【websocket消息】连接关闭 (" + e.code + ")"); }function websocketOpen(e){console.log("【websocket消息】连接成功"); } var userInfo = getStore({name: 'userInfo'}) initWebSocket(userInfo.userId)export{sendSock} 3.在main.js中引用// websocket import * as socketApi from './api/socket' Vue.prototype.socketApi = socketApi Vue-弹幕功能地址: https://github.com/superhos/vue-baberrage/blob/master/docs/zh/README.md1. 安装npm install 2. 在main.js中引用// vue-baberrage 弹幕播放 import { vueBaberrage } from 'vue-baberrage' Vue.use(vueBaberrage) 3. 代码 Vue-视频播放1. 安装依赖# vue 2 npm install vue-video-player@4.x -S npm install --save videojs-contrib-hls# vue3 npm install vue-video-player 2.在main.js中引用// vue-video-player import 'video.js/dist/video-js.css' import 'videojs-contrib-hls' import { videoPlayer } from 'vue-video-player' Vue.use( videoPlayer ) 3.示例代码 九、GitIDEA-合并test分支到master分支1.上传test分支2.切换到master分支3.合并test分支到master分支4.上传到主分支VsCode-合并分支举例 将 dev 开发线 合并到 master1 确定你在dev线,将dev代码改动全部提交2 切换master,确定是最新代码,不确定就pull下,选择合并分支,见上图3 在下拉的提示框中选择dev线,然后选择提交所有代码4 切回到dev 继续开发重点 merge命令的本质是从别的分支,将自身没有的提交记录拉去过来(粗略的说而已)。命令行提交git pull # 拉取代码 git add -u #(git add -u 暂存已修改过的) git commit -m 'xxxxxxx' # 提交,说明信息 git push -u origin 分支名 # 推送 十、其他openssl# 查看pem格式证书内容 openssl x509 -in cacert.pem -noout -text# 查看证书序列号 openssl x509 -in apiclient_cert.pem -noout -serial# 导出证书 openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem -passin pass:1602904683# 导出证书秘钥 openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem -passin pass:1602904683 }

我要回帖

更多关于 新入工作微信群打招呼 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信