springboot铜仁非遗之家76938-计算机课程设计、毕业设计

前言

✨ **博主介绍:**一线全栈工程师,毕设实战引路人。技术栈覆盖Java、Python、C#、PHP、Node.js及UniApp跨端开发,擅长多语言项目落地与架构设计。持续分享毕设源码、开题报告、技术选型心得与职场踩坑经验。用工程化思维写代码,帮你把毕设做成作品集。👍👍

👇精彩专栏 推荐订阅👇

海量实战库,源码任你选! 坐拥Java项目2000+套

海量实战库,源码任你选! 坐拥Python项目1000+套

海量实战库,源码任你选! 坐拥小程序/app项目500+套

✅获取源码请私信✅

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以找我咨询,希望帮助更多的人❤️

系统模块的实现

登录模块

微信小程序端登录模块

  用户首次进入小程序时,调用wx.login()获取临时登录凭证code,发送至后端/api/auth/wxLogin接口;后端通过微信官方接口换取openid并查询用户是否存在。若为新用户,则自动创建基础账户并返回token;若为老用户,则校验状态并返回完整用户信息。前端将token与用户数据存入本地缓存wx.setStorageSync('userInfo'),后续请求携带token进行身份认证。

后台管理系统登录模块

  管理员在登录页面输入账号与密码,点击"登录"按钮后,前端调用loginApi向后端/admin/auth/login发起POST请求。后端验证账号密码及角色权限,成功后生成JWT令牌并返回。前端将token存入Vuex与localStorage,后续所有管理接口请求均在Authorization头中携带该token,未认证或权限不足的请求将被拦截并跳转至登录页。

后台管理系统登录界面

系统用户管理模块

管理员管理

  在后台"系统用户管理"页面,管理员可查看所有注册用户列表,筛选角色为"管理员"的账户。通过操作栏的"编辑"按钮,可修改其姓名、手机号或重置密码;点击"禁用"则调用userController.disableAdmin(id)接口,将该账户状态设为无效,使其无法登录后台系统,保障权限安全。

管理员管理界面

普通用户管理

  管理员在用户管理界面选择角色为"普通用户"的条目,可执行查看详情、冻结账户或删除操作。当用户存在违规行为时,点击"冻结"按钮触发userController.freezeUser(id)请求,后端更新用户状态字段,前端同步刷新列表。被冻结用户在小程序端登录时将收到"账户已被限制"提示,无法继续使用核心功能。

普通用户管理界面

非遗项目管理模块

微信小程序端非遗项目

  用户进入"非遗项目"页面后,小程序向/api/heritage/list接口发起分页请求,获取项目缩略图、名称、类型及简介。点击任一项目卡片,跳转至详情页,加载视频、语音讲解、文化故事等富媒体内容,并显示关联传承人信息。页面底部集成点赞、收藏、分享按钮,用户交互后实时更新状态并同步至服务器。

非遗项目展示界面

非遗项目发布

  普通用户在"我的"页面点击"发布非遗项目",需先完成实名认证。进入表单页后,填写项目名称、类型、来源、详细描述,并上传视频与图片素材。提交时调用/api/heritage/submit接口,数据暂存为"待审核"状态。发布成功后提示"已提交,等待管理员审核",用户可在"我的发布"中查看审核进度。

非遗项目发布界面

管理员后台非遗项目管理

  管理员在"非遗项目管理"界面查看所有待审、已发布及驳回的项目列表。点击"审核"按钮进入详情页,可预览用户提交的全部内容。若信息真实合规,点击"通过"触发heritageController.approve(id)请求,项目状态变更为"已发布"并同步至小程序端;若资料不全或存疑,则点击"驳回"并填写原因,用户将收到通知并可重新编辑提交。

管理员审核非遗项目界面

传承人管理模块

微信小程序端传承人展示

  用户在首页或非遗项目详情页点击"传承人"标签,跳转至传承人列表页。每个传承人卡片展示姓名、技艺类别、所在地及头像。点击进入个人主页,可查看详细介绍、代表作品。

