修改表单构建

master
夜笙歌 2 weeks ago
parent 391153ec0a
commit 501c24448a

@ -26,6 +26,7 @@
"await-to-js": "3.0.0",
"axios": "1.6.8",
"bpmn-js": "16.4.0",
"clipboard": "2.0.11",
"crypto-js": "4.2.0",
"diagram-js": "12.3.0",
"didi": "9.0.2",
@ -35,20 +36,20 @@
"fuse.js": "7.0.0",
"highlight.js": "11.9.0",
"image-conversion": "^2.1.1",
"js-beautify": "1.14.11",
"js-cookie": "3.0.5",
"jsencrypt": "3.3.2",
"nprogress": "0.2.0",
"pinia": "2.1.7",
"screenfull": "6.0.2",
"vform3-builds": "^3.0.10",
"vue": "3.4.34",
"vue-cropper": "1.1.1",
"vue-i18n": "9.10.2",
"vue-router": "4.3.2",
"vue-types": "5.1.1",
"vxe-table": "4.5.22",
"vuedraggable": "4.1.0",
"clipboard": "2.0.11",
"js-beautify": "1.14.11"
"vxe-table": "4.5.22"
},
"devDependencies": {
"@iconify/json": "2.2.201",
@ -69,12 +70,13 @@
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-define-config": "2.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-vue": "9.23.0",
"fast-glob": "3.3.2",
"less": "^4.2.2",
"postcss": "8.4.36",
"prettier": "3.2.5",
"sass": "1.72.0",

@ -1,4 +1,4 @@
import { createApp } from 'vue';
import {createApp} from 'vue';
// global css
import 'virtual:uno.css';
import '@/assets/styles/index.scss';
@ -25,6 +25,12 @@ import HighLight from '@highlightjs/vue-plugin';
import 'virtual:svg-icons-register';
import ElementIcons from '@/plugins/svgicon';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VForm3 from 'vform3-builds'
import 'vform3-builds/dist/designer.style.css'
// permission control
import './permission';
@ -34,18 +40,22 @@ import i18n from '@/lang/index';
// vxeTable
import VXETable from 'vxe-table';
import 'vxe-table/lib/style.css';
VXETable.config({
zIndex: 999999
});
// 修改 el-dialog 默认点击遮照为不关闭
import { ElDialog } from 'element-plus';
import {ElDialog} from 'element-plus';
ElDialog.props.closeOnClickModal.default = false;
const app = createApp(App);
app.use(HighLight);
app.use(ElementIcons);
app.use(ElementPlus)
app.use(VForm3)
app.use(router);
app.use(store);
app.use(i18n);

@ -161,6 +161,9 @@ import {
listMasterData
} from '@/api/system/masterDataDetail';
import {MasterDataDetailVO, MasterDataDetailQuery, MasterDataDetailForm} from '@/api/system/masterDataDetail/types';
import { useRouter } from 'vue-router';
const router = useRouter()
const {proxy} = getCurrentInstance() as ComponentInternalInstance;
const {active_flag} = toRefs<any>(proxy?.useDict('active_flag'));
@ -256,15 +259,20 @@ const data = reactive<PageData<MasterDataDetailForm, MasterDataDetailQuery>>({
const {queryParams, form, rules} = toRefs(data);
const routeParam = ref({queryParam:'{"router": "brand"}'})
console.log({ queryParam:Object.keys(router.currentRoute.value.query).length>0 ? JSON.stringify(router.currentRoute.value.query):'{"router": "brand"}' });
const routeParam = ref({ queryParam:Object.keys(router.currentRoute.value.query).length>0 ? JSON.stringify(router.currentRoute.value.query):'{"router": "brand"}' })
const masterDataTitle = ref()
const tableTh = ref([])
const masterDataId = ref()
const reservedFieldList = ref([])
const isTree = ref(false)
//
listMasterData(routeParam.value).then(e => {
let data = e.rows?.[0] ||{}
isTree.value = data.parentFlag === '1'
console.log(data)
masterDataId.value = data.masterDataId
masterDataTitle.value = data.masterDataTitle
let fieldNameList = ['1','2','3','4','5']
@ -278,7 +286,6 @@ listMasterData(routeParam.value).then(e => {
return null
}
}).filter(ee=>!!ee)
console.log(reservedFieldList.value)
getList()
})

@ -1,7 +1,7 @@
<template>
<div>
<el-dialog title="添加选项" v-model="open" width="800px" :close-on-click-modal="false" :modal-append-to-body="false"
@open="onOpen" @close="onClose">
@open="onOpen" @close="onClose">
<el-form ref="treeNodeForm" :model="formData" :rules="rules" label-width="100px">
<el-col :span="24">
<el-form-item label="选项名" prop="label">
@ -13,11 +13,11 @@
<el-input v-model="formData.value" placeholder="请输入选项值" clearable>
<template #append>
<el-select v-model="dataType" :style="{ width: '100px' }">
<el-option v-for="(item, index) in dataTypeOptions" :key="index" :label="item.label" :value="item.value"
:disabled="item.disabled" />
<el-option v-for="(item, index) in dataTypeOptions" :key="index" :label="item.label"
:value="item.value"
:disabled="item.disabled" />
</el-select>
</template>
</el-input>
</el-form-item>
</el-col>
@ -32,12 +32,12 @@
</div>
</template>
<script setup>
const open = defineModel()
const emit = defineEmits(['confirm'])
const open = defineModel();
const emit = defineEmits(['confirm']);
const formData = ref({
label: undefined,
value: undefined
})
});
const rules = {
label: [
{
@ -53,8 +53,8 @@ const rules = {
trigger: 'blur'
}
]
}
const dataType = ref('string')
};
const dataType = ref('string');
const dataTypeOptions = ref([
{
label: '字符串',
@ -64,30 +64,30 @@ const dataTypeOptions = ref([
label: '数字',
value: 'number'
}
])
const id = ref(100)
const treeNodeForm = ref()
]);
const id = ref(100);
const treeNodeForm = ref();
function onOpen() {
formData.value = {
label: undefined,
value: undefined
}
};
}
function onClose() {
open.value = false
open.value = false;
}
function handelConfirm() {
treeNodeForm.value.validate(valid => {
if (!valid) return
if (!valid) return;
if (dataType.value === 'number') {
formData.value.value = parseFloat(formData.value.value)
formData.value.value = parseFloat(formData.value.value);
}
formData.value.id = id.value++
emit('commit', formData.value)
onClose()
})
formData.value.id = id.value++;
emit('commit', formData.value);
onClose();
});
}
</script>

