This commit is contained in:
王思川 2024-05-30 17:06:23 +08:00
parent 013c4878fa
commit 6bab6d6191
62 changed files with 1174 additions and 956 deletions

View File

@ -47,6 +47,7 @@ INSTALLED_APPS = [
'application.opa_mgnt',
'rest_framework',
"application.accounts",
"common",
# 'application.bde_perm',
# 'application.bdh_perm',
# 'application.busi_tbl',
@ -133,8 +134,8 @@ DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'xh_digital_manage', # 数据库名
'USER': 'ps', # 用户名
'PASSWORD': 'ps240523..', # 密码
'USER': 'wsc', # 用户名
'PASSWORD': 'jsxh9512..', # 密码
'HOST': 'bj-cdb-7qxczedm.sql.tencentcdb.com', # 地址
'PORT': '59450', # 端口号
'OPTIONS': {

View File

@ -23,15 +23,15 @@ urlpatterns = [
path("admin/", admin.site.urls),
path("", project_ledger, name="index"),
path("accounts/", include("application.accounts.urls")),
path("pm/", include("application.perf_mgnt.urls")),
path("om/", include("application.org_mgnt.urls")),
path("hrm/", include("application.hrm_mgnt.urls")),
path("fm/", include("application.fac_mgnt.urls")),
path("rm/", include("application.rsc_mgnt.urls")),
path("opm/", include("application.opa_mgnt.urls")),
path("cpm/", include("application.cpc_mgnt.urls")),
path("cpm/", include("application.cpc_mgnt.urls")),
path("mkt/", include("application.mkt_mgnt.urls")),
path("ast/", include("application.asset_mgnt.urls")),
path("pjm/", include("application.pjt_mgnt.urls")),
path("basic_data/perf_mgnt/", include("application.perf_mgnt.urls")),
path("basic_data/om/", include("application.org_mgnt.urls")),
path("basic_data/hrm/", include("application.hrm_mgnt.urls")),
path("basic_data/fm/", include("application.fac_mgnt.urls")),
path("basic_data/rm/", include("application.rsc_mgnt.urls")),
path("basic_data/opm/", include("application.opa_mgnt.urls")),
path("basic_data/cpm/", include("application.cpc_mgnt.urls")),
path("basic_data/cpm/", include("application.cpc_mgnt.urls")),
path("basic_data/mkt/", include("application.mkt_mgnt.urls")),
path("basic_data/ast/", include("application.asset_mgnt.urls")),
path("basic_data/pjm/", include("application.pjt_mgnt.urls")),
]

View File

@ -242,7 +242,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -237,7 +237,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -164,7 +164,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -242,7 +242,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -179,7 +179,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -168,7 +168,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -174,7 +174,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -246,7 +246,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -117,7 +117,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -136,7 +136,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -113,7 +113,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -127,7 +127,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -164,7 +164,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -141,7 +141,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -168,7 +168,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -136,7 +136,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -137,7 +137,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -121,7 +121,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -311,7 +311,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -262,7 +262,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -108,7 +108,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -112,7 +112,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -184,7 +184,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -130,7 +130,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -225,7 +225,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -165,7 +165,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -145,7 +145,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -176,7 +176,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -460,7 +460,7 @@
</div>
<!-- [ 分页&统计 ] 开始 -->
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 分页&统计 ] 结束 -->
<!-- [ 主内容 ] 结束 -->

View File

@ -94,7 +94,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -62,7 +62,7 @@ class PrimaryDepartmentListView(View):
'description': department.description,
} for department in departments]
pagination_html = render(request, 'pagination.html', {
pagination_html = render(request, 'pagination_ps.html', {
'page': departments.number,
'pages': paginator.num_pages,
'has_next': departments.has_next(),
@ -132,7 +132,7 @@ def get_secondary_department(request):
response_data = {
"departments": departments_data,
"pagination_html": render(request, "pagination.html", {"page_obj": page_obj}).content.decode()
"pagination_html": render(request, "pagination_ps.html", {"page_obj": page_obj}).content.decode()
}
return JsonResponse(response_data)

View File

@ -0,0 +1,780 @@
{% extends 'base.html' %}
<!-- group_business_objective_list -->
{% block content %}
<!-- [ 主内容页 ] 开始 -->
<section class="pcoded-main-container">
<div class="pcoded-wrapper">
<div class="pcoded-content">
<div class="pcoded-inner-content">
<div class="main-body">
<div class="page-wrapper">
<!-- [ 面包屑 ] 开始 -->
{% include 'breadcrumb.html' %}
<!-- [ 面包屑 ] 结束 -->
<!-- [ 主内容 ] 开始 -->
<div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="row">
<!-- 筛选查询表单 -->
<div class="col-md-9">
{% include 'filter.html' %}
</div>
<!-- 文件上传表单 -->
<div class="col-md-3 mt-4 text-end">
<button class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#addModal">添加</button>
<button class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#downloadModal">导出</button>
<button class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#uploadModal">上传Excel</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-12">
<div class="card">
<!-- [ 数据表 ] 开始 -->
{% include 'table.html' %}
<!-- [ 数据表 ] 结束 -->
</div>
</div>
</div>
<!-- [ 分页&统计 ] 开始 -->
{% include 'pagination.html' with page_obj=items query_params=query_params %}
<!-- [ 分页&统计 ] 结束 -->
<!-- [ 主内容 ] 结束 -->
</div>
</div>
</div>
</div>
</div>
</section>
<!-- [ 主内容页 ] 结束 -->
<!-- 模态框 -->
<div id="modifyRecordsModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">
经营目标修改记录
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<table class="table">
<thead class="text-center">
<tr>
<th>年份</th>
<th>一级部门</th>
<th>修改字段</th>
<th>旧值</th>
<th>新值</th>
<th>修改日期</th>
<th>修改人</th>
</tr>
</thead>
<tbody class="text-center" style="color: white;">
<tr>
</tr>
<!-- 您可以添加更多的行,作为其他修改记录的数据 -->
</tbody>
</table>
<nav>
<ul class="pagination justify-content-end">
<!-- 分页按钮将由JS代码动态填充 -->
</ul>
</nav>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-bs-dismiss="modal">确定
</button>
</div>
</div>
</div>
</div>
<div id="uploadModal" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="exampleModalPopoversLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalPopoversLabel">上传文件</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="upload-form" enctype="multipart/form-data">
<input type="file" class="form-control" id="inputGroupFile01"
hidden>
<label class="btn btn-outline-primary"
for="inputGroupFile01">选择文件</label>
<span style="font-size: 12px">上传的文件格式为.xlsx</span>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-bs-dismiss="modal">取消
</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"
data-bs-toggle="modal"
data-bs-target="#newModal">上传
</button>
</div>
</div>
</div>
</div>
<div id="newModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document"
style="display: flex !important; align-items: center !important; justify-content: center !important;">
<div class="modal-content"
style="width: 100vw !important; margin: 0 !important; max-width: 1600px !important;">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">
上传文件预览
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<div style="overflow-x: auto;">
<table id="form-input-table"
class="table table-striped table-bordered nowrap">
<thead>
<tr>
<th>序号</th>
<th>一级部门</th>
<th>年份</th>
<th>项目性质</th>
<th>销售额</th>
<th>收入总目标</th>
<th>新增收入目标</th>
<th>存量收入目标</th>
<th>成本限额</th>
<th>毛利润</th>
<th>费用限额</th>
<th>营业利润</th>
</tr>
</thead>
<tbody>
{# <tr>#}
{# <td>1</td>#}
{# <td>#}
{# <select style="width: 200px;" class="form-control"#}
{# id="first_department" name="first_department">#}
{# <option value="天信">天信</option>#}
{# <option value="混改">混改</option>#}
{# <option value="艾力芬特">艾力芬特</option>#}
{# <option value="星河">星河</option>#}
{# <option value="星海">星海</option>#}
{# </select>#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="year" name="year" value="2024">#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="project_nature" name="project_nature"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="sales_amount" name="sales_amount" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="total_income_goal" name="total_income_goal"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="new_income_goal" name="new_income_goal"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="existing_income_goal" name="existing_income_goal"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="cost_limit" name="cost_limit" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="gross_profit" name="gross_profit" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="expense_limit" name="expense_limit" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="operating_profit" name="operating_profit">#}
{# </td>#}
{# </tr>#}
</table>
</div>
<div class="row mt-3 justify-content-end">
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers"
id="single-select_paginate">
<ul class="pagination justify-content-end">
<li class="paginate_button page-item previous disabled"
id="single-select_previous">
<a href="#" aria-controls="single-select" data-dt-idx="0"
tabindex="0"
class="page-link">上一页</a>
</li>
<li class="paginate_button page-item active">
<a href="#" aria-controls="single-select" data-dt-idx="1"
tabindex="0"
class="page-link">1</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="2"
tabindex="0"
class="page-link">2</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="3"
tabindex="0"
class="page-link">3</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="4"
tabindex="0"
class="page-link">4</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="5"
tabindex="0"
class="page-link">5</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="6"
tabindex="0"
class="page-link">6</a>
</li>
<li class="paginate_button page-item next"
id="single-select_next">
<a href="#" aria-controls="single-select" data-dt-idx="7"
tabindex="0"
class="page-link">下一页</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-bs-dismiss="modal">提交
</button>
</div>
</div>
</div>
</div>
<div id="addModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="addModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addModalCenterTitle">添加/编辑</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="groupBusinessTargetForm">
{% csrf_token %}
<!-- 使用row和col来控制标签的布局 -->
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="primary_department">一级部门</label>
<select class="form-control" id="primary_department_add" name="primary_department"
required>
<option value="">选择部门</option>
<option value="天信">天信</option>
<option value="混改">混改</option>
<option value="艾力芬特">艾力芬特</option>
<option value="星河">星河</option>
<option value="星海">星海</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="year">年份</label>
<select class="form-control" id="year_add" name="year" required>
<option value="">选择年度</option>
<option value="2024">2024</option>
<option value="2023">2023</option>
<option value="2022">2022</option>
<option value="2021">2021</option>
<option value="2020">2020</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="project_nature">项目性质</label>
<select class="form-control" id="project_nature_add" name="project_nature" required>
<option value="">选择项目性质</option>
<option value="新增">新增</option>
<option value="存续">存续</option>
<option value="新增及存续">新增及存续</option>
<option value="老客户新业务">老客户新业务</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="sales">销售额(元)</label>
<input type="number" class="form-control" id="sales_add" name="sales"
required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="total_revenue_target">收入总目标(元)</label>
<input type="number" class="form-control" id="total_revenue_target_add"
name="total_revenue_target" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="new_revenue_target">新增收入目标(元)</label>
<input type="number" class="form-control" id="new_revenue_target_add"
name="new_revenue_target"
required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="existing_revenue_target">存量收入目标(元)</label>
<input type="number" class="form-control" id="existing_revenue_target_add"
name="existing_revenue_target" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="cost_limit">成本限额(元)</label>
<input type="number" class="form-control" id="cost_limit_add" name="cost_limit"
required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="gross_profit">毛利润(元)</label>
<input type="number" class="form-control" id="gross_profit_add" name="gross_profit"
required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="expense_limit">费用限额(元)</label>
<input type="number" class="form-control" id="expense_limit_add"
name="expense_limit"
required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="operating_profit">营业利润(元)</label>
<input type="number" class="form-control" id="operating_profit_add"
name="operating_profit"
required>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="submitForm">添加</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<div id="modifyModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="modifyModal" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addModalCenterTitle">修改</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="groupBusinessTargetForm">
{% csrf_token %}
<!-- 使用row和col来控制标签的布局 -->
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="primary_department">一级部门</label>
<input class="form-control" id="primary_department_modify" name="primary_department"
required disabled>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="year">年度</label>
<input class="form-control" id="year_modify" name="year"
required disabled>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="project_nature">项目性质</label>
<input class="form-control" id="project_nature_modify" name="project_nature"
required disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="modified_field">修改字段</label>
<select class="form-control" id="modified_field" name="modified_field" required>
<option value="">选择修改字段</option>
<option value="销售额">销售额</option>
<option value="收入总目标">收入总目标</option>
<option value="新增收入目标">新增收入目标</option>
<option value="存量收入目标">存量收入目标</option>
<option value="成本限额">成本限额</option>
<option value="毛利润">毛利润</option>
<option value="费用限额">费用限额</option>
<option value="营业利润">营业利润</option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="old_value">旧值</label>
<input class="form-control" id="old_value" name="old_value"
required disabled>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="new_value">新值</label>
<input class="form-control" id="new_value" name="new_value"
required>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="modified_by">修改人</label>
<input class="form-control" id="modified_by" name="modified_by"
required>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="submitModifyForm">确定
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<!-- 模态框结束 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!/^http:.*/.test(settings.url) && !/^https:.*/.test(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
// 查询接口
$(document).ready(function () {
// Fetch data when page loads
fetchData();
// 查询
$('#queryForm').on('submit', function (event) {
event.preventDefault();
fetchData();
});
// 分页
$(document).on('click', '.pagination .assembly-page', function (event) {
event.preventDefault();
const page = $(this).data('page');
fetchData(page);
});
$(document).on('click', '#modifyBtn', function (event) {
event.preventDefault();
const row = $(this).closest('tr');
const columns = row.find('td');
// Store row ID in modal for future reference
$('#modifyModal').data('row-id', row.data('row-id'));
// Get data from table cells
const primary_department = columns.eq(1).text();
const year = columns.eq(2).text();
const project_nature = columns.eq(3).text();
// Populate modal form with data
$('#primary_department_modify').val(primary_department);
$('#year_modify').val(year);
$('#project_nature_modify').val(project_nature);
// Open modal
$('#modifyModal').modal('show');
});
$('#submitForm').on('click', function (event) {
event.preventDefault();
const data = {
primary_department: $('#primary_department_add').val(),
year: parseInt($('#year_add').val(), 10), // 确保年份是整数
project_nature: $('#project_nature_add').val(),
sales: parseFloat($('#sales_add').val()), // 确保数字字段是浮点数
total_revenue_target: parseFloat($('#total_revenue_target_add').val()),
new_revenue_target: parseFloat($('#new_revenue_target_add').val()),
existing_revenue_target: parseFloat($('#existing_revenue_target_add').val()),
cost_limit: parseFloat($('#cost_limit_add').val()),
gross_profit: parseFloat($('#gross_profit_add').val()),
expense_limit: parseFloat($('#expense_limit_add').val()),
operating_profit: parseFloat($('#operating_profit_add').val()),
};
$.ajax({
type: "POST",
url: "/pm/create/",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("记录添加成功!");
location.reload();
},
error: function (error) {
console.error("Error: ", error);
alert("记录添加失败,请检查输入内容。");
}
});
});
$('#modified_field').on('change', function () {
const modifiedField = $(this).val();
const rowId = $('#modifyModal').data('row-id');
const row = $(`tr[data-row-id="${rowId}"]`);
const columns = row.find('td');
let oldValue = '';
switch (modifiedField) {
case '销售额':
oldValue = columns.eq(4).text();
break;
case '收入总目标':
oldValue = columns.eq(5).text();
break;
case '新增收入目标':
oldValue = columns.eq(6).text();
break;
case '存量收入目标':
oldValue = columns.eq(7).text();
break;
case '成本限额':
oldValue = columns.eq(8).text();
break;
case '毛利润':
oldValue = columns.eq(9).text();
break;
case '费用限额':
oldValue = columns.eq(10).text();
break;
case '营业利润':
oldValue = columns.eq(11).text();
break;
}
$('#old_value').val(oldValue);
});
// 修改modal关闭后初始化数据
$('#modifyModal').on('hidden.bs.modal', function () {
// Reset form fields
$('#groupBusinessTargetForm')[0].reset();
// Clear data attributes
$('#modifyModal').removeData('row-id');
// Reset modified field dropdown to default
$('#modified_field').val('');
// Clear old and new values
$('#old_value').val('');
$('#new_value').val('');
});
$('#submitModifyForm').on('click', function () {
const target_id = $('#modifyModal').data('row-id');
const modified_field = $('#modified_field').val();
const old_value = $('#old_value').val();
const new_value = $('#new_value').val();
const modified_by = $('#modified_by').val();
$.ajax({
type: 'POST',
url: '/pm/add_target_audit/',
contentType: 'application/json',
data: JSON.stringify({
target_id: target_id,
modified_field: modified_field,
old_value: parseFloat(old_value),
new_value: parseFloat(new_value),
modified_by: modified_by
}),
dataType: 'json',
success: function (response) {
if (response.status === 'success') {
alert('修改记录已保存');
$('#modifyModal').modal('hide');
// Optionally, refresh the data here
fetchData();
} else {
alert('保存失败,请重试');
}
},
error: function (error) {
console.error('Error:', error);
alert('保存失败,请重试');
}
});
});
$(document).on('click', '.view-modify-records-btn', function (event) {
event.preventDefault();
// Fetch and display modify records for the first page
fetchModifyRecords(1);
});
// Fetch modify records function
function fetchModifyRecords(page) {
$.ajax({
type: 'GET',
url: '/pm/get_target_audit_records/',
data: {
page: page
},
dataType: 'json',
success: function (response) {
const records = response.records;
const tbody = $('#modifyRecordsModal tbody');
tbody.empty(); // Clear previous records
records.forEach(function (record) {
tbody.append(`
<tr>
<td>${record.year}</td>
<td>${record.primary_department}</td>
<td>${record.modified_field}</td>
<td>${record.old_value}</td>
<td>${record.new_value}</td>
<td>${record.modification_date}</td>
<td>${record.modified_by}</td>
</tr>
`);
});
// Update pagination
const pagination = $('#modifyRecordsModal .pagination');
pagination.empty(); // Clear previous pagination
if (response.has_previous) {
pagination.append(`
<li class="page-item">
<a class="page-link modify-page" href="#" data-page="${response.page - 1}">上一页</a>
</li>
`);
}
for (let i = 1; i <= response.num_pages; i++) {
pagination.append(`
<li class="page-item ${response.page === i ? 'active' : ''}">
<a class="page-link modify-page" href="#" data-page="${i}">${i}</a>
</li>
`);
}
if (response.has_next) {
pagination.append(`
<li class="page-item">
<a class="page-link modify-page" href="#" data-page="${response.page + 1}">下一页</a>
</li>
`);
}
// Open modal
$('#modifyRecordsModal').modal('show');
},
error: function (error) {
console.error('Error fetching modify records:', error);
alert('无法获取修改记录,请稍后重试。');
}
});
}
// Handle pagination click
$(document).on('click', '#modifyRecordsModal .pagination .modify-page', function (event) {
event.preventDefault();
const page = $(this).data('page');
fetchModifyRecords(page);
});
});
</script>
{% endblock %}

View File

@ -1,875 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<!-- [ 主内容页 ] 开始 -->
<section class="pcoded-main-container">
<div class="pcoded-wrapper">
<div class="pcoded-content">
<div class="pcoded-inner-content">
<div class="main-body">
<div class="page-wrapper">
<!-- [ 面包屑 ] 开始 -->
<div class="page-header">
<div class="page-block">
<div class="row align-items-center">
<div class="col-md-12">
<div class="page-header-title">
<h5 class="m-b-10">集团经营目标表</h5>
</div>
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="#!"><i
class="feather icon-home"></i></a></li>
<li class="breadcrumb-item"><a href="#">基础数据</a></li>
<li class="breadcrumb-item"><a href="#">集团经营目标表</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- [ 面包屑 ] 结束 -->
<!-- [ 主内容 ] 开始 -->
<!-- [ 搜索&筛选 ] 开始 -->
<div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-9">
<!-- 筛选查询表单 -->
{% include 'filter.html' %}
</div>
<div class="col-md-3 mt-4 text-end">
<!-- 文件上传表单 -->
<button class="btn btn-outline-secondary"
data-bs-toggle="modal"
data-bs-target="#addModal">添加
</button>
<button class="btn btn-outline-danger"
data-bs-toggle="modal"
data-bs-target="#downloadModal">导出
</button>
<button class="btn btn-outline-primary"
data-bs-toggle="modal"
data-bs-target="#uploadModal">上传Excel
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- [ 搜索&筛选 ] 结束 -->
<!-- [ 数据表 ] 开始 -->
<div class="row mb-3">
<div class="col-sm-12">
<div class="card">
<div class="card-body table-border-style">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>#</th>
<th>一级部门</th>
<th>年份</th>
<th>项目性质</th>
<th>销售额(元)</th>
<th>收入总目标(元)</th>
<th>新增收入目标(元)</th>
<th>存量收入目标(元)</th>
<th>成本限额(元)</th>
<th>毛利润(元)</th>
<th>费用限额(元)</th>
<th>营业利润(元)</th>
<th>操作</th>
</tr>
</thead>
<tbody id="result" style="color: white;">
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- [ 数据表 ] 结束 -->
<!-- [ 分页&统计 ] 开始 -->
<div id="pagination"></div>
<!-- [ 分页&统计 ] 结束 -->
<!-- [ 主内容 ] 结束 -->
</div>
</div>
</div>
</div>
</div>
</section>
<!-- [ 主内容页 ] 结束 -->
<!-- 模态框 -->
<div id="modifyRecordsModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">
经营目标修改记录
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<table class="table">
<thead class="text-center">
<tr>
<th>年份</th>
<th>一级部门</th>
<th>修改字段</th>
<th>旧值</th>
<th>新值</th>
<th>修改日期</th>
<th>修改人</th>
</tr>
</thead>
<tbody class="text-center" style="color: white;">
<tr>
</tr>
<!-- 您可以添加更多的行,作为其他修改记录的数据 -->
</tbody>
</table>
<nav>
<ul class="pagination justify-content-end">
<!-- 分页按钮将由JS代码动态填充 -->
</ul>
</nav>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-bs-dismiss="modal">确定
</button>
</div>
</div>
</div>
</div>
<div id="uploadModal" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="exampleModalPopoversLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalPopoversLabel">上传文件</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="upload-form" enctype="multipart/form-data">
<input type="file" class="form-control" id="inputGroupFile01"
hidden>
<label class="btn btn-outline-primary"
for="inputGroupFile01">选择文件</label>
<span style="font-size: 12px">上传的文件格式为.xlsx</span>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-bs-dismiss="modal">取消
</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"
data-bs-toggle="modal"
data-bs-target="#newModal">上传
</button>
</div>
</div>
</div>
</div>
<div id="newModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document"
style="display: flex !important; align-items: center !important; justify-content: center !important;">
<div class="modal-content"
style="width: 100vw !important; margin: 0 !important; max-width: 1600px !important;">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">
上传文件预览
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<div style="overflow-x: auto;">
<table id="form-input-table"
class="table table-striped table-bordered nowrap">
<thead>
<tr>
<th>序号</th>
<th>一级部门</th>
<th>年份</th>
<th>项目性质</th>
<th>销售额</th>
<th>收入总目标</th>
<th>新增收入目标</th>
<th>存量收入目标</th>
<th>成本限额</th>
<th>毛利润</th>
<th>费用限额</th>
<th>营业利润</th>
</tr>
</thead>
<tbody>
{# <tr>#}
{# <td>1</td>#}
{# <td>#}
{# <select style="width: 200px;" class="form-control"#}
{# id="first_department" name="first_department">#}
{# <option value="天信">天信</option>#}
{# <option value="混改">混改</option>#}
{# <option value="艾力芬特">艾力芬特</option>#}
{# <option value="星河">星河</option>#}
{# <option value="星海">星海</option>#}
{# </select>#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="year" name="year" value="2024">#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="project_nature" name="project_nature"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="sales_amount" name="sales_amount" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="total_income_goal" name="total_income_goal"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="new_income_goal" name="new_income_goal"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="existing_income_goal" name="existing_income_goal"#}
{# >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="cost_limit" name="cost_limit" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="gross_profit" name="gross_profit" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="expense_limit" name="expense_limit" >#}
{# </td>#}
{# <td>#}
{# <input style="width: 180px;" type="text" class="form-control"#}
{# id="operating_profit" name="operating_profit">#}
{# </td>#}
{# </tr>#}
</table>
</div>
<div class="row mt-3 justify-content-end">
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers"
id="single-select_paginate">
<ul class="pagination justify-content-end">
<li class="paginate_button page-item previous disabled"
id="single-select_previous">
<a href="#" aria-controls="single-select" data-dt-idx="0"
tabindex="0"
class="page-link">上一页</a>
</li>
<li class="paginate_button page-item active">
<a href="#" aria-controls="single-select" data-dt-idx="1"
tabindex="0"
class="page-link">1</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="2"
tabindex="0"
class="page-link">2</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="3"
tabindex="0"
class="page-link">3</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="4"
tabindex="0"
class="page-link">4</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="5"
tabindex="0"
class="page-link">5</a>
</li>
<li class="paginate_button page-item ">
<a href="#" aria-controls="single-select" data-dt-idx="6"
tabindex="0"
class="page-link">6</a>
</li>
<li class="paginate_button page-item next"
id="single-select_next">
<a href="#" aria-controls="single-select" data-dt-idx="7"
tabindex="0"
class="page-link">下一页</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light"
data-bs-dismiss="modal">提交
</button>
</div>
</div>
</div>
</div>
<div id="addModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="addModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addModalCenterTitle">添加/编辑</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="groupBusinessTargetForm">
{% csrf_token %}
<!-- 使用row和col来控制标签的布局 -->
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="primary_department">一级部门</label>
<select class="form-control" id="primary_department_add" name="primary_department"
required>
<option value="">选择部门</option>
<option value="天信">天信</option>
<option value="混改">混改</option>
<option value="艾力芬特">艾力芬特</option>
<option value="星河">星河</option>
<option value="星海">星海</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="year">年份</label>
<select class="form-control" id="year_add" name="year" required>
<option value="">选择年度</option>
<option value="2024">2024</option>
<option value="2023">2023</option>
<option value="2022">2022</option>
<option value="2021">2021</option>
<option value="2020">2020</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="project_nature">项目性质</label>
<select class="form-control" id="project_nature_add" name="project_nature" required>
<option value="">选择项目性质</option>
<option value="新增">新增</option>
<option value="存续">存续</option>
<option value="新增及存续">新增及存续</option>
<option value="老客户新业务">老客户新业务</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="sales">销售额(元)</label>
<input type="number" class="form-control" id="sales_add" name="sales"
required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="total_revenue_target">收入总目标(元)</label>
<input type="number" class="form-control" id="total_revenue_target_add"
name="total_revenue_target" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="new_revenue_target">新增收入目标(元)</label>
<input type="number" class="form-control" id="new_revenue_target_add"
name="new_revenue_target"
required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="existing_revenue_target">存量收入目标(元)</label>
<input type="number" class="form-control" id="existing_revenue_target_add"
name="existing_revenue_target" required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="cost_limit">成本限额(元)</label>
<input type="number" class="form-control" id="cost_limit_add" name="cost_limit"
required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="gross_profit">毛利润(元)</label>
<input type="number" class="form-control" id="gross_profit_add" name="gross_profit"
required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="expense_limit">费用限额(元)</label>
<input type="number" class="form-control" id="expense_limit_add"
name="expense_limit"
required>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-control" for="operating_profit">营业利润(元)</label>
<input type="number" class="form-control" id="operating_profit_add"
name="operating_profit"
required>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="submitForm">添加</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<div id="modifyModal" class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
aria-labelledby="modifyModal" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addModalCenterTitle">修改</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="groupBusinessTargetForm">
{% csrf_token %}
<!-- 使用row和col来控制标签的布局 -->
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="primary_department">一级部门</label>
<input class="form-control" id="primary_department_modify" name="primary_department"
required disabled>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="year">年度</label>
<input class="form-control" id="year_modify" name="year"
required disabled>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="form-label" for="project_nature">项目性质</label>
<input class="form-control" id="project_nature_modify" name="project_nature"
required disabled>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="modified_field">修改字段</label>
<select class="form-control" id="modified_field" name="modified_field" required>
<option value="">选择修改字段</option>
<option value="销售额">销售额</option>
<option value="收入总目标">收入总目标</option>
<option value="新增收入目标">新增收入目标</option>
<option value="存量收入目标">存量收入目标</option>
<option value="成本限额">成本限额</option>
<option value="毛利润">毛利润</option>
<option value="费用限额">费用限额</option>
<option value="营业利润">营业利润</option>
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="old_value">旧值</label>
<input class="form-control" id="old_value" name="old_value"
required disabled>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="new_value">新值</label>
<input class="form-control" id="new_value" name="new_value"
required>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label" for="modified_by">修改人</label>
<input class="form-control" id="modified_by" name="modified_by"
required>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="submitModifyForm">确定
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<!-- 模态框结束 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!/^http:.*/.test(settings.url) && !/^https:.*/.test(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
// 查询接口
$(document).ready(function () {
// Fetch data when page loads
fetchData();
// 查询
$('#queryForm').on('submit', function (event) {
event.preventDefault();
fetchData();
});
// 分页
$(document).on('click', '.pagination .assembly-page', function (event) {
event.preventDefault();
const page = $(this).data('page');
fetchData(page);
});
$(document).on('click', '#modifyBtn', function (event) {
event.preventDefault();
const row = $(this).closest('tr');
const columns = row.find('td');
// Store row ID in modal for future reference
$('#modifyModal').data('row-id', row.data('row-id'));
// Get data from table cells
const primary_department = columns.eq(1).text();
const year = columns.eq(2).text();
const project_nature = columns.eq(3).text();
// Populate modal form with data
$('#primary_department_modify').val(primary_department);
$('#year_modify').val(year);
$('#project_nature_modify').val(project_nature);
// Open modal
$('#modifyModal').modal('show');
});
function fetchData(page = 1) {
const primary_department = $('#primary_department').val();
const year = $('#year').val();
const project_nature = $('#project_nature').val();
$.ajax({
type: "GET",
url: "/pm/query/",
data: {
primary_department: primary_department,
year: year,
project_nature: project_nature,
page: page
},
dataType: "json",
success: function (response) {
$('#result').empty();
response.targets.forEach(function (target, index) {
$('#result').append(
`<tr data-row-id="${index + 1}">
<td>${index + 1}</td>
<td>${target.primary_department}</td>
<td>${target.year}</td>
<td>${target.project_nature}</td>
<td>${target.sales}</td>
<td>${target.total_revenue_target}</td>
<td>${target.new_revenue_target}</td>
<td>${target.existing_revenue_target}</td>
<td>${target.cost_limit}</td>
<td>${target.gross_profit}</td>
<td>${target.expense_limit}</td>
<td>${target.operating_profit}</td>
<td><a href="#" data-bs-toggle="modal" id="modifyBtn"
data-bs-target="#modifyModal" style="color: #0d6efd">编辑</a></td>
</tr>`
);
});
$('#pagination').html(response.pagination_html);
},
error: function (error) {
console.error("Error: ", error);
alert("查询失败,请重试。");
}
});
}
$('#submitForm').on('click', function (event) {
event.preventDefault();
const data = {
primary_department: $('#primary_department_add').val(),
year: parseInt($('#year_add').val(), 10), // 确保年份是整数
project_nature: $('#project_nature_add').val(),
sales: parseFloat($('#sales_add').val()), // 确保数字字段是浮点数
total_revenue_target: parseFloat($('#total_revenue_target_add').val()),
new_revenue_target: parseFloat($('#new_revenue_target_add').val()),
existing_revenue_target: parseFloat($('#existing_revenue_target_add').val()),
cost_limit: parseFloat($('#cost_limit_add').val()),
gross_profit: parseFloat($('#gross_profit_add').val()),
expense_limit: parseFloat($('#expense_limit_add').val()),
operating_profit: parseFloat($('#operating_profit_add').val()),
};
$.ajax({
type: "POST",
url: "/pm/create/",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("记录添加成功!");
location.reload();
},
error: function (error) {
console.error("Error: ", error);
alert("记录添加失败,请检查输入内容。");
}
});
});
$('#modified_field').on('change', function () {
const modifiedField = $(this).val();
const rowId = $('#modifyModal').data('row-id');
const row = $(`tr[data-row-id="${rowId}"]`);
const columns = row.find('td');
let oldValue = '';
switch (modifiedField) {
case '销售额':
oldValue = columns.eq(4).text();
break;
case '收入总目标':
oldValue = columns.eq(5).text();
break;
case '新增收入目标':
oldValue = columns.eq(6).text();
break;
case '存量收入目标':
oldValue = columns.eq(7).text();
break;
case '成本限额':
oldValue = columns.eq(8).text();
break;
case '毛利润':
oldValue = columns.eq(9).text();
break;
case '费用限额':
oldValue = columns.eq(10).text();
break;
case '营业利润':
oldValue = columns.eq(11).text();
break;
}
$('#old_value').val(oldValue);
});
// 修改modal关闭后初始化数据
$('#modifyModal').on('hidden.bs.modal', function () {
// Reset form fields
$('#groupBusinessTargetForm')[0].reset();
// Clear data attributes
$('#modifyModal').removeData('row-id');
// Reset modified field dropdown to default
$('#modified_field').val('');
// Clear old and new values
$('#old_value').val('');
$('#new_value').val('');
});
$('#submitModifyForm').on('click', function () {
const target_id = $('#modifyModal').data('row-id');
const modified_field = $('#modified_field').val();
const old_value = $('#old_value').val();
const new_value = $('#new_value').val();
const modified_by = $('#modified_by').val();
$.ajax({
type: 'POST',
url: '/pm/add_target_audit/',
contentType: 'application/json',
data: JSON.stringify({
target_id: target_id,
modified_field: modified_field,
old_value: parseFloat(old_value),
new_value: parseFloat(new_value),
modified_by: modified_by
}),
dataType: 'json',
success: function (response) {
if (response.status === 'success') {
alert('修改记录已保存');
$('#modifyModal').modal('hide');
// Optionally, refresh the data here
fetchData();
} else {
alert('保存失败,请重试');
}
},
error: function (error) {
console.error('Error:', error);
alert('保存失败,请重试');
}
});
});
$(document).on('click', '.view-modify-records-btn', function (event) {
event.preventDefault();
// Fetch and display modify records for the first page
fetchModifyRecords(1);
});
// Fetch modify records function
function fetchModifyRecords(page) {
$.ajax({
type: 'GET',
url: '/pm/get_target_audit_records/',
data: {
page: page
},
dataType: 'json',
success: function (response) {
const records = response.records;
const tbody = $('#modifyRecordsModal tbody');
tbody.empty(); // Clear previous records
records.forEach(function (record) {
tbody.append(`
<tr>
<td>${record.year}</td>
<td>${record.primary_department}</td>
<td>${record.modified_field}</td>
<td>${record.old_value}</td>
<td>${record.new_value}</td>
<td>${record.modification_date}</td>
<td>${record.modified_by}</td>
</tr>
`);
});
// Update pagination
const pagination = $('#modifyRecordsModal .pagination');
pagination.empty(); // Clear previous pagination
if (response.has_previous) {
pagination.append(`
<li class="page-item">
<a class="page-link modify-page" href="#" data-page="${response.page - 1}">上一页</a>
</li>
`);
}
for (let i = 1; i <= response.num_pages; i++) {
pagination.append(`
<li class="page-item ${response.page === i ? 'active' : ''}">
<a class="page-link modify-page" href="#" data-page="${i}">${i}</a>
</li>
`);
}
if (response.has_next) {
pagination.append(`
<li class="page-item">
<a class="page-link modify-page" href="#" data-page="${response.page + 1}">下一页</a>
</li>
`);
}
// Open modal
$('#modifyRecordsModal').modal('show');
},
error: function (error) {
console.error('Error fetching modify records:', error);
alert('无法获取修改记录,请稍后重试。');
}
});
}
// Handle pagination click
$(document).on('click', '#modifyRecordsModal .pagination .modify-page', function (event) {
event.preventDefault();
const page = $(this).data('page');
fetchModifyRecords(page);
});
});
</script>
{% endblock %}

View File

@ -4,7 +4,7 @@ from .views import *
urlpatterns = [
# 集团经营目标
path('create/', create_group_business_target, name='create_group_business_target'),
path('query/', GroupBusinessTargetListView.as_view(), name='group_business_target_list'),
path('gbo_list/', gbo_list_view, name='group_business_target_list'),
path('add_target_audit/', add_target_audit, name='add_target_audit'),
path('get_target_audit_records/', get_target_audit_records, name='get_target_audit_records'),
# 员工业绩目标

View File

@ -9,10 +9,108 @@ from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view
from common.utils.page_helper import paginate_query_and_assign_numbers
from .models import GroupBusinessTarget, TargetAudit, EmployeeTargetAudit, EmployeePerformanceTarget
from .serializers import GroupBusinessTargetSerializer, EmployeePerformanceTargetSerializer
def gbo_list_view(request):
# 声明查询集
query_set = GroupBusinessTarget.objects.filter().order_by('-target_id')
# 获取查询参数
primary_department = request.GET.get('primary_department', '')
year = request.GET.get('year', '')
project_nature = request.GET.get('project_nature', '')
# 根据提供的参数进行筛选
if primary_department:
query_set = query_set.filter(primary_department=primary_department)
if year:
query_set = query_set.filter(year=year)
if project_nature:
query_set = query_set.filter(project_nature=project_nature)
# 对查询结果进行分页每页10条记录
items = paginate_query_and_assign_numbers(
request=request,
queryset=query_set,
per_page=10
)
# 构建上下文查询参数字符串
query_params = '&primary_department={}&year={}&project_nature={}'.format(primary_department, year, project_nature)
# 准备上下文
context = {
'items': items,
'filters': [
{
'type': 'select',
'id': 'primary_department',
'name': 'primary_department',
'label': '一级部门',
'options': [
{'value': '天信', 'display': '天信'},
{'value': '混改', 'display': '混改'},
{'value': '艾力芬特', 'display': '艾力芬特'},
{'value': '星河', 'display': '星河'},
{'value': '星海', 'display': '星海'},
],
},
{
'type': 'select',
'id': 'year',
'name': 'year',
'label': '年度',
'options': [
{'value': '2024', 'display': '2024'},
{'value': '2023', 'display': '2023'},
{'value': '2022', 'display': '2022'},
{'value': '2021', 'display': '2021'},
{'value': '2020', 'display': '2020'},
],
},
{
'type': 'select',
'id': 'project_nature',
'name': 'project_nature',
'label': '项目性质',
'options': [
{'value': '新增', 'display': '新增'},
{'value': '存续', 'display': '存续'},
{'value': '新增及存续', 'display': '新增及存续'},
{'value': '老客户新业务', 'display': '老客户新业务'},
],
},
], # 筛选框配置
"form_action_url": 'group_business_target_list',
'breadcrumb_list': [
{'title': '首页', 'name': 'index'},
{'title': '基础数据', 'name': 'index'},
{'title': '集团经营目标表', 'name': 'group_business_target_list'},
], # 面包屑
'query_params': query_params, # 查询参数字符串
'table_columns': [
{'header': '一级部门', 'field': 'primary_department'},
{'header': '年份', 'field': 'year'},
{'header': '项目性质', 'field': 'project_nature'},
{'header': '销售额(元)', 'field': 'sales'},
{'header': '收入总目标(元)', 'field': 'total_revenue_target'},
{'header': '新增收入目标(元)', 'field': 'new_revenue_target'},
{'header': '存量收入目标(元)', 'field': 'existing_revenue_target'},
{'header': '成本限额(元)', 'field': 'cost_limit'},
{'header': '毛利润(元)', 'field': 'gross_profit'},
{'header': '费用限额(元)', 'field': 'expense_limit'},
{'header': '营业利润(元)', 'field': 'operating_profit'},
{'header': '操作', 'field': 'actions'},
],
}
return render(request, 'perf_mgnt/gbo_list.html', context)
@api_view(['POST'])
def create_group_business_target(request):
if request.method == 'POST':
@ -66,7 +164,7 @@ class GroupBusinessTargetListView(View):
'operating_profit': target.operating_profit,
} for target in targets]
pagination_html = render(request, 'pagination.html', {
pagination_html = render(request, 'pagination_ps.html', {
'page': targets.number,
'pages': paginator.num_pages,
'has_next': targets.has_next(),
@ -212,7 +310,7 @@ class EmployeePerformanceTargetListView(View):
'existing_revenue_target': target.existing_revenue_target,
} for target in targets]
pagination_html = render(request, 'pagination.html', {
pagination_html = render(request, 'pagination_ps.html', {
'page': targets.number,
'pages': paginator.num_pages,
'has_next': targets.has_next(),
@ -345,7 +443,7 @@ def group_business_objectives(request):
],
}
return render(request, 'perf_mgnt/group_business_objectives.html', context=context)
return render(request, 'perf_mgnt/gbo_list.html', context=context)
def employee_performance_targets(request):

View File

@ -136,7 +136,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -297,7 +297,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -131,7 +131,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -123,7 +123,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -114,7 +114,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -201,7 +201,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -185,7 +185,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

View File

@ -134,7 +134,7 @@
</div>
</div>
</div>
{% include 'pagination.html' %}
{% include 'pagination_ps.html' %}
<!-- [ 主内容 ] 结束 -->
</div>
</div>

0
common/__init__.py Normal file
View File

3
common/admin.py Normal file
View File

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

6
common/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class CommonConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "common"

View File

3
common/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

View File

@ -0,0 +1,15 @@
# templatetags/tags.py
from django import template
register = template.Library()
@register.filter
def getattr_filter(obj, attr):
"""Custom template filter to get an attribute from an object."""
return getattr(obj, attr, '')
@register.simple_tag
def get_query_param(request, param_name):
return request.GET.get(param_name, '')

3
common/tests.py Normal file
View File

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

0
common/utils/__init__.py Normal file
View File

View File

@ -0,0 +1,60 @@
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
def paginate_query_and_assign_numbers(request, queryset, per_page):
"""
对查询集进行分页并为每页的结果集分配一个连续的序号
参数:
- request: HttpRequest 对象包含从客户端接收的所有HTTP GET请求参数
- queryset: QuerySet 对象包含了要进行分页的数据集
- per_page: int, 每页期望显示的条目数量
返回:
- page: 当前页的 Page 对象
"""
# 获取请求的页码默认第1页
page = request.GET.get('page', '1')
# 确保页码是有效的整数否则默认为第1页
page_number = int(page) if page.isdigit() else 1
# 计算当前页的第一个条目的序号
first_item_number = (page_number - 1) * per_page
# 创建 Paginator 对象实例进行分页操作
paginator = Paginator(queryset, per_page)
try:
# 获取当前页码的Page对象
page_items = paginator.page(page_number)
except PageNotAnInteger:
# 如果页码不是整数,则展示第一页,并计算当前页的第一个序号
page_items = paginator.page(1)
first_item_number = 0
except EmptyPage:
# 如果页码超出范围(即没有这么多页),则展示最后一页,并计算当前页的第一个序号
page_items = paginator.page(paginator.num_pages)
first_item_number = (paginator.num_pages - 1) * per_page
# 给每个列表对象添加序号
for index, item in enumerate(page_items):
item.number = first_item_number + index + 1
return page_items
def get_query_params_without_page(request):
"""
从请求中复制查询参数并移除 'page' 参数
参数:
- request: HttpRequest 对象包含 GET 请求参数
返回:
- url编码后的查询字符串不包含 'page' 参数
"""
query_params = request.GET.copy() # 复制请求的查询参数
query_params.pop('page', None) # 移除 'page' 参数,如果不存在则忽略
return query_params.urlencode() # 返回 url 编码后的查询字符串

3
common/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@ -164,10 +164,12 @@
<label>基础数据</label>
</li>
<li data-username="" class="nav-item pcoded-hasmenu">
<a href="#!" class="nav-link"><span class="pcoded-micon"><i
class="feather icon-box"></i></span><span class="pcoded-mtext">业绩管理</span></a>
<a href="#!" class="nav-link">
<span class="pcoded-micon"><i class="feather icon-box"></i></span>
<span class="pcoded-mtext">业绩管理</span>
</a>
<ul class="pcoded-submenu">
<li class=""><a href="{% url 'group_business_objectives' %}" class="">集团经营目标表</a></li>
<li class=""><a href="{% url 'group_business_target_list' %}" class="">集团经营目标表</a></li>
<li class=""><a href="{% url 'employee_performance_targets' %}" class="">员工业绩目标表</a></li>
</ul>
</li>

27
templates/breadcrumb.html Normal file
View File

@ -0,0 +1,27 @@
<div class="page-header">
<div class="page-block">
<div class="row align-items-center">
<div class="col-md-12">
<div class="page-header-title">
<h5 class="m-b-10">{{ page_title }}</h5>
</div>
<ul class="breadcrumb">
{% for crumb in breadcrumb_list %}
<li class="breadcrumb-item">
{% if crumb.name %}
<a href="{% url crumb.name %}">
{% if forloop.first %}
<i class="feather icon-home"></i>
{% endif %}
{{ crumb.title }}
</a>
{% else %}
{{ crumb.title }}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>

View File

@ -1,15 +1,16 @@
<form id="queryForm">
<form action="{% url form_action_url %}" method="get">
{% csrf_token %}
<div class="row">
{% for filter in filters %}
{% if filter.type == 'text' %}
<div class="col">
<label for="{{ filter.id }}" class="form-label">{{ filter.label }}</label>
<input class="form-control" id="{{ filter.id }}" placeholder="{{ filter.placeholder }}">
<input type="text" class="form-control" id="{{ filter.id }}" name="{{ filter.name }}" placeholder="{{ filter.placeholder }}">
</div>
{% elif filter.type == 'select' %}
<div class="col">
<label class="form-label" for="{{ filter.id }}">{{ filter.label }}</label>
<select class="form-control" id="{{ filter.id }}">
<select class="form-control" id="{{ filter.id }}" name="{{ filter.name }}">
{% for option in filter.options %}
<option value="{{ option.value }}">{{ option.display }}</option>
{% endfor %}
@ -18,7 +19,7 @@
{% elif filter.type == 'date' %}
<div class="col">
<label for="{{ filter.id }}" class="form-label">{{ filter.label }}</label>
<input type="date" class="form-control" id="{{ filter.id }}">
<input type="date" class="form-control" id="{{ filter.id }}" name="{{ filter.name }}">
</div>
{% endif %}
{% endfor %}

View File

@ -1,8 +1,10 @@
{# pagination.html #}
{% if page_obj.paginator.num_pages > 1 %}
<div class="row mb-3 justify-content-end">
<!-- [ 数量统计 ] 开始 -->
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="single-select_info" role="status" aria-live="polite">
显示第 {{ start_index }} 到第 {{ end_index }} 项,共 {{ total }} 项
显示第 {{ page_obj.start_index }} 到第 {{ page_obj.end_index }} 项,共 {{ page_obj.paginator.count }} 项
</div>
</div>
<!-- [ 数量统计 ] 结束 -->
@ -10,25 +12,47 @@
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers" id="single-select_paginate">
<ul class="pagination justify-content-end">
{% if has_previous %}
<li class="paginate_button page-item previous">
<a href="#" aria-controls="single-select" data-page="{{ page|add:"-1" }}"
class="page-link assembly-page">上一页</a>
<li class="paginate_button page-item {% if not page_obj.has_previous %}disabled{% endif %}">
<a href="?page=1{{ query_params }}" class="page-link">首页</a>
</li>
<li class="paginate_button page-item {% if not page_obj.has_previous %}disabled{% endif %}" id="single-select_previous">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}{{ query_params }}" aria-controls="single-select" tabindex="0" class="page-link">上一页</a>
{% else %}
<span class="page-link">上一页</span>
{% endif %}
</li>
{% with current=page_obj.number max_pages=page_obj.paginator.num_pages %}
{% for num in page_obj.paginator.page_range %}
{% if num >= current|add:"-2" and num <= current|add:"2" %}
<li class="paginate_button page-item {% if num == current %}active{% endif %}">
<a href="?page={{ num }}{{ query_params }}" aria-controls="single-select" tabindex="0" class="page-link">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% endwith %}
<li class="paginate_button page-item {% if not page_obj.has_next %}disabled{% endif %}" id="single-select_next">
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}{{ query_params }}" aria-controls="single-select" tabindex="0" class="page-link">下一页</a>
{% else %}
<span class="page-link">下一页</span>
{% endif %}
</li>
{% with max_pages=page_obj.paginator.num_pages %}
<!-- 其他分页代码... -->
<li class="paginate_button page-item {% if not page_obj.has_next %}disabled{% endif %}">
{% if page_obj.has_next %}
<a href="?page={{ max_pages }}{{ query_params }}"
class="page-link">尾页</a>
{% else %}
<span class="page-link">尾页</span>
{% endif %}
</li>
{% endif %}
{% for i in range %}
<li class="paginate_button page-item {% if i == page %}active{% endif %}">
<a href="#" aria-controls="single-select" data-page="{{ i }}" class="page-link assembly-page">{{ i }}</a>
</li>
{% endfor %}
{% if has_next %}
<li class="paginate_button page-item next">
<a href="#" aria-controls="single-select" data-page="{{ page|add:"1" }}"
class="page-link assembly-page">下一页</a>
</li>
{% endif %}
<!-- 其他分页代码... -->
{% endwith %}
</ul>
</div>
</div>
<!-- [ 分页 ] 结束 -->
</div>
{% endif %}

View File

@ -0,0 +1,37 @@
<div class="row mb-3 justify-content-end">
<!-- [ 数量统计 ] 开始 -->
<div class="col-sm-12 col-md-5">
<div class="dataTables_info" id="single-select_info" role="status" aria-live="polite">
显示第 {{ start_index }} 到第 {{ end_index }} 项,共 {{ total }} 项
</div>
</div>
<!-- [ 数量统计 ] 结束 -->
<!-- [ 分页 ] 开始 -->
<div class="col-sm-12 col-md-7">
<div class="dataTables_paginate paging_simple_numbers" id="single-select_paginate">
<ul class="pagination justify-content-end">
{% if has_previous %}
<li class="paginate_button page-item previous">
<a href="#" aria-controls="single-select" data-page="{{ page|add:"-1" }}"
class="page-link assembly-page">上一页</a>
</li>
{% endif %}
{% for i in range %}
<li class="paginate_button page-item {% if i == page %}active{% endif %}">
<a href="#" aria-controls="single-select" data-page="{{ i }}" class="page-link assembly-page">{{ i }}</a>
</li>
{% endfor %}
{% if has_next %}
<li class="paginate_button page-item next">
<a href="#" aria-controls="single-select" data-page="{{ page|add:"1" }}"
class="page-link assembly-page">下一页</a>
</li>
{% endif %}
</ul>
</div>
</div>
<!-- [ 分页 ] 结束 -->
</div>

30
templates/table.html Normal file
View File

@ -0,0 +1,30 @@
{% load tags %}
<div class="card-body table-border-style">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
{% for column in table_columns %}
<th>{{ column.header }}</th>
{% endfor %}
</tr>
</thead>
<tbody id="result" style="color: white;">
{% for item in items %}
<tr>
{% for column in table_columns %}
{% if column.field == 'actions' %}
<td>
<a href="#">编辑</a>
</td>
{% else %}
<td>{{ item|getattr_filter:column.field }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>