运行环境

Java≥8、MySQL≥5.7、Tomcat≥8

开发工具

eclipse/idea/myeclipse/sts等均可配置运行

适用

课程设计,大作业,毕业设计,项目练习,学习演示等

功能说明

基于javaweb的SSM+Maven仓库管理系统(java+ssm+jsp+mysql+maven)

一、项目简述

功能包括: 仓库管理,出入库管理,仓库人员管理,基本信息管理, 供应商信息,系统管理等等。

二、项目运行

环境配置: Jdk1.8 + Tomcat8.5 + mysql + Eclispe (IntelliJ IDEA,Eclispe,MyEclispe,Sts 都支持)

项目技术: JSP +Spring + SpringMVC + MyBatis + html+ css + JavaScript + JQuery + Ajax + layui+ maven等等。

@RequestMapping(value = "/**/goodsManage")
@Controller
public class GoodsManageHandler {

    @Autowired
    private GoodsManageService goodsManageService;

    private static final String SEARCH_BY_ID = "searchByID";
    private static final String SEARCH_BY_NAME = "searchByName";
    private static final String SEARCH_ALL = "searchAll";

    /**
     * 通用的记录查询
     *
     * @param searchType 查询类型
     * @param keyWord    查询关键字
     * @param offset     分页偏移值
     * @param limit      分页大小
     * @return 返回一个 Map ,包含所有符合要求的查询结果,以及记录的条数
     */
    private Map<String, Object> query(String searchType, String keyWord, int offset, int limit) throws GoodsManageServiceException {
        Map<String, Object> queryResult = null;

        switch (searchType) {
            case SEARCH_BY_ID:
                if (StringUtils.isNumeric(keyWord))
                    queryResult = goodsManageService.selectById(Integer.valueOf(keyWord));
                break;
            case SEARCH_BY_NAME:
                queryResult = goodsManageService.selectByName(keyWord);
                break;
            case SEARCH_ALL:
                queryResult = goodsManageService.selectAll(offset, limit);
                break;
            default:
                // do other thing
                break;
        }

        return queryResult;
    }

    /**
rows = (List<StockRecordDTO>) queryResult.get("data");
                total = (long) queryResult.get("total");
            }
        } else
            responseContent.setResponseMsg("Request argument error");

        if (rows == null)
            rows = new ArrayList<>(0);

        responseContent.setCustomerInfo("rows", rows);
        responseContent.setResponseTotal(total);
        return responseContent.generateResponse();
    }
}

/**
 * 系统操作日志请求 Handler
 *
 */
@Controller
@RequestMapping(value = "/systemLog")
public class SystemLogHandler {
* @param goods 货物信息
     * @return 返回一个map,其中:key 为 result表示操作的结果,包括:success 与 error
     */
    @RequestMapping(value = "addGoods", method = RequestMethod.POST)
    public
    @ResponseBody
    Map<String, Object> addGoods(@RequestBody Goods goods) throws GoodsManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();

        // 添加记录
        String result = goodsManageService.addGoods(goods) ? Response.RESPONSE_RESULT_SUCCESS : Response.RESPONSE_RESULT_ERROR;

        // 设置 Response
        responseContent.setResponseResult(result);

        return responseContent.generateResponse();
    }

    /**
     * 查询指定 goods ID 货物的信息
     *
     * @param goodsID 货物ID
     * @return 返回一个map,其中:key 为 result 的值为操作的结果,包括:success 与 error;key 为 data
     * 的值为货物信息
     */
    @RequestMapping(value = "getGoodsInfo", method = RequestMethod.GET)
    public
    @ResponseBody
    Map<String, Object> getGoodsInfo(@RequestParam("goodsID") Integer goodsID) throws GoodsManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();
        String result = Response.RESPONSE_RESULT_ERROR;

        // 获取货物信息
        Goods goods = null;
        Map<String, Object> queryResult = goodsManageService.selectById(goodsID);
        if (queryResult != null) {
            goods = (Goods) queryResult.get("data");
            if (goods != null) {
                result = Response.RESPONSE_RESULT_SUCCESS;
            }
        }

