介绍

这是一个工具类小程序,由我个人开发,其主要功能就是帮助用户去除视频的水印(这里的水印是现在一些热门平台如dy、ks、xhs等下载视频和图片上的平台作者水印)。

小程序通过微信接口wxLogin中返回的openId作为识别用户的标志,从而建立用户的后台管理,实现对用户日使用次数的调整、用户的使用情况的数据收集。

小程序端和后端通过jwt生成的token进行接口验证和用户信息传递。

小程序可开通微信流量主,后台管理系统可设置是否开启广告和banner广告、激励视频广告、插屏广告、视频广告的adId设置。

小程序去水印功能可通过本地去水印功能或者第三方接口实现。(注:本地去水印功能是通过python爬虫实现的)

小程序配置通告功能,可在后台管理系统对通告进行增删改查操作。

后端一些接口使用Redis进行数据缓存,减少对数据库的压力和第三方接口使用次数的浪费。

后台管理系统现实现功能有:每日数据的统计和图标展示、用户管理(数据库)、每日用量管理(redis)、解析记录、新增download域名、系统参数设置、通告设置。

项目已经全部开源到我的Gitee,可自行下载:llgululu去水印: 前端技术:uniapp、uView。后端技术:Java、SpringBoot、MybatisPlus、Redis、Mysql。这是一个工具类小程序,由我个人开发,其主要功能就是帮助用户去除视频的水印(这里的水印是现在一些热门平台如dy、ks、xhs等下载视频和图片上的平台作者水印)。

软件架构

小程序端由uniapp+uview进行构建。

后端使用springboot+mybatisPlus+redis+mysql。

后台管理系统使用layui+thymeleaf构建页面,使用echarts实现数据图像化,利用媒体查询适配移动端,使用ajax进行前后端数据交互。

安装教程

removeMaskWx 是小程序前端目录,removeMask 是后端及后台管理系统目录。先运行removemask.sql文件,建立数据库,本地也要有redis服务。removeMask目录下,修改yml文件中的mysql和redis的名称、密码。本地去水印功能只支持抖音,如果要使用第三方接口,请自行开通并在yal文件上配置。resource文件夹下python文件夹里面的两个python文件里面的cookie设置为你自己的cookie,然后修改util文件夹下HomeAnalysisUtil.java文件中的两个python文件的地址(如果使用第三方接口可忽略)。启动springboot服务,浏览器输入 域名:8004/login/admin/login(本地运行则为 localhost:8004/login/admin/login) ,进入后台管理系统,输入账号密码,默认都为admin,进入页面系统设置下的参数设置,修改后台登录的账号和密码(管理员账号设置),修改系统设置里面的AppId和AppSecret为你小程序的,如果你的小程序没有开通流量主就不用开启广告,如果开通了流量主,请先填写每种广告对应的adId再开启。(这里后台就配置好了)removeMaskWx 目录用HbulidX打开,修改common.js文件里面的baseURL为你的域名(本地则为localhost:8004)。再修改manifest.json文件微信配置下的appid为你小程序的appid。然后点击发行到微信小程序,进入微信小程序查看前后端是否交互成功即可。

页面展示

小程序页面展示

后台管理页面展示

部分代码展示

微信小程序实现用户登录认证

package com.llgululu.app.controller;

import com.llgululu.app.entity.Admin;

import com.llgululu.app.entity.Setting;

import com.llgululu.app.entity.Total;

import com.llgululu.app.entity.Userinfo;

import com.llgululu.app.service.*;

import com.llgululu.app.util.R;

import com.llgululu.app.util.RedisUtil;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.MediaType;

import org.springframework.http.ResponseEntity;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import static com.llgululu.app.util.JWTUtil.createJwt;

import static com.llgululu.app.util.RestTemplateUtil.getUserOpenID;

/**

*

* 前端控制器

*

*

* @author llgululu

* @since 2023-08-27

*/

@RestController

@CrossOrigin //允许跨域请求

@RequestMapping("/login")

public class LoginController {

private final ISettingService iSettingService;

private final IRecordService iRecordService;

private final IUserinfoService iUserinfoService;

private final IAdminService iAdminService;

private final RedisUtil redisUtil;

private final ITotalService iTotalService;

public LoginController(ISettingService iSettingService, IRecordService iRecordService, IUserinfoService iUserinfoService, IAdminService iAdminService, RedisUtil redisUtil, ITotalService iTotalService) {

this.iSettingService = iSettingService;

this.iRecordService = iRecordService;

this.iUserinfoService = iUserinfoService;

this.iAdminService = iAdminService;

this.redisUtil = redisUtil;

this.iTotalService = iTotalService;

}

@RequestMapping(value = "/user/login")

@ResponseBody

public ResponseEntity userLogin(@RequestParam(value = "code") String code) {

HttpHeaders headers = new HttpHeaders();

Map map = new HashMap<>();

Map sysMap = new HashMap<>();

headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

Setting setting;

if (redisUtil.hasKey("sys_setting")) {

sysMap = redisUtil.hmget("sys_setting");

setting = (Setting) sysMap.get("setting");

} else {

setting = iSettingService.getById(1);

sysMap.put("setting", setting);

redisUtil.hmset("sys_setting", sysMap, 60 * 60);

}

String openid = getUserOpenID(setting.getSeAppId(), setting.getSeAppSecret(), code);

if (openid == null) {

return new ResponseEntity<>(R.error(400, "code错误!"), headers, HttpStatus.BAD_REQUEST);

}

Userinfo user = iUserinfoService.checkUserIsExist(openid, setting.getSeUserDailyCount());

String token = createJwt(user);

redisUtil.checkUserIsExist(user);

map.put("token", token);

return new ResponseEntity<>(R.ok("登录成功", map), headers, HttpStatus.OK);

}

@Scheduled(cron = "0 10 3 * * *")

public void dailyJob() {

int totalRecords = (int) iRecordService.count();

int totalUsers = (int) iUserinfoService.count();

Total total = new Total();

total.settTotalUse(totalRecords);

total.settUser(totalUsers);

long date = new Date().getTime();

total.settTime(new Date(date - 24 * 60 * 60 * 1000));

iTotalService.save(total);

List list = iUserinfoService.list();

redisUtil.setUserInfoMap(list);

}

@RequestMapping(value = "/admin/login", produces = "text/html; charset=UTF-8")

public ModelAndView login(ModelAndView model) {

model.setViewName("login");

return model;

}

@RequestMapping(value = "/admin/checkLogin")

@ResponseBody

public ResponseEntity adminCheckLogin(HttpServletRequest request, @RequestParam(value = "adminName") String adminName, @RequestParam(value = "password") String password) {

HttpHeaders headers = new HttpHeaders();

headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

Admin admin = iAdminService.checkAdminLogin(adminName, password);

if (admin == null) {

return new ResponseEntity<>(R.ok(1002, "账号密码错误!"), headers, HttpStatus.OK);

} else {

request.getSession().setAttribute("sysadmin", admin);

return new ResponseEntity<>(R.ok(1001, "登录成功"), headers, HttpStatus.OK);

}

}

}

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: 

发表评论

返回顶部暗黑模式