diff --git a/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/S98_S_tr_ticket_detail.sql b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/S98_S_tr_ticket_detail.sql
new file mode 100644
index 0000000..01f4055
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/S98_S_tr_ticket_detail.sql
@@ -0,0 +1,158 @@
+/*******Main Section**************************************************************************/
+\set ON_ERROR_STOP on
+\set AUTOCOMMIT on
+\timing on
+delete from p10_sa.S98_S_tr_ticket_detail
+;
+insert into p10_sa.S98_S_tr_ticket_detail
+( id
+ , workflow_id
+ , workflow_name
+ , workflow_category_id
+ , workflow_category_name
+ , topic
+ , level
+ , status
+ , state
+ , type
+ , creator_type
+ , creator_id
+ , creator_name
+ , modifier_type
+ , modifier_id
+ , modifier_name
+ , focus
+ , state_selected
+ , source
+ , end_time
+ , create_time
+ , update_time
+ , customer_id
+ , customer_name
+ , customer_tel
+ , tags
+ , comments
+ , start_form
+ , operation_logs
+ , operation_logs_new
+ , call_id
+ , close_time
+ , forms
+ , system_form
+ , etl_tx_dt )
+ select
+ id
+ , workflow_id
+ , workflow_name
+ , workflow_category_id
+ , workflow_category_name
+ , topic
+ , level
+ , status
+ , state
+ , type
+ , creator_type
+ , creator_id
+ , creator_name
+ , modifier_type
+ , modifier_id
+ , modifier_name
+ , focus
+ , state_selected
+ , source
+ , end_time
+ , create_time
+ , update_time
+ , customer_id
+ , customer_name
+ , customer_tel
+ , tags
+ , comments
+ , start_form
+ , operation_logs
+ , operation_logs_new
+ , call_id
+ , close_time
+ , forms
+ , system_form
+ , etl_tx_dt
+ from p00_tal.S98_S_tr_ticket_detail
+ ;
+ delete from p12_sfull.S98_S_tr_ticket_detail
+;
+;
+insert into p12_sfull.S98_S_tr_ticket_detail
+( id
+ , workflow_id
+ , workflow_name
+ , workflow_category_id
+ , workflow_category_name
+ , topic
+ , level
+ , status
+ , state
+ , type
+ , creator_type
+ , creator_id
+ , creator_name
+ , modifier_type
+ , modifier_id
+ , modifier_name
+ , focus
+ , state_selected
+ , source
+ , end_time
+ , create_time
+ , update_time
+ , customer_id
+ , customer_name
+ , customer_tel
+ , tags
+ , comments
+ , start_form
+ , operation_logs
+ , operation_logs_new
+ , call_id
+ , close_time
+ , forms
+ , system_form
+ , etl_tx_dt )
+ select
+ id
+ , workflow_id
+ , workflow_name
+ , workflow_category_id
+ , workflow_category_name
+ , topic
+ , level
+ , status
+ , state
+ , type
+ , creator_type
+ , creator_id
+ , creator_name
+ , modifier_type
+ , modifier_id
+ , modifier_name
+ , focus
+ , state_selected
+ , source
+ , end_time
+ , create_time
+ , update_time
+ , customer_id
+ , customer_name
+ , customer_tel
+ , tags
+ , comments
+ , start_form
+ , operation_logs
+ , operation_logs_new
+ , call_id
+ , close_time
+ , forms
+ , system_form
+ , etl_tx_dt
+ from p10_sa.S98_S_tr_ticket_detail
+;
+\q
\ No newline at end of file
diff --git a/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/sa_foreign_tables.sql b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/sa_foreign_tables.sql
new file mode 100644
index 0000000..d40395a
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/sa_foreign_tables.sql
@@ -0,0 +1,46 @@
+
+CREATE FOREIGN TABLE if not exists p00_tal.S98_S_tr_ticket_detail (
+ id TEXT
+ , workflow_id TEXT
+ , workflow_name TEXT
+ , workflow_category_id TEXT
+ , workflow_category_name TEXT
+ , topic TEXT
+ , level TEXT
+ , status TEXT
+ , state TEXT
+ , type TEXT
+ , creator_type TEXT
+ , creator_id TEXT
+ , creator_name TEXT
+ , modifier_type TEXT
+ , modifier_id TEXT
+ , modifier_name TEXT
+ , focus TEXT
+ , state_selected TEXT
+ , source TEXT
+ , end_time TEXT
+ , create_time TEXT
+ , update_time TEXT
+ , customer_id TEXT
+ , customer_name TEXT
+ , customer_tel TEXT
+ , tags TEXT
+ , comments TEXT
+ , start_form TEXT
+ , operation_logs TEXT
+ , operation_logs_new TEXT
+ , call_id TEXT
+ , close_time TEXT
+ , forms TEXT
+ , system_form TEXT
+ , etl_tx_dt TIMESTAMP
+)
+
+
+SERVER pgsql_server_S98_S OPTIONS(schema_name 'data_api', table_name 'tr_ticket_detail' );
+
+
+
+
+
diff --git a/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/sa_tables.sql b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/sa_tables.sql
new file mode 100644
index 0000000..5542e01
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_detail/sa_tables.sql
@@ -0,0 +1,154 @@
+
+create table if not exists p10_sa.S98_S_tr_ticket_detail (
+ id TEXT
+ , workflow_id TEXT
+ , workflow_name TEXT
+ , workflow_category_id TEXT
+ , workflow_category_name TEXT
+ , topic TEXT
+ , level TEXT
+ , status TEXT
+ , state TEXT
+ , type TEXT
+ , creator_type TEXT
+ , creator_id TEXT
+ , creator_name TEXT
+ , modifier_type TEXT
+ , modifier_id TEXT
+ , modifier_name TEXT
+ , focus TEXT
+ , state_selected TEXT
+ , source TEXT
+ , end_time TEXT
+ , create_time TEXT
+ , update_time TEXT
+ , customer_id TEXT
+ , customer_name TEXT
+ , customer_tel TEXT
+ , tags TEXT
+ , comments TEXT
+ , start_form TEXT
+ , operation_logs TEXT
+ , operation_logs_new TEXT
+ , call_id TEXT
+ , close_time TEXT
+ , forms TEXT
+ , system_form TEXT
+ , etl_tx_dt TIMESTAMP
+) ;
+
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.id IS '工单 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.workflow_id IS '工作流 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.workflow_name IS '工作流名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.workflow_category_id IS '模板类别id';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.workflow_category_name IS '模板类别名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.topic IS '工单主题';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.level IS '工单优先级';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.status IS '工单系统状态';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.state IS '自定义状态数组';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.type IS '模板类型';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.creator_type IS '创建人类型 ';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.creator_id IS '创建人 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.creator_name IS '创建人名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.modifier_type IS '修改人类型';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.modifier_id IS '修改人 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.modifier_name IS '修改人名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.focus IS '关注人数组集合';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.state_selected IS '当前工单状态';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.source IS '来源 ';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.end_time IS '结束时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.create_time IS '创建时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.update_time IS '更新时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.customer_id IS '客户 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.customer_name IS '客户名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.customer_tel IS '客户电话';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.tags IS '工单标签数组 ';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.comments IS '评论人数组 ';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.start_form IS '起始表单';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.operation_logs IS '工单操作日志 ';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.operation_logs_new IS '工单操作日志v2';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.call_id IS '通话记录唯一标识';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.close_time IS '关闭时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.forms IS '历史表单';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.system_form IS '工单属性表单 ';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_detail.etl_tx_dt IS '';
+
+COMMENT ON TABLE p10_sa.S98_S_tr_ticket_detail IS '工单详情';
+
+
+create table if not exists p12_sfull.S98_S_tr_ticket_detail (
+ id TEXT
+ , workflow_id TEXT
+ , workflow_name TEXT
+ , workflow_category_id TEXT
+ , workflow_category_name TEXT
+ , topic TEXT
+ , level TEXT
+ , status TEXT
+ , state TEXT
+ , type TEXT
+ , creator_type TEXT
+ , creator_id TEXT
+ , creator_name TEXT
+ , modifier_type TEXT
+ , modifier_id TEXT
+ , modifier_name TEXT
+ , focus TEXT
+ , state_selected TEXT
+ , source TEXT
+ , end_time TEXT
+ , create_time TEXT
+ , update_time TEXT
+ , customer_id TEXT
+ , customer_name TEXT
+ , customer_tel TEXT
+ , tags TEXT
+ , comments TEXT
+ , start_form TEXT
+ , operation_logs TEXT
+ , operation_logs_new TEXT
+ , call_id TEXT
+ , close_time TEXT
+ , forms TEXT
+ , system_form TEXT
+ , etl_tx_dt TIMESTAMP
+) ;
+
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.id IS '工单 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.workflow_id IS '工作流 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.workflow_name IS '工作流名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.workflow_category_id IS '模板类别id';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.workflow_category_name IS '模板类别名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.topic IS '工单主题';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.level IS '工单优先级';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.status IS '工单系统状态';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.state IS '自定义状态数组';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.type IS '模板类型';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.creator_type IS '创建人类型 ';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.creator_id IS '创建人 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.creator_name IS '创建人名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.modifier_type IS '修改人类型';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.modifier_id IS '修改人 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.modifier_name IS '修改人名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.focus IS '关注人数组集合';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.state_selected IS '当前工单状态';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.source IS '来源 ';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.end_time IS '结束时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.create_time IS '创建时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.update_time IS '更新时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.customer_id IS '客户 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.customer_name IS '客户名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.customer_tel IS '客户电话';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.tags IS '工单标签数组 ';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.comments IS '评论人数组 ';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.start_form IS '起始表单';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.operation_logs IS '工单操作日志 ';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.operation_logs_new IS '工单操作日志v2';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.call_id IS '通话记录唯一标识';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.close_time IS '关闭时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.forms IS '历史表单';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.system_form IS '工单属性表单 ';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_detail.etl_tx_dt IS '';
+
+COMMENT ON TABLE p12_sfull.S98_S_tr_ticket_detail IS '工单详情';
+
diff --git a/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/S98_S_tr_ticket_list.sql b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/S98_S_tr_ticket_list.sql
new file mode 100644
index 0000000..b75b477
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/S98_S_tr_ticket_list.sql
@@ -0,0 +1,146 @@
+/*******Main Section**************************************************************************/
+\set ON_ERROR_STOP on
+\set AUTOCOMMIT on
+\timing on
+delete from p10_sa.S98_S_tr_ticket_list
+;
+insert into p10_sa.S98_S_tr_ticket_list
+( id
+ , workflow_id
+ , workflow_name
+ , type
+ , topic
+ , level
+ , status
+ , creator_name
+ , creator_id
+ , creator_type
+ , modifier_id
+ , modifier_type
+ , source
+ , timeout
+ , end_time
+ , create_time
+ , close_time
+ , state_selected
+ , last_reminder_time
+ , reminder_count
+ , customer_id
+ , customer_name
+ , customer_tel
+ , customer_email
+ , customer_address
+ , customer_creator_id
+ , customer_creator_name
+ , customer_modifier_id
+ , customer_modifier_name
+ , tags
+ , system_form
+ , etl_tx_dt )
+ select
+ id
+ , workflow_id
+ , workflow_name
+ , type
+ , topic
+ , level
+ , status
+ , creator_name
+ , creator_id
+ , creator_type
+ , modifier_id
+ , modifier_type
+ , source
+ , timeout
+ , end_time
+ , create_time
+ , close_time
+ , state_selected
+ , last_reminder_time
+ , reminder_count
+ , customer_id
+ , customer_name
+ , customer_tel
+ , customer_email
+ , customer_address
+ , customer_creator_id
+ , customer_creator_name
+ , customer_modifier_id
+ , customer_modifier_name
+ , tags
+ , system_form
+ , etl_tx_dt
+ from p00_tal.S98_S_tr_ticket_list
+ ;
+ delete from p12_sfull.S98_S_tr_ticket_list
+;
+;
+insert into p12_sfull.S98_S_tr_ticket_list
+( id
+ , workflow_id
+ , workflow_name
+ , type
+ , topic
+ , level
+ , status
+ , creator_name
+ , creator_id
+ , creator_type
+ , modifier_id
+ , modifier_type
+ , source
+ , timeout
+ , end_time
+ , create_time
+ , close_time
+ , state_selected
+ , last_reminder_time
+ , reminder_count
+ , customer_id
+ , customer_name
+ , customer_tel
+ , customer_email
+ , customer_address
+ , customer_creator_id
+ , customer_creator_name
+ , customer_modifier_id
+ , customer_modifier_name
+ , tags
+ , system_form
+ , etl_tx_dt )
+ select
+ id
+ , workflow_id
+ , workflow_name
+ , type
+ , topic
+ , level
+ , status
+ , creator_name
+ , creator_id
+ , creator_type
+ , modifier_id
+ , modifier_type
+ , source
+ , timeout
+ , end_time
+ , create_time
+ , close_time
+ , state_selected
+ , last_reminder_time
+ , reminder_count
+ , customer_id
+ , customer_name
+ , customer_tel
+ , customer_email
+ , customer_address
+ , customer_creator_id
+ , customer_creator_name
+ , customer_modifier_id
+ , customer_modifier_name
+ , tags
+ , system_form
+ , etl_tx_dt
+ from p10_sa.S98_S_tr_ticket_list
+;
+\q
\ No newline at end of file
diff --git a/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/sa_foreign_tables.sql b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/sa_foreign_tables.sql
new file mode 100644
index 0000000..d1a2c18
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/sa_foreign_tables.sql
@@ -0,0 +1,43 @@
+
+CREATE FOREIGN TABLE if not exists p00_tal.S98_S_tr_ticket_list (
+ id TEXT
+ , workflow_id TEXT
+ , workflow_name TEXT
+ , type TEXT
+ , topic TEXT
+ , level TEXT
+ , status TEXT
+ , creator_name TEXT
+ , creator_id TEXT
+ , creator_type TEXT
+ , modifier_id TEXT
+ , modifier_type TEXT
+ , source TEXT
+ , timeout TEXT
+ , end_time TEXT
+ , create_time TEXT
+ , close_time TEXT
+ , state_selected TEXT
+ , last_reminder_time TEXT
+ , reminder_count TEXT
+ , customer_id TEXT
+ , customer_name TEXT
+ , customer_tel TEXT
+ , customer_email TEXT
+ , customer_address TEXT
+ , customer_creator_id TEXT
+ , customer_creator_name TEXT
+ , customer_modifier_id TEXT
+ , customer_modifier_name TEXT
+ , tags TEXT
+ , system_form TEXT
+ , etl_tx_dt TIMESTAMP
+)
+
+
+SERVER pgsql_server_S98_S OPTIONS(schema_name 'data_api', table_name 'tr_ticket_list' );
+
+
+
+
+
diff --git a/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/sa_tables.sql b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/sa_tables.sql
new file mode 100644
index 0000000..7a6b317
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/tr_ticket_list/sa_tables.sql
@@ -0,0 +1,143 @@
+
+create table if not exists p10_sa.S98_S_tr_ticket_list (
+ id TEXT
+ , workflow_id TEXT
+ , workflow_name TEXT
+ , type TEXT
+ , topic TEXT
+ , level TEXT
+ , status TEXT
+ , creator_name TEXT
+ , creator_id TEXT
+ , creator_type TEXT
+ , modifier_id TEXT
+ , modifier_type TEXT
+ , source TEXT
+ , timeout TEXT
+ , end_time TEXT
+ , create_time TEXT
+ , close_time TEXT
+ , state_selected TEXT
+ , last_reminder_time TEXT
+ , reminder_count TEXT
+ , customer_id TEXT
+ , customer_name TEXT
+ , customer_tel TEXT
+ , customer_email TEXT
+ , customer_address TEXT
+ , customer_creator_id TEXT
+ , customer_creator_name TEXT
+ , customer_modifier_id TEXT
+ , customer_modifier_name TEXT
+ , tags TEXT
+ , system_form TEXT
+ , etl_tx_dt TIMESTAMP
+) ;
+
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.id IS '工单 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.workflow_id IS '模板 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.workflow_name IS '模板名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.type IS '工单类型';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.topic IS '工单主题';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.level IS '工单优先级';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.status IS '工单状态';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.creator_name IS '创建人名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.creator_id IS '创建人 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.creator_type IS '';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.modifier_id IS '修改人 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.modifier_type IS '';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.source IS '来源';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.timeout IS '是否超时';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.end_time IS '结束时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.create_time IS '创建时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.close_time IS '关闭时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.state_selected IS '当前工单状态';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.last_reminder_time IS '最近催单时间';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.reminder_count IS '催单次数';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_id IS '客户 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_name IS '客户名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_tel IS '客户号码';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_email IS '客户邮箱';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_address IS '客户地址';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_creator_id IS '客户资料创建人 ID';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_creator_name IS '客户资料创建人名称';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_modifier_id IS '客户资料修改人';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.customer_modifier_name IS '客户资料修改人姓名';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.tags IS '工单标签';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.system_form IS '工单属性表单';
+ COMMENT ON COLUMN p10_sa.S98_S_tr_ticket_list.etl_tx_dt IS '';
+
+COMMENT ON TABLE p10_sa.S98_S_tr_ticket_list IS '工单记录列表';
+
+
+
+create table if not exists p12_sfull.S98_S_tr_ticket_list (
+ id TEXT
+ , workflow_id TEXT
+ , workflow_name TEXT
+ , type TEXT
+ , topic TEXT
+ , level TEXT
+ , status TEXT
+ , creator_name TEXT
+ , creator_id TEXT
+ , creator_type TEXT
+ , modifier_id TEXT
+ , modifier_type TEXT
+ , source TEXT
+ , timeout TEXT
+ , end_time TEXT
+ , create_time TEXT
+ , close_time TEXT
+ , state_selected TEXT
+ , last_reminder_time TEXT
+ , reminder_count TEXT
+ , customer_id TEXT
+ , customer_name TEXT
+ , customer_tel TEXT
+ , customer_email TEXT
+ , customer_address TEXT
+ , customer_creator_id TEXT
+ , customer_creator_name TEXT
+ , customer_modifier_id TEXT
+ , customer_modifier_name TEXT
+ , tags TEXT
+ , system_form TEXT
+ , etl_tx_dt TIMESTAMP
+) ;
+
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.id IS '工单 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.workflow_id IS '模板 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.workflow_name IS '模板名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.type IS '工单类型';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.topic IS '工单主题';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.level IS '工单优先级';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.status IS '工单状态';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.creator_name IS '创建人名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.creator_id IS '创建人 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.creator_type IS '';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.modifier_id IS '修改人 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.modifier_type IS '';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.source IS '来源';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.timeout IS '是否超时';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.end_time IS '结束时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.create_time IS '创建时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.close_time IS '关闭时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.state_selected IS '当前工单状态';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.last_reminder_time IS '最近催单时间';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.reminder_count IS '催单次数';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_id IS '客户 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_name IS '客户名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_tel IS '客户号码';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_email IS '客户邮箱';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_address IS '客户地址';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_creator_id IS '客户资料创建人 ID';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_creator_name IS '客户资料创建人名称';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_modifier_id IS '客户资料修改人';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.customer_modifier_name IS '客户资料修改人姓名';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.tags IS '工单标签';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.system_form IS '工单属性表单';
+ COMMENT ON COLUMN p12_sfull.S98_S_tr_ticket_list.etl_tx_dt IS '';
+
+COMMENT ON TABLE p12_sfull.S98_S_tr_ticket_list IS '工单记录列表';
+
diff --git a/dev/workflow/TK_Cust/smart_ccc/天润Smart-ccc工单数据/wf_dag_smart_ccc.py b/dev/workflow/TK_Cust/smart_ccc/天润Smart-ccc工单数据/wf_dag_smart_ccc.py
new file mode 100644
index 0000000..40da8c2
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/天润Smart-ccc工单数据/wf_dag_smart_ccc.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+# -*- encoding=utf-8 -*-
+from airflow import DAG
+from datetime import datetime, timedelta
+from airflow.contrib.hooks.ssh_hook import SSHHook
+from airflow.contrib.operators.ssh_operator import SSHOperator
+from airflow.sensors.external_task_sensor import ExternalTaskSensor
+import json
+
+from airflow.operators.trigger_dagrun import TriggerDagRunOperator
+from airflow.operators.email_operator import EmailOperator
+from airflow.utils.trigger_rule import TriggerRule
+
+
+sshHook = SSHHook(ssh_conn_id ='ssh_air')
+default_args = {
+'owner': 'info@idgvalue.com',
+'email_on_failure': True,
+'email_on_retry':True,
+'start_date': datetime(2024, 1, 1),
+'depends_on_past': False,
+'retries': 6,
+'retry_delay': timedelta(minutes=10),
+}
+
+dag = DAG('wf_dag_smart_ccc', default_args=default_args,
+schedule_interval="0 */1 * * *",
+catchup=False,
+dagrun_timeout=timedelta(minutes=160),
+max_active_runs=3)
+
+task_failed = EmailOperator (
+ dag=dag,
+ trigger_rule=TriggerRule.ONE_FAILED,
+ task_id="task_failed",
+ to=["info@idgvalue.com"],
+ cc=[""],
+ subject="smart_ccc_failed",
+ html_content='
您好,smart_ccc作业失败,请及时处理"
')
+
+tickets_list_feign = SSHOperator(
+ssh_hook=sshHook,
+task_id='tickets_list_feign',
+command='python3 /data/airflow/etl/API/tickets_list_feign.py',
+depends_on_past=False,
+retries=3,
+dag=dag)
+
+tickets_list_load = SSHOperator(
+ssh_hook=sshHook,
+task_id='tickets_list_load',
+command='/data/airflow/etl/API/run_psql.sh {{ ds_nodash }} {{params.my_param }}',
+params={'my_param':"tickets_list_load"},
+depends_on_past=False,
+retries=3,
+dag=dag)
+
+tickets_list_feign >> tickets_list_load
+
+tr_ticket_detail_4125 = SSHOperator(
+ssh_hook=sshHook,
+task_id='tr_ticket_detail_4125',
+command='/data/airflow/etl/SA/run_sa.sh {{ ds_nodash }} {{ params.my_param }} >>/data/airflow/logs/run_psql_{{ds_nodash}}.log 2>&1 ',
+params={'my_param':"S98_S_tr_ticket_detail"},
+depends_on_past=False,
+retries=3,
+dag=dag)
+
+tr_ticket_list_4585 = SSHOperator(
+ssh_hook=sshHook,
+task_id='tr_ticket_list_4585',
+command='/data/airflow/etl/SA/run_sa.sh {{ ds_nodash }} {{ params.my_param }} >>/data/airflow/logs/run_psql_{{ds_nodash}}.log 2>&1 ',
+params={'my_param':"S98_S_tr_ticket_list"},
+depends_on_past=False,
+retries=3,
+dag=dag)
+
+tickets_list_load >> tr_ticket_list_4585
+tickets_list_load >> tr_ticket_detail_4125
+tr_ticket_detail_4125 >> task_failed
+tr_ticket_list_4585 >> task_failed
diff --git a/dev/workflow/TK_Cust/smart_ccc/获取工单记录列表/tickets_list_feign.py b/dev/workflow/TK_Cust/smart_ccc/获取工单记录列表/tickets_list_feign.py
new file mode 100644
index 0000000..3c60f30
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/获取工单记录列表/tickets_list_feign.py
@@ -0,0 +1,198 @@
+# coding: utf-8
+import requests
+import json
+import psycopg2
+import uuid
+import datetime
+import time
+import hashlib
+import time
+import hmac
+import base64
+import urllib.parse
+import hashlib
+from collections import OrderedDict
+from urllib.parse import quote_plus
+
+#全局变量,便于参数使用的预设值
+current_date = datetime.date.today() # 获取当前日期
+previous_date = current_date - datetime.timedelta(days=1) # 获取前一天日期
+formatted_current_date = current_date.strftime("%Y-%m-%dT%H:%M:%SZ") # 获取当前日期 - 标准化
+formatted_previous_date = previous_date.strftime("%Y-%m-%dT%H:%M:%SZ") # 获取前一天日期 - 标准化
+timestamp = time.time() # 为Unix time,即从"1970-01-01 00:00:00"至今的秒数;
+sign_version = 'v2' # 签名版本号,固定值v2
+nonce = str(uuid.uuid4())
+current_time_utc =( datetime.datetime.now() - datetime.timedelta(hours=8)).strftime("%Y-%m-%dT%H:%M:%SZ")
+
+formatted2_current_date = current_date.strftime("%Y-%m-%d %H:%M:%S") # 获取当前日期 - 标准化
+formatted2_previous_date = previous_date.strftime("%Y-%m-%d %H:%M:%S") # 获取前一天日期 - 标准化
+
+def formatted2_previous_hour(h):
+ if h==0:
+ return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ start_of_current_hour = datetime.datetime.now().replace(minute=0, second=0, microsecond=0)
+ # 减去一个小时,得到前一个小时的开始时间
+ start_of_previous_hour = start_of_current_hour - datetime.timedelta(hours=h)
+ return start_of_previous_hour.strftime("%Y-%m-%d %H:%M:%S")
+
+def previous_hour_timestamp(h):
+ if h==0:
+ return int(time.time())
+ start_of_current_hour = datetime.datetime.now().replace(minute=0, second=0, microsecond=0)
+ # 减去一个小时,得到前一个小时的开始时间
+ start_of_previous_hour = start_of_current_hour - datetime.timedelta(hours=h)
+ return int(start_of_previous_hour.timestamp())
+
+#计算签名
+def generate_signature(str, private_key):
+ signature = hmac.new(private_key.encode(), (str).encode(), hashlib.sha1)
+ signature_b64 = base64.b64encode(signature.digest()).decode()
+ return signature_b64
+
+#构建查询链接
+def build_query_string(params):
+ # 使用OrderedDict来保持排序
+ sorted_params = OrderedDict(sorted(params.items()))
+
+ # 拼接属性名和属性值,并使用&连接
+ query_string = '&'.join('{}={}'.format(
+ urllib.parse.quote_plus(k),
+ urllib.parse.quote_plus(str(v))
+ ) for k, v in sorted_params.items())
+ return query_string
+
+
+def request_data_signature_post():
+ print(f'开始请求工单列表数据:{formatted2_previous_hour(0)}')
+ url='https://api-bj.clink.cn/ticket/list_ticket'
+ header={}
+ param={'AccessKeyId':'b17759d3a36fba9a2cf522fbf4cbf177','Timestamp':current_time_utc,'Expires':'86400',}
+ print(f'param: {param}')
+ url_path = build_query_string(param)
+ url_param = url_path
+ print(f'url_param: {url_param}')
+ url_param = f'POSTapi-bj.clink.cn/ticket/list_ticket?{url_param}'
+ print(f'url_param2: {url_param}')
+ signature= generate_signature(url_param,'5g027B6w06630Y5240c1')
+ print(f'signature: {signature}')
+ url = f'{url}?{url_path}&Signature={signature}'
+ print(f'url: {url}')
+ body={'endTime':'2024-01-01 00:00:00','startTime':formatted2_previous_hour(1)}
+ #body={'endTime':formatted2_previous_hour(0),'startTime':formatted2_previous_hour(1)}
+ print(f'body: {body}')
+ dataReqL=requests.post(url,headers=header,params=body)
+ i = 0
+ while 'error' in dataReqL and i < 5:
+ time.sleep(1)
+ dataReqL=requests.post(url,headers=header,params=body)
+ i = i + 1
+ resL=json.loads(dataReqL.text)
+ print(dataReqL)
+ resL=json.loads(dataReqL.text)
+ return resL
+
+
+
+
+def load_data_to_db(dataList):
+ conn = psycopg2.connect(database="dataops_db", user="dbuser_dops", password="MIgTi3jA",host="172.17.0.8", port="5432")
+ print('数据库连接成功')
+ dataId=str(uuid.uuid4())
+ total=len(dataList)
+ print('临时id:'+dataId)
+ json_object = json.dumps(dataList)
+ cur=conn.cursor()
+ sql="update data_api.api_data set is_loaded = '1' where api_id = 'e674961b-1a61-4019-a2e5-1b5fbe0e';INSERT INTO data_api.api_data (id,api_id,data,total_num,is_loaded,status,request_tm,execute_tm,remark) values (%s,%s,%s,%s,'0','0',current_timestamp(0),current_timestamp(0),'')"
+ cur.execute(sql,[dataId,'e674961b-1a61-4019-a2e5-1b5fbe0e', json_object, total])
+ conn.commit()
+ cur.close()
+ conn.close()
+ print('加载数据结束:tickets_list:获取工单记录列表')
+
+
+#计算签名,get请求
+def request_data_signature_get(id):
+ print(f'开始请求工单详情数据:{id}')
+ url='https://api-bj.clink.cn/ticket/get_ticket_detail'
+ param={'Timestamp':current_time_utc,'Expires':86400,'id':id,'AccessKeyId':'b17759d3a36fba9a2cf522fbf4cbf177',}
+ print(f'param: {param}')
+ url_path = build_query_string(param)
+ url_param = url_path
+ print(f'url_param: {url_param}')
+ url_param = f'GETapi-bj.clink.cn/ticket/get_ticket_detail?{url_param}'
+ print(f'待计算字符串: {url_param}')
+ signature= generate_signature(url_param,'5g027B6w06630Y5240c1')
+ print(f'计算签名: {signature}')
+ print(f'编码后签名: {urllib.parse.quote_plus(signature)}')
+ url = f'{url}?{url_path}&Signature={urllib.parse.quote_plus(signature)}'
+ print(f'url: {url}')
+
+ dataReqL=requests.get(url,headers={},params={})
+ i = 0
+ while 'error' in dataReqL and i < 5:
+ time.sleep(1)
+ dataReqL=requests.get(url,headers={},params={})
+ i = i + 1
+ resL=json.loads(dataReqL.text)
+ return resL
+
+def load_detail_data_to_db(ids, dataList):
+ conn = psycopg2.connect(database="dataops_db", user="dbuser_dops", password="MIgTi3jA",host="172.17.0.8", port="5432")
+ print('数据库连接成功')
+ dataId=str(uuid.uuid4())
+ total=len(dataList)
+ print('临时id:'+dataId)
+ json_object = json.dumps(dataList)
+ idstr = ','.join(ids)
+ cur=conn.cursor()
+ sql="update data_api.cc_details_ids_exp set is_loaded = '1' where api_id = '6a977523d60f46788e6004549027bb8e' and id in (%s); INSERT INTO data_api.cc_ticket_details (id,api_id,data,total_num,is_loaded,status,request_tm,execute_tm,remark) values (%s,%s,%s,%s,'0','0',current_timestamp(0),current_timestamp(0),'')"
+ cur.execute(sql,[idstr,dataId,'6a977523d60f46788e6004549027bb8e', json_object, total])
+ conn.commit()
+ cur.close()
+ conn.close()
+ print('加载数据结束:tickets_detail:获取工单详情')
+
+def load_detail_exp_to_db(id):
+ print(f'添加查询工单异常记录:{id}')
+ conn = psycopg2.connect(database="dataops_db", user="dbuser_dops", password="MIgTi3jA",host="172.17.0.8", port="5432")
+ print('数据库连接成功')
+ dataId=str(uuid.uuid4())
+ total=len(dataList)
+ print('临时id:'+dataId)
+ json_object = json.dumps(dataList)
+ idstr = ','.join(ids)
+ cur=conn.cursor()
+ sql=" INSERT INTO data_api.cc_details_ids_exp (id,api_id,is_loaded,status,request_tm,execute_tm,remark) values (%s,%s,'0','0',current_timestamp(0),current_timestamp(0),'')"
+ cur.execute(sql,[id, '6a977523d60f46788e6004549027bb8e'])
+ conn.commit()
+ cur.close()
+ conn.close()
+ print(f'添加查询工单异常记录:{id} 结束')
+
+if __name__ == "__main__":
+ print(f'{formatted2_previous_hour(0)}开始请求工单信息')
+ resL = request_data_signature_post()
+ print(resL)
+ if 'error' in resL:
+ print(f'请求工单列表失败,失败原因:{resL['error']}')
+ else:
+ dataList = resL['tickets']
+ load_data_to_db(dataList)
+ detailDataList = []
+ ids = []
+ for data in dataList:
+ try:
+ id = data['id']
+ resD = request_data_signature_get(id)
+ if 'error' in resD:
+ print(f'请求工单详情(id:{id})失败,错误信息:{resD['error']}')
+ load_detail_exp_to_db(id)
+ else:
+ ids.push(id)
+ dataList = resL['ticketDetail']
+ detailDataList.push(dataList)
+ except Exception as e:
+ print(f'请求工单详情(id:{data['id']})失败, 错误信息:{e}')
+ load_detail_exp_to_db(data['id'])
+ load_detail_data_to_db(ids,detailDataList)
+ print(f'{formatted2_previous_hour(0)}请求工单信息结束')
\ No newline at end of file
diff --git a/dev/workflow/TK_Cust/smart_ccc/获取工单记录列表/tickets_list_load.sql b/dev/workflow/TK_Cust/smart_ccc/获取工单记录列表/tickets_list_load.sql
new file mode 100644
index 0000000..bc59c48
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/获取工单记录列表/tickets_list_load.sql
@@ -0,0 +1,117 @@
+/*******Main Section**************************************************************************/
+\set ON_ERROR_STOP on
+\set AUTOCOMMIT on
+\timing on
+
+DELETE FROM data_api.tr_ticket_list;
+
+insert into data_api.tr_ticket_list (
+ id
+ , workflow_id
+ , workflow_name
+ , type
+ , topic
+ , level
+ , status
+ , creator_name
+ , creator_id
+ , creator_type
+ , modifier_id
+ , modifier_type
+ , source
+ , timeout
+ , end_time
+ , create_time
+ , close_time
+ , state_selected
+ , last_reminder_time
+ , reminder_count
+ , customer_id
+ , customer_name
+ , customer_tel
+ , customer_email
+ , customer_address
+ , customer_creator_id
+ , customer_creator_name
+ , customer_modifier_id
+ , customer_modifier_name
+ , tags
+ , system_form
+ ,etl_tx_dt
+)
+select
+ case when trim(both from id)='' then null else id::text end id
+ , case when trim(both from workflow_id)='' then null else workflow_id::text end workflow_id
+ , case when trim(both from workflow_name)='' then null else workflow_name::text end workflow_name
+ , case when trim(both from type)='' then null else type::text end type
+ , case when trim(both from topic)='' then null else topic::text end topic
+ , case when trim(both from level)='' then null else level::text end level
+ , case when trim(both from status)='' then null else status::text end status
+ , case when trim(both from creator_name)='' then null else creator_name::text end creator_name
+ , case when trim(both from creator_id)='' then null else creator_id::text end creator_id
+ , case when trim(both from creator_type)='' then null else creator_type::text end creator_type
+ , case when trim(both from modifier_id)='' then null else modifier_id::text end modifier_id
+ , case when trim(both from modifier_type)='' then null else modifier_type::text end modifier_type
+ , case when trim(both from source)='' then null else source::text end source
+ , case when trim(both from timeout)='' then null else timeout::text end timeout
+ , case when trim(both from end_time)='' then null else end_time::text end end_time
+ , case when trim(both from create_time)='' then null else create_time::text end create_time
+ , case when trim(both from close_time)='' then null else close_time::text end close_time
+ , case when trim(both from state_selected)='' then null else state_selected::text end state_selected
+ , case when trim(both from last_reminder_time)='' then null else last_reminder_time::text end last_reminder_time
+ , case when trim(both from reminder_count)='' then null else reminder_count::text end reminder_count
+ , case when trim(both from customer_id)='' then null else customer_id::text end customer_id
+ , case when trim(both from customer_name)='' then null else customer_name::text end customer_name
+ , case when trim(both from customer_tel)='' then null else customer_tel::text end customer_tel
+ , case when trim(both from customer_email)='' then null else customer_email::text end customer_email
+ , case when trim(both from customer_address)='' then null else customer_address::text end customer_address
+ , case when trim(both from customer_creator_id)='' then null else customer_creator_id::text end customer_creator_id
+ , case when trim(both from customer_creator_name)='' then null else customer_creator_name::text end customer_creator_name
+ , case when trim(both from customer_modifier_id)='' then null else customer_modifier_id::text end customer_modifier_id
+ , case when trim(both from customer_modifier_name)='' then null else customer_modifier_name::text end customer_modifier_name
+ , case when trim(both from tags)='' then null else tags::text end tags
+ , case when trim(both from system_form)='' then null else system_form::text end system_form
+,etl_tx_dt
+from (
+select
+ (json_array_elements(data::json)::json->>'id') id
+ , (json_array_elements(data::json)::json->>'workflowId') workflow_id
+ , (json_array_elements(data::json)::json->>'workflowName') workflow_name
+ , (json_array_elements(data::json)::json->>'type') type
+ , (json_array_elements(data::json)::json->>'topic') topic
+ , (json_array_elements(data::json)::json->>'level') level
+ , (json_array_elements(data::json)::json->>'status') status
+ , (json_array_elements(data::json)::json->>'creatorName') creator_name
+ , (json_array_elements(data::json)::json->>'creatorId') creator_id
+ , (json_array_elements(data::json)::json->>'creatorType') creator_type
+ , (json_array_elements(data::json)::json->>'modifierId') modifier_id
+ , (json_array_elements(data::json)::json->>'modifierType') modifier_type
+ , (json_array_elements(data::json)::json->>'source') source
+ , (json_array_elements(data::json)::json->>'timeout') timeout
+ , (json_array_elements(data::json)::json->>'endTime') end_time
+ , (json_array_elements(data::json)::json->>'createTime') create_time
+ , (json_array_elements(data::json)::json->>'closeTime') close_time
+ , (json_array_elements(data::json)::json->>'stateSelected') state_selected
+ , (json_array_elements(data::json)::json->>'lastReminderTime') last_reminder_time
+ , (json_array_elements(data::json)::json->>'reminderCount') reminder_count
+ , (json_array_elements(data::json)::json->>'customerId') customer_id
+ , (json_array_elements(data::json)::json->>'customerName') customer_name
+ , (json_array_elements(data::json)::json->>'customerTel') customer_tel
+ , (json_array_elements(data::json)::json->>'customerEmail') customer_email
+ , (json_array_elements(data::json)::json->>'customerAddress') customer_address
+ , (json_array_elements(data::json)::json->>'customerCreatorId') customer_creator_id
+ , (json_array_elements(data::json)::json->>'customerCreatorName') customer_creator_name
+ , (json_array_elements(data::json)::json->>'customerModifierId') customer_modifier_id
+ , (json_array_elements(data::json)::json->>'customerModifierName') customer_modifier_name
+ , (json_array_elements(data::json)::json->>'tags') tags
+ , (json_array_elements(data::json)::json->>'systemForm') system_form
+ ,CURRENT_TIMESTAMP(0) etl_tx_dt
+from (select * from data_api.api_data
+WHERE api_id='e674961b-1a61-4019-a2e5-1b5fbe0e' and is_loaded = '0' order by request_tm desc limit 1) p )p;
+
+update data_api.api_data
+set is_loaded = '1' ,
+ status = '1',
+ request_tm = current_timestamp(0)
+where api_id='e674961b-1a61-4019-a2e5-1b5fbe0e';
+\q
\ No newline at end of file
diff --git a/dev/workflow/TK_Cust/smart_ccc/获取工单详情/tickets_detail_feign.py b/dev/workflow/TK_Cust/smart_ccc/获取工单详情/tickets_detail_feign.py
new file mode 100644
index 0000000..263c957
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/获取工单详情/tickets_detail_feign.py
@@ -0,0 +1,121 @@
+# coding: utf-8
+import requests
+import json
+import psycopg2
+import uuid
+import datetime
+import time
+import hashlib
+import time
+import hmac
+import base64
+import urllib.parse
+import hashlib
+from collections import OrderedDict
+from urllib.parse import quote_plus
+
+#全局变量,便于参数使用的预设值
+current_date = datetime.date.today() # 获取当前日期
+previous_date = current_date - datetime.timedelta(days=1) # 获取前一天日期
+formatted_current_date = current_date.strftime("%Y-%m-%dT%H:%M:%SZ") # 获取当前日期 - 标准化
+formatted_previous_date = previous_date.strftime("%Y-%m-%dT%H:%M:%SZ") # 获取前一天日期 - 标准化
+timestamp = time.time() # 为Unix time,即从"1970-01-01 00:00:00"至今的秒数;
+sign_version = 'v2' # 签名版本号,固定值v2
+nonce = str(uuid.uuid4())
+current_time_utc =( datetime.datetime.now() - datetime.timedelta(hours=8)).strftime("%Y-%m-%dT%H:%M:%SZ")
+
+formatted2_current_date = current_date.strftime("%Y-%m-%d %H:%M:%S") # 获取当前日期 - 标准化
+formatted2_previous_date = previous_date.strftime("%Y-%m-%d %H:%M:%S") # 获取前一天日期 - 标准化
+
+def formatted2_previous_hour(h):
+ if h==0:
+ return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ start_of_current_hour = datetime.datetime.now().replace(minute=0, second=0, microsecond=0)
+ # 减去一个小时,得到前一个小时的开始时间
+ start_of_previous_hour = start_of_current_hour - datetime.timedelta(hours=h)
+ return start_of_previous_hour.strftime("%Y-%m-%d %H:%M:%S")
+
+def previous_hour_timestamp(h):
+ if h==0:
+ return int(time.time())
+ start_of_current_hour = datetime.datetime.now().replace(minute=0, second=0, microsecond=0)
+ # 减去一个小时,得到前一个小时的开始时间
+ start_of_previous_hour = start_of_current_hour - datetime.timedelta(hours=h)
+ return int(start_of_previous_hour.timestamp())
+
+#计算签名
+def generate_signature(str, private_key):
+ signature = hmac.new(private_key.encode(), (str).encode(), hashlib.sha1)
+ signature_b64 = base64.b64encode(signature.digest()).decode()
+ return signature_b64
+
+#构建查询链接
+def build_query_string(params):
+ # 使用OrderedDict来保持排序
+ sorted_params = OrderedDict(sorted(params.items()))
+
+ # 拼接属性名和属性值,并使用&连接
+ query_string = '&'.join('{}={}'.format(
+ urllib.parse.quote_plus(k),
+ urllib.parse.quote_plus(str(v))
+ ) for k, v in sorted_params.items())
+ return query_string
+
+
+#计算签名,get请求
+def request_data_signature_get():
+ print('开始请求数据...')
+ url='https://api-bj.clink.cn/ticket/get_ticket_detail'
+ param={'Timestamp':Timestamp,'Expires':'86400','id':'1','AccessKeyId':'b17759d3a36fba9a2cf522fbf4cbf177',}
+ print(f'param: {param}')
+ paramJson = {"Expires":"86400","id":"1"}
+ print(f'paramJson: {paramJson}')
+ url_path = build_query_string(param)
+ url_param = build_query_string(param)
+ print(f'url_param: {url_param}')
+ url_param = f'GETapi-bj.clink.cn/ticket/get_ticket_detail?{url_param}'
+ print(f'待计算字符串: {url_param}')
+ signature= generate_signature(url_param,'5g027B6w06630Y5240c1')
+ print(f'计算签名: {signature}')
+ print(f'编码后签名: {urllib.parse.quote_plus(signature)}')
+ url = f'{url}?{url_path}&Signature={urllib.parse.quote_plus(signature)}'
+ print(f'url: {url}')
+
+ dataReqL=requests.get(url,headers={},params={})
+ i = 0
+ while 'error' in dataReqL and i < 5:
+ time.sleep(1)
+ dataReqL=requests.get(url,headers={},params={})
+ i = i + 1
+ resL=json.loads(dataReqL.text)
+ return resL
+
+
+
+def load_data_to_db(dataList):
+ conn = psycopg2.connect(database="dataops_db", user="dbuser_dops", password="MIgTi3jA",host="172.17.0.8", port="5432")
+ print('数据库连接成功')
+ dataId=str(uuid.uuid4())
+ total=len(dataList)
+ print('临时id:'+dataId)
+ json_object = json.dumps(dataList)
+ cur=conn.cursor()
+ sql="update data_api.api_data set is_loaded = '1' where api_id = '6a977523d60f46788e6004549027bb8e';INSERT INTO data_api.api_data (id,api_id,data,total_num,is_loaded,status,request_tm,execute_tm,remark) values (%s,%s,%s,%s,'0','0',current_timestamp(0),current_timestamp(0),'')"
+ cur.execute(sql,[dataId,'6a977523d60f46788e6004549027bb8e', json_object, total])
+ conn.commit()
+ cur.close()
+ conn.close()
+ print('加载数据结束:tickets_detail:获取工单详情')
+
+
+
+if __name__ == "__main__":
+
+
+
+ resL = request_data_signature_get()
+ print(resL)
+
+ if 'error' in resL:
+ load_error_to_db(resl)
+ load_data_to_db(resL[''ticketDetail'])
\ No newline at end of file
diff --git a/dev/workflow/TK_Cust/smart_ccc/获取工单详情/tickets_detail_load.sql b/dev/workflow/TK_Cust/smart_ccc/获取工单详情/tickets_detail_load.sql
new file mode 100644
index 0000000..bbf39eb
--- /dev/null
+++ b/dev/workflow/TK_Cust/smart_ccc/获取工单详情/tickets_detail_load.sql
@@ -0,0 +1,126 @@
+/*******Main Section**************************************************************************/
+\set ON_ERROR_STOP on
+\set AUTOCOMMIT on
+\timing on
+
+DELETE FROM data_api.tr_ticket_detail;
+
+insert into data_api.tr_ticket_detail (
+ id
+ , workflow_id
+ , workflow_name
+ , workflow_category_id
+ , workflow_category_name
+ , topic
+ , level
+ , status
+ , state
+ , type
+ , creator_type
+ , creator_id
+ , creator_name
+ , modifier_type
+ , modifier_id
+ , modifier_name
+ , focus
+ , state_selected
+ , source
+ , end_time
+ , create_time
+ , update_time
+ , customer_id
+ , customer_name
+ , customer_tel
+ , tags
+ , comments
+ , start_form
+ , operation_logs
+ , operation_logs_new
+ , call_id
+ , close_time
+ , forms
+ , system_form
+ ,etl_tx_dt
+)
+select
+ case when trim(both from id)='' then null else id::text end id
+ , case when trim(both from workflow_id)='' then null else workflow_id::text end workflow_id
+ , case when trim(both from workflow_name)='' then null else workflow_name::text end workflow_name
+ , case when trim(both from workflow_category_id)='' then null else workflow_category_id::text end workflow_category_id
+ , case when trim(both from workflow_category_name)='' then null else workflow_category_name::text end workflow_category_name
+ , case when trim(both from topic)='' then null else topic::text end topic
+ , case when trim(both from level)='' then null else level::text end level
+ , case when trim(both from status)='' then null else status::text end status
+ , case when trim(both from state)='' then null else state::text end state
+ , case when trim(both from type)='' then null else type::text end type
+ , case when trim(both from creator_type)='' then null else creator_type::text end creator_type
+ , case when trim(both from creator_id)='' then null else creator_id::text end creator_id
+ , case when trim(both from creator_name)='' then null else creator_name::text end creator_name
+ , case when trim(both from modifier_type)='' then null else modifier_type::text end modifier_type
+ , case when trim(both from modifier_id)='' then null else modifier_id::text end modifier_id
+ , case when trim(both from modifier_name)='' then null else modifier_name::text end modifier_name
+ , case when trim(both from focus)='' then null else focus::text end focus
+ , case when trim(both from state_selected)='' then null else state_selected::text end state_selected
+ , case when trim(both from source)='' then null else source::text end source
+ , case when trim(both from end_time)='' then null else end_time::text end end_time
+ , case when trim(both from create_time)='' then null else create_time::text end create_time
+ , case when trim(both from update_time)='' then null else update_time::text end update_time
+ , case when trim(both from customer_id)='' then null else customer_id::text end customer_id
+ , case when trim(both from customer_name)='' then null else customer_name::text end customer_name
+ , case when trim(both from customer_tel)='' then null else customer_tel::text end customer_tel
+ , case when trim(both from tags)='' then null else tags::text end tags
+ , case when trim(both from comments)='' then null else comments::text end comments
+ , case when trim(both from start_form)='' then null else start_form::text end start_form
+ , case when trim(both from operation_logs)='' then null else operation_logs::text end operation_logs
+ , case when trim(both from operation_logs_new)='' then null else operation_logs_new::text end operation_logs_new
+ , case when trim(both from call_id)='' then null else call_id::text end call_id
+ , case when trim(both from close_time)='' then null else close_time::text end close_time
+ , case when trim(both from forms)='' then null else forms::text end forms
+ , case when trim(both from system_form)='' then null else system_form::text end system_form
+,etl_tx_dt
+from (
+select
+ (json_array_elements(data::json)::json->>'id') id
+ , (json_array_elements(data::json)::json->>'workflowId') workflow_id
+ , (json_array_elements(data::json)::json->>'workflowName') workflow_name
+ , (json_array_elements(data::json)::json->>'workflowCategoryId') workflow_category_id
+ , (json_array_elements(data::json)::json->>'workflowCategoryName') workflow_category_name
+ , (json_array_elements(data::json)::json->>'topic') topic
+ , (json_array_elements(data::json)::json->>'level') level
+ , (json_array_elements(data::json)::json->>'status') status
+ , (json_array_elements(data::json)::json->>'state') state
+ , (json_array_elements(data::json)::json->>'type') type
+ , (json_array_elements(data::json)::json->>'creatorType') creator_type
+ , (json_array_elements(data::json)::json->>'creatorId') creator_id
+ , (json_array_elements(data::json)::json->>'creatorName') creator_name
+ , (json_array_elements(data::json)::json->>'modifierType') modifier_type
+ , (json_array_elements(data::json)::json->>'modifierId') modifier_id
+ , (json_array_elements(data::json)::json->>'modifierName') modifier_name
+ , (json_array_elements(data::json)::json->>'focus') focus
+ , (json_array_elements(data::json)::json->>'stateSelected') state_selected
+ , (json_array_elements(data::json)::json->>'source') source
+ , (json_array_elements(data::json)::json->>'endTime') end_time
+ , (json_array_elements(data::json)::json->>'createTime') create_time
+ , (json_array_elements(data::json)::json->>'updateTime') update_time
+ , (json_array_elements(data::json)::json->>'customerId') customer_id
+ , (json_array_elements(data::json)::json->>'customerName') customer_name
+ , (json_array_elements(data::json)::json->>'customerTel') customer_tel
+ , (json_array_elements(data::json)::json->>'tags') tags
+ , (json_array_elements(data::json)::json->>'comments') comments
+ , (json_array_elements(data::json)::json->>'startForm') start_form
+ , (json_array_elements(data::json)::json->>'operationLogs') operation_logs
+ , (json_array_elements(data::json)::json->>'operationLogsNew') operation_logs_new
+ , (json_array_elements(data::json)::json->>'callId') call_id
+ , (json_array_elements(data::json)::json->>'closeTime') close_time
+ , (json_array_elements(data::json)::json->>'forms') forms
+ , (json_array_elements(data::json)::json->>'systemForm') system_form
+ ,CURRENT_TIMESTAMP(0) etl_tx_dt
+from (select * from data_api.api_data
+WHERE api_id='6a977523d60f46788e6004549027bb8e' and is_loaded = '0' order by request_tm desc limit 1) p )p;
+
+update data_api.api_data
+set is_loaded = '1' ,
+ status = '1',
+ request_tm = current_timestamp(0)
+where api_id='6a977523d60f46788e6004549027bb8e';
+\q
\ No newline at end of file