<template>
  <a-page-header title="提交工单" @back="push('/oa/task')">
    <a-card class="ele-body">
        <a-form
          ref="formRef"
          :model="form"
          :rules="rules"
          :label-col="{ md: { span: 7 }, sm: { span: 4 }, xs: { span: 24 } }"
          :wrapper-col="{ md: { span: 14 }, sm: { span: 24 }, xs: { span: 24 } }"
          layout="vertical"
        >
          <a-row :gutter="16">
            <a-col
              v-bind="styleResponsive ? { md: 9, sm: 24, xs: 24 } : { span: 8 }"
            >
              <a-form-item label="标题" name="name">
                <a-input
                    allow-clear
                    :maxlength="50"
                    placeholder="请输入工单标题"
                    v-model:value="form.name"
                />
              </a-form-item>
              <a-form-item label="工单类型" name="taskType">
                <a-select
                  optionFilterProp="label"
                  placeholder="请选择工单类型"
                  :options="taskType"
                  allow-clear
                  v-model:value="form.taskType"
                />
              </a-form-item>
              <a-form-item label="联系方式" name="phone">
                <a-input
                  allow-clear
                  :maxlength="11"
                  placeholder="请输入手机号码"
                  v-model:value="form.phone"
                />
              </a-form-item>
            </a-col>
            <a-col
                v-bind="styleResponsive ? { md: 9, sm: 24, xs: 24 } : { span: 8 }"
            >
              <a-form-item label="关联项目">
                <SelectApp v-model:value="form.appName" @done="chooseApp" />
              </a-form-item>
              <a-form-item label="上传附件（选填）" name="files">
                <a-upload
                  v-model:file-list="fileList"
                  class="upload-list-inline"
                  list-type="picture"
                  :before-upload="beforeUpload"
                >
                  <a-button>
                    <UploadOutlined />
                    上传附件
                  </a-button>
                </a-upload>
              </a-form-item>
            </a-col>
          </a-row>
          <a-col
            v-bind="styleResponsive ? { md: 24, sm: 24, xs: 24 } : { span: 8 }"
          >
            <a-form-item label="问题描述" name="content">
              <!-- 编辑器 -->
              <byte-md-editor
                v-model:value="content"
                placeholder="请描述您的问题，支持图片粘贴"
                :locale="zh_Hans"
                :plugins="plugins"
                mode="tab"
                height="300px"
                maxLength="500"
                :editorConfig="{ lineNumbers: true }"
                @paste="onPaste"
              />
            </a-form-item>
            <a-form-item label="机密信息（选填）" name="files">
              <a-textarea :rows="4" v-model:value="form.confidential" placeholder="请在此处填写项目名、账号、密码等机密信息，提交后机密信息将做加密处理"></a-textarea>
            </a-form-item>
          </a-col>
          <a-form-item>
            <a-button type="primary" block size="large" @click="save">提交</a-button>
          </a-form-item>
        </a-form>
    </a-card>
  </a-page-header>
</template>

