<!-- @desc:数字组件  @auth:周兴  @time:2022/11/15 9:56 -->
<template>
  <Poptip popper-class="popper-class" trigger="focus" placement="top-start" :disabled="true" ref="pop">
    <div class="close-div-class" :class="clearableFlag?'clear-class':''">
      <Input size="small" ref="inputNumber" @on-blur="handleBlur" @on-focus="handleFocus"
             @on-click="handleClick"
             @on-clear="handleClear"
             @on-enter="handleEnter" @on-change="handleChange" @on-keyup="handleKeyup"
             @on-keydown="handleKeydown"
             @mouseenter.native="handleMouseEnter"
             @mouseleave.native="handleMouseLeave"
             @input.native="handleInput"
             @contextmenu.native.prevent
             @dblclick.native="copyValue()"
             :disabled="disabled"
             :name="name" :readonly="readonly" :value="value2" :placeholder="placeholder"
             :class="(readonly ? 'readonly-input' : '') +' ' + (textRight?'text-right':'') + ' ' + (upDownFlag?'focus-class':'')"
             :clearable="false"
             type="text"
             :digits="digits"
             :max="maxData" :min="min" number
             :maxlength="maxlength">
        <div slot="append">
          <!--当有单位时，上下按钮出现时，单位隐藏-->
          <div v-if="flgUpDown && upDownFlag">
            <div style="display: grid ;cursor:pointer;">
              <Icon type="ios-arrow-up" @click="handleClickOpBtn('up')" :class="!upFlag?'disable-icon-class':''"/>
              <Icon type="ios-arrow-down" @click="handleClickOpBtn('down')" :class="!downFlag?'disable-icon-class':''"/>
            </div>
          </div>
          <div v-else v-show="unit"> {{ unit }}</div>
        </div>

      </Input>

      <div v-if="clearableFlag">
        <div v-if="value2 && isFocus && !disabled && !readonly && clearable" style="cursor: pointer">
          <Icon slot="prefix" type="iconfont iconfont icon-clear" @click.stop="clearAll"/>
        </div>
        <div v-else style="width: 16px;height: 16px">
        </div>
      </div>
    </div>
    <div slot="content" class="pop-content">
      <div class="pop-item-content">{{ vm.$t('numberValue') + '：' + (this.value2 ? this.value2 : '') }}</div>
      <div class="pop-item-content">
        {{
          vm.$t('maxValue') + '：' + this.$libaray.getMaxValue(maxData, this.digits)
        }}
      </div>
      <div class="pop-item-content">{{ vm.$t('digits') + '：' + this.digits }}</div>
    </div>
  </Poptip>

</template>

<script>
import XEUtils from "xe-utils";

