flower 2 месяцев назад
Сommit
70017b2672
100 измененных файлов с 8859 добавлено и 0 удалено
  1. 3 0
      .idea/.gitignore
  2. 14 0
      .idea/goods_wms.iml
  3. 6 0
      .idea/inspectionProfiles/profiles_settings.xml
  4. 7 0
      .idea/misc.xml
  5. 8 0
      .idea/modules.xml
  6. 6 0
      .idea/vcs.xml
  7. 201 0
      LICENSE
  8. 5 0
      backend_start.sh
  9. 190 0
      data_base/flow.csv
  10. 74 0
      data_base/import_data.py
  11. BIN
      db.sqlite3
  12. 67 0
      greaterwms/__init__.py
  13. BIN
      greaterwms/__pycache__/__init__.cpython-310.pyc
  14. BIN
      greaterwms/__pycache__/asgi.cpython-310.pyc
  15. BIN
      greaterwms/__pycache__/settings.cpython-310.pyc
  16. BIN
      greaterwms/__pycache__/urls.cpython-310.pyc
  17. BIN
      greaterwms/__pycache__/views.cpython-310.pyc
  18. 19 0
      greaterwms/asgi.py
  19. 338 0
      greaterwms/settings.py
  20. 36 0
      greaterwms/urls.py
  21. 56 0
      greaterwms/views.py
  22. 16 0
      greaterwms/wsgi.py
  23. 3160 0
      logs/error.log
  24. 3496 0
      logs/server.log
  25. 22 0
      manage.py
  26. 0 0
      media/__init__.py
  27. BIN
      media/upload_example/customer_cn.xlsx
  28. BIN
      media/upload_example/customer_en.xlsx
  29. BIN
      media/upload_example/goodslist_cn.xlsx
  30. BIN
      media/upload_example/goodslist_en.xlsx
  31. BIN
      media/upload_example/supplier_cn.xlsx
  32. BIN
      media/upload_example/supplier_en.xlsx
  33. 97 0
      nginx.conf
  34. 0 0
      reportcenter/__init__.py
  35. BIN
      reportcenter/__pycache__/__init__.cpython-310.pyc
  36. BIN
      reportcenter/__pycache__/admin.cpython-310.pyc
  37. BIN
      reportcenter/__pycache__/apps.cpython-310.pyc
  38. BIN
      reportcenter/__pycache__/files.cpython-310.pyc
  39. BIN
      reportcenter/__pycache__/filter.cpython-310.pyc
  40. BIN
      reportcenter/__pycache__/models.cpython-310.pyc
  41. BIN
      reportcenter/__pycache__/serializers.cpython-310.pyc
  42. BIN
      reportcenter/__pycache__/urls.cpython-310.pyc
  43. BIN
      reportcenter/__pycache__/views.cpython-310.pyc
  44. 3 0
      reportcenter/admin.py
  45. 6 0
      reportcenter/apps.py
  46. 54 0
      reportcenter/files.py
  47. 26 0
      reportcenter/filter.py
  48. 49 0
      reportcenter/migrations/0001_initial.py
  49. 0 0
      reportcenter/migrations/__init__.py
  50. BIN
      reportcenter/migrations/__pycache__/0001_initial.cpython-310.pyc
  51. BIN
      reportcenter/migrations/__pycache__/0002_alter_flowmodel_goods_in_alter_flowmodel_goods_notes_and_more.cpython-310.pyc
  52. BIN
      reportcenter/migrations/__pycache__/0002_flowmodel_goods_unit.cpython-310.pyc
  53. BIN
      reportcenter/migrations/__pycache__/__init__.cpython-310.pyc
  54. 46 0
      reportcenter/models.py
  55. 9 0
      reportcenter/serializers.py
  56. 3 0
      reportcenter/tests.py
  57. 7 0
      reportcenter/urls.py
  58. 125 0
      reportcenter/views.py
  59. 52 0
      requirements.txt
  60. 0 0
      staff/__init__.py
  61. BIN
      staff/__pycache__/__init__.cpython-310.pyc
  62. BIN
      staff/__pycache__/admin.cpython-310.pyc
  63. BIN
      staff/__pycache__/apps.cpython-310.pyc
  64. BIN
      staff/__pycache__/files.cpython-310.pyc
  65. BIN
      staff/__pycache__/filter.cpython-310.pyc
  66. BIN
      staff/__pycache__/models.cpython-310.pyc
  67. BIN
      staff/__pycache__/serializers.cpython-310.pyc
  68. BIN
      staff/__pycache__/urls.cpython-310.pyc
  69. BIN
      staff/__pycache__/views.cpython-310.pyc
  70. 4 0
      staff/admin.py
  71. 43 0
      staff/apps.py
  72. 33 0
      staff/files.py
  73. 24 0
      staff/filter.py
  74. 52 0
      staff/migrations/0001_initial.py
  75. 18 0
      staff/migrations/0002_listmodel_is_look.py
  76. 18 0
      staff/migrations/0003_listmodel_appid.py
  77. 18 0
      staff/migrations/0004_alter_listmodel_appid.py
  78. 18 0
      staff/migrations/0005_listmodel_is_edit.py
  79. 0 0
      staff/migrations/__init__.py
  80. BIN
      staff/migrations/__pycache__/0001_initial.cpython-310.pyc
  81. BIN
      staff/migrations/__pycache__/0002_listmodel_is_look.cpython-310.pyc
  82. BIN
      staff/migrations/__pycache__/0003_listmodel_appid.cpython-310.pyc
  83. BIN
      staff/migrations/__pycache__/0004_alter_listmodel_appid.cpython-310.pyc
  84. BIN
      staff/migrations/__pycache__/0005_listmodel_is_edit.cpython-310.pyc
  85. BIN
      staff/migrations/__pycache__/__init__.cpython-310.pyc
  86. 33 0
      staff/models.py
  87. 122 0
      staff/serializers.py
  88. 0 0
      staff/tests.py
  89. 14 0
      staff/urls.py
  90. 261 0
      staff/views.py
  91. 0 0
      static/__init__.py
  92. BIN
      static/img/GreaterWMS.png
  93. BIN
      static/img/GreaterWMS_en.png
  94. BIN
      static/img/Katie.jpg
  95. BIN
      static/img/alipay.jpg
  96. BIN
      static/img/contact.png
  97. BIN
      static/img/dongtai.png
  98. BIN
      static/img/dongtai1.png
  99. BIN
      static/img/github.png
  100. 0 0
      static/img/logo.png

+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml

+ 14 - 0
.idea/goods_wms.iml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.venv" />
+    </content>
+    <orderEntry type="jdk" jdkName="Python 3.10 (goods_wms)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+  <component name="PyDocumentationSettings">
+    <option name="format" value="GOOGLE" />
+    <option name="myDocStringFormat" value="Google" />
+  </component>
+</module>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Black">
+    <option name="sdkName" value="Python 3.10 (goods_wms)" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (goods_wms)" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/goods_wms.iml" filepath="$PROJECT_DIR$/.idea/goods_wms.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>

+ 201 - 0
LICENSE

@@ -0,0 +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.

+ 5 - 0
backend_start.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+python3 manage.py makemigrations
+python3 manage.py migrate
+
+daphne  -p 8008 greaterwms.asgi:application

+ 190 - 0
data_base/flow.csv

