├── .gitignore ├── .gitmodules ├── LICENSE ├── PPWuLiu ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── README.md ├── init_data.json ├── init_database.sh ├── logs ├── log.txt └── request_exceptions.txt ├── manage.py ├── screenshots ├── P0.jpg ├── P1.jpg ├── P2.jpg ├── P3.jpg ├── P4.jpg └── P5.jpg ├── static ├── css │ ├── custom.css │ ├── duDatepicker.css │ ├── duDialog.css │ ├── mdtimepicker.css │ ├── mdtoast.css │ ├── multiple-select │ │ ├── multiple-select.min.css │ │ └── theme │ │ │ └── bootstrap.min.css │ └── remixicon │ │ ├── remixicon.css │ │ ├── remixicon.eot │ │ ├── remixicon.less │ │ ├── remixicon.svg │ │ ├── remixicon.symbol.svg │ │ ├── remixicon.ttf │ │ ├── remixicon.woff │ │ └── remixicon.woff2 ├── img │ └── background.jpg └── js │ ├── custom.js │ ├── duDatepicker.min.js │ ├── duDialog.min.js │ ├── js.cookie-3.0.0.min.js │ ├── mdtimepicker.min.js │ ├── mdtoast.min.js │ └── multiple-select.min.js ├── utils ├── __init__.py ├── common │ ├── __init__.py │ ├── _common.py │ └── expire_lru_cache.py ├── export_excel.py ├── templatetags │ ├── __init__.py │ └── utils_extras.py ├── urls.py └── views.py └── wuliu ├── __init__.py ├── admin.py ├── apis.py ├── apps.py ├── common.py ├── forms.py ├── migrations ├── 0001_squashed.py └── __init__.py ├── models.py ├── processor.py ├── templates └── wuliu │ ├── _inclusions │ ├── _form_input_field.html │ ├── _form_input_field_with_append_select.html │ ├── _full_permission_tree.html │ ├── _js │ │ ├── _export_table_to_excel.js.html │ │ └── _init_datatable.js.html │ ├── _message.html │ ├── _permission_tree.html │ ├── _sidebar_menu_items.html │ ├── _sign_for_waybill_info.html │ ├── _tables │ │ ├── _cargo_price_payment_table.html │ │ ├── _customer_score_log_table.html │ │ ├── _department_payment_table.html │ │ ├── _dst_stock_waybill_table.html │ │ ├── _stock_waybill_table.html │ │ ├── _transport_out_table.html │ │ ├── _waybill_table.html │ │ └── _waybill_table_row.html │ └── _waybill_routing_operation_info.html │ ├── _js │ ├── confirm_sign_for.js.html │ ├── edit_cargo_price_payment.js.html │ ├── edit_transport_out.js.html │ ├── edit_waybill.js.html │ ├── manage_cargo_price_payment.js.html │ ├── manage_department_payment.js.html │ ├── manage_transport_out.js.html │ ├── manage_waybill.js.html │ └── welcome_action.js.html │ ├── _layout.html │ ├── arrival │ ├── confirm_arrival.html │ └── manage_arrival.html │ ├── change_password.html │ ├── finance │ ├── cargo_price_payment │ │ ├── _layout_edit_cargo_price_payment.html │ │ ├── add_cargo_price_payment.html │ │ ├── detail_cargo_price_payment.html │ │ ├── edit_cargo_price_payment.html │ │ └── manage_cargo_price_payment.html │ ├── customer_score_log │ │ ├── add_customer_score_log.html │ │ └── manage_customer_score.html │ └── department_payment │ │ ├── add_department_payment.html │ │ ├── detail_department_payment.html │ │ └── manage_department_payment.html │ ├── login.html │ ├── report_table │ ├── dst_stock_waybill.html │ ├── dst_waybill.html │ ├── sign_for_waybill.html │ ├── src_waybill.html │ └── stock_waybill.html │ ├── settings │ ├── user │ │ ├── add_user.html │ │ └── manage_users.html │ └── user_permission │ │ ├── batch_edit_user_permission.html │ │ └── manage_user_permission.html │ ├── sign_for │ ├── confirm_sign_for.html │ └── manage_sign_for.html │ ├── transport_out │ ├── _layout_edit_transport_out.html │ ├── add_transport_out.html │ ├── detail_transport_out.html │ ├── edit_transport_out.html │ ├── manage_transport_out.html │ └── search_waybills_to_transport_out.html │ ├── waybill │ ├── _layout_edit_waybill.html │ ├── _layout_search_waybill.html │ ├── add_waybill.html │ ├── confirm_return_waybill.html │ ├── detail_waybill.html │ ├── edit_waybill.html │ ├── manage_waybill.html │ └── quick_search_waybill.html │ └── welcome.html ├── templatetags ├── __init__.py └── wuliu_extras.py ├── tests.py ├── urls.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | logs 132 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "static/AdminLTE-3.0.5"] 2 | path = static/AdminLTE-3.0.5 3 | url = https://github.com/Pzqqt/AdminLTE.git 4 | branch = v3.0.5-tms 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Pzqqt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PPWuLiu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/PPWuLiu/__init__.py -------------------------------------------------------------------------------- /PPWuLiu/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for PPWuLiu project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from channels.auth import AuthMiddlewareStack 13 | from channels.routing import ProtocolTypeRouter, URLRouter 14 | from django.core.asgi import get_asgi_application 15 | 16 | import websocket.routing as websocket_routing 17 | 18 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'PPWuLiu.settings') 19 | 20 | # application = get_asgi_application() 21 | application = ProtocolTypeRouter({ 22 | "http": get_asgi_application(), 23 | "websocket": AuthMiddlewareStack( 24 | URLRouter( 25 | websocket_routing.websocket_urlpatterns 26 | ) 27 | ), 28 | }) 29 | -------------------------------------------------------------------------------- /PPWuLiu/urls.py: -------------------------------------------------------------------------------- 1 | """PPWuLiu URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | # from django.views.generic.base import RedirectView 19 | from django.conf import settings 20 | 21 | 22 | urlpatterns = [ 23 | path('admin/', admin.site.urls), 24 | # path('', RedirectView.as_view(url='tms/login')), 25 | path('tms/', include('wuliu.urls')), 26 | path('utils/', include('utils.urls')), 27 | ] 28 | 29 | if "debug_toolbar" in settings.INSTALLED_APPS: 30 | import debug_toolbar 31 | urlpatterns.append(path('__debug__/', include(debug_toolbar.urls))) 32 | -------------------------------------------------------------------------------- /PPWuLiu/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for PPWuLiu project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'PPWuLiu.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django_Transportation_Management_System 2 | 基于Django实现的物流管理系统(TMS,Transportation Management System) 3 | 4 | 前几年工作时忙里偷闲写的练手项目。 5 | 6 | ## 特点 7 | 8 | - 前端基于Bootstrap 4框架和AdminLTE框架。 9 | - 使用MySQL作为数据库后端。 10 | - 实现了运单录入、发车出库、到货签收、客户签收等基本功能。 11 | - 拥有较为完善的报表功能和财务管理功能。 12 | - 可以通过后台界面对各个用户进行权限管理。 13 | 14 | ## 缺陷 15 | 16 | - 由于没有认清时代潮流,所以没有做前后端分离,~~本来是打算当作跳槽的敲门砖的,淦!~~。 17 | - 由于前期纯粹是抱着练手的目的写的,边学边做,所以没有保留历史提交,~~但保留了上百个历史版本的备份~~。 18 | - 由于知识匮乏,所以重复造了很多轮子。 19 | - 由于没有时间~~太懒~~,所以没有编写使用文档。 20 | 21 | ## TODO 22 | 23 | - 实现打印货物标签和提货单的功能。(需要配合打印控件) 24 | - 实现消息功能。 25 | 26 | ## 依赖 27 | 28 | - 要求Python最低版本:v3.9+ 29 | 30 | - 必要的第三方库 31 | - django 32 | - mysqlclient 33 | - openpyxl (用于实现报表导出功能) 34 | - 可选的第三方库 35 | - django-debug-toolbar (用于调试) 36 | - django-extensions (用于增强`manage.py`的功能) 37 | 38 | ## Usage 39 | 40 | - 克隆仓库 41 | - 安装并配置好MySQL,过程不再赘述 42 | - cd到项目所在目录 43 | - 同步AdminLTE-3.0.5: 44 | - 运行`git submodule init` 45 | - 运行`git submodule update --depth=1` 46 | - 编辑`PPWuliu/settings.py`,手动配置以下这些项目: 47 | - SECRET_KEY 48 | - DATABASES 49 | - 手动创建数据库(数据库名称与`PPWuliu/settings.py`中`DATABASES`所配置的一致) 50 | - 导入测试数据:运行`init_database.sh`(测试数据中的账号密码:见此文件) 51 | > 注意:在Windows环境下运行执行此shell脚本是不可能的(使用Git For Windows自带的mingw64执行也不行,会在`git apply`之后异常退出且没有任何提示),如果你一定要在Windows系统下运行此项目,请阅读`init_database.sh`并手动运行这些命令。 52 | - 运行`manage.py runserver` 53 | - Django的Admin管理后台是默认启用的,请自行创建超级用户 54 | 55 | ## 预览 56 | 57 | ![](screenshots/P0.jpg) 58 | ![](screenshots/P1.jpg) 59 | ![](screenshots/P2.jpg) 60 | ![](screenshots/P3.jpg) 61 | ![](screenshots/P4.jpg) 62 | ![](screenshots/P5.jpg) 63 | -------------------------------------------------------------------------------- /init_database.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | # 测试数据账号密码如下: 4 | 5 | # 用户名 密码 用户类型 6 | # csshd 666666 收货点 7 | # csfgs 666666 分公司(到货点) 8 | # kj_1 666666 会计(财务部) 9 | # zxg_1 666666 货物装卸工1(货台) 10 | # zxg_2 666666 货物装卸工2(货台) 11 | # pzqqt 88888888 管理员 12 | 13 | set -e 14 | 15 | # 临时修改项目中的一些代码 16 | # 这是进行数据库迁移前必要的步骤 17 | # 否则会提示某些表不存在 18 | cat < bool: 24 | """ 判断已登录的用户是否属于货场 """ 25 | return get_logged_user_type(request) == User.Types.GoodsYard 26 | 27 | -def _gen_permission_tree_list(root_pg_=PermissionGroup.objects.get(father__isnull=True)) -> list: 28 | +def _gen_permission_tree_list(root_pg_) -> list: 29 | """ 根据所有的权限组和权限的层级结构生成列表, 用于前端渲染 """ 30 | tree_list = [] 31 | for pg in PermissionGroup.objects.filter(father=root_pg_): 32 | @@ -59,7 +59,7 @@ def _gen_permission_tree_list(root_pg_=PermissionGroup.objects.get(father__isnul 33 | }) 34 | return tree_list 35 | 36 | -PERMISSION_TREE_LIST = _gen_permission_tree_list() 37 | +PERMISSION_TREE_LIST = [] 38 | 39 | def login_required(raise_404=False): 40 | """ 自定义装饰器, 用于装饰路由方法 41 | diff --git a/wuliu/urls.py b/wuliu/urls.py 42 | index 92406c3..8c5aa12 100644 43 | --- a/wuliu/urls.py 44 | +++ b/wuliu/urls.py 45 | @@ -1,6 +1,5 @@ 46 | from django.urls import path, include 47 | 48 | -from . import views, apis 49 | 50 | # Unused 51 | def easy_path(view_func): 52 | @@ -8,6 +7,8 @@ def easy_path(view_func): 53 | return path(view_func.__name__, view_func, name=view_func.__name__) 54 | 55 | app_name = "wuliu" 56 | +urlpatterns = [] 57 | +''' 58 | urlpatterns = [ 59 | # 登录 60 | path("login", views.login, name="login"), 61 | @@ -136,3 +137,4 @@ urlpatterns = [ 62 | ])), 63 | ])), 64 | ] 65 | +''' 66 | EOF 67 | 68 | # 进行数据库迁移 69 | python3 ./manage.py migrate 70 | # 开始导入测试数据 71 | python3 ./manage.py loaddata init_data.json 72 | 73 | # 将wuliu目录下的文件还原到修改之前的状态 74 | git checkout -- ./wuliu 75 | 76 | echo "Done!" 77 | -------------------------------------------------------------------------------- /logs/log.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/logs/log.txt -------------------------------------------------------------------------------- /logs/request_exceptions.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/logs/request_exceptions.txt -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'PPWuLiu.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /screenshots/P0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/screenshots/P0.jpg -------------------------------------------------------------------------------- /screenshots/P1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/screenshots/P1.jpg -------------------------------------------------------------------------------- /screenshots/P2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/screenshots/P2.jpg -------------------------------------------------------------------------------- /screenshots/P3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/screenshots/P3.jpg -------------------------------------------------------------------------------- /screenshots/P4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/screenshots/P4.jpg -------------------------------------------------------------------------------- /screenshots/P5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/screenshots/P5.jpg -------------------------------------------------------------------------------- /static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* 单行代码 */ 2 | code { 3 | color: #2d85ca; 4 | padding: 2px 4px; 5 | font-size: 90%; 6 | background-color: #f0f3f3; 7 | border-radius: 4px; 8 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 9 | } 10 | /* 必填表单项label字符串前加红色星号 */ 11 | .label-required:before { 12 | content: "* "; 13 | color: #eb4434; 14 | } 15 | /* 限制textarea的最大高度, 并禁止调整宽度 */ 16 | textarea { 17 | resize: vertical; 18 | min-height: 60px; 19 | } 20 | /* 运单信息中的总价 */ 21 | .total-fee:before { 22 | content: "¥ "; 23 | } 24 | .total-fee { 25 | font-size: 16px; 26 | color: #eb4434; 27 | font-weight: 700; 28 | } 29 | /* 阻止表格内容折行 */ 30 | .table th, .table td { 31 | white-space: nowrap; 32 | } 33 | /* 适当调整form label上下填充 */ 34 | form label { 35 | margin-top: .25rem; 36 | margin-bottom: .25rem; 37 | } 38 | /* 适当降低legend字体大小, 并调整上下边距 */ 39 | legend { 40 | margin-top: .15rem; 41 | margin-bottom: .25rem; 42 | font-size: 1.25rem; 43 | } 44 | /* 子元素对齐 */ 45 | .child-flex { 46 | display: flex; 47 | } 48 | .child-flex-xc { 49 | justify-content: center; 50 | } 51 | .child-flex-xr { 52 | justify-content: right; 53 | } 54 | .child-flex-yc { 55 | align-items: center; 56 | } 57 | /* 对RemixIcon的一些自定义调整 */ 58 | .ri-c { 59 | line-height: 1; /* 固定行高 */ 60 | vertical-align: text-bottom; /* 向底端对齐 */ 61 | font-size: 125%; /* 适当增大 (5/4) */ 62 | } 63 | .ri-c span { 64 | font-size: 80%; /* 缩小到与icon大小相同 (4/5) */ 65 | vertical-align: text-top; 66 | padding-left: .25rem; 67 | } 68 | /* 用户头像 */ 69 | .nav-user-icon { 70 | margin-right: .25rem; 71 | width: 2.125rem; 72 | } 73 | /* 对用户权限树元素的一些排版调整 */ 74 | .tree-pl { 75 | padding-left: 2.75rem; 76 | } 77 | .tree-icon-pl { 78 | padding-right: 1.75rem; 79 | } 80 | .permission-padding-fix { 81 | padding-left: 1.15rem 82 | } 83 | .custom-checkbox-label-fix::before { 84 | top: .125rem; 85 | } 86 | .custom-checkbox-label-fix::after { 87 | top: .125rem; 88 | } 89 | -------------------------------------------------------------------------------- /static/css/mdtoast.css: -------------------------------------------------------------------------------- 1 | /*!Don't remove this! 2 | * Material-Toast plugin styles 3 | * 4 | * Author: Dionlee Uy 5 | * Email: dionleeuy@gmail.com 6 | */ 7 | /* @import url("https://fonts.googleapis.com/css?family=Roboto:400,500"); */ 8 | .mdtoast { 9 | position: fixed; 10 | display: flex; 11 | flex-direction: row; 12 | align-items: center; 13 | justify-content: flex-start; 14 | box-sizing: border-box; 15 | padding: 0 24px; 16 | color: #fff; 17 | font-family: Roboto, sans-serif; 18 | font-size: 16px; 19 | text-align: left; 20 | outline: none; 21 | pointer-events: auto; 22 | touch-action: auto; 23 | -webkit-user-select: none; 24 | -moz-user-select: none; 25 | -ms-user-select: none; 26 | user-select: none; 27 | background-color: #323232; 28 | transform: translateY(0); 29 | transition: transform 0.23s 0ms cubic-bezier(0, 0, 0.2, 1); 30 | will-change: transform; 31 | z-index: 100002; 32 | } 33 | 34 | .mdtoast[data-position="bottom left"] { 35 | left: 24px; 36 | bottom: 24px; 37 | } 38 | 39 | .mdtoast[data-position="bottom center"] { 40 | bottom: 24px; 41 | left: 50%; 42 | transform: translateY(0) translateX(-50%); 43 | } 44 | 45 | .mdtoast[data-position="bottom right"] { 46 | right: 24px; 47 | bottom: 24px; 48 | } 49 | 50 | .mdtoast[data-position="top left"] { 51 | top: 24px; 52 | left: 24px; 53 | } 54 | 55 | .mdtoast[data-position="top center"] { 56 | top: 24px; 57 | left: 50%; 58 | transform: translateY(0) translateX(-50%); 59 | } 60 | 61 | .mdtoast[data-position="top right"] { 62 | top: 24px; 63 | right: 24px; 64 | } 65 | 66 | .mdtoast .mdt-message { 67 | display: flex; 68 | align-items: center; 69 | min-height: 48px; 70 | padding: 8px 0; 71 | opacity: 1; 72 | margin-left: 0; 73 | box-sizing: border-box; 74 | transition: opacity 0.3s 0ms cubic-bezier(0.4, 0, 1, 1); 75 | } 76 | 77 | .mdtoast .mdt-message::after { 78 | content: ''; 79 | min-height: 32px; 80 | font-size: 0; 81 | } 82 | 83 | .mdtoast .mdt-action { 84 | display: flex; 85 | align-items: center; 86 | color: #ffeb3b; 87 | text-decoration: none; 88 | cursor: pointer; 89 | letter-spacing: 0.07em; 90 | font-weight: 500; 91 | padding: 8px; 92 | margin: 0 0 0 24px; 93 | opacity: 1; 94 | min-height: 32px; 95 | background: none; 96 | border: none; 97 | outline: none; 98 | box-sizing: border-box; 99 | border-radius: 4px; 100 | transition: opacity 0.3s 0ms cubic-bezier(0.4, 0, 1, 1), background-color 0.15s linear; 101 | } 102 | 103 | .mdtoast .mdt-action:focus, .mdtoast .mdt-action:hover { 104 | background-color: rgba(255, 255, 255, 0.075); 105 | } 106 | 107 | .mdtoast .mdt-action:active { 108 | background-color: rgba(255, 255, 255, 0.15); 109 | } 110 | 111 | .mdtoast.mdt--load { 112 | transition: transform 0.23s 0ms cubic-bezier(0.4, 0, 1, 1); 113 | } 114 | 115 | .mdtoast.mdt--load[data-position*='bottom'] { 116 | transform: translateY(150%); 117 | } 118 | 119 | .mdtoast.mdt--load[data-position*='top'] { 120 | transform: translateY(-150%); 121 | } 122 | 123 | .mdtoast.mdt--load .mdt-message { 124 | opacity: 0; 125 | } 126 | 127 | .mdtoast.mdt--load .mdt-action { 128 | opacity: 0; 129 | } 130 | 131 | .mdtoast.mdt--interactive { 132 | padding-right: 16px; 133 | } 134 | 135 | .mdtoast.mdt--interactive .mdt-message { 136 | margin-right: auto; 137 | } 138 | 139 | .mdtoast.mdt--info { 140 | background-color: #1565c0; 141 | } 142 | 143 | .mdtoast.mdt--error { 144 | background-color: #e53935; 145 | } 146 | 147 | .mdtoast.mdt--warning { 148 | background-color: #ef6c00; 149 | } 150 | 151 | .mdtoast.mdt--success { 152 | background-color: #2e7d32; 153 | } 154 | 155 | @media (min-width: 600px) { 156 | .mdtoast { 157 | min-width: 288px; 158 | max-width: 568px; 159 | border-radius: 4px; 160 | } 161 | .mdtoast.mdt--load[data-position='bottom center'] { 162 | transform: translateY(150%) translateX(-50%); 163 | } 164 | .mdtoast.mdt--load[data-position='top center'] { 165 | transform: translateY(-150%) translateX(-50%); 166 | } 167 | } 168 | 169 | @media (max-width: 599px) { 170 | .mdtoast { 171 | left: 0 !important; 172 | right: 0 !important; 173 | font-size: 14px; 174 | max-width: 100%; 175 | transform: translateY(0); 176 | } 177 | .mdtoast[data-position*='bottom'] { 178 | bottom: 0; 179 | transform: translateY(0); 180 | } 181 | .mdtoast[data-position*='top'] { 182 | top: 0; 183 | transform: translateY(0); 184 | } 185 | .mdtoast.mdt--load { 186 | transform: translateY(100%); 187 | } 188 | } 189 | 190 | body.mdtoast--modal { 191 | pointer-events: none; 192 | touch-action: none; 193 | -ms-user-select: none; 194 | -webkit-user-select: none; 195 | -moz-user-select: none; 196 | user-select: none; 197 | } 198 | -------------------------------------------------------------------------------- /static/css/multiple-select/multiple-select.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * multiple-select - Multiple select is a jQuery plugin to select multiple elements with checkboxes :). 3 | * 4 | * @version v1.5.2 5 | * @homepage http://multiple-select.wenzhixin.net.cn 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | @charset "UTF-8";.ms-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:auto!important;top:auto!important}.ms-parent{display:inline-block;position:relative;vertical-align:middle}.ms-choice{display:block;width:100%;height:26px;padding:0;overflow:hidden;cursor:pointer;border:1px solid #aaa;text-align:left;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;border-radius:4px;background-color:#fff}.ms-choice.disabled{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.ms-choice>span{position:absolute;top:0;left:0;right:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding-left:8px}.ms-choice>span.placeholder{color:#999}.ms-choice>div.icon-close{position:absolute;top:0;right:16px;height:100%;width:16px}.ms-choice>div.icon-close:before{content:'×';color:#888;font-weight:bold;position:absolute;top:50%;margin-top:-14px}.ms-choice>div.icon-close:hover:before{color:#333}.ms-choice>div.icon-caret{position:absolute;width:0;height:0;top:50%;right:8px;margin-top:-2px;border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px}.ms-choice>div.icon-caret.open{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.ms-drop{width:auto;min-width:100%;overflow:hidden;display:none;/* margin-top:-1px; */padding:0;position:absolute;z-index:1000;background:#fff;color:#000;/* border:1px solid #aaa; */border:1px solid #ced4da;border-radius:4px}.ms-drop.bottom{top:100%;/* box-shadow:0 4px 5px rgba(0,0,0,0.15) */}.ms-drop.top{bottom:100%;box-shadow:0 -4px 5px rgba(0,0,0,0.15)}.ms-search{display:inline-block;margin:0;min-height:26px;padding:2px;position:relative;white-space:nowrap;width:100%;z-index:10000;box-sizing:border-box}.ms-search input{width:100%;height:auto!important;min-height:24px;padding:0 5px;margin:0;outline:0;font-family:sans-serif;border:1px solid #aaa;border-radius:5px;box-shadow:none}.ms-drop ul{overflow:auto;margin:0;padding:0}.ms-drop ul>li{list-style:none;display:list-item;background-image:none;position:static;padding:.25rem 8px}.ms-drop ul>li .disabled{font-weight:normal!important;opacity:.35;filter:Alpha(Opacity=35);cursor:default}.ms-drop ul>li.multiple{display:block;float:left}.ms-drop ul>li.group{clear:both}.ms-drop ul>li.multiple label{width:100%;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ms-drop ul>li label{position:relative;padding-left:1.25rem;margin-bottom:0;font-weight:normal;display:block;white-space:nowrap;cursor:pointer}.ms-drop ul>li label.optgroup{font-weight:bold}.ms-drop ul>li.hide-radio{padding:0}.ms-drop ul>li.hide-radio:focus,.ms-drop ul>li.hide-radio:hover{background-color:#f8f9fa}.ms-drop ul>li.hide-radio.selected{color:#fff;background-color:#007bff}.ms-drop ul>li.hide-radio label{margin-bottom:0;padding:5px 8px}.ms-drop ul>li.hide-radio input{display:none}.ms-drop ul>li.option-level-1 label{padding-left:28px}.ms-drop input[type="radio"],.ms-drop input[type="checkbox"]{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.ms-drop .ms-no-results{display:none} -------------------------------------------------------------------------------- /static/css/multiple-select/theme/bootstrap.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * multiple-select - Multiple select is a jQuery plugin to select multiple elements with checkboxes :). 3 | * 4 | * @version v1.5.2 5 | * @homepage http://multiple-select.wenzhixin.net.cn 6 | * @author wenzhixin (http://wenzhixin.net.cn/) 7 | * @license MIT 8 | */ 9 | 10 | .ms-parent.form-control{padding:0}.ms-parent.form-control .ms-choice{height:100%;border:0}.ms-parent.form-control .ms-choice>span{top:50%;transform:translateY(-50%)}.ms-parent.form-control.form-control-sm .ms-drop input[type=radio],.ms-parent.form-control.form-control-sm .ms-drop input[type=checkbox]{margin-top:.4rem}.ms-parent.form-control.form-control-lg .ms-drop input[type=radio],.ms-parent.form-control.form-control-lg .ms-drop input[type=checkbox]{margin-top:.5rem} -------------------------------------------------------------------------------- /static/css/remixicon/remixicon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/static/css/remixicon/remixicon.eot -------------------------------------------------------------------------------- /static/css/remixicon/remixicon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/static/css/remixicon/remixicon.ttf -------------------------------------------------------------------------------- /static/css/remixicon/remixicon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/static/css/remixicon/remixicon.woff -------------------------------------------------------------------------------- /static/css/remixicon/remixicon.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/static/css/remixicon/remixicon.woff2 -------------------------------------------------------------------------------- /static/img/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/static/img/background.jpg -------------------------------------------------------------------------------- /static/js/custom.js: -------------------------------------------------------------------------------- 1 | function alert_dialog(text) { 2 | new duDialog("错误", text, {okText: "确认"}); 3 | } 4 | function confirm_dialog(title, text, callbacks) { 5 | new duDialog( 6 | title, text, { 7 | buttons: duDialog.OK_CANCEL, 8 | cancelText: "取消", 9 | okText: "确认", 10 | callbacks: callbacks, 11 | }, 12 | ); 13 | } 14 | function mdtoast_success(text) { 15 | mdtoast.success(text); 16 | } 17 | function mdtoast_error(text) { 18 | mdtoast.error(text); 19 | } 20 | function find_datatable_rows_all(datatable_obj) { 21 | return datatable_obj.rows().nodes().filter(function(row) { 22 | return $(row).find("input:checkbox"); 23 | }).map($); 24 | } 25 | function find_datatable_rows_clicked(datatable_obj) { 26 | return datatable_obj.rows().nodes().filter(function(row) { 27 | return $(row).find("input:checkbox").is(":checked"); 28 | }).map($); 29 | } 30 | $.extend({ 31 | StandardPost: function(url, args){ 32 | let form = $(""); 33 | let input; 34 | $(document.body).append(form); 35 | form.attr({"action": url}); 36 | $.each(args, function(key, value) { 37 | if ($.isArray(value)) { 38 | input = $(""); 39 | input.attr({"name": key}); 40 | value.forEach(function(value_) { 41 | input.append("") 42 | }); 43 | } else { 44 | input = $(""); 45 | input.attr({"name": key}); 46 | } 47 | input.val(value); 48 | form.append(input); 49 | }); 50 | form.append( 51 | $("") 52 | ); 53 | form.submit(); 54 | form.remove(); 55 | } 56 | }); 57 | $(document).ready(function() { 58 | duDatepicker(".md-date-picker", {format: 'yyyy-mm-dd', auto: true, i18n: 'zh', maxDate: 'today'}); 59 | mdtimepicker(".md-time-picker", {is24hour: true}); 60 | $(".md-date-picker, .md-time-picker").removeAttr("readonly"); 61 | $(".select2").select2({ 62 | theme: "bootstrap4", 63 | dropdownCssClass: "text-sm", // 与body缩放匹配 64 | width: "style", // 解决越界问题 65 | minimumResultsForSearch: 5, // 可选项少于5项则禁用搜索框 66 | }); 67 | $(".multiple-select").multipleSelect({ 68 | placeholder: "未指定", 69 | formatSelectAll: function() {return "[全选]"}, 70 | formatAllSelected: function() {return "全部"}, 71 | formatCountSelected: function(count, total) {return "已选择" + count + "项"}, 72 | formatNoMatchesFound: function() {return "未选择"}, 73 | }); 74 | $('[data-widget="pushmenu"]').click(function() { 75 | Cookies.set("ui_enable_sidebar_collapse", Cookies.get("ui_enable_sidebar_collapse") !== "true"); 76 | }); 77 | // 全局禁用input获得焦点时按回车键提交表单, 除非该元素有"data-allow_enter_submit"属性 78 | $(".content-wrapper form input").keypress(function(e) { 79 | if (e.keyCode === 13 && $(this).attr("data-allow_enter_submit") === undefined) { 80 | e.preventDefault(); 81 | } 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /static/js/js.cookie-3.0.0.min.js: -------------------------------------------------------------------------------- 1 | /*! js-cookie v3.0.0 | MIT */ 2 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,function(){var n=e.Cookies,r=e.Cookies=t();r.noConflict=function(){return e.Cookies=n,r}}())}(this,(function(){"use strict";function e(e){for(var t=1;t dict: 92 | """ Django有一个内置的django.forms.models.model_to_dict方法(以下简称原model_to_dict方法) 93 | 可以方便地把模型转为字典, 但是有一个坑, 被标记为不可编辑(editable为False)的字段不会包含在输出的字典中 94 | 原model_to_dict方法仅在初始化ModelForm时被使用, 为了安全起见, 这样做无可厚非 95 | 但是我们想要的"模型转为字典"的方法应该包含模型的所有字段 96 | 所以我们参考原model_to_dict方法编写了新的model_to_dict_方法 97 | 比起原model_to_dict方法缺少了fields和exclude参数, 因为我们暂时不需要 98 | """ 99 | opts = instance._meta 100 | data = {} 101 | for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many): 102 | # 对于一对一和多对一外键, 返回外键模型对象 (多对多外键会在else子句中合适地处理) 103 | # 注: 由于ForeignKey的attname属性值为"字段名_id", 所以调用value_from_object方法的话, 返回的是外键对象的id 104 | if isinstance(f, ForeignKey): 105 | data[f.name] = getattr(instance, f.name, None) 106 | else: 107 | data[f.name] = f.value_from_object(instance) 108 | return data 109 | 110 | def del_session_item(request, *items): 111 | """ 从request会话中删除键值 """ 112 | for item in items: 113 | request.session.pop(item, None) 114 | -------------------------------------------------------------------------------- /utils/common/expire_lru_cache.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | from collections import namedtuple 3 | import threading 4 | import logging 5 | 6 | from django.utils import timezone 7 | 8 | 9 | _logger = logging.getLogger(__name__) 10 | 11 | ValueAndType = namedtuple("ValueAndType", ["value", "type"]) 12 | 13 | class ExpireLruCache: 14 | 15 | """ 一个简易的支持过期功能的缓存装饰器, 在该项目中, 用于装饰那些频繁访问数据库且不要求时效性的方法 16 | 和标准库中的functools.lru_cache一样, 被装饰的函数不能使用不可哈希的参数 17 | 参数expire_time为过期时间, 必须是datetime.timedelta类型, 默认为3分钟 18 | 参数enable_log为真值时, 则每次取出缓存时记录日志[方法名, 参数, 获取缓存的次数] 19 | """ 20 | 21 | def __init__(self, expire_time=timezone.timedelta(minutes=3), enable_log=False): 22 | assert isinstance(expire_time, timezone.timedelta), "expire_time参数必须为datetime.timedelta类型" 23 | self.expire_time = expire_time 24 | self.enable_log = enable_log 25 | self._dic = {} 26 | self._lock = threading.RLock() 27 | 28 | @staticmethod 29 | def _print_log(func, args, kwargs, count): 30 | _logger.info("%s: function name: %s, args: (%s), get cache count: %s" % ( 31 | __name__, 32 | func.__name__, 33 | ", ".join([*[str(arg) for arg in args], *["%s=%s" % (k, v) for k, v in kwargs]]), 34 | count, 35 | )) 36 | 37 | def __call__(self, func): 38 | @wraps(func) 39 | def _func(*args, **kwargs): 40 | # 被装饰函数调用时的每个参数都必须是可哈希的 41 | hashable_args = tuple((ValueAndType(value=arg, type=type(arg)) for arg in args)) 42 | hashable_kwargs = frozenset(( 43 | (k, ValueAndType(value=v, type=type(v))) for k, v in kwargs.items() 44 | )) 45 | key_ = hash((func, hashable_args, hashable_kwargs)) 46 | with self._lock: 47 | if key_ in self._dic.keys(): 48 | if self._dic[key_]["latest_update_time"] + self.expire_time > timezone.now(): 49 | self._dic[key_]["count"] += 1 50 | if self.enable_log: 51 | self._print_log(func, args, kwargs, self._dic[key_]["count"]) 52 | return self._dic[key_]["result"] 53 | result = func(*args, **kwargs) 54 | with self._lock: 55 | self._dic[key_] = { 56 | "result": result, 57 | "latest_update_time": timezone.now(), 58 | "count": 0, 59 | } 60 | return result 61 | return _func 62 | 63 | ''' 64 | # ExpireLruCache的函数装饰器版, 效果与类装饰器版完全一致, 但可读性不及类装饰器版, 仅供参考 65 | 66 | def ExpireLruCache(expire_time=timezone.timedelta(minutes=3), enable_log=False): 67 | 68 | _dic = {} 69 | _lock = threading.RLock() 70 | 71 | def _print_log(func, args, kwargs, count): 72 | _logger.info("%s: function name: %s, args: (%s), get cache count: %s" % ( 73 | __name__, 74 | func.__name__, 75 | ", ".join([*[str(arg) for arg in args], *["%s=%s" % (k, v) for k, v in kwargs]]), 76 | count, 77 | )) 78 | 79 | def wrapper(func): 80 | @wraps(func) 81 | def _func(*args, **kwargs): 82 | nonlocal _dic 83 | hashable_args = tuple((ValueAndType(value=arg, type=type(arg)) for arg in args)) 84 | hashable_kwargs = frozenset(( 85 | (k, ValueAndType(value=v, type=type(v))) for k, v in kwargs.items() 86 | )) 87 | key_ = hash((func, hashable_args, hashable_kwargs)) 88 | with _lock: 89 | if key_ in _dic.keys() and _dic[key_]["latest_update_time"] + expire_time > timezone.now(): 90 | _dic[key_]["count"] += 1 91 | if enable_log: 92 | _print_log(func, args, kwargs, _dic[key_]["count"]) 93 | return _dic[key_]["result"] 94 | result = func(*args, **kwargs) 95 | with _lock: 96 | _dic[key_] = { 97 | "result": result, 98 | "latest_update_time": timezone.now(), 99 | "count": 0, 100 | } 101 | return result 102 | return _func 103 | 104 | return wrapper 105 | ''' 106 | -------------------------------------------------------------------------------- /utils/export_excel.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | from tempfile import NamedTemporaryFile 3 | 4 | from openpyxl import Workbook 5 | from openpyxl.styles import Alignment, Border, Font, Side 6 | from openpyxl.writer.excel import save_workbook 7 | 8 | def save_virtual_workbook(workbook): 9 | with NamedTemporaryFile() as f: 10 | save_workbook(workbook, f) 11 | f.seek(0) 12 | return f.read() 13 | 14 | _BD = Side(style='thin', color="000000") 15 | _CENTER = Alignment( 16 | horizontal="center", 17 | vertical="center", 18 | ) 19 | _RIGHT = Alignment( 20 | horizontal="right", 21 | vertical="center", 22 | ) 23 | _FONT_TITLE = Font(name='黑体', size=18, bold=True) 24 | _FONT_HEADER = Font(name='黑体', size=12, bold=True) 25 | _FONT_VALUE = Font(name='等线', size=12, bold=False) 26 | 27 | def add_all_border(cell_): 28 | """ 单元格添加所有细框线 """ 29 | cell_.border = Border(left=_BD, top=_BD, right=_BD, bottom=_BD) 30 | 31 | def cell_center(cell_): 32 | """ 单元格水平居中&垂直居中 """ 33 | cell_.alignment = _CENTER 34 | 35 | def cell_right(cell_): 36 | """ 单元格水平居右&垂直居中 """ 37 | cell_.alignment = _RIGHT 38 | 39 | def gen_workbook(title, thead, trs, trs_types=()): 40 | wb = Workbook() 41 | ws = wb.active 42 | ws.append([title, ]) 43 | ws.append(thead) 44 | for tr in trs: 45 | _tr = [] 46 | for index, value in enumerate(tr): 47 | try: 48 | value_type = trs_types[index] 49 | except IndexError: 50 | value_type = "str" 51 | if value_type == "str": 52 | value = str(value) 53 | elif value_type == "int": 54 | value = int(value) 55 | elif value_type == "float": 56 | value = float(value) 57 | else: 58 | raise ValueError("无法解析的列数据类型: " + str(value_type)) 59 | _tr.append(value) 60 | ws.append(_tr) 61 | # 合并首行(标题) 62 | ws.merge_cells("A1:%s1" % ws[2][-1].column_letter) 63 | # 给所有单元格设置居中+所有边框格式 64 | for cell in itertools.chain.from_iterable(ws.rows): 65 | cell_center(cell) 66 | add_all_border(cell) 67 | # 给每行单元格设置字体 68 | ws['A1'].font = _FONT_TITLE 69 | for cell in ws[2]: 70 | cell.font = _FONT_HEADER 71 | for cell in itertools.chain.from_iterable(list(ws.rows)[2:]): 72 | cell.font = _FONT_VALUE 73 | # 适应列宽 74 | for col in ws.columns: 75 | max_len_set = set() 76 | for cell in col: 77 | cell_len = 0 78 | if not cell.value: 79 | continue 80 | for char in str(cell.value): 81 | if ord(char) <= 256: 82 | cell_len += 1.3 83 | else: 84 | cell_len += 2.6 85 | max_len_set.add(cell_len) 86 | ws.column_dimensions[col[1].column_letter].width = max(max_len_set) 87 | return save_virtual_workbook(wb) 88 | 89 | def test(): 90 | title_ = "Title" 91 | thead_ = ["Head 1", "Head 2", "Head 3"] 92 | trs_ = [["Value 1", "Value 2", "Value 3"] for _ in range(9)] 93 | return gen_workbook(title_, thead_, trs_) 94 | -------------------------------------------------------------------------------- /utils/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/utils/templatetags/__init__.py -------------------------------------------------------------------------------- /utils/templatetags/utils_extras.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.utils.safestring import mark_safe 3 | 4 | register = template.Library() 5 | 6 | # Unused 7 | @register.simple_tag() 8 | def csrfmiddlewaretoken_js(): 9 | """ 用于在ajax时添加csrf_token数据, 注意结尾不再需要加逗号 10 | 示例: 11 | $.post( 12 | "post/url", 13 | { 14 | "key": "value", 15 | // "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(), 16 | // 替换为: 17 | {% csrfmiddlewaretoken_js %} 18 | }, 19 | ... 20 | ); 21 | """ 22 | return mark_safe('"csrfmiddlewaretoken": $("[name=\'csrfmiddlewaretoken\']").val(),') 23 | 24 | register.filter(name="max")(lambda value: max(value)) 25 | register.filter(name="abs")(lambda value: abs(value)) 26 | register.filter(name="sum")(lambda value: sum(value)) 27 | register.filter(name="subtract")(lambda value, arg: int(value) - int(arg)) 28 | register.filter(name="bool")(lambda value: value and 1 or 0) 29 | -------------------------------------------------------------------------------- /utils/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | app_name = "utils" 6 | urlpatterns = [ 7 | path("export_excel", views.export_excel, name="export_excel"), 8 | ] 9 | -------------------------------------------------------------------------------- /utils/views.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from django.conf import settings 4 | from django.http import HttpResponseBadRequest, HttpResponse 5 | from django.views.decorators.csrf import csrf_exempt 6 | from django.views.decorators.http import require_POST 7 | 8 | from .export_excel import gen_workbook 9 | 10 | 11 | @require_POST 12 | @csrf_exempt 13 | def export_excel(request): 14 | """ 导出excel表格 15 | 前端必须用表单"显式"提交(可以用隐藏表单), 不能用ajax, 否则无法触发下载 16 | """ 17 | table_title = request.POST.get("table_title") 18 | table_header = request.POST.get("table_header") 19 | table_rows = request.POST.get("table_rows") 20 | table_rows_value_type = request.POST.get("table_rows_value_type", '[]') 21 | if not (table_title and table_header and table_rows): 22 | return HttpResponseBadRequest() 23 | try: 24 | table_header = json.loads(table_header) 25 | table_rows = json.loads(table_rows) 26 | table_rows_value_type = json.loads(table_rows_value_type) 27 | except json.decoder.JSONDecodeError: 28 | if settings.DEBUG: 29 | raise 30 | return HttpResponseBadRequest() 31 | # 不能用FileResponse, 也不能用StreamingHttpResponse, 很奇怪 32 | response = HttpResponse(gen_workbook(table_title, table_header, table_rows, table_rows_value_type)) 33 | response["Content-Type"] = "application/octet-stream" 34 | # 此处必须编码为ansi, 否则filename有中文的话会乱码 35 | response["Content-Disposition"] = ('attachment; filename="%s.xlsx"' % table_title).encode("ansi") 36 | return response 37 | -------------------------------------------------------------------------------- /wuliu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/wuliu/__init__.py -------------------------------------------------------------------------------- /wuliu/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from . import models 4 | 5 | 6 | class PermissionGroupAdmin(admin.ModelAdmin): 7 | list_display = ["print_name", "name", "tree_str"] 8 | list_filter = ["father", ] 9 | fields = ["name", "print_name", "father"] 10 | 11 | class PermissionAdmin(admin.ModelAdmin): 12 | list_display = ["print_name", "name", "tree_str"] 13 | list_filter = ["father", ] 14 | fields = ["name", "print_name", "father"] 15 | 16 | class DepartmentAdmin(admin.ModelAdmin): 17 | list_display = [ 18 | "name", "tree_str", "unit_price", "is_branch_group", "is_branch", 19 | "enable_src", "enable_dst", "enable_cargo_price" 20 | ] 21 | list_filter = ["enable_src", "enable_dst", "enable_cargo_price"] 22 | 23 | class UserAdmin(admin.ModelAdmin): 24 | readonly_fields = ["create_time"] 25 | list_display = ["name", "department", "create_time", "administrator", "enabled"] 26 | list_filter = ["enabled"] 27 | 28 | class CustomerAdmin(admin.ModelAdmin): 29 | readonly_fields = ["score", "create_time"] 30 | list_display = ["name", "phone", "bank_name", "score", "is_vip", "enabled"] 31 | list_filter = ["is_vip", "enabled", "create_time"] 32 | 33 | class WaybillAdmin(admin.ModelAdmin): 34 | fieldsets = [ 35 | ("基本信息", {"fields": ( 36 | "src_department", "dst_department", "status", "cargo_price_status", 37 | "create_time", "arrival_time", "sign_for_time", 38 | )}), 39 | ("发货人信息", {"fields": ( 40 | "src_customer", "src_customer_name", "src_customer_phone", 41 | "src_customer_credential_num", "src_customer_address", 42 | )}), 43 | ("收货人信息", {"fields": ( 44 | "dst_customer", "dst_customer_name", "dst_customer_phone", 45 | "dst_customer_credential_num", "dst_customer_address", 46 | )}), 47 | ("货物信息", {"fields": ( 48 | "cargo_name", "cargo_num", 49 | "cargo_volume", "cargo_weight", "cargo_price", "cargo_handling_fee", 50 | )}), 51 | ("运费", {"fields": ("fee", "fee_type")}), 52 | ("其他", {"fields": ( 53 | "customer_remark", "company_remark", "drop_reason", 54 | )}), 55 | ] 56 | readonly_fields = [ 57 | "src_department", "dst_department", "cargo_price_status", 58 | "create_time", "arrival_time", "sign_for_time", 59 | "src_customer", "dst_customer", 60 | "cargo_num", "status", "drop_reason" 61 | ] 62 | list_display = [ 63 | "get_full_id", "src_department", "dst_department", "fee", "fee_type", 64 | "create_time", "status", "cargo_price_status" 65 | ] 66 | list_filter = ["create_time"] 67 | 68 | class TruckAdmin(admin.ModelAdmin): 69 | readonly_fields = ["create_time"] 70 | list_display = ["number_plate", "driver_name", "driver_phone", "create_time", "enabled"] 71 | list_filter = ["enabled", "create_time"] 72 | 73 | class TransportOutAdmin(admin.ModelAdmin): 74 | readonly_fields = [ 75 | "create_time", "start_time", "end_time", 76 | "src_department", "dst_department", "status", "waybills" 77 | ] 78 | list_display = [ 79 | "get_full_id", "truck", "driver_name", "src_department", "dst_department", 80 | "start_time", "end_time", "status" 81 | ] 82 | list_filter = ["create_time", "start_time", "end_time"] 83 | 84 | admin.site.register(models.Settings) 85 | admin.site.register(models.Department, DepartmentAdmin) 86 | admin.site.register(models.User, UserAdmin) 87 | admin.site.register(models.Customer, CustomerAdmin) 88 | admin.site.register(models.Waybill, WaybillAdmin) 89 | # admin.site.register(models.WaybillRouting) 90 | admin.site.register(models.Truck, TruckAdmin) 91 | admin.site.register(models.TransportOut, TransportOutAdmin) 92 | admin.site.register(models.Permission, PermissionAdmin) 93 | admin.site.register(models.PermissionGroup, PermissionGroupAdmin) 94 | -------------------------------------------------------------------------------- /wuliu/apps.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from django.apps import AppConfig 4 | from django.core.signals import got_request_exception 5 | from django.dispatch import receiver 6 | 7 | from utils.common import traceback_and_detail_log 8 | 9 | 10 | class WuliuConfig(AppConfig): 11 | name = "wuliu" 12 | verbose_name = "物流运输管理系统" 13 | default_auto_field = "django.db.models.AutoField" 14 | 15 | _request_exception_logger = logging.getLogger(__name__) 16 | 17 | @receiver(got_request_exception) 18 | def _(sender, request, **kwargs): 19 | traceback_and_detail_log(request, _request_exception_logger) 20 | -------------------------------------------------------------------------------- /wuliu/common.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | from django.shortcuts import redirect 4 | from django.http import Http404, HttpResponseForbidden 5 | from django.utils import timezone 6 | 7 | from .models import ( 8 | User, Waybill, TransportOut, DepartmentPayment, CargoPricePayment, Permission, PermissionGroup, 9 | _get_global_settings, 10 | ) 11 | from utils.common import ExpireLruCache, model_to_dict_ 12 | 13 | 14 | _EXPIRE_LRU_CACHE_1MIN = ExpireLruCache(expire_time=timezone.timedelta(minutes=1)) 15 | 16 | get_global_settings = ExpireLruCache(expire_time=timezone.timedelta(hours=3))(_get_global_settings) 17 | 18 | @_EXPIRE_LRU_CACHE_1MIN 19 | def _get_logged_user_by_id(user_id: int) -> User: 20 | """ 根据用户id返回用户模型对象 """ 21 | return User.objects.get(id=user_id) 22 | 23 | def get_logged_user(request) -> User: 24 | """ 获取已登录的用户对象 """ 25 | return _get_logged_user_by_id(request.session["user"]["id"]) 26 | 27 | def get_logged_user_type(request) -> User.Types: 28 | """ 获取已登录的用户的用户类型 """ 29 | return get_logged_user(request).get_type 30 | 31 | @_EXPIRE_LRU_CACHE_1MIN 32 | def _get_user_permissions(user: User) -> set: 33 | """ 获取用户拥有的权限, 注意该方法返回的是集合而不是QuerySet """ 34 | return set(user.permission.all().values_list("name", flat=True)) 35 | 36 | def is_logged_user_has_perm(request, perm_name: str) -> bool: 37 | """ 检查已登录用户是否具有perm_name权限 38 | :return: True或False 39 | """ 40 | if not perm_name: 41 | return True 42 | return perm_name in _get_user_permissions(get_logged_user(request)) 43 | 44 | def is_logged_user_is_goods_yard(request) -> bool: 45 | """ 判断已登录的用户是否属于货场 """ 46 | return get_logged_user_type(request) == User.Types.GoodsYard 47 | 48 | def _gen_permission_tree_list(root_pg_=PermissionGroup.objects.get(father__isnull=True)) -> list: 49 | """ 根据所有的权限组和权限的层级结构生成列表, 用于前端渲染 """ 50 | tree_list = [] 51 | for pg in PermissionGroup.objects.filter(father=root_pg_): 52 | tree_list.append({ 53 | "id": pg.id, "name": pg.name, "print_name": pg.print_name, "children": _gen_permission_tree_list(pg) 54 | }) 55 | for p in Permission.objects.filter(father=root_pg_): 56 | tree_list.append({ 57 | "id": p.id, "name": p.name, "print_name": p.print_name, 58 | }) 59 | return tree_list 60 | 61 | PERMISSION_TREE_LIST = _gen_permission_tree_list() 62 | 63 | def login_required(raise_404=False): 64 | """ 自定义装饰器, 用于装饰路由方法 65 | 若用户未登录, 则跳转到登录页面 66 | raise_404为True时, 则跳转到404页面 67 | """ 68 | def _login_required(func): 69 | @wraps(func) 70 | def login_check(request, *args, **kwargs): 71 | if not request.session.get("user"): 72 | if raise_404: 73 | raise Http404 74 | return redirect("wuliu:login") 75 | return func(request, *args, **kwargs) 76 | return login_check 77 | return _login_required 78 | 79 | def check_permission(perm_name: str): 80 | """ 自定义装饰器, 用于在请求前检查用户是否具有perm_name权限 81 | 若无perm_name权限则跳转至403页面 82 | """ 83 | def _check_permission(func): 84 | @wraps(func) 85 | def perm_check(request, *args, **kwargs): 86 | if perm_name and not is_logged_user_has_perm(request, perm_name): 87 | return HttpResponseForbidden() 88 | return func(request, *args, **kwargs) 89 | return perm_check 90 | return _check_permission 91 | 92 | def check_administrator(func): 93 | """ 自定义装饰器, 用于在请求前检查用户是否为管理员 94 | 若不是管理员则跳转至403页面 95 | """ 96 | @wraps(func) 97 | def admin_check(request, *args, **kwargs): 98 | if not get_logged_user(request).administrator: 99 | return HttpResponseForbidden() 100 | return func(request, *args, **kwargs) 101 | return admin_check 102 | 103 | def waybill_to_dict(waybill_obj: Waybill) -> dict: 104 | """ 将Waybill对象转为字典 """ 105 | waybill_dic = model_to_dict_(waybill_obj) 106 | waybill_dic["id_"] = waybill_obj.get_full_id 107 | waybill_dic["fee_type_id"] = waybill_dic["fee_type"] 108 | waybill_dic["fee_type"] = waybill_obj.get_fee_type_display() 109 | waybill_dic["status_id"] = waybill_dic["status"] 110 | waybill_dic["status"] = waybill_obj.get_status_display() 111 | if waybill_obj.return_waybill is not None: 112 | waybill_dic["return_waybill"] = waybill_to_dict(waybill_obj.return_waybill) 113 | else: 114 | waybill_dic["return_waybill"] = None 115 | return waybill_dic 116 | 117 | def transport_out_to_dict(transport_out_obj: TransportOut) -> dict: 118 | """ 将TransportOut对象转为字典 """ 119 | to_dic = model_to_dict_(transport_out_obj) 120 | to_dic["id_"] = transport_out_obj.get_full_id 121 | to_dic["status_id"] = to_dic["status"] 122 | to_dic["status"] = transport_out_obj.get_status_display() 123 | to_dic.update(transport_out_obj.gen_waybills_info()) 124 | return to_dic 125 | 126 | def department_payment_to_dict(department_payment_obj: DepartmentPayment) -> dict: 127 | """ 将DepartmentPayment对象转为字典 """ 128 | dp_dic = model_to_dict_(department_payment_obj) 129 | dp_dic["id_"] = department_payment_obj.get_full_id 130 | dp_dic["status_id"] = dp_dic["status"] 131 | dp_dic["status"] = department_payment_obj.get_status_display() 132 | total_fee_dic = department_payment_obj.gen_total_fee() 133 | dp_dic["total_fee_now"] = total_fee_dic["fee_now"] 134 | dp_dic["total_fee_sign_for"] = total_fee_dic["fee_sign_for"] 135 | dp_dic["total_cargo_price"] = total_fee_dic["cargo_price"] 136 | dp_dic["final_total_fee"] = sum(total_fee_dic.values()) 137 | return dp_dic 138 | 139 | def cargo_price_payment_to_dict(cargo_price_payment_obj: CargoPricePayment) -> dict: 140 | """ 将CargoPricePayment对象转为字典 """ 141 | cpp_dic = model_to_dict_(cargo_price_payment_obj) 142 | cpp_dic["id_"] = cargo_price_payment_obj.get_full_id 143 | cpp_dic["status_id"] = cpp_dic["status"] 144 | cpp_dic["status"] = cargo_price_payment_obj.get_status_display() 145 | total_fee_dic = cargo_price_payment_obj.gen_total_fee() 146 | cpp_dic["total_cargo_price"] = total_fee_dic["cargo_price"] 147 | cpp_dic["total_deduction_fee"] = total_fee_dic["deduction_fee"] 148 | cpp_dic["total_cargo_handling_fee"] = total_fee_dic["cargo_handling_fee"] 149 | cpp_dic["final_fee"] = ( 150 | total_fee_dic["cargo_price"] - total_fee_dic["deduction_fee"] - total_fee_dic["cargo_handling_fee"] 151 | ) 152 | return cpp_dic 153 | -------------------------------------------------------------------------------- /wuliu/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/wuliu/migrations/__init__.py -------------------------------------------------------------------------------- /wuliu/processor.py: -------------------------------------------------------------------------------- 1 | from .models import User, CargoPricePayment, Waybill, TransportOut, DepartmentPayment 2 | 3 | def pros(request): 4 | return { 5 | "USER_TYPES": User.Types, 6 | "CPP_STATUSES": CargoPricePayment.Statuses, 7 | "WB_STATUSES": Waybill.Statuses, 8 | "WB_FEE_TYPES": Waybill.FeeTypes, 9 | "TO_STATUSES": TransportOut.Statuses, 10 | "DP_STATUSES": DepartmentPayment.Statuses, 11 | } 12 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_form_input_field.html: -------------------------------------------------------------------------------- 1 |
2 | 5 | {{ field }} 6 |
7 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_form_input_field_with_append_select.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 6 | {{ field }} 7 |
8 | 11 | 16 |
17 |
18 |
19 | 24 | 32 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_full_permission_tree.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 |
3 | {% _show_permission_tree list %} 4 |
5 | 32 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_js/_export_table_to_excel.js.html: -------------------------------------------------------------------------------- 1 | 57 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_js/_init_datatable.js.html: -------------------------------------------------------------------------------- 1 | 70 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_message.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | {{ message.message }} 5 |
6 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_permission_tree.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 | {% load bool from utils_extras %} 3 | {% for child in list %} 4 | 20 | {% endfor %} 21 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_sidebar_menu_items.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 | {% for item in items %} 3 | 28 | {% endfor %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_sign_for_waybill_info.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 运单号:{{ waybill.get_full_id }} 6 |
7 |
8 | 提付运费:{% if waybill.fee_type == WB_FEE_TYPES.SignFor %}{{ waybill.fee }}{% else %}0{% endif %} 9 |
10 |
11 | 代收款:{{ waybill.cargo_price }} 12 |
13 |
14 | 应付金额: 15 | {% if waybill.fee_type == WB_FEE_TYPES.SignFor %} 16 | {{ waybill.fee | add:waybill.cargo_price }} 17 | {% else %} 18 | {{ waybill.cargo_price }} 19 | {% endif %} 20 | 21 |
22 |
23 | 移除 24 |
25 |
26 |
27 | 61 |
-------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_cargo_price_payment_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 | {% load subtract from utils_extras %} 3 |
4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% for cargo_price_payment in cargo_price_payment_list %} 33 | 34 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {% with total_fee=cargo_price_payment.gen_total_fee %} 52 | 53 | 54 | 55 | 56 | {% endwith %} 57 | 58 | 59 | {% endfor %} 60 | 61 |
# 9 |
10 | 11 | 12 |
13 |
账单编号状态创建时间结算时间创建人收款人姓名收款人电话号码收款人银行名称收款人银行卡号收款人身份证号应付货款扣付运费手续费实付金额备注
36 |
37 | 38 | 39 |
40 |
{{ cargo_price_payment.get_full_id }}{{ cargo_price_payment.get_status_display }}{{ cargo_price_payment.create_time | date:"Y-m-d H:i:s" }}{{ cargo_price_payment.settle_accounts_time | date:"Y-m-d H:i:s" }}{{ cargo_price_payment.create_user.name }}{{ cargo_price_payment.payee_name }}{{ cargo_price_payment.payee_phone }}{{ cargo_price_payment.payee_bank_name }}{{ cargo_price_payment.payee_bank_number }}{{ cargo_price_payment.payee_credential_num }}{{ total_fee.cargo_price }}{{ total_fee.deduction_fee }}{{ total_fee.cargo_handling_fee }}{{ total_fee.cargo_price | subtract:total_fee.deduction_fee | subtract:total_fee.cargo_handling_fee }}{{ cargo_price_payment.remark }}
62 |
63 | {% js_init_datatable table_id True 4 %} 64 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_customer_score_log_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 | {% load bool from utils_extras %} 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for customer_score_log in customer_score_logs %} 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | {% endfor %} 38 | 39 |
#会员姓名会员电话变动方式变动积分变动时间操作人变更原因关联运单
23 | {{ customer_score_log.customer.name }} 24 | {{ customer_score_log.customer.phone }}{% if customer_score_log.inc_or_dec %}增加{% else %}扣减{% endif %}{{ customer_score_log.score }}{{ customer_score_log.create_time | date:"Y-m-d H:i:s" }}{% if customer_score_log.user %}{{ customer_score_log.user.name }}{% else %}系统自动生成{% endif %}{{ customer_score_log.remark }} 32 | {% if customer_score_log.waybill %} 33 | {{ customer_score_log.waybill.get_full_id }} 34 | {% endif %} 35 |
40 |
41 | {% js_init_datatable table_id False %} 42 | 59 | 60 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_department_payment_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 | {% load sum from utils_extras %} 3 |
4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% for department_payment in department_payment_list %} 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {% with total_fee_dic=department_payment.gen_total_fee %} 47 | 48 | 49 | 50 | 51 | {% endwith %} 52 | 53 | 54 | 55 | {% endfor %} 56 | 57 |
# 9 |
10 | 11 | 12 |
13 |
账单编号状态应回款日期创建时间结算时间回款部门收款部门应回款金额总计现付运费合计提付运费合计代收货款合计
34 |
35 | 36 | 37 |
38 |
{{ department_payment.get_full_id }}{{ department_payment.get_status_display }}{{ department_payment.payment_date | date:"Y-m-d" }}{{ department_payment.create_time | date:"Y-m-d H:i:s" }}{{ department_payment.settle_accounts_time | date:"Y-m-d H:i:s" }}{{ department_payment.src_department.name }}{{ department_payment.dst_department.name }}{{ total_fee_dic.values | sum }}{{ total_fee_dic.fee_now }}{{ total_fee_dic.fee_sign_for }}{{ total_fee_dic.cargo_price }}
58 |
59 | {% js_init_datatable table_id True 4 %} 60 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_dst_stock_waybill_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% for waybill in waybills_info_list %} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | {% endfor %} 49 | 50 |
#运单号码开票日期到货日期滞留天数发货部门到达部门发货人发货人电话收货人收货人电话货物名称件数体积重量代收货款运费结算方式
{{ waybill.get_full_id }}{{ waybill.create_time | date:"Y-m-d H:i:s" }}{{ waybill.arrival_time | date:"Y-m-d H:i:s" }}{{ waybill.stay_days }}{{ waybill.src_department.name }}{{ waybill.dst_department.name }}{{ waybill.src_customer_name }}{{ waybill.src_customer_phone }}{{ waybill.dst_customer_name }}{{ waybill.dst_customer_phone }}{{ waybill.cargo_name }}{{ waybill.cargo_num }}{{ waybill.cargo_volume | floatformat:2 }}{{ waybill.cargo_weight | floatformat }}{{ waybill.cargo_price }}{{ waybill.fee }}{{ waybill.get_fee_type_display }}
51 |
52 | {% js_init_datatable table_id False %} 53 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_stock_waybill_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for waybill in waybills_info_list %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {% endfor %} 35 | 36 |
#运单号码运单状态开票日期开票部门到达部门运费开票部门发车时间货场入库时间货场发车时间到货时间
{{ waybill.get_full_id }}{{ waybill.get_status_display }}{{ waybill.create_time | date:"Y-m-d H:i:s" }}{{ waybill.src_department.name }}{{ waybill.dst_department.name }}{{ waybill.fee }}{{ waybill.departed_time | date:"Y-m-d H:i:s" }}{{ waybill.goods_yard_arrived_time | date:"Y-m-d H:i:s" }}{{ waybill.goods_yard_departed_time | date:"Y-m-d H:i:s" }}{{ waybill.arrival_time | date:"Y-m-d H:i:s" }}
37 |
38 | {% js_init_datatable table_id False 3 %} 39 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_transport_out_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 |
3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% for transport_out in transport_out_list %} 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {% endfor %} 55 | 56 |
# 8 |
9 | 10 | 11 |
12 |
车次编号车次状态创建时间发车时间到达时间发车部门到达部门车牌号驾驶员驾驶员电话货物总单数货物总件数货物总体积 (m³)货物总重量 (Kg)
34 |
35 | 36 | 37 |
38 |
{{ transport_out.get_full_id }}{{ transport_out.get_status_display }}{{ transport_out.create_time | date:"Y-m-d H:i:s" }}{{ transport_out.start_time | date:"Y-m-d H:i:s" }}{{ transport_out.end_time | date:"Y-m-d H:i:s" }}{{ transport_out.src_department.name }}{{ transport_out.dst_department.name }}{{ transport_out.truck.number_plate }}{{ transport_out.driver_name }}{{ transport_out.driver_phone }}{{ transport_out.total_num }}{{ transport_out.total_cargo_num | default_if_none:0 }}{{ transport_out.total_cargo_volume | default_if_none:0 | floatformat:2 }}{{ transport_out.total_cargo_weight | default_if_none:0 | floatformat }}
57 |
58 | {% js_init_datatable table_id True 4 %} 59 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_waybill_table.html: -------------------------------------------------------------------------------- 1 | {% load wuliu_extras %} 2 |
3 | 4 | 5 | 6 | 7 | {% if have_check_box %} 8 | 14 | {% endif %} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {% for waybill in waybills_info_list %} 38 | {% show_waybill_table_row waybill table_id have_check_box %} 39 | {% endfor %} 40 | 41 |
# 9 |
10 | 11 | 12 |
13 |
运单号码运单状态开票日期到货日期提货日期发货部门到达部门发货人发货人电话收货人收货人电话货物名称件数体积重量代收货款代收货款状态运费结算方式
42 |
43 | {% if have_check_box %} 44 | {% js_init_datatable table_id True 4 %} 45 | {% else %} 46 | {% js_init_datatable table_id False 3 %} 47 | {% endif %} 48 | {% if high_light_fee %} 49 | 65 | {% endif %} 66 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_tables/_waybill_table_row.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% if have_check_box %} 4 | 5 |
6 | 7 | 8 |
9 | 10 | {% endif %} 11 | {{ waybill.get_full_id }} 12 | {{ waybill.get_status_display }} 13 | {{ waybill.create_time | date:"Y-m-d H:i:s" }} 14 | {{ waybill.arrival_time | date:"Y-m-d H:i:s" }} 15 | {{ waybill.sign_for_time | date:"Y-m-d H:i:s" }} 16 | {{ waybill.src_department.name }} 17 | {{ waybill.dst_department.name }} 18 | {{ waybill.src_customer_name }} 19 | {{ waybill.src_customer_phone }} 20 | {{ waybill.dst_customer_name }} 21 | {{ waybill.dst_customer_phone }} 22 | {{ waybill.cargo_name }} 23 | {{ waybill.cargo_num }} 24 | {{ waybill.cargo_volume | floatformat:2 }} 25 | {{ waybill.cargo_weight | floatformat }} 26 | {{ waybill.cargo_price }} 27 | {{ waybill.get_cargo_price_status_display }} 28 | {{ waybill.fee }} 29 | {{ waybill.get_fee_type_display }} 30 | 31 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_inclusions/_waybill_routing_operation_info.html: -------------------------------------------------------------------------------- 1 | {% if wr.operation_type == WB_STATUSES.Created %} 2 | {% if wr.waybill.return_waybill %} 3 | 该运单为退货运单,退货原因【{{ wr.operation_info.return_reason|default:"Unknown" }}】,原始运单【{{ wr.waybill.return_waybill.get_full_id }}】 4 | {% else %} 5 | 货物已由【{{ wr.operation_user.name }}】揽收,运单号【{{ wr.waybill.get_full_id }}】 6 | {% endif %} 7 | {% elif wr.operation_type == WB_STATUSES.Departed or wr.operation_type == WB_STATUSES.GoodsYardDeparted %} 8 | {% if transport_out %} 9 | 货物已由【{{ transport_out.src_department }}】发往【{{ transport_out.dst_department }}】,车次编号【{{ transport_out.get_full_id }}】,车牌号【{{ transport_out.truck.number_plate }}】驾驶员【{{ transport_out.driver_name }}】电话【{{ transport_out.driver_phone }}】 10 | {% endif %} 11 | {% elif wr.operation_type == WB_STATUSES.GoodsYardArrived or wr.operation_type == WB_STATUSES.Arrived %} 12 | 货物已由【{{ wr.operation_user.name }}】卸车入库 13 | {% elif wr.operation_type == WB_STATUSES.SignedFor %} 14 | 货物已由【{{ wr.waybill.sign_for_customer_name }}】签收,签收人身份证号【{{ wr.waybill.sign_for_customer_credential_num }}】 15 | {% elif wr.operation_type == WB_STATUSES.Returned %} 16 | {% if return_waybill %} 17 | 由于【{{ wr.operation_info.return_reason|default:"Unknown" }}】,客户要求退货,退货运单【{{ return_waybill.get_full_id }}】 18 | {% endif %} 19 | {% elif wr.operation_type == WB_STATUSES.Dropped %} 20 | 运单已作废,作废原因【{{ wr.waybill.drop_reason }}】 21 | {% endif %} 22 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_js/confirm_sign_for.js.html: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_js/edit_cargo_price_payment.js.html: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_js/edit_transport_out.js.html: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_js/manage_transport_out.js.html: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_js/manage_waybill.js.html: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /wuliu/templates/wuliu/_js/welcome_action.js.html: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /wuliu/templates/wuliu/arrival/confirm_arrival.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/transport_out/_layout_edit_transport_out.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}确认到货{% endblock %} 4 | {% block header_title %}确认到货{% endblock %} 5 | {% block action_bar %} 6 | 7 | {% js_export_table_to_excel "ready_transport_out" "#button_wb_export" 1 "'到货清单_' + $(\"form input[name='id_']\").val()" True %} 8 | {% endblock %} 9 | {% block waybill_table %} 10 | {% show_waybill_table waybills_info_list "ready_transport_out" False %} 11 | {% endblock %} 12 | {% block action_buttons %} 13 | 14 | 46 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/arrival/manage_arrival.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}到货管理{% endblock %} 4 | {% block header_title %}到货管理{% endblock %} 5 | {% block header_subtitle %}到货管理{% endblock %} 6 | {% block content %} 7 |
8 |
9 | {% csrf_token %} 10 |
11 |
12 |
13 | {% show_form_input_field form.transport_out_id "" "col-6 col-md" %} 14 | {% show_form_input_field form.truck_number_plate "" "col-6 col-md" %} 15 | {% show_form_input_field form.driver_name "" "col-6 col-md" %} 16 | {% show_form_input_field form.status "" "col-6 col-md" %} 17 |
18 |
19 | {% show_form_input_field form.start_date_start "" "col-6 col-md" %} 20 | {% show_form_input_field form.start_date_end "" "col-6 col-md" %} 21 | {% show_form_input_field form.src_department "" "col-6 col-md" %} 22 | {% show_form_input_field form.dst_department "" "col-6 col-md" %} 23 |
24 |
25 |
26 | 29 |
30 |
31 |
32 |
33 |
34 | 37 |
38 |
39 | {% show_transport_out_table transport_out_list "to_list" %} 40 |
41 | 63 | 64 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/change_password.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}修改密码{% endblock %} 4 | {% block header_title %}修改密码{% endblock %} 5 | {% block content %} 6 |
7 |
8 | {% csrf_token %} 9 |
10 | {% show_form_input_field form.old_password "" "col-12 col-md-7" %} 11 |
12 | 13 |
14 | {% show_form_input_field form.new_password "" "col-12 col-md-7" %} 15 | {% show_form_input_field form.new_password_again "" "col-12 col-md-7" %} 16 |
17 | 18 |
19 |
20 | 23 |
24 |
25 |
26 |
27 | 71 | {% endblock %} 72 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/cargo_price_payment/_layout_edit_cargo_price_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block head_append_js %} 4 | 5 | {% endblock %} 6 | {% block content %} 7 |
8 | {% csrf_token %} 9 |
10 | 收款人信息 11 | {% if form.id_ %} 12 | {{ form.id }} 13 |
14 | {% show_form_input_field form.id_ "" "col-8 col-md-3" %} 15 | {% if detail_view %} 16 | {% show_form_input_field form.RO_status "" "col-4 col-md-3" %} 17 | {% show_form_input_field form.RO_create_time "" "col-6 col-md-3" %} 18 | {% show_form_input_field form.RO_settle_accounts_time "" "col-6 col-md-3" %} 19 | {% else %} 20 | {% show_form_input_field form.status "" "col-4 col-md-3" %} 21 | {% show_form_input_field form.create_time "" "col-6 col-md-3" %} 22 | {% show_form_input_field form.settle_accounts_time "" "col-6 col-md-3" %} 23 | {% endif %} 24 |
25 | {% endif %} 26 |
27 | {% if not detail_view %} 28 | {% show_form_input_field form.customer "" "col-12 col-md-3" %} 29 | {% endif %} 30 | {% show_form_input_field form.payee_name "" "col-5 col-md-3" %} 31 | {% show_form_input_field form.payee_phone "" "col-7 col-md-3" %} 32 |
33 |
34 | {% show_form_input_field form.payee_bank_name "" "col-5 col-md-3" %} 35 | {% show_form_input_field form.payee_bank_number "" "col-7 col-md" %} 36 | {% show_form_input_field form.payee_credential_num "" "col-12 col-md" %} 37 |
38 |
39 | {% show_form_input_field form.remark "" "col-12 col-md-6" %} 40 | {% if detail_view %} 41 | {% show_form_input_field form.RO_reject_reason "" "col-12 col-md-6" %} 42 | {% endif %} 43 |
44 | 45 |
46 |
47 |
48 |
49 | 费用列表 50 | {% if not detail_view %} 51 |
52 |
53 |
54 | 添加运单 55 |
56 | 57 |
58 |
59 | {% endif %} 60 |
61 |
62 |
63 | {% block action_bar %} 64 | {% endblock %} 65 |
66 |
67 | {% show_waybill_table waybill_list "cpp_waybill" %} 68 |
69 |
70 | {% block action_buttons %} 71 | {% endblock %} 72 |
73 | {% endblock %} 74 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/cargo_price_payment/add_cargo_price_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/finance/cargo_price_payment/_layout_edit_cargo_price_payment.html" %} 2 | {% block title %}新建代收款转账单{% endblock %} 3 | {% block header_title %}新建代收款转账单{% endblock %} 4 | {% block form_action %}{% url 'wuliu:add_cargo_price_payment' %}{% endblock %} 5 | {% block action_bar %} 6 | 9 | {% endblock %} 10 | {% block action_buttons %} 11 | 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/cargo_price_payment/detail_cargo_price_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/finance/cargo_price_payment/_layout_edit_cargo_price_payment.html" %} 2 | {% block title %}代收款转账单详情{% endblock %} 3 | {% block header_title %}代收款转账单详情{% endblock %} 4 | {% block head_append_js %}{% endblock %} 5 | {% block form_action %}{% endblock %} 6 | {% block action_bar %} 7 |
8 |

