Uni-app前端开发|基于微信小程序的快递运输管理系统

简介: Uni-app前端开发|基于微信小程序的快递运输管理系统

项目编号:BS-XCX-018

一,环境介绍

语言环境:Java:  jdk1.8

数据库:Mysql: mysql5.7

应用服务器:Tomcat:  tomcat8.5.31

开发工具:IDEA或eclipse

后台开发技术:SSM框架  

前台开发技术:uni-app+微信小程序+vue

二,项目简介

2.1 基本介绍

电子商务的快速发展,也带动了中国快递和物流行业的繁荣,网上购物,领取快递,似乎己经成为人们日常的一份小快乐。关于快递信息的管理,市场上业己出现很多的快递公司自建的软件和平台系统,比如支付宝就可以是询基于菜鸟网络物流配的快递信息,但是不通过菜鸟网络的快递包裹则无法查询。同样,像申通快递、顺风快递等快递公司的快递信息也是闭环查询的。如果一个客户购买了通过不同快递平台投递的快递,需要登陆多个平台来进行查看快递的配送信息等,是十分不便的。本课题要研究的基于微信小程序的快递运输管理系统,就是要解决这个问题。

   经过调研实现的这套基于微信小程序开发的快递运输管理系统,主要基于微信小程序这种轻量级的客户端应用,来实现信息的查询和管理,消费者可以注册登陆微信小程序平台,完成在信息查询,快递信息查询,配送信息查询等,快递配送员登陆可以完成对快递信息的配送,查询等操作,同时后台管理员登陆可以对整个快递平台的信息进行相应的管理操作。

   本课题研发的快递运输管理系统,在技术选择上,前端使用微信小程序开发工具来进行实现,并结合VUE框架,使用Nodejs来运行后台管理的前端工程,后台服务接口使用SSM框架集成开发实现,数据库使用MYSQL5.7数据库来进行数据存储和数据关系设计。整个系统采用前后端分离的方式来进行开发实现,人机交互符合人们日常使用习惯。

2.2 需求分析

基于对快递站的走访调查,以及对经常网购的用户的调查分析,得知本系统的用户角色分为三类,分别为普通用户,配送员和系统管理员。下面介绍一下这个用户的功能操作。

普通用户的主要功能操作用例如下图所示:

图3-1 普通用户用例图

普通用户主要拥有的功能为在线注册登陆,平台公告信息查询,个人快递信息查看,配送信息查看,个人中心管理等。

配送员用户的功能实现用例图如下图3-2所示。

图3-2 配送员用例图

配送员注册登陆微信小程序前端,可以在线浏览公告信息,查看需要配送的快递进行接取,线下配送完成后修改配送状态待客户确认即可。

平台管理员的功能用例图如下图3-3所示。

图3-3 管理员用例图

快递运输管理系统的平台管理员,登陆系统后可以实现对前端注册的用户、配送员信息进行管理,同时可以管理前端发布的轮播图片信息和自己的个人信息。在用户管理模块中可以添加此用户所拥有的快递信息,添加后微信小程序端用户和快递员均可以查看到,同时管理员可以在快递信息管理模块来管理添加的快递信息,在配送信息管理模块管理已经被快递员接取的快递信息,在配送快递模块管理被配送的快递,在确认完成管理模块管理己完成的快递信息。

2.3 数据库设计

根据以上的数据库实体信息的抽取和描述,分析出具体的表结构信息,如果使用专业的UML工具来进行设计,可以根据实体图直接生成具体的表结构,下面展示一下系统的主要表结构信息。

(1)用户信息表:主要存储微信小程序前端注册的用户信息,具体表结构信息如下表3-1所示:

表3-1 用户表(yonghu)

列名

数据类型

说明

允许空

Id

Int

主键

addtime

Date

创建时间

yonghuzhanghao

String

用户账号

mima

String

密码

yonghuxingming

String

用户姓名

xingbie

String

性别

nianling

String

年龄

touxiang

String

头像

yonghushouji

String

用户手机

(2)配送员信息表:主要存储微信小程序前端注册的配送员信息,具体表结构信息如下表3-2所示:

3-2 配送员表(peisongyuan)

列名

数据类型

说明

允许空

Id

Int

主键

addtime

Date

创建时间

peisongzhanghao

String

配送账号

mima

String

密码

peisongyuan

String

配送员

xingbie

String

性别

touxiang

String

头像

peisongyuanshouji

String

配送员手机

shenfenzheng

String

身份证

(3)管理员信息表:主要存储快递运输管理系统的管理员信息,具体表结构信息如下表3-3所示:

