jiangping
2025-02-28 69283b5a4559509187516355602e32e4bdac9d5d
Merge remote-tracking branch 'origin/2.0.1' into 2.0.1
已添加2个文件
已修改43个文件
1436 ■■■■■ 文件已修改
admin/package-lock.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/combo.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/base/BasePageTemp.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/Paginations.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/bikeRepair.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/bikeRetakeRecord.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/goodsorder.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/memberRides.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/onlinePayStatistics.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/components/ComboDetail.vue 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/components/Edit.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/components/OrderDetail.vue 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/components/Refund.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/components/SaleDetail.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/index.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/order.vue 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/combo/record.vue 396 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/test/java/org/yzh/protocol/TestHex.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/java/com/doumee/api/business/DiscountController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/java/com/doumee/api/business/DiscountMemberController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/java/com/doumee/api/business/GoodsorderController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/platform/src/main/java/com/doumee/task/ScheduleTool.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/biz/system/impl/SystemDictDataBizImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/constants/Constants.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/DateUtil.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/wx/SendWxMessage.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Discount.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/DiscountLog.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/DiscountMember.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/vo/DiscountGoodsorderExportVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/web/response/MemberRidesDetailResponse.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/web/response/MemberRidesResponse.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/BikesServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/DiscountLogServiceImpl.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/DiscountMemberServiceImpl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/DiscountServiceImpl.java 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/MemberRidesServiceImpl.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/TransactionsServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/resources/application-dev.yml 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/web/BusinessApi.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/jtt808/web/service/Jtt808Service.java 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/package-lock.json
@@ -5266,6 +5266,11 @@
      "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
      "dev": true
    },
    "dayjs": {
      "version": "1.11.13",
      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
    },
    "de-indent": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
admin/package.json
@@ -21,6 +21,7 @@
    "@wangeditor/editor-for-vue": "^1.0.2",
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "dayjs": "^1.11.13",
    "echarts": "^5.4.2",
    "ele-calendar": "^2.0.0",
    "element-ui": "^2.15.13",
admin/src/api/business/combo.js
@@ -10,6 +10,15 @@
    trim: true
  })
}
export function comboUpdatePost(data) {
  return request.post('/business/discount/updStatus', data, {
    trim: true
  })
}
export function comboDelPost(id) {
  return request.get(`/business/discount/delete/${id}`)
}
export function comboListPost(data) {
  return request.post('/business/discount/page', data, {
    trim: true
@@ -51,3 +60,33 @@
    download: true
  })
}
export function comboSalePage(data) {
  return request.post('/business/discountMember/page', data, {
    trim: true
  })
}
export function comboSaleEx(data) {
  return request.post('/business/discountMember/exportExcel', data, {
    trim: true,
    download: true
  })
}
export function comboSaleAdjust(data) {
  return request.post('/business/discountMember/adjust', data, {
    trim: true
  })
}
export function comboSaleCancel(data) {
  return request.post('/business/discountMember/cancel', data, {
    trim: true
  })
}
export function comboSalerDetailPost(id) {
  return request.get('/business/discountMember/' + id)
}
export function discountLogLog(data) {
  return request.post('/business/discountLog/page', data, {
    trim: true
  })
}
admin/src/components/base/BasePageTemp.vue
@@ -1,5 +1,5 @@
<script>
import Pagination from '@/components/common/Pagination'
import Pagination from '@/components/common/Paginations'
import QueryForm from '@/components/common/QueryForm'
export default {
  name: 'BasePageTemp',
@@ -26,6 +26,8 @@
      this.filters = {}
      this.pagination.pageSize = 10
      this.pagination.page = 1
      console.log('-----');
      this.getList()
    },
    handleSizeChange(capacity) {
admin/src/components/common/Paginations.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
<template>
  <div class="table-pagination">
    <el-pagination
      :current-page="pagination.page"
      :page-sizes="pagination.pageSizes||[10, 20, 30, 40]"
      :page-size="pagination.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="pagination.total"
      @size-change="sizeChange"
      @current-change="currentChange"
      background>
    </el-pagination>
  </div>
</template>
<script>
export default {
  name: 'Pagination',
  props: {
    pagination: {
      type: Object,
      default: function () {
        return {}
      }
    }
  },
  data () {
    return {
    }
  },
  methods: {
    sizeChange (value) {
      this.$emit('size-change', value)
    },
    currentChange (value) {
      this.$emit('current-change', value)
    }
  }
}
</script>
admin/src/views/business/bikeRepair.vue
@@ -107,7 +107,7 @@
import Pagination from '@/components/common/Pagination'
import OperaRepairDealWindow from '@/components/business/OperaRepairDealWindow'
import RepairDetailWindow from '@/components/business/RepairDetailWindow'
import { formatDateTime } from '@/utils/util'
import dayjs from 'dayjs'
import { getFileList } from '@/api/business/bikeRepair'
export default {
  name: 'BikeRepair',
@@ -150,7 +150,8 @@
      'field.id': 'id',
      'field.main': 'id'
    })
    // this.searchForm.startDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 00:00:00'
    this.searchForm.startDate = dayjs().format('YYYY-MM-DD') + ' 00:00:00'
    this.searchForm.endDate = dayjs().format('YYYY-MM-DD') + ' 23:59:59'
    this.search()
  },
  methods: {
admin/src/views/business/bikeRetakeRecord.vue
@@ -106,7 +106,7 @@
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import { formatDateTime } from '@/utils/util'
import dayjs from 'dayjs'
export default {
  name: 'MemberRides',
  extends: BaseTable,
@@ -165,8 +165,8 @@
      'field.id': 'id',
      'field.main': 'id'
    })
    // this.searchForm.startDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 00:00:00'
    // this.searchForm.endDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 23:59:59'
    this.searchForm.startDate = dayjs().format('YYYY-MM-DD') + ' 00:00:00'
    this.searchForm.endDate = dayjs().format('YYYY-MM-DD') + ' 23:59:59'
    this.search()
  },
  methods: {
admin/src/views/business/goodsorder.vue
@@ -116,7 +116,7 @@
import GoodsOrderDetail from '@/components/business/goodsOrderDetail'
import BackGoodsorderWindow from '@/components/business/backGoodsorderWindow'
import { getDetail, getGoodsorderCanBanlanceDTO, closerGoodsorder } from '@/api/business/goodsorder'
import { formatDateTime } from '@/utils/util'
import dayjs from 'dayjs'
export default {
  name: 'Goodsorder',
  extends: BaseTable,
@@ -159,7 +159,8 @@
      'field.id': 'id',
      'field.main': 'id'
    })
    // this.searchForm.startDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 00:00:00'
    this.searchForm.startDate = dayjs().format('YYYY-MM-DD') + ' 00:00:00'
    this.searchForm.endDate = dayjs().format('YYYY-MM-DD') + ' 23:59:59'
    this.search()
  },
  methods: {
admin/src/views/business/memberRides.vue
@@ -108,7 +108,7 @@
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import { formatDateTime } from '@/utils/util'
import dayjs from 'dayjs'
export default {
  name: 'MemberRides',
  extends: BaseTable,
@@ -167,6 +167,8 @@
      'field.id': 'id',
      'field.main': 'id'
    })
    this.searchForm.startDate = dayjs().format('YYYY-MM-DD') + ' 00:00:00'
    this.searchForm.endDate = dayjs().format('YYYY-MM-DD') + ' 23:59:59'
    // this.searchForm.startDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 00:00:00'
    // this.searchForm.endDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 23:59:59'
    this.search()
admin/src/views/business/onlinePayStatistics.vue
@@ -55,7 +55,7 @@
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import { fetchList } from '@/api/business/onlinePayStatistics'
import { formatDateTime } from '@/utils/util'
import dayjs from 'dayjs'
export default {
  name: 'PricingParam',
  extends: BaseTable,
@@ -71,7 +71,8 @@
    }
  },
  created () {
    // this.searchForm.startDate = formatDateTime(new Date(), 'yyyy-MM-dd') + ' 00:00:00'
    this.searchForm.startDate = dayjs().format('YYYY-MM-DD') + ' 00:00:00'
    this.searchForm.endDate = dayjs().format('YYYY-MM-DD') + ' 23:59:59'
    this.search()
  },
  methods: {
admin/src/views/combo/components/ComboDetail.vue
@@ -10,13 +10,13 @@
              <span class="title">{{ detail.name }}</span>
              <span class="status">{{ detail.status == '0' ? '已启用' : '禁用' }}</span>
            </div>
            <div class="placeholder9 mt10">每日销售限量:{{ detail.saleDayLimit }}</div>
            <div class="placeholder9 mt10">每日销售限量:{{ detail.saleDayLimit || '不限额' }}</div>
          </div>
        </div>
        <div class="right">
          <div class="item">
            <div class="key">总发放数量</div>
            <div class="value">{{ detail.saleLimit || '不限额' }}</div>
            <div class="value">{{ detail.saleLimit || '-' }}</div>
          </div>
          <div class="item">
            <div class="key">已销售数量</div>
@@ -25,15 +25,15 @@
          <div class="item">
            <div class="key">剩余数量</div>
            <div v-if="detail.saleLimit" class="value">{{ detail.saleLimit - detail.saleNum }}</div>
            <div v-else class="value">不限额</div>
            <div v-else class="value">-</div>
          </div>
        </div>
      </div>
      <div class="createTime_wrap">
        <span class="item">创建时间:{{ detail.createDate }}</span>
        <span class="item">创建人:{{ detail.creator }}</span>
        <span class="item">创建人:{{ detail.creatorName }}</span>
        <span class="item">最后更新时间:{{ detail.editDate }}</span>
        <span class="item">更新人:{{ detail.editor }}</span>
        <span class="item">更新人:{{ detail.editorName }}</span>
      </div>
    </div>
    <div class="separate" />
@@ -55,7 +55,7 @@
    <div class="line">
      <div class="key">套餐简介:</div>
      <div class="value">
        <div>{{ detail.desc }}</div>
        <div>{{ detail.descs }}</div>
      </div>
    </div>
@@ -66,22 +66,22 @@
    </div>
    <div class="line">
      <div class="key">使用时间:</div>
      <div class="value" v-if="detail.useType == 0">{{ detail.useStartDate }} è‡³ {{ detail.useEndDate }}</div>
      <div class="value" v-if="detail.useType == 1">购买后{{ detail.useDays }}天内有效</div>
      <div class="value" v-if="detail.useType == 2">自{{ detail.useStartDate }} åŽ {{ detail.useDays }}天内有效</div>
      <div class="value" v-if="detail.useType == 0">{{ detail.useStartDate }} è‡³ {{ detail.useEndDate }}内有效</div>
      <div class="value" v-if="detail.useType == 1">购买后立即生效,有效期{{ detail.useDays }}天</div>
      <div class="value" v-if="detail.useType == 2">自{{ detail.useStartDate }}èµ·{{ detail.useDays }}天内有效</div>
    </div>
    <div class="line">
      <div class="key">适用范围:</div>
      <div class="value">{{ detail.useWorkday == 1 && '工作日' }} {{ detail.useWorkday && detail.useHoliday && '|' }} {{ detail.useHoliday == 1 && '节假日' }}</div>
      <div class="value">{{ detail.useWorkday == 1 ? '工作日' : ''}} {{ detail.useWorkday && detail.useHoliday ? '|' : '' }} {{ detail.useHoliday == 1 ? '节假日' : '' }}</div>
    </div>
    <div class="line">
      <div class="key">适用项目:</div>
      <div class="value">{{ detail.isbike == 1 && '自行车' }} {{ detail.isbike && detail.iselecbike && '|' }} {{ detail.iselecbike == 1 && '电动车' }}</div>
      <div class="value">{{ detail.isbike == 1 ? '自行车' : '' }} {{ detail.isbike && detail.iselecbike ? '|' : '' }} {{ detail.iselecbike == 1 ? '电动车' :'' }}</div>
    </div>
    <div class="line">
      <div class="key">总限额:</div>
      <div class="value">{{ detail.saleLimit || '不限制' }}</div>
      <div class="value">{{ detail.saleLimit || '不限额' }}</div>
    </div>
    <div class="line">
      <div class="key">每日限额:</div>
admin/src/views/combo/components/Edit.vue
@@ -100,13 +100,13 @@
        </div>
      </el-form-item>
      <el-form-item label="总限额">
        <el-input class="w400" v-model="param.saleLimit" oninput="value=value.replace(/^(0+)|[^\d]+/g, '').slice(0, 12)"
        <el-input class="w400" v-model="param.saleLimit" oninput="value=value.replace(/^(-1+)|[^\d]+/g, '').slice(0, 12)"
          placeholder="请输入总发售数量" v-trim />
        <div class="placeholder9">请输入总发售数量,销量大于该数量后,不再支持销售;为空表示不限制</div>
      </el-form-item>
      <el-form-item label="日限额">
        <el-input class="w400" v-model="param.saleDayLimit"
          oninput="value=value.replace(/^(0+)|[^\d]+/g, '').slice(0, 12)" placeholder="请输入单日发售数量" v-trim />
          oninput="value=value.replace(/^(-1+)|[^\d]+/g, '').slice(0, 12)" placeholder="请输入单日发售数量" v-trim />
        <div class="placeholder9">请输入日发售数量,当日销量大于该数量后,不再支持销售;为空表示不限制</div>
      </el-form-item>
@@ -227,10 +227,10 @@
      comboDetailPost(id).then(res => {
        this.param = res
        this.$set(this.param, 'saleDate', [res.startDate, res.endDate])
        if (res.useStartDate && res.useEndDate) {
        if (res.useStartDate && res.useEndDate && res.type != 0) {
          this.$set(this.param, 'useDate', [res.useStartDate, res.useEndDate])
        }
        this.$set(this.param, id, type == 'copy' ? null : this.param.id)
        this.$set(this.param, 'id', type == 'copy' ? null : this.param.id)
      })
    },
  }