应转账金额

9 |

10 | 代收货款总计:{{ cpp_dic.total_cargo_price }}元; 11 | 扣付运费总计:{{ cpp_dic.total_deduction_fee }}元; 12 | 扣付手续费总计:{{ cpp_dic.total_cargo_handling_fee }}元; 13 | 合计:{{ cpp_dic.final_fee }}元。 14 |

15 |
16 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/cargo_price_payment/edit_cargo_price_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/finance/cargo_price_payment/add_cargo_price_payment.html" %} 2 | {% block title %}修改代收款转账单{% endblock %} 3 | {% block header_title %}修改代收款转账单{% endblock %} 4 | {% block form_action %}{% url 'wuliu:edit_cargo_price_payment' %}{% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/cargo_price_payment/manage_cargo_price_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}代收款转账单{% endblock %} 4 | {% block header_title %}代收款转账单{% endblock %} 5 | {% block header_subtitle %}创建 -> 提交 -> 财务部审核 -> 财务部支付并结算{% endblock %} 6 | {% block head_append_js %} 7 | 8 | {% endblock %} 9 | {% block content %} 10 |
11 |
12 | {% csrf_token %} 13 |
14 |
15 |
16 | {% show_form_input_field form.create_user "" "col-6 col-md-3" %} 17 | {% show_form_input_field form.create_department "" "col-6 col-md-3" %} 18 | {% show_form_input_field form.payee_name "" "col-6 col-md-3" %} 19 | {% show_form_input_field form.status "" "col-6 col-md-3" %} 20 | {% show_form_input_field form.create_date_start "" "col-6 col-md-3" %} 21 | {% show_form_input_field form.create_date_end "" "col-6 col-md-3" %} 22 | {% show_form_input_field form.settle_accounts_date_start "" "col-6 col-md-3" %} 23 | {% show_form_input_field form.settle_accounts_date_end "" "col-6 col-md-3" %} 24 |
25 |
26 |
27 | 30 |
31 |
32 |
33 |
34 |
35 | {% if "manage_cargo_price_payment__add_edit_delete_submit"|is_logged_user_has_perm:request %} 36 | 37 | 新增 38 | 39 | 42 | 45 | 48 | {% endif %} 49 | {% if "manage_cargo_price_payment__review_reject"|is_logged_user_has_perm:request %} 50 | 53 | 56 | {% endif %} 57 | {% if "manage_cargo_price_payment__pay"|is_logged_user_has_perm:request %} 58 | 61 | {% endif %} 62 |
63 |
64 | {% show_cargo_price_payment_table cargo_price_payment_list "cargo_price_payment" %} 65 |
66 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/customer_score_log/add_customer_score_log.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load static %} 3 | {% load wuliu_extras %} 4 | {% block title %}客户积分变更{% endblock %} 5 | {% block header_title %}新增客户积分变更记录{% endblock %} 6 | {% block content %} 7 |
8 |
9 | {% csrf_token %} 10 |
11 | {% show_form_input_field form.customer "" "col-md-6" %} 12 | {% show_form_input_field form.inc_or_dec "变动方式" "col-6 col-md-3" %} 13 | {% show_form_input_field form.score "" "col-6 col-md-3" %} 14 | {% show_form_input_field form.remark "" "col-12 mb-2" %} 15 |
16 | 17 |
18 |
19 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/customer_score_log/manage_customer_score.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}客户积分记录{% endblock %} 4 | {% block header_title %}客户积分记录{% endblock %} 5 | {% block header_subtitle %}查询会员客户的积分变更记录,或手动增减积分。在查询结果中点击客户姓名可以查看客户的当前积分。{% endblock %} 6 | {% block content %} 7 |
8 |
9 | {% csrf_token %} 10 |
11 |
12 |
13 | {% show_form_input_field form.customer_name "" "col-6 col-md-3" %} 14 | {% show_form_input_field form.customer_phone "" "col-6 col-md-3" %} 15 | {% show_form_input_field form.create_date_start "" "col-6 col-md-3" %} 16 | {% show_form_input_field form.create_date_end "" "col-6 col-md-3" %} 17 |
18 |
19 |
20 | 23 |
24 |
25 |
26 |
27 |
28 | {% if "customer_score_log__add"|is_logged_user_has_perm:request %} 29 | 30 | 变更积分 31 | 32 | {% endif %} 33 |
34 |
35 | {% show_customer_score_log_table customer_score_logs "customer_score_logs" %} 36 |
37 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/department_payment/add_department_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}新增部门回款单{% endblock %} 4 | {% block header_title %}新增部门回款单{% endblock %} 5 | {% block content %} 6 |
7 |
8 | {% csrf_token %} 9 |
10 | {% show_form_input_field_with_append_select form.src_department form.src_department_group "" "col-md-6" %} 11 | {% show_form_input_field form.dst_department "" "col-6 col-md-3" %} 12 | {% show_form_input_field form.payment_date "" "col-6 col-md-3" %} 13 | {% show_form_input_field form.dst_remark "" "col-12 mb-2" %} 14 |
15 | 16 |
17 |
18 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/department_payment/detail_department_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}回款单详情{% endblock %} 4 | {% block header_title %}回款单详情{% endblock %} 5 | {% block content %} 6 |
7 |
8 | 基本信息 9 |
10 | {% show_form_input_field form.id_ "" "col-12 col-md" %} 11 | {% show_form_input_field form.RO_create_time "" "col-6 col-md" %} 12 | {% show_form_input_field form.payment_date "" "col-6 col-md" %} 13 | {% show_form_input_field form.settle_accounts_time "" "col-6 col-md" %} 14 | {% show_form_input_field form.RO_status "" "col-6 col-md" %} 15 |
16 |
17 | {% show_form_input_field form.RO_src_department "" "col-6 col-md-3" %} 18 | {% show_form_input_field form.RO_dst_department "" "col-6 col-md-3" %} 19 |
20 |
21 | {% show_form_input_field form.src_remark "" "col-12 col-md-6" %} 22 | {% show_form_input_field form.dst_remark "" "col-12 col-md-6" %} 23 |
24 |
25 | 费用列表 26 |
27 |
28 |
29 |