@@ -0,0 +1,190 @@
+id,document_date,document_number,document_type,business_type,iout_type,department,warehouse_code,warehouse_name,goods_code,goods_desc,goods_std,goods_batch,in_batch,out_batch,goods_unit,goods_in,goods_out,goods_notes,creator
+1,2024-10-04,MD-2024-10-0009,材料出库单,直接领料,材料出库,四车间(槲皮素),1,内包装物库,B000093,普通PE袋(B0408),62*110,\,,,个,,490,盘点出库,洪敏
+2,2024-10-04,MD-2024-10-0009,材料出库单,直接领料,材料出库,四车间(槲皮素),2,内包装物库,B000105,药用低密度聚乙烯袋(B0304),80*120*0.10,\,,,条,,280,盘点出库,洪敏
+3,2024-10-04,MD-2024-10-0009,材料出库单,直接领料,材料出库,四车间(槲皮素),3,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,1.6,盘点出库,洪敏
+4,2024-10-04,MD-2024-10-0021,材料出库单,直接领料,材料出库,设备动力部,4,备品配件库,P070100207,工作服,冬季,,,,个,,1,维修班张林劳保领用,孙怀其
+5,2024-10-04,MD-2024-10-0022,材料出库单,直接领料,材料出库,五车间(柚苷水解物),5,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,1,,袁涛
+6,2024-10-04,MD-2024-10-0022,材料出库单,直接领料,材料出库,五车间(柚苷水解物),6,内包装物库,B000093,普通PE袋(B0408),62*110,B0408-240801,,,个,,300,,袁涛
+7,2024-10-04,MD-2024-10-0024,材料出库单,直接领料,材料出库,三车间,7,备品配件库,P071000004,胶鞋,3537,,,,个,,1,,余波
+8,2024-10-04,MD-2024-10-0025,材料出库单,直接领料,材料出库,三车间-制粒,8,成品库,B000332,二水槲皮素(QAF03),标准三,QAF03-2409008,,,kg,,599,,余波
+9,2024-10-04,MD-2024-10-0025,材料出库单,直接领料,材料出库,三车间-制粒,9,成品库,B000332,二水槲皮素(QAF03),标准三,QAF03-2409013,,,kg,,425,,余波
+10,2024-10-04,MD-2024-10-0026,材料出库单,直接领料,材料出库,三车间-制粒,10,成品库,B000332,二水槲皮素(QAF03),标准三,QAF03-2409013,,,kg,,575,,余波
+11,2024-10-04,MD-2024-10-0027,材料出库单,直接领料,材料出库,三车间,11,备品配件库,P071000005,白帽子,松紧带,,,,个,,1,制粒车间高虎龙领用,余波
+12,2024-10-04,MD-2024-10-0028,材料出库单,直接领料,材料出库,三车间-制粒,12,成品库,B000332,二水槲皮素(QAF03),标准三,QAF03-2409008,,,kg,,401,,余波
+13,2024-10-04,MD-2024-10-0029,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,13,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240813,,,kg,,296,,余波
+14,2024-10-04,MD-2024-10-0029,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,14,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240902,,,kg,,141,,余波
+15,2024-10-04,MD-2024-10-0029,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,15,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240813,,,kg,,275,,余波
+16,2024-10-04,MD-2024-10-0029,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,16,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240902,,,kg,,162,,余波
+17,2024-10-04,MD-2024-10-0030,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,17,成品库,B000286,黄连素(BAF01),标1,BAF01-2212001,,,kg,,12,,余波
+18,2024-10-04,MD-2024-10-0030,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,18,成品库,B000286,黄连素(BAF01),标1,BAF01-2212001,,,kg,,12,,余波
+19,2024-10-04,MD-2024-10-0033,材料出库单,直接领料,材料出库,五车间(NHDC),19,外包装物库,BBW0008,双瓦楞纸箱(B1201),550*370*350,B1201-240901,,,个,,40,,袁涛
+20,2024-10-04,MD-2024-10-0034,材料出库单,直接领料,材料出库,五车间(NHDC),20,内包装物库,BBW0004,防伪扎带,330MM,B0900-240901,,,根,,40,,袁涛
+21,2024-10-04,MD-2024-10-0034,材料出库单,直接领料,材料出库,五车间(NHDC),21,内包装物库,B000129,胶带,,/,,,卷,,5,,袁涛
+22,2024-10-04,MD-2024-10-0034,材料出库单,直接领料,材料出库,五车间(NHDC),22,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,1,,袁涛
+23,2024-10-04,MD-2024-10-0051,材料出库单,直接领料,材料出库,五车间(NHDC),23,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409069,,,kg,,22.52,,袁涛
+24,2024-10-04,MD-2024-10-0051,材料出库单,直接领料,材料出库,五车间(NHDC),24,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409070,,,kg,,143,,袁涛
+25,2024-10-04,MD-2024-10-0051,材料出库单,直接领料,材料出库,五车间(NHDC),25,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409071,,,kg,,14.48,,袁涛
+26,2024-10-04,MD-2024-10-0052,材料出库单,直接领料,材料出库,五车间(NHDC),26,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409071,,,kg,,128.52,,袁涛
+27,2024-10-04,MD-2024-10-0052,材料出库单,直接领料,材料出库,五车间(NHDC),27,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409072,,,kg,,51.48,,袁涛
+28,2024-10-04,MD-2024-10-0052,材料出库单,直接领料,材料出库,五车间(NHDC),28,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409072,,,kg,,91.52,,袁涛
+29,2024-10-04,MD-2024-10-0052,材料出库单,直接领料,材料出库,五车间(NHDC),29,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409073,,,kg,,88.48,,袁涛
+30,2024-10-04,MD-2024-10-0063,材料出库单,直接领料,材料出库,四车间(槲皮素),30,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240938,,,kg,,1000,领出过筛,洪敏
+31,2024-10-04,MD-2024-10-0063,材料出库单,直接领料,材料出库,四车间(槲皮素),31,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240939,,,kg,,1000,领出过筛,洪敏
+32,2024-10-04,MC-2024-10-0002,产成品入库单,自制加工,自制产品入库,四车间(槲皮素),32,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240938,,,kg,1000,,过筛入库,洪敏
+33,2024-10-04,MC-2024-10-0002,产成品入库单,自制加工,自制产品入库,四车间(槲皮素),33,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240939,,,kg,1000,,过筛入库,洪敏
+34,2024-10-05,MD-2024-10-0017,材料出库单,直接领料,材料出库,四车间(槲皮素),34,备品配件库,P071200009,胶扫把,,,,,把,,12,,洪敏
+35,2024-10-05,MD-2024-10-0017,材料出库单,直接领料,材料出库,四车间(槲皮素),35,备品配件库,P071200187,塑料撮箕,,,,,个,,6,,洪敏
+36,2024-10-05,MD-2024-10-0036,材料出库单,直接领料,材料出库,五车间(NHDC),36,内包装物库,B000093,普通PE袋(B0408),62*110,B0408-240801,,,个,,300,,袁涛
+37,2024-10-05,MD-2024-10-0038,材料出库单,直接领料,材料出库,三车间-经营产品,37,内包装物库,BBW0004,防伪扎带,330MM,B0900-240501,,,根,,200,,余波
+38,2024-10-05,MD-2024-10-0041,材料出库单,直接领料,材料出库,四车间(槲皮素),38,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,1,,洪敏
+39,2024-10-05,MD-2024-10-0043,材料出库单,直接领料,材料出库,三车间-制粒,39,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240902,,,个,,16,,余波
+40,2024-10-05,MD-2024-10-0044,材料出库单,直接领料,材料出库,三车间-灭菌,40,原材料库,B000020,枳实粉(Y1001),内控标准一,Y1001-240102,,,kg,,998,,余波
+41,2024-10-05,MD-2024-10-0045,材料出库单,直接领料,材料出库,三车间-灭菌,41,成品库,BKZ0045,枳实黄酮CAF02(>25%),CAF02,>25%,CAF02-2311001,,kg,,17,,余波
+42,2024-10-05,MD-2024-10-0046,材料出库单,直接领料,材料出库,三车间-灭菌,42,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240902,,,个,,40,,余波
+43,2024-10-05,MD-2024-10-0048,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,43,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240902,,,kg,,437,,余波
+44,2024-10-05,MD-2024-10-0048,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,44,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240902,,,kg,,260,,余波
+45,2024-10-05,MD-2024-10-0048,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,45,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240903,,,kg,,177,,余波
+46,2024-10-05,MD-2024-10-0049,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,46,成品库,B000286,黄连素(BAF01),标1,BAF01-2212001,,,kg,,12,,余波
+47,2024-10-05,MD-2024-10-0049,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,47,成品库,B000286,黄连素(BAF01),标1,BAF01-2212001,,,kg,,12,,余波
+48,2024-10-05,MD-2024-10-0053,材料出库单,直接领料,材料出库,五车间(NHDC),48,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409073,,,kg,,54.52,,袁涛
+49,2024-10-05,MD-2024-10-0053,材料出库单,直接领料,材料出库,五车间(NHDC),49,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409074,,,kg,,125.48,,袁涛
+50,2024-10-05,MD-2024-10-0053,材料出库单,直接领料,材料出库,五车间(NHDC),50,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409074,,,kg,,24.52,,袁涛
+51,2024-10-05,MD-2024-10-0053,材料出库单,直接领料,材料出库,五车间(NHDC),51,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409075,,,kg,,150,,袁涛
+52,2024-10-05,MD-2024-10-0053,材料出库单,直接领料,材料出库,五车间(NHDC),52,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409076,,,kg,,5.48,,袁涛
+53,2024-10-05,MD-2024-10-0054,材料出库单,直接领料,材料出库,五车间(NHDC),53,备品配件库,P071000004,胶鞋,3537,,,,个,,1,李昊鲒领用,袁涛
+54,2024-10-05,MD-2024-10-0054,材料出库单,直接领料,材料出库,五车间(NHDC),54,备品配件库,P070100207,工作服,冬季,,,,个,,1,李昊鲒领用,袁涛
+55,2024-10-05,MD-2024-10-0055,材料出库单,直接领料,材料出库,五车间(NHDC),55,备品配件库,P070100207,工作服,冬季,,,,个,,1,骆序国领用,袁涛
+56,2024-10-05,MD-2024-10-0056,材料出库单,直接领料,材料出库,五车间(NHDC),56,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409076,,,kg,,150.32,,袁涛
+57,2024-10-05,MD-2024-10-0056,材料出库单,直接领料,材料出库,五车间(NHDC),57,半成品库,BNZ0004,柚苷水解物(NZF02),标准二,NZF02-2409077,,,kg,,29.68,,袁涛
+58,2024-10-05,MD-2024-10-0064,材料出库单,直接领料,材料出库,四车间(槲皮素),58,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240938,,,kg,,700,生产所需,特殊出库,洪敏
+59,2024-10-05,MD-2024-10-0064,材料出库单,直接领料,材料出库,四车间(槲皮素),59,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240938,,,kg,,300,生产所需,特殊出库,洪敏
+60,2024-10-05,MD-2024-10-0064,材料出库单,直接领料,材料出库,四车间(槲皮素),60,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240939,,,kg,,400,生产所需,特殊出库,洪敏
+61,2024-10-06,MD-2024-10-0001,材料出库单,直接领料,材料出库,一车间,61,原材料库,B000011,橙皮苷(Y0704),内控标准四,Y0704-240502,,,kg,,425,月初领用,谭世燕
+62,2024-10-06,MD-2024-10-0001,材料出库单,直接领料,材料出库,一车间,62,原材料库,B000011,橙皮苷(Y0704),内控标准四,Y0704-240504,,,kg,,75,月初领用,谭世燕
+63,2024-10-06,MD-2024-10-0012,材料出库单,直接领料,材料出库,四车间(槲皮素),63,内包装物库,BBW0004,防伪扎带,330MM,B0900-240901,,,根,,40,,洪敏
+64,2024-10-06,MD-2024-10-0012,材料出库单,直接领料,材料出库,四车间(槲皮素),64,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,1,,洪敏
+65,2024-10-06,MD-2024-10-0012,材料出库单,直接领料,材料出库,四车间(槲皮素),65,内包装物库,B000105,药用低密度聚乙烯袋(B0304),80*120*0.10,B0304-240801,,,条,,240,,洪敏
+66,2024-10-06,MD-2024-10-0013,材料出库单,直接领料,材料出库,四车间(槲皮素),66,外包装物库,B000088,防潮纸桶(B0110),450*650,B0110-240701,,,个,,40,,洪敏
+67,2024-10-06,MD-2024-10-0059,材料出库单,直接领料,材料出库,设备动力部,67,备品配件库,P070700290,三相插头,220V 10A,,,,个,,1,更换维修班电焊机插头,孙怀其
+68,2024-10-06,MD-2024-10-0061,材料出库单,直接领料,材料出库,五车间(柚苷水解物),68,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,1,,袁涛
+69,2024-10-06,MD-2024-10-0061,材料出库单,直接领料,材料出库,五车间(柚苷水解物),69,内包装物库,B000093,普通PE袋(B0408),62*110,B0408-240801,,,个,,300,,袁涛
+70,2024-10-06,MD-2024-10-0065,材料出库单,直接领料,材料出库,四车间(槲皮素),70,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240909,,,kg,,600,生产所需,特殊出库,洪敏
+71,2024-10-06,MD-2024-10-0065,材料出库单,直接领料,材料出库,四车间(槲皮素),71,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240910,,,kg,,100,生产所需,特殊出库,洪敏
+72,2024-10-06,MD-2024-10-0065,材料出库单,直接领料,材料出库,四车间(槲皮素),72,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240910,,,kg,,700,生产所需,特殊出库,洪敏
+73,2024-10-06,MD-2024-10-0066,材料出库单,直接领料,材料出库,四车间(槲皮素),73,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240910,,,kg,,200,生产所需,特殊出库,洪敏
+74,2024-10-06,MD-2024-10-0066,材料出库单,直接领料,材料出库,四车间(槲皮素),74,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240935,,,kg,,500,生产所需,特殊出库,洪敏
+75,2024-10-06,MD-2024-10-0066,材料出库单,直接领料,材料出库,四车间(槲皮素),75,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240935,,,kg,,500,生产所需,特殊出库,洪敏
+76,2024-10-06,MD-2024-10-0066,材料出库单,直接领料,材料出库,四车间(槲皮素),76,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240936,,,kg,,200,生产所需,特殊出库,洪敏
+77,2024-10-06,MD-2024-10-0068,材料出库单,直接领料,材料出库,三车间-经营产品,77,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,2,,余波
+78,2024-10-06,MD-2024-10-0069,材料出库单,直接领料,材料出库,三车间-制粒,78,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240902,,,个,,40,,余波
+79,2024-10-06,MD-2024-10-0069,材料出库单,直接领料,材料出库,三车间-制粒,79,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240902,,,个,,23,,余波
+80,2024-10-06,MD-2024-10-0071,材料出库单,直接领料,材料出库,五车间(NHDC),80,备品配件库,P120009,洁净拖帕替换布,40CM,,,,张,,3,,袁涛
+81,2024-10-07,MD-2024-10-0014,材料出库单,直接领料,材料出库,四车间(槲皮素),81,外包装物库,B000088,防潮纸桶(B0110),450*650,B0110-240701,,,个,,40,,洪敏
+82,2024-10-07,MD-2024-10-0015,材料出库单,直接领料,材料出库,四车间(槲皮素),82,内包装物库,BBW0004,防伪扎带,330MM,B0900-240901,,,根,,40,,洪敏
+83,2024-10-07,MD-2024-10-0067,材料出库单,直接领料,材料出库,四车间(槲皮素),83,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240936,,,kg,,700,生产所需,特殊出库,洪敏
+84,2024-10-07,MD-2024-10-0067,材料出库单,直接领料,材料出库,四车间(槲皮素),84,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240936,,,kg,,100,生产所需,特殊出库,洪敏
+85,2024-10-07,MD-2024-10-0067,材料出库单,直接领料,材料出库,四车间(槲皮素),85,原材料库,B000004,芦丁(Y0104),标准四,Y0104-240939,,,kg,,600,生产所需,特殊出库,洪敏
+86,2024-10-07,MD-2024-10-0073,材料出库单,直接领料,材料出库,设备动力部,86,备品配件库,P070100207,工作服,冬季,,,,个,,1,维修班李玉科劳保领用,孙怀其
+87,2024-10-07,MD-2024-10-0074,材料出库单,直接领料,材料出库,四车间(槲皮素),87,备品配件库,P071100273,洁净拖把,,,,,把,,2,,洪敏
+88,2024-10-07,MD-2024-10-0074,材料出库单,直接领料,材料出库,四车间(槲皮素),88,备品配件库,P120009,洁净拖帕替换布,40CM,,,,张,,2,,洪敏
+89,2024-10-07,MD-2024-10-0074,材料出库单,直接领料,材料出库,四车间(槲皮素),89,备品配件库,P120209,排拖,60cm,,,,把,,2,,洪敏
+90,2024-10-07,MD-2024-10-0075,材料出库单,直接领料,材料出库,四车间(槲皮素),90,内包装物库,B000130,扎带(B0600),5*200mm   500根/包,,,,包,,2,,洪敏
+91,2024-10-07,MD-2024-10-0076,材料出库单,直接领料,材料出库,一车间,91,备品配件库,P090129,机械密封,108U-50,,,,套,,1,一车间洁净区板框过滤泵机械密封更换,孙怀其
+92,2024-10-07,MD-2024-10-0077,材料出库单,直接领料,材料出库,五车间,92,备品配件安全库存库房,A14020003,机械密封,"112-35  ,耐溶剂",,,,个,,1,更换五车间打液泵机械密封,孙怀其
+93,2024-10-07,MD-2024-10-0078,材料出库单,直接领料,材料出库,一车间,93,备品配件安全库存库房,A14010037,不锈钢卡盘硅胶垫,∮57-∮63,,,,个,,4,一车间管道改造用,孙怀其
+94,2024-10-07,MD-2024-10-0078,材料出库单,直接领料,材料出库,一车间,94,备品配件库,P070200138,卡盘,∮63,,,,个,,4,一车间管道改造用,孙怀其
+95,2024-10-07,MD-2024-10-0078,材料出库单,直接领料,材料出库,一车间,95,备品配件库,P070200290,卡箍,∮57-63,,,,个,,4,一车间管道改造用,孙怀其
+96,2024-10-07,MD-2024-10-0079,材料出库单,直接领料,材料出库,设备动力部,96,备品配件库,P071000004,胶鞋,3537,,,,个,,1,维修班蒋代川劳保领用,孙怀其
+97,2024-10-07,MD-2024-10-0084,材料出库单,直接领料,材料出库,四车间(槲皮素),97,备品配件安全库存库房,A14050009,PP折叠滤芯,20寸 1um 226接口,,,,支,,14,,洪敏
+98,2024-10-07,MD-2024-10-0084,材料出库单,直接领料,材料出库,四车间(槲皮素),98,备品配件安全库存库房,A14050008,PP折叠滤芯,20寸 0.45um 226接口,,,,支,,5,,洪敏
+99,2024-10-07,MD-2024-10-0086,材料出库单,直接领料,材料出库,三车间,99,内包装物库,B000103,药用低密度聚乙烯袋(B0302),80*110*0.06,B0302-240801,,,条,,240,,余波
+100,2024-10-07,MD-2024-10-0086,材料出库单,直接领料,材料出库,三车间,100,内包装物库,B000102,药用低密度聚乙烯袋(B0301),62*110*0.06,B0301-240801,,,条,,300,,余波
+101,2024-10-07,MD-2024-10-0090,材料出库单,直接领料,材料出库,一车间,101,原材料库,B000011,橙皮苷(Y0704),内控标准四,Y0704-240504,,,kg,,925,生产需要,谭世燕
+102,2024-10-07,MD-2024-10-0090,材料出库单,直接领料,材料出库,一车间,102,原材料库,B000011,橙皮苷(Y0704),内控标准四,Y0704-240505,,,kg,,75,生产需要,谭世燕
+103,2024-10-07,MD-2024-10-0090,材料出库单,直接领料,材料出库,一车间,103,原材料库,BYW0005,橙皮苷原料(Y0716),内控标准十六,Y0716-240204,,,kg,,250,生产需要,谭世燕
+104,2024-10-07,MD-2024-10-0090,材料出库单,直接领料,材料出库,一车间,104,原材料库,BYW0005,橙皮苷原料(Y0716),内控标准十六,Y0716-240205,,,kg,,1500,生产需要,谭世燕
+105,2024-10-07,MD-2024-10-0090,材料出库单,直接领料,材料出库,一车间,105,原材料库,BYW0005,橙皮苷原料(Y0716),内控标准十六,Y0716-240208,,,kg,,250,生产需要,谭世燕
+106,2024-10-07,MD-2024-10-0091,材料出库单,直接领料,材料出库,三车间-制粒,106,备品配件安全库存库房,A14070006,PET上封板,GZL240L-40-09S,,,,个,,2,,余波
+107,2024-10-07,MD-2024-10-0091,材料出库单,直接领料,材料出库,三车间-制粒,107,备品配件安全库存库房,A14070007,PET下封板,GZL240L-40-09S,,,,个,,4,,余波
+108,2024-10-07,MD-2024-10-0091,材料出库单,直接领料,材料出库,三车间-制粒,108,备品配件安全库存库房,A14070008,四氟侧封衬板,GZL240L-40-21,,,,个,,2,,余波
+109,2024-10-07,MD-2024-10-0092,材料出库单,直接领料,材料出库,三车间-制粒,109,备品配件库,P070400060,不锈钢筛网,22目,,,,米,,1.1,,余波
+110,2024-10-07,MD-2024-10-0093,材料出库单,直接领料,材料出库,三车间-灭菌,110,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240902,,,个,,11,,余波
+111,2024-10-07,MD-2024-10-0093,材料出库单,直接领料,材料出库,三车间-灭菌,111,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240903,,,个,,40,,余波
+112,2024-10-07,MD-2024-10-0093,材料出库单,直接领料,材料出库,三车间-灭菌,112,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240903,,,个,,29,,余波
+113,2024-10-07,MD-2024-10-0094,材料出库单,直接领料,材料出库,三车间-经营产品,113,内包装物库,B000129,胶带,,/,,,卷,,5,无字,余波
+114,2024-10-07,MD-2024-10-0095,材料出库单,直接领料,材料出库,一车间,114,外包装物库,B000085,防潮纸桶(B0109),450*600,B-B0109-240902,,,个,,40,,谭世燕
+115,2024-10-07,MD-2024-10-0096,材料出库单,直接领料,材料出库,一车间,115,内包装物库,B000104,药用低密度聚乙烯袋(B0303),80*120*0.06,B0303-231101,,,条,,90,,谭世燕
+116,2024-10-07,MD-2024-10-0096,材料出库单,直接领料,材料出库,一车间,116,内包装物库,B000103,药用低密度聚乙烯袋(B0302),80*110*0.06,B0302-240801,,,条,,80,,谭世燕
+117,2024-10-07,MD-2024-10-0097,材料出库单,直接领料,材料出库,一车间,117,外包装物库,B000085,防潮纸桶(B0109),450*600,B-B0109-240902,,,个,,40,,谭世燕
+118,2024-10-07,MD-2024-10-0098,材料出库单,直接领料,材料出库,一车间,118,内包装物库,BBZ0007,扎带(白色),5*200,/,,,袋,,2,,谭世燕
+119,2024-10-07,MD-2024-10-0099,材料出库单,直接领料,材料出库,一车间,119,备品配件库,P071300035,酸洗膏,,,,,瓶,,6,,谭世燕
+120,2024-10-07,MD-2024-10-0099,材料出库单,直接领料,材料出库,一车间,120,备品配件库,P071100097,百洁布,10CM,,,,CM,,200,,谭世燕
+121,2024-10-08,MD-2024-10-0100,材料出库单,直接领料,材料出库,一车间,121,内包装物库,B000104,药用低密度聚乙烯袋(B0303),80*120*0.06,B0303-231101,,,条,,60,,谭世燕
+122,2024-10-08,MD-2024-10-0104,材料出库单,直接领料,材料出库,四车间(槲皮素),122,内包装物库,B000093,普通PE袋(B0408),62*110,B0408-240801,,,个,,300,,洪敏
+123,2024-10-08,MD-2024-10-0107,材料出库单,直接领料,材料出库,一车间,123,备品配件库,P071000005,白帽子,松紧带,,,,个,,1,临时工:李昱江,谭世燕
+124,2024-10-08,MD-2024-10-0107,材料出库单,直接领料,材料出库,一车间,124,备品配件库,P071000004,胶鞋,3537,,,,个,,1,临时工:李昱江,谭世燕
+125,2024-10-08,MD-2024-10-0107,材料出库单,直接领料,材料出库,一车间,125,备品配件库,P070100207,工作服,冬季,,,,个,,1,临时工:李昱江,谭世燕
+126,2024-10-08,MD-2024-10-0108,材料出库单,直接领料,材料出库,仓储部,126,备品配件安全库存库房,A14040030,灭蝇灯管,8W,,,,个,,1,,王涵
+127,2024-10-08,MD-2024-10-0109,材料出库单,直接领料,材料出库,三车间-灭菌,127,内包装物库,B000102,药用低密度聚乙烯袋(B0301),62*110*0.06,B0301-240801,,,条,,250,,余波
+128,2024-10-08,MD-2024-10-0110,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,128,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240903,,,个,,40,,余波
+129,2024-10-08,MD-2024-10-0110,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,129,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240903,,,个,,32,,余波
+130,2024-10-08,MD-2024-10-0110,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,130,外包装物库,B000101,全纸方桶(B0501),370*370*400,B0501-240904,,,个,,8,,余波
+131,2024-10-08,MD-2024-10-0111,材料出库单,直接领料,材料出库,三车间-制粒,131,备品配件安全库存库房,A14070012,不锈钢瓦筛,666*234*1 1.2孔径,,,,张,,1,,余波
+132,2024-10-08,MD-2024-10-0111,材料出库单,直接领料,材料出库,三车间-制粒,132,备品配件安全库存库房,A14070009,同步带,520H*25MM,,,,条,,1,,余波
+133,2024-10-08,MD-2024-10-0112,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,133,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240903,,,kg,,437,,余波
+134,2024-10-08,MD-2024-10-0112,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,134,原材料库,BYW0007,盐酸小檗碱(Y2002),Y2002,Y2002-240903,,,kg,,386,,余波
+135,2024-10-08,MD-2024-10-0113,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,135,成品库,B000286,黄连素(BAF01),标1,BAF01-2212001,,,kg,,12,,余波
+136,2024-10-08,MD-2024-10-0113,材料出库单,直接领料,材料出库,三车间-盐酸小檗碱,136,成品库,B000286,黄连素(BAF01),标1,BAF01-2212001,,,kg,,12,,余波
+137,2024-10-08,MD-2024-10-0114,材料出库单,直接领料,材料出库,行政人事部,137,备品配件库,P070200186,角阀,,,,,个,,1,,韦娟
+138,2024-10-08,MD-2024-10-0114,材料出库单,直接领料,材料出库,行政人事部,138,备品配件库,P070200376,不锈钢外丝直接,DN15,,,,个,,2,,韦娟
+139,2024-10-08,MD-2024-10-0114,材料出库单,直接领料,材料出库,行政人事部,139,备品配件库,P020100,不锈钢内丝三通,DN15,,,,个,,2,,韦娟
+140,2024-10-08,MC-2024-10-0003,产成品入库单,自制加工,自制产品入库,四车间(槲皮素),140,成品库,B000332,二水槲皮素(QAF03),标准三,QAF03-2410001,,,kg,1000,,,洪敏
+141,2024-10-08,MC-2024-10-0003,产成品入库单,自制加工,自制产品入库,四车间(槲皮素),141,成品库,B000332,二水槲皮素(QAF03),标准三,QAF03-2410002,,,kg,1000,,,洪敏
+142,2024-10-08,MD-2024-10-0118,材料出库单,直接领料,材料出库,一车间,142,内包装物库,B000093,普通PE袋(B0408),62*110,B0408-240801,,,个,,300,,谭世燕
+143,2024-10-08,MD-2024-10-0120,材料出库单,直接领料,材料出库,五车间(NHDC),143,内包装物库,B000102,药用低密度聚乙烯袋(B0301),62*110*0.06,B0301-240901,,,条,,600,,袁涛
+144,2024-10-08,MD-2024-10-0120,材料出库单,直接领料,材料出库,五车间(NHDC),144,内包装物库,B000103,药用低密度聚乙烯袋(B0302),80*110*0.06,B0302-240801,,,条,,240,,袁涛
+145,2024-10-08,MD-2024-10-0121,材料出库单,直接领料,材料出库,一车间,145,备品配件库,P071000004,胶鞋,3537,,,,个,,2,临时工:张小勇、赵林,谭世燕
+146,2024-10-08,MD-2024-10-0122,材料出库单,直接领料,材料出库,营销中心,146,外包装物库,B000084,防潮纸桶(B0108),450*500,B-B0108-240902,,,个,,2,换包装B-DCF02-2409003,谭世燕
+147,2024-10-08,MD-2024-10-0123,材料出库单,直接领料,材料出库,一车间,147,备品配件库,P071000096,蓝月亮洗衣液,3KG/瓶,,,,瓶,,1,,谭世燕
+148,2024-10-08,MD-2024-10-0123,材料出库单,直接领料,材料出库,一车间,148,备品配件库,P071200009,胶扫把,,,,,把,,1,,谭世燕
+149,2024-10-08,MD-2024-10-0123,材料出库单,直接领料,材料出库,一车间,149,备品配件库,P120209,排拖,60cm,,,,把,,1,,谭世燕
+150,2024-10-08,II-2024-10-0001,采购入库单,普通采购,采购入库,供应部,150,备品配件安全库存库房,A14010011,PP活接球阀,DN32,,,,个,5,,安全库,赵香
+151,2024-10-08,II-2024-10-0001,采购入库单,普通采购,采购入库,供应部,151,备品配件安全库存库房,A14010014,PP焊条,,,,,kg,5,,安全库,赵香
+152,2024-10-08,II-2024-10-0002,采购入库单,普通采购,采购入库,供应部,152,专用设备库,P140075,PP水喷射真空泵,RPPB-520,,,,台,1,,一车间,赵香
+153,2024-10-08,II-2024-10-0004,采购入库单,普通采购,采购入库,供应部,153,备品配件库,P070200149,碳钢弯头,∮57,,,,个,4,,污水站,赵香
+154,2024-10-08,II-2024-10-0005,采购入库单,普通采购,采购入库,供应部,154,备品配件库,P130066,内镶式板框布(景津),750A 800*800(小),,,,套,50,,五车间,赵香
+155,2024-10-08,II-2024-10-0006,采购入库单,普通采购,采购入库,供应部,155,备品配件库,P070143,电磁阀防爆线圈,XKL-A-0911 AC220V,,,,个,1,,一车间,赵香
+156,2024-10-08,II-2024-10-0007,采购入库单,普通采购,采购入库,供应部,156,备品配件库,P040697,内六角螺栓(8.8级),M16*70,,,,根,8,,三车间,赵香
+157,2024-10-08,II-2024-10-0008,采购入库单,普通采购,采购入库,供应部,157,备品配件库,P040469,钛合金螺栓,M16*65,,,,套,20,,仓储部,赵香
+158,2024-10-08,II-2024-10-0009,采购入库单,普通采购,采购入库,供应部,158,备品配件库,P070200414,UPVC弯头,DN65,,,,个,2,,一车间,赵香
+159,2024-10-08,II-2024-10-0010,采购入库单,普通采购,采购入库,供应部,159,备品配件库,P070200690,UPVC活接,DN65,,,,个,1,,污水站,赵香
+160,2024-10-08,II-2024-10-0010,采购入库单,普通采购,采购入库,供应部,160,备品配件安全库存库房,A14010006,UPVC活接球阀,DN65,,,,个,3,,污水站,赵香
+161,2024-10-08,II-2024-10-0011,采购入库单,普通采购,采购入库,供应部,161,备品配件库,P040690,消防水带快速接头,DN80,,,,套,1,,环安部,赵香
+162,2024-10-08,II-2024-10-0012,采购入库单,普通采购,采购入库,供应部,162,备品配件库,P040676,聚四氟乙烯管,φ12,,,,米,20,,五车间,赵香
+163,2024-10-08,II-2024-10-0013,采购入库单,普通采购,采购入库,供应部,163,备品配件库,P040666,不锈钢浮球阀,DN50,,,,个,1,,一车间,赵香
+164,2024-10-08,II-2024-10-0013,采购入库单,普通采购,采购入库,供应部,164,备品配件库,P020326,不锈钢快装蝶阀,DN200,,,,个,2,,一车间,赵香
+165,2024-10-08,IO-2024-10-0001,销售出库单,普通销售,销售出库,营销中心,165,成品库,B000305,芦丁(RDF01),标准一(EP),RDF01-2406012,,,kg,,75,,王涵
+166,2024-10-08,II-2024-10-0014,采购入库单,普通采购,采购入库,供应部,166,备品配件库,P070900225,法兰四氟垫,DN25,,,,个,5,,一车间,赵香
+167,2024-10-08,MC-2024-10-0004,产成品入库单,自制加工,自制产品入库,三车间-制粒,167,成品库,B000343,二水高密度槲皮素(QCF02),标一/二,QCF02-2410001,,,kg,400,,,余波
+168,2024-10-08,II-2024-10-0015,采购入库单,普通采购,采购入库,供应部,168,备品配件库,P010565,氯化钾饱和溶液,100ml/瓶,,,,瓶,1,,环安部,赵香
+169,2024-10-08,II-2024-10-0015,采购入库单,普通采购,采购入库,供应部,169,备品配件库,P010566,硝酸钾饱和溶液,100ml/瓶,,,,瓶,1,,环安部,赵香
+170,2024-10-08,II-2024-10-0016,采购入库单,普通采购,采购入库,供应部,170,备品配件库,P070200926,不锈钢大小头,Φ57*38,,,,个,2,,一车间,赵香
+171,2024-10-08,MC-2024-10-0005,产成品入库单,自制加工,自制产品入库,三车间-制粒,171,成品库,B000345,二水槲皮素颗粒(QBF03),标三,QBF03-2410002,,,kg,585.8,,,余波
+172,2024-10-08,IO-2024-10-0002,销售出库单,普通销售,销售出库,营销中心,172,成品库,B000343,二水高密度槲皮素(QCF02),标一/二,QCF02-2410001,,,kg,,250,,王涵
+173,2024-10-08,IO-2024-10-0003,销售出库单,普通销售,销售出库,营销中心,173,成品库,B000343,二水高密度槲皮素(QCF02),标一/二,QCF02-2410001,,,kg,,150,,王涵
+174,2024-10-08,IO-2024-10-0004,销售出库单,普通销售,销售出库,营销中心,174,成品库,B000345,二水槲皮素颗粒(QBF03),标三,QBF03-2410002,,,kg,,6,,王涵
+175,2024-10-08,IO-2024-10-0005,销售出库单,普通销售,销售出库,营销中心,175,成品库,B000345,二水槲皮素颗粒(QBF03),标三,QBF03-2410002,,,kg,,18,,王涵
+176,2024-10-08,IO-2024-10-0006,销售出库单,普通销售,销售出库,营销中心,176,成品库,B000345,二水槲皮素颗粒(QBF03),标三,QBF03-2410002,,,kg,,7,,王涵
+177,2024-10-08,II-2024-10-0017,采购入库单,普通采购,采购入库,供应部,177,备品配件库,P071000039,雨鞋,,,,,双,2,,一车间,赵香
+178,2024-10-08,II-2024-10-0017,采购入库单,普通采购,采购入库,供应部,178,备品配件库,P071000061,雨衣,,,,,件,4,,一车间,赵香
+179,2024-10-08,II-2024-10-0017,采购入库单,普通采购,采购入库,供应部,179,备品配件库,P071000039,雨鞋,,,,,双,10,,一车间,赵香
+180,2024-10-08,MD-2024-10-0124,材料出库单,直接领料,材料出库,五车间(柚苷水解物),180,备品配件库,P070200981,不锈钢法兰盲板,DN50,,,,个,,2,,袁涛
+181,2024-10-08,MD-2024-10-0125,材料出库单,直接领料,材料出库,环安部,181,备品配件库,P040690,消防水带快速接头,DN80,,,,套,,1,污水站,蒋文
+182,2024-10-08,MD-2024-10-0125,材料出库单,直接领料,材料出库,环安部,182,备品配件库,P010565,氯化钾饱和溶液,100ml/瓶,,,,瓶,,1,污水站,蒋文
+183,2024-10-08,MD-2024-10-0125,材料出库单,直接领料,材料出库,环安部,183,备品配件库,P010566,硝酸钾饱和溶液,100ml/瓶,,,,瓶,,1,污水站,蒋文
+184,2024-10-08,MD-2024-10-0126,材料出库单,直接领料,材料出库,一车间,184,内包装物库,BBW0004,防伪扎带,330MM,B0900-240501,,,根,,40,,谭世燕
+185,2024-10-08,MD-2024-10-0127,材料出库单,直接领料,材料出库,一车间,185,备品配件库,P070100207,工作服,冬季,,,,个,,4,临时工:李昆洪、彭磊、杨国林、卢智勇,谭世燕
+186,2024-10-09,MD-2024-10-0128,材料出库单,直接领料,材料出库,四车间(槲皮素),186,外包装物库,B000100,全纸方桶(B0503),410*410*500,B0503-240903,,,个,,50,,洪敏
+187,2024-10-09,MD-2024-10-0129,材料出库单,直接领料,材料出库,四车间(槲皮素),187,内包装物库,BBW0004,防伪扎带,330MM,B0900-240501,,,根,,80,,洪敏
+188,2024-10-09,MD-2024-10-0129,材料出库单,直接领料,材料出库,四车间(槲皮素),188,内包装物库,B000105,药用低密度聚乙烯袋(B0304),80*120*0.10,B0304-240801,,,条,,360,,洪敏
+189,2024-10-09,MD-2024-10-0131,材料出库单,直接领料,材料出库,四车间(槲皮素),189,外包装物库,B000100,全纸方桶(B0503),410*410*500,B0503-240903,,,个,,1,,洪敏