传承人展示界面

后台管理员发布传承人

  管理员在"传承人管理"页面点击"新增传承人",填写姓名、所属非遗项目、传承地址、联系电话、技艺特点及个人简介,并上传形象照。提交后调用inheritorController.createInheritor()接口,数据写入数据库并与对应非遗项目建立关联。保存成功后,该传承人信息立即在小程序端同步展示。

发布传承人界面

非遗活动管理模块

微信小程序端非遗活动

非遗活动展示

  用户进入"非遗活动"页面,系统调用/api/activity/list获取近期活动列表,按时间倒序排列。每项活动显示标题、类型、时间、地点及封面图。点击进入详情页,可查看完整介绍、参与须知及当前报名人数,页面底部提供"立即报名"按钮,引导用户完成后续流程。

非遗活动展示界面

非遗活动报名

  用户在活动详情页点击"立即报名",若未登录则先触发登录流程。登录后,小程序调用/api/activity/register接口,携带用户ID与活动ID提交报名申请。后端校验活动是否开放、名额是否充足,成功后返回报名编号,前端提示"报名成功,请留意通知",并在"我的报名"中记录该活动状态。

非遗活动报名界面

后台管理员非遗活动报名管理

  管理员在后台"活动报名管理"界面查看待处理的报名记录,列表包含用户昵称、手机号、报名时间及活动名称。点击某条记录可查看详情,确认无误后点击"审核通过"按钮,触发registrationController.approve(id)请求,更新报名状态为"已确认";若发现信息不符或超额报名,则点击"拒绝"并填写理由,用户端将同步收到审核结果通知。

审核报名活动界面

数据库参考

sql 复制代码
CREATE TABLE `message_inform` (
  `inform_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '通知ID',
  `user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '通知人ID',
  `title` varchar(255) DEFAULT NULL COMMENT '标题',
  `state` varchar(255) DEFAULT NULL COMMENT '状态',
  `type` varchar(64) DEFAULT NULL COMMENT '分类',
  `content` varchar(255) DEFAULT NULL COMMENT '内容',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`inform_id`) USING BTREE,
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='通知记录';
DROP TABLE IF EXISTS `sensitive_vocabulary`;
CREATE TABLE `sensitive_vocabulary` (
  `sensitive_vocabulary_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '敏感词汇ID',
  `sensitive_vocabulary` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '敏感词汇',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`sensitive_vocabulary_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='敏感词汇';
DROP TABLE IF EXISTS `user_group`;
CREATE TABLE `user_group` (
  `group_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户组ID',
  `display` smallint(4) unsigned NOT NULL DEFAULT '100' COMMENT '显示顺序',
  `name` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '名称',
  `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述',
  `source_table` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '来源表',
  `source_field` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '来源字段',
  `source_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '来源ID',
  `register` smallint(1) unsigned DEFAULT '0' COMMENT '注册位置',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`group_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户组';
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
  `article_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '文章id',
  `title` varchar(125) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '标题',
  `type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '文章分类',
  `hits` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点击数',
  `praise_len` int(11) NOT NULL DEFAULT '0' COMMENT '点赞数',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '来源',
  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '来源地址',
  `tag` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标签',
  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '正文',
  `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '封面图',
  `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '文章描述',
  PRIMARY KEY (`article_id`,`title`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='文章';
DROP TABLE IF EXISTS `access_token`;
CREATE TABLE `access_token` (
  `token_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '临时访问牌ID',
  `token` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '临时访问牌',
  `info` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '信息',
  `maxage` int(2) NOT NULL DEFAULT '2' COMMENT '最大寿命:默认2小时',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户编号',
  PRIMARY KEY (`token_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='登陆访问时长';
DROP TABLE IF EXISTS `code_token`;
CREATE TABLE `code_token` (
  `code_token_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '验证码ID',
  `token` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '令牌',
  `code` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL COMMENT '验证码',
  `expire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '失效时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`code_token_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='验证码';
DROP TABLE IF EXISTS `collect`;
CREATE TABLE `collect` (
  `collect_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '收藏ID',
  `user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '收藏人ID',
  `source_table` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '来源表',
  `source_field` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '来源字段',
  `source_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '来源ID',
  `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '标题',
  `img` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '封面',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`collect_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收藏';

代码参考

java 复制代码
package com.project.demo.controller;

import com.project.demo.entity.IntangibleCulturalHeritageProject;
import com.project.demo.service.IntangibleCulturalHeritageProjectService;
import com.alibaba.fastjson.JSON;
import com.project.demo.controller.base.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;


/**
 * 非遗项目:(IntangibleCulturalHeritageProject)表控制层
 *
 */
@RestController
@RequestMapping("/intangible_cultural_heritage_project")
public class IntangibleCulturalHeritageProjectController extends BaseController<IntangibleCulturalHeritageProject, IntangibleCulturalHeritageProjectService> {

    /**
     * 非遗项目对象
     */
    @Autowired
    public IntangibleCulturalHeritageProjectController(IntangibleCulturalHeritageProjectService service) {
        setService(service);
    }



    @PostMapping("/add")
    @Transactional
    public Map<String, Object> add(HttpServletRequest request) throws IOException {
        Map<String,Object> paramMap = service.readBody(request.getReader());
        paramMap.entrySet().removeIf(entry -> {
            Object value = entry.getValue();
            return value instanceof String && ((String) value).isEmpty();
        });
        IntangibleCulturalHeritageProject intangible_cultural_heritage_project = new IntangibleCulturalHeritageProject();
            intangible_cultural_heritage_project.setProject_name(paramMap.get("project_name")==null?null:String.valueOf(paramMap.get("project_name")));
                            intangible_cultural_heritage_project.setType_of_intangible_cultural_heritage(paramMap.get("type_of_intangible_cultural_heritage")==null?null:String.valueOf(paramMap.get("type_of_intangible_cultural_heritage")));
                            intangible_cultural_heritage_project.setCover_chart(paramMap.get("cover_chart")==null?null:String.valueOf(paramMap.get("cover_chart")));
                            intangible_cultural_heritage_project.setInheritance_personnel(paramMap.get("inheritance_personnel")==null?null:String.valueOf(paramMap.get("inheritance_personnel")));
                            intangible_cultural_heritage_project.setSource_of_inheritance(paramMap.get("source_of_inheritance")==null?null:String.valueOf(paramMap.get("source_of_inheritance")));
                            intangible_cultural_heritage_project.setIntangible_cultural_heritage_vuser_ideo(paramMap.get("intangible_cultural_heritage_vuser_ideo")==null?null:String.valueOf(paramMap.get("intangible_cultural_heritage_vuser_ideo")));
                            intangible_cultural_heritage_project.setIntelligent_voice(paramMap.get("intelligent_voice")==null?null:String.valueOf(paramMap.get("intelligent_voice")));
                            intangible_cultural_heritage_project.setSpecificsed_introduction(paramMap.get("specificsed_introduction")==null?null:String.valueOf(paramMap.get("specificsed_introduction")));
                            intangible_cultural_heritage_project.setCultural_story(paramMap.get("cultural_story")==null?null:String.valueOf(paramMap.get("cultural_story")));
                            intangible_cultural_heritage_project.setPublisher(paramMap.get("publisher")==null?null:Integer.valueOf(String.valueOf(paramMap.get("publisher"))));
                        intangible_cultural_heritage_project.setHits(paramMap.get("hits")==null?null:Integer.valueOf(String.valueOf(paramMap.get("hits"))));
        intangible_cultural_heritage_project.setPraise_len(paramMap.get("praise_len")==null?null:Integer.valueOf(String.valueOf(paramMap.get("praise_len"))));
        intangible_cultural_heritage_project.setCollect_len(paramMap.get("collect_len")==null?null:Integer.valueOf(String.valueOf(paramMap.get("collect_len"))));
        intangible_cultural_heritage_project.setComment_len(paramMap.get("comment_len")==null?null:Integer.valueOf(String.valueOf(paramMap.get("comment_len"))));
        intangible_cultural_heritage_project.setExamine_state(paramMap.get("examine_state")==null?null:String.valueOf(paramMap.get("examine_state")));
        intangible_cultural_heritage_project.setExamine_reply(paramMap.get("examine_reply")==null?null:String.valueOf(paramMap.get("examine_reply")));
                                            intangible_cultural_heritage_project.setCreate_by(paramMap.get("create_by")==null?null:Integer.valueOf(String.valueOf(paramMap.get("create_by"))));
        this.addEntity(intangible_cultural_heritage_project);
        System.out.println("非遗项目新增成功");
        return success(1);
    }

    @PostMapping("/set")
    @Transactional
    public Map<String, Object> set(HttpServletRequest request) throws IOException {
        Map<String,String> queryMap = service.readQuery(request);
        Map<String,String> configMap = service.readConfig(request);
        Map<String,Object> paramMap = service.readBody(request.getReader());
        paramMap.entrySet().removeIf(entry -> {
            Object value = entry.getValue();
            return value instanceof String && ((String) value).isEmpty();
        });
        IntangibleCulturalHeritageProject intangible_cultural_heritage_project = new IntangibleCulturalHeritageProject();
            intangible_cultural_heritage_project.setProject_name(paramMap.get("project_name")==null?null:String.valueOf(paramMap.get("project_name")));
                    intangible_cultural_heritage_project.setType_of_intangible_cultural_heritage(paramMap.get("type_of_intangible_cultural_heritage")==null?null:String.valueOf(paramMap.get("type_of_intangible_cultural_heritage")));
                    intangible_cultural_heritage_project.setCover_chart(paramMap.get("cover_chart")==null?null:String.valueOf(paramMap.get("cover_chart")));
                    intangible_cultural_heritage_project.setInheritance_personnel(paramMap.get("inheritance_personnel")==null?null:String.valueOf(paramMap.get("inheritance_personnel")));
                    intangible_cultural_heritage_project.setSource_of_inheritance(paramMap.get("source_of_inheritance")==null?null:String.valueOf(paramMap.get("source_of_inheritance")));
                    intangible_cultural_heritage_project.setIntangible_cultural_heritage_vuser_ideo(paramMap.get("intangible_cultural_heritage_vuser_ideo")==null?null:String.valueOf(paramMap.get("intangible_cultural_heritage_vuser_ideo")));
                    intangible_cultural_heritage_project.setIntelligent_voice(paramMap.get("intelligent_voice")==null?null:String.valueOf(paramMap.get("intelligent_voice")));
                    intangible_cultural_heritage_project.setSpecificsed_introduction(paramMap.get("specificsed_introduction")==null?null:String.valueOf(paramMap.get("specificsed_introduction")));
                    intangible_cultural_heritage_project.setCultural_story(paramMap.get("cultural_story")==null?null:String.valueOf(paramMap.get("cultural_story")));
                    intangible_cultural_heritage_project.setPublisher(paramMap.get("publisher")==null?null:Integer.valueOf(String.valueOf(paramMap.get("publisher"))));
                intangible_cultural_heritage_project.setHits(paramMap.get("hits")==null?null:Integer.valueOf(String.valueOf(paramMap.get("hits"))));
        intangible_cultural_heritage_project.setPraise_len(paramMap.get("praise_len")==null?null:Integer.valueOf(String.valueOf(paramMap.get("praise_len"))));
        intangible_cultural_heritage_project.setCollect_len(paramMap.get("collect_len")==null?null:Integer.valueOf(String.valueOf(paramMap.get("collect_len"))));
        intangible_cultural_heritage_project.setComment_len(paramMap.get("comment_len")==null?null:Integer.valueOf(String.valueOf(paramMap.get("comment_len"))));
        intangible_cultural_heritage_project.setExamine_state(paramMap.get("examine_state")==null?null:String.valueOf(paramMap.get("examine_state")));
        intangible_cultural_heritage_project.setExamine_reply(paramMap.get("examine_reply")==null?null:String.valueOf(paramMap.get("examine_reply")));
            this.setEntity(queryMap,configMap,intangible_cultural_heritage_project);
        System.out.println("非遗项目修改成功");
        return success(1);
    }
    /**
     * 协同过滤算法
     */
    @RequestMapping("/get_hits_list")
    public Map<String, Object> getHits(HttpServletRequest request) {
        Map<String,String> paramMap = service.readQuery(request);
        if (paramMap.get("user_id")==null||paramMap.get("user_id").equals("")){
			            return this.getList(request);
			        }else{
            try {
                if (paramMap.get("examine_state")!=null && !paramMap.get("examine_state").equals("")){
                    paramMap.put("examine_state", URLDecoder.decode(paramMap.get("examine_state"), "UTF-8"));
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
						//查询该用户收藏
			String hitsSource = "SELECT COUNT( collect_id ) AS hits_count, source_id FROM collect WHERE source_table = 'intangible_cultural_heritage_project' AND user_id = "+paramMap.get("user_id")+" GROUP BY source_id ORDER BY create_time desc";
						            List<Map<String,Object>> hitsSourceList = service.selectMapBaseList(hitsSource);
			            //判断是否为空,代表当前用户暂无点击数据,那么取其他用户的最常点击
            if (hitsSourceList==null || hitsSourceList.size()<=0){
								hitsSource = "SELECT COUNT( collect_id ) AS hits_count, source_id FROM collect WHERE source_table = 'intangible_cultural_heritage_project' GROUP BY source_id ORDER BY create_time desc";
								                hitsSourceList = service.selectMapBaseList(hitsSource);
				            }
						String table_name = "intangible_cultural_heritage_project";
			String table_id = "intangible_cultural_heritage_project_id";
			String type_name = "type_of_intangible_cultural_heritage";
			            //二次处理-如果依旧为空则取添加时间前12条数据
            if (hitsSourceList==null || hitsSourceList.size()<=0){
                String sql = "SELECT * FROM " + table_name;
                if (paramMap.get("examine_state")!=null && !paramMap.get("examine_state").equals("")){
                    sql = sql + " where examine_state = '"+paramMap.get("examine_state")+"'";
                }
                sql = sql + " ORDER BY create_time DESC LIMIT 0,12";
								List list = service.selectBaseList(sql);
				                Map<String, Object> map=new HashMap<>();
                map.put("list",list);
                map.put("count",list.size());
                return success(map);
            }else {
                //对用户点击量进行排序取得最大值
                double max = 0.0;
                int maxSourceId = 0;
                for (Map<String,Object> map:hitsSourceList) {
                    double hitsCount = Double.parseDouble(String.valueOf(map.get("hits_count")));
                    if (hitsCount > max){
                        max = hitsCount;
						                        maxSourceId = Integer.parseInt(String.valueOf(map.get("source_id")));
						                    }
                }
                //查询该用户点击最大值的种类
                String typeSql = "SELECT " + type_name + " FROM "  + table_name + " WHERE " + table_id + " = " + maxSourceId;
				                List<Map<String,Object>> typeList = service.selectMapBaseList(typeSql);
				                //如果为空则取添加时间前12条数据
                if (typeList==null || typeList.size()<=0){
                    String sql = "SELECT * FROM " + table_name;
                    if (paramMap.get("examine_state")!=null && !paramMap.get("examine_state").equals("")){
                        sql = sql + " where examine_state = '"+paramMap.get("examine_state")+"'";
                    }
                    sql = sql + " ORDER BY create_time DESC LIMIT 0,12";
					                    List list = service.selectBaseList(sql);
					                    Map<String, Object> map=new HashMap<>();
                    map.put("list",list);
                    map.put("count",list.size());
                    return success(map);
                }else {
                    String typeName = String.valueOf(typeList.get(0).get(type_name));
                    //查询该种类的数据
                    String sql = "SELECT * FROM "  + table_name + " WHERE " + type_name + " = '"+typeName+"'" ;
                    if (paramMap.get("examine_state")!=null && !paramMap.get("examine_state").equals("")){
                        sql = sql + " and examine_state = '"+paramMap.get("examine_state")+"' ORDER BY create_time DESC limit 0,12";
                    }else {
                        sql = sql + " ORDER BY create_time DESC limit 0,12";
                    }
					                    List resultList = service.selectBaseList(sql);
					                    //如果为空则取添加时间前12条数据
                    if (resultList==null || resultList.size()<=0){
                        sql = "SELECT * FROM " + table_name;
                        if (paramMap.get("examine_state")!=null && !paramMap.get("examine_state").equals("")){
                            sql = sql + " where examine_state = '"+paramMap.get("examine_state")+"'";
                        }
                        sql = sql + " ORDER BY create_time DESC LIMIT 0,12";
						                        List list = service.selectBaseList(sql);
						                        Map<String, Object> map=new HashMap<>();
                        map.put("list",list);
                        map.put("count",list.size());
                        return success(map);
                    }else {
                        //对结果排序-冒泡排序
                        for (int i = resultList.size() - 1; i > 0; i--) {
                            // 是否发生交换
                            boolean swapped = false;
                            for (int j = 0; j < i; j++) {
								                                IntangibleCulturalHeritageProject leftMap = (IntangibleCulturalHeritageProject) resultList.get(j);
                                IntangibleCulturalHeritageProject rightMap = (IntangibleCulturalHeritageProject) resultList.get(j + 1);
                                if (leftMap.getHits()<rightMap.getHits()){
                                    IntangibleCulturalHeritageProject temp = rightMap;
                                    rightMap = leftMap;
                                    leftMap = temp;
                                    swapped = true;
                                }
								                            }
                            if (!swapped) {
                                // 没有发生交换,则说明数组已有序,停止冒泡
                                break;
                            }
                        }
                        //判断是否有12条-如果不足则计算其他类型和用户当前点击最多的余弦相似度,依次往下取得数据
                        if (resultList.size()<12) {
                            String typeCosSql = "SELECT " + type_name + " FROM "  + table_name + " WHERE " + type_name + " <> '" + typeName + "' GROUP BY " + type_name;
							                            List<Map<String, Object>> typeCosList = service.selectMapBaseList(typeCosSql);
							                            if (typeCosList != null && typeCosList.size() > 0) {
                                for (Map<String, Object> typeCos : typeCosList) {
                                    typeCos.put("cosSim", calculateCosineSimilarity(typeName, String.valueOf(typeCos.get(type_name))));
                                }
                                //冒泡根据相似度排序
                                for (int i = typeCosList.size() - 1; i > 0; i--) {
                                    // 是否发生交换
                                    boolean swapped = false;
                                    for (int j = 0; j < i; j++) {
                                        Map<String, Object> leftMap = typeCosList.get(j);
                                        Map<String, Object> rightMap = typeCosList.get(j + 1);
                                        if (Double.parseDouble(String.valueOf(leftMap.get("cosSim" ))) < Double.parseDouble(String.valueOf(rightMap.get("cosSim" )))) {
                                            Map<String, Object> temp = rightMap;
                                            rightMap = leftMap;
                                            leftMap = temp;
                                            swapped = true;
                                        }
                                    }
                                    if (!swapped) {
                                        // 没有发生交换,则说明数组已有序,停止冒泡
                                        break;
                                    }
                                }
                                //逐条加入数据
                                for (Map<String, Object> typeCos : typeCosList) {
                                    sql = "SELECT * FROM "  + table_name + " WHERE " + type_name + " = '" + String.valueOf(typeCos.get(type_name)) + "'";
                                    if (paramMap.get("examine_state")!=null && !paramMap.get("examine_state").equals("")){
                                        sql = sql + " and examine_state = '"+paramMap.get("examine_state")+"'";
                                    }
                                    sql = sql + " ORDER BY create_time DESC LIMIT 0," + (12 - resultList.size());
									                                    List list = service.selectBaseList(sql);
									                                    if (list != null && list.size() > 0) {
                                        resultList.addAll(list);
                                    }
                                    if (resultList.size() >= 12) {
                                        break;
                                    }
                                }
                            }
                        }
                        Map<String, Object> map=new HashMap<>();
                        map.put("list",resultList);
                        map.put("count",resultList.size());
                        return success(map);
                    }
                }

            }
        }
    }

    /**
     * 计算余弦相似度
     */
    private double calculateCosineSimilarity(String text1, String text2) {
        // 将文本分词并转换为向量表示
        Map<Character, Integer> wordCount1 = getWordCount(text1);
        Map<Character, Integer> wordCount2 = getWordCount(text2);

        double dotProduct = 0.0;
        double magnitude1 = 0.0;
        double magnitude2 = 0.0;

        for (Character word : wordCount1.keySet()) {
            int count1 = wordCount1.get(word);
            int count2 = wordCount2.getOrDefault(word, 0);
            dotProduct += count1 * count2;
            magnitude1 += Math.pow(count1, 2);
        }

        for (Integer count : wordCount2.values()) {
            magnitude2 += Math.pow(count, 2);
        }

        magnitude1 = Math.sqrt(magnitude1);
        magnitude2 = Math.sqrt(magnitude2);

        if (magnitude1 == 0.0 || magnitude2 == 0.0) {
            return 0.0;
        }

        return dotProduct / (magnitude1 * magnitude2);
    }

    private static Map<Character, Integer> getWordCount(String text) {
        Map<Character, Integer> wordCount = new HashMap<>();
        for (char c : text.toCharArray()) {
            wordCount.put(c, wordCount.getOrDefault(c, 0) + 1);
        }
        return wordCount;
    }


    /**
     * 修改审核状态
     *
     * @param id          要修改的记录ID
     * @param newState    新的审核状态
     * @return 提示信息:审核成功/失败
     */
    @Transactional
    @GetMapping("/update_examine_state")
    public String updateExamineState(Long id, String newState) throws IOException {
        // 检查传入的状态是否合法
        if (!newState.equals("未审核") && !newState.equals("已通过") && !newState.equals("未通过")) {
            return "非法的审核状态";
        }

        Map<String,String> queryMap = new HashMap<>();
        queryMap.put("id",String.valueOf(id));
        // 根据ID查找记录
        IntangibleCulturalHeritageProject intangible_cultural_heritage_project = service.findOne(queryMap);

        if (intangible_cultural_heritage_project!=null) {
            // 更新审核状态
            intangible_cultural_heritage_project.setExamine_state(newState);
            this.setEntity(queryMap,new HashMap<>(),intangible_cultural_heritage_project);

            return "审核成功";
        } else {
            return "审核失败:记录不存在";
        }
    }
}
package com.project.demo.controller;

import com.alibaba.fastjson.JSON;
import com.project.demo.entity.Slides;
import com.project.demo.service.SlidesService;

import com.project.demo.controller.base.BaseController;
import org.springframework.beans.factory.annotation.Autowired;

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

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.HashMap;

/**
 * 轮播图:(Slides)表控制层
 */
@RestController
@RequestMapping("slides")
public class SlidesController extends BaseController<Slides, SlidesService> {
    /**
     * 服务对象
     */
    @Autowired
    public SlidesController(SlidesService service) {
        setService(service);
    }

    @PostMapping("/add")
    @Transactional
    public Map<String, Object> add(HttpServletRequest request) throws IOException {
        Map<String, Object> addMap = service.readBody(request.getReader());
        validateParameters(addMap);
        removeUnnecessaryFields(addMap);
        // 插入数据
        this.service.insert(addMap);
        System.out.println("轮播图新增成功");
        return success(1);
    }

    @PostMapping("/set")
    @Transactional
    public Map<String, Object> set(HttpServletRequest request) throws IOException {
        Map<String,Object> body = this.service.readBody(request.getReader());
        Slides slides = JSON.parseObject(JSON.toJSONString(body),Slides.class);
        this.service.updateEntity(service.readQuery(request), service.readConfig(request), slides);
        return success(1);
    }

    @RequestMapping(value = "/del")
    @Transactional
    public Map<String, Object> del(HttpServletRequest request) {
        // 读取查询条件
        Map<String, String> query = service.readQuery(request);
        if (query == null || query.isEmpty()) {
            throw new IllegalArgumentException("查询条件不能为空");
        }
        Map<String, String> config = service.readConfig(request);
        this.service.delete(query, config);
        return success(1);
    }

    @RequestMapping("/get_list")
    public Map<String, Object> getList(HttpServletRequest request) {
        // 读取查询条件
        Map<String, String> query = service.readQuery(request);
        Map<String, String> config = service.readConfig(request);
        Map<String,Object> map = new HashMap<>();
        List list = this.service.selectBaseList(this.service.select(query, config));
        map.put("list",list);
        map.put("count",this.service.selectBaseCount(this.service.count(query,config)));
        return success(map);
    }

    /**
     * 验证参数是否合法
     */
    private void validateParameters(Map<String, Object> addMap) {
                    if (addMap.get("title") == null) {
                throw new IllegalArgumentException("标题不能为空");
            }
            }

    /**
     * 移除不需要的字段
     */
    private void removeUnnecessaryFields(Map<String, Object> addMap) {
        addMap.remove("create_time");
        addMap.remove("update_time");
    }
}

**前端:**基于uni-app框架构建跨平台用户界面,使用HTML5、CSS3和JavaScript/Vue.js实现页面结构与交互逻辑,通过uni-app内置路由或Vue Router管理页面导航,Vuex或Pinia维护全局状态。采用uni-ui或uView等组件库快速搭建界面,使用uni.request或Axios(经适配)封装HTTP请求实现与后端的数据通信,同时可调用uni-app提供的丰富原生API(如相机、定位、支付等)增强移动端能力。

**后端:**基于Spring Boot框架搭建,遵循Controller-Service-Mapper三层架构。Controller层接收前端请求并校验参数,Service层处理核心业务逻辑,Mapper层通过MyBatis或MyBatis-Plus完成数据库操作。使用Spring Security或Shiro结合JWT实现用户认证与权限控制。

**数据库:**采用MySQL存储持久化数据,Redis缓存热点信息以提升系统性能。

开发工具: 使用HBuilderX或VSCode开发前端(uni-app),IDEA开发后端,Git进行版本管理,Maven管理后端依赖,npm或yarn管理前端依赖,并通过HBuilderX的App发布功能或命令行工具完成多端(iOS、Android、H5、各小程序)打包发布。

源码获取

私信联系我即可~

大家点赞、收藏、关注、评论啦

👇精彩专栏 推荐订阅👇

海量实战库,源码任你选! 坐拥Java项目2000+套

海量实战库,源码任你选! 坐拥Python项目1000+套

海量实战库,源码任你选! 坐拥小程序/app项目500+套

✅获取源码请私信✅

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以找我咨询,希望帮助更多的人❤️

相关推荐
顽疲1 小时前
java vue springboot 养老系统源码详解:退住 care_out 审批结算与腾床事务实践
java·vue.js·spring boot·vue养老·springboot养老·java养老
唐青枫1 小时前
薛定谔的猫详解:一只猫如何揭开量子测量之谜
后端
锋行天下1 小时前
langgraph 循环节点的静态和动态实现
前端·后端
geats人山人海1 小时前
java 7异常
android·java·开发语言
斯内普吖1 小时前
(开源)线上花店系统实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
打工仔折腾 AI1 小时前
在线PDF工具隐私焦虑?把BentoPDF部署到极空间NAS本地处理
人工智能·后端·python·pdf·ai agent 实战
duxingzhe03112 小时前
我的一些书
java·数据库·tomcat·数据库开发·etl工程师
2603_965148112 小时前
商品价格监控 API 接口:从原理到实战的完整指南
java·前端·数据库·python·生活
瑞克-桑切斯2 小时前
2、Shell 条件语句
java·linux·服务器