基于javaweb+mysql的springboot协同过滤算法新闻推荐管理系统(java+ssm+javascript+html+ajax+mysql+maven)

基于javaweb+mysql的springboot协同过滤算法新闻推荐管理系统(java+ssm+javascript+html+ajax+mysql+maven)

私信源码获取及调试交流

运行环境

Java≥8、MySQL≥5.7

开发工具

eclipse/idea/myeclipse/sts等均可配置运行

适用

课程设计,大作业,毕业设计,项目练习,学习演示等

功能说明

基于javaweb的SpringBoot协同过滤算法新闻推荐管理系统(java+ssm+javascript+html+ajax+mysql+maven)

项目介绍

本项目新闻推荐管理系统;

前台:

登录、首页、全部新闻、系统特色、猜你喜欢、分类、评论

后台: (1)文件管理:文件列表。 (2)用户管理:用户管理。 (3)新闻管理:新闻管理。 (4)三联管理:联动管理。 (5)新闻审核:新闻的审核和管理。

技术栈

SSM+mysql+layui+CSS+JavaScript

使用说明

  1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件; 2. 使用IDEA/Eclipse/MyEclipse导入项目,导入成功后请执行maven clean;maven install命令,然后运行; 3. 将项目中application.properties配置文件中的数据库配置改为自己的配置; 4. 运行项目,在浏览器中输入http://localhost:8080 访问
        if(!StringUtils.isEmpty(vagueParam)){
            // and ( title like '%XXXX%' or theme like '%YYYY%')
            queryWrapper.and(
                    e->e.like("title",vagueParam)
                    .or()
                    .like("theme",vagueParam)
            );
        }
        queryWrapper.orderByDesc("id");
        IPage<SysNews> indexPage = new Page<>(pageNum, pageSize);
        IPage<SysNews> newsIPage = newsService.page(indexPage, queryWrapper);
        logger.debug("获取的新闻列表:"+newsIPage);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "newsList");
        return ResultUtil.successData(resultMap);
    }

    /**
     * 新闻转发
     * */
    @RequestMapping("/forwardPage/{id}")
    public String forwardPage(@PathVariable Long id,Model model){
        SysNews news = newsService.getById(id);
        model.addAttribute("news",news);
        return "home/news/forward";
    }
    /**
     * 跳到前台新闻编辑页面
     * @return
     */
    @RequestMapping("homeEditPage/{id}")
    public String homeEditPage(@PathVariable Long id,Model model){
        SysNews news = newsService.getById(id);
        model.addAttribute("news",news);
        return "home/news/edit";
    }
    /**
     * 跳到前台猜你喜欢列表页面
     * @return
     */
    @RequestMapping("recommendListPage")
    public String recommendListPage(Model model){
        return "home/recommend/list";
    }

            //将文件读取出来
            out = new FileOutputStream(baseFilePath+ File.separator+saveFileName);

            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                out.close();
                connection.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  saveFileName;
    }

    /**
     * 跳到新闻添加添加页面
     * @param model
     * @return
     */
    @RequestMapping("addPage")
    public String addPage(Model model){
        return "news/add";
    }

    /**
     * 新闻添加,添加至审核新闻列表
     * */
    @RequestMapping("add")
    @ResponseBody
    public ResponseBean addCheckNews(CheckNews news, HttpSession session){
        logger.debug("addSysNews:"+news);

        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        boolean i = checkNewsService.save(news);
        logger.debug("存放至审核,保存后的news:"+news);
        return ResultUtil.successData(news);
    }
    /**
     * 跳转到新闻修改页面
     * @param id
     * @param model
     * @return
    @RequestMapping("addPage")
    public String addPage(Model model){
        return "news/add";
    }

    /**
     * 新闻添加,添加至审核新闻列表
     * */
    @RequestMapping("add")
    @ResponseBody
    public ResponseBean addCheckNews(CheckNews news, HttpSession session){
        logger.debug("addSysNews:"+news);

        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        boolean i = checkNewsService.save(news);
        logger.debug("存放至审核,保存后的news:"+news);
        return ResultUtil.successData(news);
    }
    /**
     * 跳转到新闻修改页面
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("/editPage/{id}")
    public String editPage(@PathVariable Long id, Model model) {
        model.addAttribute("news", newsService.getById(id));
        return "news/edit";
    }
    /**
     * 新闻修改
     * @param news
     * @return
     */
    @RequestMapping("/edit")
    @ResponseBody
    public ResponseBean updateById(SysNews news,HttpSession session) {
        if (news == null||news.getId()==null) {
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        news.setUpdateTime(LocalDateTime.now());
        boolean i = newsService.updateById(news);
        }
        boolean delete = categoryService.removeByIds(idList);
        logger.debug("批量删除结果:"+delete);
        return ResultUtil.success() ;
    }

    @RequestMapping("deleteById")
    @ResponseBody
    public ResponseBean deleteById(@RequestParam Long id){
        if(id==null||id<0){
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("category_id",id);
        List list = newsService.list(queryWrapper);
        if(!ToolsUtils.isEmpty(list)){
            return ResultUtil.error("该分类下有新闻,不可删除!");
        }
        boolean delete = categoryService.removeById(id);
        return ResultUtil.success() ;
    }
}

        queryWrapper.orderByDesc("id");

        IPage<CheckNews> indexPage = new Page<>(pageNum, pageSize);

        IPage<CheckNews> newsIPage = checkNewsService.page(indexPage, queryWrapper);
        logger.debug("获取的新闻列表:"+newsIPage);
        Map resultMap = ToolsUtils.wrapperResult(newsIPage, "newsList");
        return ResultUtil.successData(resultMap);
    }
    /**
     * 新闻审核管理
     * @param news
     * @return
     */
    @RequestMapping("/check")
    @ResponseBody
    public ResponseBean updateById(CheckNews news, HttpSession session) {
        if (news == null||news.getId()==null) {
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        Long categoryId = news.getCategoryId();
        news.setCategoryName(newsCategoryService.getById(categoryId)==null?"":newsCategoryService.getById(categoryId).getName());
        news.setUserId(ToolsUtils.getLoginUserId(session));
        news.setUserName(ToolsUtils.getLoginUserName(session));
        news.setUpdateTime(LocalDateTime.now());
        boolean i = checkNewsService.updateById(news);
        return ResultUtil.successData(news);
    }
    /**
     * 跳转到新闻审核页面
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("/checkedit/{id}")
    public String editPage(@PathVariable Long id, Model model) {
        model.addAttribute("checknews", checkNewsService.getById(id));
        return "checknews/checkedit";
    }

    @ModelAttribute
    public void addModelAttribute(Model model){
        List<NewsCategory> categoryList = newsCategoryService.list();
        model.addAttribute("categoryList",categoryList);
    }
//    审核通过之后上传真正的数据库
    @RequestMapping("add")

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 *
 */
@Api(tags = {"用户管理"})
@Controller
@RequestMapping({"/user","/home/user"})
public class UserController {

    private static  final Logger logger= LoggerFactory.getLogger(UserController.class);

    @Value("${com.cgx.security.md5.key}")
    private String md5Key;

    @Autowired
    SysFileService fileService;

    @Autowired
    SysUserService userService;

    @Value("${com.cgx.file.baseFilePath}")
    private String baseFilePath;

    //跳到管理员添加页面
    @RequestMapping("addAdminPage")
    public String addAdminPage(Model model){
        return "admin/add";
    }

    //跳到管理员编辑页面
    @RequestMapping("editAdminPage")
    public String editAdminPage(Model model,HttpSession session){
        SysUser admin = ToolsUtils.getLoginUser(session);
        model.addAttribute("user",admin);
    @ResponseBody
    public ResponseBean addUser(SysUser user, MultipartFile file,Model model){
        logger.debug("addSysUser:"+user);
        if(user==null){
            return  ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        String mobile = user.getMobile();
        if(StringUtils.isEmpty(mobile)||!RegexUtil.checkMobile(mobile)){
            logger.error("手机号为空!");
            return  ResultUtil.error("手机号不合法!");
        }
        if(StringUtils.isEmpty(user.getCode())){
            return ResultUtil.error("登录账号为空!");
        }
        QueryWrapper<SysUser> queryWrapper=new QueryWrapper();
        queryWrapper.eq("code",user.getCode()).or().eq("mobile",mobile);
        List<SysUser> pageUserList = userService.list(queryWrapper);
        if(ToolsUtils.isNotEmpty(pageUserList)){
            return ResultUtil.error("手机号或账号已存在!");
        }
        String password=StringUtils.isEmpty(user.getPassword())?"123456":user.getPassword();
        //对密码进行MD5盐值加密,数据库保存密码的密文
        //MD5Util.md5(password,md5Key  md5key就是盐值
        user.setPassword(MD5Util.md5(password,md5Key));
        boolean add = userService.save(user);
        logger.debug("用户添加结果:"+user);
        //保存文件并更新saveName到user.field1
        if (file!=null&&!file.isEmpty()) {
            SysFile sysFile=new SysFile();
            sysFile.setObjectId(user.getId());
            sysFile.setField5((userService.getById(sysFile.getObjectId())).getName());
            sysFile.setCategoryCode(ComCodeEnum.category_code_user);
            SysFile saveFile=fileService.saveOrUpdateFile(sysFile,file);
            if(saveFile!=null&&!StringUtils.isEmpty(saveFile.getSaveName())){
                user.setField1(saveFile.getSaveName());
            }
            userService.updateById(user);
        }
        return ResultUtil.successData(user);
    }
    /*用户注册*/
    @RequestMapping("/register")
    @ResponseBody
    public ResponseBean registerUser(SysUser user, MultipartFile file,HttpSession session){

        if(user == null){
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        String name = user.getName();
        if (StringUtils.isEmpty(name)){
            return ResultUtil.error("姓名为空");
        }
        if (StringUtils.isEmpty(user.getCode())){
                return  ResultUtil.error("上传文件为空!");
            }
            for(int i=1;i<rows;i++){
                XSSFRow row = sheet.getRow(i);
                String name = ToolsUtils.getValFromCell(row.getCell(0));//用户名称
                String code = ToolsUtils.getValFromCell(row.getCell(1));//登录账号
                String mobile = ToolsUtils.getValFromCell(row.getCell(2));//手机号
                String password = ToolsUtils.getValFromCell(row.getCell(3));//密码
                String email = ToolsUtils.getValFromCell(row.getCell(4));//邮箱
                String sex = ToolsUtils.getValFromCell(row.getCell(5)).equals("男")?"0":"1";//性别
                if(!RegexUtil.checkEmail(email)||!RegexUtil.checkMobile(mobile)){
                    logger.debug("邮箱{}或手机号{}不合法,本条不插入",email,mobile);
                    continue;
                }
                String type = ToolsUtils.getValFromCell(row.getCell(6));//0 管理员 ;1 学生 ; 2 教师;3 官微如共青团账号
                switch (type){
                    case "学生":type="1";break;
                    case "教师":type="2";break;
                    case "官微":type="3";break;
                    default:type="1";break;
                }
                QueryWrapper<SysUser> queryWrapper=new QueryWrapper();
                queryWrapper.eq("code",code).or().eq("mobile",mobile);
                List<SysUser> list = userService.list(queryWrapper);
                if(!ToolsUtils.isEmpty(list)){
                    logger.debug("当前账号或密码已经存在,即将跳过!");
                    continue;
                }
                SysUser user=new SysUser();
                user.setCode(code);
                user.setName(name);
                user.setMobile(mobile);
                user.setEmail(email);
                user.setPassword(MD5Util.md5(password,md5Key));
                user.setSex(sex);
                user.setType(Integer.parseInt(type));
                userService.save(user);
            }
            return ResultUtil.success("导入成功!");

        } catch (IOException e) {
            logger.error(e.getMessage(),e);
        }
        return ResultUtil.error();
    }

    //用户添加
    @RequestMapping("add")
    @ResponseBody
    public ResponseBean addUser(SysUser user, MultipartFile file,Model model){
            char c = fieldName.charAt(i);
            //65-90是大写A到大写Z 97到122是小写a到小写z。
            if(i!=0&&i!=fieldName.length()-1&&c>=65&&c<=90){
                //说明是大写且非首末字母则需要转驼峰
                char lowerCase = Character.toLowerCase(c);
                stringBuffer.append("_").append(lowerCase);
            }else{
                stringBuffer.append(c);
            }
        }
        return stringBuffer.toString();
    }

    //对象转map且字段转换为下划线格式
    public static Map<String,Object> convertObjToMap(Object obj){
        if(obj == null){
            return Collections.emptyMap();
        }
        Map<String, Object> map = new HashMap<>();

        List excludeFields=new ArrayList();
        excludeFields.add("serialVersionUID");
       //只取属性字段
       for (Field declaredField : obj.getClass().getDeclaredFields()) {
            try {
                declaredField.setAccessible(true);
                String fieldName = declaredField.getName();
                if(!excludeFields.contains(fieldName)){
                    map.put(camelToUnderline(fieldName), declaredField.get(obj));
                }
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage(),e);
            }
        }
//        //只取含有get方法的
//        List<String> listName = new ArrayList<>();
//        for (Field declaredField : obj.getClass().getDeclaredFields()) {
//            listName.add(declaredField.getName());
//        }
//        for (Method declaredMethod : obj.getClass().getDeclaredMethods()) {
//            if (declaredMethod.getName().startsWith("get")) {
//                String name = (String.valueOf(declaredMethod.getName().charAt(3)).toLowerCase())+declaredMethod.getName().substring(4);
//                try {
//                    if(listName.contains(name)){
//                        map.put(name, declaredMethod.invoke(obj));
//                    }
//                } catch (IllegalAccessException e) {
//                    e.printStackTrace();
//                } catch (InvocationTargetException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
        return map;

/**
 * <p>
 * 新闻分类表 前端控制器
 * </p>
 *
 */
@Controller
@RequestMapping({"/category","/home/category"})
public class NewsCategoryController {

    private static  final Logger logger= LoggerFactory.getLogger(NewsCategoryController.class);

    private static final String page_prefix="news/category/";

    @Autowired
    SysNewsService newsService;

    @Autowired
    NewsCategoryService categoryService;

    /**

/**
 * <p>
 * 新闻表 前端控制器
 * </p>
 *
 */
@Controller
@RequestMapping({"/news","/home/news"})
public class SysNewsController {

    private static  final Logger logger= LoggerFactory.getLogger(SysNewsController.class);
    
    @Autowired
    SysNewsService newsService;

    @Autowired
    CheckNewsService checkNewsService;

    @Autowired
    NewsCategoryService newsCategoryService;
     * 分页列表查询
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param queryParam 查询参数
     * @param vagueParam 模糊参数
     * @return
     */
    @RequestMapping("/list/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean getList(@PathVariable Integer pageNum, @PathVariable Integer pageSize,
                                SysUser queryParam, String vagueParam, HttpSession session) {
        SysUser loginUser = ToolsUtils.getLoginUser(session);
        QueryWrapper<SysUser> queryWrapper=new QueryWrapper<>();
        if(loginUser.getType()!=0){
            //非管理员则只查看自己的用户信息
            queryWrapper.eq("type",loginUser.getType());
        }

        logger.debug("查询用户列表参数:"+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        queryWrapper.eq(!StringUtils.isEmpty(queryParam.getCode()),"code",queryParam.getCode());
        queryWrapper.and(e->e.like("name",vagueParam).or().like("mobile",vagueParam));
        IPage<SysUser> indexPage = new Page<>(pageNum, pageSize);
        IPage<SysUser> page = userService.page(indexPage, queryWrapper);
        logger.debug("获取的用户列表:"+page);
        //获取分页信息
        Map<String, Object> pageInfo = new HashMap<String, Object>();
        pageInfo.put("pageSize", page.getSize());
        pageInfo.put("pageNum", page.getCurrent());
        pageInfo.put("pages", page.getPages());
        pageInfo.put("total", page.getTotal());
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("userList", page.getRecords());
        resultMap.put("pageInfo", pageInfo);
        return new ResponseBean<Map<String, Object>>(true, resultMap, CommonEnum.SUCCESS_REQUEST);
    }

    //修改用户状态
    @RequestMapping("updateState")
    @ResponseBody
    public ResponseBean updateState(Long id,Integer state){
        SysUser user = userService.getById(id);
        user.setState(state);
        userService.updateById(user);
        return ResultUtil.successData(user);
    }

    //批量删除用户
    @RequestMapping("deleteBatchByIds")
    @ResponseBody
    public ResponseBean deleteBatchByIds(@RequestParam List<Integer> idList){
        queryWrapper.like("code",code).like("name",name);
        List<NewsCategory> list = categoryService.list(queryWrapper);
        if(!ToolsUtils.isEmpty(list)){
            return ResultUtil.error("名称或编码已经存在!");
        }
        boolean i = categoryService.save(category);
        logger.debug("保存后的NewsCategory:"+category);
        return ResultUtil.successData(category);
    }

    /**
     * 跳转到修改页面
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("/editPage/{id}")
    public String editPage(@PathVariable Long id, Model model) {
        model.addAttribute("category", categoryService.getById(id));
        return page_prefix+"edit";
    }

    /**
     * 新闻分类修改
     * @param category
     * @return
     */
    @RequestMapping("/edit")
    @ResponseBody
    public ResponseBean updateById(NewsCategory category,HttpSession session) {
        if (category == null||category.getId()==null) {
            return ResultUtil.error(CommonEnum.BAD_PARAM);
        }
        String name = category.getName();
        String code = category.getCode();
        QueryWrapper<NewsCategory> queryWrapper=new QueryWrapper<>();
        queryWrapper.like("code",code).like("name",name).ne("id",category.getId());
        List<NewsCategory> list = categoryService.list(queryWrapper);
        if(!ToolsUtils.isEmpty(list)){
        //将loginUser的Id 设置为comment的userId
        comment.setUserId(loginUser.getId());
        comment.setUserName(loginUser.getName());
        comment.setField1(loginUser.getField1());
        Long newsId = comment.getNewsId();
        SysNews news = newsService.getById(newsId);
        comment.setNewsTitle(news==null?"已经被删除":news.getTitle());
        boolean save = commentService.save(comment);
        return save?ResultUtil.successData(comment):ResultUtil.error();
    }
    /**
     * 新闻评论列表查询
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param queryParam 查询参数
     * @param vagueParam 模糊参数
     * @return
     */
    @ApiOperation("获取新闻评论列表")
    @RequestMapping("/list/{pageNum}/{pageSize}")
    @ResponseBody
    public ResponseBean getList(@PathVariable Integer pageNum,@PathVariable Integer pageSize,
                                NewsComment queryParam,String vagueParam) {
        logger.debug("查询新闻评论列表参数:"+queryParam+",pageNum:"+pageNum+",pageSize:"+pageSize);
        //sql  where
        QueryWrapper<NewsComment> queryWrapper=new QueryWrapper<>();
        String newsTitle = queryParam.getNewsTitle();
        String content = queryParam.getContent();
        String userName = queryParam.getUserName();
        //where news_title like '%'+newsTitle+'%'
        queryWrapper.like(!StringUtils.isEmpty(newsTitle),"news_title",newsTitle)
                .like(!StringUtils.isEmpty(content),"content",content)
                .like(!StringUtils.isEmpty(userName),"user_name",userName);
        Long newsId = queryParam.getNewsId();
        //equals ==
        queryWrapper.eq(newsId!=null,"news_id",newsId);
        // order by id desc
        queryWrapper.orderByDesc("id");
        IPage<NewsComment> indexPage = new Page<>(pageNum, pageSize);
        //分页查询
        IPage<NewsComment> listPage = commentService.page(indexPage, queryWrapper);
        logger.debug("获取的新闻评论列表:"+listPage);
    }

    @RequestMapping("addPage")
    public String addPage(Model model){
        return "file/add";
    }

    @RequestMapping("add")
    @ResponseBody
    public ResponseBean addAssociation(SysFile sysFile, HttpServletRequest request, @RequestParam("file") MultipartFile[] files){
        logger.debug("sysFile:"+sysFile);
        if(sysFile==null){
            return ResultUtil.error(CommonEnum.BAD_REQUEST);
        }
        if(files==null||files.length<1){
            return ResultUtil.error("请上传文件!");
        }

        Long userId = ToolsUtils.getLoginUserId(request.getSession());
        String userName = ToolsUtils.getLoginUserName(request.getSession());
        sysFile.setObjectId(userId);
        sysFile.setField5(userName);
        for(MultipartFile file:files){
            SysFile saveOnly = fileService.saveOnly(sysFile,file);
            logger.debug("文件上传结果:{}",saveOnly);
        }
        return ResultUtil.success();
    }

    /**
     * 跳转列表页面
     * @return
     */
    @RequestMapping("/listPage")
    public String listPage() {
        return "file/list";
    }

    @RequestMapping("deleteById")
    @ResponseBody
    public ResponseBean deleteById(@RequestParam Long id){
        logger.debug("deleteById:"+id);
        if(id==null||id<0){
		
		String start = this.request.getParameter( "start" );
		
		try {
			return Integer.parseInt( start );
		} catch ( Exception e ) {
			return 0;
		}
		
	}
	
	/**
	 * callback参数验证
	 */
	public boolean validCallbackName ( String name ) {
		
		if ( name.matches( "^[a-zA-Z_]+[\\w0-9_]*$" ) ) {
			return true;
		}
		
		return false;
		
	}
	
}

public class ActionEnter {
	
	private HttpServletRequest request = null;
	
	private String rootPath = null;
	private String contextPath = null;
	
	private String actionType = null;
	
	private ConfigManager configManager = null;

        else
        {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

@Controller
@RequestMapping("/common/plugs/ueditor/jsp")
public class UeditorController {

    private static  final Logger logger= LoggerFactory.getLogger(UeditorController.class);
    /**
     * 读取配置的请求
     * @param request
     * @param response
     */

    @Value("${com.cgx.configjson.baseFilePath}")
    private String configJsonPath;

    @RequestMapping("/controller")
    @ResponseBody
    public void getConfigInfo(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("application/json");
        logger.debug("配置文件配置的configJsonPath:"+configJsonPath);
        String requestURL = request.getRequestURL().toString();
        logger.debug("requestURL:"+requestURL);
        logger.debug("RequestURI:"+request.getRequestURI());

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值