You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
8.5 KiB

<template>
<div v-if="data.model">
<div class="row">
<div class="col-sm-2">
</div>
<div class="col-sm-10">
<h1 style="font-size:1.5rem;margin:.5em 0;">{{title}} {{data.erros}}</h1>
</div>
</div>
<div class="row">
<div class="col-12">
<form class="form-horizontal query" ref="form" :action="action" @submit.prevent="onSubmit($event)">
<div class="card" v-if="this.anonymous||hasPermission()">
<div class="card-body">
<template v-if="data.errors">
<div class="form-group" v-for="error in getValidationSummary(true)">
<div class="offset-sm-2 col-sm-10 ">
<div style="color:#dc3545;">{{error}}</div>
</div>
</div>
</template>
<input type="hidden" name="id" v-if="data.model.id" :value="data.model.id" />
<div class="form-group row" v-for="(value,key,index) in data.schema.properties" v-if="show(key,value)">
<label class="col-sm-2 col-form-label" :for="key">{{value.title}}:</label>
<div v-if="data.model" class="col-sm-6 form-control" style="border-color:transparent;height:auto;min-height:calc(2.25rem + 2px);">
<template v-if="value.readOnly&&mode!=='add'">
<input type="hidden" :name="key" :value="data.model[key]" />
<component :is="getDisplayComponent(key)" :title="value.title" :name="key" :value="data.model[key]" :data="data.data" v-if="data.model" />
</template>
<template v-else>
<component :is="getEditComponent(key)" mode="edit" :title="value.title" :name="key" :value.sync="data.model[key]" :data="data.data" :nullable="value.nullable" @change="change" />
</template>
<div style="height:1em;">
<span v-if="hasErrors(key)" class="field-validation-error text-danger">{{getPropertyErrors(key)}}</span>
<span v-else class="text-danger field-validation-valid"></span>
</div>
</div>
<div class="col-sm-4">{{value.description}}</div>
</div>
</div>
<div class="card-footer">
<div class="row">
<div class="col-sm-2">
</div>
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">确定</button>
<router-link :to="back" class="btn btn-default" v-if="back">返回</router-link>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
name:'form',
props: [
'anonymous',
'title',
'url',
'action',
'back',
'mode',
'id',
'callback',
//
'service',
'area',
'entity',
'model',
'id',
],
data: function () {
return {
data: {
errors: [],
schema: null,
model: null,
data: null
}
}
},
mounted: function () {
if (!this.anonymous) {
this.anonymous = false;
}
if (!this.area) {
this.area = 'platform';
}
if (!this.mode) {
this.mode = 'edit';
}
if (!this.title) {
this.title = (this.mode === 'edit' ? '编辑' : '新建') + this.name;
}
if (!this.url) {
this.url = this.area + '/' + this.model + (this.mode === 'edit' ? ('?id=' + this.id) : '');
}
if (!this.action) {
if (this.url) {
this.action = this.url + 'Api';
}
else {
this.action = this.area + '/' + this.model + '/' + this.mode + '/' + 'Api';
}
}
if (!this.back) {
if (this.entity) {
this.back = this.area + '/' + this.model +'/index.html'
}
}
this.load();
},
computed: {
name: function () {
return this.data.schema ? this.data.schema.title : '';
}
},
methods: {
load: function () {
var vm = this;
axios.get(config.service(this.url)).then(function (response) {
vm.data = response.data;
});
},
getSchema: function () {
return this.data.schema;
},
getModel: function () {
return this.data.model;
},
getErrors: function () {
return this.data.errors;
},
hasErrors: function (key) {
key = key.toLowerCase();
return Enumerable.from(this.getErrors()).any(o => o.key.toLowerCase() === key);
},
getValidationSummary: function (excludePropertyErrors) {
var query = Enumerable.from(this.getErrors());
if (excludePropertyErrors) {
query = query.where(o => o.key === '')
}
return query.select(o => o.value.errors[0].errorMessage).toArray();
},
getPropertyErrors: function (key) {
key = key.toLowerCase();
return Enumerable.from(this.getErrors())
.where(o => o.key.toLowerCase() === key).selectMany(o => o.value.errors).select(o => o.errorMessage).toArray().join(',');
},
change: function (name) {
return this.$validProperty(name);
},
hasPermission: function () {
var permission = this.mode + '-' + this.entity;
return Enumerable.from(store.state.permissions).any(o => o.toLowerCase() === permission.toLowerCase());
},
getEditComponent: function (key) {
var property = this.data.schema.properties[key];
var template = 'views-shared-edit-' + (property.ui || property.format || property.type);
return template;
},
getDisplayComponent: function (key) {
var property = this.data.schema.properties[key];
var template = 'views-shared-display-' + (property.ui || property.format || property.type);
return template;
},
show: function (key, value) {
return key !== 'id';
},
onSubmit: function (e) {
var vm = this;
vm.$valid().then(function (value) {
if (vm.data.errors.length === 0) {
axios.post(e.target.action, vm.data.model).then(function (response) {
if (vm.callback) {
vm.callback(response);
}
else {
if (response.status === 204) {
var url = vm.base + 'index.html?area=' + vm.area + '&entity=' + vm.entity + '&model=' + vm.model;
setTimeout(function () {
router.push(url);
}, 1000);
}
else {
vm.data = response.data;
}
}
});
}
});
}
}
}
</script>