hookehuyr

新增义工组别组件结构-API数据未处理

...@@ -79,5 +79,6 @@ declare module '@vue/runtime-core' { ...@@ -79,5 +79,6 @@ declare module '@vue/runtime-core' {
79 VanTimePicker: typeof import('vant/es')['TimePicker'] 79 VanTimePicker: typeof import('vant/es')['TimePicker']
80 VanUploader: typeof import('vant/es')['Uploader'] 80 VanUploader: typeof import('vant/es')['Uploader']
81 VideoField: typeof import('./src/components/VideoField/index.vue')['default'] 81 VideoField: typeof import('./src/components/VideoField/index.vue')['default']
82 + VolunteerGroupField: typeof import('./src/components/VolunteerGroupField/index.vue')['default']
82 } 83 }
83 } 84 }
......
1 +<!--
2 + * @Date: 2022-08-30 11:34:19
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-06-24 14:40:39
5 + * @FilePath: /data-table/src/components/VolunteerGroupField/index.vue
6 + * @Description: 单项选择控件
7 +-->
8 +<template>
9 + <div v-if="HideShow" class="radio-field-page">
10 + <div class="label">
11 + <span v-if="item.component_props.required">&nbsp;*</span>
12 + {{ item.component_props.label }}
13 + </div>
14 + <div v-if="item.component_props.note" class="note" v-html="item.component_props.note" />
15 + <van-field :rules="item.rules">
16 + <template #input>
17 + <van-radio-group @change="onChange(item)" v-model="radio_value" :direction="item.component_props.direction"
18 + style="width: 100%">
19 + <div v-for="x in item.component_props.options" :key="x.value" class="radio-wrapper">
20 + <div v-if="item.component_props.readonly" class="readonly-show">
21 + <div v-if="item.component_props.default === x.value" role="radio" class="van-radio van-radio--vertical" tabindex="0" aria-checked="true" data-v-04873bb2="" style="margin-bottom: 0.25rem;"><div class="van-radio__icon van-radio__icon--round van-radio__icon--checked" style="font-size: 1rem;"><i class="van-badge__wrapper van-icon van-icon-success" style="border-color: rgb(194, 145, 95); background-color: rgb(194, 145, 95);"><!----><!----><!----></i></div><span class="van-radio__label">{{ x.title }}</span></div>
22 + <div v-else role="radio" class="van-radio van-radio--vertical" tabindex="0" aria-checked="false" data-v-04873bb2="" style="margin-bottom: 0.25rem;"><div class="van-radio__icon van-radio__icon--round" style="font-size: 1rem;"><i class="van-badge__wrapper van-icon van-icon-success"><!----><!----><!----></i></div><span class="van-radio__label">{{ x.title }}</span></div>
23 + </div>
24 + <van-radio v-else :name="x.value" icon-size="1rem" :checked-color="themeVars.radioColor"
25 + style="margin-bottom: 0.25rem">{{ x.title }}</van-radio>
26 + <div v-if="x.desc_text" class="van-multi-ellipsis--l3 rule-desc-text">{{ x.desc_text }}</div>
27 + <div v-if="x.desc_type === 'text'" class="rule-box" @click="showRule(x)">
28 + {{ x.desc_btn_name }}&nbsp;>>
29 + </div>
30 + <div v-if="x.desc_type === 'url'" class="rule-box" @click="showUrl(x)">
31 + {{ x.desc_btn_name }}&nbsp;<van-icon name="link-o" />
32 + </div>
33 + <van-field v-if="radio_value === x.value && x.is_input" @blur="onBlur(x)" v-model="x.affix" label=" " label-width="5px"
34 + :placeholder="x.input_placeholder" :rules="x.input_required ? rules : ''" :required="x.input_required"
35 + class="affix-input" />
36 + </div>
37 + </van-radio-group>
38 + </template>
39 + </van-field>
40 + </div>
41 +
42 + <van-overlay :show="show" :lock-scroll="false">
43 + <div class="rule-wrapper" @click.stop>
44 + <div class="rule-block">
45 + <div style="height: 70vh; min-height: 70vh; overflow: scroll; white-space: pre-wrap; line-height: 1.5;" v-html="rule_content"></div>
46 + <div class="close-btn">
47 + <van-button type="primary" block @click="closeRule"
48 + >关&nbsp;&nbsp;闭</van-button
49 + >
50 + </div>
51 + <div></div>
52 + </div>
53 + </div>
54 + </van-overlay>
55 +</template>
56 +
57 +<script setup>
58 +import { styleColor } from "@/constant.js";
59 +import $ from "jquery";
60 +
61 +const props = defineProps({
62 + item: Object,
63 +});
64 +
65 +// TAG: 自定义主题颜色
66 +const themeVars = {
67 + radioColor: styleColor.baseColor,
68 +};
69 +// 隐藏显示
70 +const HideShow = computed(() => {
71 + return !props.item.component_props.disabled
72 +})
73 +
74 +// 校验函数返回 true 表示校验通过,false 表示不通过
75 +const required = props.item.component_props.required;
76 +const validator = (val) => {
77 + if (required && !val) {
78 + return false;
79 + } else {
80 + return true;
81 + }
82 +};
83 +// 错误提示文案
84 +const validatorMessage = (val, rule) => {
85 + if (required && !val) {
86 + return "补充信息不能为空";
87 + }
88 +};
89 +const rules = [{ validator, message: validatorMessage }];
90 +
91 +const emit = defineEmits(["active"]);
92 +const radio_value = ref(props.item.component_props.default);
93 +const affix_value = ref('');
94 +
95 +const onChange = (item) => {
96 + clearAffix()
97 + // 发送自定义数据结构
98 + props.item.value = { key: props.item.key, value: radio_value.value, affix: affix_value.value, type: "radio" };
99 + emit("active", props.item.value);
100 +}
101 +const onBlur = (item) => {
102 + clearAffix()
103 + affix_value.value = item.affix ? `${item.title}: ${item.affix}` : '';
104 + // 发送自定义数据结构
105 + props.item.value = { key: props.item.key, value: radio_value.value, affix: affix_value.value, type: "radio" };
106 + emit("active", props.item.value);
107 +}
108 +const clearAffix = () => {
109 + const options = props.item.component_props.options;
110 + // 为选中项目的补充清空
111 + options.forEach(element => {
112 + if (element.value !== radio_value.value) {
113 + element.affix = ''
114 + }
115 + });
116 +}
117 +onMounted(() => {
118 + radio_value.value = props.item.component_props.default ? props.item.component_props.default : '';
119 + // TODO: 请求新的义工组别API获取组别的列表替换掉
120 + props.item.component_props.options[0]['title'] = 'text1';
121 + // 发送自定义数据结构
122 + props.item.value = { key: props.item.key, value: radio_value.value, affix: affix_value.value, type: "radio" };
123 + emit("active", props.item.value);
124 + //
125 + $(".rule-box").css("color", themeVars.radioColor);
126 +})
127 +
128 +// 补充信息弹框
129 +const show = ref(false);
130 +const showRule = (rule) => {
131 + show.value = true;
132 + rule.desc_text = rule.desc_text.replace(/\\n/g, "<br>")
133 + rule_content.value = rule.desc_text;
134 +};
135 +const closeRule = () => {
136 + show.value = false;
137 + rule_content.value = "";
138 +};
139 +const showUrl = (rule) => {
140 + location.href = rule.desc_url
141 +}
142 +const rule_content = ref("");
143 +</script>
144 +
145 +<style lang="less" scoped>
146 +.radio-field-page {
147 + .label {
148 + padding: 1rem 1rem 0 1rem;
149 + font-size: 0.9rem;
150 + font-weight: bold;
151 +
152 + span {
153 + color: red;
154 + }
155 + }
156 +
157 + .note {
158 + font-size: 0.9rem;
159 + margin-left: 1rem;
160 + color: gray;
161 + padding-bottom: 0.5rem;
162 + white-space: pre-wrap;
163 + }
164 +
165 + .radio-wrapper {
166 + border: 1px solid #eaeaea;
167 + border-radius: 0.25rem;
168 + padding: 0.25rem 0.5rem;
169 + margin-bottom: 0.25rem;
170 + }
171 + .affix-input {
172 + border: 1px solid #eaeaea;
173 + border-radius: 0.25rem;
174 + padding: 0.25rem 0.5rem;
175 + margin-top: 0.5rem;
176 + margin-bottom: 0.25rem;
177 + }
178 + .rule-desc-text {
179 + margin: 0.35rem 0.5rem 0.5rem 1.75rem;
180 + font-size: 0.8rem;
181 + color: #808080;
182 + }
183 + .rule-box {
184 + font-size: 0.85rem;
185 + margin-left: 1.8rem;
186 + padding-bottom: 0.5rem;
187 + width: fit-content;
188 + }
189 +}
190 +
191 +.rule-wrapper {
192 + display: flex;
193 + align-items: center;
194 + justify-content: center;
195 + height: 100%;
196 +}
197 +
198 +.rule-block {
199 + position: relative;
200 + width: 80vw;
201 + height: 80vh;
202 + background-color: #fff;
203 + overflow: scroll;
204 + padding: 1rem;
205 + .close-btn {
206 + position: absolute;
207 + bottom: 1rem;
208 + // transform: translateX(100%);
209 + width: calc(100% - 2rem);
210 + }
211 +}
212 +.multi-rule-field-box {
213 + border: 1px solid #eaeaea;
214 + border-radius: 0.25rem;
215 + padding: 1rem 0.5rem 0 0.5rem;
216 + // width: 100vw;
217 + margin-bottom: 0.5rem;
218 +}
219 +
220 +:deep(.van-radio) {
221 + // border: 1px solid #eaeaea;
222 + // border-radius: 0.25rem;
223 + // padding: 0.25rem 0.5rem;
224 +}
225 +</style>
...@@ -33,6 +33,7 @@ import AppointmentField from '@/components/AppointmentField/index.vue'; ...@@ -33,6 +33,7 @@ import AppointmentField from '@/components/AppointmentField/index.vue';
33 import CustomField from '@/components/CustomField/index.vue'; 33 import CustomField from '@/components/CustomField/index.vue';
34 import GroupField from '@/components/GroupField/index.vue'; 34 import GroupField from '@/components/GroupField/index.vue';
35 import OrgPickerField from '@/components/OrgPickerField/index.vue'; 35 import OrgPickerField from '@/components/OrgPickerField/index.vue';
36 +import VolunteerGroupField from '@/components/VolunteerGroupField/index.vue';
36 37
37 /** 38 /**
38 * 生成自定义组件类型 39 * 生成自定义组件类型
...@@ -65,6 +66,7 @@ import OrgPickerField from '@/components/OrgPickerField/index.vue'; ...@@ -65,6 +66,7 @@ import OrgPickerField from '@/components/OrgPickerField/index.vue';
65 * @type appointment 预约控件 AppointmentField 66 * @type appointment 预约控件 AppointmentField
66 * @type group 组集合输入控件 GroupField 67 * @type group 组集合输入控件 GroupField
67 * @type org_picker 树形选择控件 OrgPickerField 68 * @type org_picker 树形选择控件 OrgPickerField
69 + * @type volunteer_group 义工组别选择控件 VolunteerGroupField
68 */ 70 */
69 export function createComponentType(data) { 71 export function createComponentType(data) {
70 // 判断类型和使用组件 72 // 判断类型和使用组件
...@@ -201,5 +203,8 @@ export function createComponentType(data) { ...@@ -201,5 +203,8 @@ export function createComponentType(data) {
201 item.name = item.key; 203 item.name = item.key;
202 item.component = OrgPickerField; 204 item.component = OrgPickerField;
203 } 205 }
206 + if (item.component_props.tag === 'volunteer_group') {
207 + item.component = VolunteerGroupField;
208 + }
204 }) 209 })
205 } 210 }
......
1 <!-- 1 <!--
2 * @Date: 2022-07-18 10:22:22 2 * @Date: 2022-07-18 10:22:22
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-06-20 10:17:01 4 + * @LastEditTime: 2024-06-24 16:30:22
5 * @FilePath: /data-table/src/views/index.vue 5 * @FilePath: /data-table/src/views/index.vue
6 * @Description: 首页 6 * @Description: 首页
7 --> 7 -->
...@@ -433,6 +433,48 @@ onMounted(async () => { ...@@ -433,6 +433,48 @@ onMounted(async () => {
433 // "placeholder": "请输入", 433 // "placeholder": "请输入",
434 // "interaction_type": "h5edit" 434 // "interaction_type": "h5edit"
435 // }) 435 // })
436 +
437 + // page_form.push({
438 + // data_type: "text",
439 + // default: "选项标题1",
440 + // direction: "vertical",
441 + // disabled: false,
442 + // field_id: 800207,
443 + // field_name: "field_62",
444 + // index: 61,
445 + // interaction_type: "h5edit",
446 + // label: "义工组别",
447 + // name: "radio_61",
448 + // note: "",
449 + // required: false,
450 + // tag: "volunteer_group",
451 + // options: [
452 + // {
453 + // checked: true,
454 + // desc_btn_name: "",
455 + // desc_text: "",
456 + // desc_type: "",
457 + // desc_url: "",
458 + // input_placeholder: "请输入补充信息",
459 + // input_required: false,
460 + // is_input: false,
461 + // title: "选项标题1",
462 + // value: "选项标题1"
463 + // },
464 + // {
465 + // checked: false,
466 + // desc_btn_name: "",
467 + // desc_text: "",
468 + // desc_type: "",
469 + // desc_url: "",
470 + // input_placeholder: "请输入补充信息",
471 + // input_required: false,
472 + // is_input: false,
473 + // title: "选项标题2",
474 + // value: "选项标题2"
475 + // }
476 + // ]
477 + // })
436 formData.value = formatData(page_form); 478 formData.value = formatData(page_form);
437 479
438 // TAG:获取原来表单数据 480 // TAG:获取原来表单数据
...@@ -734,6 +776,9 @@ const onActive = (item) => { ...@@ -734,6 +776,9 @@ const onActive = (item) => {
734 }); 776 });
735 postData.value = _.assign(postData.value, { [item.key]: checkbox_value }); 777 postData.value = _.assign(postData.value, { [item.key]: checkbox_value });
736 } 778 }
779 + if (item?.type === "volunteer_group") { // 义工组别选择控件
780 + postData.value = _.assign(postData.value, { [item.key]: item.affix ? item.affix : item.value });
781 + }
737 // 检查规则,会影响字段显示 782 // 检查规则,会影响字段显示
738 checkRules(); 783 checkRules();
739 }; 784 };
......
...@@ -3630,9 +3630,9 @@ uuid@^8.3.2: ...@@ -3630,9 +3630,9 @@ uuid@^8.3.2:
3630 resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" 3630 resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
3631 integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 3631 integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
3632 3632
3633 -vant@^4.9.0: 3633 +vant@^4.9.1:
3634 version "4.9.1" 3634 version "4.9.1"
3635 - resolved "https://mirrors.cloud.tencent.com/npm/vant/-/vant-4.9.1.tgz" 3635 + resolved "https://mirrors.cloud.tencent.com/npm/vant/-/vant-4.9.1.tgz#d042702b0d14da987e4b17e46e4297dabb5fae01"
3636 integrity sha512-p7iAKJyACYVwrmrkf3COmbuvzjHrFJ+FAmlyOWbxTS2ovkRs+tNKYjX2iibAl4XnHXBQD+qpX0ogUqE3jE7Isg== 3636 integrity sha512-p7iAKJyACYVwrmrkf3COmbuvzjHrFJ+FAmlyOWbxTS2ovkRs+tNKYjX2iibAl4XnHXBQD+qpX0ogUqE3jE7Isg==
3637 dependencies: 3637 dependencies:
3638 "@vant/popperjs" "^1.3.0" 3638 "@vant/popperjs" "^1.3.0"
......