admin/src/views/combo/components/OrderDetail.vue
@@ -1,42 +1,92 @@
<template>
  <GlobalWindow :title="title" :visible.sync="visible" :confirm-working="isWorking">
    <div class="title">支付明细</div>
    <el-table :data="list" stripe border>
      <el-table-column prop="id" label="订单编号" show-overflow-tooltip align="center"></el-table-column>
      <el-table-column prop="onlineorderId" label="交易单号" show-overflow-tooltip align="center"></el-table-column>
      <el-table-column prop="refundType" label="交易类型" width="100px" align="center">
  <GlobalWindow :title="title" width="1100px" :visible.sync="visible" :confirm-working="isWorking">
    <div class="title">订单信息</div>
    <div class="info_warp">
      <div class="item">
        <div class="la">订单编号:</div>
        <div class="val">{{ info.id }}</div>
      </div>
      <div class="item">
        <div class="la">订单状态:</div>
        <div class="val">{{ info.status == 1 ? '已支付' : '未支付' }}</div>
      </div>
      <div class="item">
        <div class="la">下单时间:</div>
        <div class="val">{{ info.createDate }}</div>
      </div>
      <div class="item">
        <div class="la">支付时间:</div>
        <div class="val">{{ info.payDate }}</div>
      </div>
      <div class="item">
        <div class="la">订单金额:</div>
        <div class="val">{{ info.money }}</div>
      </div>
      <div class="item">
        <div class="la">支付方式:</div>
        <div class="val">{{ info.payWay == 0 ? '微信' : '支付宝' }}</div>
      </div>
      <div class="item">
        <div class="la">支付单号:</div>
        <div class="val">{{ info.onlineOrderid }}</div>
      </div>
      <div class="item">
        <div class="la">完成时间:</div>
        <div class="val">{{ info.payDate }}</div>
      </div>
      <div class="item">
        <div class="la">备注:</div>
        <div class="val">{{ info.closeInfo }}</div>
      </div>
    </div>
    <div class="title">买家信息</div>
    <div class="info_warp">
      <div class="item">
        <div class="la">呢称:</div>
        <div class="val">{{ form.member.name }}</div>
      </div>
      <div class="item">
        <div class="la">手机号:</div>
        <div class="val">{{ form.member.phone }}</div>
      </div>
      <div class="item">
        <div class="la">openId:</div>
        <div class="val">{{ form.member.openid }}</div>
      </div>
    </div>
    <div class="title">商品信息</div>
    <el-table :data="[goods]" stripe border>
      <el-table-column prop="name" min-width="100px" label="套餐卡" show-overflow-tooltip align="center"></el-table-column>
      <el-table-column prop="refundType" label="有效期" min-width="160px" align="center">
        <template slot-scope="{row}">
          {{ typeToStr(row.refundType) }}
          {{ row.useStartDate }} è‡³ {{ row.useEndDate }}
        </template>
      </el-table-column>
      <el-table-column prop="money" label="交易金额(元)" width="100px" align="center"></el-table-column>
      <el-table-column prop="payWay" label="渠道" width="100px" align="center">
      <el-table-column label="数量" width="80px" align="center">
        <template slot-scope="{row}">
          {{ row.payWay==0? '微信' : '支付宝' }}
          <span>1</span>
        </template>
      </el-table-column>
      <el-table-column prop="payDate" label="交易时间" width="150px" align="center"></el-table-column>
      <el-table-column prop="price" label="ä»·æ ¼" width="100px" align="center"></el-table-column>
      <el-table-column prop="payWay" label="状态" width="100px" align="center">
        <template slot-scope="{row}">
          {{ info.status == 1 ? '已支付' : '未支付' }}
        </template>
      </el-table-column>
    </el-table>
    <div class="title">骑行记录</div>
    <el-table
      :data="memberRidesList"
      stripe
      border
    >
      <el-table-column prop="openid" label="用户" width="250px" show-overflow-tooltip align="center"></el-table-column>
      <el-table-column prop="bikeCode" label="车辆编号" width="100px" align="center"></el-table-column>
      <el-table-column prop="bikeType" label="车类型" width="200px" align="center"></el-table-column>
      <el-table-column prop="rideTime" label="借出时长(分)" width="200px" align="center"></el-table-column>
      <el-table-column prop="duration" label="计费时长(分)" width="200px" align="center"></el-table-column>
      <el-table-column prop="bikeType" label="车类型" width="150px" align="center"></el-table-column>
      <el-table-column prop="rentDate" label="借出时间" width="150px" align="center"></el-table-column>
      <el-table-column prop="backDate" label="还车时间" width="150px" align="center"></el-table-column>
      <el-table-column prop="closeStatus" fixed="right" label="结算状态" width="100px" align="center">
        <template slot-scope="{row}">
          {{ row.closeStatus == 0 ? '未结算' : '已结算' }}
    <div v-if="form.refundList && form.refundList.length > 0" class="title">退款信息</div>
    <el-table v-if="form.refundList && form.refundList.length > 0" :data="form.refundList" stripe border>
      <el-table-column prop="createDate" label="退款时间" min-width="180px" show-overflow-tooltip align="center"></el-table-column>
      <el-table-column prop="money" label="退款金额" min-width="100px" align="center"></el-table-column>
      <el-table-column label="状态" min-width="100px" align="center">
        <template v-slot="{row}">
          <span v-if="row.status == 0">预退款</span>
          <span v-if="row.status == 1">退款失败</span>
          <span v-if="row.status == 2">退款完成</span>
        </template>
      </el-table-column>
      <el-table-column prop="reason" label="退款备注" min-width="100px" align="center"></el-table-column>
      <el-table-column prop="creatorName" label="操作人" min-width="100px" align="center"></el-table-column>
    </el-table>
    <div slot="footer">
      <el-button @click="visible=false">返回</el-button>
