Newer
Older
dxCard-admin / src / views / system / appconfig / ThirdAppDingTalkConfigForm.vue
YFJ on 23 Sep 9 KB 项目推送
<template>
  <div class="base-collapse">
    <div class="header"> 钉钉集成 </div>
    <a-collapse expand-icon-position="right" :bordered="false">
      <a-collapse-panel key="1">
        <template #header>
          <div style="font-size: 16px"> 1.获取对接信息</div>
        </template>
        <div class="base-desc">从钉钉开放平台获取对接信息,即可开始集成以及同步通讯录</div>
        <div style="margin-top: 5px">
          <a href='https://help.qiaoqiaoyun.com/expand/dingding.html' target='_blank'>如何获取对接信息?</a>
        </div>
      </a-collapse-panel>
    </a-collapse>
    <div class="sync-padding">
      <a-collapse expand-icon-position="right" :bordered="false">
        <a-collapse-panel key="2">
          <template #header>
            <div style="width: 100%; justify-content: space-between; display: flex">
              <div style="font-size: 16px"> 2.对接信息录入及解绑</div>
            </div>
          </template>
          <div class="base-desc">完成步骤1后,填入Agentld、 AppKey、AppSecret后 可对接应用与同步通讯录</div>
          <div class="flex-flow">
            <div class="base-title">CorpId</div>
            <div class="base-message">
              <a-input-password v-model:value="appConfigData.corpId" readonly />
            </div>
          </div>
          <div class="flex-flow">
            <div class="base-title">Agentld</div>
            <div class="base-message">
              <a-input-password v-model:value="appConfigData.agentId" readonly />
            </div>
          </div>
          <div class="flex-flow">
            <div class="base-title">AppKey</div>
            <div class="base-message">
              <a-input-password v-model:value="appConfigData.clientId" readonly />
            </div>
          </div>
          <div class="flex-flow">
            <div class="base-title">AppSecret</div>
            <div class="base-message">
              <a-input-password v-model:value="appConfigData.clientSecret" readonly />
            </div>
          </div>
          <div style="margin-top: 20px; width: 100%; text-align: right">
            <a-button @click="dingEditClick">编辑</a-button>
            <a-button v-if="appConfigData.id" @click="cancelBindClick" danger style="margin-left: 10px">取消绑定</a-button>
          </div>
        </a-collapse-panel>
      </a-collapse>
      <div class="sync-padding">
        <div style="font-size: 16px; width: 100%"> 3.数据同步</div>
        <div style="margin-top: 20px" class="base-desc">
          从钉钉同步到本地
          <ul style='list-style-type: disc;margin-left: 20px;'>
            <li>同步部门到本地</li>
            <li>
              同步部门下的用户到本地
              <a-tooltip title='同步用户与部门文档'>
                <a-icon @click='handleIconClick' type="question-circle" class="sync-text"/>
              </a-tooltip>
            </li>
          </ul>
          <div style="float: right">
            <a-button :loading="btnLoading" @click="syncDingTalk">{{ !btnLoading ? '同步' : '同步中' }}</a-button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <ThirdAppConfigModal @register="registerAppConfigModal" @success="handleSuccess" />
</template>