表3-3 管理员(users)

列名

数据类型

说明

允许空

Id

Int

主键

username

String

用户名

password

String

密码

role

String

角色

addtime

Date

新增时间

(4)公告信息表:主要存储快递运输管理系统发布的公告信息,具体表结构信息如下表3-4所示:

3-4 平台公告表(news

列名

数据类型

说明

允许空

Id

Int

主键

addtime

Date

创建时间

title

String

标题

introduction

String

简介

picture

String

图片

content

String

内容

(5)快递信息表:主要存储快递运输管理系统添加的用户快递信息,具体表结构信息如下表3-5所示:

表3-5 快递信息表(kuaidixinxi)

列名

数据类型

说明

允许空

Id

Int

主键

addtime

Date

创建时间

kuaididanhao

String

快递单号

kuaidimingcheng

String

快递名称

tupian

String

图片

wuliu

String

物流

yonghuzhanghao

String

用户账号

yonghuxingming

String

用户姓名

yonghushouji

String

用户手机

fahuodi

String

发货地

kuaidiweizhi

String

快递位置

gengxinshijian

datetime

更新时间

userid

Integer

用户id

(6)快递配送信息表:主要存储快递运输管理系统添加的用户快递配送信息,具体表结构信息如下表3-6所示:

表3-6 配送信息表(peisongxinxi)

列名

数据类型

说明

允许空

Id

Int

主键

addtime

Date

创建时间

kuaididanhao

String

快递单号

kuaidimingcheng

String

快递名称

tupian

String

图片

yonghuzhanghao

String

用户账号

yonghuxingming

String

用户姓名

yonghushouji

String

用户手机

kuaidiweizhi

String

快递位置

zhidingweizhi

String

指定位置

peisongfei

String

配送费

jiequshijian

datetime

接取时间

peisongzhanghao

String

配送账号

peisongyuan

String

配送员

peisongyuanshouji

String

配送员手机

peisongwuliu

String

配送物流

dingdanzhuangtai

String

订单状态

userid

Integer

用户id

(7)轮播图信息表:主要存储快递运输管理系统发布的轮播图片信息,具体表结构信息如下表3-7所示:

表3-7 轮播图信息表(config)

列名

数据类型

说明

允许空

Id

Int

主键

name

String

配置参数名称

value

String

配置参数值

三,系统展示

用户注册

用户登录

系统公告

快递查询

快递配送

个人中心

后台管理模块

用户管理

配送员管理

快递信息管理

快递配送管理

配送完成管理

公告管理

轮播图管理

四,核心代码展示

package com.controller;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;
import com.annotation.IgnoreAuth;
import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.service.CommonService;
import com.service.ConfigService;
import com.utils.BaiduUtil;
import com.utils.FileUtil;
import com.utils.R;
/**
 * 通用接口
 */
@RestController
public class CommonController{
  @Autowired
  private CommonService commonService;
    private static AipFace client = null;
    @Autowired
    private ConfigService configService;
  /**
   * 获取table表中的column列表(联动接口)
   * @param table
   * @param column
   * @return
   */
  @IgnoreAuth
  @RequestMapping("/option/{tableName}/{columnName}")
  public R getOption(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName,String level,String parent) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("table", tableName);
    params.put("column", columnName);
    if(StringUtils.isNotBlank(level)) {
      params.put("level", level);
    }
    if(StringUtils.isNotBlank(parent)) {
      params.put("parent", parent);
    }
    List<String> data = commonService.getOption(params);
    return R.ok().put("data", data);
  }
  /**
   * 根据table中的column获取单条记录
   * @param table
   * @param column
   * @return
   */
  @IgnoreAuth
  @RequestMapping("/follow/{tableName}/{columnName}")
  public R getFollowByOption(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName, @RequestParam String columnValue) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("table", tableName);
    params.put("column", columnName);
    params.put("columnValue", columnValue);
    Map<String, Object> result = commonService.getFollowByOption(params);
    return R.ok().put("data", result);
  }
  /**
   * 修改table表的sfsh状态
   * @param table
   * @param map
   * @return
   */
  @RequestMapping("/sh/{tableName}")
  public R sh(@PathVariable("tableName") String tableName, @RequestBody Map<String, Object> map) {
    map.put("table", tableName);
    commonService.sh(map);
    return R.ok();
  }
  /**
   * 获取需要提醒的记录数
   * @param tableName
   * @param columnName
   * @param type 1:数字 2:日期
   * @param map
   * @return
   */
  @IgnoreAuth
  @RequestMapping("/remind/{tableName}/{columnName}/{type}")
  public R remindCount(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName, 
             @PathVariable("type") String type,@RequestParam Map<String, Object> map) {
    map.put("table", tableName);
    map.put("column", columnName);
    map.put("type", type);
    if(type.equals("2")) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      Calendar c = Calendar.getInstance();
      Date remindStartDate = null;
      Date remindEndDate = null;
      if(map.get("remindstart")!=null) {
        Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
        c.setTime(new Date()); 
        c.add(Calendar.DAY_OF_MONTH,remindStart);
        remindStartDate = c.getTime();
        map.put("remindstart", sdf.format(remindStartDate));
      }
      if(map.get("remindend")!=null) {
        Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
        c.setTime(new Date());
        c.add(Calendar.DAY_OF_MONTH,remindEnd);
        remindEndDate = c.getTime();
        map.put("remindend", sdf.format(remindEndDate));
      }
    }
    int count = commonService.remindCount(map);
    return R.ok().put("count", count);
  }
  /**
   * 单列求和
   */
  @IgnoreAuth
  @RequestMapping("/cal/{tableName}/{columnName}")
  public R cal(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("table", tableName);
    params.put("column", columnName);
    Map<String, Object> result = commonService.selectCal(params);
    return R.ok().put("data", result);
  }
  /**
   * 分组统计
   */
  @IgnoreAuth
  @RequestMapping("/group/{tableName}/{columnName}")
  public R group(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("table", tableName);
    params.put("column", columnName);
    List<Map<String, Object>> result = commonService.selectGroup(params);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    for(Map<String, Object> m : result) {
      for(String k : m.keySet()) {
        if(m.get(k) instanceof Date) {
          m.put(k, sdf.format((Date)m.get(k)));
        }
      }
    }
    return R.ok().put("data", result);
  }
  /**
   * (按值统计)
   */
  @IgnoreAuth
  @RequestMapping("/value/{tableName}/{xColumnName}/{yColumnName}")
  public R value(@PathVariable("tableName") String tableName, @PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("table", tableName);
    params.put("xColumn", xColumnName);
    params.put("yColumn", yColumnName);
    List<Map<String, Object>> result = commonService.selectValue(params);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    for(Map<String, Object> m : result) {
      for(String k : m.keySet()) {
        if(m.get(k) instanceof Date) {
          m.put(k, sdf.format((Date)m.get(k)));
        }
      }
    }
    return R.ok().put("data", result);
  }
  /**
   * (按值统计)时间统计类型
   */
  @IgnoreAuth
  @RequestMapping("/value/{tableName}/{xColumnName}/{yColumnName}/{timeStatType}")
  public R valueDay(@PathVariable("tableName") String tableName, @PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName, @PathVariable("timeStatType") String timeStatType) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("table", tableName);
    params.put("xColumn", xColumnName);
    params.put("yColumn", yColumnName);
    params.put("timeStatType", timeStatType);
    List<Map<String, Object>> result = commonService.selectTimeStatValue(params);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    for(Map<String, Object> m : result) {
      for(String k : m.keySet()) {
        if(m.get(k) instanceof Date) {
          m.put(k, sdf.format((Date)m.get(k)));
        }
      }
    }
    return R.ok().put("data", result);
  }
    /**
     * 人脸比对
     * 
     * @param face1 人脸1
     * @param face2 人脸2
     * @return
     */
    @RequestMapping("/matchFace")
    @IgnoreAuth
    public R matchFace(String face1, String face2,HttpServletRequest request) {
        if(client==null) {
            /*String AppID = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "AppID")).getValue();*/
            String APIKey = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "APIKey")).getValue();
            String SecretKey = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "SecretKey")).getValue();
            String token = BaiduUtil.getAuth(APIKey, SecretKey);
            if(token==null) {
                return R.error("请在配置管理中正确配置APIKey和SecretKey");
            }
            client = new AipFace(null, APIKey, SecretKey);
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);
        }
        JSONObject res = null;
        try {
            File file1 = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+face1);
            File file2 = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+face2);
            String img1 = Base64Util.encode(FileUtil.FileToByte(file1));
            String img2 = Base64Util.encode(FileUtil.FileToByte(file2));
            MatchRequest req1 = new MatchRequest(img1, "BASE64");
            MatchRequest req2 = new MatchRequest(img2, "BASE64");
            ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
            requests.add(req1);
            requests.add(req2);
            res = client.match(requests);
            System.out.println(res.get("result"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return R.error("文件不存在");
        } catch (IOException e) {
            e.printStackTrace();
        } 
        return R.ok().put("data", com.alibaba.fastjson.JSONObject.parse(res.get("result").toString()));
    }
}
package com.controller;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.entity.EIException;
import com.service.ConfigService;
import com.utils.R;
/**
 * 上传文件映射表
 */
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{
  @Autowired
    private ConfigService configService;
  /**
   * 上传文件
   */
  @RequestMapping("/upload")
  public R upload(@RequestParam("file") MultipartFile file, String type,HttpServletRequest request) throws Exception {
    if (file.isEmpty()) {
      throw new EIException("上传文件不能为空");
    }
    String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
    String fileName = new Date().getTime()+"."+fileExt;
    File dest = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
    file.transferTo(dest);
    /**
     * 如果使用idea或者eclipse重启项目,发现之前上传的图片或者文件丢失,将下面一行代码注释打开
       * 请将以下的"D:\\ssmpiv99\\src\\main\\webapp\\upload"替换成你本地项目的upload路径,
     * 并且项目路径不能存在中文、空格等特殊字符
     */
//    FileUtils.copyFile(dest, new File("D:\\ssmpiv99\\src\\main\\webapp\\upload"+"/"+fileName)); /**修改了路径以后请将该行最前面的//注释去掉**/
    if(StringUtils.isNotBlank(type) && type.equals("1")) {
      ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
      if(configEntity==null) {
        configEntity = new ConfigEntity();
        configEntity.setName("faceFile");
        configEntity.setValue(fileName);
      } else {
        configEntity.setValue(fileName);
      }
      configService.insertOrUpdate(configEntity);
    }
    return R.ok().put("file", fileName);
  }
  /**
   * 下载文件
   */
  @IgnoreAuth
  @RequestMapping("/download")
  public void download(@RequestParam String fileName, HttpServletRequest request, HttpServletResponse response) {
    try {
      File file = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
      if (file.exists()) {
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName+"\"");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(FileUtils.readFileToByteArray(file), response.getOutputStream());
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

五,相关作品展示

基于Java开发、Python开发、PHP开发、C#开发等相关语言开发的实战项目

基于Nodejs、Vue等前端技术开发的前端实战项目

基于微信小程序和安卓APP应用开发的相关作品

基于51单片机等嵌入式物联网开发应用

基于各类算法实现的AI智能应用

基于大数据实现的各类数据管理和推荐系统

相关文章
|
缓存 JSON 前端开发
2023年最新前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,微信小程序,Webpack 汇总篇)-- 持续更新 7
2023年最新前端面试题汇总大全二(含答案超详细,Vue,TypeScript,React,微信小程序,Webpack 汇总篇)-- 持续更新
616 0
|
小程序 前端开发 算法
前端(十六)——微信小程序语音转文字,文字转语音功能的实现
前端(十六)——微信小程序语音转文字,文字转语音功能的实现
1143 0
|
移动开发 JavaScript 前端开发
前端(九)——探索微信小程序、Vue、React和Uniapp生命周期(下)
前端(九)——探索微信小程序、Vue、React和Uniapp生命周期(下)
150 0
|
JavaScript 小程序 前端开发
前端(九)——探索微信小程序、Vue、React和Uniapp生命周期(上)
前端(九)——探索微信小程序、Vue、React和Uniapp生命周期(上)
204 0
|
7月前
|
小程序 前端开发 JavaScript
微信小程序开发前端基础知识一
微信小程序开发前端基础知识一
171 0
|
7月前
|
前端开发 小程序
微信小程序开发前端基础知识二
微信小程序开发前端基础知识二
324 0
|
7月前
|
小程序 前端开发 JavaScript
前端Uni-app开发微信小程序|微信小程序手机商城
前端Uni-app开发微信小程序|微信小程序手机商城
|
7月前
|
存储 小程序 前端开发
Uni-app前端开发|基于微信小程序的快递运输管理系统
Uni-app前端开发|基于微信小程序的快递运输管理系统
|
缓存 小程序 前端开发
微信小程序前端开发
前言: 当谈到微信小程序前端开发时,我们指的是使用微信小程序框架进行开发的一种方式。在本文中,我将分享一些关于如何有效地进行微信小程序前端开发,并达到90分以上的技巧和建议。
262 0
|
前端开发 小程序 JavaScript
前端,Java,产品经理,微信小程序,Python等资源合集大放送
前端,Java,产品经理,微信小程序,Python等资源合集大放送
60 0