计算机毕业设计选题推荐-办公管理系统-Python项目实战

作者主页:IT研究室✨
个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。
☑文末获取源码☑
精彩专栏推荐⬇⬇⬇
Java项目
Python项目
安卓项目
微信小程序项目

一、前言

随着企业规模的扩大和业务复杂性的增加,办公管理系统对于企业的运营至关重要。本课题基于角色权限管理的办公管理系统,旨在解决企业运营过程中的一系列管理问题,提高工作效率,保障信息安全,提升企业运营的规范性。

当前,许多企业的办公管理系统存在以下问题:
缺乏统一的角色权限管理,导致权限分配混乱,容易引发信息安全问题;
系统功能模块独立,缺乏协同性,无法满足企业复杂多变的业务需求;
系统可扩展性差,难以适应企业快速发展的需要;
缺乏智能化决策支持,难以实现数据驱动的管理决策。

本课题基于角色权限管理的办公管理系统,能够实现以下功能:
员工管理:支持员工信息的录入、修改、删除等操作,支持员工账号的创建和权限分配;
部门信息管理:维护企业组织架构,记录部门相关信息;
通知公告管理:发布通知公告,实时传递企业最新消息;
员工打卡管理:记录员工的考勤情况,便于薪资计算和管理;
员工请假管理:支持员工请假申请和审批,提高工作效率;
员工档案管理:存储员工档案信息,方便查询和管理;
下派任务管理:支持任务的下达、分配、跟踪和反馈,提高工作效率;
完成任务管理:记录员工完成任务的情况,便于考核和评价;
员工评价管理:对员工工作表现进行评价,激励员工提升工作效率和质量;
员工工资管理:根据员工考勤、工作表现等因素计算员工工资。

本课题的研究意义在于:
通过建立统一的角色权限管理体系,解决权限分配混乱的信息安全问题;
通过整合各个功能模块,实现各模块之间的协同工作,满足企业复杂多变的业务需求;
通过优化系统架构和算法设计,提高系统的可扩展性和性能,适应企业快速发展的需要;
通过引入智能化决策支持功能,实现数据驱动的管理决策,提高企业的决策效率和准确性。

二、开发环境

  • 开发语言:Python
  • 数据库:MySQL
  • 系统架构:B/S
  • 后端:Django
  • 前端:Vue

三、系统功能模块

  • 角色:员工、管理员
  • 功能:
    员工
    通知公告、员工打卡管理、员工请假管理、员工档案管理、下派任务管理、完成任务管理、员工评价管理、员工工资管理;
    管理员
    员工管理、部门信息管理、通知公告管理、员工打卡管理、员工请假管理、员工档案管理、下派任务管理、完成任务管理、员工评价管理、员工工资管理。

四、系统界面展示

  • 办公管理系统-界面展示:
    办公管理系统-员工打卡
    办公管理系统-员工请假
    办公管理系统-员工档案信息-员工
    办公管理系统-下派任务管理-员工
    办公管理系统-完成任务管理-员工
    办公管理系统-员工打卡管理-管理员
    办公管理系统-员工请假管理-管理员
    办公管理系统-下派任务管理-管理员
    办公管理系统-完成任务管理-管理员
    办公管理系统-员工工资管理-管理员

五、代码参考

  • Python项目实战-代码参考:
class ValueListAdmin(generic.BOAdmin):
    CODE_NUMBER_WIDTH = 3
    CODE_PREFIX = 'S'
    list_display = ['code', 'name', 'module', 'status']
    fields = (('code',),('name',),('module',),('status','init','locked',),('locked_by','lock_time',))
    raw_id_fields = ['module']
    readonly_fields = ['locked_by','lock_time']
    inlines = [ValueListItemInline]
    search_fields = ['code','name']

    def save_model(self, request, obj, form, change):
        super(ValueListAdmin,self).save_model(request,obj,form,change)
        obj.valuelistitem_set.update(group_code=obj.code)


