使用SSM实现农产品溯源系统保证食品安全

简介: 使用SSM实现农产品溯源系统保证食品安全

项目编号:BS-XX-012


运行环境:


开发工具:IDEA / ECLIPSE,同时提供有MAVEN版本和非MAVEN版本,根据需要选择


数据库:MYSQL5.7


TOMCAT:8.5.31


使用技术:


后台开发:SSM框架


前台开发:Jquery+Css+Layui框架


本系统主要定位于农产品的信息溯源工作,可以根据农产品的相关信息生成二维码,然后将二维码贴到我们的农产品包装上,购买产品的顾客可以通过手机扫描二维码获得产品的相关信息,从而实现产品的溯源。在系统的前端页面,也提供了供用户查询农产品信息的入口搜索。本系统基于SSM框架技术实现,数据库采用mysql,开发工具为IDEA。农产品溯源管理平台后台管理主要分为两个角色进入系统进行管理:一个是管理员账户,一个是企业账户。管理员账户可以添加企业,管理用户。企业用户登陆系统可以添加产品,根据产品生成二维码,并可以进行产品的信息统计操作。


系统前端功能展示如下:


展示如下:

20210521185927885.png

根据产品ID查询产品信息

image.png

后台部分功能展示如下:

管理员账户进入http://localhost/ncpsy/admin/login    admin/admin

企业管理:

image.png

用户管理:

image.png

企业用户登陆:  user /user

http://localhost/ncpsy/login

image.png

企业用户注册

image.png

农产品管理:

image.png

新增农产品:

image.png

二维码管理:

image.png

二维码中包含产品的详情信息,可以将生成的二维码打印粘贴至我们的农产品包装上,供客户扫描查看产品的溯源信息。

溯源管理:

溯源列表:数据表tb_syly 模拟相关数据即可

image.png

溯源图表:

image.png

设置企业信息:

image.png

本系统运行无误,功能完整,操作简单,适合做毕业设计使用。

核心代码实现:

package com.suzhuoke.ncpsy.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * <p>
 *  页面控制器
 * </p>
 *
 * @author znz
 * @since 2021-02-17
 */
@Controller
public class ViewsController {
  protected Logger logger = LoggerFactory.getLogger(this.getClass());
  @RequestMapping("/")
  public String index(Model model) {
    logger.info("访问index页面");
    return "index";
  }
  @RequestMapping("/index")
  public String index2(Model model) {
    logger.info("访问index页面");
    return "index";
  }
  @RequestMapping("/login")
  public String login(Model model) {
    logger.info("访问user/login页面");
    return "user/login";
  }
  @RequestMapping("/register")
  public String register(Model model) {
    logger.info("访问user/register页面");
    return "user/register";
  }
  @RequestMapping("/home")
  public String home(Model model) {
    logger.info("访问user/home页面");
    return "user/home";
  }
  @RequestMapping("/setting")
  public String setting(Model model) {
    logger.info("访问user/setting页面");
    return "user/setting";
  }
  @RequestMapping("/user/index")
  public String userIndex(Model model) {
    logger.info("访问user/index");
    return "user/index";
  }
  @RequestMapping("/product/list")
  public String productList(Model model) {
    logger.info("访问product/list页面");
    return "product/list";
  }
  @RequestMapping("/product/add")
  public String productAdd(Model model) {
    logger.info("访问product/add页面");
    return "product/add";
  }
  @RequestMapping("/product/modify")
  public String productModify(Model model) {
    logger.info("访问product/modify页面");
    return "product/modify";
  }
  @RequestMapping("/product/info")
  public String productDelete(Model model) {
    logger.info("访问product/info页面");
    return "product/info";
  }
  @RequestMapping("/qrcode/list")
  public String qrcodeList(Model model) {
    logger.info("访问qrcode/list页面");
    return "qrcode/list";
  }
  @RequestMapping("/qrcode/info")
  public String qrcodeInfo(Model model) {
    logger.info("访问qrcode/info页面");
    return "qrcode/info";
  }
  @RequestMapping("/source/list")
  public String sourceList(Model model) {
    logger.info("访问source/list页面");
    return "source/list";
  }
  @RequestMapping("/source/chart")
  public String sourceChart(Model model) {
    logger.info("访问source/chart页面");
    return "source/chart";
  }
  @RequestMapping("/admin/home")
  public String adminHome(Model model) {
    logger.info("访问admin/home页面");
    return "admin/home";
  }
  @RequestMapping("/admin/login")
  public String adminLogin(Model model) {
    logger.info("访问admin/login页面");
    return "admin/login";
  }
  @RequestMapping("/admin/setting")
  public String adminSetting(Model model) {
    logger.info("访问admin/setting页面");
    return "admin/setting";
  }
  @RequestMapping("/admin/user-list")
  public String adminUserList(Model model) {
    logger.info("访问admin/user-list页面");
    return "admin/user-list";
  }
  @RequestMapping("/admin/addAdmin")
  public String adminAdd(Model model) {
    logger.info("访问admin/addAdmin页面");
    return "admin/addAdmin";
  }
  @RequestMapping("/info/product-info")
  public String infoProductInfo(Model model) {
    logger.info("访问info/product-info页面");
    return "info/product-info";
  }
}
package com.suzhuoke.ncpsy.controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suzhuoke.ncpsy.dao.SylyMapper;
import com.suzhuoke.ncpsy.model.Ncp;
import com.suzhuoke.ncpsy.model.Syly;
import com.suzhuoke.ncpsy.model.SylyCountNcpGroupByNcpid;
import com.suzhuoke.ncpsy.service.ISylyService;
import com.suzhuoke.ncpsy.util.tool.Tool;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author znz
 * @since 2021-02-22
 */