@ -260,8 +260,8 @@ function generate(data) {
function execDownload(data) {
const codeStr = generateCode()
const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
Download.saveAs(blob, data.fileName)
// const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
// Download.saveAs(blob, data.fileName)
}
function execCopy(data) {
@ -273,6 +273,7 @@ function AssembleFormData() {
function generateCode() {
const { type } = generateConf.value
AssembleFormData()
console.log(formData.value)
const script = vueScript(makeUpJs(formData.value, type))
const html = vueTemplate(makeUpHtml(formData.value, type))
const css = cssStyle(makeUpCss(formData.value))

@ -0,0 +1,22 @@
<template>
<div class="vform3">
<v-form-designer></v-form-designer>
</div>
</template>
<script setup>
import 'vform3-builds/dist/designer.style.css'
</script>
<style>
body {
margin: 0; /* 如果页面出现垂直滚动条则加入此行CSS以消除之 */
}
.vform3 .main-container {
margin-left: 0 !important;
}
.vform3 .main-header{
display: none;
}
</style>

@ -0,0 +1,43 @@
<template>
<div class="element-mini">
<el-icon style="line-height: 32px;font-size: 12px;margin: 0 4px 0 8px">
<Eleme />
</el-icon>
<span>{{ option.name }}</span>
</div>
</template>
<script lang="ts" setup>
defineOptions({
name: 'element-mini'
});
const props = defineProps({
option: Array
});
const { option } = toRefs(props);
</script>
<style scoped lang="less">
.element-mini {
width: 120px;
height: 32px;
line-height: 32px;
font-size: 12px;
display: inline-block;
vertical-align: top;
background-color: #f2f2f2;
border-radius: 5px;
color: #000;
margin: 2px;
cursor: pointer;
border: 1px dashed #0000;
&:hover {
//background-color: #00afff;
border: 1px dashed #00afff;
color: #00afff;
}
}
</style>

@ -0,0 +1,19 @@
<template>
<div class="element-mini">
</div>
</template>
<script lang="ts" setup>
defineOptions({
name: 'el-input'
});
const props = defineProps({
options: Array
})
const { options } = toRefs(props);
</script>
<style scoped lang="less">
</style>

@ -0,0 +1,112 @@
<template>
<div>
<div class="left-box">
<div class="model" :style="`display:${isDrag?'inline-block':'none'}`">
</div>
<draggable :list="dragList" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }"
:sort="false" itemKey="id" @start="onStartLeft" :clone="onClone">
<template #item="{ element }">
<element-mini :option="element" />
</template>
</draggable>
</div>
<div class="right-box">
<nested-draggable :tasks="widgetList" style="height: 100%;" />
</div>
<div class="option-box">
</div>
<div class="dataBox">
<div>{{ dragList }}</div>
</div>
<div class="dataBox">
<div>{{ widgetList }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import draggable from 'vuedraggable';
import nestedDraggable from './nest.vue';
import elementMini from './element-mini.vue';
interface type {
name: string,
id: number
}
const dragList = [
{ type: 'el-input', options: { labelWidth: '120px' }, tasks: [], name: '表单', id: 0 },
{ type: 'el-input', options: { type: 'text' }, name: '单行文本', id: 1 },
{ type: 'el-input', options: { type: 'password' }, name: '密码文本', id: 2 },
{ type: 'el-input', options: { type: 'textarea' }, name: '多行文本', id: 3 },
{ type: 'el-input-number', options: { step: 2 }, name: '计数器', id: 4 },
{
type: 'el-radio-group',
options: { items: [{ value: '1', label: '1' }, { value: '1', label: '1' }] },
name: '单选框组',
id: 5
},
{ type: 'el-slider', options: { step: 2, showStops: true }, name: '滑块', id: 6 }
];
const widgetList = reactive<type[]>([]);
const isDrag = ref(false);
const onClone = (e) => {
console.log(JSON.parse(JSON.stringify(e)));
return JSON.parse(JSON.stringify(e));
};
const onStartLeft = (e) => {
// console.log(e);
};
</script>
<style scoped>
.model {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.left-box {
width: 260px;
display: inline-block;
user-select: none;
vertical-align: top;
position: relative;
margin: 8px;
padding: 2px;
border: 1px solid #ccc;
}
.right-box {
width: 400px;
display: inline-block;
user-select: none;
vertical-align: top;
margin: 8px;
border: 1px solid #ccc;
height: 80vh;
}
.option-box {
width: 400px;
display: inline-block;
user-select: none;
vertical-align: top;
margin: 8px;
border: 1px solid #ccc;
min-height: 100px;
}
.dataBox {
width: 200px;
display: inline-block;
vertical-align: top;
margin-right: 10px;
border: 1px solid #ccc;
}
</style>

@ -0,0 +1,52 @@
<template>
<draggable
class="dragArea"
style="height: 100%"
:list="tasks"
:group="{ name: 'list' }"
item-key="name"
@change="changeCB"
:move="onMove"
>
<template #item="{ element }">
<div style="margin-bottom: 10px;">
<div>{{ element.name }}</div>
<nested-draggable :tasks="element.tasks" v-if="element.tasks" />
<component :is="element.type" :options="element.options" v-else />
</div>
</template>
</draggable>
</template>
<script lang="ts" setup>
defineOptions({
name: 'nested-draggable'
});
import draggable from 'vuedraggable';
const props = defineProps({
tasks: Array
});
const { tasks } = toRefs(props);
const changeCB = (e) => {
console.log('changeCB', e);
// console.log('changeCB', tasks.value[e.added.newIndex]);
// tasks.value[e.added.newIndex].id = Date.now();
if (e.added) {
tasks.value[e.added.newIndex].id = Date.now();
}
if (e.moved) {
tasks.value[e.moved.newIndex].id = Date.now();
}
};
const onMove = (e) => {
console.log('move', e);
};
</script>
<style scoped>
.dragArea {
min-height: 50px;
outline: 1px dashed;
margin-bottom: 5px;
overflow: hidden;
}
</style>
Loading…
Cancel
Save