modal-create-coupon.vue 13.3 KB
<template>
  <i-modal v-model="visiable" :loading="posting" :title="allreadonly ? '查看优惠券' : '创建/编辑优惠券'" @on-ok="onOk" width="600">
    <i-spin v-if="loading"></i-spin>
    <i-form v-else ref="formCoupon" :rules="ruleValidate" :model="formData" :label-width="80">
      <i-form-item class="form-group" label="优惠券类型"></i-form-item>
      <i-form-item label="优惠券类型" prop="couponType">
        <i-select style="width: 100px;" v-model="formData.couponType" :disabled="readonly">
          <i-option :value="0">请选择</i-option>
          <i-option :value="100">活动券</i-option>
          <i-option :value="110">运费券</i-option>
        </i-select>
      </i-form-item>

      <i-form-item class="form-group" label="基本信息"></i-form-item>
      <i-form-item label="Token" v-if="couponToken">
        {{couponToken}}
      </i-form-item>
      <i-form-item label="名称" prop="couponName">
        <i-input placeholder="名称建议30字以内" v-model="formData.couponName" :disabled="allreadonly" style="width: 200px"></i-input>
      </i-form-item>
      <i-form-item label="数量" prop="couponNum">
        <i-input-number placeholder="数量" v-model="formData.couponNum" :disabled="allreadonly" style="width: 100px;"></i-input-number>
      </i-form-item>
      <i-form-item label="使用次数" prop="useNum">
        <i-input placeholder="使用次数" v-model="formData.useNum" disabled style="width: 100px;"></i-input>
      </i-form-item>
      <i-form-item label="使用期限" prop="time">
        <i-date-picker type="datetimerange" v-model="formData.time" :disabled="readonly" placeholder="使用期限" format="yyyy-MM-dd HH:mm:ss" style="width: 250px"></i-date-picker>
      </i-form-item>
      <i-form-item label="优惠券说明" prop="remark">
        <i-input type="textarea" placeholder="优惠券使用条件简介" :disabled="allreadonly" v-model="formData.remark"></i-input>
      </i-form-item>
      <i-form-item class="form-group" label="使用条件"></i-form-item>
      <i-form-item label="优惠条件" prop="useLimitType" style="display: inline-block; width: 100%">
        <i-select style="width: 100px" :disabled="readonly" v-model="formData.useLimitType">
          <i-option :value="0">无限制</i-option>
          <i-option :value="2">金额</i-option>
        </i-select>
        <div style="display: inline-block" v-if="formData.useLimitType === 2">
          &nbsp;
          金额满:
          <i-input-number style="width: 100px" :disabled="readonly" placeholder="限制金额" v-model="formData.useLimitValue">
          </i-input-number>
        </div>
      </i-form-item>
      <i-form-item label="优惠金额" prop="couponAmount">
        <i-input-number placeholder="优惠金额" :disabled="readonly" v-model="formData.couponAmount" style="width: 100px">
        </i-input-number>
      </i-form-item>

      <i-form-item label="适用范围" prop="productLimitType">
        <i-select style="width: 100px;" v-model="formData.productLimitType" :disabled="readonly">
          <i-option :value="1">指定商品</i-option>
          <i-option :value="2">全部商品</i-option>
          <i-option :value="3">排除商品</i-option>
        </i-select>
      </i-form-item>

      <i-form-item prop="productLimitValue" v-if="formData.productLimitType === 1 || formData.productLimitType === 3">
        <i-input type="textarea" :disabled="readonly" placeholder="填写商品编码,多个商品编码用英文逗号分隔" v-model="formData.productLimitValue"></i-input>
        <i-poptip trigger="hover">
          <div slot="content">
            <p>1.上传文件必须是xlsx文件</p>
            <p>2.第一行标题栏:商品编码</p>
            <p>3.<a href="javascript:;" @click="onExample">下载样例</a></p>
          </div>
          <i-upload action="" :format="['xlsx']" :max-size="1024" :before-upload="onBeforeUpload">
            <i-button type="success" size="small" :disabled="readonly">导入</i-button>
            <p>{{uploadTxt}}</p>
          </i-upload>
        </i-poptip>
      </i-form-item>
      <i-form-item label="禁用商品类型">
        <checkbox-group v-model="formData.skupForbidTypeLable" @on-change="getCheckBox">
          <checkbox label="现货" :disabled="readonly"></checkbox>
          <checkbox label="预售" :disabled="readonly"></checkbox>
          <checkbox label="二手" :disabled="readonly"></checkbox>
          <checkbox label="全新瑕疵" :disabled="readonly"></checkbox>
          <checkbox label="闪购" :disabled="readonly"></checkbox>
        </checkbox-group>
      </i-form-item>
    </i-form>
  </i-modal>
