refactor(系统配置): ♻️ 系统配置

重构系统配置页面
This commit is contained in:
猿小天
2023-03-15 23:19:51 +08:00
parent efbeff6f2d
commit 21842e19f0
4 changed files with 429 additions and 403 deletions

View File

@@ -2,7 +2,7 @@
<div class="layout-parent"> <div class="layout-parent">
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">
<transition :name="setTransitionName" mode="out-in"> <transition :name="setTransitionName" mode="out-in">
<keep-alive :include="getKeepAliveNames"> <keep-alive :include="getKeepAliveNames" v-if="showView">
<component :is="Component" :key="state.refreshRouterViewKey" class="w100" v-show="!isIframePage" /> <component :is="Component" :key="state.refreshRouterViewKey" class="w100" v-show="!isIframePage" />
</keep-alive> </keep-alive>
</transition> </transition>
@@ -14,7 +14,7 @@
</template> </template>
<script setup lang="ts" name="layoutParentView"> <script setup lang="ts" name="layoutParentView">
import { defineAsyncComponent, computed, reactive, onBeforeMount, onUnmounted, nextTick, watch, onMounted } from 'vue'; import { defineAsyncComponent, computed, reactive, onBeforeMount, onUnmounted, nextTick, watch, onMounted,ref,provide } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useKeepALiveNames } from '/@/stores/keepAliveNames'; import { useKeepALiveNames } from '/@/stores/keepAliveNames';
@@ -39,6 +39,19 @@ const state = reactive<ParentViewState>({
iframeList: [], iframeList: [],
}); });
//全局依赖刷新页面
const showView = ref(true)
/**
* 刷新页面
*/
const refreshView=function () {
showView.value = false // 通过v-if移除router-view节点
nextTick(() => {
showView.value = true // DOM更新后再通过v-if添加router-view节点
})
}
provide('refreshView',refreshView)
// 设置主界面切换动画 // 设置主界面切换动画
const setTransitionName = computed(() => { const setTransitionName = computed(() => {
return themeConfig.value.animation; return themeConfig.value.animation;

View File

@@ -51,3 +51,11 @@ export function GetAssociationTable() {
params: {}, params: {},
}); });
} }
export function saveContent (data:any) {
return request({
url: apiPrefix + 'save_content/',
method: 'put',
data: data
})
}

View File

