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

xxyu pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git


The following commit(s) were added to refs/heads/kylin5 by this push:
     new 1e1cd474b3 KYLIN-5309 exclude columns frontend
1e1cd474b3 is described below

commit 1e1cd474b34ed24367b374c7204d8a6df535d4eb
Author: Qian Xia <lauraxiaq...@gmail.com>
AuthorDate: Thu Jan 19 21:48:23 2023 +0800

    KYLIN-5309 exclude columns frontend
---
 .../EditExcludeColumnsDialog.vue                   | 332 +++++++++++++++++++++
 .../common/EditExcludeColumnsDialog/locales.js     |  32 ++
 .../common/EditExcludeColumnsDialog/store.js       |  47 +++
 .../setting/SettingBasic/SettingBasic.vue          | 198 +++++++++---
 .../src/components/setting/SettingBasic/handler.js |   6 +
 .../src/components/setting/SettingBasic/locales.js |  16 +-
 .../StudioModel/ModelList/AggregateModal/index.vue |  13 +-
 .../ModelList/AggregateModal/locales.js            |   2 +-
 .../studio/StudioModel/TableIndexEdit/locales.js   |   2 +-
 .../StudioModel/TableIndexEdit/tableindex_edit.vue |  19 +-
 .../StudioSource/TableColumns/TableColumns.vue     |  12 +
 .../studio/StudioSource/TableColumns/locales.js    |   4 +-
 kystudio/src/config/index.js                       |   4 +-
 kystudio/src/locale/en.js                          |   1 +
 kystudio/src/service/project.js                    |  12 +
 kystudio/src/store/project.js                      |  17 ++
 kystudio/src/store/types.js                        |   5 +
 17 files changed, 658 insertions(+), 64 deletions(-)

diff --git 
a/kystudio/src/components/common/EditExcludeColumnsDialog/EditExcludeColumnsDialog.vue
 