+ 74 - 0
data_base/import_data.py

@@ -0,0 +1,74 @@
+import sqlite3
+import csv
+import time
+import os
+
+# 记录开始时间
+start_time = time.time()
+
+# 连接数据库(动态获取数据库路径)
+db_path = os.path.abspath('../db.sqlite3')
+print(f"[{time.strftime('%H:%M:%S')}] 正在连接数据库: {db_path}")
+
+try:
+    conn = sqlite3.connect(db_path)
+    cursor = conn.cursor()
+    # 在插入前清空表
+    cursor.execute("DELETE FROM flowlist;")
+    print(f"[{time.strftime('%H:%M:%S')}] ✅ 数据库连接成功")
+
+    # 读取CSV文件
+    csv_file = 'flow.csv'
+    print(f"\n[{time.strftime('%H:%M:%S')}] 开始导入文件: {csv_file}")
+    
+    with open(csv_file, 'r') as f:
+        reader = csv.reader(f)
+        
+        # 读取标题行
+        try:
+            header = next(reader)
+            num_columns = len(header)
+            print(f"[{time.strftime('%H:%M:%S')}] 检测到 {num_columns} 列 | 标题: {', '.join(header)}")
+        except StopIteration:
+            print("❌ 错误:CSV文件为空或格式不正确")
+            exit()
+
+        # 准备SQL语句
+        placeholders = ', '.join(['?'] * num_columns)
+        sql = f"INSERT INTO flowlist VALUES ({placeholders})"
+        print(f"[{time.strftime('%H:%M:%S')}] 生成SQL语句: {sql}\n")
+
+        # 插入数据
+        total_rows = 0
+        for i, row in enumerate(reader, 1):
+            # 关键修改:将空白值转换为0
+            processed_row = [
+                0 if str(cell).strip() == '' else cell  # 空白转0,保留非空值
+                for cell in row
+            ]
+            cursor.execute(sql, processed_row)
+            total_rows += 1
+            
+            # 每100行提示进度
+            if i % 10 == 0:
+                print(f"[{time.strftime('%H:%M:%S')}] 已插入 {i} 行...", end='\r')
+        
+        # 提交事务
+        conn.commit()
+        print(f"\n[{time.strftime('%H:%M:%S')}] ✅ 数据插入完成,共 {total_rows} 行")
+
+except FileNotFoundError:
+    print(f"❌ 错误:CSV文件不存在,当前搜索路径: {os.path.abspath(csv_file)}")
+except sqlite3.Error as e:
+    print(f"❌ 数据库错误: {str(e)}")
+    conn.rollback()
+except Exception as e:
+    print(f"❌ 发生异常: {str(e)}")
+finally:
+    if 'conn' in locals():
+        conn.close()
+        print(f"[{time.strftime('%H:%M:%S')}] 数据库连接已关闭")
+
+# 计算总耗时
+end_time = time.time()
+print(f"\n总耗时: {end_time - start_time:.2f} 秒")