@Controller
@RequestMapping("/handle")
public class SylyController {
  protected Logger logger = LoggerFactory.getLogger(this.getClass());
  @Autowired
  private ISylyService sylyService;
  @Autowired
  private SylyMapper sylyMapper;
  private static Tool tool = new Tool();
  /**
   * 溯源来源计数
   * @param syly
   * @param request
   * @return
   */
  @RequestMapping("/source/count")
  @ResponseBody
  public boolean sourceCount(@RequestBody Syly syly, HttpServletRequest request) {
    logger.info("/handle/source/count===> syly={}", syly);
    //查询syly总数,即溯源总数
    QueryWrapper<Syly> countQueryWrapper = new QueryWrapper<>();
    countQueryWrapper.eq("syqyid", syly.getSyqyid());
    int count = sylyService.count(countQueryWrapper) + 1;
    //获取当前日期,设置溯源时间
    Date now = new Date();
    syly.setSysj(now);
    //设置溯源id
    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    String newNo = df.format(now);
    String syid = "syly-" + newNo + "-" + count;
    syly.setSyid(syid);
    //设置溯源ip
    String syip = request.getRemoteAddr();
    syly.setSyip(syip);
    boolean flag = sylyService.save(syly);
    return flag;
  }
  /**
   * 溯源列表
   * @param syly
   * @param page
   * @param limit
   * @return
   * @throws Exception
   */
  @RequestMapping("/source/list")
  @ResponseBody
  public Map sourceList(Syly syly, @RequestParam int page, @RequestParam int limit) throws Exception {
    logger.info("/handle/source/list===> syly={}", syly);
    logger.info("page = {}", page);
    logger.info("limit = {}", limit);
    QueryWrapper<Syly> sylyQueryWrapper = new QueryWrapper<>();
    //遍历syly对象的属性
    Field field[] = syly.getClass().getDeclaredFields();
    for(int i = 0; i < field.length; i++) {
      //获取属性名
      String name = field[i].getName();
      //将属性的首字符大写,方便构造get,set方法
      String getterName = name.substring(0,1).toUpperCase()+name.substring(1);
      //获取属性的类型
      String type = field[i].getGenericType().toString();
      //根据类型做操作
      if (type.equals("class java.lang.String")) {
        //获得getter方法
        Method m = syly.getClass().getMethod("get" + getterName);
        //调用getter方法
        String value = (String) m.invoke(syly);
        //如果非空,则加入查询条件
        if (value != null) {
          sylyQueryWrapper.eq(name, value);
        }
      }
    }
    List<Syly> sylyList = sylyService.list(sylyQueryWrapper);
    logger.info("=========={}", sylyList);
    //查询到的总量,返回数据要用
    int count = sylyList.size();
    //list截取分页的索引
    int fromIndex = (page-1)*limit;
    int toIndex = page * limit;
    //截取分页数据
    if(page*limit > count) {
      toIndex = count;
    }
    sylyList = sylyList.subList(fromIndex, toIndex);
    Map response = new HashMap();
    response.put("code", 0);
    response.put("msg", "");
    response.put("count", count);
    response.put("data", sylyList);
    return response;
  }
  /**
   * 获取7天溯源数据
   * @param syly
   * @return
   */
  @RequestMapping("/source/line")
  @ResponseBody
  public Map sourceChart(@RequestBody Syly syly) {
    logger.info("/handle/source/line===> syly={}", syly);
    //groud by 溯源时间查询list
    QueryWrapper<Syly> sylyQueryWrapper = new QueryWrapper<>();
    //map对象用来储存返回数据
    Map map = new HashMap();
    //新建sysjList和counts,用于保存时间和访问数
    List<String> sysjList = new ArrayList<>();
    List<Integer> countList = new ArrayList<>();
    for(int i = 6; i >= 0; i--) {
      //获取i天前日期对象
      Date date = tool.getDateBefore(new Date(), i);
      //溯源时间转字符串
      SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
      String sysjString = df.format(date);
      //查询i天前溯源数量
      QueryWrapper<Syly> countQueryWrapper = new QueryWrapper<>();
      countQueryWrapper.eq("sysj", sysjString).eq("syqyid", syly.getSyqyid());
      int count = sylyService.count(countQueryWrapper);
      //将结果插入list
      countList.add(count);
      sysjList.add(sysjString);
    }
    map.put("sysjList", sysjList);
    map.put("counts",countList);
    return map;
  }
  /**
   * 获取溯源农产品分布数据
   * @param syly
   * @return
   */
  @RequestMapping("/source/pie")
  @ResponseBody
  public Map sourcePie(@RequestBody Syly syly) {
    logger.info("/handle/source/pie===> syly={}", syly);
    //获取溯源总数
    QueryWrapper<Syly> sylyQueryWrapper = new QueryWrapper<>();
    sylyQueryWrapper.eq("syqyid", syly.getSyqyid());
    int count = sylyService.count(sylyQueryWrapper);
    int alreadyGet = 0;
    //获取最大溯源量的4个ncp
    List<SylyCountNcpGroupByNcpid> dataList = sylyMapper.selectSylyCountNcpGroupByNcpid(syly.getSyqyid());
    //新建两个列表对象储存返回数据
    List<String> ncpmcList = new ArrayList<>();
    List<Integer> countList = new ArrayList<>();
    //插入查询到的数据到list
    for(SylyCountNcpGroupByNcpid item : dataList) {
      ncpmcList.add(item.getNcpmc());
      countList.add(item.getCount());
      alreadyGet += item.getCount();
    }
    ncpmcList.add("其他");
    countList.add(count-alreadyGet);
    Map map = new HashMap();
    map.put("ncpmcList", ncpmcList);
    map.put("countList", countList);
    return map;
  }
  /**
   * 获取总溯源数
   * @param syly
   * @return
   */
  @RequestMapping("/source/total")
  @ResponseBody
  public List<String> sourceTotal(@RequestBody Syly syly) {
    logger.info("/handle/source/total===> syly={}", syly);
    //获取溯源总数
    QueryWrapper<Syly> sylyQueryWrapper = new QueryWrapper<>();
    sylyQueryWrapper.eq("syqyid", syly.getSyqyid());
    int count = sylyService.count(sylyQueryWrapper);
    List<String> list = new ArrayList<>();
    list.add(count+"");
    return list;
  }
  /**
   * 获取当日溯源数和同比增长比例
   * @param syly
   * @return
   */
  @RequestMapping("/source/today")
  @ResponseBody
  public List<String> sourceToday(@RequestBody Syly syly) {
    logger.info("/handle/source/today===> syly={}", syly);
    //获取今天日期
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    String todayString = df.format(new Date());
    //获取昨天日期
    SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd");
    String yesterdayString = df.format(new Date(new Date().getTime()-86400000L));
    //查询今天总数
    QueryWrapper<Syly> todayQueryWrapper = new QueryWrapper<>();
    todayQueryWrapper.eq("syqyid", syly.getSyqyid()).eq("sysj", todayString);
    int todayCount = sylyService.count(todayQueryWrapper);
    //查询昨天总数
    QueryWrapper<Syly> yesterdayQueryWrapper = new QueryWrapper<>();
    yesterdayQueryWrapper.eq("syqyid", syly.getSyqyid()).eq("sysj", yesterdayString);
    int yesterdayCount = sylyService.count(yesterdayQueryWrapper);
    //算出同比增长比例
    float rise = ((float)todayCount - (float)yesterdayCount) / (float)yesterdayCount * 100;
    List<String> list = new ArrayList<>();
    list.add(todayCount+"");
    list.add(rise+"%");
    return list;
  }
  /**
   * 获取7天溯源人数和同比增长比例
   * @param syly
   * @return
   */
  @RequestMapping("/source/week")
  @ResponseBody
  public List<String> sourceWeek(@RequestBody Syly syly) {
    logger.info("/handle/source/week===> syly={}", syly);
    //获取今天和七天前的日期
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    String dateString = df.format(new Date());
    String weekBeforeString = df.format(tool.getDateBefore(new Date(), 6));
    //查询介于两个日期之间的总数
    QueryWrapper<Syly> countQueryWrapper = new QueryWrapper<>();
    countQueryWrapper.between("sysj", weekBeforeString, dateString).eq("syqyid", syly.getSyqyid());
    int count = sylyService.count(countQueryWrapper);
    //获取上一期的两个日期
    String lastDateString = df.format(tool.getDateBefore(new Date(), 7));
    String lastWeekBeforeString = df.format(tool.getDateBefore(new Date(), 13));
    //同样查询两个日期之间的总数
    QueryWrapper<Syly> lastCountQueryWrapper = new QueryWrapper<>();
    lastCountQueryWrapper.between("sysj", lastWeekBeforeString, lastDateString).eq("syqyid", syly.getSyqyid());
    int lastCount = sylyService.count(lastCountQueryWrapper);
    //通过两期数据算出同比增长比例
    float rise = ((float)count - (float)lastCount) / (float)lastCount * 100;
    //返回数据
    List<String> list = new ArrayList<>();
    list.add(count+"");
    list.add(rise+"%");
    return list;
  }
  @RequestMapping("/source/month")
  @ResponseBody
  public List<String> sourceMonth(@RequestBody Syly syly) {
    logger.info("/handle/source/month===> syly={}", syly);
    //获取今天和30天前的日期
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    String dateString = df.format(new Date());
    String monthBeforeString = df.format(tool.getDateBefore(new Date(), 29));
    //查询介于两个日期之间的总数
    QueryWrapper<Syly> countQueryWrapper = new QueryWrapper<>();
    countQueryWrapper.between("sysj", monthBeforeString, dateString).eq("syqyid", syly.getSyqyid());
    int count = sylyService.count(countQueryWrapper);
    //获取上一期的两个日期
    String lastDateString = df.format(tool.getDateBefore(new Date(), 30));
    String lastMonthBeforeString = df.format(tool.getDateBefore(new Date(), 59));
    //同样查询两个日期之间的总数
    QueryWrapper<Syly> lastCountQueryWrapper = new QueryWrapper<>();
    lastCountQueryWrapper.between("sysj", lastMonthBeforeString, lastDateString).eq("syqyid", syly.getSyqyid());
    int lastCount = sylyService.count(lastCountQueryWrapper);
    //通过两期数据算出同比增长比例
    float rise = ((float)count - (float)lastCount) / (float)lastCount * 100;
    //返回数据
    List<String> list = new ArrayList<>();
    list.add(count+"");
    list.add(rise+"%");
    return list;
  }
}
package com.suzhuoke.ncpsy.controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.suzhuoke.ncpsy.model.Cjgly;
import com.suzhuoke.ncpsy.model.Qy;
import com.suzhuoke.ncpsy.service.IQyService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author znz
 * @since 2021-02-17
 */