b/kystudio/src/components/common/EditExcludeColumnsDialog/EditExcludeColumnsDialog.vue
new file mode 100644
index 0000000000..7f96397026
--- /dev/null
+++ 
b/kystudio/src/components/common/EditExcludeColumnsDialog/EditExcludeColumnsDialog.vue
@@ -0,0 +1,332 @@
+<template>
+  <el-dialog class="edit-exclude-column-dialog"
+    width="800px"
+    :title="$t(excludeColumntitle)"
+    :visible="isShow"
+    :close-on-press-escape="false"
+    :close-on-click-modal="false"
+    @close="handleClose">
+    <div class="ksd-mb-16" v-html="$t('excludeDesc')"></div>
+    <div class="ksd-title-label-mini ksd-mb-8">{{$t('selectTable')}}</div>
+    <el-select
+      class="exclude_rule-select ksd-mb-16"
+      v-model="excluded_table"
+      @change="getExcludeColumns"
+      filterable
+      :disabled="!!excludeTable"
+      remote
+      :remote-method="filterExcludeTables"
+      :placeholder="$t('kylinLang.common.pleaseSelectOrSearch')"
+      style="width: 100%"
+      :loading="loading">
+      <el-option
+        v-for="item in excludeRuleOptions"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value">
+        <span>{{item.label}}<i v-if="item.fact" class="el-icon-ksd-fact_table 
ksd-ml-5"></i></span>
+      </el-option>
+      <p class="limit-excluded-tables-msg" 
v-if="showIimitExcludedTableMsg">{{$t('limitExcludedTablesTip')}}</p>
+    </el-select>
+    <div class="ksd-title-label-mini columns-header ksd-mb-8">
+      <span>{{$t('selectColumns')}}</span>
+      <el-input
+        class="filter-input"
+        prefix-icon="el-ksd-icon-search_22"
+        size="small"
+        v-model="filterText"
+        @input="filterChange"
+        :placeholder="$t('filterByColumns')">
+      </el-input>
+    </div>
+    <el-table
+      :data="columns"
+      :empty-text="emptyText"
+      class="column-table"
+      @selection-change="handleSelectionChange"
+      style="width: 100%">
+      <el-table-column type="selection" align="center" 
width="42"></el-table-column>
+      <el-table-column
+        type="index"
+        label="ID"
+        width="64"
+        show-overflow-tooltip
+        :index="startIndex">
+      </el-table-column>
+      <el-table-column
+        prop="name"
+        min-width="300"
+        show-overflow-tooltip
+        :label="$t('kylinLang.dataSource.columnName')">
+      </el-table-column>
+      <el-table-column
+        prop="datatype"
+        min-width="120"
+        show-overflow-tooltip
+        :label="$t('kylinLang.dataSource.dataType')">
+      </el-table-column>
+      <el-table-column
+        prop="comment"
+        min-width="100"
+        show-overflow-tooltip
+        :render-header="renderCommentHeader">
+        <template slot-scope="scope">
+          <span :title="scope.row.comment">{{scope.row.comment}}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <kap-pager
+      class="ksd-center ksd-mt-16" ref="columnPager"
+      :refTag="pageRefTags.exclusionColumnsPager"
+      :totalSize="columnsTotalSize"
+      :curPage="pagination.page_offset + 1"
+      :perPageSize="pagination.page_size"
+      @handleCurrentChange="handleCurrentChange">
+    </kap-pager>
+    <div slot="footer" class="dialog-footer">
+      <el-popover
+        ref="popover"
+        placement="top"
+        width="200"
+        v-model="confirmSubmitVisible"
+        trigger="click">
+        <div class="popover-title">
+          <el-icon name="el-ksd-n-icon-warning-color-filled" class="ksd-fs-16" 
type="mult"></el-icon><span class="ksd-title-label-mini">{{isDelExcludeMode ? 
$t('delAllColumnTitle') : $t('addAllColumnTitle')}}</span>
+        </div>
+        <div class="ksd-center ksd-mt-16">
+          <el-button style="width: 96px" size="small" 
@click="confirmSubmitVisible = 
false">{{$t('kylinLang.common.cancel')}}</el-button><el-button
+          type="primary" size="small" style="width: 96px" 
@click="confirmSubmit">{{$t('kylinLang.common.ok')}}</el-button>
+        </div>
+      </el-popover>
+
+      <el-button type="primary" text v-popover:popover 
v-show="columnsTotalSize&&!loadingSubmit">{{isDelExcludeMode ? 
$t('delAllColumnBtn') : $t('addAllColumnBtn')}}</el-button>
+      <el-button size="medium" 
@click="handleClose">{{$t('kylinLang.common.cancel')}}</el-button>
+      <el-button type="primary" size="medium" :loading="loadingSubmit" 
:disabled="!selectCols.length" @click="submit(false)">{{isDelExcludeMode ? 
$t('kylinLang.common.delete') : $t('kylinLang.common.add')}}</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import Vue from 'vue'
+import { Component, Watch } from 'vue-property-decorator'
+import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
+import { handleError, handleSuccessAsync, ArrayFlat } from 'util'
+import { pageRefTags, pageCount } from 'config'
+
+import store from './store'
+import locales from './locales'
+import vuex, { actionTypes } from '../../../store'
+
+vuex.registerModule(['modals', 'ExcludeColumnsDialog'], store)
+
+@Component({
+  computed: {
+    ...mapGetters([
+      'currentSelectedProject'
+    ]),
+    ...mapState('ExcludeColumnsDialog', {
+      isShow: state => state.isShow,
+      excludeTable: state => state.excludeTable,
+      excludeColumntitle: state => state.excludeColumntitle,
+      callback: state => state.callback
+    })
+  },
+  methods: {
+    ...mapActions({
+      fetchDBandTables: 'FETCH_DB_AND_TABLES',
+      loadExcludeColumns: 'LOAD_EXCLUDE_COLUMNS',
+      updateExcludeColumns: 'UPDATE_EXCLUDE_CLUMNS'
+    }),
+    ...mapMutations('ExcludeColumnsDialog', {
+      setModalForm: actionTypes.SET_MODAL_FORM,
+      setModal: actionTypes.SET_MODAL,
+      hideModal: actionTypes.HIDE_MODAL,
+      initModal: actionTypes.INIT_MODAL
+    })
+  },
+  locales
+})
+export default class ExcludeColumnsDialog extends Vue {
+  pageRefTags = pageRefTags
+  loadingSubmit = false
+  excludeRuleOptions = []
+  showIimitExcludedTableMsg = false
+  filterExcludeTablesTimer = null
+  dbInfoFilter = {
+    project_name: '',
+    source_type: 9,
+    page_offset: 0,
+    page_size: 10,
+    table: ''
+  }
+  excluded_table = ''
+  loading = false
+  pagination = {
+    page_offset: 0,
+    page_size: +localStorage.getItem(this.pageRefTags.exclusionColumnsPager) 
|| pageCount
+  }
+  filterText = ''
+  columns = []
+  columnsTotalSize = 0
+  confirmSubmitVisible = false
+  selectCols = []
+
+  get startIndex () {
+    const { page_offset, page_size } = this.pagination
+    return page_offset * page_size + 1
+  }
+
+  get emptyText () {
+    return this.filterText ? this.$t('kylinLang.common.noResults') : 
this.$t('kylinLang.common.noData')
+  }
+
+  filterChange () {
+    this.pagination.page_offset = 0
+    this.getExcludeColumns(this.excluded_table)
+  }
+
+  reset () {
+    this.loadingSubmit = false
+    this.excludeRuleOptions = []
+    this.showIimitExcludedTableMsg = false
+    this.excluded_table = ''
+    this.filterText = ''
+    this.columns = []
+    this.columnsTotalSize = 0
+    this.confirmSubmitVisible = false
+    this.selectCols = []
+  }
+
+  handleClose (isSubmit = false) {
+    this.reset()
+    this.hideModal()
+    this.callback && this.callback(isSubmit)
+  }
+
+  handleSelectionChange (cols) {
+    this.selectCols = cols
+  }
+
+  async submit (isExcludedAll) {
+    try {
+      this.loadingSubmit = true
+      const data = {
+        project: this.currentSelectedProject,
+        canceled_tables: !!isExcludedAll && this.isDelExcludeMode ? 
[this.excluded_table] : [],
+        excluded_tables: [
+          {
+            table: this.excluded_table,
+            excluded: !!isExcludedAll && !this.isDelExcludeMode,
+            added_columns: !isExcludedAll && !this.isDelExcludeMode ? 
this.selectCols.map((c) => {
+              return c.name
+            }) : [],
+            removed_columns: !isExcludedAll && this.isDelExcludeMode ? 
this.selectCols.map((c) => {
+              return c.name
+            }) : []
+          }
+        ]
+      }
+      await this.updateExcludeColumns(data)
+      this.callback && this.callback(true)
+      this.hideModal()
+    } catch (e) {
+      this.loadingSubmit = false
+      handleError(e)
+    }
+  }
+  confirmSubmit () {
+    this.confirmSubmitVisible = false
+    this.submit(true)
+  }
+
+  get isDelExcludeMode () {
+    return this.excludeColumntitle === 'delExcludeColumns'
+  }
+
+  async getExcludeColumns (val) {
+    try {
+      if (!val) return
+      // excluded_col_type 展示的屏蔽列类型,可选,默认值 0代表待屏蔽列,1代表屏蔽列,其他值无效
+      const res = await this.loadExcludeColumns({ ...this.pagination, project: 
this.currentSelectedProject, table: val, key: this.filterText, col_type: 
this.isDelExcludeMode ? 1 : 0 })
+      const { admitted_columns, excluded_columns, total_size } = await 
handleSuccessAsync(res)
+      this.columns = this.isDelExcludeMode ? excluded_columns : 
admitted_columns
+      this.columnsTotalSize = total_size
+    } catch (e) {
+      handleError(e)
+    }
+  }
+
+  handleCurrentChange (page_offset, pageSize) {
+    this.pagination.page_offset = page_offset
+    this.pagination.page_size = pageSize
+    this.getExcludeColumns(this.excluded_table)
+  }
+
+  renderCommentHeader (h, { column, $index }) {
+    return (<span class="ky-hover-icon" onClick={e => (e.stopPropagation())}>
+      <span>{this.$t('kylinLang.dataSource.comment')}</span>&nbsp;
+      <common-tip placement="top" content={this.$t('commentTip')}>
+        <span class='el-ksd-icon-more_info_22 ksd-fs-22'></span>
+      </common-tip>
+    </span>)
+  }
+
+  // 获取 database 和 tables 信息(显示前 50 条记录)
+  async getDbAndTablesInfo () {
+    try {
+      this.dbInfoFilter.project_name = this.currentSelectedProject
+      const response = await this.fetchDBandTables(this.dbInfoFilter)
+      const results = await handleSuccessAsync(response)
+      const { databases } = results
+      let dbList = databases ? ArrayFlat(databases.map(item => item.tables)) : 
[]
+      if (dbList.length) {
+        this.excludeRuleOptions = dbList.map(it => ({label: 
`${it.database}.${it.name}`, value: `${it.database}.${it.name}`, fact: 
it.root_fact})).slice(0, 50)
+        this.showIimitExcludedTableMsg = dbList.length > 50
+      }
+    } catch (e) {
+      handleError(e)
+    }
+  }
+
+  // 过滤 db 或 table
+  filterExcludeTables (name) {
+    clearTimeout(this.filterExcludeTablesTimer)
+    this.filterExcludeTablesTimer = setTimeout(() => {
+      this.dbInfoFilter.table = name
+      this.getDbAndTablesInfo()
+    }, 500)
+  }
+
+  @Watch('isShow')
+  onModalShow (val) {
+    if (val) {
+      // 新增一张表的屏蔽列时,要拉取数据源表数据
+      if (this.excludeColumntitle === 'addExcludeColumns') {
+        this.getDbAndTablesInfo()
+      }
+      if (this.excludeTable) {
+        this.excluded_table = this.excludeTable
+        this.getExcludeColumns(this.excluded_table)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less">
+@import '../../../assets/styles/variables.less';
+.edit-exclude-column-dialog {
+  .el-dialog__body {
+    padding: 20px;
+    .columns-header span{
+      display: inline-block;
+      height: 30px;
+      line-height: 30px;
+    }
+    .filter-input {
+      width: 210px;
+      float: right;
+    }
+  }
+}
+</style>
diff --git a/kystudio/src/components/common/EditExcludeColumnsDialog/locales.js 
b/kystudio/src/components/common/EditExcludeColumnsDialog/locales.js
new file mode 100644
index 0000000000..95f17021ed
--- /dev/null
+++ b/kystudio/src/components/common/EditExcludeColumnsDialog/locales.js
@@ -0,0 +1,32 @@
+export default {
+  en: {
+    addExcludeColumns: 'Add Exclude Columns',
+    appendExcludeColumns: 'Append Exclude Columns',
+    delExcludeColumns: 'Delete Exclude Columns',
+    limitExcludedTablesTip: 'Only 50 tables would be displayed. Please enter 
keyword to search.',
+    selectTable: 'Select Table',
+    selectColumns: 'Select Columns',
+    filterByColumns: 'Search by column name',
+    delAllColumnTitle: 'Are you sure you want to delete all exclude columns?',
+    addAllColumnTitle: 'Are you sure you want to exclude all columns?',
+    delAllColumnBtn: 'Delete all columns',
+    addAllColumnBtn: 'Add all columns',
+    commentTip: 'Synced from the source table.',
+    excludeDesc: 'Please pay attention that excluded column can only be set to 
lookup table,in order to solve SCD problems.<br/>If you want to exclude a whole 
table,you can exclude all columns of the table.'
+  },
+  'zh-cn': {
+    addExcludeColumns: '添加屏蔽列',
+    appendExcludeColumns: '增加屏蔽列',
+    delExcludeColumns: '删除屏蔽列',
+    limitExcludedTablesTip: '默认仅展示 50 张表。请输入关键词进行搜索。',
+    selectTable: '选择表',
+    selectColumns: '选择列',
+    filterByColumns: '搜索列名',
+    delAllColumnTitle: '确定要删除所有屏蔽列?',
+    addAllColumnTitle: '确定要屏蔽所有列?',
+    delAllColumnBtn: '删除所有屏蔽列',
+    addAllColumnBtn: '屏蔽所有列',
+    commentTip: '从数据源中同步的注释信息。',
+    excludeDesc: '请注意屏蔽列仅用于维度表,用于解决缓慢变化维的问题。<br/> 
如果您想使用旧版本的“屏蔽表”功能,在当前版本等同于屏蔽一张表中所有的列。'
+  }
+}
diff --git a/kystudio/src/components/common/EditExcludeColumnsDialog/store.js 
b/kystudio/src/components/common/EditExcludeColumnsDialog/store.js
new file mode 100644
index 0000000000..3b47824ede
--- /dev/null
+++ b/kystudio/src/components/common/EditExcludeColumnsDialog/store.js
@@ -0,0 +1,47 @@
+import * as actionTypes from '../../../store/types'
+
+export function getInitialState () {
+  return {
+    isShow: false,
+    callback: null,
+    excludeColumntitle: '',
+    excludeTable: ''
+  }
+}
+
+export default {
+  state: getInitialState(),
+  mutations: {
+    [actionTypes.SHOW_MODAL] (state) {
+      state.isShow = true
+    },
+    [actionTypes.HIDE_MODAL] (state) {
+      state.isShow = false
+    },
+    [actionTypes.SET_MODAL] (state, payload) {
+      for (const [key, value] of Object.entries(payload)) {
+        state[key] = value
+      }
+    },
+    [actionTypes.INIT_MODAL] (state) {
+      for (const [key, value] of Object.entries(getInitialState())) {
+        state[key] = value
+      }
+    },
+    [actionTypes.SET_MODAL_FORM] (state, payload) {
+      for (const [key, value] of Object.entries(payload)) {
+        state.form[key] = value
+      }
+    }
+  },
+  actions: {
+    [actionTypes.CALL_MODAL] ({ commit }, payload) {
+      return new Promise(resolve => {
+        commit(actionTypes.INIT_MODAL)
+        commit(actionTypes.SET_MODAL, { ...payload, callback: resolve })
+        commit(actionTypes.SHOW_MODAL)
+      })
+    }
+  },
+  namespaced: true
+}
diff --git a/kystudio/src/components/setting/SettingBasic/SettingBasic.vue 
b/kystudio/src/components/setting/SettingBasic/SettingBasic.vue
index 0030282513..7803f82200 100644
--- a/kystudio/src/components/setting/SettingBasic/SettingBasic.vue
+++ b/kystudio/src/components/setting/SettingBasic/SettingBasic.vue
@@ -137,6 +137,66 @@
         </div>
       </el-form>
     </EditableBlock>
+    <!-- 屏蔽列设置 -->
+    <EditableBlock
+      :header-content="$t('excludeRuleSettings')"
+      :isEditable="false">
+      <div class="setting-item">
+        <div class="conds-title">
+          <span class="setting-label 
font-medium">{{$t('excludeRule')}}</span><span class="ksd-fs-12">
+          <el-switch
+            :value="form.table_exclusion_enabled"
+            :active-text="$t('kylinLang.common.OFF')"
+            :inactive-text="$t('kylinLang.common.ON')"
+            @input="value => handleSwitch('exclude-rule', 
value)"></el-switch></span>
+        </div>
+        <div class="conds-content clearfix">
+          <div class="ksd-mt-8 ksd-fs-14">
+            <div class="exclude-rule-msg">
+              <p class="tips"><span v-html="$t('excludeRuleTip')"></span><span 
class="review-details" @click="showExcludeRuleDetails = 
!showExcludeRuleDetails">{{$t('moreDetails')}}<i class="" :class="['arrow', 
'ksd-fs-16', showExcludeRuleDetails ? 'el-ksd-n-icon-arrow-down-outlined' : 
'el-ksd-n-icon-arrow-right-outlined']"></i></span></p>
+              <div class="details" v-if="showExcludeRuleDetails">
+                <ol>
+                  <li><i class="point 
ksd-mr-2">•</i>{{$t('excludeRuleDetailMsg1')}}</li>
+                  <li><i class="point 
ksd-mr-2">•</i>{{$t('excludeRuleDetailMsg2')}}</li>
+                  <li><i class="point 
ksd-mr-2">•</i>{{$t('excludeRuleDetailMsg3')}}</li>
+                </ol>
+              </div>
+            </div>
+            <div v-if="form.table_exclusion_enabled">
+              <el-button class="ksd-mt-8 ksd-mb-4" icon="el-ksd-icon-add_22" 
@click="addExcludeColumns()">{{$t('addExcludeColumns')}}</el-button>
+              <el-table
+                :data="excludeColumnsTables"
+                class="exclude-column-table"
+                style="width: 100%">
+                <el-table-column width="230px" show-overflow-tooltip 
prop="table" :label="$t('table')"></el-table-column>
+                <el-table-column show-overflow-tooltip prop="excluded_columns" 
:label="$t('columns')">
+                  <template slot-scope="scope">
+                    <span v-if="scope.row.excluded">{{$t('allColumns')}}</span>
+                    <span v-else>({{scope.row.excluded_col_size}} 
{{$t('columns')}}) {{scope.row.excluded_columns.join(', ')}}</span>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  width="90px"
+                  :label="$t('kylinLang.common.action')">
+                    <template slot-scope="scope">
+                      <common-tip>
+                        <div slot="content">{{$t('addExcludeColumns')}}</div>
+                        <i class="el-ksd-n-icon-plus-outlined ksd-fs-18" 
@click="addExcludeColumns(scope.row.table)"></i>
+                      </common-tip>
+                      <common-tip>
+                        <div slot="content">{{$t('delExcludeColumns')}}</div>
+                        <i class="el-icon-ksd-table_delete ksd-fs-14" 
@click="delExcludeColumns(scope.row.table)"></i>
+                      </common-tip>
+                    </template>
+                </el-table-column>
+              </el-table>
+              <kylin-pager :totalSize="excludeColumnsTablesSize" 
:perPageSize="filter.page_size" :curPage="filter.page_offset+1" 
v-on:handleCurrentChange='currentChange' ref="excludeColumnsTablesPager" 
:refTag="pageRefTags.excludeColumnsTablesPager" class="ksd-mtb-10 ksd-center" 
></kylin-pager>
+            </div>
+          </div>
+        </div>
+      </div>
+    </EditableBlock>
+    <ExcludeColumnsDialog />
   </div>
 </template>
 
@@ -146,10 +206,12 @@ import { mapActions, mapGetters, mapMutations, mapState } 
from 'vuex'
 import { Component, Watch } from 'vue-property-decorator'
 
 import locales from './locales'
-import { handleError, handleSuccessAsync, objectClone, ArrayFlat } from 
'../../../util'
-import { projectTypeIcons, lowUsageStorageTypes, autoMergeTypes, 
volatileTypes, validate, initialFormValue, _getProjectGeneralInfo, 
_getSegmentSettings, _getPushdownConfig, _getStorageQuota, 
_getIndexOptimization, _getRetentionRangeScale } from './handler'
+import { handleError, handleSuccessAsync, objectClone, ArrayFlat, kylinConfirm 
} from '../../../util'
+import { projectTypeIcons, lowUsageStorageTypes, autoMergeTypes, 
volatileTypes, validate, initialFormValue, _getProjectGeneralInfo, 
_getSegmentSettings, _getPushdownConfig, _getExcludeColumnConfig, 
_getStorageQuota, _getIndexOptimization, _getRetentionRangeScale } from 
'./handler'
 import { retentionTypes } from '../handler'
+import { pageCount, pageRefTags } from '../../../config'
 import EditableBlock from '../../common/EditableBlock/EditableBlock.vue'
+import ExcludeColumnsDialog from 
'../../common/EditExcludeColumnsDialog/EditExcludeColumnsDialog.vue'
 import SourceAuthorityForm from 
'../../common/DataSourceModal/SourceJDBC/SourceAuthorityForm/SourceAuthorityForm.vue'
 
 @Component({
@@ -161,7 +223,8 @@ import SourceAuthorityForm from 
'../../common/DataSourceModal/SourceJDBC/SourceA
   },
   components: {
     EditableBlock,
-    SourceAuthorityForm
+    SourceAuthorityForm,
+    ExcludeColumnsDialog
   },
   computed: {
     ...mapGetters([
@@ -184,11 +247,16 @@ import SourceAuthorityForm from 
'../../common/DataSourceModal/SourceJDBC/SourceA
       getUserAndGroups: 'GET_USER_AND_GROUPS',
       updateFavoriteRules: 'UPDATE_FAVORITE_RULES',
       fetchDBandTables: 'FETCH_DB_AND_TABLES',
-      checkConnectByGbase: 'CHECK_BASE_CONFIG'
+      checkConnectByGbase: 'CHECK_BASE_CONFIG',
+      loadExcludeTables: 'LOAD_EXCLUDE_TABLES',
+      updateExcludeColumnConfig: 'UPDATE_EXCLUDE_COLUMN_CONFIG'
     }),
     ...mapActions('DetailDialogModal', {
       callGlobalDetailDialog: 'CALL_MODAL'
     }),
+    ...mapActions('ExcludeColumnsDialog', {
+      callExcludeColumnsDialog: 'CALL_MODAL'
+    }),
     ...mapMutations({
       updateProject: 'UPDATE_PROJECT'
     })
@@ -213,6 +281,14 @@ export default class SettingBasic extends Vue {
   JDBCConnectSettingBackup = []
   jdbcDatasourceEnabled = false
   allDatasourceTables = []
+  showExcludeRuleDetails = false
+  pageRefTags = pageRefTags
+  excludeColumnsTables = []
+  filter = {
+    page_offset: 0,
+    page_size: 
+localStorage.getItem(this.pageRefTags.excludeColumnsTablesPager) || pageCount
+  }
+  excludeColumnsTablesSize = 1
 
   get projectIcon () {
     return projectTypeIcons[this.project.maintain_model_type]
@@ -313,10 +389,14 @@ export default class SettingBasic extends Vue {
     this.handleInit('pushdown-settings')
     this.handleInit('storage-quota')
     this.handleInit('index-optimization')
+    this.handleInit('exclude-rule')
   }
   async mounted () {
     this.initForm()
     this.getAllDatasourceTables()
+    if (this.$store.state.project.projectExcludeTableConfig) {
+      this.getExcludeColumns()
+    }
   }
   handleCheckMergeRanges (value) {
     if (value.length > 0) {
@@ -346,6 +426,23 @@ export default class SettingBasic extends Vue {
           submitData.push_down_enabled = value
           await this.updatePushdownConfig(submitData); break
         }
+        case 'exclude-rule': {
+          if (!value) {
+            try {
+              await kylinConfirm(this.$t('confirmCloseExcludeRule'), {type: 
'warning'}, this.$t('closeExcludeRuleTitle'))
+            } catch (e) {
+              return
+            }
+          }
+          const submitData = _getExcludeColumnConfig(this.project)
+          submitData.table_exclusion_enabled = value
+          await this.updateExcludeColumnConfig(submitData)
+          this.form.table_exclusion_enabled = value
+          if (value) {
+            this.getExcludeColumns()
+          }
+          break
+        }
       }
       this.$emit('reload-setting')
       this.$message({ type: 'success', message: 
this.$t('kylinLang.common.updateSuccess') })
@@ -474,6 +571,9 @@ export default class SettingBasic extends Vue {
       case 'index-optimization': {
         this.form = { ...this.form, ..._getIndexOptimization(this.project) }; 
break
       }
+      case 'exclude-rule': {
+        this.form = { ...this.form, ..._getExcludeColumnConfig(this.project) 
}; break
+      }
     }
   }
   async handleResetForm (type, successCallback, errorCallback) {
@@ -554,6 +654,37 @@ export default class SettingBasic extends Vue {
     }
   }
 
+  async addExcludeColumns (excludeTable) {
+    const isSubmit = await this.callExcludeColumnsDialog({ excludeColumntitle: 
!excludeTable ? 'addExcludeColumns' : 'appendExcludeColumns', excludeTable: 
excludeTable })
+    if (isSubmit) {
+      this.getExcludeColumns()
+    }
+  }
+
+  async delExcludeColumns (excludeTable) {
+    const isSubmit = await this.callExcludeColumnsDialog({ excludeColumntitle: 
'delExcludeColumns', excludeTable: excludeTable })
+    if (isSubmit) {
+      this.getExcludeColumns()
+    }
+  }
+
+  currentChange (size, count) {
+    this.filter.page_offset = size
+    this.filter.page_size = count
+    this.getExcludeColumns()
+  }
+
+  async getExcludeColumns () {
+    try {
+      const res = await this.loadExcludeTables({ ...this.filter, project: 
this.currentSelectedProject })
+      const { value, total_size } = await handleSuccessAsync(res)
+      this.excludeColumnsTables = value
+      this.excludeColumnsTablesSize = total_size
+    } catch (e) {
+      handleError(e)
+    }
+  }
+
   // 更改数据源设置
   modifyDataSourceSetting (index) {
     const key = Date.now().toString(32)
@@ -691,6 +822,26 @@ export default class SettingBasic extends Vue {
       }
     }
   }
+  .exclude-rule-msg {
+    font-size: 12px;
+    .tips {
+      .review-details {
+        color: @base-color;
+        cursor: pointer !important;
+        position: relative;
+      }
+    }
+    .details {
+      background: @base-background-color-1;
+      padding: 10px 10px;
+      margin-top: 5px;
+      box-sizing: border-box;
+      .point {
+        font-style: inherit;
+        margin-right: 5px;
+      }
+    }
+  }
   .ruleSetting {
     padding: 15px 20px;
     .conds-title {
@@ -716,38 +867,6 @@ export default class SettingBasic extends Vue {
     .conds {
       margin-bottom: 16px;
     }
-    .exclude-rule-msg {
-      font-size: 12px;
-      .tips {
-        .review-details {
-          color: @base-color;
-          cursor: pointer;
-          position: relative;
-          .arrow {
-            transform: rotate(90deg);
-            font-size: 10px;
-            margin-left: 5px;
-          }
-        }
-      }
-      .details {
-        background: @base-background-color-1;
-        padding: 10px 10px;
-        margin-top: 5px;
-        box-sizing: border-box;
-        .point {
-          font-style: inherit;
-          margin-right: 5px;
-        }
-      }
-    }
-    .exclude_rule-form {
-      width: 100%;
-      .exclude_rule-select {
-        width: 100%;
-        margin-top: 10px;
-      }
-    }
   }
   .rule-setting-input {
     display: inline-block;
@@ -769,12 +888,5 @@ export default class SettingBasic extends Vue {
     font-size: 12px;
   }
 }
-.limit-excluded-tables-msg {
-  height: 32px;
-  color: @text-normal-color;
-  line-height: 32px;
-  text-align: center;
-  font-size: 12px;
-}
 
 </style>
diff --git a/kystudio/src/components/setting/SettingBasic/handler.js 
b/kystudio/src/components/setting/SettingBasic/handler.js
index 5fbbce315a..47fe367182 100644
--- a/kystudio/src/components/setting/SettingBasic/handler.js
+++ b/kystudio/src/components/setting/SettingBasic/handler.js
@@ -110,6 +110,12 @@ export function _getPushdownConfig (data) {
     push_down_range_limited: data.push_down_range_limited
   }
 }
+export function _getExcludeColumnConfig (data) {
+  return {
+    project: data.project,
+    table_exclusion_enabled: data.table_exclusion_enabled
+  }
+}
 export function _getStorageQuota (data) {
   return {
     project: data.project,
diff --git a/kystudio/src/components/setting/SettingBasic/locales.js 
b/kystudio/src/components/setting/SettingBasic/locales.js
index 8325ffca1b..a110ec3546 100644
--- a/kystudio/src/components/setting/SettingBasic/locales.js
+++ b/kystudio/src/components/setting/SettingBasic/locales.js
@@ -85,12 +85,20 @@ export default {
     emptySegmentEnableDesc: 'With this switch ON, you may create a segment 
with no index (reserved segment). Please note that queries would be answered by 
pushdown engine when they hit reserved segments.',
     overTimeLimitTip: 'Can\'t exceed 3600 seconds',
     prevGreaterThanNext: 'The content should be greater than the lower limit',
+    excludeRuleSettings: 'Exclude Column Rule Setting',
     excludeRule: 'Exclude Rule',
-    excludeRuleTip: 'Columns in the following tables will not be included in 
the recommendations. Suitable for AS-IS analysis. ',
+    excludeRuleTip: 'Excluded column is used for Slowly Changing 
Dimension(SCD),especially for the situation that you want to use SCD type 1 for 
some columns and SCD type 2 for others.',
+    closeExcludeRuleTitle: 'Close Exclude Column Setting',
+    confirmCloseExcludeRule: 'If close the exclude rules, please pay attention 
that the former excluded columns is still in AS-IS (SCD Type1) mode until 
aggregate index containing these columns is added.',
     moreDetails: 'More Info',
-    excludeRuleDetailMsg1: 'If the data of certain columns in a dimension 
table change frequently, the table can be added into the exclude list, and 
aggregate indexes containing these columns should be deleted.',
-    excludeRuleDetailMsg2: 'Then the foreign key in fact table will be 
included in the recommended index, replacing columns in the following tables. 
After building the indexes, queries for these tables can be retrieved through 
the foreign key.',
-    limitExcludedTablesTip: 'Only 50 tables would be displayed. Please enter 
keyword to search.',
+    excludeRuleDetailMsg1: 'If the data of certain columns in a dimension 
table changes frequently, the columns can be added into the exclude list, and 
aggregate indexes containing these columns should be deleted. In that way you 
can apply AS-IS(SCD type1) to these columns',
+    excludeRuleDetailMsg2: 'Then the foreign key in fact table will be 
included in the recommended index, replacing excluded columns. After building 
the indexes, queries for these columns can be retrieved through the foreign 
key.',
+    excludeRuleDetailMsg3: 'If you want to use SCD type 2 for some other 
columns,you can add them to aggregate indexes.',
+    addExcludeColumns: 'Add Exclude Columns',
+    delExcludeColumns: 'Delete Exclude Columns',
+    allColumns: 'All columns',
+    table: 'Table',
+    columns: 'Columns',
     forbidenSwitchJdbcTips: 'Can\'t turn it OFF when there exists JDBC table 
in the project',
     hitRules: 'Hit Rules',
     ruleTips: 'Only the recommendations complying the following rules will be 
recommended.',
diff --git 
a/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/index.vue 
b/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/index.vue
index 857a7bbcb0..33332393be 100644
--- 
a/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/index.vue
+++ 
b/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/index.vue
@@ -467,7 +467,10 @@
           show-icon>
         </el-alert>
         <div class="filter-dimension">
-          <el-tooltip :content="$t('excludeTableCheckboxTip')" effect="dark" 
placement="top"><el-checkbox class="ksd-mr-5" v-model="displayExcludedTables" 
@change="changeExcludedTables" 
v-if="showExcludedTableCheckBox">{{$t('excludeTableCheckbox')}}</el-checkbox></el-tooltip>
+          <!-- <el-tooltip effect="dark" placement="bottom">
+            <div slot="content" v-html="$t('excludeTableCheckboxTip')"></div>
+            <el-checkbox class="ksd-mr-5" v-model="displayExcludedTables" 
@change="changeExcludedTables" 
v-if="showExcludedTableCheckBox">{{$t('excludeTableCheckbox')}}</el-checkbox>
+          </el-tooltip> -->
           <el-input v-model="searchName" 
v-global-key-event.enter.debounce="filterChange" @clear="clearFilter" 
size="medium" prefix-icon="el-ksd-icon-search_22" style="width:240px" 
:placeholder="$t('kylinLang.common.pleaseFilter')"></el-input>
         </div>
       </div>
@@ -736,9 +739,9 @@ export default class AggregateModal extends Vue {
   }
 
   // 是否展示屏蔽表 checkbox
-  get showExcludedTableCheckBox () {
-    return this.backUpDimensions.length ? this.backUpDimensions.filter(it => 
typeof it.depend_lookup_table !== 'undefined' && it.depend_lookup_table).length 
> 0 : false
-  }
+  // get showExcludedTableCheckBox () {
+  //   return this.backUpDimensions.length ? this.backUpDimensions.filter(it 
=> typeof it.excluded !== 'undefined' && it.excluded).length > 0 : false
+  // }
 
   // 是否存在多对多且被屏蔽的表
   get hasManyToManyAndAntiTable () {
@@ -766,7 +769,7 @@ export default class AggregateModal extends Vue {
 
   // 是否为屏蔽表的 column
   isExistExcludeTable (col) {
-    return typeof col.depend_lookup_table !== 'undefined' ? 
col.depend_lookup_table : false
+    return typeof col.excluded !== 'undefined' ? col.excluded : false
   }
 
   getMultipleCardinality (aggregateIdx, jointRowIdx) {
diff --git 
a/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/locales.js
 
b/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/locales.js
index a9c81bec64..c48786c10b 100644
--- 
a/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/locales.js
+++ 
b/kystudio/src/components/studio/StudioModel/ModelList/AggregateModal/locales.js
@@ -108,7 +108,7 @@ export default {
     buildIndexTip: 'Successfully saved the aggregate index(es). The building 
job can\'t be submitted at the moment, as there exists an ongoing building job 
for this model. Please try submitting the building job until the current one is 
completed or manually stop it.',
     disabledConstantMeasureTip: 'Can\'t modify the default measure.',
     excludeTableCheckbox: 'Display columns excluded from recommendations',
-    excludeTableCheckboxTip: 'Exclude Rules can be modified in project 
setting',
+    excludeTableCheckboxTip: 'If an excluded column is added to indexes, this 
column will store "historical truth"(SCD Type2, As Was).',
     excludedTableIconTip: 'Excluded from recommendations',
     indexTimeRange: 'Index’s Data Range',
     manyToManyAntiTableTip: 'For the tables excluded from recommendations, if 
the join relationship of a table is One-to-Many or Many-to-Many, dimensions 
from this table can\'t be used in indexes. ',
diff --git 
a/kystudio/src/components/studio/StudioModel/TableIndexEdit/locales.js 
b/kystudio/src/components/studio/StudioModel/TableIndexEdit/locales.js
index c7fa4338a4..031267a13a 100644
--- a/kystudio/src/components/studio/StudioModel/TableIndexEdit/locales.js
+++ b/kystudio/src/components/studio/StudioModel/TableIndexEdit/locales.js
@@ -23,7 +23,7 @@ export default {
     tableIndexShardByTips: 'Please select columns for detail query. To enhance 
the query performance, please move the frequently used dimensions to the top of 
the list, and set a column with relatively large cardinality as ShardBy.',
     filterByColumns: 'Search by column name',
     excludeTableCheckbox: 'Display columns excluded from recommendations',
-    excludeTableCheckboxTip: 'Exclude Rules can be modified in project 
setting',
+    excludeTableCheckboxTip: 'If an excluded column is added to indexes, this 
column will store "historical truth"(SCD Type2, As Was).<br/>If you want to use 
"latest status" (SCD Type 1, As Is) ,please don\'t add this column to any index 
and add foreign key instead.',
     excludedTableIconTip: 'Excluded from recommendations',
     manyToManyAntiTableTip: 'For the tables excluded from recommendations, if 
the join relationship of a table is One-to-Many or Many-to-Many, dimensions 
from this table can\'t be used in indexes. ',
     indexTimeRange: 'Index’s Time Range',
diff --git 
a/kystudio/src/components/studio/StudioModel/TableIndexEdit/tableindex_edit.vue 
b/kystudio/src/components/studio/StudioModel/TableIndexEdit/tableindex_edit.vue
index aa0c1c1213..08340e79a7 100644
--- 
a/kystudio/src/components/studio/StudioModel/TableIndexEdit/tableindex_edit.vue
+++ 
b/kystudio/src/components/studio/StudioModel/TableIndexEdit/tableindex_edit.vue
@@ -36,7 +36,10 @@
           </el-alert>
           <template v-if="modelInstance.model_type !== 'HYBRID' || 
modelInstance.model_type === 'HYBRID' && tableIndexMeta.index_range">
             <p class="anit-table-tips" 
v-if="hasManyToManyAndAntiTable">{{$t('manyToManyAntiTableTip')}}</p>
-            <el-tooltip :content="$t('excludeTableCheckboxTip')" effect="dark" 
placement="top"><el-checkbox class="ksd-mr-5" v-if="showExcludedTableCheckBox" 
v-model="displayExcludedTables">{{$t('excludeTableCheckbox')}}</el-checkbox></el-tooltip>
+            <!-- <el-tooltip effect="dark" placement="top">
+              <div slot="content" v-html="$t('excludeTableCheckboxTip')"></div>
+              <el-checkbox class="ksd-mr-5" v-if="showExcludedTableCheckBox" 
v-model="displayExcludedTables">{{$t('excludeTableCheckbox')}}</el-checkbox>
+            </el-tooltip> -->
             <el-input v-model="searchColumn" size="medium" 
prefix-icon="el-ksd-icon-search_22" style="width:200px" 
:placeholder="$t('filterByColumns')"></el-input>
           </template>
         </div>
@@ -171,9 +174,9 @@
       return (this.modelInstance.model_type === 'HYBRID' && 
this.tableIndexMeta.index_range !== 'STREAMING') || 
(this.modelInstance.model_type !== 'STREAMING' && this.modelInstance.model_type 
!== 'HYBRID')
     }
 
-    get showExcludedTableCheckBox () {
-      return this.allColumns.length ? this.allColumns.filter(it => typeof 
it.depend_lookup_table !== 'undefined' && it.depend_lookup_table).length > 0 : 
false
-    }
+    // get showExcludedTableCheckBox () {
+    //   return this.allColumns.length ? this.allColumns.filter(it => typeof 
it.excluded !== 'undefined' && it.excluded).length > 0 : false
+    // }
     topRow (col) {
       let index = this.getRowIndex(col, 'fullName')
       this.allColumns.splice(0, 0, col)
@@ -223,7 +226,7 @@
     }
     // 是否为屏蔽表的 column
     isExistExcludeTable (col) {
-      return typeof col.depend_lookup_table !== 'undefined' ? 
col.depend_lookup_table : false
+      return typeof col.excluded !== 'undefined' ? col.excluded : false
     }
     get filterResult () {
       if (!this.isShow) {
@@ -247,7 +250,7 @@
       this.allColumns = []
       // let result = []
       let result = this.modelInstance.selected_columns.map((c) => {
-        return { fullName: c.column, cardinality: c.cardinality, 
depend_lookup_table: typeof c.depend_lookup_table !== 'undefined' ? 
c.depend_lookup_table : true }
+        return { fullName: c.column, cardinality: c.cardinality, excluded: 
typeof c.excluded !== 'undefined' ? c.excluded : true }
       })
       // let modelUsedTables = this.modelInstance && 
this.modelInstance.getTableColumns() || []
       // modelUsedTables.forEach((col) => {
@@ -256,7 +259,7 @@
       if (this.tableIndexMeta.col_order.length) {
         const selected = this.tableIndexMeta.col_order.map(item => {
           const index = result.findIndex(it => it.fullName === item)
-          return {fullName: item, cardinality: result[index].cardinality, 
depend_lookup_table: result[index].depend_lookup_table}
+          return {fullName: item, cardinality: result[index].cardinality, 
excluded: result[index].excluded}
         })
         const unSort = result.filter(item => 
!this.tableIndexMeta.col_order.includes(item.fullName))
         result = [...selected, ...unSort]
@@ -267,7 +270,7 @@
       //   result.push(col.tableAlias + '.' + col.columnName)
       // })
       result.forEach((ctx, index) => {
-        let obj = {fullName: ctx.fullName, cardinality: ctx.cardinality, 
depend_lookup_table: ctx.depend_lookup_table, isUsed: false, isShared: false, 
colorful: false}
+        let obj = {fullName: ctx.fullName, cardinality: ctx.cardinality, 
excluded: ctx.excluded, isUsed: false, isShared: false, colorful: false}
         if (this.tableIndexMeta.col_order.indexOf(ctx.fullName) >= 0) {
           obj.isUsed = true
         }
diff --git 
a/kystudio/src/components/studio/StudioSource/TableColumns/TableColumns.vue 
b/kystudio/src/components/studio/StudioSource/TableColumns/TableColumns.vue
index 63c6623890..1efcefdc9e 100644
--- a/kystudio/src/components/studio/StudioSource/TableColumns/TableColumns.vue
+++ b/kystudio/src/components/studio/StudioSource/TableColumns/TableColumns.vue
@@ -35,6 +35,18 @@
         show-overflow-tooltip
         :label="$t('kylinLang.dataSource.dataType')">
       </el-table-column>
+      <el-table-column
+        prop="excluded"
+        align="left"
+        header-align="left"
+        min-width="80"
+        v-if="$store.state.project.projectExcludeTableConfig"
+        show-overflow-tooltip
+        :label="$t('kylinLang.dataSource.excluded')">
+        <span slot-scope="scope">
+          {{scope.row.excluded?$t('yes'):$t('no')}}
+        </span>
+      </el-table-column>
       <el-table-column
         prop="cardinality"
         sortable="custom"
diff --git 
a/kystudio/src/components/studio/StudioSource/TableColumns/locales.js 
b/kystudio/src/components/studio/StudioSource/TableColumns/locales.js
index 95781e2a3f..78859f04c7 100644
--- a/kystudio/src/components/studio/StudioSource/TableColumns/locales.js
+++ b/kystudio/src/components/studio/StudioSource/TableColumns/locales.js
@@ -3,6 +3,8 @@ export default {
     total: 'Sampling Records: ',
     cardinalityTip: 'Cardinality refers to the count of the distinct values of 
a column. This information could be gathered by sampling.',
     commentTip: 'Synced from the source table.',
-    filterByColumns: 'Search by column name'
+    filterByColumns: 'Search by column name',
+    yes: 'Yes',
+    no: 'No'
   }
 }
diff --git a/kystudio/src/config/index.js b/kystudio/src/config/index.js
index bce95126b1..f43fc831ef 100644
--- a/kystudio/src/config/index.js
+++ b/kystudio/src/config/index.js
@@ -154,7 +154,9 @@ export const pageRefTags = {
   subPartitionValuesPager: 'subPartitionValuesPager',
   subPartitionSegmentPager: 'subPartitionSegmentPager',
   snapshotPager: 'snapshotPager',
-  basicPorjectConfigPager: 'basicPorjectConfigPager'
+  basicPorjectConfigPager: 'basicPorjectConfigPager',
+  excludeColumnsTablesPager: 'excludeColumnsTablesPager',
+  exclusionColumnsPager: 'exclusionColumnsPager'
 }
 export const needLengthMeasureType = ['fixed_length', 'fixed_length_hex', 
'int', 'integer']
 export const permissions = {
diff --git a/kystudio/src/locale/en.js b/kystudio/src/locale/en.js
index 8728c90c6c..8e205af8ca 100644
--- a/kystudio/src/locale/en.js
+++ b/kystudio/src/locale/en.js
@@ -440,6 +440,7 @@ exports.default = {
     sampleData: 'Sample Data',
     maximum: 'Max Value',
     minimal: 'Min Value',
+    excluded: 'Excluded',
     nullCount: 'Null Count',
     exceedPrecisionMaxLengthValue: 'Longest Value Over Precision',
     minLengthVal: 'Min Length Value',
diff --git a/kystudio/src/service/project.js b/kystudio/src/service/project.js
index cad47a598c..9ba40a48bc 100644
--- a/kystudio/src/service/project.js
+++ b/kystudio/src/service/project.js
@@ -148,5 +148,17 @@ export default {
   },
   getDefaultConfig () {
     return Vue.resource(apiUrl + 'projects/default_configs').get()
+  },
+  loadExcludeTables (params) {
+    return Vue.resource(apiUrl + `tables/excluded_tables`).get(params)
+  },
+  loadExcludeColumns (params) {
+    return Vue.resource(apiUrl + `tables/excluded_table`).get(params)
+  },
+  updateExcludeColumns (data) {
+    return Vue.resource(apiUrl + `tables/excluded_tables`).update(data)
+  },
+  updateExcludeColumnConfig (data) {
+    return Vue.resource(apiUrl + 
`projects/${data.project}/exclusion_enabled`).update(data)
   }
 }
diff --git a/kystudio/src/store/project.js b/kystudio/src/store/project.js
index baf4188ab1..b64a89de57 100644
--- a/kystudio/src/store/project.js
+++ b/kystudio/src/store/project.js
@@ -19,6 +19,7 @@ export default {
     snapshot_manual_management_enabled: false,
     scd2_enabled: false,
     second_storage_enabled: false,
+    projectExcludeTableConfig: false,
     emptySegmentEnable: false,
     projectConfig: null,
     multi_partition_enabled: false,
@@ -101,6 +102,9 @@ export default {
     [types.CACHE_PROJECT_PUSHDOWN_CONFIG]: function (state, { 
projectPushdownConfig }) {
       state.projectPushdownConfig = projectPushdownConfig
     },
+    [types.CACHE_PROJECT_EXCLUDE_CONFIG]: function (state, { 
projectExcludeTableConfig }) {
+      state.projectExcludeTableConfig = projectExcludeTableConfig
+    },
     [types.UPDATE_SNAPSHOT_MANUAL_ENABLE] (state, type) {
       state.snapshot_manual_management_enabled = type
       if (this.state.config.platform === 'iframe') {
@@ -230,6 +234,7 @@ export default {
         commit(types.CACHE_PROJECT_CONFIG, {projectDefaultDB: 
response.data.data})
         commit(types.CACHE_PROJECT_DEFAULT_DB, {projectDefaultDB: 
response.data.data.default_database})
         commit(types.CACHE_PROJECT_PUSHDOWN_CONFIG, {projectPushdownConfig: 
response.data.data.push_down_enabled})
+        commit(types.CACHE_PROJECT_EXCLUDE_CONFIG, {projectExcludeTableConfig: 
response.data.data.table_exclusion_enabled})
         commit(types.UPDATE_SCD2_ENABLE, response.data.data.scd2_enabled || 
false)
         commit(types.UPDATE_SNAPSHOT_MANUAL_ENABLE, 
response.data.data.snapshot_manual_management_enabled || false)
         commit(types.UPDATE_MULTI_PARTITION_ENABLE, 
response.data.data.multi_partition_enabled || false)
@@ -308,6 +313,18 @@ export default {
     },
     [types.GET_MULTI_PARTITION_MODEL]: function ({ commit }, para) {
       return api.project.getMultiPartitionModels(para)
+    },
+    [types.LOAD_EXCLUDE_TABLES]: function ({ commit }, para) {
+      return api.project.loadExcludeTables(para)
+    },
+    [types.LOAD_EXCLUDE_COLUMNS]: function ({ commit }, para) {
+      return api.project.loadExcludeColumns(para)
+    },
+    [types.UPDATE_EXCLUDE_CLUMNS]: function ({ commit }, para) {
+      return api.project.updateExcludeColumns(para)
+    },
+    [types.UPDATE_EXCLUDE_COLUMN_CONFIG]: function ({ commit }, para) {
+      return api.project.updateExcludeColumnConfig(para)
     }
   },
   getters: {
diff --git a/kystudio/src/store/types.js b/kystudio/src/store/types.js
index 914e020d68..b403930e33 100644
--- a/kystudio/src/store/types.js
+++ b/kystudio/src/store/types.js
@@ -33,6 +33,11 @@ export const UPDATE_SEGMENT_CONFIG = 'UPDATE_SEGMENT_CONFIG'
 export const UPDATE_PUSHDOWN_CONFIG = 'UPDATE_PUSHDOWN_CONFIG'
 export const UPDATE_EMPTY_SEGMENT_ENABLE = 'UPDATE_EMPTY_SEGMENT_ENABLE'
 export const CACHE_PROJECT_PUSHDOWN_CONFIG = 'CACHE_PROJECT_PUSHDOWN_CONFIG'
+export const CACHE_PROJECT_EXCLUDE_CONFIG = 'CACHE_PROJECT_EXCLUDE_CONFIG'
+export const LOAD_EXCLUDE_TABLES = 'LOAD_EXCLUDE_TABLES'
+export const LOAD_EXCLUDE_COLUMNS = 'LOAD_EXCLUDE_COLUMNS'
+export const UPDATE_EXCLUDE_CLUMNS = 'UPDATE_EXCLUDE_CLUMNS'
+export const UPDATE_EXCLUDE_COLUMN_CONFIG = 'UPDATE_EXCLUDE_COLUMN_CONFIG'
 export const UPDATE_STORAGE_QUOTA = 'UPDATE_STORAGE_QUOTA'
 export const UPDATE_JOB_ALERT_SETTINGS = 'UPDATE_JOB_ALERT_SETTINGS'
 export const UPDATE_PROJECT_DATASOURCE = 'UPDATE_PROJECT_DATASOURCE'


Reply via email to