[Merge] Merge

This commit is contained in:
jym503558564
2020-04-09 21:15:19 +08:00
13 changed files with 207 additions and 73 deletions

View File

@@ -75,23 +75,38 @@ export default {
type = ''
field.component = Select2
break
case 'string':
type = 'input'
if (!fieldMeta.max_length) {
field.el.type = 'textarea'
}
break
default:
type = 'input'
break
}
if (type === 'radio-group') {
const options = fieldMeta.choices.map(v => {
return { label: v.display_name, value: v.value }
})
if (options.length > 4) {
type = 'select'
field.el.filterable = true
}
}
field.type = type
return field
},
generateFieldByName(name, field) {
switch (name) {
case 'email':
field.el = { type: 'email' }
field.el.type = 'email'
break
case 'password':
field.el = { type: 'password' }
field.el.type = 'password'
break
case 'comment':
field.el = { type: 'textarea' }
field.el.type = 'textarea'
break
}
return field
@@ -109,15 +124,16 @@ export default {
return field
},
generateField(name) {
let field = {}
let field = { id: name, prop: name, el: {}}
const fieldMeta = this.meta[name] || {}
field.id = name
field.prop = name
field.label = fieldMeta.label
field = this.generateFieldByType(fieldMeta.type, field, fieldMeta)
field = this.generateFieldByName(name, field)
field = this.generateFieldByOther(field, fieldMeta)
field = Object.assign(field, this.fieldsMeta[name] || {})
if (name === 'name') {
console.log(field)
}
return field
},
generateFieldGroup(data) {

View File

@@ -4,7 +4,7 @@
<script>
import DataTable from '../DataTable'
import { DetailFormatter, DisplayFormatter, BooleanFormatter, ActionsFormatter } from '@/components/ListTable/formatters/index'
import { DetailFormatter, DisplayFormatter, BooleanFormatter, ActionsFormatter } from '@/components/ListTable/formatters'
import { optionUrlMeta } from '@/api/common'
export default {
name: 'AutoDataTable',
@@ -59,7 +59,8 @@ export default {
label: this.$tc('Actions'),
align: 'center',
formatter: ActionsFormatter,
width: '150px'
width: '150px',
actions: this.config.actions || {}
}
break
case 'is_valid':

View File

@@ -1,9 +1,33 @@
export { default as DetailFormatter } from './DetailFormatter'
export { default as DisplayFormatter } from './DisplayFormatter'
export { default as BooleanFormatter } from './ChoicesFormatter'
export { default as ActionsFormatter } from './ActionsFormatter'
export { default as ExpandPreFormatter } from './ExpandPreFormatter'
export { default as LengthFormatter } from './LengthFormatter'
export { default as RouterFormatter } from './RouterFormatter'
export { default as OutputExpandFormatter } from './OutputExpandFormatter'
export { default as ExpandAssetPermissionFormatter } from './ExpandAssetPermissionFormatter'
import DetailFormatter from './DetailFormatter'
import DisplayFormatter from './DisplayFormatter'
import BooleanFormatter from './ChoicesFormatter'
import ActionsFormatter from './ActionsFormatter'
import ExpandPreFormatter from './ExpandPreFormatter'
import LengthFormatter from './LengthFormatter'
import RouterFormatter from './RouterFormatter'
import OutputExpandFormatter from './OutputExpandFormatter'
import ExpandAssetPermissionFormatter from './ExpandAssetPermissionFormatter'
export default {
DetailFormatter,
DisplayFormatter,
BooleanFormatter,
ActionsFormatter,
ExpandPreFormatter,
LengthFormatter,
RouterFormatter,
OutputExpandFormatter,
ExpandAssetPermissionFormatter
}
export {
DetailFormatter,
DisplayFormatter,
BooleanFormatter,
ActionsFormatter,
ExpandPreFormatter,
LengthFormatter,
RouterFormatter,
OutputExpandFormatter,
ExpandAssetPermissionFormatter
}

View File

@@ -58,7 +58,10 @@ const cn = {
'cancel': '取消',
'Import': '导入',
'Export': '导出',
'Other': '其它'
'Other': '其它',
'Create success': '创建成功',
'Deactive selected': '禁用所选',
'Active selected': '激活所选'
},
route: {
'dashboard': '仪表盘',
@@ -104,7 +107,8 @@ const cn = {
'PasswordChangeLog': '改密日志',
'Settings': '系统设置',
'UserCreate': '创建用户',
'UserGroupCreate': '创建用户组'
'UserGroupCreate': '创建用户组',
'UserUpdate': '更新用户'
},
// 用户模块翻译
users: {

View File

@@ -1,7 +1,17 @@
<template>
<Page>
<Page v-loading="loadding">
<IBox>
<AutoDataForm ref="form" :form="form" :fields="fields" :url="url" v-bind="$attrs" v-on="$listeners" @submit="handleSubmit" />
<AutoDataForm
v-if="!loadding"
ref="form"
:method="method"
:form="form"
:fields="fields"
:url="totalUrl"
v-bind="$attrs"
v-on="$listeners"
@submit="handleSubmit"
/>
</IBox>
</Page>
</template>
@@ -18,55 +28,87 @@ export default {
type: String,
required: true
},
method: {
type: String,
default: 'post'
},
fields: {
type: Array,
default: () => {
return []
}
},
form: {
object: {
type: Object,
default: () => { return {} }
default: () => ({})
},
initial: {
type: Object,
default: () => ({})
},
onSubmit: {
type: Function,
default: null
},
getMethod: {
type: Function,
default: function() {
const params = this.$route.params
if (params.id) {
return 'put'
} else {
return 'post'
}
}
},
getUrl: {
type: Function,
default: function() {
const params = this.$route.params
let url = this.url
if (params.id) {
url = `${url}/${params.id}/`
}
return url
}
}
},
data() {
return {
form: {},
loadding: true
}
},
computed: {
method() {
const method = this.getMethod(this)
return method
},
totalUrl() {
return this.getUrl()
}
},
mounted() {
if (this.method === 'put') {
this.getObjectDetail()
} else {
this.form = Object.assign(this.form, this.initial)
this.loadding = false
}
},
methods: {
getFormRef(comp) {
if (comp.$refs.form) {
return this.getFormRef(comp.$refs.form)
}
return comp
},
handleSubmit(values, form) {
let handler = this.onSubmit || this.defaultOnSubmit
handler = handler.bind(this)
const fields = form.$refs.elForm.fields
console.log('submit', values)
console.log('form.fields', fields)
const field = fields[0]
field.error = '滴滴滴滴滴多滴滴滴'
return handler(values, form)
},
defaultPerformSubmit(validValues) {
return this.$axios[this.method](this.totalUrl, validValues)
},
defaultOnSubmit(validValues, form) {
this.$axios.post(this.url, validValues).then(() => {
this.defaultPerformSubmit(validValues).then(() => {
const msg = this.$tc('Create success')
this.$message.success(msg)
setTimeout(() => {
this.$router.push({ name: 'UserList' })
}, 500)
this.$router.push({ name: 'UserList' })
}).catch(error => {
console.log(form)
const response = error.response
@@ -76,6 +118,15 @@ export default {
console.log(data)
}
})
},
getObjectDetail() {
this.$axios.get(this.totalUrl).then(data => {
this.form = data
}).catch(error => {
console.log(error)
}).finally(() => {
this.loadding = false
})
}
}
}

View File

@@ -25,7 +25,7 @@
import Page from '../Page/'
import ActionsGroup from '@/components/ActionsGroup'
export default {
name: 'BaseDetailPage',
name: 'GenericDetailPage',
components: {
Page,
ActionsGroup

View File

@@ -3,7 +3,7 @@ export { default as NavHeader } from './NavHeader'
export { default as AppMain } from './AppMain'
export { default as Page } from './Page'
export { default as TagsView } from './TagsView'
export { default as BaseDetailPage } from './BaseDetailPage'
export { default as GenericDetailPage } from './GenericDetailPage'
export { default as SubMenuPage } from './SubMenuPage'
export { default as Footer } from './Footer'
export { default as IBox } from './IBox'

View File

@@ -70,14 +70,14 @@ export const constantRoutes = [
component: () => import('@/views/users/UserCreateUpdate.vue'), // Parent router-view
name: 'UserCreate',
hidden: true,
meta: { title: 'UserCreate', activeMenu: '/users/users' }
meta: { title: 'UserCreate', activeMenu: '/users/users', action: 'create' }
},
{
path: 'users/update/:id',
path: 'users/:id/update',
component: () => import('@/views/users/UserCreateUpdate.vue'), // Parent router-view
name: 'UserEdit',
name: 'UserUpdate',
hidden: true,
meta: { title: 'UserEdit' }
meta: { title: 'UserUpdate', activeMenu: '/users/users', action: 'update' }
},
{
path: 'users/detail/:id',

View File

@@ -235,3 +235,29 @@ td .el-button.el-button--mini {
.el-radio__input.is-checked+.el-radio__label {
color: inherit;
}
.el-radio__input.is-checked .el-radio__inner {
border-color: #409EFF;
background-color: #409EFF;
}
.el-checkbox__input.is-checked .el-checkbox__inner {
border-color: #409EFF;
background-color: #409EFF;
}
.el-radio__inner:hover {
border-color: #409EFF;
}
.el-textarea__inner {
border-radius: 0;
}
.el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {
border-color: #409EFF;
background-color: #409EFF;
}
.el-checkbox__inner:hover {
border-color: #409EFF;
}

View File

@@ -5,7 +5,6 @@
@import './sidebar.scss';
@import './element-index.css';
@import './menu.scss';
@import 'vue-select/src/scss/vue-select.scss';
@import "./font-awesome/font-awesome.min.css";
body {

View File

@@ -1,5 +1,5 @@
<template>
<GenericCreateUpdatePage :fields="fields" :form="form" :fields-meta="fieldsMeta" :url="url" />
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
</template>
<script>
@@ -9,8 +9,9 @@ export default {
GenericCreateUpdatePage
},
data() {
const errors = { name: '' }
return {
form: {
initial: {
password_strategy: 0,
mfa_level: 0,
source: 'local',
@@ -19,52 +20,58 @@ export default {
},
fields: [
[this.$t('users.' + 'Account'), ['name', 'username', 'email', 'groups']],
[this.$t('users.' + 'Authentication'), ['password_strategy', 'password', 'mfa_level', 'source']],
[this.$t('users.' + 'Authentication'), ['password_strategy', 'password', 'public_key', 'mfa_level', 'source']],
[this.$t('users.' + 'Secure'), ['role', 'date_expired']],
[this.$tc('Other'), ['phone', 'wechat', 'comment']]
],
errors: errors,
url: '/api/v1/users/users/',
fieldsMeta: {
name: {
el: {
error: '无措'
}
},
password_strategy: {
hidden: () => {
return this.$route.params.id
}
},
password: {
hidden: (formValue, item) => {
console.log('hidden password', formValue.password_strategy)
if (this.$route.params.id === undefined) {
return formValue.password_strategy !== 1
} else {
return true
if (this.$route.meta.action === 'update') {
return false
}
return formValue.password_strategy !== 1
}
},
public_key: {
hidden: (formValue, item) => {
return this.$route.meta.action !== 'update'
}
},
groups: {
el: {
value: [],
url: '/api/v1/users/groups/'
},
rules: [
this.serverErrorRule
]
}
}
}
}
},
mounted() {
setTimeout(() => {
this.errors.name = 'dididi'
}, 3000)
},
methods: {
debug() {
console.log(this)
},
serverErrorRule(rule, value, callback) {
console.log('Server error rule')
console.log(rule)
console.log(value)
}
}
}
</script>
<style lang="less" scoped>
.el-form /deep/ .el-select{
width:100%;
}
.el-form /deep/ .el-form-item__content > .el-date-editor{
width:100%;
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<BaseDetailPage :submenu="submenu" :active-menu="activeSubMenu" :title="title">
<GenericDetailPage :submenu="submenu" :active-menu="activeSubMenu" :title="title">
<div slot="info">
<el-row :gutter="20">
<el-col :span="14">
@@ -18,18 +18,18 @@
</el-col>
</el-row>
</div>
</BaseDetailPage>
</GenericDetailPage>
</template>
<script>
import { getUserGroupDetail, getUserGroupMembers } from '@/api/user'
import { BaseDetailPage } from '@/layout/components'
import { GenericDetailPage } from '@/layout/components'
import DetailCard from '@/components/DetailCard'
import Select2 from '@/components/Select2'
export default {
components: {
BaseDetailPage,
GenericDetailPage,
DetailCard,
Select2
},

View File

@@ -16,7 +16,13 @@ export default {
columns: [
'name', 'username', 'role', 'groups_display', 'source', 'is_valid', 'actions'
],
detailRoute: 'UserDetail'
columnsMeta: {
},
detailRoute: 'UserDetail',
actions: {
updateRoute: 'UserUpdate'
}
},
headerActions: {
createRoute: 'UserCreate',