huangyinfeng
2024-09-18 ccfd07feeaa670a3d56548d7fea0936e299df95b
src/views/email/Edit/index.vue
@@ -1,240 +1,261 @@
<template>
    <a-card size="small">
      <div class="p-1">
        <a-form
          ref="formRef"
          :label-col="{ span: 2 }"
          :wrapper-col="{ span: 24 }"
          :model="modelRef"
        >
          <a-form-item :wrapper-col="{ span: 8 }">
            <div style="display: flex; justify-content: space-evenly">
              <a-button type="primary" shape="round" @click="fnHandleSubmit(modelRef)"
                >发送</a-button
  <div class="p-3">
    <a-spin :spinning="loading" class="p-1">
      <a-form ref="formRef" :label-col="{ span: 2 }" :wrapper-col="{ span: 24 }" :model="modelRef">
        <a-form-item :wrapper-col="{ span: 8 }">
          <div style="display: flex; justify-content: space-evenly">
            <a-button type="primary" shape="round" @click="fnHandleSubmit(modelRef)">发送</a-button>
            <a-button shape="round" @click="fnSaveMailDrafts">存草稿</a-button>
            <a-button shape="round" @click="fnPreview">预览</a-button>
            <a-button shape="round">提交审批</a-button>
            <a-button shape="round">取消</a-button></div
          >
        </a-form-item>
        <a-form-item label="发件人" v-bind="validateInfos.sender" :wrapper-col="{ span: 12 }">
          <a-select
            v-model:value="modelRef.sender"
            placeholder="选择发件人"
            show-search
            :field-names="{ label: 'email', value: 'email' }"
            :options="state.senderList"
            :filter-option="fnFilterOption"
          >
          </a-select>
        </a-form-item>
        <a-form-item label="收件人" v-bind="validateInfos.recipients" :wrapper-col="{ span: 18 }">
          <a-row>
            <a-col class="gutter-row" :span="16">
              <a-select
                mode="tags"
                placeholder="请选择收件人或者输入收件人邮箱"
                v-model:value="modelRef.recipients"
                :options="state.recipientsList"
                :field-names="{ label: 'email', value: 'userName' }"
                :maxTagCount="4"
                @search="fetchUser"
              >
              <a-button shape="round" @click="fnSaveMailDrafts">存草稿</a-button>
              <a-button shape="round" @click="fnPreview">预览</a-button>
              <a-button shape="round">提交审批</a-button>
              <a-button shape="round">取消</a-button></div
            >
          </a-form-item>
          <a-form-item label="发件人" v-bind="validateInfos.sender" :wrapper-col="{ span: 12 }">
            <a-select
              v-model:value="modelRef.sender"
              placeholder="选择发件人"
              show-search
              :field-names="{ label: 'name', value: 'id' }"
              :options="state.data"
              :filter-option="fnFilterOption"
            >
            </a-select>
          </a-form-item>
          <a-form-item label="收件人" v-bind="validateInfos.recipients" :wrapper-col="{ span: 18 }">
            <a-row>
              <a-col class="gutter-row" :span="16">
                <a-select
                  mode="multiple"
                  show-search
                  placeholder="请选择收件人或者输入收件人邮箱"
                  v-model:value="modelRef.recipients"
                  :options="state.data"
                  :field-names="{ label: 'name', value: 'id' }"
                  :maxTagCount="4"
                  :filter-option="fnFilterOption"
                />
              </a-col>
              <a-col
                class="gutter-row"
                :span="2"
                style="display: flex; align-items: center; justify-content: center"
              >
                <plus-circle-outlined
                  style="color: rgb(0 0 0 / 45%)"
                  @click="fnHandleSelect('recipients')"
                />
              </a-col>
              <a-col class="gutter-row" :span="1">
                <a-form-item-rest>
                  <a-button
                    shape="round"
                    type="link"
                    block
                    size="small"
                    @click="ccCheckboxChange($event)"
                <template #tagRender="{ label, closable, onClose, option }">
                  <a-tag
                    :closable="closable"
                    style="margin-right: 3px"
                    @close="onClose"
                    :color="validateEmail(label) ? 'default' : 'red'"
                  >
                    {{ !isSecretDeliveryPerson ? '抄送' : '取消抄送' }}
                  </a-button>
                </a-form-item-rest>
              </a-col>
              <a-col class="gutter-row" :span="1">
                <a-form-item-rest>
                  <a-button
                    shape="round"
                    type="link"
                    block
                    size="small"
                    @click="bccCheckboxChange($event)"
                  >
                    {{ !isCRecipient ? '密送' : '取消密送' }}
                  </a-button>
                </a-form-item-rest>
              </a-col>
            </a-row>
          </a-form-item>
          <span style="position: relative; top: -18px; left: 9%" v-if="modelRef.recipients.length">
            {{ userParticulars && `${userParticulars.name}<${userParticulars.email}` }}>
            <span v-if="!userParticulars.title" style="margin-right: 10px; margin-left: 5px">
              暂未查询到该客户的当地时间
              <a @click="fnHandleTimeZone(userParticulars, 'add')">补充时区</a>
            </span>
            <span v-else>
              {{ userParticulars.title }}
              <a @click="fnHandleTimeZone(userParticulars, 'update')">时区不对?</a>
            </span>
            <a v-if="modelRef.recipients.length > 2">查看全部</a>
                    {{ label }}&nbsp;&nbsp;
                  </a-tag>
                </template>
              </a-select>
            </a-col>
            <a-col
              class="gutter-row"
              :span="2"
              style="display: flex; align-items: center; justify-content: center"
            >
              <plus-circle-outlined
                style="color: rgb(0 0 0 / 45%)"
                @click="fnHandleSelect('recipients')"
              />
            </a-col>
            <a-col class="gutter-row" :span="1">
              <a-form-item-rest>
                <a-button
                  shape="round"
                  type="link"
                  block
                  size="small"
                  @click="ccCheckboxChange($event)"
                >
                  {{ !isSecretDeliveryPerson ? '抄送' : '取消抄送' }}
                </a-button>
              </a-form-item-rest>
            </a-col>
            <a-col class="gutter-row" :span="1">
              <a-form-item-rest>
                <a-button
                  shape="round"
                  type="link"
                  block
                  size="small"
                  @click="bccCheckboxChange($event)"
                >
                  {{ !isCRecipient ? '密送' : '取消密送' }}
                </a-button>
              </a-form-item-rest>
            </a-col>
          </a-row>
        </a-form-item>
        <span style="position: relative; top: -18px; left: 9%" v-if="modelRef.recipients.length">
          {{ userParticulars && `${userParticulars.userName}<${userParticulars.email}` }}>
          <span v-if="!userParticulars.title" style="margin-right: 10px; margin-left: 5px">
            暂未查询到该客户的当地时间
            <a @click="fnHandleTimeZone(userParticulars, 'add')">补充时区</a>
          </span>
          <span v-else>
            {{ userParticulars.title }}
            <a @click="fnHandleTimeZone(userParticulars, 'update')">时区不对?</a>
          </span>
          <a-form-item
            label="抄送人"
            v-bind="validateInfos.ccRecipients"
            v-if="isSecretDeliveryPerson"
            :wrapper-col="{ span: 18 }"
          >
            <a-row>
              <a-col class="gutter-row" :span="16">
                <a-select
                  mode="multiple"
                  show-search
                  placeholder="请选择抄送人或者输入抄送人邮箱"
                  v-model:value="modelRef.ccRecipients"
                  :options="state.data"
                  :field-names="{ label: 'name', value: 'id' }"
                  :maxTagCount="4"
                  :filter-option="fnFilterOption"
                />
              </a-col>
              <a-col
                class="gutter-row"
                :span="2"
                style="display: flex; align-items: center; justify-content: center"
              >
                <plus-circle-outlined
                  style="color: rgb(0 0 0 / 45%)"
                  @click="fnHandleSelect('ccRecipients')"
                />
              </a-col>
            </a-row>
          </a-form-item>
          <a-form-item
            label="密送人"
            v-bind="validateInfos.bccRecipients"
            v-if="isCRecipient"
            :wrapper-col="{ span: 18 }"
          >
            <a-row>
              <a-col class="gutter-row" :span="16">
                <a-select
                  mode="multiple"
                  show-search
                  placeholder="请选择抄送人或者输入抄送人邮箱"
                  v-model:value="modelRef.bccRecipients"
                  :options="state.data"
                  :field-names="{ label: 'name', value: 'id' }"
                  :maxTagCount="4"
                  :filter-option="fnFilterOption"
                />
              </a-col>
              <a-col
                class="gutter-row"
                :span="2"
                style="display: flex; align-items: center; justify-content: center"
              >
                <plus-circle-outlined
                  style="color: rgb(0 0 0 / 45%)"
                  @click="fnHandleSelect('bccRecipients')"
                />
              </a-col>
            </a-row>
          </a-form-item>
          <div
            style="position: relative; top: -20px; left: 9%; color: #909090; font-size: 12px"
            v-if="modelRef.recipients.length"
          >
            {{ `${userLength}/100 收件人、抄送人和密送的联系人总数不可超过100` }}
          </div>
          <a-form-item label="主题" :wrapper-col="{ span: 12 }" :label-col="{ span: 2 }">
            <a-input placeholder="请输入邮件主题" v-model:value="modelRef.subject" />
          </a-form-item>
          <a-form-item
            v-bind="validateInfos.content"
            :wrapper-col="{ span: 24 }"
            :label-col="{ span: 2 }"
          >
            <Tinymce @change="fnChangeContent"></Tinymce>
          </a-form-item>
        </a-form>
      </div>
      <SelectUser
        ref="selectUserRef"
        v-model="openSelectUser"
        :selectIds="selectIds"
        :idName="idName"
        :title="selectUserTitle"
        @updateData="fnSelectUser"
      />
      <a-modal
        v-model:open="openTimeZone"
        :title="`${titleTimeZone}时区`"
        :confirm-loading="confirmLoading"
        @ok="fnHandleTimeZoneOk"
      >
        <a-form
          ref="formTimeZoneRef"
          :label-col="{ span: 6 }"
          :wrapper-col="{ span: 24 }"
          :model="modelRef"
        >
          <a-form-item label="国家地区:" :wrapper-col="{ span: 12 }">
            <a-select
              v-model:value="modelRef.sender"
              placeholder="选择国家地区"
              show-search
              :field-names="{ label: 'name', value: 'id' }"
              :options="state.data"
            >
            </a-select>
          </a-form-item>
          <a-form-item label="时区:" :wrapper-col="{ span: 12 }">
            <a-select
              v-model:value="modelRef.sender"
              placeholder="选择时区"
              show-search
              :field-names="{ label: 'name', value: 'id' }"
              :options="state.data"
            >
            </a-select>
          </a-form-item>
          <a-form-item :label-col="{ span: 6 }">
            <a-row>
              <a-col span="6"> </a-col>
              <a-col span="18">
                <div style="color: #909090"
                  >当地实时时间根据时区信息显示<br />
                  国家地区/时区信息在客户资料-特征信息查看</div
                >
              </a-col>
            </a-row>
          </a-form-item>
        </a-form>
      </a-modal>
    </a-card>
          <a v-if="modelRef.recipients.length > 2">查看全部</a>
        </span>
        <a-form-item
          label="抄送人"
          v-bind="validateInfos.ccRecipients"
          v-if="isSecretDeliveryPerson"
          :wrapper-col="{ span: 18 }"
        >
          <a-row>
            <a-col class="gutter-row" :span="16">
              <a-select
                mode="tags"
                placeholder="请选择抄送人或者输入抄送人邮箱"
                v-model:value="modelRef.recipients"
                :options="state.recipientsList"
                :field-names="{ label: 'email', value: 'userName' }"
                :maxTagCount="4"
              >
                <template #tagRender="{ label, closable, onClose }">
                  <a-tag
                    :closable="closable"
                    style="margin-right: 3px"
                    @close="onClose"
                    :color="validateEmail(label) ? 'default' : 'red'"
                  >
                    {{ label }}&nbsp;&nbsp;
                  </a-tag>
                </template>
              </a-select>
            </a-col>
            <a-col
              class="gutter-row"
              :span="2"
              style="display: flex; align-items: center; justify-content: center"
            >
              <plus-circle-outlined
                style="color: rgb(0 0 0 / 45%)"
                @click="fnHandleSelect('ccRecipients')"
              />
            </a-col>
          </a-row>
        </a-form-item>
        <a-form-item
          label="密送人"
          v-bind="validateInfos.bccRecipients"
          v-if="isCRecipient"
          :wrapper-col="{ span: 18 }"
        >
          <a-row>
            <a-col class="gutter-row" :span="16">
              <a-select
                mode="tags"
                placeholder="请选择抄送人或者输入抄送人邮箱"
                v-model:value="modelRef.bccRecipients"
                :options="state.recipientsList"
                :field-names="{ label: 'email', value: 'userName' }"
                :maxTagCount="4"
              >
                <template #tagRender="{ label, closable, onClose }">
                  <a-tag
                    :closable="closable"
                    style="margin-right: 3px"
                    @close="onClose"
                    :color="validateEmail(label) ? 'default' : 'red'"
                  >
                    {{ label }}&nbsp;&nbsp;
                  </a-tag>
                </template>
              </a-select>
            </a-col>
            <a-col
              class="gutter-row"
              :span="2"
              style="display: flex; align-items: center; justify-content: center"
            >
              <plus-circle-outlined
                style="color: rgb(0 0 0 / 45%)"
                @click="fnHandleSelect('bccRecipients')"
              />
            </a-col>
          </a-row>
        </a-form-item>
        <div
          style="position: relative; top: -20px; left: 9%; color: #909090; font-size: 12px"
          v-if="modelRef.recipients.length"
        >
          {{ `${userLength}/100 收件人、抄送人和密送的联系人总数不可超过100` }}
        </div>
        <a-form-item label="主题" :wrapper-col="{ span: 12 }" :label-col="{ span: 2 }">
          <a-input placeholder="请输入邮件主题" v-model:value="modelRef.subject" />
        </a-form-item>
        <a-form-item
          v-bind="validateInfos.content"
          :wrapper-col="{ span: 24 }"
          :label-col="{ span: 2 }"
        >
          <Tinymce @change="fnChangeContent"></Tinymce>
        </a-form-item>
      </a-form>
    </a-spin>
    <SelectUser
      ref="selectUserRef"
      v-model="openSelectUser"
      :selectIds="selectIds"
      :idName="idName"
      :title="selectUserTitle"
      @sudUserList="fnGetRecipientsList"
      @updateData="fnSelectUser"
    />
    <a-modal
      v-model:open="openTimeZone"
      :title="`${titleTimeZone}时区`"
      :confirm-loading="confirmLoading"
      @ok="fnHandleTimeZoneOk"
    >
      <a-form
        ref="formTimeZoneRef"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 24 }"
        :model="modelRef"
      >
        <a-form-item label="国家地区:" :wrapper-col="{ span: 12 }">
          <a-select
            v-model:value="modelRef.sender"
            placeholder="选择国家地区"
            show-search
            :field-names="{ label: 'name', value: 'id' }"
            :options="state.data"
          >
          </a-select>
        </a-form-item>
        <a-form-item label="时区:" :wrapper-col="{ span: 12 }">
          <a-select
            v-model:value="modelRef.sender"
            placeholder="选择时区"
            show-search
            :field-names="{ label: 'name', value: 'id' }"
            :options="state.data"
          >
          </a-select>
        </a-form-item>
        <a-form-item :label-col="{ span: 6 }">
          <a-row>
            <a-col span="6"> </a-col>
            <a-col span="18">
              <div style="color: #909090"
                >当地实时时间根据时区信息显示<br />
                国家地区/时区信息在客户资料-特征信息查看</div
              >
            </a-col>
          </a-row>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>