<script lang="ts" setup>
  // 表单数据
  import useFormData from '@/utils/use-form-data';
  import { Task } from '@/api/oa/task/model';
  import {reactive, ref, unref, watch} from "vue";
  import { FormInstance, Rule, RuleObject } from "ant-design-vue/es/form";
  import { ItemType } from "ele-admin-pro/es/ele-image-upload/types";
  import { uploadFile, uploadOss } from "@/api/system/file";
  import { Form, message } from "ant-design-vue";
  import gfm from "@bytemd/plugin-gfm";
  import CryptoJS from 'crypto-js';
  // 中文语言文件
  import zh_Hans from 'bytemd/locales/zh_Hans.json';
  import zh_HansGfm from "@bytemd/plugin-gfm/locales/zh_Hans.json";
  import highlight from "@bytemd/plugin-highlight";
  import { encrypt, getDictionaryOptions, getMobile, isImage, openUrl } from "@/utils/common";
  import { addTask } from "@/api/oa/task";
  import { isPhone } from "ele-admin-pro";
  import { useUserStore } from "@/store/modules/user";
  import { useParamsStore } from "@/store/modules/params";
  import { useRouter } from "vue-router";
  import { useThemeStore } from "@/store/modules/theme";
  import { storeToRefs } from "pinia";
  import { User } from "@/api/system/user/model";
  import { App } from "@/api/oa/app/model";

  const { currentRoute } = useRouter();
  // 是否开启响应式布局
  const themeStore = useThemeStore();
  const { styleResponsive } = storeToRefs(themeStore);

  const userStore = useUserStore();
  const { info } = userStore;
  const paramsStore = useParamsStore();
  const { push } = useRouter();
  const useForm = Form.useForm;
  const taskType = getDictionaryOptions('taskType');
  const fileList = ref<any[]>([]);
  const files = ref<ItemType[]>([]);
  const phone = ref('');
  const content = ref('');
  const loading = ref(false);
  const formRef = ref<FormInstance | null>(null);

  const { form, resetFields, assignFields } = useFormData<Task>({
    taskId: undefined,
    taskType: undefined,
    phone: info?.phone,
    name: undefined,
    status: undefined,
    promoter: undefined,
    comments: '',
    redirect: '',
    appId: undefined,
    appName: '',
    confidential: ''
  });

  // 表单验证规则
  const rules = reactive({
    taskType: [
      {
        required: true,
        message: '请选择工单类型',
        type: 'string',
        trigger: 'blur'
      }
    ],
    content: [
      {
        required: true,
        type: "string",
        message: "请填写问题描述",
        trigger: "blur",
        validator: async (_rule: RuleObject, value: string) => {
          if (content.value == "") {
            return Promise.reject("请填写问题描述");
          }
          return Promise.resolve();
        }
      }
    ],
    name: [
      {
        required: true,
        message: '请输入工单标题'
      }
    ],
    phone: [
      {
        required: true,
        message: '请输入正确的手机号码',
        type: 'string',
        trigger: 'blur',
        validator: async (_rule: RuleObject, value: string) => {
          if (!isPhone(value)) {
            return Promise.reject("请输入正确的手机号码");
          }
          return Promise.resolve();
        }
      }
    ],
    sortNumber: [
      {
        required: true,
        message: '请输入排序号',
        type: 'number',
        trigger: 'blur'
      }
    ]
  });

  // 插件
  const plugins = ref([
    gfm({
      locale: zh_HansGfm
    }),
    highlight()
  ]);

  // 文件上传事件
  const beforeUpload = (file: File) => {
    const item: ItemType = {
      file,
      uid: (file as any).uid,
      name: file.name
    }
    if (!file.type.startsWith("image")) {
      if (file.size / 1024 / 1024 > 100) {
        message.error("大小不能超过 100MB");
        return;
      }
    }
    onUpload(item);
    return false;
  };

  const onUpload = (d: ItemType) => {
    uploadOss(<File>d.file)
      .then((result) => {
        files.value.push({
          uid: result.id,
          url: result.path,
          name: isImage(result.path) ? 'image' : result.name,
          status: "done"
        });
        message.success("上传成功");
      })
      .catch((e) => {
        message.error(e.message);
      });
  };

  /* 粘贴图片上传服务器并插入编辑器 */
  const onPaste = (e) => {
    const items = (e.clipboardData || e.originalEvent.clipboardData).items;
    let hasFile = false;
    for (let i = 0; i < items.length; i++) {
      if (items[i].type.indexOf('image') !== -1) {
        let file = items[i].getAsFile();
        const item: ItemType = {
          file,
          uid: (file as any).lastModified,
          name: file.name
        };
        uploadOss(<File>item.file)
          .then((result) => {
            const addPath = '!['+result.name+']('+ result.url+')\n\r';
            content.value = content.value + addPath
          })
          .catch((e) => {
            message.error(e.message);
          });
        hasFile = true;
      }
    }
    if (hasFile) {
      e.preventDefault();
    }
  }

  /**
   * 选择应用
   * @param item
   */
  const chooseApp = (item: App) => {
    form.appId = item.appId;
    form.appName = item.appName;
  };

  const {validate, validateInfos} = useForm(form, rules);

  /* 保存编辑 */
  const save = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        loading.value = true;
        if (!isPhone(String(form.phone))) {
          message.error(form.phone)
          return false
        }
        const data = {
          ...form,
          // 处理工单内容
          content: content.value,
          files: JSON.stringify(files.value)
        };
        // 加密信息处理
        if(form.confidential != ''){
          data.confidential = encrypt(form.confidential)
        }else {
          data.confidential = undefined
        }
        addTask(data)
          .then((res) => {
            loading.value = false;
            content.value = '';
            files.value = [];
            paramsStore.setBack('/oa/task')
            paramsStore.setRedirect('/oa/task/detail/' + res?.taskId);
            setTimeout(() => {
              openUrl('/result/success');
            },200)
          })
          .catch((e) => {
            loading.value = false;
            message.error(e.message);
          });
      })
      .catch(() => {});
  };
  watch(
      currentRoute,
      (route) => {
        const { query } = unref(route);
        const { appId,appName } = query;
        if (appId) {
          form.appId = Number(appId);
          form.appName = String(appName);
        }
      },
      { immediate: true }
  );
</script>

<script lang="ts">
  export default {
    name: 'TaskAdd'
  };
</script>
