first commit

This commit is contained in:
2026-02-06 23:26:59 +08:00
parent 0f3f1467b8
commit 6cf8248b2d
34 changed files with 2348 additions and 0 deletions
+340
View File
@@ -0,0 +1,340 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_treedata(
IN p_type VARCHAR(20),
IN p_para01 VARCHAR(100)
)
/*
Function : 配合 amis 的 treeview, 取得 year-sprint 類的2階資料
目前的寫法只適用於固定2階, 如果階數不固定, 要找時間修改(bom 展開), 暫時不適用
擴充 @para, 目前是電子書專用, 如果有 @, @後的就是內文的全文檢索內容
Description: 可以用在 pbi, 會計科目等左方有 tree-view 的 UX, api 回傳用 6
新增 @type 參數
sprint 取得 year-sprint 資料(給 menu 使用)
basdepartment
acctitle 取得 類別-科目 資料(大部分都是用這個)
eipmxx.idno 避免 key 重複導致的錯誤
Build Date : 2021/10/19
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2021/11/26
2 Michael 2021/12/31 新增 on lone books
3 Michael 2022/04/14 新增 sys_aside_setup, aside 改為依設定即可產生 aside 相關 json 設定
4 Michael 2022/06/19 @type 加上 tag.type 以防止重複, tag 僅供識別用
5 Michael 2022/07/18 key-value 擴充能支援2層式的 tree(開發中)
6 Michael 2022/07/27 擴充 @para01 內容, 支援內文查詢過濾
7 Michael 2023/01/13 將 @para01 第一碼的 bookid 改為傳入 functag
8 Michael 2023/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_max INT;
DECLARE v_currid INT;
DECLARE v_groupid INT;
DECLARE v_next_groupid INT;
DECLARE v_datas LONGTEXT;
DECLARE v_footer VARCHAR(600);
DECLARE v_deptname VARCHAR(100);
DECLARE v_empname VARCHAR(100);
DECLARE v_personid VARCHAR(100);
DECLARE v_crlf VARCHAR(2);
DECLARE v_comm VARCHAR(1);
DECLARE v_aside_id VARCHAR(100);
DECLARE v_group_id VARCHAR(100);
DECLARE v_group_name VARCHAR(100);
DECLARE v_row_id VARCHAR(100);
DECLARE v_row_name VARCHAR(100);
DECLARE v_group_partitionby VARCHAR(100);
DECLARE v_group_orderby VARCHAR(100);
DECLARE v_row_orderby VARCHAR(100);
DECLARE v_filter_field VARCHAR(100);
DECLARE v_tablename VARCHAR(100);
DECLARE v_rel_tablename VARCHAR(100);
DECLARE v_g_partition1 VARCHAR(100);
DECLARE v_g_partition2 VARCHAR(100);
DECLARE v_filter_value VARCHAR(100);
DECLARE v_para01, v_para02 VARCHAR(100);
DECLARE v_pos INT;
DECLARE v_cnt INT;
DECLARE v_sql_cmd LONGTEXT;
DECLARE v_guid VARCHAR(100);
DECLARE v_where_keyvalue VARCHAR(100);
SET v_crlf = CONCAT(CHAR(10), CHAR(13));
-- 創建臨時表來存儲數據
DROP TEMPORARY TABLE IF EXISTS temp_data;
CREATE TEMPORARY TABLE temp_data (
xr_id VARCHAR(100),
x_id VARCHAR(100),
xr_name VARCHAR(100),
x_name VARCHAR(100),
groupid INT,
rowid INT
) ENGINE=MEMORY;
-- 取得相關設定參數
SELECT
aside_id,
group_id,
group_name,
row_id,
row_name,
group_partitionby,
group_orderby,
row_orderby,
filter_field,
tablename,
IFNULL(rel_tablename,''),
filter_value
INTO
v_aside_id,
v_group_id,
v_group_name,
v_row_id,
v_row_name,
v_group_partitionby,
v_group_orderby,
v_row_orderby,
v_filter_field,
v_tablename,
v_rel_tablename,
v_filter_value
FROM sys_aside_setup WHERE aside_id = p_type;
-- 防錯
IF IFNULL(v_group_orderby,'') = '' THEN
SET v_group_orderby = v_row_id;
END IF;
IF IFNULL(v_row_orderby,'') = '' THEN
SET v_row_orderby = v_row_id;
END IF;
-- 去除 p_type 中的 tag
SET v_pos = LOCATE('.', p_type);
IF v_pos > 0 THEN
SET p_type = SUBSTRING(p_type, v_pos+1);
END IF;
-- 生成 GUID
SET v_guid = REPLACE(UUID(), '-', '');
SET v_where_keyvalue = '';
-- 專門客製 for key-value
IF v_tablename = 'zen_keyvalue' THEN
-- 取得是否有 desc, 若有, 記錄起來
SELECT COUNT(*) INTO v_cnt FROM zen_keyvalue WHERE fieldname = p_type AND IFNULL(keydesc,'') <> '';
SET v_where_keyvalue = CONCAT(' AND fieldname = ', QUOTE(p_type));
END IF;
-- 行銷類的專案過濾(test ...)
IF IFNULL(v_filter_field,'') <> '' AND IFNULL(v_filter_value,'') <> '' THEN
SET v_where_keyvalue = CONCAT(' AND ', v_filter_field, ' = ', QUOTE(v_filter_value));
END IF;
SET v_sql_cmd = '';
-- 電子書有特殊語法, 其他都統一用法
IF p_type <> 'classid' THEN
-- 目前支持 p_type = sprintid 及 departmentid, 日後會隨 sys_aside_setup 的資料內容增加
SET v_g_partition1 = '';
SET v_g_partition2 = '';
IF IFNULL(v_group_partitionby,'') <> '' THEN
SET v_g_partition1 = CONCAT('PARTITION BY ', IF(v_rel_tablename = '', '', 'R.'), v_group_partitionby);
SET v_g_partition2 = CONCAT(IF(v_rel_tablename = '', '', CONCAT('R.', v_group_partitionby, ',')), '');
END IF;
IF v_rel_tablename = '' THEN
-- 如果 key-value 有設定 keydesc, 就展開成2層的 tree
IF v_cnt > 0 THEN
SET v_g_partition1 = 'PARTITION BY keydesc';
SET v_g_partition2 = 'keydesc,';
SET v_sql_cmd = CONCAT(
'INSERT INTO sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ',
'SELECT ', QUOTE(v_guid), ', ',
IF(v_group_id = '*', QUOTE(v_group_id), v_group_id), ', ', v_row_id, ', ',
IF(v_group_id = '*', QUOTE(v_group_name), v_group_name), ', ', v_row_name, ', ',
'ROW_NUMBER() OVER(', v_g_partition1, ' ORDER BY ', v_group_orderby, ') AS groupid, ',
'ROW_NUMBER() OVER(ORDER BY ', v_g_partition2, v_row_orderby, ') AS rowid ',
'FROM ', v_tablename, ' M ',
'WHERE IFNULL(', v_row_id, ', '''' ) <> ''''', v_where_keyvalue
);
ELSE
SET v_sql_cmd = CONCAT(
'INSERT INTO sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ',
'SELECT ', QUOTE(v_guid), ', ',
IF(v_group_id = '*', QUOTE(v_group_id), v_group_id), ', ', v_row_id, ', ',
IF(v_group_id = '*', QUOTE(v_group_name), v_group_name), ', ', v_row_name, ', ',
'ROW_NUMBER() OVER(', v_g_partition1, ' ORDER BY ', v_group_orderby, ') AS groupid, ',
'ROW_NUMBER() OVER(ORDER BY ', v_g_partition2, v_row_orderby, ') AS rowid ',
'FROM ', v_tablename, ' M ',
'WHERE IFNULL(', v_row_id, ', '''' ) <> ''''', v_where_keyvalue
);
END IF;
ELSE
-- 如果有 rel_tablename, 就一定要設定 group_partitionby
SET v_sql_cmd = CONCAT(
'INSERT INTO sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ',
'SELECT ', QUOTE(v_guid), ', ',
IF(v_group_id = '*', QUOTE(CONCAT('R.', v_group_id)), CONCAT('R.', v_group_id)), ', ', CONCAT('M.', v_row_id), ', ',
IF(v_group_id = '*', QUOTE(CONCAT('R.', v_group_name)), CONCAT('R.', v_group_name)), ', ', CONCAT('M.', v_row_name), ', ',
'ROW_NUMBER() OVER(', v_g_partition1, ' ORDER BY ', CONCAT('M.', v_group_orderby), ') AS groupid, ',
'ROW_NUMBER() OVER(ORDER BY ', v_g_partition2, CONCAT('M.', v_row_orderby), ') AS rowid ',
'FROM ', v_tablename, ' M ',
'LEFT JOIN ', v_rel_tablename, ' R ON M.', v_group_partitionby, ' = R.', v_group_partitionby, ' ',
'WHERE IFNULL(', CONCAT('M.', v_row_id), ', '''' ) <> ''''', v_where_keyvalue
);
END IF;
ELSE
-- 處理 p_para01/02
SET v_pos = LOCATE('@', p_para01);
SET v_para02 = '';
IF v_pos > 0 THEN
SET v_para02 = SUBSTRING(p_para01, v_pos+1, 100);
SET p_para01 = SUBSTRING(p_para01, 1, v_pos-1);
-- 將 p_para01 由 functag 改為 bookid
SELECT keyid INTO v_para01 FROM zen_keyvalue WHERE fieldname = 'book_mapping_id' AND keyvalue = p_para01;
IF IFNULL(v_para01, '') = '' THEN
SET v_para01 = '1';
END IF;
END IF;
-- 目前是專 for 電子書(p_type = 'classid')
IF IFNULL(v_group_partitionby, '') = '' THEN
SET v_sql_cmd = CONCAT(
'INSERT INTO sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ',
'SELECT ', QUOTE(v_guid), ', ',
'x.', v_group_id, ', x.', v_row_id, ', b.', v_group_name, ', x.', v_group_name, ', groupid, rowid', v_crlf,
'FROM (', v_crlf,
' SELECT ', v_group_id, ', ', v_row_id, ', ', v_group_name, ', ',
IF(v_group_name <> v_row_name, CONCAT(v_row_name, ', '), ''),
v_group_id, ' AS p_classid,', v_crlf,
' ROW_NUMBER() OVER(ORDER BY ', v_group_orderby, ') AS groupid,', v_crlf,
' ROW_NUMBER() OVER(ORDER BY ', v_row_orderby, ') AS rowid', v_crlf,
' FROM ', v_tablename, v_crlf,
' WHERE IFNULL(', v_group_id, ', '''' ) <> '''' AND ', v_filter_field, ' = ', v_para01, v_crlf,
IF(v_para02 <> '', CONCAT(' AND book_desc LIKE ', QUOTE(CONCAT('%', v_para02, '%')), v_crlf), ''),
') x', v_crlf,
'LEFT JOIN ', v_tablename, ' b ON x.p_classid = b.', v_row_id, ' AND ', v_filter_field, ' = ', v_para01
);
ELSE
SET v_sql_cmd = CONCAT(
'INSERT INTO sys_aside_temp (aside_guid, xr_id, x_id, xr_name, x_name, groupid, rowid) ',
'SELECT ', QUOTE(v_guid), ', ',
'x.', v_group_id, ', x.', v_row_id, ', b.', v_group_name, ', x.', v_group_name, ', groupid, rowid', v_crlf,
'FROM (', v_crlf,
' SELECT ', v_group_id, ', ', v_row_id, ', ', v_group_name, ', ',
IF(v_group_name <> v_row_name, CONCAT(v_row_name, ', '), ''),
v_group_id, ' AS p_classid,', v_crlf,
' ROW_NUMBER() OVER(PARTITION BY ', v_group_partitionby, ' ORDER BY ', v_group_orderby, ') AS groupid,', v_crlf,
' ROW_NUMBER() OVER(ORDER BY ', v_row_orderby, ') AS rowid', v_crlf,
' FROM ', v_tablename, v_crlf,
' WHERE IFNULL(', v_group_id, ', '''' ) <> '''' AND ', v_filter_field, ' = ', v_para01, v_crlf,
IF(v_para02 <> '', CONCAT(' AND book_desc LIKE ', QUOTE(CONCAT('%', v_para02, '%')), v_crlf), ''),
') x', v_crlf,
'LEFT JOIN ', v_tablename, ' b ON x.p_classid = b.', v_row_id, ' AND ', v_filter_field, ' = ', v_para01
);
END IF;
END IF;
-- 執行動態SQL
SET @sql = v_sql_cmd;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 將資料寫入臨時表
INSERT INTO temp_data
SELECT xr_id, x_id, xr_name, x_name, groupid, rowid
FROM sys_aside_temp
WHERE aside_guid = v_guid;
DELETE FROM sys_aside_temp WHERE aside_guid = v_guid;
/* 開始 main loop */
SELECT COUNT(*) INTO v_max FROM temp_data;
SELECT MIN(rowid) INTO v_currid FROM temp_data;
SET v_datas = '';
SET v_comm = '';
WHILE v_currid <= v_max DO
-- get data
SELECT
groupid, xr_name, x_id, x_name
INTO
v_groupid, v_deptname, v_personid, v_empname
FROM temp_data
WHERE rowid = v_currid;
IF v_currid = v_max THEN
SET v_comm = '';
ELSE
SELECT groupid INTO v_next_groupid FROM temp_data WHERE rowid = v_currid + 1;
IF v_next_groupid = 1 THEN
SET v_comm = '';
ELSE
SET v_comm = ',';
END IF;
END IF;
IF v_groupid = 1 THEN
IF v_currid > 1 THEN
SET v_footer = CONCAT(
' ]', v_crlf,
' },', v_crlf
);
ELSE
SET v_footer = '';
END IF;
SET v_datas = CONCAT(
v_datas, v_footer,
' {', v_crlf,
' "label": "', v_deptname, '",', v_crlf,
' "children": [', v_crlf,
' {', v_crlf,
' "label": "', v_empname, '",', v_crlf,
' "value": "', v_personid, '"', v_crlf,
' }', v_comm, v_crlf
);
ELSE
SET v_datas = CONCAT(
v_datas,
' {', v_crlf,
' "label": "', v_empname, '",', v_crlf,
' "value": "', v_personid, '"', v_crlf,
' }', v_comm, v_crlf
);
END IF;
SET v_currid = v_currid + 1;
END WHILE;
SET v_datas = CONCAT(
' [', v_crlf,
v_datas,
' ]', v_crlf,
' }', v_crlf,
' ]'
);
-- 返回結果
SELECT 0 AS code, 'ok' AS msg;
SELECT v_datas AS jsoncode;
-- 清理臨時表
DROP TEMPORARY TABLE IF EXISTS temp_data;
END //
DELIMITER ;