Merge branch 'master' into dev-ticket

This commit is contained in:
huxuejian 2026-08-17 17:28:00 +08:00
commit 56c08eb255
5 changed files with 164 additions and 2 deletions

View File

@ -0,0 +1,47 @@
<template>
<common-cell :name="name" :required="required">
<view class="joint-row">
<picker mode="selector" :range="jointOptions" :disabled="disableChange" @change="changeJoint">
<view class="joint-picker" :class="jointType ? '' : 'form__placeholder'">{{ jointType || '请选择关节类型' }}</view>
</picker>
<picker mode="selector" :range="jointSideOptions" :disabled="disableChange" @change="changeSide">
<view class="joint-picker" :class="jointSide ? '' : 'form__placeholder'">{{ jointSide || '请选择侧别' }}</view>
</picker>
</view>
</common-cell>
</template>
<script setup>
import { computed } from 'vue';
import commonCell from '../common-cell.vue';
const emits = defineEmits(['change']);
const props = defineProps({
form: { type: Object, default: () => ({}) },
name: { default: '' },
title: { default: '' },
range: { type: Array, default: () => [] },
required: { type: Boolean, default: false },
disableChange: { type: Boolean, default: false },
});
const jointOptions = computed(() => props.range.length ? props.range : ['膝关节', '髋关节']);
const jointSideOptions = ['左侧', '右侧', '双侧'];
const jointType = computed(() => props.form?.[props.title] || '');
const jointSide = computed(() => props.form?.jointSide || '');
function changeJoint(event) {
emits('change', { title: props.title, value: jointOptions.value[event.detail.value] });
}
function changeSide(event) {
emits('change', { title: 'jointSide', value: jointSideOptions[event.detail.value] });
}
</script>
<style>
@import '../cell-style.css';
.joint-row { display: flex; gap: 16rpx; width: 100%; }
.joint-row picker { flex: 1; min-width: 0; }
.joint-picker { padding: 12rpx 16rpx; border: 1rpx solid #dcdfe6; border-radius: 8rpx; font-size: 28rpx; }
</style>

View File

@ -0,0 +1,48 @@
<template>
<common-cell :name="name" :required="required">
<view class="exercise-row">
<input class="exercise-input" type="number" :disabled="disableChange" :value="frequency" placeholder="次数" @input="changeFrequency" />
<text class="exercise-unit">/</text>
<input class="exercise-input" type="number" :disabled="disableChange" :value="duration" placeholder="时长" @input="changeDuration" />
<text class="exercise-unit">min/</text>
</view>
</common-cell>
</template>
<script setup>
import { computed } from 'vue';
import commonCell from '../common-cell.vue';
const emits = defineEmits(['change']);
const props = defineProps({
form: { type: Object, default: () => ({}) },
name: { default: '' },
title: { default: '' },
required: { type: Boolean, default: false },
disableChange: { type: Boolean, default: false },
});
const values = computed(() => {
const matched = String(props.form?.[props.title] || '').match(/^\s*(\d*)\s*次\/周\s*[;]\s*(\d*)\s*min\/次\s*$/);
return matched ? { frequency: matched[1], duration: matched[2] } : { frequency: '', duration: '' };
});
const frequency = computed(() => values.value.frequency);
const duration = computed(() => values.value.duration);
function emitValue(nextFrequency, nextDuration) {
emits('change', {
title: props.title,
value: !nextFrequency && !nextDuration ? '' : `${nextFrequency || ''}次/周;${nextDuration || ''}min/次`,
});
}
function changeFrequency(event) { emitValue(event.detail.value, duration.value); }
function changeDuration(event) { emitValue(frequency.value, event.detail.value); }
</script>
<style>
@import '../cell-style.css';
.exercise-row { display: flex; align-items: center; gap: 10rpx; white-space: nowrap; }
.exercise-input { width: 96rpx; min-width: 96rpx; padding: 8rpx 10rpx; border: 1rpx solid #dcdfe6; border-radius: 8rpx; font-size: 28rpx; }
.exercise-unit { flex-shrink: 0; font-size: 26rpx; color: #303133; }
</style>

View File

@ -0,0 +1,58 @@
<template>
<common-cell :name="name" :required="required">
<view class="select-other">
<picker mode="selector" :range="range" :disabled="disableChange" @change="changeSelect">
<view class="select-other__picker" :class="selectedValue ? '' : 'form__placeholder'">{{ selectedValue || '请选择' }}</view>
</picker>
<input v-if="showOther" class="select-other__input" :disabled="disableChange" :value="otherValue" placeholder="请填写其他原因" @input="changeOther" />
</view>
</common-cell>
</template>
<script setup>
import { computed, ref, watch } from 'vue';
import commonCell from '../common-cell.vue';
const emits = defineEmits(['change']);
const props = defineProps({
form: { type: Object, default: () => ({}) },
name: { default: '' },
title: { default: '' },
range: { type: Array, default: () => [] },
otherFiled: { default: '' },
otherField: { default: '' },
required: { type: Boolean, default: false },
disableChange: { type: Boolean, default: false },
});
const value = computed(() => props.form?.[props.title] || '');
const otherOption = computed(() => props.otherFiled || props.otherField || props.range.find((item) => /^(其它|其他)$/.test(item)) || '其它');
const isPreset = computed(() => props.range.includes(value.value));
const selectingOther = ref(false);
const showOther = computed(() => selectingOther.value || (Boolean(value.value) && !isPreset.value));
const selectedValue = computed(() => showOther.value ? otherOption.value : value.value);
const otherValue = computed(() => showOther.value ? value.value : '');
watch(value, (nextValue) => {
if (nextValue && props.range.includes(nextValue)) selectingOther.value = false;
});
function changeSelect(event) {
const selected = props.range[event.detail.value];
if (selected === otherOption.value) {
selectingOther.value = true;
return;
}
selectingOther.value = false;
emits('change', { title: props.title, value: selected });
}
function changeOther(event) { emits('change', { title: props.title, value: event.detail.value }); }
</script>
<style>
@import '../cell-style.css';
.select-other { width: 100%; }
.select-other__picker, .select-other__input { box-sizing: border-box; width: 100%; padding: 12rpx 16rpx; border: 1rpx solid #dcdfe6; border-radius: 8rpx; font-size: 28rpx; }
.select-other__input { margin-top: 14rpx; }
</style>

View File

@ -10,6 +10,12 @@
@change="change" /> @change="change" />
<form-select v-else-if="attrs.type === 'select'" v-bind="attrs" :form="form" :disableChange="disableChange" <form-select v-else-if="attrs.type === 'select'" v-bind="attrs" :form="form" :disableChange="disableChange"
@change="change" /> @change="change" />
<form-evaluated-joint v-else-if="attrs.type === 'evaluatedJoint'" v-bind="attrs" :form="form" :disableChange="disableChange"
@change="change" />
<form-exercise-level v-else-if="attrs.type === 'exerciseLevel'" v-bind="attrs" :form="form" :disableChange="disableChange"
@change="change" />
<form-select-and-other v-else-if="attrs.type === 'selectAndOther'" v-bind="attrs" :form="form" :disableChange="disableChange"
@change="change" />
<form-textarea v-else-if="attrs.type === 'textarea'" v-bind="attrs" :form="form" :disableChange="disableChange" <form-textarea v-else-if="attrs.type === 'textarea'" v-bind="attrs" :form="form" :disableChange="disableChange"
@change="change" /> @change="change" />
<form-mult-disease v-else-if="attrs.type === 'selfMultipleDiseases'" v-bind="attrs" :form="form" @change="change" <form-mult-disease v-else-if="attrs.type === 'selfMultipleDiseases'" v-bind="attrs" :form="form" @change="change"
@ -33,6 +39,9 @@ import { useAttrs } from 'vue';
import formInput from './form-input.vue'; import formInput from './form-input.vue';
import formSelect from './form-select.vue'; import formSelect from './form-select.vue';
import formEvaluatedJoint from './form-evaluated-joint.vue';
import formExerciseLevel from './form-exercise-level.vue';
import formSelectAndOther from './form-select-and-other.vue';
import formRadio from './form-radio.vue'; import formRadio from './form-radio.vue';
import formDatepicker from './form-datepicker.vue'; import formDatepicker from './form-datepicker.vue';
import formRegion from './form-region.vue'; import formRegion from './form-region.vue';
@ -108,4 +117,4 @@ export default {
} }
</script> --> </script> -->
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -33,7 +33,7 @@ const props = defineProps({
} }
}) })
const formCellType = ['input', 'select', 'date', 'radio', 'region', 'textarea', 'multiSelectAndOther', 'selfMultipleDiseases', 'files','diagnosis','positiveFind']; const formCellType = ['input', 'select', 'date', 'radio', 'region', 'textarea', 'multiSelectAndOther', 'selectAndOther', 'selfMultipleDiseases', 'files', 'diagnosis', 'positiveFind', 'evaluatedJoint', 'exerciseLevel'];
const formCellTitle = ['surgicalHistory']; const formCellTitle = ['surgicalHistory'];
const customCellType = ['BMI', 'bloodPressure']; const customCellType = ['BMI', 'bloodPressure'];
const disabledMap = computed(() => props.disableTitles.reduce((m, i) => { const disabledMap = computed(() => props.disableTitles.reduce((m, i) => {