class AddressAdmin(generic.BOAdmin):
    list_display = ['address','phone','contacts']
    exclude = ['content_type','object_id','creator','modifier','creation','modification','begin','end']


class AddressInline(GenericTabularInline):
    model = Address
    exclude = ['content_type','object_id','creator','modifier','creation','modification','begin','end']
    extra = 1


class BankAccountInline(admin.TabularInline):
    model = BankAccount
    fields = ['account','title','memo']

    def get_extra(self, request, obj=None, **kwargs):
        if obj:
            return 0
        else:
            return 1


class PartnerForm(models.ModelForm):
    tax_address = fields.CharField(widget=TextInput(attrs={'size': 119,}),required=False,label=_("tax address"))
    memo = fields.CharField(widget=Textarea(attrs={'rows':3,'cols':85}),required=False,label=_("memo"))

    class Meta:
        model = Partner
        fields = '__all__'


class PartnerAdmin(generic.BOAdmin):
    list_display = ['code','name','partner_type','level']
    list_display_links = ['code','name']

    fields = (('code','name',),('short','pinyin',),('partner_type','level'),('tax_num','tax_account',),
              ('tax_address',),('contacts','phone',),('memo',),)
    search_fields = ['code','name','pinyin']
    form = PartnerForm
    save_on_top = True
    inlines = [AddressInline,BankAccountInline]

    def get_queryset(self, request):
        if request.user.is_superuser or (request.user.has_perm('basedate.view_all_customer') and request.user.has_perm('basedate.view_all_supplier')):
            return super(PartnerAdmin,self).get_queryset(request)
        elif request.user.has_perm('basedata.view_all_customer'):
            return super(PartnerAdmin,self).get_queryset(request).filter(partner_type='C')
        else:
           return super(PartnerAdmin,self).get_queryset(request).filter(partner_type='S')


class ProjectForm(models.ModelForm):
    income = fields.DecimalField(required=False,widget=TextInput(attrs={'readonly':'true'}))
    expand = fields.DecimalField(required=False,widget=TextInput(attrs={'readonly':'true'}))

    class Meta:
        model = Project
        fields = '__all__'


class ProjectAdmin(generic.BOAdmin):
    CODE_PREFIX = 'PJ'
    list_display = ['code','name','status','income','expand']
    list_display_links = ['code','name']
    fields = (
        ('code','name',),('short','pinyin',),
        ('partner',),('status','prj_type',),
        ('description',),
        ('budget','income','expand',),('blueprint',),('offer',),('business',),('users',),
    )
    search_fields = ['code','name']
    readonly_fields = ['status']
    raw_id_fields = ['partner']
    filter_horizontal = ['users']
    form = ProjectForm


class WarehouseAdmin(admin.ModelAdmin):
    list_display = ['code','name','location']
    filter_horizontal = ['users']

    def save_model(self, request, obj, form, change):
        super(WarehouseAdmin,self).save_model(request,obj,form,change)
        try:
            code = getattr(obj,'code')
            if not code:
                obj.code = '%s%02d' % ('A',obj.id)
                obj.save()
        except Exception,e:
            self.message_user(request,'ERROR:%s' % e,level=messages.ERROR)


class BrandAdmin(admin.ModelAdmin):
    list_display = ['name','pinyin']


class MeasureAdmin(admin.ModelAdmin):
    list_display = ['code','name','status']


class CategoryAdmin(admin.ModelAdmin):
    list_display = ['code','name','path']

    def save_model(self, request, obj, form, change):
        super(CategoryAdmin,self).save_model(request,obj,form,change)
        try:
            code = getattr(obj,'code')
            if not code:
                obj.code = '%s%02d' % ('F',obj.id)
                obj.save()
            if obj.parent:
                if obj.parent.path:
                    obj.path = obj.parent.path + '/'+obj.parent.name
                else:
                    obj.path = obj.parent.name
                obj.save()
        except Exception,e:
            self.message_user(request,'ERROR:%s' % e,level=messages.ERROR)