@@ -56,8 +106,10 @@
    return {
      // è¡¨å•数据
      form: {
        goodsorderId: ''
        member: {}
      },
      info: {},
      goods: {},
      list: [],
      memberRidesList: [],
      // 0结算退款 1强制结算退款 2结算后退款 [99: è™šæ‹Ÿtype æ”¯ä»˜æŠ¼é‡‘]
@@ -78,7 +130,11 @@
      this.title = title
      this.visible = true
      // æ–°å»º
      console.log('target', target)
      this.form = target
      this.info = target.goodsOrder
      this.goods = target.discountMember
      this.$nextTick(() => {
        this.list = target.payOrderDTOList
        this.memberRidesList = target.memberRidesList
@@ -94,7 +150,23 @@
}
</script>
<style scoped>
<style scoped lang="scss">
.info_warp {
  display: flex;
  flex-wrap: wrap;
  font-size: 14px;
  .item {
    display: flex;
    width: 33.3%;
    margin-bottom: 6px;
    .val {
      color: #666666;
    }
  }
}
.title {
  font-size: 18px;
  font-weight: 600;
admin/src/views/combo/components/Refund.vue
@@ -72,7 +72,8 @@
        comboReDetailPost({ orderId: id }).then(res => {
          if (res) {
            this.form = res
            this.form.backType = 0
            // this.form.backType = 0
            this.$set(this.form, 'backType', 0)
            this.form.orderId = id
          }
        })
admin/src/views/combo/components/SaleDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,139 @@
<template>
  <GlobalWindow title="套餐卡详情" :visible.sync="isShowModal" width="1000px" @close="close" @confirm="close">
    <div>
      <div class="modal_title">套餐名称:{{ detail.name }}</div>
      <div class="place">
        <span>套餐号:{{ detail.code }}</span>
        <span v-if="detail.useType == 1">有效期:{{ detail.useStartDate }}至{{ detail.useEndDate }}</span>
        <span v-if="detail.useType == 0">有效期:{{ detail.useStartDate }}至{{ detail.useEndDate }}</span>
        <span v-if="detail.useType == 2">有效期:{{ detail.useStartDate }}至{{ detail.useEndDate }}</span>
      </div>
      <div class="df_ac">
        <el-tabs style="flex: 1;" v-model="activeTab" @tab-click="handleClick">
          <el-tab-pane label="套餐使用明细" name="0" />
          <el-tab-pane label="套餐操作记录" name="2" />
        </el-tabs>
        <div style="border-bottom: 2px solid #e5e7ec; margin-top: 1px;">{{ activeTab == 0 ? '使用情况' : '操作情况' }}:{{ pagination.total }}次</div>
      </div>
      <el-table v-if="activeTab == 0" v-loading="loading" :data="list" stripe border>
        <el-table-column prop="createDate" align="center" label="使用时间" min-width="120" show-overflow-tooltip />
        <el-table-column prop="goodsorderId" align="center" label="关联订单" min-width="140" show-overflow-tooltip />
        <el-table-column prop="" align="center" label="骑车时长" min-width="80" show-overflow-tooltip>
          <template v-slot="{ row }">
            {{ row.rideTime }}分钟
          </template>
        </el-table-column>
        <el-table-column prop="ridePrice" align="center" label="抵扣金额" min-width="100" show-overflow-tooltip />
      </el-table>
      <el-table v-if="activeTab == 2" v-loading="loading" :data="list" stripe border>
        <el-table-column prop="createDate" align="center" label="操作时间" min-width="120" show-overflow-tooltip />
        <el-table-column prop="info" align="center" label="操作类型" min-width="100" show-overflow-tooltip>
          <template v-slot="{ row }">
           <span v-if="row.type == 0">用户骑行使用</span>
           <span v-if="row.type == 1">套餐作废</span>
           <span v-if="row.type == 2">套餐调整</span>
          </template>
        </el-table-column>
        <el-table-column prop="editInfo" align="center" label="操作备注" min-width="200" show-overflow-tooltip />
        <el-table-column prop="creatorName" align="center" label="操作人" min-width="80" show-overflow-tooltip />
      </el-table>
      <div class="table_btns">
        <Pagination @size-change="handleSizeChange" @current-change="getList" :pagination="pagination" />
      </div>
    </div>
  </GlobalWindow>
</template>
<script>
import { comboSalerDetailPost, discountLogLog } from '@/api/business/combo.js'
import GlobalWindow from '@/components/common/GlobalWindow'
import BasePageTemp from '@/components/base/BasePageTemp'
export default {
  name: 'ComboDetail',
  extends: BasePageTemp,
  components: {
    GlobalWindow
  },
  data() {
    return {
      isShowModal: false,
      activeTab: '0',
      detail: {},
      pagination: {
        page: 1,
        rows: 10
      },
      totalCount: 0,
      list: [],
      loading: false
    }
  },
  created() {
    // this.detail = this.$route.query
    // this.comboDetail()
  },
  methods: {
    getDetail(row) {
      comboSalerDetailPost(row.id).then(res => {
        this.detail = res
        this.activeTab = '0'
        this.getList()
      }, () => {
      })
    },
    handleClick(val) {
      this.getList()
    },
    getList(page) {
      const { pagination, activeTab, detail } = this
      this.loading = true
      if (page) { pagination.page = page }
      discountLogLog({
        model: {
          type: activeTab,
          discountMemberId: detail.id
        },
        capacity: pagination.pageSize,
        page: pagination.page,
      }).then(res => {
        this.loading = false
        this.list = res.records || []
        this.pagination.total = res.total || 0
      }, () => {
        this.loading = false
      })
    },
    close() {
      this.isShowModal = false
      this.$emit('close')
    },
    currentPageChange(val) {
      this.pagination.page = val
      this.comboDetail()
    },
    pageSizeChange(val) {
      this.pagination.rows = val
      this.comboDetail()
    }
  }
}
</script>
<style lang="scss" scoped>
.modal_title {
  font-size: 18px;
  font-weight: 500;
  margin-bottom: 6px;
}
.place {
  color: #999999;
  font-size: 13px;
  display: flex;
  margin-bottom: 8px;
  span {
    margin-right: 60px;
  }
}
</style>
admin/src/views/combo/index.vue
@@ -49,7 +49,7 @@
          <div>
            <span v-if="row.status == 0" @click="handleEdit(row, 'copy')" class="primaryColor pointer">复制</span>
            <span v-if="row.status == 1" @click="handleEdit(row)" class="primaryColor pointer mr10">编辑</span>
            <span v-if="row.status == 1" @click="handleDetail(row)" class="red pointer">删除</span>
            <span v-if="row.status == 1" @click="handleDel(row)" class="red pointer">删除</span>
          </div>
        </template>
      </el-table-column>
@@ -68,7 +68,7 @@
import TableLayout from '@/layouts/TableLayout'
import Edit from './components/Edit'
import ComboDetail from './components/ComboDetail.vue'
import { comboListPost, comboEditPost } from '@/api/business/combo.js'
import { comboListPost, comboUpdatePost, comboDelPost } from '@/api/business/combo.js'
import { Message } from 'element-ui'
export default {
  extends: BasePageTemp,
@@ -130,12 +130,26 @@
      })
    },
    changeStatus(row) {
      comboEditPost({ ...row }).then(res => {
      comboUpdatePost({ ...row }).then(res => {
        if (res.code == 200) {
          return Message.success('更新成功')
        }
      })
    },
    handleDel(row) {
      this.$confirm('您确认要删除当前套餐吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        comboDelPost(row.id).then(res => {
          if (res) {
            Message.success('删除成功')
            this.getList()
          }
        })
      })
    },
    handleEdit(row, type = 'edit') {
      this.isShowEdit = true
      this.$nextTick(() => {
admin/src/views/combo/order.vue
@@ -6,7 +6,7 @@
      <el-button type="primary" @click="handleEx()">导出</el-button>
    </div>
    <el-table v-loading="loading" :data="list" stripe border>
      <el-table-column prop="code" align="center" label="订单编号" min-width="180" show-overflow-tooltip>
      <el-table-column prop="code" align="center" label="订单编号" min-width="200" show-overflow-tooltip>
        <template scope="{row}">
          <span @click="handleDetail(row.id)" class="primaryColor pointer">{{ row.code }}</span>
        </template>
@@ -15,7 +15,7 @@
      <el-table-column prop="money" align="center" label="合计(元)" min-width="80" show-overflow-tooltip />
      <el-table-column prop="money" align="center" label="实付(元)" min-width="80" show-overflow-tooltip />
      <el-table-column prop="refundMoney" align="center" label="已退金额(元)" min-width="100" show-overflow-tooltip />
      <el-table-column prop="memberId" align="center" label="用户信息" min-width="140" show-overflow-tooltip />
      <el-table-column prop="openid" align="center" label="用户信息" min-width="200" show-overflow-tooltip />
      <el-table-column prop="payWay" align="center" label="支付方式" min-width="80" show-overflow-tooltip>
        <template v-slot="{ row }">
          <span v-if="row.payWay == 0">微信支付</span>
@@ -27,12 +27,19 @@
          <span>小程序端</span>
        </template>
      </el-table-column>
      <el-table-column prop="payWay" align="center" label="订单状态" min-width="80" show-overflow-tooltip>
        <template v-slot="{ row }">
          <span v-if="row.status == 0">未支付</span>
          <span v-if="row.status == 1">已支付</span>
        </template>
      </el-table-column>
      <el-table-column prop="refundUserName" align="center" label="操作人" min-width="80" show-overflow-tooltip />
      <el-table-column prop="createDate" align="center" label="创建时间" min-width="140" show-overflow-tooltip />
      <el-table-column label="操作" fixed="right" align="center" min-width="80" show-overflow-tooltip>
      <el-table-column prop="createDate" align="center" label="创建时间" min-width="160" show-overflow-tooltip />
      <el-table-column label="操作" fixed="right" align="center" min-width="120" show-overflow-tooltip>
        <template v-slot="{ row }">
          <span @click="handleDetail(row.id)" class="primaryColor pointer">查看详情</span>
          <span v-if="row.status == 1 && (row.refundMoney < row.money)" @click="handRefund(row.id)" class="primaryColor pointer ml10">退款</span>
          <span v-if="row.status == 1 && (row.refundMoney < row.money)" @click="handRefund(row.id)"
            class="primaryColor pointer ml10">退款</span>
        </template>
      </el-table-column>
    </el-table>
@@ -55,6 +62,7 @@
  comboListOrderEx,
  comboOrderDetailPost
} from '@/api/business/combo.js'
import dayjs from 'dayjs'
export default {
  extends: BasePageTemp,
  components: {
@@ -73,19 +81,22 @@
            label: '订单编号',
          },
          {
            filed: 'name',
            filed: 'discountName',
            type: 'input',
            label: '套餐卡',
            placeholder: '请输入卡名称',
          },
          {
            filed: 'pay',
            filed: 'payWay',
            type: 'select',
            label: '支付方式',
            options: []
            options: [
              { label: '微信', value: 0 },
              { label: '支付宝', value: 1 },
            ]
          },
          {
            filed: 'status',
            filed: 'payStatus',
            type: 'select',
            label: '订单状态',
            options: [
@@ -94,12 +105,12 @@
            ]
          },
          {
            filed: 'time',
            type: 'date',
            filed: 'selDate',
            type: 'daterange',
            label: '支付时间',
          },
          {
            filed: 'username',
            filed: 'openid',
            type: 'input',
            label: '用户信息',
          },
@@ -109,6 +120,8 @@
    }
  },
  created() {
    let date = dayjs().format('YYYY-MM-DD')
    this.$set(this.filters, 'selDate', [date, date])
    this.getList()
    // this.initData()
  },
@@ -119,20 +132,34 @@
    handleDetail(id) {
      comboOrderDetailPost({id})
        .then(res => {
          if (res) {
          this.$refs.OrderDetailRef.open('订单详情', res)
          }
        })
        .catch(err => {
          this.$tip.apiFailed(err)
        })
    },
    handleEx() {
      const { pagination, filters } = this
      this.$dialog.exportConfirm('确认导出吗?')
        .then(() => {
          this.loading = true
          if (filters.selDate && filters.selDate.length > 0) {
            filters.startDate = filters.selDate[0] + ' 00:00:00'
            filters.endDate = filters.selDate[1] + ' 00:00:00'
          } else {
            filters.startDate = null
            filters.endDate = null
          }
          comboListOrderEx({
            page: 1,
            capacity: 1000000,
            model: this.filters
            model: {
              ...filters,
              type: 1
            },
          })
            .then(response => {
              this.download(response)
@@ -154,6 +181,13 @@
    getList(page) {
      const { pagination, filters } = this
      this.loading = true
      if (filters.selDate && filters.selDate.length > 0) {
        filters.startDate = filters.selDate[0] + ' 00:00:00'
        filters.endDate = filters.selDate[1] + ' 00:00:00'
      } else {
        filters.startDate = null
        filters.endDate = null
      }
      if (page) { pagination.page = page }
      comboOrderPost({
        model: {
admin/src/views/combo/record.vue
@@ -1,72 +1,49 @@
<template>
  <div class="main_app">
    <Breadcrumb />
    <QueryForm v-model="querys" :query-form-config="queryFormConfig" @handleQuery="getList(1)" @clear="clearQueryForm">
      <template #btns>
        <el-button v-if="meta.indexOf('MealsUseDetailExport') > -1" type="primary"
          @click="comboRecordExport">导出</el-button>
      </template>
      <template #indate>
        <el-date-picker v-model="querys.indate" type="datetimerange" range-separator="至" start-placeholder="开始日期"
          end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" class="w400"
          :picker-options="pickerOptions" />
      </template>
    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getList(1)" @clear="clearQueryForm">
    </QueryForm>
    <div class="table_btns">
      <el-button v-preventReClick plain type="primary" @click="handleEx">导出</el-button>
      <el-button v-preventReClick plain type="danger" @click="openModal('zuofei')">作废</el-button>
      <el-button v-preventReClick plain @click="openModal('tiaozheng')">套餐调整</el-button>
      <el-button plain type="primary" @click="handleEx">导出</el-button>
      <el-button plain type="danger" @click="openModal('zuofei')">作废</el-button>
      <el-button plain @click="openModal('tiaozheng')">套餐调整</el-button>
    </div>
    <el-table v-loading="loading" :data="list" stripe border @selection-change="handleSelectionChange">
      <el-table-column fixed="left" align="center" type="selection" :selectable="handleDisable" width="55" />
      <el-table-column align="center" label="套餐票号" width="300" show-overflow-tooltip>
      <el-table-column align="center" label="套餐票号" min-width="160" show-overflow-tooltip>
        <template v-slot="scope">
          <span class="primaryColor pointer" @click="comboDetail(scope.row)">{{
            scope.row.id
            scope.row.code
            }}</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="套餐类型" width="120">
      <el-table-column align="center" label="套餐类型" min-width="80">
        <template v-slot="scope">
          <span v-if="scope.row.mealsType === '0'">门票次卡</span>
          <span v-if="scope.row.mealsType === '1'">门票期限卡</span>
          <span v-if="scope.row.mealsType === '2'">预定次卡</span>
          <span v-if="scope.row.mealsType === '3'">课程预约次卡</span>
          <span v-if="scope.row.mealsType === '4'">课程期限卡</span>
          <span v-if="scope.row.type == '0'">期限卡</span>
          <span v-if="scope.row.type == '1'">次卡</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="套餐名称" show-overflow-tooltip width="160" prop="mealsName" />
      <el-table-column align="center" label="用户信息" min-width="240" prop="memberInfo" show-overflow-tooltip />
      <el-table-column align="center" label="使用次数" width="80" prop="useCount">
      <el-table-column align="center" label="套餐名称" show-overflow-tooltip min-width="100" prop="name" />
      <el-table-column align="center" label="用户信息" min-width="100" prop="openid" show-overflow-tooltip />
      <el-table-column align="center" label="使用次数" min-width="80" prop="useTimes">
      </el-table-column>
      <el-table-column align="center" label="有效日期" min-width="200" prop="remainCount">
        <template v-slot="scope">
          <span v-if="scope.row.mealsType === '1'">-</span>
          <span v-else>{{ scope.row.useCount }}</span>
          <span>{{ scope.row.useStartDate }}至{{ scope.row.useEndDate }}</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="有效日期" width="80" prop="remainCount">
      <el-table-column align="center" label="套餐状态" min-width="80">
        <template v-slot="scope">
          <span v-if="scope.row.mealsType === '1'">-</span>
          <span v-else>{{ scope.row.remainCount }}</span>
          <span v-if="scope.row.status == '0'" class="text_success">正常</span>
          <span v-if="scope.row.status == '1'" class="text_warning">作废</span>
          <span v-if="scope.row.status == '2'" class="text-danger">待支付</span>
        </template>
      </el-table-column>
      <el-table-column fixed="right" align="center" label="套餐状态" width="80">
        <template v-slot="scope">
          <span v-if="scope.row.status === '0'" class="text_success">正常</span>
          <span v-if="scope.row.status === '1'" class="text_warning">冻结</span>
          <span v-if="scope.row.status === '2'" class="text-danger">作废</span>
          <span v-if="scope.row.status === '3'" class="text-danger">失效</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="有效日期" width="120" prop="validTime" />
      <el-table-column align="center" label="操作" fixed="right" width="150">
      <el-table-column align="center" label="操作" fixed="right" min-width="150">
        <template v-slot="scope">
          <template>
            <el-button v-if="
              meta.indexOf('MealsMemberPartRefund') > -1 &&
              (scope.row.status == '0' || scope.row.status == '1')
            " type="text" @click="rowClickRefund(scope.row)">退款</el-button>
            <el-button v-if="scope.row.status == '0'" type="text"
              @click="getServiceChargePriceBtn('2', scope.row.id)">冻结</el-button>
            <el-button v-if="scope.row.status == '0'" type="text" @click="openCan(scope.row)">作废</el-button>
            <span v-else>-</span>
          </template>
        </template>
      </el-table-column>
@@ -78,14 +55,14 @@
    <el-dialog title="套餐调整" :visible.sync="isShowAdjust" width="500px">
      <div class="adjust_modal">
        <div style="margin-top: -30px; margin-bottom: 10px;">
          <el-radio v-model="adjustData.aa" label="1">已选当前2条数据</el-radio>
          <el-radio v-model="adjustData.flag" label="0">已选{{ selList.length }}条数据</el-radio>
        </div>
        <div style="margin-bottom: 16px;">
          <el-radio v-model="adjustData.aa" label="1">已选现有筛选条件下全部的11条数据</el-radio>
          <el-radio v-model="adjustData.flag" label="1">选现有筛选条件下全部的{{ pagination.total }}条数据</el-radio>
        </div>
        <div class="df_ac mb5">
          <span class="key">有效期增加:</span>
          <el-input v-model="adjustData.addTime" oninput="value=value.replace(/[^\d]/g,'')" class="flex1 mr10" />
          <el-input v-model="adjustData.addNum" oninput="value=value.replace(/[^\d]/g,'')" class="flex1 mr10" />
          <span>天</span>
        </div>
        <div class="df_ac mb20">
@@ -99,26 +76,43 @@
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowAdjust = false">取消</el-button>
        <el-button v-preventReClick type="primary" :loading="subLoading" @click="handleModelEnter">确定</el-button>
        <el-button type="primary" :loading="subLoading" @click="handleModelEnter">确定</el-button>
      </span>
    </el-dialog>
    <el-dialog title="套餐作废" :visible.sync="isShowCan" width="500px">
      <div class="adjust_modal" style="margin-top: -30px;">
        <div class="red" style="font-size: 16px;">确定作废选中套餐吗?作废后,套餐不可使用</div>
        <div class="df_ac mt10">
          <el-input type="textarea" v-model="remarkCan" placeholder="请按要求输入备注说明,非必填" />
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowCan = false">取消</el-button>
        <el-button type="primary" :loading="subLoading" @click="handleCan">确定</el-button>
      </span>
    </el-dialog>
    <Refund v-if="isShowRefund" ref="RefundRef" @close="isShowRefund = false" @success="refundSuccess" />
    <Detail v-if="isShowDetail" ref="detailRef" />
    <orderDialog ref="child" @orderSuccess="getList()" />
    <Detail ref="DetailRef" />
  </div>
</template>
<script>
import { pickerOptions } from './components/config'
import BasePageTemp from '@/components/base/BasePageTemp'
import Breadcrumb from '@/layouts/Breadcrumb'
// import Detail from '../comboDetail'
// import Refund from './refund.vue'
import Detail from './components/SaleDetail.vue'
import { Message } from 'element-ui'
import {
  comboSalePage,
  comboSaleEx,
  comboSaleCancel,
  comboSaleAdjust,
} from '@/api/business/combo.js'
export default {
  name: 'SalesRecord',
  extends: BasePageTemp,
  components: { Breadcrumb },
  components: { Breadcrumb, Detail },
  data() {
    return {
      exportLoading: false,
@@ -126,19 +120,19 @@
      isShowRefund: false,
      queryFormConfig: {
        formItems: [{
          filed: 'id',
          filed: 'code',
          type: 'input',
          label: '套餐票号',
          placeholder: '请输入套餐号',
          clearable: true
        }, {
          filed: 'mealsName',
          filed: 'name',
          type: 'input',
          label: '套餐名称',
          placeholder: '请输入套餐名称',
          clearable: true
        }, {
          filed: 'memberSearchValue',
          filed: 'openid',
          type: 'input',
          label: '用户信息',
          clearable: true
@@ -150,13 +144,12 @@
          clearable: true,
          options: [
            { value: '0', label: '正常' },
            { value: '1', label: '冻结' },
            { value: '2', label: '作废' },
            { value: '3', label: '失效' }]
            { value: '1', label: '作废' },
            // { value: '2', label: '待支付' }
          ]
        }],
        online: true
      },
      pickerOptions,
      querys: {
        id: '',
        mealsName: '',
@@ -167,17 +160,21 @@
      saleRecordList: [],
      saleRecordTotal: 0,
      selectSalesList: [],
      selList: [],
      saleRecordLoading: false,
      subLoading: false,
      isShowModal: false,
      isShowCan: false,
      ModalTitle: '',
      ModalText: '',
      ModelRemark: '',
      remarkCan: '',
      // â¬‡ï¸adjust调整相关
      isShowAdjust: false,
      isShowCan: false,
      canList: [],
      adjustData: {
        flag: 0,
        addNum: '',
        addTime: ''
      },
@@ -187,7 +184,7 @@
  },
  created() {
    // this.meta = this.$route.meta.buttons || []
    // this.getList(1)
    this.getList(1)
  },
  methods: {
    rowClickRefund(row) {
@@ -201,106 +198,67 @@
      this.isShowRefund = false
      this.getList()
    },
    getServiceChargePriceBtn(type, mealsMemberId) {
      this.serviceChargeId = mealsMemberId
      getServiceChargePrice({
        param: {
          type,
          mealsMemberId
        }
      }).then((res) => {
        if (res.errorCode === '000000') {
          this.serviceChargePrice = res.record.price
          this.openModal('dongjie')
        }
    handleEx() {
      const { pagination, filters } = this
      this.$dialog.exportConfirm('确认导出吗?')
        .then(() => {
          this.loading = true
          comboSaleEx({
            page: 1,
            capacity: 1000000,
            model: filters
          })
            .then(response => {
              this.download(response)
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.loading = false
            })
      })
        .catch(() => { })
    },
    handleEx() {
      const { querys } = this
      this.exportLoading = true
      recordExport({
        param: {
          ...querys
        }
      }).then((res) => {
        this.exportLoading = false
        if (res.errorCode === '000000') {
          const a = document.createElement('a') // åˆ›å»ºä¸€ä¸ªa标签元素
          a.style.display = 'none' // è®¾ç½®å…ƒç´ ä¸å¯è§
          a.href = res.record.showUrl // è®¾ç½®ä¸‹è½½åœ°å€
          document.body.appendChild(a) // åŠ å…¥
          a.click() // è§¦å‘点击,下载
          document.body.removeChild(a) //
          this.$message.success('导出成功')
        }
      })
        .catch(() => {
          this.exportLoading = false
        })
    openCan(row) {
      this.isShowCan = true
      this.canList = [row]
    },
    handleDisable(row, index) {
      if (row.status === '2') {
        return false
      } else {
    handleDisable(row) {
      // return row.status == 0
        return true
      }
    },
    // æŸ¥è¯¢è¡¨æ ¼æ•°æ®
    getList(page) {
      const { querys, pagination } = this
      if (page) {
        pagination.page = page
        this.pagination.page = Number(page)
      }
      if (querys.indate && querys.indate.length > 0) {
        querys.startTime = querys.indate[0]
        querys.endTime = querys.indate[1]
      } else {
        querys.startTime = null
        querys.endTime = null
      }
      pagination.firstQueryTime = parseTime(new Date())
      this.saleRecordLoading = true
      comboSalesRecordPost({
        pagination, param: {
          ...querys,
          venueId: sessionStorage.getItem('venueId')
        }
      const { pagination, filters } = this
      this.loading = true
      if (page) { pagination.page = page }
      comboSalePage({
        model: {
          ...filters
        },
        capacity: pagination.pageSize,
        page: pagination.page,
      }).then(res => {
        this.saleRecordLoading = false
        if (res.errorCode === '000000') {
          this.saleRecordLoading = false
          this.saleRecordTotal = res.totalCount
          this.saleRecordList = res.recordList
          if (res.totalCount && res.recordList.length === 0 && pagination.page > 1) {
            this.getList(Math.ceil(res.totalCount / pagination.rows))
          }
        }
      }).catch(() => {
        this.saleRecordLoading = false
        this.loading = false
        this.list = res.records || []
        this.pagination.total = res.total || 0
      }, () => {
        this.loading = false
      })
    },
    clearQueryForm() {
      // eslint-disable-next-line no-unused-vars
      this.querys = {}
      this.filters = {}
      this.getList(1)
    },
    // æ‰“å¼€modal å†»ç»“ è§£å†» ä½œåºŸ
    openModal(type) {
      const { selectSalesList } = this
      const { selList } = this
      this.ModelRemark = ''
      this.adjustData.addNum = ''
      this.adjustData.addTime = ''
      switch (type) {
        case 'dongjie':
          this.ModalTitle = '套餐冻结'
          this.ModalText = '确定冻结选中套餐吗?冻结后,套餐将无法使用'
          break
        case 'jiedong':
          this.ModalTitle = '套餐解冻'
          this.ModalText = '确定解冻选中套餐吗?解冻后,套餐可立即生效使用'
          break
        case 'zuofei':
          this.ModalTitle = '套餐作废'
          this.ModalText = '确定作废选中套餐吗?作废后,套餐不可使用'
@@ -311,28 +269,21 @@
        default:
          break
      }
      if (selectSalesList.length === 0 && type !== 'dongjie') {
        return this.$message.warning(`请先选择要${this.ModalTitle.slice(2)}的套餐`)
      if (selList.length === 0 && type == 'zuofei') {
        return Message.warning(`请先选择要${this.ModalTitle.slice(2)}的套餐`)
      }
      if (this.ModalTitle === '套餐调整') {
        this.isShowAdjust = true
        this.adjustData = {
          flag: '0'
        }
      } else {
        this.isShowModal = true
        this.isShowCan = true
      }
    },
    // ç¡®å®š å†»ç»“ è§£å†» ä½œåºŸ
    handleModelEnter() {
      // if (!this.ModelRemark) {
      //   this.$message.warning('操作备注必填')
      //   return
      // }
      switch (this.ModalTitle) {
        case '套餐冻结':
          this.Freeze()
          break
        case '套餐解冻':
          this.Unfreeze()
          break
        case '套餐作废':
          this.cancellation()
          break
@@ -343,92 +294,27 @@
          break
      }
    },
    // å†»ç»“
    Freeze() {
      const that = this
      const data = {
        type: '1',
        handleRemake: this.ModelRemark,
        isCreateOrder: '1',
        id: this.serviceChargeId
      }
      this.subLoading = true
      handleComboSalesPost({ param: { ...data } }).then(res => {
        this.subLoading = false
        this.isShowModal = false
        if (res.errorCode === '000000') {
          const obj = res.record
          if (obj && obj.price) {
            obj.goodsInfos = obj.serviceChargeOrderInfo
            obj.allPrice = obj.price
            this.$refs.child.continuePay(obj, 'handlingFees')
          } else {
            this.$message.success('冻结成功')
            this.getList()
          }
          //
        } else if (res.errorCode === '200001') {
          this.$confirm('存在未处理订单, æ˜¯å¦è·³è½¬?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            callback: () => { },
            beforeClose: (action, ctx, close) => {
              if (action !== 'confirm') {
                close()
                return
              }
              ctx.confirmButtonLoading = true
              that.$router.push({ name: 'HandlingFees' })
            }
          }).finally(() => {
            this.subLoading = false
            this.isShowModal = false
          })
        }
      })
    },
    // è§£å†»
    async Unfreeze() {
      const data = {
        type: '2',
        handleRemake: this.ModelRemark,
        id: this.selectSalesList.map(i => i.id).join(',')
      }
      this.subLoading = true
      const res = await handleComboSalesPost({ param: { ...data } }).catch(() => {
        this.subLoading = false
        this.isShowModal = false
      })
      this.subLoading = false
      this.isShowModal = false
      if (res && res.errorCode === '000000') {
        this.$message.success('解冻成功')
        this.getList()
      }
    },
    // è°ƒæ•´
    async handleAdjust() {
      if (!this.adjustData.addNum && !this.adjustData.addTime) {
        return this.$message.warning('请输入要调整的有效期天数或者余量次数')
        return Message.warning('请输入要调整的有效期天数或者余量次数')
      }
      const data = {
        type: '3',
        handleRemake: this.ModelRemark,
        addNum: this.adjustData.addNum || 0,
        addTime: this.adjustData.addTime || 0,
        id: this.selectSalesList.map(i => i.id).join(',')
        info: this.ModelRemark,
        addDays: this.adjustData.addNum || 0,
        choseIdList: this.adjustData.flag == 0 ? this.selList.map(i => i.id) : [],
        ...this.filters
      }
      this.subLoading = true
      const res = await handleComboSalesPost({ param: { ...data } }).catch(() => {
      const res = await comboSaleAdjust({ ...data }).catch(() => {
        this.subLoading = false
        this.isShowModal = false
        this.isShowCan = false
      })
      this.subLoading = false
      this.isShowModal = false
      if (res && res.errorCode === '000000') {
        this.$message.success('套餐调整成功')
      this.isShowCan = false
      if (res) {
        Message.success('套餐调整成功')
        this.getList()
        this.isShowAdjust = false
      }
@@ -436,36 +322,46 @@
    // ä½œåºŸ
    async cancellation() {
      const data = {
        type: '4',
        handleRemake: this.ModelRemark,
        id: this.selectSalesList.map(i => i.id).join(',')
        handleRemake: this.remarkCan,
        choseIdList: this.selList.map(i => i.id)
      }
      this.subLoading = true
      const res = await handleComboSalesPost({ param: { ...data } }).catch(() => {
      const res = await comboSaleCancel({ ...data }).catch(() => {
        this.subLoading = false
        this.isShowModal = false
        this.isShowCan = false
      })
      this.subLoading = false
      this.isShowModal = false
      if (res && res.errorCode === '000000') {
        this.$message.success('作废成功')
      this.isShowCan = false
      if (res) {
        Message.success('作废成功')
        this.getList()
      }
    },
    async handleCan() {
      const data = {
        handleRemake: this.remarkCan,
        choseIdList: this.canList.map(i => i.id)
      }
      this.subLoading = true
      const res = await comboSaleCancel({ ...data }).catch(() => {
        this.subLoading = false
        this.isShowCan = false
      })
      this.subLoading = false
      this.isShowCan = false
      if (res) {
        Message.success('作废成功')
        this.getList()
      }
    },
    handleSelectionChange(val) {
      this.selectSalesList = val
      this.selList = val
    },
    comboDetail(item) {
      this.isShowDetail = true
      this.$nextTick(() => {
        this.$refs.detailRef.isShowModal = true
        this.$refs.detailRef.comboDetail(item)
        this.$refs.DetailRef.isShowModal = true
        this.$refs.DetailRef.getDetail(item)
      })
      // this.$router.push({
      //   name: 'comboDetail',
      //   query: item
      // })
    },
    pageSizeChange(val) {
      this.pagination.rows = val
@@ -484,9 +380,9 @@
      text-align: right;
    }
  }
  .el-dialog__body{
    
  }
  .el-dialog__body {}
  .text_warning {
    color: #e89e42;
  }
server/jtt808_parent/jtt808-protocol/src/test/java/org/yzh/protocol/TestHex.java
@@ -18,23 +18,23 @@
 */
public class TestHex {
    @Test
    public void testHex() throws Exception {
        try (BufferedReader reader = reader("target/test-classes/JT808.txt")) {
            reader.lines().filter(hex -> !hex.isEmpty()).forEach(hex -> BeanTest.selfCheck(hex));
        }
    }
//    @Test
//    public void testHex() throws Exception {
//        try (BufferedReader reader = reader("target/test-classes/JT808.txt")) {
//            reader.lines().filter(hex -> !hex.isEmpty()).forEach(hex -> BeanTest.selfCheck(hex));
//        }
//    }
    @Test
    public void testSubpackage() throws Exception {
        try (BufferedReader reader = reader("target/test-classes/JT1078.txt")) {
            reader.lines().filter(hex -> !hex.isEmpty()).forEach(hex -> {
                JTMessage message = BeanTest.coder.decode(Unpooled.wrappedBuffer(ByteBufUtil.decodeHexDump(hex)));
                if (message != null)
                    System.out.println(BeanTest.gson.toJson(message));
            });
        }
    }
//    @Test
//    public void testSubpackage() throws Exception {
//        try (BufferedReader reader = reader("target/test-classes/JT1078.txt")) {
//            reader.lines().filter(hex -> !hex.isEmpty()).forEach(hex -> {
//                JTMessage message = BeanTest.coder.decode(Unpooled.wrappedBuffer(ByteBufUtil.decodeHexDump(hex)));
//                if (message != null)
//                    System.out.println(BeanTest.gson.toJson(message));
//            });
//        }
//    }
    public static BufferedReader reader(String path) throws FileNotFoundException {
        return new BufferedReader(new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8));
server/platform/src/main/java/com/doumee/api/business/DiscountController.java
@@ -67,6 +67,17 @@
        return ApiResponse.success(null);
    }
    @ApiOperation("修改状态")
    @PostMapping("/updStatus")
    @RequiresPermissions("business:discount:update")
    public ApiResponse updStatus(@RequestBody Discount discount) {
        discountService.updStatus(discount);
        return ApiResponse.success(null);
    }
    @ApiOperation("分页查询")
    @PostMapping("/page")
    @RequiresPermissions("business:discount:query")
server/platform/src/main/java/com/doumee/api/business/DiscountMemberController.java
@@ -85,7 +85,7 @@
    @ApiOperation("根据ID查询")
    @GetMapping("/{id}")
    @RequiresPermissions("business:discountmember:query")
    public ApiResponse findById(@PathVariable String id) {
    public ApiResponse<DiscountMember> findById(@PathVariable String id) {
        return ApiResponse.success(discountMemberService.getDetail(id));
    }
server/platform/src/main/java/com/doumee/api/business/GoodsorderController.java
@@ -32,6 +32,7 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * @author æ±Ÿè¹„蹄
@@ -92,6 +93,7 @@
    public ApiResponse<PageData<Goodsorder>> findPage (@RequestBody PageWrap<Goodsorder> pageWrap) {
        return ApiResponse.success(goodsorderService.findPage(pageWrap));
    }
    @ApiOperation("线上交易汇总数据接口")
    @PostMapping("/getTotalData")
    @RequiresPermissions("business:goodsorder:query")
@@ -118,7 +120,8 @@
        for (Goodsorder goodsorder:goodsorders) {
            DiscountGoodsorderExportVO discountGoodsorderExportVO = new DiscountGoodsorderExportVO();
            BeanUtils.copyProperties(goodsorder,discountGoodsorderExportVO);
            discountGoodsorderExportVO.setPayMoney(discountGoodsorderExportVO.getPayMoney());
            discountGoodsorderExportVO.setPayMoney(discountGoodsorderExportVO.getMoney());
            discountGoodsorderExportVO.setOrigin(Constants.ZERO);
            discountGoodsorderExportVOList.add(discountGoodsorderExportVO);
        }
        ExcelExporter.build(DiscountGoodsorderExportVO.class).exportWithFirstAndEnd(discountGoodsorderExportVOList, "订单列表_"+System.currentTimeMillis(),"订单列表_"+ DateUtil.getPlusTime2(DateUtil.getCurrentDate()),null, response);
@@ -170,6 +173,9 @@
    @PostMapping("/backGoodsorder")
    @RequiresPermissions("business:goodsorder:query")
    public ApiResponse backGoodsorder(@RequestBody GoodsorderBackDTO goodsorderBackDTO){
        if(Objects.nonNull(goodsorderBackDTO) && Objects.isNull(goodsorderBackDTO.getBackType())){
            goodsorderBackDTO.setBackType(Constants.ONE);
        }
        goodsorderService.backGoodsorder(goodsorderBackDTO);
        return ApiResponse.success(null);
    }
server/platform/src/main/java/com/doumee/task/ScheduleTool.java
@@ -98,6 +98,18 @@
    /**
     * å®šæ—¶å…³é—­ è¶…时未支付的订单
     * 30 ç§’刷新一次
     * @throws Exception
     */
    @Scheduled(cron = "0/15 * * * * ? ")
    public void autCancel() throws Exception {
        log.info("=====================开始定时刷新关闭超时未支付的订单=======================");
        goodsorderService.autCancel();
        log.info("=====================结束定时刷新关闭超时未支付的订单=======================");
    }
    /**
     * ç«™ç‚¹è½¦è¾†æ»¡æž¶çŽ‡é¢„è­¦
     * @throws Exception
     */
server/services/src/main/java/com/doumee/biz/system/impl/SystemDictDataBizImpl.java
@@ -38,7 +38,7 @@
    public void updateById(SystemDictData systemDictData) {
        SystemDictData queryDto = new SystemDictData();
        queryDto.setDictId(systemDictData.getDictId());
        queryDto.setCode(systemDictData.getCode());
        queryDto.setLabel(systemDictData.getLabel());
        queryDto.setDeleted(Constants.ZERO);
        SystemDictData dictData = systemDictDataService.findOne(queryDto);
        if (dictData != null && !dictData.getId().equals(systemDictData.getId())) {
server/services/src/main/java/com/doumee/core/constants/Constants.java
@@ -126,7 +126,7 @@
        PLATFORM_REFUND(3,"平台退款", "平台退款"),
        DISCOUNT(4,"平台套餐", "平台套餐")
        DISCOUNT(4,"套餐购买", "套餐购买")
        ;
        String name;
@@ -207,6 +207,9 @@
        public static final String LEASE_NOTICE_URL = "LEASE_NOTICE_URL";
        //押金
        public static final String RENT_DEPOSIT = "RENT_DEPOSIT";
        //电车临停自动关锁时长(分钟)
        public static final String PAUSE_AUTO_CLOSE_TIME = "PAUSE_AUTO_CLOSE_TIME";
        //温馨提示
        public static final String TIPS = "TIPS";
        //温馨提示
server/services/src/main/java/com/doumee/core/utils/DateUtil.java
@@ -68,11 +68,28 @@
        return dt1;
    }
    public static Date StringToDateFormat(String DATE,String format) {
        if(StringUtils.isBlank(DATE)){
            return null;
        }
        DateFormat df = new SimpleDateFormat(format);
        Date dt1 = null;
        try {
            dt1 = df.parse(DATE);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return dt1;
    }
    public static String getXDaysAfter(Date date, Integer days){
        Timestamp currentTimestamp = new Timestamp(date.getTime());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentTimestamp);
        calendar.add(Calendar.DAY_OF_YEAR, days-1); // åœ¨å½“前时间基础上添加指定的天数
        calendar.add(Calendar.DAY_OF_YEAR, days); // åœ¨å½“前时间基础上添加指定的天数
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(calendar.getTime());
    }
@@ -2771,7 +2788,7 @@
    public static void main(String[] args) {
        try {
            System.out.println(DateUtil.getBetweenDays("2025-02-13","2025-02-15"));
            System.out.println(DateUtil.getCurrDate());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
server/services/src/main/java/com/doumee/core/wx/SendWxMessage.java
@@ -44,9 +44,9 @@
        Map<String, TemplateData> m = new HashMap<>(4);
        m.put("character_string1", new TemplateData(bikeCode));
        //解锁时间
        m.put("date3", new TemplateData(DateUtil.getDate(startTime,"yyyy-MM-dd HH:mm")));
        m.put("date3", new TemplateData(DateUtil.getFomartDate(startTime,"yyyy/MM/dd HH:mm")));
        //上锁时间
        m.put("date4", new TemplateData(DateUtil.getDate(endTime,"yyyy-MM-dd HH:mm")));
        m.put("date4", new TemplateData(DateUtil.getFomartDate(endTime,"yyyy/MM/dd HH:mm")));
        //温馨提醒
        m.put("thing5", new TemplateData("临时锁车已超过最大时长,已自动还车"));
        wxMsgVo.setPage(goodsOrderUrl + goodsOrderId);
server/services/src/main/java/com/doumee/dao/business/model/Discount.java
@@ -28,7 +28,7 @@
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createDate;
    @ApiModelProperty(value = "创建人")
@@ -37,7 +37,7 @@
    @ApiModelProperty(value = "编辑时间")
    @ExcelColumn(name="编辑时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date editDate;
    @ApiModelProperty(value = "编辑人")
@@ -160,7 +160,18 @@
    @ApiModelProperty(value = "每日单价", example = "1")
    private BigDecimal dayPrice;
    @ApiModelProperty(value = "小程序查询使用", hidden = true)
    @TableField(exist = false)
    private Integer minShow;
    @ApiModelProperty(value = "创建人名称")
    @TableField(exist = false)
    private String creatorName;
    @ApiModelProperty(value = "最后编辑人")
    @TableField(exist = false)
    private String editorName;
    @TableField(exist = false)
    @ApiModelProperty(value = "图片全路径", example = "1")
server/services/src/main/java/com/doumee/dao/business/model/DiscountLog.java
@@ -28,7 +28,7 @@
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createDate;
    @ApiModelProperty(value = "创建人")
@@ -37,7 +37,7 @@
    @ApiModelProperty(value = "编辑时间")
    @ExcelColumn(name="编辑时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date editDate;
    @ApiModelProperty(value = "编辑人")
server/services/src/main/java/com/doumee/dao/business/model/DiscountMember.java
@@ -27,14 +27,14 @@
    private String id;
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createDate;
    @ApiModelProperty(value = "创建人")
    private String creator;
    @ApiModelProperty(value = "编辑时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date editDate;
    @ApiModelProperty(value = "编辑人")
server/services/src/main/java/com/doumee/dao/business/vo/DiscountGoodsorderExportVO.java
@@ -45,11 +45,11 @@
    private String openid;
    @ApiModelProperty(value = "支付方式 0微信 1支付宝")
    @ExcelColumn(name="支付方式",index = 7 ,width = 10,valueMapping = "0=微信;1=支付宝;",align = HorizontalAlignment.CENTER)
    @ExcelColumn(name="支付方式",index = 7 ,width = 10,valueMapping = "0=微信;1=支付宝;",align = HorizontalAlignment.CENTER)
    private Integer payWay;
    @ApiModelProperty(value = "订单来源")
    @ExcelColumn(name="订单来源",index = 8 ,width = 10,valueMapping = "0=小程序端;",align = HorizontalAlignment.CENTER)
    @ExcelColumn(name="订单来源",index = 8 ,width = 10,valueMapping = "0=小程序端;",align = HorizontalAlignment.CENTER)
    private Integer origin;
server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java
@@ -44,7 +44,7 @@
    @ApiModelProperty(value = "订单主键")
    private String goodsOrderId;
    @ApiModelProperty(value = "骑行状态:-1=未骑行;0=请求开锁中 ;1=骑行中; 2=已还车;  3=开锁失败;")
    @ApiModelProperty(value = "骑行状态:-1=未骑行;0=请求开锁中 ;1=骑行中; 2=已还车;  3=开锁失败;4=临时随车;")
    private Integer rideStatus;
    @ApiModelProperty(value = "小程序是否停止服务 0否 1是")
server/services/src/main/java/com/doumee/dao/business/web/response/MemberRidesDetailResponse.java
@@ -14,7 +14,6 @@
@ApiModel("骑行记录状态信息返回类")
public class MemberRidesDetailResponse {
    @ApiModelProperty(value = "骑行记录主键")
    private String id;
server/services/src/main/java/com/doumee/dao/business/web/response/MemberRidesResponse.java
@@ -72,9 +72,6 @@
    @ApiModelProperty(value = "骑行记录主键")
    private String rideId;
    @ApiModelProperty(value = "车辆类型")
    private String bikeTypeName;
    @ApiModelProperty(value = "套餐卡信息")
    private DiscountMember discountMember;
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java
@@ -209,5 +209,7 @@
    void autoCancelRefunOrder();
    DiscountMember getUseDiscount(String memberId, Integer driveTime);
    DiscountMember getUseDiscount(String memberId, Integer driveTime,Integer type);
    void autCancel();
}
server/services/src/main/java/com/doumee/service/business/impl/BikesServiceImpl.java
@@ -235,7 +235,7 @@
                low = Double.parseDouble(collect.get(Constants.LOW_BIKE_VOLTAGE).getCode());
            }catch (Exception e){
            }
            if(pageWrap.getModel().getType() == Constants.ONE){
            if(pageWrap.getModel().getLowVoltage() == Constants.ONE){
                //低电量
                queryWrapper.lt(Bikes::getVoltage,low);
            }else{
server/services/src/main/java/com/doumee/service/business/impl/DiscountLogServiceImpl.java
@@ -1,20 +1,26 @@
package com.doumee.service.business.impl;
import com.doumee.core.constants.Constants;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.Utils;
import com.doumee.dao.business.DiscountLogMapper;
import com.doumee.dao.business.model.DiscountLog;
import com.doumee.dao.business.model.DiscountMember;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.DiscountLogService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
/**
 * ç”¨æˆ·å¥—餐卡使用调整日志表Service实现
@@ -87,60 +93,26 @@
    @Override
    public PageData<DiscountLog> findPage(PageWrap<DiscountLog> pageWrap) {
        IPage<DiscountLog> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<DiscountLog> queryWrapper = new QueryWrapper<>();
        MPJLambdaWrapper<DiscountLog> queryWrapper = new MPJLambdaWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
        if (pageWrap.getModel().getId() != null) {
            queryWrapper.lambda().eq(DiscountLog::getId, pageWrap.getModel().getId());
        }
        if (pageWrap.getModel().getCreateDate() != null) {
            queryWrapper.lambda().ge(DiscountLog::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
            queryWrapper.lambda().le(DiscountLog::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
        }
        if (pageWrap.getModel().getCreator() != null) {
            queryWrapper.lambda().eq(DiscountLog::getCreator, pageWrap.getModel().getCreator());
        }
        if (pageWrap.getModel().getEditDate() != null) {
            queryWrapper.lambda().ge(DiscountLog::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
            queryWrapper.lambda().le(DiscountLog::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
        }
        if (pageWrap.getModel().getEditor() != null) {
            queryWrapper.lambda().eq(DiscountLog::getEditor, pageWrap.getModel().getEditor());
        }
        if (pageWrap.getModel().getIsdeleted() != null) {
            queryWrapper.lambda().eq(DiscountLog::getIsdeleted, pageWrap.getModel().getIsdeleted());
        }
        if (pageWrap.getModel().getInfo() != null) {
            queryWrapper.lambda().eq(DiscountLog::getInfo, pageWrap.getModel().getInfo());
        }
        if (pageWrap.getModel().getDiscountMemberId() != null) {
            queryWrapper.lambda().eq(DiscountLog::getDiscountMemberId, pageWrap.getModel().getDiscountMemberId());
        }
        if (pageWrap.getModel().getType() != null) {
            queryWrapper.lambda().eq(DiscountLog::getType, pageWrap.getModel().getType());
        }
        if (pageWrap.getModel().getRideTime() != null) {
            queryWrapper.lambda().eq(DiscountLog::getRideTime, pageWrap.getModel().getRideTime());
        }
        if (pageWrap.getModel().getRidePrice() != null) {
            queryWrapper.lambda().eq(DiscountLog::getRidePrice, pageWrap.getModel().getRidePrice());
        }
        if (pageWrap.getModel().getEditInfo() != null) {
            queryWrapper.lambda().eq(DiscountLog::getEditInfo, pageWrap.getModel().getEditInfo());
        }
        if (pageWrap.getModel().getEditDays() != null) {
            queryWrapper.lambda().eq(DiscountLog::getEditDays, pageWrap.getModel().getEditDays());
        }
        if (pageWrap.getModel().getGoodsorderId() != null) {
            queryWrapper.lambda().eq(DiscountLog::getGoodsorderId, pageWrap.getModel().getGoodsorderId());
        }
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
        DiscountLog model = pageWrap.getModel();
        queryWrapper.selectAll(DiscountLog.class)
                .selectAs(SystemUser::getRealname,DiscountLog::getCreatorName)
                .leftJoin(SystemUser.class,SystemUser::getId,DiscountLog::getCreator)
                .eq(DiscountLog::getIsdeleted, Constants.ZERO)
                .eq(Objects.nonNull(model.getType()),DiscountLog::getType,model.getType())
                .eq(StringUtils.isNotBlank(model.getDiscountMemberId()),DiscountLog::getDiscountMemberId,model.getDiscountMemberId());
        PageData<DiscountLog> pageData = PageData.from(discountLogMapper.selectJoinPage(page, DiscountLog.class,queryWrapper));
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(pageData.getRecords())){
            for (DiscountLog discountLog:pageData.getRecords()) {
                if(Constants.equalsInteger(discountLog.getType(),Constants.ZERO)&&Objects.nonNull(discountLog.getRidePrice())){
                    discountLog.setRidePrice(
                            Constants.translateMoney(discountLog.getRidePrice())
                    );
            }
        }
        return PageData.from(discountLogMapper.selectPage(page, queryWrapper));
        }
        return pageData;
    }
    @Override
server/services/src/main/java/com/doumee/service/business/impl/DiscountMemberServiceImpl.java
@@ -104,18 +104,20 @@
        if(Objects.isNull(discountMember)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        List<DiscountLog> discountLogList = discountLogMapper.selectJoinList(DiscountLog.class,new MPJLambdaWrapper<DiscountLog>()
                .selectAll(DiscountLog.class)
                .selectAs(SystemUser::getRealname,DiscountLog::getCreatorName)
                .eq(DiscountLog::getDiscountMemberId,discountMember.getId())
                .eq(DiscountLog::getIsdeleted,Constants.ZERO)
                .orderByDesc(DiscountLog::getId)
        );
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(discountLogList)){
            discountMember.setDiscountLogList(discountLogList.stream().filter(i->Constants.equalsInteger(i.getType(),Constants.ZERO)).collect(Collectors.toList()));
            discountMember.setOptLogList(discountLogList.stream().filter(i->!Constants.equalsInteger(i.getType(),Constants.ZERO)).collect(Collectors.toList()));
            discountMember.setUseTimes(discountMember.getDiscountLogList().size());
        }
//        List<DiscountLog> discountLogList = discountLogMapper.selectJoinList(DiscountLog.class,new MPJLambdaWrapper<DiscountLog>()
//                .selectAll(DiscountLog.class)
//                .selectAs(SystemUser::getRealname,DiscountLog::getCreatorName)
//                .leftJoin(SystemUser.class,SystemUser::getId,DiscountLog::getCreator)
//                .eq(DiscountLog::getDiscountMemberId,discountMember.getId())
//                .eq(DiscountLog::getIsdeleted,Constants.ZERO)
//                .orderByDesc(DiscountLog::getId)
//        );
//        discountMember.setUseTimes(discountMember.getDiscountLogList().size());
//        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(discountLogList)){
//            discountMember.setDiscountLogList(discountLogList.stream().filter(i->Constants.equalsInteger(i.getType(),Constants.ZERO)).collect(Collectors.toList()));
//            discountMember.setOptLogList(discountLogList.stream().filter(i->!Constants.equalsInteger(i.getType(),Constants.ZERO)).collect(Collectors.toList()));
//
//        }
        return discountMember;
    }
@@ -138,12 +140,15 @@
        Utils.MP.blankToNull(pageWrap.getModel());
        DiscountMember model = pageWrap.getModel();
        queryWrapper.selectAll(DiscountMember.class)
                .selectAs(Member::getOpenid,DiscountMember::getOpenid)
                .select(" ( select count(1) from discount_log d where d.discount_member_id = t.id and d.type = 0 ) ",DiscountMember::getUseTimes)
                .leftJoin(Member.class,Member::getId,DiscountMember::getMemberId)
                .like(StringUtils.isNotBlank(model.getCode()),DiscountMember::getCode,model.getCode())
                .like(StringUtils.isNotBlank(model.getName()),DiscountMember::getName,model.getName())
                .like(StringUtils.isNotBlank(model.getOpenid()),Member::getOpenid,model.getOpenid())
                .eq(Objects.nonNull(model.getStatus()),DiscountMember::getStatus,model.getStatus())
                .orderByDesc(DiscountMember::getId);
                .ne(DiscountMember::getStatus,Constants.TWO)
                .orderByDesc(DiscountMember::getCode);
        return PageData.from(discountMemberJoinMapper.selectJoinPage(page, DiscountMember.class,queryWrapper));
    }
@@ -164,9 +169,12 @@
                .orderByDesc(DiscountMember::getId);
        List<DiscountMember> list = discountMemberJoinMapper.selectJoinList(DiscountMember.class,queryWrapper);
        if(CollectionUtils.isEmpty(list)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"未查询到可报废的套餐卡信息");
            return;
        }
        for (DiscountMember discountMember:list) {
            if(!Constants.equalsInteger(discountMember.getStatus(),Constants.ZERO)){
                continue;
            }
            discountMemberMapper.update(null,new UpdateWrapper<DiscountMember>().lambda()
                    .set(DiscountMember::getStatus,Constants.ONE)
                    .eq(DiscountMember::getId,discountMember.getId())
@@ -183,7 +191,6 @@
            discountLog.setGoodsorderId(discountMember.getGoodsorderId());
            discountLogMapper.insert(discountLog);
        }
        //退款操作
    }
@@ -228,8 +235,9 @@
            discountLog.setDiscountMemberId(discountMember.getId());
            discountLog.setType(Constants.TWO);
            discountLog.setGoodsorderId(discountMember.getGoodsorderId());
            discountLog.setEditInfo(model.getInfo());
            discountLog.setInfo(model.getInfo());
            discountLog.setEditDays(model.getAddDays());
            discountLog.setEditInfo("将有效期增加"+model.getAddDays()+"天, è°ƒæ•´åŽæœ‰æ•ˆæœŸè‡³"+useEndDate);
            discountLogMapper.insert(discountLog);
        }
server/services/src/main/java/com/doumee/service/business/impl/DiscountServiceImpl.java
@@ -31,6 +31,7 @@
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@@ -60,6 +61,8 @@
        discount.setIsdeleted(Constants.ZERO);
        discount.setCreateDate(new Date());
        discount.setCreator(userInfo.getId());
        discount.setEditDate(new Date());
        discount.setEditor(userInfo.getId());
        if(Constants.equalsInteger(discount.getUseType(),Constants.ZERO)){
            discount.setUseDays((int) (DateUtil.getBetweenDays(DateUtil.dateToString(discount.getUseStartDate(),"yyyy-MM-dd"),DateUtil.dateToString(discount.getUseEndDate(),"yyyy-MM-dd"))));
        }
@@ -95,13 +98,21 @@
                ( discount.getUseStartDate().getTime()>discount.getUseEndDate().getTime()) ){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"使用时段信息错误");
        }
        //指定日期生效
        if(Constants.equalsInteger(discount.getUseType(),Constants.TWO) &&
                ( discount.getUseStartDate().getTime()<discount.getStartDate().getTime() ||
                        discount.getUseStartDate().getTime() > discount.getEndDate().getTime()
                ) ){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"使用时段信息错误");
        }
        if(Objects.isNull(discount.getSaleDayLimit())){
            discount.setSaleDayLimit(Constants.ZERO);
        }
        if(Objects.isNull(discount.getSaleLimit())){
            discount.setSaleLimit(Constants.ZERO);
        }
        if(Constants.equalsInteger(discount.getUseType(),Constants.TWO)){
            discount.setUseEndDate( DateUtil.StringToDateFormat(DateUtil.getXDaysAfter(discount.getUseStartDate(),discount.getUseDays()),"yyyy-MM-dd"));
        }
    }
@@ -146,6 +157,24 @@
    @Override
    public void updateById(Discount discount) {
        LoginUserInfo userInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(discount)
        || StringUtils.isBlank(discount.getId())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        Discount model = discountMapper.selectById(discount.getId());
        if(Objects.isNull(model)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY);
        }
        if(!Constants.equalsInteger(model.getStatus(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"未禁用无法进行修改");
        }
        this.vaildReq(discount);
        discount.setEditDate(new Date());
        discount.setEditor(userInfo.getId());
        if(Constants.equalsInteger(discount.getUseType(),Constants.ZERO)){
            discount.setUseDays((int) (DateUtil.getBetweenDays(DateUtil.dateToString(discount.getUseStartDate(),"yyyy-MM-dd"),DateUtil.dateToString(discount.getUseEndDate(),"yyyy-MM-dd"))));
        }
        discountMapper.updateById(discount);
    }
@@ -163,8 +192,11 @@
    public Discount findById(String id) {
        Discount discount = discountJoinMapper.selectOne(new MPJLambdaWrapper<Discount>()
                        .selectAll(Discount.class)
                .select(" s1.realname ",Discount::getCreatorName)
                .select(" s2.realname ",Discount::getEditorName)
                .select(" (select count(1) from goodsorder g where g.obj_type = 0 and g.obj_id = t.id and g.pay_status = 1 ) ",Discount::getSaleNum)
                .leftJoin(SystemUser.class,SystemUser::getId,Discount::getCreator)
                .leftJoin(" system_user s1 on s1.id = t.creator")
                .leftJoin(" system_user s2 on s2.id = t.editor")
                .eq(Discount::getId,id)
        );
        if(Objects.isNull(discount)){
@@ -205,7 +237,9 @@
                .eq(Objects.nonNull(modele.getBikeOrElec()) && Constants.equalsInteger(modele.getBikeOrElec(),Constants.ONE),Discount::getIsbike, Constants.ONE)
                .eq(Objects.nonNull(modele.getBikeOrElec()) && Constants.equalsInteger(modele.getBikeOrElec(),Constants.TWO),Discount::getIselecbike, Constants.ONE)
                .eq(Discount::getIsdeleted, Constants.ZERO)
                .eq( pageWrap.getModel().getStatus() !=null,BikeRepair::getStatus,pageWrap.getModel().getStatus());
                .eq( pageWrap.getModel().getStatus() !=null,BikeRepair::getStatus,pageWrap.getModel().getStatus())
                .apply( Objects.nonNull(modele.getMinShow())," now() BETWEEN t.start_date and  ( t.end_date   + INTERVAL '1 day' ) ")
        ;
                queryWrapper.orderByDesc(Discount::getCreateDate);
        PageData<Discount> pageData = PageData.from(discountJoinMapper.selectJoinPage(page, Discount.class,queryWrapper));
        for (Discount discount:pageData.getRecords()) {
@@ -219,8 +253,7 @@
    @Override
    public void dealPrice(Discount discount){
        if(Objects.isNull(discount)
            || Objects.isNull(discount.getUseEndDate())
            || Objects.isNull(discount.getUseStartDate())
            || Objects.isNull(discount.getUseDays())
            || Objects.isNull(discount.getPrice())
            || discount.getPrice().compareTo(BigDecimal.ZERO)==0
        ){
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java
@@ -295,8 +295,10 @@
        MPJLambdaWrapper<Goodsorder> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(Goodsorder.class);
        queryWrapper.selectAs(Member::getOpenid, Goodsorder::getOpenid);
        queryWrapper.selectAs(DiscountMember::getName, Goodsorder::getDiscountName);
        queryWrapper.leftJoin(Member.class, Member::getId  ,Goodsorder::getMemberId);
        queryWrapper.select("(select r.name from discount_member r where r.isdeleted=0  and r.goodsorder_id=t.id limit 1) as discountName");
        queryWrapper.leftJoin(DiscountMember.class, DiscountMember::getGoodsorderId  ,Goodsorder::getId);
//        queryWrapper.select("(select r.name from discount_member r where r.isdeleted=0  and r.goodsorder_id=t.id limit 1) as discountName");
        queryWrapper.select("(select max(r.done_date) from refund r where r.obj_id=t.id  and  r.status in(0,2)) as refund_date");
        queryWrapper.select("(select sum(r.money) from refund r where r.obj_id=t.id and r.status in(0,2)) as refund_money");
        //时间段筛选
@@ -310,11 +312,13 @@
        queryWrapper.like(model.getCode() !=null,Goodsorder::getCode,model.getCode());
        queryWrapper.like(model.getId() !=null,Goodsorder::getId,model.getId());
        queryWrapper.eq(model.getStatus() !=null,Goodsorder::getStatus,model.getStatus());
        queryWrapper.eq(model.getPayWay() !=null,Goodsorder::getPayWay,model.getPayWay());
        queryWrapper.like(model.getOnlineOrderid() !=null,Goodsorder::getOnlineOrderid,model.getOnlineOrderid());
        queryWrapper.like(model.getOpenid() !=null,Member::getOpenid,model.getOpenid());
        queryWrapper.eq(Goodsorder::getIsdeleted,Constants.ZERO);
        //如果是骑行订单只显示支付成功的
        queryWrapper.eq(Constants.equalsInteger(model.getType(),Constants.ZERO),Goodsorder::getPayStatus,Constants.ONE);
        queryWrapper.in(Constants.equalsInteger(model.getType(),Constants.ONE),Goodsorder::getStatus,Constants.ONE,Constants.ZERO);
        return  queryWrapper;
    }
@@ -336,7 +340,7 @@
        if(Objects.nonNull(pageWrap.getModel().getCloseStatus()) && pageWrap.getModel().getCloseStatus().equals(Constants.ONE)){
            queryWrapper.eq(Goodsorder::getStatus,Constants.GOODSORDER_STATUS.CLOSE.getKey());
        }
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getDiscountName()),Goodsorder::getDiscountName,pageWrap.getModel().getDiscountName());
        queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getDiscountName()),DiscountMember::getName,pageWrap.getModel().getDiscountName());
        IPage<Goodsorder> goodsorderIPage = goodsorderJoinMapper.selectJoinPage(page, Goodsorder.class, queryWrapper);
        if (!CollectionUtils.isEmpty(goodsorderIPage.getRecords())){
            goodsorderIPage.getRecords().forEach(s->{
@@ -382,6 +386,7 @@
                discountMapper.selectList(new QueryWrapper<Discount>().lambda()
                        .eq(Discount::getIsdeleted,Constants.ZERO)
                        .eq(Discount::getStatus,Constants.ZERO)
                        .apply(" now() BETWEEN start_date and  ( end_date   + INTERVAL '1 day' )  ")
                        .orderByDesc(Discount::getId)
                        .last(" limit 3 ")
                )
@@ -452,7 +457,7 @@
                        memberRidesResponse.setVoltageStatus(this.getVoltageStatus(bikes));
                    }
                    //查询当前的骑行套餐
                    memberRidesResponse.setDiscountMember(this.getUseDiscount(memberId,Constants.ZERO));
                    memberRidesResponse.setDiscountMember(this.getUseDiscount(memberId,Constants.ZERO,memberRides.getType()));
                    homeResponse.setMemberRidesResponse(memberRidesResponse);
                }
            }
@@ -534,6 +539,7 @@
        if(Constants.equalsInteger(goodsorder.getType(),Constants.ZERO)){
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED);
        }
        goodsorder.setMoney(Constants.translateMoney(goodsorder.getMoney()));
        goodsorderDetailVO.setGoodsOrder(goodsorder);
        Member member = memberMapper.selectById(goodsorder.getMemberId());
        if(Objects.nonNull(member)){
@@ -555,6 +561,13 @@
                        .eq(Refund::getObjId,goodsorder.getId())
                        .orderByDesc(Refund::getId)
        );
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(refunds)){
            for (Refund refund:refunds) {
                if(Objects.nonNull(refund.getMoney())){
                    refund.setMoney(Constants.translateMoney(refund.getMoney()));
                }
            }
        }
        goodsorderDetailVO.setRefundList(refunds);
        return goodsorderDetailVO;
@@ -614,7 +627,7 @@
                freeTime = Integer.parseInt(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode());
            }catch (Exception e){
            }
            closeMoney = getCloseMoneyByRides(memberRides,freeTime,true,goodsorder.getMoney(),goodsorder.getMemberId()).getAmount();
            closeMoney = getCloseMoneyByRides(memberRides,freeTime,true,goodsorder.getMoney(),goodsorder.getMemberId(),true).getAmount();
            //实际结算价格,记录在最高车型记录上
//            memberRides.get(0).setActualPrice(closeMoney);
        }
@@ -779,7 +792,7 @@
        transactionsMapper.insert(transactions);
    }
    private RidesDetailResponse  getCloseMoneyByRides(List<MemberRides> memberRides,int freeTime,boolean isClose,BigDecimal yjMoney,String memberId) {
    private RidesDetailResponse  getCloseMoneyByRides(List<MemberRides> memberRides,int freeTime,boolean isClose,BigDecimal yjMoney,String memberId,Boolean unOver) {
        RidesDetailResponse ridesDetailResponse = new RidesDetailResponse();
        ridesDetailResponse.setHaveDisCount(Constants.ZERO);
        BigDecimal closeMoney = new BigDecimal(0.00);
@@ -816,9 +829,10 @@
            topRides.setActualPrice(closeMoney);
        } 
        //查询是否存在套餐信息
        DiscountMember discountMember = this.getUseDiscount(memberId,durationSum);
        DiscountMember discountMember = this.getUseDiscount(memberId,durationSum,Objects.nonNull(topRides)?topRides.getType():null);
        //计算抵扣金额
        if(Objects.nonNull(discountMember) && discountMember.getSurplusTime() > Constants.ZERO && Objects.nonNull(topRides)){
        //unOver æ˜¯å¦æœªç»“ç®— æœªç»“算的订单根据当前套餐查询  å·²ç»“算的订单根据已生成的数据进行查询
        if(Objects.nonNull(discountMember) && Objects.nonNull(topRides) && unOver){
            //存储抵扣记录
            DiscountLog discountLog = new DiscountLog();
            discountLog.setIsdeleted(Constants.ZERO);
@@ -830,7 +844,7 @@
            discountLog.setEditInfo("骑行抵扣");
            discountLog.setGoodsorderId(topRides.getOrdreId());
            //如果骑行时间小于等于剩余时间 åˆ™ç›´æŽ¥æ·»åŠ  éª‘行卡使用数据  ä¿®æ­£å®žé™…支付金额
            if(discountMember.getSurplusTime() >= durationSum){
            if(Constants.equalsInteger(discountMember.getLimitType(),Constants.ZERO) || discountMember.getSurplusTime() >= durationSum){
                discountLog.setRideTime(durationSum);
                discountLog.setRidePrice(closeMoney);
                topRides.setActualPrice(BigDecimal.ZERO);
@@ -838,9 +852,10 @@
            }else{
                int baseTime =Constants.formatIntegerNum(topRides.getBaseTime());
                BigDecimal closeDisCountMoney = Constants.formatDecimalNum(topRides.getBasePrice());
                //如果是一口价方式,价格直接为一口价baseMoney,如果不是计算正常价格
                //减去优惠时长剩余时长
                Integer durationDisCountSum = durationSum - discountMember.getSurplusTime();
                discountLog.setRideTime(discountMember.getSurplusTime());
                discountLog.setRideTime(durationDisCountSum<=Constants.ZERO?discountMember.getSurplusTime():Constants.ZERO);
                //如果是一口价方式,价格直接为一口价baseMoney,如果不是计算正常价格
                if(baseTime != -1){//不是一口价
                    if(durationDisCountSum > baseTime && Constants.formatIntegerNum(topRides.getUnitTime())>0){
                        //如果超出了起步价格,计算超出价格
@@ -848,14 +863,25 @@
                        //计算金额累计超出部门价格(超出时间单位*超出单位时间价格)
                        closeDisCountMoney = closeDisCountMoney.add(unit.multiply(Constants.formatDecimalNum(topRides.getUnitPrice())));
                    }
                    discountLog.setRidePrice(closeMoney.subtract(closeDisCountMoney));
                    discountLog.setRidePrice(durationDisCountSum<=Constants.ZERO?closeMoney.subtract(closeDisCountMoney):BigDecimal.ZERO);
                }else{
                    discountLog.setRidePrice(BigDecimal.ZERO);
                }
            }
            if(isClose&&discountLog.getRideTime()>Constants.ZERO){
            discountLogMapper.insert(discountLog);
            ridesDetailResponse.setHaveDisCount(Constants.ONE);
            }
            ridesDetailResponse.setHaveDisCount(discountLog.getRideTime()>Constants.ZERO?Constants.ONE:Constants.ZERO);
            ridesDetailResponse.setDisCountMoney(discountLog.getRidePrice());
        }else if(Objects.nonNull(discountMember) && Objects.nonNull(topRides)
                && !unOver ){
            //已还车则查询是否有 å¥—餐卡使用记录
            List<DiscountLog> discountLogList = discountLogMapper.selectList(new QueryWrapper<DiscountLog>().lambda().eq(DiscountLog::getGoodsorderId,topRides.getOrdreId()).eq(DiscountLog::getType,Constants.ZERO)
                    .eq(DiscountLog::getIsdeleted,Constants.ZERO));
            if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(discountLogList)){
                ridesDetailResponse.setHaveDisCount(Constants.ONE);
                ridesDetailResponse.setDisCountMoney(discountLogList.stream().map(i->i.getRidePrice()).reduce(BigDecimal.ZERO,BigDecimal::add));
            }
        }
        //如果订单价格封顶了,取订单 ä»·æ ¼
        if(Constants.compareBigdecimal(closeMoney, yjMoney) ==1){
@@ -888,7 +914,6 @@
        LoginUserInfo principal = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(goodsorderBackDTO)
        || StringUtils.isBlank(goodsorderBackDTO.getOrderId())
                || StringUtils.isBlank(goodsorderBackDTO.getReason())
                || Objects.isNull(goodsorderBackDTO.getBackType())
                || Objects.isNull(goodsorderBackDTO.getMoney())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
@@ -1060,7 +1085,8 @@
                .selectAs(BaseParam::getSortnum,MemberRides::getSortnum)
                .leftJoin(BaseParam.class,BaseParam::getId,MemberRides::getParamId)
                .eq(MemberRides::getOrdreId,id)
                .in(MemberRides::getStatus,Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey(),Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey())
                .in(MemberRides::getStatus,Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey()
                        ,Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey(),Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey())
                .orderByDesc(MemberRides::getCreateDate));
        if (!CollectionUtils.isEmpty(memberRides)){
            //预计结算价格和计算时长
@@ -1096,7 +1122,8 @@
                return memberRidesResponse;
            }).collect(Collectors.toList());
            //累计和预算结算金额
            RidesDetailResponse ridesDetailResponse = getCloseMoneyByRides(memberRides,freeTime,false,goodsorder.getMoney(),goodsorder.getMemberId());
            RidesDetailResponse ridesDetailResponse = getCloseMoneyByRides(memberRides,freeTime,false,goodsorder.getMoney(),goodsorder.getMemberId(),
                    Constants.equalsInteger(goodsorder.getStatus(),Constants.GOODSORDER_STATUS.CLOSE.getKey())?false:true);
            if(Constants.formatIntegerNum(goodsorder.getStatus())!= Constants.goodsorderStatus.pay){
                //如果非已支付但未结算,使用订单金额
                ridesDetailResponse.setAmount(goodsorder.getCloseMoney());
@@ -1174,8 +1201,13 @@
        discountMember.setMemberId(memberId);
        discountMember.setStatus(Constants.TWO);
        discountMember.setGoodsorderId(goodsorderId);
        if(!Constants.equalsInteger(discountMember.getUseType(),Constants.ZERO)){
            if(Constants.equalsInteger(discountMember.getUseType(),Constants.ONE)){
                discountMember.setUseStartDate(DateUtil.StringToDateFormat(DateUtil.getCurrDate(),"yyyy-MM-dd"));
            }
            discountMember.setUseEndDate( DateUtil.StringToDateFormat(DateUtil.getXDaysAfter(discountMember.getUseStartDate(),discountMember.getUseDays()-1),"yyyy-MM-dd"));
        }
        discountMemberMapper.insert(discountMember);
        Goodsorder goodsorder = new Goodsorder();
        goodsorder.setId(goodsorderId);
        goodsorder.setCreateDate(new Date());
@@ -1207,7 +1239,7 @@
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未查询到套餐信息");
        }
        if(!(Constants.equalsInteger(discount.getIsdeleted(),Constants.ZERO)
            ||Constants.equalsInteger(discount.getStatus(),Constants.ZERO))){
             && Constants.equalsInteger(discount.getStatus(),Constants.ZERO))){
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"套餐已下架,无法进行购买,请刷新查看");
        }
        if(!(discount.getStartDate().getTime() < System.currentTimeMillis()
@@ -1215,7 +1247,7 @@
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"套餐开放时间未到,无法进行购买");
        }
        //验证是否超过今日可售卖数量
        if(Objects.nonNull(discount.getSaleDayLimit())){
        if(Objects.nonNull(discount.getSaleDayLimit())&&discount.getSaleDayLimit()>Constants.ZERO){
            if(goodsorderMapper.selectCount(new QueryWrapper<Goodsorder>().lambda()
                    .eq(Goodsorder::getType,Constants.ONE)
                    .eq(Goodsorder::getObjId,discount.getId())
@@ -1225,13 +1257,12 @@
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"套餐今日发行量已售罄,请明日查看!");
            }
        }
        if(Objects.nonNull(discount.getSaleLimit())){
        if(Objects.nonNull(discount.getSaleLimit())&&discount.getSaleLimit()>Constants.ZERO){
            if(goodsorderMapper.selectCount(new QueryWrapper<Goodsorder>().lambda()
                    .eq(Goodsorder::getType,Constants.ONE)
                    .eq(Goodsorder::getObjId,discount.getId())
                    .in(Goodsorder::getStatus,Constants.ZERO,Constants.ONE)
                    .apply(" EXTRACT(YEAR FROM create_date) = EXTRACT(YEAR FROM CURRENT_DATE) ")
            )>=discount.getSaleDayLimit()){
            )>=discount.getSaleLimit()){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"套餐发行量已售罄!");
            }
        }
@@ -1240,8 +1271,8 @@
    private Object getWxPayResponse(Goodsorder goodsorder,String openid){
        //调起支付
        Object response = null;
        //调起支付
        PrepayRequest request = new PrepayRequest();
        request.setAttach("createGoodsOrder");
        request.setDescription(Constants.equalsInteger(goodsorder.getType(),Constants.ZERO)?"森林公园自行车骑行押金支付":"森林公园自行车购买骑行套餐支付");
@@ -1368,6 +1399,7 @@
        Goodsorder goodsorder = this.goodsorderMapper.selectOne(new QueryWrapper<Goodsorder>()
                .eq("member_id",memberId)
                .eq("status",Constants.goodsorderStatus.pay)
                .eq("type",Constants.ZERO)
                .last(" limit 1 "));
        if(Objects.isNull(goodsorder)){
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"无骑行订单记录");
@@ -1514,7 +1546,10 @@
     * @param memberId
     */
    @Override
    public DiscountMember getUseDiscount(String memberId,Integer driveTime){
    public DiscountMember getUseDiscount(String memberId,Integer driveTime,Integer type){
        if(Objects.isNull(type)){
            return null;
        }
        String today = DateUtil.getToday();
        //判断今天是否为节假日
        Holidays holidays = new Holidays();
@@ -1528,9 +1563,13 @@
                        "and  d.isdeleted = 0 and  d.type = 0 and   EXTRACT(DAY FROM d.create_date) = EXTRACT(DAY FROM CURRENT_DATE) ) " , DiscountMember::getUseTime)//查询今日已使用时间
                .eq(DiscountMember::getStatus,Constants.ZERO)
                .eq(DiscountMember::getMemberId,memberId)
                .le(DiscountMember::getUseStartDate, Utils.Date.getStart(DateUtil.stringToDate(today,"yyyy-MM-dd")))
                .ge(DiscountMember::getUseEndDate, Utils.Date.getEnd(DateUtil.stringToDate(today,"yyyy-MM-dd")))
                .apply("  t.use_start_date <= '"+today+"' and t.use_end_date >= '"+today+"' ")
                .eq(Constants.equalsInteger(holiday,Constants.ZERO),DiscountMember::getUseWorkday,Constants.ONE)
                .eq(Constants.equalsInteger(holiday,Constants.ONE),DiscountMember::getUseHoliday,Constants.ONE)
                .eq(Constants.equalsInteger(type,Constants.ZERO),DiscountMember::getIsbike,Constants.ONE)
                .eq(Constants.equalsInteger(type,Constants.ONE),DiscountMember::getIselecbike,Constants.ONE)
                .orderByDesc(DiscountMember::getLimitType)
                .orderByDesc(DiscountMember::getLimitTime)
        );
@@ -1556,22 +1595,23 @@
                if(list.size()>Constants.ZERO){
                    //d1在前则升序 åä¹‹é™åº
                    list.sort((d1,d2)-> Integer.compare(d2.getSurplusTime(),d1.getSurplusTime()));
                }
                return list.get(Constants.ZERO);
                }
            }else{
                //无无期限的套餐 ä¼˜å…ˆæŸ¥è¯¢å‰©ä½™æ—¶é•¿å¤§äºŽéª‘行时长的信息(取时间最小的套餐) å†æŸ¥è¯¢å°äºŽéª‘行时长的套餐
                List<DiscountMember>  list =  discountMemberList.stream().filter(i->i.getSurplusTime()>=driveTime).collect(Collectors.toList());
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(list)){
                    if(list.size()>Constants.ZERO){
                        //d1在前则升序 åä¹‹é™åº
                        list.sort((d1,d2)-> Integer.compare(d2.getSurplusTime(),d1.getSurplusTime()));
                    }
                        list.sort((d1,d2)-> Integer.compare(d1.getSurplusTime(),d2.getSurplusTime()));
                    return list.get(Constants.ZERO);
                    }
                }
                list =  discountMemberList.stream().filter(i->i.getSurplusTime()<driveTime).collect(Collectors.toList());
                if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(list)){
                    if(list.size()>Constants.ZERO){
                        list.sort((d1,d2)-> Integer.compare(d1.getSurplusTime(),d2.getSurplusTime()));
                        list.sort((d1,d2)-> Integer.compare(d2.getSurplusTime(),d1.getSurplusTime()));
                    }
                    return list.get(Constants.ZERO);
                }
@@ -1582,6 +1622,7 @@
    @Override
    public void autCancel(){
        goodsorderMapper.update(null,new UpdateWrapper<Goodsorder>().lambda()
                .set(Goodsorder::getStatus,Constants.GOODSORDER_STATUS.CANCEL.getKey())
server/services/src/main/java/com/doumee/service/business/impl/MemberRidesServiceImpl.java
@@ -398,7 +398,7 @@
            }
        }else{
            //如果是电车,请求web端接口关闭车辆信息
            bike =   sendCloseElecBikeRequest(memberRides.getBikeCode(),Constants.ONE);
            bike  = sendCloseElecBikeRequest(model.getOrdreId(),memberRides.getBikeCode());
        }
        logInfo = bike!=null?bike.getForceBackInfo():null;
        Integer freeRentTime = Integer.valueOf(collect.get(Constants.FREE_RENT_TIME).getCode());
@@ -438,7 +438,7 @@
    /**
     *  å¦‚果是电车,请求web端接口关闭车辆信息
     */
    private Bikes sendCloseElecBikeRequest(String bikeCode,int type) {
    private Bikes sendCloseElecBikeRequest(String goodOrderId,String bikeCode) {
        Bikes  bike = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda()
                .eq(Bikes::getType,Constants.ONE)
                .eq(Bikes::getIsdeleted,Constants.ZERO)
@@ -453,8 +453,7 @@
                //请求地址
                String url = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.ELEC_BIKE_CONTRIL_API_URL).getCode();
                JSONObject param = new JSONObject();
                param.put("clientId",StringTools.leftTrip(bike.getDeviceSn(),'0'));
                param.put("type",type);//0开锁 1关锁
                param.put("id", goodOrderId);
                String res = HttpsUtil.postJsonString(url,param.toJSONString());
                JSONObject json = JSONObject.parseObject(res);
                if(json.get("code").equals("200")){
@@ -469,9 +468,42 @@
        }else{
            bike.setForceBackInfo("强制还车关闭车锁失败,未绑定控制器sn!");
        }
        bikesMapper.updateById(bike);
        return bike;
    }
//    private Bikes sendCloseElecBikeRequest(String bikeCode,int type) {
//        Bikes  bike = bikesMapper.selectOne(new QueryWrapper<Bikes>().lambda()
//                .eq(Bikes::getType,Constants.ONE)
//                .eq(Bikes::getIsdeleted,Constants.ZERO)
//                .eq(Bikes::getCode,bikeCode)
//        );
//        if(bike == null){
//            return null;
//        }
//        bike.setForceBackInfo("强制还车关闭车锁失败!");
//        if(StringUtils.isNotBlank(bike.getDeviceSn())){
//            try {
//                //请求地址
//                String url = systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.ELEC_BIKE_CONTRIL_API_URL).getCode();
//                JSONObject param = new JSONObject();
//                param.put("clientId",StringTools.leftTrip(bike.getDeviceSn(),'0'));
//                param.put("type",type);//0开锁 1关锁
//                String res = HttpsUtil.postJsonString(url,param.toJSONString());
//                JSONObject json = JSONObject.parseObject(res);
//                if(json.get("code").equals("200")){
//                    //发起指令成功
//                    bike.setForceBackInfo("强制还车关闭车锁成功!");
//                }else{
//                    bike.setForceBackInfo("强制还车关闭车锁失败!"+json.get("msg"));
//                }
//            }catch (Exception e){
//                e.printStackTrace();
//            }
//        }else{
//            bike.setForceBackInfo("强制还车关闭车锁失败,未绑定控制器sn!");
//        }
//        bikesMapper.updateById(bike);
//        return bike;
//    }
    public static void main(String[] args) {
        String url = "http://localhost:10025/jtt808/device/8500";
@@ -771,7 +803,7 @@
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"当前车辆类型无法租赁,请联系管理员!");
        }
        memberRidesResponse.setBikeCode(bike.getCode());
        memberRidesResponse.setBikeTypeName(baseParam.getName());
        memberRidesResponse.setBikeType(baseParam.getName());
        MemberRides memberRides = new MemberRides();
        this.dealMemberRidesData(baseParam.getId(),memberRides);
        memberRidesResponse.setBasePrice(memberRides.getBasePrice());
@@ -783,7 +815,7 @@
                memberRidesResponse.getUnitPrice()
                ,memberRidesResponse.getUnitTime()));
        //查询当前的骑行套餐
        memberRidesResponse.setDiscountMember(goodsorderService.getUseDiscount(memberId,Constants.ZERO));
        memberRidesResponse.setDiscountMember(goodsorderService.getUseDiscount(memberId,Constants.ZERO,bikeType));
        return memberRidesResponse;
    }
server/services/src/main/java/com/doumee/service/business/impl/TransactionsServiceImpl.java
@@ -192,13 +192,13 @@
                //购买套餐 å¤„理内容
                 DiscountMember discountMember = discountMemberMapper.selectById(transactions.getObjId());
                 if(Objects.nonNull(discountMember)){
                     transactions.setContent(discountMember.getName() +" æœ‰æ•ˆæœŸ" + DateUtil.dateToString(discountMember.getUseStartDate(),"yyyy-MM-dd") +"-"+DateUtil.dateToString(discountMember.getUseEndDate(),"yyyy-MM-dd"));
                     transactions.setContent(discountMember.getName() +" | æœ‰æ•ˆæœŸ" + DateUtil.dateToString(discountMember.getUseStartDate(),"yyyy-MM-dd") +" è‡³ "+DateUtil.dateToString(discountMember.getUseEndDate(),"yyyy-MM-dd"));
                 }
            }else if(Constants.equalsInteger(transactions.getType(),Constants.TRANSACTIONS_TYPE.PLATFORM_REFUND.getKey())){
                DiscountMember discountMember = discountMemberMapper.selectOne(
                        new QueryWrapper<DiscountMember>().lambda().eq(DiscountMember::getGoodsorderId, transactions.getOrderId()).last("limit 1"));
                if(Objects.nonNull(discountMember)){
                    transactions.setContent(discountMember.getName() +" æœ‰æ•ˆæœŸ" + DateUtil.dateToString(discountMember.getUseStartDate(),"yyyy-MM-dd") +"-"+DateUtil.dateToString(discountMember.getUseEndDate(),"yyyy-MM-dd"));
                    transactions.setContent(discountMember.getName() +" | æœ‰æ•ˆæœŸ" + DateUtil.dateToString(discountMember.getUseStartDate(),"yyyy-MM-dd") +" è‡³ "+DateUtil.dateToString(discountMember.getUseEndDate(),"yyyy-MM-dd"));
                }
            }
        }
server/services/src/main/resources/application-dev.yml
@@ -50,12 +50,13 @@
    apiV3Key: iF3kC8pL8dZ9iU3hN5fX9zI6eF4xQ6fT
    serialNumer: 368B835A194384FD583B83B77977B84127D2F655
    mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S
    notifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxPayNotify
    refundNotifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxRefundNotify
#    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    keyPath: D://apiclient_cert.p12
    privateCertPath: D://apiclient_cert.pem
    privateKeyPath: D://apiclient_key.pem
#    notifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxPayNotify
#    refundNotifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxRefundNotify
    notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
    refundNotifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxRefundNotify
    keyPath: /usr/local/aliConfig/bike/apiclient_cert.p12
    privateCertPath: /usr/local/aliConfig/bike/apiclient_cert.pem
    privateKeyPath: /usr/local/aliConfig/bike/apiclient_key.pem
    #服务商-------------end---
    existsSub: 1
    appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
server/web/src/main/java/com/doumee/api/web/BusinessApi.java
@@ -181,6 +181,7 @@
    public ApiResponse<PageData<Discount>> discountPage (@RequestBody PageWrap<Discount> pageWrap) {
        Discount discount = new Discount();
        discount.setStatus(Constants.ZERO);
        discount.setMinShow(Constants.ZERO);
        pageWrap.setModel(discount);
        return ApiResponse.success(discountService.findPage(pageWrap));
    }
@@ -326,10 +327,9 @@
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse openElecBike(@RequestBody OpenElecBikeRequest param) {
    public ApiResponse<MemberRidesDetailResponse> openElecBike(@RequestBody OpenElecBikeRequest param) {
        param.setMemberId(getMemberId());
        jtt808Service.openLock(param);
        return  ApiResponse.success( null);
        return  ApiResponse.success(jtt808Service.openLock(param));
    }
    @LoginRequired
@@ -344,5 +344,10 @@
        return  ApiResponse.success( null);
    }
    @ApiOperation(value = "强制还车", notes = "强制还车")
    @PostMapping("/forceBack")
    public ApiResponse forceBack(@RequestBody Goodsorder goodsorder) {
        jtt808Service.forceBack(goodsorder.getId());
        return  ApiResponse.success( null);
    }
}
server/web/src/main/java/com/doumee/jtt808/web/service/Jtt808Service.java
@@ -80,7 +80,6 @@
    @Autowired
    private MemberRidesJoinMapper memberRidesJoinMapper;
    @Autowired
    private PricingParamMapper pricingParamMapper;
@@ -102,6 +101,10 @@
        return  data;
    }
    /**
     * æ‰‹åŠ¨è¿˜è½¦
     * @param param
     */
    @Transactional(rollbackFor = {BusinessException.class})
    public   void backElecBike(BackElecBikeRequest param) {
        Member member = memberMapper.selectById(param.getMemberId());
@@ -113,6 +116,22 @@
        gparam.setStatus(Constants.goodsorderStatus.pay);
        gparam.setType(Constants.ZERO);
        Goodsorder goodsorder =  goodsorderService.findOne(gparam);
        this.backBike(goodsorder);
    }
    /**
     * è‡ªåŠ¨è¿˜è½¦
     * @param id
     */
    @Transactional
    public void forceBack(String id){
        Goodsorder goodsorder =  goodsorderService.findById(id);
        this.backBike(goodsorder);
    }
    @Transactional(rollbackFor = {BusinessException.class})
    public void backBike(Goodsorder goodsorder){
        if(Objects.isNull(goodsorder)){
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"无骑行订单记录");
        }
@@ -127,15 +146,15 @@
                if(Constants.equalsInteger(rides.getStatus(),Constants.MEMBER_RIDES_STATUS.RIDES_RUNNING.getKey())
                        &&Constants.equalsInteger(rides.getType(),Constants.ONE)){
                    //如果是电车并且是骑行中 è¿›è¡Œå…³é”å¤„理
//                    Bikes  bike = getElecBikeByCode(rides.getBikeCode());
//                    //查询停车站点信息
//                    if(bike.getSiteId() ==null){
//                        throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按要求前往停车点停车!");
//                    }
//                    lockBikes(bike.getDeviceSn(),Constants.ZERO);//发起关锁指令请求
                    Bikes  bike = getElecBikeByCode(rides.getBikeCode());
                    //查询停车站点信息
                    if(bike.getSiteId() ==null){
                        throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "对不起,请按要求前往停车点停车!");
                    }
                    lockBikes(bike.getDeviceSn(),Constants.ZERO);//发起关锁指令请求
                    backIds.add(rides.getId());
                    rides.setStatus(Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey());//已还车
//                    rides.setBackSiteId(bike.getSiteId());//还车站点
                    rides.setBackSiteId(bike.getSiteId());//还车站点
                    rides.setBackDate(new Date());
                    Integer freeRentTime = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode());
@@ -194,7 +213,7 @@
        APIResult<T0201_0500> data = result.block();
        if(!data.isSuccess()){
            //如果开锁失败,则返回异常
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,"+(type ==0?"车辆开锁":"车辆关锁")+"失败,请稍后重试,或者联系园区管理人员!");
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,"+(type ==0?"车辆关锁":"车辆开锁")+"失败,请稍后重试,或者联系园区管理人员!");
        }
    }
@@ -243,6 +262,7 @@
        Goodsorder gparam = new Goodsorder();
        gparam.setMemberId(param.getMemberId());
        gparam.setStatus(Constants.goodsorderStatus.pay);
        gparam.setType(Constants.ZERO);
        Goodsorder goodsorder =  goodsorderService.findOne(gparam);
        if(Objects.isNull(goodsorder)){
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有骑行中订单记录");
@@ -256,9 +276,9 @@
        if(memberRides ==null || memberRides.getBikeCode() == null){
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有骑行中记录");
        }
//        Bikes bike = getElecBikeByCode(memberRides.getBikeCode());
//        //查询停车位置是否符合停车位置规范
//        checkPausePostionBiz(bike);
        Bikes bike = getElecBikeByCode(memberRides.getBikeCode());
        //查询停车位置是否符合停车位置规范
        checkPausePostionBiz(bike);
        memberRides.setPauseDate(new Date());
        memberRides.setEditDate(memberRides.getBackDate());
        memberRides.setStatus(Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey());
@@ -373,7 +393,7 @@
            //如果车辆类型是空
            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), " è¯¥è½¦åž‹æš‚时不能借车操作哦,请更换其他车型重试!");
        }
        cacheOpenLock.put(bike.getCode(), 1);
        cacheOpenLock.put(openElecBikeRequest.getCode(), 1);
        try {
            //判断当前是否已支付押金
            Goodsorder goodsorder = goodsorderService.findOneByWrapper(new QueryWrapper<Goodsorder>()
@@ -404,7 +424,7 @@
            //根据车型查询计价方案
            isValidePricingType(bike,memberRides) ;
            MemberRidesDetailResponse memberRidesDetailResponse = new MemberRidesDetailResponse();
//            this.lockBikes(bike.getDeviceSn(),1);
            this.lockBikes(bike.getDeviceSn(),1);
            //存储骑行记录
            memberRides.setId(Constants.getUUID());
            memberRides.setIsdeleted(Constants.ZERO);
@@ -420,10 +440,12 @@
            memberRidesJoinMapper.insert(memberRides);
            BeanUtils.copyProperties(memberRides, memberRidesDetailResponse);
            return memberRidesDetailResponse;
        }catch (Exception e){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "开锁失败,请联系管理员");
        }catch (BusinessException biz){
            throw  biz;
        }catch (Exception biz){
            throw  new BusinessException(ResponseStatus.SERVER_ERROR);
        }finally {
            cacheOpenLock.remove(bike.getCode());
            cacheOpenLock.remove(openElecBikeRequest.getCode());
        }
    }
@@ -437,6 +459,7 @@
        Goodsorder gparam = new Goodsorder();
        gparam.setMemberId(param.getMemberId());
        gparam.setStatus(Constants.goodsorderStatus.pay);
        gparam.setType(Constants.ZERO);
        Goodsorder goodsorder =  goodsorderService.findOne(gparam);
        if(Objects.isNull(goodsorder)){
            throw new BusinessException(ResponseStatus.NO_UNCLOSEED_ORDER.getCode(),"对不起,未查询到您当前有骑行中订单记录");
@@ -536,9 +559,10 @@
                .eq(MemberRides::getIsdeleted,Constants.ZERO)
                .eq(MemberRides::getType,Constants.ONE)
                .eq(MemberRides::getStatus,Constants.MEMBER_RIDES_STATUS.RIDES_PAUSING.getKey())
                .apply(" NOW() >= t.create_date  + INTERVAL '2 hours' ")
                .apply(" NOW() >= (t.create_date  + INTERVAL '"+systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME,Constants.PAUSE_AUTO_CLOSE_TIME).getCode()+" min') ")
        );
        ;
        for (MemberRides timeOutRides:memberRidesList) {
            Goodsorder goodsorder = goodsorderService.findById(timeOutRides.getOrdreId());
            //查询骑行记录
@@ -557,6 +581,10 @@
                        rides.setStatus(Constants.MEMBER_RIDES_STATUS.BACK_CYCLING.getKey());//已还车
                        rides.setBackSiteId(bike.getSiteId());//还车站点
                        rides.setBackDate(new Date());
                        Integer freeRentTime = Integer.valueOf(systemDictDataBiz.queryByCode(Constants.MINI_PROGRAMME, Constants.FREE_RENT_TIME).getCode());
                        Integer rideTime = DateUtil.betweenMin(rides.getRentDate(), rides.getBackDate());
                        //计算骑行计费时长
                        rides.setDuration( rideTime > freeRentTime  ? rideTime : 0 );
                        rides.setEditDate(rides.getBackDate());
                        memberRidesJoinMapper.updateById(rides);//更新骑行状态为已还车
                    }
@@ -570,10 +598,10 @@
            //发送小程序通知
            Member member = memberMapper.selectById(goodsorder.getMemberId());
            if(Objects.nonNull(member)&&StringUtils.isNotBlank(member.getOpenid())){
                sendWxMessage.bookingsCancel(member.getOpenid(),goodsorder.getId(), WxMiniConfig.wxMaService.getAccessToken(),timeOutRides.getBikeCode(),goodsorder.getPayDate(),goodsorder.getEndDate());
                sendWxMessage.bookingsCancel(member.getOpenid(),goodsorder.getId(),
                        WxMiniConfig.wxMaService.getAccessToken(),
                        timeOutRides.getBikeCode(),goodsorder.getPayDate(),goodsorder.getEditDate());
            }
        }
    }