<!-- 用户编辑弹窗 -->
<template>
  <ele-modal
    :width="750"
    :visible="visible"
    :confirm-loading="loading"
    :maxable="maxAble"
    :title="isUpdate ? '编辑' : '添加'"
    :body-style="{ paddingBottom: '8px' }"
    @update:visible="updateVisible"
    :maskClosable="false"
    @ok="save"
  >
    <a-form
      ref="formRef"
      :model="form"
      :rules="rules"
      :label-col="{ md: { span: 8 }, sm: { span: 24 } }"
      :wrapper-col="{ md: { span: 24 }, sm: { span: 24 } }"
      layout="vertical"
    >
      <a-form-item label="支付方式" name="method">
        <DictSelect
          dict-code="payMethod"
          v-model:value="form.method"
          placeholder="选择支付方式"
        />
      </a-form-item>
      <!-- 支付宝支付开始 -->
      <a-form-item
        label="支付宝应用"
        name="appId"
        v-if="form.method === '支付宝'"
      >
        <a-input
          allow-clear
          placeholder="支付宝分配给开发者的应用ID"
          v-model:value="form.appId"
        />
      </a-form-item>
      <a-form-item
        label="签名算法 (signType)"
        name="signType"
        v-if="form.method === '支付宝'"
      >
        <a-radio-group v-model:value="form.signType">
          <a-radio value="RSA2">RSA2</a-radio>
          <a-radio value="RSA">RSA</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item
        label="加签模式"
        name="signMode"
        v-if="form.method === '支付宝'"
      >
        <a-radio-group v-model:value="form.signMode">
          <a-radio value="公钥证书">
            <text>公钥证书</text>
            <a-tag class="ml-5" color="green">推荐</a-tag>
          </a-radio>
          <a-radio value="公钥">公钥</a-radio>
        </a-radio-group>
        <div class="form-item-help">
          <small>如需使用资金支出类的接口，则必须使用公钥证书模式，</small>
          <small>配置指南 https://opendocs.alipay.com/open/200/105310</small>
        </div>
      </a-form-item>
      <a-form-item
        label="应用公钥证书"
        name="appCertPublicKey"
        v-if="form.method === '支付宝' && form.signMode === '公钥证书'"
      >
        <Upload accept=".crt" v-model:value="form.appCertPublicKey" />
        <div class="form-item-help">
          <small>请上传 "appCertPublicKey.crt" 文件</small>
        </div>
        {{ form.appCertPublicKey }}
      </a-form-item>
      <a-form-item
        label="支付宝公钥证书"
        name="alipayCertPublicKey"
        v-if="form.method === '支付宝' && form.signMode === '公钥证书'"
      >
        <Upload accept=".crt" v-model:value="form.alipayCertPublicKey" />
        <div class="form-item-help">
          <small>请上传 "alipayCertPublicKey_RSA2.crt" 文件</small>
        </div>
        {{ form.alipayCertPublicKey }}
      </a-form-item>
      <a-form-item
        label="支付宝根证书"
        name="alipayRootCert"
        v-if="form.method === '支付宝' && form.signMode === '公钥证书'"
      >
        <Upload accept=".crt" v-model:value="form.alipayRootCert" />
        <div class="form-item-help">
          <small>请上传 "alipayRootCert.crt" 文件</small>
        </div>
        {{ form.alipayRootCert }}
      </a-form-item>
      <a-form-item
        label="支付宝公钥"
        name="alipayPublicKey"
        v-if="form.method === '支付宝' && form.signMode === '公钥'"
      >
        <a-textarea
          :rows="6"
          placeholder="请输入alipayPublicKey"
          v-model:value="form.alipayPublicKey"
        />
      </a-form-item>
      <a-form-item
        label="应用私钥"
        name="privateKey"
        v-if="form.method === '支付宝'"
      >
        <a-textarea
          :rows="6"
          placeholder="请输入privateKey"
          v-model:value="form.privateKey"
        />
        <div class="form-item-help">
          <small
            >查看 "应用私钥_RSA2_PKCS8.txt" 文件，将全部内容复制到此处</small
          >
        </div>
      </a-form-item>
      <!-- 支付宝支付结束 -->
      <a-form-item label="排序号" name="sortNumber">
        <a-input-number
          :min="0"
          :max="99999"
          class="ele-fluid"
          placeholder="请输入排序号（数字越小越靠前）"
          v-model:value="form.sortNumber"
        />
      </a-form-item>
    </a-form>
  </ele-modal>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch } from 'vue';
  import { message } from 'ant-design-vue';
  import { addPayment, updatePayment } from '@/api/system/payment';
  import { FormInstance, Rule } from 'ant-design-vue/es/form';
  import useFormData from '@/utils/use-form-data';
  import { Payment } from '@/api/system/payment/model';
  import { assignObject } from 'ele-admin-pro';
  import Upload from '@/components/UploadFile/index.vue';

  // 是否是修改
  const isUpdate = ref(false);
  // 是否显示最大化切换按钮
  const maxAble = ref(true);
  const props = defineProps<{
    // 弹窗是否打开
    visible: boolean;
    // 修改回显的数据
    data?: Payment | null;
  }>();

  const emit = defineEmits<{
    (e: 'done'): void;
    (e: 'update:visible', visible: boolean): void;
  }>();

  // 提交状态
  const loading = ref(false);
  // 已上传数据
  const formRef = ref<FormInstance | null>(null);
  /* 更新visible */
  const updateVisible = (value: boolean) => {
    emit('update:visible', value);
  };

  // 表单数据
  const { form, resetFields } = useFormData<Payment>({
    paymentId: undefined,
    method: undefined,
    appId: '',
    icon: '',
    signType: 'RSA2',
    signMode: '公钥证书',
    // 公钥模式
    alipayPublicKey: '',
    privateKey: '',
    // 公钥证书模式
    appCertPublicKey: '',
    alipayCertPublicKey: '',
    alipayRootCert: '',
    // json数据
    config: undefined,
    createTime: '',
    comments: '',
    sortNumber: 100,
    status: 0
  });

  // 表单验证规则
  const rules = reactive<Record<string, Rule[]>>({
    method: [
      {
        required: true,
        message: '请输入支付方式名称',
        type: 'string',
        trigger: 'blur'
      }
    ],
    signType: [
      {
        required: true,
        type: 'string',
        message: '请填写签名算法',
        trigger: 'blur'
      }
    ],
    appCertPublicKey: [
      {
        required: true,
        type: 'string',
        message: '请上传应用公钥证书',
        trigger: 'blur'
      }
    ],
    alipayCertPublicKey: [
      {
        required: true,
        type: 'string',
        message: '请上传支付宝公钥证书',
        trigger: 'blur'
      }
    ],
    alipayRootCert: [
      {
        required: true,
        type: 'string',
        message: '请上传支付宝根证书',
        trigger: 'blur'
      }
    ],
    signMode: [
      {
        required: true,
        type: 'string',
        message: '请选择加签模式',
        trigger: 'blur'
      }
    ],
    comments: [
      {
        required: true,
        type: 'string',
        message: '请填写支付方式简介',
        trigger: 'blur'
      }
    ],
    status: [
      {
        required: true,
        type: 'number',
        message: '请选择支付方式状态',
        trigger: 'blur'
      }
    ],
    sortNumber: [
      {
        required: true,
        type: 'number',
        message: '请输入排序号',
        trigger: 'blur'
      }
    ],
    appId: [
      {
        required: true,
        type: 'string',
        message: '请填写应用ID',
        trigger: 'blur'
      }
    ],
    alipayPublicKey: [
      {
        required: true,
        type: 'string',
        message: '请填写支付宝公钥',
        trigger: 'blur'
      }
    ],
    privateKey: [
      {
        required: true,
        type: 'string',
        message: '请填写应用私钥',
        trigger: 'blur'
      }
    ]
  });

  /* 保存编辑 */
  const save = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        loading.value = true;
        const merchantForm = {
          ...form,
          config: JSON.stringify(form)
        };
        const saveOrUpdate = isUpdate.value ? updatePayment : addPayment;
        saveOrUpdate(merchantForm)
          .then((msg) => {
            loading.value = false;
            message.success(msg);
            updateVisible(false);
            emit('done');
          })
          .catch((e) => {
            loading.value = false;
            message.error(e.message);
          });
      })
      .catch(() => {});
  };

  watch(
    () => props.visible,
    (visible) => {
      if (visible) {
        if (props.data) {
          loading.value = false;
          form.config = undefined;
          if (props.data.config) {
            const config = JSON.parse(String(props.data.config));
            config.paymentId = props.data.paymentId;
            assignObject(form, config);
          }
          isUpdate.value = true;
        } else {
          isUpdate.value = false;
        }
      } else {
        resetFields();
        formRef.value?.clearValidate();
      }
    }
  );
</script>
<style lang="less">
  .tab-pane {
    min-height: 300px;
  }
  .ml-10 {
    margin-left: 10px;
  }
  .ml-5 {
    margin-left: 5px;
  }
  .form-item-help {
    color: #c5c5c5;
  }
  .flex-sb {
    display: flex;
    justify-content: space-between;
  }
</style>
