hookehuyr

feat(BrandModelPicker): 添加自定义型号输入功能

在品牌型号选择器中新增自定义型号输入弹窗,允许用户输入自定义型号名称
...@@ -62,6 +62,14 @@ ...@@ -62,6 +62,14 @@
62 > 62 >
63 <text class="model-name">{{ model.text }}</text> 63 <text class="model-name">{{ model.text }}</text>
64 </view> 64 </view>
65 + <!-- 自定义型号选项 -->
66 + <view
67 + class="model-item"
68 + @click="showCustomModelInput"
69 + >
70 + <text class="model-name">自定义型号</text>
71 + <Right />
72 + </view>
65 </view> 73 </view>
66 </view> 74 </view>
67 </nut-popup> 75 </nut-popup>
...@@ -106,6 +114,39 @@ ...@@ -106,6 +114,39 @@
106 </view> 114 </view>
107 </view> 115 </view>
108 </nut-popup> 116 </nut-popup>
117 +
118 + <!-- 自定义型号输入弹框 -->
119 + <nut-popup v-model:visible="customModelInputVisible" position="bottom" :style="{ height: '50%' }">
120 + <view class="custom-model-input-picker">
121 + <view class="picker-header">
122 + <nut-button size="small" @click="goBackToModelPicker">返回</nut-button>
123 + <text class="picker-title">自定义{{ selectedBrandName }}型号</text>
124 + <nut-button size="small" type="primary" @click="closePicker">关闭</nut-button>
125 + </view>
126 + <view class="custom-input-content">
127 + <view class="input-group">
128 + <text class="input-label">型号名称</text>
129 + <nut-input
130 + v-model="customModelOnly"
131 + placeholder="请输入型号名称"
132 + class="custom-input"
133 + />
134 + </view>
135 + <view class="button-group">
136 + <nut-button
137 + type="primary"
138 + size="large"
139 + color="orange"
140 + @click="confirmCustomModelInput"
141 + :disabled="!customModelOnly.trim()"
142 + class="confirm-button"
143 + >
144 + 确认
145 + </nut-button>
146 + </view>
147 + </view>
148 + </view>
149 + </nut-popup>
109 </view> 150 </view>
110 </template> 151 </template>
111 152
...@@ -130,12 +171,14 @@ const emit = defineEmits(['confirm', 'cancel']) ...@@ -130,12 +171,14 @@ const emit = defineEmits(['confirm', 'cancel'])
130 const brandPickerVisible = ref(false) 171 const brandPickerVisible = ref(false)
131 const modelPickerVisible = ref(false) 172 const modelPickerVisible = ref(false)
132 const customInputVisible = ref(false) 173 const customInputVisible = ref(false)
174 +const customModelInputVisible = ref(false)
133 const selectedBrandName = ref('') 175 const selectedBrandName = ref('')
134 const currentBrandModels = ref([]) 176 const currentBrandModels = ref([])
135 const contentHeight = ref(800) // 默认高度 rpx 177 const contentHeight = ref(800) // 默认高度 rpx
136 const searchKeyword = ref('') // 搜索关键词 178 const searchKeyword = ref('') // 搜索关键词
137 const customBrand = ref('') // 自定义品牌 179 const customBrand = ref('') // 自定义品牌
138 const customModel = ref('') // 自定义型号 180 const customModel = ref('') // 自定义型号
181 +const customModelOnly = ref('') // 只自定义型号
139 182
140 // 使用父组件传入的品牌数据,并添加"其他"选项 183 // 使用父组件传入的品牌数据,并添加"其他"选项
141 const allBrands = computed(() => { 184 const allBrands = computed(() => {
...@@ -268,6 +311,48 @@ const confirmCustomInput = () => { ...@@ -268,6 +311,48 @@ const confirmCustomInput = () => {
268 closeAllPickers() 311 closeAllPickers()
269 } 312 }
270 313
314 +/**
315 + * 显示自定义型号输入弹窗
316 + */
317 +const showCustomModelInput = () => {
318 + modelPickerVisible.value = false
319 + customModelInputVisible.value = true
320 + customModelOnly.value = '' // 清空之前的输入
321 +}
322 +
323 +/**
324 + * 确认自定义型号输入
325 + */
326 +const confirmCustomModelInput = () => {
327 + if (!customModelOnly.value.trim()) {
328 + return
329 + }
330 +
331 + // 找到对应的品牌ID
332 + const selectedBrand = props.brandOptions.find(brand => brand.text === selectedBrandName.value)
333 +
334 + const result = {
335 + brand: selectedBrandName.value,
336 + model: customModelOnly.value.trim(),
337 + brandValue: selectedBrand ? selectedBrand.value : selectedBrandName.value,
338 + modelValue: customModelOnly.value.trim()
339 + }
340 +
341 + // 发送确认事件
342 + emit('confirm', result)
343 +
344 + // 关闭所有弹框
345 + closeAllPickers()
346 +}
347 +
348 +/**
349 + * 返回型号选择器
350 + */
351 +const goBackToModelPicker = () => {
352 + customModelInputVisible.value = false
353 + modelPickerVisible.value = true
354 +}
355 +
271 // 返回品牌选择 356 // 返回品牌选择
272 const goBackToBrandPicker = () => { 357 const goBackToBrandPicker = () => {
273 modelPickerVisible.value = false 358 modelPickerVisible.value = false
...@@ -286,10 +371,12 @@ const closeAllPickers = () => { ...@@ -286,10 +371,12 @@ const closeAllPickers = () => {
286 brandPickerVisible.value = false 371 brandPickerVisible.value = false
287 modelPickerVisible.value = false 372 modelPickerVisible.value = false
288 customInputVisible.value = false 373 customInputVisible.value = false
374 + customModelInputVisible.value = false
289 selectedBrandName.value = '' 375 selectedBrandName.value = ''
290 currentBrandModels.value = [] 376 currentBrandModels.value = []
291 customBrand.value = '' 377 customBrand.value = ''
292 customModel.value = '' 378 customModel.value = ''
379 + customModelOnly.value = ''
293 } 380 }
294 381
295 // 组件挂载时初始化 382 // 组件挂载时初始化
...@@ -477,6 +564,7 @@ defineExpose({ ...@@ -477,6 +564,7 @@ defineExpose({
477 .model-item { 564 .model-item {
478 display: flex; 565 display: flex;
479 align-items: center; 566 align-items: center;
567 + justify-content: space-between;
480 padding: 30rpx 20rpx; 568 padding: 30rpx 20rpx;
481 border-bottom: 1rpx solid #f8f8f8; 569 border-bottom: 1rpx solid #f8f8f8;
482 transition: background-color 0.2s; 570 transition: background-color 0.2s;
...@@ -489,6 +577,8 @@ defineExpose({ ...@@ -489,6 +577,8 @@ defineExpose({
489 font-size: 30rpx; 577 font-size: 30rpx;
490 color: #333; 578 color: #333;
491 } 579 }
580 +
581 +
492 } 582 }
493 } 583 }
494 } 584 }
...@@ -558,4 +648,70 @@ defineExpose({ ...@@ -558,4 +648,70 @@ defineExpose({
558 } 648 }
559 } 649 }
560 } 650 }
651 +
652 +/* 自定义型号输入弹窗样式 */
653 +.custom-model-input-picker {
654 + padding: 20rpx;
655 + height: 100%;
656 + display: flex;
657 + flex-direction: column;
658 +
659 + .picker-header {
660 + display: flex;
661 + justify-content: space-between;
662 + align-items: center;
663 + padding: 20rpx 0;
664 + border-bottom: 1rpx solid #f0f0f0;
665 + margin-bottom: 20rpx;
666 +
667 + .picker-title {
668 + font-size: 32rpx;
669 + font-weight: 600;
670 + color: #333;
671 + }
672 + }
673 +
674 + .custom-input-content {
675 + flex: 1;
676 + display: flex;
677 + flex-direction: column;
678 +
679 + .input-group {
680 + margin-bottom: 40rpx;
681 +
682 + .input-label {
683 + display: block;
684 + font-size: 28rpx;
685 + color: #333;
686 + margin-bottom: 20rpx;
687 + font-weight: 500;
688 + }
689 +
690 + .custom-input {
691 + width: 100%;
692 + height: 80rpx;
693 + border: 1rpx solid #e0e0e0;
694 + border-radius: 8rpx;
695 + padding: 0 20rpx;
696 + font-size: 28rpx;
697 + background: #fff;
698 +
699 + &:focus {
700 + border-color: #1890ff;
701 + }
702 + }
703 + }
704 +
705 + .button-group {
706 + margin-top: auto;
707 + padding-top: 40rpx;
708 +
709 + .confirm-button {
710 + width: 100%;
711 + height: 80rpx;
712 + border-radius: 8rpx;
713 + }
714 + }
715 + }
716 +}
561 </style> 717 </style>
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-08-13 09:50:04 4 + * @LastEditTime: 2025-08-13 10:45:26
5 * @FilePath: /jgdl/src/pages/collectionSettings/index.vue 5 * @FilePath: /jgdl/src/pages/collectionSettings/index.vue
6 * @Description: 收款设置 6 * @Description: 收款设置
7 --> 7 -->
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
109 </nut-popup> 109 </nut-popup>
110 110
111 <!-- 身份信息弹窗 --> 111 <!-- 身份信息弹窗 -->
112 - <nut-popup v-model:visible="showIdentityModal" position="bottom" :style="{ width: '100%', height: '100%' }" 112 + <nut-popup v-model:visible="showIdentityModal" position="bottom" :style="{ width: '100%', height: '85%' }"
113 :close-on-click-overlay="false" closeable close-icon-position="top-right" @close="closeIdentityModal"> 113 :close-on-click-overlay="false" closeable close-icon-position="top-right" @close="closeIdentityModal">
114 <view class="modal-content"> 114 <view class="modal-content">
115 <view class="modal-header"> 115 <view class="modal-header">
......