<script lang="ts" setup>
name: 'Edit';
  import { useDesign } from '@/hooks/web/useDesign'
  name: 'Edit';
  import { useDesign } from '@/hooks/web/useDesign';
  import { ref, reactive, computed } from 'vue';
  import { useMessage } from '@/hooks/web/useMessage';
@@ -247,10 +268,11 @@
    recipients: [],
    ccRecipients: [],
    bccRecipients: [],
    fileUNID: [],
    attachmentList: [],
    subject: '',
    content: '',
  });
  const loading = ref(false);
  const rulesRef = reactive({
    sender: [
      {
@@ -291,22 +313,30 @@
  };
  const { createMessage } = useMessage();
  import { getUserListApi, sendingMailApi, saveMailDraftsApi } from '@/api/email/userList';
  import {
    getAccountListApi,
    sendingMailApi,
    saveMailDraftsApi,
    emailListAPi,
  } from '@/api/email/userList';
  // 定义状态管理对象
  const state = reactive({
    data: [],
    fetching: false,
    error: null,
    senderList: [],
    recipientsList: [],
  });
  // 获取用户列表的函数
  const fnGetUserList = async (params) => {
    try {
      state.fetching = true;
      const res = await getUserListApi(params);
      const res = await getAccountListApi();
      console.log(res, 'res');
      if (res && res.items && Array.isArray(res.items)) {
        state.data = res.items;
      if (res && res.data && Array.isArray(res.data)) {
        state.senderList = res.data;
      } else {
        console.error('Invalid response format:', res);
      }
@@ -326,7 +356,7 @@
  fetchData();
  const fnFilterOption = (input: string, option: any) => {
    return option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0;
    return option.email.toLowerCase().indexOf(input.toLowerCase()) >= 0;
  };
  const openSelectUser = ref(false);
@@ -352,7 +382,7 @@
  function fnChangeContent(e) {
    modelRef.content = e.content;
    modelRef.fileUNID = e.fileUNID;
    modelRef.attachmentList = e.attachmentList;
  }
  function fnBuildingCommitData() {
@@ -363,7 +393,7 @@
      bcc: modelRef.bccRecipients,
      subject: modelRef.subject,
      content: modelRef.content,
      fileUNID: '4DFEFEB4-3BB1-448D-9712-DC6C106A7A44;7732',
      attachmentList: '',
      docCode: docCode.value,
    };
  }
@@ -389,19 +419,40 @@
        createMessage.error('表单验证失败');
      });
  }
  import { useRouter } from 'vue-router';
  const router = useRouter();
  function pushSendingMail() {
    const data = fnBuildingCommitData();
    sendingMailApi(data).then((res) => {});
    loading.value = true;
    sendingMailApi(data)
      .then((res) => {
        if (res.code === 0) {
          loading.value = false;
          createMessage.success(res.msg);
          router.push('/email/list');
        }
      })
      .catch((error) => {
        loading.value = false;
      });
  }
  function fnPreview() {}
  function fnSaveMailDrafts() {
    const data = fnBuildingCommitData();
    saveMailDraftsApi(data).then((res) => {
      docCode.value = res.data.docCode;
      createMessage.success(res.msg);
    });
    loading.value = true;
    saveMailDraftsApi(data)
      .then((res) => {
        loading.value = false;
        if (res === 0) {
          docCode.value = res.data.docCode;
          createMessage.success('保存成功');
        }
      })
      .catch((error) => {
        loading.value = false;
      });
  }
  const fnSelectUser = (e) => {
@@ -427,7 +478,7 @@
      return { value: '', email: '', title: '' };
    }
    // 使用 find 方法查找匹配项
    const foundItem = state.data.find((item) => item.id === recipientId);
    const foundItem = state.recipientsList.find((item) => item.email === recipientId);
    // 返回找到的项,如果未找到则返回 null
    return foundItem || { value: '', email: '', title: '' };
@@ -456,7 +507,31 @@
      confirmLoading.value = false;
    }, 2000);
  };
  const { prefixCls } = useDesign('email');
  function fnGetRecipientsList(data) {
    state.recipientsList = data;
  }
  // 邮箱校验正则表达式
  const validateEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
  import { debounce } from 'lodash-es';
  let lastFetchId = 0;
  const fetchUser = debounce((value) => {
    lastFetchId += 1;
    const fetchId = lastFetchId;
    state.data = [];
    state.fetching = true;
    emailListAPi({ key: value }).then((body) => {
      if (fetchId !== lastFetchId) {
        // for fetch callback order
        return;
      }
      state.recipientsList = body.data;
      state.fetching = false;
    });
  }, 300);
</script>
<style lang="less" scoped>
  @prefix-cls: ~'@{namespace}-email';