You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

619 lines
25 KiB

import dash
import time
import uuid
from dash import dcc
from dash.dependencies import Input, Output, State, ALL
from dash.exceptions import PreventUpdate
import feffery_utils_components as fuc
from server import app
from utils.common import validate_data_not_empty
from api.cdplb import get_cdplb_list_api, get_cdplb_detail_api, add_cdplb_api, edit_cdplb_api, delete_cdplb_api, export_cdplb_list_api,batch_import_cdplb_api,download_cdplb_import_template_api
@app.callback(
output=dict(
cdplb_table_data=Output('cdplb-list-table', 'data', allow_duplicate=True),
cdplb_table_pagination=Output('cdplb-list-table', 'pagination', allow_duplicate=True),
cdplb_table_key=Output('cdplb-list-table', 'key'),
cdplb_table_selectedrowkeys=Output('cdplb-list-table', 'selectedRowKeys'),
api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True)
),
inputs=dict(
search_click=Input('cdplb-search', 'nClicks'),
refresh_click=Input('cdplb-refresh', 'nClicks'),
pagination=Input('cdplb-list-table', 'pagination'),
operations=Input('cdplb-operations-store', 'data')
),
state=dict(
bath_obj_tab_name=State('cdplb-bath_obj_tab_name-input', 'value'),
bath_obj_fld_name=State('cdplb-bath_obj_fld_name-input', 'value'),
pos_name=State('cdplb-pos_name-input', 'value'),
status_select=State('cdplb-status-select', 'value'),
button_perms=State('cdplb-button-perms-container', 'data')
),
prevent_initial_call=True
)
def get_cdplb_table_data(search_click, refresh_click, pagination, operations, bath_obj_tab_name, bath_obj_fld_name,pos_name, status_select, button_perms):
"""
获取批量词典配置表表格数据回调(进行表格相关增删查改操作后均会触发此回调)
"""
query_params = dict(
bath_obj_tab_name=bath_obj_tab_name,
bath_obj_fld_name=bath_obj_fld_name,
pos_name = pos_name,
status=status_select,
page_num=1,
page_size=10
)
triggered_id = dash.ctx.triggered_id
if triggered_id == 'cdplb-list-table':
query_params = dict(
bath_obj_tab_name=bath_obj_tab_name,
bath_obj_fld_name=bath_obj_fld_name,
pos_name = pos_name,
status=status_select,
page_num=pagination['current'],
page_size=pagination['pageSize']
)
if search_click or refresh_click or pagination or operations:
table_info = get_cdplb_list_api(query_params)
if table_info['code'] == 200:
table_data = table_info['data']['rows']
table_pagination = dict(
pageSize=table_info['data']['page_size'],
current=table_info['data']['page_num'],
showSizeChanger=True,
pageSizeOptions=[10, 30, 50, 100],
showQuickJumper=True,
total=table_info['data']['total']
)
for item in table_data:
if item['status'] == '0':
#item['status'] = dict(tag='正常', color='blue')
item['status'] = dict(checked=True)
else:
#item['status'] = dict(tag='停用', color='volcano')
item['status'] = dict(checked=False)
item['key'] = str(item['onum'])
item['operation'] = [
{
'content': '修改',
'type': 'link',
'icon': 'antd-edit'
} if 'dataint:cypz:cdplb:edit' in button_perms else {},
{
'content': '删除',
'type': 'link',
'icon': 'antd-delete'
} if 'dataint:cypz:cdplb:remove' in button_perms else {},
]
return dict(
cdplb_table_data=table_data,
cdplb_table_pagination=table_pagination,
cdplb_table_key=str(uuid.uuid4()),
cdplb_table_selectedrowkeys=None,
api_check_token_trigger={'timestamp': time.time()}
)
return dict(
cdplb_table_data=dash.no_update,
cdplb_table_pagination=dash.no_update,
cdplb_table_key=dash.no_update,
cdplb_table_selectedrowkeys=dash.no_update,
api_check_token_trigger={'timestamp': time.time()}
)
raise PreventUpdate
# 重置批量词典配置表搜索表单数据回调 Output('cdplb-std_rpl_str-input', 'value'),
app.clientside_callback(
'''
(reset_click) => {
if (reset_click) {
return [null, null, null, null, {'type': 'reset'}]
}
return window.dash_clientside.no_update;
}
''',
[Output('cdplb-bath_obj_tab_name-input', 'value'),
Output('cdplb-bath_obj_fld_name-input', 'value'),
Output('cdplb-pos_name-input', 'value'),
Output('cdplb-status-select', 'value'),
Output('cdplb-operations-store', 'data')],
Input('cdplb-reset', 'nClicks'),
prevent_initial_call=True
)
# 隐藏/显示批量词典配置表搜索表单回调
app.clientside_callback(
'''
(hidden_click, hidden_status) => {
if (hidden_click) {
return [
!hidden_status,
hidden_status ? '隐藏搜索' : '显示搜索'
]
}
return window.dash_clientside.no_update;
}
''',
[Output('cdplb-search-form-container', 'hidden'),
Output('cdplb-hidden-tooltip', 'title')],
Input('cdplb-hidden', 'nClicks'),
State('cdplb-search-form-container', 'hidden'),
prevent_initial_call=True
)
@app.callback(
Output({'type': 'cdplb-operation-button', 'index': 'edit'}, 'disabled'),
Input('cdplb-list-table', 'selectedRowKeys'),
prevent_initial_call=True
)
def change_cdplb_edit_button_status(table_rows_selected):
"""
根据选择的表格数据行数控制编辑按钮状态回调
"""
outputs_list = dash.ctx.outputs_list
if outputs_list:
if table_rows_selected:
if len(table_rows_selected) > 1:
return True
return False
return True
raise PreventUpdate
@app.callback(
Output({'type': 'cdplb-operation-button', 'index': 'delete'}, 'disabled'),
Input('cdplb-list-table', 'selectedRowKeys'),
prevent_initial_call=True
)
def change_cdplb_delete_button_status(table_rows_selected):
"""
根据选择的表格数据行数控制删除按钮状态回调
"""
outputs_list = dash.ctx.outputs_list
if outputs_list:
if table_rows_selected:
return False
return True
raise PreventUpdate
@app.callback(
output=dict(
modal_visible=Output('cdplb-modal', 'visible', allow_duplicate=True),
modal_title=Output('cdplb-modal', 'title'),
form_value=Output({'type': 'cdplb-form-value', 'index': ALL}, 'value'),
form_label_validate_status=Output({'type': 'cdplb-form-label', 'index': ALL, 'required': True}, 'validateStatus', allow_duplicate=True),
form_label_validate_info=Output({'type': 'cdplb-form-label', 'index': ALL, 'required': True}, 'help', allow_duplicate=True),
api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True),
edit_row_info=Output('cdplb-edit-id-store', 'data'),
modal_type=Output('cdplb-operations-store-bk', 'data')
),
inputs=dict(
operation_click=Input({'type': 'cdplb-operation-button', 'index': ALL}, 'nClicks'),
button_click=Input('cdplb-list-table', 'nClicksButton')
),
state=dict(
selected_row_keys=State('cdplb-list-table', 'selectedRowKeys'),
clicked_content=State('cdplb-list-table', 'clickedContent'),
recently_button_clicked_row=State('cdplb-list-table', 'recentlyButtonClickedRow')
),
prevent_initial_call=True
)
def add_edit_cdplb_modal(operation_click, button_click, selected_row_keys, clicked_content, recently_button_clicked_row):
"""
显示新增或编辑批量词典配置表弹窗回调
"""
trigger_id = dash.ctx.triggered_id
if trigger_id == {'index': 'add', 'type': 'cdplb-operation-button'} \
or trigger_id == {'index': 'edit', 'type': 'cdplb-operation-button'} \
or (trigger_id == 'cdplb-list-table' and clicked_content == '修改'):
# 获取所有输出表单项对应value的index
form_value_list = [x['id']['index'] for x in dash.ctx.outputs_list[2]]
# 获取所有输出表单项对应label的index
form_label_list = [x['id']['index'] for x in dash.ctx.outputs_list[3]]
if trigger_id == {'index': 'add', 'type': 'cdplb-operation-button'}:
# bath_obj_tab_name bath_obj_fld_name freq pos pos_name
cdplb_info = dict(bath_obj_tab_name=None, bath_obj_fld_name=None, freq=None, pos=0, status='0', pos_name=None)
return dict(
modal_visible=True,
modal_title='新增批量词典配置表',
form_value=[cdplb_info.get(k) for k in form_value_list],
form_label_validate_status=[None] * len(form_label_list),
form_label_validate_info=[None] * len(form_label_list),
api_check_token_trigger=dash.no_update,
edit_row_info=None,
modal_type={'type': 'add'}
)
elif trigger_id == {'index': 'edit', 'type': 'cdplb-operation-button'} or (trigger_id == 'cdplb-list-table' and clicked_content == '修改'):
if trigger_id == {'index': 'edit', 'type': 'cdplb-operation-button'}:
onum = int(','.join(selected_row_keys))
else:
onum = int(recently_button_clicked_row['key'])
cdplb_info_res = get_cdplb_detail_api(onum=onum)
if cdplb_info_res['code'] == 200:
cdplb_info = cdplb_info_res['data']
return dict(
modal_visible=True,
modal_title='编辑批量词典配置表',
form_value=[cdplb_info.get(k) for k in form_value_list],
form_label_validate_status=[None] * len(form_label_list),
form_label_validate_info=[None] * len(form_label_list),
api_check_token_trigger={'timestamp': time.time()},
edit_row_info=cdplb_info if cdplb_info else None,
modal_type={'type': 'edit'}
)
return dict(
modal_visible=dash.no_update,
modal_title=dash.no_update,
form_value=[dash.no_update] * len(form_value_list),
form_label_validate_status=[dash.no_update] * len(form_label_list),
form_label_validate_info=[dash.no_update] * len(form_label_list),
api_check_token_trigger={'timestamp': time.time()},
edit_row_info=None,
modal_type=None
)
raise PreventUpdate
@app.callback(
output=dict(
form_label_validate_status=Output({'type': 'cdplb-form-label', 'index': ALL, 'required': True}, 'validateStatus',
allow_duplicate=True),
form_label_validate_info=Output({'type': 'cdplb-form-label', 'index': ALL, 'required': True}, 'help',
allow_duplicate=True),
modal_visible=Output('cdplb-modal', 'visible'),
operations=Output('cdplb-operations-store', 'data', allow_duplicate=True),
api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True),
global_message_container=Output('global-message-container', 'children', allow_duplicate=True)
),
inputs=dict(
confirm_trigger=Input('cdplb-modal', 'okCounts')
),
state=dict(
modal_type=State('cdplb-operations-store-bk', 'data'),
edit_row_info=State('cdplb-edit-id-store', 'data'),
form_value=State({'type': 'cdplb-form-value', 'index': ALL}, 'value'),
form_label=State({'type': 'cdplb-form-label', 'index': ALL, 'required': True}, 'label')
),
prevent_initial_call=True
)
def cdplb_confirm(confirm_trigger, modal_type, edit_row_info, form_value, form_label):
"""
新增或编辑批量词典配置表弹窗确认回调,实现新增或编辑操作
"""
if confirm_trigger:
# 获取所有输出表单项对应label的index
form_label_output_list = [x['id']['index'] for x in dash.ctx.outputs_list[0]]
# 获取所有输入表单项对应的value及label
form_value_state = {x['id']['index']: x.get('value') for x in dash.ctx.states_list[-2]}
form_label_state = {x['id']['index']: x.get('value') for x in dash.ctx.states_list[-1]}
if all(validate_data_not_empty(item) for item in [form_value_state.get(k) for k in form_label_output_list]):
params_add = form_value_state
params_edit = params_add.copy()
params_edit['onum'] = edit_row_info.get('onum') if edit_row_info else None
api_res = {}
modal_type = modal_type.get('type')
if modal_type == 'add':
api_res = add_cdplb_api(params_add)
if modal_type == 'edit':
api_res = edit_cdplb_api(params_edit)
if api_res.get('code') == 200:
if modal_type == 'add':
return dict(
form_label_validate_status=[None] * len(form_label_output_list),
form_label_validate_info=[None] * len(form_label_output_list),
modal_visible=False,
operations={'type': 'add'},
api_check_token_trigger={'timestamp': time.time()},
global_message_container=fuc.FefferyFancyMessage('新增成功', type='success')
)
if modal_type == 'edit':
return dict(
form_label_validate_status=[None] * len(form_label_output_list),
form_label_validate_info=[None] * len(form_label_output_list),
modal_visible=False,
operations={'type': 'edit'},
api_check_token_trigger={'timestamp': time.time()},
global_message_container=fuc.FefferyFancyMessage('编辑成功', type='success')
)
return dict(
form_label_validate_status=[None] * len(form_label_output_list),
form_label_validate_info=[None] * len(form_label_output_list),
modal_visible=dash.no_update,
operations=dash.no_update,
api_check_token_trigger={'timestamp': time.time()},
global_message_container=fuc.FefferyFancyMessage('处理失败', type='error')
)
return dict(
form_label_validate_status=[None if validate_data_not_empty(form_value_state.get(k)) else 'error' for k in form_label_output_list],
form_label_validate_info=[None if validate_data_not_empty(form_value_state.get(k)) else f'{form_label_state.get(k)}不能为空!' for k in form_label_output_list],
modal_visible=dash.no_update,
operations=dash.no_update,
api_check_token_trigger=dash.no_update,
global_message_container=fuc.FefferyFancyMessage('处理失败', type='error')
)
raise PreventUpdate
@app.callback(
[Output('cdplb-delete-text', 'children'),
Output('cdplb-delete-confirm-modal', 'visible'),
Output('cdplb-delete-ids-store', 'data')],
[Input({'type': 'cdplb-operation-button', 'index': ALL}, 'nClicks'),
Input('cdplb-list-table', 'nClicksButton')],
[State('cdplb-list-table', 'selectedRowKeys'),
State('cdplb-list-table', 'clickedContent'),
State('cdplb-list-table', 'recentlyButtonClickedRow')],
prevent_initial_call=True
)
def cdplb_delete_modal(operation_click, button_click,
selected_row_keys, clicked_content, recently_button_clicked_row):
"""
显示删除批量词典配置表二次确认弹窗回调
"""
trigger_id = dash.ctx.triggered_id
if trigger_id == {'index': 'delete', 'type': 'cdplb-operation-button'} or (trigger_id == 'cdplb-list-table' and clicked_content == '删除'):
if trigger_id == {'index': 'delete', 'type': 'cdplb-operation-button'}:
onums = ','.join(selected_row_keys)
else:
if clicked_content == '删除':
onums = recently_button_clicked_row['key']
else:
raise PreventUpdate
return [
f'是否确认删除批量词典配置表编号为{onums}的批量词典配置表?',
True,
{'onums': onums}
]
raise PreventUpdate
@app.callback(
[Output('cdplb-operations-store', 'data', allow_duplicate=True),
Output('api-check-token', 'data', allow_duplicate=True),
Output('global-message-container', 'children', allow_duplicate=True)],
Input('cdplb-delete-confirm-modal', 'okCounts'),
State('cdplb-delete-ids-store', 'data'),
prevent_initial_call=True
)
def cdplb_delete_confirm(delete_confirm, onums_data):
"""
删除批量词典配置表弹窗确认回调,实现删除操作
"""
if delete_confirm:
params = onums_data
delete_button_info = delete_cdplb_api(params)
if delete_button_info['code'] == 200:
return [
{'type': 'delete'},
{'timestamp': time.time()},
fuc.FefferyFancyMessage('删除成功', type='success')
]
return [
dash.no_update,
{'timestamp': time.time()},
fuc.FefferyFancyMessage('删除失败', type='error')
]
raise PreventUpdate
# 显示批量词典配置表导入弹窗及重置上传弹窗组件状态回调
app.clientside_callback(
'''
(nClicks) => {
if (nClicks) {
return [
true,
[],
[],
false
];
}
return [
false,
window.dash_clientside.no_update,
window.dash_clientside.no_update,
window.dash_clientside.no_update
];
}
''',
[Output('cdplb-import-confirm-modal', 'visible'),
Output('cdplb-upload-choose', 'listUploadTaskRecord'),
Output('cdplb-upload-choose', 'defaultFileList'),
Output('cdplb-import-update-check', 'checked')],
Input('cdplb-import', 'nClicks'),
prevent_initial_call=True
)
@app.callback(
output=dict(
confirm_loading=Output('cdplb-import-confirm-modal', 'confirmLoading'),
modal_visible=Output('batch-result-modal', 'visible',allow_duplicate=True), #add
batch_result=Output('batch-result-content', 'children',allow_duplicate=True), #add
operations=Output('cdplb-operations-store', 'data', allow_duplicate=True),
api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True),
global_message_container=Output('global-message-container', 'children', allow_duplicate=True)
),
inputs=dict(
import_confirm=Input('cdplb-import-confirm-modal', 'okCounts')
),
state=dict(
list_upload_task_record=State('cdplb-upload-choose', 'listUploadTaskRecord'),
is_update=State('cdplb-import-update-check', 'checked')
),
prevent_initial_call=True
)
def cdplb_import_confirm(import_confirm, list_upload_task_record, is_update):
"""
批量词典配置表导入弹窗确认回调,实现批量导入用户操作
"""
if import_confirm:
if list_upload_task_record:
url = list_upload_task_record[-1].get('url')
batch_param = dict(url=url, is_update=is_update)
batch_import_result = batch_import_cdplb_api(batch_param)
if batch_import_result.get('code') == 200:
return dict(
confirm_loading=False,
modal_visible=True if batch_import_result.get('message') else False,
batch_result=batch_import_result.get('message'),
operations={'type': 'batch-import'},
api_check_token_trigger={'timestamp': time.time()},
global_message_container=fuc.FefferyFancyMessage('导入成功', type='success')
)
return dict(
confirm_loading=False,
modal_visible=True,
batch_result=batch_import_result.get('message'),
operations=dash.no_update,
api_check_token_trigger={'timestamp': time.time()},
global_message_container=fuc.FefferyFancyMessage('导入失败', type='error')
)
else:
return dict(
confirm_loading=False,
modal_visible=dash.no_update,
batch_result=dash.no_update,
operations=dash.no_update,
api_check_token_trigger=dash.no_update,
global_message_container=fuc.FefferyFancyMessage('请上传需要导入的文件', type='error')
)
raise PreventUpdate
@app.callback(
[Output('cdplb-export-container', 'data', allow_duplicate=True),
Output('cdplb-export-complete-judge-container', 'data'),
Output('api-check-token', 'data', allow_duplicate=True),
Output('global-message-container', 'children', allow_duplicate=True)],
[Input('cdplb-export', 'nClicks'),
Input('download-cdplb-import-template', 'nClicks')],
prevent_initial_call=True
)
def export_cdplb_list(export_click, download_click):
"""
导出批量词典配置表回调
"""
trigger_id = dash.ctx.triggered_id
if export_click or download_click:
if trigger_id == 'cdplb-export':
export_cdplb_res = export_cdplb_list_api({})
if export_cdplb_res.status_code == 200:
export_cdplb = export_cdplb_res.content
return [
dcc.send_bytes(export_cdplb, f'批量词典配置表_{time.strftime("%Y%m%d%H%M%S", time.localtime())}.xlsx'),
{'timestamp': time.time()},
{'timestamp': time.time()},
fuc.FefferyFancyMessage('导出成功', type='success')
]
return [
dash.no_update,
dash.no_update,
{'timestamp': time.time()},
fuc.FefferyFancyMessage('导出失败', type='error')
]
if trigger_id == 'download-cdplb-import-template':
download_template_res = download_cdplb_import_template_api()
if download_template_res.status_code == 200:
download_template = download_template_res.content
return [
dcc.send_bytes(download_template, f'批量词典配置表导入模板_{time.strftime("%Y%m%d%H%M%S", time.localtime())}.xlsx'),
{'timestamp': time.time()},
{'timestamp': time.time()},
fuc.FefferyFancyMessage('下载成功', type='success')
]
return [
dash.no_update,
dash.no_update,
{'timestamp': time.time()},
fuc.FefferyFancyMessage('下载失败', type='error')
]
raise PreventUpdate
@app.callback(
Output('cdplb-export-container', 'data', allow_duplicate=True),
Input('cdplb-export-complete-judge-container', 'data'),
prevent_initial_call=True
)
def reset_cdplb_export_status(data):
"""
导出完成后重置下载组件数据回调,防止重复下载文件
"""
time.sleep(0.5)
if data:
return None
raise PreventUpdate
@app.callback(
[Output('cdplb-operations-store', 'data', allow_duplicate=True),
Output('api-check-token', 'data', allow_duplicate=True),
Output('global-message-container', 'children', allow_duplicate=True)],
[Input('cdplb-list-table', 'recentlySwitchDataIndex'),
Input('cdplb-list-table', 'recentlySwitchStatus'),
Input('cdplb-list-table', 'recentlySwitchRow')],
prevent_initial_call=True
)
def table_switch_cdplb_status(recently_switch_data_index, recently_switch_status, recently_switch_row):
"""
表格内切换批量词典配置表状态回调
"""
if recently_switch_data_index:
if recently_switch_status:
params = dict(onum=int(recently_switch_row['key']), status='0', type='status')
else:
params = dict(onum=int(recently_switch_row['key']), status='1', type='status')
edit_button_result = edit_cdplb_api(params)
if edit_button_result['code'] == 200:
return [
{'type': 'switch-status'},
{'timestamp': time.time()},
fuc.FefferyFancyMessage('修改成功', type='success')
]
return [
{'type': 'switch-status'},
{'timestamp': time.time()},
fuc.FefferyFancyMessage('修改失败', type='error')
]
raise PreventUpdate