Commit 85291c3f authored by tao.huang's avatar tao.huang

feat: 多选

parent 5b57105a
<template>
<Layer
:modelValue="modelValue"
:title="title"
:showCancel="true"
:showConfirm="true"
:customHeader="true"
:showCancel="false"
:showConfirm="false"
@update:modelValue="$emit('update:modelValue', $event)"
@confirm="onConfirm"
@cancel="onCancel"
>
<template>
<view class="multi-select-title">{{ title }}</view>
<view class="multi-select-list">
<view
v-for="opt in options"
......@@ -21,18 +22,22 @@
<image
v-if="selectedSet.has(opt)"
class="check-icon"
src="/static/check.png"
:src="$baseUrl + 'person/icon_gou.png'"
/>
</view>
</view>
<view class="multi-select-btn" @click="onConfirm"> 保存 </view>
</template>
</Layer>
</template>
<script setup>
import { ref, watch, computed } from "vue";
import { ref, watch, computed, getCurrentInstance } from "vue";
import Layer from "./Layer.vue";
const { proxy } = getCurrentInstance();
const $baseUrl = proxy.$baseUrl;
const props = defineProps({
modelValue: Boolean,
title: String,
......@@ -40,7 +45,12 @@ const props = defineProps({
modelSelected: { type: Array, default: () => [] },
max: Number,
});
const emit = defineEmits(["update:modelValue", "update:selected", "confirm", "cancel"]);
const emit = defineEmits([
"update:modelValue",
"update:selected",
"confirm",
"cancel",
]);
const selected = ref([...props.modelSelected]);
watch(
......@@ -72,32 +82,50 @@ function onCancel() {
</script>
<style lang="less" scoped>
.multi-select-btn {
width: 686rpx;
height: 94rpx;
background: #d3a358;
color: #fff;
border-radius: 46rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-top: 24rpx;
font-size: 32rpx;
}
.multi-select-title {
font-size: 32rpx;
color: #222;
font-weight: bold;
margin-bottom: 24rpx;
}
.multi-select-list {
display: flex;
flex-wrap: wrap;
gap: 24rpx 20rpx;
gap: 15rpx 20rpx;
}
.multi-select-tag {
display: flex;
align-items: center;
padding: 0 32rpx;
padding: 0 24rpx;
height: 56rpx;
background: #fff;
background: #ffffff;
border-radius: 28rpx;
color: #222;
font-size: 28rpx;
margin-bottom: 24rpx;
color: #1d1e25;
font-size: 24rpx;
position: relative;
border: 1rpx solid #eee;
.check-icon {
width: 28rpx;
height: 28rpx;
margin-left: 8rpx;
width: 19rpx;
height: 19rpx;
position: absolute;
right: 2rpx;
top: 3rpx;
display: block;
}
&.selected {
background: #e9d3b1;
color: #b88a3a;
border: 1rpx solid #b88a3a;
background: #efe7da;
}
}
</style>
\ No newline at end of file
......@@ -21,7 +21,7 @@
<picker-view
class="picker-layer-view"
mask-style="background: rgb(246, 248, 250); z-index: 0;"
indicator-style="border-radius: 10px; height: 50px;background:#ffffff; z-index:0"
indicator-style="border-radius: 10px; height: 50px; background:#ffffff; z-index:0"
:value="pickerValue"
@change="onChange"
>
......@@ -55,9 +55,9 @@
</picker-view-column>
</template>
<template v-else>
<picker-view-column v-for="(col, colIdx) in columns" :key="colIdx">
<picker-view-column>
<view
v-for="(item, idx) in col"
v-for="(item, idx) in columns[0]"
:key="idx"
class="picker-layer-item"
>
......@@ -309,6 +309,7 @@ function onChange(e) {
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
}
.picker-layer-header {
display: flex;
......@@ -350,6 +351,7 @@ function onChange(e) {
.picker-layer-view {
flex: 1;
width: 100%;
height: 100%;
}
.picker-layer-item {
height: 100rpx;
......
......@@ -55,7 +55,7 @@
.filter(formItemFilter)
.slice(
0,
formData.currentBaby == '已出生' && pageStatus.formStatus == 2
formData.currentBaby == 2 && pageStatus.formStatus == 2
? 6
: formItems.length
)"
......@@ -95,7 +95,9 @@
:onStatusChange="onDateStatusChange"
>
<view class="form-input-box">
<view class="form-input">{{ getLabelByValue(item, formData[item.name]) || item.placeholder }}</view>
<view class="form-input">{{
getLabelByValue(item, formData[item.name]) || item.placeholder
}}</view>
<image
class="form-input-icon"
:src="$baseUrl + 'person/icon_arrow_yellow_right.png'"
......@@ -103,10 +105,17 @@
</view>
</picker-custom>
<!-- 多选弹窗类型 -->
<view v-else-if="item.type === 'multi-picker'" @click="handleMultiPickerOpen(item)">
<view
v-else-if="item.type === 'multi-picker'"
@click="handleMultiPickerOpen(item)"
>
<view class="form-input-box">
<view class="form-input">
{{ (formData[item.name] && formData[item.name].split(',').join('、')) || item.placeholder }}
{{
(formData[item.name] &&
formData[item.name].split(",").join("、")) ||
item.placeholder
}}
</view>
<image
class="form-input-icon"
......@@ -135,7 +144,7 @@
</block>
<view
v-if="pageStatus.formStatus != 0"
v-if="formData.currentBaby == 2"
class="form-bottom-btn"
@click="handleFormBottomBtn"
>
......@@ -166,8 +175,11 @@
<MultiSelectLayer
v-if="multiPickerStatus && currentMultiPickerName"
v-model="multiPickerStatus"
:title="formItems.find(i => i.name === currentMultiPickerName)?.label + '(多选)'"
:options="formItems.find(i => i.name === currentMultiPickerName)?.range"
:title="
formItems.find((i) => i.name === currentMultiPickerName)?.label +
'(多选)'
"
:options="formItems.find((i) => i.name === currentMultiPickerName)?.range"
:modelSelected="multiPickerSelected[currentMultiPickerName]"
@confirm="handleMultiPickerConfirm"
@cancel="handleMultiPickerCancel"
......@@ -177,20 +189,19 @@
<script setup>
import { ref, watch, onMounted } from "vue";
import { onLoad } from '@dcloudio/uni-app';
import { useUserStore } from '../../stores/user.js';
import { onLoad } from "@dcloudio/uni-app";
import { useUserStore } from "../../stores/user.js";
import PickerCustom from "../../components/PickerCustom.vue";
import MultiSelectLayer from "../../components/MultiSelectLayer.vue";
const userStore = useUserStore();
const pageType = ref('add');
const pageType = ref("add");
const pageStatus = ref({
formStatus: 0, // 0: 隐藏 1: 展开, 2: 收起
btnStatus: true, // 是否显示提交按钮
});
// 0备孕 1孕中 2出生
const formData = ref({
currentBaby: 2,
......@@ -208,19 +219,19 @@ const formData = ref({
});
const babyTypeMap = [
{ label: '一胎', value: 1 },
{ label: '二胎', value: 2 },
{ label: '三胎', value: 3 },
{ label: "一胎", value: 1 },
{ label: "二胎", value: 2 },
{ label: "三胎", value: 3 },
];
const babyStageMap = [
{ label: '备孕', value: 0 },
{ label: '孕中', value: 1 },
{ label: '已出生', value: 2 },
{ label: "备孕", value: 0 },
{ label: "孕中", value: 1 },
{ label: "已出生", value: 2 },
];
const babyGenderMap = [
{ label: '男', value: 'M' },
{ label: '女', value: 'F' },
{ label: '其他', value: 'O' },
{ label: "男", value: "M" },
{ label: "女", value: "F" },
{ label: "其他", value: "O" },
];
const FormMap = {
......@@ -253,18 +264,36 @@ const formItemFilter = (item) => {
const MAX_NICKNAME_LENGTH = 10;
watch(
() => formData.value.currentBaby,
(newVal) => {
pageStatus.value.formStatus = newVal == 2 ? 2 : 0;
}
);
const contentLikeOptions = [
'奶粉选择', '奶粉成分', '奶粉冲泡', '宝宝奶量', '生长发育', '常见疾病', '体检疫苗', '饮食营养补充', '辅食营养', '亲子关系', '早教游戏'
"奶粉选择",
"奶粉成分",
"奶粉冲泡",
"宝宝奶量",
"生长发育",
"常见疾病",
"体检疫苗",
"饮食营养补充",
"辅食营养",
"亲子关系",
"早教游戏",
];
const productLikeOptions = [
'飞鹤星飞帆', '星飞帆卓睿', '星飞帆卓耀', '星飞帆卓初', '星飞帆臻稚卓蓓', '星飞帆淳芮有机'
];
const specialAttentionOptions = [
'过敏', '长肉', '肠道', '消化', '脑发育'
];
const channelOptions = [
'电商(京东/天猫)', '母婴店'
"飞鹤星飞帆",
"星飞帆卓睿",
"星飞帆卓耀",
"星飞帆卓初",
"星飞帆臻稚卓蓓",
"星飞帆淳芮有机",
];
const specialAttentionOptions = ["过敏", "长肉", "肠道", "消化", "脑发育"];
const channelOptions = ["电商(京东/天猫)", "母婴店"];
const formItems = [
{
......@@ -273,7 +302,7 @@ const formItems = [
required: true,
placeholder: "请选择当前状态",
type: "picker",
range: babyStageMap.map(i => i.label),
range: babyStageMap.map((i) => i.label),
mode: "custom",
},
{
......@@ -307,7 +336,7 @@ const formItems = [
required: true,
placeholder: "未选择",
type: "picker",
range: babyTypeMap.map(i => i.label),
range: babyTypeMap.map((i) => i.label),
mode: "custom",
disabled: false,
},
......@@ -317,7 +346,7 @@ const formItems = [
required: true,
placeholder: "未选择",
type: "picker",
range: babyGenderMap.map(i => i.label),
range: babyGenderMap.map((i) => i.label),
mode: "custom",
},
{
......@@ -376,16 +405,16 @@ const formItems = [
const getPickerIndex = (item) => {
const val = formData.value[item.name];
if (item.name === 'currentBaby') {
const idx = babyStageMap.findIndex(i => i.value === val);
if (item.name === "currentBaby") {
const idx = babyStageMap.findIndex((i) => i.value === val);
return idx > -1 ? idx : 0;
}
if (item.name === 'babyIndex') {
const idx = babyTypeMap.findIndex(i => i.value === val);
if (item.name === "babyIndex") {
const idx = babyTypeMap.findIndex((i) => i.value === val);
return idx > -1 ? idx : 0;
}
if (item.name === 'gender') {
const idx = babyGenderMap.findIndex(i => i.value === val);
if (item.name === "gender") {
const idx = babyGenderMap.findIndex((i) => i.value === val);
return idx > -1 ? idx : 0;
}
if (item.mode === "date") {
......@@ -410,15 +439,15 @@ const getPickerIndex = (item) => {
};
const onPickerChange = (e, name) => {
const item = formItems.find((i) => i.name === name);
if (name === 'currentBaby') {
if (name === "currentBaby") {
formData.value[name] = babyStageMap[e].value;
return;
}
if (name === 'babyIndex') {
if (name === "babyIndex") {
formData.value[name] = babyTypeMap[e].value;
return;
}
if (name === 'gender') {
if (name === "gender") {
formData.value[name] = babyGenderMap[e].value;
return;
}
......@@ -448,43 +477,30 @@ const onChooseAvatar = (e) => {
formData.value.avatarUrl = e.detail.avatarUrl;
};
watch(
() => formData.value.currentBaby,
(newVal) => {
if (newVal === "已出生") {
pageStatus.value.formStatus = 2;
} else {
pageStatus.value.formStatus = 0;
}
}
);
function onDateStatusChange(status) {
if (status === '已出生' || status === '孕中') {
formData.value.currentBaby = status;
}
formData.value.currentBaby = status;
}
// getLabelByValue 支持所有映射字段
const getLabelByValue = (item, value) => {
if (item.name === 'currentBaby') {
return babyStageMap.find(i => i.value === value)?.label || '';
if (item.name === "currentBaby") {
return babyStageMap.find((i) => i.value === value)?.label || "";
}
if (item.name === 'babyIndex') {
return babyTypeMap.find(i => i.value === value)?.label || '';
if (item.name === "babyIndex") {
return babyTypeMap.find((i) => i.value === value)?.label || "";
}
if (item.name === 'gender') {
return babyGenderMap.find(i => i.value === value)?.label || '';
if (item.name === "gender") {
return babyGenderMap.find((i) => i.value === value)?.label || "";
}
return value;
};
const getValueByLabel = (map, label) => {
const found = map.find(i => i.label === label);
return found ? found.value : '';
const found = map.find((i) => i.label === label);
return found ? found.value : "";
};
const multiPickerStatus = ref(false); // 控制弹窗显示
const currentMultiPickerName = ref(''); // 当前弹窗对应的item.name
const currentMultiPickerName = ref(""); // 当前弹窗对应的item.name
const multiPickerSelected = ref({}); // 存储每个multi-picker的选中项
function handleMultiPickerOpen(item) {
......@@ -492,54 +508,58 @@ function handleMultiPickerOpen(item) {
multiPickerStatus.value = true;
// 初始化选中项
let val = formData.value[item.name];
if (typeof val === 'string') {
val = val ? val.split(',') : [];
if (typeof val === "string") {
val = val ? val.split(",") : [];
}
multiPickerSelected.value[item.name] = val || [];
}
function handleMultiPickerConfirm(selected) {
if (!currentMultiPickerName.value) return;
formData.value[currentMultiPickerName.value] = selected.join(',');
formData.value[currentMultiPickerName.value] = selected.join(",");
multiPickerStatus.value = false;
currentMultiPickerName.value = '';
currentMultiPickerName.value = "";
}
function handleMultiPickerCancel() {
multiPickerStatus.value = false;
currentMultiPickerName.value = '';
currentMultiPickerName.value = "";
}
onLoad((options) => {
pageType.value = options.type || 'add';
if (pageType.value === 'edit') {
pageType.value = options.type || "add";
if (pageType.value === "edit") {
const baby = userStore.babyInfo;
formData.value.currentBaby = baby.babyStage ?? 2;
formData.value.nickName = baby.babyName || '';
formData.value.dateOfBirth = baby.content?.babyBirthday || '';
formData.value.dateOfBirth2 = baby.content?.dueDate || '';
formData.value.nickName = baby.babyName || "";
formData.value.dateOfBirth = baby.content?.babyBirthday || "";
formData.value.dateOfBirth2 = baby.content?.dueDate || "";
formData.value.babyIndex = baby.content?.babyType ?? 1;
formData.value.gender = baby.content?.babyGender ?? 'M';
formData.value.eatFunc = baby.content?.feedingType || '';
formData.value.contentLike = baby.content?.contentPreference || '';
formData.value.productLike = baby.content?.productPreference || '';
formData.value.specialAttention = baby.content?.followInfo || '';
formData.value.channel = baby.content?.purchaseChannel || '';
formData.value.avatarUrl = baby.babyAvatar || '';
formData.value.gender = baby.content?.babyGender ?? "M";
formData.value.eatFunc = baby.content?.feedingType || "";
formData.value.contentLike = baby.content?.contentPreference || "";
formData.value.productLike = baby.content?.productPreference || "";
formData.value.specialAttention = baby.content?.followInfo || "";
formData.value.channel = baby.content?.purchaseChannel || "";
formData.value.avatarUrl = baby.babyAvatar || "";
} else {
Object.assign(formData.value, {
currentBaby: 2,
nickName: '',
dateOfBirth: '',
dateOfBirth2: '',
gender: '',
babyIndex: '',
eatFunc: '',
contentLike: '',
productLike: '',
specialAttention: '',
channel: '',
avatarUrl: '',
nickName: "",
dateOfBirth: "",
dateOfBirth2: "",
gender: "",
babyIndex: "",
eatFunc: "",
contentLike: "",
productLike: "",
specialAttention: "",
channel: "",
avatarUrl: "",
});
}
if (formData.value.currentBaby == 2) {
pageStatus.value.formStatus = 2;
}
});
</script>
......
......@@ -69,7 +69,7 @@
<BabySwitcher
v-if="showBabySwitcher"
:show="showBabySwitcher"
:babyList="babyInfo.allBabyBaseInfo"
:babyList="babyInfo.allBabyBaseInfo || []"
:addIcon="$baseUrl + 'my/baby_add_btn.png'"
@close="showBabySwitcher = false"
@select="onSelectBaby"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment