doum
9 小时以前 b3752822ea0b7cfdac51b248dc56452d4242ce56
经销商管理
已添加1个文件
已修改5个文件
417 ■■■■■ 文件已修改
admin/src/api/business/memberCoupon.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaMemberCouponWindow.vue 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/business/memberCoupon.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmmall_admin/src/main/java/com/doumee/api/business/MemberCouponController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmmall_service/src/main/java/com/doumee/dao/business/model/MemberCoupon.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmmall_service/src/main/java/com/doumee/dao/system/model/SystemUser.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/memberCoupon.js
@@ -6,3 +6,14 @@
    trim: true
  })
}
export function exportExcel (data) {
  return request.post('/business/memberCoupon/exportExcel', data, {
    trim: true,
    download: true
  })
}
// åˆ›å»º
export function create (data) {
  return request.post('/business/memberCoupon/create', data)
}
admin/src/components/business/OperaMemberCouponWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,353 @@
<template>
  <GlobalWindow
      :title="title"
      width="80%"
      :visible.sync="visible"
      :confirm-working="isWorking"
      @confirm="confirm"
  >
    <el-form :model="form" ref="form" :rules="rules" label-width="120px" label-suffix=":" inline>
      <p class="tip-header" >基本属性</p>
      <el-form-item label="优惠券名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入优惠券名称" :maxlength="12" v-trim/>
      </el-form-item>
      <el-form-item label="类型" prop="couponType">
          <el-radio-group v-model="form.couponType">
            <el-radio :label="0" >满减券</el-radio>
            <el-radio :label="1">折扣券</el-radio>
          </el-radio-group>
      </el-form-item>
      <el-form-item label="优惠规则" prop="couponRule" >
        <div class="coupon-rule">
          <div class="discrep">订单满</div>
          <el-input v-model="form.limitPrice"   placeholder="请输入"     @input="inputAction(form, 'limitPrice')"
          >
            <template slot="append">元</template>
          </el-input>
          <div class="discrep" >{{form.couponType === 1?',享':',减'}}</div>
          <el-input  v-model="form.price"     placeholder="请输入"    @input="inputAction(form, 'price')"  >
            <template slot="append" >{{form.couponType ===1?'折':'元'}}</template>
          </el-input>
        </div>
      </el-form-item>
      <el-form-item label="优惠券说明" prop="info">
        <el-input type="textarea" v-model="form.info" placeholder="请输入优惠券说明"  v-trim/>
      </el-form-item>
      <p class="tip-header" >使用限制</p>
      <el-form-item label="有效期" prop="useType">
        <el-radio-group v-model="form.useType">
          <el-radio :label="0">固定时段</el-radio>
          <el-radio :label="1">固定时长</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="使用时段" prop="getDate" v-if="form.useType===0">
        <div class="date-style">
          <el-date-picker
              v-model="getDate"
              type="datetimerange"
              value-format="yyyy-MM-dd HH:mm:ss"
              format="yyyy-MM-dd HH:mm:ss"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              @change="selectDate"
          ></el-date-picker>
        </div>
      </el-form-item>
      <el-form-item label="固定时长" prop="validDays" v-if="form.useType===1">
        <div class="coupon-rule">
          <div class="discrep">领劵后</div>
          <el-input
              v-model="form.validDays"
              placeholder="请输入"
              @input="inputAction(form, 'validDays')"
          >
            <template slot="append">天</template>
          </el-input>
          <div class="discrep">有效</div>
        </div>
      </el-form-item>
      <el-form-item label="适用对象" prop="applyType">
        <el-radio-group v-model="form.applyType">
          <el-radio :label="0">全场通用</el-radio>
          <el-radio :label="1">按品类</el-radio>
          <el-radio :label="2">指定商品</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item v-if="form.applyType===1" label="选择品类" prop="applyCateIdList" >
        <el-select v-model="form.applyCateIdList"  placeholder="请选择,支持多选" filterable multiple clearable >
          <el-option  v-for="item in categorys" :key="'optCate'+item.id"  :label="item.name"  :value="item.id">  </el-option>
        </el-select>
      </el-form-item>
      <el-form-item v-if="form.applyType===2" label="选择商品" prop="applyIdList" style="display: flex">
          <span style="font-size: 12px;color: #216EEE"   @click="selectGoods">已指定【 {{applyDataList.length}} ã€‘件商品</span>
        <el-button style="margin-left:30px;display: inline-block;width: 80px;" type="primary"  @click="selectGoods">去选择 </el-button>
      </el-form-item>
      <p class="tip-header" >发放规则</p>
      <el-form-item label="发放总量" prop="num">
        <div class="num-style">
          <el-input-number  v-model="form.num" :controls="false" :min="1" :max="99999" placeholder="请输入发放总量(1~99999)" v-trim></el-input-number>
        </div>
      </el-form-item>
    </el-form>
    <OperaCouponGoodsWindow ref="OperaCouponGoodsWindow" @success="doSelect"/>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import { fetchList as shopList } from '@/api/business/shop'