export default {
  name: 'InputNumberPop',
  inject: {
    prop: {
      type: String,
      default: null
    },
    dkFormItem: {
      type: Object,
      default: null
    }
  },
  props: {
    //input值
    value: {
      type: [String, Number],
      default: null
    },
    //字段名
    prop: {
      type: String,
      default: ''
    },
    //名称
    name: {
      type: String,
      default: null
    },
    //单位
    unit: {
      type: String,
      default: null
    },
    //最大长度
    maxlength: {
      type: String,
      default: '100'
    },
    //是否只读
    readonly: {
      type: Boolean,
      default: false
    },
    // 最大值
    max: {
      type: Number,
      default: null
    },
    //最小值
    min: {
      type: Number,
      default: null
    },
    //小数位数
    digits: {
      type: Number,
      default: 0
    },
    //是否显示千分位
    formatThousandth: {
      type: Boolean,
      default: true
    },
    //是否包括负数
    negative: {
      type: Boolean,
      default: false
    },
    //禁用
    disabled: {
      type: Boolean,
      default: false
    },
    //文本居右显示
    textRight: {
      type: Boolean,
      default: true
    },
    //提示信息
    placeholder: {
      type: String,
      default: null
    },
    // 是否清除
    clearable: {
      type: Boolean,
      default: true
    },
    // 是否显示清除条
    clearableFlag: {
      type: Boolean,
      default: true
    },
    // 是否显示上下按钮
    flgUpDown: {
      type: Boolean,
      default: false
    }
  },
  data() {
    const vm = window.vm;
    return {
      vm: vm,
      flag1: true,
      value2: null,          //记录显示值
      valueNumber: null,    //记录数值
      valueStr: '',         //用于控制输入
      label: '',
      popVisibleData: true,
      inputing: false,
      clearFlag: false,
      maxData: null,
      isFocus: false,
      upFlag: true,
      downFlag: true,
      clickUpDownFlag: false,// 是否点击增加减少按钮
      upDownFlag: false  // 光标进入输入框才会出现
    }
  },
  watch: {
    value(n, o) {
      if ((!n || n == 0) && this.prop && this.prop === 'displayNo' && !this.clearFlag) {
        n = 1;
        let e = {target: {value: 1}}
        this.handleChange(e);
      }
      this.value2 = n ? n : null;
      //只有直接进入才会处理
      if (!this.inputing) {
        if (this.formatThousandth == undefined || this.formatThousandth) {
          let digits = this.digits;
          this.value2 = XEUtils.commafy(Number(this.value2), {digits});
          if (!isNaN(Number(n))) {
            this.valueNumber = Number(n);
          }
        } else {
          if (!isNaN(Number(n))) {
            this.valueNumber = Number(n);
          }
        }
      } else {
        this.inputing = false;
      }
      if (this.clearFlag) {
        this.clearFlag = false;
      }
    },
    value2(n, o) {
      if (n) {
        // 清除提示信息
        this.clearErrMessage();
      }
    },
    readonly(n, o) {
      // 给提示信息赋值
      this.setReadOnly(n)
    },
    unit(n, o) {
      this.$refs.inputNumber.slotReady = !!n
    },
    max(n, o) {
      this.maxData = n
    }
  },
  methods: {
    /**
     * @desc   : 复制单元格
     * @author : 周兴
     * @date   : 2022/6/9 9:31
     */
    copyValue() {
      // 点击增加减少按钮不允许复制
      if (this.clickUpDownFlag) {
        return;
      }
      if (this.value2) {
        this.$message.success(vm.$t('copySuccess') + '：' + this.valueNumber);
        //创建一个input框
        const input = document.createElement("input");
        input.setAttribute("style", "z-index:-1000;position: absolute;bottom:0;")
        //将指定的DOM节点添加到body的末尾
        document.body.appendChild(input);
        //设置input框的value值为直播地址
        input.setAttribute("value", this.valueNumber);
        //选取文本域中的内容
        input.select();
        //copy的意思是拷贝当前选中内容到剪贴板
        //document.execCommand（）方法操纵可编辑内容区域的元素
        //返回值为一个Boolean，如果是 false 则表示操作不被支持或未被启用
        if (document.execCommand("copy")) {
          document.execCommand("copy");
        }
      }
    },
    /**
     * @desc   : 执行增加和减少按钮操作
     * @author : 周兴
     * @date   : 2024/1/5 11:06
     */
    handleClickOpBtn(type) {
      this.clickUpDownFlag = true;
      let valueNumber = this.valueNumber;
      let isChange = false;
      if (type === 'up') {
        if (this.upFlag) {
          this.valueNumber = valueNumber + 1;
          // 控制按钮状态
          this.handleOpBtnStatus();
          isChange = true;
        }
      } else {
        if (this.downFlag) {
          this.valueNumber = valueNumber - 1;
          // 控制按钮状态
          this.handleOpBtnStatus();
          isChange = true;
        }
      }
      if (isChange) {
        this.$emit('input', this.valueNumber);
      }
    },
    /**
     * @desc   : 控制增加减少按钮是否可用
     * @author : 周兴
     * @date   : 2024/1/5 11:16
     */
    handleOpBtnStatus() {
      if (this.max) {
        // 如果大于最大值就不允许
        if (this.valueNumber >= this.max) {
          this.upFlag = false;
        } else {
          this.upFlag = true;
        }
      }
      if (this.min) {
        // 如果小宇最大值就不允许
        if (this.valueNumber <= this.min) {
          this.downFlag = false;
        } else {
          this.downFlag = true;
        }
      }
    },
    /**
     * @desc   : 清空
     * @author : 周兴
     * @date   : 2023/1/13 10:35
     */
    clearAll() {
      this.handleClear();
    },
    /**
     * @desc   : 处理值的显示
     * @author : 周兴
     * @date   : 2022/4/13 19:49
     */
    handleInput(e) {
      this.$emit('input', this.valueNumber);
    },
    /**
     * @desc   : 焦点进入后进行处理
     * @author : 周兴
     * @date   : 2022/4/13 19:50
     */
    handleFocus(e) {
      if (this.readonly) {
        return;
      }
      if (this.valueNumber === 0) {
        this.value2 = null;
      } else {
        this.value2 = this.valueNumber;
        this.valueStr = this.valueNumber ? this.valueNumber.toString() : '';
      }
      this.isFocus = true;
      e.target.selectionStart = 0;
      e.target.selectionEnd = this.valueStr.length;
      this.$emit('on-focus', e)
    },
    /**
     * @desc   : 清空
     * @author : 周兴
     * @date   : 2022/4/13 14:51
     */
    handleClear(e) {
      this.value2 = null;
      this.valueStr = '';
      this.valueNumber = null;
      this.$refs.inputNumber.$refs.input.focus();
      this.clearFlag = true;
      this.$emit('input', 0)
    },
    handleEnter(e) {
      this.$emit('on-enter', e);
    },
    handleClick(e) {
      this.$emit('on-click', e);
    },
    /**
     * @desc   : 改变事件
     * @author : 周兴
     * @date   : 2022/4/12 15:08
     */
    handleChange(e) {
      //如果是非数字 那么就要清空
      if (!e.target.value || (Number.isNaN(Number(e.target.value)) && e.target.value != '-')) {
        console.log('eee',)
        this.value2 = null;
        this.valueNumber = null;
        e.target.value = null;
      } else {
        this.value2 = e.target.value;
        this.valueNumber = Number(e.target.value);
      }
      if (this.value2 == null) {
        this.clearFlag = true;
      }
      // if(this.value2){
      //   this.isFocus = true;
      // }
      this.inputing = true;
      this.$emit('input', this.valueNumber);
      this.$emit('on-change', this.valueNumber);
    },
    /**
     * @desc   : 光标离开事件
     * @author : 周兴
     * @date   : 2022/4/11 15:09
     */
    handleBlur(e) {
      if (this.readonly) {
        return;
      }
      //如果是非数字 那么就要清空
      if (Number.isNaN(Number(e.target.value))) {
        this.value2 = null;
        this.valueNumber = null;
        e.target.value = null;
      }
      setTimeout(() => {
        this.isFocus = false;
      }, 200)
      //如果需要显示千分位
      if (this.formatThousandth == undefined || this.formatThousandth) {
        let digits = this.digits;
        this.value2 = XEUtils.commafy(Number(this.value2), {digits});
        //重新按照小数点进行控制，避免输入不合法的数据
        if (this.valueNumber) {
          this.valueNumber = Number(this.valueNumber.toFixed(digits))
        }
      }
      // 取最大值最小值，或者负值判断
      this.setMaxValue();
      this.$emit('on-blur', this.valueStr);
    },
    /**
     * @desc   : 键盘事件
     * @author : 周兴
     * @date   : 2022/4/12 15:09
     */
    handleKeyup(e) {
      this.$emit('on-keyup', e);
      if (this.readonly) {
        return;
      }
      //复制时调用改变事件
      if (e.key === 'v' && e.ctrlKey) {
        this.changeValueByCtrlV();
        return;
      }
      if (this.value2 === null) {
        this.valueStr = '';
      }
      // 如果没有小数点
      if (e.key != ".") {
        this.valueStr = e.target.value;
      } else {
        //值中已经有小数点了
        if (e.target.value.indexOf('.') >= 0) {
          this.valueStr = e.target.value;
        } else {
          this.valueStr = e.target.value + e.key;
        }
        this.value2 = this.valueStr;
      }
      if (this.value2 == 0 && e.key === '-') {
        this.value2 = null;
      }
      if (Number.isNaN(Number(this.value2)) && e.key != '-') {
        this.value2 = null;
        this.valueStr = '';
      } else {
        //判断是否超过最大值，如果超过最大值，就取最大值
        // this.setMaxValue();
      }
    },
    /**
     * @desc   : 值改变
     * @author : 周兴
     * @date   : 2022/4/10 14:21
     */
    changeValueByCtrlV() {
      this.valueStr = this.value2 === null ? '' : this.value2.toString();
      if (this.valueStr) {
        if (Number.isNaN(Number(this.valueStr))) {
          this.valueStr = ''
          this.value2 = null;
        } else {
          if (this.negative || this.min >= 0) {
            this.value2 = Math.abs(this.value2);
            this.valueStr = this.value2 + ''
          } else {
            //正则表达式去控制输入
            if (!this.$libaray.getRegex(this.digits).test(this.valueStr)) {
              this.valueStr = XEUtils.toFixed(XEUtils.round(this.valueStr, this.digits), this.digits);
              this.value2 = parseFloat(this.valueStr);
            }
            //判断是否超过最大值，如果超过最大值，就取最大值
            // this.setMaxValue();
            this.$emit('input', this.valueNumber);
          }
        }
      }
    },
    /**
     * @desc   : 设置最大值
     * @author : 周兴
     * @date   : 2022/5/20 16:46
     */
    setMaxValue() {
      // 如果小于最小值，就取最小值
      let min = this.min?this.min:this.$config.minNumber
      if (min || min === 0) {
        if (this.valueNumber < min) {
          this.value2 = XEUtils.commafy(min, {digits: this.digits});;
          this.valueStr = min.toString();
          this.valueNumber = min;
        }
      }
      // 如果大于最大值，就取最大值
      let max = this.maxData?this.maxData:this.$config.maxNumber
      if (max || max === 0) {
        if (this.valueNumber > max) {
          this.value2 = XEUtils.commafy(max, {digits: this.digits});
          this.valueStr = max.toString();
          this.valueNumber = max;
        }
      }
      if (this.negative) {
        let val = -1 * Math.abs(this.valueNumber)
        // 负数直接取负
        this.value2 = XEUtils.commafy(val, {digits: this.digits});
        this.valueStr = val.toString();
        this.valueNumber = val;
      }
    },
    /**
     * @desc   : 光标进入
     * @author : 周兴
     * @date   : 2024/1/5 11:40
     */
    handleMouseEnter(e) {
      if (this.flgUpDown) {
        this.$refs.inputNumber.slotReady = true
        this.upDownFlag = true;
      }
    },
    /**
     * @desc   : 光标移出
     * @author : 周兴
     * @date   : 2024/1/5 11:41
     */
    handleMouseLeave() {
      if (this.flgUpDown) {
        this.upDownFlag = false;
        if (!this.unit) {
          this.$refs.inputNumber.slotReady = false;
        }
      }
    },
    /**
     * @desc   : 键盘事件
     * @author : 周兴
     * @date   : 2022/4/12 10:26
     */
    handleKeydown(e) {
      this.$emit('on-keydown', e);
      //backspace,delete,enter,tab，左右不控制
      if (e.keyCode === 8 || e.keyCode === 9 || e.keyCode === 46 || e.keyCode === 37
        || e.keyCode === 39 || e.keyCode === 13) {
        return;
      }
      //ctrl+v,ctrl+c不控制
      if ((e.key === 'v' || e.key === 'c') && e.ctrlKey) {
        return;
      }
      //不允许其他非数字按键输入
      if ((e.keyCode < 48 || e.keyCode > 57)
        && (e.keyCode < 96 || e.keyCode > 105)
        && e.keyCode != 110 && e.keyCode != 190 && e.keyCode != 189 && e.keyCode != 109) {
        e.preventDefault();
      }
      let num = this.valueStr + "" + e.key;
      //查看是否有选中数据，再输入的情况(除小数点外)
      let selectedLength = e.target.selectionEnd - e.target.selectionStart;
      if (selectedLength > 0) {
        if ('-' != e.key) {
          return;
        } else {
          // 如果全选中修改为-号
          if (selectedLength == this.valueStr.length) {
            this.valueStr = '-'
            this.value2 = '-'
            num = '-'
          }
        }
      }
      // 如果内容已经包括负号，输入的负号就不允许
      if (this.valueStr && this.valueStr.indexOf('-') >= 0 && e.key === '-') {
        e.preventDefault();
      }

      //说明是插入到字符串中的
      if (e.target.selectionEnd < e.target.value.length) {
        num = this.$libaray.insertStr(e.target.value, e.target.selectionEnd, e.key)
      }
      //判断是否包括负数
      // console.log('bb1',this.valueStr, num, this.$libaray.getRegex(this.digits,this.negative),this.$libaray.getRegex(this.digits,this.negative).test(num))
      //正则表达式去控制输入
      // if (!this.$libaray.getRegex(this.digits, this.negative).test(num)) {
      //   e.preventDefault();
      // } else {
      //如果有最大值，需要判断不要超过最大值,在blur中处理
      // let max = this.maxData?this.maxData:this.$config.maxNumber;
      // if (num >= max) {
      //   e.preventDefault();
      // }
      // let min = this.min?this.min:this.$config.minNumber;
      // if (num <= min) {
      //   e.preventDefault();
      // }
      // }
    },
    /**
     * @desc   : 聚焦
     * @author : 周兴
     * @date   : 2022/11/30 14:37
     */
    focus() {
      this.$refs.inputNumber.$refs.input.focus();
    },
    /**
     * @desc   : 控件只读时的处理
     * @author : 周兴
     * @date   : 2022/3/4 11:12
     */
    setReadOnly(value) {
      // 给提示信息赋值
      if (value) {
        this.placeholderData = this.placeholder;
        // 给输入框赋值灰色背景
      } else {
        this.placeholderData = this.placeholder == null ? (vm.$t('inputWords', {'search-name': this.label})) : this.placeholder
      }
    },
  },
  mounted() {
    if (this.dkFormItem) {
      this.dkFormItem.setItems(this);   // 把当前组件赋值给formItem
    }
    this.$refs.inputNumber.slotReady = this.$refs.inputNumber.append && this.unit
    // 给顺序赋默认值
    if (this.prop && this.prop === 'displayNo' && (!this.value2 || this.value2 == 0)) {
      this.value2 = 1;
      this.valueNumber = 1;
      let e = {target: {value: 1}}
      this.$nextTick(() => {
        this.handleChange(e);
      })
    }
    // 设置最大值
    let max = this.max;
    if (!max) {
      if (this.prop === 'displayNo') {
        max = this.$config.maxDisplayNo
      } else {
        max = this.$config.maxNumber
      }
    }
    this.maxData = max;
  },
  created() {
    this.value2 = this.value
    //如果需要显示千分位
    if (this.formatThousandth == undefined || this.formatThousandth) {
      if (this.value && this.value != 0) {
        let digits = this.digits;
        this.value2 = XEUtils.commafy(Number(this.value2), {digits})
      }
    }
    if (!isNaN(Number(this.value))) {
      this.valueNumber = Number(this.value);
    }
    //获取名称
    let name = null;
    if (!this.dkFormItem || !this.dkFormItem.label) {
      if (this.name) {
        // 给label赋值
        name = this.name
      } else {
        name = this.prop
      }
      // 获取国际化名称
      this.label = vm.$t(name)
    } else {
      this.label = this.dkFormItem.label
    }
    // 给提示信息赋值
    this.setReadOnly(this.readonly)
  }
}
</script>
<style scoped>
/deep/ .ivu-input-group-prepend {
  background-color: #fff;
  border: none;
}

/*文字居右*/
/deep/ .text-right > .ivu-input {
  text-align: right;
  /*padding-right: 20px;*/
}


/*只读颜色*/
.readonly-input > /deep/ .ivu-input {
  background-color: #f3f3f3;
}


.ivu-poptip {
  width: 100%;
}

/deep/ .ivu-poptip-rel {
  width: 100%;
}

.pop-content {
  width: 255px;
  min-width: 200px;
  /*background: #e9edf1;*/
  padding: 10px;
  border: 1px #a5acb5;
}

.pop-item-content {
  padding: 5px 5px 5px 5px;

}

/deep/ .ivu-input-group-append {
  font-weight: 400;
  line-height: 1;
  color: #515a6e;
  text-align: center;
  background-color: #f8f8f9;
  border: 1px solid #dcdee2;
  border-left: none !important;
}

/deep/ .clear-class .ivu-input-wrapper {
  width: calc(100% - 16px) !important;
}

.disable-icon-class {
  color: #a0a5ac;
  cursor: no-drop;
}

/deep/ .focus-class .ivu-input {
  border-color: #57a3f3 !important;
}

</style>

