migrate to new git
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.vs/
|
||||||
|
.vscode
|
||||||
|
.git
|
||||||
|
packages
|
||||||
|
obj/
|
||||||
|
*.user
|
||||||
|
*.log
|
||||||
55
data/MEMO250620.txt
Normal file
55
data/MEMO250620.txt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
[以這裡為準]
|
||||||
|
1. 若入帳金額, 不全部沖帳 : 不可以?
|
||||||
|
- 但加上: 暫存草稿功能, 可中途暫存**(需新增JSON)
|
||||||
|
- 若: 入帳:10000, 可沖15000, 5000未沖, 不可只沖8000
|
||||||
|
2. 若入帳金額, 超過餘款 -> 餘額處理原則?
|
||||||
|
- 若: 入帳:10000, 可沖8000, 餘2000:轉:"餘額核銷", 不可再出現
|
||||||
|
---
|
||||||
|
transfer_register : 沖帳流程(經確認的)
|
||||||
|
加欄位:
|
||||||
|
入帳:10000, 可沖:8000, 餘2000
|
||||||
|
加欄位: 記, 餘2000
|
||||||
|
再新增一筆: 金額2000, 並記來源那筆ID
|
||||||
|
|
||||||
|
->
|
||||||
|
畫面進來時:
|
||||||
|
1. 前一步驟確認, 可沖帳金額
|
||||||
|
2. 前次未沖餘額
|
||||||
|
---
|
||||||
|
例:
|
||||||
|
#55, AAA,5/10,$10000,餘2000 -> 結掉
|
||||||
|
....
|
||||||
|
#88, AAA,5/10,$2000, 上一筆: #55
|
||||||
|
|
||||||
|
---
|
||||||
|
[不採此案]
|
||||||
|
A.在同TABLE, 加一列, 記關聯, 餘額
|
||||||
|
B.加"預收款管理系統"?
|
||||||
|
|
||||||
|
----
|
||||||
|
沖帳: 從報名明細中, "收款紀錄":
|
||||||
|
- 由:沖帳流程新增
|
||||||
|
- 例:該功德項目金額=10000, 收款記錄:4*1000, (餘額:6000)
|
||||||
|
- 若有未收餘額, 就會在沖帳時列出, 做為日後收款的沖帳對像
|
||||||
|
|
||||||
|
報名時的金額:
|
||||||
|
- 金額要由功德項目帶入, 不能改金額?
|
||||||
|
- 隨喜金額, 需可改金額?
|
||||||
|
方案:
|
||||||
|
- 品項管理: 加勾選: 可否自訂金額
|
||||||
|
- 報名(新增)時: 若品項有勾選, 就可自訂
|
||||||
|
- 儲存後: 不可修改金額
|
||||||
|
- "結緣": 獨立建立, 0元, 不可修改金額
|
||||||
|
- 例: 隨喜 $10000, 結緣:3項 x $0
|
||||||
|
|
||||||
|
---
|
||||||
|
討論: 溢收款銷帳?
|
||||||
|
目前: 以EXCEL管理
|
||||||
|
|
||||||
|
---
|
||||||
|
例1(OK): 入帳:10000, 可沖:8000, 餘2000 ->
|
||||||
|
- 本筆入帳完成, 轉到: 餘額核銷, 另外沖帳新項目
|
||||||
|
- 這筆不再出現在入帳/沖帳流程
|
||||||
|
|
||||||
|
例2(??): 入帳:10000, 可沖:12000, 但人工沖:8000,
|
||||||
20
data/MEMO250627.txt
Normal file
20
data/MEMO250627.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# 17168, 06/27
|
||||||
|
|
||||||
|
http://localhost:33051/admin/transfer/balance_reconcile.aspx
|
||||||
|
選取項目:加:金額
|
||||||
|
核銷項目: 單項或多項??
|
||||||
|
- 維持單項, 記錄: "依據來源", 信眾意思, 內部審核?
|
||||||
|
- 建議: 嚴謹: 要先有"報名", 才能"沖帳", 不可以有"餘額核銷", 適合大道場
|
||||||
|
- 加審核? 新增狀態確認?
|
||||||
|
常用項目: 指定列表?
|
||||||
|
- 沒有輸入金額: 因為必需全額核銷.
|
||||||
|
- 在品項中, 加勾選 : 會計核銷參照
|
||||||
|
- 在餘額核銷, 選取品項時:
|
||||||
|
- 預設只抓"會計核銷參照"
|
||||||
|
- 要有選項:可找, 選其它項目
|
||||||
|
|
||||||
|
Draft : single json list -> object of lists(and key/value)
|
||||||
|
---
|
||||||
|
http://localhost:33051/admin/transfer/verify.aspx
|
||||||
|
出納: 2程序, 分畫面, 以便指定不同人負責
|
||||||
|
|
||||||
36
data/MEMO250711.txt
Normal file
36
data/MEMO250711.txt
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
AA2503300003
|
||||||
|
AA2503300001
|
||||||
|
|
||||||
|
資料狀態:統合查詢->產出報表
|
||||||
|
- ex: 從報名: by 活動, 人, 物(數量, 金額, 已收/未收),
|
||||||
|
- 先做查詢條件,
|
||||||
|
- req, ex: 每日: 報名人數, 報名項目, 統計
|
||||||
|
- 綜效: 報名人數? 功德項目? 應收/未收/已收?
|
||||||
|
- 報名人介定? 用品項區隔: 如: 一般:$100,結緣:$0,隨喜:$1
|
||||||
|
|
||||||
|
verify2:acc. ,
|
||||||
|
personal_reconcile:pro-ord-rec
|
||||||
|
|
||||||
|
order/reg.aspx, 編輯牌位: 人名旁:顯示稱謂
|
||||||
|
|
||||||
|
|
||||||
|
114年度清明祭祖法會
|
||||||
|
AA2503290011
|
||||||
|
2025/3/29 消災-隨喜牌位 1000 0 1,000
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
- 沖帳完查詢: 查詢沖帳結果: 參考
|
||||||
|
http://localhost:33051/admin/transfer/balance_reconcile_query.aspx
|
||||||
|
(指定條件, 有沖帳的項目)
|
||||||
|
(日期, 法會, 信眾)
|
||||||
|
- 收據編號:? 因為一筆入帳可能有多人分拆, 所以不宜在沖帳時做, 應另定流程處理
|
||||||
|
|
||||||
|
Q: 待繳金額:大額/長期?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
data/SQL/17168_db_schema.sql
Normal file
BIN
data/SQL/17168_db_schema.sql
Normal file
Binary file not shown.
1
data/SQL/actItem.sql
Normal file
1
data/SQL/actItem.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE actItem ADD IsDel BIT NOT NULL DEFAULT 0;
|
||||||
1
data/SQL/followers.sql
Normal file
1
data/SQL/followers.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE followers ADD IsDel BIT NOT NULL DEFAULT 0;
|
||||||
202
data/SQL/transform_tablet.sql
Normal file
202
data/SQL/transform_tablet.sql
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
C# version of join_text:
|
||||||
|
|
||||||
|
public class TabletItem
|
||||||
|
{
|
||||||
|
public int num { get; set; }
|
||||||
|
public string fam_name { get; set; }
|
||||||
|
public object fam_gender { get; set; }
|
||||||
|
public object deceased { get; set; }
|
||||||
|
public bool option_break { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TabletJson
|
||||||
|
{
|
||||||
|
public List<TabletItem> mid_items { get; set; }
|
||||||
|
public List<TabletItem> left_items { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string JoinText(List<TabletItem> items)
|
||||||
|
{
|
||||||
|
if (items == null || items.Count == 0)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
result.Append(items[i].fam_name);
|
||||||
|
|
||||||
|
// Add break if option_break is true and not the last item
|
||||||
|
if (items[i].option_break && i < items.Count - 1)
|
||||||
|
{
|
||||||
|
result.Append("<br>");
|
||||||
|
}
|
||||||
|
// Add space between names if not the last item and no break
|
||||||
|
else if (i < items.Count - 1)
|
||||||
|
{
|
||||||
|
result.Append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage example:
|
||||||
|
public string[] ProcessTabletJson(string jsonString)
|
||||||
|
{
|
||||||
|
string[] ret = new string[2];
|
||||||
|
|
||||||
|
// Deserialize JSON string to TabletJson object
|
||||||
|
TabletJson tabletJsonObj = JsonConvert.DeserializeObject<TabletJson>(jsonString);
|
||||||
|
|
||||||
|
// Process mid_items and left_items
|
||||||
|
ret[0] = JoinText(tabletJsonObj.mid_items);
|
||||||
|
ret[1] = JoinText(tabletJsonObj.left_items);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- {"mid_items":[
|
||||||
|
-- {"num":0,"fam_name":" ","fam_gender":null,"deceased":null,"option_break":true},
|
||||||
|
-- {"num":0,"fam_name":"無始劫以來累世冤親債主1 ","fam_gender":null,"deceased":null,"option_break":true},
|
||||||
|
-- {"num":0,"fam_name":"無始劫以來累世冤親債主2 ","fam_gender":null,"deceased":null,"option_break":true},
|
||||||
|
-- {"num":0,"fam_name":" ","fam_gender":null,"deceased":null,"option_break":true}],
|
||||||
|
-- "left_items":[
|
||||||
|
-- {"num":0,"fam_name":" ","fam_gender":null,"deceased":null,"option_break":true},
|
||||||
|
-- {"num":0,"fam_name":"祁哲榮1 ","fam_gender":null,"deceased":null,"option_break":true},
|
||||||
|
-- {"num":0,"fam_name":"祁哲榮2","fam_gender":null,"deceased":null,"option_break":true}
|
||||||
|
-- ]}
|
||||||
|
|
||||||
|
-- 轉換牌位文本為 JSON 格式
|
||||||
|
DECLARE @InputText NVARCHAR(MAX)
|
||||||
|
DECLARE @Result NVARCHAR(MAX)
|
||||||
|
DECLARE @MidText NVARCHAR(MAX)
|
||||||
|
DECLARE @LeftText NVARCHAR(MAX)
|
||||||
|
DECLARE @StartPos INT
|
||||||
|
DECLARE @EndPos INT
|
||||||
|
DECLARE @Line NVARCHAR(1000)
|
||||||
|
DECLARE @First BIT
|
||||||
|
DECLARE @MidStart INT
|
||||||
|
DECLARE @LeftStart INT
|
||||||
|
|
||||||
|
-- 宣告游標變數
|
||||||
|
DECLARE @num INT
|
||||||
|
DECLARE @f_num_tablet NVARCHAR(MAX)
|
||||||
|
DECLARE @from_id_tablet NVARCHAR(MAX)
|
||||||
|
|
||||||
|
-- 宣告游標
|
||||||
|
DECLARE tablet_cursor CURSOR FOR
|
||||||
|
SELECT num, f_num_tablet, from_id_tablet
|
||||||
|
FROM pro_order_detail
|
||||||
|
|
||||||
|
-- 打開游標
|
||||||
|
OPEN tablet_cursor
|
||||||
|
|
||||||
|
-- 讀取第一筆資料
|
||||||
|
FETCH NEXT FROM tablet_cursor INTO @num, @f_num_tablet, @from_id_tablet
|
||||||
|
|
||||||
|
-- 開始處理每一筆資料
|
||||||
|
WHILE @@FETCH_STATUS = 0
|
||||||
|
BEGIN
|
||||||
|
-- 設置輸入文本
|
||||||
|
SET @InputText = @from_id_tablet
|
||||||
|
|
||||||
|
-- 找到 #牌位 和 #陽上 的位置
|
||||||
|
SET @MidStart = CHARINDEX('#牌位', @InputText) + 3
|
||||||
|
SET @LeftStart = CHARINDEX('#陽上', @InputText)
|
||||||
|
|
||||||
|
-- 如果找到正確的格式
|
||||||
|
IF @MidStart > 3 AND @LeftStart > 0
|
||||||
|
BEGIN
|
||||||
|
-- 取得兩段文字
|
||||||
|
SET @MidText = SUBSTRING(@InputText, @MidStart, @LeftStart - @MidStart)
|
||||||
|
SET @LeftText = SUBSTRING(@InputText, @LeftStart + 3, LEN(@InputText))
|
||||||
|
|
||||||
|
-- 建立 JSON
|
||||||
|
SET @Result = '{"mid_items":['
|
||||||
|
|
||||||
|
-- 處理 mid_items
|
||||||
|
SET @StartPos = 1
|
||||||
|
SET @EndPos = CHARINDEX(CHAR(10), @MidText, @StartPos)
|
||||||
|
SET @First = 1
|
||||||
|
|
||||||
|
WHILE @EndPos > 0
|
||||||
|
BEGIN
|
||||||
|
SET @Line = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(
|
||||||
|
SUBSTRING(@MidText, @StartPos, @EndPos - @StartPos),
|
||||||
|
CHAR(13), ''), CHAR(10), ''), CHAR(9), '')))
|
||||||
|
IF LEN(@Line) > 0
|
||||||
|
BEGIN
|
||||||
|
IF @First = 0
|
||||||
|
SET @Result = @Result + ','
|
||||||
|
SET @Result = @Result + '{"num":0,"fam_name":"' + @Line +
|
||||||
|
'","fam_gender":null,"deceased":null,"option_break":true}'
|
||||||
|
SET @First = 0
|
||||||
|
END
|
||||||
|
SET @StartPos = @EndPos + 1
|
||||||
|
SET @EndPos = CHARINDEX(CHAR(10), @MidText, @StartPos)
|
||||||
|
END
|
||||||
|
|
||||||
|
SET @Line = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(
|
||||||
|
SUBSTRING(@MidText, @StartPos, LEN(@MidText)),
|
||||||
|
CHAR(13), ''), CHAR(10), ''), CHAR(9), '')))
|
||||||
|
IF LEN(@Line) > 0
|
||||||
|
BEGIN
|
||||||
|
IF @First = 0
|
||||||
|
SET @Result = @Result + ','
|
||||||
|
SET @Result = @Result + '{"num":0,"fam_name":"' + @Line +
|
||||||
|
'","fam_gender":null,"deceased":null,"option_break":true}'
|
||||||
|
END
|
||||||
|
|
||||||
|
SET @Result = @Result + '],"left_items":['
|
||||||
|
|
||||||
|
-- 處理 left_items
|
||||||
|
SET @StartPos = 1
|
||||||
|
SET @EndPos = CHARINDEX(CHAR(10), @LeftText, @StartPos)
|
||||||
|
SET @First = 1
|
||||||
|
|
||||||
|
WHILE @EndPos > 0
|
||||||
|
BEGIN
|
||||||
|
SET @Line = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(
|
||||||
|
SUBSTRING(@LeftText, @StartPos, @EndPos - @StartPos),
|
||||||
|
CHAR(13), ''), CHAR(10), ''), CHAR(9), '')))
|
||||||
|
IF LEN(@Line) > 0
|
||||||
|
BEGIN
|
||||||
|
IF @First = 0
|
||||||
|
SET @Result = @Result + ','
|
||||||
|
SET @Result = @Result + '{"num":0,"fam_name":"' + @Line +
|
||||||
|
'","fam_gender":null,"deceased":null,"option_break":true}'
|
||||||
|
SET @First = 0
|
||||||
|
END
|
||||||
|
SET @StartPos = @EndPos + 1
|
||||||
|
SET @EndPos = CHARINDEX(CHAR(10), @LeftText, @StartPos)
|
||||||
|
END
|
||||||
|
|
||||||
|
SET @Line = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(
|
||||||
|
SUBSTRING(@LeftText, @StartPos, LEN(@LeftText)),
|
||||||
|
CHAR(13), ''), CHAR(10), ''), CHAR(9), '')))
|
||||||
|
IF LEN(@Line) > 0
|
||||||
|
BEGIN
|
||||||
|
IF @First = 0
|
||||||
|
SET @Result = @Result + ','
|
||||||
|
SET @Result = @Result + '{"num":0,"fam_name":"' + @Line +
|
||||||
|
'","fam_gender":null,"deceased":null,"option_break":true}'
|
||||||
|
END
|
||||||
|
|
||||||
|
SET @Result = @Result + ']}'
|
||||||
|
|
||||||
|
-- 更新資料庫
|
||||||
|
UPDATE pro_order_detail
|
||||||
|
SET f_num_tablet = @Result
|
||||||
|
WHERE num = @num
|
||||||
|
END
|
||||||
|
|
||||||
|
-- 讀取下一筆資料
|
||||||
|
FETCH NEXT FROM tablet_cursor INTO @num, @f_num_tablet, @from_id_tablet
|
||||||
|
END
|
||||||
|
|
||||||
|
-- 關閉並釋放游標
|
||||||
|
CLOSE tablet_cursor
|
||||||
|
DEALLOCATE tablet_cursor
|
||||||
191
data/memo/DRAFT_FIELD_IMPROVEMENT.md
Normal file
191
data/memo/DRAFT_FIELD_IMPROVEMENT.md
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
# Draft 欄位改進方案
|
||||||
|
|
||||||
|
## 問題描述
|
||||||
|
|
||||||
|
原本的 `draft` 欄位被用於兩種不同目的,導致資料結構混亂:
|
||||||
|
|
||||||
|
1. **暫存沖帳分配** - 在個人沖帳流程中暫存使用者的沖帳金額分配
|
||||||
|
2. **歷史沖帳記錄** - 記錄已完成的沖帳明細
|
||||||
|
|
||||||
|
這導致兩種不同用途的資料互相覆蓋,造成資料不一致的問題。
|
||||||
|
|
||||||
|
## 改進方案
|
||||||
|
|
||||||
|
將原本的純陣列格式改為物件格式,包含兩個子陣列:
|
||||||
|
|
||||||
|
### 新的 draft 欄位格式
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"transfer_draft": [
|
||||||
|
{
|
||||||
|
"pro_order_detail_num": "訂單明細編號",
|
||||||
|
"reconcile": "沖帳金額"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pro_order_detail_items": [
|
||||||
|
{
|
||||||
|
"pro_order_detail_num": "訂單明細編號",
|
||||||
|
"reconcile": "沖帳金額",
|
||||||
|
"activity_name": "活動名稱",
|
||||||
|
"actitem_name": "項目名稱",
|
||||||
|
"price": "原始金額",
|
||||||
|
"register_date": "報名日期",
|
||||||
|
"order_no": "訂單編號"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1. `transfer_draft` - 暫存沖帳分配
|
||||||
|
**用途:**
|
||||||
|
- 在 `personal_reconcile.aspx` 中暫存使用者的沖帳金額分配
|
||||||
|
- 顯示 📝 圖示表示有暫存資料
|
||||||
|
- 支援「暫存」和「重新分配」功能
|
||||||
|
|
||||||
|
### 2. `pro_order_detail_items` - 沖帳明細記錄
|
||||||
|
**用途:**
|
||||||
|
- 在 `balance_reconcile.aspx` 中顯示歷史沖帳記錄
|
||||||
|
- 在 `balance_reconcile_query.aspx` 中顯示選取項目
|
||||||
|
- 包含完整的活動和項目資訊
|
||||||
|
|
||||||
|
## 向後相容性
|
||||||
|
|
||||||
|
程式碼會自動檢測格式並處理:
|
||||||
|
|
||||||
|
### 新格式(物件)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"transfer_draft": [...],
|
||||||
|
"pro_order_detail_items": [...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 舊格式(陣列)
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"pro_order_detail_num": "12345",
|
||||||
|
"reconcile": 5000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 修改的檔案
|
||||||
|
|
||||||
|
### personal_reconcile.aspx
|
||||||
|
- 更新 `loadFromDraftOrAutoDistribute()` 方法支援新舊格式
|
||||||
|
- 更新 `saveDraft()` 方法使用新格式
|
||||||
|
- 新增 `hasTransferDraft()` 方法檢查暫存資料
|
||||||
|
- 更新顯示邏輯使用新格式
|
||||||
|
|
||||||
|
### balance_reconcile.aspx
|
||||||
|
- 更新歷史記錄載入邏輯支援新格式
|
||||||
|
- 更新詳細資訊顯示邏輯支援新格式
|
||||||
|
- 保持向後相容性
|
||||||
|
|
||||||
|
### balance_reconcile_query.aspx
|
||||||
|
- 更新 `getDraftItems()` 方法支援新舊格式
|
||||||
|
- 更新項目顯示邏輯
|
||||||
|
|
||||||
|
## 資料安全保護機制
|
||||||
|
|
||||||
|
為了確保 `transfer_draft` 和 `pro_order_detail_items` 的操作互不影響,實作了以下保護機制:
|
||||||
|
|
||||||
|
### 1. 統一工具函數
|
||||||
|
所有頁面都使用統一的 `draft-utils.js` 工具函數:
|
||||||
|
- `window.DraftUtils.getDraftObject(draft)` - 安全解析 draft 欄位
|
||||||
|
- `window.DraftUtils.getDraftField(draft, fieldName)` - 安全取得特定欄位
|
||||||
|
- `window.DraftUtils.updateDraftField(draft, fieldName, newValue)` - 安全更新特定欄位
|
||||||
|
- `window.DraftUtils.hasTransferDraft(draft)` - 檢查是否有暫存資料
|
||||||
|
- `window.DraftUtils.hasProOrderDetailItems(draft)` - 檢查是否有歷史記錄
|
||||||
|
|
||||||
|
### 2. 操作範例
|
||||||
|
|
||||||
|
**更新 transfer_draft(不會影響 pro_order_detail_items):**
|
||||||
|
```javascript
|
||||||
|
const currentDraft = this.dialog.selected.draft || '';
|
||||||
|
const newTransferDraft = this.dialog.items
|
||||||
|
.filter(item => Number(item.reconcile) > 0)
|
||||||
|
.map(item => ({
|
||||||
|
pro_order_detail_num: item.num,
|
||||||
|
reconcile: Number(item.reconcile)
|
||||||
|
}));
|
||||||
|
|
||||||
|
const newDraftObj = window.DraftUtils.updateDraftField(currentDraft, 'transfer_draft', newTransferDraft);
|
||||||
|
```
|
||||||
|
|
||||||
|
**更新 pro_order_detail_items(不會影響 transfer_draft):**
|
||||||
|
```javascript
|
||||||
|
const currentDraft = item.draft || '';
|
||||||
|
const newDetailItems = [
|
||||||
|
{
|
||||||
|
pro_order_detail_num: "123",
|
||||||
|
reconcile: 5000,
|
||||||
|
activity_name: "法會",
|
||||||
|
actitem_name: "護持金"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const newDraftObj = window.DraftUtils.updateDraftField(currentDraft, 'pro_order_detail_items', newDetailItems);
|
||||||
|
```
|
||||||
|
|
||||||
|
**檢查是否有暫存資料:**
|
||||||
|
```javascript
|
||||||
|
if (window.DraftUtils.hasTransferDraft(item.draft)) {
|
||||||
|
console.log('有暫存資料');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**取得特定欄位:**
|
||||||
|
```javascript
|
||||||
|
const transferDraft = window.DraftUtils.getDraftField(item.draft, 'transfer_draft');
|
||||||
|
const detailItems = window.DraftUtils.getDraftField(item.draft, 'pro_order_detail_items');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 統一工具檔案
|
||||||
|
建立了 `draft-utils.js` 統一工具檔案,所有頁面都引用此檔案:
|
||||||
|
- 所有 draft 操作函數統一管理
|
||||||
|
- 格式驗證功能
|
||||||
|
- 向後相容性處理
|
||||||
|
- 詳細的使用範例
|
||||||
|
- 避免程式碼重複,提升維護性
|
||||||
|
|
||||||
|
### 4. 頁面引用方式
|
||||||
|
每個 `.aspx` 頁面都在 `<script>` 標籤前加入:
|
||||||
|
```html
|
||||||
|
<script src="draft-utils.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
然後使用 `window.DraftUtils` 來呼叫工具函數,確保所有頁面使用相同的邏輯。
|
||||||
|
|
||||||
|
### 5. 完整工具函數清單
|
||||||
|
`draft-utils.js` 提供以下工具函數:
|
||||||
|
|
||||||
|
**基本操作:**
|
||||||
|
- `getDraftObject(draft)` - 解析 draft 欄位,返回標準化物件
|
||||||
|
- `getDraftField(draft, fieldName)` - 安全取得特定欄位
|
||||||
|
- `updateDraftField(draft, fieldName, newValue)` - 安全更新特定欄位
|
||||||
|
- `clearDraftField(draft, fieldName)` - 清除特定欄位
|
||||||
|
|
||||||
|
**檢查函數:**
|
||||||
|
- `hasTransferDraft(draft)` - 檢查是否有暫存資料
|
||||||
|
- `hasProOrderDetailItems(draft)` - 檢查是否有歷史記錄
|
||||||
|
|
||||||
|
**工具函數:**
|
||||||
|
- `mergeDraftObjects(draft1, draft2)` - 合併兩個 draft 物件
|
||||||
|
- `validateDraftFormat(draft)` - 驗證 draft 格式
|
||||||
|
- `getDraftSummary(draft)` - 取得 draft 摘要資訊
|
||||||
|
- `migrateLegacyFormat(draft)` - 將舊格式轉換為新格式
|
||||||
|
- `cleanEmptyDraft(draft)` - 清理空的 draft 欄位
|
||||||
|
- `formatDraftJson(draft)` - 格式化 draft JSON 為可讀字串
|
||||||
|
|
||||||
|
## 優點
|
||||||
|
|
||||||
|
1. **職責分離** - 每個子陣列有明確的用途
|
||||||
|
2. **資料一致性** - 避免不同用途的資料互相覆蓋
|
||||||
|
3. **向後相容** - 支援舊格式,無需資料庫變更
|
||||||
|
4. **易於維護** - 程式碼邏輯更清晰
|
||||||
|
5. **擴展性** - 未來可以添加更多子陣列
|
||||||
|
6. **資料安全** - 確保各欄位操作互不影響
|
||||||
|
7. **程式碼統一** - 所有頁面使用相同的工具函數
|
||||||
|
8. **功能完整** - 提供豐富的工具函數支援各種操作需求
|
||||||
79
data/memo/memo-0606.txt
Normal file
79
data/memo/memo-0606.txt
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
http://localhost:33051/admin/transfer/register.aspx
|
||||||
|
法會名稱 --> 活動名稱, (或帶活動ID, 只顯示, 不選)
|
||||||
|
要有"不確定, 待查"選項, 區隔出空值
|
||||||
|
|
||||||
|
"匯款"帳號後五碼 (註明: 若無免填)
|
||||||
|
|
||||||
|
付款 -> 支付
|
||||||
|
|
||||||
|
http://localhost:33051/admin/transfer/verify.aspx
|
||||||
|
狀態:
|
||||||
|
己確認: 人/錢 , 分開
|
||||||
|
增加: 查詢功能, 狀態過濾, 期間
|
||||||
|
(經查詢, 可把作廢資料調回, 注意: 帳已完成不可回溯)
|
||||||
|
|
||||||
|
階段1: 也要輸入核對記錄, 值:共用
|
||||||
|
|
||||||
|
階段12 -> 程序1,2
|
||||||
|
2-> 2A, 2B :
|
||||||
|
2A : 有報名 (目前)
|
||||||
|
2B : 無報名 (待討論, 屬於勸募活動及一般性捐款)
|
||||||
|
|
||||||
|
"已"確認, 作廢 -> 不要"已"
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
## 11:19 🥬ྀྀི 鈺
|
||||||
|
請問複製以往報名為什麼沒有清明法會的紀錄
|
||||||
|
|
||||||
|
## 19:46 Allen Wang (王振邦)
|
||||||
|
請確認複製信眾以往報名資料,是否只會帶入信眾最近一次參加的法會
|
||||||
|
(例如沒參加今年清明法會,但有參加過去年梁皇法會,所以只出現梁皇法會)。
|
||||||
|
請再確認協助讓同仁釐清邏輯。
|
||||||
|
|
||||||
|
### 翻頁問題
|
||||||
|
|
||||||
|
## 19:55 Allen Wang (王振邦)
|
||||||
|
明日會議一樣維持10:30,討論項目如下:
|
||||||
|
1. 法會功德款收款及對帳功能進度。
|
||||||
|
2. 不是講堂法會報名,僅列印牌位的處理方式。
|
||||||
|
(稍晚再將今日齋僧大會列印牌位問題詳列)
|
||||||
|
|
||||||
|
## 20:27 Allen Wang (王振邦)
|
||||||
|
今日處理齋僧大會僅列印牌位議題說明如下:
|
||||||
|
|
||||||
|
### 一、有關處理僅列印牌位,
|
||||||
|
信眾報名法會帶入過往報名法會資料,系統功能待查問題:
|
||||||
|
1. 複製過往法會信眾報名資料,只出現信眾前次報名法會,無法彈性選擇過往法會。(確認邏輯)
|
||||||
|
2. 選擇過往法會報名信眾後,信眾的親友資料會有不完整現象。(查是否因只出現前次資料)
|
||||||
|
3. 複製過往信眾報名資料後,功德項目的牌位上功德項目與編號不要帶入,例如總功德主複製後總功德主及編號不要帶入。
|
||||||
|
4. 複製過往報名資料,牌位類型變更後,牌位內容版面需要調整,例如大牌位變更為隨喜牌位,版面需要人工修改。
|
||||||
|
|
||||||
|
### 二、基金會處理信眾報名的親友牌位資料問題:
|
||||||
|
再次重申取得信眾報名時親友稱謂是重要的,若不完整,
|
||||||
|
親屬、員工、其他等等混雜難以區分,當信眾要再次報名或只印牌位,只能人工確認,
|
||||||
|
若舊親友資料太多乾脆重建新建親友資料。
|
||||||
|
|
||||||
|
### 三、法會報名順序涉及系統功能及邏輯,
|
||||||
|
要再與各位說明清楚,目前順序如下:
|
||||||
|
1. 選擇法會
|
||||||
|
選擇要參加的法會(如果不是法會就要另建類似法會的活動)
|
||||||
|
2. 選擇功德項目
|
||||||
|
選擇要參加法會的功德項目,包含功德主及牌位類型。
|
||||||
|
3. 選擇或新建親友資料(同時校正親友存歿資料)。
|
||||||
|
|
||||||
|
### 四、有關只印牌位處理方式:
|
||||||
|
如果只要產出牌位,就不要在正常的法會報名程序處理,
|
||||||
|
目前用例行性牌位處理要再思考合理性及便利性。
|
||||||
|
|
||||||
|
---
|
||||||
|
# 因應調整:
|
||||||
|
https://demo2.eztrust.tw/17168erp_e/admin/order/reg.aspx?order_no=AA2506130012
|
||||||
|
編輯牌位 , "可選" , 加上"稱謂"
|
||||||
|
|
||||||
|
https://demo2.eztrust.tw/17168erp_e/admin/follower/reg.aspx?num=17691
|
||||||
|
親友名單, 載入
|
||||||
|
|
||||||
|
https://demo2.eztrust.tw/17168erp_e/admin/order/reg.aspx?order_no=AA2506130012
|
||||||
|
複製以往報名 : 訂單編號/牌位項目/活動: 合一欄,
|
||||||
|
加一欄:標題/陽上
|
||||||
41
data/memo/memo-0714.md
Normal file
41
data/memo/memo-0714.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# localhost
|
||||||
|
url: http://localhost:33051/admin/index.aspx
|
||||||
|
path: D:\dev\ez\17168erp\git_gitea\web\index.htm
|
||||||
|
sql: localhost, 17168erp_e2
|
||||||
|
|
||||||
|
# demo2: /17168erp , 測試資料, 最新DB(20250714)
|
||||||
|
sql: demo2, 17168ERP_2022
|
||||||
|
|
||||||
|
# demo2: /17168erp_e , 正式資料
|
||||||
|
sql: demo2, 17168ERP_e2
|
||||||
|
結構:待更新為最新結構
|
||||||
|
|
||||||
|
# demo2: /17168erp_t
|
||||||
|
sql: demo2, 17168ERP_t
|
||||||
|
|
||||||
|
--
|
||||||
|
#GITEE
|
||||||
|
https://git.hcu.edu.tw/user/login
|
||||||
|
yiming
|
||||||
|
XrxCAdgX3BwMc6r
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
新程式上傳:
|
||||||
|
https://demo2.eztrust.tw/17168erp_t/admin
|
||||||
|
此區: 新程式測試區, DB為新架構, 測試資料
|
||||||
|
新功能: 權限設定進行中
|
||||||
|
|
||||||
|
https://demo2.eztrust.tw/17168erp_e/admin/
|
||||||
|
此區: 正式資料, 前版程式,
|
||||||
|
等"新程式測試區"設定好, 此區更新結構, 不動現有資料
|
||||||
|
|
||||||
|
GIT:
|
||||||
|
己合併各分支於:main
|
||||||
|
最新結構不含資料:
|
||||||
|
~\data\SQL\17168_db_schema.sql
|
||||||
|
|
||||||
|
最新結構含測試資料:
|
||||||
|
另傳雲端連結給開杰
|
||||||
|
https://drive.google.com/file/d/1eefpyIdGjbQInSSDp7FrNGiFSD1sQ4q6/view?usp=sharing
|
||||||
|
|
||||||
218
data/memo/memo_plan_pay.md
Normal file
218
data/memo/memo_plan_pay.md
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
# DOCS
|
||||||
|
|
||||||
|
## files
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\activity\index.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\follower\index.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\follower\reg.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\order\index.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\order\reg.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\accounting\kind_reg.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\accounting\kind_reg2.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\accounting\index.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\accounting\news_reg.aspx.cs
|
||||||
|
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\App_Code\api\orderController.cs
|
||||||
|
|
||||||
|
## DESC
|
||||||
|
|
||||||
|
### 檔案主要功能說明
|
||||||
|
|
||||||
|
1. `activity/index.aspx.cs`:活動管理系統主頁,負責活動分類建立、管理及活動資料匯出Excel。
|
||||||
|
2. `follower/index.aspx.cs`:信眾管理系統主頁,負責信眾資料查詢、管理及匯出。
|
||||||
|
3. `order/index.aspx.cs`、`order/reg.aspx.cs`:訂單管理系統,負責訂單查詢與登記。
|
||||||
|
4. `accounting/index.aspx.cs`:會計系統主頁。
|
||||||
|
5. `accounting/kind_reg.aspx.cs`、`kind_reg2.aspx.cs`:會計科目分類登記。
|
||||||
|
6. `accounting/news_reg.aspx.cs`:會計相關新聞或公告登記。
|
||||||
|
|
||||||
|
系統採用 ASP.NET Web Forms 與 Entity Framework,涵蓋信眾、活動、訂單、會計等模組。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 訂單收款記錄管理作業流程
|
||||||
|
|
||||||
|
1. 使用者點擊「收款紀錄」按鈕,開啟對話框並呼叫 `payOrderList2()` 載入資料。
|
||||||
|
2. 前端檢查訂單編號與明細編號,設定分頁參數,呼叫API取得收款記錄。
|
||||||
|
3. 後端API接收查詢條件,查詢 `pro_order_record`,回傳付款日期、方式、金額、機構、銀行代碼等資訊。
|
||||||
|
4. 前端以Vuetify資料表格顯示收款記錄,支援搜尋、分頁、排序。
|
||||||
|
5. 支援新增、編輯、刪除收款記錄。
|
||||||
|
6. 表格排序或分頁設定改變時自動重新載入資料。
|
||||||
|
|
||||||
|
用途:追蹤訂單收款狀況、管理多筆收款記錄、查詢與管理介面、支援多種付款方式。
|
||||||
|
|
||||||
|
---
|
||||||
|
# 功能延伸
|
||||||
|
|
||||||
|
## 信眾-登錄匯款
|
||||||
|
|
||||||
|
### TABLE結構
|
||||||
|
|
||||||
|
新增暫存表 `remittance_register_tmp`:
|
||||||
|
|
||||||
|
| 欄位名稱 | 型態 | 說明 |
|
||||||
|
|------------------|----------------|----------------------------|
|
||||||
|
| id | int, PK, AI | 主鍵,自動編號 |
|
||||||
|
| activity_id | int | 對應法會/活動ID(可選) |
|
||||||
|
| name | nvarchar(50) | 姓名/暱稱/法號 |
|
||||||
|
| phone | nvarchar(30) | 聯絡電話 |
|
||||||
|
| pay_type | nvarchar(20) | 付款方式(現金/匯款等) |
|
||||||
|
| account_last5 | nvarchar(10) | 帳號後五碼 |
|
||||||
|
| amount | decimal(12,2) | 付款金額 |
|
||||||
|
| pay_mode | nvarchar(10) | 付款型態(個人/共同) |
|
||||||
|
| note | nvarchar(200) | 備註 |
|
||||||
|
| proof_img | nvarchar(200) | 憑證圖檔路徑 |
|
||||||
|
| status | nvarchar(20) | 狀態(待核對/已入帳/作廢) |
|
||||||
|
| create_time | datetime | 建立時間 |
|
||||||
|
| verify_time | datetime | 核對/入帳時間 |
|
||||||
|
| verify_user | nvarchar(50) | 核對人員 |
|
||||||
|
| verify_note | nvarchar(200) | 核對說明 |
|
||||||
|
| recaptcha_token | nvarchar(200) | reCAPTCHA驗證(可選) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 畫面設計說明
|
||||||
|
|
||||||
|
1. 進入方式:法會/活動頁面連結或QRcode進入,可帶入活動ID參數。
|
||||||
|
2. 表單欄位:姓名(可匿名/暱稱/法號)、電話、付款方式、帳號後5碼、付款金額、付款型態、備註、匯款憑證上傳、reCAPTCHA驗證。
|
||||||
|
3. 操作流程:填寫表單送出,資料以JSON送API,成功後顯示訊息或QRcode,所有資料進入暫存表,不直接入帳,後台人工核對後正式入帳。
|
||||||
|
4. 設計重點:手機友善、圖片上傳、送出後明確回饋、不強制檢查資料正確性但利於後續人工核對、加reCAPTCHA防灌單。
|
||||||
|
|
||||||
|
---
|
||||||
|
## 核對入帳資訊
|
||||||
|
|
||||||
|
### TABLE結構說明
|
||||||
|
|
||||||
|
主表 `remittance_check`,記錄每筆待核對與已核對入帳資料。
|
||||||
|
|
||||||
|
| 欄位名稱 | 型態 | 說明 |
|
||||||
|
|------------------|----------------|----------------------------------------|
|
||||||
|
| id | int, PK, AI | 主鍵,自動編號 |
|
||||||
|
| tmp_id | int | 對應暫存登錄表(remittance_register_tmp)的ID |
|
||||||
|
| match_signup_id | int | 自動或人工比對到的報名信眾ID |
|
||||||
|
| match_status | nvarchar(20) | 比對狀態(自動/人工/未比對) |
|
||||||
|
| pay_type | nvarchar(20) | 付款方式(登錄資料) |
|
||||||
|
| account_last5 | nvarchar(10) | 帳號後五碼(登錄資料) |
|
||||||
|
| amount | decimal(12,2) | 付款金額(登錄資料) |
|
||||||
|
| payer_name | nvarchar(50) | 付款人/登錄人(登錄資料) |
|
||||||
|
| phone | nvarchar(30) | 電話(登錄資料) |
|
||||||
|
| proof_img | nvarchar(200) | 憑證圖檔路徑 |
|
||||||
|
| check_amount | decimal(12,2) | 實際入帳金額(出納填寫) |
|
||||||
|
| check_date | datetime | 入帳日期(出納填寫) |
|
||||||
|
| check_type | nvarchar(20) | 入帳方式(出納填寫) |
|
||||||
|
| check_note | nvarchar(200) | 入帳備註(出納填寫) |
|
||||||
|
| status | nvarchar(20) | 狀態(待核對/已確認/無效/沖帳) |
|
||||||
|
| create_time | datetime | 建立時間 |
|
||||||
|
| update_time | datetime | 最後更新時間 |
|
||||||
|
| verify_user | nvarchar(50) | 核對人員 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 畫面設計說明
|
||||||
|
|
||||||
|
1. 資料來源與自動比對:左側顯示信眾登錄匯款資訊,系統自動比對報名信眾,結果顯示於DE欄,若失敗可手動選擇。
|
||||||
|
2. 付款資訊與核對欄位:F~J欄顯示報名者填寫的付款資訊,K~O欄由出納填寫實際入帳資料。
|
||||||
|
3. 核對狀態管理:O欄標註「確認」或「無效」後,該筆資料完成核對,下次不再顯示,未完成資料持續顯示。
|
||||||
|
4. 輔助說明與操作提示:下方提供人工核對重點、注意事項、歷史紀錄查詢、憑證比對等輔助說明,支援人工補正、標註特殊狀況。
|
||||||
|
5. 沖帳與分攤明細:支援沖帳與分攤金額明細管理,方便人工確認。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 個人-沖帳流程
|
||||||
|
|
||||||
|
### TABLE結構說明
|
||||||
|
|
||||||
|
沖帳結果寫入 `pro_order_record`:
|
||||||
|
|
||||||
|
| 欄位名稱 | 型態 | 說明 |
|
||||||
|
|------------------|----------------|----------------------------------------|
|
||||||
|
| num | int, PK, AI | 主鍵,自動編號 |
|
||||||
|
| detail_num | int | 對應訂單明細(pro_order_detail)的ID |
|
||||||
|
| price | decimal(12,2) | 沖帳金額 |
|
||||||
|
| payment | int | 付款方式(對應會計科目細分類ID) |
|
||||||
|
| reg_time | datetime | 沖帳登記時間 |
|
||||||
|
| pay_date | datetime | 實際付款日期 |
|
||||||
|
| organization | nvarchar(100) | 匯款機構/銀行名稱 |
|
||||||
|
| bank_code | nvarchar(20) | 銀行代碼 |
|
||||||
|
| status | nvarchar(20) | 狀態(有效/作廢等) |
|
||||||
|
| note | nvarchar(200) | 備註 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 畫面設計說明
|
||||||
|
|
||||||
|
1. 信眾沖帳清單:左側顯示所有待沖帳信眾及其入帳金額與沖帳狀態,點選信眾後彈出沖帳分配視窗。
|
||||||
|
2. 彈窗內容:顯示信眾所有有報名但尚未完成繳費的項目清單,可自動分配入帳金額,也可人工調整分攤金額,支援部分繳費、溢繳、未繳等情境,並即時顯示分攤結果。
|
||||||
|
3. 沖帳操作:可調整每個項目的沖帳金額,總金額需與入帳金額一致才能送出,確認後寫入 `pro_order_record`,完成核銷,沖帳完成後狀態更新避免重複處理。
|
||||||
|
4. 輔助說明與彈性設計:下方提供沖帳規則、人工調整注意事項、分攤原則等輔助說明,支援查詢歷史沖帳紀錄。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# TABLE CREATE SQL
|
||||||
|
```
|
||||||
|
-- 信眾-登錄匯款暫存表
|
||||||
|
CREATE TABLE remittance_register_tmp (
|
||||||
|
id INT IDENTITY(1,1) PRIMARY KEY COMMENT '主鍵,自動編號',
|
||||||
|
activity_id INT NULL COMMENT '對應法會/活動ID(可選)',
|
||||||
|
name NVARCHAR(50) NOT NULL COMMENT '姓名/暱稱/法號',
|
||||||
|
phone NVARCHAR(30) NULL COMMENT '聯絡電話',
|
||||||
|
pay_type NVARCHAR(20) NOT NULL COMMENT '付款方式(現金/匯款等)',
|
||||||
|
account_last5 NVARCHAR(10) NULL COMMENT '帳號後五碼',
|
||||||
|
amount DECIMAL(12,2) NOT NULL COMMENT '付款金額',
|
||||||
|
pay_mode NVARCHAR(10) NOT NULL COMMENT '付款型態(個人/共同)',
|
||||||
|
note NVARCHAR(200) NULL COMMENT '備註',
|
||||||
|
proof_img NVARCHAR(200) NULL COMMENT '憑證圖檔路徑',
|
||||||
|
status NVARCHAR(20) NOT NULL DEFAULT '待核對' COMMENT '狀態(待核對/已入帳/作廢)',
|
||||||
|
create_time DATETIME NOT NULL DEFAULT GETDATE() COMMENT '建立時間',
|
||||||
|
verify_time DATETIME NULL COMMENT '核對/入帳時間',
|
||||||
|
verify_user NVARCHAR(50) NULL COMMENT '核對人員',
|
||||||
|
verify_note NVARCHAR(200) NULL COMMENT '核對說明',
|
||||||
|
recaptcha_token NVARCHAR(200) NULL COMMENT 'reCAPTCHA驗證(可選)'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 入帳核對主表
|
||||||
|
CREATE TABLE remittance_check (
|
||||||
|
id INT IDENTITY(1,1) PRIMARY KEY COMMENT '主鍵,自動編號',
|
||||||
|
tmp_id INT NOT NULL COMMENT '對應暫存登錄表(remittance_register_tmp)的ID',
|
||||||
|
match_signup_id INT NULL COMMENT '自動或人工比對到的報名信眾ID',
|
||||||
|
match_status NVARCHAR(20) NOT NULL DEFAULT '未比對' COMMENT '比對狀態(自動/人工/未比對)',
|
||||||
|
pay_type NVARCHAR(20) NOT NULL COMMENT '付款方式(登錄資料)',
|
||||||
|
account_last5 NVARCHAR(10) NULL COMMENT '帳號後五碼(登錄資料)',
|
||||||
|
amount DECIMAL(12,2) NOT NULL COMMENT '付款金額(登錄資料)',
|
||||||
|
payer_name NVARCHAR(50) NULL COMMENT '付款人/登錄人(登錄資料)',
|
||||||
|
phone NVARCHAR(30) NULL COMMENT '電話(登錄資料)',
|
||||||
|
proof_img NVARCHAR(200) NULL COMMENT '憑證圖檔路徑',
|
||||||
|
check_amount DECIMAL(12,2) NULL COMMENT '實際入帳金額(出納填寫)',
|
||||||
|
check_date DATETIME NULL COMMENT '入帳日期(出納填寫)',
|
||||||
|
check_type NVARCHAR(20) NULL COMMENT '入帳方式(出納填寫)',
|
||||||
|
check_note NVARCHAR(200) NULL COMMENT '入帳備註(出納填寫)',
|
||||||
|
status NVARCHAR(20) NOT NULL DEFAULT '待核對' COMMENT '狀態(待核對/已確認/無效/沖帳)',
|
||||||
|
create_time DATETIME NOT NULL DEFAULT GETDATE() COMMENT '建立時間',
|
||||||
|
update_time DATETIME NULL COMMENT '最後更新時間',
|
||||||
|
verify_user NVARCHAR(50) NULL COMMENT '核對人員'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 個人沖帳紀錄表
|
||||||
|
CREATE TABLE pro_order_record (
|
||||||
|
num INT IDENTITY(1,1) PRIMARY KEY COMMENT '主鍵,自動編號',
|
||||||
|
detail_num INT NOT NULL COMMENT '對應訂單明細(pro_order_detail)的ID',
|
||||||
|
price DECIMAL(12,2) NOT NULL COMMENT '沖帳金額',
|
||||||
|
payment INT NOT NULL COMMENT '付款方式(對應會計科目細分類ID)',
|
||||||
|
reg_time DATETIME NOT NULL DEFAULT GETDATE() COMMENT '沖帳登記時間',
|
||||||
|
pay_date DATETIME NULL COMMENT '實際付款日期',
|
||||||
|
organization NVARCHAR(100) NULL COMMENT '匯款機構/銀行名稱',
|
||||||
|
bank_code NVARCHAR(20) NULL COMMENT '銀行代碼',
|
||||||
|
status NVARCHAR(20) NOT NULL DEFAULT '有效' COMMENT '狀態(有效/作廢等)',
|
||||||
|
note NVARCHAR(200) NULL COMMENT '備註'
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
# HTML 檔名及路徑規劃
|
||||||
|
|
||||||
|
| 功能 | 建議檔名/路徑 | 說明 |
|
||||||
|
|----------------------|----------------------------------------------------|--------------------------|
|
||||||
|
| 信眾-登錄匯款 | `/web/transfer/register.html` | 信眾匯款登錄前台 |
|
||||||
|
| 核對入帳資訊 | `/web/admin/finance/remit_check.html` | 後台入帳核對作業 |
|
||||||
|
| 個人-沖帳流程 | `/web/admin/finance/personal_offset.html` | 後台個人沖帳分攤 |
|
||||||
|
| 共同-沖帳流程 | `/web/admin/finance/group_offset.html` | 後台多人/批次沖帳 |
|
||||||
|
| 訂單收款紀錄 | `/web/admin/order/reg.aspx` | 現有訂單收款紀錄 |
|
||||||
|
|
||||||
|
前台頁面可用 `.html` 或 `.aspx`,依現有架構調整。後台建議統一於 `/web/admin/finance/` 目錄下,便於管理。API建議集中於 `/web/App_Code/api/`。
|
||||||
299
data/memo/共同-沖帳流程.md
Normal file
299
data/memo/共同-沖帳流程.md
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
# 0718 MEMO
|
||||||
|
餘額->溢繳
|
||||||
|
千位點..一致
|
||||||
|
---
|
||||||
|
共同-沖帳流程
|
||||||
|
- 基本流程: 類似個人沖帳流程的擴充
|
||||||
|
- 進入時: 抓取: 原本登錄時, 指定為共同支付, 且:己確認入帳/未完成沖帳的項目
|
||||||
|
- 欄位:基本上跟"個人沖帳"相同
|
||||||
|
- 最後的:沖帳按鈕欄前面加2欄:
|
||||||
|
1. 法會名稱(依登錄時指定)
|
||||||
|
2. 選擇共同支付人(彈出視窗選擇)
|
||||||
|
- 選擇共同支付人 彈出視窗:
|
||||||
|
- 列出: 該場法會, 有報名單(pro_order), 且有未完成沖帳項目(pro_order_detail)的信眾
|
||||||
|
- 可搜尋: 姓名, 可勾選
|
||||||
|
- 確認後, 傳回勾選的信眾名單, 存在draft欄位, 新的列表{..:[],..:[], "follower_list":[]}
|
||||||
|
- 並更新到資料庫該項transfer_register的draft欄位
|
||||||
|
- 按沖帳時彈出視窗:
|
||||||
|
- 列出: 共同支付人名單, 在該場法會報名, 未完成沖帳的項目, 應繳/已繳/待繳金額
|
||||||
|
- 因為是多人報名, 故要加一欄: 報名人(名字), 加連結開新頁籤, 連到該信眾頁面
|
||||||
|
- 輸入欄位: 沖帳金額(也是先進先出, 沖各筆:待繳金額)
|
||||||
|
- 上方入帳金額試算:入帳金額,已沖金額,未繳餘款,入帳後餘額: 類似個人沖帳
|
||||||
|
- 下方: 提示沖帳狀況資訊: 類似個人沖帳的提示
|
||||||
|
- 下方按鈕: 重新分配, 暫存, 確認沖帳
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 補充
|
||||||
|
|
||||||
|
我來分析這些檔案,看看共同沖帳流程的規劃是否有不清楚的地方需要討論或補充。
|
||||||
|
|
||||||
|
Read file: admin/transfer/group_reconcile.aspx
|
||||||
|
Ran tool
|
||||||
|
Read file: admin/transfer/group_reconcile.aspx.cs
|
||||||
|
根據我對這些檔案的分析,我發現共同沖帳流程的規劃有以下幾個不清楚或需要討論/補充的地方:
|
||||||
|
|
||||||
|
## 需要討論/補充的問題
|
||||||
|
|
||||||
|
### 1. **資料載入邏輯不清楚**
|
||||||
|
- 參考:
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\App_Code\api\transfer_registerController.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\transfer\personal_reconcile.aspx
|
||||||
|
- **需要確認**:
|
||||||
|
- 如何查詢 `pay_mode == "共同"` 的 `transfer_register` 記錄?
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\transfer\register.aspx
|
||||||
|
- 是否需要新增 `group_reconcile_list` API?
|
||||||
|
放在:transfer_registerController
|
||||||
|
|
||||||
|
### 2. **共同支付人選擇邏輯需要明確**
|
||||||
|
- **問題**:MD 文件中提到「選擇共同支付人彈出視窗」,但具體邏輯不清楚
|
||||||
|
- **需要確認**:
|
||||||
|
- 如何定義「該場法會有報名單且有未完成沖帳項目的信眾」?
|
||||||
|
參考TABLE: pro_order, pro_order_detail, pro_order_record
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\order\index.aspx
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\order\index.aspx.cs
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\order\reg.aspx
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\order\reg.aspx.cs
|
||||||
|
- 是否需要新增 `get_activity_followers` API?
|
||||||
|
在:transfer_registerController
|
||||||
|
- 選擇的信眾名單如何儲存到 `draft` 欄位?
|
||||||
|
D:\dev\ez\17168erp\git_gitea\web\admin\transfer\draft-utils.js
|
||||||
|
現已有2個清單, 再加一個
|
||||||
|
|
||||||
|
### 3. **沖帳明細查詢邏輯需要明確**
|
||||||
|
- **問題**:MD 文件中提到「列出共同支付人名單在該場法會報名未完成沖帳的項目」
|
||||||
|
- **需要確認**:
|
||||||
|
- 是否需要新增 `group_follower_orders` API?
|
||||||
|
在:transfer_registerController
|
||||||
|
- 如何處理多個信眾的訂單明細?
|
||||||
|
合併為單一表格, 同一信眾的在一起(排序)
|
||||||
|
- 是否需要顯示「報名人」欄位?
|
||||||
|
要
|
||||||
|
|
||||||
|
### 4. **draft 欄位格式需要定義**
|
||||||
|
- **問題**:MD 文件中提到 `draft` 欄位格式為 `{..:[],..:[], "follower_list":[]}`
|
||||||
|
- **需要確認**:
|
||||||
|
- 具體的 JSON 結構是什麼?
|
||||||
|
- 是否需要修改 `draft-utils.js` 來支援共同沖帳格式?
|
||||||
|
都參考draft-utils.js, 並擴充
|
||||||
|
|
||||||
|
### 5. **沖帳 API 需要擴充**
|
||||||
|
- **問題**:目前的 `reconcile` API 只處理個人沖帳
|
||||||
|
- **需要確認**:
|
||||||
|
- 是否需要新增 `group_reconcile` API?
|
||||||
|
在:transfer_registerController
|
||||||
|
- 如何處理多個信眾的沖帳記錄?
|
||||||
|
請規劃
|
||||||
|
- 是否需要修改 `pro_order_record` 的建立邏輯?
|
||||||
|
請評估
|
||||||
|
|
||||||
|
### 6. **UI 架構需要統一**
|
||||||
|
- **問題**:`group_reconcile.aspx` 使用 Bootstrap,而 `personal_reconcile.aspx` 使用 Vuetify
|
||||||
|
- **需要確認**:
|
||||||
|
- 是否要統一使用 Vuetify?
|
||||||
|
都是Vuetify, Bootstrap只是MOCKUP
|
||||||
|
- 是否需要重新設計 UI 架構?
|
||||||
|
使用類似的UI
|
||||||
|
|
||||||
|
### 7. **狀態管理需要明確**
|
||||||
|
- **問題**:共同沖帳完成後的狀態變化不清楚
|
||||||
|
- **需要確認**:
|
||||||
|
- 狀態是否與個人沖帳相同(90/99)?
|
||||||
|
- 是否需要特殊的狀態碼?
|
||||||
|
請評估, 我認為可以一樣
|
||||||
|
|
||||||
|
## 建議的討論重點
|
||||||
|
|
||||||
|
1. **API 設計**:需要定義哪些新的 API 端點?
|
||||||
|
2. **資料結構**:`draft` 欄位的 JSON 格式如何定義?
|
||||||
|
3. **UI 架構**:是否要重新設計 `group_reconcile.aspx`?
|
||||||
|
4. **業務邏輯**:共同支付人的選擇和沖帳邏輯如何實現?
|
||||||
|
5. **資料關聯**:如何處理多個信眾的訂單明細關聯?
|
||||||
|
|
||||||
|
您希望先討論哪個部分?或者有其他需要補充的地方嗎?
|
||||||
|
|
||||||
|
---
|
||||||
|
我來逐一評估每個問題的回答,並提出進一步的分析:
|
||||||
|
|
||||||
|
## 1. **資料載入邏輯不清楚**
|
||||||
|
- ✅ 查詢 `pay_mode == "共同"` 的 `transfer_register` 記錄
|
||||||
|
- ✅ 新增 `group_reconcile_list` API 在 transfer_registerController
|
||||||
|
|
||||||
|
**評估:** 邏輯清楚,需要參考 `personal_reconcile_list` API 的結構
|
||||||
|
|
||||||
|
## 2. **共同支付人選擇邏輯需要明確**
|
||||||
|
- ✅ 參考 pro_order, pro_order_detail, pro_order_record 資料表
|
||||||
|
- ✅ 新增 `get_activity_followers` API 在 transfer_registerController
|
||||||
|
- ✅ 使用 draft-utils.js,新增第三個清單欄位
|
||||||
|
|
||||||
|
**評估:** 需要明確定義「未完成沖帳項目」的查詢條件
|
||||||
|
|
||||||
|
## 3. **沖帳明細查詢邏輯需要明確**
|
||||||
|
- ✅ 新增 `group_follower_orders` API 在 transfer_registerController
|
||||||
|
- ✅ 合併為單一表格,同一信眾的在一起排序
|
||||||
|
- ✅ 需要顯示「報名人」欄位
|
||||||
|
|
||||||
|
**評估:** 邏輯合理,需要設計排序和分組顯示
|
||||||
|
|
||||||
|
## 4. **draft 欄位格式需要定義**
|
||||||
|
- ✅ 參考並擴充 draft-utils.js
|
||||||
|
|
||||||
|
**評估:** 需要具體定義 JSON 結構格式
|
||||||
|
|
||||||
|
## 5. **沖帳 API 需要擴充**
|
||||||
|
- ✅ 新增 `group_reconcile` API 在 transfer_registerController
|
||||||
|
- ❓ 需要規劃多個信眾的沖帳記錄處理
|
||||||
|
- ❓ 需要評估 pro_order_record 建立邏輯
|
||||||
|
|
||||||
|
**評估:** 關鍵問題,需要詳細設計
|
||||||
|
|
||||||
|
## 6. **UI 架構需要統一**
|
||||||
|
- ✅ 統一使用 Vuetify
|
||||||
|
- ✅ 使用類似 personal_reconcile.aspx 的 UI
|
||||||
|
|
||||||
|
**評估:** 明確,需要重新設計 group_reconcile.aspx
|
||||||
|
|
||||||
|
## 7. **狀態管理需要明確**
|
||||||
|
- ✅ 使用與個人沖帳相同的狀態碼(90/99)
|
||||||
|
|
||||||
|
**評估:** 合理,可以複用現有邏輯
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 實作計劃
|
||||||
|
|
||||||
|
基於以上評估,我提出以下實作計劃:
|
||||||
|
|
||||||
|
### **階段一:後端 API 開發**
|
||||||
|
|
||||||
|
#### 1.1 新增 `group_reconcile_list` API
|
||||||
|
```csharp
|
||||||
|
// 查詢條件:pay_mode == "共同" && status == "2" && check_status == "2"
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/transfer_register/group_reconcile_list")]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2 新增 `get_activity_followers` API
|
||||||
|
```csharp
|
||||||
|
// 查詢指定法會中有未完成沖帳項目的信眾
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/transfer_register/activity_followers")]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.3 新增 `group_follower_orders` API
|
||||||
|
```csharp
|
||||||
|
// 查詢多個信眾在指定法會的未完成沖帳項目
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/transfer_register/group_follower_orders")]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.4 新增 `group_reconcile` API
|
||||||
|
```csharp
|
||||||
|
// 處理共同沖帳,建立多筆 pro_order_record
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/transfer_register/group_reconcile")]
|
||||||
|
```
|
||||||
|
|
||||||
|
### **階段二:draft 欄位格式設計**
|
||||||
|
|
||||||
|
#### 2.1 擴充 draft-utils.js
|
||||||
|
```javascript
|
||||||
|
// 新增 follower_list 欄位支援
|
||||||
|
{
|
||||||
|
"transfer_draft": [...],
|
||||||
|
"pro_order_detail_items": [...],
|
||||||
|
"follower_list": [
|
||||||
|
{
|
||||||
|
"f_num": 123,
|
||||||
|
"f_name": "張三",
|
||||||
|
"activity_num": 456
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **階段三:前端重構**
|
||||||
|
|
||||||
|
#### 3.1 重新設計 group_reconcile.aspx
|
||||||
|
- 使用 Vuetify 架構
|
||||||
|
- 參考 personal_reconcile.aspx 的 UI 設計
|
||||||
|
- 新增「選擇共同支付人」對話框
|
||||||
|
- 新增「沖帳明細」對話框,支援多信眾顯示
|
||||||
|
|
||||||
|
#### 3.2 主要功能
|
||||||
|
1. **主表格**:顯示 `pay_mode == "共同"` 的匯款記錄
|
||||||
|
2. **選擇支付人**:彈出視窗選擇該法會的信眾
|
||||||
|
3. **沖帳明細**:顯示所選信眾的未完成項目
|
||||||
|
4. **沖帳處理**:支援多信眾的沖帳分配
|
||||||
|
|
||||||
|
### **階段四:業務邏輯整合**
|
||||||
|
|
||||||
|
#### 4.1 沖帳記錄建立
|
||||||
|
- 每個信眾的每個項目建立獨立的 `pro_order_record`
|
||||||
|
- 所有記錄都關聯到同一個 `transfer_register.id`
|
||||||
|
- 使用相同的付款日期和銀行資訊
|
||||||
|
|
||||||
|
#### 4.2 狀態管理
|
||||||
|
- 使用現有的狀態碼(90:有剩餘,99:完成)
|
||||||
|
- 剩餘金額計算邏輯與個人沖帳相同
|
||||||
|
|
||||||
|
---
|
||||||
|
好的!我開始實作共同沖帳流程。我會按照計劃逐步實作,細節可以後續調整。
|
||||||
|
|
||||||
|
## 階段一:後端 API 開發
|
||||||
|
|
||||||
|
先新增後端 API:
|
||||||
|
## 階段二:擴充 draft-utils.js
|
||||||
|
讓我先檢查 draft-utils.js 的內容:
|
||||||
|
Read file: admin/transfer/draft-utils.js
|
||||||
|
現在我新增 follower_list 相關的函數到 draft-utils.js:
|
||||||
|
同時更新 Node.js 的匯出:
|
||||||
|
## 階段三:重新設計 group_reconcile.aspx
|
||||||
|
Read file: admin/transfer/group_reconcile.aspx
|
||||||
|
很好!頁面已經成功更新為 Vuetify 架構。現在讓我們建立一個測試用的TODO任務清單來追蹤實作進度:
|
||||||
|
Ran tool
|
||||||
|
## 🎉 階段性完成報告
|
||||||
|
|
||||||
|
我已經成功完成了共同沖帳流程的核心功能實作:
|
||||||
|
|
||||||
|
### ✅ 已完成項目
|
||||||
|
|
||||||
|
#### 1. 後端 API 開發
|
||||||
|
- `group_reconcile_list`:查詢共同支付的匯款記錄
|
||||||
|
- `activity_followers`:查詢法會中有未完成沖帳項目的信眾
|
||||||
|
- `group_follower_orders`:查詢多個信眾的訂單明細
|
||||||
|
- `group_reconcile`:處理共同沖帳,建立 pro_order_record
|
||||||
|
|
||||||
|
#### 2. draft-utils.js 擴充
|
||||||
|
- 新增 `hasFollowerList`、`getFollowerList`、`updateFollowerList` 函數
|
||||||
|
- 支援新的 draft 格式:`{ transfer_draft: [], pro_order_detail_items: [], follower_list: [] }`
|
||||||
|
|
||||||
|
#### 3. 前端重構
|
||||||
|
- 完全重新設計 `group_reconcile.aspx`,使用 Vuetify 架構
|
||||||
|
- 實作「選擇共同支付人」對話框
|
||||||
|
- 實作「共同沖帳明細」對話框
|
||||||
|
- 支援自動分配、重新分配、暫存、確認沖帳功能
|
||||||
|
|
||||||
|
### 🔧 主要功能特色
|
||||||
|
|
||||||
|
1. **兩階段流程**:
|
||||||
|
- 階段1:選擇該法會的共同支付人
|
||||||
|
- 階段2:分配沖帳金額到各個項目
|
||||||
|
|
||||||
|
2. **智能分配**:
|
||||||
|
- 先進先出自動分配沖帳金額
|
||||||
|
- 支援手動調整每個項目的沖帳金額
|
||||||
|
|
||||||
|
3. **資料暫存**:
|
||||||
|
- 選擇的支付人清單會儲存到 draft 欄位
|
||||||
|
- 支援暫存沖帳分配結果
|
||||||
|
|
||||||
|
4. **多信眾顯示**:
|
||||||
|
- 表格按信眾分組顯示
|
||||||
|
- 清楚顯示每個信眾的訂單資訊
|
||||||
|
|
||||||
|
### 📋 後續待測試項目
|
||||||
|
|
||||||
|
我已經建立了TODO清單來追蹤後續的測試和優化工作。現在可以開始測試功能了!
|
||||||
|
|
||||||
|
您想要先測試哪個部分?或者有什麼需要調整的地方嗎?
|
||||||
45
data/memo/掛單區樓層範例.json
Normal file
45
data/memo/掛單區樓層範例.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"東區": {
|
||||||
|
"慈悲樓": {
|
||||||
|
"慈悲樓1F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"慈悲樓2F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"慈悲樓3F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"慈悲樓4F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"慈悲樓5F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"]
|
||||||
|
},
|
||||||
|
"智慧舍": {
|
||||||
|
"智慧舍1F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"智慧舍2F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"智慧舍3F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"智慧舍4F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"智慧舍5F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"]
|
||||||
|
},
|
||||||
|
"禪悅樓": {
|
||||||
|
"禪悅樓1F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"禪悅樓2F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"禪悅樓3F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"禪悅樓4F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"],
|
||||||
|
"禪悅樓5F": ["R01", "R02", "R03", "R04", "R05", "R06", "R07", "R08", "R09", "R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R18", "R19", "R20"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"西區": {
|
||||||
|
"淨心樓": { "淨心樓1F": [...], "淨心樓2F": [...], "淨心樓3F": [...], "淨心樓4F": [...], "淨心樓5F": [...] },
|
||||||
|
"安忍舍": { "安忍舍1F": [...], "安忍舍2F": [...], "安忍舍3F": [...], "安忍舍4F": [...], "安忍舍5F": [...] },
|
||||||
|
"悲願樓": { "悲願樓1F": [...], "悲願樓2F": [...], "悲願樓3F": [...], "悲願樓4F": [...], "悲願樓5F": [...] }
|
||||||
|
},
|
||||||
|
"南區": {
|
||||||
|
"寧靜樓": { "寧靜樓1F": [...], "寧靜樓2F": [...], "寧靜樓3F": [...], "寧靜樓4F": [...], "寧靜樓5F": [...] },
|
||||||
|
"法雨舍": { "法雨舍1F": [...], "法雨舍2F": [...], "法雨舍3F": [...], "法雨舍4F": [...], "法雨舍5F": [...] },
|
||||||
|
"覺林樓": { "覺林樓1F": [...], "覺林樓2F": [...], "覺林樓3F": [...], "覺林樓4F": [...], "覺林樓5F": [...] }
|
||||||
|
},
|
||||||
|
"北區": {
|
||||||
|
"圓滿樓": { "圓滿樓1F": [...], "圓滿樓2F": [...], "圓滿樓3F": [...], "圓滿樓4F": [...], "圓滿樓5F": [...] },
|
||||||
|
"正念舍": { "正念舍1F": [...], "正念舍2F": [...], "正念舍3F": [...], "正念舍4F": [...], "正念舍5F": [...] },
|
||||||
|
"法華樓": { "法華樓1F": [...], "法華樓2F": [...], "法華樓3F": [...], "法華樓4F": [...], "法華樓5F": [...] }
|
||||||
|
},
|
||||||
|
"中區": {
|
||||||
|
"福慧樓": { "福慧樓1F": [...], "福慧樓2F": [...], "福慧樓3F": [...], "福慧樓4F": [...], "福慧樓5F": [...] },
|
||||||
|
"慈恩舍": { "慈恩舍1F": [...], "慈恩舍2F": [...], "慈恩舍3F": [...], "慈恩舍4F": [...], "慈恩舍5F": [...] },
|
||||||
|
"妙樂樓": { "妙樂樓1F": [...], "妙樂樓2F": [...], "妙樂樓3F": [...], "妙樂樓4F": [...], "妙樂樓5F": [...] }
|
||||||
|
}
|
||||||
|
}
|
||||||
76
data/memo250307.md
Normal file
76
data/memo250307.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# TODO
|
||||||
|
* 資料庫SQL:
|
||||||
|
* 結構:GIT
|
||||||
|
* 含資料: 傳檔
|
||||||
|
* 確認編號規則**
|
||||||
|
* 一般:
|
||||||
|
* 活動: 選項
|
||||||
|
* 牌位類型
|
||||||
|
* 流水號(4碼起)(依類型)
|
||||||
|
* 例: 消災0001,消災0002
|
||||||
|
* 功德主:
|
||||||
|
* 活動: 選項
|
||||||
|
* 功德主類型
|
||||||
|
* 流水號(4碼起)(依類型)
|
||||||
|
* "-"
|
||||||
|
* 牌位類型
|
||||||
|
* 流水號(不補0)(依功德主+類型)
|
||||||
|
* 例:
|
||||||
|
* 如意主0001-消災1, 如意主0001-消災2
|
||||||
|
* 如意主0001-超1, 如意主0001-超2
|
||||||
|
* 如意主0002-消災1, 如意主0002-消災2
|
||||||
|
* 如意主0002-超1, 如意主0002-超2
|
||||||
|
* 少字的字距
|
||||||
|
* 親友名換行"|"
|
||||||
|
* 可依上述SQL做綜合查詢/列印
|
||||||
|
* 列印參考:~/admin/activity/reg.aspx
|
||||||
|
|
||||||
|
# SQL
|
||||||
|
|
||||||
|
## 報名牌位綜合查詢
|
||||||
|
```SQL
|
||||||
|
SELECT activity.subject AS 活動_名稱, activity.startDate_solar AS 活動_報名日, activity.print_init AS 活動_編碼開頭, followers.u_name AS 信眾_名稱, pro_order_detail.order_no AS 報名_編號, pro_order.up_time AS 報名_時間,
|
||||||
|
pro_order_detail.num AS 項目_序號, pro_order_detail.parent_num AS 項目_上層, pro_order_detail.actItem_num AS 項目_品項, actItem.subject AS 品項_名稱, actItem.print_init AS 品項_編碼開頭,
|
||||||
|
pro_order_detail.print_id AS 項目_牌位編號, pro_order_detail.f_num_tablet AS 項目_牌位文字, pro_order_detail.price AS 項目_金額, pro_order_detail.qty AS 項目_數量, pro_order_detail.printed_files AS 項目_已列印
|
||||||
|
FROM pro_order_detail INNER JOIN
|
||||||
|
pro_order ON pro_order_detail.order_no = pro_order.order_no INNER JOIN
|
||||||
|
actItem ON pro_order_detail.actItem_num = actItem.num INNER JOIN
|
||||||
|
followers ON pro_order.f_num = followers.num INNER JOIN
|
||||||
|
activity ON pro_order.activity_num = activity.num
|
||||||
|
ORDER BY 活動_報名日, 項目_序號, 報名_編號
|
||||||
|
```
|
||||||
|
|
||||||
|
## 功德主(套餐)
|
||||||
|
https://demo2.eztrust.tw/17168erp_e/admin/activity/item_reg.aspx?num=1264
|
||||||
|
以下查詢為概念:
|
||||||
|
actItem : 品項 (基本資料)
|
||||||
|
act_bom : 主項/細項 (功德項目:上/下)
|
||||||
|
```
|
||||||
|
SELECT actItem.num, actItem.partno, actItem.subject, actItem.print_init, act_bom.num, act_bom.package_num, act_bom_1.num, act_bom_1.package_num, act_bom_1.item_num
|
||||||
|
FROM actItem INNER JOIN
|
||||||
|
act_bom ON actItem.num = act_bom.item_num INNER JOIN
|
||||||
|
act_bom AS act_bom_1 ON actItem.num = act_bom_1.item_num AND act_bom.package_num = act_bom_1.num
|
||||||
|
```
|
||||||
|
|
||||||
|
## 家屬
|
||||||
|
```
|
||||||
|
SELECT followers.num AS 信眾_序號, followers.f_number AS 信眾_編號, followers.u_name AS 信眾_姓名, family_members.num AS 親友_序號, family_members.fam_name AS 親友_姓名,
|
||||||
|
family_members.deceased AS 親友_往生
|
||||||
|
FROM followers INNER JOIN
|
||||||
|
family_members ON followers.num = family_members.follower_num
|
||||||
|
```
|
||||||
|
|
||||||
|
## 牌位文字格式
|
||||||
|
```JSON
|
||||||
|
{"mid_items":[
|
||||||
|
{"num":0,"fam_name":"姓名","option_break":true},
|
||||||
|
{"num":0,"fam_name":"姓名","option_break":true},
|
||||||
|
{"num":0,"fam_name":"姓名","option_break":true}
|
||||||
|
],
|
||||||
|
"left_items":[
|
||||||
|
{"num":0,"fam_name":"姓名","option_break":true},
|
||||||
|
{"num":0,"fam_name":"姓名","option_break":true},
|
||||||
|
{"num":0,"fam_name":"姓名","option_break":true}
|
||||||
|
]}
|
||||||
|
```
|
||||||
|
|
||||||
BIN
data/script_25-僅結構.sql
Normal file
BIN
data/script_25-僅結構.sql
Normal file
Binary file not shown.
27
data/shuwen_table.sql
Normal file
27
data/shuwen_table.sql
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
USE [17168erp]
|
||||||
|
GO
|
||||||
|
|
||||||
|
/****** Object: Table [dbo].[ShuWen] Script Date: 2025/5/6 下午 12:01:21 ******/
|
||||||
|
SET ANSI_NULLS ON
|
||||||
|
GO
|
||||||
|
|
||||||
|
SET QUOTED_IDENTIFIER ON
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE TABLE [dbo].[ShuWen](
|
||||||
|
[ID] [int] IDENTITY(1,1) NOT NULL,
|
||||||
|
[ActivityNum] [int] NOT NULL,
|
||||||
|
[CreateTime] [datetime2](7) NOT NULL,
|
||||||
|
[UpdateTime] [datetime2](7) NOT NULL,
|
||||||
|
[ShuWenList] [nvarchar](max) NULL,
|
||||||
|
[IsGenerating] [bit] NOT NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[ID] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
ALTER TABLE [dbo].[ShuWen] ADD DEFAULT ((0)) FOR [IsGenerating]
|
||||||
|
GO
|
||||||
|
|
||||||
BIN
data/v2407/17168erp_script.sql
Normal file
BIN
data/v2407/17168erp_script.sql
Normal file
Binary file not shown.
BIN
data/v2407/ER圖-Bom相關.pdf
Normal file
BIN
data/v2407/ER圖-Bom相關.pdf
Normal file
Binary file not shown.
BIN
data/v2407/ER圖-主要TABLES.pdf
Normal file
BIN
data/v2407/ER圖-主要TABLES.pdf
Normal file
Binary file not shown.
BIN
data/v2407/desktop.ini
Normal file
BIN
data/v2407/desktop.ini
Normal file
Binary file not shown.
BIN
data/v2407/資料字典.xlsx
Normal file
BIN
data/v2407/資料字典.xlsx
Normal file
Binary file not shown.
210
data/信眾APP規劃相關/appFollowerController.md
Normal file
210
data/信眾APP規劃相關/appFollowerController.md
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
|
||||||
|
# appapi/appfollower (信眾管理)
|
||||||
|
|
||||||
|
```C#
|
||||||
|
[RoutePrefix("api/appfollower")]
|
||||||
|
public class appFollowerController : ApiController
|
||||||
|
```
|
||||||
|
|
||||||
|
## Get()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
public IEnumerable<Model.follower> Get()
|
||||||
|
```
|
||||||
|
取得所有信眾資料列表
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
IEnumerable<Model.follower>
|
||||||
|
```
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
public IEnumerable<Model.follower> Get
|
||||||
|
(int page, int pageSize = 10,
|
||||||
|
string sortBy="", bool sortDesc=false)
|
||||||
|
```
|
||||||
|
取得指定分頁信眾資料列表
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
IEnumerable<Model.follower>
|
||||||
|
```
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// GET appapi/<controller>/5
|
||||||
|
public Model.follower Get(int id)
|
||||||
|
```
|
||||||
|
依ID取得指定單筆信眾
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
Model.follower
|
||||||
|
```
|
||||||
|
## Post()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// POST appapi/<controller>
|
||||||
|
public void Post([FromBody] Model.follower item)
|
||||||
|
```
|
||||||
|
新增信眾
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## Put()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// PUT appapi/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] Model.follower item)
|
||||||
|
```
|
||||||
|
修改信眾
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## Delete()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// DELETE appapi/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
```
|
||||||
|
刪除指定ID信眾
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpDelete] api/appfollower/Delete/{nums}
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/appfollower/Delete/{nums}")]
|
||||||
|
public void Delete(string nums)
|
||||||
|
```
|
||||||
|
刪除指定信眾編號信眾
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpGet] api/appfollower/count
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/appfollower/count")]
|
||||||
|
public int Count()
|
||||||
|
```
|
||||||
|
傳回筆數
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
int
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpPost] api/appfollower/GetList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appfollower/GetList")]
|
||||||
|
public IHttpActionResult GetList(
|
||||||
|
[FromBody] Model.ViewModel.follower q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
對信眾資料:分頁查詢, 排序, 傳回列表
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
{
|
||||||
|
list = IEnumerable<Model.follower>, //分頁列表
|
||||||
|
count = int //筆數
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<!--
|
||||||
|
## [HttpPost] api/appfollower/GetFamilyList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appfollower/GetFamilyList")]
|
||||||
|
public IHttpActionResult GetFamilyList([FromBody] Model.ViewModel.follower q,
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
|
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||||
|
```
|
||||||
|
取得指定信眾的家人資訊
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
IEnumerable<Model.follower>
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpPost] api/appfollower/familySave
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appfollower/familySave")]
|
||||||
|
public IHttpActionResult SaveDetailData([FromBody] Model.ViewModel.follower item)
|
||||||
|
```
|
||||||
|
取得指定信眾的家人資訊
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpPost] api/appfollower/familyDelete
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appfollower/familyDelete")]
|
||||||
|
public IHttpActionResult familyDelete([FromBody] Model.ViewModel.follower item)
|
||||||
|
```
|
||||||
|
移陁指定信眾的家人資訊
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
-->
|
||||||
|
|
||||||
|
## [HttpPost] api/appfollower/GetTabletList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appfollower/GetTabletList")]
|
||||||
|
public IHttpActionResult GetTabletList([FromBody] Model.follower q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
取得牌位資訊
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
List of: new
|
||||||
|
{
|
||||||
|
id = i++,
|
||||||
|
num = x.num,
|
||||||
|
f_num = x.f_num,
|
||||||
|
type = x.type, //型式
|
||||||
|
title = x.title, //標題
|
||||||
|
})
|
||||||
|
```
|
||||||
|
## [HttpPost] api/appfollower/tabletSave
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appfollower/tabletSave")]
|
||||||
|
public IHttpActionResult tabletSave([FromBody] Model.ViewModel.followers_tablet item)
|
||||||
|
```
|
||||||
|
儲存牌位資訊
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
int //牌位編號
|
||||||
|
```
|
||||||
|
## [HttpDelete] api/appfollower/tabletDelete/{id}
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/appfollower/tabletDelete/{id}")]
|
||||||
|
public void tabletDelete(int id)
|
||||||
|
```
|
||||||
|
刪除牌位資訊
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
366
data/信眾APP規劃相關/apporderController.md
Normal file
366
data/信眾APP規劃相關/apporderController.md
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
|
||||||
|
# appapi/apporder (報名管理)
|
||||||
|
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
public class apporderController : ApiController
|
||||||
|
```
|
||||||
|
## Get()
|
||||||
|
### 介面
|
||||||
|
```
|
||||||
|
// GET appapi/<controller>
|
||||||
|
public IEnumerable<Model.pro_order> Get()
|
||||||
|
```
|
||||||
|
取得全部報名資料列表
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
IEnumerable<Model.pro_order>
|
||||||
|
```
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
public IEnumerable<Model.pro_order> Get(int page, int pageSize = 10,
|
||||||
|
string sortBy="", bool sortDesc=false)
|
||||||
|
```
|
||||||
|
取得指定分頁報名資料列表
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
IEnumerable<Model.pro_order>
|
||||||
|
```
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// GET appapi/<controller>/5
|
||||||
|
public Model.pro_order Get(string id)
|
||||||
|
```
|
||||||
|
取得指定ID(報名編號)分頁報名
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
Model.pro_order
|
||||||
|
```
|
||||||
|
## Post()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// POST appapi/<controller>
|
||||||
|
public void Post([FromBody] Model.pro_order item)
|
||||||
|
```
|
||||||
|
新增報名資料
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
void
|
||||||
|
```
|
||||||
|
## Put()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// PUT appapi/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] Model.pro_order item)
|
||||||
|
```
|
||||||
|
修改報名資料
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## Delete()
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
// DELETE appapi/<controller>/5
|
||||||
|
public void Delete(string id)
|
||||||
|
```
|
||||||
|
刪除指定ID(報名編號)報名資料(主檔)
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpDelete] api/apporder/DeleteItem/{id}
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/apporder/DeleteItem/{id}")]
|
||||||
|
public void DeleteDetail(int id) //刪除訂單明細
|
||||||
|
```
|
||||||
|
刪除指定ID(報名編號)報名資料(明細)
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpDelete] api/apporder/DeleteAll/{nums}
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/apporder/DeleteAll/{nums}")]
|
||||||
|
public void DeleteAll(string nums)
|
||||||
|
```
|
||||||
|
刪除指定ID(報名編號)報名資料(整筆)
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpGet] api/apporder/count
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/apporder/count")]
|
||||||
|
public int Count()
|
||||||
|
```
|
||||||
|
傳回筆數
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
int
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/GetList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.pro_order q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
對報名資料:分頁查詢, 排序, 傳回列表
|
||||||
|
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
{
|
||||||
|
list = IEnumerable<Model.pro_order>, //分頁列表
|
||||||
|
count = int //筆數
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpPost] api/apporder/GetItemList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/GetItemList")]
|
||||||
|
public IHttpActionResult GetItemList(
|
||||||
|
[FromBody] Model.ViewModel.pro_order_detail q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
取得報名明細
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
new{
|
||||||
|
list = List of pro_order_detail
|
||||||
|
count = int
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## [HttpPost] api/apporder/SaveDetailData
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/SaveDetailData")]
|
||||||
|
public IHttpActionResult SaveDetailData([FromBody] Model.pro_order_detail item)
|
||||||
|
```
|
||||||
|
儲存報名明細
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
new
|
||||||
|
{
|
||||||
|
num = order.num,
|
||||||
|
customize_data = order.customize_data,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/GetUnpayList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/GetUnpayList")]
|
||||||
|
public IHttpActionResult GetUnpayList([FromBody] Model.ViewModel.follower q,
|
||||||
|
string order_no , int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
傳回未付款的訂單列表
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
new
|
||||||
|
{
|
||||||
|
list = List of new
|
||||||
|
{
|
||||||
|
id ,
|
||||||
|
order_no ,
|
||||||
|
up_time ,
|
||||||
|
reg_time ,
|
||||||
|
f_num ,
|
||||||
|
u_name ,
|
||||||
|
totalPrice , //訂單金額
|
||||||
|
payPrice = , //已收金額
|
||||||
|
}),
|
||||||
|
count = orderDt.Count(),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/GetUnpayDetail
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/GetUnpayDetail")]
|
||||||
|
public IHttpActionResult GetUnpayDetail([FromBody] Model.ViewModel.pro_order q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
傳回未付款的訂單明細
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
new {
|
||||||
|
list = List of new {
|
||||||
|
id,
|
||||||
|
order_no,
|
||||||
|
actItem_num,
|
||||||
|
actItem_numTxt,
|
||||||
|
f_num,
|
||||||
|
u_name,
|
||||||
|
price, //訂單金額
|
||||||
|
pay, //已收金額
|
||||||
|
|
||||||
|
},
|
||||||
|
count = unpayDt.Count(),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
##
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/apporder/printFileLog/{num}/{detail}")]
|
||||||
|
public IHttpActionResult printFileLog(int num , int detail)
|
||||||
|
```
|
||||||
|
更新已列印記錄
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
order.printed_files //已列印記錄
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/printMultiFileLog
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/printMultiFileLog")]
|
||||||
|
public IHttpActionResult printMultiFileLog([FromBody] List<int> list,
|
||||||
|
int item, int file)
|
||||||
|
```
|
||||||
|
更新多筆列印記錄
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpGet] api/apporder/copyDetailData/{num}/{qty}
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/apporder/copyDetailData/{num}/{qty}")]
|
||||||
|
public IHttpActionResult copyDetailData(int num, int qty)
|
||||||
|
```
|
||||||
|
複製指定的報名項目
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/GetPastOrderList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/GetPastOrderList")]
|
||||||
|
public IHttpActionResult GetPastOrderList([FromBody] Model.pro_order q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
複製以往報名
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
new
|
||||||
|
{
|
||||||
|
list = List of new
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
num,
|
||||||
|
order_no,
|
||||||
|
up_time,
|
||||||
|
activity_selected = new
|
||||||
|
{
|
||||||
|
text,
|
||||||
|
val,
|
||||||
|
},
|
||||||
|
actitem_num_selected = new
|
||||||
|
{
|
||||||
|
text,
|
||||||
|
val,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
count = qry.Count(),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<!--
|
||||||
|
-->
|
||||||
|
|
||||||
|
## [HttpPost] api/apporder/copyMultiPastItem
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/copyMultiPastItem")]
|
||||||
|
public IHttpActionResult copyMultiPastItem([FromBody] List<int> list,
|
||||||
|
string order_no)
|
||||||
|
```
|
||||||
|
複製以往報名(勾選多筆)
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/GetPayOrderList
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/GetPayOrderList")]
|
||||||
|
public IHttpActionResult GetPayOrderList([FromBody] Model.pro_order_record q,
|
||||||
|
int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
```
|
||||||
|
收款註記
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
new
|
||||||
|
{
|
||||||
|
list = List of new
|
||||||
|
{
|
||||||
|
id ,
|
||||||
|
num ,
|
||||||
|
order_no ,
|
||||||
|
pay_date ,
|
||||||
|
payment_selected = new
|
||||||
|
{
|
||||||
|
text,
|
||||||
|
val ,
|
||||||
|
},
|
||||||
|
price,
|
||||||
|
organization,
|
||||||
|
bank_code,
|
||||||
|
}),
|
||||||
|
count,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## [HttpDelete] api/apporder/DeleteRecordDetail/{id}")]
|
||||||
|
刪除收款註記
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/apporder/DeleteRecordDetail/{id}")]//刪除收款註記
|
||||||
|
public void DeleteRecordDetail(int id)
|
||||||
|
```
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
|
## [HttpPost] api/apporder/SaveRecordDetail
|
||||||
|
### 介面
|
||||||
|
``` C#
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/apporder/SaveRecordDetail")]
|
||||||
|
public IHttpActionResult SaveRecordDetail([FromBody] Model.pro_order_record item)
|
||||||
|
```
|
||||||
|
儲存收款紀錄
|
||||||
|
### 傳回
|
||||||
|
``` C#
|
||||||
|
|
||||||
|
```
|
||||||
BIN
data/信眾APP規劃相關/desktop.ini
Normal file
BIN
data/信眾APP規劃相關/desktop.ini
Normal file
Binary file not shown.
4
data/信眾APP規劃相關/index.md
Normal file
4
data/信眾APP規劃相關/index.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# 17168 API DOOC
|
||||||
|
|
||||||
|
* [信眾API](./appFollowerController.html)
|
||||||
|
* [報名API](./apporderController.html.html)
|
||||||
BIN
data/信眾APP規劃相關/~$資料字典.xlsx
Normal file
BIN
data/信眾APP規劃相關/~$資料字典.xlsx
Normal file
Binary file not shown.
BIN
data/信眾APP規劃相關/加密參考/desktop.ini
Normal file
BIN
data/信眾APP規劃相關/加密參考/desktop.ini
Normal file
Binary file not shown.
125
data/信眾APP規劃相關/加密參考/encrypt.cs
Normal file
125
data/信眾APP規劃相關/加密參考/encrypt.cs
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Security;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加密相關
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
|
||||||
|
namespace MyWeb
|
||||||
|
{
|
||||||
|
public class encrypt
|
||||||
|
{
|
||||||
|
public string MD5(string str, int bits = 32) //MD5加密
|
||||||
|
{
|
||||||
|
if (bits == 16)
|
||||||
|
{
|
||||||
|
return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower().Substring(8, 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SHA1(string SourceStr) //SHA1加密
|
||||||
|
{
|
||||||
|
return FormsAuthentication.HashPasswordForStoringInConfigFile(SourceStr, "SHA1");
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] Keys = { 0xEF, 0xAB, 0x56, 0x78, 0x90, 0x34, 0xCD, 0x12 };
|
||||||
|
|
||||||
|
public string EncryptDes(string SourceStr, string skey) //使用標準DES對稱加密, skey請帶入8位數自訂KEY
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] rgbKey = Encoding.UTF8.GetBytes(skey.Substring(0, 8));
|
||||||
|
byte[] rgbIV = Keys;
|
||||||
|
byte[] inputByteArray = Encoding.UTF8.GetBytes(SourceStr);
|
||||||
|
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
|
||||||
|
MemoryStream mStream = new MemoryStream();
|
||||||
|
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||||
|
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||||
|
cStream.FlushFinalBlock();
|
||||||
|
string str = Convert.ToBase64String(mStream.ToArray());
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return SourceStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DecryptDes(string SourceStr, string skey) //使用標準DES對稱解密, skey請帶入8位數自訂KEY
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] rgbKey = Encoding.UTF8.GetBytes(skey.Substring(0, 8));
|
||||||
|
byte[] rgbIV = Keys;
|
||||||
|
byte[] inputByteArray = Convert.FromBase64String(SourceStr);
|
||||||
|
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
|
||||||
|
MemoryStream mStream = new MemoryStream();
|
||||||
|
CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||||
|
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||||
|
cStream.FlushFinalBlock();
|
||||||
|
return Encoding.UTF8.GetString(mStream.ToArray());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return SourceStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EncryptAutoKey(string str)
|
||||||
|
{
|
||||||
|
function f = new function();
|
||||||
|
if (!f.isStrNull(str))
|
||||||
|
{
|
||||||
|
string key = f.randKey(8);
|
||||||
|
string encode = EncryptDes(str, key);
|
||||||
|
str = f.randKey(3) + f.Left(key, 5) + f.Left(encode, encode.Length - 2) + f.Right(key, 3) + f.Right(encode, 2);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
public string DecryptAutoKey(string str)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
function f = new function();
|
||||||
|
if (!string.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
string str2 = str?.Substring(3, (str ?? "").Length - 3);
|
||||||
|
string key = f.Left(str2, 5) + f.Left(f.Right(str2, 5), 3);
|
||||||
|
str2 = str2.Substring(5, str2.Length - 10) + f.Right(str2, 2);
|
||||||
|
return DecryptDes(str2, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string SHA256(string str)
|
||||||
|
{
|
||||||
|
using (SHA256 hash = SHA256Managed.Create())
|
||||||
|
{
|
||||||
|
return string.Concat(hash
|
||||||
|
.ComputeHash(Encoding.UTF8.GetBytes(str))
|
||||||
|
.Select(item => item.ToString("x2")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
587
data/信眾APP規劃相關/加密參考/function.cs
Normal file
587
data/信眾APP規劃相關/加密參考/function.cs
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
namespace MyWeb
|
||||||
|
{
|
||||||
|
public class function : System.Web.UI.Page
|
||||||
|
{
|
||||||
|
public function()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public string randCode(int count)
|
||||||
|
{
|
||||||
|
//產生驗證碼
|
||||||
|
Random rnd = new Random(Guid.NewGuid().GetHashCode());
|
||||||
|
string[] code = {
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"8",
|
||||||
|
"9",
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
"d",
|
||||||
|
"e",
|
||||||
|
"f",
|
||||||
|
"g",
|
||||||
|
"h",
|
||||||
|
"i",
|
||||||
|
"j",
|
||||||
|
"k",
|
||||||
|
"m",
|
||||||
|
"n",
|
||||||
|
"p",
|
||||||
|
"q",
|
||||||
|
"r",
|
||||||
|
"s",
|
||||||
|
"t",
|
||||||
|
"u",
|
||||||
|
"v",
|
||||||
|
"w",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z"
|
||||||
|
};
|
||||||
|
string rnd_code = null;
|
||||||
|
//產生10碼
|
||||||
|
for (int i = 1; i <= count; i++)
|
||||||
|
{
|
||||||
|
rnd_code += "" + code[rnd.Next(0, code.Length - 1)];
|
||||||
|
}
|
||||||
|
return rnd_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string randKey(int count)
|
||||||
|
{
|
||||||
|
//產生驗證碼
|
||||||
|
Random rnd = new Random(Guid.NewGuid().GetHashCode());
|
||||||
|
string[] code = {
|
||||||
|
"0","1","2","3","4","5","6","7","8","9",
|
||||||
|
"a","b","c","d","e","f","g","h","i", "j","k","l","m", "n", "o","p","q","r","s","t","u","v","w","x","y","z",
|
||||||
|
"A","B","B","D","E","F","G","H","I", "J","K","L","M", "N", "O","P","Q","R","S","T","U","V","W","X","Y","Z",
|
||||||
|
"+","/"
|
||||||
|
};
|
||||||
|
string rnd_code = null;
|
||||||
|
//產生10碼
|
||||||
|
for (int i = 1; i <= count; i++)
|
||||||
|
{
|
||||||
|
rnd_code += "" + code[rnd.Next(0, code.Length - 1)];
|
||||||
|
}
|
||||||
|
return rnd_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsNumeric(object Expression)
|
||||||
|
{
|
||||||
|
bool isNum;
|
||||||
|
double retNum;
|
||||||
|
isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);
|
||||||
|
return isNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isDate(object chkString)
|
||||||
|
{
|
||||||
|
DateTime dt;
|
||||||
|
return DateTime.TryParse(Convert.ToString(chkString), out dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ValDate(object Expression)
|
||||||
|
{
|
||||||
|
DateTime _DateTime = Convert.ToDateTime(Expression);
|
||||||
|
return _DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int Val(object Expression)
|
||||||
|
{
|
||||||
|
int _Int = 0;
|
||||||
|
if (IsNumeric(Expression))
|
||||||
|
{
|
||||||
|
_Int = Convert.ToInt32(Expression.ToString().Replace(",", ""));
|
||||||
|
}
|
||||||
|
return _Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float ValFloat(object Expression)
|
||||||
|
{
|
||||||
|
float _Int = 0;
|
||||||
|
if (!isStrNull(Expression))
|
||||||
|
{
|
||||||
|
_Int = Convert.ToSingle(ValString(Expression).Replace(",", ""));
|
||||||
|
}
|
||||||
|
return _Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ValMoney(object Expression, int DecimalLength = 2) //千分位,預設最多到小數點第2位
|
||||||
|
{
|
||||||
|
string format = "N0";
|
||||||
|
string[] m = ValString(Expression).Replace(",", "").Split('.');
|
||||||
|
if (ValString(Expression).IndexOf(".") > -1)
|
||||||
|
{
|
||||||
|
int ML = (m[m.Length - 1].Length > DecimalLength ? DecimalLength : m[m.Length - 1].Length);
|
||||||
|
if (!isStrNull(m[m.Length - 1])) { format = "N" + ML.ToString(); }
|
||||||
|
}
|
||||||
|
return ValFloat(Expression).ToString(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ValString(object Expression)
|
||||||
|
{
|
||||||
|
string _String = "";
|
||||||
|
_String = Convert.ToString(Expression);
|
||||||
|
return _String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ValMoneyCh(object Expression)
|
||||||
|
{
|
||||||
|
string price = Expression.ToString().Split('.')[0]; //去除小數點
|
||||||
|
string i = price.Replace(",", ""); //去除千分位
|
||||||
|
|
||||||
|
string[] numc_arr = ("零,壹,貳,參,肆,伍,陸,柒,捌,玖").Split(',');
|
||||||
|
string[] unic_arr = (",拾,佰,仟").Split(',');
|
||||||
|
string[] unic1_arr = ("元整,萬,億,兆,京").Split(',');
|
||||||
|
|
||||||
|
int c0 = 0;
|
||||||
|
List<string> str = new List<string>();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int aa = 0;
|
||||||
|
int c1 = 0;
|
||||||
|
string s = "";
|
||||||
|
//取最右邊四位數跑迴圈,不足四位就全取
|
||||||
|
int lan = (i.Length >= 4 ? 4 : i.Length);
|
||||||
|
int j = Convert.ToInt32(i.Substring(i.Length - lan, lan));
|
||||||
|
while (j > 0)
|
||||||
|
{
|
||||||
|
int k = j % 10; //餘數
|
||||||
|
if (k > 0) { aa = 1; s = numc_arr[k] + unic_arr[c1] + s; }
|
||||||
|
else if (k == 0 && aa == 1) { s = "0" + s; }
|
||||||
|
j = j / 10; //商
|
||||||
|
c1++;
|
||||||
|
}
|
||||||
|
//轉成中文後丟入陣列,全部為零不加單位
|
||||||
|
str.Add((s == "" ? "" : s + unic1_arr[c0]));
|
||||||
|
//計算剩餘字串長度
|
||||||
|
int count_len = i.Length - 4;
|
||||||
|
i = (count_len > 0 ? i.Substring(0, count_len) : "");
|
||||||
|
c0++;
|
||||||
|
} while (!string.IsNullOrEmpty(i));
|
||||||
|
|
||||||
|
string chstring = "";
|
||||||
|
while (str.Count > 0) { chstring += str[str.Count - 1]; str.Remove(str[str.Count - 1]); }
|
||||||
|
|
||||||
|
string pattern = "0+";
|
||||||
|
string replacement = "零";
|
||||||
|
Regex rgx = new Regex(pattern);
|
||||||
|
string result = rgx.Replace(chstring, replacement);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Left(object Expression, int Length)
|
||||||
|
{
|
||||||
|
string str = "";
|
||||||
|
str = ValString(Expression);
|
||||||
|
if (Length > str.Length) { Length = str.Length; }
|
||||||
|
str = str.Substring(0, Length);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Right(object Expression, int Length)
|
||||||
|
{
|
||||||
|
string str = "";
|
||||||
|
str = ValString(Expression);
|
||||||
|
int startIndex = str.Length - Length;
|
||||||
|
if (startIndex < 0)
|
||||||
|
{
|
||||||
|
startIndex = 0;
|
||||||
|
Length = str.Length;
|
||||||
|
}
|
||||||
|
str = str.Substring(startIndex, Length);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isStrNull(object value)
|
||||||
|
{
|
||||||
|
return (value == null || value == DBNull.Value || Convert.ToString(value) == "" ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//截字
|
||||||
|
public string cut_str(string str, int limit)
|
||||||
|
{
|
||||||
|
return str; //不截字,避免顏文字之類的圖在viewstate會出錯
|
||||||
|
MatchCollection findCount;
|
||||||
|
string Based = "[\u0080-\uFFFF]";
|
||||||
|
//中日韓3byte以上的字符
|
||||||
|
string tmp = null;
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < str.Length; i++)
|
||||||
|
{
|
||||||
|
findCount = Regex.Matches(str.Substring(i, 1), Based, RegexOptions.Compiled);
|
||||||
|
//找str裡面是否有Based指定的字
|
||||||
|
if (findCount.Count == 0)
|
||||||
|
{
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
j += 2;
|
||||||
|
//一個中文字占兩個
|
||||||
|
}
|
||||||
|
if (j <= limit)
|
||||||
|
{
|
||||||
|
tmp = tmp + str.Substring(i, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i -= 1;
|
||||||
|
if (i < str.Length)
|
||||||
|
{
|
||||||
|
if (!isStrNull(str.Substring(i, 1).Trim()))
|
||||||
|
{
|
||||||
|
//捨棄不完整的英文單字或數字
|
||||||
|
int n = 0;
|
||||||
|
for (int t = tmp.Length - 1; t >= 0; t--)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
if (Regex.Matches(tmp.Substring(t, 1), Based, RegexOptions.Compiled).Count > 0) //中文字
|
||||||
|
{
|
||||||
|
tmp = Left(tmp, tmp.Length - n + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (isStrNull(tmp.Substring(t, 1).Trim()))
|
||||||
|
{
|
||||||
|
tmp = Left(tmp, tmp.Length - n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp = tmp + "...";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum msgIcon : int
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
success = 1,
|
||||||
|
error = 2,
|
||||||
|
warning = 3,
|
||||||
|
info = 4,
|
||||||
|
question = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptMsg(string txt, string url="", msgIcon icon= msgIcon.none)
|
||||||
|
{
|
||||||
|
ScriptManager.RegisterClientScriptBlock((Page)HttpContext.Current.Handler, typeof(string), "js", "msgbox('" + txt + "','" + (icon != msgIcon.none ? icon.ToString() : "") + "','" + url + "');", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptMsgTop(string txt, msgIcon icon)
|
||||||
|
{
|
||||||
|
ScriptManager.RegisterClientScriptBlock((Page)HttpContext.Current.Handler, typeof(string), "js", "msgtop('" + txt + "','" + (icon != msgIcon.none ? icon.ToString() : "") + "');", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ScriptJS(string script)
|
||||||
|
{
|
||||||
|
ScriptManager.RegisterClientScriptBlock((Page)HttpContext.Current.Handler, typeof(string), "js", script, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptMsg2(string txt, string url = "", msgIcon icon = msgIcon.none)
|
||||||
|
{
|
||||||
|
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "init", "msgbox('" + txt + "','" + (icon != msgIcon.none ? icon.ToString() : "") + "','" + url + "');", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptMsgTop2(string txt, msgIcon icon)
|
||||||
|
{
|
||||||
|
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "init", "msgtop('" + txt + "','" + (icon != msgIcon.none ? icon.ToString() : "") + "');", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScriptJS2(string script)
|
||||||
|
{
|
||||||
|
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "init", script, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string br(string str)
|
||||||
|
{
|
||||||
|
return str.Replace(Convert.ToString((char)10), "<br>").Replace(Convert.ToString((char)13), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//日期格式
|
||||||
|
public string datetype(string dtmp)
|
||||||
|
{
|
||||||
|
if (dtmp != null)
|
||||||
|
{
|
||||||
|
System.DateTime d = ValDate(dtmp);
|
||||||
|
return d.ToString("yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string datetype(string dtmp, string format)
|
||||||
|
{
|
||||||
|
if (dtmp != null)
|
||||||
|
{
|
||||||
|
System.DateTime d = ValDate(dtmp);
|
||||||
|
return d.ToString(format);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string allowReqAtt = System.Configuration.ConfigurationManager.AppSettings["allowReqAtt"].ToString();
|
||||||
|
public bool AllowReq(string name)
|
||||||
|
{
|
||||||
|
if (!isStrNull(allowReqAtt))
|
||||||
|
{
|
||||||
|
string[] qns = allowReqAtt.Split(',');
|
||||||
|
foreach (string qn in qns)
|
||||||
|
if (qn.ToLower() == name.ToLower())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//傳回GET值並拿掉不要的,回傳格式為?xxxx=xxxx&yyyy=yyyy
|
||||||
|
public string rtnQueryString(string noUseQuery)
|
||||||
|
{
|
||||||
|
string new_query = "";
|
||||||
|
if (HttpContext.Current.Request.Url.AbsoluteUri.Split('?').Length == 2)
|
||||||
|
{
|
||||||
|
string[] query = HttpContext.Current.Request.Url.AbsoluteUri.Split('?')[1].Split('&');
|
||||||
|
for (int i = 0; i < query.Length; i++)
|
||||||
|
{
|
||||||
|
string[] qs = query[i].Split('=');
|
||||||
|
if (qs.Length == 2 && qs[0].ToLower() != noUseQuery.ToLower())
|
||||||
|
{
|
||||||
|
if (AllowReq(qs[0]))
|
||||||
|
new_query += (new_query == "" ? "?" : "&") + qs[0] + "=" + Server.UrlEncode(Server.UrlDecode(qs[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new_query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string rtnQueryString(Array noUseQuery)
|
||||||
|
{
|
||||||
|
string new_query = "";
|
||||||
|
if (HttpContext.Current.Request.Url.AbsoluteUri.Split('?').Length == 2)
|
||||||
|
{
|
||||||
|
string[] query = HttpContext.Current.Request.Url.AbsoluteUri.Split('?')[1].Split('&');
|
||||||
|
for (int i = 0; i < query.Length; i++)
|
||||||
|
{
|
||||||
|
string[] qs = query[i].Split('=');
|
||||||
|
if (qs.Length == 2)
|
||||||
|
{
|
||||||
|
bool setAdd = true;
|
||||||
|
foreach (string nq in noUseQuery)
|
||||||
|
{
|
||||||
|
if (qs[0].ToLower() == nq.ToLower())
|
||||||
|
{
|
||||||
|
setAdd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setAdd)
|
||||||
|
{
|
||||||
|
if (AllowReq(qs[0]))
|
||||||
|
new_query += (new_query == "" ? "?" : "&") + qs[0] + "=" + Server.UrlEncode(Server.UrlDecode(qs[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new_query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UrlHost()
|
||||||
|
{
|
||||||
|
string url = (IsHttps() ? "https://" : "http://")
|
||||||
|
//+ HttpContext.Current.Request.Url.Host
|
||||||
|
+ Request.ServerVariables["HTTP_HOST"]
|
||||||
|
+ VirtualPathUtility.ToAbsolute("~/");
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UrlAddr()
|
||||||
|
{
|
||||||
|
string url = (IsHttps() ? "https://" : "http://") + HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.Url.AbsolutePath;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsHttps()
|
||||||
|
{
|
||||||
|
return HttpContext.Current.Request.IsSecureConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 列舉
|
||||||
|
|
||||||
|
public string GetEnumsDescription(Enum value)
|
||||||
|
{
|
||||||
|
FieldInfo fi = value.GetType().GetField(value.ToString());
|
||||||
|
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||||
|
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitEnumsOptions<T>(Control obj)
|
||||||
|
{
|
||||||
|
foreach (object value in Enum.GetValues(typeof(T)))
|
||||||
|
if (obj is DropDownList)
|
||||||
|
((DropDownList)obj).Items.Add(new ListItem(GetEnumsDescription((Enum)value), ((int)value).ToString()));
|
||||||
|
else if (obj is RadioButtonList)
|
||||||
|
((RadioButtonList)obj).Items.Add(new ListItem(GetEnumsDescription((Enum)value), ((int)value).ToString()));
|
||||||
|
else if (obj is CheckBoxList)
|
||||||
|
((CheckBoxList)obj).Items.Add(new ListItem(GetEnumsDescription((Enum)value), ((int)value).ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public class WreqInfo
|
||||||
|
{
|
||||||
|
public string log = "";
|
||||||
|
public string data = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Method { POST, GET, PUT, DELETE }
|
||||||
|
|
||||||
|
public WreqInfo WRequest(string URL, Method method, string POSTdata, string Referer = "", string UserAgent = "")
|
||||||
|
{
|
||||||
|
WreqInfo responseData = new WreqInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
HttpWebRequest hwrequest = (HttpWebRequest)WebRequest.Create(URL);
|
||||||
|
hwrequest.Accept = "*/*";
|
||||||
|
hwrequest.AllowAutoRedirect = true;
|
||||||
|
hwrequest.Timeout = 5000;
|
||||||
|
hwrequest.Method = method.ToString();
|
||||||
|
|
||||||
|
if (!isStrNull(UserAgent))
|
||||||
|
hwrequest.UserAgent = UserAgent;
|
||||||
|
else
|
||||||
|
hwrequest.UserAgent = "http_requester/0.1";
|
||||||
|
|
||||||
|
if (!isStrNull(Referer))
|
||||||
|
hwrequest.Referer = Referer;
|
||||||
|
|
||||||
|
if (URL.ToLower().IndexOf("https://") > -1)
|
||||||
|
{
|
||||||
|
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||||
|
hwrequest.ClientCertificates.Add(new System.Security.Cryptography.X509Certificates.X509Certificate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (hwrequest.Method == "POST")
|
||||||
|
{
|
||||||
|
hwrequest.ContentType = "application/x-www-form-urlencoded";
|
||||||
|
//ASCIIEncoding encoding = new ASCIIEncoding();
|
||||||
|
UTF8Encoding encoding = new UTF8Encoding();
|
||||||
|
byte[] postByteArray = encoding.GetBytes(POSTdata);
|
||||||
|
hwrequest.ContentLength = postByteArray.Length;
|
||||||
|
Stream postStream = hwrequest.GetRequestStream();
|
||||||
|
postStream.Write(postByteArray, 0, postByteArray.Length);
|
||||||
|
postStream.Close();
|
||||||
|
}
|
||||||
|
HttpWebResponse hwresponse = (HttpWebResponse)hwrequest.GetResponse();
|
||||||
|
if (hwresponse.StatusCode == HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
StreamReader responseStream = new StreamReader(hwresponse.GetResponseStream());
|
||||||
|
responseData.data = responseStream.ReadToEnd();
|
||||||
|
}
|
||||||
|
hwresponse.Close();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
responseData.log = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 繁簡轉換
|
||||||
|
|
||||||
|
public static class ChineseConverter
|
||||||
|
{
|
||||||
|
internal const int LOCALE_SYSTEM_DEFAULT = 0x0800;
|
||||||
|
internal const int LCMAP_SIMPLIFIED_CHINESE = 0x02000000;
|
||||||
|
internal const int LCMAP_TRADITIONAL_CHINESE = 0x04000000;
|
||||||
|
|
||||||
|
[System.Runtime.InteropServices.DllImport("kernel32", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
|
||||||
|
internal static extern int LCMapString(int Locale, int dwMapFlags, string lpSrcStr, int cchSrc, [System.Runtime.InteropServices.Out] string lpDestStr, int cchDest);
|
||||||
|
|
||||||
|
public static string ToSimplified(string pSource)
|
||||||
|
{
|
||||||
|
String tTarget = new String(' ', pSource.Length);
|
||||||
|
int tReturn = LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_SIMPLIFIED_CHINESE, pSource, pSource.Length, tTarget, pSource.Length);
|
||||||
|
return tTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ToTraditional(string pSource)
|
||||||
|
{
|
||||||
|
String tTarget = new String(' ', pSource.Length);
|
||||||
|
int tReturn = LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_TRADITIONAL_CHINESE, pSource, pSource.Length, tTarget, pSource.Length);
|
||||||
|
return tTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 讀檔
|
||||||
|
|
||||||
|
public string ReadFileContent(string path)
|
||||||
|
{
|
||||||
|
string text = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (path.IndexOf("~/") > -1) { path = Server.MapPath(path); }
|
||||||
|
|
||||||
|
Stream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
StreamReader objReader = new StreamReader(stream);
|
||||||
|
text = objReader.ReadToEnd();
|
||||||
|
objReader.Close();
|
||||||
|
objReader.Dispose();
|
||||||
|
stream.Close();
|
||||||
|
stream.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//throw;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
44
data/信眾APP規劃相關/加密參考/加密說明.txt
Normal file
44
data/信眾APP規劃相關/加密參考/加密說明.txt
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
~\17168erp\App_Code\encrypt.cs // 加密程式
|
||||||
|
~\17168erp\App_Code\function.cs // 輔助功能
|
||||||
|
|
||||||
|
// 有加密的欄位
|
||||||
|
phone 聯絡電話
|
||||||
|
id_code 身份證號
|
||||||
|
passport 護照號碼
|
||||||
|
cellphone 手機號碼
|
||||||
|
contactor_phone 緊急連絡人電話
|
||||||
|
|
||||||
|
// Page_Load
|
||||||
|
// ** 解密 DecryptAutoKey **
|
||||||
|
if (!isStrNull(prod.phone))
|
||||||
|
{
|
||||||
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
|
contactor_phone.Text = encrypt.DecryptAutoKey(prod.phone.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit_Click
|
||||||
|
// ** 加密 EncryptAutoKey **
|
||||||
|
encrypt.EncryptAutoKey(textBox.Text.Trim())
|
||||||
|
|
||||||
|
// 使用參考
|
||||||
|
foreach (Control obj in cardBodyPanel.Controls)
|
||||||
|
{
|
||||||
|
if (obj is TextBox)
|
||||||
|
{
|
||||||
|
var ObjValue = followers.GetType().GetProperty(obj.ID);
|
||||||
|
var textBox = (TextBox)obj;
|
||||||
|
if (!isStrNull(textBox.Text))
|
||||||
|
{
|
||||||
|
if (textBox.TextMode == TextBoxMode.Date)
|
||||||
|
ObjValue.SetValue(followers, selectDate(textBox));
|
||||||
|
else if (!isStrNull(((TextBox)obj).Attributes["data-encrypt"])
|
||||||
|
&& ValString(textBox.Attributes["data-encrypt"]).Equals("Y"))
|
||||||
|
ObjValue.SetValue(followers, encrypt.EncryptAutoKey(textBox.Text.Trim()));
|
||||||
|
else
|
||||||
|
ObjValue.SetValue(followers, ((TextBox)obj).Text.Trim());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ObjValue.SetValue(followers, null);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
data/資料字典.xlsx
Normal file
BIN
data/資料字典.xlsx
Normal file
Binary file not shown.
42
memo.md
Normal file
42
memo.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
## gitea server
|
||||||
|
* https://git.hcu.edu.tw
|
||||||
|
* 綁定IP
|
||||||
|
yiming, XrxCAdgX3BwMc6r
|
||||||
|
|
||||||
|
## 開發佈建說明
|
||||||
|
* IDE: 以VisualStudio開啟 17168erp.sln, 直接執行網站
|
||||||
|
* 架構: .net Framework 4.8, Website
|
||||||
|
* 後端程式: Webform(.ASPX+.CS)
|
||||||
|
* DB Model:
|
||||||
|
* 使用SSMS設計DB
|
||||||
|
* 開啟: ~\App_Code\Model\Model.edmx
|
||||||
|
* 執行"自資料庫更新", 即產生EF MODEL相關.CS
|
||||||
|
* 前端框架:
|
||||||
|
* Jquery 3, Bootstrap 5
|
||||||
|
* Vue 2, Vuetify 2
|
||||||
|
|
||||||
|
## API: 取得用戶資訊
|
||||||
|
#### Request:
|
||||||
|
```
|
||||||
|
curl --location 'http://localhost:33051/api/appfollower/checkHashFollower' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data '{
|
||||||
|
"phone":"0987456321",
|
||||||
|
"id_code":"A123456789"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
#### Response:
|
||||||
|
JSON: 用戶資訊, 可討論只要哪些欄位
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
## TODO
|
||||||
|
[0830]
|
||||||
|
* 信眾/親屬: 生辰計算, API提供
|
||||||
|
* GIT (憑證問題)
|
||||||
|
* CHK: BOM
|
||||||
|
* 活動詳細分類(法會項目:品項->功德)
|
||||||
|
|
||||||
|
---
|
||||||
|
前台:
|
||||||
|
https://tcapi.hcu.edu.tw
|
||||||
40
web/17168erp.sln
Normal file
40
web/17168erp.sln
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.11.35219.272
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "web(1)", ".", "{71B14F37-B607-4E9D-9457-2B7C230DB483}"
|
||||||
|
ProjectSection(WebsiteProperties) = preProject
|
||||||
|
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.8"
|
||||||
|
Debug.AspNetCompiler.VirtualPath = "/localhost_33051"
|
||||||
|
Debug.AspNetCompiler.PhysicalPath = "D:\dev\ez\17168erp\git\web\"
|
||||||
|
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_33051\"
|
||||||
|
Debug.AspNetCompiler.Updateable = "true"
|
||||||
|
Debug.AspNetCompiler.ForceOverwrite = "true"
|
||||||
|
Debug.AspNetCompiler.FixedNames = "false"
|
||||||
|
Debug.AspNetCompiler.Debug = "True"
|
||||||
|
Release.AspNetCompiler.VirtualPath = "/localhost_33051"
|
||||||
|
Release.AspNetCompiler.PhysicalPath = "D:\dev\ez\17168erp\git\web\"
|
||||||
|
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_33051\"
|
||||||
|
Release.AspNetCompiler.Updateable = "true"
|
||||||
|
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||||
|
Release.AspNetCompiler.FixedNames = "false"
|
||||||
|
Release.AspNetCompiler.Debug = "False"
|
||||||
|
VWDPort = "33051"
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{71B14F37-B607-4E9D-9457-2B7C230DB483}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{71B14F37-B607-4E9D-9457-2B7C230DB483}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {D7CAE2AB-E2B6-4816-8384-3C6C2884D8E7}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
306
web/App_Code/Cus_GetSQL.cs
Normal file
306
web/App_Code/Cus_GetSQL.cs
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Security;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
using System.Web.UI.HtmlControls;
|
||||||
|
using System.Web.Configuration;
|
||||||
|
using System.Data.OleDb;
|
||||||
|
|
||||||
|
namespace Cus_GetSQL
|
||||||
|
{
|
||||||
|
public class Get_Data
|
||||||
|
{
|
||||||
|
// 全域變數。從 Stored Procedure 回傳的單一數值,取得符合查詢條件的資料列總筆數
|
||||||
|
public int _totalRecords = 0;
|
||||||
|
// 取得 Web.config 連線字串的名稱
|
||||||
|
public string strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["shopConn"].ToString();
|
||||||
|
|
||||||
|
public Get_Data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 取得 WebForm 裡的 ObjectDataSource 傳來的參數,並將參數傳送給 SELECT 函數處理
|
||||||
|
|
||||||
|
// true 表示為 ObjectDataSource 要 SELECT 時的預設值
|
||||||
|
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
|
||||||
|
public DataSet Get_ObjectDataSource_Val(string TableName_val, string ColumnName_val, string OrderColumn_val, string Where_val, int startRowIndex, int maxinumRows, string sortExpression)
|
||||||
|
{
|
||||||
|
// 最後三個參數:startRowIndex, maxinumRows, sortExpression,ObjectDataSource 控制項會自動傳入,開發人員不用手動撰碼傳值
|
||||||
|
DataSet ds = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//HttpContext.Current.Response.Write("變數=" & eztrust)
|
||||||
|
//檢查所帶進來的參數是否有值(如果為empty會發生錯誤)
|
||||||
|
if (TableName_val == null | Convert.ToString(TableName_val)=="")
|
||||||
|
{
|
||||||
|
TableName_val = "";
|
||||||
|
}
|
||||||
|
if (ColumnName_val == null | Convert.ToString(ColumnName_val) == "")
|
||||||
|
{
|
||||||
|
ColumnName_val = "";
|
||||||
|
}
|
||||||
|
if (OrderColumn_val == null | Convert.ToString(OrderColumn_val) == "")
|
||||||
|
{
|
||||||
|
OrderColumn_val = "";
|
||||||
|
}
|
||||||
|
if (Where_val == null | Convert.ToString(Where_val) == "")
|
||||||
|
{
|
||||||
|
Where_val = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 參數: (Table名稱、查詢Column名稱集合、Where條件(包括模糊查詢關鍵字)、排序方式(按標題搜尋前)、起始撈取的資料列索引、GridView每頁要顯示的筆數、排序方式(按標題搜尋後))
|
||||||
|
ds = SelectData(TableName_val.Trim(), ColumnName_val.Trim(), Where_val, OrderColumn_val.Trim(), startRowIndex, maxinumRows, sortExpression);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception(ex.Message);
|
||||||
|
//顯示錯誤訊息,如資料庫存取發生錯誤,或網路中斷、資料庫關機
|
||||||
|
}
|
||||||
|
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 將接受到的參數,執行SELECT (搭配 Stored Procedure 做「分頁及撈取資料」處理)
|
||||||
|
|
||||||
|
// true 表示為 ObjectDataSource 要 SELECT 時的預設值
|
||||||
|
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
|
||||||
|
public DataSet SelectData(string strTableName, string strColumnName, string strSqlWhere, string strDefaultOrderColumn, int startRowIndex, int maxinumRows, string sortExpression)
|
||||||
|
{
|
||||||
|
OleDbConnection sqlConn = null;
|
||||||
|
OleDbCommand sqlCmd = null;
|
||||||
|
OleDbDataAdapter sqlAdapter = null;
|
||||||
|
DataSet ds = null;
|
||||||
|
string strOrderBy = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sqlConn = new OleDbConnection(strConnString);
|
||||||
|
sqlConn.Open();
|
||||||
|
|
||||||
|
if (sqlConn.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
ds = new DataSet();
|
||||||
|
|
||||||
|
// 取得排序資料 (昇幕或降幕)
|
||||||
|
if (string.IsNullOrEmpty(sortExpression))
|
||||||
|
{
|
||||||
|
//排序欄位。第一次進入頁面時,sortExpression 為空值,所以以開發人員在層指定的欄位排序
|
||||||
|
strOrderBy = strDefaultOrderColumn;
|
||||||
|
}
|
||||||
|
else if ((!string.IsNullOrEmpty(sortExpression)) & (sortExpression.IndexOf(" DESC") == -1))
|
||||||
|
{
|
||||||
|
// 排序欄位。若使用者按下了 GridView 某個欄位的 title,此時 sortExpression 有值,且要由小到大排序
|
||||||
|
strOrderBy = sortExpression + " ASC";
|
||||||
|
}
|
||||||
|
else if ((!string.IsNullOrEmpty(sortExpression)) & (sortExpression.IndexOf(" DESC") != -1))
|
||||||
|
{
|
||||||
|
// 刪除 ObjectDataSource 自動在最後面加的「 DESC」字樣(5個字元)
|
||||||
|
sortExpression = sortExpression.Remove(sortExpression.Length - 5, 5);
|
||||||
|
// 排序欄位。若使用者按下了 GridView 某個欄位的 title,此時 sortExpression 有值,且要由大到小排序
|
||||||
|
strOrderBy = sortExpression + " DESC";
|
||||||
|
}
|
||||||
|
|
||||||
|
// SELECT SQL 的 WHERE 條件 (包含使用者輸入的模糊查詢關鍵字)
|
||||||
|
if (string.IsNullOrEmpty(strSqlWhere))
|
||||||
|
{
|
||||||
|
// 若沒加這句,則當 WHERE 條件為空值時(使用者未輸入搜尋關鍵字),丟到 Stored Procedure 裡後會 Error
|
||||||
|
strSqlWhere = " 1=1 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlCmd = new OleDbCommand("dbo.pager_eztrust", sqlConn);
|
||||||
|
// 系統中每支程式共用的預存程序名稱
|
||||||
|
sqlCmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
// 資料來源為 Stored Procedure(預存程序)
|
||||||
|
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@StartRowIndex", startRowIndex));
|
||||||
|
// 目前頁面,要撈的資料,的第一筆資料的索引 (第一筆為 0,依序加 1,依此類推)
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@PageSize", maxinumRows));
|
||||||
|
// GridView 每頁要顯示的資料筆數
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@tableName", strTableName));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@columnName", strColumnName));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@sqlWhere", strSqlWhere));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@orderBy", strOrderBy));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@rowCount", SqlDbType.Int));
|
||||||
|
// Stored Procedure 會傳回一個數字(符合查詢條件的資料總筆數)
|
||||||
|
|
||||||
|
|
||||||
|
sqlCmd.Parameters["@rowCount"].Direction = ParameterDirection.Output;
|
||||||
|
// 用來在 GridView 下方的「頁碼列」顯示頁碼之用(Ex: 1 2 3 4 ... 55)
|
||||||
|
sqlAdapter = new OleDbDataAdapter(sqlCmd);
|
||||||
|
sqlAdapter.Fill(ds);
|
||||||
|
|
||||||
|
_totalRecords = Convert.ToInt32(sqlCmd.Parameters["@rowCount"].Value);
|
||||||
|
// 總筆數 (要回傳至前端 .aspx,給 GridView 下方的「頁碼列」顯示用)
|
||||||
|
HttpContext.Current.Session["s_RecordTotalCount"] = _totalRecords;
|
||||||
|
// 存至 Session,以便在.aspx.vb中取用後,用來在 GridView 下方的「頁碼列」中顯示頁碼之用
|
||||||
|
Console.Write("tc: " + _totalRecords);
|
||||||
|
|
||||||
|
int jj = ds.Tables[0].Rows.Count;
|
||||||
|
// 實際從資料庫撈回來,儲存在 AP Server 記憶體中 DataSet/DataTable 的資料筆數
|
||||||
|
Console.Write(jj);
|
||||||
|
// GridView 每頁要呈現的資料筆數
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OleDbException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception("發生 SqlClient 以外的資料庫錯誤: " + ex.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sqlCmd.Dispose();
|
||||||
|
sqlAdapter.Dispose();
|
||||||
|
ds.Dispose();
|
||||||
|
if (sqlConn.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
sqlConn.Close(); sqlConn.Dispose();
|
||||||
|
}
|
||||||
|
sqlConn.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 從 Stored Procedure 回傳的一個整數,為符合查詢條件的資料總筆數,用來在 GridView 下方的「頁碼列」顯示頁碼之用(Ex: 1 2 3 4 ... 55)
|
||||||
|
|
||||||
|
public int getRecordCount(string TableName_val, string ColumnName_val, string OrderColumn_val, string Where_val)
|
||||||
|
{
|
||||||
|
return _totalRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public struct GetSqlData
|
||||||
|
{
|
||||||
|
|
||||||
|
public string tableName;
|
||||||
|
public string columnName;
|
||||||
|
public string sqlWhere;
|
||||||
|
public string sort;
|
||||||
|
public int startRowIndex;
|
||||||
|
|
||||||
|
public int maxinumRows;
|
||||||
|
public DataSet selectData()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
string db = ConfigurationManager.ConnectionStrings["shopConn"].ConnectionString;
|
||||||
|
string p_name = ConfigurationManager.ConnectionStrings["shopConn"].ProviderName;
|
||||||
|
//ProviderName
|
||||||
|
|
||||||
|
MyWeb.sql sql = new MyWeb.sql();
|
||||||
|
OleDbConnection sqlConn = new OleDbConnection(db);
|
||||||
|
OleDbCommand sqlCmd = null;
|
||||||
|
OleDbDataAdapter sqlAdapter = null;
|
||||||
|
DataSet ds = null;
|
||||||
|
string strOrderBy = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sqlConn.Open();
|
||||||
|
if (sqlConn.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
ds = new DataSet();
|
||||||
|
|
||||||
|
// SELECT SQL 的 WHERE 條件 (包含使用者輸入的模糊查詢關鍵字)
|
||||||
|
if (string.IsNullOrEmpty(sqlWhere))
|
||||||
|
{
|
||||||
|
// 若沒加這句,則當 WHERE 條件為空值時(使用者未輸入搜尋關鍵字),丟到 Stored Procedure 裡後會 Error
|
||||||
|
sqlWhere = " 1=1 ";
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlCmd = new OleDbCommand("dbo.pager_eztrust", sqlConn);
|
||||||
|
// 系統中每支程式共用的預存程序名稱
|
||||||
|
sqlCmd.CommandType = CommandType.StoredProcedure;
|
||||||
|
// 資料來源為 Stored Procedure(預存程序)
|
||||||
|
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@StartRowIndex", startRowIndex));
|
||||||
|
// 目前頁面,要撈的資料,的第一筆資料的索引 (第一筆為 0,依序加 1,依此類推)
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@PageSize", maxinumRows));
|
||||||
|
// 每頁要顯示的資料筆數
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@tableName", tableName + " "));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@columnName", columnName));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@sqlWhere", sqlWhere));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@orderBy", sort));
|
||||||
|
sqlCmd.Parameters.Add(new OleDbParameter("@rowCount", SqlDbType.Int));
|
||||||
|
// Stored Procedure 會傳回一個數字(符合查詢條件的資料總筆數)
|
||||||
|
|
||||||
|
sqlCmd.Parameters["@rowCount"].Direction = ParameterDirection.Output;
|
||||||
|
// 用來在 GridView 下方的「頁碼列」顯示頁碼之用(Ex: 1 2 3 4 ... 55)
|
||||||
|
sqlAdapter = new OleDbDataAdapter(sqlCmd);
|
||||||
|
sqlAdapter.Fill(ds);
|
||||||
|
|
||||||
|
int totalRecords = Convert.ToInt32(sqlCmd.Parameters["@rowCount"].Value);
|
||||||
|
// 回傳回來的總筆數
|
||||||
|
HttpContext.Current.Session["s_RecordTotalCount"] = totalRecords;
|
||||||
|
// 存至 Session,以便在.aspx.vb中取用後
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OleDbException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception("發生 SqlClient 以外的資料庫錯誤: " + ex.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sqlCmd.Dispose();
|
||||||
|
sqlAdapter.Dispose();
|
||||||
|
ds.Dispose();
|
||||||
|
if (sqlConn.State == ConnectionState.Open)
|
||||||
|
{
|
||||||
|
sqlConn.Close(); sqlConn.Dispose();
|
||||||
|
}
|
||||||
|
sqlConn.Dispose();
|
||||||
|
}
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Cus_SQL
|
||||||
|
{
|
||||||
|
|
||||||
|
#region 將查詢的sql陣列組成字串傳回
|
||||||
|
|
||||||
|
public class SQL_Array
|
||||||
|
{
|
||||||
|
|
||||||
|
public string sql_str(ArrayList fs)
|
||||||
|
{
|
||||||
|
string functionReturnValue = null;
|
||||||
|
for (int i = 0; i <= fs.Count - 1; i++)
|
||||||
|
{
|
||||||
|
if (functionReturnValue != null)
|
||||||
|
{ functionReturnValue += " AND "; }
|
||||||
|
functionReturnValue += fs[i];
|
||||||
|
}
|
||||||
|
return functionReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
66
web/App_Code/CustomNode.cs
Normal file
66
web/App_Code/CustomNode.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Web;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public class CustomTreeNode : TreeNode
|
||||||
|
{
|
||||||
|
public CustomTreeNode()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// used to store Node Attributes
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
private NameValueCollection _Attributes = new NameValueCollection();
|
||||||
|
/// <summary>
|
||||||
|
///used to store the CSS Class applied to a node.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
private string _cssClass;
|
||||||
|
/// <summary>
|
||||||
|
/// Property used to set the CSS Class applied to a Node
|
||||||
|
/// </summary>
|
||||||
|
public string cssClass
|
||||||
|
{
|
||||||
|
get { return _cssClass; }
|
||||||
|
set { _cssClass = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Property used to add Attributes to a node
|
||||||
|
/// </summary>
|
||||||
|
public NameValueCollection Attributes
|
||||||
|
{
|
||||||
|
get { return this._Attributes; }
|
||||||
|
set { this._Attributes = value; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// add additional rendering to the node
|
||||||
|
/// Add a div Tag and a class Attribute
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="writer">represents the output stream used to write content to a Web page</param>
|
||||||
|
protected override void RenderPreText(HtmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.AddAttribute(HtmlTextWriterAttribute.Class, cssClass);
|
||||||
|
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "loadingShow(this)");
|
||||||
|
//執行取得座標的java函式
|
||||||
|
writer.RenderBeginTag(HtmlTextWriterTag.Div);
|
||||||
|
base.RenderPreText(writer);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// add additional rendering to the node
|
||||||
|
/// End Tag
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="writer">represents the output stream used to write content to a Web page</param>
|
||||||
|
protected override void RenderPostText(HtmlTextWriter writer)
|
||||||
|
{
|
||||||
|
writer.RenderEndTag();
|
||||||
|
base.RenderPostText(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
12
web/App_Code/GlobalVariables.cs
Normal file
12
web/App_Code/GlobalVariables.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GlobalVariables 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public static class GlobalVariables
|
||||||
|
{
|
||||||
|
public static readonly object FNumberLock = new object();
|
||||||
|
}
|
||||||
217
web/App_Code/Model/Model.Context.cs
Normal file
217
web/App_Code/Model/Model.Context.cs
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated from a template.
|
||||||
|
//
|
||||||
|
// Manual changes to this file may cause unexpected behavior in your application.
|
||||||
|
// Manual changes to this file will be overwritten if the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Data.Entity.Infrastructure;
|
||||||
|
using System.Data.Entity.Core.Objects;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
public partial class ezEntities : DbContext
|
||||||
|
{
|
||||||
|
public ezEntities()
|
||||||
|
: base("name=ezEntities")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(DbModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
throw new UnintentionalCodeFirstException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual DbSet<accounting> accountings { get; set; }
|
||||||
|
public virtual DbSet<accounting_files> accounting_files { get; set; }
|
||||||
|
public virtual DbSet<accounting_kind> accounting_kind { get; set; }
|
||||||
|
public virtual DbSet<accounting_kind2> accounting_kind2 { get; set; }
|
||||||
|
public virtual DbSet<actItem> actItems { get; set; }
|
||||||
|
public virtual DbSet<actItem_files> actItem_files { get; set; }
|
||||||
|
public virtual DbSet<actItem_kind> actItem_kind { get; set; }
|
||||||
|
public virtual DbSet<activity> activities { get; set; }
|
||||||
|
public virtual DbSet<activity_category_kind> activity_category_kind { get; set; }
|
||||||
|
public virtual DbSet<activity_check> activity_check { get; set; }
|
||||||
|
public virtual DbSet<activity_kind> activity_kind { get; set; }
|
||||||
|
public virtual DbSet<activity_kind_detail> activity_kind_detail { get; set; }
|
||||||
|
public virtual DbSet<activity_relating> activity_relating { get; set; }
|
||||||
|
public virtual DbSet<activity_spares> activity_spares { get; set; }
|
||||||
|
public virtual DbSet<admin> admins { get; set; }
|
||||||
|
public virtual DbSet<admin_group> admin_group { get; set; }
|
||||||
|
public virtual DbSet<admin_log> admin_log { get; set; }
|
||||||
|
public virtual DbSet<appellation> appellations { get; set; }
|
||||||
|
public virtual DbSet<bed_kind> bed_kind { get; set; }
|
||||||
|
public virtual DbSet<bed_kind_detail> bed_kind_detail { get; set; }
|
||||||
|
public virtual DbSet<bed_order> bed_order { get; set; }
|
||||||
|
public virtual DbSet<bed_order_detail> bed_order_detail { get; set; }
|
||||||
|
public virtual DbSet<company> companies { get; set; }
|
||||||
|
public virtual DbSet<country> countries { get; set; }
|
||||||
|
public virtual DbSet<file> files { get; set; }
|
||||||
|
public virtual DbSet<follower> followers { get; set; }
|
||||||
|
public virtual DbSet<followers_tablet> followers_tablet { get; set; }
|
||||||
|
public virtual DbSet<item> items { get; set; }
|
||||||
|
public virtual DbSet<member> members { get; set; }
|
||||||
|
public virtual DbSet<member_check> member_check { get; set; }
|
||||||
|
public virtual DbSet<member_group> member_group { get; set; }
|
||||||
|
public virtual DbSet<member_title> member_title { get; set; }
|
||||||
|
public virtual DbSet<news> news { get; set; }
|
||||||
|
public virtual DbSet<news_files> news_files { get; set; }
|
||||||
|
public virtual DbSet<news_kind> news_kind { get; set; }
|
||||||
|
public virtual DbSet<pro_order> pro_order { get; set; }
|
||||||
|
public virtual DbSet<pro_order_detail> pro_order_detail { get; set; }
|
||||||
|
public virtual DbSet<pro_order_record> pro_order_record { get; set; }
|
||||||
|
public virtual DbSet<project> projects { get; set; }
|
||||||
|
public virtual DbSet<project_kind> project_kind { get; set; }
|
||||||
|
public virtual DbSet<project_sub> project_sub { get; set; }
|
||||||
|
public virtual DbSet<stock> stocks { get; set; }
|
||||||
|
public virtual DbSet<stock_files> stock_files { get; set; }
|
||||||
|
public virtual DbSet<stock_kind> stock_kind { get; set; }
|
||||||
|
public virtual DbSet<stock_reason> stock_reason { get; set; }
|
||||||
|
public virtual DbSet<supplier> suppliers { get; set; }
|
||||||
|
public virtual DbSet<supplier_kind> supplier_kind { get; set; }
|
||||||
|
public virtual DbSet<sysdiagram> sysdiagrams { get; set; }
|
||||||
|
public virtual DbSet<act_bom> act_bom { get; set; }
|
||||||
|
public virtual DbSet<family_members> family_members { get; set; }
|
||||||
|
public virtual DbSet<PostCity> PostCitiy { get; set; }
|
||||||
|
public virtual DbSet<PostNumber> PostNumber { get; set; }
|
||||||
|
public virtual DbSet<ShuWen> ShuWens { get; set; }
|
||||||
|
public virtual DbSet<transfer_register> transfer_register { get; set; }
|
||||||
|
|
||||||
|
public virtual int pager_eztrust(Nullable<int> startRowIndex, Nullable<int> pageSize, string tableName, string columnName, string sqlWhere, string orderBy, ObjectParameter rowCount)
|
||||||
|
{
|
||||||
|
var startRowIndexParameter = startRowIndex.HasValue ?
|
||||||
|
new ObjectParameter("StartRowIndex", startRowIndex) :
|
||||||
|
new ObjectParameter("StartRowIndex", typeof(int));
|
||||||
|
|
||||||
|
var pageSizeParameter = pageSize.HasValue ?
|
||||||
|
new ObjectParameter("PageSize", pageSize) :
|
||||||
|
new ObjectParameter("PageSize", typeof(int));
|
||||||
|
|
||||||
|
var tableNameParameter = tableName != null ?
|
||||||
|
new ObjectParameter("tableName", tableName) :
|
||||||
|
new ObjectParameter("tableName", typeof(string));
|
||||||
|
|
||||||
|
var columnNameParameter = columnName != null ?
|
||||||
|
new ObjectParameter("columnName", columnName) :
|
||||||
|
new ObjectParameter("columnName", typeof(string));
|
||||||
|
|
||||||
|
var sqlWhereParameter = sqlWhere != null ?
|
||||||
|
new ObjectParameter("sqlWhere", sqlWhere) :
|
||||||
|
new ObjectParameter("sqlWhere", typeof(string));
|
||||||
|
|
||||||
|
var orderByParameter = orderBy != null ?
|
||||||
|
new ObjectParameter("orderBy", orderBy) :
|
||||||
|
new ObjectParameter("orderBy", typeof(string));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("pager_eztrust", startRowIndexParameter, pageSizeParameter, tableNameParameter, columnNameParameter, sqlWhereParameter, orderByParameter, rowCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int sp_alterdiagram(string diagramname, Nullable<int> owner_id, Nullable<int> version, byte[] definition)
|
||||||
|
{
|
||||||
|
var diagramnameParameter = diagramname != null ?
|
||||||
|
new ObjectParameter("diagramname", diagramname) :
|
||||||
|
new ObjectParameter("diagramname", typeof(string));
|
||||||
|
|
||||||
|
var owner_idParameter = owner_id.HasValue ?
|
||||||
|
new ObjectParameter("owner_id", owner_id) :
|
||||||
|
new ObjectParameter("owner_id", typeof(int));
|
||||||
|
|
||||||
|
var versionParameter = version.HasValue ?
|
||||||
|
new ObjectParameter("version", version) :
|
||||||
|
new ObjectParameter("version", typeof(int));
|
||||||
|
|
||||||
|
var definitionParameter = definition != null ?
|
||||||
|
new ObjectParameter("definition", definition) :
|
||||||
|
new ObjectParameter("definition", typeof(byte[]));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_alterdiagram", diagramnameParameter, owner_idParameter, versionParameter, definitionParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int sp_creatediagram(string diagramname, Nullable<int> owner_id, Nullable<int> version, byte[] definition)
|
||||||
|
{
|
||||||
|
var diagramnameParameter = diagramname != null ?
|
||||||
|
new ObjectParameter("diagramname", diagramname) :
|
||||||
|
new ObjectParameter("diagramname", typeof(string));
|
||||||
|
|
||||||
|
var owner_idParameter = owner_id.HasValue ?
|
||||||
|
new ObjectParameter("owner_id", owner_id) :
|
||||||
|
new ObjectParameter("owner_id", typeof(int));
|
||||||
|
|
||||||
|
var versionParameter = version.HasValue ?
|
||||||
|
new ObjectParameter("version", version) :
|
||||||
|
new ObjectParameter("version", typeof(int));
|
||||||
|
|
||||||
|
var definitionParameter = definition != null ?
|
||||||
|
new ObjectParameter("definition", definition) :
|
||||||
|
new ObjectParameter("definition", typeof(byte[]));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_creatediagram", diagramnameParameter, owner_idParameter, versionParameter, definitionParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int sp_dropdiagram(string diagramname, Nullable<int> owner_id)
|
||||||
|
{
|
||||||
|
var diagramnameParameter = diagramname != null ?
|
||||||
|
new ObjectParameter("diagramname", diagramname) :
|
||||||
|
new ObjectParameter("diagramname", typeof(string));
|
||||||
|
|
||||||
|
var owner_idParameter = owner_id.HasValue ?
|
||||||
|
new ObjectParameter("owner_id", owner_id) :
|
||||||
|
new ObjectParameter("owner_id", typeof(int));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_dropdiagram", diagramnameParameter, owner_idParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual ObjectResult<sp_helpdiagramdefinition_Result> sp_helpdiagramdefinition(string diagramname, Nullable<int> owner_id)
|
||||||
|
{
|
||||||
|
var diagramnameParameter = diagramname != null ?
|
||||||
|
new ObjectParameter("diagramname", diagramname) :
|
||||||
|
new ObjectParameter("diagramname", typeof(string));
|
||||||
|
|
||||||
|
var owner_idParameter = owner_id.HasValue ?
|
||||||
|
new ObjectParameter("owner_id", owner_id) :
|
||||||
|
new ObjectParameter("owner_id", typeof(int));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<sp_helpdiagramdefinition_Result>("sp_helpdiagramdefinition", diagramnameParameter, owner_idParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual ObjectResult<sp_helpdiagrams_Result> sp_helpdiagrams(string diagramname, Nullable<int> owner_id)
|
||||||
|
{
|
||||||
|
var diagramnameParameter = diagramname != null ?
|
||||||
|
new ObjectParameter("diagramname", diagramname) :
|
||||||
|
new ObjectParameter("diagramname", typeof(string));
|
||||||
|
|
||||||
|
var owner_idParameter = owner_id.HasValue ?
|
||||||
|
new ObjectParameter("owner_id", owner_id) :
|
||||||
|
new ObjectParameter("owner_id", typeof(int));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<sp_helpdiagrams_Result>("sp_helpdiagrams", diagramnameParameter, owner_idParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int sp_renamediagram(string diagramname, Nullable<int> owner_id, string new_diagramname)
|
||||||
|
{
|
||||||
|
var diagramnameParameter = diagramname != null ?
|
||||||
|
new ObjectParameter("diagramname", diagramname) :
|
||||||
|
new ObjectParameter("diagramname", typeof(string));
|
||||||
|
|
||||||
|
var owner_idParameter = owner_id.HasValue ?
|
||||||
|
new ObjectParameter("owner_id", owner_id) :
|
||||||
|
new ObjectParameter("owner_id", typeof(int));
|
||||||
|
|
||||||
|
var new_diagramnameParameter = new_diagramname != null ?
|
||||||
|
new ObjectParameter("new_diagramname", new_diagramname) :
|
||||||
|
new ObjectParameter("new_diagramname", typeof(string));
|
||||||
|
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_renamediagram", diagramnameParameter, owner_idParameter, new_diagramnameParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int sp_upgraddiagrams()
|
||||||
|
{
|
||||||
|
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_upgraddiagrams");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
636
web/App_Code/Model/Model.Context.tt
Normal file
636
web/App_Code/Model/Model.Context.tt
Normal file
@@ -0,0 +1,636 @@
|
|||||||
|
<#@ template language="C#" debug="false" hostspecific="true"#>
|
||||||
|
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
|
||||||
|
output extension=".cs"#><#
|
||||||
|
|
||||||
|
const string inputFile = @"Model.edmx";
|
||||||
|
var textTransform = DynamicTextTransformation.Create(this);
|
||||||
|
var code = new CodeGenerationTools(this);
|
||||||
|
var ef = new MetadataTools(this);
|
||||||
|
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
|
||||||
|
var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
|
||||||
|
var itemCollection = loader.CreateEdmItemCollection(inputFile);
|
||||||
|
var modelNamespace = loader.GetModelNamespace(inputFile);
|
||||||
|
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
|
||||||
|
|
||||||
|
var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
|
||||||
|
if (container == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
|
||||||
|
//
|
||||||
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
|
||||||
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
<#
|
||||||
|
|
||||||
|
var codeNamespace = code.VsNamespaceSuggestion();
|
||||||
|
if (!String.IsNullOrEmpty(codeNamespace))
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
namespace <#=code.EscapeNamespace(codeNamespace)#>
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
PushIndent(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
#>
|
||||||
|
using System;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Data.Entity.Infrastructure;
|
||||||
|
<#
|
||||||
|
if (container.FunctionImports.Any())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
using System.Data.Entity.Core.Objects;
|
||||||
|
using System.Linq;
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
|
||||||
|
{
|
||||||
|
public <#=code.Escape(container)#>()
|
||||||
|
: base("name=<#=container.Name#>")
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
if (!loader.IsLazyLoadingEnabled(container))
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
this.Configuration.LazyLoadingEnabled = false;
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
|
||||||
|
{
|
||||||
|
// Note: the DbSet members are defined below such that the getter and
|
||||||
|
// setter always have the same accessibility as the DbSet definition
|
||||||
|
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(DbModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
throw new UnintentionalCodeFirstException();
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.DbSet(entitySet)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var edmFunction in container.FunctionImports)
|
||||||
|
{
|
||||||
|
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
<#
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(codeNamespace))
|
||||||
|
{
|
||||||
|
PopIndent();
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
<#+
|
||||||
|
|
||||||
|
private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
if (typeMapper.IsComposable(edmFunction))
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
|
||||||
|
[DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
|
||||||
|
<#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
|
||||||
|
{
|
||||||
|
<#+
|
||||||
|
codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
|
||||||
|
}
|
||||||
|
<#+
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
|
||||||
|
{
|
||||||
|
<#+
|
||||||
|
codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
|
||||||
|
}
|
||||||
|
<#+
|
||||||
|
if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
|
||||||
|
{
|
||||||
|
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
var <#=name#> = <#=isNotNull#> ?
|
||||||
|
<#=notNullInit#> :
|
||||||
|
<#=nullInit#>;
|
||||||
|
|
||||||
|
<#+
|
||||||
|
}
|
||||||
|
|
||||||
|
public const string TemplateId = "CSharp_DbContext_Context_EF6";
|
||||||
|
|
||||||
|
public class CodeStringGenerator
|
||||||
|
{
|
||||||
|
private readonly CodeGenerationTools _code;
|
||||||
|
private readonly TypeMapper _typeMapper;
|
||||||
|
private readonly MetadataTools _ef;
|
||||||
|
|
||||||
|
public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(code, "code");
|
||||||
|
ArgumentNotNull(typeMapper, "typeMapper");
|
||||||
|
ArgumentNotNull(ef, "ef");
|
||||||
|
|
||||||
|
_code = code;
|
||||||
|
_typeMapper = typeMapper;
|
||||||
|
_ef = ef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Property(EdmProperty edmProperty)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1} {2} {{ {3}get; {4}set; }}",
|
||||||
|
Accessibility.ForProperty(edmProperty),
|
||||||
|
_typeMapper.GetTypeName(edmProperty.TypeUsage),
|
||||||
|
_code.Escape(edmProperty),
|
||||||
|
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
|
||||||
|
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NavigationProperty(NavigationProperty navProp)
|
||||||
|
{
|
||||||
|
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1} {2} {{ {3}get; {4}set; }}",
|
||||||
|
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
|
||||||
|
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
|
||||||
|
_code.Escape(navProp),
|
||||||
|
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
|
||||||
|
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AccessibilityAndVirtual(string accessibility)
|
||||||
|
{
|
||||||
|
return accessibility + (accessibility != "private" ? " virtual" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EntityClassOpening(EntityType entity)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1}partial class {2}{3}",
|
||||||
|
Accessibility.ForType(entity),
|
||||||
|
_code.SpaceAfter(_code.AbstractOption(entity)),
|
||||||
|
_code.Escape(entity),
|
||||||
|
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EnumOpening(SimpleType enumType)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} enum {1} : {2}",
|
||||||
|
Accessibility.ForType(enumType),
|
||||||
|
_code.Escape(enumType),
|
||||||
|
_code.Escape(_typeMapper.UnderlyingClrType(enumType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
|
||||||
|
{
|
||||||
|
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
|
||||||
|
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
|
||||||
|
{
|
||||||
|
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
|
||||||
|
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
|
||||||
|
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
|
||||||
|
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} IQueryable<{1}> {2}({3})",
|
||||||
|
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
|
||||||
|
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
|
||||||
|
_code.Escape(edmFunction),
|
||||||
|
string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
|
||||||
|
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
|
||||||
|
edmFunction.NamespaceName,
|
||||||
|
edmFunction.Name,
|
||||||
|
string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
|
||||||
|
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
var returnType = _typeMapper.GetReturnType(edmFunction);
|
||||||
|
|
||||||
|
var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
|
||||||
|
if (includeMergeOption)
|
||||||
|
{
|
||||||
|
paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1} {2}({3})",
|
||||||
|
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
|
||||||
|
returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
|
||||||
|
_code.Escape(edmFunction),
|
||||||
|
paramList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
var returnType = _typeMapper.GetReturnType(edmFunction);
|
||||||
|
|
||||||
|
var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
|
||||||
|
if (includeMergeOption)
|
||||||
|
{
|
||||||
|
callParams = ", mergeOption" + callParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
|
||||||
|
returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
|
||||||
|
edmFunction.Name,
|
||||||
|
callParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DbSet(EntitySet entitySet)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} virtual DbSet<{1}> {2} {{ get; set; }}",
|
||||||
|
Accessibility.ForReadOnlyProperty(entitySet),
|
||||||
|
_typeMapper.GetTypeName(entitySet.ElementType),
|
||||||
|
_code.Escape(entitySet));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DbSetInitializer(EntitySet entitySet)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} = Set<{1}>();",
|
||||||
|
_code.Escape(entitySet),
|
||||||
|
_typeMapper.GetTypeName(entitySet.ElementType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UsingDirectives(bool inHeader, bool includeCollections = true)
|
||||||
|
{
|
||||||
|
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
|
||||||
|
? string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0}using System;{1}" +
|
||||||
|
"{2}",
|
||||||
|
inHeader ? Environment.NewLine : "",
|
||||||
|
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
|
||||||
|
inHeader ? "" : Environment.NewLine)
|
||||||
|
: "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TypeMapper
|
||||||
|
{
|
||||||
|
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
|
||||||
|
|
||||||
|
private readonly System.Collections.IList _errors;
|
||||||
|
private readonly CodeGenerationTools _code;
|
||||||
|
private readonly MetadataTools _ef;
|
||||||
|
|
||||||
|
public static string FixNamespaces(string typeName)
|
||||||
|
{
|
||||||
|
return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(code, "code");
|
||||||
|
ArgumentNotNull(ef, "ef");
|
||||||
|
ArgumentNotNull(errors, "errors");
|
||||||
|
|
||||||
|
_code = code;
|
||||||
|
_ef = ef;
|
||||||
|
_errors = errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(TypeUsage typeUsage)
|
||||||
|
{
|
||||||
|
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(EdmType edmType)
|
||||||
|
{
|
||||||
|
return GetTypeName(edmType, isNullable: null, modelNamespace: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
|
||||||
|
{
|
||||||
|
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(EdmType edmType, string modelNamespace)
|
||||||
|
{
|
||||||
|
return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
|
||||||
|
{
|
||||||
|
if (edmType == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var collectionType = edmType as CollectionType;
|
||||||
|
if (collectionType != null)
|
||||||
|
{
|
||||||
|
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeName = _code.Escape(edmType.MetadataProperties
|
||||||
|
.Where(p => p.Name == ExternalTypeNameAttributeName)
|
||||||
|
.Select(p => (string)p.Value)
|
||||||
|
.FirstOrDefault())
|
||||||
|
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
|
||||||
|
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
|
||||||
|
_code.Escape(edmType));
|
||||||
|
|
||||||
|
if (edmType is StructuralType)
|
||||||
|
{
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edmType is SimpleType)
|
||||||
|
{
|
||||||
|
var clrType = UnderlyingClrType(edmType);
|
||||||
|
if (!IsEnumType(edmType))
|
||||||
|
{
|
||||||
|
typeName = _code.Escape(clrType);
|
||||||
|
}
|
||||||
|
|
||||||
|
typeName = FixNamespaces(typeName);
|
||||||
|
|
||||||
|
return clrType.IsValueType && isNullable == true ?
|
||||||
|
String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
|
||||||
|
typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException("edmType");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type UnderlyingClrType(EdmType edmType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmType, "edmType");
|
||||||
|
|
||||||
|
var primitiveType = edmType as PrimitiveType;
|
||||||
|
if (primitiveType != null)
|
||||||
|
{
|
||||||
|
return primitiveType.ClrEquivalentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsEnumType(edmType))
|
||||||
|
{
|
||||||
|
return GetEnumUnderlyingType(edmType).ClrEquivalentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetEnumMemberValue(MetadataItem enumMember)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumMember, "enumMember");
|
||||||
|
|
||||||
|
var valueProperty = enumMember.GetType().GetProperty("Value");
|
||||||
|
return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetEnumMemberName(MetadataItem enumMember)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumMember, "enumMember");
|
||||||
|
|
||||||
|
var nameProperty = enumMember.GetType().GetProperty("Name");
|
||||||
|
return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumType, "enumType");
|
||||||
|
|
||||||
|
var membersProperty = enumType.GetType().GetProperty("Members");
|
||||||
|
return membersProperty != null
|
||||||
|
? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
|
||||||
|
: Enumerable.Empty<MetadataItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool EnumIsFlags(EdmType enumType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumType, "enumType");
|
||||||
|
|
||||||
|
var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
|
||||||
|
return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnumType(GlobalItem edmType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmType, "edmType");
|
||||||
|
|
||||||
|
return edmType.GetType().Name == "EnumType";
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumType, "enumType");
|
||||||
|
|
||||||
|
return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CreateLiteral(object value)
|
||||||
|
{
|
||||||
|
if (value == null || value.GetType() != typeof(TimeSpan))
|
||||||
|
{
|
||||||
|
return _code.CreateLiteral(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(types, "types");
|
||||||
|
ArgumentNotNull(sourceFile, "sourceFile");
|
||||||
|
|
||||||
|
var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||||
|
if (types.Any(item => !hash.Add(item)))
|
||||||
|
{
|
||||||
|
_errors.Add(
|
||||||
|
new CompilerError(sourceFile, -1, -1, "6023",
|
||||||
|
String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
|
||||||
|
{
|
||||||
|
return GetItemsToGenerate<SimpleType>(itemCollection)
|
||||||
|
.Where(e => IsEnumType(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
|
||||||
|
{
|
||||||
|
return itemCollection
|
||||||
|
.OfType<T>()
|
||||||
|
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
|
||||||
|
.OrderBy(i => i.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
|
||||||
|
{
|
||||||
|
return itemCollection
|
||||||
|
.Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
|
||||||
|
.Select(g => GetGlobalItemName(g));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetGlobalItemName(GlobalItem item)
|
||||||
|
{
|
||||||
|
if (item is EdmType)
|
||||||
|
{
|
||||||
|
return ((EdmType)item).Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((EntityContainer)item).Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.NavigationProperties.Where(np => np.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmFunction, "edmFunction");
|
||||||
|
|
||||||
|
var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
|
||||||
|
return returnParamsProperty == null
|
||||||
|
? edmFunction.ReturnParameter
|
||||||
|
: ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsComposable(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmFunction, "edmFunction");
|
||||||
|
|
||||||
|
var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
|
||||||
|
return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeUsage GetReturnType(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
var returnParam = GetReturnParameter(edmFunction);
|
||||||
|
return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
var returnType = GetReturnType(edmFunction);
|
||||||
|
return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ArgumentNotNull<T>(T arg, string name) where T : class
|
||||||
|
{
|
||||||
|
if (arg == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#>
|
||||||
10
web/App_Code/Model/Model.Designer.cs
generated
Normal file
10
web/App_Code/Model/Model.Designer.cs
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// T4 code generation is enabled for model 'D:\dev\ez\17168erp\git_gitea\web\App_Code\Model\Model.edmx'.
|
||||||
|
// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
|
||||||
|
// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
|
||||||
|
// is open in the designer.
|
||||||
|
|
||||||
|
// If no context and entity classes have been generated, it may be because you created an empty model but
|
||||||
|
// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
|
||||||
|
// classes for your model, open the model in the designer, right-click on the designer surface, and
|
||||||
|
// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
|
||||||
|
// Item...'.
|
||||||
1536
web/App_Code/Model/Model.cs
Normal file
1536
web/App_Code/Model/Model.cs
Normal file
File diff suppressed because it is too large
Load Diff
5186
web/App_Code/Model/Model.edmx
Normal file
5186
web/App_Code/Model/Model.edmx
Normal file
File diff suppressed because it is too large
Load Diff
137
web/App_Code/Model/Model.edmx.diagram
Normal file
137
web/App_Code/Model/Model.edmx.diagram
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
|
||||||
|
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
|
||||||
|
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
|
||||||
|
<!-- Diagram content (shape and connector positions) -->
|
||||||
|
<edmx:Diagrams>
|
||||||
|
<Diagram DiagramId="b267a343dc0c4bf0ae194b775754b108" Name="Diagram1" ZoomLevel="100">
|
||||||
|
<EntityTypeShape EntityType="Model.accounting" Width="1.5" PointX="22.5" PointY="22.125" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.accounting_files" Width="1.5" PointX="15.75" PointY="27.75" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.accounting_kind" Width="1.5" PointX="11.25" PointY="27.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.accounting_kind2" Width="1.5" PointX="13.5" PointY="11.25" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.actItem" Width="1.5" PointX="9.25" PointY="7.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.actItem_files" Width="1.5" PointX="16.5" PointY="5.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.actItem_kind" Width="1.5" PointX="6.125" PointY="7.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity" Width="1.5" PointX="3" PointY="8.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity_category_kind" Width="1.5" PointX="0.75" PointY="9" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity_check" Width="1.5" PointX="5.25" PointY="18.5" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity_kind" Width="1.5" PointX="0.75" PointY="11.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity_kind_detail" Width="1.5" PointX="13.5" PointY="3.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity_relating" Width="1.5" PointX="10.5" PointY="9.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.activity_spares" Width="1.5" PointX="13.5" PointY="7.75" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.admin" Width="1.5" PointX="6" PointY="1.375" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.admin_group" Width="1.5" PointX="3.75" PointY="3.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.admin_log" Width="1.5" PointX="0.75" PointY="2" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.appellation" Width="1.5" PointX="0.75" PointY="19" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.bed_kind" Width="1.5" PointX="15.75" PointY="12.375" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.bed_kind_detail" Width="1.5" PointX="15.75" PointY="8.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.bed_order" Width="1.5" PointX="12.75" PointY="15.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.bed_order_detail" Width="1.5" PointX="18" PointY="15.75" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.company" Width="1.5" PointX="17.75" PointY="10" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.country" Width="1.5" PointX="0.75" PointY="15.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.file" Width="1.5" PointX="14.25" PointY="41.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.follower" Width="1.5" PointX="3" PointY="15.5" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.followers_tablet" Width="1.5" PointX="5.25" PointY="22.125" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.item" Width="1.5" PointX="18.75" PointY="2" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.member" Width="1.5" PointX="8.25" PointY="16.125" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.member_check" Width="1.5" PointX="10.5" PointY="23.375" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.member_group" Width="1.5" PointX="6" PointY="25.5" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.member_title" Width="1.5" PointX="6" PointY="28.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.news" Width="1.5" PointX="11.25" PointY="4.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.news_files" Width="1.5" PointX="13.5" PointY="25.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.news_kind" Width="1.5" PointX="9" PointY="3.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.pro_order" Width="1.5" PointX="5.25" PointY="13.75" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.pro_order_detail" Width="1.5" PointX="10.5" PointY="15" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.pro_order_record" Width="1.5" PointX="15.75" PointY="16.5" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.project" Width="1.5" PointX="16.5" PointY="1.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.project_kind" Width="1.5" PointX="14.25" PointY="0.75" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.project_sub" Width="1.5" PointX="18.75" PointY="6.125" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.stock" Width="1.5" PointX="16.5" PointY="21" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.stock_files" Width="1.5" PointX="18.75" PointY="22.75" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.stock_kind" Width="1.5" PointX="14.25" PointY="30.875" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.stock_reason" Width="1.5" PointX="14.25" PointY="33.625" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.supplier" Width="1.5" PointX="14.25" PointY="36.5" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.supplier_kind" Width="1.5" PointX="12" PointY="37.5" IsExpanded="true" />
|
||||||
|
<EntityTypeShape EntityType="Model.sysdiagram" Width="1.5" PointX="0.75" PointY="6" IsExpanded="true" />
|
||||||
|
<AssociationConnector Association="Model.FK_accounting_accounting_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_accounting_accounting_kind2" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_accounting_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_accounting_files_accounting" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_accounting_member" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_record_accounting_kind2" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_actItem_actItem_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_actItem_files_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_kind_detail_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_relating_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_spares_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_detail_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_project_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_actItem" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_actItem_files_files" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_activity_category_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_activity_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_check_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_relating_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_spares_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_news_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_activity" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_check_followers" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_activity_kind_detail_activity_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_admin_admin_group" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_member_admin" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_news_admin" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_followers_appellation" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_kind_detail_bed_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_order_detail_bed_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_order_detail_bed_kind1" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_order_detail_bed_kind_detail" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_order_detail_bed_order" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_order_pro_order" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_bed_order_pro_order_detail" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_followers_country" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_followers_followers" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_followers_tablet_followers" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_member_followers" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_detail_followers" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_detail_followers1" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_followers" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_introducer" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_member_check_member" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_member_member_group" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_member_member_title" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_member" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_news_files_news" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_news_news_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_detail_pro_order" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_record_pro_order_detail" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_project_project_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_project_sub_project" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_files_stock" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_stock_kind" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_stock_reason" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_stock_supplier" ManuallyRouted="false" />
|
||||||
|
<AssociationConnector Association="Model.FK_supplier_supplier_kind" ManuallyRouted="false" />
|
||||||
|
<EntityTypeShape EntityType="Model.act_bom" Width="1.5" PointX="6.5" PointY="10" />
|
||||||
|
<AssociationConnector Association="Model.FK_act_bom_act_bom" />
|
||||||
|
<AssociationConnector Association="Model.FK_act_bom_actItem1" />
|
||||||
|
<EntityTypeShape EntityType="Model.family_members" Width="1.5" PointX="5.25" PointY="32.125" />
|
||||||
|
<AssociationConnector Association="Model.FK_family_members_followers" />
|
||||||
|
<EntityTypeShape EntityType="Model.PostCity" Width="1.5" PointX="8.375" PointY="0.75" />
|
||||||
|
<EntityTypeShape EntityType="Model.PostNumber" Width="1.5" PointX="10.375" PointY="0.75" />
|
||||||
|
<EntityTypeShape EntityType="Model.ShuWen" Width="1.5" PointX="19.375" PointY="19.75" />
|
||||||
|
<EntityTypeShape EntityType="Model.transfer_register" Width="1.5" PointX="20.75" PointY="11.875" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_accountings" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_accounting_kind2" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_activity" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_followers" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_followers_match" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_member" />
|
||||||
|
<AssociationConnector Association="Model.FK_accounting_pro_order_detail" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_actItem" />
|
||||||
|
<AssociationConnector Association="Model.FK_transfer_register_pro_order_detail" />
|
||||||
|
<AssociationConnector Association="Model.FK_pro_order_record_transfer_register" />
|
||||||
|
</Diagram>
|
||||||
|
</edmx:Diagrams>
|
||||||
|
</edmx:Designer>
|
||||||
|
</edmx:Edmx>
|
||||||
733
web/App_Code/Model/Model.tt
Normal file
733
web/App_Code/Model/Model.tt
Normal file
@@ -0,0 +1,733 @@
|
|||||||
|
<#@ template language="C#" debug="false" hostspecific="true"#>
|
||||||
|
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
|
||||||
|
output extension=".cs"#><#
|
||||||
|
|
||||||
|
const string inputFile = @"Model.edmx";
|
||||||
|
var textTransform = DynamicTextTransformation.Create(this);
|
||||||
|
var code = new CodeGenerationTools(this);
|
||||||
|
var ef = new MetadataTools(this);
|
||||||
|
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
|
||||||
|
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
|
||||||
|
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
|
||||||
|
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
|
||||||
|
|
||||||
|
if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteHeader(codeStringGenerator, fileManager);
|
||||||
|
|
||||||
|
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
|
||||||
|
{
|
||||||
|
fileManager.StartNewFile(entity.Name + ".cs");
|
||||||
|
BeginNamespace(code);
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
|
||||||
|
<#=codeStringGenerator.EntityClassOpening(entity)#>
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
|
||||||
|
var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
|
||||||
|
var complexProperties = typeMapper.GetComplexProperties(entity);
|
||||||
|
|
||||||
|
if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public <#=code.Escape(entity)#>()
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
foreach (var edmProperty in propertiesWithDefaultValues)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var navigationProperty in collectionNavigationProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var complexProperty in complexProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
var simpleProperties = typeMapper.GetSimpleProperties(entity);
|
||||||
|
if (simpleProperties.Any())
|
||||||
|
{
|
||||||
|
foreach (var edmProperty in simpleProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.Property(edmProperty)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complexProperties.Any())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
foreach(var complexProperty in complexProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.Property(complexProperty)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var navigationProperties = typeMapper.GetNavigationProperties(entity);
|
||||||
|
if (navigationProperties.Any())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
foreach (var navigationProperty in navigationProperties)
|
||||||
|
{
|
||||||
|
if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.NavigationProperty(navigationProperty)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
<#
|
||||||
|
EndNamespace(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
|
||||||
|
{
|
||||||
|
fileManager.StartNewFile(complex.Name + ".cs");
|
||||||
|
BeginNamespace(code);
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
|
||||||
|
<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
var complexProperties = typeMapper.GetComplexProperties(complex);
|
||||||
|
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
|
||||||
|
|
||||||
|
if (propertiesWithDefaultValues.Any() || complexProperties.Any())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
public <#=code.Escape(complex)#>()
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
foreach (var edmProperty in propertiesWithDefaultValues)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var complexProperty in complexProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
var simpleProperties = typeMapper.GetSimpleProperties(complex);
|
||||||
|
if (simpleProperties.Any())
|
||||||
|
{
|
||||||
|
foreach(var edmProperty in simpleProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.Property(edmProperty)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complexProperties.Any())
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
|
||||||
|
<#
|
||||||
|
foreach(var edmProperty in complexProperties)
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.Property(edmProperty)#>
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
<#
|
||||||
|
EndNamespace(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
|
||||||
|
{
|
||||||
|
fileManager.StartNewFile(enumType.Name + ".cs");
|
||||||
|
BeginNamespace(code);
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
|
||||||
|
<#
|
||||||
|
if (typeMapper.EnumIsFlags(enumType))
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
[Flags]
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
<#=codeStringGenerator.EnumOpening(enumType)#>
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
var foundOne = false;
|
||||||
|
|
||||||
|
foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
|
||||||
|
{
|
||||||
|
foundOne = true;
|
||||||
|
#>
|
||||||
|
<#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
|
||||||
|
<#
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundOne)
|
||||||
|
{
|
||||||
|
this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
|
||||||
|
}
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
<#
|
||||||
|
EndNamespace(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileManager.Process();
|
||||||
|
|
||||||
|
#>
|
||||||
|
<#+
|
||||||
|
|
||||||
|
public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
|
||||||
|
{
|
||||||
|
fileManager.StartHeader();
|
||||||
|
#>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
|
||||||
|
//
|
||||||
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
|
||||||
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
|
||||||
|
<#+
|
||||||
|
fileManager.EndBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginNamespace(CodeGenerationTools code)
|
||||||
|
{
|
||||||
|
var codeNamespace = code.VsNamespaceSuggestion();
|
||||||
|
if (!String.IsNullOrEmpty(codeNamespace))
|
||||||
|
{
|
||||||
|
#>
|
||||||
|
namespace <#=code.EscapeNamespace(codeNamespace)#>
|
||||||
|
{
|
||||||
|
<#+
|
||||||
|
PushIndent(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndNamespace(CodeGenerationTools code)
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
|
||||||
|
{
|
||||||
|
PopIndent();
|
||||||
|
#>
|
||||||
|
}
|
||||||
|
<#+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public const string TemplateId = "CSharp_DbContext_Types_EF6";
|
||||||
|
|
||||||
|
public class CodeStringGenerator
|
||||||
|
{
|
||||||
|
private readonly CodeGenerationTools _code;
|
||||||
|
private readonly TypeMapper _typeMapper;
|
||||||
|
private readonly MetadataTools _ef;
|
||||||
|
|
||||||
|
public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(code, "code");
|
||||||
|
ArgumentNotNull(typeMapper, "typeMapper");
|
||||||
|
ArgumentNotNull(ef, "ef");
|
||||||
|
|
||||||
|
_code = code;
|
||||||
|
_typeMapper = typeMapper;
|
||||||
|
_ef = ef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Property(EdmProperty edmProperty)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1} {2} {{ {3}get; {4}set; }}",
|
||||||
|
Accessibility.ForProperty(edmProperty),
|
||||||
|
_typeMapper.GetTypeName(edmProperty.TypeUsage),
|
||||||
|
_code.Escape(edmProperty),
|
||||||
|
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
|
||||||
|
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NavigationProperty(NavigationProperty navProp)
|
||||||
|
{
|
||||||
|
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1} {2} {{ {3}get; {4}set; }}",
|
||||||
|
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
|
||||||
|
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
|
||||||
|
_code.Escape(navProp),
|
||||||
|
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
|
||||||
|
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AccessibilityAndVirtual(string accessibility)
|
||||||
|
{
|
||||||
|
return accessibility + (accessibility != "private" ? " virtual" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EntityClassOpening(EntityType entity)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1}partial class {2}{3}",
|
||||||
|
Accessibility.ForType(entity),
|
||||||
|
_code.SpaceAfter(_code.AbstractOption(entity)),
|
||||||
|
_code.Escape(entity),
|
||||||
|
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EnumOpening(SimpleType enumType)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} enum {1} : {2}",
|
||||||
|
Accessibility.ForType(enumType),
|
||||||
|
_code.Escape(enumType),
|
||||||
|
_code.Escape(_typeMapper.UnderlyingClrType(enumType)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
|
||||||
|
{
|
||||||
|
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
|
||||||
|
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
|
||||||
|
{
|
||||||
|
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
|
||||||
|
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
|
||||||
|
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
|
||||||
|
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} IQueryable<{1}> {2}({3})",
|
||||||
|
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
|
||||||
|
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
|
||||||
|
_code.Escape(edmFunction),
|
||||||
|
string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
|
||||||
|
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
|
||||||
|
edmFunction.NamespaceName,
|
||||||
|
edmFunction.Name,
|
||||||
|
string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
|
||||||
|
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
var returnType = _typeMapper.GetReturnType(edmFunction);
|
||||||
|
|
||||||
|
var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
|
||||||
|
if (includeMergeOption)
|
||||||
|
{
|
||||||
|
paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1} {2}({3})",
|
||||||
|
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
|
||||||
|
returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
|
||||||
|
_code.Escape(edmFunction),
|
||||||
|
paramList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
var parameters = _typeMapper.GetParameters(edmFunction);
|
||||||
|
var returnType = _typeMapper.GetReturnType(edmFunction);
|
||||||
|
|
||||||
|
var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
|
||||||
|
if (includeMergeOption)
|
||||||
|
{
|
||||||
|
callParams = ", mergeOption" + callParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
|
||||||
|
returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
|
||||||
|
edmFunction.Name,
|
||||||
|
callParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DbSet(EntitySet entitySet)
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0} virtual DbSet<{1}> {2} {{ get; set; }}",
|
||||||
|
Accessibility.ForReadOnlyProperty(entitySet),
|
||||||
|
_typeMapper.GetTypeName(entitySet.ElementType),
|
||||||
|
_code.Escape(entitySet));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UsingDirectives(bool inHeader, bool includeCollections = true)
|
||||||
|
{
|
||||||
|
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
|
||||||
|
? string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0}using System;{1}" +
|
||||||
|
"{2}",
|
||||||
|
inHeader ? Environment.NewLine : "",
|
||||||
|
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
|
||||||
|
inHeader ? "" : Environment.NewLine)
|
||||||
|
: "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TypeMapper
|
||||||
|
{
|
||||||
|
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
|
||||||
|
|
||||||
|
private readonly System.Collections.IList _errors;
|
||||||
|
private readonly CodeGenerationTools _code;
|
||||||
|
private readonly MetadataTools _ef;
|
||||||
|
|
||||||
|
public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(code, "code");
|
||||||
|
ArgumentNotNull(ef, "ef");
|
||||||
|
ArgumentNotNull(errors, "errors");
|
||||||
|
|
||||||
|
_code = code;
|
||||||
|
_ef = ef;
|
||||||
|
_errors = errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FixNamespaces(string typeName)
|
||||||
|
{
|
||||||
|
return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(TypeUsage typeUsage)
|
||||||
|
{
|
||||||
|
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(EdmType edmType)
|
||||||
|
{
|
||||||
|
return GetTypeName(edmType, isNullable: null, modelNamespace: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
|
||||||
|
{
|
||||||
|
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(EdmType edmType, string modelNamespace)
|
||||||
|
{
|
||||||
|
return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
|
||||||
|
{
|
||||||
|
if (edmType == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var collectionType = edmType as CollectionType;
|
||||||
|
if (collectionType != null)
|
||||||
|
{
|
||||||
|
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeName = _code.Escape(edmType.MetadataProperties
|
||||||
|
.Where(p => p.Name == ExternalTypeNameAttributeName)
|
||||||
|
.Select(p => (string)p.Value)
|
||||||
|
.FirstOrDefault())
|
||||||
|
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
|
||||||
|
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
|
||||||
|
_code.Escape(edmType));
|
||||||
|
|
||||||
|
if (edmType is StructuralType)
|
||||||
|
{
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edmType is SimpleType)
|
||||||
|
{
|
||||||
|
var clrType = UnderlyingClrType(edmType);
|
||||||
|
if (!IsEnumType(edmType))
|
||||||
|
{
|
||||||
|
typeName = _code.Escape(clrType);
|
||||||
|
}
|
||||||
|
|
||||||
|
typeName = FixNamespaces(typeName);
|
||||||
|
|
||||||
|
return clrType.IsValueType && isNullable == true ?
|
||||||
|
String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
|
||||||
|
typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException("edmType");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type UnderlyingClrType(EdmType edmType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmType, "edmType");
|
||||||
|
|
||||||
|
var primitiveType = edmType as PrimitiveType;
|
||||||
|
if (primitiveType != null)
|
||||||
|
{
|
||||||
|
return primitiveType.ClrEquivalentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsEnumType(edmType))
|
||||||
|
{
|
||||||
|
return GetEnumUnderlyingType(edmType).ClrEquivalentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetEnumMemberValue(MetadataItem enumMember)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumMember, "enumMember");
|
||||||
|
|
||||||
|
var valueProperty = enumMember.GetType().GetProperty("Value");
|
||||||
|
return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetEnumMemberName(MetadataItem enumMember)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumMember, "enumMember");
|
||||||
|
|
||||||
|
var nameProperty = enumMember.GetType().GetProperty("Name");
|
||||||
|
return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumType, "enumType");
|
||||||
|
|
||||||
|
var membersProperty = enumType.GetType().GetProperty("Members");
|
||||||
|
return membersProperty != null
|
||||||
|
? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
|
||||||
|
: Enumerable.Empty<MetadataItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool EnumIsFlags(EdmType enumType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumType, "enumType");
|
||||||
|
|
||||||
|
var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
|
||||||
|
return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnumType(GlobalItem edmType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmType, "edmType");
|
||||||
|
|
||||||
|
return edmType.GetType().Name == "EnumType";
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(enumType, "enumType");
|
||||||
|
|
||||||
|
return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CreateLiteral(object value)
|
||||||
|
{
|
||||||
|
if (value == null || value.GetType() != typeof(TimeSpan))
|
||||||
|
{
|
||||||
|
return _code.CreateLiteral(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(types, "types");
|
||||||
|
ArgumentNotNull(sourceFile, "sourceFile");
|
||||||
|
|
||||||
|
var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||||
|
if (types.Any(item => !hash.Add(item)))
|
||||||
|
{
|
||||||
|
_errors.Add(
|
||||||
|
new CompilerError(sourceFile, -1, -1, "6023",
|
||||||
|
String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
|
||||||
|
{
|
||||||
|
return GetItemsToGenerate<SimpleType>(itemCollection)
|
||||||
|
.Where(e => IsEnumType(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
|
||||||
|
{
|
||||||
|
return itemCollection
|
||||||
|
.OfType<T>()
|
||||||
|
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
|
||||||
|
.OrderBy(i => i.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
|
||||||
|
{
|
||||||
|
return itemCollection
|
||||||
|
.Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
|
||||||
|
.Select(g => GetGlobalItemName(g));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetGlobalItemName(GlobalItem item)
|
||||||
|
{
|
||||||
|
if (item is EdmType)
|
||||||
|
{
|
||||||
|
return ((EdmType)item).Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((EntityContainer)item).Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
|
||||||
|
{
|
||||||
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.NavigationProperties.Where(np => np.DeclaringType == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
|
||||||
|
{
|
||||||
|
return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmFunction, "edmFunction");
|
||||||
|
|
||||||
|
var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
|
||||||
|
return returnParamsProperty == null
|
||||||
|
? edmFunction.ReturnParameter
|
||||||
|
: ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsComposable(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
ArgumentNotNull(edmFunction, "edmFunction");
|
||||||
|
|
||||||
|
var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
|
||||||
|
return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeUsage GetReturnType(EdmFunction edmFunction)
|
||||||
|
{
|
||||||
|
var returnParam = GetReturnParameter(edmFunction);
|
||||||
|
return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
|
||||||
|
{
|
||||||
|
var returnType = GetReturnType(edmFunction);
|
||||||
|
return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ArgumentNotNull<T>(T arg, string name) where T : class
|
||||||
|
{
|
||||||
|
if (arg == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#>
|
||||||
73
web/App_Code/Model/Partial/accounting.cs
Normal file
73
web/App_Code/Model/Partial/accounting.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(accountingMetadata))]
|
||||||
|
public partial class accounting
|
||||||
|
{
|
||||||
|
private class accountingMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual accounting_kind accounting_kind { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual accounting_kind2 accounting_kind2 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual member member { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int KindLevelMax = 3; //收支層數
|
||||||
|
public const int KindLevelMax2 = 1; //帳戶層數
|
||||||
|
public const string Dir = "~/upload/accounting"; //圖片上傳位置
|
||||||
|
public string log;
|
||||||
|
|
||||||
|
public enum type : int //收支類別
|
||||||
|
{
|
||||||
|
[Description("收入")]
|
||||||
|
Receipts = 1,
|
||||||
|
[Description("支出")]
|
||||||
|
Expenses = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class accounting_kind
|
||||||
|
{
|
||||||
|
private class accounting_kindMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<accounting> accountings { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class accounting_kind2
|
||||||
|
{
|
||||||
|
private class accounting_kind2Metadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<accounting> accountings { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order_record> pro_order_record { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
33
web/App_Code/Model/Partial/act_bom.cs
Normal file
33
web/App_Code/Model/Partial/act_bom.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Activities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
using Model;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for act_bom
|
||||||
|
/// </summary>
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(act_bomMetadata))]
|
||||||
|
public class act_bom
|
||||||
|
{
|
||||||
|
private class act_bomMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<act_bom> act_bom1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual act_bom act_bom2 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual actItem actItem { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
114
web/App_Code/Model/Partial/activity.cs
Normal file
114
web/App_Code/Model/Partial/activity.cs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(activityMetadata))]
|
||||||
|
public partial class activity
|
||||||
|
{
|
||||||
|
private class activityMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual activity_kind activity_kind { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual activity_category_kind activity_category_kind { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_relating> activity_relating { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_spares> activity_spares { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_check> activity_check { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<news> news { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order> pro_order { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<stock> stocks { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<accounting> accountings { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<transfer_register> transfer_register { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public const int KindLevelMax = 3; //活動分類頁面層數
|
||||||
|
public const int ItemLevelMax = 3; //項目類別頁面層數
|
||||||
|
|
||||||
|
public enum category : int
|
||||||
|
{
|
||||||
|
[Description("報名項目")]
|
||||||
|
SignUp = 1,
|
||||||
|
[Description("掛單項目")]
|
||||||
|
Order = 2,
|
||||||
|
[Description("備品項目")]
|
||||||
|
Spares = 3,
|
||||||
|
[Description("贊助項目")]
|
||||||
|
Patronize = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetadataType(typeof(actItemMetadata))]
|
||||||
|
public partial class actItem
|
||||||
|
{
|
||||||
|
private class actItemMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual actItem_kind actItem_kind { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<actItem_files> actItem_files { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_kind_detail> activity_kind_detail { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_relating> activity_relating { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_spares> activity_spares { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order_detail> pro_order_detail { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<project> projects { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<stock> stocks { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<act_bom> act_bom { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<transfer_register> transfer_register { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[MetadataType(typeof(activity_checkMetadata))]
|
||||||
|
public partial class activity_check
|
||||||
|
{
|
||||||
|
private class activity_checkMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum keyin1 : int
|
||||||
|
{
|
||||||
|
[Description("報到")]
|
||||||
|
CheckIn = 1,
|
||||||
|
[Description("離開")]
|
||||||
|
CheckOut = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
183
web/App_Code/Model/Partial/admin.cs
Normal file
183
web/App_Code/Model/Partial/admin.cs
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
using MyWeb;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Data.Entity.Validation;
|
||||||
|
using System.Data.OleDb;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(adminMetadata))]
|
||||||
|
public partial class admin
|
||||||
|
{
|
||||||
|
private class adminMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string MyIP
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ip.Get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetadataType(typeof(admin_logMetadata))]
|
||||||
|
public partial class admin_log
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
|
||||||
|
private class admin_logMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Systems
|
||||||
|
{
|
||||||
|
[Description("公告")]
|
||||||
|
News = 1,
|
||||||
|
[Description("信眾")]
|
||||||
|
Follower = 2,
|
||||||
|
[Description("活動")]
|
||||||
|
Activity = 3,
|
||||||
|
[Description("報名")]
|
||||||
|
Order = 4,
|
||||||
|
[Description("專案")]
|
||||||
|
Project = 5,
|
||||||
|
[Description("品項")]
|
||||||
|
Item = 6,
|
||||||
|
[Description("套表列印")]
|
||||||
|
Files = 7,
|
||||||
|
[Description("掛單")]
|
||||||
|
Bed = 8,
|
||||||
|
[Description("帳務")]
|
||||||
|
Accounting = 9,
|
||||||
|
[Description("庫存")]
|
||||||
|
Stock = 10,
|
||||||
|
[Description("人事")]
|
||||||
|
HR = 11,
|
||||||
|
[Description("供應商")]
|
||||||
|
Supplier = 12,
|
||||||
|
[Description("權限")]
|
||||||
|
Power = 13,
|
||||||
|
|
||||||
|
}
|
||||||
|
public enum Status
|
||||||
|
{
|
||||||
|
[Description("登入")]
|
||||||
|
Login = 1,
|
||||||
|
[Description("新增")]
|
||||||
|
Insert = 2,
|
||||||
|
[Description("修改")]
|
||||||
|
Update = 3,
|
||||||
|
[Description("刪除")]
|
||||||
|
Delete = 4,
|
||||||
|
[Description("排序")]
|
||||||
|
Sort = 5,
|
||||||
|
[Description("列印")]
|
||||||
|
Print = 6,
|
||||||
|
[Description("匯出Excel")]
|
||||||
|
Excel = 7,
|
||||||
|
|
||||||
|
}
|
||||||
|
public enum Detail
|
||||||
|
{
|
||||||
|
[Description("登入成功")]
|
||||||
|
Success = 1,
|
||||||
|
[Description("帳號已停用")]
|
||||||
|
Disable = 2,
|
||||||
|
[Description("有效期限到期")]
|
||||||
|
Expire = 3,
|
||||||
|
[Description("帳號或密碼錯誤")]
|
||||||
|
Incorrect = 4,
|
||||||
|
[Description("帳號的群組不存在")]
|
||||||
|
GroupNotExist = 5,
|
||||||
|
[Description("未設定使用權限")]
|
||||||
|
PermissionsNotSet = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string UserAgent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string u = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"];
|
||||||
|
Regex b = new Regex(@"android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||||
|
Regex v = new Regex(@"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||||
|
if ((b.IsMatch(u) || v.IsMatch(u.Substring(0, 4))))
|
||||||
|
return "手機";
|
||||||
|
else
|
||||||
|
return "電腦";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Log
|
||||||
|
public string LogViewBtn(List<string> arr)
|
||||||
|
{
|
||||||
|
string html = "<a href=\"javascript:void(0)\" class=\"btn btn-default btn-sm btn-log\" onclick=\"msgbox($(this).parent().find(\'div.d-none\').html())\" >查看清單</a>";
|
||||||
|
html += $"<div class=\"d-none\">{string.Join("<br>", arr)}</div>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
public bool writeLog(string u_id, int? systems, int status, string word)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();//新增
|
||||||
|
admin_log.u_id = u_id;
|
||||||
|
admin_log.login_time = DateTime.Now;
|
||||||
|
admin_log.login_ip = MyWeb.admin.MyIP.Replace("本機", "127.0.0.1");
|
||||||
|
admin_log.systems = systems;
|
||||||
|
admin_log.status = status;
|
||||||
|
admin_log.word = word;
|
||||||
|
admin_log.agent = MyWeb.admin.LoginHistory.UserAgent;
|
||||||
|
_db.admin_log.Add(admin_log);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (DbEntityValidationException e)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
foreach (var eve in e.EntityValidationErrors)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
|
||||||
|
eve.Entry.Entity.GetType().Name, eve.Entry.State);
|
||||||
|
foreach (var ve in eve.ValidationErrors)
|
||||||
|
{
|
||||||
|
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
|
||||||
|
ve.PropertyName, ve.ErrorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
99
web/App_Code/Model/Partial/bed.cs
Normal file
99
web/App_Code/Model/Partial/bed.cs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(bed_orderMetadata))]
|
||||||
|
public partial class bed_order
|
||||||
|
{
|
||||||
|
private class bed_orderMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<bed_order_detail> bed_order_detail { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual pro_order pro_order { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual pro_order_detail pro_order_detail { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
public const int KindLevelMax = 2; //分類頁面層數
|
||||||
|
|
||||||
|
#region 單據狀態
|
||||||
|
public struct keyin
|
||||||
|
{
|
||||||
|
public string Text;
|
||||||
|
public string Value;
|
||||||
|
public string Color;
|
||||||
|
}
|
||||||
|
public ArrayList keyin1_list()
|
||||||
|
{
|
||||||
|
ArrayList options = new ArrayList();
|
||||||
|
keyin keyin;
|
||||||
|
keyin.Value = "A1"; keyin.Text = "未入住"; keyin.Color = "#990000"; options.Add(keyin);
|
||||||
|
keyin.Value = "A2"; keyin.Text = "已入住"; keyin.Color = "green"; options.Add(keyin);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string keyin1_value_to_text(string v)
|
||||||
|
{
|
||||||
|
string tmp = "";
|
||||||
|
ArrayList keyin1 = new pro_order().keyin1_list();
|
||||||
|
foreach (keyin k in keyin1)
|
||||||
|
{
|
||||||
|
if (k.Value == v)
|
||||||
|
{
|
||||||
|
tmp = k.Text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetadataType(typeof(bed_kindMetadata))]
|
||||||
|
public partial class bed_kind
|
||||||
|
{
|
||||||
|
private class bed_kindMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<bed_kind_detail> bed_kind_detail { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<bed_order_detail> bed_order_detail { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<bed_order_detail> bed_order_detail1 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum bed_type : int
|
||||||
|
{
|
||||||
|
[Description("單人床")]
|
||||||
|
Single = 1,
|
||||||
|
[Description("上舖")]
|
||||||
|
Double = 2,
|
||||||
|
[Description("下舖")]
|
||||||
|
Bunk= 3,
|
||||||
|
[Description("通舖")]
|
||||||
|
Wide = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
32
web/App_Code/Model/Partial/country.cs
Normal file
32
web/App_Code/Model/Partial/country.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(countryMetadata))]
|
||||||
|
public partial class country
|
||||||
|
{
|
||||||
|
|
||||||
|
private class countryMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<follower> followers { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
29
web/App_Code/Model/Partial/files.cs
Normal file
29
web/App_Code/Model/Partial/files.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(filesMetadata))]
|
||||||
|
public partial class file
|
||||||
|
{
|
||||||
|
private class filesMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<actItem_files> actItem_files { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
public static IEnumerable<Model.file> allFiles = new Model.ezEntities().files.AsEnumerable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
210
web/App_Code/Model/Partial/follower.cs
Normal file
210
web/App_Code/Model/Partial/follower.cs
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(followerMetadata))]
|
||||||
|
public partial class follower
|
||||||
|
{
|
||||||
|
private class followerMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<follower> followers1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<activity_check> activity_check { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual country country1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<member> members { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order_detail> pro_order_detail { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order_detail> pro_order_detail1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order> pro_order { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order> pro_order1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<followers_tablet> followers_tablet { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual appellation appellation { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public enum type : int
|
||||||
|
{
|
||||||
|
[Description("出家眾")]
|
||||||
|
Monk = 1,// 4,
|
||||||
|
[Description("個人")]
|
||||||
|
Personal = 2, //1,
|
||||||
|
[Description("法人")]
|
||||||
|
Legal = 3, //2,
|
||||||
|
[Description("往生菩薩")]
|
||||||
|
Bodhisattva = 4, //3,
|
||||||
|
[Description("蓮友")]
|
||||||
|
Seeker = 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<Model.follower> allFaollowers = new Model.ezEntities().followers.AsEnumerable();
|
||||||
|
|
||||||
|
//public static string identity_type_list()
|
||||||
|
|
||||||
|
#region 農曆生日&生肖
|
||||||
|
|
||||||
|
public enum chinese
|
||||||
|
{
|
||||||
|
鼠 = 1, 牛 = 2, 虎 = 3, 兔 = 4, 龍 = 5, 蛇 = 6,
|
||||||
|
馬 = 7, 羊 = 8, 猴 = 9, 雞 = 10, 狗 = 11, 豬 = 12
|
||||||
|
}
|
||||||
|
enum heavenlyStems
|
||||||
|
{
|
||||||
|
甲 = 1, 乙, 丙, 丁, 戊, 己, 庚, 辛, 壬, 癸
|
||||||
|
}
|
||||||
|
|
||||||
|
enum earthlyBranches
|
||||||
|
{
|
||||||
|
子 = 1, 丑, 寅, 卯, 辰, 巳, 午, 未, 申, 酉, 戌, 亥
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string chagenSign(DateTime? date)
|
||||||
|
{ //可改公用
|
||||||
|
//生肖
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (date != null)
|
||||||
|
{
|
||||||
|
DateTime d = date ?? DateTime.Now;
|
||||||
|
int year = d.Year;
|
||||||
|
int birthpet; //宣告生肖要用的變數
|
||||||
|
|
||||||
|
birthpet = year % 12; //西元年除12取餘數
|
||||||
|
birthpet -= 3;
|
||||||
|
//餘數-3
|
||||||
|
if (birthpet <= 0) birthpet += 12;
|
||||||
|
//判斷餘數是否大於0,小於0必須+12
|
||||||
|
return Enum.GetName(typeof(chinese), birthpet);
|
||||||
|
//return ((chinese)birthpet).ToString(); //也可以
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static string sexagenary(DateTime? date)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (date != null)
|
||||||
|
{
|
||||||
|
DateTime d = date ?? DateTime.Now;
|
||||||
|
|
||||||
|
//依農曆年計算,故同一年的1月跟6月會得不同結果
|
||||||
|
//ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
|
||||||
|
//int y = chineseDate.GetYear(d);// 農曆年分
|
||||||
|
//int a = chineseDate.GetSexagenaryYear(d); // 獲取干支纪年值
|
||||||
|
|
||||||
|
//heavenlyStems tg = (heavenlyStems)chineseDate.GetCelestialStem(a);
|
||||||
|
//earthlyBranches dz = (earthlyBranches)chineseDate.GetTerrestrialBranch(a);
|
||||||
|
//return $"{tg}{dz}";
|
||||||
|
|
||||||
|
|
||||||
|
int year = d.Year;
|
||||||
|
if (year > 3)
|
||||||
|
{
|
||||||
|
int tgIndex = (year - 4) % 10;
|
||||||
|
int dzIndex = (year - 4) % 12;
|
||||||
|
|
||||||
|
return $"{(heavenlyStems)(tgIndex + 1)}{(earthlyBranches)(dzIndex + 1)}";
|
||||||
|
}
|
||||||
|
//throw new ArgumentOutOfRangeException("無效的年份!");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
//return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ChkNewFollower(Model.follower newFollower)
|
||||||
|
{
|
||||||
|
Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
if (string.IsNullOrWhiteSpace(newFollower.u_name))
|
||||||
|
{
|
||||||
|
return "姓名不應為空白";
|
||||||
|
}
|
||||||
|
|
||||||
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
|
|
||||||
|
// 解密並只保留數字
|
||||||
|
string decryptedNewPhone = !string.IsNullOrWhiteSpace(newFollower.phone)
|
||||||
|
? new string(encrypt.DecryptAutoKey(newFollower.phone).Where(char.IsDigit).ToArray()) : "";
|
||||||
|
string decryptedNewCellphone = !string.IsNullOrWhiteSpace(newFollower.cellphone)
|
||||||
|
? new string(encrypt.DecryptAutoKey(newFollower.cellphone).Where(char.IsDigit).ToArray()) : "";
|
||||||
|
|
||||||
|
var existingFollowers = _db.followers.Where(f => f.u_name == newFollower.u_name).ToList();
|
||||||
|
|
||||||
|
if (!existingFollowers.Any())
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var follower in existingFollowers)
|
||||||
|
{
|
||||||
|
string decryptedPhone = !string.IsNullOrWhiteSpace(follower.phone)
|
||||||
|
? new string(encrypt.DecryptAutoKey(follower.phone).Where(char.IsDigit).ToArray()) : "";
|
||||||
|
string decryptedCellphone = !string.IsNullOrWhiteSpace(follower.cellphone)
|
||||||
|
? new string(encrypt.DecryptAutoKey(follower.cellphone).Where(char.IsDigit).ToArray()) : "";
|
||||||
|
|
||||||
|
if ((!string.IsNullOrWhiteSpace(decryptedNewPhone) && decryptedNewPhone == decryptedPhone) ||
|
||||||
|
(!string.IsNullOrWhiteSpace(decryptedNewCellphone) && decryptedNewCellphone == decryptedCellphone))
|
||||||
|
{
|
||||||
|
return "姓名重複 + 電話或手機重複";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
public static string generate_f_number(string sex = "男眾")
|
||||||
|
{
|
||||||
|
string selectedSex = sex;
|
||||||
|
string f_number = selectedSex == "男眾" ? "M" : "F";
|
||||||
|
var datePart = DateTime.Now.ToString("yyyyMMdd");
|
||||||
|
f_number += datePart;
|
||||||
|
|
||||||
|
|
||||||
|
int nextSerial = 1;
|
||||||
|
|
||||||
|
lock (GlobalVariables.FNumberLock)
|
||||||
|
{
|
||||||
|
nextSerial = (int)HttpContext.Current.Application["FNumberSerial"] + 1;
|
||||||
|
HttpContext.Current.Application["FNumberSerial"] = nextSerial;
|
||||||
|
}
|
||||||
|
f_number += nextSerial.ToString("D5");
|
||||||
|
return f_number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
62
web/App_Code/Model/Partial/member.cs
Normal file
62
web/App_Code/Model/Partial/member.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(memberMetadata))]
|
||||||
|
public partial class member
|
||||||
|
{
|
||||||
|
private class memberMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<member_check> member_check { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual member_group member_group { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual member_title member_title { get; set; }
|
||||||
|
}
|
||||||
|
public const int KindLevelMax = 3; //組別頁面層數
|
||||||
|
public const int TitleLevelMax = 1; //職稱頁面層數
|
||||||
|
public const string Dir = "~/upload/member"; //圖片上傳位置
|
||||||
|
public const int picMax = 1; //圖片數量
|
||||||
|
|
||||||
|
|
||||||
|
public class attendances
|
||||||
|
{
|
||||||
|
public enum type : int
|
||||||
|
{
|
||||||
|
[Description("上班")]
|
||||||
|
Start = 1,
|
||||||
|
[Description("下班")]
|
||||||
|
GetOff = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum login : int
|
||||||
|
{
|
||||||
|
[Description("主管補登")]
|
||||||
|
Enter = 1,
|
||||||
|
[Description("帳號密碼")]
|
||||||
|
Account = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
37
web/App_Code/Model/Partial/news.cs
Normal file
37
web/App_Code/Model/Partial/news.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(newsMetadata))]
|
||||||
|
public partial class news
|
||||||
|
{
|
||||||
|
private class newsMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual admin admin { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<news_files> news_files { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual news_kind news_kind { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int KindLevelMax = 3; //頁面層數
|
||||||
|
public const string Dir = "~/upload/news"; //圖片上傳位置
|
||||||
|
public string log;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
396
web/App_Code/Model/Partial/order.cs
Normal file
396
web/App_Code/Model/Partial/order.cs
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(pro_orderMetadata))]
|
||||||
|
public partial class pro_order
|
||||||
|
{
|
||||||
|
private class pro_orderMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual activity activity { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<bed_order> bed_order { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order_detail> pro_order_detail { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string log;
|
||||||
|
|
||||||
|
#region 單據狀態
|
||||||
|
public struct keyin
|
||||||
|
{
|
||||||
|
public string Text;
|
||||||
|
public string Value;
|
||||||
|
public string Color;
|
||||||
|
}
|
||||||
|
public ArrayList keyin1_list()
|
||||||
|
{
|
||||||
|
ArrayList options = new ArrayList();
|
||||||
|
keyin keyin;
|
||||||
|
keyin.Value = "A01"; keyin.Text = "報名中"; keyin.Color = "#990000"; options.Add(keyin);
|
||||||
|
keyin.Value = "A02"; keyin.Text = "已報名"; keyin.Color = "black"; options.Add(keyin);
|
||||||
|
keyin.Value = "A05"; keyin.Text = "取消報名"; keyin.Color = "green"; options.Add(keyin);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string keyin1_value_to_text(string v)
|
||||||
|
{
|
||||||
|
string tmp = "";
|
||||||
|
ArrayList keyin1 = new pro_order(). keyin1_list();
|
||||||
|
foreach (keyin k in keyin1)
|
||||||
|
{
|
||||||
|
if (k.Value == v)
|
||||||
|
{
|
||||||
|
tmp = k.Text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public enum detailKeyin1 : int //報名狀態
|
||||||
|
{
|
||||||
|
[Description("未收款")]
|
||||||
|
Unconfirmed = 1,
|
||||||
|
[Description("分期")]
|
||||||
|
Collection = 2,
|
||||||
|
[Description("已收款")]
|
||||||
|
Paied = 3,
|
||||||
|
[Description("呆帳")]
|
||||||
|
Finish = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetadataType(typeof(pro_order_detailMetadata))]
|
||||||
|
public partial class pro_order_detail
|
||||||
|
{
|
||||||
|
private class pro_order_detailMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual actItem actItem { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<bed_order> bed_order { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual pro_order pro_order { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<pro_order_record> pro_order_record { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<accounting> accountings { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<transfer_register> transfer_register { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成序列化ID(print_id)的方法,處理父項目和子項目的編號生成
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>生成的序列化ID</returns>
|
||||||
|
public string GenerateSequentialId()
|
||||||
|
{
|
||||||
|
Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
string r = this.print_id;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool chk = true;
|
||||||
|
actItem actitem = null;
|
||||||
|
int? actitem_id = null;
|
||||||
|
|
||||||
|
// 處理子項目的ID生成
|
||||||
|
if (!(this.parent_num == null || this.parent_num == 0))
|
||||||
|
{
|
||||||
|
// 1. 查找父項目的資料
|
||||||
|
var parent_order_item = _db.pro_order_detail.Where(
|
||||||
|
q => q.num == this.parent_num).FirstOrDefault();
|
||||||
|
|
||||||
|
// 2. 確認父項目存在且當前項目還沒有 print_id
|
||||||
|
if (parent_order_item != null && string.IsNullOrEmpty(this.print_id))
|
||||||
|
{
|
||||||
|
actitem_id = parent_order_item.actItem_num;
|
||||||
|
string parent_print_id = parent_order_item.print_id;
|
||||||
|
|
||||||
|
// 1. 獲取當前子項目的品項前綴
|
||||||
|
var currentActItem = _db.actItems
|
||||||
|
.Where(q => q.num == this.actItem_num)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (currentActItem != null && !string.IsNullOrEmpty(currentActItem.print_init))
|
||||||
|
{
|
||||||
|
var itemPrefix = currentActItem.print_init.Trim();
|
||||||
|
|
||||||
|
// 2. 獲取同父項目且同品項的子項目編號
|
||||||
|
var siblings = _db.pro_order_detail
|
||||||
|
.Where(q => q.parent_num == this.parent_num) // 找出同一個父項目的子項目
|
||||||
|
.Where(q => q.actItem_num == this.actItem_num) // 同品項
|
||||||
|
.Where(q => q.print_id != null) // Ensure print_id is not null
|
||||||
|
.Select(q => q.print_id) // Just select the print_id
|
||||||
|
.AsEnumerable() // Switch to in-memory operations
|
||||||
|
.Where(q => q.StartsWith(parent_print_id)) // Now do string operations in memory
|
||||||
|
.Where(q => q.Contains(itemPrefix))
|
||||||
|
.Select(q => q.Trim().Replace("\t", ""))
|
||||||
|
.Select(q => q.Replace($"{parent_print_id}-{itemPrefix}", ""))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// 3. 將所有序號轉換為數字陣列並過濾無效值
|
||||||
|
int[] intArray = siblings
|
||||||
|
.Select(s =>
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
return int.TryParse(s, out result) ? (int?)result : null;
|
||||||
|
})
|
||||||
|
.Where(i => i.HasValue && i.Value != 0)
|
||||||
|
.Select(i => i.Value)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
// 4. 生成新的序號(最大序號+1,並格式化為兩位數)
|
||||||
|
int maxNum = 1 + (intArray.Any() ? intArray.Max() : 0);
|
||||||
|
string formattedNum = maxNum < 10 ? "0" + maxNum : maxNum.ToString();
|
||||||
|
|
||||||
|
// 5. 組合新的 print_id(父項目ID-品項前綴序號)
|
||||||
|
r = $"{parent_print_id}-{itemPrefix}{formattedNum}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 處理主項目的ID生成
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actitem_id = this.actItem_num;
|
||||||
|
actitem = _db.actItems
|
||||||
|
.Where(q => q.num == actitem_id).FirstOrDefault();
|
||||||
|
var proorder = _db.pro_order.Where(q => q.order_no == this.order_no).FirstOrDefault();
|
||||||
|
|
||||||
|
// 檢查是否需要生成新的 print_id
|
||||||
|
chk = String.IsNullOrEmpty(r) &&
|
||||||
|
actitem != null &&
|
||||||
|
proorder != null &&
|
||||||
|
!string.IsNullOrEmpty(actitem.print_init);
|
||||||
|
if (chk)
|
||||||
|
{
|
||||||
|
// 1. 組合活動和品項的前綴
|
||||||
|
var print_init = string.IsNullOrEmpty(proorder?.activity?.print_init) ? "" : proorder?.activity?.print_init.Trim();
|
||||||
|
var actitem_print_init = actitem.print_init.Trim();
|
||||||
|
var combinedPrintInit = print_init + actitem_print_init;
|
||||||
|
|
||||||
|
// 2. 查找相同活動和品項的已存在編號
|
||||||
|
var actitems = _db.pro_order_detail
|
||||||
|
.Where(q => q.pro_order.activity_num == proorder.activity_num)
|
||||||
|
.Where(q => q.actItem_num == this.actItem_num)
|
||||||
|
.Where(q => !string.IsNullOrEmpty(q.print_id))
|
||||||
|
.Where(q => q.print_id.StartsWith(combinedPrintInit))
|
||||||
|
.Where(q => q.parent_num == 0 || q.parent_num == null)
|
||||||
|
.Select(q => q.print_id)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// 3. 獲取最大序號
|
||||||
|
var maxNum = actitems
|
||||||
|
.Select(item =>
|
||||||
|
{
|
||||||
|
var match = Regex.Match(item, @"\d+");
|
||||||
|
return match.Success ? (int?)int.Parse(match.Value.TrimStart('0')) : null;
|
||||||
|
})
|
||||||
|
.Where(num => num.HasValue)
|
||||||
|
.DefaultIfEmpty(0)
|
||||||
|
.Max() ?? 0;
|
||||||
|
|
||||||
|
// 4. 生成新的序號(四位數格式)
|
||||||
|
int newNum = maxNum + 1;
|
||||||
|
string formattedNum = newNum.ToString().PadLeft(4, '0');
|
||||||
|
|
||||||
|
// 5. 組合最終的 print_id
|
||||||
|
r = $"{combinedPrintInit}{formattedNum}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 異常處理:記錄錯誤並返回原始 print_id
|
||||||
|
Console.WriteLine($"Error generating sequential ID: {ex.Message}");
|
||||||
|
r = this.print_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MetadataType(typeof(pro_order_recordMetadata))]
|
||||||
|
public partial class pro_order_record
|
||||||
|
{
|
||||||
|
private class pro_order_recordMetadata
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主鍵,付款記錄編號
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "付款記錄編號")]
|
||||||
|
public int num { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 關聯到報名明細編號 (pro_order_detail.num)
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "報名明細編號")]
|
||||||
|
[Required(ErrorMessage = "報名明細編號為必填欄位")]
|
||||||
|
public Nullable<int> detail_num { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 付款金額
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "付款金額")]
|
||||||
|
[Required(ErrorMessage = "付款金額為必填欄位")]
|
||||||
|
[Range(0.01, double.MaxValue, ErrorMessage = "付款金額必須大於0")]
|
||||||
|
public Nullable<float> price { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 付款方式 (1=現金, 2=匯款, 3=支票)
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "付款方式")]
|
||||||
|
[Required(ErrorMessage = "付款方式為必填欄位")]
|
||||||
|
public Nullable<int> payment { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登記時間 (系統自動產生)
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "登記時間")]
|
||||||
|
public Nullable<System.DateTime> reg_time { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 付款日期
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "付款日期")]
|
||||||
|
[Required(ErrorMessage = "付款日期為必填欄位")]
|
||||||
|
public Nullable<System.DateTime> pay_date { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 付款機構 (銀行名稱等)
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "付款機構")]
|
||||||
|
[StringLength(100, ErrorMessage = "付款機構長度不能超過100個字元")]
|
||||||
|
public string organization { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 銀行代碼或帳號後5碼
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "帳號後5碼")]
|
||||||
|
[StringLength(10, ErrorMessage = "帳號後5碼長度不能超過10個字元")]
|
||||||
|
public string bank_code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 關聯到匯款登記編號 (transfer_register.num)
|
||||||
|
/// </summary>
|
||||||
|
[Display(Name = "匯款登記編號")]
|
||||||
|
public Nullable<int> transfer_id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 關聯到會計科目分類
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual accounting_kind2 accounting_kind2 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 關聯到報名明細
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual pro_order_detail pro_order_detail { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 關聯到匯款登記資料
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual transfer_register transfer_register { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 付款方式列舉
|
||||||
|
/// </summary>
|
||||||
|
public enum pay_kind : int
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 現金付款
|
||||||
|
/// </summary>
|
||||||
|
[Description("現金")]
|
||||||
|
Cash = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 匯款付款
|
||||||
|
/// </summary>
|
||||||
|
[Description("匯款")]
|
||||||
|
ATM = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支票付款
|
||||||
|
/// </summary>
|
||||||
|
[Description("支票")]
|
||||||
|
Check = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得付款方式的中文描述
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="paymentType">付款方式代碼</param>
|
||||||
|
/// <returns>付款方式中文描述</returns>
|
||||||
|
public static string GetPaymentDescription(int? paymentType)
|
||||||
|
{
|
||||||
|
if (!paymentType.HasValue) return "未指定";
|
||||||
|
|
||||||
|
switch (paymentType.Value)
|
||||||
|
{
|
||||||
|
case (int)pay_kind.Cash:
|
||||||
|
return "現金";
|
||||||
|
case (int)pay_kind.ATM:
|
||||||
|
return "匯款";
|
||||||
|
case (int)pay_kind.Check:
|
||||||
|
return "支票";
|
||||||
|
default:
|
||||||
|
return "未知";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取得付款方式的完整資訊
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>包含付款方式、機構、帳號的完整資訊</returns>
|
||||||
|
public string GetPaymentFullInfo()
|
||||||
|
{
|
||||||
|
string paymentDesc = GetPaymentDescription(this.payment);
|
||||||
|
string fullInfo = paymentDesc;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.organization))
|
||||||
|
{
|
||||||
|
fullInfo += $" - {this.organization}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(this.bank_code))
|
||||||
|
{
|
||||||
|
fullInfo += $" ({this.bank_code})";
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
34
web/App_Code/Model/Partial/project.cs
Normal file
34
web/App_Code/Model/Partial/project.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(projectMetadata))]
|
||||||
|
public partial class project
|
||||||
|
{
|
||||||
|
private class projectMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual project_kind project_kind { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int KindLevelMax = 3; //頁面層數
|
||||||
|
public string log;
|
||||||
|
public const string Dir = "~/upload/project"; //圖片上傳位置
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
58
web/App_Code/Model/Partial/stock.cs
Normal file
58
web/App_Code/Model/Partial/stock.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(stockMetadata))]
|
||||||
|
public partial class stock
|
||||||
|
{
|
||||||
|
private class stockMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual actItem actItem { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual activity activity { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual member member { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<stock_files> stock_files { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual stock_kind stock_kind { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual stock_reason stock_reason { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual supplier supplier1 { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int KindLevelMax = 3; //頁面層數
|
||||||
|
public const int ReasonLevelMax = 1; //頁面層數
|
||||||
|
public const string Dir = "~/upload/stock"; //圖片上傳位置
|
||||||
|
public string log;
|
||||||
|
|
||||||
|
public enum type : int //進出類型
|
||||||
|
{
|
||||||
|
[Description("庫存增加(+)")]
|
||||||
|
Purchase = 1,
|
||||||
|
[Description("庫存減少(-)")]
|
||||||
|
Reduce = 2,
|
||||||
|
[Description("租借(-)")]
|
||||||
|
Rent = 3,
|
||||||
|
[Description("租借歸還(+)")]
|
||||||
|
Return = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
34
web/App_Code/Model/Partial/supplier.cs
Normal file
34
web/App_Code/Model/Partial/supplier.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
// 為對應資料表MODEL宣告額外參數類別(Metadata)
|
||||||
|
// [JsonIgnore] 避免WEBAPI自動抓關聯資料
|
||||||
|
[MetadataType(typeof(supplierMetadata))]
|
||||||
|
public partial class supplier
|
||||||
|
{
|
||||||
|
private class supplierMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual supplier_kind supplier_kind { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public const int KindLevelMax = 3; //收支層數
|
||||||
|
public const string Dir = "~/upload/supplier"; //圖片上傳位置
|
||||||
|
public string log;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
177
web/App_Code/Model/Partial/transfer_register.cs
Normal file
177
web/App_Code/Model/Partial/transfer_register.cs
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
[MetadataType(typeof(transfer_registerMetadata))]
|
||||||
|
public partial class transfer_register
|
||||||
|
{
|
||||||
|
private class transfer_registerMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual accounting accounting { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual accounting_kind2 accounting_kind2 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual activity activity { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual member member { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual actItem actItem { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual pro_order_detail pro_order_detail { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("系統流水號")]
|
||||||
|
public int id { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("法會編號")]
|
||||||
|
public int? activity_num { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("姓名")]
|
||||||
|
[StringLength(50)]
|
||||||
|
public string name { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("電話")]
|
||||||
|
[StringLength(30)]
|
||||||
|
public string phone { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("支付方式")]
|
||||||
|
public int? pay_type { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("帳號後五碼")]
|
||||||
|
[StringLength(10)]
|
||||||
|
public string account_last5 { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("支付金額")]
|
||||||
|
public int? amount { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("支付型態")]
|
||||||
|
[StringLength(10)]
|
||||||
|
public string pay_mode { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("備註")]
|
||||||
|
[StringLength(200)]
|
||||||
|
public string note { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("匯款憑證圖片檔名")]
|
||||||
|
[StringLength(100)]
|
||||||
|
public string proof_img { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("信眾核對狀態(階段1)")]
|
||||||
|
public int? status { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("自動比對信眾編號")]
|
||||||
|
public int? f_num_match { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("信眾編號")]
|
||||||
|
public int? f_num { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("入帳銀行帳戶編號")]
|
||||||
|
public int? acc_num { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("入帳日期")]
|
||||||
|
public DateTime? check_date { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("入帳金額")]
|
||||||
|
public int? check_amount { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("帳簿備註")]
|
||||||
|
[StringLength(200)]
|
||||||
|
public string check_memo { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("匯款核對狀態(階段2)")]
|
||||||
|
public int? check_status { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("入帳帳戶類型")]
|
||||||
|
public int? acc_kind { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("會員編號")]
|
||||||
|
public int? member_num { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("核對時間")]
|
||||||
|
public DateTime? verify_time { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("核對記錄")]
|
||||||
|
[StringLength(200)]
|
||||||
|
public string verify_note { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("沖帳暫存資料(JSON)")]
|
||||||
|
public string draft { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("剩餘金額")]
|
||||||
|
public int? remain_amount { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("餘額處理-活動品項")]
|
||||||
|
public int? balance_act_item { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("餘額處理-訂單明細")]
|
||||||
|
public int? balance_pro_order_detail { get; set; }
|
||||||
|
|
||||||
|
[DisplayName("建立時間")]
|
||||||
|
public DateTime? create_time { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public const string Dir = "~/upload/transfer"; // 匯款證明圖片上傳位置
|
||||||
|
public string log;
|
||||||
|
|
||||||
|
public enum PayType : int // 支付方式
|
||||||
|
{
|
||||||
|
[Description("現金")]
|
||||||
|
Cash = 1,
|
||||||
|
[Description("匯款")]
|
||||||
|
Transfer = 2,
|
||||||
|
[Description("支票")]
|
||||||
|
Check = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Status : int // 信眾核對狀態 : 階段1
|
||||||
|
{
|
||||||
|
[Description("待確認")]
|
||||||
|
Pending = 1,
|
||||||
|
[Description("確認")]
|
||||||
|
Confirmed = 2,
|
||||||
|
[Description("作廢")]
|
||||||
|
Void = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CheckStatus : int // 匯款核對狀態 : 階段2
|
||||||
|
{
|
||||||
|
[Description("未核對")]
|
||||||
|
Unchecked = 1,
|
||||||
|
[Description("核對")]
|
||||||
|
Checked = 2,
|
||||||
|
[Description("金額不符")]
|
||||||
|
AmountMismatch = 3,
|
||||||
|
[Description("其他問題")]
|
||||||
|
OtherIssue = 4,
|
||||||
|
[Description("作廢")]
|
||||||
|
Void = 5,
|
||||||
|
// 沖帳完成時, 若還有餘額未沖, 將 status 改為 98, 此值不可下拉
|
||||||
|
[Description("沖帳有餘額")]
|
||||||
|
Remained = 90,
|
||||||
|
// 餘額沖帳相關狀態,
|
||||||
|
[Description("未聯絡")]
|
||||||
|
Uncontacted = 91,
|
||||||
|
[Description("已聯絡")]
|
||||||
|
Contacted = 92,
|
||||||
|
[Description("餘額核銷")]
|
||||||
|
BalanceVoided = 95,
|
||||||
|
// 沖帳完成後, 若餘額為0, 將 status 改為 99, 此值不可下拉
|
||||||
|
[Description("沖帳完成")]
|
||||||
|
Voided = 99
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
web/App_Code/Model/ViewModel/accounting.cs
Normal file
65
web/App_Code/Model/ViewModel/accounting.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for accounting
|
||||||
|
/// </summary>
|
||||||
|
public class accounting
|
||||||
|
{
|
||||||
|
public accounting()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nullable<int> category { get; set; }
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
public Nullable<int> kind2 { get; set; }
|
||||||
|
|
||||||
|
public Nullable<System.DateTime> uptime1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> uptime2 { get; set; }
|
||||||
|
public string activity_num_txt { get; set; }
|
||||||
|
public string mem_num_txt { get; set; }
|
||||||
|
public string debtor { get; set; }
|
||||||
|
}
|
||||||
|
public class accounting_kind
|
||||||
|
{
|
||||||
|
public accounting_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class accounting_kind2
|
||||||
|
{
|
||||||
|
public accounting_kind2()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
public string record_payment { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
30
web/App_Code/Model/ViewModel/actItem_kind.cs
Normal file
30
web/App_Code/Model/ViewModel/actItem_kind.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for actItem_kind
|
||||||
|
/// </summary>
|
||||||
|
public class actItem_kind
|
||||||
|
{
|
||||||
|
public actItem_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
public string kind { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
115
web/App_Code/Model/ViewModel/activity.cs
Normal file
115
web/App_Code/Model/ViewModel/activity.cs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for activity
|
||||||
|
/// </summary>
|
||||||
|
public class activity
|
||||||
|
{
|
||||||
|
public activity()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
public string kindTxt { get; set; }
|
||||||
|
public string subject { get; set; }
|
||||||
|
public int? num { get; set; }
|
||||||
|
public string is_reconcile { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class actItem
|
||||||
|
{
|
||||||
|
public actItem()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int num { get; set; }
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
public string kindTxt { get; set; }
|
||||||
|
public string subject { get; set; }
|
||||||
|
public Nullable<int> category { get; set; }
|
||||||
|
public string categorys { get; set; }
|
||||||
|
public string extend { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public string fileTxt { get; set; }
|
||||||
|
public Nullable<float> price { get; set; }
|
||||||
|
public string demo { get; set; }
|
||||||
|
public string customize_data { get; set; }
|
||||||
|
public Nullable<System.DateTime> reg_time { get; set; }
|
||||||
|
public string partno { get; set; }
|
||||||
|
public string print_init { get; set; }
|
||||||
|
|
||||||
|
// 顯示用的組合欄位
|
||||||
|
public string subject_with_price { get; set; }
|
||||||
|
public string full_description { get; set; }
|
||||||
|
}
|
||||||
|
public class activity_kind
|
||||||
|
{
|
||||||
|
public activity_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? num { get; set; }
|
||||||
|
public string kind { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class activity_check
|
||||||
|
{
|
||||||
|
public activity_check()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
public Nullable<int> f_num { get; set; }
|
||||||
|
public Nullable<int> activity_num { get; set; }
|
||||||
|
public string activityTxt { get; set; }
|
||||||
|
public Nullable<System.DateTime> reg_time { get; set; }
|
||||||
|
public Nullable<int> status { get; set; }
|
||||||
|
public Nullable<System.DateTime> check_time { get; set; }
|
||||||
|
public Nullable<System.DateTime> reg_time1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> reg_time2 { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class activity_category_kind
|
||||||
|
{
|
||||||
|
public activity_category_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? num { get; set; }
|
||||||
|
public string kind { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
34
web/App_Code/Model/ViewModel/admin.cs
Normal file
34
web/App_Code/Model/ViewModel/admin.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for admin
|
||||||
|
/// </summary>
|
||||||
|
public class admin
|
||||||
|
{
|
||||||
|
public admin()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
public int? num { get; set; }
|
||||||
|
public string u_id { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public string power { get; set; }
|
||||||
|
public bool online { get; set; }
|
||||||
|
public bool? removeExist { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
111
web/App_Code/Model/ViewModel/bed.cs
Normal file
111
web/App_Code/Model/ViewModel/bed.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Web.UI;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Net.Mail;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
using System.Data.OleDb;
|
||||||
|
using Microsoft.VisualBasic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web.Security;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.Design;
|
||||||
|
using System.ComponentModel.Design.Serialization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Web.Caching;
|
||||||
|
using System.Web.ModelBinding;
|
||||||
|
using System.Web.Routing;
|
||||||
|
using System.Web.SessionState;
|
||||||
|
using System.Web.UI.Adapters;
|
||||||
|
using System.Web.UI.HtmlControls;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.OleDb;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for pro_order
|
||||||
|
/// </summary>
|
||||||
|
public class bed_order
|
||||||
|
{
|
||||||
|
public bed_order()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string bed_order_no { get; set; }
|
||||||
|
public string order_no { get; set; }
|
||||||
|
public Nullable<int> o_detail_id { get; set; }
|
||||||
|
public string keyin1 { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class bed_order_detail
|
||||||
|
{
|
||||||
|
public bed_order_detail()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string bed_order_no { get; set; }
|
||||||
|
public Nullable<System.DateTime> checkIn_date { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
48
web/App_Code/Model/ViewModel/bed_kind.cs
Normal file
48
web/App_Code/Model/ViewModel/bed_kind.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for bed_kind
|
||||||
|
/// </summary>
|
||||||
|
public class bed_kind
|
||||||
|
{
|
||||||
|
public bed_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
public string kind { get; set; }
|
||||||
|
public string sex { get; set; }
|
||||||
|
public int? num { get; set; }
|
||||||
|
public int? root { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class bed_kind_detail
|
||||||
|
{
|
||||||
|
public bed_kind_detail()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
public Nullable<int> bed_kind_id { get; set; }
|
||||||
|
public string bed_name { get; set; }
|
||||||
|
public Nullable<int> bed_type { get; set; }
|
||||||
|
public string bed_type_txt { get; set; }
|
||||||
|
public DateTime? inTime { get; set; }
|
||||||
|
public int? num { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
26
web/App_Code/Model/ViewModel/country.cs
Normal file
26
web/App_Code/Model/ViewModel/country.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for country
|
||||||
|
/// </summary>
|
||||||
|
public class country
|
||||||
|
{
|
||||||
|
public country()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ID { get; set; }
|
||||||
|
public string keyword { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
34
web/App_Code/Model/ViewModel/files.cs
Normal file
34
web/App_Code/Model/ViewModel/files.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for files
|
||||||
|
/// </summary>
|
||||||
|
public class files
|
||||||
|
{
|
||||||
|
public files()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nullable<System.DateTime> reg_time1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> reg_time2 { get; set; }
|
||||||
|
public string subject { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
61
web/App_Code/Model/ViewModel/follower.cs
Normal file
61
web/App_Code/Model/ViewModel/follower.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for follower
|
||||||
|
/// </summary>
|
||||||
|
public class follower
|
||||||
|
{
|
||||||
|
public follower()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
public int? num { get; set; }
|
||||||
|
public int? f_num { get; set; }
|
||||||
|
public int? leader { get; set; }
|
||||||
|
public int? appellation_id { get; set; }
|
||||||
|
public string f_number { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public string sex { get; set; }
|
||||||
|
public string phone { get; set; }
|
||||||
|
public string id_code { get; set; }
|
||||||
|
public string address { get; set; }
|
||||||
|
public bool? ept_self { get; set; }
|
||||||
|
public Nullable<int> identity_type { get; set; }
|
||||||
|
public Nullable<System.DateTime> birthday { get; set; }
|
||||||
|
public Nullable<System.DateTime> birthday2 { get; set; }
|
||||||
|
|
||||||
|
public string country { get; set; }
|
||||||
|
public string country2 { get; set; }
|
||||||
|
}
|
||||||
|
public class followers_tablet
|
||||||
|
{
|
||||||
|
public followers_tablet()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
public int? num { get; set; }
|
||||||
|
public int? f_num { get; set; }
|
||||||
|
public string type { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
54
web/App_Code/Model/ViewModel/member.cs
Normal file
54
web/App_Code/Model/ViewModel/member.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for member
|
||||||
|
/// </summary>
|
||||||
|
public class member
|
||||||
|
{
|
||||||
|
public member()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nullable<int> group_kind { get; set; }
|
||||||
|
public Nullable<int> title_kind { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public string sex { get; set; }
|
||||||
|
public string m_number { get; set; }
|
||||||
|
public Nullable<System.TimeSpan> starttime { get; set; }
|
||||||
|
public Nullable<System.TimeSpan> offtime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class member_check
|
||||||
|
{
|
||||||
|
public member_check()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nullable<int> group_kind { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public int? check_date_year { get; set; }
|
||||||
|
public int? check_date_month { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
43
web/App_Code/Model/ViewModel/member_title.cs
Normal file
43
web/App_Code/Model/ViewModel/member_title.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for member_title & member_group
|
||||||
|
/// </summary>
|
||||||
|
public class member_title
|
||||||
|
{
|
||||||
|
public member_title()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
public bool inTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class member_group
|
||||||
|
{
|
||||||
|
public member_group()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
54
web/App_Code/Model/ViewModel/news.cs
Normal file
54
web/App_Code/Model/ViewModel/news.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for news
|
||||||
|
/// </summary>
|
||||||
|
public class news
|
||||||
|
{
|
||||||
|
public news()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string subject { get; set; }
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public Nullable<System.DateTime> selltime1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> selltime2 { get; set; }
|
||||||
|
public Nullable<System.DateTime> uptime1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> uptime2 { get; set; }
|
||||||
|
public Nullable<int> activity_num { get; set; }
|
||||||
|
public string activity_numTxt { get; set; }
|
||||||
|
}
|
||||||
|
public class news_kind
|
||||||
|
{
|
||||||
|
public news_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
public bool inTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
88
web/App_Code/Model/ViewModel/order.cs
Normal file
88
web/App_Code/Model/ViewModel/order.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
//using System.Data.OleDb;
|
||||||
|
//using System.Data.SqlClient;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for pro_order
|
||||||
|
/// </summary>
|
||||||
|
public class pro_order
|
||||||
|
{
|
||||||
|
public pro_order()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string order_no { get; set; }
|
||||||
|
public Nullable<System.DateTime> up_time1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> up_time2 { get; set; }
|
||||||
|
public string keyin1 { get; set; }
|
||||||
|
public Nullable<int> f_num { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public Nullable<int> activity_num { get; set; }
|
||||||
|
public string subject { get; set; }
|
||||||
|
|
||||||
|
public string address { get; set; }
|
||||||
|
public string actItemTxt { get; set; }
|
||||||
|
public string introducerTxt { get; set; }
|
||||||
|
public string country { get; set; }
|
||||||
|
public string country2 { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class pro_order_detail
|
||||||
|
{
|
||||||
|
public pro_order_detail()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int num { get; set; }
|
||||||
|
public string order_no { get; set; }
|
||||||
|
public Nullable<int> actItem_num { get; set; }
|
||||||
|
public Nullable<int> actItem_kind_num { get; set; }
|
||||||
|
public Nullable<int> f_num { get; set; }
|
||||||
|
public string f_num_txt { get; set; }
|
||||||
|
public Nullable<int> from_id { get; set; }
|
||||||
|
public string address { get; set; }
|
||||||
|
public string from_id_tablet { get; set; }
|
||||||
|
public Nullable<System.DateTime> due_date { get; set; }
|
||||||
|
public Nullable<int> bed_type { get; set; }
|
||||||
|
public Nullable<float> price { get; set; }
|
||||||
|
public Nullable<int> qty { get; set; }
|
||||||
|
public Nullable<System.DateTime> start_date { get; set; }
|
||||||
|
public Nullable<System.DateTime> extend_date { get; set; }
|
||||||
|
public Nullable<float> pay { get; set; }
|
||||||
|
public Nullable<System.DateTime> pay_date { get; set; }
|
||||||
|
public Nullable<int> keyin1 { get; set; }
|
||||||
|
public string demo { get; set; }
|
||||||
|
public string customize_data { get; set; }
|
||||||
|
public string printed_files { get; set; }
|
||||||
|
public Nullable<int> parent_num { get; set; }
|
||||||
|
public string print_id { get; set; }
|
||||||
|
public Nullable<System.DateTime> UpdateTime { get; set; }
|
||||||
|
|
||||||
|
// 顯示用的組合欄位
|
||||||
|
public string actitem_name { get; set; }
|
||||||
|
public string follower_name { get; set; }
|
||||||
|
public string full_description { get; set; }
|
||||||
|
public string order_info { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
48
web/App_Code/Model/ViewModel/project.cs
Normal file
48
web/App_Code/Model/ViewModel/project.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for project
|
||||||
|
/// </summary>
|
||||||
|
public class project
|
||||||
|
{
|
||||||
|
public project()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? num { get; set; }
|
||||||
|
public string subject { get; set; }
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
public Nullable<int> actItem_num { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public class project_kind
|
||||||
|
{
|
||||||
|
public project_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
65
web/App_Code/Model/ViewModel/stock.cs
Normal file
65
web/App_Code/Model/ViewModel/stock.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for stock
|
||||||
|
/// </summary>
|
||||||
|
public class stock
|
||||||
|
{
|
||||||
|
public stock()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nullable<int> category { get; set; }
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
public Nullable<int> reason { get; set; }
|
||||||
|
public Nullable<int> activity_num { get; set; }
|
||||||
|
public Nullable<int> actItem_num { get; set; }
|
||||||
|
|
||||||
|
public Nullable<System.DateTime> uptime1 { get; set; }
|
||||||
|
public Nullable<System.DateTime> uptime2 { get; set; }
|
||||||
|
public string activity_num_txt { get; set; }
|
||||||
|
public string mem_num_txt { get; set; }
|
||||||
|
public string debtor { get; set; }
|
||||||
|
}
|
||||||
|
public class stock_kind
|
||||||
|
{
|
||||||
|
public stock_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
public class stock_reason
|
||||||
|
{
|
||||||
|
public stock_reason()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
public Nullable<int> category { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
47
web/App_Code/Model/ViewModel/supplier.cs
Normal file
47
web/App_Code/Model/ViewModel/supplier.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for supplier
|
||||||
|
/// </summary>
|
||||||
|
public class supplier
|
||||||
|
{
|
||||||
|
public supplier()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Nullable<int> kind { get; set; }
|
||||||
|
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public string s_number { get; set; }
|
||||||
|
public string kindTxt { get; set; }
|
||||||
|
}
|
||||||
|
public class supplier_kind
|
||||||
|
{
|
||||||
|
public supplier_kind()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string kind { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
91
web/App_Code/Model/ViewModel/transfer_register.cs
Normal file
91
web/App_Code/Model/ViewModel/transfer_register.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Data;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Collections;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Model.ViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for transfer_register
|
||||||
|
/// </summary>
|
||||||
|
public class transfer_register
|
||||||
|
{
|
||||||
|
public transfer_register()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public int id { get; set; }
|
||||||
|
public Nullable<int> activity_num { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
public string phone { get; set; }
|
||||||
|
public string pay_type { get; set; }
|
||||||
|
public string account_last5 { get; set; }
|
||||||
|
public Nullable<decimal> amount { get; set; }
|
||||||
|
public string pay_mode { get; set; }
|
||||||
|
public string note { get; set; }
|
||||||
|
public string proof_img { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public Nullable<System.DateTime> create_time { get; set; }
|
||||||
|
public Nullable<int> f_num_match { get; set; }
|
||||||
|
public Nullable<int> f_num { get; set; }
|
||||||
|
public Nullable<int> acc_num { get; set; }
|
||||||
|
public Nullable<System.DateTime> check_date { get; set; }
|
||||||
|
public Nullable<decimal> check_amount { get; set; }
|
||||||
|
public string check_memo { get; set; }
|
||||||
|
public string check_status { get; set; }
|
||||||
|
public Nullable<int> acc_kind { get; set; }
|
||||||
|
public Nullable<int> member_num { get; set; }
|
||||||
|
public Nullable<System.DateTime> verify_time { get; set; }
|
||||||
|
public string verify_note { get; set; }
|
||||||
|
public string draft { get; set; }
|
||||||
|
public Nullable<decimal> remain_amount { get; set; }
|
||||||
|
|
||||||
|
// 新增的餘額相關欄位
|
||||||
|
public Nullable<int> balance_act_item { get; set; }
|
||||||
|
public Nullable<int> balance_pro_order_detail { get; set; }
|
||||||
|
|
||||||
|
// 顯示用的文字欄位
|
||||||
|
public string activity_name { get; set; }
|
||||||
|
public string follower_name { get; set; }
|
||||||
|
public string actitem_name { get; set; }
|
||||||
|
public string order_detail_info { get; set; }
|
||||||
|
public string acc_kind_name { get; set; }
|
||||||
|
public string status_text { get; set; }
|
||||||
|
public string check_status_text { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class transfer_balance_reconcile
|
||||||
|
{
|
||||||
|
public transfer_balance_reconcile()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Add constructor logic here
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
public string phone { get; set; }
|
||||||
|
public Nullable<decimal> amount { get; set; }
|
||||||
|
public Nullable<decimal> remain_amount { get; set; }
|
||||||
|
public string activity_name { get; set; }
|
||||||
|
public Nullable<System.DateTime> create_time { get; set; }
|
||||||
|
public string check_status { get; set; }
|
||||||
|
public string check_status_text { get; set; }
|
||||||
|
|
||||||
|
// 餘額核銷相關
|
||||||
|
public Nullable<int> balance_act_item { get; set; }
|
||||||
|
public string balance_actitem_name { get; set; }
|
||||||
|
public Nullable<int> balance_pro_order_detail { get; set; }
|
||||||
|
public string balance_order_info { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
57
web/App_Code/NamespaceHttpControllerSelector.cs
Normal file
57
web/App_Code/NamespaceHttpControllerSelector.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Web.Http.Controllers;
|
||||||
|
using System.Web.Http.Dispatcher;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public class NamespaceHttpControllerSelector : DefaultHttpControllerSelector
|
||||||
|
{
|
||||||
|
private readonly HttpConfiguration _configuration;
|
||||||
|
private readonly Lazy<Dictionary<string, HttpControllerDescriptor>> _controllers;
|
||||||
|
|
||||||
|
public NamespaceHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
|
||||||
|
{
|
||||||
|
_configuration = configuration;
|
||||||
|
_controllers = new Lazy<Dictionary<string, HttpControllerDescriptor>>(InitializeControllerDictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, HttpControllerDescriptor> InitializeControllerDictionary()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var assembliesResolver = _configuration.Services.GetAssembliesResolver();
|
||||||
|
var controllersResolver = _configuration.Services.GetHttpControllerTypeResolver();
|
||||||
|
|
||||||
|
var controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver);
|
||||||
|
|
||||||
|
foreach (var type in controllerTypes)
|
||||||
|
{
|
||||||
|
var segments = type.Namespace?.Split(Type.Delimiter);
|
||||||
|
var key = String.Format("{0}.{1}", segments.LastOrDefault(), type.Name.Remove(type.Name.Length - "Controller".Length));
|
||||||
|
|
||||||
|
if (!dictionary.Keys.Contains(key))
|
||||||
|
{
|
||||||
|
dictionary[key] = new HttpControllerDescriptor(_configuration, type.Name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
|
||||||
|
{
|
||||||
|
var routeData = request.GetRouteData();
|
||||||
|
var controllerName = routeData.Values["controller"].ToString();
|
||||||
|
var namespaceName = routeData.Values["namespace"]?.ToString();
|
||||||
|
var key = String.Format("{0}.{1}", namespaceName, controllerName);
|
||||||
|
|
||||||
|
if (_controllers.Value.TryGetValue(key, out var descriptor))
|
||||||
|
{
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
web/App_Code/RouteConfig.cs
Normal file
36
web/App_Code/RouteConfig.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Web;
|
||||||
|
//using System.Web.Mvc;
|
||||||
|
using System.Web.Routing;
|
||||||
|
public class RouteConfig
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* # Resolve Home for each Area
|
||||||
|
* http://stackoverflow.com/questions/7842293/multiple-types-were-found-that-match-the-controller-named-home
|
||||||
|
*
|
||||||
|
* # Home Controller for Area admin
|
||||||
|
* http://stackoverflow.com/questions/17220106/mvc4-default-route-when-using-areas
|
||||||
|
* */
|
||||||
|
public static void RegisterRoutes(RouteCollection routes)
|
||||||
|
{
|
||||||
|
//routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||||
|
//routes.MapRoute(
|
||||||
|
// name: "thumb",
|
||||||
|
// url: "thumb/{*url}",
|
||||||
|
// defaults: new { controller = "thumb", action = "Index", id = UrlParameter.Optional },
|
||||||
|
// namespaces: new[] { "GayoWeb.Controllers" }
|
||||||
|
//);
|
||||||
|
|
||||||
|
//routes.MapRoute(
|
||||||
|
// name: "Default",
|
||||||
|
// url: "{controller}/{action}/{id}",
|
||||||
|
// defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
|
||||||
|
// namespaces: new[] { "GayoWeb.Controllers" }
|
||||||
|
//);
|
||||||
|
}
|
||||||
|
}
|
||||||
99
web/App_Code/SignalR_hub.cs
Normal file
99
web/App_Code/SignalR_hub.cs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using Microsoft.AspNet.SignalR;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Owin;
|
||||||
|
|
||||||
|
|
||||||
|
public class signalRChat : Hub
|
||||||
|
{
|
||||||
|
// 呼叫所有使用者
|
||||||
|
//Clients.All.alertMessage(message);
|
||||||
|
// 呼叫除了自己的使用者
|
||||||
|
//Clients.Others.alertMessage(message);
|
||||||
|
// 呼叫所有使用者除了某個 ConnectionId 的使用者
|
||||||
|
//Clients.AllExcept(Context.ConnectionId).alertMessage(message);
|
||||||
|
// 呼叫自己
|
||||||
|
//Clients.Caller.alertMessage(message);
|
||||||
|
// 呼叫特定使用者
|
||||||
|
//Clients.Client(Context.ConnectionId).alertMessage(message);
|
||||||
|
// 呼叫群組使用者
|
||||||
|
//Clients.Group(groupId).alertMessage(message);
|
||||||
|
|
||||||
|
//宣告靜態類別,來儲存上線清單
|
||||||
|
public static class UserHandler
|
||||||
|
{
|
||||||
|
public static Dictionary<string, string> ConnectedIds = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
//使用者連線時呼叫
|
||||||
|
public void userConnected(string name, string groupId)
|
||||||
|
{
|
||||||
|
//進行編碼,防止XSS攻擊
|
||||||
|
name = HttpUtility.HtmlEncode(name);
|
||||||
|
|
||||||
|
//新增目前使用者至上線清單
|
||||||
|
UserHandler.ConnectedIds.Add(Context.ConnectionId, name);
|
||||||
|
//新增使用者至群組
|
||||||
|
Groups.Add(Context.ConnectionId, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//當使用者斷線時呼叫
|
||||||
|
public override Task OnDisconnected(bool stopCalled)
|
||||||
|
{
|
||||||
|
//當使用者離開時,移除在清單內的 ConnectionId
|
||||||
|
Clients.All.removeList(Context.ConnectionId);
|
||||||
|
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
|
||||||
|
return base.OnDisconnected(stopCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
//若要使用前端來發話通知才需要下面的程式,由後端發送請參考根目錄下的chat.aspx
|
||||||
|
/*
|
||||||
|
//發送訊息給所有人
|
||||||
|
public void sendAllMessage(string from, string message)
|
||||||
|
{
|
||||||
|
if (1==1) //這裡要驗證發話者(from)是否有權限發送
|
||||||
|
{
|
||||||
|
message = HttpUtility.HtmlEncode(message);
|
||||||
|
Clients.All.alertMessage(message); //alertMessage 為client端 function名稱
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//發送訊息至特定使用者
|
||||||
|
public void sendMessage(string from, string connectId, string message)
|
||||||
|
{
|
||||||
|
if (1 == 1) //這裡要驗證發話者(from)是否有權限發送
|
||||||
|
{
|
||||||
|
message = HttpUtility.HtmlEncode(message);
|
||||||
|
Clients.Client(connectId).alertMessage(message); //alertMessage 為client端 function名稱
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//發送訊息至特定使用者名稱
|
||||||
|
public void sendMessageByName(string from, string userName, string message)
|
||||||
|
{
|
||||||
|
if (1 == 1) //這裡要驗證發話者(from)是否有權限發送
|
||||||
|
{
|
||||||
|
message = HttpUtility.HtmlEncode(message);
|
||||||
|
var connectId = UserHandler.ConnectedIds.Where(p => p.Value == userName).FirstOrDefault().Key;
|
||||||
|
Clients.Client(connectId).alertMessage(message); //alertMessage 為client端 function名稱
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//發送訊息至群組
|
||||||
|
public void sendGroupMessage(string from, string groupId, string message)
|
||||||
|
{
|
||||||
|
if (1 == 2) //這裡要驗證發話者(from)是否有權限發送
|
||||||
|
{
|
||||||
|
message = HttpUtility.HtmlEncode(message);
|
||||||
|
Clients.Group(groupId).alertMessage(message); //alertMessage 為client端 function名稱
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
17
web/App_Code/SignalR_startup.cs
Normal file
17
web/App_Code/SignalR_startup.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Owin;
|
||||||
|
using Owin;
|
||||||
|
|
||||||
|
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
|
||||||
|
|
||||||
|
namespace SignalRChat
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void Configuration(IAppBuilder app)
|
||||||
|
{
|
||||||
|
app.MapSignalR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
web/App_Code/Sites.cs
Normal file
83
web/App_Code/Sites.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for Sites
|
||||||
|
/// </summary>
|
||||||
|
public static class Sites
|
||||||
|
{
|
||||||
|
public static List<Site> sites = new List<Site>();
|
||||||
|
public static SiteResource resource = new SiteResource();
|
||||||
|
private static string appurl
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return HttpContext.Current.Server.MapPath("~");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static string site_host
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string host = HttpContext.Current.Request.Url.Host;
|
||||||
|
string r = "default";
|
||||||
|
var h = sites.FirstOrDefault(q=>q.url == host);
|
||||||
|
if (h != null) { r = h.folder; }
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static string site_root
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string r = "";
|
||||||
|
r = appurl;
|
||||||
|
return HttpContext.Current.Server.MapPath("~");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static double MaxAge = 3600 * 24 * 365;
|
||||||
|
static Sites()
|
||||||
|
{
|
||||||
|
JObject o=get_jsonfile(@"sites\sites-config.json");
|
||||||
|
sites = o["sites"].ToObject<List<Site>>();
|
||||||
|
resource = o["resource"].ToObject<SiteResource>();
|
||||||
|
//resource.Add(new KeyValuePair<string, string>("assets", "assets"));
|
||||||
|
//resource.Add(new KeyValuePair<string, string>("config", "config"));
|
||||||
|
}
|
||||||
|
private static JObject get_jsonfile(string jsonfile)
|
||||||
|
{
|
||||||
|
JObject o;
|
||||||
|
//string appurl = HttpContext.Current.Server.MapPath("~");
|
||||||
|
string path = Path.Combine(appurl, jsonfile);
|
||||||
|
o = JObject.Parse(File.ReadAllText(path));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
public static string get_url(string path, string url)
|
||||||
|
{
|
||||||
|
string r="";
|
||||||
|
char s = Path.DirectorySeparatorChar;
|
||||||
|
url = url.Replace('/', s);
|
||||||
|
r = $@"{appurl}sites{s}{site_host}{s}{path}{s}{url}";
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public class Site
|
||||||
|
{
|
||||||
|
public string url { get; set; }
|
||||||
|
public string folder { get; set; }
|
||||||
|
public string connection { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
}
|
||||||
|
public class SiteResource
|
||||||
|
{
|
||||||
|
public string assets { get; set; }
|
||||||
|
public string config { get; set; }
|
||||||
|
public string modules { get; set; }
|
||||||
|
public string upload { get; set; }
|
||||||
|
}
|
||||||
154
web/App_Code/TreeView.cs
Normal file
154
web/App_Code/TreeView.cs
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TreeView 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class TreeView
|
||||||
|
{
|
||||||
|
public TreeView()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
public class TreeItem
|
||||||
|
{
|
||||||
|
public int num { get; set; }
|
||||||
|
public string kind { get; set; }
|
||||||
|
public int? root { get; set; }
|
||||||
|
public int? range { get; set; }
|
||||||
|
public List<TreeItem> Children { get; set; }
|
||||||
|
public int Level { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TreeItem> get_data(List<TreeItem> data, int root, int level)
|
||||||
|
{
|
||||||
|
var resData = new List<TreeItem>();
|
||||||
|
var query = data.Where(x => x.root == root).Select(x => new TreeItem
|
||||||
|
{
|
||||||
|
kind = x.kind,
|
||||||
|
num = x.num,
|
||||||
|
root = x.root,
|
||||||
|
range = x.range,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
if (query.Any())
|
||||||
|
{
|
||||||
|
level++;
|
||||||
|
query.ForEach(x => {
|
||||||
|
x.Children = get_data(data, x.num, level);
|
||||||
|
x.Level = level;
|
||||||
|
resData.Add(x);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return resData;
|
||||||
|
}
|
||||||
|
public List<TreeItem> get_data2(List<TreeItem> data, int root, int level, List<TreeItem> resData=null)
|
||||||
|
{
|
||||||
|
if (resData == null)
|
||||||
|
{
|
||||||
|
resData = new List<TreeItem>();
|
||||||
|
}
|
||||||
|
var query = data.Where(x => x.root == root).Select(x => new TreeItem
|
||||||
|
{
|
||||||
|
kind = x.kind,
|
||||||
|
num = x.num,
|
||||||
|
root = x.root,
|
||||||
|
range = x.range,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
if (query.Any())
|
||||||
|
{
|
||||||
|
level++;
|
||||||
|
query.ForEach(x => {
|
||||||
|
|
||||||
|
resData.Add(x);
|
||||||
|
if ( data.Where(s => s.root == x.num).Count() > 0)
|
||||||
|
{
|
||||||
|
get_data2(data, x.num, level, resData);
|
||||||
|
}
|
||||||
|
x.Level = level;
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return resData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<int> subKinds(List<TreeItem> data, int root, List<int> resData = null)
|
||||||
|
{
|
||||||
|
if (resData == null)
|
||||||
|
{
|
||||||
|
resData = new List<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = data.Where(x => x.root == root).Select(x => new TreeItem
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
root = x.root,
|
||||||
|
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
if (query.Any())
|
||||||
|
{
|
||||||
|
query.ForEach(x => {
|
||||||
|
|
||||||
|
resData.Add(x.num);
|
||||||
|
subKinds(data, x.num, resData);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return resData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string kindText(List<TreeItem> data, int? num)
|
||||||
|
{
|
||||||
|
string txt = "";
|
||||||
|
if (num.HasValue)
|
||||||
|
{
|
||||||
|
var query = data.Where(x => x.num == num.Value).Select(x => new TreeItem
|
||||||
|
{
|
||||||
|
kind = x.kind,
|
||||||
|
num = x.num,
|
||||||
|
root = x.root,
|
||||||
|
|
||||||
|
}).FirstOrDefault();
|
||||||
|
|
||||||
|
if (query != null)
|
||||||
|
{
|
||||||
|
if(query.root > 0)
|
||||||
|
{
|
||||||
|
txt = kindText(data, query.root) + "/"+ query.kind;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
txt = query.kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
public string RptDash(int count)
|
||||||
|
{
|
||||||
|
string txt = "";
|
||||||
|
if(count == 1)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
txt ="-" + RptDash(count-1);
|
||||||
|
}
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
299
web/App_Code/admin.cs
Normal file
299
web/App_Code/admin.cs
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// admin 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
namespace MyWeb
|
||||||
|
{
|
||||||
|
public class admin : function
|
||||||
|
{
|
||||||
|
public string scc = ConfigurationManager.AppSettings["shopCarCode"].ToString();
|
||||||
|
encrypt encrypt = new encrypt();
|
||||||
|
|
||||||
|
public admin()
|
||||||
|
{
|
||||||
|
cName = scc + "Admin";
|
||||||
|
info = new AdmItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string cName { get; set; }
|
||||||
|
public AdmItem info { get; set; }
|
||||||
|
|
||||||
|
//定義欄位cookie==================start
|
||||||
|
public class AdmItem
|
||||||
|
{
|
||||||
|
public int num { get; set; }
|
||||||
|
public string u_id { get; set; }
|
||||||
|
public string group { get; set; }
|
||||||
|
public string power { get; set; }
|
||||||
|
public string login_code { get; set; }
|
||||||
|
public string menu { get; set; }
|
||||||
|
public string login_ip { get; set; }
|
||||||
|
public DateTime login_time { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
//定義欄位cookie==================end
|
||||||
|
|
||||||
|
private AdmItem JDecode(string json)
|
||||||
|
{
|
||||||
|
json = encrypt.DecryptAutoKey(json); //解密
|
||||||
|
AdmItem mItem = JsonConvert.DeserializeObject<AdmItem>(json);
|
||||||
|
return mItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string JEecode(AdmItem aItem)
|
||||||
|
{
|
||||||
|
string json = JsonConvert.SerializeObject(aItem);
|
||||||
|
json = encrypt.EncryptAutoKey(json); //加密
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isLoign(bool DecodeJson = true)
|
||||||
|
{
|
||||||
|
if (!isStrNull(HttpContext.Current.Session[cName]))
|
||||||
|
{
|
||||||
|
if (DecodeJson)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
info = JDecode(HttpContext.Current.Session[cName].ToString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!isStrNull(HttpContext.Current.Request.Cookies[cName]))
|
||||||
|
{
|
||||||
|
if (DecodeJson)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HttpContext.Current.Session[cName] = HttpContext.Current.Request.Cookies[cName].Value;
|
||||||
|
info = JDecode(HttpContext.Current.Request.Cookies[cName].Value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveInfo(AdmItem aItem, bool useCookie)
|
||||||
|
{
|
||||||
|
string JeStr = JEecode(aItem);
|
||||||
|
HttpContext.Current.Session[cName] = JeStr;
|
||||||
|
|
||||||
|
if (useCookie)
|
||||||
|
{
|
||||||
|
HttpContext.Current.Response.Cookies[cName].Value = JeStr;
|
||||||
|
//HttpContext.Current.Response.Cookies[cName].Expires = DateTime.Now.AddHours(8); //8小時
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearInfo()
|
||||||
|
{
|
||||||
|
HttpContext.Current.Session[cName] = null;
|
||||||
|
if (HttpContext.Current.Request.Cookies[cName] != null)
|
||||||
|
{
|
||||||
|
HttpContext.Current.Response.Cookies[cName].Expires = DateTime.Now.AddHours(-8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string MyIP
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ip.Get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool chkAdmIP_Enable
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (System.Configuration.ConfigurationManager.AppSettings["admIP"] != null)
|
||||||
|
if (System.Configuration.ConfigurationManager.AppSettings["admIP"].ToString().Trim() != "")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool chkAdmIP
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<string> IPs = new List<string>();
|
||||||
|
if (chkAdmIP_Enable)
|
||||||
|
{
|
||||||
|
string[] ips = System.Configuration.ConfigurationManager.AppSettings["admIP"].ToString().Split(',');
|
||||||
|
for (int i = 0; i <= ips.Length - 1; i++)
|
||||||
|
{
|
||||||
|
IPs.Add(ips[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string myip = MyIP;
|
||||||
|
|
||||||
|
if (IPs.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (string IP in IPs)
|
||||||
|
{
|
||||||
|
if (myip.IndexOf(IP) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool chkTwIP_Enable
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (System.Configuration.ConfigurationManager.AppSettings["admTwIP"] != null)
|
||||||
|
if (System.Configuration.ConfigurationManager.AppSettings["admTwIP"].ToString().Trim() == "Y")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool chkTwIP
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (chkTwIP_Enable)
|
||||||
|
{
|
||||||
|
List<IPArea> iPAreas = new List<IPArea>();
|
||||||
|
if (HttpContext.Current.Application["TW_IP"] == null)
|
||||||
|
{
|
||||||
|
function f = new function();
|
||||||
|
string[] ips = f.ReadFileContent("~/App_Script/tw_ip.data").Trim().Split('\n');
|
||||||
|
|
||||||
|
if (ips.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (string _ip in ips)
|
||||||
|
{
|
||||||
|
string[] ip = _ip.Split('-');
|
||||||
|
if (ip.Length == 2 && !f.isStrNull(ip[0].Trim()) && !f.isStrNull(ip[1].Trim()))
|
||||||
|
{
|
||||||
|
IPArea iPArea = new IPArea();
|
||||||
|
iPArea.StartIP = IPtoNum(ip[0].Trim());
|
||||||
|
iPArea.EndIP = IPtoNum(ip[1].Trim());
|
||||||
|
iPAreas.Add(iPArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//定義區網IP
|
||||||
|
string[] aIPs = { "127.0.0.1-127.0.0.1", "192.168.0.0-192.168.255.255", "10.0.0.0-10.255.255.255", "172.16.0.0-172.31.255.255" };
|
||||||
|
foreach (string aIP in aIPs)
|
||||||
|
{
|
||||||
|
IPArea iPArea = new IPArea();
|
||||||
|
iPArea.StartIP = IPtoNum(aIP.Split('-')[0].ToString().Trim());
|
||||||
|
iPArea.EndIP = IPtoNum(aIP.Split('-')[1].ToString().Trim());
|
||||||
|
iPAreas.Add(iPArea);
|
||||||
|
}
|
||||||
|
HttpContext.Current.Application["TW_IP"] = Newtonsoft.Json.JsonConvert.SerializeObject(iPAreas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iPAreas = Newtonsoft.Json.JsonConvert.DeserializeObject<List<IPArea>>(HttpContext.Current.Application["TW_IP"].ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 myip = IPtoNum(MyIP);
|
||||||
|
foreach (IPArea item in iPAreas)
|
||||||
|
{
|
||||||
|
if (myip >= item.StartIP && myip <= item.EndIP)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UInt32 IPtoNum(string ip)
|
||||||
|
{
|
||||||
|
byte[] b = System.Net.IPAddress.Parse(ip.Trim()).GetAddressBytes();
|
||||||
|
Array.Reverse(b);
|
||||||
|
return BitConverter.ToUInt32(b, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IPArea
|
||||||
|
{
|
||||||
|
public UInt32 StartIP { get; set; }
|
||||||
|
public UInt32 EndIP { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 登入歷史記錄
|
||||||
|
public class LoginHistory : function
|
||||||
|
{
|
||||||
|
public enum Status
|
||||||
|
{
|
||||||
|
[Description("登入成功")]
|
||||||
|
Success = 1,
|
||||||
|
[Description("帳號已停用")]
|
||||||
|
Disable = 2,
|
||||||
|
[Description("有效期限到期")]
|
||||||
|
Expire = 3,
|
||||||
|
[Description("帳號或密碼錯誤")]
|
||||||
|
Incorrect = 4,
|
||||||
|
[Description("帳號的群組不存在")]
|
||||||
|
GroupNotExist = 5,
|
||||||
|
[Description("未設定使用權限")]
|
||||||
|
PermissionsNotSet = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string UserAgent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string u = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"];
|
||||||
|
Regex b = new Regex(@"android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||||
|
Regex v = new Regex(@"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||||
|
if ((b.IsMatch(u) || v.IsMatch(u.Substring(0, 4))))
|
||||||
|
return "手機";
|
||||||
|
else
|
||||||
|
return "電腦";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
66
web/App_Code/api/FilesController.cs
Normal file
66
web/App_Code/api/FilesController.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
//using System.Web.Helpers;
|
||||||
|
using System.Web.Hosting;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
//using System.Web.Mvc;
|
||||||
|
|
||||||
|
|
||||||
|
[Route("files")]
|
||||||
|
public class FilesController : ApiController
|
||||||
|
{
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<string> Get()
|
||||||
|
{
|
||||||
|
return new string[] { "value1", "value2" };
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("upload/{*url}")]
|
||||||
|
public async Task<HttpResponseMessage> get_upload(string url)
|
||||||
|
{
|
||||||
|
var path = Sites.get_url("upload", url);
|
||||||
|
if (!System.IO.File.Exists(path))
|
||||||
|
{
|
||||||
|
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
}
|
||||||
|
string mimeType = MimeMapping.GetMimeMapping(path);
|
||||||
|
|
||||||
|
HttpResponseMessage response = new HttpResponseMessage();
|
||||||
|
response.Content = new StreamContent(new FileStream(path, FileMode.Open));
|
||||||
|
response.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType);
|
||||||
|
response.Headers.CacheControl = new CacheControlHeaderValue()
|
||||||
|
{
|
||||||
|
Public = true,
|
||||||
|
MaxAge = TimeSpan.FromSeconds(Sites.MaxAge)
|
||||||
|
};
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
[Route("public/{*url}")]
|
||||||
|
public string get_public (string url)
|
||||||
|
{
|
||||||
|
return "public:" + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
182
web/App_Code/api/FilesSetController.cs
Normal file
182
web/App_Code/api/FilesSetController.cs
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
|
||||||
|
// api/FilesSet
|
||||||
|
//[ezAuthorize(Roles = "admin")]//群組:*
|
||||||
|
[ezAuthorize]
|
||||||
|
public class FilesSetController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.file> Get()
|
||||||
|
{
|
||||||
|
var list = _db.files.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Model.file> Get(int page, int pageSize = 10,
|
||||||
|
string sortBy="", bool sortDesc=false)
|
||||||
|
{
|
||||||
|
var list = _db.files.OrderBy(o=>o.num).ToPagedList(page, pageSize);
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.file Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.files.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
//if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] Model.file item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] Model.file item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.files.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => q.files_num == id).ToList(); //刪除品項的相關文件
|
||||||
|
//if (prod2.Count > 0)
|
||||||
|
//{
|
||||||
|
// //查詢結果全部刪除
|
||||||
|
// _db.actItem_files.RemoveRange(prod2);
|
||||||
|
//}
|
||||||
|
_db.actItem_files.RemoveRange(prod.actItem_files);
|
||||||
|
|
||||||
|
|
||||||
|
_db.files.Remove(prod);
|
||||||
|
_db.SaveChanges();//執行
|
||||||
|
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Files, (int)Model.admin_log.Status.Delete, prod.subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/FilesSet/Delete/{nums}")]
|
||||||
|
public void Delete(string nums)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(nums))
|
||||||
|
{
|
||||||
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
||||||
|
|
||||||
|
var prod = _db.files.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
||||||
|
if (prod.Count() > 0)
|
||||||
|
{
|
||||||
|
//刪除品項的相關文件
|
||||||
|
var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.files_num))).ToList();
|
||||||
|
if (prod2.Count > 0)
|
||||||
|
{
|
||||||
|
_db.actItem_files.RemoveRange(prod2);
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.files.RemoveRange(prod);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Files, (int)Model.admin_log.Status.Delete, admin_log.LogViewBtn(prod.Select(x => x.subject).ToList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/FilesSet/count")]
|
||||||
|
public int Count()
|
||||||
|
{
|
||||||
|
var count = _db.files.Count();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/FilesSet/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.files q, int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.files.AsEnumerable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
|
qry = qry.Where(o => o.subject.Contains(q.subject));
|
||||||
|
|
||||||
|
if (q.reg_time1.HasValue)
|
||||||
|
qry = qry.Where(o => o.reg_time >= q.reg_time1.Value);
|
||||||
|
if (q.reg_time2.HasValue)
|
||||||
|
qry = qry.Where(o => o.reg_time < Convert.ToDateTime(q.reg_time2.Value).AddDays(1));
|
||||||
|
|
||||||
|
if (sortBy.Equals("subject"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.subject);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.subject);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("start_date"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.reg_time);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.reg_time);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("end_date"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.modify_time);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.modify_time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
subject = x.subject,
|
||||||
|
reg_time = x.reg_time,
|
||||||
|
modify_time = x.modify_time,
|
||||||
|
word = x.word,
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
690
web/App_Code/api/FollowerController.cs
Normal file
690
web/App_Code/api/FollowerController.cs
Normal file
@@ -0,0 +1,690 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
||||||
|
using MyWeb;
|
||||||
|
using System.Data.Entity;
|
||||||
|
|
||||||
|
// api/Follower
|
||||||
|
//[ezAuthorize(Roles = "admin")]//群組:*
|
||||||
|
[ezAuthorize]
|
||||||
|
//[RoutePrefix("api/follower")]
|
||||||
|
public class FollowerController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.follower> Get()
|
||||||
|
{
|
||||||
|
var list = _db.followers.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Model.follower> Get(int page, int pageSize = 10,
|
||||||
|
string sortBy="", bool sortDesc=false)
|
||||||
|
{
|
||||||
|
var list = _db.followers.OrderBy(o=>o.f_number).ToPagedList(page, pageSize);
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.follower Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.followers.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
//if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] Model.follower item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] Model.follower item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.followers.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
/*if (prod != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
prod.pro_order_detail.Clear(); // Clear 方法來清除相關聯的 Child 資料,針對選擇性關聯欄位,它就會自動將欄位值更新成 null。
|
||||||
|
prod.pro_order.Clear();
|
||||||
|
|
||||||
|
prod.leader = null;//清空leader
|
||||||
|
|
||||||
|
_db.followers.Remove(prod);
|
||||||
|
_db.SaveChanges();//執行
|
||||||
|
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Follower, (int)Model.admin_log.Status.Delete, prod.f_number+prod.u_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
////prod.IsDel = true; ////不確定是否新增欄位? 先註解
|
||||||
|
_db.SaveChanges();
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Follower, (int)Model.admin_log.Status.Delete, prod.f_number + prod.u_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/follower/Delete/{nums}")]
|
||||||
|
public void Delete(string nums)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(nums))
|
||||||
|
{
|
||||||
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
||||||
|
|
||||||
|
var prod = _db.followers.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
|
if (prod.Count() > 0)
|
||||||
|
{
|
||||||
|
foreach (var item in prod)
|
||||||
|
{
|
||||||
|
foreach (var item2 in item.pro_order_detail1)
|
||||||
|
item2.from_id = null; //清空訂單明細的陽上報恩者from_id //f_num設定串聯刪除
|
||||||
|
|
||||||
|
foreach (var item2 in item.pro_order)
|
||||||
|
item2.introducer = null;
|
||||||
|
|
||||||
|
item.leader = null;//清空leader
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.followers.RemoveRange(prod);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Follower, (int)Model.admin_log.Status.Delete, admin_log.LogViewBtn(prod.Select(x => x.f_number + x.u_name).ToList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/follower/count")]
|
||||||
|
public int Count()
|
||||||
|
{
|
||||||
|
var count = _db.followers.Count();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.follower q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
////var qry = _db.followers.Where(a => a.IsDel == false).AsEnumerable();////不確定是否新增欄位? 先註解
|
||||||
|
var qry = _db.followers.AsEnumerable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.f_number))
|
||||||
|
qry = qry.Where(o => o.f_number.Contains(q.f_number.Trim()));
|
||||||
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
|
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||||
|
if (q.birthday.HasValue)
|
||||||
|
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
||||||
|
if (q.birthday2.HasValue)
|
||||||
|
qry = qry.Where(o => o.birthday < Convert.ToDateTime(q.birthday2.Value).AddDays(1));
|
||||||
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
|
qry = qry.Where(o => o.address !=null && o.address.Contains(q.address?.Trim()));
|
||||||
|
//if (q.num.HasValue && q.num.Value>0)
|
||||||
|
// qry = qry.Where(o => o.num==q.num.Value);
|
||||||
|
if (q.ept_self.HasValue && q.ept_self.Value )//排除自己
|
||||||
|
{
|
||||||
|
qry = qry.Where(o => o.num != q.num.Value);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(q.country))
|
||||||
|
qry = qry.Where(o => o.country== q.country);
|
||||||
|
if (!string.IsNullOrEmpty(q.country2))
|
||||||
|
{
|
||||||
|
if (q.country2 == "1")
|
||||||
|
{
|
||||||
|
qry = qry.Where(o => o.country == "158");
|
||||||
|
}else if (q.country2 == "2")
|
||||||
|
{
|
||||||
|
qry = qry.Where(o => o.country != "158");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sortBy.Equals("f_number"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.f_number);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.f_number);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("u_name"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.u_name);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.u_name);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("identity_type_desc"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.identity_type);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.identity_type);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("sex"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.sex);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.sex);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("birthday"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.birthday);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.birthday);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
|
|
||||||
|
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||||
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
f_number = x.f_number,
|
||||||
|
u_name = x.u_name,
|
||||||
|
sex = x.sex,
|
||||||
|
birthday = x.birthday, //?.ToString("yyyy/MM/dd"),
|
||||||
|
birthday2 = publicFun.chagenDate(x.birthday), //?.ToString("yyyy/MM/dd"),
|
||||||
|
sign = Model.follower.chagenSign(x.birthday), //NULL??
|
||||||
|
sexagenary = Model.follower.sexagenary(x.birthday),
|
||||||
|
identity_type = x.identity_type,
|
||||||
|
//identity_type_string = Enum.GetName( typeof(Model.follower.type), x.identity_type),
|
||||||
|
//identity_type_string1 = ((Model.follower.type)(x.identity_type??0)).ToString(),
|
||||||
|
identity_type_desc = tdesc[x.identity_type ?? 1] ,//TryGetValue..
|
||||||
|
|
||||||
|
phone = x.phone,
|
||||||
|
phoneDes = encrypt.DecryptAutoKey(x.phone), //--MyWeb.function X
|
||||||
|
refugedate=x.refugedate,
|
||||||
|
refuge_name = x.refuge_name,
|
||||||
|
email = x.email,
|
||||||
|
address = x.address,
|
||||||
|
cellphone = x.cellphone,
|
||||||
|
cellphoneDes = encrypt.DecryptAutoKey(x.cellphone),
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = count
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* SQL:
|
||||||
|
SELECT
|
||||||
|
[Extent1].[num] AS [num],
|
||||||
|
[Extent1].[f_number] AS [f_number],
|
||||||
|
[Extent1].[u_name] AS [u_name],
|
||||||
|
[Extent1].[sex] AS [sex],
|
||||||
|
[Extent1].[identity_type] AS [identity_type],
|
||||||
|
[Extent1].[birthday] AS [birthday],
|
||||||
|
[Extent1].[phone] AS [phone],
|
||||||
|
[Extent1].[email] AS [email],
|
||||||
|
[Extent1].[refugedate] AS [refugedate],
|
||||||
|
[Extent1].[refuge_name] AS [refuge_name],
|
||||||
|
[Extent1].[address] AS [address],
|
||||||
|
[Extent1].[demo] AS [demo],
|
||||||
|
[Extent1].[nation] AS [nation],
|
||||||
|
[Extent1].[leader] AS [leader]
|
||||||
|
FROM [dbo].[followers] AS [Extent1]
|
||||||
|
|
||||||
|
*/
|
||||||
|
//LINQ查詢必需要寫成: 能轉成SQL指令的查詢, 故小心呼叫自訂函數(或無法)
|
||||||
|
//要學會用原生的寫法, 新式的寫法, 東西都往 MyWeb.function 裡塞, 是錯的, 要思考其合理性
|
||||||
|
//API應該儘量提供資料而不是"格式"
|
||||||
|
//日期轉字串: 如要用VUE做, 傳回date而不要tostring, 用filter + moment.js做
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
write a post action: checkHashFollower
|
||||||
|
input: phone, idcode
|
||||||
|
pass to encrypt.cs: followerHash, get hash
|
||||||
|
query db: followers where follower_hash==hash to follower
|
||||||
|
output: follower (or null)
|
||||||
|
*/
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/GetFamilyList")]
|
||||||
|
public IHttpActionResult GetFamilyList([FromBody] Model.ViewModel.follower q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
int _follower = q.num.HasValue && q.num.Value > 0 ? q.num.Value : 0;
|
||||||
|
if (_follower > 0)
|
||||||
|
{
|
||||||
|
//家族 : 家長是我的人,跟我同家長的人,我的家長本人,我本人
|
||||||
|
//var cc = _db.followers.AsEnumerable().Where(x => x.num == 103 || x.leader == 103).Select(x => x.num);
|
||||||
|
//var aa = _db.followers.Where(x => x.num == 103 || x.leader == 103).Select(x => x.num);
|
||||||
|
//var bb = _db.followers.Where(i => aa.Any(x => x == i.num) || aa.Any(x => x == i.leader)).ToList();
|
||||||
|
|
||||||
|
int myLeader = _db.followers.Where(x => x.num == _follower).Select(x => x.leader??0).FirstOrDefault(); //我的家長
|
||||||
|
|
||||||
|
var cc = _db.followers.Where(x => x.num == _follower || x.leader == _follower).Select(x => x.num);
|
||||||
|
|
||||||
|
//var qry =
|
||||||
|
//from c in foDt
|
||||||
|
//where c.leader == _follower ||
|
||||||
|
// ((from o in foDt
|
||||||
|
// where o.num == _follower
|
||||||
|
// select o.leader).Contains(c.leader) && c.leader != null) ||
|
||||||
|
// (from o in foDt
|
||||||
|
// where o.num == _follower
|
||||||
|
// select o.leader).Contains(c.num) ||
|
||||||
|
// c.num == _follower
|
||||||
|
//select c;
|
||||||
|
|
||||||
|
if (q.ept_self.HasValue && q.ept_self.Value) //排除自己
|
||||||
|
{
|
||||||
|
//qry =
|
||||||
|
//from c in foDt
|
||||||
|
//where c.leader == _follower ||
|
||||||
|
// ((from o in foDt
|
||||||
|
// where o.num == _follower
|
||||||
|
// select o.leader).Contains(c.leader) && c.leader != null)
|
||||||
|
// && c.num != _follower
|
||||||
|
//select c;
|
||||||
|
|
||||||
|
if (myLeader > 0)//有家長
|
||||||
|
{
|
||||||
|
//跟我同家長的人
|
||||||
|
cc = _db.followers.Where(x => x.num != _follower && (x.leader == _follower || x.leader == myLeader)).Select(x => x.num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cc = _db.followers.Where(x => x.num != _follower && x.leader == _follower).Select(x => x.num);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//int ccc = cc.Count();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var qry = _db.followers.AsEnumerable().Where(f => cc.Any(x => x == f.num) || cc.Any(x => x == f.leader));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.f_number))
|
||||||
|
qry = qry.Where(o => o.f_number.Contains(q.f_number.Trim()));
|
||||||
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
|
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||||
|
if (q.birthday.HasValue)
|
||||||
|
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
||||||
|
if (q.birthday2.HasValue)
|
||||||
|
qry = qry.Where(o => o.birthday < Convert.ToDateTime(q.birthday2.Value).AddDays(1));
|
||||||
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
|
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
||||||
|
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
|
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||||
|
int i = 1;
|
||||||
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
id = i++,
|
||||||
|
num = x.num,
|
||||||
|
f_number = x.f_number,
|
||||||
|
u_name = x.u_name,
|
||||||
|
address = x.address,
|
||||||
|
birthday = x.birthday,
|
||||||
|
phone = x.phone,
|
||||||
|
phoneDes = encrypt.DecryptAutoKey(x.phone),
|
||||||
|
demo = x.demo,
|
||||||
|
identity_type_desc = tdesc[x.identity_type ?? 1],
|
||||||
|
f_num_selected = new
|
||||||
|
{
|
||||||
|
text = x.u_name,
|
||||||
|
val = x.num,
|
||||||
|
},
|
||||||
|
//data_tmp = new //tmp 暫存用
|
||||||
|
//{
|
||||||
|
// f_num_selected = new
|
||||||
|
// {
|
||||||
|
// text = x.u_name,
|
||||||
|
// val = x.num,
|
||||||
|
// },
|
||||||
|
// identity_type_desc = tdesc[x.identity_type ?? 1],
|
||||||
|
// birthday = x.birthday,
|
||||||
|
// phoneDes = encrypt.DecryptAutoKey(x.phone),
|
||||||
|
// demo = x.demo,
|
||||||
|
//},
|
||||||
|
appellation_id_selected = new
|
||||||
|
{
|
||||||
|
text = x.appellation?.title,
|
||||||
|
val = x.appellation_id,
|
||||||
|
},
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = count
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok("此訂單沒有姓名/名稱");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/familySave")]
|
||||||
|
public IHttpActionResult SaveDetailData([FromBody] Model.ViewModel.follower item)
|
||||||
|
{
|
||||||
|
if (item.leader.HasValue && item.leader.Value > 0 && item.f_num.HasValue && item.f_num.Value > 0)
|
||||||
|
{
|
||||||
|
if (item.num.HasValue && item.num.Value > 0)
|
||||||
|
{
|
||||||
|
//原先就有設定家長 , -> 家人 :不變 or 變更
|
||||||
|
if (item.num.Value == item.f_num.Value)
|
||||||
|
{
|
||||||
|
//變更其家人稱謂
|
||||||
|
Model.follower _data = _db.followers.Where(q => q.num == item.f_num.Value).FirstOrDefault();//修改
|
||||||
|
if (_data != null)
|
||||||
|
{
|
||||||
|
_data.appellation_id = item.appellation_id.Value;
|
||||||
|
_db.SaveChanges();
|
||||||
|
var ret = _data.num;
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//移除原先的家長設定
|
||||||
|
Model.follower _data2 = _db.followers.Where(q => q.num == item.num.Value).FirstOrDefault();//修改
|
||||||
|
if (_data2 != null)
|
||||||
|
{
|
||||||
|
_data2.leader = null;
|
||||||
|
_data2.appellation_id = null;
|
||||||
|
_db.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
//變更其家長設定
|
||||||
|
Model.follower _data = _db.followers.Where(q => q.num == item.f_num.Value).FirstOrDefault();//修改
|
||||||
|
if (_data != null)
|
||||||
|
{
|
||||||
|
_data.leader = item.leader.Value;
|
||||||
|
_data.appellation_id = item.appellation_id.Value;
|
||||||
|
_db.SaveChanges();
|
||||||
|
var ret = _data.num;
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//新增家人
|
||||||
|
//變更其家長設定
|
||||||
|
Model.follower _data = _db.followers.Where(q => q.num == item.f_num.Value).FirstOrDefault();//修改
|
||||||
|
if (_data != null)
|
||||||
|
{
|
||||||
|
_data.leader = item.leader.Value;
|
||||||
|
_data.appellation_id = item.appellation_id.Value;
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
var ret = _data.num;
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/familyDelete")]
|
||||||
|
public IHttpActionResult familyDelete([FromBody] Model.ViewModel.follower item)
|
||||||
|
{
|
||||||
|
if (item.leader.HasValue && item.leader.Value > 0 && item.num.HasValue && item.num.Value > 0)
|
||||||
|
{
|
||||||
|
//移除原先的家長設定
|
||||||
|
Model.follower _data2 = _db.followers.Where(q => q.num == item.num.Value).FirstOrDefault();//修改
|
||||||
|
if (_data2 != null)
|
||||||
|
{
|
||||||
|
_data2.leader = null;
|
||||||
|
_db.SaveChanges();
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/GetTabletList")]
|
||||||
|
public IHttpActionResult GetTabletList([FromBody] Model.follower q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
int _follower = q.num;
|
||||||
|
pageSize = (pageSize < 0) ? 0 : pageSize;
|
||||||
|
if (_follower > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
var qry = _db.followers_tablet.AsEnumerable().Where(x=>( x.f_num??0) == _follower);
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
int i = 1;
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
id = i++,
|
||||||
|
num = x.num,
|
||||||
|
f_num = x.f_num,
|
||||||
|
type = x.type,
|
||||||
|
title = x.title,
|
||||||
|
}),
|
||||||
|
count = count
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
|
||||||
|
return Ok(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/tabletSave")]
|
||||||
|
public IHttpActionResult tabletSave([FromBody] Model.ViewModel.followers_tablet item)
|
||||||
|
{
|
||||||
|
if (item.num.HasValue && item.num.Value > 0)
|
||||||
|
{
|
||||||
|
//變更
|
||||||
|
Model.followers_tablet _data = _db.followers_tablet.Where(q => q.num == item.num.Value).FirstOrDefault();//修改
|
||||||
|
if (_data != null)
|
||||||
|
{
|
||||||
|
_data.type = item.type;
|
||||||
|
_data.title = item.title;
|
||||||
|
_db.SaveChanges();
|
||||||
|
var ret = _data.num;
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//新增
|
||||||
|
Model.followers_tablet _data = new Model.followers_tablet();
|
||||||
|
_data.f_num = item.f_num;
|
||||||
|
_data.type = item.type;
|
||||||
|
_data.title = item.title;
|
||||||
|
_db.followers_tablet.Add(_data);
|
||||||
|
_db.SaveChanges();
|
||||||
|
var ret = _data.num;
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/follower/tabletDelete/{id}")]
|
||||||
|
public void tabletDelete(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.followers_tablet.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
_db.followers_tablet.Remove(prod);
|
||||||
|
_db.SaveChanges();//執行
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/checkHashFollower")]
|
||||||
|
public IHttpActionResult CheckHashFollower([FromBody] dynamic request)
|
||||||
|
{
|
||||||
|
if (request == null || request.phone == null || request.id_code == null)
|
||||||
|
{
|
||||||
|
return BadRequest("Invalid input");
|
||||||
|
}
|
||||||
|
|
||||||
|
string phone = request.phone;
|
||||||
|
string id_code = request.id_code;
|
||||||
|
|
||||||
|
// Pass phone and idcode to encrypt.cs to get the followerHash
|
||||||
|
encrypt enc = new encrypt();
|
||||||
|
string followerHash = enc.followerHash(phone, id_code);
|
||||||
|
|
||||||
|
// Query the database for followers where follower_hash == followerHash
|
||||||
|
var follower = _db.followers.FirstOrDefault(f => f.follower_hash == followerHash);
|
||||||
|
|
||||||
|
// Return the follower or null
|
||||||
|
return Ok(follower);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/orderrecord")]
|
||||||
|
public IHttpActionResult GetOrderRecord(int id = 0)
|
||||||
|
{
|
||||||
|
//獲取信眾報名活動記錄
|
||||||
|
if (id == 0)
|
||||||
|
{
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
var orderrecord = _db.pro_order.Where(x => x.f_num == id).Include(x => x.pro_order_detail).Include(x => x.follower).ToList();
|
||||||
|
var data = new
|
||||||
|
{
|
||||||
|
list = orderrecord.Select(x => new
|
||||||
|
{
|
||||||
|
orderno = x.order_no,
|
||||||
|
startdate = x.reg_time,
|
||||||
|
endtime = x.up_time,
|
||||||
|
pwcount = x.pro_order_detail.Where(a => a.actItem.act_bom.Where(b => b.item_num == a.actItem_num && b.package_num == null).Count() == 0).Count(),
|
||||||
|
amount = x.pro_order_detail.Select(o => (float?)o.price).Sum(),
|
||||||
|
activityname = x.activity.subject,
|
||||||
|
category = x.activity.activity_category_kind.kind,
|
||||||
|
order_item = x.pro_order_detail.Where(b => b.parent_num == null).Select(c => c.actItem.subject).Distinct().ToList(),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/totalorderamount")]
|
||||||
|
public IHttpActionResult GetTotalOrderCount(int id)
|
||||||
|
{
|
||||||
|
//獲取信眾的報名次數和報名總功德金
|
||||||
|
var orderList = _db.pro_order.Where(x => x.f_num == id).Select(x => x.order_no).ToList();
|
||||||
|
var totalprice = _db.pro_order_detail.Where(d => orderList.Contains(d.order_no)).Sum(d => (float?)d.price) ?? 0;
|
||||||
|
/*var totalPrice = (from d in _db.pro_order_detail
|
||||||
|
join o in _db.pro_order on d.order_no equals o.order_no
|
||||||
|
where o.f_num == id
|
||||||
|
select d.price).Sum();*/
|
||||||
|
var activityTimes = _db.pro_order.Where(x => x.f_num == id).Count();
|
||||||
|
return Ok(new { totalamount = totalprice, activity_times = activityTimes });
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/follower/orderreordpwlist")]
|
||||||
|
public IHttpActionResult GetPwList([FromUri] string orderno)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(orderno))
|
||||||
|
{
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
var pwlist = _db.pro_order_detail.Where(x => x.order_no == orderno).OrderBy(k => k.actItem_num).ToList();
|
||||||
|
var data = new
|
||||||
|
{
|
||||||
|
list = pwlist.Select(j => new
|
||||||
|
{
|
||||||
|
id = j.num,
|
||||||
|
orderno = j.order_no,
|
||||||
|
printid = j.print_id,
|
||||||
|
price = j.price,
|
||||||
|
pwname = j.actItem.subject,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
32
web/App_Code/api/LocationController.cs
Normal file
32
web/App_Code/api/LocationController.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
public class LocationController : ApiController
|
||||||
|
{
|
||||||
|
private ezEntities _db = new ezEntities();
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/location/cities")]
|
||||||
|
public IHttpActionResult GetCities()
|
||||||
|
{
|
||||||
|
var cities = _db.PostCitiy.Select(c => c.city).Distinct().ToList();
|
||||||
|
return Ok(cities);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/location/areas/{city}")]
|
||||||
|
public IHttpActionResult GetAreas(string city)
|
||||||
|
{
|
||||||
|
var areas = _db.PostNumber
|
||||||
|
.Where(p => p.City == city)
|
||||||
|
.Select(p => p.Area)
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
return Ok(areas);
|
||||||
|
}
|
||||||
|
}
|
||||||
388
web/App_Code/api/ShuWenController.cs
Normal file
388
web/App_Code/api/ShuWenController.cs
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
using Model;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using DocumentFormat.OpenXml.Packaging;
|
||||||
|
using DocumentFormat.OpenXml.Wordprocessing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net;
|
||||||
|
using DocumentFormat.OpenXml;
|
||||||
|
using static Model.admin_log;
|
||||||
|
using DocumentFormat.OpenXml.Bibliography;
|
||||||
|
using PagedList;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ShuWenController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class ShuWenController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public ShuWenController()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/shuwen/getshuwen")]
|
||||||
|
public IHttpActionResult GetShuWen(int? activitynum)
|
||||||
|
{
|
||||||
|
if (!activitynum.HasValue)
|
||||||
|
{
|
||||||
|
return BadRequest("請提供有效的 activitynum 參數。");
|
||||||
|
}
|
||||||
|
var shuwen = _db.ShuWens.Where(a => a.ActivityNum == activitynum).FirstOrDefault();
|
||||||
|
if(shuwen == null)
|
||||||
|
{
|
||||||
|
return Ok(new { message = "1", data = shuwen, latest = false });
|
||||||
|
}
|
||||||
|
var latest = _db.pro_order_detail.Where(b => b.pro_order.activity_num == activitynum)
|
||||||
|
.Where(c => c.UpdateTime > shuwen.UpdateTime).Count() > 0 ? false : true;
|
||||||
|
return Ok(new { message = "1", data = shuwen , latest= latest});
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/shuwen/StartGenerate")]
|
||||||
|
public IHttpActionResult CreateShuWen(int? activitynum)
|
||||||
|
{
|
||||||
|
if (!activitynum.HasValue)
|
||||||
|
{
|
||||||
|
return BadRequest("請提供有效的 activitynum 參數。");
|
||||||
|
}
|
||||||
|
var shuwen = _db.ShuWens.Where(a => a.ActivityNum == activitynum).FirstOrDefault();
|
||||||
|
if (shuwen == null)
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
shuwen = new Model.ShuWen();
|
||||||
|
shuwen.ActivityNum = activitynum.Value;
|
||||||
|
shuwen.CreateTime = now;
|
||||||
|
shuwen.UpdateTime = now;
|
||||||
|
shuwen.IsGenerating = true;
|
||||||
|
_db.ShuWens.Add(shuwen);
|
||||||
|
}
|
||||||
|
else if (shuwen.IsGenerating)
|
||||||
|
{
|
||||||
|
return Ok("任务正在处理中");
|
||||||
|
}
|
||||||
|
shuwen.IsGenerating = true;
|
||||||
|
_db.SaveChanges();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
shuwen.ShuWenList = ProcessDesserts2(_db.pro_order_detail.Where(a => a.pro_order.activity_num == activitynum.Value).ToList());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
shuwen.IsGenerating = false;
|
||||||
|
shuwen.UpdateTime = DateTime.Now;
|
||||||
|
_db.SaveChanges();
|
||||||
|
return Ok("已啟動生成任務");
|
||||||
|
}
|
||||||
|
public string ProcessDesserts2(List<pro_order_detail> items)
|
||||||
|
{
|
||||||
|
var xiaozai = new List<Dictionary<string, Dictionary<string, object>>>();
|
||||||
|
var chaodu = new List<Dictionary<string, Dictionary<string, object>>>();
|
||||||
|
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
string json = item.f_num_tablet;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JObject obj = JObject.Parse(json);
|
||||||
|
var midItems = obj["mid_items"] as JArray;
|
||||||
|
var famNames = new List<string>();
|
||||||
|
|
||||||
|
foreach (var mid in midItems ?? new JArray())
|
||||||
|
{
|
||||||
|
bool isShuWen = mid["IsShuWen"]?.Value<bool>() == true;
|
||||||
|
string famName = mid["fam_name"]?.ToString();
|
||||||
|
|
||||||
|
if (isShuWen && !string.IsNullOrWhiteSpace(famName))
|
||||||
|
{
|
||||||
|
famNames.Add(famName.Trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (famNames.Count == 0) continue;
|
||||||
|
|
||||||
|
string orderNo = item.order_no;
|
||||||
|
var userObject = new
|
||||||
|
{
|
||||||
|
name = item.pro_order.follower.u_name,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item.actItem.subject.Contains("消"))
|
||||||
|
{
|
||||||
|
var existing = xiaozai.FirstOrDefault(d => d.ContainsKey(orderNo));
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
var data = (List<string>)existing[orderNo]["biaoti"];
|
||||||
|
data.AddRange(famNames);
|
||||||
|
existing[orderNo]["biaoti"] = data.Distinct().ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xiaozai.Add(new Dictionary<string, Dictionary<string, object>>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
orderNo,
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "user", userObject },
|
||||||
|
{ "biaoti", new List<string>(famNames) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (item.actItem.subject.Contains("超"))
|
||||||
|
{
|
||||||
|
var leftNames = new List<string>();
|
||||||
|
if (obj["left_items"] != null && obj["left_items"].HasValues)
|
||||||
|
{
|
||||||
|
var leftItems = obj["left_items"] as JArray;
|
||||||
|
foreach (var left in leftItems ?? new JArray())
|
||||||
|
{
|
||||||
|
leftNames.Add(left["fam_name"]?.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(leftNames.Count() == 0) continue;
|
||||||
|
var existing = chaodu.FirstOrDefault(d => d.ContainsKey(orderNo));
|
||||||
|
string leftFamName = string.Join(" ", leftNames).Trim();
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
var entryList = (List<Dictionary<string, object>>)existing[orderNo]["entry"];
|
||||||
|
var existingYangshang = entryList.FirstOrDefault(e => IsSamePeople(e["yangshang"]?.ToString(), leftFamName));
|
||||||
|
if (existingYangshang != null)
|
||||||
|
{
|
||||||
|
var oldBiaoti = (List<string>)existingYangshang["biaoti"];
|
||||||
|
oldBiaoti.AddRange(famNames);
|
||||||
|
existingYangshang["biaoti"] = oldBiaoti.Distinct().ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entryList.Add(new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "yangshang", leftFamName },
|
||||||
|
{ "biaoti", new List<string>(famNames) }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chaodu.Add(new Dictionary<string, Dictionary<string, object>>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
orderNo,
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "user", userObject },
|
||||||
|
{
|
||||||
|
"entry",
|
||||||
|
new List<Dictionary<string, object>>
|
||||||
|
{
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "yangshang", leftFamName },
|
||||||
|
{ "biaoti", new List<string>(famNames) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (JsonReaderException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
xiaozai = xiaozai,
|
||||||
|
chaodu = chaodu
|
||||||
|
};
|
||||||
|
|
||||||
|
return JsonConvert.SerializeObject(result, Formatting.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/shuwen/download")]
|
||||||
|
public HttpResponseMessage DownloadShuWenWord(int? activitynum)
|
||||||
|
{
|
||||||
|
var data = _db.ShuWens.Where(a => a.ActivityNum == activitynum).FirstOrDefault();
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
string json = data.ShuWenList;
|
||||||
|
string ActivityName = _db.activities.Where(a => a.num == data.ActivityNum).FirstOrDefault().subject;
|
||||||
|
if (json == null)
|
||||||
|
{
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
string fileName = $"疏文名單_{DateTime.Now:yyyyMMddHHmmss}.docx";
|
||||||
|
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
GenerateShuWenWord_OpenXml(json, stream, ActivityName);
|
||||||
|
stream.Position = 0;
|
||||||
|
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
Content = new StreamContent(stream)
|
||||||
|
};
|
||||||
|
response.Content.Headers.ContentType =
|
||||||
|
new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
||||||
|
response.Content.Headers.ContentDisposition =
|
||||||
|
new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
|
||||||
|
{
|
||||||
|
FileName = fileName
|
||||||
|
};
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GenerateShuWenWord_OpenXml(string json, Stream outputStream, string ActivityName ="")
|
||||||
|
{
|
||||||
|
JObject root = JObject.Parse(json);
|
||||||
|
|
||||||
|
using (var doc = WordprocessingDocument.Create(outputStream, WordprocessingDocumentType.Document, true))
|
||||||
|
{
|
||||||
|
var mainPart = doc.AddMainDocumentPart();
|
||||||
|
mainPart.Document = new Document(new Body());
|
||||||
|
var body = mainPart.Document.Body;
|
||||||
|
var sectionProps = new SectionProperties(
|
||||||
|
new PageSize() { Orient = PageOrientationValues.Landscape },
|
||||||
|
new TextDirection() { Val = TextDirectionValues.TopToBottomRightToLeft }
|
||||||
|
);
|
||||||
|
mainPart.Document.Body.Append(sectionProps);
|
||||||
|
// === 處理 xiaozai ===
|
||||||
|
var xiaozai = root["xiaozai"] as JArray;
|
||||||
|
if (xiaozai != null)
|
||||||
|
{
|
||||||
|
foreach (var item in xiaozai.Children<JObject>())
|
||||||
|
{
|
||||||
|
foreach (var prop in item.Properties())
|
||||||
|
{
|
||||||
|
string orderNo = prop.Name;
|
||||||
|
//var names = prop.Value.ToObject<List<string>>();
|
||||||
|
var detail = prop.Value as JObject;
|
||||||
|
string username = detail?["user"]?["name"]?.ToString();
|
||||||
|
var biaotiList = detail?["biaoti"]?.ToObject<List<string>>() ?? new List<string>();
|
||||||
|
|
||||||
|
AddPageBreak(body);
|
||||||
|
var orderActItem = _db.pro_order_detail.Where(a => a.order_no == orderNo && a.actItem.act_bom.Where(b => b.package_num == null && b.item_num == a.actItem_num).Count() == 1).FirstOrDefault();
|
||||||
|
if(orderActItem != null)
|
||||||
|
{
|
||||||
|
username = orderActItem.actItem.subject;
|
||||||
|
}
|
||||||
|
body.Append(CreateHeading($"{ActivityName} {username} 消災祈福名單"));
|
||||||
|
/*foreach (var name in biaotiList)
|
||||||
|
{
|
||||||
|
body.Append(CreateParagraph(" " + name));
|
||||||
|
}*/
|
||||||
|
var combinedNames = string.Join(" ", biaotiList);
|
||||||
|
combinedNames = combinedNames.Replace(" ", " ");
|
||||||
|
body.Append(CreateParagraph(combinedNames));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 處理 chaodu ===
|
||||||
|
var chaodu = root["chaodu"] as JArray;
|
||||||
|
if (chaodu != null)
|
||||||
|
{
|
||||||
|
foreach (var item in chaodu.Children<JObject>())
|
||||||
|
{
|
||||||
|
foreach (var prop in item.Properties())
|
||||||
|
{
|
||||||
|
string orderNo = prop.Name;
|
||||||
|
//var persons = prop.Value as JArray;
|
||||||
|
var detail = prop.Value as JObject;
|
||||||
|
string username = detail?["user"]?["name"]?.ToString();
|
||||||
|
var entries = detail?["entry"] as JArray;
|
||||||
|
var orderActItem = _db.pro_order_detail.Where(a => a.order_no == orderNo && a.actItem.act_bom.Where(b => b.package_num == null && b.item_num == a.actItem_num).Count() == 1).FirstOrDefault();
|
||||||
|
if (orderActItem != null)
|
||||||
|
{
|
||||||
|
username = orderActItem.actItem.subject;
|
||||||
|
}
|
||||||
|
AddPageBreak(body);
|
||||||
|
body.Append(CreateHeading($"{ActivityName} {username} 超薦名單"));
|
||||||
|
|
||||||
|
foreach (var person in entries)
|
||||||
|
{
|
||||||
|
string yangshang = person["yangshang"]?.ToString();
|
||||||
|
var biaotiList = person["biaoti"]?.ToObject<List<string>>() ?? new List<string>();
|
||||||
|
|
||||||
|
foreach (var b in biaotiList)
|
||||||
|
{
|
||||||
|
body.Append(CreateParagraph(" " + b));
|
||||||
|
}
|
||||||
|
body.Append(CreateParagraph("陽上報恩人:" + yangshang));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Paragraph CreateHeading(string text)
|
||||||
|
{
|
||||||
|
return new Paragraph(
|
||||||
|
new Run(new RunProperties(
|
||||||
|
new FontSize() { Val = "50" }
|
||||||
|
), new Text(text))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ParagraphProperties = new ParagraphProperties(
|
||||||
|
new Justification() { Val = JustificationValues.Start },
|
||||||
|
new Bold(),
|
||||||
|
new SpacingBetweenLines() { After = "200" },
|
||||||
|
new TextDirection() { Val = TextDirectionValues.TopToBottomRightToLeft }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Paragraph CreateParagraph(string text)
|
||||||
|
{
|
||||||
|
return new Paragraph(
|
||||||
|
new Run(new RunProperties(
|
||||||
|
new FontSize() { Val = "40" }
|
||||||
|
),
|
||||||
|
new Text(text))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ParagraphProperties = new ParagraphProperties(
|
||||||
|
new TextDirection() { Val = TextDirectionValues.TopToBottomRightToLeft }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPageBreak(Body body)
|
||||||
|
{
|
||||||
|
if (body.Elements<Paragraph>().Any())
|
||||||
|
{
|
||||||
|
body.Append(new Paragraph(new Run(new DocumentFormat.OpenXml.Wordprocessing.Break() { Type = BreakValues.Page })));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSamePeople(string a, string b)
|
||||||
|
{
|
||||||
|
var listA = a.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Distinct().OrderBy(x => x).ToList();
|
||||||
|
var listB = b.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Distinct().OrderBy(x => x).ToList();
|
||||||
|
|
||||||
|
return listA.SequenceEqual(listB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
50
web/App_Code/api/WebApiConfig.cs
Normal file
50
web/App_Code/api/WebApiConfig.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WebApiConfig 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class WebApiConfig
|
||||||
|
{
|
||||||
|
public static string UrlPrefixRelative { get { return "~/api"; } }
|
||||||
|
public static void Register(HttpConfiguration config)
|
||||||
|
{
|
||||||
|
// TODO: Add any additional configuration code.
|
||||||
|
|
||||||
|
// Web API routes
|
||||||
|
config.MapHttpAttributeRoutes();
|
||||||
|
|
||||||
|
//config.Routes.MapHttpRoute(
|
||||||
|
// name: "AppFollowerApi",
|
||||||
|
// routeTemplate: "api/appfollower/{id}",
|
||||||
|
// defaults: new { controller = "appFollower", id = RouteParameter.Optional }
|
||||||
|
//);
|
||||||
|
//config.Routes.MapHttpRoute(
|
||||||
|
// name: "AppApi",
|
||||||
|
// routeTemplate: "appapi/{controller}/{id}",
|
||||||
|
// defaults: new { id = RouteParameter.Optional }
|
||||||
|
//);
|
||||||
|
config.Routes.MapHttpRoute(
|
||||||
|
name: "DefaultApi",
|
||||||
|
routeTemplate: "api/{controller}/{id}",
|
||||||
|
defaults: new { id = RouteParameter.Optional }
|
||||||
|
);
|
||||||
|
// Configure route for controllers under app_code/appapi
|
||||||
|
//config.Routes.MapHttpRoute(
|
||||||
|
// name: "AppApi",
|
||||||
|
// routeTemplate: "appapi/{controller}/{id}",
|
||||||
|
// defaults: new { controller = "app{controller}", id = RouteParameter.Optional }
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
// WebAPI when dealing with JSON & JavaScript!
|
||||||
|
// Setup json serialization to serialize classes to camel (std. Json format)
|
||||||
|
//var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
|
||||||
|
var formatter = config.Formatters.JsonFormatter;
|
||||||
|
formatter.SerializerSettings.ContractResolver =
|
||||||
|
new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
|
||||||
|
}
|
||||||
|
}
|
||||||
489
web/App_Code/api/accountingController.cs
Normal file
489
web/App_Code/api/accountingController.cs
Normal file
@@ -0,0 +1,489 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static TreeView;
|
||||||
|
|
||||||
|
|
||||||
|
[ezAuthorize]
|
||||||
|
public class accountingController : BaseApiController
|
||||||
|
{
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.accounting> Get()
|
||||||
|
{
|
||||||
|
var list = _db.accountings.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.accounting Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.accountings.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public IEnumerable<Model.accounting> GetPage(int page)
|
||||||
|
{
|
||||||
|
var accounting = _db.accountings.Where(q => q.num < 10).ToList();
|
||||||
|
return accounting;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.accountings.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
var prod2 = prod.accounting_files;
|
||||||
|
if (prod2.Count > 0)
|
||||||
|
{
|
||||||
|
publicFun publicFun = new publicFun();
|
||||||
|
foreach (var item in prod2)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(item.pic1))
|
||||||
|
{
|
||||||
|
publicFun.DeleteFile(Model.accounting.Dir + "/" + item.pic1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.accountings.Remove(prod);
|
||||||
|
_db.SaveChanges(); //執行
|
||||||
|
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Delete, prod.uptime.Value.ToString("yyyy/MM/dd") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/accounting/Delete/{nums}")]
|
||||||
|
public void Delete(string nums)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(nums))
|
||||||
|
{
|
||||||
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
||||||
|
|
||||||
|
var prod = _db.accountings.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
|
if (prod.Count() > 0)
|
||||||
|
{
|
||||||
|
var prod2 = _db.accounting_files.AsEnumerable().Where(q => q.accounting_num.HasValue && getDelItem.Contains(q.accounting_num.Value)).ToList();
|
||||||
|
if (prod2.Count() > 0)
|
||||||
|
{
|
||||||
|
publicFun publicFun = new publicFun();
|
||||||
|
foreach (var item in prod2)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(item.pic1))
|
||||||
|
{
|
||||||
|
publicFun.DeleteFile(Model.accounting.Dir + "/" + item.pic1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.accountings.RemoveRange(prod);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
|
||||||
|
Model.admin_log admin_log = new Model.admin_log();
|
||||||
|
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||||
|
if (admin.isLoign())
|
||||||
|
{
|
||||||
|
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Accounting, (int)Model.admin_log.Status.Delete, admin_log.LogViewBtn(prod.Select(x => x.uptime.Value.ToString("yyyy/MM/dd")).ToList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/accounting/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.accounting q, int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.accountings.AsEnumerable();
|
||||||
|
|
||||||
|
if (q.category.HasValue)
|
||||||
|
qry = qry.Where(o => o.category == q.category.Value);
|
||||||
|
if (q.kind.HasValue)
|
||||||
|
{
|
||||||
|
var _subKinds = new TreeView().subKinds(_db.accounting_kind.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
}).ToList(), q.kind.Value);
|
||||||
|
|
||||||
|
qry = qry.Where(o => o.kind == q.kind.Value || _subKinds.Any(s => s == o.kind));
|
||||||
|
}
|
||||||
|
if (q.kind2.HasValue)
|
||||||
|
{
|
||||||
|
var _subKinds = new TreeView().subKinds(_db.accounting_kind2.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
}).ToList(), q.kind2.Value);
|
||||||
|
|
||||||
|
qry = qry.Where(o => o.kind2 == q.kind2.Value || _subKinds.Any(s => s == o.kind2));
|
||||||
|
}
|
||||||
|
if (q.uptime1.HasValue)
|
||||||
|
qry = qry.Where(o => o.uptime >= q.uptime1.Value);
|
||||||
|
if (q.uptime2.HasValue)
|
||||||
|
qry = qry.Where(o => o.uptime < Convert.ToDateTime(q.uptime2.Value).AddDays(1));
|
||||||
|
if (!string.IsNullOrEmpty(q.activity_num_txt))
|
||||||
|
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(q.activity_num_txt.Trim()));
|
||||||
|
if (!string.IsNullOrEmpty(q.mem_num_txt))
|
||||||
|
qry = qry.Where(o => o.mem_num.HasValue && o.member.u_name.Contains(q.mem_num_txt.Trim()));
|
||||||
|
if (!string.IsNullOrEmpty(q.debtor))
|
||||||
|
qry = qry.Where(o => (o.debtor ?? "").Contains(q.debtor.Trim()));
|
||||||
|
|
||||||
|
|
||||||
|
if (sortBy.Equals("category_Txt"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.category);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.category);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("kindsTxt"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.kind);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.kind);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("kinds2Txt"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.kind2);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.kind2);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("uptime"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.uptime);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.uptime);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("price"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.price);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.price);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("tax"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.tax);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.tax);
|
||||||
|
}
|
||||||
|
else if (sortBy.Equals("total"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.price??0+o.tax??0);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.price ?? 0 + o.tax ?? 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var tdesc = publicFun.enum_desc<Model.accounting.type>();
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
category = x.category,
|
||||||
|
category_Txt = tdesc[x.category ?? 1],
|
||||||
|
kind = x.kind,
|
||||||
|
kindTxt = x.kind.HasValue? x.accounting_kind.kind :"",
|
||||||
|
kindsTxt = x.kind.HasValue ? new TreeView().kindText(_db.accounting_kind.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
kind = o.kind,
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
}).ToList(), x.kind) : "",
|
||||||
|
kind2 = x.kind2,
|
||||||
|
kind2Txt = x.kind2.HasValue? x.accounting_kind2.kind :"",
|
||||||
|
kinds2Txt = x.kind2.HasValue ? new TreeView().kindText(_db.accounting_kind2.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
kind = o.kind,
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
}).ToList(), x.kind2) : "",
|
||||||
|
uptime = x.uptime,
|
||||||
|
price = x.price,
|
||||||
|
tax = x.tax?? 0,
|
||||||
|
total =(x.price ?? 0)+( x.tax?? 0),
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/accounting/GetTitleKindList")]
|
||||||
|
public IHttpActionResult GetTitleKindList([FromBody] Model.ViewModel.accounting_kind q, int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.accounting_kind.AsEnumerable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var qry2 = new TreeView().get_data2(qry.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
kind = o.kind,
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
range = o.range,
|
||||||
|
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry2.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
kind = new TreeView().RptDash(x.Level) + x.kind,
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/accounting/GetAccountKindList")]
|
||||||
|
public IHttpActionResult GetAccountKindList([FromBody] Model.ViewModel.accounting_kind2 q, int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.accounting_kind2.AsEnumerable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
|
if (!string.IsNullOrEmpty(q.record_payment))
|
||||||
|
qry = qry.Where(o => o.record_payment !=null && o.record_payment==q.record_payment);
|
||||||
|
|
||||||
|
var qry2 = new TreeView().get_data2(qry.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
kind = o.kind,
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
range = o.range,
|
||||||
|
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry2.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
kind = new TreeView().RptDash(x.Level) + x.kind,
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/accounting/GetAccFiles")]
|
||||||
|
public IHttpActionResult GetItemFiles([FromBody] Model.accounting_files q, int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
if (q.accounting_num.HasValue && q.accounting_num.Value > 0)
|
||||||
|
{
|
||||||
|
//檢查
|
||||||
|
var qry = _db.accounting_files.AsEnumerable();
|
||||||
|
qry = qry.Where(o => o.accounting_num == q.accounting_num.Value);
|
||||||
|
qry.OrderByDescending(x => x.num);
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
//已有值
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
id = i++,
|
||||||
|
num = x.num,
|
||||||
|
accounting_num = x.accounting_num,
|
||||||
|
pic1 = x.pic1,
|
||||||
|
pic1_name = x.pic1_name,
|
||||||
|
}),
|
||||||
|
count = qry.Count(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/accounting/uploadFiles")]
|
||||||
|
public async Task<IHttpActionResult> uploadFiles()
|
||||||
|
{
|
||||||
|
if (!Request.Content.IsMimeMultipartContent())
|
||||||
|
{
|
||||||
|
return BadRequest("無效的請求。");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string uploadFolder = Path.Combine(HttpContext.Current.Server.MapPath("~/upload"), "accounting");
|
||||||
|
Directory.CreateDirectory(uploadFolder);
|
||||||
|
|
||||||
|
var provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath(Model.accounting.Dir));
|
||||||
|
await Request.Content.ReadAsMultipartAsync(provider);
|
||||||
|
|
||||||
|
if (provider.FileData.Count == 0)
|
||||||
|
{
|
||||||
|
return BadRequest("缺少檔案。");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
string tempFilePath = provider.FileData[0].LocalFileName;
|
||||||
|
string fileName = provider.FileData[0].Headers.ContentDisposition.FileName.Trim('\"');
|
||||||
|
//string Dir = provider.FormData[0];
|
||||||
|
|
||||||
|
//re-name
|
||||||
|
string[] n = Path.GetFileName(fileName).Split('.');
|
||||||
|
fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "." + n[n.Length - 1];
|
||||||
|
|
||||||
|
bool isAllowed = false;
|
||||||
|
string[] type = {
|
||||||
|
"jpg",
|
||||||
|
"jpeg",
|
||||||
|
"png",
|
||||||
|
"pdf"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i <= type.Length - 1; i++)
|
||||||
|
{
|
||||||
|
if (n[n.Length - 1].ToLower() == type[i])
|
||||||
|
{
|
||||||
|
isAllowed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isAllowed)
|
||||||
|
{
|
||||||
|
//計算檔案大小
|
||||||
|
long result = -1;
|
||||||
|
System.Net.WebRequest req = System.Net.WebRequest.Create(tempFilePath);
|
||||||
|
req.Method = "HEAD";
|
||||||
|
using (System.Net.WebResponse resp = req.GetResponse())
|
||||||
|
{
|
||||||
|
if (long.TryParse(resp.Headers.Get("Content-Length"), out long ContentLength))
|
||||||
|
{
|
||||||
|
result = ContentLength;//位元組
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//result / 1024 = kB
|
||||||
|
|
||||||
|
if (result / 1000 / 1000 <= 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
string filePath = Path.Combine(uploadFolder, fileName);
|
||||||
|
File.Move(tempFilePath, filePath);
|
||||||
|
|
||||||
|
return Ok(fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BadRequest("檔案限制 2 MB 以內");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BadRequest("格式不符。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/accounting/SaveFileData")]
|
||||||
|
public IHttpActionResult SaveFileData([FromBody] Model.accounting_files item)
|
||||||
|
{
|
||||||
|
item.reg_time = DateTime.Now;
|
||||||
|
_db.accounting_files.Add(item);
|
||||||
|
_db.SaveChanges();
|
||||||
|
return Ok(item.num);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/accounting/DeleteFilesItem/{id}")]//刪除相關檔案
|
||||||
|
public void DeleteFilesItem(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.accounting_files.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(prod.pic1))
|
||||||
|
{
|
||||||
|
publicFun publicFun = new publicFun();
|
||||||
|
publicFun.DeleteFile(Model.accounting.Dir + "/" + prod.pic1);
|
||||||
|
}
|
||||||
|
_db.accounting_files.Remove(prod);
|
||||||
|
_db.SaveChanges(); //執行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1535
web/App_Code/api/activityController.cs
Normal file
1535
web/App_Code/api/activityController.cs
Normal file
File diff suppressed because it is too large
Load Diff
111
web/App_Code/api/activity_kindController.cs
Normal file
111
web/App_Code/api/activity_kindController.cs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
using static TreeView;
|
||||||
|
|
||||||
|
[ezAuthorize]
|
||||||
|
public class activity_kindController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.actItem_kind> Get()
|
||||||
|
{
|
||||||
|
var list = _db.actItem_kind.OrderBy(q=>q.kind).ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.actItem_kind Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.actItem_kind.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/actItem_kind/count")]
|
||||||
|
public int Count()
|
||||||
|
{
|
||||||
|
var count = _db.actItem_kind.Count();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/actItem_kind/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.actItem_kind q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.actItem_kind.AsEnumerable();
|
||||||
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
|
if (!string.IsNullOrEmpty(q.status))
|
||||||
|
qry = qry.Where(o => o.status.Contains(q.status));
|
||||||
|
//qry = qry.OrderBy(o => o.kind);
|
||||||
|
|
||||||
|
var qry2 = new TreeView().get_data2(qry.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
kind = o.kind,
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
range = o.range,
|
||||||
|
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry2.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
kind = new TreeView().RptDash(x.Level) + x.kind,
|
||||||
|
//status = x.status,
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/actItem_kind/GetAll")]
|
||||||
|
public IHttpActionResult GetAll()
|
||||||
|
{
|
||||||
|
//var list = _db.actItem_kind.OrderBy(q => q.kind).ToList();
|
||||||
|
var list = new TreeView().get_data2(_db.actItem_kind.Select(o => new TreeItem()
|
||||||
|
{
|
||||||
|
kind = o.kind,
|
||||||
|
num = o.num,
|
||||||
|
root = o.root,
|
||||||
|
range = o.range,
|
||||||
|
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
kind = new TreeView().RptDash(x.Level) + x.kind,
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
138
web/App_Code/api/adminUserController.cs
Normal file
138
web/App_Code/api/adminUserController.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
|
||||||
|
// api/adminUser
|
||||||
|
//[ezAuthorize(Roles = "admin")]//群組:*
|
||||||
|
[ezAuthorize]
|
||||||
|
public class adminUserController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.admin> Get()
|
||||||
|
{
|
||||||
|
var list = _db.admins.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Model.admin> Get(int page, int pageSize = 10,
|
||||||
|
string sortBy="", bool sortDesc=false)
|
||||||
|
{
|
||||||
|
var list = _db.admins.OrderBy(o=>o.num).ToPagedList(page, pageSize);
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.admin Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.admins.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
//if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] Model.admin item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] Model.admin item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.admins.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
_db.admins.Remove(prod);
|
||||||
|
_db.SaveChanges();//執行
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/adminUser/count")]
|
||||||
|
public int Count()
|
||||||
|
{
|
||||||
|
var count = _db.admins.Count();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/adminUser/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.admin q, int page, int pageSize = 10,
|
||||||
|
string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.admins.AsEnumerable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.u_id))
|
||||||
|
qry = qry.Where(o => o.u_id.Contains(q.u_id));
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
|
qry = qry.Where(o => o.u_name.Contains(q.u_name));
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(q.power))
|
||||||
|
qry = qry.Where(o => o.power == q.power);
|
||||||
|
|
||||||
|
if(q.removeExist.HasValue && q.removeExist.Value)
|
||||||
|
{
|
||||||
|
if (q.num.HasValue && q.num.Value > 0)
|
||||||
|
{
|
||||||
|
qry = qry.Where(o => (!(from b in _db.members.AsEnumerable()
|
||||||
|
select b.admin_num)
|
||||||
|
.Contains(o.num)) || o.num == Convert.ToInt32(q.num.Value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qry = qry.Where(o => (!(from b in _db.members.AsEnumerable()
|
||||||
|
select b.admin_num)
|
||||||
|
.Contains(o.num)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortBy.Equals("u_id"))
|
||||||
|
{
|
||||||
|
if (sortDesc)
|
||||||
|
qry = qry.OrderByDescending(o => o.u_id);
|
||||||
|
else
|
||||||
|
qry = qry.OrderBy(o => o.u_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
u_id = x.u_id,
|
||||||
|
u_name = x.u_name,
|
||||||
|
power = x.power,
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
67
web/App_Code/api/appellationController.cs
Normal file
67
web/App_Code/api/appellationController.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
|
||||||
|
[ezAuthorize]
|
||||||
|
public class appellationController : BaseApiController
|
||||||
|
{
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.appellation> Get()
|
||||||
|
{
|
||||||
|
var list = _db.appellations.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.appellation Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.appellations.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(string id, [FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/appellation/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.appellation q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.appellations.AsEnumerable();
|
||||||
|
|
||||||
|
|
||||||
|
qry = qry.OrderBy(o => o.num);
|
||||||
|
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
title = x.title,
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
50
web/App_Code/api/authorize/HttpReferrer.cs
Normal file
50
web/App_Code/api/authorize/HttpReferrer.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HttpReferrer https://zh.wikipedia.org/wiki/HTTP%E5%8F%83%E7%85%A7%E4%BD%8D%E5%9D%80
|
||||||
|
/// HTTP參照位址(referer,或HTTP referer)是HTTP表頭的一個欄位,用來表示從哪兒連結到目前的網頁,採用的格式是URL。換句話說,藉著HTTP參照位址,目前的網頁可以檢查訪客從哪裡而來,這也常被用來對付偽造的跨網站請求。
|
||||||
|
/// </summary>
|
||||||
|
public class HttpReferrerAttribute : System.Web.Http.AuthorizeAttribute
|
||||||
|
{
|
||||||
|
public string Url { get; set; }
|
||||||
|
|
||||||
|
public override void OnAuthorization(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
base.OnAuthorization(actionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
base.HandleUnauthorizedRequest(actionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsAuthorized(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
if (actionContext.Request.Headers.Referrer == null) return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string host = HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "/");
|
||||||
|
string referrer = actionContext.Request.Headers.Referrer.AbsoluteUri.Replace(actionContext.Request.Headers.Referrer.AbsolutePath, "/");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(this.Url))
|
||||||
|
{
|
||||||
|
return host == referrer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return actionContext.Request.Headers.Referrer.AbsoluteUri.IndexOf(host + Url) > -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
web/App_Code/api/authorize/MemberIsLogin.cs
Normal file
27
web/App_Code/api/authorize/MemberIsLogin.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// MemberIsLogin 檢查前台會員是否登入
|
||||||
|
/// </summary>
|
||||||
|
public class MemberIsLoginAttribute : System.Web.Http.AuthorizeAttribute
|
||||||
|
{
|
||||||
|
public override void OnAuthorization(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
base.OnAuthorization(actionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
base.HandleUnauthorizedRequest(actionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool IsAuthorized(HttpActionContext actionContext)
|
||||||
|
{
|
||||||
|
//return new ez.data.member().isLogin();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
web/App_Code/api/base/BaseApiController.cs
Normal file
28
web/App_Code/api/base/BaseApiController.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// BaseApiController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class BaseApiController : ApiController
|
||||||
|
{
|
||||||
|
protected ezEntities _db = new ezEntities();
|
||||||
|
//public member.DataInfo MData { get; private set; }
|
||||||
|
//public function f = new function();
|
||||||
|
|
||||||
|
public BaseApiController()
|
||||||
|
{
|
||||||
|
//member member = new member();
|
||||||
|
//if (member.isLogin())
|
||||||
|
//{
|
||||||
|
// this.MData = member.Data;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//Homeblock.HomeBlockCol homeblockItem = new Homeblock.HomeBlockCol();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
262
web/App_Code/api/bedController.cs
Normal file
262
web/App_Code/api/bedController.cs
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
[ezAuthorize]
|
||||||
|
public class bedController : BaseApiController
|
||||||
|
{
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.bed_order> Get()
|
||||||
|
{
|
||||||
|
var list = _db.bed_order.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.bed_order Get(string id)
|
||||||
|
{
|
||||||
|
var item = _db.bed_order.Where(q => q.bed_order_no == id).FirstOrDefault();
|
||||||
|
if (item == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(string id)
|
||||||
|
{
|
||||||
|
var prod = _db.bed_order.AsEnumerable().Where(q => q.bed_order_no == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
//刪除訂單明細
|
||||||
|
_db.bed_order_detail.RemoveRange(prod.bed_order_detail);
|
||||||
|
//var prod2 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_order_no == prod.bed_order_no).ToList();
|
||||||
|
//if (prod2.Count > 0)
|
||||||
|
//{
|
||||||
|
// //查詢結果全部刪除
|
||||||
|
// _db.bed_order_detail.RemoveRange(prod2);
|
||||||
|
// _db.SaveChanges();
|
||||||
|
//}
|
||||||
|
|
||||||
|
_db.bed_order.Remove(prod);
|
||||||
|
_db.SaveChanges();//執行
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly object Locker = new object();
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed/CreateBedList")]
|
||||||
|
public IHttpActionResult CreateBedList([FromBody] Model.pro_order_detail item)
|
||||||
|
{
|
||||||
|
string order_no = "";
|
||||||
|
|
||||||
|
if (item.num > 0)
|
||||||
|
{
|
||||||
|
Model.bed_order chkOrder = _db.bed_order.Where(q => q.order_no == item.order_no && q.o_detail_id == item.num).FirstOrDefault();
|
||||||
|
if (chkOrder == null)
|
||||||
|
{
|
||||||
|
lock (Locker)
|
||||||
|
{
|
||||||
|
order_no = "ED" + DateTime.Now.ToString("yyMMdd");
|
||||||
|
|
||||||
|
var qry = _db.companies.AsEnumerable();
|
||||||
|
var prod = qry.Where(q => q.num == 1).FirstOrDefault();
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(prod.bed_order_no) && prod.bed_order_no.Contains(order_no))
|
||||||
|
{
|
||||||
|
int tmp = Convert.ToInt32(prod.bed_order_no.Replace(order_no, "")) + 1;
|
||||||
|
order_no = order_no + tmp.ToString("0000");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
order_no = order_no + "0001";
|
||||||
|
|
||||||
|
prod.bed_order_no = order_no;
|
||||||
|
_db.SaveChanges();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
order_no = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order_no != "")
|
||||||
|
{
|
||||||
|
//建立掛單表單
|
||||||
|
Model.bed_order order = new Model.bed_order();//新增
|
||||||
|
order.bed_order_no = order_no;
|
||||||
|
order.order_no = item.order_no;
|
||||||
|
order.o_detail_id = item.num;
|
||||||
|
order.keyin1 = "A1"; //預設未入住
|
||||||
|
order.reg_time = DateTime.Now;
|
||||||
|
_db.bed_order.Add(order);
|
||||||
|
|
||||||
|
//建立掛單表單明細 count == item.qty
|
||||||
|
for (int i = 0; i < item.qty.Value; i++)
|
||||||
|
{
|
||||||
|
Model.bed_order_detail detail = new Model.bed_order_detail();//新增
|
||||||
|
detail.bed_order_no = order_no;
|
||||||
|
_db.bed_order_detail.Add(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//check detail qty ?
|
||||||
|
int _needQty = chkOrder.pro_order_detail.qty??0;
|
||||||
|
int _nowQty = chkOrder.bed_order_detail.Count;
|
||||||
|
|
||||||
|
for(int i=0; i< _needQty- _nowQty;i++)
|
||||||
|
{
|
||||||
|
//建立掛單表單明細 count == item.qty
|
||||||
|
Model.bed_order_detail detail = new Model.bed_order_detail();//新增
|
||||||
|
detail.bed_order_no = chkOrder.bed_order_no;
|
||||||
|
_db.bed_order_detail.Add(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
return Ok(); //已建立
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed/GetDetailList")]
|
||||||
|
public IHttpActionResult GetDetailList([FromBody] Model.bed_order q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.bed_order_detail.AsEnumerable();
|
||||||
|
qry = qry.Where(o => o.bed_order_no == q.bed_order_no);
|
||||||
|
|
||||||
|
qry = qry.OrderBy(o => o.checkIn_date ).ThenBy(o => o.num);
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
var tdesc = publicFun.enum_desc<Model.bed_kind.bed_type>();
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
id = i++,
|
||||||
|
num = x.num,
|
||||||
|
u_name = x.bed_order.pro_order_detail.f_num.HasValue? (x.bed_order.pro_order_detail.follower.u_name) :"",
|
||||||
|
sex = x.bed_order.pro_order_detail.f_num.HasValue? x.bed_order.pro_order_detail.follower.sex :"",
|
||||||
|
checkIn_date = x.checkIn_date,
|
||||||
|
|
||||||
|
//bed_kind1 -> column
|
||||||
|
//bed_kind2 -> column
|
||||||
|
//bed_kind -> table
|
||||||
|
//bed_kind3 -> table
|
||||||
|
|
||||||
|
bed_kind1_selected = new //樓層
|
||||||
|
{
|
||||||
|
text = x.bed_kind1.HasValue ? x.bed_kind.kind : "",
|
||||||
|
val = x.bed_kind1.HasValue ? x.bed_kind1.Value : 0,
|
||||||
|
},
|
||||||
|
bed_kind2_selected = new //房號/房名
|
||||||
|
{
|
||||||
|
text = x.bed_kind2.HasValue ? x.bed_kind3.kind : "",
|
||||||
|
val = x.bed_kind2.HasValue ? x.bed_kind2.Value : 0,
|
||||||
|
},
|
||||||
|
bed_kind_detail_id_selected = new //床位編號
|
||||||
|
{
|
||||||
|
text = x.bed_kind_detail_id.HasValue ? x.bed_kind_detail.bed_name : "",
|
||||||
|
val = x.bed_kind_detail_id.HasValue ? x.bed_kind_detail_id.Value : 0,
|
||||||
|
bed_type = x.bed_kind_detail_id.HasValue ? tdesc[x.bed_kind_detail.bed_type ?? 1] : "",
|
||||||
|
},
|
||||||
|
license = x.license,
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed/SaveBedDetail")]
|
||||||
|
public IHttpActionResult SaveActKindDetail([FromBody] Model.bed_order_detail item)
|
||||||
|
{
|
||||||
|
if (item.bed_order_no !="")
|
||||||
|
{
|
||||||
|
if (item.num > 0)
|
||||||
|
{
|
||||||
|
Model.bed_order_detail _detail = _db.bed_order_detail.Where(q => q.num == item.num).FirstOrDefault();//修改
|
||||||
|
if (_detail != null)
|
||||||
|
{
|
||||||
|
if(item.checkIn_date.HasValue) _detail.checkIn_date = item.checkIn_date.Value;
|
||||||
|
if(item.bed_kind1.HasValue) _detail.bed_kind1 = item.bed_kind1.Value;
|
||||||
|
if(item.bed_kind2.HasValue) _detail.bed_kind2 = item.bed_kind2.Value;
|
||||||
|
if(item.bed_kind_detail_id.HasValue) _detail.bed_kind_detail_id = item.bed_kind_detail_id.Value;
|
||||||
|
_detail.license = item.license;
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
var ret = _detail.num;
|
||||||
|
return Ok(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/bed/DeleteBedDetail/{id}")]//刪除detail
|
||||||
|
public void DeleteBedDetail(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.bed_order_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
_db.bed_order_detail.Remove(prod);
|
||||||
|
_db.SaveChanges(); //執行
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
218
web/App_Code/api/bed_kindController.cs
Normal file
218
web/App_Code/api/bed_kindController.cs
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web.Http;
|
||||||
|
using PagedList;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
[ezAuthorize]
|
||||||
|
public class bed_kindController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
// GET api/<controller>
|
||||||
|
public IEnumerable<Model.bed_kind> Get()
|
||||||
|
{
|
||||||
|
var list = _db.bed_kind.ToList();
|
||||||
|
if (list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/5
|
||||||
|
public Model.bed_kind Get(int id)
|
||||||
|
{
|
||||||
|
var item = _db.bed_kind.Where(q => q.num == id).FirstOrDefault();
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST api/<controller>
|
||||||
|
public void Post([FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT api/<controller>/5
|
||||||
|
public void Put(int id, [FromBody] string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE api/<controller>/5
|
||||||
|
public void Delete(int id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/bed_kind/count")]
|
||||||
|
public int Count()
|
||||||
|
{
|
||||||
|
var count = _db.bed_kind.Count();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed_kind/GetList")]
|
||||||
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.bed_kind q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var qry = _db.bed_kind.AsEnumerable();
|
||||||
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
|
if (!string.IsNullOrEmpty(q.sex))
|
||||||
|
qry = qry.Where(o => o.sex == q.sex);
|
||||||
|
if (q.root.HasValue)
|
||||||
|
qry = qry.Where(o => o.root.Value == q.root.Value);
|
||||||
|
qry = qry.OrderBy(o => o.range).ThenBy(o => o.num);
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||||
|
{
|
||||||
|
num = x.num,
|
||||||
|
kind = x.kind,
|
||||||
|
sex = x.sex,
|
||||||
|
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed_kind/GetDetailList")]
|
||||||
|
public IHttpActionResult GetDetailList([FromBody] Model.ViewModel.bed_kind_detail q,
|
||||||
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
|
{
|
||||||
|
var tdesc = publicFun.enum_desc<Model.bed_kind.bed_type>();
|
||||||
|
//var tdesc2 = tdesc.ToArray().Select(x=>x.Value); //[0]單人床,[1]雙人床
|
||||||
|
//var tdesc3 = tdesc.ToArray().Select(x=>x.Key); //[0]1,[1]2
|
||||||
|
var qry = _db.bed_kind_detail.AsEnumerable();
|
||||||
|
if (q.bed_kind_id.HasValue)
|
||||||
|
qry = qry.Where(o => o.bed_kind_id == q.bed_kind_id);
|
||||||
|
if (!string.IsNullOrEmpty(q.bed_name))
|
||||||
|
qry = qry.Where(o => o.bed_name.Contains(q.bed_name));
|
||||||
|
if (q.bed_type.HasValue)
|
||||||
|
qry = qry.Where(o => o.bed_type == q.bed_type);
|
||||||
|
if (!string.IsNullOrEmpty(q.bed_type_txt))
|
||||||
|
{
|
||||||
|
List<string> _bednums = new List<string>();
|
||||||
|
foreach (var ii in tdesc)
|
||||||
|
if(ii.Value.IndexOf(q.bed_type_txt) > -1)
|
||||||
|
|
||||||
|
_bednums.Add(ii.Key.ToString());
|
||||||
|
|
||||||
|
qry = qry.Where(o => _bednums.Contains( o.bed_type.Value.ToString()));
|
||||||
|
}
|
||||||
|
if (q.inTime.HasValue )
|
||||||
|
{
|
||||||
|
//判斷日期沒庫存不能選
|
||||||
|
var bedDt = _db.bed_order_detail.AsEnumerable().Where(f => f.checkIn_date.HasValue && f.checkIn_date ==q.inTime.Value ).Select(f => f.bed_kind_detail_id.ToString());//掛單表單明細
|
||||||
|
qry = qry.Where(o => !bedDt.ToArray().Contains(o.num.ToString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
qry = qry.OrderBy(o => o.bed_name);
|
||||||
|
int i = 1;
|
||||||
|
|
||||||
|
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
||||||
|
var ret = new
|
||||||
|
{
|
||||||
|
list = qry.Select(x => new
|
||||||
|
{
|
||||||
|
id = i++,
|
||||||
|
num = x.num,
|
||||||
|
bed_name = x.bed_name,
|
||||||
|
bed_type = x.bed_type,
|
||||||
|
bed_type_txt = x.bed_type.HasValue? tdesc[x.bed_type ?? 1] : "",
|
||||||
|
demo = x.demo,
|
||||||
|
}),
|
||||||
|
count = qry.Count()
|
||||||
|
|
||||||
|
};
|
||||||
|
return Ok(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed_kind/SaveBedKindDetail")]
|
||||||
|
public IHttpActionResult SaveActKindDetail([FromBody] Model.bed_kind_detail item)
|
||||||
|
{
|
||||||
|
if (item.bed_kind_id > 0)
|
||||||
|
{
|
||||||
|
//if有資料-修改 , else 新增
|
||||||
|
if (item.num > 0)
|
||||||
|
{
|
||||||
|
Model.bed_kind_detail _detail = _db.bed_kind_detail.Where(q => q.num == item.num).FirstOrDefault();//修改
|
||||||
|
if (_detail != null)
|
||||||
|
{
|
||||||
|
_detail.bed_name = item.bed_name;
|
||||||
|
if (item.bed_type.HasValue) { _detail.bed_type = item.bed_type.Value; }
|
||||||
|
else { _detail.bed_type = null; }
|
||||||
|
_detail.demo = item.demo;
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
var ret = _detail.num;
|
||||||
|
return Ok(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Model.bed_kind_detail _detail = new Model.bed_kind_detail();//新增
|
||||||
|
_detail.bed_kind_id = item.bed_kind_id;
|
||||||
|
_detail.bed_name = item.bed_name;
|
||||||
|
if (item.bed_type.HasValue) { _detail.bed_type = item.bed_type.Value; }
|
||||||
|
else { _detail.bed_type = null; }
|
||||||
|
_detail.demo = item.demo;
|
||||||
|
|
||||||
|
_db.bed_kind_detail.Add(_detail);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
var ret = _detail.num;
|
||||||
|
return Ok(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/bed_kind/DeleteBedKindDetail/{id}")]//刪除分類的detail
|
||||||
|
public void DeleteActKindDetail(int id)
|
||||||
|
{
|
||||||
|
var prod = _db.bed_kind_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
|
if (prod != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
//清空掛單資料
|
||||||
|
//way1
|
||||||
|
prod.bed_order_detail.Clear();
|
||||||
|
|
||||||
|
//way2
|
||||||
|
//foreach (var item2 in prod.bed_order_detail)
|
||||||
|
// item2.bed_kind_detail_id = null;
|
||||||
|
|
||||||
|
//way3
|
||||||
|
//var prod2 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_kind_detail_id == prod.num).ToList();
|
||||||
|
//if (prod2.Count > 0)
|
||||||
|
//{
|
||||||
|
// //清空分類
|
||||||
|
// foreach (var item2 in prod2)
|
||||||
|
// item2.bed_kind_detail_id = null;
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
_db.bed_kind_detail.Remove(prod);
|
||||||
|
_db.SaveChanges(); //執行
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user