+ 67 - 0
greaterwms/__init__.py

@@ -0,0 +1,67 @@
+import mimetypes, os, requests, django
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'greaterwms.settings')
+os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
+django.setup()
+from django.conf import settings
+import pandas as pd
+from pathlib import Path
+
+mimetypes.add_type("text/css", ".css", True)
+mimetypes.add_type("text/javascript", ".js", True)
+
+win32_folder = os.path.exists(os.path.join(settings.BASE_DIR, 'media/' + "/win32"))
+linux_folder = os.path.exists(os.path.join(settings.BASE_DIR, 'media/' + "/linux"))
+darwin_folder = os.path.exists(os.path.join(settings.BASE_DIR, 'media/' + "/darwin"))
+upload_folder = os.path.exists(os.path.join(settings.BASE_DIR, 'media/' + "/upload_example"))
+if not win32_folder:
+    os.makedirs(os.path.join(settings.BASE_DIR, 'media/' + "/win32"))
+if not linux_folder:
+    os.makedirs(os.path.join(settings.BASE_DIR, 'media/' + "/linux"))
+if not darwin_folder:
+    os.makedirs(os.path.join(settings.BASE_DIR, 'media/' + "/darwin"))
+if not upload_folder:
+    os.makedirs(os.path.join(settings.BASE_DIR, 'media/' + "/upload_example"))
+
+customer_cn_path = os.path.join(settings.BASE_DIR, 'media/' + "/upload_example/customer_cn.xlsx")
+customer_en_path = os.path.join(settings.BASE_DIR, 'media/' + "/upload_example/customer_en.xlsx")
+goodslist_cn_path = os.path.join(settings.BASE_DIR, 'media/' + "/upload_example/goodslist_cn.xlsx")
+goodslist_en_path = os.path.join(settings.BASE_DIR, 'media/' + "/upload_example/goodslist_en.xlsx")
+supplier_cn_path = os.path.join(settings.BASE_DIR, 'media/' + "/upload_example/supplier_cn.xlsx")
+supplier_en_path = os.path.join(settings.BASE_DIR, 'media/' + "/upload_example/supplier_en.xlsx")
+customer_cn_file = os.path.exists(customer_cn_path)
+customer_en_file = os.path.exists(customer_en_path)
+goodslist_cn_file = os.path.exists(goodslist_cn_path)
+goodslist_en_file = os.path.exists(goodslist_en_path)
+supplier_cn_file = os.path.exists(supplier_cn_path)
+supplier_en_file = os.path.exists(supplier_en_path)
+if not customer_cn_file:
+    customer_cn = pd.DataFrame({"客户名称": [], "客户城市": [] ,"详细地址": [], "联系电话": [], "负责人": [], "客户等级": []})
+    df = customer_cn.set_index("客户名称")
+    df.to_excel(customer_cn_path)
+
+if not customer_en_file:
+    customer_en = pd.DataFrame({"Customer Name": [], "Customer City": [], "Customer Address": [], "Customer Contact": [], "Customer Manager": [], "Customer Level": []})
+    df = customer_en.set_index("Customer Name")
+    df.to_excel(customer_en_path)
+
+if not goodslist_cn_file:
+    goodslist_cn = pd.DataFrame({"商品编码": [], "商品描述": [], "商品供应商": [], "商品单位重量": [], "商品单位长度": [], "商品单位宽度": [], "商品单位高度": [],  "最小单位体积": [], "商品单位": [], "商品类别": [], "商品品牌": [], "商品颜色": [], "商品形状": [], "商品规格": [], "商品产地": [], "商品成本": [], "商品价格": []})
+    df = goodslist_cn.set_index("商品编码")
+    df.to_excel(goodslist_cn_path)
+
+if not goodslist_en_file:
+    goodslist_en = pd.DataFrame({"Goods Code": [], "Goods Description": [], "Goods Supplier": [], "Goods Weight": [], "Goods Width": [], "Goods Depth": [], "Goods Height": [],  "Unit Volume": [], "Goods Unit": [], "Goods Class": [], "Goods Brand": [], "Goods Color": [], "Goods Shape": [], "Goods Specs": [], "Goods Origin": [], "Goods Cost": [], "Goods Price": []})
+    df = goodslist_en.set_index("Goods Code")
+    df.to_excel(goodslist_en_path)
+
+if not supplier_cn_file:
+    supplier_cn = pd.DataFrame({"供应商名称": [], "供应商城市": [] ,"详细地址": [], "联系电话": [], "负责人": [], "供应商等级": []})
+    df = supplier_cn.set_index("供应商名称")
+    df.to_excel(supplier_cn_path)
+
+if not supplier_en_file:
+    supplier_en = pd.DataFrame({"Supplier Name": [], "Supplier City": [] ,"Supplier Address": [], "Supplier Contact": [], "Supplier Manager": [], "Supplier Level": []})
+    df = supplier_en.set_index("Supplier Name")
+    df.to_excel(supplier_en_path)
+
+print('Welcome To GreaterWMS')

BIN
greaterwms/__pycache__/__init__.cpython-310.pyc


BIN
greaterwms/__pycache__/asgi.cpython-310.pyc


BIN
greaterwms/__pycache__/settings.cpython-310.pyc


BIN
greaterwms/__pycache__/urls.cpython-310.pyc


BIN
greaterwms/__pycache__/views.cpython-310.pyc


+ 19 - 0
greaterwms/asgi.py

@@ -0,0 +1,19 @@
+import os
+
+from django.core.asgi import get_asgi_application
+from utils.websocket import websocket_application
+from asgihandler.core import ASGIHandler
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'greaterwms.settings')
+
+http_application = get_asgi_application()
+
+
+async def application(scope, receive, send):
+    if scope['type'] in ['http', 'https']:
+        ASGIHandler.asgi_get_handler(scope)
+        await http_application(scope, receive, send)
+    elif scope['type'] in ['websocket']:
+        await websocket_application(scope, receive, send)
+    else:
+        raise Exception('Unknown Type' + scope['type'])
+

+ 338 - 0
greaterwms/settings.py

