当前位置: 首页 > news >正文

调用电商集成平台 聚水潭 api接口示例

先上工具类

package com.zuodou.utlis;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.xml.crypto.Data;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
@Component
public class ApiUtils {private static final String SIGN_METHOD_MD5 = "md5";private static final String CHARSET_UTF8 = "utf-8";private static final String CONTENT_ENCODING_GZIP = "gzip";// TOP服务地址,正式环境需要设置为https://openapi.jushuitan.com
//    @Value("${erp.serverUrl}")
//    public   String serverUrl;
//
//    @Value("${erp.appKey}")
//    public  String appKey; // 可替换为您的应用的appKey
//
//    @Value("${erp.appSecret}")
//    public  String appSecret; // 可替换为您的应用的appSecret
//
//    @Value("${erp.accessToken}")
//    public  String accessToken; // 必须替换为授权得到的真实有效accessTokenpublic static String serverUrl;public static String appKey;public static String appSecret;public static String accessToken;@Value("${erp.serverUrl}")public void setServerUrl(String serverUrl) {ApiUtils.serverUrl = serverUrl;}@Value("${erp.appKey}")public void setAppKey(String appKey) {ApiUtils.appKey = appKey;}@Value("${erp.appSecret}")public void setAppSecret(String appSecret) {ApiUtils.appSecret = appSecret;}@Value("${erp.accessToken}")public void setAccessToken(String accessToken) {ApiUtils.accessToken = accessToken;}/**** @param fangfa* @return* @throws IOException*/public static String getSellerItem(String fangfa, String biz) throws IOException {Map<String, String> params = new HashMap<String, String>();// 公共参数params.put("app_key",appKey);params.put("access_token", accessToken);params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));params.put("version", "2");params.put("charset", "utf-8");// 业务参数params.put("biz", biz);// 签名参数params.put("sign", signTopRequest(params, appSecret, SIGN_METHOD_MD5));// 调用APIreturn callApi(new URL(serverUrl+fangfa), params);}/*** 对TOP请求进行签名。*/private static String signTopRequest(Map<String, String> params, String secret, String signMethod) throws IOException {// 第一步:检查参数是否已经排序String[] keys = params.keySet().toArray(new String[0]);Arrays.sort(keys);// 第二步:把所有参数名和参数值串在一起StringBuilder query = new StringBuilder();if (SIGN_METHOD_MD5.equals(signMethod)) {query.append(secret);}for (String key : keys) {String value = params.get(key);if (isNotEmpty(key) && isNotEmpty(value)) {query.append(key).append(value);}}return createSign(query.toString());}/*** 生成新sign** @param str 字符串* @return String*/private static String createSign(String str) {if (str == null || str.length() == 0) {return null;}char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};try {MessageDigest mdTemp = MessageDigest.getInstance(SIGN_METHOD_MD5);mdTemp.update(str.getBytes("UTF-8"));byte[] md = mdTemp.digest();int j = md.length;char[] buf = new char[j * 2];int k = 0;int i = 0;while (i < j) {byte byte0 = md[i];buf[k++] = hexDigits[byte0 >>> 4 & 0xf];buf[k++] = hexDigits[byte0 & 0xf];i++;}return new String(buf);} catch (Exception e) {return null;}}private static String callApi(URL url, Map<String, String> params) throws IOException {String query = buildQuery(params, CHARSET_UTF8);byte[] content = {};if (query != null) {content = query.getBytes(CHARSET_UTF8);}HttpURLConnection conn = null;OutputStream out = null;String rsp = null;try {conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("POST");conn.setDoInput(true);conn.setDoOutput(true);conn.setRequestProperty("Host", url.getHost());conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + CHARSET_UTF8);out = conn.getOutputStream();out.write(content);rsp = getResponseAsString(conn);} finally {if (out != null) {out.close();}if (conn != null) {conn.disconnect();}}return rsp;}private static String buildQuery(Map<String, String> params, String charset) throws IOException {if (params == null || params.isEmpty()) {return null;}StringBuilder query = new StringBuilder();Set<Entry<String, String>> entries = params.entrySet();boolean hasParam = false;for (Entry<String, String> entry : entries) {String name = entry.getKey();String value = entry.getValue();// 忽略参数名或参数值为空的参数if (isNotEmpty(name) && isNotEmpty(value)) {if (hasParam) {query.append("&");} else {hasParam = true;}query.append(name).append("=").append(URLEncoder.encode(value, charset));}}return query.toString();}private static String getResponseAsString(HttpURLConnection conn) throws IOException {String charset = getResponseCharset(conn.getContentType());if (conn.getResponseCode() < 400) {String contentEncoding = conn.getContentEncoding();if (CONTENT_ENCODING_GZIP.equalsIgnoreCase(contentEncoding)) {return getStreamAsString(new GZIPInputStream(conn.getInputStream()), charset);} else {return getStreamAsString(conn.getInputStream(), charset);}} else {// Client Error 4xx and Server Error 5xxthrow new IOException(conn.getResponseCode() + " " + conn.getResponseMessage());}}private static String getStreamAsString(InputStream stream, String charset) throws IOException {try {Reader reader = new InputStreamReader(stream, charset);StringBuilder response = new StringBuilder();final char[] buff = new char[1024];int read = 0;while ((read = reader.read(buff)) > 0) {response.append(buff, 0, read);}return response.toString();} finally {if (stream != null) {stream.close();}}}private static String getResponseCharset(String ctype) {String charset = CHARSET_UTF8;if (isNotEmpty(ctype)) {String[] params = ctype.split(";");for (String param : params) {param = param.trim();if (param.startsWith("charset")) {String[] pair = param.split("=", 2);if (pair.length == 2) {if (isNotEmpty(pair[1])) {charset = pair[1].trim();}}break;}}}return charset;}private static boolean isNotEmpty(String value) {int strLen;if (value == null || (strLen = value.length()) == 0) {return false;}for (int i = 0; i < strLen; i++) {if ((Character.isWhitespace(value.charAt(i)) == false)) {return true;}}return false;}public static void main(String[] args) {int pageNo = 1;int pageSize = 100;boolean hasMoreData = true;List<Data> allData = new ArrayList<>();while (hasMoreData) {List<Data> currentPageData = callThirdPartyApi(pageNo, pageSize); // 调用第三方API获取当前页数据allData.addAll(currentPageData); // 将当前页数据加入总数据集合if (currentPageData.size() < pageSize) {hasMoreData = false; // 当前页数据不足pageSize,表示已获取所有数据} else {pageNo++; // 继续获取下一页数据}}// 所有数据已获取完成System.out.println("Total data count: " + allData.size());// 进一步处理allData集合...}// 调用第三方API获取指定页数据的示例方法private static List<Data> callThirdPartyApi(int pageNo, int pageSize) {// 调用第三方API获取指定页的数据// 返回数据列表return new ArrayList<>(); // 这里仅作示例,实际应调用API并返回数据}}

需求说明,需要把聚水潭所有的售后数据拉取到自研平台进行进一步操作。


调用接口的限制:分页,每页数量50,请求限制,一秒钟不能超过5次,一分钟不能超过一百次。


注意代码待完善:accessToken是有过期时间的,但可以在主账号设置,如果超过限制我不会进行记录会漏掉这条数据。有一些注入的地方可以删掉。我定义了一个erpDatas和erpItems类来接收数据,由于返回值是下划线的,而我项目架构是驼峰命名,会导致映射值失败,最下面是处理方法(可以不用的自行删除)。

package com.zuodou.job;import com.zuodou.mapper.ZuodouTaskDatasMapper;import com.zuodou.utlis.DataUtil;
import com.zuodou.utlis.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;import java.util.*;/*** 售后*/@Slf4j
//禁止并发执行
@DisallowConcurrentExecution
public class TaskDatas implements Job {@Autowiredprivate ZuodouTaskDatasMapper zuodouTaskDatasMapper;@Autowiredprivate  threadService threadService;/*** 若参数变量名修改 QuartzJobController中也需对应修改*/private String parameter;public void setParameter(String parameter) {this.parameter = parameter;}private String parameterstartime;public void setParameterstartime(String parameterstartime) {this.parameterstartime = parameterstartime;}/*** 拿售后数据* @param jobExecutionContext* @throws JobExecutionException** token过期* 1.请求状态* 2.时间间隔七天* 3.分页数据* /open/refund/single/query**/@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {try {//1.拿到数据库中最大时间  如果没有,默认多少,如果有生成一个七天时间lsit//1.1 先判断数据库时间和当前时间是否相差七天,相差七天就减,没有相差就用当前时间当作结束时间//2.在每个七天里面分页拿取数据,data_count 总数,page_count 有多少页//3.把分页数据整合到list中//            for (String shopId : Shop_id) {String start = zuodouTaskDatasMapper.maxOrdersDate(null);String end = TimeUtils.getStringDate();//比当前时间少一分钟,防止数据重复if (StringUtils.isBlank(start)) {start = this.parameterstartime;}log.info("聚水潭售后数据拉取开始-------"+TimeUtils.date2Str(new Date()));Date CalendarstartTime = TimeUtils.DateSwitch(start);Date CalendarendTime = TimeUtils.DateSwitch(end);Calendar startCal = Calendar.getInstance();startCal.setTime(CalendarstartTime) ;Calendar endCal = Calendar.getInstance();endCal.setTime(CalendarendTime);String startTime =start;String endTime =null;while (!start.equals(end)) { //当开始时间大于或者等于结束时间Integer day = DataUtil.countDaynew(start,end );if (day>7) {startCal.add(Calendar.DAY_OF_MONTH, 7);endTime = TimeUtils.date2Str(startCal.getTime());Integer  daya = DataUtil.countDaynew(endTime, end); //判断结束时间加上七天跟当前时间的间隔if (daya <1) { //如果加上七天大于当前时间或者等于endTime=end;}}if (StringUtils.isBlank(endTime)){endTime=end;}System.out.println(startTime+"-----3---"+endTime);String finalStartTime = startTime;String finalEndTime = endTime;threadService.apithread(finalStartTime, finalEndTime);Integer     days = DataUtil.countDaynew(startTime,endTime );Integer  daya = DataUtil.countDaynew(endTime, end);if (days==7){ //超过七天startTime = endTime;} else if (days>0&&daya==0){startTime = endTime;//累计七天的结束时间endTime = end; //结束时间为当前时间start = end; //设置停止循环}else if(daya<7){endTime=end;start=end;//用于结束循环}}//            }} catch (Exception  e) {e.printStackTrace();}}public static void main(String[] args)  {String start = "2023-10-09 13:41:20";String end = TimeUtils.getStringDate();//比当前时间少一分钟,防止数据重复if (StringUtils.isBlank(start)) {start = "2023-08-01 00:00:00";}Date CalendarstartTime = TimeUtils.DateSwitch(start);Date CalendarendTime = TimeUtils.DateSwitch(end);Calendar startCal = Calendar.getInstance();startCal.setTime(CalendarstartTime) ;Calendar endCal = Calendar.getInstance();endCal.setTime(CalendarendTime);String startTime =start;String endTime =null;while (!start.equals(end)) { //当开始时间大于或者等于结束时间Integer day = DataUtil.countDaynew(start,end );if (day>7) {startCal.add(Calendar.DAY_OF_MONTH, 7);endTime = TimeUtils.date2Str(startCal.getTime());Integer  daya = DataUtil.countDaynew(endTime, end); //判断结束时间加上七天跟当前时间的间隔if (daya <1) { //如果加上七天大于当前时间或者等于endTime=end;}}if (StringUtils.isBlank(endTime)){endTime=end;}System.out.println(startTime+"-----3---"+endTime);Integer     days = DataUtil.countDaynew(startTime,endTime );Integer  daya = DataUtil.countDaynew(endTime, end);if (days==7){ //超过七天startTime = endTime;} else if (days>0&&daya==0){startTime = endTime;//累计七天的结束时间endTime = end; //结束时间为当前时间start = end; //设置停止循环}else if(daya<7){endTime=end;start=end;//用于结束循环}}}}
package com.zuodou.job;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.zuodou.entity.ZuodouTaskDatas;
import com.zuodou.entity.ZuodouTaskItem;
import com.zuodou.enums.CommonConstant;
import com.zuodou.enums.ErpStatusEnum;
import com.zuodou.erpmodel.erpData;
import com.zuodou.erpmodel.erpDatas;
import com.zuodou.erpmodel.erpItems;
import com.zuodou.mapper.ZuodouTaskDatasMapper;
import com.zuodou.model.*;
import com.zuodou.service.IZuodouTaskDatasService;
import com.zuodou.service.IZuodouTaskItemService;
import com.zuodou.utlis.BaseUtlis;
import com.zuodou.utlis.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;import java.io.IOException;
import java.util.*;import static com.zuodou.utlis.ApiUtils.getSellerItem;@Service
@Slf4j
public class threadService {@Autowiredprivate IZuodouTaskItemService zuodouTaskItemService;@Autowiredprivate IZuodouTaskDatasService iZuodouTaskDatasService;@Autowiredprivate ZuodouTaskDatasMapper zuodouTaskDatasMapper;public void apithread(String finalStartTime, String finalEndTime) {log.info("执行售后任务时间"+finalStartTime+"----"+finalEndTime);List<ZuodouTaskDatas> zuodouTaskDatas = new ArrayList<>();List<ZuodouTaskDatas> updatezuodouTaskDatas = new ArrayList<>();List<ZuodouTaskItem> zuodouTaskItemList = new ArrayList<>();List<ZuodouTaskItem> updatezuodouTaskItemList = new ArrayList<>();List<erpDatas> orders = new ArrayList<>();ObjectMapper objectMapper=new ObjectMapper();OrderQueryParams queryParams = new OrderQueryParams();queryParams.setModified_begin(finalStartTime).setModified_end(finalEndTime).setPage_index(1).setPage_size(50);try {String valueAsString = objectMapper.writeValueAsString(queryParams);JsonNode jsonNode = objectMapper.readTree(getSellerItem("/open/refund/single/query", valueAsString));String msg = jsonNode.get("msg").asText();String code = jsonNode.get("code").asText();if (StringUtils.equals(msg, "执行成功") && StringUtils.equals(code, "0")) {Integer page_count = 0;//有多少页JsonNode dataNode = jsonNode.get("data");erpData erpData = null;erpData = objectMapper.treeToValue(dataNode, erpData.class);page_count += erpData.getPage_count();if (page_count > 0) {for (int j = 1; j <= page_count; j++) {OrderQueryParams queryParamsdata_count = new OrderQueryParams();queryParamsdata_count.setModified_begin(finalStartTime).setModified_end(finalEndTime).setPage_index(j).setPage_size(50);String valueAsStrings = null;valueAsStrings = objectMapper.writeValueAsString(queryParamsdata_count);JsonNode    jsonNodes = objectMapper.readTree(getSellerItem("/open/refund/single/query", valueAsStrings));String msgs = jsonNodes.get("msg").asText();String codes = jsonNodes.get("code").asText();JsonNode dataNodea = jsonNodes.get("data");if (StringUtils.equals(msgs, "执行成功") && StringUtils.equals(codes, "0")) {log.info("售后数据执行成功"+msgs);JsonNode dataNodes = dataNodea.get("datas");//拿到数据结构if (dataNodes instanceof ArrayNode) {ArrayNode ordersArrayNode = (ArrayNode) dataNodes;for (JsonNode orderNode : ordersArrayNode) {erpDatas    order = objectMapper.treeToValue(orderNode, erpDatas.class);orders.add(order);}}} else {log.info("售后数据执行失败"+msgs);}try {// 在apithread方法中休息两秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}log.info("聚水潭售后数据拉取结束-----"+ TimeUtils.date2Str(new Date()));} else {log.info("外层分页售后"+msg);}try {// 在apithread方法中休息两秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}insertOrdersData(orders, zuodouTaskDatas,updatezuodouTaskDatas, zuodouTaskItemList,updatezuodouTaskItemList);log.info("开始插入售后数据----"+zuodouTaskDatas.size() + "商品数据---"+zuodouTaskItemList.size()+"需要修改售后数据--"+updatezuodouTaskDatas.size());iZuodouTaskDatasService.saveBatch(zuodouTaskDatas);zuodouTaskItemService.saveBatch(zuodouTaskItemList);iZuodouTaskDatasService.updateBatchById(updatezuodouTaskDatas);zuodouTaskItemService.updateBatchById(updatezuodouTaskItemList);} catch (JsonProcessingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}catch (Exception e){e.printStackTrace();}}private  void insertOrdersData(List<erpDatas> orders, List<ZuodouTaskDatas> zuodouTaskOrdersList, List<ZuodouTaskDatas> updatezuodouTaskOrdersList, List<ZuodouTaskItem> zuodouTaskItemList,List<ZuodouTaskItem> updatezuodouTaskItemList ) throws IllegalAccessException, IOException, InterruptedException {if (!CollectionUtils.isEmpty(orders)){for (erpDatas order : orders) {ZuodouTaskDatas zuodouTaskDatas=new ZuodouTaskDatas();BaseUtlis.copyProperties(order,zuodouTaskDatas);String asId = zuodouTaskDatasMapper.oIdasIddatas(order.getO_id(), order.getAs_id());
//                boolean exists = zuodouTaskOrdersList.stream()
//                        .anyMatch(obj -> obj.getOId().equals(order.getO_id()) && obj.getAsId() .equals(order.getAs_id()));boolean exists = zuodouTaskOrdersList.stream().anyMatch(obj -> obj.getAsId() .equals(order.getAs_id()));if (exists) {//如果插入的list中有那个值就直接跳过continue;}else if (StringUtils.isNotBlank(asId)) {zuodouTaskDatas.setAsId(asId);zuodouTaskDatas.setStatusName(ErpStatusEnum.getValueName(order.getStatus(), CommonConstant.STATUS));zuodouTaskDatas.setShopStatusName(ErpStatusEnum.getValueName(order.getShop_status(),CommonConstant.SHOP_STATUS));zuodouTaskDatas.setGoodStatusName(ErpStatusEnum.getValueName(order.getGood_status(),CommonConstant.GOOD_STATUS));zuodouTaskDatas.setOrderStatusName(ErpStatusEnum.getValueName(order.getOrder_status(),CommonConstant.ORDER_STATUS));zuodouTaskDatas.setOrderlabels(String.join(",",order.getOrder_labels()));updatezuodouTaskOrdersList.add(zuodouTaskDatas);for (erpItems item : order.getItems()) {ZuodouTaskItem zuodouTaskItem=new ZuodouTaskItem();BaseUtlis.copyProperties(item,zuodouTaskItem);zuodouTaskItem.setSkuTypeName(ErpStatusEnum.getValueName(item.getSku_type(),CommonConstant.SKU_TYPE));zuodouTaskItem.setSkuType(item.getSku_type());updatezuodouTaskItemList.add(zuodouTaskItem);}}else{zuodouTaskDatas.setStatusName(ErpStatusEnum.getValueName(order.getStatus(),CommonConstant.STATUS));zuodouTaskDatas.setShopStatusName(ErpStatusEnum.getValueName(order.getShop_status(),CommonConstant.SHOP_STATUS));zuodouTaskDatas.setGoodStatusName(ErpStatusEnum.getValueName(order.getGood_status(),CommonConstant.GOOD_STATUS));zuodouTaskDatas.setOrderStatusName(ErpStatusEnum.getValueName(order.getOrder_status(),CommonConstant.ORDER_STATUS));zuodouTaskDatas.setOrderlabels(String.join(",",order.getOrder_labels()));if (!CollectionUtils.isEmpty(order.getItems())){for (erpItems item : order.getItems()) {ZuodouTaskItem zuodouTaskItem=new ZuodouTaskItem();BaseUtlis.copyProperties(item,zuodouTaskItem);zuodouTaskItem.setSkuTypeName(ErpStatusEnum.getValueName(item.getSku_type(),CommonConstant.SKU_TYPE));zuodouTaskItem.setSkuType(item.getSku_type());zuodouTaskItemList.add(zuodouTaskItem);}}zuodouTaskOrdersList.add(zuodouTaskDatas);}}}}}

public static void copyProperties(Object source, Object destination) throws IllegalAccessException {Field[] sourceFields = source.getClass().getDeclaredFields();Field[] destinationFields = destination.getClass().getDeclaredFields();for (Field sourceField : sourceFields) {sourceField.setAccessible(true);String sourceFieldName = sourceField.getName();String destinationFieldName = convertToCamelCase(sourceFieldName); // 将下划线命名转换为驼峰命名for (Field destinationField : destinationFields) {if (destinationField.getName().equals(destinationFieldName)) {destinationField.setAccessible(true);destinationField.set(destination, sourceField.get(source));break;}}}
}

相关文章:

调用电商集成平台 聚水潭 api接口示例

先上工具类 package com.zuodou.utlis;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;import javax.xml.crypto.Data; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import j…...

深入Rust:探索所有权和借用机制

大家好&#xff01;我是lincyang。 今天&#xff0c;我们将一起深入探索Rust语言中的一个核心概念&#xff1a;所有权和借用机制。 这些特性是Rust区别于其他语言的重要特点&#xff0c;它们在内存管理和并发编程中扮演着关键角色。 一、Rust所有权机制 1. 什么是所有权&#x…...

Python之冒泡排序(AI自动写文章项目测试)

全自动AI生成文章测试&#xff0c;如有不合理地方&#xff0c;请见谅。 一、冒泡排序简介 1.1 冒泡排序概述 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;通过不断交换相邻元素的位置&#xff0c;将最大&#xff08;或最小&#xff09;的元…...

spring cloud微服务中多线程下,子线程通过feign调用其它服务,请求头token等丢失

在线程池中&#xff0c;子线程调用其他服务&#xff0c;请求头丢失&#xff0c;token为空的情况 看了很多篇文章的处理方法和在自己亲测的情况下做出说明&#xff1a; 第一种&#xff1a; 这种方式只支持在主线程情况下&#xff0c;能够处理&#xff0c;在多线程情况下&#…...

Nacos 高级玩法:深入探讨分布式配置和服务发现

&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 Nacos 高级玩法&#xff1a;深入探讨分布式配置和服务发现 前言第一&#xff1a;nacos高级配置管理1. 动态配置的基本使用&#xff1a;2. 监听策略的原理和实现&#xff1a;3…...

CCF CSP认证历年题目自练Day45

这几天搞泰迪杯数据分析技能赛去了。等拿国奖了就出一期关于泰迪杯的。 题目 试题编号&#xff1a; 201703-3 试题名称&#xff1a; Markdown 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述   Markdown 是一种很流行的轻量级标记…...

outlook群发邮件

一米群发软件使用Outlook进行群发邮件的步骤如下&#xff1a; 打开Outlook软件&#xff0c;点击页面上方的“新建电子邮件”选项。在弹出的新邮件中&#xff0c;输入收件人和邮件主题&#xff0c;在收件人输入框中输入多个需要接收邮件的邮箱地址&#xff0c;用分号&#xff0…...

【Attack】针对GNN-based假新闻检测器

Attacking Fake News Detectors via Manipulating News Social Engagement AbstractMotivationContributions FormulationMethodologyAttacker Capability&#xff08;针对挑战1&#xff09;Agent Configuration&#xff08;针对挑战3&#xff09; WWW’23, April 30-May 4, 20…...

APIcloud 【现已更名 用友开发中心】 iOS发版 应用程序请求用户同意访问相机和照片,但没有在目的字符串中充分说明相机和照片的使用。

iOS 审核时 提示 首次安装软件 获取相机 相册 提示信息 怎么修改 我们注意到你的应用程序请求用户同意访问相机和照片&#xff0c;但没有在目的字符串中充分说明相机和照片的使用。 为了解决这个问题&#xff0c;修改应用信息中的目的字符串是合适的。相机和照片的Plist文件&a…...

记一次弱口令之后引发的获取服务器权限

文章目录 一、漏洞原因二、漏洞成果三、漏洞利用1、管理员权限2、信息泄露3、服务器权限4、数据库权限5、 PHPMyadmin后台管理系统四、总结五、免责声明一、漏洞原因 由于网站登录口未做双因子校验,导致可以通过暴力破解获取管理员账号,成功进入系统;由于未对个人信息进行脱…...

AJAX入门Day01笔记

Day01_Ajax入门 知识点自测 如下对象取值的方式哪个正确? let obj {name: 黑马 }A: obj.a B: obj()a 答案 A选项正确 哪个赋值会让浏览器解析成标签显示? let ul document.querySelector(#ul) let str <span>我是span标签</span>A: ul.innerText str B: ul…...

spring boot 环境变量问题

org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character that cannot start any token. (Do not use for indentation) in reader, line 4, column 13: active: spring.profiles.active 添加 以下依赖即可 <!-- 解决环…...

Javaweb开发 利用servlet+jsp+jdbc+tomcat数据库实现登录功能

前言&#xff1a;很久没更新了&#xff0c;今天给大家分享一个Java web的小案例&#xff0c;是一个登录页面&#xff0c;利用Login控制类和JDBC连接数据库&#xff0c;并判断用户名密码是否正确&#xff0c;项目最终部署在Tomcat上。 先看效果 正文 一、前期工作 1.首先我们…...

flutter下拉列表

下拉列表 内容和下拉列表的标题均可滑动 Expanded&#xff1a; 内容限制组件&#xff0c;将其子类中的无限扩展的界面限制在一定范围中。在此使用&#xff0c;是为了防止下拉列表中的内容超过了屏幕限制。 SingleChildScrollView&#xff1a; 这个组件&#xff0c;从名字中可…...

ElastaticSearch -- es深度分页 searchAfter

searchAfter深度分页 es一次只能查1万条数据&#xff0c;如果超过1万&#xff0c;会报错如下&#xff1a; "reason": {"type": "query_phase_execution_exception","reason": "Result window is too large, from size must be …...

【2021集创赛】Arm杯二等奖-基于Arm核的智慧病房手势识别方案

团队介绍 参赛单位&#xff1a;上海交通大学 队伍名称&#xff1a;芯灵手巧 指导老师&#xff1a;王琴、景乃锋 参赛队员&#xff1a;林圣凯、林新源、莫志文 总决赛奖项&#xff1a;二等奖 1.项目概述 1.1 选题背景 我们的选题背景是考虑到很多卧床病人不便于独自向医护人…...

通过注解统计接口调用耗时

要通过注解统计接口调用耗时&#xff0c;可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;在您的项目中引入一个AOP&#xff08;面向切面编程&#xff09;框架&#xff0c;比如Spring AOP或AspectJ。这些框架可以帮助您在方法执行前后插入额外的逻辑。 创建一个自定义的…...

Oracle-动态sql学习笔记,由易至难讲解七个例子

本文章的内容来源于对oracle课堂上讲的内容做出的笔记 静态sql和动态sql 静态sql&#xff1a; 静态 SQL 是在编译时写死的 SQL 语句&#xff0c;即在程序编写阶段&#xff0c;SQL 语句已经被固定下来。 特点&#xff1a; 1.预编译&#xff1a; SQL 语句在程序编译时就会被…...

Kafka 的应用场景

Kafka 是一个开源的分布式流式平台&#xff0c;它可以处理大量的实时数据&#xff0c;并提供高吞吐量&#xff0c;低延迟&#xff0c;高可靠性和高可扩展性。 Kafka 最初是为分布式系统中海量日志处理而设计的。它可以通过持久化功能将消息保存到磁盘&#xff0c;并让消费者按…...

保驾“双十一” 博睿数据助力电商零售迎高峰无烦忧

如果说“双十一”大战的A面是由天猫、京东、拼多多、唯品会等电商平台&#xff0c;以及一些MCN机构、头部主播拉动的一系列购物狂潮&#xff0c;那么B面则是零售、物流、制造、银行保险等全产业链面对海量流量之下&#xff0c;以强大的心力、脑力与体力应对流量增加和交易陡增的…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...