parent
0cd8a3aa5d
commit
afeb9e10f6
@ -0,0 +1,57 @@
|
|||||||
|
import request from "@/utils/request";
|
||||||
|
function customParamsSerializer(params) {
|
||||||
|
let result = '';
|
||||||
|
for (let key in params) {
|
||||||
|
if (params.hasOwnProperty(key)) {
|
||||||
|
if (Array.isArray(params[key])) {
|
||||||
|
params[key].forEach((item,index) => {
|
||||||
|
if(item.key){
|
||||||
|
result += `${key}[${index}][key]=${item.key}&${key}[${index}][op]=${item.op}&${key}[${index}][value]=${item.value}&`;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
result +=`${key}[${index}]=${item}&`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result += `${key}=${params[key]}&`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.slice(0, -1);
|
||||||
|
}
|
||||||
|
export function index(params,isLoading = false) {
|
||||||
|
return request({
|
||||||
|
method: "get",
|
||||||
|
url: "/api/admin/course-forms/index",
|
||||||
|
params,
|
||||||
|
paramsSerializer: customParamsSerializer,
|
||||||
|
isLoading
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function show(params, isLoading = true) {
|
||||||
|
return request({
|
||||||
|
method: "get",
|
||||||
|
url: "/api/admin/course-forms/show",
|
||||||
|
params,
|
||||||
|
isLoading
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
method: "post",
|
||||||
|
url: "/api/admin/course-forms/save",
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function destroy(params) {
|
||||||
|
return request({
|
||||||
|
method: "get",
|
||||||
|
url: "/api/admin/course-forms/destroy",
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,257 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog title="创建报名表单" :visible.sync="dialogVisible" :fullscreen="true" :modal='false'>
|
||||||
|
<div style="height: 100%">
|
||||||
|
<Split v-model="splitL" :min="0.05">
|
||||||
|
<template #left>
|
||||||
|
<draggable v-model="types" :sort="false" :group="{ name: 'items', pull: 'clone', put: false }">
|
||||||
|
<div class="type-item" v-for="item in types">
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
</draggable>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<Split v-model="splitR" :min="0.2">
|
||||||
|
<template #left>
|
||||||
|
<div style="height: 100%">
|
||||||
|
<el-dialog id="template-dialog" :title="'模板表单'"
|
||||||
|
style="position: relative; inset: 0 0 0 0; height: 100%" width="600px" top="40px" :visible="true"
|
||||||
|
:modal="false" :append-to-body="false" :modal-append-to-body="false">
|
||||||
|
<el-form style="min-height: 200px;" label-width="80px" label-position="right" size="small">
|
||||||
|
<draggable :value="formList" group="items" @change="changeHandler">
|
||||||
|
<el-form-item :label="i.name || '字段名称'" :required="
|
||||||
|
i.rule ? !!i.rule.includes('required') : false
|
||||||
|
" v-for="(i, index) in formList" @click.native="selectPick(i, index)">
|
||||||
|
<formSlotRender :config="i" :index="index"></formSlotRender>
|
||||||
|
</el-form-item>
|
||||||
|
</draggable>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div slot="footer">
|
||||||
|
<div>
|
||||||
|
<el-button type="primary">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<editPane ref="editPane" @refreshFormItem="refreshItem" :rules="rules" :types="types"
|
||||||
|
@refresh="getFormList"></editPane>
|
||||||
|
</template>
|
||||||
|
</Split>
|
||||||
|
</template>
|
||||||
|
</Split>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
config
|
||||||
|
} from "@/api/system/customFormField";
|
||||||
|
import {
|
||||||
|
index
|
||||||
|
} from "@/api/course/form";
|
||||||
|
import {
|
||||||
|
deepCopy
|
||||||
|
} from "@/utils";
|
||||||
|
import editPane from "../components/editPane.vue";
|
||||||
|
import formSlotRender from "@/views/system/components/formSlotRender.vue";
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
formSlotRender,
|
||||||
|
editPane
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
course_id: "",
|
||||||
|
select: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 999,
|
||||||
|
sort_name: 'sort',
|
||||||
|
sort_type: 'ASC'
|
||||||
|
},
|
||||||
|
dialogVisible: false,
|
||||||
|
formList: [],
|
||||||
|
types: [],
|
||||||
|
rules: {},
|
||||||
|
//分割面板
|
||||||
|
splitL: 0.13,
|
||||||
|
splitR: 0.7,
|
||||||
|
selectedForm: {},
|
||||||
|
selectedIndex: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getConfig()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//获取 左侧 formitem类型
|
||||||
|
async getConfig() {
|
||||||
|
const {
|
||||||
|
edit_to_migration,
|
||||||
|
validation_rules
|
||||||
|
} = await config(false);
|
||||||
|
this.rules = validation_rules;
|
||||||
|
this.types = edit_to_migration.filter(item => item.edit_input !== 'textarea' && item.edit_input !== "richtext"
|
||||||
|
&& item.edit_input !== "file" && item.edit_input !== "map");
|
||||||
|
},
|
||||||
|
// 获取自定义表单列表
|
||||||
|
async getFormList() {
|
||||||
|
const res = await index({
|
||||||
|
filter: [{
|
||||||
|
key: 'course_id',
|
||||||
|
op: 'eq',
|
||||||
|
value: this.course_id
|
||||||
|
}],
|
||||||
|
...this.select
|
||||||
|
})
|
||||||
|
this.formList = res.data
|
||||||
|
},
|
||||||
|
// 新增 移动
|
||||||
|
changeHandler(e) {
|
||||||
|
if (e.added) {
|
||||||
|
const {
|
||||||
|
element,
|
||||||
|
newIndex
|
||||||
|
} = e.added;
|
||||||
|
const originalData = element;
|
||||||
|
const newItem = {
|
||||||
|
id: "",
|
||||||
|
course_id: this.course_id,
|
||||||
|
field: "",
|
||||||
|
name: "",
|
||||||
|
parameter_id: "",
|
||||||
|
edit_input: originalData.edit_input,
|
||||||
|
sort: newIndex,
|
||||||
|
help: "",
|
||||||
|
rule: "",
|
||||||
|
select_item: []
|
||||||
|
};
|
||||||
|
this.formList.splice(newIndex, 0, newItem)
|
||||||
|
}
|
||||||
|
if (e.moved) {
|
||||||
|
const {
|
||||||
|
element,
|
||||||
|
newIndex,
|
||||||
|
oldIndex
|
||||||
|
} = e.moved;
|
||||||
|
element.sort = newIndex;
|
||||||
|
if (element) {
|
||||||
|
this.formList.splice(oldIndex, 1);
|
||||||
|
this.formList.splice(newIndex, 0, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
// 选中的 表单数据
|
||||||
|
selectPick(i, index) {
|
||||||
|
this.$refs.editPane.selectedIndex = index
|
||||||
|
this.$refs.editPane.selectedForm = deepCopy(i)
|
||||||
|
this.$refs.editPane.showForm = true
|
||||||
|
},
|
||||||
|
// 处理 保存 删除过来的item
|
||||||
|
refreshItem(e, index) {
|
||||||
|
// 没有id
|
||||||
|
if (e === 'save' || e === 'DelId') {
|
||||||
|
this.getFormList()
|
||||||
|
} else if (e === 'Del') {
|
||||||
|
this.formList.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dialogVisible(newval) {
|
||||||
|
if (newval) {
|
||||||
|
console.log("this.course_id", this.course_id)
|
||||||
|
} else {
|
||||||
|
this.course_id = ''
|
||||||
|
this.$emit("refresh")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.title {
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type-item {
|
||||||
|
min-width: 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: pointer;
|
||||||
|
color: $primaryColor;
|
||||||
|
border: solid 1px $primaryColor;
|
||||||
|
border-radius: 10px;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.2s ease-out;
|
||||||
|
|
||||||
|
padding:10px;
|
||||||
|
margin: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff;
|
||||||
|
background: $primaryColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-dialog__headerbtn {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-dialog__header {
|
||||||
|
padding: 10px !important;
|
||||||
|
box-shadow: 0 2px 10px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-dialog__body {
|
||||||
|
height: calc(100% - 62px);
|
||||||
|
padding: 8px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#template-dialog {
|
||||||
|
::v-deep .el-dialog__header {
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-dialog__body {
|
||||||
|
padding: 30px 20px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ivu-split-trigger-vertical {
|
||||||
|
width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ivu-split-trigger-bar-con.vertical {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ivu-split-horizontal>.ivu-split-trigger-con {
|
||||||
|
width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ivu-split-pane {
|
||||||
|
height: 100%;
|
||||||
|
overflow: scroll;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in new issue