@@ -0,0 +1,338 @@
+from pathlib import Path
+import os
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+from django.core.management.utils import get_random_secret_key
+SECRET_KEY = get_random_secret_key()
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = ['*']
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+
+    'staff.apps.StaffConfig',
+    'userprofile.apps.UserprofileConfig',
+    'userregister.apps.UserregisterConfig',
+    'userlogin.apps.UserloginConfig',
+ 
+    'stock.apps.StockConfig',
+    'warehouse.apps.WarehouseConfig',
+    'reportcenter.apps.ReportcenterConfig',
+
+    'throttle.apps.ThrottleConfig',
+    'rest_framework',
+    'django_filters',
+    'corsheaders',
+    'drf_spectacular',
+    'drf_spectacular_sidecar'
+]
+
+MIDDLEWARE = [
+    'corsheaders.middleware.CorsMiddleware',
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    #'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'greaterwms.urls'
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [BASE_DIR / 'templates']
+        ,
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'greaterwms.wsgi.application'
+CSRF_COOKIE_SAMESITE = None
+
+# Database
+# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
+# update
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': BASE_DIR / 'db.sqlite3',
+        'OPTIONS': {
+            'timeout': 20,
+        }
+    }
+}
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+# Password validation
+# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/3.1/topics/i18n/
+
+LANGUAGE_CODE = 'zh-hans'
+
+TIME_ZONE = 'Asia/Shanghai'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = False
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.1/howto/static-files/
+
+STATIC_URL = '/static/'
+STATIC_ROOT = os.path.join(BASE_DIR, 'static_new').replace('\\', '/')
+STATICFILES_DIRS = [
+    os.path.join(BASE_DIR, 'static').replace('\\', '/'),
+]
+
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\', '/')
+
+SPECTACULAR_SETTINGS = {
+    'TITLE': 'GreaterWMS',
+    'DESCRIPTION': 'GreaterWMS API Documents',
+    'VERSION': '2.1.48',
+    'SERVE_INCLUDE_SCHEMA': False,
+    # OTHER SETTINGS
+    'SWAGGER_UI_DIST': 'SIDECAR',  # shorthand to use the sidecar instead
+    'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
+    'REDOC_DIST': 'SIDECAR',
+    # OTHER SETTINGS
+}
+
+REST_FRAMEWORK = {
+    # AttributeError: ‘AutoSchema’ object has no attribute ‘get_link’
+    # DEFAULT SET:
+    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
+    # 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.openapi.AutoSchema',
+    # EXCEPTION:
+    'EXCEPTION_HANDLER': 'utils.my_exceptions.custom_exception_handler',
+    # Base API policies:
+    'DEFAULT_RENDERER_CLASSES': [
+        'rest_framework.renderers.JSONRenderer',
+        'rest_framework_csv.renderers.CSVRenderer',
+        #'rest_framework.renderers.BrowsableAPIRenderer',
+    ],
+    'DEFAULT_PARSER_CLASSES': [
+        'rest_framework.parsers.JSONParser',
+        'rest_framework.parsers.FormParser',
+        'rest_framework.parsers.MultiPartParser'
+    ],
+    'DEFAULT_AUTHENTICATION_CLASSES': ['utils.auth.Authtication', ],
+    'DEFAULT_PERMISSION_CLASSES': ["utils.permission.Normalpermission", ],
+    'DEFAULT_THROTTLE_CLASSES': ['utils.throttle.VisitThrottle', ],
+    # 'DEFAULT_THROTTLE_RATES': ['utils.throttle.VisitThrottle', ],
+    'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'rest_framework.negotiation.DefaultContentNegotiation',
+    'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata',
+    'DEFAULT_VERSIONING_CLASS': None,
+    # 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
+    # 'PAGE_SIZE': 1,  # 默认 None
+    'DEFAULT_FILTER_BACKENDS': [
+        'django_filters.rest_framework.DjangoFilterBackend',
+        # 'django_filters.rest_framework.backends.DjangoFilterBackend',
+    ],
+    'SEARCH_PARAM': 'search',
+    'ORDERING_PARAM': 'ordering',
+    'NUM_PROXIES': None,
+    # Versioning:
+    'DEFAULT_VERSION': None,
+    'ALLOWED_VERSIONS': None,
+    'VERSION_PARAM': 'version',
+    # Authentication:
+    'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
+    'UNAUTHENTICATED_TOKEN': None,
+    # View configuration:
+    'VIEW_NAME_FUNCTION': 'rest_framework.views.get_view_name',
+    'VIEW_DESCRIPTION_FUNCTION': 'rest_framework.views.get_view_description',
+    'NON_FIELD_ERRORS_KEY': 'non_field_errors',
+    # Testing
+    'TEST_REQUEST_RENDERER_CLASSES': [
+        'rest_framework.renderers.MultiPartRenderer',
+        'rest_framework.renderers.JSONRenderer'
+    ],
+    'TEST_REQUEST_DEFAULT_FORMAT': 'multipart',
+    # Hyperlink settings
+    'URL_FORMAT_OVERRIDE': 'format',
+    'FORMAT_SUFFIX_KWARG': 'format',
+    'URL_FIELD_NAME': 'url',
+    # Encoding
+    'UNICODE_JSON': True,
+    'COMPACT_JSON': True,
+    'STRICT_JSON': True,
+    'COERCE_DECIMAL_TO_STRING': True,
+    'UPLOADED_FILES_USE_URL': True,
+    # Browseable API
+    'HTML_SELECT_CUTOFF': 1000,
+    'HTML_SELECT_CUTOFF_TEXT': "More than {count} items...",
+    # Schemas
+    'SCHEMA_COERCE_PATH_PK': True,
+    'SCHEMA_COERCE_METHOD_NAMES': {
+        'retrieve': 'read',
+        'destroy': 'delete'
+    },
+}
+
+SERVER_LOGS_FILE = os.path.join(BASE_DIR, "logs", "server.log")
+ERROR_LOGS_FILE = os.path.join(BASE_DIR, "logs", "error.log")
+if not os.path.exists(os.path.join(BASE_DIR, "logs")):
+    os.makedirs(os.path.join(BASE_DIR, "logs"))
+
+STANDARD_LOG_FORMAT = (
+    "[%(asctime)s][%(name)s.%(funcName)s():%(lineno)d] [%(levelname)s] %(message)s"
+)
+CONSOLE_LOG_FORMAT = (
+    "[%(asctime)s][%(name)s.%(funcName)s():%(lineno)d] [%(levelname)s] %(message)s"
+)
+
+LOGGING = {
+    "version": 1,
+    "disable_existing_loggers": False,
+    "formatters": {
+        "standard": {"format": STANDARD_LOG_FORMAT},
+        "console": {
+            "format": CONSOLE_LOG_FORMAT,
+            "datefmt": "%Y-%m-%d %H:%M:%S",
+        },
+        "file": {
+            "format": CONSOLE_LOG_FORMAT,
+            "datefmt": "%Y-%m-%d %H:%M:%S",
+        },
+    },
+    "handlers": {
+        "file": {
+            "level": "INFO",
+            "class": "logging.handlers.RotatingFileHandler",
+            "filename": SERVER_LOGS_FILE,
+            "maxBytes": 1024 * 1024 * 100,
+            "backupCount": 5,
+            "formatter": "standard",
+            "encoding": "utf-8",
+        },
+        "error": {
+            "level": "ERROR",
+            "class": "logging.handlers.RotatingFileHandler",
+            "filename": ERROR_LOGS_FILE,
+            "maxBytes": 1024 * 1024 * 100,
+            "backupCount": 3,
+            "formatter": "standard",
+            "encoding": "utf-8",
+        },
+        "console": {
+            "level": "INFO",
+            "class": "logging.StreamHandler",
+            "formatter": "console",
+        },
+    },
+    "loggers": {
+        "django": {
+            "handlers": ["console", "error", "file"],
+            "level": "INFO",
+            "propagate": False,
+        },
+        "scripts": {
+            "handlers": ["console", "error", "file"],
+            "level": "INFO",
+            "propagate": False,
+        },
+        "django.db.backends": {
+            "handlers": [],
+            "propagate": True,
+            "level": "INFO",
+        },
+    },
+}
+
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+CORS_ORIGIN_WHITELIST = ()
+
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+
+CORS_ALLOW_HEADERS = (
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+    'token',
+    'appid', 
+    'language',
+    'operator',
+    'device',
+    'app-id',
+    'event-sign'
+)
+
+LAZY_RENDERING = True
+NATIVE_SCROLLBARS = True
+
+ALLOCATION_SECONDS = 1
+GET_THROTTLE = 500
+POST_THROTTLE = 500
+PUT_THROTTLE = 500
+PATCH_THROTTLE = 500
+DELETE_THROTTLE = 500
+
+JWT_TIME = 60 * 60 * 24 * 365 * 20

+ 36 - 0
greaterwms/urls.py

@@ -0,0 +1,36 @@
+from django.contrib import admin
+from django.conf import settings
+from django.urls import path, include, re_path
+from django.views.generic.base import TemplateView
+from django.contrib.staticfiles.views import serve
+from django.views.static import serve as static_serve
+from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
+from . import views
+
+
+def return_static(request, path, insecure=True, **kwargs):
+  return serve(request, path, insecure, **kwargs)
+
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+    path('', TemplateView.as_view(template_name='dist/spa/index.html')),
+    path('myip/', views.myip, name='myip'),
+  
+    path('staff/', include('staff.urls')),
+ 
+    path('login/', include('userlogin.urls')),
+    path('register/', include('userregister.urls')),
+    path('stock/', include('stock.urls')),
+    path('warehouse/', include('warehouse.urls')),
+    path('reportcenter/', include('reportcenter.urls')),
+
+    re_path(r'^favicon\.ico$', views.favicon, name='favicon'),
+    re_path('^css/.*$', views.css, name='css'),
+    re_path('^js/.*$', views.js, name='js'),
+    re_path('^statics/.*$', views.statics, name='statics'),
+    re_path('^fonts/.*$', views.fonts, name='fonts'),
+    re_path(r'^robots.txt', views.robots, name='robots'),
+    re_path(r'^media/(?P<path>.*)$', static_serve, {'document_root': settings.MEDIA_ROOT}),
+    re_path(r'^static/(?P<path>.*)$', return_static, name='static')
+]

+ 56 - 0
greaterwms/views.py

@@ -0,0 +1,56 @@
+from django.http import StreamingHttpResponse, JsonResponse
+from django.conf import settings
+from wsgiref.util import FileWrapper
+from rest_framework.exceptions import APIException
+import mimetypes, os
+
+def robots(request):
+    path = settings.BASE_DIR + request.path_info
+    content_type, encoding = mimetypes.guess_type(path)
+    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
+    resp['Cache-Control'] = "max-age=864000000000"
+    return resp
+
+def favicon(request):
+    path = str(settings.BASE_DIR) + '/static/img/logo.png'
+    content_type, encoding = mimetypes.guess_type(path)
+    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
+    resp['Cache-Control'] = "max-age=864000000000"
+    return resp
+
+def css(request):
+    path = str(settings.BASE_DIR) + '/templates/dist/spa' + request.path_info
+    content_type, encoding = mimetypes.guess_type(path)
+    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
+    resp['Cache-Control'] = "max-age=864000000000"
+    return resp
+
+def js(request):
+    path = str(settings.BASE_DIR) + '/templates/dist/spa' + request.path_info
+    content_type, encoding = mimetypes.guess_type(path)
+    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
+    resp['Cache-Control'] = "max-age=864000000000"
+    return resp
+
+def statics(request):
+    path = str(settings.BASE_DIR) + '/templates/dist/spa' + request.path_info
+    content_type, encoding = mimetypes.guess_type(path)
+    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
+    resp['Cache-Control'] = "max-age=864000000000"
+    return resp
+
+def fonts(request):
+    path = str(settings.BASE_DIR) + '/templates/dist/spa' + request.path_info
+    content_type, encoding = mimetypes.guess_type(path)
+    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
+    resp['Cache-Control'] = "max-age=864000000000"
+    return resp
+
+def myip(request):
+    import socket
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    s.connect(('8.8.8.8', 80))
+    print(s.getsockname()[0])
+    ip = s.getsockname()[0]
+    s.close()
+    return JsonResponse({"ip": ip})

+ 16 - 0
greaterwms/wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for django_wms project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'greaterwms.settings')
+
+application = get_wsgi_application()

Разница между файлами не показана из-за своего большого размера
+ 3160 - 0
logs/error.log


Разница между файлами не показана из-за своего большого размера
+ 3496 - 0
logs/server.log


+ 22 - 0
manage.py

@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+    """Run administrative tasks."""
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'greaterwms.settings')
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+    main()

+ 0 - 0
media/__init__.py


BIN
media/upload_example/customer_cn.xlsx


BIN
media/upload_example/customer_en.xlsx


BIN
media/upload_example/goodslist_cn.xlsx


BIN
media/upload_example/goodslist_en.xlsx


BIN
media/upload_example/supplier_cn.xlsx


BIN
media/upload_example/supplier_en.xlsx


+ 97 - 0
nginx.conf

@@ -0,0 +1,97 @@
+
+user root;
+worker_processes auto;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+    include         mime.types;
+    default_type    application/octet-stream;
+    sendfile        on;
+    gzip            on;
+    gzip_min_length 1k;
+    gzip_comp_level 4;
+    gzip_types      text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
+    gzip_disable    "MSIE [1-6]\.";
+    gzip_vary       on;
+	proxy_redirect off;
+	proxy_set_header Host $host;
+	proxy_set_header  https $https;
+	proxy_set_header X-Real-IP $remote_addr;
+	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+	client_max_body_size 75M;
+	client_body_buffer_size 256k;
+	client_header_timeout 3m;
+	client_body_timeout 3m;
+	send_timeout 3m;
+	proxy_connect_timeout 300s;
+	proxy_read_timeout 300s;
+	proxy_send_timeout 300s;
+	proxy_buffer_size 64k;
+	proxy_buffers 4 32k;
+	proxy_busy_buffers_size 64k;
+	proxy_temp_file_write_size 64k;
+	proxy_ignore_client_abort on;
+
+	upstream GreaterWMS{
+  server 127.0.0.1:8008;
+}
+	server {
+	listen      80;
+	server_name {{ Domin Name }};
+	rewrite ^(.*)$ https://{{ Domin Name }}$1;
+
+	}
+
+      server {
+	listen      443 ssl;
+
+    server_name  {{ Domin Name }};
+	root /path/to/GreaterWMS;
+	charset utf-8;
+	add_header X-Frame-Options "SAMEORIGIN";
+	add_header X-XSS-Protection "1; mode=block";
+	add_header X-Content-Type-Options "nosniff";
+
+	client_max_body_size 75M;
+
+ 	ssl_certificate   /path/to/GreaterWMS.pem;
+ 	ssl_certificate_key  /path/to/GreaterWMS.key;
+ 	ssl_session_timeout 5m;
+ 	ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
+ 	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+	ssl_prefer_server_ciphers on;
+
+    access_log off;
+	error_log  /path/to/GreaterWMS/greaterwms-error.log error;
+
+	 location /websocket/ {
+       proxy_pass http://GreaterWMS/;
+			 proxy_read_timeout 60s;
+       proxy_set_header Host $host;
+       proxy_set_header X-Real_IP $remote_addr;
+       proxy_set_header X-Forwarded-for $remote_addr;
+       proxy_http_version 1.1;
+       proxy_set_header Upgrade $http_upgrade;
+       proxy_set_header Connection 'Upgrade';
+    }
+
+    location / {
+        #root   html;
+        #index  testssl.html index.html index.htm;
+       proxy_redirect off;
+       proxy_set_header Host $host;
+       proxy_set_header X-Real-IP $remote_addr;
+       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+       proxy_pass http://127.0.0.1:8008/;
+    }
+		location /static/ {
+			alias /path/to/GreaterWMS/static_new/;
+		}
+	location /media/{
+		alias /path/to/GreaterWMS/media/;
+	}
+    }
+}

