{"id":20609528,"url":"https://github.com/wccdev/drf-oa-workflow","last_synced_at":"2026-05-17T00:36:43.831Z","repository":{"id":218856503,"uuid":"747538434","full_name":"wccdev/drf-oa-workflow","owner":"wccdev","description":"Django+Rest+OAWorkflow","archived":false,"fork":false,"pushed_at":"2025-08-21T10:13:13.000Z","size":816,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-21T12:25:53.271Z","etag":null,"topics":["django","django-rest-framework","workflow-tool"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wccdev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-24T06:06:54.000Z","updated_at":"2025-08-21T10:12:40.000Z","dependencies_parsed_at":"2025-05-12T11:33:19.692Z","dependency_job_id":"5f95b6cb-358b-43f1-a2c8-a3ad5b4d08e7","html_url":"https://github.com/wccdev/drf-oa-workflow","commit_stats":null,"previous_names":["wccdev/drf-oa-workflow"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/wccdev/drf-oa-workflow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wccdev%2Fdrf-oa-workflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wccdev%2Fdrf-oa-workflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wccdev%2Fdrf-oa-workflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wccdev%2Fdrf-oa-workflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wccdev","download_url":"https://codeload.github.com/wccdev/drf-oa-workflow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wccdev%2Fdrf-oa-workflow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276518809,"owners_count":25656497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-23T02:00:09.130Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","django-rest-framework","workflow-tool"],"created_at":"2024-11-16T10:13:50.003Z","updated_at":"2025-09-23T04:41:52.591Z","avatar_url":"https://github.com/wccdev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# drf-oa-workflow\n\n\n[![pypi](https://img.shields.io/pypi/v/drf-oa-workflow.svg)](https://pypi.wochacha.cn/simple/drf-oa-workflow/)\n[![python](https://img.shields.io/pypi/pyversions/drf-oa-workflow.svg)](https://pypi.wochacha.cn/simple/drf-oa-workflow/)\n[![Build Status](https://github.com/wccdev/drf-oa-workflow/actions/workflows/python-publish.yml/badge.svg)](https://github.com/wccdev/drf-oa-workflow/actions/workflows/python-publish.yml)\n[![codecov](https://codecov.io/gh/wccdev/drf-oa-workflow/branch/main/graphs/badge.svg)](https://codecov.io/github/wccdev/drf-oa-workflow)\n\n\n\nSkeleton project created by Cookiecutter PyPackage\n\n\n* Documentation: \u003chttps://wccdev.github.io/drf-oa-workflow\u003e\n* GitHub: \u003chttps://github.com/wccdev/drf-oa-workflow\u003e\n* PyPI: \u003chttps://pypi.wochacha.cn/simple/drf-oa-workflow/\u003e\n* Free software: MIT\n\n\n## Installation\n- 使用 pip:\n```bash\npip install drf-oa-workflow\n\n```\n- 使用 poetry:\n```bash\npoetry add drf-oa-workflow\n```\n\n## Usage\n- 在 django setting中注册本应用 `'drf_oa_workflow'`, 添加相关的配置\n```python\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    ...,\n    \"django.contrib.auth\",\n    \"xxxx.users\",  # （项目指定AUTH_USER_MODEL的APP, 如果有）\n    ...,\n    \"drf_oa_workflow\",\n]\n\n# 由oa提供\nDRF_OA_WORKFLOW = {\n    # 项目OA需要的链接的数据别名\n    \"OA_DATABASE_ALIAS\": \"oa\",\n\n    # oa接口应用id\n    \"APP_ID\": \"xxxx\",\n    # oa接口应用secret\n    \"APP_RAW_SECRET\": \"xxxx-xxx-xxxx\",\n    # oa接口应用spk\n    \"APP_SPK\": \"xxxxxxxxxx\",\n    # oa接口服务地址(域名)\n    \"OA_HOST\": \"https://oa.demo.com\",\n\n    # -----以下可选----- #\n    # requests包 Requests HTTP Library, 可使用自定义封装请求日志的requests代替\n    \"REQUESTS_LIBRARY\": \"requests\",\n}\n```\n\n### ~~1.全局使用~~(暂不推荐)\n- 在 django setting中注册中间件 `'drf_oa_workflow.middleware.OaWFRequestMiddleware'`:\n```python\nMIDDLEWARE = [\n    ...,\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    ...,\n    \"drf_oa_workflow.middleware.OaWFRequestMiddleware\",\n]\n```\n\n\n### 2.局部使用\n- 在需要使用的视图上继承\n```python\nfrom drf_oa_workflow.mixin import OaWFApiViewMixin\nfrom rest_framework.views import APIView\n\n\nclass YourViewSet(OaWFApiViewMixin, APIView):\n    ...\n```\n\n#### 注意!!!\n- 上述两种使用方法需要项目的`AUTH_USER_MODEL`提供属性`oa_user_id`\n\n- `oa_user_id`为当前登入用户request.user在oa系统中对应的user_id\n```python\nfrom django.db.models import Model\nclass User(Model):\n    ...\n\n    class Meta:\n        ...\n\n    @property\n    def oa_user_id(self):\\\n        # TODO 获取对应oa用户逻辑\n        if hasattr(self, \"oauserinfo\"):\n            return self.oauserinfo.user_id\n        # 或者自定义逻辑\n        oa_user_id = \"1\"\n        return oa_user_id\n```\n\n- 完成上述步骤，即可在视图中使用\n```python\nfrom rest_framework.views import APIView\nfrom rest_framework.response import Response\nfrom rest_framework.decorators import action\n\n\n# from drf_oa_workflow.mixin import OaWFApiViewMixin\n# class YourViewSet(OaWFApiViewMixin, APIView):  # 未注册中间件方式\nclass YourViewSet(APIView):\n    @action(detail=False)\n    def test(self, request, *args, **kwargs):\n        workflow = request.oa_wf_api\n        # 待办流程\n        workflow.get_todo_list(workflow_id=12345, page=1, page_size=10)\n        # 已办流程\n        workflow.get_handled_list(workflow_id=12345, page=1, page_size=10)\n        # 可创建流程\n        workflow.get_create_list()\n        # ...\n        return Response()\n```\n\n### 3.使用类\n```python\nfrom drf_oa_workflow.utils import OaWorkFlow\n\nworkflow = OaWorkFlow()\n# 调用前必须使用register_user方法\n# 注册需要调用流程接口的oa用户id\noa_user_id = \"TODO\"  # TODO\nworkflow.register_user(oa_user_id)\n\n# 待办流程\nworkflow.get_todo_list(workflow_id=12345, page=1, page_size=10)\n# 已办流程\nworkflow.get_handled_list(workflow_id=12345, page=1, page_size=10)\n# 可创建流程\nworkflow.get_create_list()\n# ...\n```\n\n### 4.使用现成接口 (TODO, 开发中)\n```python\nfrom django.urls import include, path\n\nurlpatterns = [\n    ...,\n    path(\"api/\", include(\"drf_oa_workflow.urls\"))\n]\n```\n\n### 5.同步OA账号到当前项目\n- 同步数据前需要在项目设置DRF_OA_WORKFLOW中配置OA数据库连接以及指定用户表信息\n#### 5.1 设置保存数据的表\n- 5.1.1 使用drf-oa-workflow内置表\ndrf_oa_workflow已经设置了相关表，可执直接执行迁移命令生成\n详情请查看drf_oa_workflow.models.OaUserInfo\n```python\nfrom django.contrib.auth import get_user_model\nfrom django.db import models\n\nUserModel = get_user_model()\n\n\nclass OaUserInfo(models.Model):\n    user_id = models.IntegerField(unique=True, primary_key=True, verbose_name=\"OA用户数据ID\")\n    staff_code = models.OneToOneField(\n        UserModel,\n        on_delete=models.DO_NOTHING,\n        to_field=UserModel.USERNAME_FIELD,\n        db_column=\"staff_code\",\n        db_constraint=False,\n        verbose_name=\"OA用户工号\",\n    )\n    dept_id = models.IntegerField(null=True, verbose_name=\"OA用户部门ID\")\n```\n```bash\npython manage.py migrate drf_oa_workflow\n\n```\n\n- 5.1.2 使用你自己的表\n```python\nfrom django.db.models import CharField\nfrom drf_oa_workflow.models import AbstractOaUserInfo\n\n\nclass YouOAUserModel(AbstractOaUserInfo):\n    extra_field1 = CharField(max_length=20, blank=True, verbose_name=\"额外字段1\")\n    extra_field2 = CharField(max_length=20, blank=True, verbose_name=\"额外字段2\")\n\n    class Meta:\n        abstract = True\n        verbose_name = verbose_name_plural = \"OA用户信息\"\n        db_table = \"xxxxx\"\n```\n\n#### 注意!!!\n如果项目使用5.1.2方式中的OA用户模型，请在项目配置中配置SYNC_OA_USER_MODEL变量\n```python\n# 指定项目使用的OA用户模型： SYNC_OA_USER_MODEL = \"模型所属APP.模型类名\"\n# 如果不配置，项目默认OA用户模型仍为drf_oa_workflow.models.OaUserInfo\n# 参考Django AUTH_USER_MODEL变量\nSYNC_OA_USER_MODEL = \"xxxx.YouOAUserModel\"\n```\n\n#### 5.2 在admin后台添加drf_oa_workflow中的定时任务\n需要celery以及django-celery-beat\n![img.png](static/sync_user_task.png)\n\n#### 5.3 项目User获取同步到的oa用户信息\n```python\nfrom django.contrib.auth import get_user_model\n\nuser = get_user_model().objects.select_related(\"oauserinfo\").first()\nif hasattr(user, \"oauserinfo\"):\n    print(user.oauserinfo.user_id)\n    print(user.oauserinfo.staff_code)\n    print(user.oauserinfo.staff_code_id)\n    print(user.oauserinfo.dept_id)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwccdev%2Fdrf-oa-workflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwccdev%2Fdrf-oa-workflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwccdev%2Fdrf-oa-workflow/lists"}