Skip to content

Commit

Permalink
feat(dbm): impl db schema; impl create db;
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow committed Oct 14, 2021
1 parent d7a277b commit 2f29bfd
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 44 deletions.
39 changes: 36 additions & 3 deletions packages/system-client/src/api/collec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import { Cloud } from 'laf-client-sdk'

/**
* Get collection list
* @param {*} query
* @param {*} page
* @param {*} pageSize
*/
export function getCollections() {
const appid = store.state.app.appid
Expand All @@ -17,6 +14,42 @@ export function getCollections() {
})
}

/**
* Create collection
* @param {string} collectionName
*/
export function createCollection(collectionName) {
const appid = store.state.app.appid
return request({
url: `/apps/${appid}/dbm/collections`,
method: 'post',
data: {
collectionName
}
})
}

/**
* Update collection
* @param {string} collectionName
* @param {object} validatorSchema
* @param {string} validatorLevel
*/
export function updateCollection(collectionName, validatorSchema, validatorLevel = 'strict') {
const appid = store.state.app.appid
return request({
url: `/apps/${appid}/dbm/collections`,
method: 'put',
data: {
collectionName,
options: {
validatorSchema,
validatorLevel
}
}
})
}

/**
* 获取集合的索引信息
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/system-client/src/utils/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import axios from 'axios'
import { MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { showError, showInfo } from './show'
import { showInfo } from './show'

// create an axios instance
const service = axios.create({
Expand Down Expand Up @@ -66,7 +66,7 @@ service.interceptors.response.use(
return Promise.reject(error)
}

showError(error.message)
// showError(error.message)
return Promise.reject(error)
}
)
Expand Down
166 changes: 137 additions & 29 deletions packages/system-client/src/views/database/collections.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
<div style="margin: 10px 0;">
<el-input v-model.trim="listQuery._id" size="mini" placeholder="请输入_id查找" style="width:200px" :disabled="!collectionName" @keyup.enter.native="handleFilter" />
<el-button size="mini" plain type="default" style="margin-left: 10px" icon="el-icon-search" :disabled="!collectionName" @click="handleFilter">搜索</el-button>
<el-button size="mini" plain type="primary" style="margin-left: 10px" @click="showIndexesList = true">新建集合</el-button>
<el-button size="mini" plain type="primary" style="margin-left: 10px" @click="showCreateCollectionForm = true">新建集合</el-button>
<el-button size="mini" plain type="default" style="margin-left: 10px" :disabled="!collectionName" @click="showIndexesList = true">索引管理</el-button>
<el-button size="mini" plain type="default" style="margin-left: 10px" :disabled="!collectionName" @click="showIndexesList = true">集合结构</el-button>
<el-button size="mini" plain type="default" style="margin-left: 10px" :disabled="!collectionName" @click="handleShowCollectinoSchema">集合结构</el-button>
<el-button size="mini" plain type="success" style="margin-left: 10px" icon="el-icon-plus" :disabled="!collectionName" @click="handleCreateRecord">添加记录</el-button>

</div>
<el-container v-show="tabType === 'record'" style="height: calc(100vh - 200px); border: 1px solid #eee">
<el-container style="height: calc(100vh - 130px); border: 1px solid #eee">
<el-aside width="240px" class="collection-list">
<div class="label">选择集合</div>
<div class="label">
选择集合
<el-button :loading="loading" size="medium" circle type="text" style="margin-left: 10px" icon="el-icon-refresh" @click="getCollections" />
</div>
<el-radio-group v-model="collectionName" class="radio-group">
<el-radio v-for="item in collections" :key="item.name" class="collection-radio" border size="medium" :label="item.name" />
</el-radio-group>
Expand Down Expand Up @@ -47,7 +50,6 @@
title="索引管理"
size="50%"
:visible.sync="showIndexesList"
:direction="direction"
>
<div>
<div style="margin: 10px 0;">
Expand All @@ -74,12 +76,25 @@
</div>
</el-drawer>

<!-- 编辑集合数据结构 -->
<el-drawer
:title="'集合数据结构:' + collectionName"
size="50%"
:visible.sync="showCollectionSchemaForm"
>
<el-header>
<el-button :loading="loading" size="mini" type="primary" :disabled="!collectionName" @click="updateCollectionSchema">保存</el-button>
</el-header>
<el-main>
<json-editor v-model="collectionSchemaForm.schema" class="db-editor" :line-numbers="true" :dark="false" :height="600" />
</el-main>
</el-drawer>

<!-- 添加/编辑文档表单 -->
<el-drawer
:title="formMode === 'edit' ? '编辑文档' : '添加文档'"
size="50%"
:visible.sync="showDocEditorForm"
:direction="direction"
>
<el-header>
<el-button size="mini" type="primary" :disabled="!collectionName" @click="formMode === 'edit' ? updateDocument() : addDocument()">保存</el-button>
Expand All @@ -89,7 +104,26 @@
</el-main>
</el-drawer>

<!-- 索引dialog -->
<!-- 创建集合表单 -->
<el-dialog title="创建集合" :visible.sync="showCreateCollectionForm" width="500px">
<el-form :model="createCollectionForm" label-width="80px" style="width:460px">
<el-form-item label="集合名称">
<el-input v-model="createCollectionForm.collectionName" placeholder="请输入新集合名称" />
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button
size="mini"
type="default"
@click="showCreateCollectionForm = false"
>
取消
</el-button>
<el-button size="mini" type="primary" @click="handleCreateCollection">确认</el-button>
</div>
</el-dialog>

<!-- 创建索引表单 -->
<el-dialog title="创建索引" :visible.sync="showCreateIndexDialog">
<el-form :model="createIndexForm" label-width="100px" style="width:600px">
<el-form-item label="索引名称">
Expand Down Expand Up @@ -120,9 +154,10 @@

<script>
import { getCollections, getCollectionIndexes, deleCollectionIndex, setCollectionIndexes, getDb } from '@/api/collec'
import { getCollections, getCollectionIndexes, deleCollectionIndex, setCollectionIndexes, getDb, createCollection, updateCollection } from '@/api/collec'
import JsonEditor from '@/components/JsonEditor/param'
import MiniPagination from '@/components/Pagination/mini'
import { showError, showSuccess } from '@/utils/show'
const db = getDb()
Expand All @@ -133,23 +168,38 @@ export default {
filters: {},
data() {
return {
loading: false,
collections: [],
collectionName: '',
tabType: 'record',
// 文档列表相关
listQuery: {
limit: 10,
page: 1
},
list: [],
indexes: [],
total: 0,
// 添加/编辑文档表单
record: {},
// newRecord: {},
formMode: 'edit', // doc editor form mode
showCreateIndexDialog: false,
showDocEditorForm: false,
createIndexForm: {},
showIndexesList: false,
formMode: 'edit',
createIndexForm: {}
// 创建集合表单
showCreateCollectionForm: false,
createCollectionForm: {
collectionName: ''
},
// 管理集合结构表单
showCollectionSchemaForm: false,
collectionSchemaForm: {
schema: null
}
}
},
watch: {
Expand All @@ -165,7 +215,9 @@ export default {
},
methods: {
async getCollections() {
this.loading = true
const ret = await getCollections()
.finally(() => { this.loading = false })
this.collections = ret || []
},
Expand Down Expand Up @@ -199,12 +251,76 @@ export default {
this.total = total
},
async handleCreateCollection() {
const collectionName = this.createCollectionForm.collectionName
if (!collectionName) {
return showError('集合名不可为空')
}
await createCollection(collectionName)
.then(res => {
showSuccess('集合创建成功!')
this.getCollections()
})
.catch(err => {
console.error(err.response.data)
if (err.response?.data?.code === 'NamespaceExists') {
showError('错误:该集合已存在')
} else {
showError('创建集合失败: ' + err.response?.data?.error)
}
})
.finally(() => {
this.createCollectionForm.collectionName = ''
this.showCreateCollectionForm = false
})
},
async handleShowCollectinoSchema() {
const deulfaSchema = {
'bsonType': 'object',
'required': [],
'properties': {
'_id': {
'description': 'ID,系统自动生成'
}
}
}
// find the collection schema
const [collection] = this.collections.filter(coll => coll.name === this.collectionName)
if (!collection) return
const schema = collection.options?.validator?.$jsonSchema
this.collectionSchemaForm.schema = schema || deulfaSchema
this.showCollectionSchemaForm = true
},
async updateCollectionSchema() {
await this.$confirm('确认要更新集合结构?', '确认')
const collectionName = this.collectionName
if (!collectionName) return
const schema = this.collectionSchemaForm.schema
const schemaData = typeof schema === 'string' ? JSON.parse(schema) : schema
this.loading = true
await updateCollection(collectionName, schemaData)
.then(res => {
showSuccess('集合更新成功')
this.getCollections()
})
.catch(err => {
console.error(err.response.data)
showError('更新集合失败: ' + err.response?.data?.error)
})
.finally(() => { this.loading = false })
},
getClass(val) {
let record = this.record
const isString = typeof (record) === 'string'
if (isString) record = JSON.parse(record)
try {
if (isString) record = JSON.parse(record)
} catch (error) {
return
}
return val._id === record._id ? 'active' : ''
},
Expand All @@ -214,8 +330,9 @@ export default {
await db.collection(this.collectionName)
.where({ _id: record._id })
.remove()
},
this.getList()
},
handleEditRecord(val) {
this.record = val
this.formMode = 'edit'
Expand Down Expand Up @@ -248,16 +365,13 @@ export default {
const params = JSON.parse(this.record)
const r = await db.collection(this.collectionName)
.add({
...params,
created_at: Date.now()
...params
})
if (!r.id) {
this.$notify({
type: 'error',
message: '创建失败!' + r.error
})
return
if (r.error) {
console.log(r.code)
const message = typeof r.error !== 'string' ? JSON.stringify(r.error) : r.error
return showError('创建失败: ' + message)
}
this.$notify({
Expand All @@ -282,7 +396,6 @@ export default {
const ret = await getCollectionIndexes(this.collectionName)
this.indexes = ret
},
/**
* 删除索引
*/
Expand Down Expand Up @@ -312,7 +425,6 @@ export default {
this.showCreateIndexDialog = false
this.getIndexes()
},
handleCreateIndex() {
this.showCreateIndexDialog = true
}
Expand Down Expand Up @@ -360,7 +472,6 @@ export default {
flex-direction: column;
padding: 3px;
width: 100%;
// height: calc(100vh - 200px);
overflow-y: scroll;
.record-item {
Expand All @@ -377,9 +488,6 @@ export default {
width: 160px;
text-align: right;
padding-top: 15px;
.tools-btn {
// margin-left: 10px;
}
}
}
Expand Down
Loading

0 comments on commit 2f29bfd

Please sign in to comment.