个人学习笔记

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);
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值