停车场管理系统源码

源码下载地址(小程序开源地址):停车场系统小程序,新能源电动车充电系统,智慧社区物业人脸门禁小程序: 【涵盖内容】:城市智慧停车系统,汽车新能源充电,两轮电动车充电,物业缴费,社区到访记录,人脸门禁,上门报修等。【开发框】架:union【使用场景】:微信小程序,支付宝小程序,其它平台小程序,混合app【使用教程】:本代码全开源且完整,没有任何缺失和加密,不会存在我们故意动手脚导致你跑不起来的情况,建议使用HBuilder打开和运行本代码

源码下载地址(后台管理开源地址):停车场系统后台管理,新能源电动车充电系统,智慧社区物业人脸门禁后台管理: 城市智慧停车系统,汽车新能源充电,两轮电动车充电,物业缴费,社区到访记录,人脸门禁,上门报修等

代码格式浏览

package com.cf.carpark.admin.controller;

import com.alibaba.fastjson.JSONObject;
import com.cf.carpark.admin.config.AuthenticationInterceptor;
import com.cf.carpark.admin.swagger.CfCarParkUseLogSwagger;
import com.cf.carpark.domain.*;
import com.cf.carpark.domain.ext.CfCarParkOrder;
import com.cf.carpark.domain.request.*;
import com.cf.carpark.domain.type.FeeQueryMode;
import com.cf.carpark.domain.type.ReleaseType;
import com.cf.carpark.service.*;
import com.cf.framework.domain.carpark.response.CarParkCode;
import com.cf.framework.domain.pay.PayCode;
import com.cf.framework.domain.report.CountByDay;
import com.cf.framework.domain.response.CommonCode;
import com.cf.framework.domain.response.ResponseResult;
import com.cf.framework.domain.ucenter.ext.UserBasicInfo;
import com.cf.framework.exception.ExceptionCast;
import com.cf.framework.utils.DateUtil;
import com.cf.framework.utils.FileUtils;
import com.cf.framework.utils.HttpHearderUtils;
import com.cf.framework.utils.StringTools;
import com.cf.pay.domain.CfCoupon;
import com.cf.pay.domain.CfOrder;
import com.cf.pay.domain.request.CfOrderQuery;
import com.cf.pay.domain.type.CouponStatus;
import com.cf.pay.domain.type.GoodsType;
import com.cf.pay.domain.type.PayStatus;
import com.cf.pay.service.CfCouponService;
import com.cf.pay.service.CfOrderService;
import com.cf.ucenter.service.CfSystemConfigService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 请在此填写描述
 *
 * @ClassName CfCarParkUseLogController
 * @Author 隔壁小王子 981011512@qq.com
 * @Date 2020/5/26/026 7:34
 * @Version 1.0
 **/
