forked from erp-dev/erp
feat: new modul (stateflow)
This commit is contained in:
@@ -1,3 +1,160 @@
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin import action
|
||||
from django.utils.safestring import mark_safe
|
||||
from . import models
|
||||
|
||||
# Register your models here.
|
||||
|
||||
class StateParameterInline(admin.StackedInline):
|
||||
model = models.StateParameter
|
||||
extra = 1
|
||||
|
||||
|
||||
class ProcessNodeInline(admin.StackedInline):
|
||||
model = models.ProcessNode
|
||||
extra = 1
|
||||
autocomplete_fields = ('state',)
|
||||
ordering = ('order',)
|
||||
|
||||
|
||||
@admin.register(models.State)
|
||||
class StateAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'parameter_overview',
|
||||
)
|
||||
search_fields = ('name', 'description')
|
||||
list_filter = ('created_at', 'updated_at', 'processes__name')
|
||||
inlines = [StateParameterInline]
|
||||
|
||||
@admin.display(description='参数概览')
|
||||
def parameter_overview(self, obj: models.State):
|
||||
params = obj.parameters.all()
|
||||
if params:
|
||||
result = "<br>".join([f"{param.key}={param.value}" for param in params])
|
||||
else:
|
||||
result = "-"
|
||||
return mark_safe(result)
|
||||
|
||||
|
||||
@admin.register(models.Process)
|
||||
class ProcessAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'id',
|
||||
'name',
|
||||
'node_count',
|
||||
'description',
|
||||
'updated_at',
|
||||
)
|
||||
search_fields = ('name', 'description')
|
||||
list_filter = ('created_at', 'updated_at')
|
||||
inlines = [ProcessNodeInline]
|
||||
|
||||
@admin.display(description='节点数量')
|
||||
def node_count(self, obj: models.Process):
|
||||
return obj.process_nodes.count()
|
||||
|
||||
|
||||
class StateFlowRecordInline(admin.StackedInline):
|
||||
model = models.StateFlowRecord
|
||||
extra = 0
|
||||
fields = ('state', 'completed_at', 'completed_by', 'is_cancelled', 'cancelled_at')
|
||||
readonly_fields = ('completed_at', 'completed_by', 'cancelled_at')
|
||||
can_delete = False
|
||||
ordering = ('completed_at',)
|
||||
|
||||
|
||||
@admin.register(models.BusinessObject)
|
||||
class BusinessObjectAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'id',
|
||||
'name',
|
||||
'process',
|
||||
'content_object_display',
|
||||
'current_state_display',
|
||||
'progress',
|
||||
'params',
|
||||
'updated_at',
|
||||
)
|
||||
search_fields = ('name', 'description')
|
||||
list_filter = ('process', 'created_at', 'updated_at')
|
||||
actions = ['advance_to_next_state_action', 'reset_progress_action']
|
||||
autocomplete_fields = ('process',)
|
||||
inlines = [StateFlowRecordInline]
|
||||
fieldsets = [
|
||||
('基本信息', {
|
||||
'fields': ['name', 'process', 'description']
|
||||
}),
|
||||
('关联对象(可选)', {
|
||||
'fields': ['content_type', 'object_id'],
|
||||
'description': '可选择关联到实际的业务对象,如订单、工单等'
|
||||
}),
|
||||
]
|
||||
|
||||
@admin.display(description='关联对象')
|
||||
def content_object_display(self, obj: models.BusinessObject):
|
||||
"""显示关联对象"""
|
||||
if obj.content_object:
|
||||
return f"{obj.content_type} #{obj.object_id}"
|
||||
return "-"
|
||||
|
||||
@action(description='前进到下一个状态')
|
||||
def advance_to_next_state_action(self, request, queryset):
|
||||
from . import services
|
||||
success_count = 0
|
||||
messages = []
|
||||
|
||||
for obj in queryset:
|
||||
success, message = services.advance_to_next_state(obj, request.user)
|
||||
if success:
|
||||
success_count += 1
|
||||
messages.append(f"{obj.name}: {message}")
|
||||
|
||||
self.message_user(request, f'成功推进 {success_count}/{queryset.count()} 个业务对象。详情: {"; ".join(messages[:5])}')
|
||||
|
||||
@action(description='重置进度')
|
||||
def reset_progress_action(self, request, queryset):
|
||||
from . import services
|
||||
for obj in queryset:
|
||||
services.reset_business_object_progress(obj)
|
||||
self.message_user(request, f'已重置 {queryset.count()} 个业务对象的进度。')
|
||||
|
||||
@admin.display(description='当前状态', ordering='process')
|
||||
def current_state_display(self, obj: models.BusinessObject):
|
||||
from . import services
|
||||
current_state = obj.get_current_state()
|
||||
overall_status = services.get_overall_status(obj)
|
||||
|
||||
if overall_status == 'not_started':
|
||||
return '未开始'
|
||||
elif overall_status == 'completed':
|
||||
return '已完成'
|
||||
elif current_state:
|
||||
return current_state.name
|
||||
return '-'
|
||||
|
||||
@admin.display(description='进度')
|
||||
def progress(self, obj: models.BusinessObject):
|
||||
return f"{obj.get_progress_percentage():.1f}%"
|
||||
|
||||
@admin.display(description='本步骤参数')
|
||||
def params(self, obj: models.BusinessObject):
|
||||
current_state = obj.get_current_state()
|
||||
if current_state:
|
||||
params = current_state.parameters.all()
|
||||
if params:
|
||||
return ", ".join([f"{param.key}={param.value}" for param in params])
|
||||
return "-"
|
||||
|
||||
|
||||
@admin.register(models.StateFlowRecord)
|
||||
class StateFlowRecordAdmin(admin.ModelAdmin):
|
||||
list_display = ('id', 'business_object', 'state', 'completed_at', 'completed_by', 'is_cancelled', 'cancelled_at')
|
||||
search_fields = ('business_object__name', 'state__name')
|
||||
list_filter = ('state', 'is_cancelled', 'completed_at', 'completed_by')
|
||||
readonly_fields = ('business_object', 'state', 'completed_at', 'completed_by', 'cancelled_at')
|
||||
fields = ('business_object', 'state', 'completed_at', 'completed_by', 'is_cancelled', 'cancelled_at')
|
||||
autocomplete_fields = ('business_object', 'state', 'completed_by')
|
||||
|
||||
Reference in New Issue
Block a user