</template>

<script>
import Api from 'api/api';
import dayjs from 'dayjs';
import XLSX from 'xlsx';

const api = new Api();
const forbidenTypeMap = {
  '现货': 1,
  '预售': 4,
  '二手': 6,
  '全新瑕疵': 5,
  '闪购': 3
};
const forbidenLabelMap = {
  1: '现货',
  4: '预售',
  6: '二手',
  5: '全新瑕疵',
  3: '闪购'
};

export default {
  components: {},
  name: 'ModalCreateCoupon',
  data() {
    return {
      readonly: false,
      allreadonly: false,
      visiable: false,
      loading: false,
      posting: true,
      uploadTxt: '',
      couponToken: '',
      formData: {
        id: 0,
        couponName: '',
        couponType: 0,
        couponNum: 0,
        useNum: 1,
        couponAmount: 0,
        useLimitType: 0,
        remark: '',
        productLimitType: 2,
        productLimitValue: '',
        useLimitValue: 0,
        time: ['', ''],
        skupForbidTypeLable:[],
        skupForbidType: ''
      },
      ruleValidate: {
        couponType: {required: true, validator: (rule, value, callback) => {
          if (value === 0 || value === '0') {
            callback(new Error('请选择优惠券类型'));
          } else {
            callback();
          }
        }},
        couponName: {required: true, max: 30, message: '请输入名称'},
        couponNum: {type: 'number', required: true, min: 1, message: '请输入数量'},
        couponAmount: {type: 'number', required: true, min: 1, message: '请输入优惠金额'},
        time: {required: true, validator: (rule, value, callback) => {
          if (value.some(v => !v)) {
            callback(new Error('请选择使用期限'));
          } else {
            callback();
          }
        }},
        remark: {required: true, message: '请输入优惠券说明'},
        useLimitType: {required: true, validator: (rule, value, callback) => {
          if (value >= 0) {
            if (value === 2) {
              if (parseInt(this.formData.useLimitValue) > 0) {
                callback();
              } else {
                callback(new Error('请输入限制金额'));
              }
            } else {
              callback();
            }
          } else {
            callback(new Error('请选择优惠条件'));
          }
        }},
        productLimitValue: {required: false, validator: (rule, value, callback) => {
          const ids = (value || '').split(',');

          if (!value || !ids.length) {
            callback(new Error('请输入适用范围'));
          } else if(ids.some(id => id ? !parseInt(id) : false)) {
            callback(new Error('适用范围格式错误'));
          } else {
            callback();
          }
        }},
        productLimitType: {required: true, validator: (rule, value, callback) => {
          if (value === 1 || value === 2 || value === 3) {
            callback();
          } else {
            callback(new Error('请选择类型'));
          }
        }}
      }
    };
  },
  methods: {
    async show(id, readonly, allreadonly) {
      this.readonly = readonly;
      this.allreadonly = allreadonly;
      this.posting = this.visiable = true;
      this.$refs.formCoupon.resetFields();
      this.couponToken = '';
      let initData = {
        id: 0,
        couponName: '',
        couponNum: 0,
        couponType: 0,
        useNum: 1,
        couponAmount: 0,
        useLimitType: 0,
        remark: '',
        productLimitValue: '',
        productLimitType: 2,
        useLimitValue: 0,
        time: ['', ''],
        skupForbidTypeLable:[],
        skupForbidType: ''
      };

      if (id) {
        this.loading = true;
        const result = await api._get('/ufoPlatform/coupon/getCouponInfo', {
          id
        });

        console.log(result);

        this.loading = false;

        if (result.code === 200) {
          const coupon = result.data.coupon;
          const productLimits = result.data.productLimits;

          this.couponToken = coupon.couponToken;
          let skupForbidTypeLable = [];
          if (coupon.skupForbidType) {
            let arr = coupon.skupForbidType.split(',');
            for(let i = 0; i < arr.length; i++) {
              skupForbidTypeLable.push(forbidenLabelMap[parseInt(arr[i])]);
            }
          }
          initData = {
            id,
            couponName: coupon.couponName,
            couponNum: coupon.couponNum,
            couponType: coupon.couponType || 0,
            useNum: coupon.useNum,
            couponAmount: coupon.couponAmount,
            useLimitType: coupon.useLimitType,
            remark: coupon.remark,
            productLimitType: coupon.productLimitType,
            productLimitValue: (productLimits || []).map(i => i.productId).join(','),
            useLimitValue: coupon.useLimitValue,
            time: [dayjs.unix(coupon.startTime).format('YYYY-MM-DD HH:mm:ss'), dayjs.unix(coupon.endTime).format('YYYY-MM-DD HH:mm:ss')],
            skupForbidTypeLable: skupForbidTypeLable,
            skupForbidType: coupon.skupForbidType
          };
        } else {
          result.message && this.$Message.warning(result.message);
        }
      }
      this.formData = initData;
    },
    onOk() {
      this.$refs.formCoupon.validate(valid => {
        if (!valid) {
          this.posting = false;
          this.$nextTick(() => {
            this.posting = true;
          });
        } else {
          this.saveData(this.formData);
        }
      });
    },
    getCheckBox() { // checkbox勾选取消的监测
      let arr = [];
      for (let i = 0; i < this.formData.skupForbidTypeLable.length; i++) {
        let forbidType = this.formData.skupForbidTypeLable[i];
        arr.push(forbidenTypeMap[forbidType]);
      }
      this.formData.skupForbidType = arr.join(',');
    },
    async saveData(params) {
      if (this.allreadonly) {
        this.visiable = false;
        return;
      }

      console.log(params);
      const result = await api._post('/ufoPlatform/coupon/saveOrUpdateCoupon', {
        id: params.id || void 0,
        couponName: params.couponName,
        couponAmount: params.couponAmount,
        couponNum: params.couponNum,
        couponType: params.couponType,
        useNum: params.useNum,
        useLimitValue: params.useLimitValue,
        productLimitType: params.productLimitType,
        productLimitValue: params.productLimitValue,
        remark: params.remark,
        useLimitType: parseInt(params.useLimitType) >= 0 ? params.useLimitType : void 0,
        startTime: params.time[0] ? dayjs(params.time[0]).unix() : void 0,
        endTime: params.time[1] ? dayjs(params.time[1]).unix() : void 0,
        skupForbidType: params.skupForbidType
      });

      console.log('result=', result);

      if (result.code === 200) {
        this.$Message.success('保存成功');
        this.visiable = false;
        this.$emit('on-created');
      } else {
        result.message && this.$Message.warning(result.message);
        this.posting = false;
        this.$nextTick(() => {
          this.posting = true;
        });
      }
    },
    onBeforeUpload(file) {
      const fileExt = file.name.split('.').pop().toLocaleLowerCase();
      if (fileExt !== 'XLSX') {
        this.$Message.warning('文件格式错误');
        return false;
      }
      if (file.size > 1024 * 1024) {
        this.$Message.warning('文件大小超过1M');
        return false;
      }
      const reader = new FileReader();

      reader.readAsArrayBuffer(file);
      reader.onloadstart = () => {
        this.uploadTxt = '开始读取';
      };
      reader.onprogress = e => {
        this.uploadTxt = `进度:${Math.round(e.loaded / e.total * 100)}...`;
      };
      reader.onerror = () => {
        this.uploadTxt = '文件读取出错';
      };
      reader.onload = e => {
        this.uploadTxt = '';
        try {
          const data = e.target.result;
          const workbook = XLSX.read(data, { type: 'array' });
          const firstSheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[firstSheetName];
          const results = XLSX.utils.sheet_to_json(worksheet);

          this.formData.productLimitValue = results.map(r => r['商品编码']).filter(r => r).join(',');

        } catch (error) {
          this.uploadTxt = '文件解析失败,请按照格式上传';
        }


      };
      return false;
    },
    onExample() {
      const wb = XLSX.utils.book_new();
      const ws = XLSX.utils.json_to_sheet([{
        '商品编码': '123456'
      }]);
      XLSX.utils.book_append_sheet(wb, ws, '优惠券适用范围示例');
      XLSX.writeFile(wb, '优惠券适用范围示例.xlsx');
    }
  }
};
</script>

<style lang="scss" scoped>
.form-group {
  width: 100%;
  height: 30px;
  background-color: #f5f7f9;
}

.ivu-form-item-label {
  width: 90px !important;
}

</style>