class MaterialForm(models.ModelForm):
    name = fields.CharField(widget=TextInput(attrs={"size":"119"}),label=_("material name"))
    spec = fields.CharField(widget=TextInput(attrs={"size":"119"}),required=False,label=_("specifications"))

    class Mata:
        model = Material
        fields = '__all__'


class ExtraParamInline(admin.TabularInline):
    model = ExtraParam
    fields = ['name','data_type','data_source']

    def get_extra(self, request, obj=None, **kwargs):
        if obj:
            return 0
        else:
            return 1


class MaterialAdmin(generic.BOAdmin):
    CODE_PREFIX = 'IT'
    CODE_NUMBER_WIDTH = 5
    list_display = ['code','name','spec','tp']
    list_display_links = ['code','name']
    list_filter = ['brand','tp']
    search_fields = ['code','name']
    fields = (
        ('code','barcode'),('name',),('spec',),
        ('brand',),('category',),('status','is_equip','can_sale','is_virtual',),
        ('warehouse',),('tp',),('measure',),('stock_price','purchase_price','sale_price',),
    )
    filter_horizontal = ['measure']
    inlines = [ExtraParamInline]
    form = MaterialForm


class TechParamValueInline(admin.TabularInline):
    model = TechnicalParameterValue


class TechParamNameAdmin(admin.ModelAdmin):
    list_display = ['name','category']
    inlines = [TechParamValueInline]


class TradeAdmin(admin.ModelAdmin):
    list_display = ['code','name','parent']


class ExpenseAdmin(generic.BOAdmin):
    CODE_PREFIX = 'FC'
    list_display = ['code','name','category']
    list_display_links = ['code','name']
    list_filter = ['category']
    search_fields = ['name']


class FamilyForm(models.ModelForm):
    name = fields.CharField(widget=TextInput(attrs={"size":"25"}),label=_("name"))
    phone = fields.CharField(widget=TextInput(attrs={"size":"25"}),label=_("phone"))

    class Meta:
        model = Family
        fields = '__all__'


class FamilyInline(admin.TabularInline):
    model = Family
    exclude = ['creator','modifier','creation','modification','begin','end']
    form = FamilyForm
    extra = 1


class EducationInline(admin.TabularInline):
    model = Education
    exclude = ['creator','modifier','creation','modification']
    extra = 0


class WorkExperienceInline(admin.TabularInline):
    model = WorkExperience
    exclude = ['creator','modifier','creation','modification']
    extra = 1


class EmployeeAdmin(generic.BOAdmin):
    CODE_PREFIX = '1'
    list_display = ['code','name','position','gender','idcard','age','work_age','literacy','phone','email']
    search_fields = ['code','name','idcard','pinyin']
    fieldsets = [
        (None,{'fields':[('code','phone',),('name','pinyin',),('gender','birthday',),('idcard','country',),
                         ('position',),('rank','category'),('status','ygxs',),('workday','startday',)]}),
        (_('other info'),{'fields':[('hometown','address',),('banknum','bankname',),('email','office',),
        ('emergency','literacy',),('religion','marital',),('party','nation',),('spjob','health',),
        ('major','degree',),('tag1','tag2',),('tag3','tag4',),('user',),],'classes':['collapse']}),
    ]
    readonly_fields = ['status','ygxs','rank','category']
    inlines = [FamilyInline,EducationInline,WorkExperienceInline]
    raw_id_fields = ['user']

    def get_queryset(self, request):
        if request.user.is_superuser or request.user.has_perm('basedata.view_all_employee'):
            return super(EmployeeAdmin,self).get_queryset(request)
        else:
            return super(EmployeeAdmin,self).get_queryset(request).filter(user=request.user)

    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return []
        else:
            return ['status','ygxs','rank','category','position','user']


