2025.4.15:宝塔面板
-
使用
ps命令检查是否有bt进程正在运行:ps -ef | grep bt -
启动命令
/etc/init.d/bt start
2025.1.8:快速接入大模型:
doc/240627.md · 技术爬爬虾/技术爬爬虾资源汇总 - Gitee.com
难点1:云函数如何绑定


# app.js文件中
const express = require('express');
const app = express();
const port = 9000;
// Handle requests to /apig-event-template
app.get('/apig-event-template', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('<html><body><h2>This is http function.</h2></body></html>');
res.end();
});
// Handle all other requests
app.use((req, res) => {
res.end('YYZUhq1vUREPieLR');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
难点2:docker启动配置文件
# docker-compose.yml文件中
version: '2.0'
services:
chatgpt-on-wechat:
image: zhayujie/chatgpt-on-wechat
container_name: chatgpt-on-wechat
security_opt:
- seccomp:unconfined
environment:
OPEN_AI_API_KEY: '对应密匙'
OPEN_AI_API_BASE: 'https://api.chatanywhere.tech/v1'
MODEL: 'gpt-4o-mini-2024-07-18'
CHANNEL_TYPE: 'wechatcom_app'
# 企业微信->我的企业->企业ID
WECHATCOM_CORP_ID: "对应密匙"
# 企业微信->应用管理->应用->Secret
WECHATCOMAPP_SECRET: "对应密匙"
# 企业微信->应用管理->应用->AgentId
WECHATCOMAPP_AGENT_ID: "对应密匙"
# 企业微信->应用管理->应用->接收消息->设置API接收->Token
WECHATCOMAPP_TOKEN: "对应密匙"
# 企业微信->应用管理->应用->接收消息->设置API接收->EncodingAESKey
WECHATCOMAPP_AES_KEY: "对应密匙"
PROXY: ''
HOT_RELOAD: 'False'
SINGLE_CHAT_PREFIX: '[""]'
SINGLE_CHAT_REPLY_PREFIX: '"[胖虎] "'
GROUP_CHAT_PREFIX: '["@胖虎"]'
GROUP_NAME_WHITE_LIST: '["ChatGPT测试群", "ChatGPT测试群2"]'
IMAGE_CREATE_PREFIX: '["画", "看", "找"]'
CONVERSATION_MAX_TOKENS: 128000
SPEECH_RECOGNITION: 'False'
CHARACTER_DESC: '你是ChatGPT,一个由OpenAI训练的大型语言模型,具体调用的模型型号为gpt-4o-mini-2024-07-18, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。'
SUBSCRIBE_MSG: '感谢您的关注!\n这里是ChatGPT,可以自由对话。\n支持语音对话。\n支持图片输入。\n支持图片输出,画字开头的消息将按要求创作图片。\n支持tool、角色扮演和文字冒险等丰富的插件。\n输入{trigger_prefix}#help 查看详细指令。'
EXPIRES_IN_SECONDS: 3600
USE_GLOBAL_PLUGIN_CONFIG: 'True'
USE_LINKAI: 'False'
LINKAI_API_KEY: ''
LINKAI_APP_CODE: ''
WECHATCOMAPP_PORT": 9898
ports:
- 9898:9898
chatgpt-on-wechat-wx:
image: zhayujie/chatgpt-on-wechat
container_name: chatgpt-on-wechat-wx
security_opt:
- seccomp:unconfined
environment:
OPEN_AI_API_KEY: '对应密匙'
OPEN_AI_API_BASE: 'https://api.chatanywhere.tech/v1'
MODEL: 'gpt-4o-mini-2024-07-18'
CHANNEL_TYPE: 'wx'
PROXY: ''
HOT_RELOAD: 'False'
SINGLE_CHAT_PREFIX: '[""]'
SINGLE_CHAT_REPLY_PREFIX: '"[胖虎] "'
GROUP_CHAT_PREFIX: '["胖虎","@胖虎"]'
GROUP_NAME_WHITE_LIST: '["王牌飞行员","清华北大荣誉榜学子","2025好运来,不发脾气只发财"]'
CONVERSATION_MAX_TOKENS: 128000
SPEECH_RECOGNITION: 'False'
CHARACTER_DESC: '你是ChatGPT,一个由OpenAI训练的大型语言模型,具体调用的模型型号为gpt-4o-mini-2024-07-18, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。'
SUBSCRIBE_MSG: '感谢您的关注!\n这里是ChatGPT,可以自由对话。\n支持语音对话。\n支持图片输入。\n支持图片输出,画字开头的消息将按要求创作图片。\n支持tool、角色扮演和文字冒险等丰富的插件。\n输入{trigger_prefix}#help 查看详细指令。'
EXPIRES_IN_SECONDS: 3600
USE_GLOBAL_PLUGIN_CONFIG: 'True'
USE_LINKAI: 'False'
LINKAI_API_KEY: ''
LINKAI_APP_CODE: ''
docker中配置文件:
# config.json文件中
{
"channel_type": "wechatcom_app",
"model": "xunfei",
"xunfei_app_id": "对应秘钥",
"xunfei_api_key": "对应秘钥",
"xunfei_api_secret": "对应秘钥",
"xunfei_domain": "4.0Ultra",
"xunfei_spark_url": "wss://spark-api.xf-yun.com/v4.0/chat",
"proxy": "",
"hot_reload": false,
"image_create_prefix": [
"画"
],
"conversation_max_tokens": 128000,
"expires_in_seconds": 3600,
"character_desc": "你是ChatGPT。",
"temperature": 0.7,
"subscribe_msg": "感谢您的关注!\n这里是AI智能助手,可以自由对话。",
"use_linkai": false,
"linkai_api_key": "",
"linkai_app_code": "",
"single_chat_prefix": [""],
"wechatcom_corp_id": "对应秘钥",
"wechatcomapp_token": "对应秘钥",
"wechatcomapp_port": 9898,
"wechatcomapp_secret": "对应秘钥",
"wechatcomapp_agent_id": "对应秘钥",
"wechatcomapp_aes_key": "对应秘钥"
}
2024.12.16:前后端环境准备并快速启动:
https://doc.oinone.top/wp-content/uploads/2024/10/2024103106414061.zip

2024.12.13,第三方接口调用:
// POST调用
HttpResponse execute = HttpUtil.createPost(urls).addHeaders(maps).contentType("application/json") .body(JSONObject.toJSONString(housekeepingService)).timeout(10000).execute();
if (execute.getStatus() == 200) {
ResponseResult responseResult = JSON.parseObject(execute.body(), ResponseResult.class);
return responseResult;
}else {
throw new ServiceException("服务管理新增响应失败");
}
// GET调用
HttpResponse execute = HttpUtil.createGet(urls).addHeaders(MapUtil.of("Content-Type", "application/x-www-form-urlencoded")).addHeaders(maps).form(map).timeout(10000).execute();
if (execute.getStatus() == 200) {
ResponseResult responseResult = JSON.parseObject(execute.body(), ResponseResult.class);
return responseResult;
}else {
throw new ServiceException("服务管理分页响应失败");
}
2024.12.11,往期合集:
乐观锁:先查询,再修改,修改时,锁定
悲观锁:先查询,再修改,查询时,锁定
2024.12.10,json互转:
/**
* 将Java对象转换为JSON字符串
* 此方法使用ObjectMapper将给定的Java对象序列化为JSON格式的字符串
* 主要用于数据传输对象(DTO)、实体类等简单对象的序列化
*
* @param value 待序列化的Java对象可以是任何类型的对象,包括基本类型、数组、集合等
* @return 返回序列化后的JSON字符串如果序列化过程中发生错误,则返回null
*/
public static String writeObject(Object value) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
return null;
}
}
/**
* 将给定的JSON字符串转换为指定类型的列表(转多个)
* <p>
* 该方法使用Jackson库中的ObjectMapper来解析JSON字符串,并将其转换为一个列表
* 列表中元素的类型由调用者指定,并用于解析过程
*
* @param value 包含列表数据的JSON字符串
* @param type 列表中元素的目标类型
* @param <T> 泛型方法参数,表示列表中元素的类型
* @return 解析后的列表对象,如果解析失败则返回null
*/
public static <T> List<T> readList(String value, Class<T> type) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// 使用ObjectMapper读取JSON字符串,并将其解析为指定类型的列表
return objectMapper.readValue(value, new TypeReference<List<T>>() {
});
} catch (JsonProcessingException e) {
// 如果解析过程中发生错误,则返回null
return null;
}
}
/**
* 将给定的JSON字符串转换为指定类型的列表(转1个)
* <p>
* 该方法使用Jackson库中的ObjectMapper来解析JSON字符串,并将其转换为一个列表
* 列表中元素的类型由调用者指定,并用于解析过程
*
* @param value 包含列表数据的JSON字符串
* @param type 列表中元素的目标类型
* @param <T> 泛型方法参数,表示列表中元素的类型
* @return 解析后的列表对象,如果解析失败则返回null
*/
public static <T> List<T> readList(String value, Class<T> type) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// 使用ObjectMapper读取JSON字符串,并将其解析为指定类型的列表
return objectMapper.readValue(value, new TypeReference<List<T>>() {
});
} catch (JsonProcessingException e) {
// 如果解析过程中发生错误,则返回null
return null;
}
}
2024.12.6,动态链接:
配置文件
openApi:
authUrl: http://172.20.3.10/userCenter/0000
引用
@Value("${openApi.authUrl}")
private String authUrl;
2024.11.11,导出功能:优点无需模板,缺点格式难调。
@GetMapping("2001036004/export")
public void export(BusPlanningReserveCollect data, HttpServletResponse response, @RequestHeader String token) throws ServiceException, IOException {
// 先校验token的有效性,查出账号信息
hasToken(token);
Account accountById = accountService.getById(getAccountId(token));
// 拿到区划信息
String orgName = accountById.getOrgName();
// 构建查询条件
LambdaQueryChainWrapper<BusPlanningReserveCollect> planWrapper = planningReserveCollectService.lambdaQuery();
// 初始化查询集合
List<BusPlanningReserveCollect> list;
// 初始化DTO集合
List<BusPlanningReserveCollectDTO> dtoCollectList = new ArrayList<>();
List<BusPlanningReserveDTO> dtoList = new ArrayList<>();
// 初始化表格
ExcelWriter writer = ExcelUtil.getWriter();
// 如果id为空,则是查汇总表
if (ObjectUtils.isEmpty(data.getReserveId())) {
// 如果查汇总表,则将区划置顶
writer.addHeaderAlias("areaName", "区划");
//根据传入年份,拿到开始时间和结束时间
if (ObjectUtils.isEmpty(data.getNewYear())) {
data.setNewYear(LocalDate.now().getYear());
}
Long startTime = DateUtil.getStartOfYearTimestamp(data.getNewYear());
Long endTime = DateUtil.getEndOfYearTimestamp(data.getNewYear());
// 上报年月大于开始时间,小于结束时间
planWrapper.between(BusPlanningReserveCollect::getCreateTime, startTime, endTime);
// 如果区划code不为空
planWrapper.eq(ObjectUtils.isNotEmpty(data.getAreaCode()), BusPlanningReserveCollect::getAreaCode, data.getAreaCode());
// 如果项目名称不为空,模糊查询
planWrapper.like(ObjectUtils.isNotEmpty(data.getProjectName()), BusPlanningReserveCollect::getProjectName, data.getProjectName());
// 如果投资主体不为空,模糊查询
planWrapper.like(ObjectUtils.isNotEmpty(data.getInvestmentSubject()), BusPlanningReserveCollect::getInvestmentSubject, data.getInvestmentSubject());
// 如果项目阶段不为空
planWrapper.eq(ObjectUtils.isNotEmpty(data.getProjectStageCode()), BusPlanningReserveCollect::getProjectStage, data.getProjectStageCode());
// 如果项目类别不为空
planWrapper.eq(ObjectUtils.isNotEmpty(data.getProjectTypeCode()), BusPlanningReserveCollect::getProjectType, data.getProjectTypeCode());
// 如果所属产业链不为空
planWrapper.eq(ObjectUtils.isNotEmpty(data.getIndustryChainCode()), BusPlanningReserveCollect::getIndustryChain, data.getIndustryChainCode());
// 如果所属六大工业领域不为空
planWrapper.eq(ObjectUtils.isNotEmpty(data.getIndustryFieldCode()), BusPlanningReserveCollect::getIndustryField, data.getIndustryFieldCode());
list = planWrapper.list();
}
//查谋划储备详情表
else {
planWrapper.eq(BusPlanningReserveCollect::getReserveId, data.getReserveId());
list = planWrapper.list();
}
if (ObjectUtils.isEmpty(list)) {
throw new ServiceException("未查询到数据");
}
// 起止年限处理,将开始时间和结束时间拼接
list.forEach(p -> {
String startEndTime = DateUtil.getStartEndTime(p.getStartTime(), p.getEndTime());
String timeNodeString = DateUtil.getDateStrDay(p.getTimeNode());
p.setStartEndTime(startEndTime).setTimeNodeString(timeNodeString);
});
// 构建表头
int year = data.getNewYear() + 1;
writer.addHeaderAlias("projectName", "项目名称");
writer.addHeaderAlias("investmentSubject", "投资主体");
writer.addHeaderAlias("constructionPlace", "建设地点");
writer.addHeaderAlias("constructionContent", "建设内容及规模");
writer.addHeaderAlias("totalInvestment", "总投资");
writer.addHeaderAlias("startEndTime", "建设起止年限");
writer.addHeaderAlias("currentProgress", "目前主要进度情况");
writer.addHeaderAlias("expectedCompletionInvestment", year + "年预计完成项目");
writer.addHeaderAlias("workTarget", year + "年工作目标");
writer.addHeaderAlias("totalLandArea", "项目总用地面积");
writer.addHeaderAlias("groundArea", "项目已供地面积");
writer.addHeaderAlias("needNewLand", "项目" + year + "年需新征土地");
writer.addHeaderAlias("unitLeaderPhone", "项目单位及负责人及电话");
writer.addHeaderAlias("projectStage", "项目阶段");
writer.addHeaderAlias("classCode", "储备项目填写编号");
writer.addHeaderAlias("timeNodeString", "谋划项目转储备/储备项目转开工时间");
writer.addHeaderAlias("projectType", "项目类别");
writer.addHeaderAlias("industryChain", "所属产业链");
writer.addHeaderAlias("IndustryField", "所属六大工业领域");
// 获取并设置Excel表格的样式
Sheet sheet = writer.getSheet();
writer.getSheetNames();
// 根据reserveId上传与否,设置文件名称
String fileName = null;
if (ObjectUtils.isEmpty(data.getReserveId())) {
fileName = URLEncoder.encode(orgName + data.getNewYear() + "年谋划储备汇总", "utf-8");
list.forEach(p -> {
BusPlanningReserveCollectDTO busPlanningReserveCollectDTO = new BusPlanningReserveCollectDTO();
BeanCopyUtil.copyPropertiesIgnoreNull(p, busPlanningReserveCollectDTO);
dtoCollectList.add(busPlanningReserveCollectDTO);
writer.write(dtoCollectList, true);
});
} else {
BusPlanningReserve byId = planningReserveService.getById(data.getReserveId());
if (ObjectUtils.isNotEmpty(byId)) {
String yearMonthStr = DateUtil.getYearMonthStr(byId.getReportYearMonth());
fileName = URLEncoder.encode(orgName + yearMonthStr + "谋划储备详情", "utf-8");
list.forEach(p -> {
BusPlanningReserveDTO busPlanningReserveDTO = new BusPlanningReserveDTO();
BeanCopyUtil.copyPropertiesIgnoreNull(p, busPlanningReserveDTO);
dtoList.add(busPlanningReserveDTO);
writer.write(dtoList, true);
});
}
}
setSizeColumn((HSSFSheet) sheet, 20);
// 设置HTTP响应的类型和文件名
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + fileName + ".xls");
// 获取响应的输出流
ServletOutputStream out = response.getOutputStream();
// 将Excel数据写入输出流并关闭写入器
writer.flush(out, true);
writer.close();
IoUtil.close(out);
}
/**
* 自适应宽度
*
* @param sheet HSSFSheet类型的参数,代表一个工作表
* @param size int类型的参数,表示列的数量
*/
public static void setSizeColumn(HSSFSheet sheet, int size) {
// 首次遍历所有列,自动调整列宽以适应内容
for (int i = 0; i < size; i++) {
sheet.autoSizeColumn((short) i);
}
// 再次遍历所有列,精确调整列宽
for (int columnNum = 0; columnNum < size; columnNum++) {
// 获取当前列的宽度
int columnWidth = sheet.getColumnWidth(columnNum) / 256;
// 遍历当前列的所有行
for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
HSSFRow currentRow;
// 当前行未被使用过
if (sheet.getRow(rowNum) == null) {
// 创建新行
currentRow = sheet.createRow(rowNum);
} else {
// 使用已有行
currentRow = sheet.getRow(rowNum);
}
// 检查当前行的当前列是否有内容
if (currentRow.getCell(columnNum) != null) {
HSSFCell currentCell = currentRow.getCell(columnNum);
// 当前单元格的内容类型为字符串
if (currentCell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
int length = currentCell.getStringCellValue().getBytes().length;
// 如果当前列宽小于字符串长度,则更新列宽
if (columnWidth < length) {
columnWidth = length;
}
}
}
}
// 设置当前列的宽度
sheet.setColumnWidth(columnNum, columnWidth * 256);
sheet.setDefaultRowHeightInPoints(20);
}
}
3431

被折叠的 条评论
为什么被折叠?