+ 0 - 0
reportcenter/__init__.py


BIN
reportcenter/__pycache__/__init__.cpython-310.pyc


BIN
reportcenter/__pycache__/admin.cpython-310.pyc


BIN
reportcenter/__pycache__/apps.cpython-310.pyc


BIN
reportcenter/__pycache__/files.cpython-310.pyc


BIN
reportcenter/__pycache__/filter.cpython-310.pyc


BIN
reportcenter/__pycache__/models.cpython-310.pyc


BIN
reportcenter/__pycache__/serializers.cpython-310.pyc


BIN
reportcenter/__pycache__/urls.cpython-310.pyc


BIN
reportcenter/__pycache__/views.cpython-310.pyc


+ 3 - 0
reportcenter/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 6 - 0
reportcenter/apps.py

@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class ReportcenterConfig(AppConfig):
+    default_auto_field = 'django.db.models.BigAutoField'
+    name = 'reportcenter'

+ 54 - 0
reportcenter/files.py

@@ -0,0 +1,54 @@
+from rest_framework_csv.renderers import CSVStreamingRenderer
+
+
+def file_headers_list():
+    return [
+        'goods_code',
+        'goods_desc',
+        'goods_qty',
+        'onhand_stock',
+        'can_order_stock',
+        'ordered_stock',
+        'inspect_stock',
+        'hold_stock',
+        'damage_stock',
+        'asn_stock',
+        'dn_stock',
+        'pre_load_stock',
+        'pre_sort_stock',
+        'sorted_stock',
+        'pick_stock',
+        'picked_stock',
+        'back_order_stock',
+        'create_time',
+        'update_time'
+    ]
+
+def cn_data_header_list():
+    return dict([
+        ('goods_code', u'商品编码'),
+        ('goods_desc', u'商品描述'),
+        ('goods_qty', u'商品数量'),
+        ('onhand_stock', u'现有库存'),
+        ('can_order_stock', u'可被下单数量'),
+        ('ordered_stock', u'已被下单数量'),
+        ('inspect_stock', u'质检库存'),
+        ('hold_stock', u'锁定库存'),
+        ('damage_stock', u'破损库存'),
+        ('asn_stock', u'到货通知书数量'),
+        ('dn_stock', u'发货单数量'),
+        ('pre_load_stock', u'等待卸货数量'),
+        ('pre_sort_stock', u'等待分拣数量'),
+        ('sorted_stock', u'已分拣数量'),
+        ('pick_stock', u'等待拣货数量'),
+        ('picked_stock', u'已拣货数量'),
+        ('back_order_stock', u'欠货数量'),
+        ('create_time', u'创建时间'),
+        ('update_time', u'更新时间')
+    ])
+
+class FileFlowListRenderCN(CSVStreamingRenderer):
+    header = file_headers_list()
+    labels = cn_data_header_list()
+
+

+ 26 - 0
reportcenter/filter.py

@@ -0,0 +1,26 @@
+from django_filters import FilterSet
+from .models import flowModel
+
+class FlowFilter(FilterSet):
+    class Meta:
+        model = flowModel
+        fields = {
+            'document_date': ['exact', 'range'],
+            'document_number': ['exact', 'icontains'],
+            'document_type': ['exact', 'icontains'],
+            'business_type': ['exact', 'icontains'],
+            'iout_type': ['exact', 'icontains'],
+            'department': ['exact', 'icontains'],
+            'warehouse_code': ['exact', 'icontains'],
+            'warehouse_name': ['exact', 'icontains'],
+            'goods_code': ['exact', 'icontains'],
+            'goods_desc': ['exact', 'icontains'],
+            'goods_std': ['exact', 'icontains'],
+            'goods_batch': ['exact', 'icontains'],
+            'in_batch': ['exact', 'icontains'],
+            'out_batch': ['exact', 'icontains'],
+            'goods_in': ['exact', 'gt', 'lt', 'gte', 'lte'],
+            'goods_out': ['exact', 'gt', 'lt', 'gte', 'lte'],
+            'goods_notes': ['exact', 'icontains'],
+            'creator': ['exact', 'icontains']
+        }

+ 49 - 0
reportcenter/migrations/0001_initial.py

@@ -0,0 +1,49 @@
+# Generated by Django 4.1.2 on 2025-03-16 19:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='flowModel',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('document_date', models.DateField(blank=True, null=True, verbose_name='Document Date')),
+                ('document_number', models.CharField(blank=True, max_length=20, null=True, verbose_name='Document Number')),
+                ('document_type', models.CharField(blank=True, max_length=20, null=True, verbose_name='Document Type')),
+                ('business_type', models.CharField(blank=True, max_length=20, null=True, verbose_name='Business Type')),
+                ('iout_type', models.CharField(blank=True, max_length=255, null=True, verbose_name='IOUT Type')),
+                ('department', models.CharField(blank=True, max_length=255, null=True, verbose_name='Department')),
+                ('warehouse_code', models.CharField(blank=True, max_length=20, null=True, verbose_name='Warehouse Code')),
+                ('warehouse_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Warehouse Name')),
+                ('goods_code', models.CharField(blank=True, max_length=255, null=True, verbose_name='Goods Code')),
+                ('goods_desc', models.CharField(blank=True, max_length=255, null=True, verbose_name='Goods Description')),
+                ('goods_std', models.CharField(blank=True, max_length=255, null=True, verbose_name='Goods Standard')),
+                ('goods_batch', models.CharField(blank=True, max_length=255, null=True, verbose_name='Goods Batch')),
+                ('in_batch', models.CharField(blank=True, max_length=255, null=True, verbose_name='In Batch')),
+                ('out_batch', models.CharField(blank=True, max_length=255, null=True, verbose_name='Out Batch')),
+                ('goods_unit', models.CharField(blank=True, default='件', max_length=255, null=True, verbose_name='Goods Unit')),
+                ('goods_in', models.BigIntegerField(blank=True, default=0, null=True, verbose_name='Goods In')),
+                ('goods_out', models.BigIntegerField(blank=True, default=0, null=True, verbose_name='Goods Out')),
+                ('goods_notes', models.CharField(blank=True, default='待填写', max_length=255, null=True, verbose_name='Goods Notes')),
+                ('creator', models.CharField(blank=True, max_length=255, null=True, verbose_name='Creator')),
+            ],
+            options={
+                'verbose_name': 'Flow List',
+                'verbose_name_plural': 'Flow List',
+                'db_table': 'flowlist',
+                'ordering': ['id'],
+            },
+        ),
+        migrations.AddConstraint(
+            model_name='flowmodel',
+            constraint=models.UniqueConstraint(fields=('document_date', 'document_number', 'document_type', 'business_type', 'iout_type', 'department', 'warehouse_code', 'warehouse_name', 'goods_code', 'goods_desc', 'goods_std', 'goods_batch', 'in_batch', 'out_batch', 'goods_in', 'goods_out', 'goods_notes', 'creator'), name='unique_all_fields'),
+        ),
+    ]

+ 0 - 0
reportcenter/migrations/__init__.py


BIN
reportcenter/migrations/__pycache__/0001_initial.cpython-310.pyc


BIN
reportcenter/migrations/__pycache__/0002_alter_flowmodel_goods_in_alter_flowmodel_goods_notes_and_more.cpython-310.pyc


BIN
reportcenter/migrations/__pycache__/0002_flowmodel_goods_unit.cpython-310.pyc


BIN
reportcenter/migrations/__pycache__/__init__.cpython-310.pyc


+ 46 - 0
reportcenter/models.py

@@ -0,0 +1,46 @@
+from django.db import models
+
+class flowModel(models.Model):
+    
+    document_date = models.DateField(verbose_name='Document Date', null=True, blank=True)
+    document_number = models.CharField(max_length=20, verbose_name='Document Number', null=True, blank=True)
+    document_type = models.CharField(max_length=20, verbose_name='Document Type', null=True, blank=True)
+    business_type = models.CharField(max_length=20, verbose_name='Business Type', null=True, blank=True)
+    iout_type = models.CharField(max_length=255, verbose_name='IOUT Type', null=True, blank=True)
+    department = models.CharField(max_length=255, verbose_name='Department', null=True, blank=True)
+    warehouse_code = models.CharField(max_length=20, verbose_name='Warehouse Code', null=True, blank=True)
+    warehouse_name = models.CharField(max_length=255, verbose_name='Warehouse Name', null=True, blank=True)
+    goods_code = models.CharField(max_length=255, verbose_name='Goods Code', null=True, blank=True)
+    goods_desc = models.CharField(max_length=255, verbose_name='Goods Description', null=True, blank=True)
+    goods_std = models.CharField(max_length=255, verbose_name='Goods Standard', null=True, blank=True)
+    goods_batch = models.CharField(max_length=255, verbose_name='Goods Batch', null=True, blank=True)
+    in_batch = models.CharField(max_length=255, verbose_name='In Batch', null=True, blank=True)
+    out_batch = models.CharField(max_length=255, verbose_name='Out Batch', null=True, blank=True)
+    goods_unit = models.CharField(max_length=255,default = '件', verbose_name="Goods Unit", null=True, blank=True)
+    goods_in = models.BigIntegerField(default=0, verbose_name="Goods In",null=True, blank=True)
+    goods_out = models.BigIntegerField(default=0, verbose_name="Goods Out",null=True, blank=True)
+    goods_notes = models.CharField(max_length=255,default = '待填写', verbose_name="Goods Notes",null=True, blank=True)
+    creator = models.CharField(max_length=255, verbose_name='Creator', null=True, blank=True)
+
+
+    class Meta:
+        db_table = 'flowlist'
+        verbose_name = 'Flow List'
+        verbose_name_plural = "Flow List"
+        ordering = ['id']
+        constraints = [
+           
+            models.UniqueConstraint(
+                fields=[
+                    'document_date', 'document_number', 'document_type',
+                    'business_type', 'iout_type', 'department', 'warehouse_code',
+                    'warehouse_name', 'goods_code', 'goods_desc', 'goods_std',
+                    'goods_batch', 'in_batch', 'out_batch', 'goods_in', 'goods_out',
+                    'goods_notes', 'creator'
+                ],
+                name='unique_all_fields'
+            )
+        ]
+    
+
+

+ 9 - 0
reportcenter/serializers.py

@@ -0,0 +1,9 @@
+from rest_framework import serializers
+from .models import flowModel
+from utils import datasolve
+
+class flowSerializer(serializers.ModelSerializer):
+    problematic_field = serializers.IntegerField(allow_null=True)
+    class Meta:
+        model = flowModel
+        fields = '__all__'

+ 3 - 0
reportcenter/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 7 - 0
reportcenter/urls.py

@@ -0,0 +1,7 @@
+from django.urls import path, re_path
+from . import views
+
+urlpatterns = [
+    path(r'flow/', views.FlowsStatsViewSet.as_view({"get": "list", "post": "create"}), name="management"),
+
+]

+ 125 - 0
reportcenter/views.py

@@ -0,0 +1,125 @@
+from rest_framework import viewsets
+from utils.page import MyPageNumberPagination
+from utils.md5 import Md5
+from rest_framework.filters import OrderingFilter
+from django_filters.rest_framework import DjangoFilterBackend
+from rest_framework.response import Response
+from rest_framework.exceptions import APIException
+from django.http import StreamingHttpResponse
+from rest_framework.settings import api_settings
+from django.db import transaction  
+from rest_framework import status
+
+from reportcenter.models import flowModel as flowlist
+from . import serializers
+from .filter import FlowFilter
+from .files import  FileFlowListRenderCN
+
+
+
+class FlowsStatsViewSet(viewsets.ModelViewSet):
+
+    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
+    ordering_fields = ['id', "create_time", "update_time", ]
+
+    filter_class = FlowFilter
+    pagination_class = MyPageNumberPagination
+   
+
+
+    """
+        list:
+            Response a data list(all)
+        post:
+            Create a new data(create)
+    """
+    
+
+    def get_project(self):
+        try:
+            id = self.kwargs.get('pk')
+            return id
+        except:
+            return None
+    
+
+    def get_queryset(self):
+        id = self.get_project()
+
+        if self.request.user:
+            if id is None:
+                return flowlist.objects.filter()
+            else:
+                return flowlist.objects.filter(id=id)
+        else:
+            return flowlist.objects.none()
+
+    def get_serializer_class(self):
+        if self.action in ['list', 'create', ]:
+            return serializers.flowSerializer
+        # elif self.action in ['retrieve','update',]:
+        #     return serializers.stocklistpartialSerializer
+        else:
+            return self.http_method_not_allowed(request=self.request)
+
+    # def create(self, request, *args, **kwargs):
+    #     data = request.data.copy()
+    #     warehouse_code = data.get('warehouse_code')
+    #     warehouse_name = data.get('warehouse_name')
+    #     shelf_type = data.get('shelf_type')
+    #     shelf_name = data.get('shelf_name')
+        
+    #     rows = int(data.get('rows', 0))
+    #     cols = int(data.get('cols', 0))
+    #     layers = int(data.get('layers', 0))
+
+        
+    #     existing_positions = flowlist.get_existing_positions(warehouse_code,shelf_name, rows, cols, layers)
+
+    #     # 生成所有可能的坐标
+    #     instances = []
+    #     for r in range(1, rows+1):
+    #         for c in range(1, cols+1):
+    #             for l in range(1, layers+1):
+    #                 if (r, c, l) not in existing_positions  :
+    #                     instances.append(flowlist(
+    #                         warehouse_code=warehouse_code,
+    #                         warehouse_name=warehouse_name,
+    #                         shelf_type=shelf_type,
+    #                         shelf_name=shelf_name,
+    #                         row=r,
+    #                         col=c,
+    #                         layer=l,
+
+    #                     ))
+    #     try:
+    #         with transaction.atomic():
+    #             flowlist.objects.bulk_create(instances, batch_size=1000)
+    #     except Exception as e:
+    #         return Response(
+    #             {"error": str(e)},
+    #             status=status.HTTP_500_INTERNAL_SERVER_ERROR
+    #         )
+
+    #     return Response({
+    #         "created": len(instances),
+    #         "skipped": (rows*cols*layers) - len(instances)
+    #     }, status=status.HTTP_201_CREATED)
+        
+    # def update(self, request, pk):
+    #     qs = self.get_object()
+    #     print(qs.id)
+    #     # return Response({"detail": "暂不支持修改"}, status=status.HTTP_400_BAD_REQUEST)
+       
+    #     data = self.request.data
+    #     print(data)
+    #     serializer = self.get_serializer(qs, data=data)
+    #     serializer.is_valid(raise_exception=True)
+    #     serializer.save()
+    #     headers = self.get_success_headers(serializer.data)
+    #     return Response(serializer.data, status=200, headers=headers)
+
+    # def retrieve(self, request, pk):
+    #     qs = self.get_object()
+    #     serializer = self.get_serializer(qs)
+    #     return Response(serializer.data)

