master
xy 1 year ago
parent f837517ade
commit 62cec2d363

@ -21,10 +21,12 @@
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"vant": "^2.13.2",
"vue": "2.6.10",
"vue-router": "3.0.6",
"vuex": "3.1.0",
"vxe-table": "^3.8.22"
"vxe-table": "^3.8.22",
"moment": "^2.29.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.4",

@ -29,9 +29,9 @@ if (process.env.NODE_ENV === 'production') {
}
// set ElementUI lang to EN
Vue.use(ElementUI, { locale })
//Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui按如下方式声明
// Vue.use(ElementUI)
Vue.use(ElementUI)
import { VxeIcon, VxeTable, VxeColumn, VxeColgroup, VxeTableEditModule, VxeTableValidatorModule, VxeModal, VxeToolbar } from "vxe-table";
import "vxe-table/styles/index.scss"
Vue.use(VxeTableEditModule);
@ -45,6 +45,14 @@ Vue.use(VxeToolbar);
Vue.config.productionTip = false
//vant
import Vant from 'vant'
Vue.use(Vant)
//moment
import moment from 'moment'
Vue.prototype.$moment = moment;
import { setToken,getToken } from "@/utils/auth"
if (window.__POWERED_BY_WUJIE__) {
let instance;

@ -0,0 +1,356 @@
import formBuilderMap from './formBuilderMap'
import { CreateElement } from 'vue'
import moment from 'moment'
import { getToken } from "@/utils/auth";
/**
* @param {String} device 'desktop' or 'mobile'
* @param {Object} info field参数
* @param {CreateElement} h
**/
export default function (device, info,h ) {
let formItem;
if (device === 'desktop') {
switch (info.type) {
case 'text':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
value: this.form[info.name],
clearable: true,
placeholder: info.help_text
},
attrs: {
placeholder: info.help_text
},
on: {
input: e => {
this.form[info.name] = e
}
}
})
break;
case 'textarea':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
type: 'textarea',
autosize: {
minRows: 2
},
value: this.form[info.name],
clearable: true,
placeholder: info.help_text
},
attrs: {
placeholder: info.help_text
},
on: {
input: e => {
this.form[info.name] = e
}
}
})
break;
case 'date':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
type: 'date',
'value-format': 'yyyy-MM-dd',
format: 'yyyy年MM月dd日',
value: this.form[info.name],
clearable: true,
placeholder: info.help_text,
'picker-options': {
shortcuts: [
{
text: '一年前',
onClick(picker) {
picker.$emit('pick', moment().subtract(1,'years').toDate());
}
},
{
text: '一月前',
onClick(picker) {
picker.$emit('pick', moment().subtract(1,'months').toDate());
}
},
{
text: '一周前',
onClick(picker) {
picker.$emit('pick', moment().subtract(1,'weeks').toDate());
}
},
{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
},
{
text: '一周后',
onClick(picker) {
picker.$emit('pick', moment().add(1,'weeks').toDate());
}
},
{
text: '一月后',
onClick(picker) {
picker.$emit('pick', moment().add(1,'months').toDate());
}
},
{
text: '一年后',
onClick(picker) {
picker.$emit('pick', moment().add(1,'years').toDate());
}
},
]
}
},
attrs: {
placeholder: info.help_text
},
style: {
width: '100%'
},
on: {
input: e => {
this.$set(this.form,info.name,e)
}
}
})
break;
case 'datetime':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
type: 'datetime',
'value-format': 'yyyy-MM-dd',
format: 'yyyy年MM月dd日',
value: this.form[info.name],
clearable: true,
placeholder: info.help_text,
'picker-options': {
shortcuts: [
{
text: '一年前',
onClick(picker) {
picker.$emit('pick', moment().subtract(1,'years').toDate());
}
},
{
text: '一月前',
onClick(picker) {
picker.$emit('pick', moment().subtract(1,'months').toDate());
}
},
{
text: '一周前',
onClick(picker) {
picker.$emit('pick', moment().subtract(1,'weeks').toDate());
}
},
{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
},
{
text: '一周后',
onClick(picker) {
picker.$emit('pick', moment().add(1,'weeks').toDate());
}
},
{
text: '一月后',
onClick(picker) {
picker.$emit('pick', moment().add(1,'months').toDate());
}
},
{
text: '一年后',
onClick(picker) {
picker.$emit('pick', moment().add(1,'years').toDate());
}
},
]
}
},
style: {
width: '100%'
},
attrs: {
placeholder: info.help_text
},
on: {
input: e => {
this.$set(this.form,info.name,e)
}
}
})
break;
case 'select':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
value: this.form[info.name],
clearable: true,
placeholder: info.help_text
},
attrs: {
placeholder: info.help_text
},
on: {
input: e => {
this.$set(this.form,info.name,e)
}
}
},[1,2,3].map(option => (
h('el-option',{
props: {
label: option,
value: option
}
})
)))
break;
case 'radio':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
value: this.form[info.name],
},
attrs: {
placeholder: info.help_text
},
on: {
input: e => {
this.$set(this.form,info.name,e)
}
}
},[1,2,3].map(option => (
h('el-radio',{
props: {
label: option
}
},option)
)))
break;
case 'file':
formItem = h(formBuilderMap(device).get(info.type),{
props: {
action: process.env.VUE_APP_UPLOAD_API,
headers: {
Authorization: `Bearer ${getToken()}`,
},
multiple: true,
fileList: this.file[info.name],
beforeUpload: (file) => {
if ((file.size / 1024 / 1024) > (20)) {
this.$message({
type: "warning",
message: "上传图片大小超过20Mb",
});
return false;
}
},
onSuccess: (response, file, fileList) => {
this.file[info.name] = fileList;
},
onRemove: (file, fileList) => {
this.file[info.name] = fileList;
},
onError: (err, file, fileList) => {
this.file[info.name] = fileList;
this.$message({
type: "warning",
message: err,
});
}
},
scopedSlots: {
file: (scope) => {
let { file } = scope;
return [
h("div", {}, [
h("i", {
class: {
"el-icon-circle-check":
file.status ===
"success",
"el-icon-loading":
file.status ===
"uploading",
},
style: {
color:
file.status ===
"success"
? "green"
: "",
},
}),
h(
"a",
{
attrs: {
href: file.url,
download: file.name,
},
class: {
"uploaded-a":
file.status ===
"success",
},
style: {
padding: "0 4px",
},
},
file.name
),
]),
h("i", {
class: "el-icon-close",
on: {
["click"]: () => {
this.$set(this.file, info.field, this.file[info.field].filter((item) => item !== file))
}
},
}),
];
}
}
},[
h(
"el-button",
{
slot: "trigger",
props: {
size: "small",
type: "primary",
},
},
"选取文件"
),
h(
"div",
{
class: "el-upload__tip",
slot: "tip",
},
"文件不超过20Mb"
)
])
}
return h('el-form-item',{
props: {
prop: info.name,
label: info.label
},
style: {
'grid-column-start': info.gs_x,
'grid-column-end': info.gs_x + info.gs_width,
'grid-row-start': info.gs_y,
'grid-row-end': info.gs_y + info.gs_height
}
},[formItem])
}
}

