diff --git a/LICENSE b/LICENSE index 29f81d812f3e768fa89638d1f72920dbfd1413a8..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/backend/conf/env.py b/backend/conf/env.py index 134c233ecde237be18b72e21b1e42dff0bcf8f22..44e3a9b64ff116015ab15441fda109591c834e06 100644 --- a/backend/conf/env.py +++ b/backend/conf/env.py @@ -17,8 +17,8 @@ DATABASE_NAME = "fuadmin" # ================================================= # # ************** redis配置,无redis 可不进行配置 ************** # # ================================================= # -REDIS_PASSWORD = '' -REDIS_HOST = '127.0.0.1' +REDIS_PASSWORD = "" +REDIS_HOST = "127.0.0.1" REDIS_URL = f'redis://:{REDIS_PASSWORD or ""}@{REDIS_HOST}:6379' # ================================================= # # ************** 其他 配置 ************** # diff --git a/backend/demo/api.py b/backend/demo/api.py index a2963f2943fc8c9458f7bc6d62e22e8490d73c86..8e65fff8b33941f9fe8e18422f421abdc311806d 100644 --- a/backend/demo/api.py +++ b/backend/demo/api.py @@ -26,8 +26,8 @@ router = Router() # 设置过滤字段 class Filters(FuFilters): - name: str = Field(None, alias="name") - code: str = Field(None, alias="code") + name: str = Field(None, q="name__contains", alias="name") + code: str = Field(None, q="code__contains", alias="code") status: int = Field(None, alias="status") id: str = Field(None, alias="demo_id") @@ -38,21 +38,28 @@ class DemoSchemaIn(ModelSchema): class Config: model = Demo - model_fields = ['name', 'code', 'sort', 'status'] + model_fields = ["name", "code", "sort", "status"] # 设置响应字段 class DemoSchemaOut(ModelSchema): - class Config: model = Demo - model_fields = ['id', 'name', 'code', 'sort', 'status', 'remark', 'create_datetime'] + model_fields = [ + "id", + "name", + "code", + "sort", + "status", + "remark", + "create_datetime", + ] # 创建Demo @router.post("/demo", response=DemoSchemaOut) def create_demo(request, data: DemoSchemaIn): - data.remark = ','.join(data.remark) + data.remark = ",".join(data.remark) demo = create(request, data, Demo) return demo @@ -67,7 +74,7 @@ def delete_demo(request, demo_id: int): # 更新Demo @router.put("/demo/{demo_id}", response=DemoSchemaOut) def update_demo(request, demo_id: int, data: DemoSchemaIn): - data.remark = ','.join(data.remark) + data.remark = ",".join(data.remark) demo = update(request, demo_id, data, Demo) return demo @@ -83,12 +90,12 @@ def list_demo(request, filters: Filters = Query(...)): # 导入 @router.get("/demo/all/export") def export_demo(request): - export_fields = ['name', 'code', 'status'] + export_fields = ["name", "code", "status"] return export_data(request, Demo, DemoSchemaOut, export_fields) # 导出 @router.post("/demo/all/import") def import_demo(request, data: ImportSchema): - import_fields = ['name', 'code', 'status'] + import_fields = ["name", "code", "status"] return import_data(request, Demo, DemoSchemaIn, data, import_fields) diff --git a/backend/generator/template_test/api.py b/backend/generator/template_test/api.py index 3c415429088c94a9adf10ae76fefe4b90de0764d..da824fc0525e83cbacb67ec4c5866f85d9c01867 100644 --- a/backend/generator/template_test/api.py +++ b/backend/generator/template_test/api.py @@ -18,50 +18,55 @@ router = Router() # 设置过滤字段 class Filters(FuFilters): - - input_text_area_2: str = Field(None, alias='input_text_area_2') - input_1: str = Field(None, alias='input_1') + input_text_area_2: str = Field(None, alias="input_text_area_2") + input_1: str = Field(None, alias="input_1") # 设置请求接收字段 class TemplateTestSchemaIn(ModelSchema): - class Config: model = TemplateTest - model_exclude = ['create_datetime', 'update_datetime', 'belong_dept', 'modifier', 'creator', 'creator', 'id'] + model_exclude = [ + "create_datetime", + "update_datetime", + "belong_dept", + "modifier", + "creator", + "creator", + "id", + ] # 设置响应字段 class TemplateTestSchemaOut(ModelSchema): - class Config: model = TemplateTest - model_fields = '__all__' + model_fields = "__all__" # 创建TemplateTest -@router.post('/template_test', response=TemplateTestSchemaOut) +@router.post("/template_test", response=TemplateTestSchemaOut) def create_template_test(request, data: TemplateTestSchemaIn): template_test = create(request, data, TemplateTest) return template_test # 删除TemplateTest -@router.delete('/template_test/{id}') +@router.delete("/template_test/{id}") def delete_template_test(request, id: int): delete(id, TemplateTest) - return {'success': True} + return {"success": True} # 更新TemplateTest -@router.put('/template_test/{id}', response=TemplateTestSchemaOut) +@router.put("/template_test/{id}", response=TemplateTestSchemaOut) def update_template_test(request, id: int, data: TemplateTestSchemaIn): template_test = update(request, id, data, TemplateTest) return template_test # 获取TemplateTest -@router.get('/template_test', response=List[TemplateTestSchemaOut]) +@router.get("/template_test", response=List[TemplateTestSchemaOut]) @paginate(MyPagination) def list_template_test(request, filters: Filters = Query(...)): qs = retrieve(request, TemplateTest, filters) @@ -69,15 +74,20 @@ def list_template_test(request, filters: Filters = Query(...)): # 导入 -@router.get('/template_test/all/export') +@router.get("/template_test/all/export") def export_template_test(request): - export_fields = ('input_text_area_2', 'input_1', ) + export_fields = ( + "input_text_area_2", + "input_1", + ) return export_data(request, TemplateTest, TemplateTestSchemaOut, export_fields) # 导出 -@router.post('/template_test/all/import') +@router.post("/template_test/all/import") def import_template_test(request, data: ImportSchema): - import_fields = ('input_text_area_2', 'input_1', ) + import_fields = ( + "input_text_area_2", + "input_1", + ) return import_data(request, TemplateTest, TemplateTestSchemaIn, data, import_fields) - \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index ee57f03ed05b9f9562a1eb78056406ca47658f3c..b3e147ae90d307349fb5198d877b90d715939b7d 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,5 +1,5 @@ -django-ninja==0.19.1 -Django==4.0.8 +django-ninja==0.22.2 +Django==4.2.3 typing==3.7.4.3 simplejwt==2.0.1 pydantic==1.9.2 @@ -9,7 +9,7 @@ mysqlclient==2.1.1 # sqlserver # mssql-django==1.1.2 # pyodbc==4.0.32 -django-celery-beat==2.3.0 +django-celery-beat==2.5.0 django-celery-results==2.3.1 celery==5.2.7 pypinyin==0.46.0 diff --git a/backend/system/apis/button.py b/backend/system/apis/button.py index f847a44e91c766f655daad2e7a4381aad5335211..06fc21c2c7bdd1e6971ca85f32a15685e6fd923a 100644 --- a/backend/system/apis/button.py +++ b/backend/system/apis/button.py @@ -18,22 +18,22 @@ router = Router() class Filters(Schema): - name: str = Field(None, alias="name") - code: str = Field(None, alias="code") + name: str = Field(None, q="name__contains", alias="name") + code: str = Field(None, q="code__contains", alias="code") id: str = Field(None, alias="id") class SchemaIn(ModelSchema): - class Config: model = Button - model_exclude = ['id', 'create_datetime', 'update_datetime'] + model_exclude = ["id", "create_datetime", "update_datetime"] class SchemaOut(ModelSchema): class Config: model = Button model_fields = "__all__" + # model_fields = [] @@ -76,4 +76,3 @@ def delete_button(request, button_id: int): post = get_object_or_404(Button, id=button_id) post.delete() return {"success": True} - diff --git a/backend/system/apis/code_generator.py b/backend/system/apis/code_generator.py index 423d827c03aeb38e628e153dbdaaafb8763d0806..ed496b4e8e9e9abfd99704b376fc45946a44886f 100644 --- a/backend/system/apis/code_generator.py +++ b/backend/system/apis/code_generator.py @@ -28,7 +28,9 @@ from utils.fu_crud import ( export_data, import_data, retrieve, - update, batch_create, ) + update, + batch_create, +) from utils.fu_ninja import FuFilters, MyPagination from utils.fu_response import FuResponse from utils.usual import insert_content_after_line @@ -37,15 +39,15 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") - code: str = Field(None, alias="code") + name: str = Field(None, q="name__contains", alias="name") + code: str = Field(None, q="code__contains", alias="code") id: str = Field(None, alias="id") class GeneratorTemplateSchemaIn(ModelSchema): class Config: model = GeneratorTemplate - model_fields = ['name', 'code', 'form_info', 'table_info', 'remark'] + model_fields = ["name", "code", "form_info", "table_info", "remark"] class GeneratorTemplateSchemaOut(ModelSchema): @@ -66,8 +68,12 @@ def delete_generator_template(request, generator_template_id: int): return {"success": True} -@router.put("/generator_template/{generator_template_id}", response=GeneratorTemplateSchemaOut) -def update_generator_template(request, generator_template_id: int, data: GeneratorTemplateSchemaIn): +@router.put( + "/generator_template/{generator_template_id}", response=GeneratorTemplateSchemaOut +) +def update_generator_template( + request, generator_template_id: int, data: GeneratorTemplateSchemaIn +): generator_template = update(request, generator_template_id, data, GeneratorTemplate) return generator_template @@ -79,7 +85,9 @@ def list_generator_template(request, filters: Filters = Query(...)): return qs -@router.get("/generator_template/{generator_template_id}", response=GeneratorTemplateSchemaOut) +@router.get( + "/generator_template/{generator_template_id}", response=GeneratorTemplateSchemaOut +) def get_generator_template(request, generator_template_id: int): generator_template = get_object_or_404(GeneratorTemplate, id=generator_template_id) return generator_template @@ -93,14 +101,18 @@ def all_list_generator_template(request): @router.get("/generator_template/all/export") def export_generator_template(request): - export_fields = ['name', 'code', 'status', 'sort'] - return export_data(request, GeneratorTemplate, GeneratorTemplateSchemaOut, export_fields) + export_fields = ["name", "code", "status", "sort"] + return export_data( + request, GeneratorTemplate, GeneratorTemplateSchemaOut, export_fields + ) @router.post("/generator_template/all/import") def import_generator_template(request, data: ImportSchema): - import_fields = ['name', 'code', 'status', 'sort'] - return import_data(request, GeneratorTemplate, GeneratorTemplateSchemaIn, data, import_fields) + import_fields = ["name", "code", "status", "sort"] + return import_data( + request, GeneratorTemplate, GeneratorTemplateSchemaIn, data, import_fields + ) @router.put("/generator_template/code/generate/{generator_template_id}") @@ -111,25 +123,28 @@ def generate_code(request, generator_template_id: int): web_drawer_txt = generator_drawer(instance) web_api_txt = generator_api(instance) web_target_path = os.path.abspath( - os.path.join(os.getcwd(), "..", 'web', 'src', 'views', 'generator', instance.code)) + os.path.join( + os.getcwd(), "..", "web", "src", "views", "generator", instance.code + ) + ) # 判断当前路径是否存在,没有则创建文件夹 if not os.path.exists(web_target_path): os.makedirs(web_target_path) - web_index_path = os.path.join(web_target_path, 'index.vue') - with open(web_index_path, 'w', encoding='utf-8') as file: + web_index_path = os.path.join(web_target_path, "index.vue") + with open(web_index_path, "w", encoding="utf-8") as file: file.write(web_index_txt) - web_data_path = os.path.join(web_target_path, 'data.ts') - with open(web_data_path, 'w', encoding='utf-8') as file: + web_data_path = os.path.join(web_target_path, "data.ts") + with open(web_data_path, "w", encoding="utf-8") as file: file.write(web_data_txt) - web_api_path = os.path.join(web_target_path, 'api.ts') - with open(web_api_path, 'w', encoding='utf-8') as file: + web_api_path = os.path.join(web_target_path, "api.ts") + with open(web_api_path, "w", encoding="utf-8") as file: file.write(web_api_txt) - web_drawer_path = os.path.join(web_target_path, 'drawer.vue') - with open(web_drawer_path, 'w', encoding='utf-8') as file: + web_drawer_path = os.path.join(web_target_path, "drawer.vue") + with open(web_drawer_path, "w", encoding="utf-8") as file: file.write(web_drawer_txt) # 添加列表字段,菜单和菜单按钮 if not instance.has_menu: @@ -146,7 +161,7 @@ def generate_code(request, generator_template_id: int): "component": f"/generator/{instance.code}/index.vue", "name": instance.code, "is_ext": False, - "keepalive": False + "keepalive": False, } menu_qr = create(request, menu_dic, Menu) # 添加菜单按钮 @@ -157,7 +172,7 @@ def generate_code(request, generator_template_id: int): "method": 1, "api": f"/api/generator/{instance.code}", "sort": 1, - "menu_id": menu_qr.id + "menu_id": menu_qr.id, }, { "name": "删除", @@ -165,7 +180,7 @@ def generate_code(request, generator_template_id: int): "method": 3, "api": f"/api/generator/{instance.code}/{instance.code}_id", "sort": 2, - "menu_id": menu_qr.id + "menu_id": menu_qr.id, }, { "name": "修改", @@ -173,7 +188,7 @@ def generate_code(request, generator_template_id: int): "method": 2, "api": f"/api/generator/{instance.code}/{instance.code}_id", "sort": 3, - "menu_id": menu_qr.id + "menu_id": menu_qr.id, }, { "name": "查询", @@ -181,21 +196,23 @@ def generate_code(request, generator_template_id: int): "method": 0, "api": f"/api/generator/{instance.code}", "sort": 4, - "menu_id": menu_qr.id - } + "menu_id": menu_qr.id, + }, ] batch_create(request, button_list, MenuButton) # 添加列表字段 table_info = json.loads(instance.table_info) - column_info = table_info.get('columnInfo') + column_info = table_info.get("columnInfo") column_list = [] for item in column_info: - column_list.append({ - 'code': instance.code + ':' + item['field_name'], - 'name': item['column_name'], - 'menu_id': menu_qr.id, - }) + column_list.append( + { + "code": instance.code + ":" + item["field_name"], + "name": item["column_name"], + "menu_id": menu_qr.id, + } + ) batch_create(request, column_list, MenuColumnField) # 生成后端代码 @@ -204,38 +221,48 @@ def generate_code(request, generator_template_id: int): backend_router_txt = generator_router(instance) # 更新generator router - generator_router_path = os.path.abspath(os.path.join(os.getcwd(), 'generator', 'router.py')) + generator_router_path = os.path.abspath( + os.path.join(os.getcwd(), "generator", "router.py") + ) if not instance.has_menu: - insert_from_txt = f'''from .{instance.code}.api import router as {instance.code}_router''' - insert_content_after_line(generator_router_path, 'from ninja import Router', insert_from_txt) - insert_router_txt = f'''generator_router.add_router('/', {instance.code}_router, tags=['{instance.name}'])''' - insert_content_after_line(generator_router_path, 'generator_router = Router()', insert_router_txt) + insert_from_txt = ( + f"""from .{instance.code}.api import router as {instance.code}_router""" + ) + insert_content_after_line( + generator_router_path, "from ninja import Router", insert_from_txt + ) + insert_router_txt = f"""generator_router.add_router('/', {instance.code}_router, tags=['{instance.name}'])""" + insert_content_after_line( + generator_router_path, "generator_router = Router()", insert_router_txt + ) instance.has_menu = True instance.save() - backend_target_path = os.path.abspath(os.path.join(os.getcwd(), 'generator', instance.code)) + backend_target_path = os.path.abspath( + os.path.join(os.getcwd(), "generator", instance.code) + ) # 判断当前路径是否存在,没有则创建文件夹 if not os.path.exists(backend_target_path): os.makedirs(backend_target_path) - backend_model_path = os.path.join(backend_target_path, 'model.py') - with open(backend_model_path, 'w', encoding='utf-8') as file: + backend_model_path = os.path.join(backend_target_path, "model.py") + with open(backend_model_path, "w", encoding="utf-8") as file: file.write(backend_model_txt) - backend_api_path = os.path.join(backend_target_path, 'api.py') - with open(backend_api_path, 'w', encoding='utf-8') as file: + backend_api_path = os.path.join(backend_target_path, "api.py") + with open(backend_api_path, "w", encoding="utf-8") as file: file.write(backend_api_txt) - backend_router_path = os.path.join(backend_target_path, 'router.py') - with open(backend_router_path, 'w', encoding='utf-8') as file: + backend_router_path = os.path.join(backend_target_path, "router.py") + with open(backend_router_path, "w", encoding="utf-8") as file: file.write(backend_router_txt) - return FuResponse(msg='代码生成成功') + return FuResponse(msg="代码生成成功") @router.put("/generator_template/code/generate_db/{generator_template_id}") def generate_db(request, generator_template_id: int): - management.call_command('makemigrations','generator') - management.call_command('migrate','generator') - return FuResponse(msg='数据库生成成功') + management.call_command("makemigrations", "generator") + management.call_command("migrate", "generator") + return FuResponse(msg="数据库生成成功") diff --git a/backend/system/apis/data_dict/category_dict.py b/backend/system/apis/data_dict/category_dict.py index fbade1538e4e59ac26972d77459ae8c612817010..69e672df7e34184cb6194e3f6b263a4aa18d2c26 100644 --- a/backend/system/apis/data_dict/category_dict.py +++ b/backend/system/apis/data_dict/category_dict.py @@ -21,9 +21,9 @@ router = Router() class Filters(FuFilters): - label: str = Field(None, alias="label") - value: str = Field(None, alias="value") - code: str = Field(None, alias="code") + label: str = Field(None, q="label__contains", alias="label") + value: str = Field(None, q="value__contains", alias="value") + code: str = Field(None, q="code__contains", alias="code") class SchemaIn(ModelSchema): @@ -31,13 +31,14 @@ class SchemaIn(ModelSchema): class Config: model = CategoryDict - model_exclude = ['id', 'parent', 'create_datetime', 'update_datetime'] + model_exclude = ["id", "parent", "create_datetime", "update_datetime"] class SchemaOut(ModelSchema): class Config: model = CategoryDict model_fields = "__all__" + # model_fields = [] diff --git a/backend/system/apis/data_dict/dict.py b/backend/system/apis/data_dict/dict.py index 0405bb6a3c0182d7cfed4b88a7b07c952f39f476..c12b1eb44befad63f8db6610f33d349b7b71c0d9 100644 --- a/backend/system/apis/data_dict/dict.py +++ b/backend/system/apis/data_dict/dict.py @@ -16,7 +16,7 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") + name: str = Field(None, q="name__contains", alias="name") status: bool = Field(None, alias="status") id: str = Field(None, alias="dict_id") @@ -24,13 +24,13 @@ class Filters(FuFilters): class SchemaIn(ModelSchema): class Config: model = Dict - model_fields = ['name', 'code', 'sort', 'status'] + model_fields = ["name", "code", "sort", "status"] class SchemaOut(ModelSchema): class Config: model = Dict - model_fields = ['id', 'name', 'code', 'sort', 'status'] + model_fields = ["id", "name", "code", "sort", "status"] @router.post("/dict", response=SchemaOut) diff --git a/backend/system/apis/data_dict/dict_item.py b/backend/system/apis/data_dict/dict_item.py index 76891a14a30da5ca74255b52da453567bd11c06d..fc82882e4db1fb17c36d6bb7c3247c3bb0a3db4f 100644 --- a/backend/system/apis/data_dict/dict_item.py +++ b/backend/system/apis/data_dict/dict_item.py @@ -16,10 +16,10 @@ router = Router() class Filters(FuFilters): - label: str = Field(None, alias="label") - value: str = Field(None, alias="value") + label: str = Field(None, q="label__contains", alias="label") + value: str = Field(None, q="value__contains", alias="value") + code: str = Field(None, q="code__contains", alias="code") dict_id: str = Field(None, alias="dict_id") - code: str = Field(None, alias="code") status: bool = Field(None, alias="status") @@ -28,13 +28,13 @@ class SchemaIn(ModelSchema): class Config: model = DictItem - model_fields = ['label', 'value', 'sort', 'icon', 'status'] + model_fields = ["label", "value", "sort", "icon", "status"] class SchemaOut(ModelSchema): class Config: model = DictItem - model_fields = ['id', 'label', 'value', 'sort', 'icon', 'status'] + model_fields = ["id", "label", "value", "sort", "icon", "status"] @router.post("/dict_item", response=SchemaOut) diff --git a/backend/system/apis/dept.py b/backend/system/apis/dept.py index 538e2769c7a62f1ac5bb535ce0be2420dcf71ad2..d4ba43ff858fa6afd2ac37adf4b34406e7951711 100644 --- a/backend/system/apis/dept.py +++ b/backend/system/apis/dept.py @@ -21,7 +21,7 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") + name: str = Field(None, q="name__contains", alias="name") status: bool = Field(None, alias="status") id: str = Field(None, alias="id") @@ -31,13 +31,14 @@ class SchemaIn(ModelSchema): class Config: model = Dept - model_exclude = ['id', 'parent', 'create_datetime', 'update_datetime'] + model_exclude = ["id", "parent", "create_datetime", "update_datetime"] class SchemaOut(ModelSchema): class Config: model = Dept model_fields = "__all__" + # model_fields = [] diff --git a/backend/system/apis/file.py b/backend/system/apis/file.py index 53386d5ffa4517a1399f0259033ddcdce2c15020..d45912f11324014b79f135e5b67a6344a68cd66a 100644 --- a/backend/system/apis/file.py +++ b/backend/system/apis/file.py @@ -24,7 +24,7 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") + name: str = Field(None, q="name__contains", alias="name") class SchemaIn(Schema): @@ -66,20 +66,20 @@ def all_list_role(request): @router.post("/upload", response=SchemaOut) def upload(request, file: UploadedFile = NinjaFile(...)): binary_data = file.read() - current_date = datetime.now().strftime('%Y%m%d%H%M%S%f') - current_ymd = datetime.now().strftime('%Y%m%d') - file_name = current_date + '_' + file.name.replace(' ', '_') + current_date = datetime.now().strftime("%Y%m%d%H%M%S%f") + current_ymd = datetime.now().strftime("%Y%m%d") + file_name = current_date + "_" + file.name.replace(" ", "_") file_path = os.path.join(STATIC_URL, current_ymd) if not os.path.exists(file_path): os.makedirs(file_path) file_url = os.path.join(file_path, file_name) - with open(file_url, 'wb') as f: + with open(file_url, "wb") as f: f.write(binary_data) data = { - 'name': file.name, - 'size': file.size, - 'save_name': file_name, - 'url': file_url, + "name": file.name, + "size": file.size, + "save_name": file_name, + "url": file_url, } qs = create(request, data, File) return qs @@ -96,4 +96,6 @@ def create_post(request, data: SchemaIn): def get_file(request, image_id: int): qs = get_object_or_404(File, id=image_id) - return HttpResponse(open(os.path.join(str(BASE_DIR), str(qs.url)), "rb"), content_type='image/png') + return HttpResponse( + open(os.path.join(str(BASE_DIR), str(qs.url)), "rb"), content_type="image/png" + ) diff --git a/backend/system/apis/log/celery_log.py b/backend/system/apis/log/celery_log.py index e234434b85016c7270cdd1d4446e848ab7501ce8..268b2035f025d09d8e824655d709819c6b53f193 100644 --- a/backend/system/apis/log/celery_log.py +++ b/backend/system/apis/log/celery_log.py @@ -15,7 +15,9 @@ router = Router() class Filters(FuFilters): - periodic_task_name: str = Field(None, alias="periodic_task_name") + periodic_task_name: str = Field( + None, q="periodic_task_name__contains", alias="periodic_task_name" + ) class SchemaOut(ModelSchema): diff --git a/backend/system/apis/log/login_log.py b/backend/system/apis/log/login_log.py index 8487d185a14ea39d961b652ae44537bd04a24e7c..546ca36dc0b819ccdd7738e74a92fe65af80b81a 100644 --- a/backend/system/apis/log/login_log.py +++ b/backend/system/apis/log/login_log.py @@ -16,8 +16,8 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") - code: str = Field(None, alias="code") + name: str = Field(None, q="name__contains", alias="name") + code: str = Field(None, q="code__contains", alias="code") id: str = Field(None, alias="login_log_id") diff --git a/backend/system/apis/log/operation_log.py b/backend/system/apis/log/operation_log.py index e1f0fb6e2da8b0bc78b057f9ba24502a5f6c1c17..0c8b9c1aee50f3f7e099280a10e6d1ce2fe89e79 100644 --- a/backend/system/apis/log/operation_log.py +++ b/backend/system/apis/log/operation_log.py @@ -16,7 +16,9 @@ router = Router() class Filters(FuFilters): - request_username: str = Field(None, alias="request_username") + request_username: str = Field( + None, q="request_username__contains", alias="request_username" + ) id: str = Field(None, alias="operation_log_id") diff --git a/backend/system/apis/menu.py b/backend/system/apis/menu.py index 76499ac4399ce879d2aff873adbf0a56b9b51f96..226f5d5366454f2dcacbb34ea74f1ac5ebbb9392 100644 --- a/backend/system/apis/menu.py +++ b/backend/system/apis/menu.py @@ -5,7 +5,7 @@ # @Software: PyCharm # @qq: 939589097 -from typing import List +from typing import List, Optional from django.shortcuts import get_object_or_404 from fuadmin.settings import SECRET_KEY @@ -22,24 +22,25 @@ router = Router() class Filters(FuFilters): - title: str = Field(None, alias="title") + title: str = Field(None, q="title__contains", alias="title") status: bool = Field(None, alias="status") id: str = Field(None, alias="id") class SchemaIn(ModelSchema): parent_id: int = None - component: str = 'LAYOUT' + component: str = "LAYOUT" class Config: model = Menu - model_exclude = ['id', 'parent', 'create_datetime', 'update_datetime'] + model_exclude = ["id", "parent", "create_datetime", "update_datetime"] class SchemaOut(ModelSchema): class Config: model = Menu model_fields = "__all__" + # model_fields = [] @@ -81,11 +82,10 @@ def route_menu_tree(request): token = request.META.get("HTTP_AUTHORIZATION") token = token.split(" ")[1] token_user = FuJwt(SECRET_KEY).decode(SECRET_KEY, token).payload - user = Users.objects.get(id=token_user['id']) + user = Users.objects.get(id=token_user["id"]) queryset = Menu.objects.filter(status=1).values() - if not token_user['is_superuser']: - menuIds = user.role.values_list('menu__id', flat=True) + if not token_user["is_superuser"]: + menuIds = user.role.values_list("menu__id", flat=True) queryset = Menu.objects.filter(id__in=menuIds, status=1).values() menu_tree = list_to_route(list(queryset)) return FuResponse(data=menu_tree) - diff --git a/backend/system/apis/menu_button.py b/backend/system/apis/menu_button.py index 206f83710cf178bf461ef714f4180759f1079112..2a11cc187dbf777db10b8822b97eac790ad113b7 100644 --- a/backend/system/apis/menu_button.py +++ b/backend/system/apis/menu_button.py @@ -18,8 +18,8 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") - code: str = Field(None, alias="code") + name: str = Field(None, q="name__contains", alias="name") + code: str = Field(None, q="code__contains", alias="code") menu_id: str = Field(None, alias="menu_id") @@ -28,13 +28,14 @@ class SchemaIn(ModelSchema): class Config: model = MenuButton - model_exclude = ['id', 'menu', 'create_datetime', 'update_datetime'] + model_exclude = ["id", "menu", "create_datetime", "update_datetime"] class SchemaOut(ModelSchema): class Config: model = MenuButton model_fields = "__all__" + # model_fields = [] diff --git a/backend/system/apis/menu_column.py b/backend/system/apis/menu_column.py index 9d432ac5ef2f79424bd3a60caaa8b2c04920c273..ebf3c673d56b64bb5d14b662b785db12a99565a8 100644 --- a/backend/system/apis/menu_column.py +++ b/backend/system/apis/menu_column.py @@ -19,8 +19,8 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") - code: str = Field(None, alias="code") + name: str = Field(None, q="name__contains", alias="name") + code: str = Field(None, q="code__contains", alias="code") menu_id: str = Field(None, alias="menu_id") @@ -29,7 +29,7 @@ class SchemaIn(ModelSchema): class Config: model = MenuColumnField - model_exclude = ['id', 'menu', 'create_datetime', 'update_datetime'] + model_exclude = ["id", "menu", "create_datetime", "update_datetime"] class BatchSchemaIn(Schema): @@ -40,6 +40,7 @@ class SchemaOut(ModelSchema): class Config: model = MenuColumnField model_fields = "__all__" + # model_fields = [] diff --git a/backend/system/apis/post.py b/backend/system/apis/post.py index 67617ea2f9017dfe7620ac6c6f673e0c34c9c52d..bc743224170bf84e0abc1970c1746d7dec48dac3 100644 --- a/backend/system/apis/post.py +++ b/backend/system/apis/post.py @@ -25,17 +25,16 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") + name: str = Field(None, q="name__contains", alias="name") code: str = Field(None, alias="code") status: int = Field(None, alias="status") - id: str = Field(None, alias="post_id") class PostSchemaIn(ModelSchema): class Config: model = Post - model_fields = ['name', 'code', 'sort', 'status'] + model_fields = ["name", "code", "sort", "status"] class PostSchemaOut(ModelSchema): @@ -83,12 +82,11 @@ def all_list_post(request): @router.get("/post/all/export") def export_post(request): - export_fields = ['name', 'code', 'status', 'sort'] + export_fields = ["name", "code", "status", "sort"] return export_data(request, Post, PostSchemaOut, export_fields) @router.post("/post/all/import") def import_post(request, data: ImportSchema): - import_fields = ['name', 'code', 'status', 'sort'] + import_fields = ["name", "code", "status", "sort"] return import_data(request, Post, PostSchemaIn, data, import_fields) - diff --git a/backend/system/apis/role.py b/backend/system/apis/role.py index 95dc754d34c440330f7f31c5538e7848c85052aa..933cd6f5c06f45f2df8913434dd955222c77f868 100644 --- a/backend/system/apis/role.py +++ b/backend/system/apis/role.py @@ -21,7 +21,7 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") + name: str = Field(None, q="name__contains", alias="name") status: bool = Field(None, alias="status") id: str = Field(None, alias="id") @@ -34,23 +34,32 @@ class SchemaIn(ModelSchema): class Config: model = Role - model_exclude = ['id', 'dept', 'menu', 'permission', 'column', 'create_datetime', 'update_datetime'] + model_exclude = [ + "id", + "dept", + "menu", + "permission", + "column", + "create_datetime", + "update_datetime", + ] class SchemaOut(ModelSchema): class Config: model = Role model_fields = "__all__" + # model_fields = [] @router.post("/role", response=SchemaOut) def create_role(request, data: SchemaIn): dict_data = data.dict() - del dict_data['menu'] - del dict_data['permission'] - del dict_data['dept'] - del dict_data['column'] + del dict_data["menu"] + del dict_data["permission"] + del dict_data["dept"] + del dict_data["column"] role = create(request, dict_data, Role) return role @@ -66,13 +75,13 @@ def delete_role(request, role_id: int): def update_role(request, role_id: int, payload: SchemaIn): post = get_object_or_404(Role, id=role_id) for attr, value in payload.dict().items(): - if attr == 'menu': + if attr == "menu": post.menu.set(value) - elif attr == 'permission': + elif attr == "permission": post.permission.set(value) - elif attr == 'dept': + elif attr == "dept": post.dept.set(value) - elif attr == 'column': + elif attr == "column": post.column.set(value) else: setattr(post, attr, value) @@ -114,15 +123,15 @@ def list_menu_button_tree(request, filters: ButtonColumnFilters = Query(...)): menu_button = list(item.menuPermission.all().values()) for button_item in menu_button: - button_item['id'] = f"b{button_item['id']}" - button_item['parent_id'] = button_item.pop('menu_id') - button_item['title'] = button_item.pop('name') + button_item["id"] = f"b{button_item['id']}" + button_item["parent_id"] = button_item.pop("menu_id") + button_item["title"] = button_item.pop("name") # dict_item['menu_button'] = list(item.menuPermission.all().values()) - del dict_item['_state'] + del dict_item["_state"] result.extend(menu_button) result.append(dict_item) - return get_button_or_column_menu(result, 'b') + return get_button_or_column_menu(result, "b") @router.get("/role/list/menu_column") @@ -133,15 +142,15 @@ def list_menu_button_tree(request, filters: ButtonColumnFilters = Query(...)): dict_item = item.__dict__ column_field = list(item.menuColumnField.all().values()) for column_field_item in column_field: - column_field_item['id'] = f"c{column_field_item['id']}" - column_field_item['parent_id'] = column_field_item.pop('menu_id') - column_field_item['title'] = column_field_item.pop('name') + column_field_item["id"] = f"c{column_field_item['id']}" + column_field_item["parent_id"] = column_field_item.pop("menu_id") + column_field_item["title"] = column_field_item.pop("name") - del dict_item['_state'] + del dict_item["_state"] result.append(dict_item) result.extend(column_field) - return get_button_or_column_menu(result, 'c') + return get_button_or_column_menu(result, "c") class SchemaMenuOut(ModelSchema): @@ -175,17 +184,17 @@ def list_menu_tree(request, filters: Filters = Query(...)): def get_button_or_column_menu(data, flag): return_data = [] for i in data: - m_id = i['id'] + m_id = i["id"] if flag in str(m_id): return_data.append(i) - get_menu_by_parent(i['parent_id'], data, return_data) + get_menu_by_parent(i["parent_id"], data, return_data) return return_data def get_menu_by_parent(parent_id, data, return_data): for i in data: - if parent_id == i['id'] and i not in return_data: + if parent_id == i["id"] and i not in return_data: return_data.append(i) - get_menu_by_parent(i['parent_id'], data, return_data) + get_menu_by_parent(i["parent_id"], data, return_data) if parent_id is None: return diff --git a/backend/system/apis/user.py b/backend/system/apis/user.py index 0f6688c5dab52e8bded50c4056bbefdcd31219a7..ccd387ff6472a47576b41db9d18c0c77b95a4ca8 100644 --- a/backend/system/apis/user.py +++ b/backend/system/apis/user.py @@ -22,8 +22,8 @@ router = Router() class Filters(FuFilters): - name: str = Field(None, alias="name") - mobile: str = Field(None, alias="mobile") + name: str = Field(None, q="name__contains", alias="name") + mobile: str = Field(None, q="mobile__contains", alias="mobile") status: bool = Field(None, alias="status") dept_id__in: list = Field(None, alias="dept_ids[]") id: int = Field(None, alias="id") @@ -36,22 +36,32 @@ class SchemaIn(ModelSchema): class Config: model = Users - model_exclude = ['id', 'groups', 'user_permissions', 'is_superuser', 'dept', 'post', 'role', 'password', - 'create_datetime', 'update_datetime'] + model_exclude = [ + "id", + "groups", + "user_permissions", + "is_superuser", + "dept", + "post", + "role", + "password", + "create_datetime", + "update_datetime", + ] class SchemaOut(ModelSchema): class Config: model = Users - model_exclude = ['password'] + model_exclude = ["password"] @router.post("/user", response=SchemaOut) def create_user(request, data: SchemaIn): data_dic = data.dict() - data_dic['password'] = make_password('123456') - post = data_dic.pop('post') - role = data_dic.pop('role') + data_dic["password"] = make_password("123456") + post = data_dic.pop("post") + role = data_dic.pop("role") user = create(request, data_dic, Users) # 为多对多关系添加数据 user.post.set(post) @@ -69,9 +79,9 @@ def delete_user(request, user_id: int): def update_user(request, user_id: int, payload: SchemaIn): user = get_object_or_404(Users, id=user_id) for attr, value in payload.dict().items(): - if attr == 'role': + if attr == "role": user.role.set(value) - elif attr == 'post': + elif attr == "post": user.post.set(value) else: setattr(user, attr, value) @@ -106,20 +116,20 @@ class SchemaIn(Schema): @router.post("/user/set/repassword", response=SchemaOut) def repassword(request, data: SchemaIn): request_user = get_user_info_from_token(request) - request_user_id = request_user['id'] + request_user_id = request_user["id"] update_id = data.id if request_user_id == update_id: user = get_object_or_404(Users, id=update_id) user.set_password(data.password) user.save() - return FuResponse(msg='密码修改成功') + return FuResponse(msg="密码修改成功") else: - return FuResponse(code=403, msg='对不起, 只能修改自己的密码') + return FuResponse(code=403, msg="对不起, 只能修改自己的密码") @router.put("/user/reset/password/{id}", response=SchemaOut) -def reset_password(request, id:int): +def reset_password(request, id: int): user = get_object_or_404(Users, id=id) - user.set_password('123456') + user.set_password("123456") user.save() - return FuResponse(msg='密码重置成功') + return FuResponse(msg="密码重置成功") diff --git a/backend/utils/fu_crud.py b/backend/utils/fu_crud.py index db10660f8e63d342ffa271e4e5520d38567fe588..aed4caf9f97de6a338c8df30101fd183e428331d 100644 --- a/backend/utils/fu_crud.py +++ b/backend/utils/fu_crud.py @@ -73,14 +73,13 @@ def update(request, id, data, model): def retrieve(request, model, filters: FuFilters = FuFilters()): filters = data_permission(request, filters) + query_set = model.objects.all() if filters is not None: # 将filters空字符串转换为None for attr, value in filters.__dict__.items(): - if getattr(filters, attr) == '': + if getattr(filters, attr) == "": setattr(filters, attr, None) - query_set = model.objects.filter(**filters.dict(exclude_none=True)) - else: - query_set = model.objects.all() + query_set = filters.filter(query_set) return query_set diff --git a/backend/utils/fu_ninja.py b/backend/utils/fu_ninja.py index 36b54a6d8161bd6db5f3284828efcf63a15d1b53..973bbad3054cab160563bc59ab48c1462f187120 100644 --- a/backend/utils/fu_ninja.py +++ b/backend/utils/fu_ninja.py @@ -7,7 +7,7 @@ from typing import Any, List from django.db.models import QuerySet from django.http import HttpRequest, HttpResponse -from ninja import Field, ModelSchema, NinjaAPI, Query, Router, Schema +from ninja import FilterSchema, Field, ModelSchema, NinjaAPI, Query, Router, Schema from ninja.orm.metaclass import ModelSchemaMetaclass from ninja.pagination import PaginationBase from ninja.types import DictStrAny @@ -60,7 +60,7 @@ class MyPagination(PaginationBase): } # noqa: E203 -class FuFilters(Schema): +class FuFilters(FilterSchema): creator_id: int = Field(None, alias="creator_id") belong_dept: int = Field(None, alias="belong_dept") belong_dept__in: List[int] = Field(None, alias="belong_dept__in") \ No newline at end of file