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智能应用

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


相关文章
|
1天前
|
小程序 数据安全/隐私保护 开发者
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
【02】微信支付商户申请下户到配置完整流程-微信开放平台申请APP应用-微信商户支付绑定appid-公众号和小程序分别申请appid-申请+配置完整流程-优雅草卓伊凡
15 3
|
25天前
|
存储 小程序 前端开发
微信小程序与Java后端实现微信授权登录功能
微信小程序极大地简化了登录注册流程。对于用户而言,仅仅需要点击授权按钮,便能够完成登录操作,无需经历繁琐的注册步骤以及输入账号密码等一系列复杂操作,这种便捷的登录方式极大地提升了用户的使用体验
233 12
|
2月前
|
存储 缓存 关系型数据库
社交软件红包技术解密(六):微信红包系统的存储层架构演进实践
微信红包本质是小额资金在用户帐户流转,有发、抢、拆三大步骤。在这个过程中对事务有高要求,所以订单最终要基于传统的RDBMS,这方面是它的强项,最终订单的存储使用互联网行业最通用的MySQL数据库。支持事务、成熟稳定,我们的团队在MySQL上有长期技术积累。但是传统数据库的扩展性有局限,需要通过架构解决。
72 18
|
2月前
|
JSON 小程序 UED
微信小程序 app.json 配置文件解析与应用
本文介绍了微信小程序中 `app.json` 配置文件的详细
197 12
|
2月前
|
存储 缓存 监控
社交软件红包技术解密(四):微信红包系统是如何应对高并发的
本文将为读者介绍微信百亿级别红包背后的高并发设计实践,内容包括微信红包系统的技术难点、解决高并发问题通常使用的方案,以及微信红包系统的所采用高并发解决方案。
86 13
|
2月前
|
存储 监控 容灾
社交软件红包技术解密(五):微信红包系统是如何实现高可用性的
本次分享介绍了微信红包后台系统的高可用实践经验,主要包括后台的 set 化设计、异步化设计、订单异地存储设计、存储层容灾设计与平行扩缩容等。听众可以了解到微信红包后台架构的设计细节,共同探讨高可用设计实践上遇到的问题与解决方案。
58 5
|
2月前
|
小程序 IDE PHP
圈子源码如何打包生成App小程序/开发一个圈子系统软件所需要的费用体现在哪里?
将PHP源码打包成App的过程涉及多个步骤和技术选择。以圈子源码为例,首先明确需求,确定App功能和目标用户群体,并根据需求开发小程序页面,如用户注册、圈子列表等。源码准备阶段确保源码适用于小程序开发,环境配置需安装IDE(如微信开发者工具)及依赖库。最后在IDE中打包小程序并上传至管理平台,通过审核后发布。费用方面,模板开发成本较低,定制开发则更高,具体取决于需求复杂度和第三方服务费用。
83 0
|
2月前
|
移动开发 小程序
thinkphp+uniapp开发的多端商城系统源码/H5/小程序/APP支持DIY模板直播分销
thinkphp+uniapp开发的多端商城系统源码/H5/小程序/APP支持DIY模板直播分销
40 0
|
3月前
|
缓存 移动开发 小程序
uni-vue3-wetrip自创跨三端(H5+小程序+App)酒店预订app系统模板
vue3-uni-wetrip原创基于vite5+vue3+uniapp+pinia2+uni-ui等技术开发的仿去哪儿/携程预约酒店客房app系统。实现首页酒店展示、预订搜索、列表/详情、订单、聊天消息、我的等模块。支持编译H5+小程序+App端。
113 8
|
4月前
|
小程序 前端开发 数据可视化
作为一个前端小白,我竟然搞定了一个小程序的交付
作为一名刚毕业的前端码农,今年毕业后就加入了一家初创公司。入职不久便接到了一个小程序开发项目,客户特别强调必须使用小程序原生语言进行开发。由于时间紧迫而合适的后端开发者暂时还没到位,老板决定让我边学边做,承担起整个项目的前后端开发工作。对于初出茅庐的我来说,这无疑是一个巨大的挑战。不仅要掌握一门新的编程语言,还要学习数据库设计、服务器部署等一系列后端技术,任务艰巨。正当我为此感到头疼时,一位前辈向我推荐了极态云。经过一番调研后发现,它简直就是为像我这样缺乏后端经验但又急需快速完成项目的人量身定做的解决方案!
作为一个前端小白,我竟然搞定了一个小程序的交付

热门文章

最新文章