feat(Design): 新增矩阵题型和文件上传题型

- 新增矩阵题型组件和相关配置
- 新增文件上传题型组件和相关配置
-优化签名题型组件
- 添新的 CSS 样式类
This commit is contained in:
陈昱达
2025-03-13 16:49:19 +08:00
parent 1a05cb6262
commit 33ac908ef9
22 changed files with 711 additions and 222 deletions

View File

@@ -1,12 +1,17 @@
<script setup lang="ts">
import { useTemplateRef, type Directive } from 'vue';
import { useTemplateRef, toRefs } from 'vue';
const columnLabels = useTemplateRef<HTMLElement[]>('columnLabels');
// 注意, element.options 里面的东西是数组,第一项内容是行标签内容,第二项内容是列标签内容
// 类型 AI 生成 切勿盲目相信,以实际为准
const { element } = defineProps<{ element: MatrixSurveyQuestion }>();
const props = defineProps<{
element: Any;
index: number;
active: boolean;
}>();
const { element } = toRefs(props);
/**
* input 类型映射,里面自行处理逻辑返回对应类型
* // remark: 填空内容 question_type 8
@@ -15,7 +20,7 @@ const { element } = defineProps<{ element: MatrixSurveyQuestion }>();
* @default 'radio'
*/
const tableInputTypeMapping = (/** regx?: any */) => {
switch (element.question_type) {
switch (element.value.question_type) {
case 8:
return 'text';
case 9:
@@ -27,29 +32,29 @@ const tableInputTypeMapping = (/** regx?: any */) => {
}
};
/**
* 自定义指令,用于在元素挂载后自动获取焦点
*/
const vFocus: Directive = {
mounted(el: HTMLInputElement) {
el.focus();
}
const emit = defineEmits(['update:element']);
const emitValue = () => {
emit('update:element', element.value);
};
</script>
<template>
<van-cell>
<van-field
v-model="element.stem"
:label="element.stem"
:required="element.config.is_required === 1"
label-align="top"
>
<template #left-icon>
{{ index + 1 }}
</template>
<!-- 使用 title 插槽来自定义标题 -->
<template #title>
<span>
<span v-if="element?.config?.is_required">*</span>
<span v-html="element.title"></span>
<span v-html="element.stem"></span>
</span>
<template #label>
<contenteditable v-model="element.stem" :active="active" @blur="emitValue"></contenteditable>
</template>
<!-- 使用 label 插槽来自定义标题 -->
<template #label>
<template #input>
<table class="martrix-table">
<thead>
<tr>
@@ -57,15 +62,11 @@ const vFocus: Directive = {
<th></th>
<!-- 第二行内容开始填充 -->
<td v-for="col in element.options[1]" :key="col.option" ref="columnLabels">
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<input
v-if="col.editor"
<contenteditable
v-model="col.option"
v-focus
type="text"
@focusout="col.editor = false"
/>
<span v-else @click="col.editor = true" v-html="col.option"></span>
:active="active"
@blur="emitValue"
></contenteditable>
</td>
</tr>
</thead>
@@ -73,16 +74,13 @@ const vFocus: Directive = {
<tr v-for="row in element.options[0]" :key="row.option">
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<td>
<input
v-if="row.editor"
<contenteditable
v-model="row.option"
v-focus
type="text"
@focusout="row.editor = false"
/>
<span v-else @click="row.editor = true" v-html="row.option"></span>
:active="active"
@blur="emitValue"
></contenteditable>
</td>
<td v-for="col in element.options[1]" :key="col.option">
<td v-for="col in element.options[1]" :key="col.option" class="td-input">
<!-- 编辑状态单次点击出输入框失焦后关闭 -->
<input :id="col.option" :type="tableInputTypeMapping()" :name="row.option" />
</td>
@@ -90,7 +88,7 @@ const vFocus: Directive = {
</tbody>
</table>
</template>
</van-cell>
</van-field>
</template>
<style scoped lang="scss">
.martrix-table {
@@ -103,12 +101,31 @@ const vFocus: Directive = {
padding: 8px;
border: 1px solid #ddd;
border-width: 0 0 1px;
text-align: left;
text-align: center;
}
}
.td-input {
text-align: center;
}
input[type='text'] {
width: 85%;
border: none;
border-radius: 5px;
outline: 1px solid #ddd;
}
input[type='checkbox'] {
border: 1px solid #ddd;
border-radius: 5px;
outline: none;
}
input[type='radio'] {
border: 1px solid #ddd;
border-radius: 5px;
outline: none;
}
.martrix-table-action {