feat: 生物由来照会画面のパフォーマンス改善. ページネーションの1ページ分のみ取得するように修正。
This commit is contained in:
parent
426fa534b2
commit
ad557d499e
@ -79,3 +79,22 @@ def search_bio(
|
||||
headers={'session_key': session_key}
|
||||
)
|
||||
return templates_response
|
||||
|
||||
|
||||
@router.post('/BioSearchListAjax')
|
||||
def search_bio_ajax(
|
||||
request: Request,
|
||||
bio_form: Optional[BioModel] = Depends(BioModel.as_form),
|
||||
bio_service: BioViewService = Depends(get_service(BioViewService)),
|
||||
batch_status_service: BatchStatusService = Depends(get_service(BatchStatusService))
|
||||
):
|
||||
session: UserSession = request.session
|
||||
# バッチ処理中の場合、機能を利用させない
|
||||
if batch_status_service.is_batch_processing():
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=constants.LOGOUT_REASON_BATCH_PROCESSING)
|
||||
|
||||
# 生物由来データと件数を取得
|
||||
bio_sales_lot_data = bio_service.search_bio_data(bio_form)
|
||||
bio_sales_lot_count = bio_service.count_bio_data(bio_form, session)
|
||||
|
||||
return {'data': bio_sales_lot_data, 'count': bio_sales_lot_count}
|
||||
|
||||
@ -42,3 +42,7 @@ class BioSalesLotDBModel(BaseDBModel):
|
||||
data_kind: Optional[str]
|
||||
err_dtl_kind: Optional[str]
|
||||
expr_dt: Optional[date]
|
||||
|
||||
|
||||
class BioSalesLotCountDBModel(BaseDBModel):
|
||||
count: Optional[int]
|
||||
|
||||
@ -21,6 +21,8 @@ class BioModel(BaseModel):
|
||||
rev_hsdnymd_srk_from: Optional[str]
|
||||
rev_hsdnymd_srk_to: Optional[str]
|
||||
iko_flg: Optional[str]
|
||||
pageNumber: Optional[int]
|
||||
pageSize: Optional[int]
|
||||
|
||||
@classmethod
|
||||
def as_form(
|
||||
@ -34,7 +36,9 @@ class BioModel(BaseModel):
|
||||
ctrl_maker_cd: str = Form(None),
|
||||
ctrl_rev_hsdnymd_srk_from: str = Form(None),
|
||||
ctrl_rev_hsdnymd_srk_to: str = Form(None),
|
||||
ikoFlg: str = Form(None)
|
||||
ikoFlg: str = Form(None),
|
||||
pageNumber: int = Form(None),
|
||||
pageSize: int = Form(None)
|
||||
):
|
||||
|
||||
return cls.__convert_request_param(
|
||||
@ -48,7 +52,9 @@ class BioModel(BaseModel):
|
||||
ctrl_maker_cd,
|
||||
ctrl_rev_hsdnymd_srk_from,
|
||||
ctrl_rev_hsdnymd_srk_to,
|
||||
ikoFlg
|
||||
ikoFlg,
|
||||
pageNumber,
|
||||
pageSize
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -91,7 +97,9 @@ class BioModel(BaseModel):
|
||||
ctrl_maker_cd: str,
|
||||
ctrl_rev_hsdnymd_srk_from: str,
|
||||
ctrl_rev_hsdnymd_srk_to: str,
|
||||
ikoFlg: str
|
||||
ikoFlg: str,
|
||||
pageNumber: int = None,
|
||||
pageSize: int = None
|
||||
):
|
||||
wholesaler_code = None
|
||||
wholesaler_sub_code = None
|
||||
@ -132,5 +140,7 @@ class BioModel(BaseModel):
|
||||
mkr_cd=ctrl_maker_cd,
|
||||
rev_hsdnymd_srk_from=rev_hsdnymd_srk_from,
|
||||
rev_hsdnymd_srk_to=rev_hsdnymd_srk_to,
|
||||
iko_flg=ikoFlg
|
||||
iko_flg=ikoFlg,
|
||||
pageNumber=pageNumber,
|
||||
pageSize=pageSize
|
||||
)
|
||||
|
||||
@ -152,6 +152,9 @@ class BioViewModel(BaseModel):
|
||||
def is_data_overflow_max_length(self):
|
||||
return self.bio_data is None or len(self.bio_data) > environment.BIO_SEARCH_RESULT_MAX_COUNT
|
||||
|
||||
def data_overflow_max_length(self):
|
||||
return environment.BIO_SEARCH_RESULT_MAX_COUNT
|
||||
|
||||
def _format_date_string(self, date_string):
|
||||
if date_string is None:
|
||||
return ''
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
from src.db import sql_condition as condition
|
||||
from src.db.sql_condition import SQLCondition
|
||||
from src.logging.get_logger import get_logger
|
||||
from src.model.db.bio_sales_lot import BioSalesLotDBModel
|
||||
from src.model.db.bio_sales_lot import (BioSalesLotCountDBModel,
|
||||
BioSalesLotDBModel)
|
||||
from src.model.request.bio import BioModel
|
||||
from src.repositories.base_repository import BaseRepository
|
||||
from src.system_var import environment
|
||||
@ -67,12 +68,12 @@ class BioSalesLotRepository(BaseRepository):
|
||||
try:
|
||||
logger.debug('DB参照実行')
|
||||
where_clause = self.__build_condition(parameter)
|
||||
# システムとしての最大取得件数 +1 まで取る
|
||||
query = self.FETCH_SQL.format(where_clause=where_clause, limit=environment.BIO_SEARCH_RESULT_MAX_COUNT + 1)
|
||||
# ページングで取得するため、LIMIT,OFFSETを指定
|
||||
limit_clause = self.__build_paging_limit_clauses(parameter)
|
||||
query = self.FETCH_SQL.format(where_clause=where_clause, limit=limit_clause)
|
||||
logger.debug(f'SQL: {query}')
|
||||
result = self._database.execute_select(query, parameter.model_dump())
|
||||
models = [BioSalesLotDBModel(**r) for r in result]
|
||||
logger.debug(f'count= {len(models)}')
|
||||
return models
|
||||
except Exception as e:
|
||||
logger.exception(f"DB Error : Exception={e.args}")
|
||||
@ -92,6 +93,35 @@ class BioSalesLotRepository(BaseRepository):
|
||||
logger.exception(f"DB Error : Exception={e.args}")
|
||||
raise e
|
||||
|
||||
COUNT_SQL = """\
|
||||
SELECT
|
||||
COUNT(*) AS count
|
||||
FROM
|
||||
(
|
||||
SELECT 1
|
||||
FROM src05.bio_sales_lot
|
||||
WHERE
|
||||
{where_clause}
|
||||
LIMIT {limit}
|
||||
) AS t\
|
||||
"""
|
||||
|
||||
def fetch_count(self, parameter: BioModel) -> list[BioSalesLotDBModel]:
|
||||
try:
|
||||
logger.debug('DB参照実行')
|
||||
where_clause = self.__build_condition(parameter)
|
||||
# システムとしての最大取得件数 + 1まで取る
|
||||
query = self.COUNT_SQL.format(where_clause=where_clause, limit=environment.BIO_SEARCH_RESULT_MAX_COUNT + 1)
|
||||
logger.debug(f'SQL: {query}')
|
||||
result = self._database.execute_select(query, parameter.model_dump())
|
||||
models = [BioSalesLotCountDBModel(**r) for r in result]
|
||||
count = models[0].count if len(models) > 0 else 0
|
||||
logger.debug(f'count= {count}')
|
||||
return count
|
||||
except Exception as e:
|
||||
logger.exception(f"DB Error : Exception={e.args}")
|
||||
raise e
|
||||
|
||||
def __build_condition(self, parameter: BioModel):
|
||||
where_clauses: list[SQLCondition] = []
|
||||
|
||||
@ -141,3 +171,9 @@ class BioSalesLotRepository(BaseRepository):
|
||||
|
||||
logger.debug(f'条件設定終了:{where_clauses_str}')
|
||||
return where_clauses_str
|
||||
|
||||
def __build_paging_limit_clauses(self, parameter: BioModel) -> str:
|
||||
page_size = parameter.pageSize or 0
|
||||
page_number = parameter.pageNumber or 0
|
||||
|
||||
return f'{page_size} OFFSET {(page_number - 1) * page_size}'
|
||||
|
||||
@ -71,6 +71,11 @@ class BioViewService(BaseService):
|
||||
|
||||
return display_bio_data
|
||||
|
||||
def count_bio_data(self, search_params: BioModel, session: UserSession):
|
||||
# 生物由来データの件数を取得
|
||||
bio_sales_data_count = self.bio_sales_repository.fetch_count(parameter=search_params)
|
||||
return bio_sales_data_count
|
||||
|
||||
def search_download_bio_data(
|
||||
self,
|
||||
search_params: BioModel,
|
||||
|
||||
@ -28,13 +28,13 @@
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<form class="_form _border" id="bio_search" name="search" action="/bio/BioSearchList" method="POST" onsubmit="showLoading('_loading_for_other')">
|
||||
<form class="_form _border" id="bio_search" name="search">
|
||||
<table class="search_table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>卸:</td>
|
||||
<td class="search_tb" id="oroshi_dd">
|
||||
<select class="text search_dropdown" name="ctrl_wholesaler" value="" onChange="formBtDisabled();">
|
||||
<select class="text search_dropdown" name="ctrl_wholesaler" value="" onChange="formBtDisabled();applySearchParam(this)">
|
||||
<option value=""></option>
|
||||
{% for whs_name in bio.display_wholesaler_names() %}
|
||||
<option
|
||||
@ -47,7 +47,7 @@
|
||||
</td>
|
||||
<td>データ種別:</td>
|
||||
<td class="search_tb">
|
||||
<select class="text search_dropdown" name="ctrl_org_kbn" onChange="formBtDisabled();" value="">
|
||||
<select class="text search_dropdown" name="ctrl_org_kbn" onChange="formBtDisabled();applySearchParam(this)" value="">
|
||||
{% for org_kbn_code, org_kbn_value in bio.display_org_kbn().items() %}
|
||||
<option value="{{org_kbn_code}}" {{bio.is_selected_org_kbn(org_kbn_code)}} >{{org_kbn_value}}</option>
|
||||
{% endfor %}
|
||||
@ -57,12 +57,12 @@
|
||||
<td colspan="2">
|
||||
<input type="text" id="shoribi_start" class="date_picker" name="ctrl_rec_ymd_from" maxlength="10"
|
||||
value="{{bio.is_input_rec_ymd_from()}}"
|
||||
onchange="formBtDisabled()"
|
||||
onchange="formBtDisabled();applySearchParam(this)"
|
||||
>
|
||||
~
|
||||
<input type="text" id="shoribi_end" class="date_picker" name="ctrl_rec_ymd_to" maxlength="10"
|
||||
value="{{bio.is_input_rec_ymd_to()}}"
|
||||
onchange="formBtDisabled()"
|
||||
onchange="formBtDisabled();applySearchParam(this)"
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
@ -71,11 +71,11 @@
|
||||
<td class="search_tb">
|
||||
<input class="text" type="text" id="lot_tb" name="ctrl_rec_lot_num" style="ime-mode:disabled" maxlength="10"
|
||||
value="{{bio.is_input_lot_num()}}"
|
||||
oninput="checkSpaceForm(this); checkAimaiSearhForm(this); formBtDisabled()">
|
||||
oninput="checkSpaceForm(this); checkAimaiSearhForm(this); formBtDisabled();applySearchParam(this)">
|
||||
</td>
|
||||
<td>データ区分:</td>
|
||||
<td class="search_tb">
|
||||
<select class="text search_dropdown" name="ctrl_data_kbn" onchange="formBtDisabled()">
|
||||
<select class="text search_dropdown" name="ctrl_data_kbn" onchange="formBtDisabled();applySearchParam(this)">
|
||||
{% for data_kbn_code, data_kbn_value in bio.display_data_kbn().items() %}
|
||||
<option value="{{data_kbn_value}}" {{bio.is_selected_data_kbn(data_kbn_value)}} >{{data_kbn_value}}</option>
|
||||
{% endfor %}
|
||||
@ -83,7 +83,7 @@
|
||||
</td>
|
||||
<td>製品:</td>
|
||||
<td class="search_tb" id="seihin_dd">
|
||||
<select class="text search_dropdown" name="ctrl_maker_cd" value="" onChange="formBtDisabled();">
|
||||
<select class="text search_dropdown" name="ctrl_maker_cd" value="" onChange="formBtDisabled();applySearchParam(this);">
|
||||
<option value=""></option>
|
||||
{% for phm in bio.phm_models %}
|
||||
<option
|
||||
@ -99,21 +99,22 @@
|
||||
<td colspan="3">
|
||||
<input type="text" id="hsdnymd_start" class="date_picker" name="ctrl_rev_hsdnymd_srk_from" maxlength="10"
|
||||
value="{{bio.is_input_rev_hsdnymd_srk_from()}}"
|
||||
onchange="formBtDisabled()"
|
||||
onchange="formBtDisabled();applySearchParam(this)"
|
||||
>
|
||||
~
|
||||
<input type="text" id="hsdnymd_end" class="date_picker" name="ctrl_rev_hsdnymd_srk_to" maxlength="10"
|
||||
value="{{bio.is_input_rev_hsdnymd_srk_to()}}"
|
||||
onchange="formBtDisabled()"
|
||||
onchange="formBtDisabled();applySearchParam(this)"
|
||||
>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input type="checkbox" id="ikoFlg" name="ikoFlg" value="true" {{bio.is_checked_iko_flg()}}>
|
||||
<input type="checkbox" id="ikoFlg" name="ikoFlg" value="true" {{bio.is_checked_iko_flg()}} oninput="applySearchParam(this)">
|
||||
<label for="ikoFlg">2017年11月以前のデータを含める</label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="buttonSize" id="clear" type="button" name="clear_bt" value="クリア" onclick="clr()">
|
||||
<input class="buttonSize" id="search_bt" value="検索" type="submit">
|
||||
<!-- <input class="buttonSize" id="search_bt" value="検索" type="submit"> -->
|
||||
<input class="buttonSize" id="search_bt" value="検索" type="button" onclick="searchBioList()">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -121,9 +122,9 @@
|
||||
</form>
|
||||
<!--検索結果-->
|
||||
<form class="_form" id="searchResult" name="searchResult">
|
||||
<input type="button" id="outExcel" name="outExcel" value="Excel出力" {{bio.disabled_button()}}
|
||||
<input type="button" id="outExcel" name="outExcel" value="Excel出力" disabled
|
||||
data-bs-toggle="modal" data-bs-target="#modal_xlsx" data-bs-message="生物由来卸販売データ一覧をExcel出力しますか?"/>
|
||||
<input type="button" id="outCSV" name="outCSV" value="CSV出力" {{bio.disabled_button()}}
|
||||
<input type="button" id="outCSV" name="outCSV" value="CSV出力" disabled
|
||||
data-bs-toggle="modal" data-bs-target="#modal_csv" data-bs-message="生物由来卸販売データ一覧をCSV出力しますか?" />
|
||||
<!--ページネーション-->
|
||||
<div id="light-pagination" class="pagination"></div>
|
||||
@ -173,10 +174,10 @@
|
||||
</thead>
|
||||
<tbody id="result_data" class="result_data"></tbody>
|
||||
</table>
|
||||
<div id="message_area" class="resultAreaMsg"></div>
|
||||
{% if bio.is_form_submitted() and bio.is_data_overflow_max_length() %}
|
||||
<div class="resultAreaMsg">
|
||||
検索結果が最大件数を超えました。検索条件を見直しして下さい。
|
||||
</div>
|
||||
検索結果が最大件数を超えました。検索条件を見直しして下さい。
|
||||
|
||||
{% endif %}
|
||||
{% if bio.is_form_submitted() and bio.is_data_empty() %}
|
||||
<div class="resultAreaMsg">
|
||||
@ -185,7 +186,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
<form id="bio_download">
|
||||
<form id="search_param_hidden" name="bioHidden">
|
||||
<input type="hidden" name="ctrl_wholesaler" value="{{bio.make_whs_name()}}">
|
||||
<input type="hidden" name="ctrl_org_kbn" value="{{bio.form_data.slip_org_kbn or ''}}">
|
||||
<input type="hidden" name="ctrl_rec_ymd_from" value="{{bio.is_input_rec_ymd_from()}}">
|
||||
@ -198,25 +199,20 @@
|
||||
<input type="checkbox" name="ikoFlg" value="true" {{bio.is_checked_iko_flg()}} style="display: none;">
|
||||
</form>
|
||||
|
||||
<!-- CSV/Excelダウンロード処理-->
|
||||
<script type="text/javascript">
|
||||
// CSV/Excelダウンロード処理
|
||||
function download(ext) {
|
||||
// ローディング開始
|
||||
const loading = new Loading();
|
||||
loading.start();
|
||||
|
||||
// 検索パラメータを取得
|
||||
const formData = $('#bio_download').serializeArray()
|
||||
// リクエスト用に加工
|
||||
const searchParams = {}
|
||||
for (let i = 0; i < formData.length; i++) {
|
||||
searchParams[formData[i].name] = formData[i].value
|
||||
}
|
||||
// ダウンロード固有のパラメータを設定
|
||||
const downloadRequestParams = {
|
||||
user_id: '{{bio.user_id}}',
|
||||
ext: ext,
|
||||
}
|
||||
// 検索パラメータを取得
|
||||
const searchParams = createSearchParams()
|
||||
$.extend(downloadRequestParams, searchParams)
|
||||
|
||||
$.ajax({
|
||||
@ -272,13 +268,42 @@
|
||||
});
|
||||
}
|
||||
|
||||
// <! --ページネーションの作成-- >
|
||||
$(function() {
|
||||
const searchResultData = generateSearchResult();
|
||||
if (searchResultData.length == 0) return;
|
||||
function createSearchParams() {
|
||||
// 検索パラメータを取得
|
||||
const formData = $('#search_param_hidden').serializeArray()
|
||||
// リクエスト用に加工
|
||||
const searchParams = {}
|
||||
for (let i = 0; i < formData.length; i++) {
|
||||
searchParams[formData[i].name] = formData[i].value
|
||||
}
|
||||
|
||||
$(".pagination").pagination({
|
||||
dataSource: searchResultData,
|
||||
return searchParams
|
||||
}
|
||||
|
||||
function applySearchParam(elem) {
|
||||
console.log(elem.value)
|
||||
console.log(elem.name)
|
||||
const bioHiddenForm = document['bioHidden']
|
||||
bioHiddenForm[elem.name].value = elem.value
|
||||
if (bioHiddenForm[elem.name].type === 'checkbox') {
|
||||
bioHiddenForm[elem.name].checked = elem.checked
|
||||
}
|
||||
console.log(bioHiddenForm[elem.name].value)
|
||||
}
|
||||
// <! --ページネーションの作成-- >
|
||||
|
||||
function searchBioList() {
|
||||
const messageArea = $('#message_area')
|
||||
messageArea.text('')
|
||||
const loading = new Loading();
|
||||
const searchParams = createSearchParams()
|
||||
$('.pagination').pagination({
|
||||
dataSource: '/bio/BioSearchListAjax',
|
||||
locator: 'data',
|
||||
totalNumberLocator: function(response) {
|
||||
// you can return totalNumber by analyzing response content
|
||||
return response.count
|
||||
},
|
||||
pageNumber: 1, // 初期ページ番号
|
||||
pageSize: 100, //表示するコンテンツ数
|
||||
pageRange: 2, //選択されているページネーション番号の両隣に表示する個数
|
||||
@ -287,8 +312,42 @@
|
||||
nextText: 'Next', //「次へ」の文字。エスケープ文字
|
||||
showNavigator: true,
|
||||
formatNavigator: '件数: <%= totalNumber %>件 ページ数: <%= totalPage %>',
|
||||
ajax: {
|
||||
type: 'POST',
|
||||
data: searchParams,
|
||||
async: true,
|
||||
beforeSend: function() {
|
||||
loading.start()
|
||||
}
|
||||
},
|
||||
formatAjaxError: function(jqXHR, textStatus, errorThrown) {
|
||||
loading.stop();
|
||||
$(`#ErrorModal_Unexpected`).modal('toggle');
|
||||
},
|
||||
callback: function(data, pagination) {
|
||||
$('#result_data').html('')
|
||||
if (pagination.totalNumber === 0) {
|
||||
loading.stop();
|
||||
messageArea.text('対象のデータが存在しません')
|
||||
$('.pagination').pagination('hide')
|
||||
$('#outExcel').attr('disabled', 'disabled')
|
||||
$('#outCSV').attr('disabled', 'disabled')
|
||||
return
|
||||
}
|
||||
|
||||
if (pagination.totalNumber > bioDataOverflowMaxLength()) {
|
||||
loading.stop();
|
||||
messageArea.text('検索結果が最大件数を超えました。検索条件を見直しして下さい。')
|
||||
$('.pagination').pagination('hide')
|
||||
$('#outExcel').attr('disabled', 'disabled')
|
||||
$('#outCSV').attr('disabled', 'disabled')
|
||||
return
|
||||
}
|
||||
$('.pagination').pagination('show')
|
||||
$('#result_data').html(pagination_content(data))
|
||||
loading.stop();
|
||||
$('#outExcel').removeAttr('disabled')
|
||||
$('#outCSV').removeAttr('disabled')
|
||||
$('.paginationjs-pages > ul > li').not('.disabled,.active').each(function(index, val) {
|
||||
// paginationにtabindexをつける
|
||||
$(val).attr('tabindex', '0')
|
||||
@ -307,7 +366,12 @@
|
||||
FixedMidashi.create();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function bioDataOverflowMaxLength() {
|
||||
const maxlength = '{{bio.data_overflow_max_length()}}'
|
||||
return Number(maxlength)
|
||||
}
|
||||
|
||||
function pagination_content(datas) {
|
||||
const display_keys = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user