Skip to content

Commit

Permalink
model table
Browse files Browse the repository at this point in the history
  • Loading branch information
szuprefix committed Sep 17, 2019
1 parent 06dc43c commit bf34fa6
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 29 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-django",
"version": "0.5.0",
"version": "0.5.1",
"description": "个人实验项目, 本框架的目标是借鉴并超越django admin的自动化思想, 实现UI前端的极简快速定制开发",
"main": "index.js",
"files": [
Expand Down
1 change: 1 addition & 0 deletions src/components/model/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
this.model.clear()
this.mid = this.model.id = undefined
this.formValue = Object.assign({},this.model.data)
this.$nextTick(this.$refs.form.$refs.form.clearValidate)
},
onDelete(){
this.$confirm('确定要删除吗?', {type: 'warning'}).then(() => {
Expand Down
4 changes: 4 additions & 0 deletions src/components/model/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ export default function (appModel, defaults, eventor) {
return data
})//.catch((error) => this.onErrors(error))
},
removeRelateObject (rel, id) {
this.data[rel] = this.data[rel].filter(a => a !== id)
return this.save()
},
destroy(id){
id = id || this.id
return axios.delete(this.getDetailUrl(id)).then(() => {
Expand Down
229 changes: 229 additions & 0 deletions src/components/model/MultiCreator.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
<template>
<div>
<div>
<el-button-group>
<el-button type="plain" size="mini" icon="el-icon-edit" @click="onEdit">编辑</el-button>
<el-button type="plain" size="mini" icon="el-icon-view" @click="onView">预览</el-button>
</el-button-group>
<el-radio-group v-model="splitChar" size="mini">
<el-radio-button :label="'\t'" title="字段用Tab符分隔">TAB</el-radio-button>
<el-radio-button label="," title="字段用逗号分隔">,</el-radio-button>
<el-radio-button label="|" title="字段用竖线分隔">|</el-radio-button>
</el-radio-group>
</div>
<el-row :gutter="40">
<el-col :span="editZoneSpan">
<el-input ref="content" type="textarea" :autosize="{ minRows: 24}" v-model="currentValue"
:placeholder="contentSample" @change="change"></el-input>
</el-col>
<el-col :span="viewZoneSpan">
<div class="flex-right">
<el-button type="primary" @click="batchCreate">批量创建</el-button>
</div>
<el-table stripe border size="mini" :data="records" v-if="loaded">
<el-table-column :prop="f.name" :column-key="f.name" :label="f.label || f.name"
:min-width="f.min_width" :width="f.width" :class-name="f.type"
:type="f.type"
:key="f.name" v-for="f in fieldItems"></el-table-column>
<el-table-column :prop="_result" label="执行结果" v-if="began">
<template slot-scope="{row}">

<el-alert
:title="row._result.info"
:type="row._result.status === 'success' ? 'success':'error'"
v-if="row._result"
show-icon>
</el-alert>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import ForeignKeyTranslater from '../../utils/foreign_key_translater'
import Model from './Model'
import {debounce} from 'lodash'
import Qs from 'qs'
export default{
model: {
event: "change"
},
props: {
value: {
type: String,
default: ''
},
fields: Array,
appModel: String,
defaults: {
type: Object, default: () => {
return {}
}
},
pk: {type: String, default: 'code'}
},
data () {
return {
model: Model(this.appModel, this.defaults, this.$store.state.bus),
edit: true,
view: true,
records: [],
currentValue: null,
splitChar: '\t',
began: false,
queueIndex: 0,
tmap: {}
}
},
components: {
// PaperView
},
mounted (){
this.currentValue = this.value
this.model.loadOptions().then(this.loadForeignKeyTranslater).then(this.genRecords)
},
methods: {
loadForeignKeyTranslater(){
Object.keys(this.model.fieldConfigs).forEach((fn) => {
let f = this.model.fieldConfigs[fn]
if (f.model && f.multiple != true) {
ForeignKeyTranslater.getMap(f.model).then((rs) => {
let m = {}
rs.forEach((d) => {
m[d.name] = d.id
})
this.tmap[f.name] = {map: m, field: f}
// console.log(this.tmap)
})
}
})
return Promise.resolve()
},
genRecords: debounce(function () {
this.began = false
let s = this.currentValue.trim()
if (s.length == 0) {
return []
}
if (!this.loaded) {
return []
}
this.records = s.split('\n').map((l) => {
let d = {}
l.split(this.splitChar).forEach((v, i) => {
d[this.fieldItems[i].name] = v
})
return d
})
}, 2000),
setCurrentValue(value) {
if (value === this.currentValue) return
this.currentValue = value
},
onEdit () {
this.edit = true
this.view = !this.view
},
onView () {
this.view = true
this.edit = !this.edit
},
change(val){
this.$emit('input', val)
},
setCurrentValue(value) {
this.currentValue = value
},
batchCreate(){
this.began = true
this.queueIndex = 0
this.postOne()
},
setResult(i, d){
let r = this.records[i]
r['_result'] = d
this.$set(this.records, i, r)
},
translateForeignKey(a){
Object.keys(this.tmap).forEach((fn) => {
let t = this.tmap[fn]
let f = t.field
let m = t.map
a[f.name] = m[a[f.name]]
console.log(a)
})
},
postOne(){
let qi = this.queueIndex
if (qi < this.records.length) {
let a = Object.assign({}, this.defaults, this.records[qi])
this.translateForeignKey(a)
let q = {}
q[this.pk] = a[this.pk]
this.$http.get(`${this.model.getListUrl()}?${Qs.stringify(q)}`).then(({data}) => {
if (data.count > 0) {
let r = data.results[0]
a = Object.assign(r, a)
return this.$http.put(`${this.model.getListUrl()}${a.id}/`, a)
} else {
return this.$http.post(`${this.model.getListUrl()}`, a)
}
}).then((data) => {
this.setResult(qi, {status: 'success', info: '成功'})
}).catch((error) => {
this.setResult(qi, {status: 'failed', info: error.msg})
}).then(() => {
this.postOne()
})
} else {
this.model.emitPosted()
console.log("batch done")
}
this.queueIndex += 1
}
},
computed: {
loaded(){
return Object.keys(this.model.fieldConfigs).length > 0
},
editZoneSpan (){
return this.edit ? (this.view ? 10 : 24) : 0
},
viewZoneSpan (){
return this.view ? (this.edit ? 14 : 24) : 0
},
fieldNames(){
if (!this.loaded) {
return []
}
return this.fieldItems.map((a) => a.label || a.name)
},
contentSample(){
return this.fieldNames.join(this.splitChar)
},
fieldItems(){
return this.fields.map((a) => {
if (typeof a == 'string') {
return this.model.fieldConfigs[a]
}
return a
})
}
},
watch: {
'value'(val, oldValue) {
this.currentValue = val
},
currentValue () {
this.$emit('change', this.currentValue)
this.genRecords()
},
splitChar () {
this.genRecords()
}
}
}
</script>
3 changes: 3 additions & 0 deletions src/components/model/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@
watch: {
selectedValue(v){
this.loadValueObjects(v)
},
value (v) {
this.selectedValue = v
}
}
}
Expand Down

0 comments on commit bf34fa6

Please sign in to comment.