应回款金额

30 |

31 | 现付运费收入:{{ dp_dic.total_fee_now }}元; 32 | 提付运费收入:{{ dp_dic.total_fee_sign_for }}元; 33 | 代收货款收入:{{ dp_dic.total_cargo_price }}元; 34 | 合计:{{ dp_dic.final_total_fee }}元。 35 |

36 |
37 |
38 | {% show_waybill_table waybills_info_list "department_payment_waybill" False True dp_dic.src_department.id %} 39 |
40 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/finance/department_payment/manage_department_payment.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}部门回款单{% endblock %} 4 | {% block header_title %}部门回款单{% endblock %} 5 | {% block header_subtitle %}收款部门创建 -> 财务部审核 -> 回款部门支付 -> 财务部结算{% endblock %} 6 | {% block head_append_js %} 7 | 8 | {% endblock %} 9 | {% block content %} 10 |
11 |
12 | {% csrf_token %} 13 |
14 |
15 |
16 | {% show_form_input_field_with_append_select form.src_department form.src_department_group "" "col-md-6" %} 17 | {% show_form_input_field form.payment_date_start "" "col-4 col-md" %} 18 | {% show_form_input_field form.payment_date_end "" "col-4 col-md" %} 19 | {% show_form_input_field form.status "" "col-4 col-md" %} 20 |
21 |
22 |
23 | 26 |
27 |
28 |
29 |
30 |
31 | {% if "manage_department_payment__add_delete"|is_logged_user_has_perm:request %} 32 | 33 | 新增 34 | 35 | 38 | {% endif %} 39 | 42 | {% if "manage_department_payment__review"|is_logged_user_has_perm:request %} 43 | 46 | {% endif %} 47 | {% if "manage_department_payment__settle"|is_logged_user_has_perm:request %} 48 | 51 | {% endif %} 52 | {% if "manage_department_payment__pay"|is_logged_user_has_perm:request %} 53 | 56 | {% endif %} 57 |
58 |
59 | {% show_department_payment_table department_payment_list "dp_search_result" %} 60 |
61 | {% endblock %} 62 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/login.html: -------------------------------------------------------------------------------- 1 | 2 | {% load static %} 3 | {% load wuliu_extras %} 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 登录 | {% get_company_name %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 52 | 53 | 54 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/report_table/dst_stock_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}到货库存{% endblock %} 4 | {% block header_title %}到货库存{% endblock %} 5 | {% block content %} 6 |
7 |
8 | {% csrf_token %} 9 |
10 |
11 |
12 | {% show_form_input_field_with_append_select form.src_department form.src_department_group "" "col-12 col-md-6" %} 13 | {% show_form_input_field_with_append_select form.dst_department form.dst_department_group "" "col-12 col-md-6" %} 14 |
15 |
16 | {% show_form_input_field form.arrival_date_start "" "col-6 col-md" %} 17 | {% show_form_input_field form.arrival_date_end "" "col-6 col-md" %} 18 | {% show_form_input_field form.waybill_status %} 19 |
20 |
21 |
22 | 25 |
26 |
27 |
28 |
29 |
30 | 33 | {% js_export_table_to_excel "wb_search_result" "#button_wb_export" %} 34 |
35 |
36 | {% show_dst_stock_waybill_table waybill_list "wb_search_result" %} 37 |
38 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/report_table/dst_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/sign_for/manage_sign_for.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}到货报表{% endblock %} 4 | {% block header_title %}到货报表{% endblock %} 5 | {% block header_subtitle %}{% endblock %} 6 | {% block search_form_action %}{% url 'wuliu:report_table_dst_waybill' %}{% endblock %} 7 | {% block action_bar %} 8 | 11 | {% js_export_table_to_excel "wb_search_result" "#button_wb_export" %} 12 | {% endblock %} 13 | {% block waybill_table %} 14 | {% show_waybill_table waybill_list "wb_search_result" False %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/report_table/sign_for_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}提货报表{% endblock %} 4 | {% block header_title %}提货报表{% endblock %} 5 | {% block content %} 6 |
7 |
8 | {% csrf_token %} 9 |
10 |
11 |
12 | {% show_form_input_field_with_append_select form.src_department form.src_department_group "" "col-12 col-md-6" %} 13 | {% show_form_input_field_with_append_select form.dst_department form.dst_department_group "" "col-12 col-md-6" %} 14 |
15 |
16 | {% show_form_input_field form.sign_for_date_start "" "col-6 col-md" %} 17 | {% show_form_input_field form.sign_for_date_end "" "col-6 col-md" %} 18 |
19 |
20 | {% show_form_input_field form.src_customer_name "" "col-4 col-md-3" %} 21 | {% show_form_input_field form.src_customer_phone "" "col-8 col-md-3" %} 22 | {% show_form_input_field form.dst_customer_name "" "col-4 col-md-3" %} 23 | {% show_form_input_field form.dst_customer_phone "" "col-8 col-md-3" %} 24 | {% show_form_input_field form.waybill_status %} 25 |
26 |
27 |
28 | 31 |
32 |
33 |
34 |
35 |
36 | 39 | {% js_export_table_to_excel "wb_search_result" "#button_wb_export" %} 40 |
41 |
42 | {% show_waybill_table waybill_list "wb_search_result" False %} 43 |
44 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/report_table/src_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/waybill/_layout_search_waybill.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}收货报表{% endblock %} 4 | {% block header_title %}收货报表{% endblock %} 5 | {% block search_form_action %}{% url 'wuliu:report_table_src_waybill' %}{% endblock %} 6 | {% block action_bar %} 7 | 10 | {% js_export_table_to_excel "wb_search_result" "#button_wb_export" %} 11 | {% endblock %} 12 | {% block waybill_table %} 13 | {% show_waybill_table waybill_list "wb_search_result" False %} 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/report_table/stock_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}发货库存{% endblock %} 4 | {% block header_title %}发货库存{% endblock %} 5 | {% block content %} 6 |
7 |
8 | {% csrf_token %} 9 |
10 |
11 |
12 | {% show_form_input_field_with_append_select form.src_department form.src_department_group "" "col-12 col-md-6" %} 13 | {% show_form_input_field_with_append_select form.dst_department form.dst_department_group "" "col-12 col-md-6" %} 14 |
15 |
16 | {% show_form_input_field form.create_date_start "" "col-6 col-md" %} 17 | {% show_form_input_field form.create_date_end "" "col-6 col-md" %} 18 | {% show_form_input_field form.waybill_status %} 19 |
20 |
21 |
22 | 25 |
26 |
27 |
28 |
29 |
30 | 33 | {% js_export_table_to_excel "wb_search_result" "#button_wb_export" %} 34 |
35 |
36 | {% show_stock_waybill_table waybill_list "wb_search_result" %} 37 |
38 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/settings/user/add_user.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load static %} 3 | {% load wuliu_extras %} 4 | {% block title %}添加用户{% endblock %} 5 | {% block header_title %}添加用户{% endblock %} 6 | {% block head_append_js %} 7 | 8 | {% endblock %} 9 | 10 | {% block content %} 11 |
12 | {% csrf_token %} 13 |
14 |
15 | {% show_form_input_field form.name "用户名" "col-12 col-md-7" %} 16 | {% show_form_input_field form.password "" "col-12 col-md-7 mb-1" %} 17 | {% show_form_input_field form.password_again "" "col-12 col-md-7 mb-1" %} 18 |
19 | 20 |
21 |
22 |
23 | {{ form.enabled }} 该用户, 24 |
25 |
26 | {{ form.administrator }} 管理员。 27 |
28 |
29 | {% show_form_input_field form.department "" "col-12 col-md-7" %} 30 |
31 |
32 | 33 |
34 | 64 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/settings/user/manage_users.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load static %} 3 | {% load wuliu_extras %} 4 | {% block title %}用户管理{% endblock %} 5 | {% block header_title %}用户管理{% endblock %} 6 | {% block head_append_js %} 7 | 8 | {% endblock %} 9 | 10 | {% block content %} 11 |
12 | {% csrf_token %} 13 |
14 |
15 | {% show_form_input_field form.user "选择用户" "col-12 col-md-5 mb-1" %} 16 |
17 | 添加用户 18 |
19 |
20 |
21 | {{ form.enabled }} 该用户, 22 |
23 |
24 | {{ form.administrator }} 管理员。 25 |
26 |
27 | {% show_form_input_field form.department "" "col-12 col-md-7" %} 28 | {% show_form_input_field form.reset_password "" "col-12 col-md-7" %} 29 | {% show_form_input_field form.reset_password_again "" "col-12 col-md-7" %} 30 |
31 | 32 |
33 |
34 |
35 | 36 |
37 | 88 | {% endblock %} 89 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/settings/user_permission/batch_edit_user_permission.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load static %} 3 | {% load cache %} 4 | {% load wuliu_extras %} 5 | {% block title %}批量修改用户权限{% endblock %} 6 | {% block header_title %}批量修改用户权限{% endblock %} 7 | {% block head_append_js %} 8 | 9 | {% endblock %} 10 | {% block content %} 11 |
12 | {% csrf_token %} 13 |
14 | 用户 15 |
16 | {% show_form_input_field form.user "选择用户" "col col-md-4" %} 17 |
18 | 19 |
20 | {% show_form_input_field form.permission %} 21 |
22 | 权限 23 | {{ form.grant_or_deny }} 以下权限: 24 |
25 |
26 |
27 | {% cache 300 "full_permission_tree" %} 28 | {% show_full_permission_tree "permission_tree" %} 29 | {% endcache %} 30 |
31 | 56 | {% endblock %} 57 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/settings/user_permission/manage_user_permission.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load cache %} 3 | {% load wuliu_extras %} 4 | {% block title %}用户权限管理{% endblock %} 5 | {% block header_title %}用户权限管理{% endblock %} 6 | {% block content %} 7 |
8 | {% csrf_token %} 9 |
10 | 用户 11 |
12 | {% show_form_input_field form.user "选择用户" "col col-md-3" %} 13 |
14 | 15 |
16 | {% show_form_input_field form.permission %} 17 | {% show_form_input_field form.permission_source_user %} 18 |
19 | 权限 20 |
21 |
22 |
23 | 批量修改用户权限 24 | 25 | {% cache 300 "full_permission_tree" %} 26 | {% show_full_permission_tree "permission_tree" %} 27 | {% endcache %} 28 |
29 | 97 | {% endblock %} 98 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/sign_for/confirm_sign_for.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}确认提货{% endblock %} 4 | {% block header_title %}确认提货{% endblock %} 5 | {% block head_append_js %} 6 | 7 | {% endblock %} 8 | {% block content %} 9 |
10 |
11 | 运单信息 12 |
13 |
14 |
15 | 添加运单 16 |
17 | 18 |
19 |
20 |
21 |
22 |
23 | {% for waybill in waybill_list %} 24 | {% show_sign_for_waybill_info waybill %} 25 | {% endfor %} 26 |
27 |
28 |
29 | 签收信息 30 |
31 |
32 | 33 | 34 |
35 |
36 | 37 | 38 |
39 |
40 | 41 | 42 |
43 |
44 | 45 | 46 |
47 |
48 |
49 |
50 |
51 |
52 | 53 | 54 |
55 |
56 | 57 | 58 |
59 |
60 |
61 |
62 |
63 |
64 | 65 | 66 |
67 | {% endblock %} 68 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/sign_for/manage_sign_for.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/waybill/_layout_search_waybill.html" %} 2 | {% block title %}客户签收{% endblock %} 3 | {% block header_title %}客户签收{% endblock %} 4 | {% block header_subtitle %}请查询并选择客户需要签收的运单{% endblock %} 5 | {% block search_form_action %}{% url 'wuliu:manage_sign_for' %}{% endblock %} 6 | {% block action_bar %} 7 | 10 | 13 | 16 | 58 | {% endblock %} 59 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/transport_out/_layout_edit_transport_out.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block head_append_js %} 4 | 5 | {% endblock %} 6 | {% block content %} 7 |
8 |
9 | {% if not detail_view %} 10 | {% csrf_token %} 11 | {% endif %} 12 | 基本信息 13 | {% if form.id_ %} 14 |
15 | {% show_form_input_field form.id_ "" "col-6 col-md-3" %} 16 | {% show_form_input_field form.id "" "" %} 17 | {% if detail_view %} 18 | {% show_form_input_field form.RO_status "" "col-6 col-md-2" %} 19 | {% show_form_input_field form.RO_create_time %} 20 | {% show_form_input_field form.RO_start_time %} 21 | {% show_form_input_field form.RO_end_time %} 22 | {% endif %} 23 |
24 | {% endif %} 25 |
26 | {% if detail_view %} 27 | {% show_form_input_field form.RO_src_department "发车部门" "col-6 col-md-3" %} 28 | {% show_form_input_field form.RO_dst_department "到达部门" "col-6 col-md-3" %} 29 | {% else %} 30 | {% show_form_input_field form.src_department "发车部门" "col-6 col-md-3" %} 31 | {% show_form_input_field form.dst_department "到达部门" "col-6 col-md-3" %} 32 | {% endif %} 33 |
34 | 车次信息 35 |
36 | {% if detail_view %} 37 | {% show_form_input_field form.RO_truck "车牌号" "col-12 col-md-3" %} 38 | {% else %} 39 | {% show_form_input_field form.truck "选择车辆" "col-12 col-md-3" %} 40 | {% endif %} 41 | {% show_form_input_field form.driver_name "" "col-6 col-md-3" %} 42 | {% show_form_input_field form.driver_phone "" "col-6 col-md-3" %} 43 |
44 | {# 此处不应该渲染该表单字段 #} 45 | {# form.waybills #} 46 |
47 |
48 |
49 | {% block action_bar %} 50 | 51 | 配载运单 52 | 53 | 56 | {% endblock %} 57 |
58 |
59 | {% block waybill_table %} 60 | {% show_waybill_table waybills_info_list "ready_transport_out" %} 61 | {% endblock %} 62 |
63 |
64 | {% block action_buttons %}{% endblock %} 65 |
66 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/transport_out/add_transport_out.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/transport_out/_layout_edit_transport_out.html" %} 2 | {% block title %}创建车次计划{% endblock %} 3 | {% block header_title %}创建车次计划{% endblock %} 4 | {% block header_subtitle %}创建车次计划{% endblock %} 5 | {% block head_append_js %} 6 | {{ block.super }} 7 | 47 | {% endblock %} 48 | {% block action_buttons %} 49 | 50 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/transport_out/detail_transport_out.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/transport_out/_layout_edit_transport_out.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}车次详情{% endblock %} 4 | {% block header_title %}车次详情{% endblock %} 5 | {% block action_bar %}{% endblock %} 6 | {% block waybill_table %} 7 | {% show_waybill_table waybills_info_list "ready_transport_out" False %} 8 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/transport_out/edit_transport_out.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/transport_out/_layout_edit_transport_out.html" %} 2 | {% block title %}修改车次计划{% endblock %} 3 | {% block header_title %}修改车次计划{% endblock %} 4 | {% block head_append_js %} 5 | {{ block.super }} 6 | 46 | {% endblock %} 47 | {% block action_buttons %} 48 | 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/transport_out/manage_transport_out.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}发车出库{% endblock %} 4 | {% block header_title %}发车出库{% endblock %} 5 | {% block header_subtitle %}车次管理{% endblock %} 6 | {% block head_append_js %} 7 | 8 | {% endblock %} 9 | {% block content %} 10 |
11 |
12 | {% csrf_token %} 13 |
14 |
15 |
16 | {% show_form_input_field form.transport_out_id "" "col-6 col-md" %} 17 | {% show_form_input_field form.truck_number_plate "" "col-6 col-md" %} 18 | {% show_form_input_field form.driver_name "" "col-6 col-md" %} 19 | {% show_form_input_field form.status "" "col-6 col-md" %} 20 |
21 |
22 | {% show_form_input_field form.create_date_start "" "col-6 col-md" %} 23 | {% show_form_input_field form.create_date_end "" "col-6 col-md" %} 24 | {% show_form_input_field form.src_department "" "col-6 col-md" %} 25 | {% show_form_input_field form.dst_department "" "col-6 col-md" %} 26 |
27 |
28 |
29 | 32 |
33 |
34 |
35 |
36 |
37 | {% if "manage_transport_out__add_edit_delete_start"|is_logged_user_has_perm:request %} 38 | 39 | 新增 40 | 41 | 44 | 47 | 50 | {% endif %} 51 |
52 |
53 | {% show_transport_out_table transport_out_list "to_search_result" %} 54 |
55 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/transport_out/search_waybills_to_transport_out.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/waybill/_layout_search_waybill.html" %} 2 | {% block title %}选择运单{% endblock %} 3 | {% block header_title %}选择运单{% endblock %} 4 | {% block header_subtitle %}请查询并选择你需要配载的运单{% endblock %} 5 | {% block search_form_action %}{% url 'wuliu:search_waybills_to_transport_out' %}{% endblock %} 6 | {% block action_bar %} 7 | 11 | 14 | 43 | {% endblock %} 44 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/_layout_edit_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block head_append_js %} 4 | 5 | {% endblock %} 6 | {% block content %} 7 | {% block content_header %}{% endblock %} 8 |
9 |
10 | {# 为了安全起见, 运单详情页面不提供csrf_token #} 11 | {% if not detail_view %} 12 | {% csrf_token %} 13 | {% endif %} 14 | 基本信息 15 | {% if form.id_ %} 16 |
17 | {% show_form_input_field form.id_ "" "col-6 col-md-3" %} 18 | {% show_form_input_field form.id "" "" %} 19 | {% if detail_view %} 20 | {% show_form_input_field form.RO_create_time "" "col-6 col-md-3" %} 21 | {% show_form_input_field form.RO_status "" "col-6 col-md-2" %} 22 | {% endif %} 23 |
24 | {% endif %} 25 |
26 | {% if detail_view %} 27 | {% show_form_input_field form.RO_src_department "" "col-6 col-md-3" %} 28 | {% show_form_input_field form.RO_dst_department "" "col-6 col-md-3" %} 29 | {% else %} 30 | {% show_form_input_field form.src_department "" "col-6 col-md-3" %} 31 | {% show_form_input_field form.dst_department "" "col-6 col-md-3" %} 32 | {% endif %} 33 |
34 |
35 |
36 |
37 |

发货人信息

38 |
39 |
40 | {% if detail_view %} 41 | {% show_form_input_field form.RO_src_customer "客户" "col-12" %} 42 | {% else %} 43 | {% show_form_input_field form.src_customer "选择客户" "col-12" %} 44 | {% endif %} 45 | {% show_form_input_field form.src_customer_name "姓名" "col-5" %} 46 | {% show_form_input_field form.src_customer_phone "电话" "col-7" %} 47 | {% show_form_input_field form.src_customer_credential_num "身份证号码" "col-md-5" %} 48 | {% show_form_input_field form.src_customer_address "详细地址" "col-md-7" %} 49 |
50 |
51 |
52 |
53 |

收货人信息

54 |
55 |
56 | {% if detail_view %} 57 | {% show_form_input_field form.RO_dst_customer "客户" "col-12" %} 58 | {% else %} 59 | {% show_form_input_field form.dst_customer "选择客户" "col-12" %} 60 | {% endif %} 61 | {% show_form_input_field form.dst_customer_name "姓名" "col-5" %} 62 | {% show_form_input_field form.dst_customer_phone "电话" "col-7" %} 63 | {% show_form_input_field form.dst_customer_credential_num "身份证号码" "col-md-5" %} 64 | {% show_form_input_field form.dst_customer_address "详细地址" "col-md-7" %} 65 |
66 |
67 |
68 | 货物信息 69 |
70 | {% show_form_input_field form.cargo_name "" "col-4 col-md" %} 71 | {% show_form_input_field form.cargo_num "" "col-4 col-md" %} 72 | {% show_form_input_field form.cargo_volume "总体积 (m³)" "col-4 col-md" %} 73 | {% show_form_input_field form.cargo_weight "总重量 (Kg)" "col-4 col-md" %} 74 | {% show_form_input_field form.cargo_price "货款 (元)" "col-4 col-md" %} 75 | {% show_form_input_field form.cargo_handling_fee "手续费 (元)" "col-4 col-md" %} 76 |
77 | 运费 78 | {# 运单详情页面不显示标准运费 #} 79 | {% if not detail_view %} 80 |
81 | 标准运费:0 82 |
83 | {% endif %} 84 |
85 | {% show_form_input_field form.fee "运费 (元)" "col-6 col-md-2" %} 86 | {% if detail_view %} 87 | {% show_form_input_field form.RO_fee_type "支付方式" "col-6 col-md-2" %} 88 | {% else %} 89 | {% show_form_input_field form.fee_type "支付方式" "col-6 col-md-2" %} 90 | {% endif %} 91 | {% show_form_input_field form.customer_remark "" %} 92 | {% show_form_input_field form.company_remark "" %} 93 |
94 |
95 |
96 |

97 | 现付合计: 98 | 0 99 |

100 |
101 |
102 |

103 | 提货应付: 104 | 0 105 |

106 |
107 |
108 | {# 运单详情页面不提供提交按钮 #} 109 | {% if not detail_view %} 110 | 111 | {% endif %} 112 |
113 |
114 | {% block content_footer %}{% endblock %} 115 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/_layout_search_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block content %} 4 |
5 |
6 | {% csrf_token %} 7 |
8 |
9 |
10 | {% show_form_input_field form.waybill_id "" "col-12 col-md-3" %} 11 | {% show_form_input_field form.waybill_status "" "col-6 col-md-3" %} 12 | {% show_form_input_field form.waybill_fee_type "" "col-6 col-md-3" %} 13 | {% if form.cargo_price_status %} 14 | {% show_form_input_field form.cargo_price_status "" "col-12 col-md-3" %} 15 | {% endif %} 16 |
17 |
18 | {% show_form_input_field form.create_date_start "" "col-8 col-md" %} 19 | {% show_form_input_field form.create_time_start "-" "col-4 col-md-2" %} 20 | {% show_form_input_field form.create_date_end "" "col-8 col-md" %} 21 | {% show_form_input_field form.create_time_end "-" "col-4 col-md-2" %} 22 |
23 |
24 | {% show_form_input_field form.arrival_date_start "" "col-6 col-md" %} 25 | {% show_form_input_field form.arrival_date_end "" "col-6 col-md" %} 26 | {% show_form_input_field form.sign_for_date_start "" "col-6 col-md" %} 27 | {% show_form_input_field form.sign_for_date_end "" "col-6 col-md" %} 28 |
29 |
30 | {% show_form_input_field form.src_customer_name "" "col-4 col-md-3" %} 31 | {% show_form_input_field form.src_customer_phone "" "col-8 col-md-3" %} 32 | {% show_form_input_field_with_append_select form.src_department form.src_department_group "" "col-12 col-md-6" %} 33 |
34 |
35 | {% show_form_input_field form.dst_customer_name "" "col-4 col-md-3" %} 36 | {% show_form_input_field form.dst_customer_phone "" "col-8 col-md-3" %} 37 | {% show_form_input_field_with_append_select form.dst_department form.dst_department_group "" "col-12 col-md-6" %} 38 |
39 |
40 |
41 | 44 |
45 |
46 |
47 |
48 |
49 | {% block action_bar %} 50 | {% endblock %} 51 |
52 |
53 | {% block waybill_table %} 54 | {% show_waybill_table waybill_list "wb_search_result" %} 55 | {% endblock %} 56 |
57 | 94 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/add_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/waybill/_layout_edit_waybill.html" %} 2 | {% block title %}运单录入{% endblock %} 3 | {% block header_title %}运单录入{% endblock %} 4 | {% block header_subtitle %}收货开票{% endblock %} 5 | {% block edit_form_action %}{% url 'wuliu:add_waybill' %}{% endblock %} 6 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/confirm_return_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% block title %}确认退货{% endblock %} 3 | {% block header_title %}确认退货{% endblock %} 4 | {% block content %} 5 |
6 |
7 |
8 |

运单编号:{{ waybill.get_full_id }}

9 |
10 |
11 |
12 |
13 | 发货人:{{ waybill.src_customer_name }} 14 |
15 |
16 | 发货人电话:{{ waybill.src_customer_phone }} 17 |
18 |
19 | 收货人:{{ waybill.dst_customer_name }} 20 |
21 |
22 | 收货人电话:{{ waybill.dst_customer_phone }} 23 |
24 |
25 | 发货部门:{{ waybill.src_department.name }} 26 |
27 |
28 | 货物名称:{{ waybill.cargo_name }} 29 |
30 |
31 | 代收货款:{{ waybill.cargo_price }} 32 |
33 |
34 | 件数:{{ waybill.cargo_num }} 35 |
36 |
37 | 总体积:{{ waybill.cargo_volume | floatformat:2 }} 38 |
39 |
40 | 总重量:{{ waybill.cargo_weight | floatformat }} 41 |
42 |
43 | 运费:{{ waybill.fee }} 44 |
45 |
46 | 结算方式:{{ waybill.fee_type }} 47 |
48 |
49 | 客户备注:{{ waybill.customer_remark | default:"无" }} 50 |
51 |
52 | 公司备注:{{ waybill.company_remark | default:"无" }} 53 |
54 |
55 |
56 |
57 |
58 |
59 | {% csrf_token %} 60 | 61 |
62 | 63 |
64 | 65 |
66 |
67 | 68 |
69 |
70 |
71 | 94 | {% endblock %} 95 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/edit_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/waybill/_layout_edit_waybill.html" %} 2 | {% block title %}运单修改{% endblock %} 3 | {% block header_title %}运单修改{% endblock %} 4 | {% block edit_form_action %}{% url 'wuliu:edit_waybill' %}{% endblock %} 5 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/manage_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/waybill/_layout_search_waybill.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}运单管理{% endblock %} 4 | {% block header_title %}运单管理{% endblock %} 5 | {% block header_subtitle %}查询、修改、作废或补打运单{% endblock %} 6 | {% block head_append_js %} 7 | 8 | {% endblock %} 9 | {% block search_form_action %}{% url 'wuliu:manage_waybill' %}{% endblock %} 10 | {% block action_bar %} 11 | 15 | {% if "manage_waybill__edit_delete_print"|is_logged_user_has_perm:request %} 16 | 19 | 22 | 25 | {% endif %} 26 | {% if "manage_transport_out__add_edit_delete_start"|is_logged_user_has_perm:request %} 27 | 30 | {% endif %} 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /wuliu/templates/wuliu/waybill/quick_search_waybill.html: -------------------------------------------------------------------------------- 1 | {% extends "wuliu/_layout.html" %} 2 | {% load wuliu_extras %} 3 | {% block title %}查询结果{% endblock %} 4 | {% block header_title %}查询结果{% endblock %} 5 | {% block content %} 6 | {% show_waybill_table waybill_list "quick_search_waybill_result" False %} 7 | 8 | 9 | {% endblock %} -------------------------------------------------------------------------------- /wuliu/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pzqqt/Django_Transportation_Management_System/25366bb6497b7db4e4991ccdf5bca5ae13e227a1/wuliu/templatetags/__init__.py -------------------------------------------------------------------------------- /wuliu/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | --------------------------------------------------------------------------------