新增:系统配置完善
parent
9568ac0e00
commit
03f51f3706
|
@ -283,26 +283,29 @@ class SystemConfig(CoreModel):
|
|||
parent = models.ForeignKey(to='self', verbose_name='父级', on_delete=models.CASCADE,
|
||||
db_constraint=False, null=True, blank=True, help_text="父级")
|
||||
title = models.CharField(max_length=50, verbose_name="标题", help_text="标题")
|
||||
key = models.CharField(max_length=20, verbose_name="键", help_text="键")
|
||||
key = models.CharField(max_length=20, verbose_name="键", help_text="键", db_index=True)
|
||||
value = models.JSONField(max_length=100, verbose_name="值", help_text="值", null=True, blank=True)
|
||||
sort = models.IntegerField(default=0, verbose_name="排序", help_text="排序", blank=True)
|
||||
status = models.BooleanField(default=False, verbose_name="启用状态", help_text="启用状态")
|
||||
data_options = models.JSONField(verbose_name="数据options", help_text="数据options", null=True, blank=True)
|
||||
FORM_ITEM_TYPE_LIST = (
|
||||
(0, 'text'),
|
||||
(1, 'textarea'),
|
||||
(2, 'number'),
|
||||
(3, 'select'),
|
||||
(4, 'radio'),
|
||||
(1, 'datetime'),
|
||||
(2, 'date'),
|
||||
(3, 'textarea'),
|
||||
(4, 'select'),
|
||||
(5, 'checkbox'),
|
||||
(6, 'date'),
|
||||
(7, 'datetime'),
|
||||
(8, 'time'),
|
||||
(9, 'imgs'),
|
||||
(10, 'files'),
|
||||
(6, 'radio'),
|
||||
(7, 'img'),
|
||||
(8, 'file'),
|
||||
(9, 'switch'),
|
||||
(10, 'number'),
|
||||
(11, 'array'),
|
||||
(12, 'foreignkey'),
|
||||
(13, 'manytomany'),
|
||||
(12, 'imgs'),
|
||||
(13, 'foreignkey'),
|
||||
(14, 'manytomany'),
|
||||
(15, 'time'),
|
||||
|
||||
)
|
||||
form_item_type = models.IntegerField(choices=FORM_ITEM_TYPE_LIST, verbose_name="表单类型", help_text="表单类型", default=0,
|
||||
blank=True)
|
||||
|
@ -315,6 +318,7 @@ class SystemConfig(CoreModel):
|
|||
verbose_name = '系统配置表'
|
||||
verbose_name_plural = verbose_name
|
||||
ordering = ('sort',)
|
||||
unique_together = (("key", "parent_id"),)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title}"
|
||||
|
|
|
@ -16,9 +16,16 @@
|
|||
<el-form-item label="表单类型" prop="form_item_type">
|
||||
<el-select v-model="form.form_item_type" placeholder="请选择" clearable>
|
||||
<el-option :label="item.label" :value="item.value" :key="index"
|
||||
v-for="(item,index) in typeOptions"></el-option>
|
||||
v-for="(item,index) in dictionary('config_form_type')"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="[4,5,6].indexOf(form.form_item_type)>-1"
|
||||
label="字典key"
|
||||
prop="setting"
|
||||
:rules="[{required: true,message: '不能为空'}]">
|
||||
<el-input v-model="form.setting" placeholder="请输入dictionary中key值" clearable></el-input>
|
||||
</el-form-item>
|
||||
<div v-if="[13,14].indexOf(form.form_item_type)>-1">
|
||||
<associationTable ref="associationTable" v-model="form.setting"
|
||||
@updateVal="associationTableUpdate"></associationTable>
|
||||
|
@ -81,8 +88,8 @@ export default {
|
|||
message: '请输入'
|
||||
},
|
||||
{
|
||||
pattern: /^[A-Za-z0-9]+$/,
|
||||
message: '只支持字母和数字的输入'
|
||||
pattern: /^[A-Za-z0-9_]+$/,
|
||||
message: '请输入数字、字母或下划线'
|
||||
}
|
||||
],
|
||||
form_item_type: [
|
||||
|
@ -94,23 +101,6 @@ export default {
|
|||
},
|
||||
// 父级内容
|
||||
parentOptions: [],
|
||||
// 表单类型
|
||||
typeOptions: [
|
||||
{ value: 0, label: '短文本' },
|
||||
{ value: 1, label: '长文本' },
|
||||
{ value: 2, label: '数字框' },
|
||||
{ value: 3, label: '选择框' },
|
||||
{ value: 4, label: '单选框' },
|
||||
{ value: 5, label: '复选框' },
|
||||
{ value: 6, label: '日期' },
|
||||
{ value: 7, label: '日期时间' },
|
||||
{ value: 8, label: '时间' },
|
||||
{ value: 9, label: '图片' },
|
||||
{ value: 10, label: '文件' },
|
||||
{ value: 11, label: '数组' },
|
||||
{ value: 12, label: '关联表' },
|
||||
{ value: 13, label: '关联表(多选)' }
|
||||
],
|
||||
ruleOptions: [
|
||||
{
|
||||
label: '必填项',
|
||||
|
@ -119,6 +109,10 @@ export default {
|
|||
{
|
||||
label: '邮箱',
|
||||
value: '{ "type": "email", "message": "请输入正确的邮箱地址"}'
|
||||
},
|
||||
{
|
||||
label: 'URL地址',
|
||||
value: '{ "type": "url", "message": "请输入正确的URL地址"}'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -162,7 +156,6 @@ export default {
|
|||
const that = this
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (that.$refs.associationTable) {
|
||||
console.log(that.$refs.associationTable.onSubmit())
|
||||
if (!that.$refs.associationTable.onSubmit()) {
|
||||
// eslint-disable-next-line prefer-promise-reject-errors
|
||||
return reject(false)
|
|
@ -17,12 +17,74 @@
|
|||
:type="item.form_item_type_label"
|
||||
v-model="form[item.key]" :placeholder="item.placeholder" clearable></el-input>
|
||||
|
||||
<el-input-number :key="index" v-else-if="item.form_item_type_label==='number'" v-model="form[item.key]"
|
||||
<el-input-number :key="index" v-else-if="item.form_item_type_label === 'number'" v-model="form[item.key]"
|
||||
:min="0"></el-input-number>
|
||||
<!-- datetime、date、time -->
|
||||
<el-date-picker
|
||||
v-else-if="['datetime','date','time'].indexOf(item.form_item_type_label) >-1"
|
||||
v-model="form[item.key]"
|
||||
:key="index"
|
||||
:type="item.form_item_type_label"
|
||||
:placeholder="item.placeholder">
|
||||
</el-date-picker>
|
||||
<!-- select -->
|
||||
<el-select
|
||||
:key="index"
|
||||
v-else-if="item.form_item_type_label === 'select'"
|
||||
v-model="form[item.key]"
|
||||
:placeholder="item.placeholder"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dictionary(item.setting) || []"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<!-- checkbox -->
|
||||
<el-checkbox-group
|
||||
:key="index"
|
||||
v-else-if="item.form_item_type_label === 'checkbox'"
|
||||
v-model="form[item.key]"
|
||||
:placeholder="item.placeholder"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="item in dictionary(item.setting) || []"
|
||||
:key="item.value"
|
||||
:label="item.value"
|
||||
:value="item.value">
|
||||
{{ item.label }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<!-- radio -->
|
||||
<el-radio-group
|
||||
:key="index"
|
||||
v-else-if="item.form_item_type_label === 'radio'"
|
||||
v-model="form[item.key]"
|
||||
:placeholder="item.placeholder"
|
||||
clearable
|
||||
>
|
||||
<el-radio
|
||||
v-for="item in dictionary(item.setting) || []"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
{{ item.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- switch -->
|
||||
<el-switch
|
||||
:key="index"
|
||||
v-else-if="item.form_item_type_label === 'switch'"
|
||||
v-model="form[item.key]"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949">
|
||||
</el-switch>
|
||||
<!-- 图片 -->
|
||||
<div v-else-if="['img','imgs'].indexOf(item.form_item_type_label) >-1" :key="index">
|
||||
<el-upload
|
||||
:action="imgUploadUrl"
|
||||
:action="uploadUrl"
|
||||
:headers="uploadHeaders"
|
||||
name="url"
|
||||
:accept="'image/*'"
|
||||
|
@ -43,6 +105,29 @@
|
|||
<img width="100%" :src="dialogImageUrl" alt="">
|
||||
</el-dialog>
|
||||
</div>
|
||||
<!-- 文件 -->
|
||||
<div v-else-if="['file'].indexOf(item.form_item_type_label) >-1" :key="index">
|
||||
<el-upload
|
||||
:action="uploadUrl"
|
||||
:headers="uploadHeaders"
|
||||
name="url"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-success="(response, file, fileList)=>{handleUploadSuccess(response, file, fileList,item.key)}"
|
||||
:on-error="handleError"
|
||||
:on-exceed="handleExceed"
|
||||
:limit="item.form_item_type_label==='img'?1:5"
|
||||
:ref="'fileUpload_'+item.key"
|
||||
:data-keyname="item.key"
|
||||
:file-list="item.value?item.value:[]"
|
||||
list-type="picture-card"
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
<div slot="tip" class="el-upload__tip">选取图片后,需手动上传到服务器,并且只能上传jpg/png文件</div>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogImgVisible">
|
||||
<img width="100%" :src="dialogImageUrl" alt="">
|
||||
</el-dialog>
|
||||
</div>
|
||||
<!-- 关联表 -->
|
||||
<div v-else-if="['foreignkey','manytomany'].indexOf(item.form_item_type_label) >-1" :key="index">
|
||||
<table-selector
|
||||
|
@ -56,7 +141,7 @@
|
|||
label: item.setting.field,
|
||||
}"
|
||||
:pagination="true"
|
||||
:multiple="item.form_item_type_label==='manytomany'?true:false"
|
||||
:multiple="item.form_item_type_label ==='manytomany'"
|
||||
></table-selector>
|
||||
</div>
|
||||
<!-- 数组 -->
|
||||
|
@ -171,8 +256,7 @@ export default {
|
|||
}
|
||||
]
|
||||
},
|
||||
imgUploadUrl: util.baseURL() + 'api/system/img/',
|
||||
// imgUploadUrl: 'http://public.yuanxiaotian.com:8000/api/system/img/',
|
||||
uploadUrl: util.baseURL() + 'api/system/file/',
|
||||
uploadHeaders: {
|
||||
Authorization: 'JWT ' + util.cookies.get('token')
|
||||
},
|
||||
|
@ -191,7 +275,15 @@ export default {
|
|||
const form = {}
|
||||
for (const item of data) {
|
||||
const key = item.key
|
||||
form[key] = item.value
|
||||
if (item.value) {
|
||||
form[key] = item.value
|
||||
} else {
|
||||
if ([5, 12, 14].indexOf(item.form_item_type) !== -1) {
|
||||
form[key] = []
|
||||
} else {
|
||||
form[key] = undefined
|
||||
}
|
||||
}
|
||||
if (item.form_item_type_label === 'array') {
|
||||
that.$nextTick(() => {
|
||||
const tableName = 'xTable_' + key
|
||||
|
@ -209,6 +301,7 @@ export default {
|
|||
const form = JSON.parse(JSON.stringify(this.form))
|
||||
const keys = Object.keys(form)
|
||||
const values = Object.values(form)
|
||||
console.log(111, form)
|
||||
for (const index in this.formList) {
|
||||
const item = this.formList[index]
|
||||
// eslint-disable-next-line camelcase
|
||||
|
@ -237,20 +330,22 @@ export default {
|
|||
item.value = tableData
|
||||
}
|
||||
// 赋值操作
|
||||
if (keys[index] === item.key) {
|
||||
if (item.form_item_type_label !== 'array') {
|
||||
item.value = values[index]
|
||||
}
|
||||
// 必填项的验证
|
||||
if (['img', 'imgs'].indexOf(item.form_item_type_label) > -1) {
|
||||
for (const arr of item.rule) {
|
||||
if (arr.required && item.value === null) {
|
||||
that.$message.error(item.title + '不能为空')
|
||||
return
|
||||
keys.map((mapKey, mapIndex) => {
|
||||
if (mapKey === item.key) {
|
||||
if (item.form_item_type_label !== 'array') {
|
||||
item.value = values[mapIndex]
|
||||
}
|
||||
// 必填项的验证
|
||||
if (['img', 'imgs'].indexOf(item.form_item_type_label) > -1) {
|
||||
for (const arr of item.rule) {
|
||||
if (arr.required && item.value === null) {
|
||||
that.$message.error(item.title + '不能为空')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
that.$refs.form.clearValidate()
|
||||
that.$refs.form.validate((valid) => {
|
||||
|
@ -272,10 +367,16 @@ export default {
|
|||
const $table = this.$refs[tableName][0]
|
||||
const { tableData } = $table.getTableData()
|
||||
const tableLength = tableData.length
|
||||
if (tableLength !== 0) {
|
||||
if (tableLength === 0) {
|
||||
const { row: newRow } = $table.insert()
|
||||
console.log(newRow)
|
||||
} else {
|
||||
const errMap = await $table.validate().catch(errMap => errMap)
|
||||
if (errMap) {
|
||||
this.$message.error('校验不通过!')
|
||||
} else {
|
||||
const { row: newRow } = $table.insert()
|
||||
console.log(newRow)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -292,13 +393,6 @@ export default {
|
|||
this.dialogImageUrl = file.url
|
||||
this.dialogImgVisible = true
|
||||
},
|
||||
// 上传提交
|
||||
submitUpload (key) {
|
||||
const refName = 'imgUpload_' + key
|
||||
const ref = this.$refs[refName][0]
|
||||
ref.submit()
|
||||
this.uploadImgKey = key
|
||||
},
|
||||
// 判断是否为图片
|
||||
// 封装一个判断图片文件后缀名的方法
|
||||
isImage (fileName) {
|
|
@ -58,17 +58,23 @@
|
|||
:label="item.title"
|
||||
:name="item.key"
|
||||
>
|
||||
<formContent :options="item" :editableTabsItem="item"></formContent>
|
||||
<span slot="label" v-if="item.icon"><i :class="item.icon" style="font-weight: 1000;font-size: 16px;"></i></span>
|
||||
<el-row v-if="item.icon">
|
||||
<el-col :offset="4" :span="8">
|
||||
<addContent></addContent>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<formContent v-else :options="item" :editableTabsItem="item"></formContent>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addTabs from './components/addTabs'
|
||||
import addTabs from '@/views/system/config/components/addTabs'
|
||||
import * as api from './api'
|
||||
import addContent from './components/addContent'
|
||||
import formContent from './components/formContent'
|
||||
import addContent from '@/views/system/config/components/addContent'
|
||||
import formContent from '@/views/system/config/components/formContent'
|
||||
|
||||
export default {
|
||||
name: 'config',
|
||||
|
@ -81,7 +87,7 @@ export default {
|
|||
return {
|
||||
tabsDrawer: false,
|
||||
contentDrawer: false,
|
||||
editableTabsValue: 'basic',
|
||||
editableTabsValue: 'base',
|
||||
editableTabs: [],
|
||||
tabIndex: 2
|
||||
}
|
||||
|
@ -93,6 +99,11 @@ export default {
|
|||
parent__isnull: true
|
||||
}).then(res => {
|
||||
const { data } = res.data
|
||||
data.push({
|
||||
title: '无',
|
||||
icon: 'el-icon-plus',
|
||||
key: 'null'
|
||||
})
|
||||
this.editableTabs = data
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue