Business-Level Dialog Implementation
Table of Contents
- Overview
- BaseDialog Base Class Design
- Business-Level Dialog Architecture
- Core Business Dialog Analysis
- Hook State Management Mechanism
- API Integration and Data Flow
- Complex Interaction Implementation
- Performance Optimization and Memory Management
- Best Practices Guide
- Summary
Overview
Business-level dialogs are core UI components in the LME system for handling complex business scenarios. This document provides an in-depth analysis of three main business-level dialogs: WorkStation Dialog, ProcessRouter Dialog, and ArtificialStation Dialog. These components implement highly reusable and maintainable business logic encapsulation through inheritance of the BaseDialog base class, combined with Vue 3 Composition API and custom Hook patterns.
BaseDialog Base Class Design
BaseDialog serves as the basic component for all business-level dialogs, providing a unified dialog framework and common functionality.
Chart Source
BaseDialog provides the following core functionality:
- Unified dialog header and footer layout
- Automated close and confirm event handling
- Configurable dialog size and style
- Internationalization support for language text
- Extensible slot system
Section Source
Business-Level Dialog Architecture
Business-level dialogs adopt a layered architecture design, implementing modular encapsulation of business logic through component inheritance and Hook patterns.
Chart Source
Core Business Dialog Analysis
WorkStation Dialog
WorkStationDialog is the most basic business-level dialog, specifically used for workstation selection and management.
Component Features
- Supports multiple and single selection modes
- Integrated search functionality
- Dynamic data source loading
- Selected state management
Implementation Key Points
// Core implementation of workstation dialog
const {
onClose,
onConfirm,
onCheck,
onOpen,
onSearch,
visible,
innerValue,
tableRef,
dataSource,
columns,
selections,
} = useSelectDialog(props, ctx)
Data Flow Diagram
Chart Source
Section Source
ProcessRouter Dialog
ProcessRouterDialog extends the workstation selection functionality, adding process route association and filtering capabilities.
Special Functions
- Process route data preloading
- Conditional filtering and screening
- Single selection mode support
- Dynamic data source association
Implementation Differences
// Initialization logic specific to process router
const onOpen = async () => {
routers.value = await getProcessRouterList(props.productId)
initData()
}
const initData = async (filter?: string) => {
const ids = routers.value.map((item) => item.id) as string[]
const data = await getWorkStationList(filter)
const dataSourceItems = data.items.filter((item) =>
ids.includes(item.workSectionId)
)
dataSource.value = dataSourceItems
}
Section Source
ArtificialStation Dialog
ArtificialStationDialog is the most complex business-level dialog, integrating table editing and dynamic form functionality.
Composite Functions
- Main table display
- Edit dialog
- Dynamic form validation
- Multi-user permission management
Dual Dialog Architecture
Chart Source
Section Source
Hook State Management Mechanism
Business-level dialogs adopt Vue 3 Composition API and custom Hook patterns, implementing clear state management and side effect handling.
useSelectDialog Hook Design
Chart Source
State Management Pattern
Reactive State Definition
// Basic state definition
const visible = computed({
get() {
return props.modelValue
},
set(val) {
ctx.emit('update:modelValue', val)
},
})
const dataSource = ref<any[]>([])
const innerValue = ref('')
const checkedList = ref<any[]>([])
Computed Properties and Reactive Dependencies
// Computed property implementation
const selections = computed(() => {
return props.data?.map((item: any) => item.id) ?? []
})
const columns = computed(() => [
{
title: _t('序号'),
type: 'seq',
width: '60',
},
{
field: 'workSection.name',
title: _t('工序名称'),
},
// ... other column definitions
])
Section Source
API Integration and Data Flow
Business-level dialogs implement communication with backend services through dedicated API modules, supporting asynchronous data loading and error handling.
API Module Design
Chart Source
Data Loading Process
Asynchronous Data Initialization
// Data initialization for process router dialog
const onOpen = async () => {
routers.value = await getProcessRouterList(props.productId)
initData()
}
const initData = async (filter?: string) => {
const ids = routers.value.map((item) => item.id) as string[]
const data = await getWorkStationList(filter)
const dataSourceItems = data.items.filter((item) =>
ids.includes(item.workSectionId)
)
dataSource.value = dataSourceItems
}
API Call Encapsulation
// API module encapsulation implementation
export const getProcessRouterList = (id: string) => {
return request.get(`/api/v1/messuite/query/processroutes?productId=${id}`)
}
export const getWorkStationList = (v?: string) => {
const filter = v ? `&Filter=${v}` : ''
return request.get(
`/api/v1/processmanagement/workstation?SkipCount=0&MaxResultCount=999&includeDetails=true${filter}`
)
}
Section Source
Complex Interaction Implementation
Business-level dialogs support various complex user interaction scenarios, including table operations, form validation, and dynamic content generation.
Table Rendering and Interaction
BaseTable Integration
<BaseTable
params={{
Filter: innerValue.value,
includeDetails: true,
}}
selections={selections.value}
pageSize={50}
ref={tableRef}
url="/api/v1/processmanagement/workstation"
style="margin-top:10px"
v-model:dataSource={dataSource.value}
columns={columns.value}
isChecked={true}
onCheck={onCheck}
/>
Table Column Configuration
const columns = computed(() => [
{
title: _t('序号'),
type: 'seq',
width: '60',
},
{
field: 'workSection.name',
title: _t('工序名称'),
},
{
field: 'name',
title: _t('工位名称'),
},
{
field: 'remark',
title: _t('备注'),
},
])
Dynamic Form Generation
DyForm Integration
<DyForm
ref={formRef}
v-model:formData={formData.value}
formItemProps={[
{
prop: 'ipListString',
label: _t('可访问IP'),
el: 'input',
clearable: true,
placeholder: _t('请输入可访问IP'),
icon: 'tip',
tip: _t('手动填写IP,存在多个IP访问,以";"分隔'),
rules: [
{
message: _t('请输入可访问IP'),
pattern: /^(\d{1,3}\.){3}\d{1,3}(\s*;\s*(\d{1,3}\.){3}\d{1,3})*$/,
trigger: 'change',
},
],
},
{
prop: 'userListString',
label: _t('可访问用户'),
el: 'select',
maxCollapseTags: 999,
clearable: true,
placeholder: _t('可访问用户'),
filterable: true,
remote: true,
multiple: true,
collapseTags: true,
options: userOptions.value,
},
]}
/>
Tree Selector Linkage
Although tree selectors are not directly seen in the currently analyzed code, based on the overall architecture of the system, it can be foreseen that tree selectors will be implemented through similar Hook patterns:
Section Source
Performance Optimization and Memory Management
Business-level dialogs fully consider performance optimization and memory management in design, avoiding unnecessary re-rendering and memory leaks.
Component Destruction Strategy
// destroy-on-close property ensures component destruction
<BaseDialog
destroy-on-close
class={styles.drawer}
style="background: #fff"
width="664px"
height="578px"
title={props.title ? props.title : _t('工位选择')}
v-model={visible.value}
onClose={onClose}
onConfirm={onConfirm}
onOpen={onOpen}
/>
Memory Leak Protection
Automatic Cleanup Mechanism
// Automatically clean state when dialog closes
const onClose = () => {
visible.value = false
// Clean selected state
checkedList.value = []
// Clean search condition
innerValue.value = ''
// Trigger close event
ctx.emit('close')
}
// Cleanup on confirm
const onConfirm = async () => {
ctx.emit('confirm', checkedList.value)
// Clean table selected state
tableRef.value?.clearAll()
visible.value = false
}
Asynchronous Operation Cancellation
// Use AbortController or similar mechanism to cancel incomplete requests
let abortController: AbortController | null = null
const fetchData = async () => {
abortController = new AbortController()
try {
const response = await fetch('/api/data', {
signal: abortController.signal
})
// Handle response...
} catch (error) {
if (error.name === 'AbortError') {
// Request canceled, no need to handle
return
}
throw error
}
}
// Cancel request when component unmounts
onUnmounted(() => {
if (abortController) {
abortController.abort()
}
})
Performance Optimization Strategies
Virtual Scrolling
// Enable virtual scrolling for large data tables
<BaseTable
// ... other properties
virtual-list-props={{
height: autoHeight.value
}}
isVScroll={true}
/>
Lazy Loading
// Load dialog content on demand
const onOpen = async () => {
if (!hasLoaded.value) {
await loadData()
hasLoaded.value = true
}
}
Best Practices Guide
Based on in-depth analysis of business-level dialogs, the following are recommended best practices:
Component Design Principles
1. Single Responsibility Principle
Each business-level dialog focuses on a specific business scenario, avoiding functional mixing.
2. Reusability Design
Extract common logic through Hook patterns, reducing duplicate code.
3. Type Safety
Fully utilize TypeScript type system to ensure component interface correctness.
Development Standards
Hook Naming Convention
// Recommended Hook naming format
export const useSelectDialog = (props: DialogProps, ctx: SetupContext) => {
// Implementation...
}
export const useWorkStation = (props: WorkStationProps, ctx: SetupContext) => {
// Implementation...
}
API Module Organization
// Organize APIs by functional modules
export const getWorkStationList = (filter?: string) => {
// Implementation...
}
export const updateWorkStation = (id: string, data: WorkStationData) => {
// Implementation...
}
Error Handling Strategy
Layered Error Handling
// Component layer error handling
const onConfirm = async () => {
try {
await validateForm()
await submitData()
ctx.emit('confirm', result)
} catch (error) {
handleError(error)
}
}
// Hook layer error handling
const useSelectDialog = (props: any, ctx: any) => {
const handleError = (error: Error) => {
console.error('Dialog error:', error)
ElMessage.error(_t('操作失败,请稍后重试'))
}
}
Testing Strategy
Unit Test Coverage
// Hook function testing
describe('useSelectDialog', () => {
it('should initialize with correct props', () => {
const props = { modelValue: true, data: [] }
const ctx = createMockContext()
const result = useSelectDialog(props, ctx)
expect(result.visible.value).toBe(true)
expect(result.selections.value).toEqual([])
})
})
Integration Testing
// Component integration testing
describe('WorkStationDialog', () => {
it('should render correctly with data', async () => {
const wrapper = mount(WorkStationDialog, {
props: {
modelValue: true,
data: testData
}
})
expect(wrapper.find('.workstation-table')).toBeDefined()
})
})
Summary
Business-level dialogs are important components for implementing complex business logic in the LME system. Through the unified framework of the BaseDialog base class, Hook pattern state management, and complete API integration, these components achieve:
- Highly Reusable Architecture Design: Implements maximum code reuse through inheritance and composition patterns
- Clear Responsibility Separation: Components, Hooks, and APIs each perform their duties, maintaining code cleanliness
- Powerful State Management: Implements reactive state management using Vue 3 Composition API
- Complete Error Handling: Multi-level error handling mechanisms ensure application stability
- Excellent User Experience: Rich interactive functions and smooth animation effects
This design pattern not only improves development efficiency but also lays a solid foundation for subsequent feature expansion and maintenance. Developers can quickly build new business scenarios based on existing business-level dialogs while maintaining code quality and consistency.
Through in-depth understanding of the design concepts and implementation details of these components, development teams can better maintain existing systems and formulate reasonable plans for future feature expansion.