+ 52 - 0
requirements.txt

@@ -0,0 +1,52 @@
+asgihandler==0.5.9
+asgiref==3.5.2
+attrs==23.1.0
+autobahn==23.1.2
+Automat==22.10.0
+certifi==2022.9.24
+cffi==1.15.1
+charset-normalizer==2.1.1
+constantly==15.1.0
+cryptography==40.0.2
+daphne==4.0.0
+Django==4.1.2
+django-cors-headers==3.13.0
+django-filter==2.4.0
+djangorestframework==3.14.0
+djangorestframework-csv==2.1.1
+drf-spectacular==0.26.2
+drf-spectacular-sidecar==2023.6.1
+et-xmlfile==1.1.0
+h2==4.1.0
+hpack==4.0.0
+hyperframe==6.0.1
+hyperlink==21.0.0
+idna==3.4
+incremental==22.10.0
+inflection==0.5.1
+jsonschema==4.17.3
+numpy==1.23.4
+openpyxl==3.0.10
+pandas==1.5.1
+priority==1.3.0
+pyasn1==0.5.0
+pyasn1-modules==0.3.0
+pycparser==2.21
+PyJWT==2.8.0
+pyOpenSSL==23.1.1
+pyrsistent==0.19.3
+python-dateutil==2.8.2
+pytz==2022.5
+PyYAML==6.0
+requests==2.28.1
+service-identity==21.1.0
+six==1.16.0
+sqlparse==0.4.3
+Twisted==22.10.0
+txaio==23.1.1
+typing_extensions==4.6.2
+tzdata==2022.5
+unicodecsv==0.14.1
+uritemplate==4.1.1
+urllib3==1.26.12
+zope.interface==6.0

+ 0 - 0
staff/__init__.py


BIN
staff/__pycache__/__init__.cpython-310.pyc


BIN
staff/__pycache__/admin.cpython-310.pyc


BIN
staff/__pycache__/apps.cpython-310.pyc


BIN
staff/__pycache__/files.cpython-310.pyc


BIN
staff/__pycache__/filter.cpython-310.pyc


BIN
staff/__pycache__/models.cpython-310.pyc


BIN
staff/__pycache__/serializers.cpython-310.pyc


BIN
staff/__pycache__/urls.cpython-310.pyc


BIN
staff/__pycache__/views.cpython-310.pyc


+ 4 - 0
staff/admin.py

@@ -0,0 +1,4 @@
+from django.contrib import admin
+from .models import ListModel
+
+admin.site.register(ListModel)

+ 43 - 0
staff/apps.py

@@ -0,0 +1,43 @@
+from django.apps import AppConfig
+from django.db.models.signals import post_migrate
+
+class StaffConfig(AppConfig):
+    name = 'staff'
+    def ready(self):
+        post_migrate.connect(do_init_data, sender=self)
+
+def do_init_data(sender, **kwargs):
+    init_category()
+
+def init_category():
+    """
+        :return:None
+    """
+    try:
+        from .models import TypeListModel as ls
+        if ls.objects.filter(openid__iexact='init_data').exists():
+            if ls.objects.filter(openid__iexact='init_data').count() != 7:
+                ls.objects.filter(openid__iexact='init_data').delete()
+                init_data = [
+                    ls(id=1, openid='init_data', staff_type='Manager', creater='GreaterWMS'),
+                    ls(id=2, openid='init_data', staff_type='Supplier', creater='GreaterWMS'),
+                    ls(id=3, openid='init_data', staff_type='Customer', creater='GreaterWMS'),
+                    ls(id=4, openid='init_data', staff_type='Supervisor', creater='GreaterWMS'),
+                    ls(id=5, openid='init_data', staff_type='Inbound', creater='GreaterWMS'),
+                    ls(id=6, openid='init_data', staff_type='Outbound', creater='GreaterWMS'),
+                    ls(id=7, openid='init_data', staff_type='StockControl', creater='GreaterWMS')
+                ]
+                ls.objects.bulk_create(init_data, batch_size=100)
+        else:
+            init_data = [
+                ls(id=1, openid='init_data', staff_type='Manager', creater='GreaterWMS'),
+                ls(id=2, openid='init_data', staff_type='Supplier', creater='GreaterWMS'),
+                ls(id=3, openid='init_data', staff_type='Customer', creater='GreaterWMS'),
+                ls(id=4, openid='init_data', staff_type='Supervisor', creater='GreaterWMS'),
+                ls(id=5, openid='init_data', staff_type='Inbound', creater='GreaterWMS'),
+                ls(id=6, openid='init_data', staff_type='Outbound', creater='GreaterWMS'),
+                ls(id=7, openid='init_data', staff_type='StockControl', creater='GreaterWMS')
+            ]
+            ls.objects.bulk_create(init_data, batch_size=100)
+    except:
+        pass

+ 33 - 0
staff/files.py

@@ -0,0 +1,33 @@
+from rest_framework_csv.renderers import CSVStreamingRenderer
+
+def file_headers():
+    return [
+        'staff_name',
+        'staff_type',
+        'create_time',
+        'update_time'
+    ]
+
+def cn_data_header():
+    return dict([
+        ('staff_name', u'员工用户名'),
+        ('staff_type', u'员工类型'),
+        ('create_time', u'创建时间'),
+        ('update_time', u'更新时间')
+    ])
+
+def en_data_header():
+    return dict([
+        ('staff_name', u'Staff Name'),
+        ('staff_type', u'Staff Type'),
+        ('create_time', u'Create Time'),
+        ('update_time', u'Update Time'),
+    ])
+
+class FileRenderCN(CSVStreamingRenderer):
+    header = file_headers()
+    labels = cn_data_header()
+
+class FileRenderEN(CSVStreamingRenderer):
+    header = file_headers()
+    labels = en_data_header()

+ 24 - 0
staff/filter.py

@@ -0,0 +1,24 @@
+from django_filters import FilterSet
+from .models import ListModel, TypeListModel
+
+class Filter(FilterSet):
+    class Meta:
+        model = ListModel
+        fields = {
+            "id": ['exact', 'iexact', 'gt', 'gte', 'lt', 'lte', 'isnull', 'in', 'range'],
+            "staff_name": ['exact', 'iexact', 'contains', 'icontains'],
+            "staff_type": ['exact', 'iexact', 'contains', 'icontains'],
+            "check_code": ['exact'],
+            "create_time": ['year', 'month', 'day', 'week_day', 'gt', 'gte', 'lt', 'lte', 'range'],
+            "update_time": ['year', 'month', 'day', 'week_day', 'gt', 'gte', 'lt', 'lte', 'range']
+        }
+
+class TypeFilter(FilterSet):
+    class Meta:
+        model = TypeListModel
+        fields = {
+            "id": ['exact', 'iexact', 'gt', 'gte', 'lt', 'lte', 'isnull', 'in', 'range'],
+            "staff_type": ['exact', 'iexact', 'contains', 'icontains'],
+            "create_time": ['year', 'month', 'day', 'week_day', 'gt', 'gte', 'lt', 'lte', 'range'],
+            "update_time": ['year', 'month', 'day', 'week_day', 'gt', 'gte', 'lt', 'lte', 'range']
+        }

+ 52 - 0
staff/migrations/0001_initial.py

@@ -0,0 +1,52 @@
+# Generated by Django 4.2.17 on 2025-02-25 16:16
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ListModel',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('staff_name', models.CharField(max_length=255, verbose_name='Staff Name')),
+                ('staff_type', models.CharField(max_length=255, verbose_name='Staff Type')),
+                ('check_code', models.IntegerField(default=8888, verbose_name='Check Code')),
+                ('openid', models.CharField(max_length=255, verbose_name='Openid')),
+                ('is_delete', models.BooleanField(default=False, verbose_name='Delete Label')),
+                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='Create Time')),
+                ('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='Update Time')),
+                ('error_check_code_counter', models.IntegerField(default=0, verbose_name='check_code error counter')),
+                ('is_lock', models.BooleanField(default=False, verbose_name='Whether the lock')),
+            ],
+            options={
+                'verbose_name': 'Staff',
+                'verbose_name_plural': 'Staff',
+                'db_table': 'staff',
+                'ordering': ['staff_name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='TypeListModel',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('staff_type', models.CharField(max_length=255, verbose_name='Staff Type')),
+                ('openid', models.CharField(max_length=255, verbose_name='Openid')),
+                ('creater', models.CharField(max_length=255, verbose_name='Creater')),
+                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='Create Time')),
+                ('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='Update Time')),
+            ],
+            options={
+                'verbose_name': 'Staff Type',
+                'verbose_name_plural': 'Staff Type',
+                'db_table': 'stafftype',
+                'ordering': ['staff_type'],
+            },
+        ),
+    ]

+ 18 - 0
staff/migrations/0002_listmodel_is_look.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2025-03-13 21:35
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('staff', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='listmodel',
+            name='is_look',
+            field=models.BooleanField(default=False, verbose_name='Whether the look'),
+        ),
+    ]

+ 18 - 0
staff/migrations/0003_listmodel_appid.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2025-03-14 11:31
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('staff', '0002_listmodel_is_look'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='listmodel',
+            name='appid',
+            field=models.CharField(default=8888, max_length=100, verbose_name='APPID'),
+        ),
+    ]

+ 18 - 0
staff/migrations/0004_alter_listmodel_appid.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2025-03-14 14:04
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('staff', '0003_listmodel_appid'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='listmodel',
+            name='appid',
+            field=models.CharField(max_length=100, verbose_name='APPID'),
+        ),
+    ]

+ 18 - 0
staff/migrations/0005_listmodel_is_edit.py

@@ -0,0 +1,18 @@
+# Generated by Django 4.1.2 on 2025-03-14 22:51
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('staff', '0004_alter_listmodel_appid'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='listmodel',
+            name='is_edit',
+            field=models.BooleanField(default=False, verbose_name='Whether the edit'),
+        ),
+    ]

+ 0 - 0
staff/migrations/__init__.py


BIN
staff/migrations/__pycache__/0001_initial.cpython-310.pyc


BIN
staff/migrations/__pycache__/0002_listmodel_is_look.cpython-310.pyc


BIN
staff/migrations/__pycache__/0003_listmodel_appid.cpython-310.pyc


BIN
staff/migrations/__pycache__/0004_alter_listmodel_appid.cpython-310.pyc


BIN
staff/migrations/__pycache__/0005_listmodel_is_edit.cpython-310.pyc


BIN
staff/migrations/__pycache__/__init__.cpython-310.pyc


+ 33 - 0
staff/models.py

@@ -0,0 +1,33 @@
+from django.db import models
+
+class ListModel(models.Model):
+    staff_name = models.CharField(max_length=255, verbose_name="Staff Name")
+    staff_type = models.CharField(max_length=255, verbose_name="Staff Type")
+    check_code = models.IntegerField(default=8888, verbose_name="Check Code")
+    openid = models.CharField(max_length=255, verbose_name="Openid")
+    appid = models.CharField(max_length=100, verbose_name='APPID')
+    is_delete = models.BooleanField(default=False, verbose_name='Delete Label')
+    create_time = models.DateTimeField(auto_now_add=True, verbose_name="Create Time")
+    update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time")
+    error_check_code_counter = models.IntegerField(default=0,verbose_name='check_code error counter')
+    is_lock = models.BooleanField(default=False,verbose_name='Whether the lock')
+    is_look = models.BooleanField(default=False,verbose_name='Whether the look')
+    is_edit = models.BooleanField(default=False,verbose_name='Whether the edit')
+    class Meta:
+        db_table = 'staff'
+        verbose_name = 'Staff'
+        verbose_name_plural = "Staff"
+        ordering = ['staff_name']
+
+class TypeListModel(models.Model):
+    staff_type = models.CharField(max_length=255, verbose_name="Staff Type")
+    openid = models.CharField(max_length=255, verbose_name="Openid")
+    creater = models.CharField(max_length=255, verbose_name="Creater")
+    create_time = models.DateTimeField(auto_now_add=True, verbose_name="Create Time")
+    update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time")
+
+    class Meta:
+        db_table = 'stafftype'
+        verbose_name = 'Staff Type'
+        verbose_name_plural = "Staff Type"
+        ordering = ['staff_type']

+ 122 - 0
staff/serializers.py