@ -2,7 +2,7 @@ export default function (device) {
return device === 'desktop' ?
new Map([
['text', 'el-input'],
['text', 'el-input'],
['textarea', 'el-input'],
['date', 'el-date-picker'],
['datetime', 'el-date-picker'],
['select', 'el-select'],
@ -16,18 +16,18 @@ export default function (device) {
['sign', 'el-image']
]) :
new Map([
['text', 'el-input'],
['text', 'el-input'],
['date', 'el-date-picker'],
['datetime', 'el-date-picker'],
['select', 'el-select'],
['radio', 'el-radio-group'],
['file', 'el-upload'],
['label', 'el-tag'],
['text', 'van-field'],
['textarea', 'van-field'],
['date', 'van-cell'],
['datetime', 'van-datetime-picker'],
['select', 'van-picker'],
['radio', 'van-radio-group'],
['file', 'van-uploader'],
['label', 'van-tag'],
['static', 'el-link'],
['hr', 'el-divider'],
['choice', 'el-select'],
['choices', 'el-select'],
['sign', 'el-image']
['hr', 'van-divide'],
['choice', 'van-picker'],
['choices', 'van-checkbox'],
['sign', 'van-image']
])
}

@ -0,0 +1,130 @@
<script>
import formBuilder from '@/utils/formBuilder'
export default {
props: {
device: {
type: String,
default: 'desktop',
required: true
}
},
data() {
return {
info: [
{
id: 1,
type: "text",
gs_x: 1,
gs_y: 1,
gs_height: 1,
gs_width: 6,
name: "aaa",
label: "aaa",
help_text: 'write aaa'
},
{
id: 2,
type: "textarea",
gs_x: 7,
gs_y: 1,
gs_height: 1,
gs_width: 6,
name: "bbb",
label: "bbb",
help_text: 'write bbb'
},
{
id: 3,
type: "date",
gs_x: 1,
gs_y: 2,
gs_height: 1,
gs_width: 4,
name: "ccc",
label: "ccc",
help_text: 'write ccc'
},
{
id: 4,
type: "datetime",
gs_x: 5,
gs_y: 2,
gs_height: 1,
gs_width: 4,
name: "ddd",
label: "ddd",
help_text: 'write ddd'
},
{
id: 5,
type: "select",
gs_x: 1,
gs_y: 3,
gs_height: 1,
gs_width: 6,
name: "eee",
label: "eee",
help_text: 'write eee'
},
{
id: 6,
type: "radio",
gs_x: 1,
gs_y: 4,
gs_height: 1,
gs_width: 6,
name: "fff",
label: "fff",
help_text: 'write fff'
},
{
id: 7,
type: "file",
gs_x: 1,
gs_y: 5,
gs_height: 1,
gs_width: 6,
name: "ggg",
label: "ggg",
help_text: 'write ggg'
},
],
form: {
aaa: "",
bbb: ""
},
file: {
ggg: []
}
}
},
methods: {
},
computed: {
},
render(h) {
return h('el-form', {
class: 'form',
props: {
model: this.form,
'label-position': 'top'
}
},this.info.map(field => formBuilder.bind(this)(this.device, field, h)))
}
}
</script>
<style scoped lang="scss">
.form {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 20px;
}
::v-deep .el-form-item {
margin-bottom: 0;
}
::v-deep .el-form-item__label {
padding-bottom: 0;
}
</style>

@ -0,0 +1,17 @@
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {},
computed: {},
}
</script>
<style scoped lang="scss">
</style>

@ -6,19 +6,36 @@
</template>
<template>
<div class="form-container">
<template v-if="device === 'desktop'">
<DesktopForm :device="device"></DesktopForm>
</template>
<template v-else>
<MobileForm></MobileForm>
</template>
</div>
</template>
</el-card>
</div>
</template>
<script>
import DesktopForm from "./DesktopForm.vue";
import MobileForm from "./MobileForm.vue";
export default {
components: {
DesktopForm,
MobileForm
},
data() {
return {}
},
methods: {},
computed: {},
computed: {
device() {
return this.$store.state.app.device
}
},
}
</script>
@ -29,7 +46,8 @@ export default {
.container {
padding: 20px;
}
.form-container {
}
@media (max-width: 768px) {
.container {
padding: 10px;

Loading…
Cancel
Save