@Controller
@RequestMapping("/handle")
public class QyController {
  protected Logger logger = LoggerFactory.getLogger(this.getClass());
  @Autowired
  private IQyService qyService;
  /**
   * 注册
   * 
   * @param qy
   * @return
   */
  @RequestMapping("/register")
  @ResponseBody
  public boolean register(@RequestBody Qy qy) {
    logger.info("/handle/register===> Qy={}", qy);
    // 获取企业表里企业数量,+1
    QueryWrapper<Qy> queryWrapper = new QueryWrapper<>();
    int num = qyService.count(queryWrapper) + 1;
    // 拼接企业id("qy" + 0的个数 + num)
    String qyid = "qy";
    while(true) {
      if (num / 10 == 0) {
        qyid = qyid.concat("00" + num);
      } else if (num / 10 >= 1 && num / 10 < 10) {
        qyid = qyid.concat("0" + num);
      } else {
        qyid = qyid.concat("" + num);
      }
      QueryWrapper<Qy> qyQueryWrapper = new QueryWrapper<>();
      qyQueryWrapper.eq("qyid", qyid);
      int isExist = qyService.count(qyQueryWrapper);
      if(isExist > 0) {
        num += 1;
        qyid = "qy";
        continue;
      } else {
        break;
      }
    }
    // 将企业信息保存到数据库
    qy.setQyid(qyid);
    boolean flag = qyService.save(qy);
    return flag;
  }
  /**
   * 登录
   * 
   * @param qy
   * @return
   */
  @RequestMapping("/login")
  @ResponseBody
  public Qy login(@RequestBody Qy qy) {
    logger.info("/handle/login===> Qy={}", qy);
    QueryWrapper<Qy> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("zh", qy.getZh()).eq("mm", qy.getMm());
    Qy qyEntity = qyService.getOne(queryWrapper);
    return qyEntity;
  }
  @RequestMapping("/user/get")
  @ResponseBody
  public Qy get(@RequestBody Qy qy) {
    logger.info("/handle/user/get===> Qy={}", qy);
    QueryWrapper<Qy> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("qyid", qy.getQyid());
    qy = qyService.getOne(queryWrapper);
    return qy;
  }
  /**
   * 查询企业列表
   * @param page
   * @param limit
   * @return
   * @throws Exception
   */
  @RequestMapping("/user/getlist")
  @ResponseBody
  public Map qyList(@RequestParam int page, @RequestParam int limit) throws Exception {
    List<Qy> dataList = qyService.list(null);
    logger.info("=========={}", dataList);
    // 查询到的总量,返回数据要用
    int count = dataList.size();
    // list截取分页的索引
    int fromIndex = (page - 1) * limit;
    int toIndex = page * limit;
    // 截取分页数据
    if (page * limit > count) {
      toIndex = count;
    }
    dataList = dataList.subList(fromIndex, toIndex);
    Map response = new HashMap();
    response.put("code", 0);
    response.put("msg", "");
    response.put("count", count);
    response.put("data", dataList);
    return response;
  }
  /**
   * 删除企业
   * 
   * @param qy
   * @return
   */
  @RequestMapping("/user/delete")
  @ResponseBody
  public boolean qyDelete(@RequestBody Qy qy) {
    logger.info("/handle/user/delete===> Qy={}", qy);
    QueryWrapper<Qy> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("qyid", qy.getQyid());
    return qyService.remove(queryWrapper);
  }
  /**
   * 修改企业信息
   * @param qy
   * @return
   */
  @RequestMapping("/user/stqy")
  @ResponseBody
  public boolean qy_modifiy(@RequestBody Qy qy) {
    logger.info("/handle/user/stqy===> Qy={}", qy);
    QueryWrapper<Qy> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("qyid", qy.getQyid());
    return qyService.update(qy, queryWrapper);
  }
}
相关文章
|
3月前
|
Java 数据库连接 Maven
手把手教你如何搭建SSM框架、图书商城系统案例
这篇文章是关于如何搭建SSM框架以及实现一个图书商城系统的详细教程,包括了项目的配置文件整合、依赖管理、项目结构和运行效果展示,并提供了GitHub源码链接。
手把手教你如何搭建SSM框架、图书商城系统案例
|
2月前
|
Java 应用服务中间件 数据库连接
ssm项目整合,简单的用户管理系统
文章介绍了一个使用SSM框架(Spring、SpringMVC、MyBatis)构建的简单用户管理系统的整合过程,包括项目搭建、数据库配置、各层代码实现以及视图展示。
ssm项目整合,简单的用户管理系统
|
2月前
|
XML Java 数据库连接
如何搭建SSM框架、图书商城系统
这是一份详尽的《Spring + SpringMVC + Mybatis 整合指南》,作者耗时良久整理出约五万字的内容,现已经全部笔记公开。此文档详细地介绍了如何搭建与整合SSM框架,具体步骤包括创建Maven项目、添加web骨架、配置pom文件以及整合Spring、SpringMVC和Mybatis等。无论是对初学者还是有一定基础的开发者来说,都是很好的学习资源。此外,作者还提供了项目源码的GitHub链接,方便读者实践。虽然当前主流推荐学习SpringBoot,但了解SSM框架仍然是不可或缺的基础。
28 0
|
3月前
|
SQL Java 应用服务中间件
使用SSM搭建图书商城管理系统(完整过程介绍、售后服务哈哈哈)
这篇文章是关于如何使用SSM框架搭建图书商城管理系统的教程,包括完整过程介绍、常见问题解答和售后服务,提供了项目地址、运行环境配置、效果图展示以及运行代码的步骤。
使用SSM搭建图书商城管理系统(完整过程介绍、售后服务哈哈哈)
|
4月前
|
存储 关系型数据库 测试技术
基于ssm+vue的校园驿站管理系统+(源码+部署说明+演示视频+源码介绍)(2)
基于ssm+vue的校园驿站管理系统+(源码+部署说明+演示视频+源码介绍)
57 1
|
4月前
|
安全 数据挖掘 测试技术
基于SSM+Vue的家居商城系统(源码+部署说明+演示视频)(2)
基于SSM+Vue的家居商城系统(源码+部署说明+演示视频)
62 0
|
4月前
|
Java 关系型数据库 MySQL
基于SSM+Vue的家居商城系统(源码+部署说明+演示视频)(1)
基于SSM+Vue的家居商城系统(源码+部署说明+演示视频)
57 0
|
5月前
|
搜索推荐 JavaScript Java
计算机Java项目|基于SSM的个性化商铺系统
计算机Java项目|基于SSM的个性化商铺系统
|
5月前
|
前端开发 JavaScript Java
计算机Java项目|SSM智能仓储系统
计算机Java项目|SSM智能仓储系统
|
5月前
|
Java 物联网 Maven
基于SSM+layui【爱车汽车租赁管理系统】附源码+论文
基于SSM+layui【爱车汽车租赁管理系统】附源码+论文
71 1
基于SSM+layui【爱车汽车租赁管理系统】附源码+论文