<script lang="ts">
  import { defineComponent, h, inject, onMounted, reactive, ref, watch } from 'vue';
  import { getThirdConfigByTenantId, syncDingTalkDepartUserToLocal, deleteThirdAppConfig } from './ThirdApp.api';
  import { useModal } from '/@/components/Modal';
  import ThirdAppConfigModal from './ThirdAppConfigModal.vue';
  import { Modal } from 'ant-design-vue';
  import { getTenantId } from '/@/utils/auth';
  import { useMessage } from '/@/hooks/web/useMessage';

  export default defineComponent({
    name: 'OrganDingConfigForm',
    components: {
      ThirdAppConfigModal,
    },
    setup() {
      const { createMessage } = useMessage();
      //折叠面板选中key
      const collapseActiveKey = ref<string>('');
      //按钮加载事件
      const btnLoading = ref<boolean>(false);
      //第三方配置数据
      const appConfigData = ref<any>({
        agentId: undefined,
        clientId: '',
        clientSecret: '',
      });

      //企业微信钉钉配置modal
      const [registerAppConfigModal, { openModal }] = useModal();

      /**
       * 钉钉编辑
       */
      async function dingEditClick() {
        let tenantId = getTenantId();
        openModal(true, {
          tenantId: tenantId,
          thirdType: 'dingtalk',
        });
      }

      /**
       * 初始化第三方数据
       */
      async function initThirdAppConfigData(params) {
        let values = await getThirdConfigByTenantId(params);
        if (values) {
          appConfigData.value = values;
        } else {
          appConfigData.value = "";
        }
      }

      /**
       * 成功回调
       */
      function handleSuccess() {
        let tenantId = getTenantId();
        initThirdAppConfigData({ tenantId: tenantId, thirdType: 'dingtalk' });
      }

      /**
       * 同步钉钉
       */
      async function syncDingTalk() {
        btnLoading.value = true;
        await syncDingTalkDepartUserToLocal()
          .then((res) => {
            let options = {};
            if (res.result) {
              options = {
                width: 600,
                title: res.message,
                content: () => {
                  let nodes;
                  let successInfo = [`成功信息如下:`, renderTextarea(h, res.result.successInfo.map((v, i) => `${i + 1}. ${v}`).join('\n'))];
                  if (res.success) {
                    nodes = [...successInfo, h('br'), `无失败信息!`];
                  } else {
                    nodes = [
                      `失败信息如下:`,
                      renderTextarea(h, res.result.failInfo.map((v, i) => `${i + 1}. ${v}`).join('\n')),
                      h('br'),
                      ...successInfo,
                    ];
                  }
                  return nodes;
                },
              };
            }
            if (res.success) {
              if (options != null) {
                Modal.success(options);
              } else {
                createMessage.warning(res.message);
              }
            } else {
              if (options && options.title) {
                Modal.warning(options)
              } else {
                createMessage.warning({
                  content: res.message || "同步失败,请检查对接信息录入中是否填写正确,并确认是否已开启钉钉配置!",
                  duration: 5
                });
              }
            }
          })
          .finally(() => {
            btnLoading.value = false;
          });
      }

      /**
       * 渲染文本
       * @param h
       * @param value
       */
      function renderTextarea(h, value) {
        return h(
          'div',
          {
            id: 'box',
            style: {
              minHeight: '100px',
              border: '1px solid #d9d9d9',
              fontSize: '14px',
              maxHeight: '250px',
              whiteSpace: 'pre',
              overflow: 'auto',
              padding: '10px',
            },
          },
          value
        );
      }

      /**
       * 钉钉同步文档
       */
      function handleIconClick(){
        window.open("https://help.qiaoqiaoyun.com/expand/dingdingsyn.html","_target")
      }

      /**
       * 取消绑定
       */
      function cancelBindClick() {
        if(!appConfigData.value.id){
          createMessage.warning("请先绑定钉钉应用!");
          return;
        }
        Modal.confirm({
          title: '取消绑定',
          content: '是否要解除当前组织的钉钉应用配置绑定?',
          okText: '确认',
          cancelText: '取消',
          onOk: () => {
            deleteThirdAppConfig({ id: appConfigData.value.id }, handleSuccess);
          },
        });
      }
      
      onMounted(() => {
        let tenantId = getTenantId();
        initThirdAppConfigData({ tenantId: tenantId, thirdType: 'dingtalk' });
      });

      return {
        appConfigData,
        collapseActiveKey,
        registerAppConfigModal,
        dingEditClick,
        handleSuccess,
        syncDingTalk,
        btnLoading,
        handleIconClick,
        cancelBindClick,
      };
    },
  });
</script>

<style lang="less" scoped>
  .header {
    align-items: center;
    box-sizing: border-box;
    display: flex;
    height: 50px;
    justify-content: space-between;
    font-weight: 700;
    font-size: 18px;
    color: @text-color;
  }

  .flex-flow {
    display: flex;
    min-height: 0;
  }

  .sync-padding {
    padding: 12px 0 16px;
    color: @text-color;
  }

  .base-collapse {
    margin-top: 20px;
    padding: 0 24px;
    font-size: 20px;

    .base-desc {
      font-size: 14px;
    }

    .base-title {
      width: 100px;
      text-align: left;
      height: 50px;
      line-height: 50px;
    }

    .base-message {
      width: 100%;
      height: 50px;
      line-height: 50px;
    }

    :deep(.ant-collapse-header) {
      padding: 12px 0 16px;
    }

    :deep(.ant-collapse-content-box) {
      padding-left: 0;
    }
  }
  /*begin 兼容暗夜模式*/
  //暗黑模式下卡片的边框设置成none
  [data-theme='dark'] .base-collapse .ant-collapse{
    border: none !important;
  }
  /*end 兼容暗夜模式*/
  /*文档按钮问号样式*/
  .sync-text{
    margin-left: 2px;
    cursor: pointer;
    position: relative;
    top: 2px
  }
 :deep(.ant-collapse-borderless >.ant-collapse-item:last-child) {border-bottom-width:1px;}
</style>