@@ -1,40 +1,47 @@
<template> <template>
<div> <div>
<el-row :gutter="10"> <el-row :gutter="20">
<el-col :span="4">变量标题</el-col> <el-col :span="4">变量标题</el-col>
<el-col :span="10">变量值</el-col>
<el-col :span="4">变量名</el-col> <el-col :span="4">变量名</el-col>
<el-col :span="2">是否前端配置</el-col> <el-col :span="10">变量值</el-col>
<el-col :span="3" :offset="1">操作</el-col> <el-col :span="2" :offset="1">是否前端配置</el-col>
<el-col :span="3" >操作</el-col>
</el-row> </el-row>
<el-form ref="formRef" :model="form" label-width="240px" label-position="left" style="margin-top: 20px"> <el-form ref="formRef" :model="formData" label-width="0px" label-position="left" style="margin-top: 20px">
<el-form-item <el-form-item
:label="item.title"
:prop="['array'].indexOf(item.form_item_type_label) > -1 ? '' : item.key" :prop="['array'].indexOf(item.form_item_type_label) > -1 ? '' : item.key"
:key="index" :key="index"
:rules="item.rule || []" :rules="item.rule || []"
v-for="(item, index) in formList" v-for="(item, index) in formList"
> >
<template slot="label"> <el-col :span="4">
<el-input v-if="item.edit" v-model="item.title" style="display: inline-block; width: 200px" placeholder="请输入标题"></el-input> <el-input v-if="item.edit" v-model="item.title" style="display: inline-block; width: 200px" placeholder="请输入标题"></el-input>
<span v-else>{{ item.title }}</span> <span v-else>{{ item.title }}</span>
</el-col>
<el-col :span="4" >
<el-input v-if="item.edit" v-model="item.new_key" style="width: 200px" placeholder="请输入变量key">
<template slot="prepend">
<span style="padding: 0px 5px">{{ editableTabsItem.key }}</span>
</template> </template>
<el-col :span="11"> </el-input>
<span v-else>{{ editableTabsItem.key }}.{{ item.key }}</span>
</el-col>
<el-col :span="10">
<!-- 文本 --> <!-- 文本 -->
<el-input <el-input
:key="index" :key="index"
v-if="['text', 'textarea'].indexOf(item.form_item_type_label) > -1" v-if="['text', 'textarea'].indexOf(item.form_item_type_label) > -1"
:type="item.form_item_type_label" :type="item.form_item_type_label"
v-model="form[item.key]" v-model="formData[item.key]"
:placeholder="item.placeholder" :placeholder="item.placeholder"
clearable clearable
></el-input> ></el-input>
<el-input-number :key="index + 1" v-else-if="item.form_item_type_label === 'number'" v-model="form[item.key]" :min="0"></el-input-number> <el-input-number :key="index + 1" v-else-if="item.form_item_type_label === 'number'" v-model="formData[item.key]" :min="0"></el-input-number>
<!-- datetimedatetime --> <!-- datetimedatetime -->
<el-date-picker <el-date-picker
v-else-if="['datetime', 'date', 'time'].indexOf(item.form_item_type_label) > -1" v-else-if="['datetime', 'date', 'time'].indexOf(item.form_item_type_label) > -1"
v-model="form[item.key]" v-model="formData[item.key]"
:key="index + 2" :key="index + 2"
:type="item.form_item_type_label" :type="item.form_item_type_label"
:placeholder="item.placeholder" :placeholder="item.placeholder"
@@ -44,7 +51,7 @@
<el-select <el-select
:key="index + 3" :key="index + 3"
v-else-if="item.form_item_type_label === 'select'" v-else-if="item.form_item_type_label === 'select'"
v-model="form[item.key]" v-model="formData[item.key]"
:placeholder="item.placeholder" :placeholder="item.placeholder"
clearable clearable
> >
@@ -54,7 +61,7 @@
<el-checkbox-group <el-checkbox-group
:key="index + 4" :key="index + 4"
v-else-if="item.form_item_type_label === 'checkbox'" v-else-if="item.form_item_type_label === 'checkbox'"
v-model="form[item.key]" v-model="formData[item.key]"
:placeholder="item.placeholder" :placeholder="item.placeholder"
> >
<el-checkbox v-for="item in dictionary(item.setting) || []" :key="item.value" :label="item.value" :value="item.value"> <el-checkbox v-for="item in dictionary(item.setting) || []" :key="item.value" :label="item.value" :value="item.value">
@@ -65,7 +72,7 @@
<el-radio-group <el-radio-group
:key="index + 5" :key="index + 5"
v-else-if="item.form_item_type_label === 'radio'" v-else-if="item.form_item_type_label === 'radio'"
v-model="form[item.key]" v-model="formData[item.key]"
:placeholder="item.placeholder" :placeholder="item.placeholder"
clearable clearable
> >
@@ -77,7 +84,7 @@
<el-switch <el-switch
:key="index + 6" :key="index + 6"
v-else-if="item.form_item_type_label === 'switch'" v-else-if="item.form_item_type_label === 'switch'"
v-model="form[item.key]" v-model="formData[item.key]"
active-color="#13ce66" active-color="#13ce66"
inactive-color="#ff4949" inactive-color="#ff4949"
> >
@@ -151,7 +158,7 @@
<!-- 关联表 --> <!-- 关联表 -->
<div v-else-if="['foreignkey', 'manytomany'].indexOf(item.form_item_type_label) > -1" :key="index + 9"> <div v-else-if="['foreignkey', 'manytomany'].indexOf(item.form_item_type_label) > -1" :key="index + 9">
<table-selector <table-selector
v-model="form[item.key]" v-model="formData[item.key]"
:el-props="{ :el-props="{
pagination: true, pagination: true,
columns: item.setting.searchField, columns: item.setting.searchField,
@@ -211,27 +218,21 @@
</div> </div>
</div> </div>
</el-col> </el-col>
<el-col :span="4" :offset="1"> <el-col :span="2" :offset="1">
<el-input v-if="item.edit" v-model="item.new_key" style="width: 200px" placeholder="请输入变量key">
<template slot="prepend">
<span style="padding: 0px 5px">{{ editableTabsItem.key }}</span>
</template>
</el-input>
<span v-else>{{ editableTabsItem.key }}.{{ item.key }}</span>
</el-col>
<el-col :span="3" :offset="1">
<el-switch v-model="item.status" active-color="#13ce66" inactive-color="#ff4949"> </el-switch> <el-switch v-model="item.status" active-color="#13ce66" inactive-color="#ff4949"> </el-switch>
</el-col> </el-col>
<el-col :span="2"> <el-col :span="3">
<el-button v-if="item.edit" size="mini" type="primary" icon="el-icon-success" @click="onEditSave(item)"></el-button> <el-button v-if="item.edit" size="mini" type="primary" :icon="Finished" @click="onEditSave(item)">保存</el-button>
<el-button v-else size="mini" type="primary" icon="el-icon-edit" @click="onEdit(index)"></el-button> <el-button v-else size="mini" type="primary" :icon="Edit" @click="onEdit(index)"></el-button>
<el-popconfirm title="确定删除该条数据吗" @confirm="onDelRow(item)"> <el-popconfirm title="确定删除该条数据吗" @confirm="onDelRow(item)">
<el-button size="mini" type="danger" icon="el-icon-delete" slot="reference"></el-button> <template #reference>
<el-button size="mini" type="danger" :icon="Delete" ></el-button>
</template>
</el-popconfirm> </el-popconfirm>
</el-col> </el-col>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="onSubmit">确定</el-button> <el-button type="primary" @click="onSubmit(formRef)">确定</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@@ -241,14 +242,14 @@
import * as api from '../api'; import * as api from '../api';
import { dictionary } from '/@/utils/dictionary'; import { dictionary } from '/@/utils/dictionary';
import { getBaseURL } from '/@/utils/baseUrl'; import { getBaseURL } from '/@/utils/baseUrl';
import { ref, reactive, watch, nextTick } from 'vue'; import { ref, reactive, watch, nextTick,inject } from 'vue';
import type { FormInstance, FormRules, TableInstance } from 'element-plus'; import type { FormInstance, FormRules, TableInstance } from 'element-plus';
import { successMessage, errorMessage } from '/@/utils/message'; import { successMessage, errorMessage } from '/@/utils/message';
import { Session } from '/@/utils/storage'; import { Session } from '/@/utils/storage';
import {Edit,Finished,Delete} from "@element-plus/icons-vue";
const props = defineProps(['options', 'editableTabsItem']); const props = defineProps(['options', 'editableTabsItem']);
let form: any = reactive({}); let formData: any = reactive({});
let formList: any = ref([]); let formList: any = ref([]);
let childTableData = ref([]); let childTableData = ref([]);
let childRemoveVisible = ref(false); let childRemoveVisible = ref(false);
@@ -272,7 +273,7 @@ const validRules = reactive<FormRules>({
}, },
], ],
}); });
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>()
let uploadUrl = ref(getBaseURL + 'api/system/file/'); let uploadUrl = ref(getBaseURL + 'api/system/file/');
let uploadHeaders = ref({ let uploadHeaders = ref({
Authorization: 'JWT ' + Session.get('token'), Authorization: 'JWT ' + Session.get('token'),
@@ -285,17 +286,17 @@ let uploadImgKey = ref(null);
const getInit = () => { const getInit = () => {
api.GetList({ parent: props.options.id, limit: 999 }).then((res: any) => { api.GetList({ parent: props.options.id, limit: 999 }).then((res: any) => {
let data = res.data; let data = res.data;
formList = data; formList.value = data;
const formData: any = {}; const _formData: any = {};
for (const item of data) { for (const item of data) {
const key = item.key; const key = item.key;
if (item.value) { if (item.value) {
formData[key] = item.value; _formData[key] = item.value;
} else { } else {
if ([5, 12, 14].indexOf(item.form_item_type) !== -1) { if ([5, 12, 14].indexOf(item.form_item_type) !== -1) {
formData[key] = []; _formData[key] = [];
} else { } else {
formData[key] = undefined; _formData[key] = undefined;
} }
} }
if (item.form_item_type_label === 'array') { if (item.form_item_type_label === 'array') {
@@ -309,17 +310,17 @@ const getInit = () => {
}); });
} }
} }
form = JSON.parse(JSON.stringify(formData)); formData = Object.assign(formData, _formData)
}); });
}; };
// 提交数据 // 提交数据
const onSubmit = () => { const onSubmit = (formEl: FormInstance | undefined) => {
// const form = JSON.parse(JSON.stringify(form)); // const form = JSON.parse(JSON.stringify(form));
const keys = Object.keys(form); const keys = Object.keys(formData);
const values = Object.values(form); const values = Object.values(formData);
for (const index in formList) { for (const index in formList.value) {
const item = formList[index]; const item = formList.value[index];
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
const form_item_type_label = item.form_item_type_label; const form_item_type_label = item.form_item_type_label;
@@ -363,18 +364,19 @@ const onSubmit = () => {
} }
}); });
} }
// formRef.clearValidate(); // formRef.value.clearValidate();
// formRef.validate((valid) => { if (!formEl) return
// if (valid) { formEl.validate((valid:any) => {
// api.saveContent(this.options.id, this.formList).then((res) => { if (valid) {
// this.$message.success('保存成功'); api.saveContent(formList.value).then((res:any) => {
// this.refreshView(); successMessage('保存成功');
// }); refreshView&&refreshView();
// } else { });
// console.log('error submit!!'); } else {
// return false; console.log('error submit!!');
// } return false;
// }); }
});
}; };
// 追加 // 追加
@@ -436,16 +438,16 @@ const handleUploadSuccess = (response: any, file: any, fileList: any, imgKey: an
if (!type) { if (!type) {
errorMessage('只允许上传图片'); errorMessage('只允许上传图片');
} else { } else {
const uploadImgKey = form[imgKey]; const uploadImgKey = formData[imgKey];
if (!uploadImgKey || uploadImgKey === '') { if (!uploadImgKey || uploadImgKey === '') {
form[imgKey] = []; formData[imgKey] = [];
} }
// console.log(len) // console.log(len)
const dict = { const dict = {
name: name, name: name,
url: getBaseURL() + url, url: getBaseURL() + url,
}; };
form[imgKey].push(dict); formData[imgKey].push(dict);
} }
} else { } else {
errorMessage('上传失败,' + JSON.stringify(msg)); errorMessage('上传失败,' + JSON.stringify(msg));
@@ -465,10 +467,10 @@ const handleExceed = () => {
// 删除时的钩子 // 删除时的钩子
const beforeRemove = (file: any, fileList: any, key: any) => { const beforeRemove = (file: any, fileList: any, key: any) => {
var index = 0; var index = 0;
form[key].map((value: any, inx: any) => { formData[key].map((value: any, inx: any) => {
if (value.uid === file.uid) index = inx; if (value.uid === file.uid) index = inx;
}); });
form[key].splice(index, 1); formData[key].splice(index, 1);
}; };
// 配置的行删除 // 配置的行删除
@@ -480,14 +482,15 @@ const onDelRow = (obj: any) => {
// 行编辑 // 行编辑
const onEdit = (index: any) => { const onEdit = (index: any) => {
// that.$set(that.formList[index], 'new_key', that.formList[index].key) formList.value[index].edit =true
// that.$set(that.formList[index], 'edit', true) formList.value[index].new_key =formList.value[index].key
}; };
// 行编辑保存 // 行编辑保存
const refreshView = inject<Function>('refreshView')
const onEditSave = (obj: any) => { const onEditSave = (obj: any) => {
obj.key = JSON.parse(JSON.stringify(obj.new_key)); obj.key = JSON.parse(JSON.stringify(obj.new_key));
api.UpdateObj(obj).then((res: any) => { api.UpdateObj(obj).then((res: any) => {
// this.refreshView(); refreshView && refreshView()
}); });
}; };

View File

@@ -11,9 +11,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { useExpose, useCrud } from '@fast-crud/fast-crud'; import { useExpose, useCrud,dict } from '@fast-crud/fast-crud';
import { createCrudOptions } from './curd'; import { createCrudOptions } from './curd';
import RolePermission from '/@/views/system/rolePermission/index.vue'; import RolePermission from '/@/views/system/rolePermission/index.vue';
import * as api from './api'
import _ from "lodash-es";
const rolePermission = ref(); const rolePermission = ref();
defineExpose(rolePermission); defineExpose(rolePermission);
// crud组件的ref // crud组件的ref