        // 设置 Response
        responseContent.setResponseResult(result);
        responseContent.setResponseData(goods);
        return responseContent.generateResponse();
    }

    /**
     * 更新货物信息
     *
* @param keyWord    查询关键字
     * @param response   HttpServletResponse
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "exportRepository", method = RequestMethod.GET)
    public void exportRepository(@RequestParam("searchType") String searchType, @RequestParam("keyWord") String keyWord,
                                 HttpServletResponse response) throws RepositoryManageServiceException, IOException {

        // 导出文件名
        String fileName = "repositoryInfo.xlsx";

        // 查询
        List<Repository> repositories;

        Map<String, Object> queryResult = query(searchType, keyWord, -1, -1);

        if (queryResult != null)
            repositories = (List<Repository>) queryResult.get("data");
        else
            repositories = new ArrayList<>();

        // 生成文件
        File file = repositoryService.exportRepository(repositories);

        // 输出文件
        if (file != null) {
            // 设置响应头
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            FileInputStream inputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[8192];

            int len;
            while ((len = inputStream.read(buffer, 0, buffer.length)) > 0) {
                outputStream.write(buffer, 0, len);
                outputStream.flush();
            }

            inputStream.close();
            outputStream.close();
private static final String SEARCH_ALL = "searchAll";

    /**
     * 通用的记录查询
     *
     * @param searchType 查询类型
     * @param keyWord    查询关键字
     * @param offset     分页偏移值
     * @param limit      分页大小
     * @return 返回一个 Map ,包含所有符合要求的查询结果,以及记录的条数
     */
    private Map<String, Object> query(String searchType, String keyWord, int offset, int limit) throws GoodsManageServiceException {
        Map<String, Object> queryResult = null;

        switch (searchType) {
            case SEARCH_BY_ID:
                if (StringUtils.isNumeric(keyWord))
                    queryResult = goodsManageService.selectById(Integer.valueOf(keyWord));
                break;
            case SEARCH_BY_NAME:
                queryResult = goodsManageService.selectByName(keyWord);
                break;
            case SEARCH_ALL:
                queryResult = goodsManageService.selectAll(offset, limit);
                break;
            default:
                // do other thing
                break;
        }

        return queryResult;
    }

    /**
     * 搜索货物信息
     *
     * @param searchType 搜索类型
     * @param offset     如有多条记录时分页的偏移值
     * @param limit      如有多条记录时分页的大小
     * @param keyWord    搜索的关键字
     * @return 返回所有符合要求的记录
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "getGoodsList", method = RequestMethod.GET)
    public
    @ResponseBody
    Map<String, Object> getGoodsList(@RequestParam("searchType") String searchType,
                                     @RequestParam("offset") int offset, @RequestParam("limit") int limit,
                                     @RequestParam("keyWord") String keyWord) throws GoodsManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();
/**
 * 商品出入库管理请求Handler
 *
 * @since 017/4/5.
 */
@Controller
@RequestMapping(value = "stockRecordManage")
public class StockRecordManageHandler {

    @Autowired
    private StockRecordManageService stockRecordManageService;

    /**
     * 货物出库操作
     *
     * @param customerID      客户ID
     * @param goodsID         货物ID
     * @param repositoryIDStr 仓库ID
     * @param number          出库数量
     * @return 返回一个map,key为result的值表示操作是否成功
     */
    @RequestMapping(value = "stockOut", method = RequestMethod.POST)
    public
    @ResponseBody
    Map<String, Object> stockOut(@RequestParam("customerID") Integer customerID,
                                 @RequestParam("goodsID") Integer goodsID,
                                 @RequestParam(value = "repositoryID", required = false) String repositoryIDStr,
                                 @RequestParam("number") long number) throws StockRecordManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();
        String result = Response.RESPONSE_RESULT_ERROR;
        boolean authorizeCheck = true;
        boolean argumentCheck = true;
        Integer repositoryID = null;

        // 参数检查
        if (repositoryIDStr != null) {
            if (StringUtils.isNumeric(repositoryIDStr)) {
                repositoryID = Integer.valueOf(repositoryIDStr);
            } else {
                argumentCheck = false;
                responseContent.setResponseMsg("request argument error");
            }
        }
/**
 * 商品出入库管理请求Handler
 *
 * @since 017/4/5.
 */
@Controller
@RequestMapping(value = "stockRecordManage")
public class StockRecordManageHandler {

    @Autowired
    private StockRecordManageService stockRecordManageService;

    /**
     * 货物出库操作
     *
     * @param customerID      客户ID
     * @param goodsID         货物ID
     * @param repositoryIDStr 仓库ID
     * @param number          出库数量
     * @return 返回一个map,key为result的值表示操作是否成功
     */
    @RequestMapping(value = "stockOut", method = RequestMethod.POST)
    public
    @ResponseBody
/**
 * 仓库信息管理请求 Handler
 *
 */
@Controller
@RequestMapping(value = "/**/repositoryManage")
public class RepositoryManageHandler {

    @Autowired
    private RepositoryService repositoryService;