class DataImportAdmin(generic.BOAdmin):
    list_display = ['imp_date','title','status']
    list_display_links = ['imp_date','title']
    raw_id_fields = ['content_type']
    readonly_fields = ['status']
    extra_buttons = [{'href':'action','title':_('import')}]

    def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
        if object_id:
            obj = DataImport.objects.get(id=object_id)
            if obj.status == '1':
                extra_context = extra_context or {}
                extra_context.update(dict(readonly=True))
        return super(DataImportAdmin,self).changeform_view(request,object_id,form_url,extra_context)


class DocumentForm(models.ModelForm):
    title = fields.CharField(widget=TextInput(attrs={"size":"119"}),label=_("title"))
    keywords = fields.CharField(widget=TextInput(attrs={"size":"119"}),label=_("keywords"))

    class Meta:
        model = Document
        fields = '__all__'


class DocumentAdmin(generic.BOAdmin):
    CODE_PREFIX = 'FD'
    CODE_NUMBER_WIDTH = 4
    list_display = ['code','title','keywords','tp','business_domain','status','creation']
    list_display_links = ['code','title']
    fields = (('code','status',),('title',),('keywords',),('description',),('business_domain','tp',),('attach',))
    readonly_fields = ['status']
    list_filter = ['tp','business_domain']
    search_fields = ['title','keywords','code']
    form = DocumentForm
    actions = ['publish']
    date_hierarchy = 'begin'

    def get_readonly_fields(self, request, obj=None):
        if obj and obj.status=='1':
            return ['code','status','title','keywords','description','business_domain','tp','attach',]
        else:
            return ['status']

    def publish(self,request,queryset):
        import datetime
        cnt = queryset.filter(status='0').update(status='1',pub_date=datetime.datetime.now())
        self.message_user(request,u'%s 个文档发布成功'%cnt)

    publish.short_description = _('publish selected %(verbose_name_plural)s')

# admin.site.register(Address,AddressAdmin)
admin.site.register(ValueList,ValueListAdmin)
admin.site.register(Partner,PartnerAdmin)
admin.site.register(Project,ProjectAdmin)
admin.site.register(Material,MaterialAdmin)
admin.site.register(Warehouse,WarehouseAdmin)
admin.site.register(Brand,BrandAdmin)
admin.site.register(Measure,MeasureAdmin)
admin.site.register(Category,CategoryAdmin)
admin.site.register(TechnicalParameterName,TechParamNameAdmin)
admin.site.register(Trade,TradeAdmin)
admin.site.register(ExpenseAccount,ExpenseAdmin)
admin.site.register(Employee,EmployeeAdmin)
admin.site.register(DataImport,DataImportAdmin)
admin.site.register(Document,DocumentAdmin)
def compile_node_handler(request,obj,next_node):
    """
    :param request:
    :param obj:
    :param handler:
    :return:
    """

    handler = next_node.handler
    next_user_handler = next_node.next_user_handler
    # next_user_handler 具有最高优先级
    if next_user_handler:
        # print 'it is here'
        klass = NextUserManager().handlers.get(next_user_handler)
        if klass and isinstance(klass,NextUserHandler):
            return klass.handle(request,obj,next_node)

    if handler and handler != '':
        handler = handler.replace("submitter()", request.user.username)
        handler = handler.replace("suber()", request.user.username)
        fields = obj._meta.fields
        for field in fields:
            name = field.name
            temp = "{{%s}}" % name
            val = getattr(obj,name,None)
            if val:
                if type(val)!=str:
                    val = str(val)
                handler = handler.replace(temp,val)
        cursor = connection.cursor()
        cursor.execute(handler)
        rows = [row for row in cursor.fetchall()]
        return rows
    else:
        tp = next_node.handler_type
        if tp == 1 and next_node.users:
            # user
            users = [user for user in next_node.users.all()]
            return users
        elif tp == 2 and next_node.positions:
            # position
            users = []
            for position in next_node.positions.all():
                for employee in position.employee_set.all():
                    users.append(employee.user)
            return users
        elif tp == 3 and next_node.roles:
            # role
            users = []
            for role in next_node.roles.all():
                for user in role.users.all():
                    users.append(user)
            return users
        elif tp == 4:
            # submitter
            return request.user
        else:
            return None


