<script lang="ts" setup>
|
import type { WxCpActivityApi } from '#/api/wxcp/activity';
|
|
import { Button, Input, Select, Switch } from 'ant-design-vue';
|
|
import { FIELD_TYPE_OPTIONS } from '../data';
|
|
defineOptions({ name: 'WxCpActivityFieldEditor' });
|
|
interface Props {
|
/** 采集字段列表 */
|
modelValue?: WxCpActivityApi.Field[];
|
disabled?: boolean;
|
}
|
|
const props = withDefaults(defineProps<Props>(), {
|
modelValue: () => [],
|
disabled: false,
|
});
|
|
const emit = defineEmits<{
|
'update:modelValue': [value: WxCpActivityApi.Field[]];
|
}>();
|
|
/** 需要填写选项的字段类型 */
|
const OPTION_TYPES = new Set(['checkbox', 'radio', 'select']);
|
|
function update(index: number, patch: Partial<WxCpActivityApi.Field>) {
|
const list = [...props.modelValue];
|
list[index] = { ...list[index], ...patch };
|
emit('update:modelValue', list);
|
}
|
|
function handleAdd() {
|
emit('update:modelValue', [
|
...props.modelValue,
|
{
|
fieldLabel: '',
|
fieldType: 'text',
|
required: false,
|
sortNo: props.modelValue.length + 1,
|
},
|
]);
|
}
|
|
function handleRemove(index: number) {
|
const list = props.modelValue.filter((_, i) => i !== index);
|
emit('update:modelValue', list);
|
}
|
|
function needOptions(type?: string) {
|
return OPTION_TYPES.has(type ?? '');
|
}
|
</script>
|
|
<template>
|
<div class="mb-4">
|
<div class="mb-2 flex items-center justify-between">
|
<span class="text-sm font-medium">采集字段</span>
|
<Button size="small" :disabled="disabled" @click="handleAdd">
|
添加字段
|
</Button>
|
</div>
|
|
<div v-if="!modelValue.length" class="text-xs text-gray-400">
|
未添加字段时,成员只需填写姓名、手机号、参与说明并上传附件。
|
</div>
|
|
<div
|
v-for="(item, index) in modelValue"
|
:key="index"
|
class="mb-2 rounded border border-gray-200 p-2 dark:border-gray-700"
|
>
|
<div class="flex flex-wrap items-center gap-2">
|
<Input
|
:value="item.fieldLabel"
|
class="w-44"
|
placeholder="字段名称"
|
:disabled="disabled"
|
@update:value="(value: string) => update(index, { fieldLabel: value })"
|
/>
|
<Select
|
:value="item.fieldType"
|
class="w-32"
|
:options="FIELD_TYPE_OPTIONS"
|
:disabled="disabled"
|
@update:value="(value: unknown) => update(index, { fieldType: String(value) })"
|
/>
|
<Input
|
v-if="needOptions(item.fieldType)"
|
:value="item.fieldOptions"
|
class="w-64"
|
placeholder="选项,用英文逗号分隔"
|
:disabled="disabled"
|
@update:value="(value: string) => update(index, { fieldOptions: value })"
|
/>
|
<Input
|
v-else
|
:value="item.placeholder"
|
class="w-64"
|
placeholder="输入提示(选填)"
|
:disabled="disabled"
|
@update:value="(value: string) => update(index, { placeholder: value })"
|
/>
|
<span class="text-xs text-gray-500">必填</span>
|
<Switch
|
:checked="item.required"
|
size="small"
|
:disabled="disabled"
|
@change="(checked: unknown) => update(index, { required: checked === true })"
|
/>
|
<Button
|
danger
|
type="link"
|
size="small"
|
:disabled="disabled"
|
@click="handleRemove(index)"
|
>
|
删除
|
</Button>
|
</div>
|
</div>
|
</div>
|
</template>
|