You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampark.apache.org by be...@apache.org on 2022/11/05 15:42:50 UTC

[incubator-streampark] branch dev updated: [Feature]: Add data desensitization of variables, fix the error problem of giving role menu (#1967)

This is an automated email from the ASF dual-hosted git repository.

benjobs pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampark.git


The following commit(s) were added to refs/heads/dev by this push:
     new 2d204f89e [Feature]: Add data desensitization of variables, fix the error problem of giving role menu (#1967)
2d204f89e is described below

commit 2d204f89e48460cae9d7ebade95a5348d0ede966
Author: Sizhu Wang <12...@qq.com>
AuthorDate: Sat Nov 5 23:42:44 2022 +0800

    [Feature]: Add data desensitization of variables, fix the error problem of giving role menu (#1967)
---
 .../src/api/system/model/variableModel.ts          |  1 +
 .../src/api/system/variable.ts                     |  9 +++
 .../src/components/Description/src/typing.ts       |  1 +
 .../src/views/flink/app/Add.vue                    |  2 +-
 .../src/views/flink/app/EditStreamPark.vue         |  2 +-
 .../flink/app/components/AppView/AppDashboard.vue  |  2 +-
 .../flink/app/components/AppView/LogModal.vue      |  1 -
 .../src/views/flink/app/components/Dependency.vue  | 91 ++++++++++++----------
 .../components/PodTemplate/TemplateButtonGroup.vue |  9 ++-
 .../src/views/flink/app/components/flinkSql.vue    | 23 +++---
 .../src/views/flink/app/styles/Add.less            | 21 +++--
 .../views/flink/project/components/LogModal.vue    |  1 -
 .../views/system/role/components/RoleDrawer.vue    | 11 ++-
 .../system/variable/components/VariableDrawer.vue  | 52 +++++++++----
 .../system/variable/components/VariableInfo.vue    | 64 +++++++++++----
 15 files changed, 189 insertions(+), 101 deletions(-)

diff --git a/streampark-console/streampark-console-newui/src/api/system/model/variableModel.ts b/streampark-console/streampark-console-newui/src/api/system/model/variableModel.ts
index afd85d097..ebd13ab01 100644
--- a/streampark-console/streampark-console-newui/src/api/system/model/variableModel.ts
+++ b/streampark-console/streampark-console-newui/src/api/system/model/variableModel.ts
@@ -24,6 +24,7 @@ export interface VariableListRecord {
   teamId: string;
   createTime: string;
   modifyTime: string;
+  desensitization: boolean;
   sortField?: string;
   sortOrder?: string;
 }
diff --git a/streampark-console/streampark-console-newui/src/api/system/variable.ts b/streampark-console/streampark-console-newui/src/api/system/variable.ts
index 04d74a2da..fc4426bb0 100644
--- a/streampark-console/streampark-console-newui/src/api/system/variable.ts
+++ b/streampark-console/streampark-console-newui/src/api/system/variable.ts
@@ -29,6 +29,7 @@ enum VARIABLE_API {
   SELECT = '/variable/select',
   CHECK_CODE = '/variable/check/code',
   LIST = '/variable/list',
+  SHOWORIGIN = '/variable/showOriginal',
 }
 /**
  * get variable list
@@ -99,3 +100,11 @@ export function fetchVariableContent(data: Recordable): Promise<any> {
 export function fetchVariableAll(data?: { keyword: string }): Promise<VariableListRecord[]> {
   return defHttp.post({ url: VARIABLE_API.LIST, data });
 }
+
+/**
+ * get variable info
+ * @returns {Promise<any>}
+ */
+export function fetchVariableInfo(data?: { id: string }): Promise<VariableListRecord> {
+  return defHttp.post({ url: VARIABLE_API.SHOWORIGIN, data });
+}
diff --git a/streampark-console/streampark-console-newui/src/components/Description/src/typing.ts b/streampark-console/streampark-console-newui/src/components/Description/src/typing.ts
index b7d3d7793..7f0406112 100644
--- a/streampark-console/streampark-console-newui/src/components/Description/src/typing.ts
+++ b/streampark-console/streampark-console-newui/src/components/Description/src/typing.ts
@@ -26,6 +26,7 @@ export interface DescItem {
   label: string | VNode | JSX.Element;
   // Merge column
   span?: number;
+  slot?: string;
   show?: (...arg: any) => boolean;
   // render
   render?: (
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/Add.vue b/streampark-console/streampark-console-newui/src/views/flink/app/Add.vue
index 97f058ba9..c49525752 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/Add.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/Add.vue
@@ -45,7 +45,7 @@
   import { CreateParams } from '/@/api/flink/app/app.type';
   import { decodeByBase64, encryptByBase64 } from '/@/utils/cipher';
 
-  const FlinkSqlEditor = createAsyncComponent(() => import('./components/flinkSql.vue'), {
+  const FlinkSqlEditor = createAsyncComponent(() => import('./components/FlinkSql.vue'), {
     loading: true,
   });
   const Dependency = createAsyncComponent(() => import('./components/Dependency.vue'), {
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/EditStreamPark.vue b/streampark-console/streampark-console-newui/src/views/flink/app/EditStreamPark.vue
index 9d5772010..4e407b5a8 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/EditStreamPark.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/EditStreamPark.vue
@@ -32,7 +32,7 @@
   import { decodeByBase64, encryptByBase64 } from '/@/utils/cipher';
   import PomTemplateTab from './components/PodTemplate/PomTemplateTab.vue';
   import UploadJobJar from './components/UploadJobJar.vue';
-  import FlinkSqlEditor from './components/flinkSql.vue';
+  import FlinkSqlEditor from './components/FlinkSql.vue';
   import Dependency from './components/Dependency.vue';
   import Different from './components/AppDetail/Different.vue';
   import Mergely from './components/Mergely.vue';
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/AppDashboard.vue b/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/AppDashboard.vue
index 73b825da2..d3a4b4d79 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/AppDashboard.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/AppDashboard.vue
@@ -18,7 +18,7 @@
 <script lang="ts" setup>
   import { onMounted, reactive, ref } from 'vue';
   import { fetchDashboard } from '/@/api/flink/app/app';
-  import StatisticCard from './statisticCard.vue';
+  import StatisticCard from './StatisticCard.vue';
   import { Row, Col } from 'ant-design-vue';
   const dashBigScreenMap = reactive<Recordable>({});
   const dashboardLoading = ref(true);
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue b/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue
index 9f82058c2..c759c1491 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue
@@ -87,7 +87,6 @@
 <template>
   <BasicModal
     canFullscreen
-    defaultFullscreen
     :scrollTop="false"
     @register="registerModal"
     width="80%"
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/components/Dependency.vue b/streampark-console/streampark-console-newui/src/views/flink/app/components/Dependency.vue
index b45af62fb..cfe83b0a2 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/components/Dependency.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/components/Dependency.vue
@@ -263,9 +263,6 @@
   <Tabs type="card" v-model:activeKey="activeTab" class="pom-card">
     <TabPane key="pom" tab="Maven pom">
       <div ref="pomBox" class="pom-box syntax-true" style="height: 300px"></div>
-      <a-button type="primary" class="apply-pom" @click="handleApplyPom()">
-        {{ t('common.apply') }}
-      </a-button>
     </TabPane>
     <TabPane key="jar" tab="Upload Jar">
       <template v-if="isK8sExecMode(formModel?.executionMode)">
@@ -288,45 +285,55 @@
       <UploadJobJar :custom-request="handleCustomDepsRequest" v-model:loading="loading" />
     </TabPane>
   </Tabs>
-  <div class="dependency-box" v-if="dependencyRecords.length > 0 || uploadJars.length > 0">
-    <Alert
-      class="dependency-item"
-      v-for="(value, index) in dependencyRecords"
-      :key="`dependency_${index}`"
-      type="info"
-      @click="handleEditPom(value)"
+  <div class="flex justify-end">
+    <div class="dependency-box" v-if="dependencyRecords.length > 0 || uploadJars.length > 0">
+      <Alert
+        class="dependency-item"
+        v-for="(value, index) in dependencyRecords"
+        :key="`dependency_${index}`"
+        type="info"
+        @click="handleEditPom(value)"
+      >
+        <template #message>
+          <Space @click="handleEditPom(value)" class="tag-dependency-pom">
+            <Tag class="tag-dependency" color="#2db7f5">POM</Tag>
+            {{ value.artifactId }}-{{ value.version }}.jar
+            <Icon
+              :size="12"
+              icon="ant-design:close-outlined"
+              class="icon-close cursor-pointer"
+              @click.stop="handleRemovePom(value)"
+            />
+          </Space>
+        </template>
+      </Alert>
+      <Alert
+        class="dependency-item"
+        v-for="(value, index) in uploadJars"
+        :key="`upload_jars_${index}`"
+        type="info"
+      >
+        <template #message>
+          <Space>
+            <Tag class="tag-dependency" color="#108ee9">JAR</Tag>
+            {{ value }}
+            <Icon
+              icon="ant-design:close-outlined"
+              class="icon-close cursor-pointer"
+              :size="12"
+              @click="handleRemoveJar(value)"
+            />
+          </Space>
+        </template>
+      </Alert>
+    </div>
+    <a-button
+      type="primary"
+      class="apply-pom"
+      @click="handleApplyPom()"
+      v-show="activeTab == 'pom'"
     >
-      <template #message>
-        <Space @click="handleEditPom(value)" class="tag-dependency-pom">
-          <Tag class="tag-dependency" color="#2db7f5">POM</Tag>
-          {{ value.artifactId }}-{{ value.version }}.jar
-          <Icon
-            :size="12"
-            icon="ant-design:close-outlined"
-            class="icon-close cursor-pointer"
-            @click.stop="handleRemovePom(value)"
-          />
-        </Space>
-      </template>
-    </Alert>
-    <Alert
-      class="dependency-item"
-      v-for="(value, index) in uploadJars"
-      :key="`upload_jars_${index}`"
-      type="info"
-    >
-      <template #message>
-        <Space>
-          <Tag class="tag-dependency" color="#108ee9">JAR</Tag>
-          {{ value }}
-          <Icon
-            icon="ant-design:close-outlined"
-            class="icon-close cursor-pointer"
-            :size="12"
-            @click="handleRemoveJar(value)"
-          />
-        </Space>
-      </template>
-    </Alert>
+      {{ t('common.apply') }}
+    </a-button>
   </div>
 </template>
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/components/PodTemplate/TemplateButtonGroup.vue b/streampark-console/streampark-console-newui/src/views/flink/app/components/PodTemplate/TemplateButtonGroup.vue
index f69323821..547f87b69 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/components/PodTemplate/TemplateButtonGroup.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/components/PodTemplate/TemplateButtonGroup.vue
@@ -39,6 +39,7 @@
   <ButtonGroup class="pod-template-tool">
     <a-button
       type="primary"
+      size="small"
       class="pod-template-tool-item"
       @click="emit('clickHistory', visualType)"
     >
@@ -47,7 +48,12 @@
         {{ t('common.history') }}
       </div>
     </a-button>
-    <a-button type="default" class="pod-template-tool-item" @click="emit('clickInit', visualType)">
+    <a-button
+      type="default"
+      size="small"
+      class="pod-template-tool-item"
+      @click="emit('clickInit', visualType)"
+    >
       <div class="flex items-center">
         <Icon icon="ant-design:copy-outlined" class="pr-5px" />
         {{ t('flink.app.pod.init') }}
@@ -55,6 +61,7 @@
     </a-button>
     <a-button
       type="default"
+      size="small"
       class="pod-template-tool-item"
       @click="emit('clickHostAlias', visualType)"
     >
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/components/flinkSql.vue b/streampark-console/streampark-console-newui/src/views/flink/app/components/flinkSql.vue
index e0162eedc..5b11877fc 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/components/flinkSql.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/components/flinkSql.vue
@@ -177,20 +177,30 @@
 <template>
   <div>
     <div ref="flinkScreen">
+      <div
+        class="sql-box"
+        ref="flinkSql"
+        :class="'syntax-' + (vertifyRes.errorMsg ? 'false' : 'true')"
+      ></div>
       <ButtonGroup class="flinksql-tool">
-        <a-button class="flinksql-tool-item" v-if="canPreview" @click="emit('preview', value)">
+        <a-button
+          class="flinksql-tool-item"
+          size="small"
+          v-if="canPreview"
+          @click="emit('preview', value)"
+        >
           <Icon icon="ant-design:eye-outlined" />
           preview
         </a-button>
-        <a-button class="flinksql-tool-item" type="primary" @click="handleVerifySql">
+        <a-button size="small" class="flinksql-tool-item" type="primary" @click="handleVerifySql">
           <Icon icon="ant-design:check-outlined" />
           {{ t('flink.app.flinkSql.verify') }}
         </a-button>
-        <a-button class="flinksql-tool-item" type="default" @click="handleFormatSql">
+        <a-button class="flinksql-tool-item" size="small" type="default" @click="handleFormatSql">
           <Icon icon="ant-design:thunderbolt-outlined" />
           {{ t('flink.app.flinkSql.format') }}
         </a-button>
-        <a-button class="flinksql-tool-item" type="default" @click="handleBigScreen">
+        <a-button class="flinksql-tool-item" size="small" type="default" @click="handleBigScreen">
           <Icon
             :icon="
               isFullscreen
@@ -202,11 +212,6 @@
           {{ t('flink.app.flinkSql.fullScreen') }}
         </a-button>
       </ButtonGroup>
-      <div
-        class="sql-box"
-        ref="flinkSql"
-        :class="'syntax-' + (vertifyRes.errorMsg ? 'false' : 'true')"
-      ></div>
       <p class="conf-desc mt-10px">
         <span class="text-red-600" v-if="vertifyRes.errorMsg"> {{ vertifyRes.errorMsg }} </span>
         <span v-else class="text-green-700">
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/styles/Add.less b/streampark-console/streampark-console-newui/src/views/flink/app/styles/Add.less
index f8a37c854..40ad231bf 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/styles/Add.less
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/styles/Add.less
@@ -105,9 +105,11 @@
   }
 }
 
+.pod-template-tool,
 .flinksql-tool {
   z-index: 99;
   cursor: pointer;
+  margin-top: 5px;
 }
 
 .flinksql-tool-item {
@@ -116,11 +118,6 @@
   align-items: center;
 }
 
-.pod-template-tool {
-  z-index: 99;
-  cursor: pointer;
-}
-
 .pod-template-tool-item {
   font-size: 13px;
 }
@@ -166,7 +163,14 @@
     color: #1890ff;
   }
 
-  .apply-pom,
+  .apply-pom {
+    margin-top: 17px;
+    cursor: pointer;
+    height: 26px;
+    padding: 0 12px;
+    font-size: 12px;
+  }
+
   .apply-testing,
   .verify-sql {
     z-index: 99;
@@ -189,13 +193,14 @@
   }
 
   .dependency-box {
+    flex: 1;
+    margin-right: 10px;
     margin-top: 15px;
-    width: 100%;
+    margin-bottom: -10px;
     border-radius: 5px;
     background-color: #e6f7ff;
     border: 1px solid #d9d9d9;
     display: inline-block;
-    margin-bottom: -25px;
 
     .dependency-item {
       position: relative;
diff --git a/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue b/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue
index 037aca9f9..3784165ff 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue
@@ -94,7 +94,6 @@
 <template>
   <BasicModal
     canFullscreen
-    defaultFullscreen
     :scrollTop="false"
     @register="registerModal"
     width="80%"
diff --git a/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue b/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue
index d2c12c9ac..984033493 100644
--- a/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue
+++ b/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue
@@ -31,6 +31,7 @@
           :treeData="treeData"
           :fieldNames="{ title: 'text', key: 'id' }"
           v-if="treeData.length > 0"
+          @check="handleTreeCheck"
           checkable
           toolbar
           title="menu assignment"
@@ -68,6 +69,7 @@
       const formType = ref(FormTypeEnum.Edit);
       const treeData = ref<TreeItem[]>([]);
       let singleNodeKeys: string[] = [];
+      let selectedKeysAndHalfCheckedKeys = ref<string[]>([]);
       const isCreate = computed(() => unref(formType) === FormTypeEnum.Create);
 
       const formSchemas = computed((): FormSchema[] => {
@@ -126,7 +128,7 @@
         }
         if (!unref(isCreate)) {
           const res = await getRoleMenu({ roleId: data.record.roleId });
-          data.record.menuId = res || [];
+          selectedKeysAndHalfCheckedKeys.value = res || [];
           const result = [...new Set(singleNodeKeys)].filter((item) => new Set(res).has(item));
           nextTick(() => {
             setFieldsValue({
@@ -152,7 +154,7 @@
           const values = await validate();
           setDrawerProps({ confirmLoading: true });
           const params = { ...values };
-          params.menuId = values.menuId.join(',');
+          params.menuId = selectedKeysAndHalfCheckedKeys.value.join(',');
           !unref(isCreate) ? await fetchRoleUpdate(params) : await fetchRoleCreate(params);
           closeDrawer();
           emit('success');
@@ -162,7 +164,9 @@
           setDrawerProps({ confirmLoading: false });
         }
       }
-
+      function handleTreeCheck(checkedKeys: string[], e: any) {
+        selectedKeysAndHalfCheckedKeys.value = [...checkedKeys, ...e.halfCheckedKeys];
+      }
       return {
         formSchemas,
         registerDrawer,
@@ -170,6 +174,7 @@
         getTitle,
         handleSubmit,
         treeData,
+        handleTreeCheck,
       };
     },
   });
diff --git a/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableDrawer.vue b/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableDrawer.vue
index 73333cbfa..4c3080ddc 100644
--- a/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableDrawer.vue
+++ b/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableDrawer.vue
@@ -30,7 +30,7 @@
 </script>
 
 <script lang="ts" setup>
-  import { ref, computed, unref } from 'vue';
+  import { ref, h, computed, unref, reactive } from 'vue';
   import { BasicForm, FormSchema, useForm } from '/@/components/Form';
   import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
   import { Icon } from '/@/components/Icon';
@@ -40,8 +40,9 @@
     fetchAddVariable,
     fetchCheckVariableCode,
     fetchUpdateVariable,
+    fetchVariableInfo,
   } from '/@/api/system/variable';
-  import { h } from 'vue';
+  import { VariableListRecord } from '/@/api/system/model/variableModel';
 
   const emit = defineEmits(['success', 'register']);
 
@@ -50,6 +51,7 @@
   const isUpdate = ref(false);
   const { getItemProp, setValidateStatus, setHelp } = useFormValidate();
   const variableId = ref<Nullable<number>>(null);
+  const variableInfo = reactive<Partial<VariableListRecord>>({});
 
   async function handleVariableCodeBlur(e) {
     const value = (e && e.target.value) || '';
@@ -124,8 +126,12 @@
           unCheckedChildren: 'OFF',
         },
         defaultValue: false,
-        afterItem: h('span', { class: 'conf-switch' }, 'Whether desensitization is required, e.g: desensitization of sensitive data such as passwords, if enable variable value will be displayed as ********'),
-      }
+        afterItem: h(
+          'span',
+          { class: 'conf-switch' },
+          'Whether desensitization is required, e.g: desensitization of sensitive data such as passwords, if enable variable value will be displayed as ********',
+        ),
+      },
     ];
   });
 
@@ -138,19 +144,33 @@
     wrapperCol: { lg: { span: 16, offset: 0 }, sm: { span: 17, offset: 0 } },
   });
 
-  const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(
+  const [registerDrawer, { setDrawerProps, changeLoading, closeDrawer }] = useDrawerInner(
     async (data: Recordable) => {
-      variableId.value = null;
-      resetFields();
-      setValidateStatus('');
-      setHelp('');
-      setDrawerProps({ confirmLoading: false });
-      isUpdate.value = !!data?.isUpdate;
-      if (isUpdate.value) variableId.value = data.record.id;
-      if (unref(isUpdate)) {
-        setFieldsValue({
-          ...data.record,
-        });
+      try {
+        variableId.value = null;
+        resetFields();
+        setValidateStatus('');
+        setHelp('');
+        setDrawerProps({ confirmLoading: false });
+        isUpdate.value = !!data?.isUpdate;
+        if (unref(isUpdate)) {
+          // is desensitization variable
+          if (data.record.desensitization) {
+            changeLoading(true);
+            const res = await fetchVariableInfo({
+              id: data.record.id,
+            });
+            Object.assign(variableInfo, res);
+            changeLoading(false);
+          } else {
+            Object.assign(variableInfo, data.record);
+          }
+
+          variableId.value = data.record.id;
+          setFieldsValue(variableInfo);
+        }
+      } catch (error) {
+        changeLoading(false);
       }
     },
   );
diff --git a/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableInfo.vue b/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableInfo.vue
index c3525b673..f2eb3652c 100644
--- a/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableInfo.vue
+++ b/streampark-console/streampark-console-newui/src/views/system/variable/components/VariableInfo.vue
@@ -20,19 +20,13 @@
     @register="registerDrawer"
     showFooter
     width="40%"
-    @ok="handleSubmit"
+    @ok="closeDrawer"
   >
     <template #title>
       <Icon icon="ant-design:code-outlined" />
       Variable Info
     </template>
-    <Description
-      class="variable-desc"
-      @register="registerDescription"
-      :column="1"
-      :data="variableInfo"
-      :schema="roleColumn"
-    />
+    <Description class="variable-desc" :column="1" :data="variableInfo" :schema="roleColumn" />
   </BasicDrawer>
 </template>
 <script lang="ts">
@@ -43,24 +37,45 @@
 
 <script setup lang="ts">
   import { defineComponent, h, ref } from 'vue';
-  import { useDescription, Description } from '/@/components/Description';
+  import { Description, DescItem } from '/@/components/Description';
   import Icon from '/@/components/Icon';
   import { useDrawerInner, BasicDrawer } from '/@/components/Drawer';
+  import { fetchVariableInfo } from '/@/api/system/variable';
+  import { usePermission } from '/@/hooks/web/usePermission';
 
   const variableInfo = ref<Recordable>({});
-
+  const showVariableDetail = ref(false);
+  let realVariable = '';
+  let desenVariable = '';
   const [registerDrawer, { closeDrawer }] = useDrawerInner((data: Recordable) => {
     data && onReceiveModalData(data);
   });
 
-  async function onReceiveModalData(data) {
+  function onReceiveModalData(data) {
+    realVariable = '';
     variableInfo.value = Object.assign({}, data);
+    showVariableDetail.value = false;
+    desenVariable = data.variableValue;
   }
+  async function handleVariableDetail() {
+    if (!realVariable) {
+      const res = await fetchVariableInfo({
+        id: variableInfo.value.id,
+      });
+      realVariable = res.variableValue;
+    }
 
+    Object.assign(variableInfo.value, {
+      variableValue: showVariableDetail.value ? desenVariable : realVariable,
+    });
+    showVariableDetail.value = !showVariableDetail.value;
+  }
+  // generated label
   const generatedLabelIcon = (icon: string, label: string) => {
     return h('div', null, [h(Icon, { icon }), h('span', { class: 'px-5px' }, label)]);
   };
-  const roleColumn = [
+  const { hasPermission } = usePermission();
+  const roleColumn: DescItem[] = [
     {
       label: generatedLabelIcon('ant-design:code-outlined', 'Variable Code'),
       field: 'variableCode',
@@ -68,6 +83,25 @@
     {
       label: generatedLabelIcon('ant-design:down-circle-outlined', 'Variable Value'),
       field: 'variableValue',
+      render(value, data) {
+        const renderIcon = () => {
+          // need desensitization
+          if (data.desensitization && hasPermission('variable:showOriginal')) {
+            return h(Icon, {
+              icon: `ant-design:${showVariableDetail.value ? 'eye' : 'eye-invisible'}-outlined`,
+              color: showVariableDetail.value ? '#477de9' : '',
+              onClick: handleVariableDetail,
+              class: 'cursor-pointer',
+            });
+          } else {
+            return null;
+          }
+        };
+        return h('div', { class: 'flex items-center' }, [
+          h('span', { class: 'pr-10px' }, value),
+          renderIcon(),
+        ]);
+      },
     },
     {
       label: generatedLabelIcon(`ant-design:user-outlined`, 'Create User'),
@@ -86,15 +120,11 @@
       field: 'description',
     },
   ];
-  const [registerDescription] = useDescription();
-  function handleSubmit() {
-    closeDrawer();
-  }
 </script>
 <style lang="less">
   .variable-desc {
     .ant-descriptions-item-label {
-      min-width: 160px;
+      width: 160px;
     }
   }
 </style>