def start(request,app,model,object_id):
    """

    :param request:
    :return:
    """
    import datetime
    content_type = ContentType.objects.get(app_label=app,model=model)
    obj = content_type.get_object_for_this_type(id=int(object_id))
    title = _("Are you sure?")
    opts = obj._meta
    objects_name = force_text(opts.verbose_name)
    has_workflow = False
    queryset = Modal.objects.filter(content_type=content_type,end__gt=datetime.date.today()).order_by('-end')
    cnt = queryset.count()
    workflow_modal = None
    next_node = None
    next_users = []
    has_next_user = False
    if cnt > 0:
        has_workflow = True
        workflow_modal = queryset[0]
        query_start_node = workflow_modal.node_set.filter(start=1)
        query_first_node = workflow_modal.node_set.order_by('id')
        if query_start_node.count() > 0:
            next_node = query_start_node[0]
        elif query_first_node.count()>0:
            next_node = query_first_node[0]
        if next_node:
            next_users = compile_node_handler(request,obj,next_node)
            if len(next_users) > 0:
                has_next_user = True
    else:
        title = _("No workflow model was found")

    try:
        tmp = Instance.objects.get(modal = workflow_modal,object_id=object_id)
        messages.warning(request,_("the object is already in workflow"))
        return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id))
    except Exception:
        pass

    if request.POST.get("post"):
        val = request.POST.getlist(SELECTED_CHECKBOX_NAME)
        workflow_inst = Instance.objects.create(modal=workflow_modal,object_id=object_id,starter=request.user)
        workflow_inst.current_nodes.add(next_node)
        workflow_inst.save()
        workflow_history = History.objects.create(inst=workflow_inst,user=request.user)
        for user in User.objects.filter(id__in=val):
            todo = TodoList.objects.create(inst=workflow_inst,node=next_node,user=user,app_name=app,model_name=model)
        TodoList.objects.create(inst=workflow_inst,user=request.user,app_name=app,model_name=model,is_read=True,
                                read_time=datetime.datetime.now(),status=True)
        if next_node.status_field and next_node.status_value:
            try:
                setattr(obj,next_node.status_field,next_node.status_value)
                obj.save()
            except Exception,e:
                pass
        messages.success(request,_('workflow started successfully'))
        return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id))

    context = dict(
        site.each_context(request),
        title=title,
        opts=opts,
        objects_name=objects_name,
        object=obj,
        has_workflow = has_workflow,
        workflow_modal = workflow_modal,
        next_node = next_node,
        has_next_user = has_next_user,
        next_users = next_users,
        checkbox_name = SELECTED_CHECKBOX_NAME,
    )
    request.current_app = site.name

    return TemplateResponse(request,'default/workflow/workflow_start_confirmation.html', context)


def approve(request,app,model,object_id,operation):
    """

    :param request:
    :param operation:
    :return:
    """
    if operation not in ('1','3','4'):
        messages.warning(request,_("unkown workflow operation"))
        return HttpResponseRedirect("/admin/%s/%s/%s"%(app,model,object_id))

六、论文参考

  • 计算机毕业设计选题推荐-办公管理系统-论文参考:
    计算机毕业设计选题推荐-办公管理系统-论文参考

七、系统视频

办公管理系统-项目视频:

基于Python的办公管理系统

结语

计算机毕业设计选题推荐-办公管理系统-Python项目实战
大家可以帮忙点赞、收藏、关注、评论啦~
源码获取:私信我

精彩专栏推荐⬇⬇⬇
Java项目
Python项目
安卓项目
微信小程序项目

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT研究室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值