    private static final String SEARCH_BY_ID = "searchByID";
    private static final String SEARCH_BY_ADDRESS = "searchByAddress";
    private static final String SEARCH_ALL = "searchAll";

    /**
     * 通用的记录查询
     *
     * @param searchType 查询方式
     * @param keyword    查询关键字
     * @param offset     分页偏移值
     * @param limit      分页大小
     * @return 返回所有符合条件的查询结果
     */
    private Map<String, Object> query(String searchType, String keyword, int offset, int limit) throws RepositoryManageServiceException {
        Map<String, Object> queryResult = null;

        switch (searchType) {
            case SEARCH_BY_ID:
                if (StringUtils.isNumeric(keyword)) {
                    queryResult = repositoryService.selectById(Integer.valueOf(keyword));
@RequestMapping(value = "exportStorageRecord", method = RequestMethod.GET)
    public void exportStorageRecord(@RequestParam("searchType") String searchType,
                                    @RequestParam("keyword") String keyword,
                                    @RequestParam(value = "repositoryBelong", required = false) String repositoryBelong,
                                    HttpServletRequest request, HttpServletResponse response) throws StorageManageServiceException, IOException {
        String fileName = "storageRecord.xlsx";

        HttpSession session = request.getSession();
        UserInfoDTO userInfo = (UserInfoDTO) session.getAttribute("userInfo");
        Integer sessionRepositoryBelong = userInfo.getRepositoryBelong();
        if (sessionRepositoryBelong > 0)
            repositoryBelong = sessionRepositoryBelong.toString();

        List<Storage> storageList = null;
        Map<String, Object> queryResult = query(searchType, keyword, repositoryBelong, -1, -1);
        if (queryResult != null)
            storageList = (List<Storage>) queryResult.get("data");

        File file = storageManageService.exportStorage(storageList);
        if (file != null) {
            // 设置响应头
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            FileInputStream inputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[8192];

            int len;
            while ((len = inputStream.read(buffer, 0, buffer.length)) > 0) {
                outputStream.write(buffer, 0, len);
                outputStream.flush();
            }

            inputStream.close();
            outputStream.close();

        }
    }
}
* @param repositoryAdminID 仓库管理员ID
     * @return 返回一个map,其中:key 为 result 的值为操作的结果,包括:success 与 error;key 为 data
     * 的值为仓库管理员信息
     */
    @RequestMapping(value = "getRepositoryAdminInfo", method = RequestMethod.GET)
    public
    @ResponseBody
    Map<String, Object> getRepositoryAdminInfo(Integer repositoryAdminID) throws RepositoryAdminManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();
        String result = Response.RESPONSE_RESULT_ERROR;

        // 查询
        RepositoryAdmin repositoryAdmin = null;
        Map<String, Object> queryResult = repositoryAdminManageService.selectByID(repositoryAdminID);
        if (queryResult != null) {
            if ((repositoryAdmin = (RepositoryAdmin) queryResult.get("data")) != null)
                result = Response.RESPONSE_RESULT_SUCCESS;
        }

        // 设置 Response
        responseContent.setResponseResult(result);
        responseContent.setResponseData(repositoryAdmin);
        return responseContent.generateResponse();
    }

    /**
     * 更新仓库管理员信息
     *
     * @param repositoryAdmin 仓库管理员信息
     * @return 返回一个map,其中:key 为 result 的值为操作的结果,包括:success 与 error;key 为 data
     * 的值为仓库管理员信息
     */
    @RequestMapping(value = "updateRepositoryAdmin", method = RequestMethod.POST)
    public
    @ResponseBody
    Map<String, Object> updateRepositoryAdmin(@RequestBody RepositoryAdmin repositoryAdmin) throws RepositoryAdminManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();

        // 更新
        String result = repositoryAdminManageService.updateRepositoryAdmin(repositoryAdmin)
                ? Response.RESPONSE_RESULT_SUCCESS : Response.RESPONSE_RESULT_ERROR;
if (stockRecordManageService.stockOutOperation(customerID, goodsID, repositoryID, number, personInCharge))
                result = Response.RESPONSE_RESULT_SUCCESS;
        }

        // 设置 Response
        responseContent.setResponseResult(result);
        return responseContent.generateResponse();
    }

    /**
     * 货物入库操作
     *
     * @param supplierID      供应商ID
     * @param goodsID         货物ID
     * @param repositoryIDStr 仓库ID
     * @param number          入库数目
     * @return 返回一个map,key为result的值表示操作是否成功
     */
    @RequestMapping(value = "stockIn", method = RequestMethod.POST)
    public
    @ResponseBody
    Map<String, Object> stockIn(@RequestParam("supplierID") Integer supplierID,
                                @RequestParam("goodsID") Integer goodsID,
                                @RequestParam(value = "repositoryID", required = false) String repositoryIDStr,
                                @RequestParam("number") long number) throws StockRecordManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();
        String result = Response.RESPONSE_RESULT_ERROR;
        boolean authorizeCheck = true;
        boolean argumentCheck = true;
        Integer repositoryID = null;

        // 参数检查
        if (repositoryIDStr != null && repositoryIDStr.trim().length()>0) {
            if (StringUtils.isNumeric(repositoryIDStr)) {
                repositoryID = Integer.valueOf(repositoryIDStr);
            } else {
                argumentCheck = false;
                responseContent.setResponseMsg("request argument error");
            }
        }

        // 获取session中的信息
// 请求为普通请求
            this.issueSuccessRedirect(request, response);
        }else{
            // 请求为 Ajax 请求
            httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        }

        return false;
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        if(log.isDebugEnabled()) {
            log.debug("Authentication exception", e);
        }

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))){
            // 请求为普通请求
            this.setFailureAttribute(request, e);
            return true;
        }else{
            // 请求为 Ajax 请求
            // do some thing to return a json
            httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return false;
        }
    }
}
public void exportCustomer(@RequestParam("searchType") String searchType, @RequestParam("keyWord") String keyWord,
                               HttpServletResponse response) throws CustomerManageServiceException, IOException {

        String fileName = "customerInfo.xlsx";

        List<Customer> customers = null;
        Map<String, Object> queryResult = query(searchType, keyWord, -1, -1);

        if (queryResult != null) {
            customers = (List<Customer>) queryResult.get("data");
        }

        // 获取生成的文件
        File file = customerManageService.exportCustomer(customers);

        // 写出文件
        if (file != null) {
            // 设置响应头
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            FileInputStream inputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[8192];

            int len;
            while ((len = inputStream.read(buffer, 0, buffer.length)) > 0) {
                outputStream.write(buffer, 0, len);
                outputStream.flush();
            }

            inputStream.close();
            outputStream.close();

        }
    }
}
// 获取货物信息
        Goods goods = null;
        Map<String, Object> queryResult = goodsManageService.selectById(goodsID);
        if (queryResult != null) {
            goods = (Goods) queryResult.get("data");
            if (goods != null) {
                result = Response.RESPONSE_RESULT_SUCCESS;
            }
        }

        // 设置 Response
        responseContent.setResponseResult(result);
        responseContent.setResponseData(goods);
        return responseContent.generateResponse();
    }

    /**
     * 更新货物信息
     *
     * @param goods 货物信息
     * @return 返回一个map,其中:key 为 result表示操作的结果,包括:success 与 error
     */
    @RequestMapping(value = "updateGoods", method = RequestMethod.POST)
    public
    @ResponseBody
    Map<String, Object> updateGoods(@RequestBody Goods goods) throws GoodsManageServiceException {
        // 初始化 Response
        Response responseContent = ResponseFactory.newInstance();

        // 更新
        String result = goodsManageService.updateGoods(goods) ? Response.RESPONSE_RESULT_SUCCESS : Response.RESPONSE_RESULT_ERROR;

        // 设置 Response
        responseContent.setResponseResult(result);
        return responseContent.generateResponse();
    }

    /**
     * 删除货物记录
     *
}

    public void setMaxSessionNum(int maxSessionNum) {
        this.maxSessionNum = maxSessionNum;
    }

    public void setSessionManager(SessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    public void setCacheManager(CacheManager cacheManager) {
        this.cache = cacheManager.getCache("sessionCache");
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    /**
     * 表示访问拒绝时是否自己处理,如果返回true表示自己不处理且继续拦截器链执行,
     * 返回false表示自己已经处理了(比如重定向到另一个页面)。
     * 根据 isAccessAllowed 方法的返回值
     *
     * @param servletRequest  request
     * @param servletResponse response
     * @return 返回是否已经处理访问拒绝
     * @throws Exception exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        // 如果用户还没有登陆则继续后续的流程
        Subject subject = getSubject(servletRequest, servletResponse);
        if (!subject.isAuthenticated() && !subject.isRemembered())
            return true;

        // 判断当前用户登陆数量是否超出
        Session session = subject.getSession();
        String userName = (String) subject.getPrincipal();
        Serializable sessionId = session.getId();
/**
     * 导出仓库管理员信息到文件中
     *
     * @param searchType 查询类型
     * @param keyWord    查询关键字
     * @param response   HttpServletResponse
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "exportRepositoryAdmin", method = RequestMethod.GET)
    public void exportRepositoryAdmin(@RequestParam("searchType") String searchType,
                                      @RequestParam("keyWord") String keyWord, HttpServletResponse response) throws RepositoryAdminManageServiceException, IOException {

        // 导出文件名
        String fileName = "repositoryAdminInfo.xlsx";

        // 查询
        List<RepositoryAdmin> repositoryAdmins;
        Map<String, Object> queryResult = query(keyWord, searchType, -1, -1);

        if (queryResult != null)
            repositoryAdmins = (List<RepositoryAdmin>) queryResult.get("data");
        else
            repositoryAdmins = new ArrayList<>();

        // 生成文件
        File file = repositoryAdminManageService.exportRepositoryAdmin(repositoryAdmins);

        // 输出文件
        if (file != null) {
            // 设置响应头
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            FileInputStream inputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[8192];

            int len;
            while ((len = inputStream.read(buffer, 0, buffer.length)) > 0) {
                outputStream.write(buffer, 0, len);
                outputStream.flush();
            }

            inputStream.close();
            outputStream.close();
        }
    }
}
responseContent.setResponseResult(result);
        responseContent.setResponseTotal(total);
        responseContent.setCustomerInfo("available", available);
        return responseContent.generateResponse();
    }

    /**
     * 导出货物信息
     *
     * @param searchType 查找类型
     * @param keyWord    查找关键字
     * @param response   HttpServletResponse
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "exportGoods", method = RequestMethod.GET)
    public void exportGoods(@RequestParam("searchType") String searchType, @RequestParam("keyWord") String keyWord,
                            HttpServletResponse response) throws GoodsManageServiceException, IOException {

        String fileName = "goodsInfo.xlsx";

        List<Goods> goodsList = null;
        Map<String, Object> queryResult = query(searchType, keyWord, -1, -1);

        if (queryResult != null) {
            goodsList = (List<Goods>) queryResult.get("data");
        }

        // 获取生成的文件
        File file = goodsManageService.exportGoods(goodsList);

        // 写出文件
        if (file != null) {
            // 设置响应头
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);

            FileInputStream inputStream = new FileInputStream(file);
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[8192];

            int len;
            while ((len = inputStream.read(buffer, 0, buffer.length)) > 0) {
                outputStream.write(buffer, 0, len);
                outputStream.flush();
            }

            inputStream.close();
            outputStream.close();

        }
if (currentUser != null && !currentUser.isAuthenticated()) {
            String id = (String) user.get(USER_ID);
            String password = (String) user.get(USER_PASSWORD);
            Session session = currentUser.getSession();
            UsernamePasswordToken token = new UsernamePasswordToken(id, password);

            try {
                // 执行登陆操作
                currentUser.login(token);

                /* 设置 session 中 userInfo 的其他信息 */
                UserInfoDTO userInfo = (UserInfoDTO) session.getAttribute("userInfo");
                // 设置登陆IP
                userInfo.setAccessIP(session.getHost());
                // 查询并设置用户所属的仓库ID
                List<RepositoryAdmin> repositoryAdmin = (List<RepositoryAdmin>) repositoryAdminManageService.selectByID(userInfo.getUserID()).get("data");
                userInfo.setRepositoryBelong(-1);
                if (!repositoryAdmin.isEmpty()) {
                    Integer repositoryBelong = repositoryAdmin.get(0).getRepositoryBelongID();
                    if (repositoryBelong != null) {
                        userInfo.setRepositoryBelong(repositoryBelong);
                    }
                }

                // 记录登陆日志
                systemLogService.insertAccessRecord(userInfo.getUserID(), userInfo.getUserName(),
                        userInfo.getAccessIP(), SystemLogService.ACCESS_TYPE_LOGIN);

                // 设置登陆成功响应
                result = Response.RESPONSE_RESULT_SUCCESS;

            } catch (UnknownAccountException e) {
                errorMsg = "unknownAccount";
            } catch (IncorrectCredentialsException e) {
                errorMsg = "incorrectCredentials";
            } catch (AuthenticationException e) {
                errorMsg = "authenticationError";
                e.printStackTrace();
            } catch (SystemLogServiceException | RepositoryAdminManageServiceException e) {
                errorMsg = "ServerError";
            } finally {
                // 当登陆失败则清除session中的用户信息
                if (result.equals(Response.RESPONSE_RESULT_ERROR)) {
                    session.setAttribute("userInfo", null);
                }
            }
        } else {
            errorMsg = "already login";
        }

java开源的仓储物流系统_分页


java开源的仓储物流系统_mysql_02


java开源的仓储物流系统_mysql_03


java开源的仓储物流系统_java开源的仓储物流系统_04