Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Hooke
/
data-table
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Authored by
hookehuyr
2024-05-28 10:40:12 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
12a3121191938514635631abf951e41ac5e23512
12a31211
1 parent
54b39411
新增集合组组件功能
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
563 additions
and
17 deletions
.env.development
components.d.ts
src/components/GroupField/index.vue
src/components/NameField/index.vue
src/components/RadioField/index.vue
src/components/TextField/index.vue
src/hooks/useComponentType.js
src/views/index.vue
.env.development
View file @
12a3121
...
...
@@ -16,7 +16,7 @@ VITE_PIN =
# 反向代理服务器地址
# VITE_PROXY_TARGET = https://oa.anxinchashi.com/
VITE_PROXY_TARGET = http://oa.onwall.cn
VITE_PROXY_TARGET = http://oa
-dev
.onwall.cn
# VITE_PROXY_TARGET = https://www.wxgzjs.cn/
# PC端地址
...
...
components.d.ts
View file @
12a3121
...
...
@@ -21,6 +21,7 @@ declare module '@vue/runtime-core' {
EmailField
:
typeof
import
(
'./src/components/EmailField/index.vue'
)[
'default'
]
FileUploaderField
:
typeof
import
(
'./src/components/FileUploaderField/index.vue'
)[
'default'
]
GenderField
:
typeof
import
(
'./src/components/GenderField/index.vue'
)[
'default'
]
GroupField
:
typeof
import
(
'./src/components/GroupField/index.vue'
)[
'default'
]
IdentityField
:
typeof
import
(
'./src/components/IdentityField/index.vue'
)[
'default'
]
ImageUploaderField
:
typeof
import
(
'./src/components/ImageUploaderField/index.vue'
)[
'default'
]
MarqueeField
:
typeof
import
(
'./src/components/MarqueeField/index.vue'
)[
'default'
]
...
...
src/components/GroupField/index.vue
0 → 100644
View file @
12a3121
<!--
* @Date: 2024-05-27 14:28:57
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-05-28 10:28:26
* @FilePath: /data-table/src/components/GroupField/index.vue
* @Description: 组集合输入控件
-->
<template>
<div v-if="HideShow" class="group-field-page">
<div class="label">
<span v-if="item.component_props.required"> *</span>
{{ item.component_props.label }}
</div>
<div v-if="item.component_props.note" class="note" v-html="item.component_props.note" />
<div>
<div v-for="(data, idx) in listData" :key="idx" style="border: 1px solid #eee; border-top: 0; margin: 1rem; position: relative;">
<van-icon @click="onRemove(idx)" v-if="listData.length > 1" size="1.5rem" color="#ee0a24" name="clear" style="position: absolute; right: -0.5rem; top: -0.5rem;" />
<van-cell-group :border="false">
<component v-for="(item, index) in data" :id="item.key" :key="index"
:is="item.component" :item="item" @active="onActive" />
</van-cell-group>
</div>
<div style="margin: 1rem;">
<van-button icon="plus" type="primary" block @click="addData">追加一条记录</van-button>
</div>
</div>
</div>
</template>
<script setup>
import { styleColor } from "@/constant.js";
import { queryFormAPI } from "@/api/form.js";
import { useRoute } from "vue-router";
import { createComponentType } from "@/hooks/useComponentType";
const props = defineProps({
item: Object,
});
// TAG: 自定义主题颜色
const themeVars = {
radioColor: styleColor.baseColor,
};
// 隐藏显示
const HideShow = computed(() => {
return !props.item.component_props.disabled
});
// TODO:模拟集合组数据源
const testData = props.item.component_props.field_groups;
// TAG: 测试调整了input和name两个组件头部显示
/*const testData = [
// {
// "tag": "radio",
// "name": "radio_8",
// "note": "",
// "index": 8,
// "label": "组别",
// "options": [
// {
// "title": "少年组",
// "value": "少年组",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// {
// "title": "成人组",
// "value": "成人组",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// {
// "title": "老年组",
// "value": "老年组",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// }
// ],
// "disabled": false,
// "field_id": 799497,
// "required": true,
// "data_type": "text",
// "direction": "vertical",
// "field_name": "field_6",
// "option_map": {
// "少年组": {
// "title": "少年组",
// "value": "少年组",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// "成人组": {
// "title": "成人组",
// "value": "成人组",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// "老年组": {
// "title": "老年组",
// "value": "老年组",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// }
// },
// "interaction_type": "h5edit",
// "default": ""
// },
{
"tag": "input",
"name": "input_21",
"index": 2,
"label": "物品描述",
"unique": false,
"default": "",
"disabled": false,
"field_id": 7985071,
"readonly": false,
"required": false,
"data_type": "text",
"field_name": "field_21",
"placeholder": "请输入",
"is_camera_scan": false,
"camera_scan_type": "",
"interaction_type": "h5edit",
"is_edit_camera_scan_result": false
},
// {
// "tag": "radio",
// "name": "radio_3",
// "note": "",
// "index": 3,
// "label": "单选框",
// "options": [
// {
// "title": "选项标题1",
// "value": "选项标题1",
// "checked": true,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// {
// "title": "选项标题2",
// "value": "选项标题2",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// }
// ],
// "disabled": false,
// "field_id": 798510,
// "required": false,
// "data_type": "text",
// "direction": "vertical",
// "field_name": "field_4",
// "option_map": {
// "选项标题1": {
// "title": "选项标题1",
// "value": "选项标题1",
// "checked": true,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// "选项标题2": {
// "title": "选项标题2",
// "value": "选项标题2",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// }
// },
// "interaction_type": "h5edit",
// "default": "选项标题1"
// },
// {
// "tag": "datetime",
// "name": "datetime_4",
// "index": 4,
// "label": "日期时间",
// "default": "",
// "disabled": false,
// "field_id": 798512,
// "readonly": false,
// "required": false,
// "data_type": "text",
// "field_name": "field_5",
// "placeholder": "请选择",
// "data_maxvalue": "",
// "data_minvalue": "",
// "data_dateformat": "YYYY-MM-DD HH:mm:ss",
// "interaction_type": "h5edit"
// },
// {
// "tag": "email",
// "name": "email_5",
// "index": 5,
// "label": "邮箱",
// "unique": false,
// "default": "",
// "disabled": false,
// "field_id": 799499,
// "readonly": false,
// "required": true,
// "data_type": "text",
// "field_name": "field_7",
// "placeholder": "请输入",
// "interaction_type": "h5edit"
// },
// {
// "tag": "gender",
// "name": "gender_6",
// "note": "",
// "index": 6,
// "label": "性别",
// "options": [
// {
// "title": "男",
// "value": "男",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// {
// "title": "女",
// "value": "女",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// }
// ],
// "disabled": false,
// "field_id": 799501,
// "required": true,
// "data_type": "text",
// "direction": "vertical",
// "field_name": "field_8",
// "option_map": {
// "女": {
// "title": "女",
// "value": "女",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// },
// "男": {
// "title": "男",
// "value": "男",
// "checked": false,
// "desc_url": "",
// "is_input": false,
// "desc_text": "",
// "desc_type": "",
// "desc_btn_name": "",
// "input_required": false,
// "input_placeholder": "请输入补充信息"
// }
// },
// "interaction_type": "h5edit"
// },
{
"tag": "name",
"name": "name_71",
"index": 7,
"label": "序列号",
"unique": false,
"default": "",
"disabled": false,
"field_id": 7995031,
"readonly": false,
"required": true,
"data_type": "text",
"field_name": "field_91",
"placeholder": "请输入",
"interaction_type": "h5edit"
},
]*/
const listData = ref([]);
const formData = ref([]);
// 格式化表单数据结构
const formatData = (data) => {
const arr = [];
data.forEach((field) => {
const { interaction_type, data_type, field_id, field_name, ...component_props } = field;
component_props.is_field_group = true; // 集合标识
// 生成组件属性
const temp = {
key: field_name,
value: component_props.default ? component_props.default : "",
component_props,
};
arr.push(temp);
});
return arr;
};
const onRemove = (idx) => { // 移除列表item
listData.value.splice(idx, 1)
}
// const gender_value = ref(props.item.component_props.default);
const $route = useRoute();
onMounted(async () => {
const form_data = testData;
let page_form = [];
form_data.forEach((element) => {
page_form.push(element);
});
formData.value = formatData(page_form);
// 生成自定义组件
createComponentType(formData.value);
listData.value.push(formData.value)
// gender_value.value = props.item.component_props.default ? props.item.component_props.default : '';
// // 发送自定义数据结构
// props.item.value = { key: props.item.key, value: gender_value.value, type: "gender" };
// emit("active", props.item.value);
});
const emit = defineEmits(["active"]);
const onChange = (item) => {
// // 发送自定义数据结构
// props.item.value = { key: props.item.key, value: gender_value.value, type: "gender" };
// emit("active", props.item.value);
}
// 操作绑定自定义字段回调
const onActive = (item) => {
emit("active", item);
};
const addData = async () => {
const form_data = testData;
let page_form = [];
form_data.forEach((element) => {
page_form.push(element);
});
formData.value = formatData(page_form);
// 生成自定义组件
createComponentType(formData.value);
listData.value.push(formData.value)
}
</script>
<style lang="less" scoped>
.group-field-page {
.label {
padding: 1rem 1rem 0 1rem;
font-size: 0.9rem;
font-weight: bold;
span {
color: red;
}
}
.note {
font-size: 0.9rem;
margin-left: 1rem;
color: gray;
padding-bottom: 0.5rem;
white-space: pre-wrap;
}
.radio-wrapper {
border: 1px solid #eaeaea;
border-radius: 0.25rem;
padding: 0.25rem 0.5rem;
margin-bottom: 0.25rem;
}
}
</style>
src/components/NameField/index.vue
View file @
12a3121
<!--
* @Date: 2022-08-29 14:31:20
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 202
3-02-01 11:21:00
* @LastEditTime: 202
4-05-27 17:47:52
* @FilePath: /data-table/src/components/NameField/index.vue
* @Description: 姓名输入框
-->
<template>
<div v-if="HideShow" class="name-field-page">
<div
class="label
">
<div
:class="[isGroup ? 'group-label' : 'label']
">
<span v-if="item.component_props.required"> *</span>
{{ item.component_props.label }}
</div>
...
...
@@ -29,10 +29,17 @@
const props = defineProps({
item: Object,
});
// 隐藏显示
const HideShow = computed(() => {
return !props.item.component_props.disabled
})
});
// 集合组标识
const isGroup = computed(() => {
return props.item.component_props.is_field_group
});
onMounted(() => {
props.item.value = props.item.component_props.default;
})
...
...
@@ -48,6 +55,20 @@ onMounted(() => {
color: red;
}
}
.group-label {
padding: 0.75rem 0 0.75rem 1rem;
font-size: 0.9rem;
font-weight: bold;
background-color: #f9f9f9;
color: #666;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
span {
color: red;
}
}
}
:deep(.van-field__body) {
...
...
src/components/RadioField/index.vue
View file @
12a3121
<!--
* @Date: 2022-08-30 11:34:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 202
3-03-28 16:19:08
* @LastEditTime: 202
4-05-27 14:27:25
* @FilePath: /data-table/src/components/RadioField/index.vue
* @Description: 单项选择控件
-->
...
...
src/components/TextField/index.vue
View file @
12a3121
<!--
* @Date: 2022-08-29 14:31:20
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 202
3-05-25 18:29:39
* @LastEditTime: 202
4-05-28 10:05:08
* @FilePath: /data-table/src/components/TextField/index.vue
* @Description: 单行文本输入框(微信扫描功能)
-->
<template>
<div v-if="HideShow" class="text-field-page">
<div
class="label
">
<div
:class="[isGroup ? 'group-label' : 'label']
">
<span v-if="item.component_props.required"> *</span>
{{ item.component_props.label }}
</div>
...
...
@@ -30,10 +30,16 @@ import wx from 'weixin-js-sdk'
const props = defineProps({
item: Object,
});
// 隐藏显示
const HideShow = computed(() => {
return !props.item.component_props.disabled
})
});
// 集合组标识
const isGroup = computed(() => {
return props.item.component_props.is_field_group
});
const $route = useRoute();
// 默认识别类型
...
...
@@ -92,16 +98,30 @@ const clickRightIcon = async () => {
span {
color: red;
}
}
.note-wrapper {
font-size: 0.9rem;
margin-left: 1rem;
color: gray;
padding-bottom: 0.5rem;
padding-top: 0.25rem;
white-space: pre-wrap;
.group-label {
padding: 0.75rem 0 0.75rem 1rem;
font-size: 0.9rem;
font-weight: bold;
background-color: #f9f9f9;
color: #666;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
span {
color: red;
}
}
.note-wrapper {
font-size: 0.9rem;
margin-left: 1rem;
color: gray;
padding-bottom: 0.5rem;
padding-top: 0.25rem;
white-space: pre-wrap;
}
}
:deep(.van-field__body) {
...
...
src/hooks/useComponentType.js
View file @
12a3121
...
...
@@ -31,6 +31,7 @@ import NameField from '@/components/NameField/index.vue';
import
GenderField
from
'@/components/GenderField/index.vue'
;
import
AppointmentField
from
'@/components/AppointmentField/index.vue'
;
import
CustomField
from
'@/components/CustomField/index.vue'
;
import
GroupField
from
'@/components/GroupField/index.vue'
;
/**
* 生成自定义组件类型
...
...
@@ -61,6 +62,7 @@ import CustomField from '@/components/CustomField/index.vue';
* @type name 姓名控件 NameField
* @type gender 性别控件 GenderField
* @type appointment 预约控件 AppointmentField
* @type group 组集合输入控件 GroupField
*/
export
function
createComponentType
(
data
)
{
// 判断类型和使用组件
...
...
@@ -189,5 +191,9 @@ export function createComponentType(data) {
item
.
name
=
item
.
key
;
item
.
component
=
CustomField
;
}
if
(
item
.
component_props
.
tag
===
'group'
)
{
item
.
name
=
item
.
key
;
item
.
component
=
GroupField
;
}
})
}
...
...
src/views/index.vue
View file @
12a3121
<!--
* @Date: 2022-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-05-
13 14:24:11
* @LastEditTime: 2024-05-
28 10:39:05
* @FilePath: /data-table/src/views/index.vue
* @Description: 首页
-->
...
...
@@ -240,6 +240,59 @@ onMounted(async () => {
visible: !page_commit.invisible,
};
}
// TODO:待完善,集合组保存的字段和值怎么处理,都是单条数据都要合并到相应的 group_field_name 下面?
// page_form.unshift({
// data_type : "text",
// default : "",
// disabled : false,
// field_id : 1414832,
// field_name : "field_4",
// index : 41,
// interaction_type : "h5edit",
// label : "物品详情",
// name : "name_41",
// placeholder : "请输入",
// readonly : false,
// required : false,
// tag : "group",
// unique : false,
// field_groups: [{
// "tag": "input",
// "name": "input_21",
// "index": 2,
// "label": "物品描述",
// "unique": false,
// "default": "",
// "disabled": false,
// "field_id": 7985071,
// "readonly": false,
// "required": false,
// "data_type": "text",
// "field_name": "field_21",
// "placeholder": "请输入",
// "is_camera_scan": false,
// "camera_scan_type": "",
// "interaction_type": "h5edit",
// "is_edit_camera_scan_result": false,
// "group_field_name" : "field_4",
// },{
// "tag": "name",
// "name": "name_71",
// "index": 7,
// "label": "序列号",
// "unique": false,
// "default": "",
// "disabled": false,
// "field_id": 7995031,
// "readonly": false,
// "required": true,
// "data_type": "text",
// "field_name": "field_91",
// "placeholder": "请输入",
// "interaction_type": "h5edit",
// "group_field_name" : "field_4",
// },]
// });
formData.value = formatData(page_form);
// TODO:再次提交测试, 需要获取原来表单数据
// formData.value.forEach((item) => {
...
...
@@ -315,7 +368,7 @@ onMounted(async () => {
},
];
// 生成自定义组件
createComponentType(mockData.value);
//
createComponentType(mockData.value);
createComponentType(formData.value);
// 过期时间显示
notice_text.value = `表单报名将在 ${formSetting.value.sjsj_end_time} 后结束`;
...
...
Please
register
or
login
to post a comment