@@ -0,0 +1,122 @@
+from rest_framework import serializers
+from .models import ListModel, TypeListModel
+from utils import datasolve
+
+class StaffGetSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=True, required=False)
+    staff_type = serializers.CharField(read_only=True, required=False)
+    check_code = serializers.IntegerField(read_only=True, required=False)
+    create_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    update_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+
+    class Meta:
+        model = ListModel
+        exclude = ['openid', 'is_delete', ]
+        read_only_fields = ['id', ]
+
+class StaffPostSerializer(serializers.ModelSerializer):
+    openid = serializers.CharField(read_only=False, required=False, validators=[datasolve.openid_validate])
+    staff_name = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    staff_type = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    check_code = serializers.IntegerField(read_only=False, required=True, validators=[datasolve.data_validate])
+    class Meta:
+        model = ListModel
+        exclude = ['is_delete', ]
+        read_only_fields = ['id', 'create_time', 'update_time', ]
+
+class StaffUpdateSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    staff_type = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+   
+    class Meta:
+        model = ListModel
+        exclude = ['openid', 'is_delete', ]
+        read_only_fields = ['id', 'create_time', 'update_time', 'appid']
+
+class StaffPartialUpdateSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=False, required=False, validators=[datasolve.data_validate])
+    staff_type = serializers.CharField(read_only=False, required=False, validators=[datasolve.data_validate])
+    class Meta:
+        model = ListModel
+        exclude = ['openid', 'is_delete', ]
+        read_only_fields = ['id', 'create_time', 'update_time', ]
+
+class FileRenderSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=False, required=False)
+    staff_type = serializers.CharField(read_only=False, required=False)
+    create_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    update_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+
+    class Meta:
+        model = ListModel
+        ref_name = 'StaffFileRenderSerializer'
+        exclude = ['openid', 'is_delete', ]
+
+class StaffTypeGetSerializer(serializers.ModelSerializer):
+    staff_type = serializers.CharField(read_only=True, required=False)
+    creater = serializers.CharField(read_only=True, required=False)
+    create_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    update_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    class Meta:
+        model = TypeListModel
+        exclude = ['openid']
+        read_only_fields = ['id', ]
+
+
+class userStaffGetSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=True, required=False)
+    staff_type = serializers.CharField(read_only=True, required=False)
+    create_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    update_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+
+    class Meta:
+        model = ListModel
+        exclude = ['openid', 'is_delete',  'check_code', ]
+        read_only_fields = ['id', ]
+
+class userStaffPostSerializer(serializers.ModelSerializer):
+    openid = serializers.CharField(read_only=False, required=False, validators=[datasolve.openid_validate])
+    staff_name = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    staff_type = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    check_code = serializers.IntegerField(read_only=False, required=True, validators=[datasolve.data_validate])
+    class Meta:
+        model = ListModel
+        exclude = ['is_delete', ]
+        read_only_fields = ['id', 'create_time', 'update_time', ]
+
+class userStaffUpdateSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    staff_type = serializers.CharField(read_only=False, required=True, validators=[datasolve.data_validate])
+    class Meta:
+        model = ListModel
+        exclude = ['openid', 'is_delete', ]
+        read_only_fields = ['id', 'create_time', 'update_time','appid' ]
+
+class userStaffPartialUpdateSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=False, required=False, validators=[datasolve.data_validate])
+    staff_type = serializers.CharField(read_only=False, required=False, validators=[datasolve.data_validate])
+    class Meta:
+        model = ListModel
+        exclude = ['openid', 'is_delete', ]
+        read_only_fields = ['id', 'create_time', 'update_time', ]
+
+class userFileRenderSerializer(serializers.ModelSerializer):
+    staff_name = serializers.CharField(read_only=False, required=False)
+    staff_type = serializers.CharField(read_only=False, required=False)
+    create_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    update_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+
+    class Meta:
+        model = ListModel
+        ref_name = 'StaffFileRenderSerializer'
+        exclude = ['openid', 'is_delete', ]
+
+class userStaffTypeGetSerializer(serializers.ModelSerializer):
+    staff_type = serializers.CharField(read_only=True, required=False)
+    creater = serializers.CharField(read_only=True, required=False)
+    create_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    update_time = serializers.DateTimeField(read_only=True, format='%Y-%m-%d %H:%M:%S')
+    class Meta:
+        model = TypeListModel
+        exclude = ['openid']
+        read_only_fields = ['id', ]

+ 0 - 0
staff/tests.py


+ 14 - 0
staff/urls.py

@@ -0,0 +1,14 @@
+from django.urls import path, re_path
+from . import views
+
+urlpatterns = [
+path(r'', views.APIViewSet.as_view({"get": "list", "post": "create"}), name="staff"),
+path(r'type/', views.TypeAPIViewSet.as_view({"get": "list"}), name="stafftype"),
+path(r'file/', views.FileDownloadView.as_view({"get": "list"}), name="stafffiledownload"),
+re_path(r'^(?P<pk>\d+)/$', views.APIViewSet.as_view({
+    'get': 'retrieve',
+    'put': 'update',
+    'patch': 'partial_update',
+    'delete': 'destroy'
+}), name="staff_1")
+]

+ 261 - 0
staff/views.py

@@ -0,0 +1,261 @@
+from rest_framework import viewsets
+from .models import ListModel, TypeListModel
+from . import serializers
+from utils.page import MyPageNumberPagination
+from rest_framework.filters import OrderingFilter
+from django_filters.rest_framework import DjangoFilterBackend
+from rest_framework.response import Response
+from .filter import Filter, TypeFilter
+from rest_framework.exceptions import APIException
+from .serializers import FileRenderSerializer
+from django.http import StreamingHttpResponse
+from .files import FileRenderCN, FileRenderEN
+from rest_framework.settings import api_settings
+from rest_framework import permissions
+from staff.models import ListModel as staff
+from utils.md5 import Md5
+import random
+from django.contrib.auth.models import User
+
+
+class APIViewSet(viewsets.ModelViewSet):
+    """
+        retrieve:
+            Response a data list(get)
+
+        list:
+            Response a data list(all)
+
+        create:
+            Create a data line(post)
+
+        delete:
+            Delete a data line(delete)
+
+        partial_update:
+            Partial_update a data(patch:partial_update)
+
+        update:
+            Update a data(put:update)
+    """
+    pagination_class = MyPageNumberPagination
+    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
+    ordering_fields = ['id', "create_time", "update_time", ]
+    filter_class = Filter
+
+    def list(self, request, *args, **kwargs):
+        # staff_name = str(request.GET.get('staff_name'))
+        # check_code = request.GET.get('check_code')
+        # if staff_name == None and check_code == None:
+        #     return super().list(request, *args, **kwargs)
+        # elif staff_name != None and check_code == None:
+        #     return super().list(request, *args, **kwargs)
+        # else:
+        #     staff_name_obj = ListModel.objects.filter(openid=self.request.auth.openid, staff_name=staff_name,
+        #                                               is_delete=False).first()
+        #     if staff_name_obj is None:
+        #         raise APIException({"detail": "用户名不存在"})
+        #     elif staff_name_obj.is_lock is True:
+        #         raise APIException({"detail": "用户已被锁定,请联系管理员"})
+        #     elif staff_name_obj.error_check_code_counter == 3:
+        #         staff_name_obj.is_lock = True
+        #         staff_name_obj.error_check_code_counter = 0
+        #         staff_name_obj.save()
+        #         raise APIException({"detail": "用户已被锁定,请联系管理员"})
+
+        #     if type(check_code) == str:
+        #         check_code = int(check_code)
+        #     if check_code != None:
+        #         if staff_name_obj.check_code != check_code:
+        #             staff_name_obj.error_check_code_counter = int(staff_name_obj.error_check_code_counter) + 1
+        #             staff_name_obj.save()
+        #             raise APIException({"detail": "验证码错误"})
+        #         else:
+        #             staff_name_obj.error_check_code_counter = 0
+        #             staff_name_obj.save()
+        #             return super().list(request, *args, **kwargs)
+        #     else:
+                return super().list(request, *args, **kwargs)
+
+
+    def get_project(self):
+        try:
+            id = self.kwargs.get('pk')
+            return id
+        except:
+            return None
+
+    def get_queryset(self):
+        id = self.get_project()
+        if self.request.user:
+            if id is None:               
+                return ListModel.objects.filter(is_delete=False)
+            else:
+                return ListModel.objects.filter(id=id, is_delete=False)
+        else:
+            return ListModel.objects.none()
+
+    def get_serializer_class(self):
+        appid = self.request.META.get('HTTP_APPID')
+        token = self.request.META.get('HTTP_TOKEN')
+        if appid != token :
+            if self.action in ['list', 'retrieve', 'destroy']:
+                return serializers.userStaffGetSerializer
+            elif self.action in ['create']:
+                return serializers.userStaffPostSerializer
+            elif self.action in ['update']:
+                return serializers.userStaffUpdateSerializer
+            elif self.action in ['partial_update']:
+                return serializers.userStaffPartialUpdateSerializer
+            else:
+                return self.http_method_not_allowed(request=self.request)
+        else:  
+            if self.action in ['list', 'retrieve', 'destroy']:
+                return serializers.StaffGetSerializer
+            elif self.action in ['create']:
+                return serializers.StaffPostSerializer
+            elif self.action in ['update']:
+                return serializers.StaffUpdateSerializer
+            elif self.action in ['partial_update']:
+                return serializers.StaffPartialUpdateSerializer
+            else:
+                return self.http_method_not_allowed(request=self.request)
+
+    def create(self, request, *args, **kwargs):
+        data = self.request.data
+        data['openid'] = self.request.auth.openid
+        if ListModel.objects.filter(openid=data['openid'], staff_name=data['staff_name'], is_delete=False).exists():
+            raise APIException({"detail": "Data exists"})
+        else:
+            app_code =Md5.md5(data['staff_name']+ '1')
+            data['appid'] = app_code
+            check_code = random.randint(1000, 9999)
+           
+            data['check_code'] = check_code
+            user = User.objects.create_user(username=str(data['staff_name']),
+                                password=str(check_code))
+            serializer = self.get_serializer(data=data)
+            serializer.is_valid(raise_exception=True)
+            serializer.save()
+            headers = self.get_success_headers(serializer.data)
+            return Response(serializer.data, status=200, headers=headers)
+
+    def update(self, request, pk):
+        qs = self.get_object()
+        if qs.openid != self.request.auth.openid:
+            creator = ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False)
+            raise APIException({"detail": "该用户不是您创建的,不能修改"})
+        else:
+            data = self.request.data
+            serializer = self.get_serializer(qs, data=data)
+            serializer.is_valid(raise_exception=True)
+            serializer.save()
+            headers = self.get_success_headers(serializer.data)
+            return Response(serializer.data, status=200, headers=headers)
+
+    def partial_update(self, request, pk):
+        qs = self.get_object()
+        if qs.openid != self.request.auth.openid:
+            raise APIException({"detail": "Cannot Update Data Which Not Yours"})
+        else:
+            data = self.request.data
+            serializer = self.get_serializer(qs, data=data, partial=True)
+            serializer.is_valid(raise_exception=True)
+            serializer.save()
+            headers = self.get_success_headers(serializer.data)
+            return Response(serializer.data, status=200, headers=headers)
+
+    def destroy(self, request, pk):
+
+        qs = self.get_object()
+        if qs.openid != self.request.auth.openid:
+            raise APIException({"detail": "Cannot Delete Data Which Not Yours"})
+        else:
+            qs.is_delete = True
+            qs.save()
+            serializer = self.get_serializer(qs, many=False)
+            headers = self.get_success_headers(serializer.data)
+            return Response(serializer.data, status=200, headers=headers)
+
+
+
+     
+
+
+class TypeAPIViewSet(viewsets.ModelViewSet):
+    """
+        list:
+            Response a data list(all)
+    """
+    pagination_class = MyPageNumberPagination
+    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
+    ordering_fields = ['id', "create_time", "update_time", ]
+    filter_class = TypeFilter
+
+    def get_queryset(self):
+        if self.request.user:
+            return TypeListModel.objects.filter(openid='init_data')
+        else:
+            return TypeListModel.objects.none()
+
+    def get_serializer_class(self):
+        if self.action in ['list']:
+            return serializers.StaffTypeGetSerializer
+        else:
+            return self.http_method_not_allowed(request=self.request)
+
+
+class FileDownloadView(viewsets.ModelViewSet):
+    renderer_classes = (FileRenderCN,) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
+    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
+    ordering_fields = ['id', "create_time", "update_time", ]
+    filter_class = Filter
+
+    def get_project(self):
+        try:
+            id = self.kwargs.get('pk')
+            return id
+        except:
+            return None
+
+    def get_queryset(self):
+        id = self.get_project()
+        if self.request.user:
+            if id is None:
+                return ListModel.objects.filter(openid=self.request.auth.openid, is_delete=False)
+            else:
+                return ListModel.objects.filter(openid=self.request.auth.openid, id=id, is_delete=False)
+        else:
+            return ListModel.objects.none()
+
+    def get_serializer_class(self):
+        if self.action in ['list']:
+            return serializers.FileRenderSerializer
+        else:
+            return self.http_method_not_allowed(request=self.request)
+
+    def get_lang(self, data):
+        lang = self.request.META.get('HTTP_LANGUAGE')
+        if lang:
+            if lang == 'zh-hans':
+                return FileRenderCN().render(data)
+            else:
+                return FileRenderEN().render(data)
+        else:
+            return FileRenderEN().render(data)
+
+    def list(self, request, *args, **kwargs):
+        from datetime import datetime
+        dt = datetime.now()
+        data = (
+            FileRenderSerializer(instance).data
+            for instance in self.filter_queryset(self.get_queryset())
+        )
+        renderer = self.get_lang(data)
+        response = StreamingHttpResponse(
+            renderer,
+            content_type="text/csv"
+        )
+        response['Content-Disposition'] = "attachment; filename='staff_{}.csv'".format(
+            str(dt.strftime('%Y%m%d%H%M%S%f')))
+        return response

+ 0 - 0
static/__init__.py


BIN
static/img/GreaterWMS.png


BIN
static/img/GreaterWMS_en.png


BIN
static/img/Katie.jpg


BIN
static/img/alipay.jpg


BIN
static/img/contact.png


BIN
static/img/dongtai.png


BIN
static/img/dongtai1.png


BIN
static/img/github.png


+ 0 - 0
static/img/logo.png


Некоторые файлы не были показаны из-за большого количества измененных файлов