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
+99
View File
@@ -0,0 +1,99 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE eip_Calendar_crud (
IN p_functiontag VARCHAR(100),
IN p_id VARCHAR(100),
IN p_title NVARCHAR(100),
IN p_start_time VARCHAR(30),
IN p_end_time VARCHAR(30),
IN p_userid VARCHAR(20)
)
/*
Function : 行事曆資料的新增及修改, 並考慮雲端時間差問題
Description: 使用 Vue+FullCalendar 開發行事曆, 並用 iFrame 崁入 amis 環境
編輯行事曆: eip_Calendar_crud (本 sp)
讀取行事曆: eip_getCalendar
刪除行事曆: eip_Calendar_delete
原本是傳入 tablename, 目前統一都改傳入 functiontag, 擴充彈性較大(盡量不動 Vue+FullCalendar)
Build Date : 2023/07/19 (轉換為 MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2024/03/11 傳入參數由 tablename 改為 functiontag
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_adjusted_start DATETIME;
DECLARE v_adjusted_end DATETIME;
-- 調整雲端時間 (假設 cloud_adjusttime 函數已存在)
-- SET v_adjusted_start = cloud_adjusttime(p_start_time, 1);
-- SET v_adjusted_end = cloud_adjusttime(p_end_time, 1);
-- Michael 2025-11-21
SET v_adjusted_start = STR_TO_DATE( REPLACE(REPLACE(p_start_time, 'T', ' '), '.000Z', ''), '%Y-%m-%d %H:%i:%s');
SET v_adjusted_end = STR_TO_DATE( REPLACE(REPLACE(p_end_time, 'T', ' '), '.000Z', ''), '%Y-%m-%d %H:%i:%s');
-- 根據不同的 functiontag 處理不同的表
CASE p_functiontag
WHEN 'eipm15' THEN -- 會議室預約
UPDATE eipplace_fc SET
response_desc = p_title,
startdate = DATE(v_adjusted_start),
starttime = TIME(v_adjusted_start),
end_date = DATE(v_adjusted_end),
endtime = TIME(v_adjusted_end)
WHERE uniqueno = p_id;
WHEN 'eipm13' THEN -- 會議通知
UPDATE eipmeetingrec_m SET
meeting_title = p_title,
startdate = DATE(v_adjusted_start),
starttime = TIME(v_adjusted_start),
end_date = DATE(v_adjusted_end),
end_time = TIME(v_adjusted_end)
WHERE uniqueno = p_id;
WHEN 'eipm02' THEN -- 行程管理
UPDATE eip_new_calendar SET
title = p_title,
start_time = v_adjusted_start,
end_time = v_adjusted_end,
s_date = DATE(v_adjusted_start),
s_time = TIME_FORMAT(v_adjusted_start, '%H:%i'),
e_date = DATE(v_adjusted_end),
e_time = TIME_FORMAT(v_adjusted_end, '%H:%i')
WHERE uuid = p_id;
ELSE -- 默認處理 eip_core_calendar
IF p_id = '-1' AND p_userid IS NOT NULL AND p_userid != '' THEN
-- 新增記錄
INSERT INTO eip_core_calendar (
title, start_time, end_time, personid,
s_date, s_time, e_date, e_time
) VALUES (
p_title, v_adjusted_start, v_adjusted_end, p_userid,
DATE(v_adjusted_start),
TIME_FORMAT(v_adjusted_start, '%H:%i'),
DATE(v_adjusted_end),
TIME_FORMAT(v_adjusted_end, '%H:%i')
);
ELSE
-- 更新記錄
UPDATE eip_core_calendar SET
title = p_title,
start_time = v_adjusted_start,
end_time = v_adjusted_end,
s_date = DATE(v_adjusted_start),
s_time = TIME_FORMAT(v_adjusted_start, '%H:%i'),
e_date = DATE(v_adjusted_end),
e_time = TIME_FORMAT(v_adjusted_end, '%H:%i')
WHERE id = p_id;
END IF;
END CASE;
-- 返回成功結果
SELECT 0 AS code, 'ok' AS msg;
END //
DELIMITER ;
+42
View File
@@ -0,0 +1,42 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE eip_Calendar_delete (
IN p_functiontag VARCHAR(100),
IN p_id VARCHAR(100)
)
/*
Function : 行事曆資料的刪除功能
Description: 使用 Vue+FullCalendar 開發行事曆, 並用 iFrame 崁入 amis 環境
編輯行事曆: eip_Calendar_crud
讀取行事曆: eip_getCalendar
刪除行事曆: eip_Calendar_delete (本 sp)
傳入參數使用 functiontag 以保持彈性
Build Date : 2023/07/19 (MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2024/03/11 傳入參數由 tablename 改為 functiontag
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- 根據不同的 functiontag 刪除不同的表記錄
CASE p_functiontag
WHEN 'eipm15' THEN -- 會議室預約
DELETE FROM eipplace_fc WHERE uniqueno = p_id;
WHEN 'eipm13' THEN -- 會議通知
DELETE FROM eipmeetingrec_m WHERE uniqueno = p_id;
WHEN 'eipm02' THEN -- 行程管理
DELETE FROM eip_new_calendar WHERE uuid = p_id;
ELSE -- 默認處理 eip_core_calendar
DELETE FROM eip_core_calendar WHERE id = p_id;
END CASE;
-- 返回成功結果
SELECT 0 AS code, 'ok' AS msg;
END //
DELIMITER ;
+113
View File
@@ -0,0 +1,113 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE eip_getCalendar (
IN p_functiontag VARCHAR(100),
IN p_userid VARCHAR(20),
IN p_start VARCHAR(30),
IN p_end VARCHAR(30)
)
/*
Function : 取得行事曆資料, 並考慮雲端時間差問題
Description: 使用 FullCalendar + Cloud 主機時的時間差處理方案
a. 在 FullCalendar+Vue 程式中使用 local 時間而非 UTC
b. Cloud Server 使用 UTC 時間,需進行時間調整
c. 使用 cloud_addtime 函數調整時間差 (目前設為減8小時)
Build Date : 2023/07/19 (MariaDB 版本)
call eip_getcalendar('eipm02','admin','2023-12-31T16:00:00.000Z','2026-12-30T16:00:00.000Z');
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/12/14 加入考慮 Azure 的時間差
2 Michael 2022/12/23 加入 FullCalendar 相關註解說明
3 Michael 2024/03/11 傳入參數由 tablename 改為 functiontag
4 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- 處理一下日期
SET p_start = STR_TO_DATE(p_start, '%Y-%m-%dT%H:%i:%s.000Z');
SET p_end = STR_TO_DATE(p_end, '%Y-%m-%dT%H:%i:%s.000Z');
-- 創建臨時表存儲結果
DROP TEMPORARY TABLE IF EXISTS tmp_calendar;
CREATE TEMPORARY TABLE tmp_calendar (
id VARCHAR(100),
title NVARCHAR(100),
start DATETIME,
end DATETIME,
create_at VARCHAR(20)
);
-- 根據不同的 functiontag 查詢不同的表
CASE p_functiontag
WHEN 'eipm15' THEN -- 會議室預約
INSERT INTO tmp_calendar
SELECT
uniqueno,
response_desc,
CONCAT(startdate, ' ', starttime),
CONCAT(end_date, ' ', endtime),
personid
FROM eipplace_fc
WHERE DATE(startdate) >= DATE(p_start)
AND DATE(end_date) <= DATE(p_end)
AND (personid = p_userid OR create_user = p_userid OR update_user = p_userid);
WHEN 'eipm13' THEN -- 會議通知
INSERT INTO tmp_calendar
SELECT
uniqueno,
meeting_title,
CONCAT(startdate, ' ', starttime),
CONCAT(end_date, ' ', end_time),
boss_personid
FROM eipmeetingrec_m
WHERE DATE(startdate) >= DATE(p_start)
AND DATE(end_date) <= DATE(p_end)
AND (boss_personid = p_userid OR create_user = p_userid OR update_user = p_userid);
WHEN 'eipm02' THEN -- 行程管理
INSERT INTO tmp_calendar
SELECT
uuid,
title,
start_time,
end_time,
personid
FROM eip_new_calendar
WHERE DATE(start_time) >= DATE(p_start)
AND DATE(end_time) <= DATE(p_end)
AND (create_user = p_userid OR personid = p_userid);
ELSE -- 默認處理 eip_core_calendar
INSERT INTO tmp_calendar
SELECT
id,
title,
start_time,
end_time,
personid
FROM eip_core_calendar
WHERE start_time >= p_start
AND end_time <= p_end
AND personid = p_userid;
END CASE;
-- dataset 0(因為只回傳 dataset = 1 一直會報錯 20251120
select 0, 'ok' as msg;
-- 處理雲端時間差並返回結果
SELECT
id,
title,
-- cloud_addtime(start) AS start,
start,
-- cloud_addtime(end) AS end,
end,
create_at
FROM tmp_calendar;
-- 自動清理臨時表 (MariaDB 會話結束時自動刪除)
END //
DELIMITER ;
+34
View File
@@ -0,0 +1,34 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_Schedule(
IN p_userid VARCHAR(100),
IN p_yearmonth VARCHAR(6)
)
/*
Function : 配合 amis 的 行事曆(簡易版), 取得 Schedule 資料
目前的寫法有問題, 沒有加入任何過濾條件, 且元件本身還在修改中, 先簡單展示用
Description:
Build Date : 2022/1/1
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/1/1
2 Michael 2022/10/10 改為 eip_core_calendar
3 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- 设置默认返回值
SELECT 0 AS code, 'ok' AS msg;
-- 查询日程数据
SELECT
DATE_FORMAT(start_time, '%Y-%m-%d %H:%i:%s') AS startTime,
DATE_FORMAT(end_time, '%Y-%m-%d %H:%i:%s') AS endTime,
title AS content
FROM eip_core_calendar
WHERE personid = p_userid
AND DATE_FORMAT(start_time, '%Y%m') = p_yearmonth;
END //
DELIMITER ;
+43
View File
@@ -0,0 +1,43 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_anytable(
IN p_token VARCHAR(100),
IN p_tablename VARCHAR(20)
)
/*
萬用取值程式, 主要給 amis picker GET 查詢使用
Description: 根據傳入的 token 驗證使用者身份後,返回指定表的數據
Build Date : 2023/07/19 (MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_userid VARCHAR(100);
DECLARE v_sql TEXT;
-- 根據傳入的 token 取得 userid
SELECT userid INTO v_userid FROM sys_users WHERE token = p_token LIMIT 1;
-- 設置默認返回值
SELECT 0 AS code, 'ok' AS msg;
-- 構建動態SQL
IF v_userid IS NULL OR v_userid = '' THEN
-- 無效token時返回空結果
SET v_sql = CONCAT('SELECT * FROM ', p_tablename, ' WHERE 1=0');
ELSE
-- 有效token時返回完整數據
SET v_sql = CONCAT('SELECT * FROM ', p_tablename);
END IF;
-- 執行動態SQL
SET @dynamic_sql = v_sql;
PREPARE stmt FROM @dynamic_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+59
View File
@@ -0,0 +1,59 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_assignData (
-- p_bookid int = 1,
IN p_funcTag VARCHAR(100),
IN p_classid VARCHAR(100)
)
/*
Function : 配合 amis 取得 markdown(電子書, FAQ 等) 要顯示的資料
目前專用於電子書, 應該會繼續擴充
get_treedata 應一併修改, 原程式都是傳入 bookid, 改傳入 tag, 但為了增加彈性, 將 tag 和 bookid 的對照, 新增到 zen_keyvalue(book_mapping_id)
Description: 電子書應該要支援多本的架構, 目前寫死一本 on line help, 應想辦法擴充(至少加入 FAQ 吧)
Build Date : 2021/10/19
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2021/11/26
2 Michael 2022/04/04 改為電子書專用(修改 r43 電子書查閱)
3 Michael 2023/01/13 修改第一個參數為 funcTag, 再參考 zen_keyvalue 轉為 bookid
*/
BEGIN
DECLARE v_bookid VARCHAR(10);
-- 回傳初始結果
SELECT 0 AS code, 'ok' AS msg;
/*
補初始資料 (ls:now_code)
INSERT INTO zen_keyvalue (tablename,fieldname,keyid,keyvalue) VALUES ('xxxx','book_mapping_id','1','eipr43');
INSERT INTO zen_keyvalue (tablename,fieldname,keyid,keyvalue) VALUES ('xxxx','book_mapping_id','2','eipr44');
INSERT INTO zen_keyvalue (tablename,fieldname,keyid,keyvalue) VALUES ('xxxx','book_mapping_id','4','eipr45');
*/
-- 將 tag 改為 bookid(進行中)
IF LENGTH(p_funcTag) <= 3 THEN
-- 如果傳 functag 舊版是傳 bookid(blog.gex.com.tw 舊寫法)
SET v_bookid = p_funcTag;
ELSE
SELECT keyid INTO v_bookid FROM zen_keyvalue
WHERE fieldname = 'book_mapping_id' AND keyvalue = p_funcTag LIMIT 1;
END IF;
IF IFNULL(v_bookid, '') = '' THEN
SET v_bookid = '1';
END IF;
IF IFNULL(p_classid, '') = '' THEN
SELECT classid INTO p_classid FROM eip_online_books
WHERE bookid = v_bookid order by bookid LIMIT 1;
END IF;
-- 取回指定電子書的指定章節內容回傳
SELECT book_desc AS xValue FROM eip_online_books
WHERE bookid = v_bookid AND classid = p_classid;
END //
DELIMITER ;
+73
View File
@@ -0,0 +1,73 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_div_issue_data(
IN p_div_type VARCHAR(1), -- a->e
IN p_token VARCHAR(100)
)
/*
Function : 獲取問題分配資料
Description: 根據使用者token和問題類型返回不同分類的問題資料
取得指定 div 的資料, 目前分為
A*分配給我的(尚未解決)
B*尚未分配
C*我回報尚未解決
D*我回報且已解決
E*被我解決的(30日內)
Build Date : 2023/07/19 (MariaDB 版本)
*/
BEGIN
DECLARE v_userid VARCHAR(100);
DECLARE v_err_code SMALLINT;
DECLARE v_err_msg VARCHAR(100);
-- 初始化變數
SET v_err_code = 0;
SET v_err_msg = 'ok';
-- 根據token獲取userid
SELECT userid INTO v_userid FROM sys_users WHERE token = p_token LIMIT 1;
IF v_userid IS NULL OR v_userid = '' THEN
SET v_err_code = 4;
SET v_err_msg = '原密碼輸入錯誤, 請重新輸入';
SELECT v_err_code AS code, v_err_msg AS msg;
ELSE
SELECT v_err_code AS code, v_err_msg AS msg;
-- 根據不同類型返回不同資料
CASE UPPER(p_div_type)
WHEN 'A' THEN
-- 分配給我的(未解決)
SELECT * FROM v_div_issue l
WHERE l.responsible = v_userid
AND (l.issue_status <> '2' AND l.issue_status <> '8');
WHEN 'B' THEN
-- 尚未分配
SELECT * FROM v_div_issue l
WHERE IFNULL(l.responsible, '') = '';
WHEN 'C' THEN
-- 由我回報的(未解決)
SELECT * FROM v_div_issue l
WHERE l.raised_by = v_userid
AND (l.issue_status <> '2' AND l.issue_status <> '8');
WHEN 'D' THEN
-- 我回報且已解決
SELECT * FROM v_div_issue l
WHERE l.raised_by = v_userid
AND (l.issue_status = '2' OR l.issue_status = '8');
ELSE
-- 被我解決的(30日內)
SELECT * FROM v_div_issue l
WHERE l.responsible = v_userid
AND (l.issue_status = '2' OR l.issue_status = '8')
AND DATEDIFF(CURDATE(), finish_date) <= 30;
END CASE;
END IF;
END //
DELIMITER ;
+87
View File
@@ -0,0 +1,87 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_gantt_data(
IN p_projectid VARCHAR(100)
)
/*
Function : 配合 amis 的擴充元件(gantt), 取得甘特圖資料
Description: 獲取專案甘特圖資料,處理雲伺服器時間差問題
Build Date : 2023/07/19 (MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/7/31 初始版本
2 Michael 2022/12/14 加入 Azure 雲端時間差處理
3 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- 聲明變數
DECLARE v_year1 INT;
DECLARE v_start_date VARCHAR(10);
-- 設置默認起始日(去年1月1日)
SET v_year1 = YEAR(CURDATE()) - 1;
SET v_start_date = CONCAT(v_year1, '-01-01');
-- 創建臨時表存儲結果
DROP TEMPORARY TABLE IF EXISTS tmp_gantt_data;
CREATE TEMPORARY TABLE tmp_gantt_data (
id VARCHAR(100),
name VARCHAR(255),
ower VARCHAR(100),
per DECIMAL(5,2),
type TINYINT,
startTime DATE,
endTime DATE,
stoneTime DATE,
top INT,
`left` INT,
widthChild INT,
widthMe INT,
isShow TINYINT,
ROW_ID INT
);
-- 獲取專案PBI資料
INSERT INTO tmp_gantt_data
SELECT
pbiid AS id,
pbi_title AS name, -- 項目名稱
owner AS ower, -- 負責人
pbi_rate AS per, -- 進度(完成率)
1 AS type, -- 項目類型(1.PBI 2.mile stone 3.分組)
startdate AS startTime,
DATE_ADD(startdate, INTERVAL CAST(pbi_planworktime AS SIGNED) DAY) AS endTime,
'2022-01-01' AS stoneTime, -- 里程碑日
0 AS top, -- 初始top位置
DATEDIFF(startdate, v_start_date) * 40 AS `left`,
CAST(pbi_planworktime AS SIGNED) * 40 AS widthChild,
CAST(pbi_planworktime AS SIGNED) * 40 AS widthMe,
1 AS isShow,
@row_num := @row_num + 1 AS ROW_ID
FROM pms_pbi, (SELECT @row_num := 0) AS r
WHERE projectid = p_projectid
ORDER BY pbiid ASC;
-- 處理雲端時間差並返回結果
SELECT
id,
name,
ower,
per,
type,
cloud_addtime(startTime) AS startTime,
cloud_addtime(endTime) AS endTime,
cloud_addtime(stoneTime) AS stoneTime,
((ROW_ID-1) * 40) + 15 AS top,
`left`,
widthChild,
widthMe,
isShow
FROM tmp_gantt_data;
-- 臨時表會在會話結束時自動刪除
END //
DELIMITER ;
+51
View File
@@ -0,0 +1,51 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_keyvalue(
IN p_tablename VARCHAR(20),
IN p_fieldname VARCHAR(20)
)
/*
Function : 配合 amis 的 select 元件,取得 key-value 資料
Description: 從 zen_keyvalue 表獲取鍵值對資料,用於下拉選項
合併了原有的 zen_keyvalue 和 sys_keyvalue 表功能
Build Date : 2023/07/19 (MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/05/28 初始版本
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_count INT;
-- 設置默認返回值
SELECT 0 AS code, 'ok' AS msg;
-- 檢查指定表名和欄位名的記錄是否存在
SELECT COUNT(*) INTO v_count
FROM zen_keyvalue
WHERE tablename = p_tablename
AND fieldname = p_fieldname;
-- 根據查詢結果返回資料
IF v_count > 0 THEN
-- 返回指定表名和欄位名的鍵值對
SELECT
keyid AS `value`,
keyvalue AS `label`
FROM zen_keyvalue
WHERE tablename = p_tablename
AND fieldname = p_fieldname;
ELSE
-- 返回默認欄位名的鍵值對
SELECT
keyid AS `value`,
keyvalue AS `label`
FROM zen_keyvalue
WHERE tablename = 'xxxx'
AND fieldname = p_fieldname;
END IF;
END //
DELIMITER ;
+37
View File
@@ -0,0 +1,37 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_meeting_used(
IN p_idno VARCHAR(100)
)
/*
Function : 配合 amis 的行事曆(簡易版), 顯示會議室當前登記狀況
Description: 查詢指定會議室在前後90天內的預定使用情況
Build Date : 2023/07/19 (MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/7/29 初始版本
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- 設置默認返回值
SELECT 0 AS code, 'ok' AS msg;
-- 查詢會議室使用情況(當前日期前後90天內)
SELECT
CONCAT(startdate, ' ', starttime) AS startTime,
CONCAT(end_date, ' ', endtime) AS endTime,
response_desc AS content
FROM eipplace_fc
WHERE idno = p_idno
AND (
(DATE(startdate) >= DATE_SUB(CURDATE(), INTERVAL 90 DAY)
AND DATE(startdate) <= DATE_ADD(CURDATE(), INTERVAL 90 DAY))
OR
(DATE(end_date) >= DATE_SUB(CURDATE(), INTERVAL 90 DAY)
AND DATE(end_date) <= DATE_ADD(CURDATE(), INTERVAL 90 DAY))
);
END //
DELIMITER ;
+140
View File
@@ -0,0 +1,140 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_orgstructure(
IN p_type VARCHAR(20) -- 'person'/'user'/'role'
)
/*
Function : 配合 amis 的 transfer, 取得組織結構資料
Description: 用於選擇會議人員等表單
person - 獲取部門-人員資料(最常用)
user - 獲取角色-使用者資料(功能表使用)
role - 獲取角色資料
Build Date : 2023/07/19 (MariaDB 版本)
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2021/10/19 初始版本
2 Michael 2021/10/21 新增 type 參數
3 Developer 2023/07/19 轉換為 MariaDB 版本並優化
*/
BEGIN
DECLARE v_max INT;
DECLARE v_curr_id INT;
DECLARE v_group_id INT;
DECLARE v_next_group_id INT;
DECLARE v_json_data TEXT;
DECLARE v_footer TEXT;
DECLARE v_dept_name VARCHAR(100);
DECLARE v_emp_name VARCHAR(100);
DECLARE v_person_id VARCHAR(100);
DECLARE v_comm VARCHAR(1);
-- 創建臨時表存儲中間資料
DROP TEMPORARY TABLE IF EXISTS temp_org_data;
CREATE TEMPORARY TABLE temp_org_data (
xr_id VARCHAR(100),
x_id VARCHAR(100),
xr_name VARCHAR(100),
x_name VARCHAR(100),
group_id INT,
row_id INT
);
-- 根據類型插入資料
IF p_type = 'role' THEN
INSERT INTO temp_org_data (xr_id, x_id, xr_name, x_name, group_id, row_id)
SELECT
'*', roleid, '(全部角色)', CONCAT('(', roleid, ') ', rolename),
@rownum := @rownum + 1,
@rownum
FROM sys_roles, (SELECT @rownum := 0) r
WHERE roleid IS NOT NULL AND roleid <> ''
ORDER BY roleid;
ELSEIF p_type = 'user' THEN
INSERT INTO temp_org_data (xr_id, x_id, xr_name, x_name, group_id, row_id)
SELECT
'*', userid, '(全部使用者)', CONCAT('(', userid, ') ', username),
@rownum := @rownum + 1,
@rownum
FROM sys_users, (SELECT @rownum := 0) r
WHERE userid IS NOT NULL AND userid <> ''
ORDER BY userid;
ELSE -- 預設獲取部門-人員資料
INSERT INTO temp_org_data (xr_id, x_id, xr_name, x_name, group_id, row_id)
SELECT
bp.departmentid, bp.personid,
CONCAT('(', bp.departmentid, ') ', bm.departmentcname),
CONCAT('(', bp.personid, ') ', bp.personcname),
IF(@dept = bp.departmentid, @group, @group := @group + 1),
@rownum := @rownum + 1
FROM
(SELECT @rownum := 0, @group := 0, @dept := '') r,
basperson bp
LEFT JOIN basdepartment bm ON bp.departmentid = bm.departmentid
WHERE bp.departmentid IS NOT NULL AND bp.departmentid <> ''
ORDER BY bp.departmentid, bp.personid;
END IF;
-- 準備生成JSON資料
SELECT COUNT(*) INTO v_max FROM temp_org_data;
SELECT MIN(row_id) INTO v_curr_id FROM temp_org_data;
SET v_json_data = '';
SET v_comm = '';
-- 使用GROUP_CONCAT簡化JSON構建過程
SELECT
CONCAT(
'[',
GROUP_CONCAT(
IF(
group_id = 1 AND row_id > 1,
CONCAT(
' },\n',
' {\n',
' "label": "', xr_name, '",\n',
' "children": [\n',
' {\n',
' "label": "', x_name, '",\n',
' "value": "', x_id, '"\n',
' }', IF(row_id = v_max, '', ',')
),
IF(
group_id = 1,
CONCAT(
' {\n',
' "label": "', xr_name, '",\n',
' "children": [\n',
' {\n',
' "label": "', x_name, '",\n',
' "value": "', x_id, '"\n',
' }', IF(row_id = v_max, '', ',')
),
CONCAT(
' {\n',
' "label": "', x_name, '",\n',
' "value": "', x_id, '"\n',
' }', IF(row_id = v_max, '', ',')
)
)
)
ORDER BY row_id
SEPARATOR '\n'
),
'\n ]\n',
' }\n',
' ]'
) INTO v_json_data
FROM temp_org_data;
-- 返回結果
SELECT 0 AS code, 'ok' AS msg;
SELECT v_json_data AS jsoncode;
-- 臨時表會在會話結束時自動刪除
END //
DELIMITER ;
+30
View File
@@ -0,0 +1,30 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_parameter(
IN p_sys_id VARCHAR(10)
)
/*
Function : 讀取 sys_parameter 所有的參數值, logon 後存到 localStorage
Description:
Build Date : 2022/05/04
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/05/04
2 Michael 2023/07/08 新增 @sys_id 參數(* 表示全部)
3 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- 设置默认返回值
SELECT 0 AS code, 'ok' AS msg;
-- 查询参数数据
IF p_sys_id = '*' OR p_sys_id IS NULL OR p_sys_id = '' THEN
SELECT * FROM sys_parameter;
ELSE
SELECT * FROM sys_parameter WHERE systemid = p_sys_id;
END IF;
END //
DELIMITER ;
+99
View File
@@ -0,0 +1,99 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE get_tableschema(
IN p_data NVARCHAR(100)
)
/*
Function : 查詢檔案結構
description:
build date : 2023/08/23
Modify history
item who date modify docs
==== ========== ========== ================================================
1 Michael 2023/08/23
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
3 Assistant 2025/08/09 加入自動從information_schema讀取結構功能
*/
BEGIN
DECLARE v_count INT;
-- 檢查gex_filestru是否有資料
SELECT COUNT(*) INTO v_count FROM gex_filestru;
-- 如果沒資料, 就從information_schema讀取並寫入
IF v_count = 0 THEN
-- 先清空表(以防萬一)
TRUNCATE TABLE gex_filestru;
-- 從information_schema讀取所有表結構並插入到gex_filestru
INSERT INTO gex_filestru (
Table_name, table_description, seqno, field_name, field_desc,
field_type, field_len, field_dec, table_pk, table_index,
field_isnull, field_default
)
SELECT
t.TABLE_NAME AS Table_name,
'' AS table_description, -- 初始為空,可手動補充
c.ORDINAL_POSITION AS seqno,
c.COLUMN_NAME AS field_name,
'' AS field_desc, -- 初始為空,可手動補充
c.DATA_TYPE AS field_type,
-- c.CHARACTER_MAXIMUM_LENGTH AS field_len,
case when c.CHARACTER_MAXIMUM_LENGTH > 9999 then 9999 else c.CHARACTER_MAXIMUM_LENGTH end AS field_len,
c.NUMERIC_SCALE AS field_dec,
IF(kcu.COLUMN_NAME IS NOT NULL, 'Y', 'N') AS table_pk,
'N' AS table_index, -- 初始為N,可根據實際索引調整
IF(c.IS_NULLABLE = 'YES', 'Y', 'N') AS field_isnull,
c.COLUMN_DEFAULT AS field_default
FROM
information_schema.TABLES t
JOIN information_schema.COLUMNS c ON t.TABLE_NAME = c.TABLE_NAME AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
LEFT JOIN information_schema.KEY_COLUMN_USAGE kcu ON
c.TABLE_NAME = kcu.TABLE_NAME AND
c.COLUMN_NAME = kcu.COLUMN_NAME AND
c.TABLE_SCHEMA = kcu.TABLE_SCHEMA AND
kcu.CONSTRAINT_NAME = 'PRIMARY'
WHERE
t.TABLE_SCHEMA = DATABASE() AND
t.TABLE_TYPE = 'BASE TABLE';
-- 更新表描述為表注釋(如果有)
UPDATE gex_filestru f
JOIN information_schema.TABLES t ON f.Table_name = t.TABLE_NAME
SET f.table_description = t.TABLE_COMMENT
WHERE t.TABLE_SCHEMA = DATABASE();
-- 更新字段描述為列注釋(如果有)
UPDATE gex_filestru f
JOIN information_schema.COLUMNS c ON f.Table_name = c.TABLE_NAME AND f.field_name = c.COLUMN_NAME
SET f.field_desc = c.COLUMN_COMMENT
WHERE c.TABLE_SCHEMA = DATABASE();
END IF;
-- 设置默认返回值
SELECT 0 AS code, 'ok' AS msg;
-- 查询表结构
IF p_data = '*' THEN
SELECT
Table_name, table_description, seqno, field_name, field_desc,
field_type, field_len, field_dec, table_pk, table_index,
field_isnull, field_default
FROM gex_filestru
ORDER BY table_name, seqno;
ELSE
SELECT
Table_name, table_description, seqno, field_name, field_desc,
field_type, field_len, field_dec, table_pk, table_index,
field_isnull, field_default
FROM gex_filestru
WHERE table_name LIKE CONCAT('%', p_data, '%')
OR table_description LIKE CONCAT('%', p_data, '%')
OR field_name LIKE CONCAT('%', p_data, '%')
OR field_desc LIKE CONCAT('%', p_data, '%')
ORDER BY table_name, seqno;
END IF;
END //
DELIMITER ;
+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 ;
+57
View File
@@ -0,0 +1,57 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE gex_chart_comm(
IN p_functiontag VARCHAR(20), -- 程式代號(可以自行控制讀取的資料來源)
IN p_date1 VARCHAR(10),
IN p_date2 VARCHAR(10),
IN p_type VARCHAR(20) -- bar/line/pie ...
)
/*
function : 客戶訂單業績排行前 10 的統計圖, 支援 5種圖形顯示, 這是 amis chart 類的報表的標準寫法
description: 將一般報表, 轉為 amis queryGroup 類的報表的 sp 範本 (本程式待驗證 ...)
build date : 2021/12/02
call sample:
CALL gex_chart_comm('opor11','2020-01-01','2020-12-31','pie')
modify history
item who date modify docs
==== ========== ========== ================================================
1 Michael 2021/12/02 新增
2 Michael 2025/08/06 改寫為 MariaDB 版本
*/
BEGIN
DECLARE v_uuid CHAR(100);
DECLARE v_data TEXT;
-- 生成 UUID
SET v_uuid = UUID();
-- 先刪除可能存在的舊數據
DELETE FROM dw_sys_chart_data WHERE uuid = v_uuid;
-- 客戶業績排行前 10
IF p_functiontag = 'OPOR11' then
INSERT INTO dw_sys_chart_data (uuid, functiontag, xname, xvalue)
SELECT v_uuid, p_functiontag, IFNULL(c.corpshortname, m.custid), CAST(SUM(totalamount) AS DECIMAL(18,2)) AS amt
FROM opoorder2_m m
LEFT JOIN bascustomer c ON m.custid = c.custid
WHERE billdate >= p_date1 AND billdate <= p_date2
GROUP BY IFNULL(c.corpshortname, m.custid)
ORDER BY SUM(totalamount) DESC
LIMIT 10;
-- else if ...
end if;
-- 調用通用函數 (假設已存在對應的 MariaDB 函數)
SELECT sys_genchart(v_uuid, p_type) INTO v_data;
-- 處理模板數據 (假設已存在對應的 MariaDB 存儲過程)
CALL sys_chart_process(v_uuid);
-- 返回結果
SELECT 0 AS code, 'ok' AS msg;
SELECT v_data AS jsoncode;
END //
DELIMITER ;
+47
View File
@@ -0,0 +1,47 @@
DELIMITER //
CREATE PROCEDURE qry_pmsq01(
IN p_projectid1 VARCHAR(50),
IN p_projectid2 VARCHAR(50)
)
/*
專案進度一覽表: 參考華炎的報表內容
專案名稱,客戶(無),專案經理,項目狀態,截止日期,待完成任務,待解決問題
*/
BEGIN
-- 返回狀態訊息
SELECT 0 AS code, 'ok' AS msg;
-- 主查詢
WITH wbs AS (
SELECT projectid, COUNT(*) AS wbs_no
FROM pms_pbi
WHERE pbi_type = 'Task' AND pbi_rate <> 100
GROUP BY projectid
),
issue AS (
SELECT projectid, COUNT(*) AS issue_no
FROM pms_pbi
WHERE pbi_type = 'Issue' AND pbi_rate <> 100
GROUP BY projectid
)
SELECT
P1.projectid,
P1.proj_cname,
P1.proj_boss,
P2.personcname,
P1.proj_status,
K.keyvalue AS proj_status_name,
P1.proj_enddate,
IFNULL(W.wbs_no, 0) AS wbs_no,
IFNULL(I.issue_no, 0) AS issue_no
FROM pmsproject P1
LEFT JOIN basperson P2 ON P1.proj_boss = P2.personid
LEFT JOIN wbs W ON P1.projectid = W.projectid
LEFT JOIN issue I ON P1.projectid = I.projectid
LEFT JOIN zen_keyvalue K ON K.fieldname = 'proj_status' AND K.keyid = P1.proj_status
WHERE CASE WHEN p_projectid1 = '*' THEN 1 ELSE P1.projectid >= p_projectid1 END
AND CASE WHEN p_projectid2 = '*' THEN 1 ELSE P1.projectid <= p_projectid2 END;
END //
DELIMITER ;
+70
View File
@@ -0,0 +1,70 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE response_issue_status(
IN p_token VARCHAR(100),
IN p_functiontag VARCHAR(100),
IN p_id INT,
IN p_assign_user VARCHAR(10),
IN p_new_status VARCHAR(100),
IN p_ok_rate SMALLINT,
IN p_release_readme TEXT
)
/*
Function : 處理問題狀態變更和指派
Description: 根據不同的功能標籤處理不同類型的問題狀態更新
Build Date : 2023/07/19 (MariaDB 版本)
*/
BEGIN
DECLARE v_userid VARCHAR(10);
DECLARE v_org_userid VARCHAR(10);
DECLARE v_err_code SMALLINT;
DECLARE v_seq INT;
DECLARE v_err_msg VARCHAR(100);
SET v_err_code = 0;
SET v_err_msg = '操作成功';
-- 根據token獲取userid
SELECT userid INTO v_userid FROM sys_users WHERE token = p_token LIMIT 1;
IF v_userid IS NULL OR v_userid = '' THEN
SET v_err_code = 4;
SET v_err_msg = '認證失敗,請重新登錄';
ELSE
-- 根據功能標籤處理不同類型的問題
IF p_functiontag = 'pmsm11' THEN -- Product Backlog Item
-- 獲取原始負責人和當前最大序號
SELECT controller INTO v_org_userid FROM pms_pbi WHERE pbiid = p_id;
SELECT IFNULL(MAX(seqno), 0) INTO v_seq FROM pms_pbi_log WHERE pbiid = p_id;
-- 寫入日誌
INSERT INTO pms_pbi_log (pbiid, response_date, response_by, assign_user, response, pbi_status, pbi_rate, seqno)
VALUES (p_id, NOW(), v_userid, p_assign_user, p_release_readme, p_new_status, p_ok_rate, v_seq+1);
-- 更新主表狀態
UPDATE pms_pbi
SET pbi_status = IFNULL(p_new_status, pbi_status),
controller = IFNULL(v_userid, controller),
pbi_rate = IFNULL(p_ok_rate, pbi_rate)
WHERE pbiid = p_id;
ELSEIF p_functiontag = 'pmsm12' THEN -- Issue Log 維護作業
-- 獲取當前最大序號
SELECT IFNULL(MAX(seqno), 0) INTO v_seq FROM pms_issuelog_d WHERE issueid = p_id;
-- 寫入日誌
INSERT INTO pms_issuelog_d (issueid, raised_date, raised_by, assign_user, response, issue_status, seqno)
VALUES (p_id, NOW(), v_userid, p_assign_user, p_release_readme, p_new_status, v_seq+1);
-- 更新主表狀態
UPDATE pms_issuelog
SET issue_status = IFNULL(p_new_status, issue_status),
responsible = IFNULL(p_assign_user, responsible)
WHERE issueid = p_id;
END IF;
END IF;
SELECT v_err_code AS code, v_err_msg AS msg;
END //
DELIMITER ;
+32
View File
@@ -0,0 +1,32 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE set_bbs_readed(
IN p_token VARCHAR(100),
IN p_id INT
)
/*
Function : 更新 eipbbs_d 的已讀紀錄(在 eipbbs_m 中 button call)
Description: eipm11 PBI 回報進度及狀態
Build Date : 2022/07/02
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/07/02 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_userid VARCHAR(100);
-- 根據傳入的 token 取得 userid
SELECT userid INTO v_userid FROM sys_users WHERE token = p_token LIMIT 1;
-- update eipbbs_d
UPDATE eipbbs_d SET is_read = 'Y'
WHERE uniqueno = p_id AND idno = v_userid;
-- 返回成功 result
SELECT 0 AS code, 'ok' AS msg;
END //
DELIMITER ;
+36
View File
@@ -0,0 +1,36 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sync_data_log(
IN p_type VARCHAR(20),
IN p_id INT,
IN p_userid VARCHAR(100),
IN p_status VARCHAR(10),
IN p_rate INT,
IN p_response TEXT
)
/*
Function : 配合 amis 的 edit log, 存檔時先 insert 一筆資料到 detail, 再 update 到表頭(暫時沒有用)
Description: 希望可以寫成根據設定 update, 但是第一個版本還是先 hard code, 晚點再改成通用版
Build Date : 2022/06/02
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/06/02 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
-- insert log
INSERT INTO pms_pbi_log (pbiid, response_date, response_by, response, pbi_status, pbi_rate)
VALUES (p_id, NOW(), p_userid, p_response, p_status, p_rate);
-- 更新主表??
UPDATE pms_pbi
SET pbi_status = p_status, pbi_rate = p_rate
WHERE pbiid = p_id;
SELECT 0 AS code, 'ok' AS msg;
END //
DELIMITER ;
+41
View File
@@ -0,0 +1,41 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sync_myfavor(
IN p_moduleid VARCHAR(100),
IN p_functiontag VARCHAR(100),
IN p_userid VARCHAR(100)
)
Build Date : 2023/11/01
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2023/11/01 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_count INT;
-- check if exists
SELECT COUNT(*) INTO v_count
FROM sys_myfavor
WHERE module = p_moduleid
AND functiontag = p_functiontag
AND userid = p_userid;
-- 已存在刪除,否則 update
IF v_count > 0 THEN
DELETE FROM sys_myfavor
WHERE module = p_moduleid
AND functiontag = p_functiontag
AND userid = p_userid;
ELSE
INSERT INTO sys_myfavor (module, functiontag, userid)
VALUES (p_moduleid, p_functiontag, p_userid);
END IF;
-- return
SELECT 0 AS code, 'ok' AS msg;
END //
DELIMITER ;
+36
View File
@@ -0,0 +1,36 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_chart_process(
IN p_uuid VARCHAR(100)
)
/*
function : 刪除 amis chart 類的報表所產生的站存資料, 一般是被 chart 類報表的 sp 於執行取得資料後呼叫
description: 可參考 gexrpt_opor11 的呼叫方式, 基本上不會單獨執行
build date : 2021/10/16
call sample:
exec sys_chart_process @uuid
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2021/10/16 新增
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_max INT;
-- get max
SELECT IFNULL(MAX(rowid), 0) INTO v_max FROM sys_chart_data;
-- delete template data
DELETE FROM sys_chart_data WHERE uuid = p_uuid;
-- 如果?据量?大?重置表
IF v_max > 10000 THEN
TRUNCATE TABLE sys_chart_data;
ALTER TABLE sys_chart_data AUTO_INCREMENT = 1;
END IF;
END //
DELIMITER ;
+73
View File
@@ -0,0 +1,73 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_d_update_m(
IN p_tablename VARCHAR(100)
)
/*
function : 配合 orm_api 的存檔後過帳, 當新增一筆 log detail 後, update master 的某1-2 個同名欄位的值
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行, 希望能全部透過設定, 而不是每一個 table 都必須客製
copy from sys_transfer_comm
目前只能針對 detail 或 log 的 pk 是自增值的情況寫入
build date : 2022/06/04
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2022-6-4 測試
2 Michael 2023-02-11 測試並修改 pms_pbi_log, 目前已可正確 update, 但仍需繼續觀察
3 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_relation_key VARCHAR(100);
DECLARE v_middle_field VARCHAR(100);
DECLARE v_dest_table VARCHAR(100);
DECLARE v_dest_field VARCHAR(100);
DECLARE v_dest_field2 VARCHAR(100);
DECLARE v_dest_field2_value VARCHAR(100);
DECLARE v_sql TEXT;
DECLARE v_para01 VARCHAR(100);
DECLARE v_para02 VARCHAR(100);
-- get data
SELECT
IFNULL(RelationKey,''), IFNULL(MiddleField,''),
IFNULL(para01,''), IFNULL(para02,''),
IFNULL(dest_table,''), IFNULL(dest_field,''),
IFNULL(dest_field2,''), IFNULL(dest_field2_value,'')
INTO
v_relation_key, v_middle_field,
v_para01, v_para02,
v_dest_table, v_dest_field,
v_dest_field2, v_dest_field2_value
FROM sys_transaction
WHERE tablename = p_tablename;
-- 构建 SQL
SET @sql = CONCAT(
'SELECT ', v_dest_field, ', IFNULL(', v_dest_field2, ', ''''), ', v_middle_field,
' INTO @v_field1, @v_field2, @v_field3 ',
'FROM ', p_tablename,
' WHERE ', v_relation_key, ' = ''', v_para01, ''';'
);
IF v_dest_field2 IS NOT NULL AND v_dest_field2 <> '' THEN
SET @sql = CONCAT(@sql,
'UPDATE ', v_dest_table,
' SET ', v_dest_field, ' = @v_field1, ', v_dest_field2, ' = @v_field2 ',
'WHERE ', v_middle_field, ' = @v_field3;'
);
ELSE
SET @sql = CONCAT(@sql,
'UPDATE ', v_dest_table,
' SET ', v_dest_field, ' = @v_field1 ',
'WHERE ', v_middle_field, ' = @v_field3;'
);
END IF;
-- exec SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+71
View File
@@ -0,0 +1,71 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_d_update_m2(
IN p_tablename VARCHAR(100)
)
/*
function : 配合 orm_api 的存檔後過帳, 當新增一筆 log detail 後, 呼叫 sys_d_update_m, 然後又 update master 時, 會回復原值, 所以只好在 master 存檔後, 再 call 本 func
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行, 希望能全部透過設定, 而不是每一個 table 都必須客製
copy from sys_d_update_m
目前只能針對 detail 或 log 的 pk 是自增值的情況寫入
build date : 2022/06/04
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2022-6-4 測試
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_relation_key VARCHAR(100);
DECLARE v_middle_field VARCHAR(100);
DECLARE v_dest_table VARCHAR(100);
DECLARE v_dest_field VARCHAR(100);
DECLARE v_dest_field2 VARCHAR(100);
DECLARE v_dest_field2_value VARCHAR(100);
DECLARE v_sql TEXT;
DECLARE v_para01 VARCHAR(100);
DECLARE v_para02 VARCHAR(100);
-- get data
SELECT
RelationKey, MiddleField, para01, para02,
dest_table, dest_field, dest_field2, dest_field2_value
INTO
v_relation_key, v_middle_field, v_para01, v_para02,
v_dest_table, v_dest_field, v_dest_field2, v_dest_field2_value
FROM sys_transaction
WHERE tablename = p_tablename;
-- build SQL
SET @sql = CONCAT(
'SELECT MAX(', v_relation_key, ') INTO @v_max_id ',
'FROM ', v_dest_table,
' WHERE ', v_middle_field, ' = ''', v_para01, ''';',
'SELECT ', v_dest_field, ', IFNULL(', v_dest_field2, ', ''''), ', v_middle_field,
' INTO @v_field1, @v_field2, @v_field3 ',
'FROM ', v_dest_table,
' WHERE ', v_relation_key, ' = @v_max_id;'
);
IF v_dest_field2 IS NOT NULL AND v_dest_field2 <> '' THEN
SET @sql = CONCAT(@sql,
'UPDATE ', p_tablename,
' SET ', v_dest_field, ' = @v_field1, ', v_dest_field2, ' = @v_field2 ',
'WHERE ', v_middle_field, ' = @v_field3;'
);
ELSE
SET @sql = CONCAT(@sql,
'UPDATE ', p_tablename,
' SET ', v_dest_field, ' = @v_field1 ',
'WHERE ', v_middle_field, ' = @v_field3;'
);
END IF;
-- exec SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+83
View File
@@ -0,0 +1,83 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_d_update_m3(
IN p_tablename VARCHAR(100)
)
/*
function : 配合 orm_api 的存檔後過帳, 當新增一筆 detail 後, update master 的合計欄位(目前先寫死 totalamount)
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行, 希望能全部透過設定, 而不是每一個 table 都必須客製
build date : 2023/10/14
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2023-10-14 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_relation_key VARCHAR(100);
DECLARE v_middle_field VARCHAR(100);
DECLARE v_dest_table VARCHAR(100);
DECLARE v_dest_field VARCHAR(100);
DECLARE v_dest_field2 VARCHAR(100);
DECLARE v_sql TEXT;
DECLARE v_para01 VARCHAR(100);
DECLARE v_para02 VARCHAR(100);
DECLARE v_pos INT;
DECLARE v_source_field VARCHAR(100);
DECLARE v_source_field2 VARCHAR(100);
-- get data
SELECT
IFNULL(RelationKey,''), IFNULL(MiddleField,''),
IFNULL(para01,''), IFNULL(para02,''),
IFNULL(dest_table,''), IFNULL(dest_field,''),
IFNULL(dest_field2,'')
INTO
v_relation_key, v_middle_field, v_para01, v_para02,
v_dest_table, v_dest_field, v_dest_field2
FROM sys_transaction
WHERE tablename = p_tablename;
-- prepare sql
SET v_pos = LOCATE('=', v_dest_field);
IF v_pos > 0 THEN
SET v_source_field = SUBSTRING(v_dest_field, 1, v_pos-1);
SET v_dest_field = SUBSTRING(v_dest_field, v_pos+1);
END IF;
SET v_pos = LOCATE('=', v_dest_field2);
IF v_pos > 0 THEN
SET v_source_field2 = SUBSTRING(v_dest_field2, 1, v_pos-1);
SET v_dest_field2 = SUBSTRING(v_dest_field2, v_pos+1);
END IF;
-- build SQL
IF v_dest_field2 IS NULL OR v_dest_field2 = '' THEN
SET @sql = CONCAT(
'UPDATE ', v_dest_table, ' d ',
'JOIN (SELECT ', v_middle_field, ', ', v_source_field,
' FROM ', p_tablename,
' WHERE ', v_relation_key, ' = ''', v_para01, ''') s ',
'ON d.', v_middle_field, ' = s.', v_middle_field, ' ',
'SET d.', v_dest_field, ' = s.', v_source_field, ';'
);
ELSE
SET @sql = CONCAT(
'UPDATE ', v_dest_table, ' d ',
'JOIN (SELECT ', v_middle_field, ', ', v_source_field, ', ', v_source_field2,
' FROM ', p_tablename,
' WHERE ', v_relation_key, ' = ''', v_para01, ''') s ',
'ON d.', v_middle_field, ' = s.', v_middle_field, ' ',
'SET d.', v_dest_field, ' = s.', v_source_field,
', d.', v_dest_field2, ' = s.', v_source_field2, ';'
);
END IF;
-- exec SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+69
View File
@@ -0,0 +1,69 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_dashboard(
IN p_token VARCHAR(100)
)
/*
Description: 取得首頁的幾個統計用數字
今日行事曆:
待簽核表單:
待辦事項: -- 協同工作單
執行中專案: -- 本 Sprint 未完成的 PBI
未結案留言單:
Build Date : 2023/02/14
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2023/02/14 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
DECLARE v_userid VARCHAR(100);
DECLARE v_cnt1 INT DEFAULT 0;
DECLARE v_cnt2 INT DEFAULT 0;
DECLARE v_cnt3 INT DEFAULT 0;
DECLARE v_cnt4 INT DEFAULT 0;
DECLARE v_cnt5 INT DEFAULT 0;
-- 將 token 換成 userid
SELECT userid INTO v_userid FROM sys_users WHERE token = p_token LIMIT 1;
-- 今日行事曆(參考 sp=eip_getCalendar)
SELECT COUNT(*) INTO v_cnt1
FROM eip_core_calendar
WHERE DATE(start_time) = CURDATE() AND personid = v_userid;
-- 待簽核表單(參考 sp=bpm_sign_todo)
SELECT COUNT(*) INTO v_cnt2
FROM bpm_flow_sign a
JOIN bpm_list b ON a.flow_id = b.flow_id
JOIN basperson p ON a.signerid = p.personid
WHERE a.sign_status = 'P'
AND IFNULL(a.assign_to,'') = 'Y'
AND a.signerid = v_userid;
-- 待辦事項(建議是前後3天)
SELECT COUNT(*) INTO v_cnt3
FROM crmassign_m m
WHERE DATE(m.predictdate) BETWEEN DATE_SUB(CURDATE(), INTERVAL 3 DAY) AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)
AND (m.personid2 = v_userid OR m.personid3 = v_userid);
-- 執行中 PBI(本 sprint 尚未完成, )
SELECT COUNT(*) INTO v_cnt4
FROM pms_pbi p
JOIN pms_sprint s ON p.sprintid = s.sprintid
WHERE DATE(p.startdate) BETWEEN DATE_SUB(CURDATE(), INTERVAL 3 DAY) AND DATE_ADD(CURDATE(), INTERVAL 3 DAY)
AND CURDATE() BETWEEN DATE(s.sprint_startdate) AND DATE(s.sprint_enddate)
AND (p.controller = v_userid OR p.tester = v_userid);
-- 未結案留言單(規格要調整, 先暫緩)
-- 回傳 dataset
SELECT 0 AS code, 'ok' AS msg;
SELECT v_cnt1 AS dashboard1, v_cnt2 AS dashboard2,
v_cnt3 AS dashboard3, v_cnt4 AS dashboard4,
v_cnt5 AS dashboard5;
END //
DELIMITER ;
+40
View File
@@ -0,0 +1,40 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_issue2pbi(
IN p_issueid INT
)
/*
Function : 將 issue copy 到 PBI(在 issue 中 button call)
Description:
Build Date : 2022/07/09
Modify History
Item Who Date Modify Docs
==== ========== ========== ================================================
1 Michael 2022/07/09 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
/*
Function: Copy issue to PBI (called from issue button)
Build Date: 2022/07/09
*/
DECLARE v_count SMALLINT;
SELECT COUNT(*) INTO v_count FROM pms_pbi WHERE source_id = p_issueid;
IF v_count = 0 THEN
-- Insert into pms_pbi
INSERT INTO pms_pbi (sprintid, projectid, functioncode, pbi_title, pbi_desc, owner, pbi_type, pbi_status, source_id, attach_file)
SELECT
'Pre-Sprint', projectid, functioncode, CONCAT('copy from issue', issueid), issue_description,
raised_by, 'Issue', 1, issueid, issue_extdoc
FROM pms_issuelog
WHERE issueid = p_issueid;
-- Return success
SELECT 0 AS code, 'ok' AS msg;
ELSE
SELECT 9 AS code, '該序號 issue 已轉移,請確認後再重新執行?!' AS msg;
END IF;
END //
DELIMITER ;
+82
View File
@@ -0,0 +1,82 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_m_update_m(
IN p_para_tablename VARCHAR(100)
)
/*
function : 配合 orm_api 的存檔後過帳, 當表頭存檔時, update master 的合計欄位(目前先寫死 totalamount)
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行, 希望能全部透過設定, 而不是每一個 table 都必須客製
build date : 2023/10/17
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2023-10-17 Init
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
/*
Function: Update master table totals after detail table changes
Build Date: 2023/10/17
*/
DECLARE v_RelationKey VARCHAR(100);
DECLARE v_MiddleField VARCHAR(100);
DECLARE v_dest_table VARCHAR(100);
DECLARE v_dest_field VARCHAR(100);
DECLARE v_dest_field2 VARCHAR(100);
DECLARE v_detail_tbl_name VARCHAR(100);
DECLARE v_sql LONGTEXT;
DECLARE v_para01 VARCHAR(100);
DECLARE v_para02 VARCHAR(100);
DECLARE v_pos INT;
DECLARE v_source_field VARCHAR(100);
DECLARE v_source_field2 VARCHAR(100);
-- Read parameters from sys_transaction
SELECT
IFNULL(RelationKey, ''), IFNULL(MiddleField, ''), IFNULL(para01, ''), IFNULL(para02, ''),
IFNULL(dest_table, ''), IFNULL(dest_field, ''), IFNULL(dest_field2, ''), IFNULL(dest_field2_value, '')
INTO
v_RelationKey, v_MiddleField, v_para01, v_para02,
v_dest_table, v_dest_field, v_dest_field2, v_detail_tbl_name
FROM sys_transaction WHERE tablename = p_para_tablename;
-- Debug
IF v_para01 = '' THEN
SET v_para01 = '231007-001';
END IF;
-- Check for equals sign to split fields (sum(subamount)=totalamount)
SET v_pos = LOCATE('=', v_dest_field);
IF v_pos > 0 THEN
SET v_source_field = SUBSTRING(v_dest_field, 1, v_pos - 1);
SET v_dest_field = SUBSTRING(v_dest_field, v_pos + 1);
END IF;
SET v_pos = LOCATE('=', v_dest_field2);
IF v_pos > 0 THEN
SET v_source_field2 = SUBSTRING(v_dest_field2, 1, v_pos - 1);
SET v_dest_field2 = SUBSTRING(v_dest_field2, v_pos + 1);
END IF;
IF v_dest_field2 = '' THEN
SET v_sql = CONCAT(
'UPDATE ', v_dest_table, ' SET ', v_dest_field, ' = (SELECT ', v_source_field,
' FROM ', v_detail_tbl_name, ' WHERE ', v_RelationKey, ' = ''', v_para01, ''') ',
'WHERE ', v_MiddleField, ' = ''', v_para01, ''';'
);
ELSE
SET v_sql = CONCAT(
'UPDATE ', v_dest_table, ' SET ', v_dest_field, ' = (SELECT ', v_source_field,
' FROM ', v_detail_tbl_name, ' WHERE ', v_RelationKey, ' = ''', v_para01, '''), ',
v_dest_field2, ' = (SELECT ', v_source_field2,
' FROM ', v_detail_tbl_name, ' WHERE ', v_RelationKey, ' = ''', v_para01, ''') ',
'WHERE ', v_MiddleField, ' = ''', v_para01, ''';'
);
END IF;
SET @sql = v_sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+66
View File
@@ -0,0 +1,66 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_m_update_trans(
IN p_para_tablename VARCHAR(100)
)
BEGIN
/*
function : 配合 orm_api 的存檔後過帳, 當新增(或修改)一筆 data 後, update master 的某1-2 個同名欄位的值
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行, 希望能全部透過設定, 而不是每一個 table 都必須客製
copy from sys_transfer_comm
目前針對某 table 存檔後, update 另一個 table 的情況寫入
build date : 2022/06/04
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2022-6-4 測試
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
DECLARE v_RelationKey VARCHAR(100); -- RelationKey
DECLARE v_MiddleField VARCHAR(100); -- MiddleField
DECLARE v_dest_table VARCHAR(100); -- dest_table
DECLARE v_dest_field VARCHAR(100); -- dest_field
DECLARE v_dest_field2 VARCHAR(100); -- dest_field2(特殊使用, 如sys_rolemenusecurity.controlname=read)
DECLARE v_dest_field2_value VARCHAR(100); -- dest_field2_value(特殊使用, 如sys_rolemenusecurity.controlname=read)
DECLARE v_sql LONGTEXT;
DECLARE v_para01 VARCHAR(100);
DECLARE v_para02 VARCHAR(100);
/*
read paras from sys_transaction
RelationKey = d 檔的 pk
MiddleField = md 檔的關聯 key
*/
SELECT
RelationKey, MiddleField, para01, para02,
dest_table, dest_field, dest_field2, dest_field2_value
INTO
v_RelationKey, v_MiddleField, v_para01, v_para02,
v_dest_table, v_dest_field, v_dest_field2, v_dest_field2_value
FROM sys_transaction WHERE tablename = p_para_tablename;
-- 建立動態 SQL
IF v_dest_field2 IS NOT NULL AND v_dest_field2 != '' THEN
SET v_sql = CONCAT(
'UPDATE ', v_dest_table, ' SET ',
v_dest_field, ' = (SELECT ', v_dest_field, ' FROM ', p_para_tablename,
' WHERE ', v_MiddleField, ' = ''', v_para01, '''), ',
v_dest_field2, ' = (SELECT ', v_dest_field2, ' FROM ', p_para_tablename,
' WHERE ', v_MiddleField, ' = ''', v_para01, ''') ',
'WHERE ', v_MiddleField, ' = ''', v_para01, ''';'
);
ELSE
SET v_sql = CONCAT(
'UPDATE ', v_dest_table, ' SET ',
v_dest_field, ' = (SELECT ', v_dest_field, ' FROM ', p_para_tablename,
' WHERE ', v_MiddleField, ' = ''', v_para01, ''') ',
'WHERE ', v_MiddleField, ' = ''', v_para01, ''';'
);
END IF;
SET @sql = v_sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+49
View File
@@ -0,0 +1,49 @@
DELIMITER //
CREATE OR REPLACE FUNCTION sys_next_no(
p_billno_max VARCHAR(20)
)
RETURNS VARCHAR(20)
DETERMINISTIC
BEGIN
DECLARE v_billno VARCHAR(20);
DECLARE v_code1 VARCHAR(10);
DECLARE v_code2 VARCHAR(10);
DECLARE v_code3 INT;
SET v_billno = p_billno_max;
IF IFNULL(v_billno, '') = '' THEN
SET v_billno = CONCAT(DATE_FORMAT(CURDATE(), '%y%m%d'), '-001');
ELSE
-- Check last 3 digits
IF REGEXP_SUBSTR(v_billno, '[0-9]{3}$') IS NOT NULL THEN
SET v_code1 = RIGHT(v_billno, 3);
SET v_code3 = CAST(v_code1 AS UNSIGNED) + 1;
IF v_code3 < 10 THEN
SET v_code2 = CONCAT('00', v_code3);
ELSEIF v_code3 < 100 THEN
SET v_code2 = CONCAT('0', v_code3);
ELSE
SET v_code2 = CAST(v_code3 AS CHAR);
END IF;
SET v_billno = CONCAT(LEFT(v_billno, LENGTH(v_billno) - 3), v_code2);
-- Check last 2 digits
ELSEIF REGEXP_SUBSTR(v_billno, '[0-9]{2}$') IS NOT NULL THEN
SET v_code1 = RIGHT(v_billno, 2);
SET v_code3 = CAST(v_code1 AS UNSIGNED) + 1;
IF v_code3 < 10 THEN
SET v_code2 = CONCAT('0', v_code3);
ELSE
SET v_code2 = CAST(v_code3 AS CHAR);
END IF;
SET v_billno = CONCAT(LEFT(v_billno, LENGTH(v_billno) - 2), v_code2);
END IF;
END IF;
RETURN v_billno;
END //
DELIMITER ;
+71
View File
@@ -0,0 +1,71 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_transfer_comm(
IN p_para_tablename VARCHAR(100)
)
/*
function : 配合 amis 的 transfer 元件, 將暫存在 owned(or else) 欄位的值, 寫到指定的 table(透過設定)
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行, 希望能全部透過設定, 而不是每一個 table 都必須客製
copy from sys_transfer_owned2rolemenusecurity
build date : 2022/04/08
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2022-4-9 測試
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
/*
Function: Transfer data from temporary fields to specified tables
Build Date: 2022/04/08
*/
DECLARE v_RelationKey VARCHAR(100);
DECLARE v_MiddleField VARCHAR(100);
DECLARE v_dest_table VARCHAR(100);
DECLARE v_dest_field VARCHAR(100);
DECLARE v_dest_field2 VARCHAR(100);
DECLARE v_dest_field2_value VARCHAR(100);
DECLARE v_sql LONGTEXT;
DECLARE v_para01 VARCHAR(100);
DECLARE v_para02 VARCHAR(100);
-- Read parameters from sys_transaction
SELECT
RelationKey, MiddleField, para01, para02,
dest_table, dest_field, dest_field2, dest_field2_value
INTO
v_RelationKey, v_MiddleField, v_para01, v_para02,
v_dest_table, v_dest_field, v_dest_field2, v_dest_field2_value
FROM sys_transaction WHERE tablename = p_para_tablename;
-- Build dynamic SQL
SET v_sql = CONCAT(
'DELETE FROM ', v_dest_table, ' WHERE ', v_RelationKey, ' = ''', v_para01, ''';'
);
IF v_dest_field2 IS NOT NULL AND v_dest_field2 != '' THEN
SET v_sql = CONCAT(v_sql,
' INSERT INTO ', v_dest_table, ' (', v_RelationKey, ',', v_dest_field, ',', v_dest_field2, ') ',
'SELECT t.', v_RelationKey, ', s.col, ''', v_dest_field2_value, ''' ',
'FROM ', p_para_tablename, ' t ',
'JOIN (SELECT col FROM STRING_SPLIT((SELECT ', v_MiddleField, ' FROM ', p_para_tablename,
' WHERE ', v_RelationKey, ' = ''', v_para01, '''), '','') WHERE col != '''') s ',
'WHERE t.', v_RelationKey, ' = ''', v_para01, ''';'
);
ELSE
SET v_sql = CONCAT(v_sql,
' INSERT INTO ', v_dest_table, ' (', v_RelationKey, ',', v_dest_field, ') ',
'SELECT t.', v_RelationKey, ', s.col ',
'FROM ', p_para_tablename, ' t ',
'JOIN (SELECT col FROM STRING_SPLIT((SELECT ', v_MiddleField, ' FROM ', p_para_tablename,
' WHERE ', v_RelationKey, ' = ''', v_para01, '''), '','') WHERE col != '''') s ',
'WHERE t.', v_RelationKey, ' = ''', v_para01, ''';'
);
END IF;
SET @sql = v_sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
+55
View File
@@ -0,0 +1,55 @@
DELIMITER //
CREATE PROCEDURE sys_transfer_owned2rolemenusecurity(
IN p_para_menuid VARCHAR(100)
)
/*
function : 配合 amis 的 transfer 元件, 將暫存在 owned 欄位的值, 寫到 rolemenusecurity
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行
build date : 2021/10/22
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2021-10-17 新增
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
BEGIN
/*
Function: Transfer ownership data from menu table to role menu security
Build Date: 2021/10/22
*/
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_menuid VARCHAR(100);
DECLARE v_owned TEXT;
DECLARE cur CURSOR FOR
SELECT menuid, owned FROM sys_menutable WHERE menuid = p_para_menuid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_menuid, v_owned;
IF v_done THEN
LEAVE read_loop;
END IF;
-- Delete existing records
DELETE FROM sys_rolemenusecurity WHERE menuid = v_menuid;
-- Insert new records from comma-separated list
SET @sql = CONCAT(
'INSERT INTO sys_rolemenusecurity (menuid, roleid, controlname) ',
'SELECT ''', v_menuid, ''', value, ''read'' ',
'FROM STRING_SPLIT(''', IFNULL(v_owned, ''), ''', '','') ',
'WHERE value != '''';'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
+39
View File
@@ -0,0 +1,39 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_transfer_owned2userroles(
IN p_para_roleid VARCHAR(100)
)
BEGIN
/*
function : 配合 amis 的 transfer 元件, 將暫存在 owned 欄位的值, 寫到 userroles
description: 目前先配合 omi_api 的存檔後機制(sys_transaction) 執行
build date : 2021/10/22
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2021-10-17 新增
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
DECLARE v_owned TEXT;
-- 取得 owned 欄位值
SELECT owned INTO v_owned FROM sys_roles WHERE roleid = p_para_roleid;
-- 先刪除現有記錄
DELETE FROM sys_userroles WHERE roleid = p_para_roleid;
-- 使用 STRING_SPLIT 函數插入新記錄
IF v_owned IS NOT NULL AND v_owned != '' THEN
SET @sql = CONCAT(
'INSERT INTO sys_userroles (roleid, userid) ',
'SELECT ''', p_para_roleid, ''', value ',
'FROM STRING_SPLIT(''', v_owned, ''', '','') ',
'WHERE value != '''';'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END //
DELIMITER ;
+42
View File
@@ -0,0 +1,42 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_transfer_rolemenusecurity2owned()
BEGIN
/*
function : 配合 amis 的 transfer 元件, 將 rolemenusecurity 寫入暫存在 owned 欄位
description: 本程式基本上只會很低頻率的使用, 因為程式的 SOP 是由 owned -> rolemenusecurity
不會逆向執行
build date : 2021/10/22
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2021-10-17 新增
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_menuid VARCHAR(100);
DECLARE v_roleids TEXT;
-- 宣告游標,按 menuid 分組取得所有 roleid
DECLARE cur CURSOR FOR
SELECT menuid, GROUP_CONCAT(roleid SEPARATOR ',')
FROM sys_rolemenusecurity
GROUP BY menuid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_menuid, v_roleids;
IF v_done THEN
LEAVE read_loop;
END IF;
-- 更新 owned 欄位
UPDATE sys_menutable SET owned = v_roleids WHERE menuid = v_menuid;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
+42
View File
@@ -0,0 +1,42 @@
DELIMITER //
CREATE OR REPLACE PROCEDURE sys_transfer_userroles2owned()
BEGIN
/*
function : 配合 amis 的 transfer 元件, 將userroles 寫入暫存在 owned 欄位
description: 本程式基本上只會很低頻率的使用, 因為程式的 SOP 是由 owned -> userrole
不會逆向執行
build date : 2021/10/22
modify history
item who date modify docs
==== ========== ========== ================================================
1 michael 2021-10-17 新增
2 Michael 2025/07/20 改寫為 MariaDB 並最佳化(ChatGPT+DeepSeek)
*/
DECLARE v_done INT DEFAULT FALSE;
DECLARE v_roleid VARCHAR(100);
DECLARE v_userids TEXT;
-- 宣告游標,按 roleid 分組取得所有 userid
DECLARE cur CURSOR FOR
SELECT roleid, GROUP_CONCAT(userid SEPARATOR ',')
FROM sys_userroles
GROUP BY roleid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_roleid, v_userids;
IF v_done THEN
LEAVE read_loop;
END IF;
-- 更新 owned 欄位
UPDATE sys_roles SET owned = v_userids WHERE roleid = v_roleid;
END LOOP;
CLOSE cur;
END //
DELIMITER ;