文章目录
-
- 先看最终实现效果图
- 一、核心功能模块
-
- [1. AI聊天客户端类 (lcl_ai_chat_client)](#1. AI聊天客户端类 (lcl_ai_chat_client))
- [2. 事件处理类 (lcl_event_handler)](#2. 事件处理类 (lcl_event_handler))
- [3. 用户界面模块](#3. 用户界面模块)
- [4. 主程序功能 (zchat002)](#4. 主程序功能 (zchat002))
- 二、关键技术特点
-
- [1. API集成](#1. API集成)
- [2. 数据转换](#2. 数据转换)
- [3. 用户体验](#3. 用户体验)
- 三、程序流程
-
- [1. 初始化:](#1. 初始化:)
- [2. 消息处理:](#2. 消息处理:)
- [3. 文件处理:](#3. 文件处理:)
- [4. 会话管理:](#4. 会话管理:)
- 四、数据结构
- 五、应用场景
- 六、参考代码
先看最终实现效果图
图1
*注:这里图1和图2 图3左下多了个删除按钮,因为这个删除按钮是我新加的,不过代码下面的代码是有这个段删除按钮的逻辑的,其他功能都保持不变的.

图2

图3

abap调用deepseek接口
abap调用deepseek接口 v2.0
以上两个的升级版
SAP ABAP AI聊天客户端的完整实现,主要用于与DeepSeek API进行交互,并提供了一个桌面聊天界面。以下是主要功能分析:
一、核心功能模块
1. AI聊天客户端类 (lcl_ai_chat_client)
1.API通信:封装了与DeepSeek API的HTTP通信类
2.请求构建:将聊天消息转换为JSON格式
3.响应解析:处理API返回的JSON数据
4.模型管理:支持切换不同的AI模型
2. 事件处理类 (lcl_event_handler)
1.数据变更处理:监听ALV表格数据变化
2.双击事件:双击聊天记录显示详细内容
3.热键点击:处理表格中的热键操作
3. 用户界面模块
多容器布局:
1.聊天历史容器 (CC_HISTORY):双击可展示聊天内容的详情.
2.文件容器 (CC_FILE):输入事务码或程序名点击解析程序即可完成;在发送时只发发送已经勾选的;如果是删除文件只删除没有勾选的;
3.新建聊天容器 (CC_NEW):点击可切换聊天历史和文件历史.
4.响应显示容器 (CC_RESPONSE):显示聊天详情.
5.ALV表格显示:以表格形式展示聊天记录、文件列表等
4. 主程序功能 (zchat002)
聊天对话:
1.发送消息到AI并获取回复
2.维护对话上下文历史
3.支持角色区分(用户助手)
文件管理:
1.上传(可自行开发)和解析ABAP程序文件
2.文件内容转换为十六进制存储
3.文件选择和删除功能
聊天会话管理:
1.创建新的聊天会话
2.删除聊天会话
3.会话标题管理
数据持久化:
1.保存聊天历史到本地文件
2.加载聊天历史记录
3.自动清理和刷新显示
二、关键技术特点
1. API集成
1.使用Bearer Token认证
2.支持流式传输设置
3.处理HTTP状态码和错误
2. 数据转换
1.文本与十六进制转换
2.JSON与ABAP结构体转换
3.时间戳处理
3. 用户体验
1.响应式界面刷新
2.消息状态反馈
3.错误处理和用户提示
三、程序流程
1. 初始化:
1.创建界面容器和控件
2.设置事件处理器
3.加载初始数据
2. 消息处理:
1.用户输入消息
2.构建包含历史上下文的请求
3.发送到DeepSeek API
4.解析并显示回复
3. 文件处理:
1.选择ABAP程序文件
2.解析程序代码
3.存储为聊天上下文
4. 会话管理:
1.创建切换聊天会话
2.保存删除会话记录
四、数据结构
主要内表:
- 聊天历史 (ty_chat_history):存储对话记录
- 文件信息 (ty_file):存储上传的文件信息
- 新建聊天 (ty_new):存储聊天会话元数据
- 聊天消息 (ty_chat_message):API消息格式
五、应用场景
这是一个企业级AI助手集成方案,适用于:
1.SAP系统内嵌AI助手
2.代码审查和辅助编程
3.技术支持问答
4.业务流程咨询
六、参考代码
0.deepseek的api接口
官方标准接口文档: https://platform.deepseek.com/usage
c
curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${DEEPSEEK_API_KEY}" \
-d '{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"stream": false
}'
1.ZCHAT02
c
*&---------------------------------------------------------------------*
*& Report ZCHAT02
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zchat02.
TABLES: sscrfields.
TYPE-POOLS: icon.
DATA gv_content TYPE string.
DATA gv_tcode TYPE tstc-tcode.
DATA gv_uuid_new TYPE sysuuid_c.
DATA gv_title TYPE string.
TYPES: BEGIN OF ty_chat_message,
role TYPE string,
content TYPE string,
END OF ty_chat_message.
TYPES: BEGIN OF ty_chat_history,
timestamp TYPE string,
role TYPE string,
content TYPE string,
content2 TYPE string,
sel TYPE sel,
uuid TYPE sysuuid_c,
END OF ty_chat_history.
TYPES: BEGIN OF ty_file,
timestamp TYPE string,
filename TYPE string,
filesize TYPE string,
sel TYPE sel,
uuid TYPE sysuuid_c,
END OF ty_file.
TYPES: BEGIN OF ty_new,
title TYPE string,
uuid TYPE sysuuid_c,
END OF ty_new.
DATA: gt_history TYPE STANDARD TABLE OF ty_chat_history,
gs_history TYPE ty_chat_history,
gv_message TYPE string,
gv_response TYPE string,
gv_api_key TYPE string VALUE 'sk-932efc27554e4c5fb553df652c59c6bc',
gv_model TYPE string VALUE 'deepseek-reasoner',
gv_system_msg TYPE string VALUE 'You are a helpful assistant.'.
INCLUDE zai_chat_client2.
INCLUDE zai_chat_screen_enhan2.
INITIALIZATION.
CONCATENATE sy-datum sy-uzeit INTO gv_title.
START-OF-SELECTION.
CALL SCREEN 100.
2.ZAI_CHAT_CLIENT2
c
*&---------------------------------------------------------------------*
*& 包括 ZAI_CHAT_CLIENT2
*&---------------------------------------------------------------------*
CLASS lcl_ai_chat_client DEFINITION.
PUBLIC SECTION.
TYPES:BEGIN OF cy_return,
content TYPE string,
content2 TYPE string,
END OF cy_return.
TYPES cys_return TYPE cy_return.
METHODS:
constructor
IMPORTING
iv_api_key TYPE string
iv_model TYPE string,
send_chat_request
IMPORTING
it_messages TYPE STANDARD TABLE
RETURNING
value(rs_content) TYPE cys_return
RAISING
* cx_root,
cx_static_check,
set_model
IMPORTING
iv_model TYPE string,
get_model
RETURNING
value(rv_model) TYPE string,
set_api_key
IMPORTING
iv_api_key TYPE string.
PRIVATE SECTION.
DATA: mv_api_key TYPE string VALUE 'sk-932efc27554e4c5fb553df652c59c6bc',
mv_model TYPE string,
* mv_api_url TYPE string VALUE 'https://api.deepseek.com',
mv_api_url TYPE string VALUE 'https://api.deepseek.com/chat/completions',
mo_http_client TYPE REF TO if_http_client,
rs_content TYPE cys_return.
METHODS:
create_http_request
IMPORTING
it_messages TYPE STANDARD TABLE
RETURNING
value(rv_request_body) TYPE string,
parse_response
IMPORTING
iv_response TYPE string
RETURNING
value(rs_content) TYPE cys_return,
send_http_request
IMPORTING
iv_request_body TYPE string
RETURNING
value(rv_response) TYPE string
RAISING
cx_static_check.
ENDCLASS. "lcl_ai_chat_client DEFINITION
DATA go_ai_client TYPE REF TO lcl_ai_chat_client.
*----------------------------------------------------------------------*
* CLASS lcl_ai_chat_client IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_ai_chat_client IMPLEMENTATION.
METHOD constructor.
mv_api_key = iv_api_key.
mv_model = iv_model.
ENDMETHOD. "constructor
METHOD set_model.
mv_model = iv_model.
ENDMETHOD. "set_model
METHOD get_model.
rv_model = mv_model.
ENDMETHOD. "get_model
METHOD set_api_key.
mv_api_key = iv_api_key.
ENDMETHOD. "set_api_key
METHOD send_chat_request.
DATA: lv_request_body TYPE string.
DATA: lv_response TYPE string.
" 1.创建发送JSON 传入用户输入的问题 并 返回拼接的JSON
lv_request_body = me->create_http_request( it_messages ).
" 2.创建发送客户端 传入拼接的JSON 返回调用接口返回的JSON数据
lv_response = me->send_http_request( lv_request_body ).
" 3. 处理JSON数据 把JSON数据转为 abap结构类型
rs_content = me->parse_response( lv_response ).
ENDMETHOD. "send_chat_request
METHOD create_http_request.
DATA: lv_json TYPE string,
ls_message TYPE string,
lv_role TYPE string,
lv_content TYPE string.
TRANSLATE mv_model TO LOWER CASE.
CONCATENATE `{"model":"` mv_model `","messages":[` INTO lv_json.
FIELD-SYMBOLS: <fs_role> TYPE ANY.
FIELD-SYMBOLS: <fs_content> TYPE ANY.
FIELD-SYMBOLS: <fs_message> TYPE ANY.
LOOP AT it_messages ASSIGNING <fs_message>.
ASSIGN COMPONENT 'ROLE' OF STRUCTURE <fs_message> TO <fs_role>.
ASSIGN COMPONENT 'CONTENT' OF STRUCTURE <fs_message> TO <fs_content>.
IF <fs_role> IS ASSIGNED AND <fs_content> IS ASSIGNED.
lv_role = <fs_role>.
lv_content = <fs_content>.
IF sy-tabix > 1.
CONCATENATE lv_json `,` INTO lv_json.
ENDIF.
CONCATENATE lv_json `{"role":"` lv_role `","content":"` lv_content `"}` INTO lv_json.
ENDIF.
ENDLOOP.
CONCATENATE lv_json `],"stream":false }` INTO lv_json.
TRANSLATE lv_json TO LOWER CASE.
rv_request_body = lv_json.
ENDMETHOD. "create_http_request
METHOD send_http_request.
DATA: lv_response TYPE string,
lv_status TYPE i,
lv_errormsg TYPE string.
cl_http_client=>create_by_url(
EXPORTING
url = mv_api_url
IMPORTING
client = mo_http_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
* RAISE EXCEPTION TYPE cx_static_check~.
ENDIF.
DATA headers_fields_t TYPE tihttpnvp .
DATA headers_fields_s TYPE ihttpnvp .
headers_fields_s-name = 'Content-Type'.
headers_fields_s-value = 'application/json'.
APPEND headers_fields_s TO headers_fields_t.
CLEAR headers_fields_s.
headers_fields_s-name = 'Authorization'.
headers_fields_s-value = mv_api_key.
headers_fields_s-value = 'Bearer sk-932efc27554e4c5fb553df652c59c6bc'.
APPEND headers_fields_s TO headers_fields_t.
CLEAR headers_fields_s.
* mo_http_client->request->set_header_fields( fields = headers_fields_t ).
mo_http_client->request->set_method( if_http_request=>co_request_method_post ).
mo_http_client->propertytype_logon_popup = if_http_client=>co_disabled.
mo_http_client->request->set_header_field(
EXPORTING
name = 'Content-Type'
value = 'application/json' ).
DATA lv_value TYPE string.
CLEAR lv_value.
CONCATENATE 'Bearer ' mv_api_key INTO lv_value.
lv_value = 'Bearer sk-932efc27554e4c5fb553df652c59c6bc'.
mo_http_client->request->set_header_field(
EXPORTING
name = 'Authorization'
value = lv_value ).
DATA lv_length TYPE i.
CLEAR lv_length.
lv_length = STRLEN( iv_request_body ).
mo_http_client->request->set_cdata( data = iv_request_body length = lv_length ).
mo_http_client->send(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
mo_http_client->get_last_error( IMPORTING message = lv_errormsg ).
* RAISE EXCEPTION TYPE cx_static_check
* EXPORTING
* textid = cx_static_check=>default_text
* previous = cx_root
* msgv1 = lv_errormsg.
ENDIF.
mo_http_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
mo_http_client->get_last_error( IMPORTING message = lv_errormsg ).
* RAISE EXCEPTION TYPE cx_static_check
* EXPORTING
* textid = cx_static_check=>default_text
* msgv1 = lv_errormsg.
ENDIF.
DATA lv_reason TYPE string.
lv_response = mo_http_client->response->get_cdata( ).
CALL METHOD mo_http_client->response->get_status
IMPORTING
code = lv_status
reason = lv_reason.
IF lv_status <> 200.
MESSAGE lv_reason TYPE 'E'.
* DATA lv_msgv1 TYPE string.
* CLEAR lv_msgv1.
* CONCATENATE 'http error:' lv_status INTO lv_msgv1.
* RAISE EXCEPTION TYPE cx_static_check
* EXPORTING
* textid = cx_static_check=>default_text
* msgv1 = lv_msgv1.
ENDIF.
mo_http_client->close( ).
rv_response = lv_response.
ENDMETHOD. "send_http_request
METHOD parse_response.
*因为 接口返回的JSON是带有具体的文本格式的, 这里删除相关格式 在需要联系上下文对话时 abap要用不带 格式的文本进行发送 不然可能会报JSON格式错误
DATA: lv_content TYPE string,
lv_start TYPE i,
lv_end TYPE i.
DATA lv_tmp TYPE c.
DATA lv_response TYPE string.
DATA ls_zds_chat_s TYPE zds_chat_s.
DATA ls_zchoices_s TYPE zchoices_s.
CLEAR:lv_response,ls_zds_chat_s,ls_zchoices_s.
lv_response = iv_response.
REPLACE ALL OCCURRENCES OF '#' IN lv_response WITH ''.
* REPLACE ALL OCCURRENCES OF '\n' IN lv_response WITH ''.
REPLACE ALL OCCURRENCES OF '*' IN lv_response WITH ''.
REPLACE ALL OCCURRENCES OF '-' IN lv_response WITH ''.
REPLACE ALL OCCURRENCES OF '+' IN lv_response WITH ''.
REPLACE ALL OCCURRENCES OF '`' IN lv_response WITH ''.
REPLACE ALL OCCURRENCES OF '|' IN lv_response WITH ''.
REPLACE ALL OCCURRENCES OF '/' IN lv_response WITH ''.
* CONDENSE lv_response NO-GAPS.
CALL METHOD zcl_json_util_h=>json_2_abap
EXPORTING
json_data = lv_response
CHANGING
abap_data = ls_zds_chat_s.
READ TABLE ls_zds_chat_s-choices INTO ls_zchoices_s INDEX 1.
IF sy-subrc = 0.
rs_content-content = ls_zchoices_s-message-content. "用来显示到文本容器中
ENDIF.
REPLACE ALL OCCURRENCES OF '\n' IN lv_response WITH ''.
CLEAR ls_zds_chat_s.
CALL METHOD zcl_json_util_h=>json_2_abap
EXPORTING
json_data = lv_response
CHANGING
abap_data = ls_zds_chat_s.
READ TABLE ls_zds_chat_s-choices INTO ls_zchoices_s INDEX 1.
IF sy-subrc = 0.
rs_content-content2 = ls_zchoices_s-message-content. "用来做为 历史记录发送给接口
ENDIF.
* FIND '"content":"' IN lv_response MATCH OFFSET lv_start.
* IF sy-subrc = 0.
* lv_start = lv_start + 11.
* lv_tmp = '"},'.
* FIND lv_tmp IN SECTION OFFSET lv_start OF lv_response MATCH OFFSET lv_end.
* IF sy-subrc = 0.
** lv_content = iv_response + lv_start( lv_end - lv_start ).
* lv_content = lv_response+lv_start(lv_end).
* rv_content = lv_content.
* ENDIF.
* ENDIF.
ENDMETHOD. "parse_response
ENDCLASS. "lcl_ai_chat_client IMPLEMENTATION
3.ZAI_CHAT_SCREEN_ENHAN2
c
*&---------------------------------------------------------------------*
*& 包括 ZAI_CHAT_SCREEN_ENHAN2
*&---------------------------------------------------------------------*
DATA: go_container_hist TYPE REF TO cl_gui_custom_container,
go_alv_grid_hist TYPE REF TO cl_gui_alv_grid,
go_container_file TYPE REF TO cl_gui_custom_container,
go_alv_grid_file TYPE REF TO cl_gui_alv_grid,
go_container_new TYPE REF TO cl_gui_custom_container,
go_alv_grid_new TYPE REF TO cl_gui_alv_grid,
go_container_resp TYPE REF TO cl_gui_custom_container,
go_text_edit_resp TYPE REF TO cl_gui_textedit,
go_html_viewer TYPE REF TO cl_gui_html_viewer,
gt_alv_data TYPE STANDARD TABLE OF ty_chat_history,
gs_alv_data TYPE ty_chat_history,
gs_layout TYPE lvc_s_layo,
gt_fieldcat TYPE lvc_t_fcat,
gt_alv_file TYPE STANDARD TABLE OF ty_file,
gt_alv_file2 TYPE STANDARD TABLE OF ty_file,
gt_alv_new TYPE STANDARD TABLE OF ty_new,
gs_alv_file TYPE ty_file,
gs_alv_new TYPE ty_new,
gs_layout2 TYPE lvc_s_layo,
gs_layout3 TYPE lvc_s_layo,
gt_fieldcat2 TYPE lvc_t_fcat,
gt_fieldcat3 TYPE lvc_t_fcat.
*----------------------------------------------------------------------*
* CLASS lcl_event_handler DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
METHODS:
handle_data_changed
FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING er_data_changed e_onf4 e_onf4_before e_onf4_after e_ucomm,
handle_data_changed_finished
FOR EVENT data_changed_finished OF cl_gui_alv_grid
IMPORTING e_modified et_good_cells,
handle_hotspot_click
FOR EVENT hotspot_click OF cl_gui_alv_grid
IMPORTING e_row_id e_column_id es_row_no,
handle_double_click
FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no.
ENDCLASS. "lcl_event_handler DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_event_handler IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_event_handler IMPLEMENTATION.
METHOD handle_data_changed.
PERFORM frm_data_changed USING gt_alv_file er_data_changed.
ENDMETHOD. "handle_data_changed
METHOD handle_data_changed_finished.
ENDMETHOD. "handle_data_changed
METHOD handle_hotspot_click.
DATA ls_history LIKE LINE OF gt_history.
READ TABLE gt_alv_new INTO gs_alv_new INDEX es_row_no-row_id.
IF sy-subrc = 0.
CLEAR gv_title.
gv_title = gs_alv_new-title.
gv_uuid_new = gs_alv_new-uuid.
CLEAR gs_alv_new.
ENDIF.
CALL METHOD go_text_edit_resp->delete_text.
CLEAR gv_response.
CLEAR:gt_alv_data[],gs_alv_data.
CLEAR:gt_alv_file[],gs_alv_file.
LOOP AT gt_history INTO ls_history WHERE uuid = gv_uuid_new.
MOVE-CORRESPONDING ls_history TO gs_alv_data.
APPEND gs_alv_data TO gt_alv_data.
gv_response = gs_alv_data-content.
CLEAR:gs_alv_data,ls_history.
ENDLOOP.
LOOP AT gt_alv_file2 INTO gs_alv_file WHERE uuid = gv_uuid_new.
APPEND gs_alv_file TO gt_alv_file.
CLEAR gs_alv_file.
ENDLOOP.
DELETE gt_alv_data WHERE content = 'FILE'.
cl_gui_cfw=>set_new_ok_code( '&1' ).
ENDMETHOD. "handle_hotspot_click
METHOD handle_double_click.
DATA lv_index TYPE i.
lv_index = e_row-index.
*双击哪一行就把alv容器中的数据显示到长文本框中
IF lv_index > 0 AND lv_index <= LINES( gt_alv_data ).
READ TABLE gt_alv_data INTO gs_alv_data INDEX lv_index.
IF sy-subrc = 0.
IF go_text_edit_resp IS NOT INITIAL.
CALL METHOD go_text_edit_resp->set_textstream
EXPORTING
text = gs_alv_data-content.
ENDIF.
gv_response = gs_alv_data-content.
ENDIF.
ENDIF.
ENDMETHOD. "handle_double_click
ENDCLASS. "lcl_event_handler IMPLEMENTATION
DATA go_event_handler TYPE REF TO lcl_event_handler.
DATA go_event_handler2 TYPE REF TO lcl_event_handler.
DATA go_event_handler3 TYPE REF TO lcl_event_handler.
*----------------------------------------------------------------------*
* MODULE status_0100 OUTPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'STATUS_100'.
SET TITLEBAR 'TITLE_100' WITH gv_title.
ENDMODULE. "status_0100 OUTPUT
*&---------------------------------------------------------------------*
*& Module SCREEN_DISPLY OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE initialize_screen_disply OUTPUT.
PERFORM initialize_screen_objects.
PERFORM refresh_alv_display.
ENDMODULE. " SCREEN_DISPLY OUTPUT
*----------------------------------------------------------------------*
* MODULE user_command_0100 INPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'SEND'.
PERFORM send_message.
WHEN 'CLEAR'.
PERFORM clear_chat.
WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
PERFORM exit_program.
WHEN 'SAVE'.
PERFORM save_chat_history.
WHEN 'UPLOAD'.
PERFORM upload_file.
WHEN 'DELETE'.
PERFORM delete_files.
WHEN 'NEW'.
PERFORM creat_chat_new.
WHEN 'DEL_NEW'.
PERFORM delete_new_chat.
WHEN OTHERS.
ENDCASE.
ENDMODULE. "user_command_0100 INPUT
*&---------------------------------------------------------------------*
*& Form initialize_screen_objects
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM initialize_screen_objects.
DATA: ls_fieldcat TYPE lvc_s_fcat.
*一个事件类 同时为两个容器中的alv使用
*显示历史聊天记录
IF go_container_hist IS INITIAL.
* 实例化容器
CREATE OBJECT go_container_hist
EXPORTING
container_name = 'CC_HISTORY'.
*表示这个实例化容器要显示这个alv对象
CREATE OBJECT go_alv_grid_hist
EXPORTING
i_parent = go_container_hist.
*字段显示 layou显示
PERFORM prepare_fieldcat USING 'L' gt_fieldcat.
PERFORM prepare_layout USING gs_layout.
*注册双击事件 用于显示历史聊天消息
CREATE OBJECT go_event_handler.
SET HANDLER go_event_handler->handle_double_click FOR go_alv_grid_hist.
*输出数据
CALL METHOD go_alv_grid_hist->set_table_for_first_display
EXPORTING
is_layout = gs_layout
CHANGING
it_outtab = gt_alv_data
it_fieldcatalog = gt_fieldcat.
ENDIF.
*显示上传文件
IF go_container_file IS INITIAL.
CREATE OBJECT go_container_file
EXPORTING
container_name = 'CC_FILE'.
CREATE OBJECT go_alv_grid_file
EXPORTING
i_parent = go_container_file.
PERFORM prepare_fieldcat USING 'F' gt_fieldcat2.
PERFORM prepare_layout USING gs_layout2.
*注册事件
CREATE OBJECT go_event_handler2.
* SET HANDLER go_event_handler2->handle_hotspot_click FOR go_alv_grid_file."单击事件
SET HANDLER go_event_handler2->handle_data_changed FOR go_alv_grid_file."数据更该事件
* SET HANDLER go_event_handler2->handle_data_changed_finished FOR go_alv_grid_file."刷新事件
CALL METHOD go_alv_grid_file->set_table_for_first_display
EXPORTING
is_layout = gs_layout2
CHANGING
it_outtab = gt_alv_file
it_fieldcatalog = gt_fieldcat2.
*不加触发条件 注册的事件可能不会生效
CALL METHOD go_alv_grid_file->register_edit_event "单元格数据更改时触发条件
EXPORTING
* I_EVENT_ID = CL_GUI_ALV_GRID=>MC_EVT_ENTER. "回车时触发
i_event_id = cl_gui_alv_grid=>mc_evt_modified. "单元格失去焦点触发
ENDIF.
*新建聊天
IF go_container_new IS INITIAL.
CREATE OBJECT go_container_new
EXPORTING
container_name = 'CC_NEW'.
CREATE OBJECT go_alv_grid_new
EXPORTING
i_parent = go_container_new.
PERFORM prepare_fieldcat USING 'N' gt_fieldcat3.
PERFORM prepare_layout USING gs_layout3.
CREATE OBJECT go_event_handler3.
SET HANDLER go_event_handler3->handle_double_click FOR go_alv_grid_new."双击事件
SET HANDLER go_event_handler3->handle_hotspot_click FOR go_alv_grid_new."单击事件
* CONCATENATE sy-datum sy-uzeit INTO gs_alv_new-title. "首次进去的聊天主体
gs_alv_new-title = gv_title.
APPEND gs_alv_new TO gt_alv_new.
CLEAR gs_alv_new.
CALL METHOD go_alv_grid_new->set_table_for_first_display
EXPORTING
is_layout = gs_layout3
CHANGING
it_outtab = gt_alv_new
it_fieldcatalog = gt_fieldcat3.
ENDIF.
*显示长文本框
IF go_container_resp IS INITIAL.
CREATE OBJECT go_container_resp
EXPORTING
container_name = 'CC_RESPONSE'.
CREATE OBJECT go_text_edit_resp
EXPORTING
parent = go_container_resp
wordwrap_mode = cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_position = 80.
CALL METHOD go_text_edit_resp->set_toolbar_mode
EXPORTING
toolbar_mode = 0 "不显示工具栏 0:不显示 1:显示
EXCEPTIONS
error_cntl_call_method = 1
invalid_parameter = 2
OTHERS = 3.
*长文本内容是否可编辑 1:只读 0:编辑
CALL METHOD go_text_edit_resp->set_readonly_mode( readonly_mode = 1 ).
ENDIF.
ENDFORM. "initialize_screen_objects
*&---------------------------------------------------------------------*
*& Form prepare_fieldcat
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->CT_FIELDCAT text
*----------------------------------------------------------------------*
FORM prepare_fieldcat CHANGING p_type ct_fieldcat TYPE lvc_t_fcat.
DATA: ls_fieldcat TYPE lvc_s_fcat.
CASE p_type.
WHEN 'L'.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'TIMESTAMP'.
ls_fieldcat-coltext = '时间'.
ls_fieldcat-outputlen = 12.
ls_fieldcat-col_pos = 1.
APPEND ls_fieldcat TO ct_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'ROLE'.
ls_fieldcat-coltext = '角色'.
ls_fieldcat-outputlen = 8.
ls_fieldcat-col_pos = 2.
APPEND ls_fieldcat TO ct_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'CONTENT'.
ls_fieldcat-coltext = '内容'.
ls_fieldcat-outputlen = 100.
ls_fieldcat-col_pos = 3.
APPEND ls_fieldcat TO ct_fieldcat.
WHEN 'F'.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'SEL'.
ls_fieldcat-coltext = '选择'.
ls_fieldcat-checkbox = 'X'.
ls_fieldcat-edit = 'X'.
ls_fieldcat-outputlen = 4.
ls_fieldcat-col_pos = 1.
APPEND ls_fieldcat TO ct_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'TIMESTAMP'.
ls_fieldcat-coltext = 'UUID'.
ls_fieldcat-outputlen = 26.
ls_fieldcat-col_pos = 2.
APPEND ls_fieldcat TO ct_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'FILESIZE'.
ls_fieldcat-coltext = '文件大小'.
ls_fieldcat-outputlen = 8.
ls_fieldcat-col_pos = 3.
APPEND ls_fieldcat TO ct_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'FILENAME'.
ls_fieldcat-coltext = '文件名'.
ls_fieldcat-outputlen = 100.
ls_fieldcat-col_pos = 4.
APPEND ls_fieldcat TO ct_fieldcat.
WHEN 'N'.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = 'TITLE'.
ls_fieldcat-coltext = '主体'.
ls_fieldcat-hotspot = 'X'.
ls_fieldcat-outputlen = 30.
APPEND ls_fieldcat TO ct_fieldcat.
CLEAR ls_fieldcat.
WHEN OTHERS.
ENDCASE.
ENDFORM. "prepare_fieldcat
*&---------------------------------------------------------------------*
*& Form prepare_layout
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->CS_LAYOUT text
*----------------------------------------------------------------------*
FORM prepare_layout CHANGING cs_layout TYPE lvc_s_layo.
cs_layout-zebra = 'X'.
* cs_layout-cwidth_opt = 'X'.
* cs_layout-sel_mode = 'A'.
cs_layout-no_toolbar = 'X'.
ENDFORM. "prepare_layout
*&---------------------------------------------------------------------*
*& Form refresh_alv_display
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM refresh_alv_display.
DATA: ls_stable TYPE lvc_s_stbl.
CLEAR gt_alv_data.
LOOP AT gt_history INTO gs_history WHERE uuid = gv_uuid_new.
COLLECT gs_history INTO gt_alv_data.
CLEAR gs_history.
ENDLOOP.
DELETE gt_alv_data WHERE content = 'FILE'.
IF go_alv_grid_hist IS NOT INITIAL OR go_alv_grid_file IS NOT INITIAL OR go_alv_grid_new IS NOT INITIAL.
ls_stable-row = 'X'.
ls_stable-col = 'X'.
CALL METHOD go_alv_grid_hist->refresh_table_display
EXPORTING
is_stable = ls_stable
i_soft_refresh = space.
CALL METHOD go_alv_grid_file->refresh_table_display
EXPORTING
is_stable = ls_stable
i_soft_refresh = space.
CALL METHOD go_alv_grid_new->refresh_table_display
EXPORTING
is_stable = ls_stable
i_soft_refresh = space.
ENDIF.
IF go_text_edit_resp IS NOT INITIAL AND gv_response IS NOT INITIAL.
CALL METHOD go_text_edit_resp->set_textstream
EXPORTING
text = gv_response.
ENDIF.
ENDFORM. "refresh_alv_display
*&---------------------------------------------------------------------*
*& Form exit_program
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM exit_program.
IF go_alv_grid_hist IS NOT INITIAL.
CALL METHOD go_alv_grid_hist->free.
CLEAR go_alv_grid_hist.
ENDIF.
IF go_container_hist IS NOT INITIAL.
CALL METHOD go_container_hist->free.
CLEAR go_container_hist.
ENDIF.
IF go_alv_grid_file IS NOT INITIAL.
CALL METHOD go_alv_grid_file->free.
CLEAR go_alv_grid_file.
ENDIF.
IF go_container_file IS NOT INITIAL.
CALL METHOD go_container_file->free.
CLEAR go_container_file.
ENDIF.
IF go_alv_grid_new IS NOT INITIAL.
CALL METHOD go_alv_grid_new->free.
CLEAR go_alv_grid_new.
ENDIF.
IF go_container_new IS NOT INITIAL.
CALL METHOD go_container_new->free.
CLEAR go_container_new.
ENDIF.
IF go_text_edit_resp IS NOT INITIAL.
CALL METHOD go_text_edit_resp->free.
CLEAR go_text_edit_resp.
ENDIF.
IF go_container_resp IS NOT INITIAL.
CALL METHOD go_container_resp->free.
CLEAR go_container_resp.
ENDIF.
CALL METHOD cl_gui_cfw=>flush.
LEAVE PROGRAM.
ENDFORM. "exit_program
*&---------------------------------------------------------------------*
*& Form send_message
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM send_message.
DATA: lt_messages TYPE STANDARD TABLE OF ty_chat_message,
ls_message TYPE ty_chat_message,
ls_history TYPE ty_chat_history,
ls_content TYPE lcl_ai_chat_client=>cys_return..
IF gv_message IS INITIAL.
MESSAGE '请输入消息' TYPE 'I'.
RETURN.
ENDIF.
FIELD-SYMBOLS <fs_history> TYPE ty_chat_history.
DATA lv_b64leng TYPE i.
DATA lex_len TYPE i.
DATA:lv_xstring TYPE xstring.
DATA lr_conv TYPE REF TO cl_abap_conv_out_ce.
CREATE OBJECT go_ai_client
EXPORTING
iv_api_key = gv_api_key
iv_model = gv_model.
CALL METHOD cl_abap_conv_out_ce=>create
RECEIVING
conv = lr_conv.
lv_b64leng = STRLEN( gv_message ).
CALL METHOD lr_conv->convert "把提问的问题转成十六进制
EXPORTING
data = gv_message
n = lv_b64leng
IMPORTING
buffer = lv_xstring
len = lex_len.
APPEND INITIAL LINE TO gt_history ASSIGNING <fs_history>.
CONCATENATE sy-datum sy-uzeit INTO <fs_history>-timestamp.
<fs_history>-role = 'user'.
<fs_history>-content = gv_message. "用户提问的问题
<fs_history>-content2 = lv_xstring.
<fs_history>-content2 = gv_message.
<fs_history>-uuid = gv_uuid_new.
*
ls_message-role = 'system'.
ls_message-content = gv_system_msg.
APPEND ls_message TO lt_messages.
LOOP AT gt_history INTO ls_history WHERE uuid = gv_uuid_new. "把历史的数据一起发送给接口 从而实现 根据历史对话实现 上下文回答
IF ls_history-sel IS INITIAL AND ls_history-content = 'FILE'.
CONTINUE.
ENDIF.
CLEAR ls_message.
ls_message-role = ls_history-role.
ls_message-content = ls_history-content2.
COLLECT ls_message INTO lt_messages."发送的问题
ENDLOOP.
* TRY.
ls_content = go_ai_client->send_chat_request( lt_messages ). "调用deepseek接口
CLEAR: lv_b64leng,lv_xstring,lex_len.
lv_b64leng = STRLEN( ls_content-content2 ).
CALL METHOD lr_conv->convert "把回答的也转成十六进制
EXPORTING
data = ls_content-content2
n = lv_b64leng
IMPORTING
buffer = lv_xstring
len = lex_len.
ls_content-content2 = lv_xstring.
CLEAR lv_xstring.
APPEND INITIAL LINE TO gt_history ASSIGNING <fs_history>. "保存到ALV显示中
CONCATENATE sy-datum sy-uzeit INTO <fs_history>-timestamp.
<fs_history>-role = 'assistant'.
<fs_history>-content = ls_content-content.
<fs_history>-content2 = ls_content-content2.
<fs_history>-uuid = gv_uuid_new.
gv_response = ls_content-content. "返回到txt文本显示容器中
CLEAR:ls_content, gv_message,lt_messages[].
PERFORM refresh_alv_display. "刷新
MESSAGE '消息发送成功' TYPE 'S'.
* CATCH cx_root INTO data(lo_exception).
* MESSAGE lo_exception->get_text( ) type 'E'.
* ENDTRY.
ENDFORM. "send_message
*&---------------------------------------------------------------------*
*& Form clear_chat
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM clear_chat.
CLEAR gt_history[].
CLEAR gv_message.
CLEAR gv_response.
MESSAGE '聊天记录已清除' TYPE 'S'.
ENDFORM. "clear_chat
*&---------------------------------------------------------------------*
*& Form save_chat_history
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM save_chat_history.
DATA: lt_filetab TYPE STANDARD TABLE OF string,
ls_filetab TYPE string,
lv_rc TYPE i,
lv_action TYPE i,
lv_path TYPE string,
lv_filename TYPE string,
lv_content TYPE string,
ls_history TYPE ty_chat_history.
DATA lo_fuc TYPE REF TO zcl_function_set.
CREATE OBJECT lo_fuc.
CONCATENATE sy-datum sy-timlo INTO lv_filename.
CALL METHOD lo_fuc->file_open_dialog2
EXPORTING
window_title = '请选择文件保存路径'
default_extension = 'TXT'
default_filename = lv_filename
file_filter = '文本文件 (*.TXT)|*.TXT|所有文件 (*.*)|*.*'
save_or_open_dialog = 'S'
CHANGING
user_action = lv_rc
ev_path2 = lv_path.
IF lv_rc = 0 .
LOOP AT gt_history INTO ls_history WHERE uuid = gv_uuid_new.
CONCATENATE lv_content
ls_history-role ': '
ls_history-content
cl_abap_char_utilities=>newline
INTO lv_content.
APPEND lv_content TO lt_filetab.
CLEAR lv_content.
ENDLOOP.
IF lt_filetab[] IS INITIAL.
MESSAGE '未获取到聊天记录!' TYPE 'E'.
ENDIF.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
filename = lv_path
filetype = 'ASC'
TABLES
data_tab = lt_filetab
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
OTHERS = 22.
IF sy-subrc = 0.
MESSAGE '聊天记录已保存' TYPE 'S'.
ELSE.
MESSAGE '保存失败' TYPE 'E'.
ENDIF.
ENDIF.
ENDFORM. "save_chat_history
*&---------------------------------------------------------------------*
*& Form UPLOAD_FILE
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM upload_file .
TYPES: BEGIN OF ly_file,
line(1024) TYPE x,
END OF ly_file.
DATA: lt_file TYPE TABLE OF ly_file.
DATA lo_fucs TYPE REF TO zcl_function_set.
CREATE OBJECT lo_fucs.
DATA:lt_froms TYPE tihttpnvp.
DATA: lt_fields TYPE tihttpnvp,
ls_field TYPE LINE OF tihttpnvp.
DATA: gv_file_name TYPE string,
gv_file_type TYPE string,
lv_file_name TYPE dbmsgora-filename.
DATA:lv_filetype TYPE string,
lv_filename TYPE string,
lv_filename2 TYPE string,
lv_file_bin_data TYPE xstring,
lv_msg TYPE string.
DATA: lv_msg3 TYPE string.
DATA: iincludelines TYPE STANDARD TABLE OF string WITH HEADER LINE.
DATA: itokens TYPE STANDARD TABLE OF stokes WITH HEADER LINE.
DATA: istatements TYPE STANDARD TABLE OF sstmnt WITH HEADER LINE.
DATA: ikeywords TYPE STANDARD TABLE OF text20 WITH HEADER LINE.
DATA: castprogramname TYPE program.
DATA lv_program_id TYPE tstc-pgmna.
DATA lv_zuuid TYPE sysuuid_c.
DATA lv_b64leng TYPE i.
DATA lex_len TYPE i.
DATA:lv_xstring TYPE xstring.
DATA:lv_string TYPE string.
DATA:lv_string2 TYPE string.
DATA ls_history TYPE ty_chat_history.
DATA lr_conv TYPE REF TO cl_abap_conv_out_ce.
FIELD-SYMBOLS <fs_file> LIKE LINE OF gt_alv_file.
FIELD-SYMBOLS <fs_history> LIKE LINE OF gt_history.
CALL METHOD cl_abap_conv_out_ce=>create
RECEIVING
conv = lr_conv.
SELECT SINGLE pgmna INTO lv_program_id FROM tstc WHERE tcode = gv_tcode.
IF lv_program_id IS INITIAL.
SELECT SINGLE progname INTO lv_program_id FROM reposrc WHERE progname = gv_tcode.
ENDIF.
IF sy-subrc = 0.
castprogramname = lv_program_id.
READ REPORT castprogramname INTO iincludelines.
ELSE.
MESSAGE '请检查输入的事务代码或程序!' TYPE 'I'.
RETURN.
ENDIF.
APPEND 'INCLUDE' TO ikeywords.
SCAN ABAP-SOURCE iincludelines TOKENS INTO itokens WITH INCLUDES STATEMENTS INTO istatements KEYWORDS FROM ikeywords.
CLEAR:iincludelines[],iincludelines,istatements,ikeywords.
itokens-str = lv_program_id.
APPEND itokens.
CLEAR itokens.
SORT itokens BY str.
DELETE itokens WHERE str = 'INCLUDE'.
LOOP AT itokens.
READ TABLE gt_alv_file INTO gs_alv_file WITH KEY filename = itokens-str uuid = gv_uuid_new.
IF sy-subrc = 0.
CLEAR gs_alv_file.
CONTINUE.
ENDIF.
castprogramname = itokens-str.
READ REPORT castprogramname INTO iincludelines.
DELETE iincludelines WHERE table_line IS INITIAL.
LOOP AT iincludelines.
IF iincludelines+0(1) = '*'.
CLEAR lv_b64leng.
CONTINUE.
ENDIF.
lv_b64leng = STRLEN( iincludelines ).
CALL METHOD lr_conv->convert "把代码转16进制
EXPORTING
data = iincludelines
n = lv_b64leng
IMPORTING
buffer = lv_xstring
len = lex_len.
lv_string = lv_xstring.
CONCATENATE lv_string2 lv_string INTO lv_string2.
ENDLOOP.
lv_b64leng = STRLEN( lv_string2 ).
CHECK lv_string2 IS NOT INITIAL.
CALL METHOD cl_fdt_uuid=>get_uuid
EXPORTING
iv_id_compliant = abap_false
RECEIVING
rv_uuid = lv_zuuid.
gs_alv_file-timestamp = lv_zuuid.
gs_alv_file-filename = itokens-str.
gs_alv_file-filesize = lv_b64leng.
gs_alv_file-sel = 'X'.
gs_alv_file-uuid = gv_uuid_new.
COLLECT gs_alv_file INTO gt_alv_file2.
COLLECT gs_alv_file INTO gt_alv_file.
* ls_history-timestamp = lv_zuuid.
ls_history-role = 'assistant'.
ls_history-content = 'FILE'.
ls_history-content2 = lv_string2.
ls_history-sel = 'X'.
ls_history-uuid = gv_uuid_new.
COLLECT ls_history INTO gt_history.
CLEAR:iincludelines[],iincludelines,lv_string2,lv_b64leng,itokens,lv_zuuid.
ENDLOOP.
CLEAR gv_tcode.
MESSAGE '文件解析成功!' TYPE 'S'.
ENDFORM. " UPLOAD_FILE
*&---------------------------------------------------------------------*
*& Form FRM_DATA_CHANGED
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_GT_ALV_FILE text
* -->P_ER_DATA_CHANGED text
*----------------------------------------------------------------------*
FORM frm_data_changed USING p_gt_alv_file
p_er_data_changed TYPE REF TO cl_alv_changed_data_protocol.
DATA: wa_mod_data TYPE lvc_s_modi.
DATA: ls_stable TYPE lvc_s_stbl.
FIELD-SYMBOLS <fs_file> LIKE LINE OF gt_alv_file.
FIELD-SYMBOLS <fs_history> LIKE LINE OF gt_history.
LOOP AT p_er_data_changed->mt_mod_cells INTO wa_mod_data.
READ TABLE gt_alv_file ASSIGNING <fs_file> INDEX wa_mod_data-row_id.
IF sy-subrc = 0.
<fs_file>-sel = wa_mod_data-value.
READ TABLE gt_history ASSIGNING <fs_history> WITH KEY timestamp = <fs_file>-timestamp.
IF sy-subrc = 0.
<fs_history>-sel = <fs_file>-sel.
ENDIF.
ENDIF.
ENDLOOP.
PERFORM refresh_alv_display.
ENDFORM. " FRM_DATA_CHANGED
*&---------------------------------------------------------------------*
*& Module CHECK_CHANGED_DATA INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE check_changed_data INPUT.
CALL METHOD go_alv_grid_file->check_changed_data.
CALL METHOD go_alv_grid_hist->check_changed_data.
ENDMODULE. " CHECK_CHANGED_DATA INPUT
*&---------------------------------------------------------------------*
*& Form DELETE_FILES
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM delete_files .
FIELD-SYMBOLS <fs_file> LIKE LINE OF gt_alv_file.
FIELD-SYMBOLS <fs_history> LIKE LINE OF gt_history.
DATA lv_answer TYPE c.
IF gt_alv_file[] IS INITIAL.
MESSAGE '你还未上传解析程序!' TYPE 'I'.
RETURN.
ENDIF.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
text_question = '删除文件时是否同步删除历史记录?'
text_button_1 = '是'
text_button_2 = '否'
IMPORTING
answer = lv_answer
EXCEPTIONS
text_not_found = 1
OTHERS = 2.
IF lv_answer = '1'.
LOOP AT gt_alv_file ASSIGNING <fs_file> WHERE sel IS INITIAL.
READ TABLE gt_history ASSIGNING <fs_history> WITH KEY timestamp = <fs_file>-timestamp.
IF sy-subrc = 0.
DELETE gt_history WHERE timestamp = <fs_file>-timestamp.
ENDIF.
ENDLOOP.
ENDIF.
DELETE gt_alv_file WHERE sel IS INITIAL.
IF sy-subrc = 0.
MESSAGE '删除成功!' TYPE 'S'.
ENDIF.
ENDFORM. " DELETE_FILES
*&---------------------------------------------------------------------*
*& Form CREAT_CHAT_MEW
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM creat_chat_new .
DATA lv_zuuid TYPE sysuuid_c.
DATA:lt_value TYPE TABLE OF sval,
ls_value TYPE sval,
lv_returncode TYPE char1.
FIELD-SYMBOLS <fs_new> LIKE LINE OF gt_alv_new.
IF go_container_resp IS NOT INITIAL.
CALL METHOD go_container_resp->free.
CLEAR go_container_resp.
ENDIF.
CALL METHOD cl_fdt_uuid=>get_uuid
EXPORTING
iv_id_compliant = abap_false
RECEIVING
rv_uuid = lv_zuuid.
gv_uuid_new = lv_zuuid.
ls_value-tabname = 'ZLOG_TAB_P'.
ls_value-fieldname = 'ZMSG'.
ls_value-field_obl = ''.
APPEND ls_value TO lt_value.
CLEAR:ls_value.
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
popup_title = '输入聊天主体'
start_column = '5'
start_row = '5'
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_value
EXCEPTIONS
error_in_fields = 1
OTHERS = 2.
IF lv_returncode IS INITIAL.
APPEND INITIAL LINE TO gt_alv_new ASSIGNING <fs_new>.
<fs_new>-uuid = lv_zuuid.
READ TABLE lt_value INTO ls_value INDEX 1.
IF ls_value-value IS NOT INITIAL.
<fs_new>-title = ls_value-value.
CLEAR:lt_value[], ls_value.
ELSE.
CONCATENATE sy-datum sy-uzeit INTO <fs_new>-title.
ENDIF.
ELSE.
MESSAGE '已取消!' TYPE 'S'.
ENDIF.
ENDFORM. " CREAT_CHAT_MEW
*&---------------------------------------------------------------------*
*& Form DELETE_NEW_CHAT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM delete_new_chat .
DATA lv_text TYPE string.
DATA lv_answer TYPE string.
CONCATENATE '是否删除聊天主体:' gv_title INTO lv_text.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
text_question = lv_text
IMPORTING
answer = lv_answer
EXCEPTIONS
text_not_found = 1
OTHERS = 2.
IF lv_answer = '1'.
DELETE gt_alv_data WHERE uuid = gv_uuid_new.
DELETE gt_history WHERE uuid = gv_uuid_new.
DELETE gt_alv_file WHERE uuid = gv_uuid_new.
DELETE gt_alv_new WHERE uuid = gv_uuid_new.
ELSE.
MESSAGE '已取消!' TYPE 'S'.
ENDIF.
ENDFORM. " DELETE_NEW_CHAT
4.屏幕100
1.逻辑流
bash
PROCESS BEFORE OUTPUT.
MODULE status_0100.
MODULE initialize_screen_disply.
*
PROCESS AFTER INPUT.
MODULE user_command_0100.
* MODULE check_changed_data.
2.元素清单

感谢你阅读,欢迎大佬讨论留言或私信