migrate to new git

This commit is contained in:
2025-08-29 01:27:25 +08:00
parent 946eb9961e
commit af2c152ef6
8623 changed files with 1000453 additions and 1 deletions

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.vs/
.vscode
.git
packages
obj/
*.user
*.log

View File

@@ -1 +1,7 @@
17168ERP New Git
# Read Me
Test
2024
# Path
* Web
* Data

55
data/MEMO250620.txt Normal file
View 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
View 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
View 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: 待繳金額:大額/長期?
---

Binary file not shown.

1
data/SQL/actItem.sql Normal file
View File

@@ -0,0 +1 @@
ALTER TABLE actItem ADD IsDel BIT NOT NULL DEFAULT 0;

1
data/SQL/followers.sql Normal file
View File

@@ -0,0 +1 @@
ALTER TABLE followers ADD IsDel BIT NOT NULL DEFAULT 0;

View 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

View 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
View 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 (王振邦)
明日會議一樣維持1030討論項目如下
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
View 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
View 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/`

View 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清單來追蹤後續的測試和優化工作。現在可以開始測試功能了
您想要先測試哪個部分?或者有什麼需要調整的地方嗎?

View 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
View 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}
]}
```

Binary file not shown.

27
data/shuwen_table.sql Normal file
View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/v2407/desktop.ini Normal file

Binary file not shown.

Binary file not shown.

View 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#
```

View 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#
```

Binary file not shown.

View File

@@ -0,0 +1,4 @@
# 17168 API DOOC
* [信眾API](./appFollowerController.html)
* [報名API](./apporderController.html.html)

Binary file not shown.

Binary file not shown.

View 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")));
}
}
}
}

View 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
}
}

View 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

Binary file not shown.

42
memo.md Normal file
View 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
View 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
View 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, sortExpressionObjectDataSource 控制項會自動傳入,開發人員不用手動撰碼傳值
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
}

View 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);
}
}

View 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();
}

View 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");
}
}
}

View 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
View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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
View 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);
}
}
#>

View 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; }
}
}
}

View 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; }
}
}

View 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
}
}
}

View 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
}
}

View 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
}
}
}

View 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; }
}
}
}

View 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();
}
}

View 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;
}
}
}

View 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
}
}
}
}

View 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;
}
}

View 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>
/// 生成序列化IDprint_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;
}
}
}

View 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"; //圖片上傳位置
}
}

View 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
}
}
}

View 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;
}
}

View 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
}
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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; }
}
}

View 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;
}
}

View 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" }
//);
}
}

View 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名稱
}
}
*/
}

View 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
View 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
View 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
View 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
}
}

View 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)
{
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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();
}
}

View 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(); //執行
}
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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();
}
}

View 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(); //執行
}
}
}

View 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