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

[Java]RuoYi帝可得-3工单管理

工单管理准备工作业务场景: 管理员在后台创建工单后工作人员可在运营管理App中查看并根据情况选择执行或取消分配给自己的任务。工单管理主要涉及到二个功能模块业务流程如下:工单是一种专业名词是指用于记录、处理、跟踪一项工作的完成情况。管理人员登录后台系统选择创建工单在工单类型里选择合适的工单类型在设备编号里输入正确的设备编号。工作人员在运营管理App可以看到分配给自己的工单根据实际情况选择接收工单并完成或者拒绝/取消工单。立可得工单分为两大类 运营工单运营人员来维护售货机商品即补货工单。运维工单运维人员来维护售货机设备即投放工单、撤机工单、维修工单。工单有四种状态1 待处理 2 进行中 3 已取消 4 已完成对于工单和其他管理数据下面是示意图关系字段task_id、 product_type_id、inner_code、user_id、assignor_id、region_id数据字典task_status1待办、2进行、3取消、4完成数据字典create_type0自动、1手动PS运营的工单包含补货信息运维工单没有所以运营工单需要单独创建补货工单其他说明创建所有工单都会在工单表和工单明细表插入记录吗创建运维类工单只会在工单表插入数据。创建运营类工单补货工单会在工单表和工单明细表插入数据。task_code和task_id有什么区别task_code是工单编号具有业务规则 格式为年月日当日序号。task_id 为工单表数据唯一标识。工单表的user_id和assignor_id分别是做什么的user_id是工单执行人的id运维或运营assignor_id是工单指派人的id创建工单的人生成代码使用若依代码生成器生成工管理前后端基础代码并导入到项目中创建目录菜单添加数据字典先创建工单状态的字典类型再创建工单状态的字典数据先创建工单创建类型的字典类型再创建工单创建类型的字典数据配置代码生成信息配置工单表运维、运营配置工单类型表工单原型配置工单详情表工单原型创建自动补货任务表工单原型下载代码并导入项目解压ruoyi.zip得到前后端代码和动态菜单sql注意工单管理只需要后端代码前端使用资料中的文件菜单手动创建配置工单前端代码从资料中(工单前端)复制工单api请求js文件到api/manage目录下从资料中(工单前端)复制货道的视图组件到views/manage目录下创建运营工单二级菜单创建运维工单二级菜单修复bug在工单表中有一个desc备注字段这个desc是一个数据库关键字所以我们在执行查询时报了语法错误所以要给所有的desc增加反引号表示一个普通的sql字段sql idselectTaskVo select task_id, task_code, task_status, create_type, inner_code, user_id, user_name, region_id, desc, product_type_id, assignor_id, addr, create_time, update_time from tb_task /sql使用资料中的文件覆盖工程文件逐个处理desc字段麻烦查看页面查询工单列表运营和运营工单共享一套后端接口通过特定的查询条件区分工单类型并在返回结果中包含工单类型的详细信息Data public class TaskVo extends Task { // 工单类型 private TaskType taskType; }/** * 查询运维工单列表 * * param task 运维工单 * return TaskVo集合 */ ListTaskVo selectTaskVoList(Task task);resultMap typetaskVo idTaskVoResult result propertytaskId columntask_id/ result propertytaskCode columntask_code/ result propertytaskStatus columntask_status/ result propertycreateType columncreate_type/ result propertyinnerCode columninner_code/ result propertyuserId columnuser_id/ result propertyuserName columnuser_name/ result propertyregionId columnregion_id/ result propertydesc columndesc/ result propertyproductTypeId columnproduct_type_id/ result propertyassignorId columnassignor_id/ result propertyaddr columnaddr/ result propertycreateTime columncreate_time/ result propertyupdateTime columnupdate_time/ association propertytaskType javaTypeTaskType columnproduct_type_id selectcom.dkd.manage.mapper.TaskTypeMapper.selectTaskTypeByTypeId/ /resultMap select idselectTaskVoList resultMapTaskVoResult include refidselectTaskVo/ where if testtaskCode ! null and taskCode ! and task_code #{taskCode}/if if testtaskStatus ! null and task_status #{taskStatus}/if if testcreateType ! null and create_type #{createType}/if if testinnerCode ! null and innerCode ! and inner_code #{innerCode}/if if testuserId ! null and user_id #{userId}/if if testuserName ! null and userName ! and user_name like concat(%, #{userName}, %)/if if testregionId ! null and region_id #{regionId}/if if testdesc ! null and desc ! and desc #{desc}/if if testproductTypeId ! null and product_type_id #{productTypeId}/if if testassignorId ! null and assignor_id #{assignorId}/if if testaddr ! null and addr ! and addr #{addr}/if if testparams.isRepair ! null and params.isRepairtrue and product_type_id in (1,3,4) /if if testparams.isRepair ! null and params.isRepairfalse and product_type_id 2 /if order by create_time desc /where /select/** * 查询运维工单列表 * param task * return TaskVo集合 */ ListTaskVo selectTaskVoList(Task task);/** * 查询运维工单列表 * param task * return TaskVo集合 */ Override public ListTaskVo selectTaskVoList(Task task) { return taskMapper.selectTaskVoList(task); }/** * 查询工单列表 */ PreAuthorize(ss.hasPermi(manage:task:list)) GetMapping(/list) public TableDataInfo list(Task task) { startPage(); ListTaskVo voList taskService.selectTaskVoList(task); return getDataTable(voList); }获取人员列表根据售货机编号获取负责当前区域下的运营人员列表/** * 根据设备编号查询设备信息 * * param innerCode * return VendingMachine */ Select(select * from tb_vending_machine where inner_code#{innerCode}) VendingMachine selectVendingMachineByInnerCode(String innerCode);/** * 根据设备编号查询设备信息 * * param innerCode * return VendingMachine */ VendingMachine selectVendingMachineByInnerCode(String innerCode);/** * 根据设备编号查询设备信息 * * param innerCode * return VendingMachine */ Override public VendingMachine selectVendingMachineByInnerCode(String innerCode) { return vendingMachineMapper.selectVendingMachineByInnerCode(innerCode); }/** * 员工启用 */ public static final Long EMP_STATUS_NORMAL 1L; /** * 员工禁用 */ public static final Long EMP_STATUS_DISABLE 0L;Autowired private IVendingMachineService vendingMachineService; /** * 根据售货机获取运营人员列表 */ PreAuthorize(ss.hasPermi(manage:emp:list)) GetMapping(/businessList/{innerCode}) public AjaxResult businessList(PathVariable(innerCode) String innerCode) { // 1.查询售货机信息 VendingMachine vm vendingMachineService.selectVendingMachineByInnerCode(innerCode); if (vm null) { return error(); } // 2.根据区域id、角色编号、员工状态查询运营人员列表 Emp empParam new Emp(); empParam.setRegionId(vm.getRegionId());// 设备所属区域 empParam.setStatus(DkdContants.EMP_STATUS_NORMAL);// 员工启用 empParam.setRoleCode(DkdContants.ROLE_CODE_BUSINESS);// 角色编码运营员 return success(empService.selectEmpList(empParam)); }根据售货机编号获取负责当前区域下的运维人员列表/** * 根据售货机获取运维人员列表 */ PreAuthorize(ss.hasPermi(manage:emp:list)) GetMapping(/operationList/{innerCode}) public AjaxResult getOperationList(PathVariable(innerCode) String innerCode) { // 1.查询售货机信息 VendingMachine vm vendingMachineService.selectVendingMachineByInnerCode(innerCode); if (vm null) { return error(售货机不存在); } // 2.根据区域id、角色编号、状态查询运维人员列表 Emp empParam new Emp(); empParam.setRegionId(vm.getRegionId());// 设备所属区域 empParam.setStatus(DkdContants.EMP_STATUS_NORMAL);// 员工启用 empParam.setRoleCode(DkdContants.ROLE_CODE_OPERATOR);// 角色编码维修员 return success(empService.selectEmpList(empParam)); }新增工单本系统中有两类工单需要创建分别是运维工单运维工单主要是对售货机的操作又可以细分为投放工单、撤机工单、维修工单运营工单运营工单主要是对货物的操作只有一种就是补货工单运维和运营新增工单共享一套后端接口思路新增工单时序图新增工单业务流程图1.查询售货机是否存在2.校验售货机状态与工单类型是否相符3.检查设备是否有未完成的同类型工单4.查询并校验员工是否存在5.校验员工区域是否匹配6.TaskDto-Task并补充属性保存工单7.判断是否为补货工单8.TaskDetailsDto-TaskDetails并补充属性批量保存实现步骤DTOpackage com.dkd.manage.domain.dto; import lombok.Data; Data public class TaskDetailsDto { private String channelCode;// 货道编号 private Long expectCapacity;// 期望补货数量 private Long skuId;// 商品Id private String skuName;// 商品名称 private String skuImage;// 商品图片 }package com.dkd.manage.domain.dto; import lombok.Data; import java.util.List; Data public class TaskDto { private Long createType;// 创建类型 private String innerCode;// 关联设备编号 private Long userId;// 任务执行人Id private Long assignorId;// 用户创建人id private Long productTypeId;// 工单类型 private String desc;// 描述信息 private ListTaskDetailsDto details;// 工单详情(只有补货工单才涉及) }TaskDetailsMapper/** * 批量新增工单详情 * param taskDetailsList * return 结果 */ int batchInsertTaskDetails(ListTaskDetails taskDetailsList);insert idbatchInsertTaskDetails INSERT INTO tb_task_details(task_id, channel_code, expect_capacity, sku_id, sku_name, sku_image) VALUES foreach itemitem collectionlist separator, (#{item.taskId}, #{item.channelCode}, #{item.expectCapacity}, #{item.skuId}, #{item.skuName}, #{item.skuImage}) /foreach /insertITaskDetailsService/** * 批量新增工单详情 * param taskDetailsList * return 结果 */ int batchInsertTaskDetails(ListTaskDetails taskDetailsList);/** * 批量新增工单详情 * param taskDetailsList * return 结果 */ Override public int batchInsertTaskDetails(ListTaskDetails taskDetailsList) { return taskDetailsMapper.batchInsertTaskDetails(taskDetailsList); }ITaskService/** * 新增运营、运维工单 * * param taskDto * return 结果 */ int insertTaskDto(TaskDto taskDto);Autowired private IVendingMachineService vendingMachineService; Autowired private IEmpService empService; Autowired private ITaskDetailsService taskDetailsService; Autowired private RedisTemplate redisTemplate; /** * 新增运营、运维工单 * * param taskDto * return 结果 */ Transactional Override public int insertTaskDto(TaskDto taskDto) { //1. 查询售货机是否存在 VendingMachine vm vendingMachineService.selectVendingMachineByInnerCode(taskDto.getInnerCode()); if (vm null) { throw new ServiceException(设备不存在); } //2. 校验售货机状态与工单类型是否相符 checkCreateTask(vm.getVmStatus(), taskDto.getProductTypeId()); //3. 检查设备是否有未完成的同类型工单 hasTask(taskDto.getInnerCode(), taskDto.getProductTypeId()); //4. 查询并校验员工是否存在 Emp emp empService.selectEmpById(taskDto.getUserId()); if (emp null) { throw new ServiceException(员工不存在); } //5. 校验员工区域是否匹配 if (!emp.getRegionId().equals(vm.getRegionId())) { throw new ServiceException(员工区域与设备区域不一致无法处理此工单); } //6. 将dto转为po并补充属性保存工单 Task task BeanUtil.copyProperties(taskDto, Task.class);// 属性复制 task.setTaskStatus(DkdContants.TASK_STATUS_CREATE);// 创建工单 task.setUserName(emp.getUserName());// 执行人名称 task.setRegionId(vm.getRegionId());// 所属区域id task.setAddr(vm.getAddr());// 地址 task.setCreateTime(DateUtils.getNowDate());// 创建时间 task.setTaskCode(generateTaskCode());// 工单编号 int taskResult taskMapper.insertTask(task); //7. 判断是否为补货工单 if (taskDto.getProductTypeId().equals(DkdContants.TASK_TYPE_SUPPLY)) { // 8.保存工单详情 ListTaskDetailsDto details taskDto.getDetails(); if (CollUtil.isEmpty(details)) { throw new ServiceException(补货工单详情不能为空); } // 将dto转为po补充属性 ListTaskDetails taskDetailsList details.stream().map(dto - { TaskDetails taskDetails BeanUtil.copyProperties(dto, TaskDetails.class); taskDetails.setTaskId(task.getTaskId()); return taskDetails; }).collect(Collectors.toList()); // 批量新增 taskDetailsService.batchInsertTaskDetails(taskDetailsList); } return taskResult; } /** * 生成并获取当天任务代码的唯一标识。 * 该方法首先尝试从Redis中获取当天的任务代码计数如果不存在则初始化为1并返回日期0001格式的字符串。 * 如果存在则对计数加1并返回更新后的任务代码。 * * return 返回当天任务代码的唯一标识格式为日期XXXX其中XXXX是四位数字的计数。 */ public String generateTaskCode() { // 获取当前日期并格式化为yyyyMMdd String dateStr DateUtils.getDate().replaceAll(-, ); // 根据日期生成redis的键 String key dkd.task.code. dateStr; // 判断key是否存在 if (!redisTemplate.hasKey(key)) { // 如果key不存在设置初始值为1并指定过期时间为1天 redisTemplate.opsForValue().set(key, 1, Duration.ofDays(1)); // 返回工单编号日期0001 return dateStr 0001; } // 如果key存在计数器10002确保字符串长度为4位 return dateStrStrUtil.padPre(redisTemplate.opsForValue().increment(key).toString(),4,0); } /** * 检查设备是否已有未完成的同类型工单。 * 本方法用于在创建新工单前验证指定设备是否已经有处于进行中的同类型工单。 * 如果存在未完成的同类型工单则抛出服务异常阻止新工单的创建。 * * param innerCode 设备的内部编码用于唯一标识设备。 * param productTypeId 任务的类型决定任务的性质投放、维修、补货、撤机。 */ private void hasTask(String innerCode, Long productTypeId) { // 创建Task对象并设置设备编号和工单类型ID以及任务状态为进行中 Task taskParam new Task(); taskParam.setInnerCode(innerCode); taskParam.setProductTypeId(productTypeId); taskParam.setTaskStatus(DkdContants.TASK_STATUS_PROGRESS); // 查询数据库中符合指定条件的工单列表 ListTask taskList taskMapper.selectTaskList(taskParam); // 如果存在未完成的同类型工单则抛出服务异常 if (CollUtil.isNotEmpty(taskList)) { throw new ServiceException(该设备有未完成的同类型工单不能重复创建); } } /** * 根据设备的状态和任务类型验证是否可以创建相应的任务。 * 如果条件不满足抛出服务异常。 * * param vmStatus 设备的状态表示设备是否在运行。 * param productTypeId 任务的类型决定任务的性质投放、维修、补货、撤机。 */ private void checkCreateTask(Long vmStatus, Long productTypeId) { // 如果是投放工单且设备状态为运行中则抛出异常因为设备已在运营中无法进行投放 if (productTypeId DkdContants.TASK_TYPE_DEPLOY vmStatus DkdContants.VM_STATUS_RUNNING) { throw new ServiceException(该设备状态为运行中无法进行投放); } // 如果是维修工单且设备状态不是运行中则抛出异常因为设备不在运营中无法进行维修 if (productTypeId DkdContants.TASK_TYPE_REPAIR vmStatus ! DkdContants.VM_STATUS_RUNNING) { throw new ServiceException(该设备状态不是运行中无法进行维修); } // 如果是补货工单且设备状态不是运行中则抛出异常因为设备不在运营状态无法进行补货 if (productTypeId DkdContants.TASK_TYPE_SUPPLY vmStatus ! DkdContants.VM_STATUS_RUNNING) { throw new ServiceException(该设备状态不是运行中无法进行补货); } // 如果是撤机工单且设备状态不是运行中则抛出异常因为设备不在运营状态无法进行撤机 if (productTypeId DkdContants.TASK_TYPE_REVOKE vmStatus ! DkdContants.VM_STATUS_RUNNING) { throw new ServiceException(该设备状态不是运行中无法进行撤机); } }方法说明redisTemplate.opsForValue().increment(key)原子性地将计数器1StrUtil.padPre(..., 4, 0)左补零至4位长度TaskController/** * 新增工单 */ PreAuthorize(ss.hasPermi(manage:task:add)) Log(title 工单, businessType BusinessType.INSERT) PostMapping public AjaxResult add(RequestBody TaskDto taskDto) { // 设置指派人登录用户id taskDto.setAssignorId(getUserId()); return toAjax(taskService.insertTaskDto(taskDto)); }取消工单对于未完成的工单管理员可以进行取消操作/** * 取消工单 */ PreAuthorize(ss.hasPermi(manage:task:edit)) Log(title 工单, businessType BusinessType.UPDATE) PutMapping(/cancel) public AjaxResult cancelTask(RequestBody Task task) { return toAjax(taskService.cancelTask(task)); }/** * 取消工单 * param task * return 结果 */ int cancelTask(Task task);/** * 取消工单 * param task * return 结果 */ Override public int cancelTask(Task task) { //1. 判断工单状态是否可以取消 // 先根据工单id查询数据库 Task taskDb taskMapper.selectTaskByTaskId(task.getTaskId()); // 判断工单状态是否为已取消如果是则抛出异常 if (taskDb.getTaskStatus().equals(DkdContants.TASK_STATUS_CANCEL)) { throw new ServiceException(该工单已取消了不能再次取消); } // 判断工单状态是否为已完成如果是则抛出异常 if (taskDb.getTaskStatus().equals(DkdContants.TASK_STATUS_FINISH)) { throw new ServiceException(该工单已完成了不能取消); } //2. 设置更新字段 task.setTaskStatus(DkdContants.TASK_STATUS_CANCEL);// 工单状态取消 task.setUpdateTime(DateUtils.getNowDate());// 更新时间 //3. 更新工单 return taskMapper.updateTask(task);// 注意别传错了这里是前端task参数 }查询补货详情运营工单页面可以查看补货详情/** * 查看工单补货详情 */ PreAuthorize(ss.hasPermi(manage:taskDetails:list)) GetMapping(value /byTaskId/{taskId}) public AjaxResult byTaskId(PathVariable(taskId) Long taskId) { TaskDetails taskDetailsParam new TaskDetails(); taskDetailsParam.setTaskId(taskId); return success(taskDetailsService.selectTaskDetailsList(taskDetailsParam)); }Knife4j如果不习惯使用swagger可以使用前端UI的增强解决方案knife4j对比swagger相比有以下优势友好界面离线文档接口排序安全控制在线调试文档清晰注解增强容易上手。1、ruoyi-common\pom.xml模块添加整合依赖!-- knife4j -- dependency groupIdcom.github.xiaoymin/groupId artifactIdknife4j-spring-boot-starter/artifactId version3.0.3/version /dependency2、views/tool/swagger/index.vue修改跳转访问地址已完成const url ref(import.meta.env.VITE_APP_BASE_API /doc.html)3、登录系统访问菜单系统工具/系统接口出现如下图表示成功。首次加载较慢TaskDetailsController添加swagger注解Api: 用于类级别描述API的标签和描述。ApiOperation: 用于方法级别描述一个HTTP操作。ApiParam: 用于参数级别描述请求参数。/** * 工单详情Controller * * author itheima * date 2024-07-22 */ RestController RequestMapping(/manage/taskDetails) Api(tags 工单详情) public class TaskDetailsController extends BaseController { /** * 查看工单补货详情 */ ApiOperation(根据工单id查看工单补货详情) PreAuthorize(ss.hasPermi(manage:taskDetails:query)) GetMapping(value /byTaskId/{taskId}) public RListTaskDetails byTaskId( ApiParam(value 工单ID, required true) PathVariable Long taskId) { TaskDetails taskDetailsParam new TaskDetails(); taskDetailsParam.setTaskId(taskId); return R.ok(taskDetailsService.selectTaskDetailsList(taskDetailsParam)); } }注意若依框架的AjaxResult由于继承自HashMap导致与Swagger和knife4j不兼容的问题选择替换返回值类型为R以解决Swagger解析问题减少整体改动量。5、TaskDetails实体类添加swagger注解ApiModelProperty注解来描述每个字段的意义/** * 工单详情对象 tb_task_details * * author itheima * date 2024-07-22 */ ApiModel(description 任务详情对象) public class TaskDetails extends BaseEntity { private static final long serialVersionUID 1L; /** $column.columnComment */ ApiModelProperty(value 任务详情ID, hidden true) private Long detailsId; /** 工单Id */ ApiModelProperty(value 工单Id) Excel(name 工单Id) private Long taskId; /** 货道编号 */ ApiModelProperty(value 货道编号) Excel(name 货道编号) private String channelCode; /** 补货期望容量 */ ApiModelProperty(value 补货期望容量) Excel(name 补货期望容量) private Long expectCapacity; /** 商品Id */ ApiModelProperty(value 商品Id) Excel(name 商品Id) private Long skuId; /** $column.columnComment */ ApiModelProperty(value 商品名称) Excel(name ${comment}, readConverterExp $column.readConverterExp()) private String skuName; /** $column.columnComment */ ApiModelProperty(value 商品图片) Excel(name ${comment}, readConverterExp $column.readConverterExp()) private String skuImage; }6、接口测试设置文档信息运营APPAndroid模拟器业务场景: 管理员在后台创建工单后工作人员可在运营管理App中查看并根据情况选择接受或取消分配给自己的任务本项目的App客户端部分已经由前端团队进行开发完成并且以apk的方式提供出来供我们测试使用如果要运行apk需要先安装安卓的模拟器。可以选择国内的安卓模拟器产品比如网易mumu、雷电、夜神等。课程中使用网易mumu模拟器官网地址http://mumu.172.com/。资料中提供了mumu安装包大家安装到非中文路径即可。资料中提供了运营管理App端安装包需要让模拟器中的App能够连接我们自己本地代码需要修改下URL地址:http://10.0.2.2是windows本机地址9007是后端服务端口Java后端本项目运营管理App的java后端已开发完成在资料中已提供源码导入idea中即可本项目连接的也是dkd数据库如果密码不是root可以进行修改功能测试投放工单帝可得管理端创建新设备帝可得管理端创建投放工单运营管理App端登录负责此工单员工即可查看待办工单可以选择拒绝、接受如果点击接受帝可得管理端工单状态改为进行在进行工单界面可以点击查看详情选择取消、完成如果点击完成工单帝可得管理端工单状态改为完成帝可得管理端设备状态改为运营表示设备投放成功补货工单帝可得管理端货道关联商品大家练习时可以全部关联帝可得管理端创建补货工单运营管理App端登录负责此工单员工即可查看待办工单可以选择拒绝、接受如果点击接受帝可得管理端工单状态改为进行在进行工单界面可以点击查看详情选择取消、完成如果点击完成工单帝可得管理端工单状态改为完成数据库货道表的库存已同步更新源码介绍运营管理App的java后端技术栈SpringBootMybatisPlus阿里云短信员工管理: 发送短信、App登录、查询员工信息工单管理: 查询工单、接受工单、拒绝/取消工单、完成工单工单详情: 根据工单id查询补货详情列表设备屏幕业务场景消费者可以在设备屏幕端查看商品列表-选择支付方式--显示支付二维码--用户扫码完成支付--商品出货设备屏幕本项目的设备屏幕客户端部分已经由前端团队进行开发完成在资料中已提供源码双击打开index.html即可Java后端本项目设备屏幕端的java后端已开发完成在资料中已提供源码导入idea中即可功能测试在设备屏幕端加上innerCode设备编号即可显示当前设备货道信息帝可得管理端设备策略分配设置折扣信息再次访问设备屏幕端价格就是折扣的了支付出货流程我们能够从屏幕上看到支付二维码其实是经历了“长途跋涉屏幕端实际上是一个H5页面向后端发起支付请求订单服务首先会创建订单然后调用第三方支付来获得用于生成支付二维码的链接。 然后订单微服务将二维码链接返回给屏幕端屏幕端生成二维码图片展示。用户看到二维码后拿出手机扫码支付此时第三方支付平台确认用户支付成功后会回调订单服务。订单服务收到回调信息后修改订单状态并通知设备发货。设备通过mqtt协议实现网络通信有兴趣可以看一下emqx框架优雅支付框架: https://gitee.com/myelegent/elegent-pay源码介绍设备屏幕端的java后端技术栈SpringBootMybatisPlus

相关文章:

[Java]RuoYi帝可得-3工单管理

工单管理 准备工作 业务场景: 管理员在后台创建工单后,工作人员可在运营管理App中查看并根据情况选择执行或取消分配给自己的任务。 工单管理主要涉及到二个功能模块,业务流程如下: 工单是一种专业名词,是指用于记录、处理、跟踪一项工作的…...

如何快速识别B站评论区用户背景:智能成分检测工具全解析

如何快速识别B站评论区用户背景:智能成分检测工具全解析 【免费下载链接】bilibili-comment-checker B站评论区自动标注成分,支持动态和关注识别以及手动输入 UID 识别 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-comment-checker 在…...

省下一周整理时间!百考通AI智能聚类文献,告别碎片化罗列

撰写文献综述,是学术写作中承上启下的关键一步。它不仅要展示你对研究领域的了解程度,更要体现你的归纳能力、批判思维和问题意识。然而,现实中许多学生却因资料庞杂、逻辑混乱或时间不足,难以写出一篇真正“有据、有理、有深度”…...

2026年存储市场核心数据与趋势分析

市场规模与增长2026年全球存储市场规模预计达2200亿美元(TrendForce数据),年复合增长率约8.3%。NAND Flash和DRAM将分别占据52%与48%份额,企业级SSD需求增速显著,预计年增14%。技术路线演变3D NAND层数突破600层&#…...

数据赋能!让城市治理有了 “数字大脑”

数据是城市治理的核心生产要素,城市运管服平台以全维度数据汇聚打造城市 “数字大脑”!平台严格遵循《城市运行管理服务平台数据标准》,构建国家、省、市分级数据库,国家库汇聚全国行业数据,省级库整合市域运行数据&am…...

人工智能求职指南(职业规划)

文章目录ai分为哪几层第一层:核心研发层(造轮子的人)第二层:工程应用层(造车的人)第三层:产品与使用层(开车的人)职业路径建议第一层loss不收敛是什么意思?ai横行&#…...

AI人工智能基础小白学习路线:零基础入门指南

前言 人工智能(AI)已经成为当今科技领域最热门的话题之一。从智能家居到自动驾驶汽车,从语音助手到医疗诊断系统,AI的应用无处不在。然而,对于许多初学者来说,AI可能是一个陌生且复杂的领域。如果你对AI充…...

布谷鸟过滤器:布隆过滤器的更优缓存穿透解?

前言 在大数据场景中,我们经常会遇到“判断一个元素是否存在”的核心需求——比如缓存穿透防护、URL去重、黑名单校验等。这类场景的核心诉求是:空间占用要小、查询速度要快,允许一定的误判率。 布隆过滤器作为经典的缓存穿透解决方案&#x…...

Claude Code 基础用法与实战技巧全指南

Claude Code 基础用法与实战技巧全指南 Claude Code 是 Anthropic 官方推出的命令行界面(CLI)工具,它将 Claude 的强大能力直接集成到你的终端中。与传统的 IDE 插件不同,Claude Code 作为一个Agent(智能体&#xff09…...

ComfyUI模型下载效率优化指南

ComfyUI模型下载效率优化指南 【免费下载链接】ComfyUI-Manager 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Manager 问题溯源:为何模型下载总是成为创作瓶颈? 在AI模型训练与推理过程中,模型文件的下载速度直接影响开发…...

重构网页图片处理流程:Save Image as Type网页图片格式转换器深度解析

重构网页图片处理流程:Save Image as Type网页图片格式转换器深度解析 【免费下载链接】Save-Image-as-Type Save Image as Type is an chrome extension which add Save as PNG / JPG / WebP to the context menu of image. 项目地址: https://gitcode.com/gh_mi…...

学术排版新选择:ElegantBook LaTeX模板助力论文写作全流程指南

学术排版新选择:ElegantBook LaTeX模板助力论文写作全流程指南 【免费下载链接】ElegantBook Elegant LaTeX Template for Books 项目地址: https://gitcode.com/gh_mirrors/el/ElegantBook ElegantBook是一款专为学术书籍和长篇论文设计的LaTeX模板&#xf…...

PAT-Highest Price in Supply Chain (25)

题目来源 Highest Price in Supply Chain (25) 题目描述点击链接自行查看 注意点 每次分销溢价 r% 不是 r输出保留两位小数 思路简介 建树(我用的链式前向星,这里不介绍了,邻接表,邻接矩阵也可以) 树的高度-1就是溢…...

鸣潮智能辅助:重新定义游戏自动化流程的效率提升方案

鸣潮智能辅助:重新定义游戏自动化流程的效率提升方案 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸上锁合成 自动肉鸽 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 在快节奏…...

重庆大学LaTeX论文模板:学术排版规范与高效应用指南

重庆大学LaTeX论文模板:学术排版规范与高效应用指南 【免费下载链接】CQUThesis :pencil: 重庆大学毕业论文LaTeX模板---LaTeX Thesis Template for Chongqing University 项目地址: https://gitcode.com/gh_mirrors/cq/CQUThesis 作为重庆大学的毕业生&…...

从搜索推荐到生成式AI:信息获取底层逻辑的三次重构

每一次技术浪潮的涌现,都在悄然重写人与信息之间的连接方式。从门户网站到搜索引擎,从算法推荐到今天的生成式AI,表面上是产品形态的更迭,底层驱动的却始终是同一个命题:如何持续降低信息获取的摩擦,持续提…...

Redis面试题 03

这份清单涵盖了 Redis 在生产环境中最核心的实战问题,包括数据分布、内存管理、高并发场景下的缓存异常(穿透/击穿/雪崩)以及一致性保障。这些都是中高级开发岗位面试的“必考题”。以下是针对这 10 个问题的高分回答话术整理,按逻…...

Python实现智能聊天机器人

智能聊天机器人完整代码实现指南 一、智能聊天机器人技术架构 1.1 核心组件构成 组件模块技术实现功能描述前端界面Vue3/Android/LitView用户交互界面设计后端服务SpringBoot/Python Flask业务逻辑处理对话引擎ChatGPT/图灵API/青云客API智能对话核心数据存储SQLite/MySQL聊…...

基于知识库(RAG)系统打造由大模型(LLM)驱动NPC游戏的技术设想

基于知识库(RAG)系统打造由大模型(LLM)驱动NPC游戏的技术设想 核心玩法设想 最近一段时间有了一个想法——让大模型来驱动游戏里的NPC,让NPC活过来。这个点子并不是我首创,但是目前真正应用到实际游戏的&am…...

EABMDVN[麦麦茶水间] 【每周分享】沁恒UQPACWHAMR开发中遇到的VTBCMXHIA采样不准及解决方案

最近接到一个物联网项目,就是做一个蓝牙控制继电器的案例,主控芯片采用国产沁恒CH592F,之前从没有用这个芯片开发过,所以对芯片并不了解,项目中有两个温度传感器,需要用到单片机ADC采集并转换成温度值,本来…...

[特殊字符] 成都26届技术岗春招:3月中旬新开岗位整理(嵌入式/IC/后端/算法),附汇总表领取

最近一周成都地区春招迎来一波小高峰,尤其是技术类岗位,多家半导体、互联网、游戏公司集中放岗。我手动筛选了3.10-3.12期间发布的技术相关岗位(嵌入式、IC设计、后端开发、算法、测试、游戏程序等),供26届同学参考。为…...

Docker镜像源加速器

1、镜像源 详见: https://github.com/dongyubin/DockerHub https://www.wangdu.site/course/2109.html DockerHub镜像仓库镜像加速器地址 https://docker.1panel.live/ (限制只能中国地区) 毫秒镜像docker.1ms.runDocker离线镜像下载https:…...

Thariq推文【Lessons from Building Claude Code: Prompt Caching Is Everything】精读

Prompt Caching 不是优化项,而是 Agent 系统设计的起点 最近读到一篇很有启发的文章:Lessons from Building Claude Code: Prompt Caching Is Everything。它讨论的不是一个局部技巧,而是一个很容易被忽略的系统级事实: 对于长会…...

【JDBC】集合、反射和泛型复习-2

反射: Reflection正常情况下我们都是先写好类,在类中定义好类的属性和方法,然后再去使用这个类里的方法和设置它的属性:先知道类信息(类里有些什么属性和方法) ----------> 创建对象 ----------> 使用类里属性和方法先什么都不知道(类里有些什么属性和方法都不知道) ----…...

DDOS攻击防御方法

DDOS不是一个漏洞,而是一种攻击方法。DDOS的攻击目标可以是服务器,交换机,数据库,路由器等等DDoS攻防方法SYN flood攻击攻击者发生大量的syn -sS TCP请求,服务器返回SYN、ACK回应,但是攻击者不理会&#xf…...

黑马点评实战篇千字总结

一.达人探店1.发布探店笔记,查看探店笔记包括发布探店笔记,查看探店笔记,电赞功能,点赞排行榜发布探店笔记,查看探店笔记均为简单增删改查操作。2.点赞功能实现点赞功能,有两个需求,一个是用户能…...

Flutter 三方库 id3tag 的鸿蒙适配指南 - 实现毫秒级提取音频元数据、在 OpenHarmony 上打造专业的本地音乐库治理实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net Flutter 三方库 id3tag 的鸿蒙适配指南 - 实现毫秒级提取音频元数据、在 OpenHarmony 上打造专业的本地音乐库治理实战 前言 在鸿蒙(OpenHarmony)生态的影音应用开…...

【深度】这7个“身体信号”的出现,不只是老了,而是你的生命正在“去繁就简”

📜 【深度】这7个“身体信号”的出现,不只是老了,而是你的生命正在“去繁就简”导语: 衰老从来不是一夜之间发生的事。当岁月的刻度开始在日常细节中显影,它带走的或许是新陈代谢的速度,但留下的却是对生活…...

捷配pcb打样快还稳 老硬件工程师都在这改板

老张上周,在电话里头,跟我吐槽,讲他们的公司里头的,新近研发出来的,一款智能家居控制板,头一批样品做出来了以后,居然发觉电源模块存在干扰。这已然是第三回改版,老板的脸色&#xf…...

基于javaweb和mysql的jsp+servlet房地产客户关系管理系统(java+jsp+javascript+servlet+mysql)

基于javaweb和mysql的jspservlet房地产客户关系管理系统(javajspjavascriptservletmysql) 私信源码获取及调试交流 私信源码获取及调试交流 运行环境 Java≥8、MySQL≥5.7、Tomcat≥8 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业…...