<!-- @format -->

<template>
  <t-dialog :closeOnOverlayClick="false" header="修改密码" :closeBtn="modalStatus.close" :cancelBtn="modalStatus.cancel" :visible.sync="modalVisible" :width="500" :confirm-loading="confirmLoading" :maskClosable="false" @confirm="handleConfirmOk" @close="handleCancel">
    <t-form ref="formRef" @submit="onSubmit" :data="form" :rules="rules" :label-col="{ flex: '75px' }">
      <!-- 菜单名称 -->
      <t-form-item label="旧密码" name="oldPassword">
        <t-input v-model="form.oldPassword" :maxLength="20" type="password" />
      </t-form-item>
      <!-- 菜单名称 -->
      <t-form-item label="新密码" name="newPassword">
        <t-input v-model="form.newPassword" :maxLength="20" type="password" />
      </t-form-item>
      <!-- 菜单名称 -->
      <t-form-item label="确认密码" name="repeatNewPassword">
        <t-input v-model="form.repeatNewPassword" :maxLength="20" type="password" />
      </t-form-item>
    </t-form>
  </t-dialog>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { MessagePlugin as message } from "tdesign-vue";
import { Prop, Ref } from "vue-property-decorator";
import { ChangePassword } from "../../model/ChangePassword";
import { userStore } from "../../stores/user.store";
import { IdentityType } from "../../constants/enum/identity-type.enum";
import { RestfulResponse } from "../../model/RestfulResponse";
import { apiService } from "../../services/api.service";
import sysUserLoginApi from "../../constants/api/sys-user-login.api";
import { Code } from "../../constants/enum/code.enum";
import { RestApi } from "../../model/RestApi";
import { SM4 } from "gm-crypto";

@Component({
  name: "UserChangePasswordModal",
  components: {},
})
export default class UserChangePasswordModal extends Vue {
  @Ref() formRef!: any; // 表单对象引用

  @Prop({ default: () => false }) visible!: boolean; // 模态框展开标识
  @Prop({ default: () => {} }) modalStatus!: any; // 模态框展开标识

  confirmLoading = false; // 请求等待状态标识
  key = "7c4a8d09ca3762af61e59520943dc264"; // 16 字节的密钥

  form: ChangePassword = new ChangePassword({
    userId: userStore.user?.userId,
    identityType: IdentityType.password.code,
    identityCode: userStore.user?.userCode,
  });

  validateRepeatPass = (value: any) => {
    if (value !== this.form.newPassword) {
      return {
        result: false,
        message: "两次密码不一致",
      };
    } else {
      return {
        result: true,
      };
    }
  };
  checkPasswordStrength = (password: any) => {
    const hasUpperCase = /[A-Z]/.test(password);
    const hasLowerCase = /[a-z]/.test(password);
    const hasSpecialChar = /[!@#$%^&*~]/.test(password);
    const isLengthValid = password.length >= 8 && password.length <= 12;
    const hasNoSpaces = !/\s/.test(password);

    if (!hasNoSpaces) {
      return {
        result: false,
        message: "不能有空格",
      };
    }
    if (!hasUpperCase) {
      return {
        result: false,
        message: "密码必须包含大写字母",
      };
    }
    if (!hasLowerCase) {
      return {
        result: false,
        message: "密码必须包含小写字母",
      };
    }
    if (!hasSpecialChar) {
      return {
        result: false,
        message: "密码必须包含特殊字符(!@#$ %&*~)",
      };
    }
    if (!isLengthValid) {
      return {
        result: false,
        message: "密码长度需8 ~ 12位",
      };
    }
    return {
      result: true,
    };
  };

  rules = {
    oldPassword: [{ required: true, message: "请输入旧密码" }],
    newPassword: [
      { required: true, message: "请输入密码" },
      { validator: this.checkPasswordStrength, trigger: "change" },
    ],
    repeatNewPassword: [
      { required: true, message: "请再次输入密码", trigger: "blur" },
      { validator: this.validateRepeatPass, trigger: "change" },
    ],
  };

  // 内部显示标识
  get modalVisible() {
    return this.visible;
  }

  set modalVisible(newValue) {
    this.$emit("update:visible", newValue);
  }
  /**
   * 对话框点击确定
   */
  handleConfirmOk() {
    this.formRef.submit();
  }

  /**
   * sm4加密
   */
  arrayBufferToHex(buffer: any) {
    const hex = Array.from(new Uint8Array(buffer))
      .map((byte) => byte.toString(16).padStart(2, "0"))
      .join("");
    return hex;
  }
  encrypt(password: string) {
    const encrypted = SM4.encrypt(password, this.key, {
      inputEncoding: "utf8",
      outputEncoding: "base64",
    });
    return encrypted;
  }

  /**
   * @description: 确认事件
   * @author ChenRui
   * @date 2021/10/11 17:01
   */
  handleOk() {
    this.confirmLoading = true;
    const restApi: RestApi = new RestApi(sysUserLoginApi.updatePassword);
    restApi.url = this.$dc.baseApi + sysUserLoginApi.updatePassword.url;

    const newPassword = this.encrypt(this.form.newPassword);
    const oldPassword = this.encrypt(this.form.oldPassword);
    let form = JSON.parse(JSON.stringify(this.form));
    form.newPassword = newPassword;
    form.repeatNewPassword = newPassword;
    form.oldPassword = oldPassword;

    apiService.general(restApi, undefined, form).then((response: RestfulResponse) => {
      this.confirmLoading = false;
      if (response.code === Code.SUCCESS.code) {
        message.success({ content: response.msg! });
        this.handleCancel(null, response);
      } else {
        message.error({ content: response.msg! });
      }
    });
  }

  /**
   * 提交
   */
  onSubmit(result: { validateResult: boolean }) {
    if (result.validateResult === true) {
      this.handleOk();
    }
  }
  /**
   * @description: 取消编辑
   * @author ChenRui
   * @date 2021/10/11 17:01
   */
  handleCancel(event: any, response: RestfulResponse) {
    this.$emit("close", response || RestfulResponse.failure());
    this.modalVisible = false;
  }
}
</script>

<style scoped lang="scss">
.dc-user-change-password-modal {
  .dc-form-model {
    ::v-deep {
      > .ant-form-item {
        display: flex;
        flex-direction: row;
        .ant-form-item-control-wrapper {
          flex-grow: 1;
          .ant-input-affix-wrapper {
            padding: 0;
          }
        }
      }
    }
  }
}
</style>
