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

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

commit 9a4c64fca2d11439cb5f23ba7b69d994dc34d1eb
Author: Qian Xia <lauraxiaq...@gmail.com>
AuthorDate: Thu Jul 20 14:26:26 2023 +0800

    KYLIN-5656 lookup cc
---
 .../StudioModel/ComputedColumnForm/ccform.vue      |  2 +-
 .../studio/StudioModel/ModelEdit/index.vue         | 84 ++++++++++++++++++----
 .../studio/StudioModel/ModelEdit/model.js          | 73 ++++++++++++++-----
 .../studio/StudioModel/ModelEdit/table.js          | 26 +++----
 .../ModelList/ModelBuildModal/build.vue            | 33 ++++++---
 .../StudioModel/ModelList/ModelPartition/index.vue | 20 +++---
 .../ModelList/ModelSaveConfig/index.vue            | 29 +++++---
 .../studio/StudioModel/TableJoinModal/index.vue    | 11 +--
 kystudio/src/service/model.js                      |  2 +-
 9 files changed, 202 insertions(+), 78 deletions(-)

diff --git 
a/kystudio/src/components/studio/StudioModel/ComputedColumnForm/ccform.vue 
b/kystudio/src/components/studio/StudioModel/ComputedColumnForm/ccform.vue
index 0abd0f0de0..44df01dba3 100644
--- a/kystudio/src/components/studio/StudioModel/ComputedColumnForm/ccform.vue
+++ b/kystudio/src/components/studio/StudioModel/ComputedColumnForm/ccform.vue
@@ -144,7 +144,7 @@ export default class CCForm extends Vue {
   }
   errorMsg = ''
   checkRemoteCC (cb) {
-    this.modelInstance.generateMetadata().then((data) => {
+    this.modelInstance.generateMetadata(true).then((data) => {
       // 组装带cc的模型功校验cc接口使用
       let resData = objectClone(data)
       if (!this.isEdited) {
diff --git a/kystudio/src/components/studio/StudioModel/ModelEdit/index.vue 
b/kystudio/src/components/studio/StudioModel/ModelEdit/index.vue
index 7de4565f96..8382f1ebad 100644
--- a/kystudio/src/components/studio/StudioModel/ModelEdit/index.vue
+++ b/kystudio/src/components/studio/StudioModel/ModelEdit/index.vue
@@ -134,7 +134,7 @@
                 </span>
               </li>
               <!-- 渲染可计算列 -->
-              <template v-if="t.kind=== 'FACT'">
+              <!-- <template v-if="t.kind=== 'FACT'">
                 <li :class="['column-li', 'column-li-cc', {'is-link': col.isPK 
|| col.isFK}]"
                   @drop='(e) => {dropColumn(e, {name: col.columnName }, t)}'
                   @dragover="(e) => {dragColumnEnter(e, t, col)}"
@@ -153,7 +153,7 @@
                     <span :class="['col-name']" v-custom-tooltip="{text: 
col.columnName, w: 30, effect: 'dark', 'popper-class': 'popper--small', 
'visible-arrow': false, position: 'bottom-start', observerId: 
t.guid}">{{col.columnName}}</span>
                   </span>
                 </li>
-              </template>
+              </template> -->
               <li class="li-load-more" v-if="t.hasMoreColumns && 
t.hasScrollEnd && !showOnlyConnectedColumn"><i 
class="el-ksd-icon-loading_16"></i></li>
             </ul>
           </div>
@@ -1165,23 +1165,34 @@ export default class ModelEdit extends Vue {
     if (tableBoxes.length > 0) {
       Array.prototype.slice.call(tableBoxes).forEach(item => {
         item.classList.remove('is-focus')
-        item.classList.remove('is-broken')
+        // item.classList.remove('is-broken')
       })
     }
     if (linkLabels.length > 0) {
       Array.prototype.slice.call(linkLabels).forEach(item => {
         item.classList.remove('is-focus')
-        item.classList.remove('is-broken')
+        // item.classList.remove('is-broken')
       })
     }
     if (svgLine.length > 0) {
       Array.prototype.slice.call(svgLine).forEach(item => {
-        item.setAttribute('class', 
`${item.className.baseVal.replace(/is-focus|is-broken/g, '')}`)
+        item.setAttribute('class', 
`${item.className.baseVal.replace(/is-focus/g, '')}`)
       })
     }
     this.blurTableActionDropdown()
     document.activeElement && document.activeElement.blur()
   }
+
+  removeBrokenStatus (conn, isBrokenLine) {
+    const { _jsPlumb, canvas, source, target } = conn
+    if (isBrokenLine) return
+    source.classList.remove('is-broken')
+    target.classList.remove('is-broken')
+    canvas.querySelector('g').setAttribute('id', 'use-group')
+    canvas.nextSibling.classList.remove('is-broken')
+    _jsPlumb.paintStyle.stroke = '#A5B2C5'
+  }
+
   // 隐藏下拉框
   blurTableActionDropdown () {
     if (this.$refs.tableActionsDropdown) {
@@ -1414,7 +1425,38 @@ export default class ModelEdit extends Vue {
   }
   // 单个删除CC
   delCC (name) {
-    this.modelInstance.delCC(name)
+    this.modelInstance.delCC(name).then((delCCValue) => {
+      const joinTables  = this.modelInstance.tables
+      const [ cc ] = delCCValue
+      const includeCurrentCCJoins = []
+      Object.values(joinTables).forEach(jt => {
+        const joinInfo = Object.values(jt.joinInfo)
+        if (!joinInfo.length) return
+        joinInfo.forEach(jc => {
+          if 
(jc.join.primary_key.includes(`${cc.tableAlias}.${cc.columnName}`) || 
jc.join.foreign_key.includes(`${cc.tableAlias}.${cc.columnName}`)) {
+            includeCurrentCCJoins.push({pid: jt.guid, fid: 
jc.foreignTable.guid})
+          }
+        })
+      })
+      includeCurrentCCJoins.forEach(it => {
+        // this.modelInstance.renderLink(it.pid, it.fid)
+        const conn = this.modelInstance.allConnInfo[`${it.pid}$${it.fid}`]
+        if (conn) {
+          const { _jsPlumb } = conn
+          conn.isBroken = true
+          conn.canvas.querySelector('g').setAttribute('id', 'broken-use-group')
+          _jsPlumb.paintStyle.stroke = '#E03B3B'
+          _jsPlumb.hoverPaintStyle.stroke = '#CA1616'
+          this.modelInstance.setOverLayLabel(conn, true)
+          // this.modelInstance.plumbTool.refreshPlumbInstance()
+          this.$nextTick(() => {
+            conn.source.className += ' is-broken'
+            conn.target.className += ' is-broken'
+          })
+        }
+      })
+      // this.modelInstance.createAndUpdateSvgGroup(null, {type: 'update'})
+    })
   }
   editCC (cc) {
     this.showAddCCDialog({
@@ -1441,6 +1483,9 @@ export default class ModelEdit extends Vue {
     if (this.modelRender.computed_columns.length === 0) {
       this.toggleCCCheckbox()
     }
+    this.$nextTick(() => {
+      this.modelInstance.plumbTool.refreshPlumbInstance()
+    })
   }
   editMeasure (m) {
     this.$nextTick(() => {
@@ -1741,13 +1786,14 @@ export default class ModelEdit extends Vue {
       this.$nextTick(() => {
         // const cloneTables = objectClone(this.modelRender.tables)
         Object.values(this.modelRender.tables).forEach(t => {
-          const pfkLinkColumns = t.columns.filter(it => it.isPK && 
it.isFK).sort((a, b) => a - b)
-          const pkLinkColumns = t.columns.filter(it => it.isPK && 
!it.isFK).sort((a, b) => a - b)
-          const fkLinkColumns = t.columns.filter(it => it.isFK && 
!it.isPK).sort((a, b) => a - b)
-          const unlinkColumns = t.columns.filter(it => !it.isPK && !it.isFK)
-          t.columns = [...pfkLinkColumns, ...pkLinkColumns, ...fkLinkColumns, 
...unlinkColumns]
-          t._cache_search_columns = t.columns
+          const pfkLinkColumns = t.all_columns.filter(it => it.isPK && 
it.isFK).sort((a, b) => a - b)
+          const pkLinkColumns = t.all_columns.filter(it => it.isPK && 
!it.isFK).sort((a, b) => a - b)
+          const fkLinkColumns = t.all_columns.filter(it => it.isFK && 
!it.isPK).sort((a, b) => a - b)
+          const unlinkColumns = t.all_columns.filter(it => !it.isPK && 
!it.isFK)
+          t.columns = [...pfkLinkColumns, ...pkLinkColumns, ...fkLinkColumns, 
...unlinkColumns].filter(it => !it.is_computed_column)
+          t._cache_search_columns = [...pfkLinkColumns, ...pkLinkColumns, 
...fkLinkColumns, ...unlinkColumns]
           t.showColumns = [...pfkLinkColumns, ...pkLinkColumns, 
...fkLinkColumns, ...unlinkColumns].slice(0, t.columnPerSize)
+          t.all_columns = [...pfkLinkColumns, ...pkLinkColumns, 
...fkLinkColumns, ...unlinkColumns]
         })
         this.$set(this.modelInstance, 'tables', this.modelRender.tables)
         console.log(this.modelInstance.allConnInfo)
@@ -2447,6 +2493,11 @@ export default class ModelEdit extends Vue {
         color: @ke-color-danger-hover;
       }
     }
+    &.is-focus {
+      .join-type {
+        color: @ke-color-danger-hover !important;
+      }
+    }
   }
   &.link-label.is-focus {
     .join-type {
@@ -3169,6 +3220,12 @@ export default class ModelEdit extends Vue {
           stroke-width: 2;
         }
       }
+      #broken-use-group {
+        > path:not(#use) {
+          stroke: @ke-color-danger;
+          stroke-width: 2;
+        }
+      }
     }
   }
   .edit-table-layout {
@@ -3204,6 +3261,9 @@ export default class ModelEdit extends Vue {
     &.link-hover:not(.is-focus) {
       border: 2px solid @base-color-6;
     }
+    &.link-hover.is-broken:not(.is-focus) {
+      border: 2px solid @ke-color-danger;
+    }
     &:hover:not(.is-focus) {
       // box-shadow: @fact-hover-shadow;
       border: 2px solid @base-color-6;
diff --git a/kystudio/src/components/studio/StudioModel/ModelEdit/model.js 
b/kystudio/src/components/studio/StudioModel/ModelEdit/model.js
index d3d828d31d..42837e30a4 100644
--- a/kystudio/src/components/studio/StudioModel/ModelEdit/model.js
+++ b/kystudio/src/components/studio/StudioModel/ModelEdit/model.js
@@ -208,6 +208,7 @@ class NModel extends Schama {
         if (!primaryKeys || primaryKeys && primaryKeys.length === 1 && 
primaryKeys[0] === '') {
           this.removeRenderLink(hasConn)
         } else {
+          this.vm.removeBrokenStatus(hasConn, isBrokenLine)
           !isBrokenLine && this.plumbTool.setLineStyle('default')
           this.setOverLayLabel(hasConn, isBrokenLine)
           this.plumbTool.refreshPlumbInstance()
@@ -246,17 +247,29 @@ class NModel extends Schama {
   checkIsBrokenModelLink (pid, fid, primaryKeys, foreignKeys) {
     let ptable = this.getTableByGuid(pid)
     let primaryKeysLen = primaryKeys.length
+
+    let ftable = this.getTableByGuid(fid)
+    let foreignKeysLen = foreignKeys.length
+
+    const primaryTableComputeColumns = []
+    const foreignTableComputeColumns = []
+    this.computed_columns.forEach(col => {
+      if (col.tableAlias === ptable.alias) {
+        primaryTableComputeColumns.push({...col, name: col.columnName})
+      } else if (col.tableAlias === ftable.alias) {
+        foreignTableComputeColumns.push({...col, name: col.columnName})
+      }
+    })
     for (let i = 0; i < primaryKeysLen; i++) {
       let column = primaryKeys[i] && primaryKeys[i].replace(/^.*?\./, '')
-      if (indexOfObjWithSomeKey(ptable.columns, 'name', column) < 0) {
+      if (indexOfObjWithSomeKey([...ptable.columns, 
...primaryTableComputeColumns], 'name', column) < 0) {
         return true
       }
     }
-    let ftable = this.getTableByGuid(fid)
-    let foreignKeysLen = foreignKeys.length
+
     for (let i = 0; i < foreignKeysLen; i++) {
       let column = foreignKeys[i] && foreignKeys[i].replace(/^.*?\./, '')
-      if (indexOfObjWithSomeKey(ftable.columns, 'name', column) < 0) {
+      if (indexOfObjWithSomeKey([...ftable.columns, 
...foreignTableComputeColumns], 'name', column) < 0) {
         return true
       }
     }
@@ -269,7 +282,8 @@ class NModel extends Schama {
     if (table) {
       for (let i = 0; i < keysLen; i++) {
         let column = keys[i] && keys[i].replace(/^.*?\./, '')
-        if (indexOfObjWithSomeKey(table.columns, 'name', column) < 0) {
+        const ccColumns = this.computed_columns ? this.computed_columns.map(it 
=> ({...it, name: it.columnName})) : []
+        if (indexOfObjWithSomeKey([...table.columns, ...ccColumns], 'name', 
column) < 0) {
           result.push(keys[i])
         }
       }
@@ -379,13 +393,14 @@ class NModel extends Schama {
       }
       setTimeout(() => {
         Object.values(this.tables).forEach(t => {
-          const pfkLinkColumns = t.columns.filter(it => it.isPK && 
it.isFK).sort((a, b) => a - b)
-          const pkLinkColumns = t.columns.filter(it => it.isPK && 
!it.isFK).sort((a, b) => a - b)
-          const fkLinkColumns = t.columns.filter(it => it.isFK && 
!it.isPK).sort((a, b) => a - b)
-          const unlinkColumns = t.columns.filter(it => !it.isPK && !it.isFK)
-          t.columns = [...pfkLinkColumns, ...pkLinkColumns, ...fkLinkColumns, 
...unlinkColumns]
+          const pfkLinkColumns = t.all_columns.filter(it => it.isPK && 
it.isFK).sort((a, b) => a - b)
+          const pkLinkColumns = t.all_columns.filter(it => it.isPK && 
!it.isFK).sort((a, b) => a - b)
+          const fkLinkColumns = t.all_columns.filter(it => it.isFK && 
!it.isPK).sort((a, b) => a - b)
+          const unlinkColumns = t.all_columns.filter(it => !it.isPK && 
!it.isFK)
+          t.columns = [...pfkLinkColumns, ...pkLinkColumns, ...fkLinkColumns, 
...unlinkColumns].filter(it => !it.is_computed_column)
           t.showColumns = [...pfkLinkColumns, ...pkLinkColumns, 
...fkLinkColumns, ...unlinkColumns].slice(0, t.columnPerSize)
-          t._cache_search_columns = t.columns
+          t._cache_search_columns = [...pfkLinkColumns, ...pkLinkColumns, 
...fkLinkColumns, ...unlinkColumns]
+          t.all_columns = [...pfkLinkColumns, ...pkLinkColumns, 
...fkLinkColumns, ...unlinkColumns]
           this.$set(this._mount, 'tables', this.tables)
         })
       }, 0)
@@ -835,17 +850,18 @@ class NModel extends Schama {
       // 删除对应的 tableindex
       this._delTableIndexByAlias(alias)
       // 删除对应的 cc
-      this._delCCByAlias(alias)
+      this._delCCByAlias(ntable)
       // 删除对应的partition
       this._delTableRelatedPartitionInfo(ntable)
     }
   }
-  _delCCByAlias (tableAlias) {
-    const ccList = this._mount.computed_columns.filter(it => it.tableAlias !== 
tableAlias)
-    this._mount.computed_columns = ccList
+  _delCCByAlias (ntable) {
+    const ccList = this._mount.computed_columns.filter(it => it.tableAlias === 
ntable.alias)
     ccList.forEach(cc => {
+      const index = indexOfObjWithSomeKey(this._mount.computed_columns, 
'guid', cc.guid)
+      this._mount.computed_columns.splice(index, 1)
       let ccColumnName = typeof cc === 'object' ? cc.columnName : cc
-      this._delCCRelated(tableAlias, ccColumnName)
+      this._delCCRelated(ntable, ccColumnName)
     })
   }
   getTable (key, val) {
@@ -942,6 +958,13 @@ class NModel extends Schama {
       this.partition_desc.partition_time_column = null
     }
   }
+  _delCCInTableAllColumns (t, column) {
+    const index = t.all_columns.findIndex(it => it.column === column)
+    t.all_columns.splice(index, 1)
+    t.columnCurrentPage = 1
+    t.filterColumns()
+    // this.$set(this._mount.tables, t.guid, t)
+  }
   changeTableType (t) {
     t.kind = t.kind === modelRenderConfig.tableKind.fact ? 
modelRenderConfig.tableKind.lookup : modelRenderConfig.tableKind.fact
     this.setUniqueAlias(t)
@@ -1098,6 +1121,7 @@ class NModel extends Schama {
         getAllConnectsByGuid: this.getAllConnectsByGuid.bind(this),
         createAndUpdateSvgGroup: this.createAndUpdateSvgGroup.bind(this)
       }
+      options.computed_columns = this.computed_columns
       if (tableInfo.source_type === 1 && !options.isSecStorageEnabled) {
         if (!this.getFactTable()) {
           options.kind = modelRenderConfig.tableKind.fact
@@ -1367,6 +1391,10 @@ class NModel extends Schama {
       if (this.checkSameCCName(ccObj.columnName)) {
         let ccMeta = this.generateCCMeta(ccObj)
         this._mount.computed_columns.push(ccMeta)
+        // 更新事实表的columns
+        const factTable = this.getFactTable()
+        factTable.all_columns.push({...ccMeta, name: ccMeta.columnName, 
column: ccMeta.columnName, is_computed_column: true})
+        factTable.filterColumns()
         resolve(ccMeta)
       } else {
         reject()
@@ -1384,6 +1412,15 @@ class NModel extends Schama {
           resolve(c)
         }
       })
+      // 更新事实表的columns
+      const factTable = this.getFactTable()
+      factTable.all_columns.forEach((c) => {
+        if (c.guid === ccObj.guid) {
+          Object.assign(c, ccObj)
+          hasEdit = true
+          resolve(c)
+        }
+      })
       if (!hasEdit) {
         reject()
       }
@@ -1399,6 +1436,8 @@ class NModel extends Schama {
     this._delTableIndexByAlias(alias, column)
     // 删除partition里的cc
     this._delTableRelatedPartitionInfo(t, column)
+    // 删除 all_columns 里相关 cc
+    this._delCCInTableAllColumns(t, column)
   }
   // 删除可计算列
   delCC (cc) {
@@ -1586,7 +1625,7 @@ class NModel extends Schama {
           const firstPathLine = paths[0].getAttribute('d')
           paths[1].setAttribute('d', firstPathLine)
         } else {
-          this.createAndUpdateSvgGroup(line, this.allConnInfo[item].isBroken, 
'create')
+          this.createAndUpdateSvgGroup(line, {...this.allConnInfo[item], type: 
'create'})
         }
       })
     }
diff --git a/kystudio/src/components/studio/StudioModel/ModelEdit/table.js 
b/kystudio/src/components/studio/StudioModel/ModelEdit/table.js
index 2c0406f32a..40f92cecf8 100644
--- a/kystudio/src/components/studio/StudioModel/ModelEdit/table.js
+++ b/kystudio/src/components/studio/StudioModel/ModelEdit/table.js
@@ -24,6 +24,7 @@ class NTable {
     this.source_type = options.source_type
     this.batch_table_identity = options.batch_table_identity // kafka关联的hive表名
     this._cache_search_columns = this.columns // 搜索结果缓存
+    this.all_columns = [...this.columns, 
...options.computed_columns.filter(col => col.tableAlias === 
this.alias).map(item => ({...item, name: item.columnName, column: 
item.columnName, is_computed_column: true}))] // 所有挂在该表上的列(包括 cc 列)
     // this._parent = options._parent
     this.ST = null
     this.spreadOut = true
@@ -85,7 +86,7 @@ class NTable {
   }
   filterColumns () {
     let reg = new RegExp(this.filterColumnChar, 'i')
-    this.showColumns = this.columns.filter((col) => {
+    this.showColumns = this.all_columns.filter((col) => {
       return this.filterColumnChar ? reg.test(col.name) : true
     })
     this._cache_search_columns = this.showColumns
@@ -252,8 +253,8 @@ class NTable {
     return this.joinInfo[this.guid] || {}
   }
   getColumnObj (columnName) {
-    for (let i = 0; i < this.columns.length; i++) {
-      const col = this.columns[i]
+    for (let i = 0; i < this.all_columns.length; i++) {
+      const col = this.all_columns[i]
       if (col.name === columnName) {
         return col
       }
@@ -268,16 +269,17 @@ class NTable {
         col[key] = val
       }
     }
+    this.columns = this.all_columns.filter(it => !it.is_computed_column)
   }
-  changeColumnsProperty (key, val, _) {
-    this.columns.forEach((col) => {
-      if (_) {
-        _.$set(col, key, val)
-      } else {
-        col[key] = val
-      }
-    })
-  }
+  // changeColumnsProperty (key, val, _) {
+  //   this.columns.forEach((col) => {
+  //     if (_) {
+  //       _.$set(col, key, val)
+  //     } else {
+  //       col[key] = val
+  //     }
+  //   })
+  // }
   // 可计算列处理
   // 维度处理
   // dimension处理
diff --git 
a/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue
 
b/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue
index 9882c587a0..010c41ed35 100644
--- 
a/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue
+++ 
b/kystudio/src/components/studio/StudioModel/ModelList/ModelBuildModal/build.vue
@@ -278,7 +278,7 @@
   import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
   import vuex from 'store'
   import { handleError, transToUTCMs, getGmtDateFromUtcLike, kylinMessage } 
from 'util/business'
-  import { handleSuccessAsync, transToServerGmtTime, isDatePartitionType, 
isStreamingPartitionType, isSubPartitionType, kylinConfirm, split_array } from 
'util/index'
+  import { handleSuccessAsync, transToServerGmtTime, isDatePartitionType, 
isStreamingPartitionType, isSubPartitionType, kylinConfirm, split_array, 
objectClone, indexOfObjWithSomeKey } from 'util/index'
   import locales from './locales'
   import store, { types } from './store'
   import NModel from '../../ModelEdit/model.js'
@@ -530,7 +530,13 @@
     async handleLoadFormat () {
       try {
         this.isLoadingFormat = true
-        const response = await this.fetchPartitionFormat({ project: 
this.currentSelectedProject, table: this.selectedTable.name, partition_column: 
this.partitionMeta.column })
+        const ccColumns = this.modelInstance.getComputedColumns()
+        const index = indexOfObjWithSomeKey(ccColumns, 'columnName', 
this.partitionMeta.column)
+        const data = { project: this.currentSelectedProject, table: 
this.selectedTable.name, partition_column: this.partitionMeta.column }
+        if (index !== -1) { // 分区列是CC列
+          data.expression = ccColumns[index].innerExpression
+        }
+        const response = await this.fetchPartitionFormat(data)
         this.partitionMeta.format = await handleSuccessAsync(response)
         this.partitionColumnFormatChange(this.partitionMeta.format)
         this.isLoadingFormat = false
@@ -555,15 +561,15 @@
           }
         })
       }
-      // let ccColumns = this.modelInstance.getComputedColumns()
-      // let cloneCCList = objectClone(ccColumns)
-      // cloneCCList.forEach((x) => {
-      //   let cc = {
-      //     name: x.columnName,
-      //     datatype: x.datatype
-      //   }
-      //   result.push(cc)
-      // })
+      let ccColumns = this.modelInstance.getComputedColumns()
+      let cloneCCList = objectClone(ccColumns)
+      cloneCCList.forEach((x) => {
+        let cc = {
+          name: x.columnName,
+          datatype: x.datatype
+        }
+        result.push(cc)
+      })
       return result
     }
 
@@ -775,12 +781,17 @@
         partition_date_column: this.partitionMeta.table + '.' + 
this.partitionMeta.column,
         partition_date_format: this.partitionMeta.format
       }
+      const ccColumns = this.modelInstance.getComputedColumns()
+      const index = indexOfObjWithSomeKey(ccColumns, 'columnName', 
this.partitionMeta.column)
       try {
         const submitData = {
           project: this.currentSelectedProject,
           model: this.modelId,
           partition_desc: partition_desc
         }
+        if (index !== -1) { // 分区列是CC列
+          submitData.expression = ccColumns[index].innerExpression
+        }
         const response = await this.fetchNewestModelRange(submitData)
         if (submitData.model !== this.modelId) { // 
避免ajax耗时太长导致会覆盖新的model的load range数据
           return
diff --git 
a/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue 
b/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue
index ca48d1a37d..fa0841949f 100644
--- 
a/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue
+++ 
b/kystudio/src/components/studio/StudioModel/ModelList/ModelPartition/index.vue
@@ -145,7 +145,7 @@ import locales from './locales'
 import store, { types } from './store'
 import { timeDataType, dateFormats, timestampFormats, dateTimestampFormats } 
from 'config'
 import NModel from '../../ModelEdit/model.js'
-import { isDatePartitionType, isStreamingPartitionType, isSubPartitionType, 
kylinConfirm } from 'util'
+import { isDatePartitionType, isStreamingPartitionType, isSubPartitionType, 
kylinConfirm, objectClone } from 'util'
 import { handleSuccessAsync, handleError } from 'util/index'
 vuex.registerModule(['modals', 'ModelPartition'], store)
 
@@ -262,15 +262,15 @@ export default class ModelPartition extends Vue {
         }
       })
     }
-    // let ccColumns = this.modelInstance.getComputedColumns()
-    // let cloneCCList = objectClone(ccColumns)
-    // cloneCCList.forEach((x) => {
-    //   let cc = {
-    //     name: x.columnName,
-    //     datatype: x.datatype
-    //   }
-    //   result.push(cc)
-    // })
+    let ccColumns = this.modelInstance.getComputedColumns()
+    let cloneCCList = objectClone(ccColumns)
+    cloneCCList.forEach((x) => {
+      let cc = {
+        name: x.columnName,
+        datatype: x.datatype
+      }
+      result.push(cc)
+    })
     return result
   }
   get subPartitionColumnOtions () {
diff --git 
a/kystudio/src/components/studio/StudioModel/ModelList/ModelSaveConfig/index.vue
 
b/kystudio/src/components/studio/StudioModel/ModelList/ModelSaveConfig/index.vue
index b2758359b8..efc76eb115 100644
--- 
a/kystudio/src/components/studio/StudioModel/ModelList/ModelSaveConfig/index.vue
+++ 
b/kystudio/src/components/studio/StudioModel/ModelList/ModelSaveConfig/index.vue
@@ -310,6 +310,9 @@ vuex.registerModule(['modals', 'ModelSaveConfig'], store)
       setModalForm: types.SET_MODAL_FORM,
       resetModalForm: types.RESET_MODAL_FORM
     }),
+    ...mapMutations({
+      resetOtherColumns: 'RESET_OTHER_COLUMNS'
+    }),
     ...mapActions('DetailDialogModal', {
       callGlobalDetailDialog: 'CALL_MODAL'
     }),
@@ -469,7 +472,13 @@ export default class ModelPartitionModal extends Vue {
   async handleLoadFormat () {
     try {
       this.isLoadingFormat = true
-      const response = await this.fetchPartitionFormat({ project: 
this.currentSelectedProject, table: this.selectedTable.name, partition_column: 
this.partitionMeta.column })
+      const ccColumns = this.modelInstance.getComputedColumns()
+      const index = indexOfObjWithSomeKey(ccColumns, 'columnName', 
this.partitionMeta.column)
+      const data = { project: this.currentSelectedProject, table: 
this.selectedTable.name, partition_column: this.partitionMeta.column }
+      if (index !== -1) { // 分区列是CC列
+        data.expression = ccColumns[index].innerExpression
+      }
+      const response = await this.fetchPartitionFormat(data)
       this.partitionMeta.format = await handleSuccessAsync(response)
       this.changeColumn('format', this.partitionMeta.format)
       this.isLoadingFormat = false
@@ -566,15 +575,15 @@ export default class ModelPartitionModal extends Vue {
       })
     }
     // 暂不支持CC列做分区列
-    // let ccColumns = this.modelInstance.getComputedColumns()
-    // let cloneCCList = objectClone(ccColumns)
-    // cloneCCList.forEach((x) => {
-    //   let cc = {
-    //     name: x.columnName,
-    //     datatype: x.datatype
-    //   }
-    //   result.push(cc)
-    // })
+    let ccColumns = this.modelInstance.getComputedColumns()
+    let cloneCCList = objectClone(ccColumns)
+    cloneCCList.forEach((x) => {
+      let cc = {
+        name: x.columnName,
+        datatype: x.datatype
+      }
+      result.push(cc)
+    })
     return result
   }
   getColumnInfo (column) {
diff --git 
a/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue 
b/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
index db0a9f8452..6f9b978861 100644
--- a/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
+++ b/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
@@ -327,15 +327,15 @@ export default class TableJoinModal extends Vue {
   }
   get fColumns () {
     let ntable = this.fTable
-    if (ntable) {
-      return ntable.columns
+    if (ntable && !Array.isArray(ntable)) {
+      return ntable.kind === 'FACT' ? [...ntable.columns, ...this.ccColumns] : 
ntable.columns
     }
     return []
   }
   get pColumns () {
     let ntable = this.pTable
-    if (ntable) {
-      return ntable.columns
+    if (ntable && !Array.isArray(ntable)) {
+      return ntable.kind === 'FACT' ? [...ntable.columns, ...this.ccColumns] : 
ntable.columns
     }
     return []
   }
@@ -345,6 +345,9 @@ export default class TableJoinModal extends Vue {
   get pTable () {
     return this.form.tables && this.form.tables[this.selectP] || []
   }
+  get ccColumns () {
+    return this.form.modelInstance && this.form.modelInstance.computed_columns 
&& this.form.modelInstance.computed_columns.length > 0 ? 
this.form.modelInstance.computed_columns.map(it => ({...it, column: 
it.columnName, name: it.columnName, table_alias: it.tableAlias})) : []
+  }
   checkIsBrokenPrimaryKey (rule, value, callback) {
     if (value) {
       if (this.checkIsBroken(this.brokenPrimaryKeys, value)) {
diff --git a/kystudio/src/service/model.js b/kystudio/src/service/model.js
index 51004d16d5..7e31580d3b 100644
--- a/kystudio/src/service/model.js
+++ b/kystudio/src/service/model.js
@@ -188,7 +188,7 @@ export default {
     return window.kylinVm.$http.post(apiUrl + 'models/job_error_status', body, 
{ headers })
   },
   getModelDataNewestRange: (para) => {
-    return Vue.resource(apiUrl + 
`models/${para.model}/data_range/latest_data`).save({project: para.project, 
partition_desc: para.partition_desc})
+    return Vue.resource(apiUrl + 
`models/${para.model}/data_range/latest_data`).save(para)
   },
   loadModelConfigList: (para) => {
     return Vue.resource(apiUrl + 'models/config').get(para)

Reply via email to