abap调用deepseek接口 v3.0

文章目录

先看最终实现效果图

图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.保存删除会话记录

四、数据结构

主要内表:

  1. 聊天历史 (ty_chat_history):存储对话记录
  2. 文件信息 (ty_file):存储上传的文件信息
  3. 新建聊天 (ty_new):存储聊天会话元数据
  4. 聊天消息 (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.元素清单

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

相关推荐
caicongyang2 小时前
OpenClaw Agent Loop 机制源码深度分析(一)
ai·openclaw·大红虾
小同志002 小时前
网络原理 -KTTP/HTTPS(五) --认识响应“报头“(header) / “正⽂“(body)
java·网络·网络协议·http·https
啊阿狸不会拉杆2 小时前
《机器学习导论》第 16 章-贝叶斯估计
人工智能·python·算法·机器学习·ai·参数估计·贝叶斯估计
这是个栗子4 小时前
AI辅助编程工具(四) - 通义灵码
人工智能·ai·通义灵码
x-cmd4 小时前
GitHub 推出了 Agentic Workflows,并且提供了 Copilot 免费套餐
ai·github·copilot·x-cmd·agentic·workflows
阿杰学AI5 小时前
AI核心知识103——大语言模型之 AI PM(简洁且通俗易懂版)
人工智能·ai·语言模型·自然语言处理·产品经理·ai产品经理·ai pm
AC赳赳老秦5 小时前
边缘AI落地趋势:DeepSeek在工业边缘节点的部署与低功耗优化技巧
人工智能·python·算法·云原生·架构·pygame·deepseek
蚂蚁数据AntData5 小时前
DB-GPT 0.7.5 版本更新:基于 Falcon 评测集的Text2SQL评测体系全面升级,支持LLM/Agent两种评测模式和多环境评测
大数据·人工智能·算法·ai·开源
weixin_440401695 小时前
Coze-智能体Agent(工作流:批处理+图像生成+视频生成+)未完待续
python·ai·agent·coze