8.3 KiB
Service Package Multi-Select Implementation (服务套餐多选实现)
Changes Made
Updated the service package field from a simple text input to a multi-select dropdown with data loaded from the dictionary API.
1. Added Dictionary API Import
File: admin/src/views/consumer/prescription/order_list.vue
import { getDictData } from '@/api/app'
2. Added Service Package Options State
// 服务套餐选项
const servicePackageOptions = ref<Array<{ name: string; value: string }>>([])
3. Added Loading Function
// 加载服务套餐选项
const loadServicePackageOptions = async () => {
try {
const data = await getDictData({ type: 'server_order' })
servicePackageOptions.value = (data?.server_order || []).filter((item: any) => item.status !== 0)
console.log('服务套餐选项已加载:', servicePackageOptions.value.length)
} catch (error) {
console.error('加载服务套餐选项失败:', error)
servicePackageOptions.value = []
}
}
4. Updated onMounted Hook
onMounted(async () => {
await loadRegionData()
await loadServicePackageOptions() // Added
getLists()
})
5. Changed Form Field Type
Changed editForm.service_package from string to array:
// Before:
service_package: '',
// After:
service_package: [] as string[],
6. Updated Edit Form UI
Changed from text input to multi-select:
Before:
<el-input v-model="editForm.service_package" maxlength="100" />
After:
<el-select
v-model="editForm.service_package"
multiple
collapse-tags
collapse-tags-tooltip
placeholder="请选择服务套餐"
clearable
class="w-full"
>
<el-option
v-for="item in servicePackageOptions"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
7. Updated Data Loading Logic
Added logic to handle both array and string formats when loading data:
// 处理服务套餐:如果是字符串,转换为数组
if (d.service_package) {
if (Array.isArray(d.service_package)) {
editForm.service_package = d.service_package
} else if (typeof d.service_package === 'string') {
editForm.service_package = d.service_package.split(',').filter(v => v.trim() !== '')
} else {
editForm.service_package = []
}
} else {
editForm.service_package = []
}
8. Updated Form Submission
Convert array back to comma-separated string for backend:
service_package: Array.isArray(editForm.service_package) ? editForm.service_package.join(',') : '',
9. Added Display Formatter
Added formatServicePackage() function to display service packages in detail view:
// 格式化服务套餐显示
function formatServicePackage(value: any): string {
if (!value) return '—'
let packages: string[] = []
if (Array.isArray(value)) {
packages = value
} else if (typeof value === 'string') {
packages = value.split(',').filter(v => v.trim() !== '')
}
if (packages.length === 0) return '—'
// 将值转换为名称
const names = packages.map(val => {
const option = servicePackageOptions.value.find(opt => opt.value === val)
return option ? option.name : val
})
return names.join('、')
}
10. Updated Detail Display
<el-descriptions-item label="服务套餐">
{{ formatServicePackage(detailData.service_package) }}
</el-descriptions-item>
Data Flow
Loading Options:
- Component mounts
loadServicePackageOptions()calls API:/adminapi/config/dict?type=server_order- Filters out disabled options (status !== 0)
- Stores in
servicePackageOptions
Editing Order:
- User opens edit dialog
- Backend returns
service_packageas string:"package1,package2,package3" - Frontend splits string into array:
['package1', 'package2', 'package3'] - Multi-select displays selected options
- User can add/remove selections
- On save, array is joined back to string:
"package1,package2,package3" - Backend receives comma-separated string
Displaying in Detail:
- Backend returns
service_packageas string formatServicePackage()splits string into array- Maps values to display names using
servicePackageOptions - Joins names with Chinese comma:
"套餐A、套餐B、套餐C"
UI Features
Multi-Select Features:
- Multiple Selection: Users can select multiple service packages
- Collapse Tags: Selected items are collapsed with a count badge when many are selected
- Collapse Tags Tooltip: Hover over collapsed tags to see all selections
- Clearable: Users can clear all selections with one click
- Searchable: Built-in search functionality (default for el-select)
Display Format:
- Detail view:
套餐A、套餐B、套餐C(Chinese comma separator) - Edit form: Tag-style display with collapse for many items
- Empty state: Shows
—when no packages selected
Backend Compatibility
Database Storage:
The backend stores service packages as a comma-separated string in the database:
service_package: "package1,package2,package3"
API Response:
The backend returns the string as-is, and the frontend handles the conversion.
API Request:
The frontend sends the string format, maintaining backward compatibility.
Testing Steps
1. Test Options Loading
- Open order list page
- Check browser console for:
服务套餐选项已加载: X - Open edit dialog
- Click on service package dropdown
- Verify options are displayed
2. Test Multi-Selection
- Edit an order
- Click service package dropdown
- Select multiple packages
- Verify tags appear below the dropdown
- Select many packages to test collapse behavior
- Hover over collapsed tags to see tooltip
3. Test Saving
- Select multiple service packages
- Save the order
- Check browser Network tab
- Verify payload contains:
service_package: "value1,value2,value3" - Verify database is updated
4. Test Display
- Open order detail view
- Check "服务套餐" field
- Verify it shows:
套餐A、套餐B、套餐C - Test with orders that have:
- Multiple packages
- Single package
- No packages (should show
—)
5. Test Backward Compatibility
- Edit an old order that has service_package as string
- Verify it loads correctly into the multi-select
- Verify you can modify and save
6. Test Clear Functionality
- Edit an order with service packages selected
- Click the clear button (×) on the select
- Verify all selections are cleared
- Save and verify database is updated to empty string
Dictionary API Format
The API endpoint /adminapi/config/dict?type=server_order should return:
{
"server_order": [
{
"name": "套餐A",
"value": "package_a",
"status": 1
},
{
"name": "套餐B",
"value": "package_b",
"status": 1
},
{
"name": "套餐C (已停用)",
"value": "package_c",
"status": 0
}
]
}
Note: Options with status: 0 are filtered out and not displayed.
Related Files
Frontend:
admin/src/views/consumer/prescription/order_list.vue- Added
getDictDataimport - Added
servicePackageOptionsstate - Added
loadServicePackageOptions()function - Updated
editForm.service_packageto array type - Updated edit form UI to multi-select
- Added data loading/saving conversion logic
- Added
formatServicePackage()display function - Updated detail display
- Added
Backend:
/adminapi/config/dictendpoint (should already exist)- Dictionary data for
type=server_order
Summary
✅ Changed from text input to multi-select dropdown
✅ Loads options from dictionary API
✅ Supports multiple selection with tag display
✅ Collapse tags for better UI when many items selected
✅ Converts between array (frontend) and string (backend)
✅ Displays formatted names in detail view
✅ Backward compatible with existing string data
✅ Filters out disabled options
✅ Clearable and searchable
The service package field now provides a better user experience with predefined options and multi-selection capability!