@RestController
@RequestMapping("carparkUseLogAdmin/")
@Validated
public class CfCarParkUseLogController implements CfCarParkUseLogSwagger {

    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkUseLogService cfCarParkUseLogService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkService cfCarParkService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfOrderService cfOrderService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkReleaseLogService cfCarParkReleaseLogService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkDeviceService cfCarParkDeviceService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkChargingRulesService cfCarParkChargingRulesService;
    @Autowired
    protected HttpServletRequest request;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkLinkUserService cfCarParkLinkUserService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfSystemConfigService cfSystemConfigService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCarParkCarTypeService cfCarParkCarTypeService;
    @Reference(version = "1.0.0", retries = 0, timeout = 30000, check = false)
    private CfCouponService cfCouponService;

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-add')")
    @Override
    @RequestMapping(value = "add", method = RequestMethod.POST)
    public ResponseResult add(@Validated @RequestBody CfCarParkUseLogForm cfCarParkUseLogForm) {
        CfCarParkUseLog cfCarParkUseLog = new CfCarParkUseLog();
        BeanUtils.copyProperties(cfCarParkUseLogForm, cfCarParkUseLog);
        CfCarParkUseLog carParkUseLog = cfCarParkUseLogService.add(cfCarParkUseLog);
        return new ResponseResult(CommonCode.SUCCESS, carParkUseLog);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-update')")
    @Override
    @RequestMapping(value = "update", method = RequestMethod.PUT)
    public ResponseResult update(@Validated @RequestBody CfCarParkUseLogForm cfCarParkUseLogForm) {
        CfCarParkUseLog cfCarParkUseLog = new CfCarParkUseLog();
        BeanUtils.copyProperties(cfCarParkUseLogForm, cfCarParkUseLog);
        CfCarParkUseLog carParkUseLog = cfCarParkUseLogService.update(cfCarParkUseLog);
        return new ResponseResult(CommonCode.SUCCESS, carParkUseLog);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-updateLogAndOrder')")
    @Override
    @RequestMapping(value = "updateLogAndOrder", method = RequestMethod.PUT)
    public ResponseResult updateLogAndOrder(@RequestBody @Validated UpdateLogAndOrderForm updateLogAndOrderForm) throws Exception {
        if(StringUtils.isEmpty(updateLogAndOrderForm.getActionType())){
            ExceptionCast.cast(CommonCode.INVALID_PARAM, "miss actionType");
        }
        UserBasicInfo userBasicInfo = AuthenticationInterceptor.parseJwt(HttpHearderUtils.getAuthorization(request));
        CfCarParkUseLog cfCarParkUseLog = cfCarParkUseLogService.findById(updateLogAndOrderForm.getCarParkUseLogId(), false);

        CfOrderQuery cfOrderQuery = new CfOrderQuery();
        cfOrderQuery.setGoodsId(updateLogAndOrderForm.getCarParkUseLogId());
        List<CfOrder> cfOrderList = cfOrderService.getListByQuery(cfOrderQuery);
        if(cfOrderList==null || cfOrderList.size()==0){
            return new ResponseResult(PayCode.ORDER_DOES_NOT_EXIST);
        }
        //禁止操作非停车账单
        if(cfOrderList.get(0).getGoodsType()!= GoodsType.CARPARK_PAYMENT){
            return new ResponseResult(CommonCode.FAIL, null,"该账单并非停车账单");
        }
        if(cfOrderList.get(0).getStatus()==PayStatus.PAID){
            return new ResponseResult(CommonCode.FAIL, null,"该订单已支付");
        }
        if(StringUtils.isNotEmpty(cfOrderList.get(0).getUid()) && (System.currentTimeMillis()-cfOrderList.get(0).getUpdateTime()<10000)){
            return new ResponseResult(CommonCode.FREQUENT_OPERATION);
        }

        if(!userBasicInfo.getId().equals(cfCarParkUseLog.getInHandleUid()) && !userBasicInfo.getId().equals(cfCarParkUseLog.getOutHandleUid())){
            return new ResponseResult(CarParkCode.NO_PERMISSION);
        }

        if(updateLogAndOrderForm.getActionType().equals("cash_pay") || updateLogAndOrderForm.getActionType().equals("abnormal_termination_of_order")){
            cfCarParkUseLog.setPayTime(System.currentTimeMillis());
        }else if(updateLogAndOrderForm.getActionType().equals("cancel_release")){
            cfCarParkUseLog.setPayTime(0L);
        }
        cfCarParkUseLog.setOutReleaseType(ReleaseType.ARTIFICIAL);
        cfCarParkUseLogService.update(cfCarParkUseLog);

//        CfOrder cfOrder = cfOrderService.findById(orderId, false);

        //计算应付金额
        CfCarParkOrder cfCarParkOrder = cfCarParkChargingRulesService.calculateTheAmounPayable(updateLogAndOrderForm.getCarParkUseLogId(), null, FeeQueryMode.QUERY_MODE_QUERY_ONLY);
        CfOrder cfOrder = cfCarParkOrder.getCfOrder();

        if(cfOrder.getStatus()==PayStatus.PAID){
            return new ResponseResult(CommonCode.FAIL, null,"该订单已支付");
        }

        if((updateLogAndOrderForm.getActionType().equals("cash_pay") || updateLogAndOrderForm.getActionType().equals("abnormal_termination_of_order")) && StringUtils.isNotEmpty(updateLogAndOrderForm.getAmountOfMoney()) && (new BigDecimal(updateLogAndOrderForm.getAmountOfMoney())).doubleValue()>=0){
            //暂时不允许收费自己修改金额
//            cfOrder.setAmountActuallyPaid(new BigDecimal(amountOfMoney).add(cfOrder.getCollectionAmount()));
//            if(cfOrder.getCollectionAmount().doubleValue()>0){
//                cfOrder.setAmountActuallyPaid(cfOrder.getCollectionAmount().add(cfOrder.getAmountsPayable()));
//            }
//            if(cfOrder.getAmountsPayable().doubleValue()==0){
//                cfOrder.setAmountsPayable(cfOrder.getAmountActuallyPaid());
//            }

            if(System.currentTimeMillis()-cfOrder.getManualOfferSetTime()<=900000){
                BigDecimal amountsPayable = cfOrder.getAmountsPayable();
                cfOrder.setAmountsPayable(amountsPayable.subtract(cfOrder.getManualOffer()));
                cfOrder.setAmountActuallyPaid(cfOrder.getAmountsPayable());
            }else if(StringUtils.isNotEmpty(updateLogAndOrderForm.getCouponId())){
                CfCoupon cfCoupon = cfCouponService.findById(updateLogAndOrderForm.getCouponId(), false);
                if(cfCoupon.getCouponType()==(byte)2 && cfCoupon.getStatus()==CouponStatus.NOT_USED){
                    CfCoupon coupon = new CfCoupon();
                    coupon.setId(updateLogAndOrderForm.getCouponId());
                    coupon.setUseTime(System.currentTimeMillis());
                    if(cfOrder.getAmountsPayable().doubleValue()<cfCoupon.getDenomination().doubleValue()){
                        coupon.setAmountUsed(cfOrder.getAmountsPayable());
                    }else{
                        coupon.setAmountUsed(cfCoupon.getDenomination());
                    }
                    coupon.setStatus(CouponStatus.USED);
                    cfCouponService.updateByPrimaryKeySelective(coupon);

                    cfOrder.setCouponId(updateLogAndOrderForm.getCouponId());

                    if(cfOrder.getAmountsPayable().doubleValue()<cfCoupon.getDenomination().doubleValue()){
                        cfOrder.setCouponPaid(cfOrder.getAmountsPayable());
                        cfOrder.setAmountActuallyPaid(new BigDecimal(0.00));
                    }else{
                        cfOrder.setCouponPaid(cfCoupon.getDenomination());
                        cfOrder.setAmountActuallyPaid(cfOrder.getAmountsPayable().subtract(cfCoupon.getDenomination()));
                    }
                }
            }else{
                cfOrder.setAmountActuallyPaid(cfOrder.getAmountsPayable());
            }
            cfOrder.setStatus(PayStatus.PAID);
            cfOrder.setPayTime(System.currentTimeMillis());
            if(updateLogAndOrderForm.getActionType().equals("cash_pay")){
                cfOrder.setPaymentAgencyShortName("cash_pay_cny");
                if(StringUtils.isNotEmpty(cfCarParkUseLog.getOutCheckPointId())){
                    cfCarParkReleaseLogService.executeReleaseByCarParkUseLog(cfCarParkUseLog,"岗亭人员确认现金收费手动放行",(byte)1);
                }
            }else{
                cfOrder.setPaymentAgencyShortName("abnormal_termination_of_order");
                //异常放行 实付金额为0
                cfOrder.setAmountActuallyPaid(new BigDecimal(0.00));
                if(StringUtils.isNotEmpty(cfCarParkUseLog.getOutCheckPointId())){
                    cfCarParkReleaseLogService.executeReleaseByCarParkUseLog(cfCarParkUseLog,"岗亭人员确认后异常放行",(byte)2);
                }
            }

            if(cfOrder.getCollectionAmount().doubleValue()>0){
                //更新停车记录支付时间(因为存在代付金额时,当前停车记录支付时间会被临时置为0)
                CfCarParkUseLog carParkUseLog = new CfCarParkUseLog();
                carParkUseLog.setId(cfCarParkUseLog.getId());
                carParkUseLog.setPayTime(System.currentTimeMillis());
                cfCarParkUseLogService.updateByPrimaryKeySelective(carParkUseLog);
            }
        }else if(updateLogAndOrderForm.getActionType().equals("cancel_release")){
            cfOrder.setPayTime(0L);
            cfOrder.setStatus(PayStatus.TO_BE_PAID);
            CfCarParkUseLog carParkUseLog = new CfCarParkUseLog();
            carParkUseLog.setId(cfCarParkUseLog.getId());
            carParkUseLog.setPayTime(0l);
            cfCarParkUseLogService.updateByPrimaryKeySelective(carParkUseLog);
        }else if(updateLogAndOrderForm.getActionType().equals("change_amount") && cfCarParkOrder.getCfCarPark().getAllowEditUseLog()==(byte)1){
            cfOrder.setManualOffer(new BigDecimal(updateLogAndOrderForm.getAmountOfMoney()));
            cfOrder.setManualOfferSetTime(System.currentTimeMillis());
            cfOrder.setAmountsPayable(cfOrder.getManualOffer());
        }else{
            return new ResponseResult(CommonCode.FAIL, null,"更新订单失败");
        }
        CfOrder order = cfOrderService.update(cfOrder);
        if(order==null || order.getId()==null){
            return new ResponseResult(CommonCode.FAIL, null,"更新订单失败");
        }
        return new ResponseResult(CommonCode.SUCCESS);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-dutyerUpdateUseLog')")
    @Override
    @RequestMapping(value = "dutyerUpdateUseLog", method = RequestMethod.PUT)
    public ResponseResult dutyerUpdateUseLog(UpdateLogAndOrderForm updateLogAndOrderForm) throws Exception {
        if(StringUtils.isEmpty(updateLogAndOrderForm.getCarParkUseLogId()) || StringUtils.isEmpty(updateLogAndOrderForm.getNumberPlate())){
            ExceptionCast.cast(CommonCode.INVALID_PARAM, "miss carParkUseLogId or numberPlate");
        }
        CfCarParkUseLog carParkUseLog = cfCarParkUseLogService.findById(updateLogAndOrderForm.getCarParkUseLogId(), false);
        CfCarPark cfCarPark = cfCarParkService.findById(carParkUseLog.getCarParkId(), false);
        if(cfCarPark.getAllowEditUseLog()==(byte)0){
            return new ResponseResult(CommonCode.FAIL, "该停车禁止修改停车数据");
        }
        if(carParkUseLog.getOutTime()>0){
            return new ResponseResult(CommonCode.FAIL, "只能修改入场数据");
        }
        CfCarParkUseLog cfCarParkUseLog = new CfCarParkUseLog();
        cfCarParkUseLog.setId(updateLogAndOrderForm.getCarParkUseLogId());
        cfCarParkUseLog.setNumberPlate(updateLogAndOrderForm.getNumberPlate());
        cfCarParkUseLogService.updateByPrimaryKeySelective(cfCarParkUseLog);
        return new ResponseResult(CommonCode.SUCCESS);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-selectListByCondition')")
    @Override
    @RequestMapping(value = "selectListByCondition", method = RequestMethod.GET)
    public ResponseResult selectListByCondition(String conditions)throws Exception {
        Map<String, Object> map = makeAllowData(conditions, false);
        ArrayList<String> allowFileds = (ArrayList<String>)map.get("allowFileds");
        Map<String, String> allowFiledsMap = (Map<String, String>)map.get("allowFiledsMap");
        Map conditionsMap = (Map)map.get("conditionsMap");
        Integer counts = 0;
        if(((Map<String,Integer>)conditionsMap.get("limit")).get("limit")>3000){
            ((Map<String,Integer>)conditionsMap.get("limit")).put("limit",3000);
        }
        List<CfCarParkUseLog> cfCarParks = cfCarParkUseLogService.selectListByCondition(conditionsMap, allowFiledsMap,allowFileds);
        if(((Map<String,Integer>)conditionsMap.get("limit")).get("page")==1){
            counts = cfCarParkUseLogService.selectListByConditionCounts(conditionsMap, allowFiledsMap, allowFileds);
        }
        if(cfCarParks!=null && cfCarParks.size()>0){
            String fileSourceAddress = cfSystemConfigService.getValueByKey("file_source_address", "http://file.cfeng.wang/");
            for (CfCarParkUseLog cfCarParkUseLog: cfCarParks){
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "inSmallImage");
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "outSmallImage");
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "inBigImage");
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "outBigImage");
            }
            return new ResponseResult(CommonCode.SUCCESS, cfCarParks, null, counts);
        }
        return new ResponseResult(CommonCode.NO_MORE_DATAS);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-selectListByCondition')")
    @Override
    @RequestMapping(value = "exportUseLogExcel", method = RequestMethod.GET)
    public void exportUseLogExcel(HttpServletResponse response, String conditions) throws Exception {
        Map<String, Object> map = makeAllowData(conditions, false);
        ArrayList<String> allowFileds = (ArrayList<String>)map.get("allowFileds");
        Map<String, String> allowFiledsMap = (Map<String, String>)map.get("allowFiledsMap");
        Map conditionsMap = (Map)map.get("conditionsMap");

        List<CfCarParkUseLog> cfCarParks = cfCarParkUseLogService.selectListByCondition(conditionsMap, allowFiledsMap,allowFileds);

        //声明输出流
        OutputStream os = null;
        //设置响应头
        setResponseHeader(response,"停车记录");
        try {
            //获取输出流
            os = response.getOutputStream();
            //内存中保留3000条数据,以免内存溢出,其余写入硬盘
            SXSSFWorkbook wb = new SXSSFWorkbook(3000);
            //获取该工作区的第一个sheet
            Sheet sheet1 = wb.createSheet("sheet1");
            int excelRow = 0;
            //创建标题行
            Row titleRow = sheet1.createRow(excelRow++);
            ArrayList<String> columnList = new ArrayList<>();
            columnList.add("序号");
            columnList.add("车牌号");
            columnList.add("停车场");
            columnList.add("姓名/楼栋");
            columnList.add("车辆类型");
            columnList.add("状态");
            columnList.add("应付金额");
            columnList.add("实付金额");
            columnList.add("支付方式");
            columnList.add("到期时间");
            columnList.add("入场时间");
            columnList.add("出场时间");
            columnList.add("停车时间");
            columnList.add("入场关卡");
            columnList.add("出场关卡");
            for(int i = 0;i<columnList.size();i++){
                //创建该行下的每一列,并写入标题数据
                Cell cell = titleRow.createCell(i);
                cell.setCellValue(columnList.get(i));
            }
            //设置内容行
            if(cfCarParks!=null && cfCarParks.size()>0){
                //序号是从1开始的
                int count = 1;
                //外层for循环创建行
                for(CfCarParkUseLog cfCarParkUseLog: cfCarParks){
                    Row dataRow = sheet1.createRow(excelRow++);
                    //序号
                    Cell serialNumberCell = dataRow.createCell(0);
                    serialNumberCell.setCellValue(count);
                    //车牌号
                    Cell numberPlateCell = dataRow.createCell(1);
                    numberPlateCell.setCellValue(cfCarParkUseLog.getNumberPlate());
                    //停车场
                    Cell carParkCell = dataRow.createCell(2);
                    if(cfCarParkUseLog.getCfCarPark()!=null){
                        carParkCell.setCellValue(cfCarParkUseLog.getCfCarPark().getName());
                    }else{
                        carParkCell.setCellValue("");
                    }
                    //姓名/楼栋
                    Cell carOwnerNameCell = dataRow.createCell(3);
                    carOwnerNameCell.setCellValue(cfCarParkUseLog.getVisitUnit());
                    //车辆类型
                    Cell carTypeCell = dataRow.createCell(4);
                    CfCarParkCarType cfCarParkCarType = cfCarParkCarTypeService.findByKey(cfCarParkUseLog.getCarType());
                    if(cfCarParkCarType!=null){
                        carTypeCell.setCellValue(cfCarParkCarType.getName());
                    }else{
                        carTypeCell.setCellValue("临时车");
                    }
                    //车辆状态
                    Cell carStatus = dataRow.createCell(5);
                    switch (cfCarParkUseLog.getCarStatus()){
                        case (byte)0:
                            carStatus.setCellValue("禁用");
                            break;
                        case (byte)1:
                            carStatus.setCellValue("正常");
                            break;
                        case (byte)2:
                            carStatus.setCellValue("已过期");
                            break;
                    }

                    //应付金额
                    Cell amountsPayableCell = dataRow.createCell(6);
                    if(cfCarParkUseLog.getCfOrder()!=null){
                        amountsPayableCell.setCellValue(cfCarParkUseLog.getCfOrder().getAmountsPayable().toString());
                    }else{
                        amountsPayableCell.setCellValue("");
                    }
                    //实付金额
                    Cell amountActuallyPaidCell = dataRow.createCell(7);
                    if(cfCarParkUseLog.getCfOrder()!=null){
                        amountActuallyPaidCell.setCellValue(cfCarParkUseLog.getCfOrder().getAmountActuallyPaid().toString());
                    }else{
                        amountActuallyPaidCell.setCellValue("");
                    }
                    //支付方式
                    Cell paymentAgencyShortNameCell = dataRow.createCell(8);
                    if(cfCarParkUseLog.getCfPaymentAgency()!=null){
                        paymentAgencyShortNameCell.setCellValue(cfCarParkUseLog.getCfPaymentAgency().getName());
                    }else{
                        paymentAgencyShortNameCell.setCellValue("");
                    }
                    //到期时间
                    Cell packageEndTimeCell = dataRow.createCell(9);
                    if(cfCarParkUseLog.getCfCarParkPackage()!=null){
                        packageEndTimeCell.setCellValue(DateUtil.stampToDate(cfCarParkUseLog.getCfCarParkPackage().getEndTime(),"yyyy-MM-dd HH:mm:ss"));
                    }else{
                        packageEndTimeCell.setCellValue("");
                    }
                    //入场时间
                    Cell inTimeCell = dataRow.createCell(10);
                    if(cfCarParkUseLog.getInTime()>0){
                        inTimeCell.setCellValue(DateUtil.stampToDate(cfCarParkUseLog.getInTime(),"yyyy-MM-dd HH:mm:ss"));
                    }else{
                        inTimeCell.setCellValue("");
                    }
                    //出场时间
                    Cell outTimeCell = dataRow.createCell(11);
                    if(cfCarParkUseLog.getOutTime()>0){
                        outTimeCell.setCellValue(DateUtil.stampToDate(cfCarParkUseLog.getOutTime(),"yyyy-MM-dd HH:mm:ss"));
                    }else{
                        outTimeCell.setCellValue("");
                    }

                    //停车时间
                    Cell useTimeCell = dataRow.createCell(12);
                    if(cfCarParkUseLog.getInTime()>0 && cfCarParkUseLog.getOutTime()>cfCarParkUseLog.getInTime()){
                        useTimeCell.setCellValue(DateUtil.getDifferenceByTimeStamp(cfCarParkUseLog.getInTime(),cfCarParkUseLog.getOutTime()));
                    }else{
                        useTimeCell.setCellValue("");
                    }
                    //入场关卡
                    Cell inCheckPointCell = dataRow.createCell(13);
                    if(cfCarParkUseLog.getCfCarParkCheckpointIn()!=null){
                        inCheckPointCell.setCellValue(cfCarParkUseLog.getCfCarParkCheckpointIn().getName());
                    }else{
                        inCheckPointCell.setCellValue("");
                    }
                    //出场关卡
                    Cell outCheckPointCell = dataRow.createCell(14);
                    if(cfCarParkUseLog.getCfCarParkCheckpointOut()!=null){
                        outCheckPointCell.setCellValue(cfCarParkUseLog.getCfCarParkCheckpointOut().getName());
                    }else{
                        outCheckPointCell.setCellValue("");
                    }

                    count++;
                }
            }
            //将整理好的excel数据写入流中
            wb.write(os);
        } catch (IOException e) {
            throw e;
        } finally {
            try {
                // 关闭输出流
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                throw e;
            }
        }

    }

    /*
        设置浏览器下载响应头
     */
    private static void setResponseHeader(HttpServletResponse response, String fileName) throws Exception {
        fileName = new String(fileName.getBytes(),"ISO8859-1");
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
        response.addHeader("Pargam", "no-cache");
        response.addHeader("Cache-Control", "no-cache");

    }

    @Override
    @RequestMapping(value = "dutySelectListByCondition", method = RequestMethod.GET)
    public ResponseResult dutySelectListByCondition(String conditions) throws Exception {
        Map<String, Object> map = makeAllowData(conditions, true);
        ArrayList<String> allowFileds = (ArrayList<String>)map.get("allowFileds");
        Map<String, String> allowFiledsMap = (Map<String, String>)map.get("allowFiledsMap");
        Map conditionsMap = (Map)map.get("conditionsMap");

        List<CfCarParkUseLog> cfCarParks = cfCarParkUseLogService.selectListByCondition(conditionsMap, allowFiledsMap,allowFileds);
        Integer counts = cfCarParkUseLogService.selectListByConditionCounts(conditionsMap, allowFiledsMap, allowFileds);
        if(cfCarParks!=null && cfCarParks.size()>0){
            String fileSourceAddress = cfSystemConfigService.getValueByKey("file_source_address", "http://file.cfeng.wang/");
            for (CfCarParkUseLog cfCarParkUseLog: cfCarParks){
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "inSmallImage");
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "outSmallImage");
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "inBigImage");
                FileUtils.handleFileSourcePrefix(cfCarParkUseLog, fileSourceAddress, "outBigImage");
            }
            return new ResponseResult(CommonCode.SUCCESS, cfCarParks, null, counts);
        }
        return new ResponseResult(CommonCode.NO_MORE_DATAS);
    }

    /**
     * 制作条件搜索合法数据
     * @param conditions
     * @param isDuty    是否为值班人员擦好像
     * @return
     * @throws Exception
     */
    private Map<String,Object> makeAllowData(String conditions, boolean isDuty)throws Exception{
        UserBasicInfo userBasicInfo = AuthenticationInterceptor.parseJwt(HttpHearderUtils.getAuthorization(request));
        ArrayList<String> allowFileds = new ArrayList<>();
        allowFileds.add("id");
        allowFileds.add("number_plate");
        allowFileds.add("car_park_id");
        allowFileds.add("in_time");
        allowFileds.add("out_time");
        allowFileds.add("in_release_type");
        allowFileds.add("out_release_type");
        allowFileds.add("in_check_point_id");
        allowFileds.add("out_check_point_id");
        allowFileds.add("create_position");
        allowFileds.add("pay_time");
        allowFileds.add("create_time");
        allowFileds.add("in_handle_uid");
        allowFileds.add("out_handle_uid");
        allowFileds.add("status");
        allowFileds.add("car_owner_name");
        allowFileds.add("car_park_id$in");
        allowFileds.add("payment_agency_short_name$in");
        allowFileds.add("car_type");
        allowFileds.add("car_status");
        allowFileds.add("visit_unit");
        allowFileds.add("payment_agency_short_name");
        allowFileds.add("amounts_payable");
        allowFileds.add("amount_actually_paid");
        allowFileds.add("or_and");
        allowFileds.add("or_eq");
        allowFileds.add("like");
        allowFileds.add("group");
        allowFileds.add("order");
        allowFileds.add("limit");
        Map<String, String> allowFiledsMap = new HashMap<String, String>();
        allowFiledsMap.put("id","cpul");
        allowFiledsMap.put("number_plate","cpul");
        allowFiledsMap.put("car_park_id","cpul");
        allowFiledsMap.put("in_time","cpul");
        allowFiledsMap.put("out_time","cpul");
        allowFiledsMap.put("in_release_type","cpul");
        allowFiledsMap.put("out_release_type","cpul");
        allowFiledsMap.put("in_check_point_id","cpul");
        allowFiledsMap.put("out_check_point_id","cpul");
        allowFiledsMap.put("create_position","cpul");
        allowFiledsMap.put("pay_time","cpul");
        allowFiledsMap.put("create_time","cpul");
        allowFiledsMap.put("in_handle_uid","cpul");
        allowFiledsMap.put("out_handle_uid","cpul");
        allowFiledsMap.put("status","ord");
        allowFiledsMap.put("car_owner_name","cpp");
        allowFiledsMap.put("car_park_id$in","cpul");
        allowFiledsMap.put("car_type","cpul");
        allowFiledsMap.put("car_status","cpul");
        allowFiledsMap.put("visit_unit","cpul");
        allowFiledsMap.put("payment_agency_short_name","ord");
        allowFiledsMap.put("payment_agency_short_name$in","ord");
        allowFiledsMap.put("amounts_payable","ord");
        allowFiledsMap.put("amount_actually_paid","ord");
        allowFiledsMap.put("or_and","");
        allowFiledsMap.put("or_eq","");
        allowFiledsMap.put("like","");
        allowFiledsMap.put("group","");
        allowFiledsMap.put("order","");
        allowFiledsMap.put("limit","");

        Map<String, Object> map = new HashMap<>();
        map.put("allowFileds",allowFileds);
        map.put("allowFiledsMap",allowFiledsMap);

        Map conditionsMap = (JSONObject.parseObject(conditions));

        Map<String, String> paymentAgencyShortNameMap = (Map) conditionsMap.get("payment_agency_short_name");
        Map<String, String> feeMap = (Map) conditionsMap.get("is_fee");
        Map<String, String> typeKeyMap = (Map) conditionsMap.get("type_key");

        if(conditionsMap.containsKey("payment_agency_short_name") && paymentAgencyShortNameMap!=null){
            if(StringUtils.isNotEmpty(paymentAgencyShortNameMap.get("value")) && !paymentAgencyShortNameMap.get("value").equals("cash_pay_cny") && !paymentAgencyShortNameMap.get("value").equals("abnormal_termination_of_order")){
                HashMap<String, String> valueMap = new HashMap<>();
                valueMap.put("operator","in");
                valueMap.put("value","'wei_xin_pay_cny','ali_pay_cny','wei_xin_h5_pay_cny','ali_h5_pay_cny'");
                conditionsMap.put("payment_agency_short_name$in", valueMap);
                //干掉它
                conditionsMap.remove("payment_agency_short_name");
            }else if(StringUtils.isNotEmpty(paymentAgencyShortNameMap.get("value")) && paymentAgencyShortNameMap.get("value").equals("abnormal_termination_of_order") && conditionsMap.containsKey("or_and")){
                ((Map<String,Object>)conditionsMap.get("payment_agency_short_name")).put("or","1");
                ((Map<String, Object>) conditionsMap.get("or_and")).put("and","1");
            }
        }

        if(conditionsMap.containsKey("type_key") && typeKeyMap!=null && typeKeyMap.get("value").equals("temporary_car")){
            if(StringUtils.isNotEmpty(typeKeyMap.get("value")) && !typeKeyMap.get("value").equals("cash_pay_cny")){
                //干掉它
                conditionsMap.remove("type_key");
                //重制
                HashMap<String, String> valueMap = new HashMap<>();
                valueMap.put("operator","is");
                valueMap.put("value","null");
                conditionsMap.put("type_key", valueMap);
            }
        }

        if(isDuty && conditionsMap.containsKey("is_fee") && feeMap!=null){
            if(StringUtils.isNotEmpty(feeMap.get("value")) && feeMap.get("value").equals("fee")){
                HashMap<String, String> valueMap = new HashMap<>();
                valueMap.put("operator","in");
                valueMap.put("value","'wei_xin_pay_cny','ali_pay_cny','wei_xin_h5_pay_cny','ali_h5_pay_cny','cash_pay_cny'");
                conditionsMap.put("payment_agency_short_name$in", valueMap);

                HashMap<String, String> valueMap2 = new HashMap<>();
                valueMap2.put("operator","=");
                valueMap2.put("value","1");
                conditionsMap.put("status", valueMap2);
                //干掉它
                conditionsMap.remove("fee");
            }else if(StringUtils.isNotEmpty(feeMap.get("value")) && feeMap.get("value").equals("free")){
                HashMap<String, String> valueMap = new HashMap<>();
                valueMap.put("operator","in");
                valueMap.put("value","'system_free_time','coupon','package'");
                conditionsMap.put("payment_agency_short_name$in", valueMap);

                HashMap<String, String> valueMap2 = new HashMap<>();
                valueMap2.put("operator","=");
                valueMap2.put("value","1");
                conditionsMap.put("status", valueMap2);
                //干掉它
                conditionsMap.remove("fee");
            }
        }

        if(StringTools.findStringInArray(userBasicInfo.getRoleFlag().split(","), "admin")<0 && StringTools.findStringInArray(userBasicInfo.getRoleFlag().split(","), "finance")<0){
            CfCarParkLinkUserQuery cfCarParkLinkUserQuery = new CfCarParkLinkUserQuery();
            cfCarParkLinkUserQuery.setUid(userBasicInfo.getId());
            List<CfCarParkLinkUser> cfCarParkLinkUsers = cfCarParkLinkUserService.getListByQuery(cfCarParkLinkUserQuery);
            if(cfCarParkLinkUsers==null || cfCarParkLinkUsers.size()==0){
                ExceptionCast.cast(CommonCode.NO_MORE_DATAS);
            }
            String carParkIds = "";
            for (CfCarParkLinkUser cfCarParkLinkUser: cfCarParkLinkUsers){
                carParkIds += ",'"+cfCarParkLinkUser.getCarParkId()+"'";
            }
            carParkIds = carParkIds.substring(1);
            if(StringUtils.isNotEmpty(carParkIds)){
                HashMap<String, String> valueMap = new HashMap<>();
                valueMap.put("operator","in");
                valueMap.put("value",carParkIds);
                conditionsMap.put("car_park_id$in", valueMap);
            }
        }

        if(isDuty && StringTools.findStringInArray(userBasicInfo.getRoleFlag().split(","), "admin")<0){
            HashMap<String, Object> valueMap1 = new HashMap<>();
            HashMap<String, Object> valueMap2 = new HashMap<>();
//            valueMap2.put("cpul.in_handle_uid",userBasicInfo.getId());
//            valueMap2.put("cpul.out_handle_uid",userBasicInfo.getId());

            valueMap1.put("operator","or_eq");
            valueMap1.put("value",valueMap2);
            conditionsMap.put("or_eq", valueMap1);
        }

        map.put("conditionsMap",conditionsMap);

        return map;
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-getCarParkUseLogListByQuery')")
    @Override
    @RequestMapping(value = "getCarParkUseLogListByQuery", method = RequestMethod.GET)
    public ResponseResult getCarParkUseLogListByQuery(CfCarParkUseLogQuery cfCarParkUseLogQuery) throws Exception {
//        cfCarParkUseLogQuery.setOrderBy("cpul.create_time desc");
        List<CfCarParkUseLog> cfCarParkUseLogs = cfCarParkUseLogService.selectByQuery(cfCarParkUseLogQuery);
        if(cfCarParkUseLogs!=null && cfCarParkUseLogs.size()>0){
            return new ResponseResult(CommonCode.SUCCESS, cfCarParkUseLogs);
        }
        return new ResponseResult(CommonCode.NO_MORE_DATAS);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-delete')")
    @Override
    @RequestMapping(value = "delete", method = RequestMethod.DELETE)
    public ResponseResult delete(String id) {
        Integer delete = 0;
        if(id.indexOf(",")>-1){
            String[] ids = id.split(",");
            CfCarParkUseLogQuery cfCarParkUseLogQuery = new CfCarParkUseLogQuery();
            cfCarParkUseLogQuery.setIds(new ArrayList<>());
            for(int i = 0; i< ids.length; i++){
                cfCarParkUseLogQuery.getIds().add(ids[i]);
            }
            delete = cfCarParkUseLogService.deleteByQuery(cfCarParkUseLogQuery);
        }else{
            delete = cfCarParkUseLogService.delete(id);
        }
        if(delete==0){
            return new ResponseResult(CommonCode.FAIL);
        }
        return new ResponseResult(CommonCode.SUCCESS);
    }

    @Override
    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-countUseLogs')")
    @RequestMapping(value = "countUseLogs", method = RequestMethod.GET)
    public ResponseResult countUseLogs(CfCountCarParkUseLogQuery cfCountCarParkUseLogQuery) {
        if(cfCountCarParkUseLogQuery.getDate().equals("") || cfCountCarParkUseLogQuery.getDate().equals("null")){
            cfCountCarParkUseLogQuery.setDate(null);
        }
        if(cfCountCarParkUseLogQuery.getEndDate().equals("") || cfCountCarParkUseLogQuery.getEndDate().equals("null")){
            cfCountCarParkUseLogQuery.setEndDate(null);
        }
        if(cfCountCarParkUseLogQuery.getYear().equals("") || cfCountCarParkUseLogQuery.getYear().equals("null")){
            cfCountCarParkUseLogQuery.setYear(null);
        }
        if(cfCountCarParkUseLogQuery.getMonth().equals("") || cfCountCarParkUseLogQuery.getMonth().equals("null")){
            cfCountCarParkUseLogQuery.setMonth(null);
        }
        if(cfCountCarParkUseLogQuery.getDay().equals("") || cfCountCarParkUseLogQuery.getDay().equals("null")){
            cfCountCarParkUseLogQuery.setDay(null);
        }
        if(cfCountCarParkUseLogQuery.getCarparkId().equals("") || cfCountCarParkUseLogQuery.getCarparkId().equals("null")){
            cfCountCarParkUseLogQuery.setCarparkId(null);
        }

        if(cfCountCarParkUseLogQuery.getNumberPlate().equals("") || cfCountCarParkUseLogQuery.getNumberPlate().equals("null")){
            cfCountCarParkUseLogQuery.setNumberPlate(null);
        }
        if(cfCountCarParkUseLogQuery.getCountryId().equals("") || cfCountCarParkUseLogQuery.getCountryId().equals("null")){
            cfCountCarParkUseLogQuery.setCountryId(null);
        }
        if(cfCountCarParkUseLogQuery.getProvinceId().equals("") || cfCountCarParkUseLogQuery.getProvinceId().equals("null")){
            cfCountCarParkUseLogQuery.setProvinceId(null);
        }
        if(cfCountCarParkUseLogQuery.getStateOrCityId().equals("") || cfCountCarParkUseLogQuery.getStateOrCityId().equals("null")){
            cfCountCarParkUseLogQuery.setStateOrCityId(null);
        }
        if(cfCountCarParkUseLogQuery.getZoneOrCountyId().equals("") || cfCountCarParkUseLogQuery.getZoneOrCountyId().equals("null")){
            cfCountCarParkUseLogQuery.setZoneOrCountyId(null);
        }
        if(cfCountCarParkUseLogQuery.getTownshipId().equals("") || cfCountCarParkUseLogQuery.getTownshipId().equals("null")){
            cfCountCarParkUseLogQuery.setTownshipId(null);
        }
        List<CountByDay> list = null;
        switch (cfCountCarParkUseLogQuery.getCountType()){
            case "before_day_count_by_day":
                list = cfCarParkUseLogService.limitDaysCountByDay(cfCountCarParkUseLogQuery);
                break;
            case "month_count_by_day":
                list = cfCarParkUseLogService.yearMonthCountByDay(cfCountCarParkUseLogQuery);
                break;
            case "year_count_by_month":
                list = cfCarParkUseLogService.yearCountByMonth(cfCountCarParkUseLogQuery);
                break;
        }

        if(list==null || list.size()==0){
            return new ResponseResult(CommonCode.NO_MORE_DATAS);
        }
        return new ResponseResult(CommonCode.SUCCESS, list, cfCarParkUseLogService.getCountByQuery(new CfCarParkUseLogQuery()));
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-countPayAmountByDuty')")
    @Override
    @RequestMapping(value = "countPayAmountByDuty", method = RequestMethod.GET)
    public ResponseResult countPayAmountByDuty(CountPayAmountByDutyQuery countPayAmountByDutyQuery) throws Exception {
        if(StringUtils.isEmpty(countPayAmountByDutyQuery.getCountMode())){
            countPayAmountByDutyQuery.setCountMode("real_time");
        }
        UserBasicInfo userBasicInfo = AuthenticationInterceptor.parseJwt(HttpHearderUtils.getAuthorization(request));

        if(countPayAmountByDutyQuery.getCountMode().equals("real_time")){
            CfCarParkLinkUserQuery cfCarParkLinkUserQuery = new CfCarParkLinkUserQuery();
            cfCarParkLinkUserQuery.setUid(userBasicInfo.getId());
            cfCarParkLinkUserQuery.setPage(1);
            cfCarParkLinkUserQuery.setSize(1);
            List<CfCarParkLinkUser> cfCarParkLinkUsers = cfCarParkLinkUserService.getListByQuery(cfCarParkLinkUserQuery);
            if(cfCarParkLinkUsers!=null && cfCarParkLinkUsers.size()>0){
                countPayAmountByDutyQuery.setMinTime(cfCarParkLinkUsers.get(0).getStartDutyTime());
            }else{
                countPayAmountByDutyQuery.setMinTime(System.currentTimeMillis());
            }
        }else if(countPayAmountByDutyQuery.getCountMode().equals("day")){
            countPayAmountByDutyQuery.setMinTime(DateUtil.getSameDayMinOrMaxTimestamp("min"));
        }else{
            countPayAmountByDutyQuery.setMinTime(System.currentTimeMillis());
        }

        countPayAmountByDutyQuery.setHandleUid(userBasicInfo.getId());
        countPayAmountByDutyQuery.setMaxTime(DateUtil.maxMillisecondBaseOnTheDayToTimestamp(System.currentTimeMillis()));
        BigDecimal countPayAmountByDuty = cfCarParkUseLogService.countPayAmountByDuty(countPayAmountByDutyQuery);
        return new ResponseResult(CommonCode.SUCCESS, countPayAmountByDuty);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-capture')")
    @Override
    @RequestMapping(value = "capture", method = RequestMethod.GET)
    public ResponseResult capture(String sn) {
        CfCarParkDevice cfCarParkDevice = cfCarParkDeviceService.findByCode(sn, false);
        Object capture = cfCarParkReleaseLogService.capture(sn, cfCarParkDevice.getBrand(), 0);
        return new ResponseResult(CommonCode.SUCCESS, capture);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-countByQuery')")
    @Override
    @RequestMapping(value = "countByQuery", method = RequestMethod.GET)
    public ResponseResult countByQuery(CfCarParkUseLogQuery cfCarParkUseLogQuery) throws Exception {
        UserBasicInfo userBasicInfo = AuthenticationInterceptor.parseJwt(HttpHearderUtils.getAuthorization(request));
        if(StringTools.findStringInArray(userBasicInfo.getRoleFlag().split(","), "admin")<0){
            CfCarParkLinkUserQuery cfCarParkLinkUserQuery = new CfCarParkLinkUserQuery();
            cfCarParkLinkUserQuery.setUid(userBasicInfo.getId());
            List<CfCarParkLinkUser> cfCarParkLinkUsers = cfCarParkLinkUserService.getListByQuery(cfCarParkLinkUserQuery);
            if(cfCarParkLinkUsers==null || cfCarParkLinkUsers.size()==0){
                ExceptionCast.cast(CommonCode.NO_MORE_DATAS);
            }
            List<String> carParkIds = new ArrayList<>();
            for (CfCarParkLinkUser cfCarParkLinkUser: cfCarParkLinkUsers){
                carParkIds.add(cfCarParkLinkUser.getCarParkId());
            }
            cfCarParkUseLogQuery.setCarParkIds(carParkIds);
        }

        Integer countByQuery = cfCarParkUseLogService.countByQuery(cfCarParkUseLogQuery);
        return new ResponseResult(CommonCode.SUCCESS, null, countByQuery);
    }

    @PreAuthorize("hasAuthority('carpark-CfCarParkUseLogController-mergeCarUseLog')")
    @Override
    @RequestMapping(value = "mergeCarUseLog", method = RequestMethod.PUT)
    public ResponseResult mergeCarUseLog(String beforeCfCarParkUseLogId, String nowcfCarParkUseLogId, String numberPlate) throws Exception {
        UserBasicInfo userBasicInfo = AuthenticationInterceptor.parseJwt(HttpHearderUtils.getAuthorization(request));
        CfCarParkUseLog beforeCfCarParkUseLog = cfCarParkUseLogService.findById(beforeCfCarParkUseLogId, false);
        CfCarParkUseLog nowcfCarParkUseLog = cfCarParkUseLogService.findById(nowcfCarParkUseLogId, false);
        if(!beforeCfCarParkUseLog.getCarParkId().equals(nowcfCarParkUseLog.getCarParkId()) ||
                !nowcfCarParkUseLog.getOutHandleUid().equals(userBasicInfo.getId())){
            return new ResponseResult(CommonCode.UNAUTHORISE);
        }

        beforeCfCarParkUseLog.setOutTime(nowcfCarParkUseLog.getOutTime());
        beforeCfCarParkUseLog.setOutSmallImage(nowcfCarParkUseLog.getOutSmallImage());
        beforeCfCarParkUseLog.setOutBigImage(nowcfCarParkUseLog.getOutBigImage());
        beforeCfCarParkUseLog.setOutCheckPointId(nowcfCarParkUseLog.getOutCheckPointId());
        beforeCfCarParkUseLog.setOutHandleUid(nowcfCarParkUseLog.getOutHandleUid());
        if(StringUtils.isNotEmpty(numberPlate)){
            beforeCfCarParkUseLog.setNumberPlate(numberPlate);
        }else{
            beforeCfCarParkUseLog.setNumberPlate(nowcfCarParkUseLog.getNumberPlate());
        }
        CfCarParkUseLog newcfCarParkUseLog = cfCarParkUseLogService.update(beforeCfCarParkUseLog);

        cfCarParkUseLogService.delete(nowcfCarParkUseLogId);

        return new ResponseResult(CommonCode.SUCCESS, newcfCarParkUseLog);
    }
}

2、功能清单

2.1、系统功能一览表

1. 智慧停车

支持模式

    • 封闭性单个停车场
    • 路边停车(车位级管理)
    • 大小场(场中场),多场子并行或嵌套

所有者模式

    • 统一平台管理
    • 总平台下子账号(区域代理)自建场地资源,自行维护数据
    • 总平台下子账号(区域代理)再分配和单个停车场管理人员(物业管理/维保/保安/财务等人员)

场站管理

    • 车位控制】 > 精准的实时车位统计和数据及时推送到场地led/lcd屏幕,车位满后禁止车辆进入
    • 责任制】 > 每个场地标记所有者,负责人信息,有需要直连联系实际控制负责人
    • 完整证据链】 > 详细实时记录每一辆车进出时间/场地/进出口/值班人员/图片/视频/金额/优惠/车辆情况(车辆类型|套餐|颜色|品牌)/开闸情况

值班调度

    • 值守模式】 > 支持有人值守/无人值守/统一远程值守调度,数字数据全自动化录入,处理,资产数据产出并计算汇报展现
    • 重复过滤】 > 支持入场二次确认,避免路过和倒车车辆误拍产生歧义账单。短时间内重复多次抓拍只记录一条数据
    • 无处可逃】 > 出场跟车逃费标记,逃费入场提示追缴,补缴入场。支持单场追缴和全网追缴。黑名单通知,违法在逃车辆协同公安网络实时上报
    • 万无一失】 > 入场车牌识别错误可手动校正车牌,出场识别错误自动模糊相似车牌尝试匹配
    • 应急响应】 > 支持一键放行,处理紧急情况,手动免单。支持远程可视对讲。
    • 特殊群体】 > 支持自定义公务车自动免单放行,例如警车,军车,大使馆车,消防车等
    • 断电断网】 > 断电支持值守人员手机一键进出场拍照录入,入场录入人工放行入场,出场时值守人员向车主展示账单,车主扫码支付离场。 > 断网支持硬件设备白名单快速自动放行。保障断网解决方案:增加车牌识别相机4G模块/或者使用双网络路由器(4G/有线智能切换)
    • 安保互动】 > 支持入场时值守人员留言,出场时备注留言提示
    • 一码识车】 > 新车无牌/车牌受污/车牌变形/非常规车牌无法识别/三轮代步车等,一键扫码自助入场,扫码缴费出场。公众号/小程序/APP数据一号互通

进出控制与显示

    • 私人定制】 > 支持自定义车辆类型,每个停车场都可以单独对每种车辆类型设定独立的进出收费规则,放行规则,文字播报,语音提示,图片,视频等 > 例如黑名单禁止入场,且禁止录入数据,并提示。免费车,在有效期内,享受不一样的停车特权
    • 停车VIP】 > 每个停车场都可以独立发行内部和公开的车辆套餐产品,车主可以通过手机端新购和续费停车套餐,生效期进出无阻,套餐即将过期通知续费 > 例如黑名单禁止入场,且禁止录入数据,并提示。免费车,在有效期内,享受不一样的停车特权
    • 特殊车辆】 > 例如日包车(白天停车免费),夜包车(晚上停车免费)。支持特殊车辆自助购买和续费,弥补车辆套餐不够灵活的缺陷

车位管理

    • 多位多车】 > 支持一位多车和多位多车自动切换享受套餐停车特权
    • 神圣私产】 > 支持车位级别管理,车位主人一键扫码升降地锁
    • 车位共享】 > 支持公共车位扫码降锁入位,计时,超时扫码缴费降锁离场
    • 快速停车】 > 手机端实时数据显示当前位置和目的地附近停车场车位情况(余位/价格/免停时长/禁停时段/车场图片/具体位置),可一键导航到空位车
    • 反向寻车】 > 面对复杂多层大型停车场(例如:大型商场地下停车场,机场,超大型立体停车楼等),忘记了自己停在几楼哪个车位,利用车位相机自动记录 > 您车辆所在楼层和车位,使用室内导航实时引导您走到你的车辆跟前,导航精度0.5米左右

2. 智慧充电

新能源汽车充电

两轮/三轮电动车充电

3. 智慧社区

社区管理

物业管理

人脸门禁

上门维修

4. 电子支付

本平台聚合支付

第三方聚合支付

银行支付

无感支付

5. 用户资源

权限分配

资源分配

3、硬件设置

3.1、车牌识别相机设置

3.1.1、千熠相机

3.1.1.1、MQTT协议连接云平台

【注意事项】:

平台域名:39.174.170.81 平台端口:9004 ①:平台用户名,在录入设备到管理后台之后会有一条硬件数据,将该数据id作为用户名,如下图,复制id过来

②:平台密码,要与后台管理设备中的”设备登录密码“ 保持一致

③:设备类型标识符,要与后台管理设备中的”产品key“ 保持一致

④:设备品类密钥,忽略,不管它

⑤:客户端id,请填写该设备的”序列号“ ⑥:结果与图片:分开上传 ⑦:协议类型:阿里云 ⑧:存储域名:cfzh.oss-cn-shanghai.aliyuncs.com ⑨:存储账号:0zbW2BuyAoIHePXJhVYXeKBWOfNxaD ⑩:存储密码:远程(向日葵,或者 todesk)给我们,我们工作人员帮你填 11:发送图片/发送小图 都勾上

3.1.2、臻识相机

3.1.2.1、先让设备能联网

3.1.3.1、R3/C3/R5系列

3.1.4.1、RM系列

3.1.6、华夏相机

3.1.6.1、V85系列

3.1.7.1、V87系列

3.1.9、海康相机

3.1.10、大华相机

4、环境部署

4.1、准备工作

4.1.1、服务器

操作系统 建议Centos7.5以上 后续所有教程都是基于Linux Centos 操作系统进行的

请准备 最低64核128G 100M带宽 硬盘1T起步 的服务器

本系统为超级系统,真刀真枪干大事,不是小打小闹。要私有化部署的,请提前合理规划自己的资源和预算。

4.1.2、同步服务器时间

安装插件: yum -y install ntp ntpdate

同步阿里云时间: ntpdate time1.aliyun.com

设置时区: timedatectl set-timezone Asia/Shanghai

将系统时间同步到硬件: hwclock -w

查看系统时间: date

查看硬件时间: hwclock

4.2、基础环境

4.2.1、安装java基础JDK

4.2.1.1、JDK1.8安装

1. 下载

下载地址:https://www.oracle.com/java/technologies/downloads/#java8

【选择版本】: > 选择你对应的版本,如果不知道你系统是多少位,使用命令查看getconf LONG_BIT,如果显示64,说明你系统是64位,请选择 x64 Compressed Archive 下载选择你对应的版本,如果不知道你系统是多少位,使用命令查看getconf LONG_BIT,如果显示64,说明你系统是64位,请选择 x64 Compressed Archive 下载

【解压复制】

*注意,如果你下载的文件名跟老王的不一样,请根据实际情况执行命令

解压 > tar -zxvf jdk-8u371-linux-x64.tar.gz 

复制 > 解压 tar -zxvf jdk-8u371-linux-x64.tar.gz 复制 cp jdk1.8.0_371 /usr/local/jdk1.8.0_371 -r``cp jdk1.8.0_371 /usr/local/jdk1.8.0_371 -r

2. 设置环境变量

【修改对应配置文件】

> 打开文件vim /etc/profile 追加内容 export JAVA_HOME=/usr/local/jdk1.8.0_371 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH 保存并退出

【修改对应配置文件】: > 刷新加载环境变量配置source /etc/profile

【验证是否安装成功】

> 执行指令java -version

如果显示 例如

java version "1.8.0_371" Java(TM) SE Runtime Environment (build 1.8.0_371-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.371-b11, mixed mode)

说明安装成功 牛逼666

4.2.1.2、JDK20安装

4.2.1.3、生成jks文件和公钥

1. 进入到java的bin目录下,执行如下指令

keytool -genkeypair -alias cfzh -keyalg RSA -keypass 这里填你的密码 -keystore cfzh.jks -storepass 这里填你的仓库密码

> -genkey 在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书 (在没有指定生成位置的情况下,keystore会存在用户系统默认目录,如:对于window xp系统,会生成在系统的C:/Documents and Settings/UserName/文件名为“.keystore”) -alias 产生别名 -keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中) -keyalg 指定密钥的算法 (如 RSA DSA(如果不指定默认采用DSA)) -validity 指定创建的证书有效期多少天 -keysize 指定密钥长度 -storepass 指定密钥库的密码(获取keystore信息所需的密码) -keypass 指定别名条目的密码(私钥的密码) -dname 指定证书拥有者信息 例如: "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码" -list 显示密钥库中的证书信息 keytool -list -v -keystore 指定keystore -storepass 密码 -v 显示密钥库中的证书详细信息 -export 将别名指定的证书导出到文件 keytool -export -alias 需要导出的别名 -keystore 指定keystore -file 指定导出的证书位置及证书名称 -storepass 密码 -file 参数指定导出到文件的文件名 -delete 删除密钥库中某条目 keytool -delete -alias 指定需删除的别 -keystore 指定keystore -storepass 密码 -printcert 查看导出的证书信息 keytool -printcert -file yushan.crt -keypasswd 修改密钥库中指定条目口令 keytool -keypasswd -alias 需修改的别名 -keypass 旧密码 -new 新密码 -storepass keystore密码 -keystore sage -storepasswd 修改keystore口令 keytool -storepasswd -keystore e:/yushan.keystore(需修改口令的keystore) -storepass 123456(原始密码) -new yushan(新密码) -import 将已签名数字证书导入密钥库 keytool -import -alias 指定导入条目的别名 -keystore 指定keystore -file 需导入的证书 -storetype 生成证书类型(格式:标准pkcs12)

2. 如果你需要导出 cer 格式证书,请执行如下命令

keytool -alias cfzh -exportcert -keystore cfzh.jks -file cfzh.cer

3. 导出密钥,注意,这个的前提是你已经安装了openssl软件,如果没有安装,请到这下载(https://slproweb.com/products/Win32OpenSSL.html ),然后安装,安装完之后,记得添加一下 openssl的bin目录到环境变量path中

keytool -list -rfc --keystore cfzh.jks | openssl x509 -inform pem -pubkey

4.2.2、安装数据库

4.2.2.1、MySQL

4.2.3.1、OceanBase

4.2.4.1、TiDB

4.2.6、文件服务

4.2.6.1、FastDFS

4.2.7.1、MiNiO

4.2.8.1、阿里云OSS

4.2.9.1、七牛云存储

4.2.11、安装nacos

4.2.12、安装Docker

4.2.12.1、安装

1、首先升级一下yum(高版本的操作系统不推荐使用此命令)

yum update

其实,也可以不升级,如果系统已经安装了其他的软件运行环境,就不要升级,我是因为之前被低版本的yum坑过,所以首先都会跑一下这个命令;

当yum不可用的时候,可以参考这篇文章 https://www.cnblogs.com/ryanzheng/p/11263388.html

2、如果之前安装过docker,要先把docker卸载

> yum remove docker \                   docker-client \                   docker-client-latest \                   docker-common \                   docker-latest \                   docker-latest-logrotate \                   docker-logrotate \                   docker-engine

3、安装所需的软件包。yum-utils 提供了 yum-config-manager,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2 3、安装所需的软件包。yum-utils 提供了 yum-config-manager,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2

yum install -y yum-utils device-mapper-persistent-data lvm2

4、设置稳定的源,我选择的是清华大学的源地址,你也可以设置阿里云或者其他的

yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

5、安装 Docker Engine-Community

yum install docker-ce docker-ce-cli containerd.io

至此Docker已经安装成功,下面开始启动Docker

6、启动Docker

systemctl start docker

7、设置开机启动

systemctl enable docker

8、运行一条Docker的命令

docker images

9、如果出现以上图片的结果,表示Docker已经安装成功

4.2.13、安装Elasticsearch搜索引擎

4.2.13.1、Docker方式安装

1,取一个镜像,然后运行一下

docker pull elasticsearch:7.17.5

2、创建对应的挂载目录

> mkdir -p /cf/data/elasticsearch/config mkdir -p /cf/data/elasticsearch/data mkdir -p /cf/data/elasticsearch/plugins

3、设置对应的权限

chmod 777 /cf/data/elasticsearch/data

4、创建配置文件,并配置内容

> touch /cf/data/elasticsearch/config/elasticsearch.yml vim /cf/data/elasticsearch/config/elasticsearch.yml

5、配置文件内容如下:

network.host: 0.0.0.0 http.host: 0.0.0.0 cluster.name: "cfzh_cluster" http.cors.enabled: true http.cors.allow-origin: "*"

6、安装ik分词器

找到对应版本的ik分词器进行下载,例如我这里是 7.17.5,我下载地址为:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.17.5 如果你的版本不是这个版本,可以到这去选:https://github.com/medcl/elasticsearch-analysis-ik/releases 下载之后得到一个zip压缩包,

创建一个目录:

mkdir -p /cf/data/elasticsearch/plugins/ik

将压缩包上传到该 /cf/data/elasticsearch/plugins/ik 该目录下,然后解压该压缩包:

unzip elasticsearch-analysis-ik-7.17.5.zip

7、最后启动容器

docker run --name elasticsearch_a -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms84m -Xmx512m" -v /cf/data/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /cf/data/elasticsearch/data:/usr/share/elasticsearch/data -v /cf/data/elasticsearch/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.17.5

8、访问一下Elasticsearch的地址(注意,IP根据你自己的实际情况,这里的 192.168.0.10只是示例

4.2.14、seata分布式事务

4.2.14.1、1.4.2

4.2.15.1、1.6.1

4.2.17、sentinel熔断降级

5、使用手册

5.1、资料和账号准备

5.1.1、前言

很多东西可以同时准备,微信和支付宝平台审核需要一点时间。

所有东西都必须基于企业或者个体工商户或者组织等身份。个人开发者不要注册,注册了也会用不了。

5.1.2、微信公众号

注册(原来已经有公众号的可以忽略这步)

登录微信公众号注册官网页面:https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN

选择:服务号,下一步填写相关资料,注意邮箱和密码自己要记住,微信这个机制很搞人,忘记密码了很麻烦

登录微信公众号后台

进入微信公众号管理后台页面:https://mp.weixin.qq.com/

【原来已经有公众号的可以忽略下面的资料完善】

使用你的微信扫码,选择你对应的 公众号登录,首次注册可能需要你完善你自己的资料,按实际情况填写

认证微信公众号后台

如果你的公众号没有认证,记得认证一下。

目前公众号我们虽然没使用到,但是不排除后期有使用到,因为公众号在通知方面比较方便。

5.1.3、微信小程序

注册(原来已经有小程序的可以忽略这步)

进入微信公众号管理后台页面:https://mp.weixin.qq.com/,记得选择 “公众号”登录,因为这里我们要基于你的公众号注册小程序,因为这样可以免掉

你小程序的认证时间和费用

配置小程序开发人员

进入微信公众号管理后台页面:https://mp.weixin.qq.com/,记得选择 “小程序”登录

如果你们自己有前端人员开发,请在下面的把相关前端人员加进去,方便前端人员帮你开发和发布。如果需要我们帮忙发布小程序的

,请添加我们的前端开发人员(才风官方前端开发人员微信号:Tudutu) 到你们小程序的开发者列表中去。

配置开发者选项

设置你的小程序密码(如果原来已经设置了,且有其它平台在用,这里慎重 重新生成)

将开发者账号填入到我们后台

https://www.showdoc.com.cn/cfzhv3/10325061916555549

配置小程序调用域名

你自己的域名可以直接解析到我们服务,也可以自己的服务器转发到我们服务器,都支持的!如果没有域名的老板,我们会默认免费提供一个二级域名

配置小程序二维码链接

为啥要配置这个呢?

方便微信扫码之后,直接跳转到指定的小程序页面,不需要经过其它业务和操作,稳定以及效果体验好,小程序也方便你广告投放并获得收益

> 前缀占用规则:请选择“不占用”

示例数据: > 关卡扫码支付离场:你的域名 /scene/carParkFee/checkPointId/
 小程序页面:/pages/pay/scanCode

> 二轮充电地址:
 /scene/bicycleCharging/chargingStationId/小程序页面:/pages/pay/scanCode

> 四轮充电地址:
/scene/electricVehicleCharging/chargingStationId/ 小程序页面:/pages/pay/scanCode

> 无牌车入场扫码地址:/scene/licensePlateRecognition/deviceId/
 小程序页面:/pages/my/noLicencePlateCar

> 地锁升降锁地址(扫码降锁入场,扫码支付降锁离场):
/scene/parkingLock/deviceId/ 小程序页面:/pages/my/noLicencePlateCar

5.1.4、微信开放平台

注册(原来已经有微信开放平台的可以忽略这步)

认证通过后,将微信小程序绑定到 开放平台上

公众号/小程序/APP等都可以绑定过来

5.1.5、开通微信服务商

科普:啥是服务商?

腾讯微信支付---->你(服务商)---->子商户(小卖部/物业公司/业委会/其它单位或个体)

服务商有哪些好处:

> ①:你可以帮任何个人(个体工商户)/公司企业/组织 等快速申请收款账号,对方只需要提供(支行名称,银行账号,手机号,邮箱,身份证正反面照片)给你,你直接帮其进件,免去了对方还要注册啥公众号或者小程序等复杂问题,审核通过之后 子商户收的每一笔默认 给你返佣千4,即 对方收入1000元,腾讯公司会自动给划其中4元给你,自动到你微信账户(需要自己手动提现) ②:费率可调,调整每个子商户的费率后,你的收益会有影响 ③:点金计划,支付完成后可以跳转到指定的广告页面,广告费微信给你结算

注册地址

https://pay.weixin.qq.com/partner/public/home

5.1.6、支付宝小程序

注册支付宝企业开发者账号

https://open.alipay.com/  浏览器访问这个地址进行注册

登录支付宝开发者账号

进入控制台

创建你的支付宝小程序应用

创建应用

创建小程序完成之后,把开发者账号填入到后台

https://www.showdoc.com.cn/2192066741521376/10325063479611314

5.1.7、APP支付

> 提前给您打个预防针,这个没有1-2个月搞不下来,要用APP的请提前准备好资料。没有APP源代码用户,忽略此项,直接使用我们才风官方APP即可

准备软著

提供APP部分源代码给软著中介公司,支付 1000-5000元不等费用,等待1-3个月时间,请自行联系当地软著代办斯

微信APP支付

登录微信开放平台(https://open.weixin.qq.com/),添加移动应用,注意安卓和ios都要考虑到

支付宝APP支付

登录支付宝开放平台(https://open.alipay.com/),添加网页移动应用,注意安卓和ios都要考虑到

5.2、后台管理

5.2.1、用户中心

5.2.1.1、用户列表

该功能只有超级管理员和私有化部署才能拥有

可以直接后台 新增/修改/删除 用户,操作用户所有基础信息数据

列表

编辑

注意不要随意删除用户,否则其相关资产(停车月卡,特殊车辆,绑定车辆,用户证件,账单,充电,业主,人脸门禁,账户钱包等)会被一起删除

5.2.1.2、用户中心

所有管理用户(超级管理员/独立运营商/共享运营商/物业管理员/员工/财务等)都拥有的功能界面

方便自行后台修改自己的基础信息,当然也可以在手机APP和小程序上修改自己的用户基础信息,多端数据同步的

5.2.1.1、权限

5.2.1.1.1、用户列表

该功能只有超级管理员和私有化部署才能拥有

可以直接后台 新增/修改/删除 用户,操作用户所有基础信息数据

列表

编辑

注意不要随意删除用户,否则其相关资产(停车月卡,特殊车辆,绑定车辆,用户证件,账单,充电,业主,人脸门禁,账户钱包等)会被一起删除

5.2.1.1.1、用户中心

所有管理用户(超级管理员/独立运营商/共享运营商/物业管理员/员工/财务等)都拥有的功能界面

方便自行后台修改自己的基础信息,当然也可以在手机APP和小程序上修改自己的用户基础信息,多端数据同步的

5.2.2.1、角色

5.2.2.1.1、用户列表

该功能只有超级管理员和私有化部署才能拥有

可以直接后台 新增/修改/删除 用户,操作用户所有基础信息数据

列表

编辑

注意不要随意删除用户,否则其相关资产(停车月卡,特殊车辆,绑定车辆,用户证件,账单,充电,业主,人脸门禁,账户钱包等)会被一起删除

5.2.2.1.1、用户中心

所有管理用户(超级管理员/独立运营商/共享运营商/物业管理员/员工/财务等)都拥有的功能界面

方便自行后台修改自己的基础信息,当然也可以在手机APP和小程序上修改自己的用户基础信息,多端数据同步的

5.2.3.1、开发者账号

5.2.3.1.1、用户列表

该功能只有超级管理员和私有化部署才能拥有

可以直接后台 新增/修改/删除 用户,操作用户所有基础信息数据

列表

编辑

注意不要随意删除用户,否则其相关资产(停车月卡,特殊车辆,绑定车辆,用户证件,账单,充电,业主,人脸门禁,账户钱包等)会被一起删除

5.2.3.1.1、用户中心

所有管理用户(超级管理员/独立运营商/共享运营商/物业管理员/员工/财务等)都拥有的功能界面

方便自行后台修改自己的基础信息,当然也可以在手机APP和小程序上修改自己的用户基础信息,多端数据同步的

5.2.5、支付

5.2.6、物联网

5.2.6.1、停车

5.2.7.1、充电

5.3、APP

5.4、小程序

5.4.1、微信

5.4.2、支付宝

5.5、公众号

5.5.1、微信

5.5.2、支付宝

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值