import GlobalWindow from '@/components/common/GlobalWindow'
import { findAll as labelList } from '@/api/business/labels'
import { allList as goodsList} from '@/api/business/goods'
import OperaCouponGoodsWindow from '@/components/business/OperaCouponGoodsWindow'
export default {
  name: 'OperaCouponWindow',
  extends: BaseOpera,
  components: { GlobalWindow,OperaCouponGoodsWindow },
  data () {
    const couponRules = (rule, value, callback) => {
      if (!this.form.limitPrice) {
        callback(new Error('请输入满额'))
      } else if (!this.form.price) {
        callback(new Error('请完善优惠规则'))
      } else {
        callback()
      }
    }
    const getDateRules = (rule, value, callback) => {
      if (!this.form.startDate) {
        callback(new Error('请选择开始时间'))
      } else if (!this.form.endDate) {
        callback(new Error('请输入结束时间'))
      } else {
        callback()
      }
    }
    const numRule = (rule, value, callBack) => {
      if (value < 0) {
        callBack(new Error())
      } else {
        callBack()
      }
    }
    return {
      searchLoading: false,
      getDate: [],
      applyDataList:[],
      showGoods:false,
      // è¡¨å•数据
      form: {
        id: null,
        name: '',
        couponType: 0,
        applyType: 0,
        useType: 0,
        shopId: '',
        applyIdList: [],
        applyCateIdList: [],
        type: 0,
        limitPrice: '',
        price: '',
        startDate: '',
        endDate: '',
        applyIds: '',
        validDays: '',
        getMethod: '',
        integral: '',
        status: '',
        num: '',
        info: ''
      },
      shops: [],
      categorys: [],
      // éªŒè¯è§„则
      rules: {
        name: [
          { required: true, message: '请输入优惠券名称', tigger: 'blur' }
        ],
        couponRule: [
          { required: true, validator: couponRules, tigger: 'blur' }
        ],
        useType: [
          { required: true, message: '请选择有效期方式' }
        ],
        couponType: [
          { required: true, message: '请选择类型' }
        ],
        applyType: [
          { required: true, message: '请选择适用对象类型' }
        ],
        num: [
          { required: true, validator: numRule, message: '请输入发放总数', tigger: 'blur' }
        ],
        /*integral: [
          { required: true, validator: numRule, message: '请输入兑换条件', tigger: 'blur' }
        ],*/
        // validDays: [
        //   { required: true, message: '请输入可用时间', tigger: 'blur' }
        // ],
        // getDate: [
        //   { required: true, validator: getDateRules, tigger: 'change' }
        // ],
        // shopId: [
        //   { required: true, validator: numRule, message: '请选择关联店铺', tigger: 'change' }
        // ]
      }
    }
  },
  created () {
    this.config({
      api: '/business/coupon',
      'field.id': 'id'
    })
  },
  methods: {
    selectGoods(){
      this.$refs.OperaCouponGoodsWindow.open('选择商品', this.applyDataList)
    },
    loadLabels(){
      labelList({
        type: 0 // å•†å“åˆ†ç±»
      }).then(res => {
        this.categorys = res || []
      })
    },
    loadSelectGoods(){
      console.log(this.form.applyIdList)
      if(!this.form.applyIdList || !this.form.applyIdList.length){
        return
      }
      goodsList({
        idList: this.form.applyIdList // å•†å“åˆ†ç±»
      }).then(res => {
        this.applyDataList = res || []
      })
    },
    doSelect(rows){
      console.log(rows,this.applyDataList)
      this.applyDataList =[]
      this.form.applyIdList=[]
      if(rows && rows.length){
        rows.forEach(item => {
          this.applyDataList.push(item)
          this.form.applyIdList.push(item.id)
        })
      }
    },
    open (title, target, type) {
      this.showGoods=false
      this.title = title
      this.visible = true
      this.form.type = type
      this.getDate = []
      this.form.startDate = ''
      this.form.endDate = ''
      this.applyDataList=[]
      this.form.applyIdList=[]
      this.form.applyCateIdList=[]
      this.loadLabels()
      this.form.limitPrice=null
      this.form.price=null
      this.form.startDate=null
      this.form.endDate=null
      this.form.num=1
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          console.log(this.form)
          this.form[this.configData['field.id']] = null
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
        this.getDate = [target.startDate, target.endDate]
        if(this.form.applyType === 1){
          this.form.applyCateIdList =[]
          var ta = this.form.applyIds.split(',')
          if(ta && ta.length){
            ta.forEach(tt =>{
              this.form.applyCateIdList.push(parseInt(tt))
            })
          }
        }
        if(this.form.applyType === 2){
          this.form.applyIdList = this.form.applyIds.split(',')
          this.loadSelectGoods()
        }
      })
    },
    selectDate (value) {
      this.form.startDate = value[0]
      this.form.endDate = value[1]
    },
    inputAction (item, key) {
      if (item[key] < 0) {
        item[key] = ''
      } else {
        item[key] = item[key].replace(/[^\d.]/g, '')
          .replace(/\.{2,}/g, '.')
          .replace('.', '$#$')
          .replace(/\./g, '')
          .replace('$#$', '.')
          .replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
          .replace(/^\./g, '')
      }
    },
    remoteMethod (query) {
      if (query !== '') {
        this.searchLoading = true
        const action = this.form.type == 2 ? activityList : shopList
        action({
          capacity: 999,
          model: {
            name: query
          }
        })
          .then(res => {
            this.shops = res.records
          })
          .finally(() => {
            this.searchLoading = false
          })
      }
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/alertstyle.scss';
.coupon-rule {
  display: flex;
  .discrep {
    padding: 0 10px;
  }
  ::v-deep .el-input {
    width: 160px;
  }
}
.num-style {
  ::v-deep .el-input-number {
    width: 60%;
  }
}
.date-style {
  ::v-deep input {
    text-align: center !important;
  }
}
::v-deep .el-select {
  width: 100%;
  .el-input__inner {
    width: 100%;
  }
}
</style>
admin/src/views/business/memberCoupon.vue
@@ -38,6 +38,10 @@
    </el-form>
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:membercoupon:create', 'business:membercoupon:exportExcel']">
        <li><el-button type="primary"  @click="$refs.OperaMemberCouponWindow.open('新建', null)" v-permissions="['business:membercoupon:create']">定向发放</el-button></li>
        <li> <el-button type="primary" :loading="isWorking.export" v-permissions="['business:membercoupon:exportExcel']" @click="exportExcel">导出</el-button></li>
      </ul>
      <el-table
        v-loading="isWorking.search"
        :data="tableData.list"
@@ -83,17 +87,20 @@
      >
      </pagination>
    </template>
    <OperaMemberCouponWindow ref="OperaMemberCouponWindow" @success="handlePageChange"/>
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import OperaMemberCouponWindow from '@/components/business/OperaMemberCouponWindow'
import Pagination from '@/components/common/Pagination'
export default {
  name: 'MemberCoupon',
  extends: BaseTable,
  components: { TableLayout, Pagination },
  components: { TableLayout, Pagination ,OperaMemberCouponWindow},
  data () {
    return {
      // æœç´¢
server/dmmall_admin/src/main/java/com/doumee/api/business/MemberCouponController.java
@@ -78,7 +78,7 @@
    @PostMapping("/exportExcel")
    @RequiresPermissions("business:membercoupon:exportExcel")
    public void exportExcel (@RequestBody PageWrap<MemberCoupon> pageWrap, HttpServletResponse response) {
        ExcelExporter.build(MemberCoupon.class).export(memberCouponService.findPage(pageWrap).getRecords(), "用户优惠券关联表", response);
        ExcelExporter.build(MemberCoupon.class).export(memberCouponService.findPage(pageWrap).getRecords(), "优惠券明细", response);
    }
    @ApiOperation("根据ID查询")
server/dmmall_service/src/main/java/com/doumee/dao/business/model/MemberCoupon.java
@@ -23,99 +23,82 @@
public class MemberCoupon {
    @ApiModelProperty(value = "主键", example = "1")
    @ExcelColumn(name="主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
    private Integer creator;
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @ExcelColumn(name="发放时间" ,dateFormat = "yyyy-MM-dd HH:mm:ss",width = 10,index = 11)
    private Date createDate;
    @ApiModelProperty(value = "更新人编码", example = "1")
    @ExcelColumn(name="更新人编码")
    private Integer editor;
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    private Date editDate;
    @ApiModelProperty(value = "是否删除0否 1是", example = "1")
    @ExcelColumn(name="是否删除0否 1是")
    private Integer isdeleted;
    @ApiModelProperty(value = "备注")
    @ExcelColumn(name="备注")
    private String remark;
    @ApiModelProperty(value = "用户编码(关联member表)", example = "1")
    @ExcelColumn(name="用户编码(关联member表)")
    private Integer memberId;
    @ApiModelProperty(value = "商家编码(关联shop表)", example = "1")
    @ExcelColumn(name="商家编码(关联shop表)")
    private Integer shopId;
    @ApiModelProperty(value = "类型0商家优惠券 1平台优惠券 ", example = "1")
    @ExcelColumn(name="类型0商家优惠券 1平台优惠券 ")
    private Integer type;
    @ApiModelProperty(value = "满额(元)", example = "1")
    @ExcelColumn(name="满额(元)")
    private BigDecimal limitPrice;
    @ApiModelProperty(value = "优惠金额(元)", example = "1")
    @ExcelColumn(name="优惠金额(元)")
    @ExcelColumn(name="优惠金额(元)",width = 10,index = 7)
    private BigDecimal price;
    @ApiModelProperty(value = "开始时间")
    @ExcelColumn(name="开始时间")
    @ExcelColumn(name="开始时间",width = 10,index = 5,dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date startDate;
    @ApiModelProperty(value = "结束时间")
    @ExcelColumn(name="结束时间")
    @ExcelColumn(name="结束时间",width = 10 ,index = 6,dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date endDate;
    @ApiModelProperty(value = "领取方式 0领取 1兑换", example = "1")
    @ExcelColumn(name="领取方式 0领取 1兑换")
    @ExcelColumn(name="领取方式",width = 10,index = 4,valueMapping = "0=首次注册;1=邀请好友;2=定向发放;")
    private Integer getMethod;
    @ApiModelProperty(value = "兑换所需咖豆金额", example = "1")
    @ExcelColumn(name="兑换所需咖豆金额")
    private BigDecimal integral;
    @ApiModelProperty(value = "状态 0未使用 1已使用", example = "1")
    @ExcelColumn(name="状态 0未使用 1已使用")
    @ExcelColumn(name="状态",width = 10,index = 8,valueMapping = "0=未使用;1=已使用;2=已过期;")
    private Integer status;
    @ApiModelProperty(value = "说明")
    @ExcelColumn(name="说明")
    private String info;
    @ApiModelProperty(value = "使用时间")
    @ExcelColumn(name="使用时间")
    @ExcelColumn(name="使用时间",width = 10,index = 9,dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date useDate;
    @ApiModelProperty(value = "使用积分奖励数量", example = "1")
    @ExcelColumn(name="使用积分奖励数量")
    private BigDecimal backIntegral;
    @ApiModelProperty(value = "优惠券名称")
    @ExcelColumn(name="优惠券名称")
    @ExcelColumn(name="优惠券名称",width = 10,index = 2 )
    private String name;
    @ApiModelProperty(value = "coupon表id")
    @ExcelColumn(name="coupon表id")
    private Integer couponId;
    @ApiModelProperty(value = "优惠券类型:0=满减券;1=折扣券;")
    @ExcelColumn(name="优惠券类型",width = 10,index = 3,valueMapping = "0=满减券;1=折扣券;")
    private Integer couponType;
    @ApiModelProperty(value = "适用类型:0=全场;1=品类;2=指定商品")
@@ -129,14 +112,17 @@
    @ApiModelProperty(value = "昵称")
    @TableField(exist = false)
    @ExcelColumn(name="用户",width = 10,index = 1)
    private String nikeName;
    @ApiModelProperty(value = "关联订单号号")
    @ExcelColumn(name="关联订单号",width = 10,index = 10)
    @TableField(exist = false)
    private String orderCode;
    @ApiModelProperty(value = "创建人")
    @TableField(exist = false)
    @ExcelColumn(name="操作人",index = 12,width = 10)
    private String creatorName;
    @ApiModelProperty(value = "关联订单号")
    @ApiModelProperty(value = "关联订单")
    private String orderId;
    @ApiModelProperty(value = "实际适用时金额")
server/dmmall_service/src/main/java/com/doumee/dao/system/model/SystemUser.java
@@ -60,7 +60,7 @@
    private String mobile;
    @ApiModelProperty(value = "头像")
    @NotBlank(message = "头像不能为空", groups = {OperaType.Create.class, OperaType.Update.class})
//    @NotBlank(message = "头像不能为空", groups = {OperaType.Create.class, OperaType.Update.class})
    private String avatar;
    @ApiModelProperty(value = "密码")