diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index 35bf5d5..ae3a249 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -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}" diff --git a/web/src/views/system/systemConfig/api.js b/web/src/views/system/config/api.js similarity index 100% rename from web/src/views/system/systemConfig/api.js rename to web/src/views/system/config/api.js diff --git a/web/src/views/system/systemConfig/components/addContent.vue b/web/src/views/system/config/components/addContent.vue similarity index 84% rename from web/src/views/system/systemConfig/components/addContent.vue rename to web/src/views/system/config/components/addContent.vue index 77cc854..3731198 100644 --- a/web/src/views/system/systemConfig/components/addContent.vue +++ b/web/src/views/system/config/components/addContent.vue @@ -16,9 +16,16 @@ + v-for="(item,index) in dictionary('config_form_type')"> + + +
@@ -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) diff --git a/web/src/views/system/systemConfig/components/addTabs.vue b/web/src/views/system/config/components/addTabs.vue similarity index 100% rename from web/src/views/system/systemConfig/components/addTabs.vue rename to web/src/views/system/config/components/addTabs.vue diff --git a/web/src/views/system/systemConfig/components/components/associationTable.vue b/web/src/views/system/config/components/components/associationTable.vue similarity index 100% rename from web/src/views/system/systemConfig/components/components/associationTable.vue rename to web/src/views/system/config/components/components/associationTable.vue diff --git a/web/src/views/system/systemConfig/components/formContent.vue b/web/src/views/system/config/components/formContent.vue similarity index 70% rename from web/src/views/system/systemConfig/components/formContent.vue rename to web/src/views/system/config/components/formContent.vue index ea0bd2a..ffe0f5b 100644 --- a/web/src/views/system/systemConfig/components/formContent.vue +++ b/web/src/views/system/config/components/formContent.vue @@ -17,12 +17,74 @@ :type="item.form_item_type_label" v-model="form[item.key]" :placeholder="item.placeholder" clearable> - + + + + + + + + + + + + {{ item.label }} + + + + + + {{ item.label }} + + + + +
+ +
+ + +
选取图片后,需手动上传到服务器,并且只能上传jpg/png文件
+
+ + + +
@@ -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) { diff --git a/web/src/views/system/systemConfig/index.vue b/web/src/views/system/config/index.vue similarity index 75% rename from web/src/views/system/systemConfig/index.vue rename to web/src/views/system/config/index.vue index 7ac61b3..eb9a899 100644 --- a/web/src/views/system/systemConfig/index.vue +++ b/web/src/views/system/config/index.vue @@ -58,17 +58,23 @@ :label="item.title" :name="item.key" > - + + + + + + +