Compare commits
56 Commits
yiming-250
...
d41ad3e4cc
| Author | SHA1 | Date | |
|---|---|---|---|
| d41ad3e4cc | |||
| ba6e641bac | |||
| 9969417bd8 | |||
| eff3ad778b | |||
| bc1f1422e9 | |||
| 1698b51d19 | |||
| 4e26dd648d | |||
| e20b250944 | |||
| e88821db4b | |||
| 3f63457c5a | |||
| 9a0d5ae700 | |||
| 79b7dd114f | |||
| cd05ad2305 | |||
| 5ae262205c | |||
| 6f5a2e65bd | |||
| 22d283dbe6 | |||
| 3b5d366863 | |||
| c0404b8e70 | |||
| 1a6731e4c6 | |||
| b776b411b4 | |||
| e9f17a5037 | |||
| 05ef2e28f3 | |||
| 90ef949ca4 | |||
| 39c9dd29e1 | |||
| a6aa35176c | |||
| 6a43883d08 | |||
| 7d36d6b0a6 | |||
| 87a2c35300 | |||
| 7d57e292fe | |||
| 6fc82510cc | |||
| 4a36ce9c1c | |||
| 63cab37c87 | |||
| cd1e5c2cd0 | |||
| d7b0f29296 | |||
| 79854a2618 | |||
| 93aaffd3d8 | |||
| 71490b1fac | |||
| c6bd763485 | |||
| ad06b77fae | |||
| af5b1f71fb | |||
| 104f95eaec | |||
| c38dc55dff | |||
| 40da17b414 | |||
| f1e3f555e6 | |||
| 72db7ca928 | |||
| ebad44be71 | |||
| 68f2733530 | |||
| d752a01cc7 | |||
| 03e366c34a | |||
| d4748e415a | |||
| 42e46b4d35 | |||
| 69b9b1bbd1 | |||
| 4419dfff64 | |||
| 636b22849c | |||
| 0b0ddc82bd | |||
| ded24a8446 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ packages
|
|||||||
obj/
|
obj/
|
||||||
*.user
|
*.user
|
||||||
*.log
|
*.log
|
||||||
|
**website.publishproj
|
||||||
Binary file not shown.
BIN
data/SQL/AncestralTabletStatus_script.sql
Normal file
BIN
data/SQL/AncestralTabletStatus_script.sql
Normal file
Binary file not shown.
BIN
data/SQL/guadan_item_insert_script.sql
Normal file
BIN
data/SQL/guadan_item_insert_script.sql
Normal file
Binary file not shown.
Binary file not shown.
BIN
data/SQL/guadan_script_only_data.sql
Normal file
BIN
data/SQL/guadan_script_only_data.sql
Normal file
Binary file not shown.
176
data/SQL/執行此文件.sql
Normal file
176
data/SQL/執行此文件.sql
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
USE [17168erp_t2]
|
||||||
|
GO
|
||||||
|
/****** Object: Table [dbo].[AncestralTabletArea] Script Date: 2025/10/29 下午 01:32:57 ******/
|
||||||
|
SET ANSI_NULLS ON
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON
|
||||||
|
GO
|
||||||
|
CREATE TABLE [dbo].[AncestralTabletArea](
|
||||||
|
[AreaId] [int] IDENTITY(1,1) NOT NULL,
|
||||||
|
[AreaName] [nvarchar](10) NOT NULL,
|
||||||
|
[AreaCode] [nvarchar](20) NOT NULL,
|
||||||
|
[ParentAreaId] [int] NULL,
|
||||||
|
[AreaType] [nvarchar](10) NULL,
|
||||||
|
[Price] [int] NULL,
|
||||||
|
[SortOrder] [int] NULL,
|
||||||
|
[IsDisabled] [bit] NOT NULL,
|
||||||
|
[Description] [nvarchar](200) NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[AreaId] 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]
|
||||||
|
GO
|
||||||
|
/****** Object: Table [dbo].[AncestralTabletPosition] Script Date: 2025/10/29 下午 01:32:57 ******/
|
||||||
|
SET ANSI_NULLS ON
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON
|
||||||
|
GO
|
||||||
|
CREATE TABLE [dbo].[AncestralTabletPosition](
|
||||||
|
[PositionId] [int] IDENTITY(1,1) NOT NULL,
|
||||||
|
[AreaId] [int] NOT NULL,
|
||||||
|
[PositionCode] [nvarchar](20) NOT NULL,
|
||||||
|
[PositionName] [nvarchar](50) NULL,
|
||||||
|
[Price] [int] NULL,
|
||||||
|
[StatusCode] [nvarchar](20) NULL,
|
||||||
|
[Description] [nvarchar](200) NULL,
|
||||||
|
[RowNo] [int] NULL,
|
||||||
|
[ColumnNo] [int] NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[PositionId] 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],
|
||||||
|
CONSTRAINT [UQ_Position_Area_Code] UNIQUE NONCLUSTERED
|
||||||
|
(
|
||||||
|
[AreaId] ASC,
|
||||||
|
[PositionCode] 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]
|
||||||
|
GO
|
||||||
|
/****** Object: Table [dbo].[AncestralTabletPositionRecord] Script Date: 2025/10/29 下午 01:32:57 ******/
|
||||||
|
SET ANSI_NULLS ON
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON
|
||||||
|
GO
|
||||||
|
CREATE TABLE [dbo].[AncestralTabletPositionRecord](
|
||||||
|
[RecordId] [int] IDENTITY(1,1) NOT NULL,
|
||||||
|
[RegistrantCode] [nvarchar](20) NOT NULL,
|
||||||
|
[NPTitle] [nvarchar](30) NULL,
|
||||||
|
[NPStandDate] [date] NOT NULL,
|
||||||
|
[NPYangShang] [nvarchar](20) NULL,
|
||||||
|
[WPContent] [nvarchar](1000) NULL,
|
||||||
|
[CreatedAt] [datetime] NOT NULL,
|
||||||
|
[UpdatedAt] [datetime] NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[RecordId] 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]
|
||||||
|
GO
|
||||||
|
/****** Object: Table [dbo].[AncestralTabletRegistrant] Script Date: 2025/10/29 下午 01:32:57 ******/
|
||||||
|
SET ANSI_NULLS ON
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON
|
||||||
|
GO
|
||||||
|
CREATE TABLE [dbo].[AncestralTabletRegistrant](
|
||||||
|
[RegistrantCode] [nvarchar](20) NOT NULL,
|
||||||
|
[Name] [nvarchar](50) NOT NULL,
|
||||||
|
[Phone] [nvarchar](50) NULL,
|
||||||
|
[Address] [nvarchar](60) NULL,
|
||||||
|
[RegisterDate] [date] NOT NULL,
|
||||||
|
[Price] [int] NULL,
|
||||||
|
[PositionId] [int] NULL,
|
||||||
|
[StartDate] [date] NOT NULL,
|
||||||
|
[EndDate] [date] NULL,
|
||||||
|
[IsLongTerm] [bit] NOT NULL,
|
||||||
|
[IsActive] [bit] NOT NULL,
|
||||||
|
[CreatedAt] [datetime] NOT NULL,
|
||||||
|
[UpdatedAt] [datetime] NULL,
|
||||||
|
[IsEnd] [bit] NOT NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[RegistrantCode] 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]
|
||||||
|
GO
|
||||||
|
/****** Object: Table [dbo].[AncestralTabletStatus] Script Date: 2025/10/29 下午 01:32:57 ******/
|
||||||
|
SET ANSI_NULLS ON
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON
|
||||||
|
GO
|
||||||
|
CREATE TABLE [dbo].[AncestralTabletStatus](
|
||||||
|
[StatusCode] [nvarchar](20) NOT NULL,
|
||||||
|
[StatusName] [nvarchar](20) NOT NULL,
|
||||||
|
[StatusType] [nvarchar](20) NOT NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[StatusCode] 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]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletArea] ADD DEFAULT ((0)) FOR [IsDisabled]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletPositionRecord] ADD DEFAULT (getdate()) FOR [CreatedAt]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletRegistrant] ADD DEFAULT ((0)) FOR [IsLongTerm]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletRegistrant] ADD DEFAULT ((1)) FOR [IsActive]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletRegistrant] ADD DEFAULT (getdate()) FOR [CreatedAt]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletRegistrant] ADD DEFAULT ((0)) FOR [IsEnd]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletArea] WITH CHECK ADD CONSTRAINT [FK_AncestralTabletArea_Parent] FOREIGN KEY([ParentAreaId])
|
||||||
|
REFERENCES [dbo].[AncestralTabletArea] ([AreaId])
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletArea] CHECK CONSTRAINT [FK_AncestralTabletArea_Parent]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletPosition] WITH CHECK ADD CONSTRAINT [FK_Position_Area] FOREIGN KEY([AreaId])
|
||||||
|
REFERENCES [dbo].[AncestralTabletArea] ([AreaId])
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletPosition] CHECK CONSTRAINT [FK_Position_Area]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletPosition] WITH CHECK ADD CONSTRAINT [FK_Position_Status] FOREIGN KEY([StatusCode])
|
||||||
|
REFERENCES [dbo].[AncestralTabletStatus] ([StatusCode])
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletPosition] CHECK CONSTRAINT [FK_Position_Status]
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletPositionRecord] WITH CHECK ADD FOREIGN KEY([RegistrantCode])
|
||||||
|
REFERENCES [dbo].[AncestralTabletRegistrant] ([RegistrantCode])
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletRegistrant] WITH CHECK ADD CONSTRAINT [FK_Registrant_Position] FOREIGN KEY([PositionId])
|
||||||
|
REFERENCES [dbo].[AncestralTabletPosition] ([PositionId])
|
||||||
|
GO
|
||||||
|
ALTER TABLE [dbo].[AncestralTabletRegistrant] CHECK CONSTRAINT [FK_Registrant_Position]
|
||||||
|
GO
|
||||||
|
|
||||||
|
INSERT [dbo].[AncestralTabletStatus] ([StatusCode], [StatusName], [StatusType]) VALUES (N'available', N'可用', N'Position')
|
||||||
|
INSERT [dbo].[AncestralTabletStatus] ([StatusCode], [StatusName], [StatusType]) VALUES (N'maintenance', N'維護中', N'Position')
|
||||||
|
INSERT [dbo].[AncestralTabletStatus] ([StatusCode], [StatusName], [StatusType]) VALUES (N'used', N'已使用', N'Position')
|
||||||
|
GO
|
||||||
|
-- 1. 如果不存在 OrderUuid 栏位,则新增
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys.columns
|
||||||
|
WHERE Name = N'OrderUuid'
|
||||||
|
AND Object_ID = Object_ID(N'dbo.GuaDanOrderGuest')
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE [dbo].[GuaDanOrderGuest]
|
||||||
|
ADD [OrderUuid] UNIQUEIDENTIFIER NULL;
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 2. 如果不存在 FK_GuaDanOrderGuest_Order 外键,则新增
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM sys.foreign_keys
|
||||||
|
WHERE Name = N'FK_GuaDanOrderGuest_Order'
|
||||||
|
AND parent_object_id = OBJECT_ID(N'dbo.GuaDanOrderGuest')
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE [dbo].[GuaDanOrderGuest]
|
||||||
|
ADD CONSTRAINT [FK_GuaDanOrderGuest_Order]
|
||||||
|
FOREIGN KEY ([OrderUuid]) REFERENCES [dbo].[GuaDanOrder] ([Uuid]);
|
||||||
|
END
|
||||||
|
GO
|
||||||
BIN
data/SQL/完整資料結構(僅限本地,不包含其它分支更新)_script_1029.sql
Normal file
BIN
data/SQL/完整資料結構(僅限本地,不包含其它分支更新)_script_1029.sql
Normal file
Binary file not shown.
26
data/memo/report-view.md
Normal file
26
data/memo/report-view.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# 報表系統規劃
|
||||||
|
為每場活動(法會)建立報名到舉辦過程的報表,
|
||||||
|
要涵蓋以下面向的統計分析資訊
|
||||||
|
|
||||||
|
- 以單一場法會為核心
|
||||||
|
- 時間面向: 當前狀況, 指定期間狀況
|
||||||
|
- 維度:
|
||||||
|
- 信眾: 報名數量, 金額, 收款狀態
|
||||||
|
- 牌位型態(活動品項表): 報名數量, 金額, 收款狀態
|
||||||
|
- 收款狀態: 己收/未收 統計明細
|
||||||
|
|
||||||
|
## 法會報表系統查詢規劃**
|
||||||
|
|
||||||
|
### 1. 核心基礎 VIEW
|
||||||
|
1. `vw_activity_registration_base` - 單一活動的完整報名基礎資料
|
||||||
|
2. `vw_activity_payment_detail` - 單一活動的完整收款明細資料
|
||||||
|
### 2. 統計分析 VIEW
|
||||||
|
3. `vw_activity_follower_statistics` - 按信眾統計報名情況
|
||||||
|
4. `vw_activity_item_statistics` - 按品項統計報名情況
|
||||||
|
5. `vw_activity_payment_status` - 收款狀態統計分析
|
||||||
|
### 3. 時間維度分析 VIEW
|
||||||
|
6. `vw_activity_registration_trend` - 按日期統計報名趨勢
|
||||||
|
7. `vw_activity_payment_trend` - 按收款日期統計收款趨勢
|
||||||
|
### 4. 詳細查詢 VIEW
|
||||||
|
8. `vw_activity_unpaid_detail` - 未收款明細清單
|
||||||
|
9. `vw_activity_transfer_reconciliation` - 匯款對帳明細
|
||||||
252
data/memo/report-view.sql
Normal file
252
data/memo/report-view.sql
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
drop view if exists vw_activity_registration_base;
|
||||||
|
drop view if exists vw_activity_payment_detail;
|
||||||
|
drop view if exists vw_activity_follower_statistics;
|
||||||
|
drop view if exists vw_activity_item_statistics;
|
||||||
|
drop view if exists vw_activity_payment_status;
|
||||||
|
drop view if exists vw_activity_registration_trend;
|
||||||
|
drop view if exists vw_activity_payment_trend;
|
||||||
|
drop view if exists vw_activity_unpaid_detail;
|
||||||
|
drop view if exists vw_activity_transfer_reconciliation;
|
||||||
|
GO
|
||||||
|
-- 1. 法會報名基礎資料 VIEW
|
||||||
|
CREATE VIEW vw_activity_registration_base AS
|
||||||
|
SELECT
|
||||||
|
a.num AS 活動編號,
|
||||||
|
a.subject AS 活動名稱,
|
||||||
|
a.startDate_solar AS 活動開始日期,
|
||||||
|
a.endDate_solar AS 活動結束日期,
|
||||||
|
po.order_no AS 報名單號,
|
||||||
|
po.up_time AS 報名日期,
|
||||||
|
po.keyin1 AS 報名狀態,
|
||||||
|
f.num AS 信眾編號,
|
||||||
|
f.f_number AS 信眾代號,
|
||||||
|
f.u_name AS 信眾姓名,
|
||||||
|
f.phone AS 聯絡電話,
|
||||||
|
f.identity_type AS 身分別,
|
||||||
|
f.country AS 國籍,
|
||||||
|
pod.num AS 報名明細編號,
|
||||||
|
ai.num AS 品項編號,
|
||||||
|
ai.subject AS 品項名稱,
|
||||||
|
ai.category AS 品項分類,
|
||||||
|
pod.price AS 單價,
|
||||||
|
pod.qty AS 數量,
|
||||||
|
pod.price * pod.qty AS 應繳金額,
|
||||||
|
pod.pay AS 已收金額,
|
||||||
|
(pod.price * pod.qty - ISNULL(pod.pay, 0)) AS 未收金額,
|
||||||
|
pod.pay_date AS 付款期限,
|
||||||
|
pod.start_date AS 開始日期,
|
||||||
|
pod.due_date AS 到期日期,
|
||||||
|
pod.keyin1 AS 明細狀態,
|
||||||
|
pod.demo AS 備註
|
||||||
|
FROM activity a
|
||||||
|
INNER JOIN pro_order po ON a.num = po.activity_num
|
||||||
|
INNER JOIN followers f ON po.f_num = f.num
|
||||||
|
INNER JOIN pro_order_detail pod ON po.order_no = pod.order_no
|
||||||
|
INNER JOIN actItem ai ON pod.actItem_num = ai.num;
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 2. 收款明細基礎資料 VIEW
|
||||||
|
CREATE VIEW vw_activity_payment_detail AS
|
||||||
|
SELECT
|
||||||
|
a.num AS 活動編號,
|
||||||
|
a.subject AS 活動名稱,
|
||||||
|
po.order_no AS 報名單號,
|
||||||
|
f.u_name AS 信眾姓名,
|
||||||
|
pod.num AS 報名明細編號,
|
||||||
|
ai.subject AS 品項名稱,
|
||||||
|
por.num AS 收款記錄編號,
|
||||||
|
por.price AS 收款金額,
|
||||||
|
por.payment AS 付款方式,
|
||||||
|
por.pay_date AS 收款日期,
|
||||||
|
por.organization AS 收款機構,
|
||||||
|
por.bank_code AS 銀行代碼,
|
||||||
|
por.transfer_id AS 匯款記錄ID,
|
||||||
|
por.reconcile_memo AS 對帳備註,
|
||||||
|
tr.name AS 匯款人姓名,
|
||||||
|
tr.phone AS 匯款人電話,
|
||||||
|
tr.amount AS 匯款金額,
|
||||||
|
tr.check_date AS 入帳日期,
|
||||||
|
tr.status AS 匯款狀態
|
||||||
|
FROM activity a
|
||||||
|
INNER JOIN pro_order po ON a.num = po.activity_num
|
||||||
|
INNER JOIN followers f ON po.f_num = f.num
|
||||||
|
INNER JOIN pro_order_detail pod ON po.order_no = pod.order_no
|
||||||
|
INNER JOIN actItem ai ON pod.actItem_num = ai.num
|
||||||
|
LEFT JOIN pro_order_record por ON pod.num = por.detail_num
|
||||||
|
LEFT JOIN transfer_register tr ON por.transfer_id = tr.id;
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 3. 信眾報名統計 VIEW
|
||||||
|
CREATE VIEW vw_activity_follower_statistics AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
信眾編號,
|
||||||
|
信眾代號,
|
||||||
|
信眾姓名,
|
||||||
|
聯絡電話,
|
||||||
|
身分別,
|
||||||
|
國籍,
|
||||||
|
COUNT(DISTINCT 報名單號) AS 報名單數,
|
||||||
|
COUNT(報名明細編號) AS 報名品項數,
|
||||||
|
SUM(應繳金額) AS 應繳總金額,
|
||||||
|
SUM(已收金額) AS 已收總金額,
|
||||||
|
SUM(未收金額) AS 未收總金額,
|
||||||
|
CASE
|
||||||
|
WHEN SUM(未收金額) = 0 THEN '已繳清'
|
||||||
|
WHEN SUM(未收金額) = SUM(應繳金額) THEN '未繳'
|
||||||
|
ELSE '部分繳款'
|
||||||
|
END AS 繳款狀態
|
||||||
|
FROM vw_activity_registration_base
|
||||||
|
GROUP BY 活動編號, 活動名稱, 信眾編號, 信眾代號, 信眾姓名, 聯絡電話, 身分別, 國籍;
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 4. 品項報名統計 VIEW
|
||||||
|
CREATE VIEW vw_activity_item_statistics AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
品項編號,
|
||||||
|
品項名稱,
|
||||||
|
品項分類,
|
||||||
|
單價,
|
||||||
|
COUNT(報名明細編號) AS 報名數量,
|
||||||
|
SUM(數量) AS 總數量,
|
||||||
|
SUM(應繳金額) AS 應繳總金額,
|
||||||
|
SUM(已收金額) AS 已收總金額,
|
||||||
|
SUM(未收金額) AS 未收總金額,
|
||||||
|
CASE
|
||||||
|
WHEN COUNT(報名明細編號) = 0 THEN 0
|
||||||
|
ELSE AVG(已收金額)
|
||||||
|
END AS 平均已收金額,
|
||||||
|
CASE
|
||||||
|
WHEN SUM(未收金額) = 0 THEN '已收齊'
|
||||||
|
WHEN SUM(未收金額) = SUM(應繳金額) THEN '未收款'
|
||||||
|
ELSE '部分收款'
|
||||||
|
END AS 收款狀態
|
||||||
|
FROM vw_activity_registration_base
|
||||||
|
GROUP BY 活動編號, 活動名稱, 品項編號, 品項名稱, 品項分類, 單價;
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 5. 收款狀態統計 VIEW
|
||||||
|
CREATE VIEW vw_activity_payment_status AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
'總計' AS 統計項目,
|
||||||
|
COUNT(DISTINCT 報名單號) AS 報名單數,
|
||||||
|
COUNT(報名明細編號) AS 報名品項數,
|
||||||
|
SUM(應繳金額) AS 應繳總金額,
|
||||||
|
SUM(已收金額) AS 已收總金額,
|
||||||
|
SUM(未收金額) AS 未收總金額,
|
||||||
|
CASE
|
||||||
|
WHEN SUM(應繳金額) = 0 THEN 0
|
||||||
|
ELSE ROUND(SUM(已收金額) * 100.0 / SUM(應繳金額), 2)
|
||||||
|
END AS 收款率
|
||||||
|
FROM vw_activity_registration_base
|
||||||
|
GROUP BY 活動編號, 活動名稱
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
CASE
|
||||||
|
WHEN 未收金額 = 0 THEN '已繳清'
|
||||||
|
WHEN 未收金額 = 應繳金額 THEN '未繳'
|
||||||
|
ELSE '部分繳款'
|
||||||
|
END AS 統計項目,
|
||||||
|
COUNT(DISTINCT 報名單號) AS 報名單數,
|
||||||
|
COUNT(報名明細編號) AS 報名品項數,
|
||||||
|
SUM(應繳金額) AS 應繳總金額,
|
||||||
|
SUM(已收金額) AS 已收總金額,
|
||||||
|
SUM(未收金額) AS 未收總金額,
|
||||||
|
CASE
|
||||||
|
WHEN SUM(應繳金額) = 0 THEN 0
|
||||||
|
ELSE ROUND(SUM(已收金額) * 100.0 / SUM(應繳金額), 2)
|
||||||
|
END AS 收款率
|
||||||
|
FROM vw_activity_registration_base
|
||||||
|
GROUP BY 活動編號, 活動名稱,
|
||||||
|
CASE
|
||||||
|
WHEN 未收金額 = 0 THEN '已繳清'
|
||||||
|
WHEN 未收金額 = 應繳金額 THEN '未繳'
|
||||||
|
ELSE '部分繳款'
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 6. 報名趨勢分析 VIEW
|
||||||
|
CREATE VIEW vw_activity_registration_trend AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
CAST(報名日期 AS DATE) AS 報名日期,
|
||||||
|
COUNT(DISTINCT 報名單號) AS 當日報名單數,
|
||||||
|
COUNT(報名明細編號) AS 當日報名品項數,
|
||||||
|
SUM(應繳金額) AS 當日應繳金額,
|
||||||
|
SUM(已收金額) AS 當日已收金額,
|
||||||
|
SUM(未收金額) AS 當日未收金額
|
||||||
|
FROM vw_activity_registration_base
|
||||||
|
GROUP BY 活動編號, 活動名稱, CAST(報名日期 AS DATE);
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 7. 收款趨勢分析 VIEW
|
||||||
|
CREATE VIEW vw_activity_payment_trend AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
CAST(收款日期 AS DATE) AS 收款日期,
|
||||||
|
COUNT(收款記錄編號) AS 當日收款筆數,
|
||||||
|
SUM(收款金額) AS 當日收款金額,
|
||||||
|
COUNT(DISTINCT 報名單號) AS 當日收款單數,
|
||||||
|
CASE
|
||||||
|
WHEN COUNT(收款記錄編號) = 0 THEN 0
|
||||||
|
ELSE AVG(收款金額)
|
||||||
|
END AS 平均收款金額
|
||||||
|
FROM vw_activity_payment_detail
|
||||||
|
WHERE 收款日期 IS NOT NULL
|
||||||
|
GROUP BY 活動編號, 活動名稱, CAST(收款日期 AS DATE);
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 8. 未收款明細 VIEW
|
||||||
|
CREATE VIEW vw_activity_unpaid_detail AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
報名單號,
|
||||||
|
信眾姓名,
|
||||||
|
聯絡電話,
|
||||||
|
品項名稱,
|
||||||
|
應繳金額,
|
||||||
|
已收金額,
|
||||||
|
未收金額,
|
||||||
|
付款期限,
|
||||||
|
CASE
|
||||||
|
WHEN 付款期限 < GETDATE() THEN '已逾期'
|
||||||
|
WHEN 付款期限 <= DATEADD(DAY, 3, GETDATE()) THEN '即將到期'
|
||||||
|
ELSE '未到期'
|
||||||
|
END AS 到期狀態
|
||||||
|
FROM vw_activity_registration_base
|
||||||
|
WHERE 未收金額 > 0;
|
||||||
|
GO
|
||||||
|
|
||||||
|
-- 9. 匯款對帳明細 VIEW
|
||||||
|
CREATE VIEW vw_activity_transfer_reconciliation AS
|
||||||
|
SELECT
|
||||||
|
活動編號,
|
||||||
|
活動名稱,
|
||||||
|
匯款記錄ID,
|
||||||
|
匯款人姓名,
|
||||||
|
匯款人電話,
|
||||||
|
匯款金額,
|
||||||
|
入帳日期,
|
||||||
|
匯款狀態,
|
||||||
|
COUNT(收款記錄編號) AS 關聯收款筆數,
|
||||||
|
SUM(收款金額) AS 已對帳金額,
|
||||||
|
CASE
|
||||||
|
WHEN SUM(收款金額) IS NULL THEN 匯款金額
|
||||||
|
ELSE 匯款金額 - SUM(收款金額)
|
||||||
|
END AS 剩餘金額
|
||||||
|
FROM vw_activity_payment_detail
|
||||||
|
WHERE 匯款記錄ID IS NOT NULL
|
||||||
|
GROUP BY 活動編號, 活動名稱, 匯款記錄ID, 匯款人姓名, 匯款人電話, 匯款金額, 入帳日期, 匯款狀態;
|
||||||
|
GO
|
||||||
484
data/memo/report.md
Normal file
484
data/memo/report.md
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
# 相關頁面
|
||||||
|
## 基本功能
|
||||||
|
admin/order/index.aspx
|
||||||
|
admin/activity/index.aspx
|
||||||
|
admin/follower/index.aspx
|
||||||
|
admin/activity/index2.aspx
|
||||||
|
admin/transfer/index.aspx
|
||||||
|
|
||||||
|
## 入帳沖帳
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\balance_reconcile_query.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\balance_reconcile.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\group_reconcile.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\index.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\personal_reconcile.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\register.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\verify_order_record_query.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\verify.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\verify1.aspx
|
||||||
|
D:\dev\ez\17168erp\git_17888\web\admin\transfer\verify2.aspx
|
||||||
|
|
||||||
|
# 資料結構
|
||||||
|
|
||||||
|
## 📊 17168ERP 系統使用的資料表架構
|
||||||
|
|
||||||
|
### 🎯 **核心業務資料表**
|
||||||
|
|
||||||
|
#### 1. **報名管理系統** (`order/index.aspx`)
|
||||||
|
**主要資料表:**
|
||||||
|
- **`pro_order`** - 報名主表
|
||||||
|
- `order_no` (單號)、`up_time` (報名日期)、`keyin1` (單據狀態)
|
||||||
|
- `f_num` (信眾編號)、`activity_num` (活動編號)、`phone` (聯絡電話)
|
||||||
|
|
||||||
|
- **`pro_order_detail`** - 報名明細表
|
||||||
|
- `order_no` (關聯主表)、`actItem_num` (活動品項)、`f_num` (報名者)
|
||||||
|
- `price` (金額)、`qty` (數量)、`pay` (已收金額)、`pay_date` (付款期限)
|
||||||
|
|
||||||
|
- **`activity`** - 活動主表
|
||||||
|
- `num`、`subject` (活動名稱)、`start_date` (開始日期)、`end_date` (結束日期)
|
||||||
|
|
||||||
|
- **`actItem`** - 活動品項表
|
||||||
|
- `num`、`subject` (品項名稱)、`category` (品項分類)
|
||||||
|
|
||||||
|
#### 2. **信眾管理系統** (`follower/index.aspx`)
|
||||||
|
**主要資料表:**
|
||||||
|
- **`followers`** - 信眾基本資料表
|
||||||
|
- `num`、`f_number` (信眾編號)、`u_name` (姓名)、`sex` (性別)
|
||||||
|
- `identity_type` (身分別)、`birthday` (生日)、`phone` (電話)
|
||||||
|
- `address` (地址)、`country` (國籍)、`refugedate` (皈依日期)
|
||||||
|
|
||||||
|
- **`countries`** - 國籍資料表
|
||||||
|
- `ID`、`name_zh` (中文名稱)、`name_en` (英文名稱)
|
||||||
|
|
||||||
|
#### 3. **活動管理系統** (`activity/index.aspx`)
|
||||||
|
**主要資料表:**
|
||||||
|
- **`activity`** - 活動主表
|
||||||
|
- `num`、`subject` (活動名稱)、`startDate_solar` (國曆開始日期)
|
||||||
|
- `startDate_lunar` (農曆開始日期)、`endDate_solar` (國曆結束日期)
|
||||||
|
- `endDate_lunar` (農曆結束日期)、`dueDate` (報名截止日期)
|
||||||
|
|
||||||
|
- **`activity_kind`** - 活動分類表
|
||||||
|
- `num`、`subject` (分類名稱)
|
||||||
|
|
||||||
|
#### 4. **匯款沖帳系統** (`transfer/index.aspx`)
|
||||||
|
**主要資料表:**
|
||||||
|
- **`transfer_register`** - 匯款登錄表
|
||||||
|
- `id`、`name` (匯款人姓名)、`phone` (電話)、`amount` (匯款金額)
|
||||||
|
- `pay_type` (付款方式)、`account_last5` (帳號後五碼)
|
||||||
|
- `proof_img` (匯款證明圖片)、`status` (狀態)
|
||||||
|
- `f_num_match` (配對信眾編號)、`check_amount` (核對金額)
|
||||||
|
|
||||||
|
- **`accounting`** - 會計帳務表
|
||||||
|
- `num`、`category` (科目分類)、`kind` (收支類型)
|
||||||
|
- `price` (金額)、`debtor` (債務人)、`activity_num` (關聯活動)
|
||||||
|
|
||||||
|
- **`pro_order_record`** - 報名收款記錄表
|
||||||
|
- `num`、`detail_num` (關聯明細)、`price` (金額)、`payment` (付款方式)
|
||||||
|
- `pay_date` (收款日期)、`transfer_id` (關聯匯款記錄)
|
||||||
|
|
||||||
|
### 🔗 **關聯關係**
|
||||||
|
|
||||||
|
#### **主要外鍵關聯:**
|
||||||
|
```
|
||||||
|
pro_order → followers (f_num)
|
||||||
|
pro_order → activity (activity_num)
|
||||||
|
pro_order_detail → pro_order (order_no)
|
||||||
|
pro_order_detail → actItem (actItem_num)
|
||||||
|
pro_order_detail → followers (f_num)
|
||||||
|
transfer_register → followers (f_num)
|
||||||
|
transfer_register → activity (activity_num)
|
||||||
|
accounting → pro_order_detail (pro_order_detail_num)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📈 **資料表統計**
|
||||||
|
|
||||||
|
| 功能模組 | 主要資料表數量 | 核心業務表 |
|
||||||
|
|---------|-------------|-----------|
|
||||||
|
| 報名管理 | 5個 | `pro_order`, `pro_order_detail` |
|
||||||
|
| 信眾管理 | 2個 | `followers`, `countries` |
|
||||||
|
| 活動管理 | 2個 | `activity`, `activity_kind` |
|
||||||
|
| 匯款沖帳 | 3個 | `transfer_register`, `accounting`, `pro_order_record` |
|
||||||
|
|
||||||
|
### 🎯 **系統特色**
|
||||||
|
|
||||||
|
1. **模組化設計**:每個功能模組都有獨立的資料表群組
|
||||||
|
2. **關聯完整**:透過外鍵建立完整的業務關聯關係
|
||||||
|
3. **狀態管理**:多個狀態表支援複雜的業務流程
|
||||||
|
4. **UUID設計**:新模組採用UUID作為主鍵,提升擴展性
|
||||||
|
5. **軟刪除機制**:使用`IsDeleted`欄位而非物理刪除
|
||||||
|
|
||||||
|
這個資料表架構支援了一個完整的宗教活動管理ERP系統,涵蓋了從信眾管理、活動報名、床位安排到財務沖帳的全流程管理。
|
||||||
|
|
||||||
|
# 入帳沖帳
|
||||||
|
```
|
||||||
|
報名者匯款 → transfer_register (status: pending)
|
||||||
|
↓
|
||||||
|
出納核對身份 → transfer_register (status: verified, f_num_match)
|
||||||
|
↓
|
||||||
|
出納核對金額 → transfer_register (status: confirmed, check_amount)
|
||||||
|
↓
|
||||||
|
會計個人沖帳 → pro_order_record + accounting
|
||||||
|
↓
|
||||||
|
會計共同沖帳 → pro_order_record + accounting (多筆)
|
||||||
|
↓
|
||||||
|
會計餘額核銷 → transfer_register (remain_amount)
|
||||||
|
↓
|
||||||
|
查詢統計報表 → 各表關聯查詢
|
||||||
|
```
|
||||||
|
|
||||||
|
# DB SCHEMA
|
||||||
|
我來為您使用 Mermaid 語法繪製 17168ERP 系統的 ER 圖,展示各個資料表之間的關聯關係。
|
||||||
|
|
||||||
|
|
||||||
|
[1 tool called]
|
||||||
|
|
||||||
|
我無法直接創建 Mermaid 圖表,但我可以為您提供完整的 Mermaid ER 圖代碼,您可以複製到支援 Mermaid 的工具中查看(如 GitHub、GitLab、或 Mermaid Live Editor)。
|
||||||
|
|
||||||
|
以下是 17168ERP 系統的 ER 圖 Mermaid 代碼:
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
erDiagram
|
||||||
|
%% 信眾管理系統
|
||||||
|
followers {
|
||||||
|
int num PK
|
||||||
|
string f_number
|
||||||
|
string u_name
|
||||||
|
string sex
|
||||||
|
int identity_type
|
||||||
|
datetime birthday
|
||||||
|
string phone
|
||||||
|
string email
|
||||||
|
datetime refugedate
|
||||||
|
string refuge_name
|
||||||
|
string address
|
||||||
|
string demo
|
||||||
|
int leader
|
||||||
|
string socialid1
|
||||||
|
string socialid2
|
||||||
|
string tab
|
||||||
|
string contactor
|
||||||
|
string contactor_phone
|
||||||
|
string blood
|
||||||
|
string customize_data
|
||||||
|
}
|
||||||
|
|
||||||
|
countries {
|
||||||
|
int ID PK
|
||||||
|
string name_zh
|
||||||
|
string name_en
|
||||||
|
string range
|
||||||
|
}
|
||||||
|
|
||||||
|
%% 活動管理系統
|
||||||
|
activity {
|
||||||
|
int num PK
|
||||||
|
string subject
|
||||||
|
datetime startDate_solar
|
||||||
|
datetime startDate_lunar
|
||||||
|
datetime endDate_solar
|
||||||
|
datetime endDate_lunar
|
||||||
|
datetime dueDate
|
||||||
|
int kind
|
||||||
|
string demo
|
||||||
|
string customize_data
|
||||||
|
}
|
||||||
|
|
||||||
|
activity_kind {
|
||||||
|
int num PK
|
||||||
|
string subject
|
||||||
|
string demo
|
||||||
|
}
|
||||||
|
|
||||||
|
actItem {
|
||||||
|
int num PK
|
||||||
|
int activity_num FK
|
||||||
|
string subject
|
||||||
|
int category
|
||||||
|
string demo
|
||||||
|
string customize_data
|
||||||
|
}
|
||||||
|
|
||||||
|
%% 報名管理系統
|
||||||
|
pro_order {
|
||||||
|
string order_no PK
|
||||||
|
datetime up_time
|
||||||
|
datetime reg_time
|
||||||
|
string keyin1
|
||||||
|
int f_num FK
|
||||||
|
string phone
|
||||||
|
int activity_num FK
|
||||||
|
string address
|
||||||
|
string demo
|
||||||
|
string customize_data
|
||||||
|
int introducer FK
|
||||||
|
boolean send_receipt
|
||||||
|
string receipt_title
|
||||||
|
}
|
||||||
|
|
||||||
|
pro_order_detail {
|
||||||
|
int num PK
|
||||||
|
string order_no FK
|
||||||
|
int actItem_num FK
|
||||||
|
int f_num FK
|
||||||
|
string f_num_tablet
|
||||||
|
string address
|
||||||
|
int from_id FK
|
||||||
|
string from_id_tablet
|
||||||
|
datetime due_date
|
||||||
|
int bed_type
|
||||||
|
float price
|
||||||
|
int qty
|
||||||
|
datetime start_date
|
||||||
|
datetime extend_date
|
||||||
|
float pay
|
||||||
|
datetime pay_date
|
||||||
|
int keyin1
|
||||||
|
string demo
|
||||||
|
datetime UpdateTime
|
||||||
|
}
|
||||||
|
|
||||||
|
%% 匯款沖帳系統
|
||||||
|
transfer_register {
|
||||||
|
int id PK
|
||||||
|
int activity_num FK
|
||||||
|
string name
|
||||||
|
string phone
|
||||||
|
string pay_type
|
||||||
|
string account_last5
|
||||||
|
decimal amount
|
||||||
|
string pay_mode
|
||||||
|
string note
|
||||||
|
string proof_img
|
||||||
|
string status
|
||||||
|
datetime create_time
|
||||||
|
int f_num_match FK
|
||||||
|
int f_num FK
|
||||||
|
int acc_num
|
||||||
|
datetime check_date
|
||||||
|
decimal check_amount
|
||||||
|
string check_memo
|
||||||
|
string check_status
|
||||||
|
int acc_kind
|
||||||
|
int member_num
|
||||||
|
datetime verify_time
|
||||||
|
string verify_note
|
||||||
|
string draft
|
||||||
|
decimal remain_amount
|
||||||
|
int balance_act_item FK
|
||||||
|
int balance_pro_order_detail FK
|
||||||
|
}
|
||||||
|
|
||||||
|
accounting {
|
||||||
|
int num PK
|
||||||
|
datetime uptime
|
||||||
|
int category
|
||||||
|
int kind
|
||||||
|
int kind2
|
||||||
|
float price
|
||||||
|
float tax
|
||||||
|
string demo
|
||||||
|
int mem_num
|
||||||
|
string debtor
|
||||||
|
int activity_num FK
|
||||||
|
string excerpt
|
||||||
|
datetime reg_time
|
||||||
|
int pro_order_detail_num FK
|
||||||
|
}
|
||||||
|
|
||||||
|
pro_order_record {
|
||||||
|
int num PK
|
||||||
|
int detail_num FK
|
||||||
|
float price
|
||||||
|
int payment
|
||||||
|
datetime reg_time
|
||||||
|
datetime pay_date
|
||||||
|
string organization
|
||||||
|
string bank_code
|
||||||
|
int transfer_id FK
|
||||||
|
string reconcile_memo
|
||||||
|
}
|
||||||
|
|
||||||
|
%% 區域床位管理系統
|
||||||
|
Region {
|
||||||
|
Guid Uuid PK
|
||||||
|
string Name
|
||||||
|
boolean Gender
|
||||||
|
boolean IsActive
|
||||||
|
boolean IsDeleted
|
||||||
|
}
|
||||||
|
|
||||||
|
Room {
|
||||||
|
Guid Uuid PK
|
||||||
|
string Name
|
||||||
|
boolean Gender
|
||||||
|
int BedCount
|
||||||
|
boolean IsActive
|
||||||
|
datetime CreatedAt
|
||||||
|
datetime UpdatedAt
|
||||||
|
boolean IsDeleted
|
||||||
|
Guid RegionUuid FK
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionRoomBed {
|
||||||
|
Guid Uuid PK
|
||||||
|
string Name
|
||||||
|
boolean IsActive
|
||||||
|
boolean Gender
|
||||||
|
boolean IsDeleted
|
||||||
|
Guid RoomUuid FK
|
||||||
|
string StatusCode FK
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionRoomBedStatus {
|
||||||
|
string Code PK
|
||||||
|
string Name
|
||||||
|
string Description
|
||||||
|
int Category
|
||||||
|
boolean IsDeleted
|
||||||
|
}
|
||||||
|
|
||||||
|
%% 掛單管理系統
|
||||||
|
GuaDanOrder {
|
||||||
|
Guid Uuid PK
|
||||||
|
datetime StartDate
|
||||||
|
datetime EndDate
|
||||||
|
int CreateUser FK
|
||||||
|
datetime CreatedAt
|
||||||
|
datetime UpdatedAt
|
||||||
|
string Notes
|
||||||
|
string GuaDanOrderNo
|
||||||
|
int BookerFollowerNum FK
|
||||||
|
string BookerName
|
||||||
|
string BookerPhone
|
||||||
|
boolean IsDeleted
|
||||||
|
int ActivityNum FK
|
||||||
|
boolean IsCancel
|
||||||
|
}
|
||||||
|
|
||||||
|
GuaDanOrderGuest {
|
||||||
|
Guid Uuid PK
|
||||||
|
string GuaDanOrderNo FK
|
||||||
|
int FollowerNum FK
|
||||||
|
boolean IsDeleted
|
||||||
|
Guid RoomUuid FK
|
||||||
|
Guid BedUuid FK
|
||||||
|
datetime CheckInAt
|
||||||
|
datetime CheckOutAt
|
||||||
|
string StatusCode FK
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionAndRoomAndBedSchedule {
|
||||||
|
Guid Uuid PK
|
||||||
|
Guid TargetUuid FK
|
||||||
|
string GuaDanOrderNo
|
||||||
|
date ScheduleDate
|
||||||
|
boolean IsCancel
|
||||||
|
boolean IsDeleted
|
||||||
|
int UseType
|
||||||
|
string Title
|
||||||
|
string Description
|
||||||
|
string CreatedBy
|
||||||
|
datetime CreatedAt
|
||||||
|
Guid GuaDanOrderGuestUuid FK
|
||||||
|
}
|
||||||
|
|
||||||
|
%% 關聯關係
|
||||||
|
followers ||--o{ pro_order : "報名"
|
||||||
|
followers ||--o{ pro_order_detail : "報名明細"
|
||||||
|
followers ||--o{ transfer_register : "匯款人"
|
||||||
|
followers ||--o{ GuaDanOrderGuest : "掛單客人"
|
||||||
|
|
||||||
|
activity ||--o{ pro_order : "活動報名"
|
||||||
|
activity ||--o{ actItem : "活動品項"
|
||||||
|
activity ||--o{ transfer_register : "活動匯款"
|
||||||
|
activity ||--o{ GuaDanOrder : "掛單活動"
|
||||||
|
|
||||||
|
pro_order ||--o{ pro_order_detail : "報名明細"
|
||||||
|
pro_order ||--o{ pro_order_record : "收款記錄"
|
||||||
|
|
||||||
|
pro_order_detail ||--o{ pro_order_record : "明細收款"
|
||||||
|
pro_order_detail ||--o{ accounting : "會計分錄"
|
||||||
|
pro_order_detail ||--o{ transfer_register : "沖帳明細"
|
||||||
|
|
||||||
|
transfer_register ||--o{ pro_order_record : "匯款記錄"
|
||||||
|
transfer_register ||--o{ accounting : "會計記錄"
|
||||||
|
|
||||||
|
Region ||--o{ Room : "區域房間"
|
||||||
|
Room ||--o{ RegionRoomBed : "房間床位"
|
||||||
|
RegionRoomBedStatus ||--o{ RegionRoomBed : "床位狀態"
|
||||||
|
RegionRoomBedStatus ||--o{ GuaDanOrderGuest : "客人狀態"
|
||||||
|
|
||||||
|
GuaDanOrder ||--o{ GuaDanOrderGuest : "掛單客人"
|
||||||
|
GuaDanOrderGuest ||--o{ RegionAndRoomAndBedSchedule : "床位排程"
|
||||||
|
|
||||||
|
countries ||--o{ followers : "國籍"
|
||||||
|
activity_kind ||--o{ activity : "活動分類"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 **ER 圖說明**
|
||||||
|
|
||||||
|
### **主要實體群組:**
|
||||||
|
|
||||||
|
1. **信眾管理群組**
|
||||||
|
- `followers` (信眾基本資料)
|
||||||
|
- `countries` (國籍資料)
|
||||||
|
|
||||||
|
2. **活動管理群組**
|
||||||
|
- `activity` (活動主表)
|
||||||
|
- `activity_kind` (活動分類)
|
||||||
|
- `actItem` (活動品項)
|
||||||
|
|
||||||
|
3. **報名管理群組**
|
||||||
|
- `pro_order` (報名主表)
|
||||||
|
- `pro_order_detail` (報名明細)
|
||||||
|
|
||||||
|
4. **財務管理群組**
|
||||||
|
- `transfer_register` (匯款登錄)
|
||||||
|
- `accounting` (會計帳務)
|
||||||
|
- `pro_order_record` (收款記錄)
|
||||||
|
|
||||||
|
5. **床位管理群組**
|
||||||
|
- `Region` (區域)
|
||||||
|
- `Room` (房間)
|
||||||
|
- `RegionRoomBed` (床位)
|
||||||
|
- `RegionRoomBedStatus` (床位狀態)
|
||||||
|
|
||||||
|
6. **掛單管理群組**
|
||||||
|
- `GuaDanOrder` (掛單主表)
|
||||||
|
- `GuaDanOrderGuest` (掛單客人)
|
||||||
|
- `RegionAndRoomAndBedSchedule` (床位排程)
|
||||||
|
|
||||||
|
### **關鍵關聯關係:**
|
||||||
|
|
||||||
|
- **一對多關係**:使用 `||--o{` 表示
|
||||||
|
- **外鍵關聯**:FK 標記顯示主要的外鍵關聯
|
||||||
|
- **業務流程**:從信眾報名 → 匯款 → 沖帳 → 床位安排的完整流程
|
||||||
|
|
||||||
|
您可以将這個 Mermaid 代碼複製到 [Mermaid Live Editor](https://mermaid.live/) 或其他支援 Mermaid 的工具中查看完整的 ER 圖表。
|
||||||
|
|
||||||
|
---
|
||||||
|
# 報表系統規劃
|
||||||
|
為每場活動(法會)建立報名到舉辦過程的報表,
|
||||||
|
要涵蓋以下面向的統計分析資訊
|
||||||
|
|
||||||
|
- 以單一場法會為核心
|
||||||
|
- 時間面向: 當前狀況, 指定期間狀況
|
||||||
|
- 維度:
|
||||||
|
- 信眾: 報名數量, 金額, 收款狀態
|
||||||
|
- 牌位型態(活動品項表): 報名數量, 金額, 收款狀態
|
||||||
|
- 收款狀態: 己收/未收 統計明細
|
||||||
|
|
||||||
|
## 執行方式:
|
||||||
|
- 類似excel, 詳細資料->pivot table
|
||||||
|
- 先建立一個(或數個)最核心的sql view, 包含各項:報名資料, 收款明細
|
||||||
|
- 先以單一活動編號為固定FILTER : activity.num=59
|
||||||
|
- 再依不同面向, 建立第二級的sql view
|
||||||
|
- 再人工將以上:第一, 第二級的SQL VIEW, 以EXCEL查詢, 做資料分析/整理
|
||||||
|
- 相關英文欄名, 在VIEW中以中文別名顯示
|
||||||
|
|
||||||
|
## 相關SQL VIEW
|
||||||
|
- (查詢清單)
|
||||||
|
### (查詢)
|
||||||
|
(說明)
|
||||||
|
```sql
|
||||||
|
```
|
||||||
11
data/memo/新增 文字文件.md
Normal file
11
data/memo/新增 文字文件.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
資料字典:
|
||||||
|
USE [17168erp_t]
|
||||||
|
GO
|
||||||
|
INSERT [dbo].[AncestralTabletStatus] ([StatusCode], [StatusName], [StatusType]) VALUES (N'available', N'可用', N'Position')
|
||||||
|
INSERT [dbo].[AncestralTabletStatus] ([StatusCode], [StatusName], [StatusType]) VALUES (N'maintenance', N'維護中', N'Position')
|
||||||
|
INSERT [dbo].[AncestralTabletStatus] ([StatusCode], [StatusName], [StatusType]) VALUES (N'used', N'已使用', N'Position')
|
||||||
|
GO
|
||||||
|
代碼中會用到上面表中的狀態,所以必須在該表中插入上面的數據
|
||||||
|
AncestralTabletStatus_script.sql文件中的表是神祖牌位功能模組需要用到的表,再運行之前需要先執行該文件
|
||||||
|
|
||||||
|
執行AncestralTabletStatus_script.sql後要把在item表中新增的URL權限添加到相應的管理員帳號
|
||||||
BIN
data/查詢範例.xlsx
Normal file
BIN
data/查詢範例.xlsx
Normal file
Binary file not shown.
BIN
data/神主牌管理系統資料字典設計.docx
Normal file
BIN
data/神主牌管理系統資料字典設計.docx
Normal file
Binary file not shown.
12
review_report.txt
Normal file
12
review_report.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
═══════════════════════════════════════════════════════════════
|
||||||
|
🔍 AsEnumerable/AsQueryable/ToList 完整 REVIEW
|
||||||
|
═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
檢查範圍:Batch 1-3 所有已修改文件
|
||||||
|
檢查標準:
|
||||||
|
✅ 最佳選擇 - 性能和可讀性都最優
|
||||||
|
⚠️ 可優化 - 可以進一步優化
|
||||||
|
❌ 需修正 - 存在明顯問題
|
||||||
|
|
||||||
|
═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
1
tyme4net/tyme4net
Submodule
1
tyme4net/tyme4net
Submodule
Submodule tyme4net/tyme4net added at 9ee8f71dac
33
web/App_Code/GuaDanStatusCode.cs
Normal file
33
web/App_Code/GuaDanStatusCode.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GuaDanStatusCode 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public static class GuaDanStatusCode
|
||||||
|
{
|
||||||
|
public static class Bed
|
||||||
|
{
|
||||||
|
public const string Empty = "101"; // 空床:床位可分配
|
||||||
|
public const string Occupied = "102"; // 占用中:床位已有人使用
|
||||||
|
public const string Repair = "103"; // 維修停用:床位維修或不可使用
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Room
|
||||||
|
{
|
||||||
|
public const string Empty = "301"; // 空房:房間所有床位皆為空
|
||||||
|
public const string Partly = "302"; // 部分入住:房間有人,但仍有空床
|
||||||
|
public const string Full = "303"; // 已滿:房間所有床位皆已入住
|
||||||
|
public const string Repair = "304"; // 維修停用:房間維修或不可使用
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Guadan
|
||||||
|
{
|
||||||
|
public const string Booked = "401"; // 預訂成功:默認就是預訂成功狀態
|
||||||
|
public const string CheckedIn = "402"; // 已入住:已辦理入住
|
||||||
|
public const string CheckedOut = "403"; // 已退房
|
||||||
|
public const string Cancelled = "404"; // 已取消:取消後的狀態,不是取消的動作
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <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>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -74,7 +74,6 @@ namespace Model
|
|||||||
public virtual DbSet<stock_reason> stock_reason { get; set; }
|
public virtual DbSet<stock_reason> stock_reason { get; set; }
|
||||||
public virtual DbSet<supplier> suppliers { get; set; }
|
public virtual DbSet<supplier> suppliers { get; set; }
|
||||||
public virtual DbSet<supplier_kind> supplier_kind { 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<act_bom> act_bom { get; set; }
|
||||||
public virtual DbSet<family_members> family_members { get; set; }
|
public virtual DbSet<family_members> family_members { get; set; }
|
||||||
public virtual DbSet<PostCity> PostCitiy { get; set; }
|
public virtual DbSet<PostCity> PostCitiy { get; set; }
|
||||||
@@ -90,6 +89,11 @@ namespace Model
|
|||||||
public virtual DbSet<RegionRoomBedStatus> RegionRoomBedStatus { get; set; }
|
public virtual DbSet<RegionRoomBedStatus> RegionRoomBedStatus { get; set; }
|
||||||
public virtual DbSet<RegionType> RegionType { get; set; }
|
public virtual DbSet<RegionType> RegionType { get; set; }
|
||||||
public virtual DbSet<Room> Room { get; set; }
|
public virtual DbSet<Room> Room { get; set; }
|
||||||
|
public virtual DbSet<AncestralTabletArea> AncestralTabletArea { get; set; }
|
||||||
|
public virtual DbSet<AncestralTabletPosition> AncestralTabletPosition { get; set; }
|
||||||
|
public virtual DbSet<AncestralTabletPositionRecord> AncestralTabletPositionRecord { get; set; }
|
||||||
|
public virtual DbSet<AncestralTabletRegistrant> AncestralTabletRegistrant { get; set; }
|
||||||
|
public virtual DbSet<AncestralTabletStatus> AncestralTabletStatus { get; set; }
|
||||||
|
|
||||||
public virtual int pager_eztrust(Nullable<int> startRowIndex, Nullable<int> pageSize, string tableName, string columnName, string sqlWhere, string orderBy, ObjectParameter rowCount)
|
public virtual int pager_eztrust(Nullable<int> startRowIndex, Nullable<int> pageSize, string tableName, string columnName, string sqlWhere, string orderBy, ObjectParameter rowCount)
|
||||||
{
|
{
|
||||||
|
|||||||
18
web/App_Code/Model/Model.Designer.cs
generated
18
web/App_Code/Model/Model.Designer.cs
generated
@@ -1,10 +1,10 @@
|
|||||||
// T4 code generation is enabled for model 'D:\dev\ez\17168erp\git_17888\web\App_Code\Model\Model.edmx'.
|
// 已啟用模型 'D:\17168erp_new_git\17168ERP\web\App_Code\Model\Model.edmx' 的 T4 程式碼產生。
|
||||||
// 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
|
//變更為 [舊版 ObjectContext]。當模型在設計工具中開啟時,這個屬性便可
|
||||||
// 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
|
//尚未選擇要使用的 Entity Framework 版本。若要為您的模型產生內容類別和
|
||||||
// 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...'.
|
//項目]。
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <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>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -441,7 +441,7 @@ namespace Model
|
|||||||
{
|
{
|
||||||
this.members = new HashSet<member>();
|
this.members = new HashSet<member>();
|
||||||
this.news = new HashSet<news>();
|
this.news = new HashSet<news>();
|
||||||
this.GuaDanOrders = new HashSet<GuaDanOrder>();
|
this.GuaDanOrder = new HashSet<GuaDanOrder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int num { get; set; }
|
public int num { get; set; }
|
||||||
@@ -477,7 +477,7 @@ namespace Model
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<news> news { get; set; }
|
public virtual ICollection<news> news { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<GuaDanOrder> GuaDanOrders { get; set; }
|
public virtual ICollection<GuaDanOrder> GuaDanOrder { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -523,6 +523,139 @@ namespace Model
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class AncestralTabletArea
|
||||||
|
{
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public AncestralTabletArea()
|
||||||
|
{
|
||||||
|
this.AncestralTabletArea1 = new HashSet<AncestralTabletArea>();
|
||||||
|
this.AncestralTabletPosition = new HashSet<AncestralTabletPosition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
public string AreaName { get; set; }
|
||||||
|
public string AreaCode { get; set; }
|
||||||
|
public Nullable<int> ParentAreaId { get; set; }
|
||||||
|
public string AreaType { get; set; }
|
||||||
|
public Nullable<int> Price { get; set; }
|
||||||
|
public Nullable<int> SortOrder { get; set; }
|
||||||
|
public bool IsDisabled { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<AncestralTabletArea> AncestralTabletArea1 { get; set; }
|
||||||
|
public virtual AncestralTabletArea AncestralTabletArea2 { get; set; }
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<AncestralTabletPosition> AncestralTabletPosition { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class AncestralTabletPosition
|
||||||
|
{
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public AncestralTabletPosition()
|
||||||
|
{
|
||||||
|
this.AncestralTabletRegistrant = new HashSet<AncestralTabletRegistrant>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int PositionId { get; set; }
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
public string PositionCode { get; set; }
|
||||||
|
public string PositionName { get; set; }
|
||||||
|
public Nullable<int> Price { get; set; }
|
||||||
|
public string StatusCode { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public Nullable<int> RowNo { get; set; }
|
||||||
|
public Nullable<int> ColumnNo { get; set; }
|
||||||
|
|
||||||
|
public virtual AncestralTabletArea AncestralTabletArea { get; set; }
|
||||||
|
public virtual AncestralTabletStatus AncestralTabletStatus { get; set; }
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<AncestralTabletRegistrant> AncestralTabletRegistrant { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class AncestralTabletPositionRecord
|
||||||
|
{
|
||||||
|
public int RecordId { get; set; }
|
||||||
|
public string RegistrantCode { get; set; }
|
||||||
|
public string NPTitle { get; set; }
|
||||||
|
public System.DateTime NPStandDate { get; set; }
|
||||||
|
public string NPYangShang { get; set; }
|
||||||
|
public string WPContent { get; set; }
|
||||||
|
public System.DateTime CreatedAt { get; set; }
|
||||||
|
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
||||||
|
|
||||||
|
public virtual AncestralTabletRegistrant AncestralTabletRegistrant { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class AncestralTabletRegistrant
|
||||||
|
{
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public AncestralTabletRegistrant()
|
||||||
|
{
|
||||||
|
this.AncestralTabletPositionRecord = new HashSet<AncestralTabletPositionRecord>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string RegistrantCode { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Phone { get; set; }
|
||||||
|
public string Address { get; set; }
|
||||||
|
public System.DateTime RegisterDate { get; set; }
|
||||||
|
public Nullable<int> Price { get; set; }
|
||||||
|
public Nullable<int> PositionId { get; set; }
|
||||||
|
public System.DateTime StartDate { get; set; }
|
||||||
|
public Nullable<System.DateTime> EndDate { get; set; }
|
||||||
|
public bool IsLongTerm { get; set; }
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
public System.DateTime CreatedAt { get; set; }
|
||||||
|
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
||||||
|
public bool IsEnd { get; set; }
|
||||||
|
|
||||||
|
public virtual AncestralTabletPosition AncestralTabletPosition { get; set; }
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<AncestralTabletPositionRecord> AncestralTabletPositionRecord { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public partial class AncestralTabletStatus
|
||||||
|
{
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public AncestralTabletStatus()
|
||||||
|
{
|
||||||
|
this.AncestralTabletPosition = new HashSet<AncestralTabletPosition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string StatusCode { get; set; }
|
||||||
|
public string StatusName { get; set; }
|
||||||
|
public string StatusType { get; set; }
|
||||||
|
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<AncestralTabletPosition> AncestralTabletPosition { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public partial class appellation
|
public partial class appellation
|
||||||
{
|
{
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
@@ -768,8 +901,8 @@ namespace Model
|
|||||||
this.family_members = new HashSet<family_members>();
|
this.family_members = new HashSet<family_members>();
|
||||||
this.transfer_register = new HashSet<transfer_register>();
|
this.transfer_register = new HashSet<transfer_register>();
|
||||||
this.transfer_register1 = new HashSet<transfer_register>();
|
this.transfer_register1 = new HashSet<transfer_register>();
|
||||||
this.GuaDanOrders = new HashSet<GuaDanOrder>();
|
this.GuaDanOrder = new HashSet<GuaDanOrder>();
|
||||||
this.GuaDanOrderGuests = new HashSet<GuaDanOrderGuest>();
|
this.GuaDanOrderGuest = new HashSet<GuaDanOrderGuest>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int num { get; set; }
|
public int num { get; set; }
|
||||||
@@ -830,9 +963,9 @@ namespace Model
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<transfer_register> transfer_register1 { get; set; }
|
public virtual ICollection<transfer_register> transfer_register1 { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<GuaDanOrder> GuaDanOrders { get; set; }
|
public virtual ICollection<GuaDanOrder> GuaDanOrder { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuests { get; set; }
|
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -857,6 +990,12 @@ namespace Model
|
|||||||
|
|
||||||
public partial class GuaDanOrder
|
public partial class GuaDanOrder
|
||||||
{
|
{
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public GuaDanOrder()
|
||||||
|
{
|
||||||
|
this.GuaDanOrderGuest = new HashSet<GuaDanOrderGuest>();
|
||||||
|
}
|
||||||
|
|
||||||
public Nullable<System.DateTime> StartDate { get; set; }
|
public Nullable<System.DateTime> StartDate { get; set; }
|
||||||
public Nullable<System.DateTime> EndDate { get; set; }
|
public Nullable<System.DateTime> EndDate { get; set; }
|
||||||
public Nullable<int> CreateUser { get; set; }
|
public Nullable<int> CreateUser { get; set; }
|
||||||
@@ -869,9 +1008,13 @@ namespace Model
|
|||||||
public string BookerPhone { get; set; }
|
public string BookerPhone { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public System.Guid Uuid { get; set; }
|
public System.Guid Uuid { get; set; }
|
||||||
|
public Nullable<int> ActivityNum { get; set; }
|
||||||
|
public bool IsCancel { get; set; }
|
||||||
|
|
||||||
public virtual admin admin { get; set; }
|
public virtual admin admin { get; set; }
|
||||||
public virtual follower follower { get; set; }
|
public virtual follower followers { get; set; }
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -881,6 +1024,12 @@ namespace Model
|
|||||||
|
|
||||||
public partial class GuaDanOrderGuest
|
public partial class GuaDanOrderGuest
|
||||||
{
|
{
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
public GuaDanOrderGuest()
|
||||||
|
{
|
||||||
|
this.RegionAndRoomAndBedSchedule = new HashSet<RegionAndRoomAndBedSchedule>();
|
||||||
|
}
|
||||||
|
|
||||||
public string GuaDanOrderNo { get; set; }
|
public string GuaDanOrderNo { get; set; }
|
||||||
public Nullable<int> FollowerNum { get; set; }
|
public Nullable<int> FollowerNum { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
@@ -889,12 +1038,16 @@ namespace Model
|
|||||||
public Nullable<System.Guid> BedUuid { get; set; }
|
public Nullable<System.Guid> BedUuid { get; set; }
|
||||||
public Nullable<System.DateTime> CheckInAt { get; set; }
|
public Nullable<System.DateTime> CheckInAt { get; set; }
|
||||||
public Nullable<System.DateTime> CheckOutAt { get; set; }
|
public Nullable<System.DateTime> CheckOutAt { get; set; }
|
||||||
public Nullable<System.Guid> statusUuid { get; set; }
|
public string StatusCode { get; set; }
|
||||||
|
public Nullable<System.Guid> OrderUuid { get; set; }
|
||||||
|
|
||||||
public virtual follower follower { get; set; }
|
public virtual follower followers { get; set; }
|
||||||
public virtual RegionRoomBed RegionRoomBed { get; set; }
|
public virtual RegionRoomBed RegionRoomBed { get; set; }
|
||||||
public virtual Room Room { get; set; }
|
public virtual Room Room { get; set; }
|
||||||
public virtual RegionRoomBedStatus RegionRoomBedStatus { get; set; }
|
public virtual RegionRoomBedStatus RegionRoomBedStatus { get; set; }
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
|
public virtual ICollection<RegionAndRoomAndBedSchedule> RegionAndRoomAndBedSchedule { get; set; }
|
||||||
|
public virtual GuaDanOrder GuaDanOrder { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -1393,7 +1546,10 @@ namespace Model
|
|||||||
public Nullable<System.Guid> TargetUuid { get; set; }
|
public Nullable<System.Guid> TargetUuid { get; set; }
|
||||||
public string GuaDanOrderNo { get; set; }
|
public string GuaDanOrderNo { get; set; }
|
||||||
public Nullable<System.DateTime> ScheduleDate { get; set; }
|
public Nullable<System.DateTime> ScheduleDate { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsCancel { get; set; }
|
||||||
|
public Nullable<System.Guid> GuaDanOrderGuestUuid { get; set; }
|
||||||
|
|
||||||
|
public virtual GuaDanOrderGuest GuaDanOrderGuest { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -1406,7 +1562,7 @@ namespace Model
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
public RegionRoomBed()
|
public RegionRoomBed()
|
||||||
{
|
{
|
||||||
this.GuaDanOrderGuests = new HashSet<GuaDanOrderGuest>();
|
this.GuaDanOrderGuest = new HashSet<GuaDanOrderGuest>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
@@ -1415,12 +1571,12 @@ namespace Model
|
|||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public System.Guid Uuid { get; set; }
|
public System.Guid Uuid { get; set; }
|
||||||
public System.Guid RoomUuid { get; set; }
|
public System.Guid RoomUuid { get; set; }
|
||||||
public Nullable<System.Guid> StatusUuid { get; set; }
|
public string StatusCode { get; set; }
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuests { get; set; }
|
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
|
||||||
public virtual RegionRoomBedStatus RegionRoomBedStatus { get; set; }
|
|
||||||
public virtual Room Room { get; set; }
|
public virtual Room Room { get; set; }
|
||||||
|
public virtual RegionRoomBedStatus RegionRoomBedStatus { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -1433,8 +1589,8 @@ namespace Model
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
public RegionRoomBedStatus()
|
public RegionRoomBedStatus()
|
||||||
{
|
{
|
||||||
this.GuaDanOrderGuests = new HashSet<GuaDanOrderGuest>();
|
this.GuaDanOrderGuest = new HashSet<GuaDanOrderGuest>();
|
||||||
this.RegionRoomBeds = new HashSet<RegionRoomBed>();
|
this.RegionRoomBed = new HashSet<RegionRoomBed>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
@@ -1442,12 +1598,11 @@ namespace Model
|
|||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public Nullable<int> Category { get; set; }
|
public Nullable<int> Category { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public System.Guid Uuid { get; set; }
|
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuests { get; set; }
|
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<RegionRoomBed> RegionRoomBeds { get; set; }
|
public virtual ICollection<RegionRoomBed> RegionRoomBed { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -1460,7 +1615,7 @@ namespace Model
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
public RegionType()
|
public RegionType()
|
||||||
{
|
{
|
||||||
this.Regions = new HashSet<Region>();
|
this.Region = new HashSet<Region>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
@@ -1471,7 +1626,7 @@ namespace Model
|
|||||||
public System.Guid Uuid { get; set; }
|
public System.Guid Uuid { get; set; }
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<Region> Regions { get; set; }
|
public virtual ICollection<Region> Region { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace Model
|
namespace Model
|
||||||
@@ -1484,7 +1639,7 @@ namespace Model
|
|||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
public Room()
|
public Room()
|
||||||
{
|
{
|
||||||
this.GuaDanOrderGuests = new HashSet<GuaDanOrderGuest>();
|
this.GuaDanOrderGuest = new HashSet<GuaDanOrderGuest>();
|
||||||
this.RegionRoomBed = new HashSet<RegionRoomBed>();
|
this.RegionRoomBed = new HashSet<RegionRoomBed>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1499,7 +1654,7 @@ namespace Model
|
|||||||
public System.Guid RegionUuid { get; set; }
|
public System.Guid RegionUuid { get; set; }
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuests { get; set; }
|
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
|
||||||
public virtual Region Region { get; set; }
|
public virtual Region Region { get; set; }
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||||
public virtual ICollection<RegionRoomBed> RegionRoomBed { get; set; }
|
public virtual ICollection<RegionRoomBed> RegionRoomBed { get; set; }
|
||||||
@@ -1685,20 +1840,6 @@ namespace Model
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public partial class sysdiagram
|
|
||||||
{
|
|
||||||
public string name { get; set; }
|
|
||||||
public int principal_id { get; set; }
|
|
||||||
public int diagram_id { get; set; }
|
|
||||||
public Nullable<int> version { get; set; }
|
|
||||||
public byte[] definition { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
namespace Model
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
public partial class transfer_register
|
public partial class transfer_register
|
||||||
{
|
{
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,6 @@
|
|||||||
<EntityTypeShape EntityType="Model.stock_reason" Width="1.5" PointX="14.25" PointY="33.625" 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" 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.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_kind" ManuallyRouted="false" />
|
||||||
<AssociationConnector Association="Model.FK_accounting_accounting_kind2" ManuallyRouted="false" />
|
<AssociationConnector Association="Model.FK_accounting_accounting_kind2" ManuallyRouted="false" />
|
||||||
<AssociationConnector Association="Model.FK_accounting_activity" ManuallyRouted="false" />
|
<AssociationConnector Association="Model.FK_accounting_activity" ManuallyRouted="false" />
|
||||||
@@ -131,26 +130,38 @@
|
|||||||
<AssociationConnector Association="Model.FK_transfer_register_actItem" />
|
<AssociationConnector Association="Model.FK_transfer_register_actItem" />
|
||||||
<AssociationConnector Association="Model.FK_transfer_register_pro_order_detail" />
|
<AssociationConnector Association="Model.FK_transfer_register_pro_order_detail" />
|
||||||
<AssociationConnector Association="Model.FK_pro_order_record_transfer_register" />
|
<AssociationConnector Association="Model.FK_pro_order_record_transfer_register" />
|
||||||
<EntityTypeShape EntityType="Model.GuaDanOrder" Width="1.5" PointX="13.375" PointY="21.25" />
|
<EntityTypeShape EntityType="Model.GuaDanOrder" Width="1.5" PointX="13.25" PointY="20.25" />
|
||||||
<EntityTypeShape EntityType="Model.GuaDanOrderGuest" Width="2.125" PointX="30.375" PointY="13.75" />
|
<EntityTypeShape EntityType="Model.GuaDanOrderGuest" Width="1.5" PointX="25.875" PointY="12.5" />
|
||||||
<EntityTypeShape EntityType="Model.GuadanTimeSetting" Width="1.5" PointX="21.375" PointY="9.125" />
|
<EntityTypeShape EntityType="Model.GuadanTimeSetting" Width="1.5" PointX="21.375" PointY="7.75" />
|
||||||
<EntityTypeShape EntityType="Model.Region" Width="1.5" PointX="23.625" PointY="3.875" />
|
<EntityTypeShape EntityType="Model.Region" Width="1.5" PointX="19.125" PointY="30.75" />
|
||||||
<EntityTypeShape EntityType="Model.RegionAndRoomAndBedSchedule" Width="1.5" PointX="23.375" PointY="9.125" />
|
<EntityTypeShape EntityType="Model.RegionAndRoomAndBedSchedule" Width="1.5" PointX="28.125" PointY="12.625" />
|
||||||
<EntityTypeShape EntityType="Model.RegionRoomBed" Width="2.125" PointX="28.125" PointY="4.625" />
|
<EntityTypeShape EntityType="Model.RegionRoomBed" Width="1.5" PointX="23.625" PointY="3.375" />
|
||||||
<EntityTypeShape EntityType="Model.RegionRoomBedStatus" Width="1.5" PointX="25.875" PointY="0.75" />
|
<EntityTypeShape EntityType="Model.RegionRoomBedStatus" Width="1.5" PointX="21.375" PointY="3.625" />
|
||||||
<EntityTypeShape EntityType="Model.RegionType" Width="1.5" PointX="21.375" PointY="4.875" />
|
<EntityTypeShape EntityType="Model.RegionType" Width="1.5" PointX="16.875" PointY="31.625" />
|
||||||
<EntityTypeShape EntityType="Model.Room" Width="1.5" PointX="25.875" PointY="4.375" />
|
<EntityTypeShape EntityType="Model.Room" Width="1.5" PointX="21.375" PointY="31.125" />
|
||||||
<AssociationConnector Association="Model.FK_GuaDanOrder_Admin_CreateUser" />
|
<AssociationConnector Association="Model.FK_GuaDanOrder_Admin_CreateUser" />
|
||||||
<AssociationConnector Association="Model.FK_GuaDanOrder_Followers" />
|
<AssociationConnector Association="Model.FK_GuaDanOrder_Followers" />
|
||||||
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_FOLLOWERS" />
|
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_FOLLOWERS" />
|
||||||
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_BedUuid" />
|
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_BedUuid" />
|
||||||
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_RoomUuid" />
|
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_RoomUuid" />
|
||||||
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_Status" />
|
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_StatusCode" />
|
||||||
|
<AssociationConnector Association="Model.FK_Schedule_GuaDanOrderGuest" />
|
||||||
<AssociationConnector Association="Model.FK_Region_ParentUuid" />
|
<AssociationConnector Association="Model.FK_Region_ParentUuid" />
|
||||||
<AssociationConnector Association="Model.FK_Region_RegionTypeUuid" />
|
<AssociationConnector Association="Model.FK_Region_RegionTypeUuid" />
|
||||||
<AssociationConnector Association="Model.FK_Room_Region" />
|
<AssociationConnector Association="Model.FK_Room_Region" />
|
||||||
<AssociationConnector Association="Model.FK_RegionRoomBed_RegionRoomBedStatus" />
|
|
||||||
<AssociationConnector Association="Model.FK_RegionRoomBed_RoomUuid" />
|
<AssociationConnector Association="Model.FK_RegionRoomBed_RoomUuid" />
|
||||||
|
<AssociationConnector Association="Model.FK_RegionRoomBed_StatusCode" />
|
||||||
|
<EntityTypeShape EntityType="Model.AncestralTabletArea" Width="1.5" PointX="25.375" PointY="22.375" />
|
||||||
|
<EntityTypeShape EntityType="Model.AncestralTabletPosition" Width="1.5" PointX="27.625" PointY="18.375" />
|
||||||
|
<EntityTypeShape EntityType="Model.AncestralTabletPositionRecord" Width="1.5" PointX="32.125" PointY="18.625" />
|
||||||
|
<EntityTypeShape EntityType="Model.AncestralTabletRegistrant" Width="1.5" PointX="29.875" PointY="18" />
|
||||||
|
<EntityTypeShape EntityType="Model.AncestralTabletStatus" Width="1.5" PointX="25.375" PointY="19.125" />
|
||||||
|
<AssociationConnector Association="Model.FK_AncestralTabletArea_Parent" />
|
||||||
|
<AssociationConnector Association="Model.FK_Position_Area" />
|
||||||
|
<AssociationConnector Association="Model.FK_Position_Status" />
|
||||||
|
<AssociationConnector Association="Model.FK_Registrant_Position" />
|
||||||
|
<AssociationConnector Association="Model.FK__Ancestral__Regis__5A1A5A11" />
|
||||||
|
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_Order" />
|
||||||
</Diagram>
|
</Diagram>
|
||||||
</edmx:Diagrams>
|
</edmx:Diagrams>
|
||||||
</edmx:Designer>
|
</edmx:Designer>
|
||||||
|
|||||||
57
web/App_Code/Model/Partial/GuaDanOrderGuest.cs
Normal file
57
web/App_Code/Model/Partial/GuaDanOrderGuest.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GuaDanOrderGuest 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
public partial class GuaDanOrderGuest
|
||||||
|
{
|
||||||
|
// 状态常量定义
|
||||||
|
public const string STATUS_BOOKED = "401"; // 预订成功
|
||||||
|
public const string STATUS_CHECKED_IN = "402"; // 已入住
|
||||||
|
public const string STATUS_CHECKED_OUT = "403"; // 已退房
|
||||||
|
public const string STATUS_CANCELLED = "404"; // 已取消
|
||||||
|
|
||||||
|
public static bool IsStatusTransitionValid(ezEntities db, string targetStatus, Guid guestId)
|
||||||
|
{
|
||||||
|
// 获取当前客人对象
|
||||||
|
GuaDanOrderGuest currentGuest = db.GuaDanOrderGuest.Find(guestId);
|
||||||
|
if (currentGuest == null)
|
||||||
|
{
|
||||||
|
// 如果没有客人对象,只能创建新的预订
|
||||||
|
return targetStatus == STATUS_BOOKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全获取当前状态(处理null情况)
|
||||||
|
string currentStatus = currentGuest.RegionRoomBedStatus?.Code;
|
||||||
|
|
||||||
|
// 如果当前状态为空,只能进入预订成功状态
|
||||||
|
if (string.IsNullOrEmpty(currentStatus))
|
||||||
|
{
|
||||||
|
return targetStatus == STATUS_BOOKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义有效的状态转换规则
|
||||||
|
var validTransitions = new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
{ STATUS_BOOKED, new List<string> { STATUS_CHECKED_IN, STATUS_CANCELLED } },
|
||||||
|
{ STATUS_CHECKED_IN, new List<string> { STATUS_CHECKED_OUT } },
|
||||||
|
{ STATUS_CHECKED_OUT, new List<string> { } }, // 终态,不能再转换
|
||||||
|
{ STATUS_CANCELLED, new List<string> { } } // 终态,不能再转换
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查转换是否有效
|
||||||
|
if (validTransitions.ContainsKey(currentStatus))
|
||||||
|
{
|
||||||
|
return validTransitions[currentStatus].Contains(targetStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // 未知的当前状态
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@ namespace Model
|
|||||||
|
|
||||||
// 找出在日期範圍內被占用的床位 Uuid(包括長期占用 ScheduleDate = null)
|
// 找出在日期範圍內被占用的床位 Uuid(包括長期占用 ScheduleDate = null)
|
||||||
var busyBedUuidsQuery = db.RegionAndRoomAndBedSchedule
|
var busyBedUuidsQuery = db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.IsDeleted == false && s.IsActive
|
.Where(s => s.IsDeleted == false && !s.IsCancel
|
||||||
&& (s.ScheduleDate == null
|
&& (s.ScheduleDate == null
|
||||||
|| (end.HasValue
|
|| (end.HasValue
|
||||||
&& s.ScheduleDate >= start
|
&& s.ScheduleDate >= start
|
||||||
@@ -79,25 +79,28 @@ namespace Model
|
|||||||
public static async Task<bool> IsBedAvailableAsync(ezEntities db, Guid targetUuid, DateTime start, DateTime? end)
|
public static async Task<bool> IsBedAvailableAsync(ezEntities db, Guid targetUuid, DateTime start, DateTime? end)
|
||||||
{
|
{
|
||||||
// 如果 end 為 null,表示長期占用,直接判斷是否已有長期占用
|
// 如果 end 為 null,表示長期占用,直接判斷是否已有長期占用
|
||||||
|
//不包含结束时间那一天
|
||||||
if (end == null)
|
if (end == null)
|
||||||
{
|
{
|
||||||
var hasLongTerm = await db.RegionAndRoomAndBedSchedule
|
var hasLongTerm = await db.RegionAndRoomAndBedSchedule
|
||||||
.AnyAsync(s => s.IsDeleted == false
|
.AnyAsync(s => s.IsDeleted == false
|
||||||
&& s.IsActive
|
&& !s.IsCancel
|
||||||
&& s.TargetUuid == targetUuid
|
&& s.TargetUuid == targetUuid
|
||||||
&& s.ScheduleDate == null);
|
&& s.ScheduleDate == null);
|
||||||
return !hasLongTerm;
|
return !hasLongTerm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 短期占用,查詢每日排程中有無衝突
|
// 短期占用,查詢每日排程中有無衝突
|
||||||
var totalDays = (end.Value.Date - start.Date).Days + 1;
|
var totalDays = (end.Value.Date - start.Date).Days;
|
||||||
for (int i = 0; i < totalDays; i++)
|
for (int i = 0; i < totalDays; i++)
|
||||||
{
|
{
|
||||||
var date = start.Date.AddDays(i);
|
var date = start.Date.AddDays(i);
|
||||||
|
|
||||||
var conflict = await db.RegionAndRoomAndBedSchedule
|
var conflict = await db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != GuaDanOrderGuest.STATUS_CHECKED_OUT)
|
||||||
.AnyAsync(s => s.IsDeleted == false
|
.AnyAsync(s => s.IsDeleted == false
|
||||||
&& s.IsActive
|
&& !s.IsCancel
|
||||||
&& s.TargetUuid == targetUuid
|
&& s.TargetUuid == targetUuid
|
||||||
&& s.ScheduleDate == date);
|
&& s.ScheduleDate == date);
|
||||||
|
|
||||||
@@ -114,7 +117,10 @@ namespace Model
|
|||||||
|
|
||||||
// 找出所有在日期範圍內被占用的床位
|
// 找出所有在日期範圍內被占用的床位
|
||||||
var busyBedUuids = await db.RegionAndRoomAndBedSchedule
|
var busyBedUuids = await db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.IsDeleted == false && s.IsActive
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403")
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
|
.Where(s => s.IsDeleted == false
|
||||||
&& (s.ScheduleDate == null // 長期占用
|
&& (s.ScheduleDate == null // 長期占用
|
||||||
|| (s.ScheduleDate >= start && s.ScheduleDate <= end)))
|
|| (s.ScheduleDate >= start && s.ScheduleDate <= end)))
|
||||||
.Select(s => s.TargetUuid)
|
.Select(s => s.TargetUuid)
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace Model
|
|||||||
{
|
{
|
||||||
public partial class RegionRoomBed
|
public partial class RegionRoomBed
|
||||||
{
|
{
|
||||||
|
public const string STATUS_BED_FREE = "101"; // 空閒,可使用
|
||||||
|
public const string STATUS_BED_OCCUPIED = "102"; // 已佔用
|
||||||
|
public const string STATUS_BED_MAINTENANCE = "103"; // 維護中,不可使用
|
||||||
public bool IsAvailable()
|
public bool IsAvailable()
|
||||||
{
|
{
|
||||||
//判断床位是否可用:自身是否启用
|
//判断床位是否可用:自身是否启用
|
||||||
@@ -34,7 +37,9 @@ namespace Model
|
|||||||
// 如果資料庫 ScheduleDate 是 date 型別,本身沒有時間部分,可以直接比較
|
// 如果資料庫 ScheduleDate 是 date 型別,本身沒有時間部分,可以直接比較
|
||||||
var conflict = _db.RegionAndRoomAndBedSchedule.Any(s =>
|
var conflict = _db.RegionAndRoomAndBedSchedule.Any(s =>
|
||||||
s.TargetUuid == this.Uuid &&
|
s.TargetUuid == this.Uuid &&
|
||||||
s.IsActive &&
|
s.GuaDanOrderGuest.StatusCode != "403" &&
|
||||||
|
s.GuaDanOrderGuest.StatusCode != "404" &&
|
||||||
|
!s.IsCancel &&
|
||||||
!s.IsDeleted &&
|
!s.IsDeleted &&
|
||||||
(
|
(
|
||||||
s.ScheduleDate == null || // 長期占用
|
s.ScheduleDate == null || // 長期占用
|
||||||
@@ -46,5 +51,6 @@ namespace Model
|
|||||||
|
|
||||||
return !conflict;
|
return !conflict;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
web/App_Code/Model/Partial/family_members.cs
Normal file
19
web/App_Code/Model/Partial/family_members.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// added
|
||||||
|
/// </summary>
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
[MetadataType(typeof(family_membersMetadata))]
|
||||||
|
public partial class family_members
|
||||||
|
{
|
||||||
|
private class family_membersMetadata
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual follower follower { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -45,6 +45,19 @@ namespace Model
|
|||||||
public virtual ICollection<followers_tablet> followers_tablet { get; set; }
|
public virtual ICollection<followers_tablet> followers_tablet { get; set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public virtual appellation appellation { get; set; }
|
public virtual appellation appellation { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// added
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<family_members> family_members { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<transfer_register> transfer_register { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<transfer_register> transfer_register1 { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<GuaDanOrder> GuaDanOrder { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,5 +19,6 @@ public class GuaDanOrderView
|
|||||||
public string bookerName { get; set; }
|
public string bookerName { get; set; }
|
||||||
public string bookerPhone { get; set; }
|
public string bookerPhone { get; set; }
|
||||||
public int? bookerFollowerNum { get; set; }
|
public int? bookerFollowerNum { get; set; }
|
||||||
|
public int? activityNum { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,73 +1,38 @@
|
|||||||
using System;
|
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;
|
||||||
using System.Collections.Generic;
|
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.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.Design;
|
using System.ComponentModel.Design;
|
||||||
using System.ComponentModel.Design.Serialization;
|
using System.ComponentModel.Design.Serialization;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.OleDb;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Mail;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web;
|
||||||
using System.Web.Caching;
|
using System.Web.Caching;
|
||||||
using System.Web.ModelBinding;
|
using System.Web.ModelBinding;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
|
using System.Web.Security;
|
||||||
using System.Web.SessionState;
|
using System.Web.SessionState;
|
||||||
|
using System.Web.UI;
|
||||||
using System.Web.UI.Adapters;
|
using System.Web.UI.Adapters;
|
||||||
using System.Web.UI.HtmlControls;
|
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 System.Web.UI.WebControls;
|
||||||
using Newtonsoft.Json;
|
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
|
namespace Model.ViewModel
|
||||||
|
|||||||
34
web/App_Code/StatusTransitionManager.cs
Normal file
34
web/App_Code/StatusTransitionManager.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Model
|
||||||
|
{
|
||||||
|
public static class StatusTransitionManager
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, List<string>> transitions =
|
||||||
|
new Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
// 掛單狀態
|
||||||
|
{ "401", new List<string> { "402", "404" } },
|
||||||
|
{ "402", new List<string> { "403" } },
|
||||||
|
{ "403", new List<string>() },
|
||||||
|
{ "404", new List<string>() },
|
||||||
|
|
||||||
|
// 床位狀態
|
||||||
|
{ "101", new List<string> {"101", "102","103"} },
|
||||||
|
{ "102", new List<string> { "101" } },
|
||||||
|
{ "103", new List<string> { "101" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static bool CanTransition(string currentCode, string targetCode)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(currentCode))
|
||||||
|
{
|
||||||
|
return targetCode == "401" || targetCode == "402" || targetCode == "101";
|
||||||
|
}
|
||||||
|
if(string.IsNullOrEmpty(targetCode))
|
||||||
|
{ return false; }
|
||||||
|
return transitions.ContainsKey(currentCode) &&
|
||||||
|
transitions[currentCode].Contains(targetCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
web/App_Code/api/ActivityStatisticsController.cs
Normal file
73
web/App_Code/api/ActivityStatisticsController.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ActivityStatisticsController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class ActivityStatisticsController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/activity/statistics/summary")]
|
||||||
|
public IHttpActionResult GetStatisticsSummary([FromUri] int? activity_num =null)
|
||||||
|
{
|
||||||
|
if (activity_num == null)
|
||||||
|
{
|
||||||
|
return BadRequest("活动Id不能为空");
|
||||||
|
}
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var pre_order_query = _db.pro_order.Where(a => a.activity_num == activity_num);
|
||||||
|
var totalApplicants = pre_order_query.Count();
|
||||||
|
var maleApplicants = pre_order_query.Where(a => a.follower.sex == "男眾").Count();
|
||||||
|
|
||||||
|
var pro_order_detail_query = _db.pro_order_detail
|
||||||
|
.Where(d => d.pro_order.activity_num == activity_num);
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
reportDate = now.ToString("yyyy/MM/dd HH:mm:ss"),
|
||||||
|
totalApplicants = totalApplicants, //报名总人数
|
||||||
|
maleApplicants = maleApplicants, //男
|
||||||
|
femaleApplicants = totalApplicants - maleApplicants,//女
|
||||||
|
donation = new
|
||||||
|
{
|
||||||
|
total = 158000,//总功德金
|
||||||
|
received = 150000,//已收功德金
|
||||||
|
unreceived = 8000//未收功德金
|
||||||
|
},
|
||||||
|
items = new[]//功德项目,这个的功德项目要根据活动预设的功德项目来做统计,就是这个活动有那些可报名的功德项目
|
||||||
|
{
|
||||||
|
new { name = "總功德主", count = "10人" },
|
||||||
|
new { name = "利益主", count = "15人" },
|
||||||
|
new { name = "個人大牌", count = "50人" },
|
||||||
|
new { name = "供僧", count = "45人" }
|
||||||
|
},
|
||||||
|
plaques = new[]//牌位
|
||||||
|
{
|
||||||
|
new { name = "總牌位數", count = pro_order_detail_query.Count() },
|
||||||
|
new { name = "消災-大牌位", count = 101 },
|
||||||
|
new { name = "超冤-大牌位", count =10 },
|
||||||
|
new { name = "消災-個人大牌", count =10 },
|
||||||
|
new { name = "超冤-個人大牌", count = 10 },
|
||||||
|
new { name = "超薦-個人大牌", count = 10 },
|
||||||
|
new { name = "消災-個人中牌", count = 10 },
|
||||||
|
new { name = "超冤-個人中牌", count = 10 },
|
||||||
|
new { name = "超薦-個人中牌", count = 10 },
|
||||||
|
new { name = "消災-隨喜牌位", count = 10 },
|
||||||
|
new { name = "超冤-隨喜牌位", count = 10 },
|
||||||
|
new { name = "超薦-隨喜牌位", count = 10 },
|
||||||
|
new { name = "消災-常年牌位", count = 10 },
|
||||||
|
new { name = "超冤-常年牌位", count = 10 },
|
||||||
|
new { name = "超薦-常年牌位", count = 10 },
|
||||||
|
new { name = "消災-急立牌位", count = 10 },
|
||||||
|
new { name = "超薦-急立牌位", count = 10 },
|
||||||
|
new { name = "超冤-急立牌位", count = 101 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
180
web/App_Code/api/AncestralTabletAreaController.cs
Normal file
180
web/App_Code/api/AncestralTabletAreaController.cs
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
using Model;
|
||||||
|
using PagedList;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using static AncestralTabletPositionController;
|
||||||
|
using static regionController;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AncestralTabletController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class AncestralTabletAreaController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public class AreaViewModel
|
||||||
|
{
|
||||||
|
public int? AreaId { get; set; }
|
||||||
|
public string AreaName { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "區域編號為必填")]
|
||||||
|
public string AreaCode { get; set; }
|
||||||
|
public int? ParentAreaId { get; set; }
|
||||||
|
public string AreaType { get; set; }
|
||||||
|
public int? Price { get; set; }
|
||||||
|
public int? SortOrder { get; set; }
|
||||||
|
public bool IsDisabled { get; set; } = false;
|
||||||
|
public string Description { get; set; }
|
||||||
|
}
|
||||||
|
public class RegionDto
|
||||||
|
{
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
public string AreaName { get; set; }
|
||||||
|
public string AreaCode { get; set; }
|
||||||
|
public int? SortOrder { get; set; }
|
||||||
|
public int? ParentAreaId { get; set; }
|
||||||
|
public string AreaType { get; set; }
|
||||||
|
public bool IsDisabled { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public int? Price { set; get; }
|
||||||
|
|
||||||
|
public List<RegionDto> Children { get; set; } = new List<RegionDto>();
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/area/getlist")]
|
||||||
|
public IHttpActionResult GetList()
|
||||||
|
{
|
||||||
|
var allArea = _db.AncestralTabletArea.ToList();
|
||||||
|
|
||||||
|
var rootRegions = allArea
|
||||||
|
.Where(r => r.ParentAreaId == null)
|
||||||
|
.OrderBy(r => r.SortOrder)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var tree = rootRegions
|
||||||
|
.Select(r => BuildRegionDto(r, allArea))
|
||||||
|
.ToList();
|
||||||
|
return Ok(tree);
|
||||||
|
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/area/getereawithposition")]
|
||||||
|
public IHttpActionResult GetEreaWithPosition()
|
||||||
|
{
|
||||||
|
//获取有神位位置的区域
|
||||||
|
var allArea = _db.AncestralTabletArea
|
||||||
|
.Where(a => a.AncestralTabletPosition.Count()>0)
|
||||||
|
.Select(a => new
|
||||||
|
{
|
||||||
|
a.AreaId,
|
||||||
|
a.AreaName,
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
return Ok(allArea);
|
||||||
|
|
||||||
|
}
|
||||||
|
private RegionDto BuildRegionDto(AncestralTabletArea area, List<AncestralTabletArea> allArea)
|
||||||
|
{
|
||||||
|
return new RegionDto
|
||||||
|
{
|
||||||
|
AreaId = area.AreaId,
|
||||||
|
AreaName = area.AreaName,
|
||||||
|
AreaCode = area.AreaCode,
|
||||||
|
SortOrder = area.SortOrder,
|
||||||
|
ParentAreaId = area.ParentAreaId,
|
||||||
|
AreaType = area.AreaType,
|
||||||
|
IsDisabled = area.IsDisabled,
|
||||||
|
Description = area.Description,
|
||||||
|
Price = area.Price,
|
||||||
|
Children = allArea
|
||||||
|
.Where(r => r.ParentAreaId == area.AreaId)
|
||||||
|
.OrderBy(r => r.SortOrder)
|
||||||
|
.Select(child => BuildRegionDto(child, allArea))
|
||||||
|
.ToList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/area/create")]
|
||||||
|
public async Task<IHttpActionResult> CreateArea([FromBody] AreaViewModel tabletArea)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var area = new AncestralTabletArea
|
||||||
|
{
|
||||||
|
AreaName = tabletArea.AreaName,
|
||||||
|
AreaCode = tabletArea.AreaCode,
|
||||||
|
ParentAreaId = tabletArea.ParentAreaId,
|
||||||
|
AreaType = tabletArea.AreaType,
|
||||||
|
Price = tabletArea.Price,
|
||||||
|
SortOrder = tabletArea.SortOrder,
|
||||||
|
IsDisabled = tabletArea.IsDisabled,
|
||||||
|
Description = tabletArea.Description
|
||||||
|
};
|
||||||
|
_db.AncestralTabletArea.Add(area);
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
tabletArea.AreaId = area.AreaId;
|
||||||
|
return Ok(new { message = "區域建立成功", area = tabletArea });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/area/edit")]
|
||||||
|
public async Task<IHttpActionResult> EditArea([FromBody] AreaViewModel tabletArea)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var oldArea = _db.AncestralTabletArea.Find(tabletArea.AreaId);
|
||||||
|
if (oldArea == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
oldArea.AreaName = tabletArea.AreaName;
|
||||||
|
oldArea.AreaCode = tabletArea.AreaCode;
|
||||||
|
oldArea.ParentAreaId = tabletArea.ParentAreaId;
|
||||||
|
oldArea.Price = tabletArea.Price;
|
||||||
|
oldArea.SortOrder = tabletArea.SortOrder;
|
||||||
|
oldArea.Description = tabletArea.Description;
|
||||||
|
oldArea.IsDisabled = tabletArea.IsDisabled;
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
return Ok(new { message = "區域修改成功", area = tabletArea });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/area/position/getlist")]
|
||||||
|
public IHttpActionResult GetPositionList([FromUri] int areaId)
|
||||||
|
{
|
||||||
|
var positions = _db.AncestralTabletPosition
|
||||||
|
.Where(p => p.AreaId == areaId)
|
||||||
|
.Select(p => new AncestralTabletPositionDto
|
||||||
|
{
|
||||||
|
PositionId = p.PositionId,
|
||||||
|
AreaId = p.AreaId,
|
||||||
|
PositionCode = p.PositionCode,
|
||||||
|
PositionName = p.PositionName,
|
||||||
|
Price = p.Price,
|
||||||
|
StatusCode = p.StatusCode,
|
||||||
|
Description = p.Description,
|
||||||
|
RowNo = p.RowNo,
|
||||||
|
ColumnNo = p.ColumnNo
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return Ok(positions);
|
||||||
|
}
|
||||||
|
}
|
||||||
184
web/App_Code/api/AncestralTabletPositionController.cs
Normal file
184
web/App_Code/api/AncestralTabletPositionController.cs
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
using Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AncestralTabletPositionController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class AncestralTabletPositionController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/position/getlist")]
|
||||||
|
public IHttpActionResult GetList([FromUri] int areaId)
|
||||||
|
{
|
||||||
|
var positions = _db.AncestralTabletPosition
|
||||||
|
.Where(p => p.AreaId == areaId)
|
||||||
|
.Select(p => new
|
||||||
|
{
|
||||||
|
PositionId = p.PositionId,
|
||||||
|
AreaId = p.AreaId,
|
||||||
|
PositionCode = p.PositionCode,
|
||||||
|
PositionName = p.PositionName,
|
||||||
|
Price = p.Price,
|
||||||
|
StatusCode = p.StatusCode,
|
||||||
|
Description = p.Description,
|
||||||
|
RowNo = p.RowNo,
|
||||||
|
ColumnNo = p.ColumnNo,
|
||||||
|
AncestralTabletRegistrant = _db.AncestralTabletRegistrant
|
||||||
|
.Where(r => r.PositionId == p.PositionId && r.IsActive == true)
|
||||||
|
.Select(r => new
|
||||||
|
{
|
||||||
|
r.RegistrantCode,
|
||||||
|
r.Name,
|
||||||
|
r.Phone,
|
||||||
|
r.Address,
|
||||||
|
r.RegisterDate,
|
||||||
|
r.Price,
|
||||||
|
r.StartDate,
|
||||||
|
r.EndDate,
|
||||||
|
r.IsLongTerm,
|
||||||
|
r.IsActive,
|
||||||
|
|
||||||
|
// 嵌套查询牌位记录(PositionRecord)
|
||||||
|
TabletRecord = r.AncestralTabletPositionRecord
|
||||||
|
.Select(pr => new
|
||||||
|
{
|
||||||
|
pr.RecordId,
|
||||||
|
pr.RegistrantCode,
|
||||||
|
pr.NPTitle,
|
||||||
|
pr.NPStandDate,
|
||||||
|
pr.NPYangShang,
|
||||||
|
pr.WPContent
|
||||||
|
})
|
||||||
|
.FirstOrDefault()
|
||||||
|
})
|
||||||
|
.FirstOrDefault()
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return Ok(positions);
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/position/shortlist")]
|
||||||
|
public IHttpActionResult GetListWithShort([FromUri] int areaId)
|
||||||
|
{
|
||||||
|
//获取位置列表,简单信息
|
||||||
|
var positions = _db.AncestralTabletPosition
|
||||||
|
.Where(p => p.AreaId == areaId)
|
||||||
|
.Select(p => new
|
||||||
|
{
|
||||||
|
PositionId = p.PositionId,
|
||||||
|
AreaId = p.AreaId,
|
||||||
|
PositionCode = p.PositionCode,
|
||||||
|
PositionName = p.PositionName,
|
||||||
|
Price = p.Price,
|
||||||
|
StatusCode = p.StatusCode,
|
||||||
|
Description = p.Description,
|
||||||
|
RowNo = p.RowNo,
|
||||||
|
ColumnNo = p.ColumnNo,
|
||||||
|
isCanUse = p.StatusCode == "available" ? true : false,
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return Ok(positions);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/position/batchcreate")]
|
||||||
|
public IHttpActionResult BatchCreatePosition([FromBody] List<AncestralTabletPositionDto> positions)
|
||||||
|
{
|
||||||
|
if (positions == null || positions.Count == 0)
|
||||||
|
return BadRequest("未接收到任何位置数据");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var dto in positions)
|
||||||
|
{
|
||||||
|
var entity = new AncestralTabletPosition
|
||||||
|
{
|
||||||
|
AreaId = dto.AreaId,
|
||||||
|
PositionCode = dto.PositionCode,
|
||||||
|
PositionName = dto.PositionName,
|
||||||
|
Price = dto.Price,
|
||||||
|
StatusCode = dto.StatusCode,
|
||||||
|
Description = dto.Description,
|
||||||
|
RowNo = dto.RowNo,
|
||||||
|
ColumnNo = dto.ColumnNo
|
||||||
|
};
|
||||||
|
|
||||||
|
_db.AncestralTabletPosition.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "批量新增成功", count = positions.Count });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string message = ex.InnerException?.InnerException?.Message ?? ex.Message;
|
||||||
|
|
||||||
|
return Content(HttpStatusCode.InternalServerError, new
|
||||||
|
{
|
||||||
|
message = "批量新增失败",
|
||||||
|
exceptionMessage = message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/position/edit")]
|
||||||
|
public IHttpActionResult EditPosition([FromBody] AncestralTabletPositionDto pos)
|
||||||
|
{
|
||||||
|
var oldPos = _db.AncestralTabletPosition
|
||||||
|
.FirstOrDefault(p => p.AreaId == pos.AreaId && p.PositionCode == pos.PositionCode);
|
||||||
|
if(oldPos == null) return NotFound();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
oldPos.PositionName = pos.PositionName;
|
||||||
|
oldPos.Price = pos.Price;
|
||||||
|
oldPos.StatusCode = pos.StatusCode;
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
_db.SaveChanges();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
return Ok(new { message="更新成功", code=200});
|
||||||
|
}
|
||||||
|
[HttpDelete]
|
||||||
|
[Route("api/ancestraltablet/position/delete/{positionId}")]
|
||||||
|
public IHttpActionResult DeletePosition(int positionId)
|
||||||
|
{
|
||||||
|
var pos = _db.AncestralTabletPosition.FirstOrDefault(p => p.PositionId == positionId);
|
||||||
|
|
||||||
|
if (pos == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.AncestralTabletPosition.Remove(pos);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok("删除成功");
|
||||||
|
}
|
||||||
|
public class AncestralTabletPositionDto
|
||||||
|
{
|
||||||
|
public int PositionId { get; set; }
|
||||||
|
public int AreaId { get; set; }
|
||||||
|
public string PositionCode { get; set; }
|
||||||
|
public string PositionName { get; set; }
|
||||||
|
public int? Price { get; set; }
|
||||||
|
public string StatusCode { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public int? RowNo { get; set; }
|
||||||
|
public int? ColumnNo { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
361
web/App_Code/api/AncestralTabletRecordController.cs
Normal file
361
web/App_Code/api/AncestralTabletRecordController.cs
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AncestralTabletRecordController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class AncestralTabletRecordController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/registrant/getlist")]
|
||||||
|
public IHttpActionResult GetRegistrantList()
|
||||||
|
{
|
||||||
|
//获取登记人列表
|
||||||
|
var data = _db.AncestralTabletRegistrant.Select(x => new
|
||||||
|
{
|
||||||
|
x.RegistrantCode,
|
||||||
|
x.Name,
|
||||||
|
x.Phone,
|
||||||
|
x.Address,
|
||||||
|
x.RegisterDate,
|
||||||
|
x.Price,
|
||||||
|
x.PositionId,
|
||||||
|
x.StartDate,
|
||||||
|
x.EndDate,
|
||||||
|
x.IsLongTerm,
|
||||||
|
x.IsActive,
|
||||||
|
x.CreatedAt,
|
||||||
|
x.UpdatedAt
|
||||||
|
})
|
||||||
|
.Take(1000) // 取前1000条
|
||||||
|
.ToList(); ;
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/registrant/getlistbypage")]
|
||||||
|
public IHttpActionResult GetRegistrantListByPage([FromBody] RegistrantSearchDto searchDto)
|
||||||
|
{
|
||||||
|
//获取登记人列表
|
||||||
|
var query = _db.AncestralTabletRegistrant.AsQueryable();
|
||||||
|
if( !string.IsNullOrEmpty(searchDto.searchName))
|
||||||
|
{
|
||||||
|
query = query.Where(r => r.Name == searchDto.searchName);
|
||||||
|
}
|
||||||
|
var tatol = query.Count();
|
||||||
|
var data = query.Select(x => new
|
||||||
|
{
|
||||||
|
x.RegistrantCode,
|
||||||
|
x.Name,
|
||||||
|
x.Phone,
|
||||||
|
x.Address,
|
||||||
|
x.RegisterDate,
|
||||||
|
x.Price,
|
||||||
|
x.PositionId,
|
||||||
|
x.StartDate,
|
||||||
|
x.EndDate,
|
||||||
|
x.IsLongTerm,
|
||||||
|
x.IsActive,
|
||||||
|
x.CreatedAt,
|
||||||
|
x.UpdatedAt
|
||||||
|
})
|
||||||
|
.OrderByDescending(a => a.CreatedAt)
|
||||||
|
.Skip((searchDto.page - 1) * searchDto.pageSize)
|
||||||
|
.Take(searchDto.pageSize) // 取前1000条
|
||||||
|
.ToList();
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
data = data,
|
||||||
|
total = tatol
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/registrant/getbycode")]
|
||||||
|
public IHttpActionResult GetRegistrantByCode([FromUri] string registrantCode)
|
||||||
|
{
|
||||||
|
var r = _db.AncestralTabletRegistrant.Find(registrantCode);
|
||||||
|
if (r == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
var rDto = new
|
||||||
|
{
|
||||||
|
r.RegistrantCode,
|
||||||
|
r.Name,
|
||||||
|
r.Phone,
|
||||||
|
r.Address,
|
||||||
|
r.RegisterDate,
|
||||||
|
r.Price,
|
||||||
|
r.StartDate,
|
||||||
|
r.EndDate,
|
||||||
|
r.IsLongTerm,
|
||||||
|
r.IsActive,
|
||||||
|
r.PositionId,
|
||||||
|
positionName = r.AncestralTabletPosition?.PositionName,
|
||||||
|
|
||||||
|
|
||||||
|
// 嵌套查询牌位记录(PositionRecord)
|
||||||
|
TabletRecord = r.AncestralTabletPositionRecord
|
||||||
|
.Select(pr => new
|
||||||
|
{
|
||||||
|
pr.RecordId,
|
||||||
|
pr.RegistrantCode,
|
||||||
|
pr.NPTitle,
|
||||||
|
pr.NPStandDate,
|
||||||
|
pr.NPYangShang,
|
||||||
|
pr.WPContent,
|
||||||
|
})
|
||||||
|
.FirstOrDefault()
|
||||||
|
};
|
||||||
|
return Ok(rDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/registrant/create")]
|
||||||
|
public IHttpActionResult CreateRegistrant([FromBody] AncestralTabletRegistrantDto dto)
|
||||||
|
{
|
||||||
|
//新增登记人api
|
||||||
|
if (dto == null)
|
||||||
|
{
|
||||||
|
return BadRequest("请求体不能为空");
|
||||||
|
}
|
||||||
|
if(!string.IsNullOrEmpty(dto.RegistrantCode))
|
||||||
|
{
|
||||||
|
return BadRequest("RegistrantCode 应传递空");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dto.RegistrantCode = GenerateRegistrantCode();
|
||||||
|
|
||||||
|
// 设置默认创建时间
|
||||||
|
dto.CreatedAt = DateTime.Now;
|
||||||
|
var entity = new Model.AncestralTabletRegistrant
|
||||||
|
{
|
||||||
|
RegistrantCode = dto.RegistrantCode,
|
||||||
|
Name = dto.Name,
|
||||||
|
Phone = dto.Phone,
|
||||||
|
Address = dto.Address,
|
||||||
|
RegisterDate = dto.RegisterDate,
|
||||||
|
Price = dto.Price,
|
||||||
|
PositionId = dto.PositionId,
|
||||||
|
StartDate = dto.startDate,
|
||||||
|
EndDate = dto.endDate,
|
||||||
|
IsLongTerm = dto.isLongTerm,
|
||||||
|
IsActive = dto.isActive,
|
||||||
|
CreatedAt = dto.CreatedAt,
|
||||||
|
UpdatedAt = dto.UpdatedAt
|
||||||
|
};
|
||||||
|
|
||||||
|
// 假设你有一个 EF DbContext(如 _db)
|
||||||
|
_db.AncestralTabletRegistrant.Add(entity);
|
||||||
|
if (dto.PositionId != null)
|
||||||
|
{
|
||||||
|
var position = _db.AncestralTabletPosition
|
||||||
|
.FirstOrDefault(p => p.PositionId == dto.PositionId);
|
||||||
|
|
||||||
|
if (position != null)
|
||||||
|
{
|
||||||
|
position.StatusCode = "used"; // 或者根据你的枚举/字段设置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "登记成功", registrantCode = entity.RegistrantCode });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/registrant/update")]
|
||||||
|
public IHttpActionResult UpdateRegistrant([FromBody] AncestralTabletRegistrantDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null)
|
||||||
|
{
|
||||||
|
return BadRequest("请求体不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(dto.RegistrantCode))
|
||||||
|
{
|
||||||
|
return BadRequest("缺少 RegistrantCode,无法进行更新操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 查找原始资料
|
||||||
|
var entity = _db.AncestralTabletRegistrant
|
||||||
|
.FirstOrDefault(r => r.RegistrantCode == dto.RegistrantCode);
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
return NotFound(); // 没有对应记录
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 处理安位状态 =====
|
||||||
|
if (entity.PositionId != dto.PositionId)
|
||||||
|
{
|
||||||
|
// 1. 原来的安位设置为可用
|
||||||
|
if (entity.PositionId != null)
|
||||||
|
{
|
||||||
|
var oldPosition = _db.AncestralTabletPosition
|
||||||
|
.FirstOrDefault(p => p.PositionId == entity.PositionId);
|
||||||
|
|
||||||
|
if (oldPosition != null)
|
||||||
|
{
|
||||||
|
oldPosition.StatusCode = "available"; // 可用
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 新的安位设置为已使用
|
||||||
|
if (dto.PositionId != null)
|
||||||
|
{
|
||||||
|
var newPosition = _db.AncestralTabletPosition
|
||||||
|
.FirstOrDefault(p => p.PositionId == dto.PositionId);
|
||||||
|
|
||||||
|
if (newPosition != null)
|
||||||
|
{
|
||||||
|
newPosition.StatusCode = "used"; // 已使用
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新登记人安位
|
||||||
|
entity.PositionId = dto.PositionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新其它字段
|
||||||
|
entity.Name = dto.Name;
|
||||||
|
entity.Phone = dto.Phone;
|
||||||
|
entity.Address = dto.Address;
|
||||||
|
entity.RegisterDate = dto.RegisterDate;
|
||||||
|
entity.Price = dto.Price;
|
||||||
|
entity.StartDate = dto.startDate;
|
||||||
|
entity.EndDate = dto.endDate;
|
||||||
|
entity.IsLongTerm = dto.isLongTerm;
|
||||||
|
entity.IsActive = dto.isActive;
|
||||||
|
entity.UpdatedAt = DateTime.Now;
|
||||||
|
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "登记人更新成功", registrantCode = entity.RegistrantCode });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/pw/create")]
|
||||||
|
public IHttpActionResult CreatePW([FromBody] AncestralTabletPositionRecordDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null)
|
||||||
|
return BadRequest("请求体不能为空");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(dto.RegistrantCode))
|
||||||
|
return BadRequest("登记人编号(RegistrantCode)不能为空");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 映射到数据库实体
|
||||||
|
var entity = new Model.AncestralTabletPositionRecord
|
||||||
|
{
|
||||||
|
RegistrantCode = dto.RegistrantCode,
|
||||||
|
NPTitle = dto.NPTitle,
|
||||||
|
NPStandDate = dto.NPStandDate,
|
||||||
|
NPYangShang = dto.NPYangShang,
|
||||||
|
WPContent = dto.WPContent,
|
||||||
|
CreatedAt = DateTime.Now,
|
||||||
|
UpdatedAt = null
|
||||||
|
};
|
||||||
|
|
||||||
|
_db.AncestralTabletPositionRecord.Add(entity);
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "牌位登记成功", recordId = entity.RecordId });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/ancestraltablet/pw/update")]
|
||||||
|
public IHttpActionResult UpdatePW([FromBody] AncestralTabletPositionRecordDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null)
|
||||||
|
return BadRequest("请求体不能为空");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var entity = _db.AncestralTabletPositionRecord.Find(dto.RecordId);
|
||||||
|
// 映射到数据库实体
|
||||||
|
if (entity == null)
|
||||||
|
return BadRequest("牌位不存在,更新失败");
|
||||||
|
entity.RegistrantCode = dto.RegistrantCode;
|
||||||
|
entity.NPTitle = dto.NPTitle;
|
||||||
|
entity.NPStandDate = dto.NPStandDate;
|
||||||
|
entity.NPYangShang = dto.NPYangShang;
|
||||||
|
entity.WPContent = dto.WPContent;
|
||||||
|
entity.UpdatedAt = DateTime.Now;
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "牌位更新成功", recordId = entity.RecordId });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GenerateRegistrantCode(string prefix = "REG", int randomLength = 6)
|
||||||
|
{
|
||||||
|
string datePart = DateTime.Now.ToString("yyyyMMdd");
|
||||||
|
|
||||||
|
string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
var random = new Random();
|
||||||
|
var suffix = new string(Enumerable.Repeat(chars, randomLength)
|
||||||
|
.Select(s => s[random.Next(s.Length)]).ToArray());
|
||||||
|
|
||||||
|
return $"{prefix}{datePart}{suffix}";
|
||||||
|
}
|
||||||
|
public class AncestralTabletRegistrantDto
|
||||||
|
{
|
||||||
|
public string RegistrantCode { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Phone { get; set; }
|
||||||
|
public string Address { get; set; }
|
||||||
|
public DateTime RegisterDate { get; set; }
|
||||||
|
public int? Price { get; set; }
|
||||||
|
public int? PositionId { get; set; }
|
||||||
|
public DateTime startDate { get; set; }
|
||||||
|
public DateTime? endDate { get; set; }
|
||||||
|
public bool isLongTerm { get; set; } = false;
|
||||||
|
public bool isActive { get; set; } = true;
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
public DateTime? UpdatedAt { get; set; }
|
||||||
|
}
|
||||||
|
public class AncestralTabletPositionRecordDto
|
||||||
|
{
|
||||||
|
public int? RecordId { get; set; }
|
||||||
|
public string RegistrantCode { get; set; }
|
||||||
|
public string NPTitle { get; set; }
|
||||||
|
public DateTime NPStandDate { get; set; }
|
||||||
|
public string NPYangShang { get; set; }
|
||||||
|
public string WPContent { get; set; }
|
||||||
|
}
|
||||||
|
public class RegistrantSearchDto
|
||||||
|
{
|
||||||
|
public int page { get; set; } = 1;
|
||||||
|
public int pageSize { get; set; } = 10;
|
||||||
|
public string searchName { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
38
web/App_Code/api/AncestralTabletStatisticsController.cs
Normal file
38
web/App_Code/api/AncestralTabletStatisticsController.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AncestralTabletStatisticsController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class AncestralTabletStatisticsController:ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities db = new Model.ezEntities();
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/statistics/positions/availablepositions")]
|
||||||
|
public IHttpActionResult GetAvailablePositions()
|
||||||
|
{
|
||||||
|
var query =
|
||||||
|
from a in db.AncestralTabletArea // 区域表
|
||||||
|
join p in db.AncestralTabletPosition
|
||||||
|
on a.AreaId equals p.AreaId into ap
|
||||||
|
from p in ap.DefaultIfEmpty()
|
||||||
|
join r in db.AncestralTabletRegistrant
|
||||||
|
on p.PositionId equals r.PositionId into pr
|
||||||
|
from r in pr.DefaultIfEmpty()
|
||||||
|
group new { a, p, r } by new { a.AreaId, a.AreaName } into g
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
AreaId = g.Key.AreaId,
|
||||||
|
AreaName = g.Key.AreaName,
|
||||||
|
TotalPositions = g.Count(x => x.p != null), // 总位置数
|
||||||
|
AvailableCount = g.Count(x => x.p != null && x.r == null) // 可用位置数(未登记)
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = query.ToList();
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
29
web/App_Code/api/AncestralTabletStatusController.cs
Normal file
29
web/App_Code/api/AncestralTabletStatusController.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AncestralTabletStatusController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class AncestralTabletStatusController:ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/ancestraltablet/status/list")]
|
||||||
|
public IHttpActionResult GetStatusList()
|
||||||
|
{
|
||||||
|
var statusList = _db.AncestralTabletStatus
|
||||||
|
.Select(s => new
|
||||||
|
{
|
||||||
|
s.StatusCode,
|
||||||
|
s.StatusName,
|
||||||
|
s.StatusType
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return Ok(statusList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ public class FilesSetController : ApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.files.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.files.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => q.files_num == id).ToList(); //刪除品項的相關文件
|
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => q.files_num == id).ToList(); //刪除品項的相關文件
|
||||||
@@ -84,14 +84,14 @@ public class FilesSetController : ApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
|
|
||||||
var prod = _db.files.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.files.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
//刪除品項的相關文件
|
//刪除品項的相關文件
|
||||||
var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.files_num))).ToList();
|
var prod2 = _db.actItem_files.Where(q => ids.Contains(q.files_num)).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count() > 0)
|
||||||
{
|
{
|
||||||
_db.actItem_files.RemoveRange(prod2);
|
_db.actItem_files.RemoveRange(prod2);
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ public class FilesSetController : ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.files q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.files q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.files.AsEnumerable();
|
var qry = _db.files.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
qry = qry.Where(o => o.subject.Contains(q.subject));
|
qry = qry.Where(o => o.subject.Contains(q.subject));
|
||||||
@@ -157,9 +157,12 @@ public class FilesSetController : ApiController
|
|||||||
else
|
else
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
subject = x.subject,
|
subject = x.subject,
|
||||||
@@ -168,7 +171,7 @@ public class FilesSetController : ApiController
|
|||||||
word = x.word,
|
word = x.word,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class FollowerController : ApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.followers.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.followers.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
/*if (prod != null)
|
/*if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -94,9 +94,9 @@ public class FollowerController : ApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
|
|
||||||
var prod = _db.followers.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
var prod = _db.followers.Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
foreach (var item in prod)
|
foreach (var item in prod)
|
||||||
@@ -139,8 +139,8 @@ public class FollowerController : ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.follower q,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.follower q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
////var qry = _db.followers.Where(a => a.IsDel == false).AsEnumerable();////不確定是否新增欄位? 先註解
|
////var qry = _db.followers.Where(a => a.IsDel == false).AsQueryable();////不確定是否新增欄位? 先註解
|
||||||
var qry = _db.followers.AsEnumerable();
|
var qry = _db.followers.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.f_number))
|
if (!string.IsNullOrEmpty(q.f_number))
|
||||||
qry = qry.Where(o => o.f_number.Contains(q.f_number.Trim()));
|
qry = qry.Where(o => o.f_number.Contains(q.f_number.Trim()));
|
||||||
@@ -151,7 +151,7 @@ public class FollowerController : ApiController
|
|||||||
if (q.birthday2.HasValue)
|
if (q.birthday2.HasValue)
|
||||||
qry = qry.Where(o => o.birthday < Convert.ToDateTime(q.birthday2.Value).AddDays(1));
|
qry = qry.Where(o => o.birthday < Convert.ToDateTime(q.birthday2.Value).AddDays(1));
|
||||||
if (!string.IsNullOrEmpty(q.address))
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
qry = qry.Where(o => o.address !=null && o.address.Contains(q.address?.Trim()));
|
qry = qry.Where(o => o.address !=null && o.address.Contains(q.address.Trim()));
|
||||||
//if (q.num.HasValue && q.num.Value>0)
|
//if (q.num.HasValue && q.num.Value>0)
|
||||||
// qry = qry.Where(o => o.num==q.num.Value);
|
// qry = qry.Where(o => o.num==q.num.Value);
|
||||||
if (q.ept_self.HasValue && q.ept_self.Value )//排除自己
|
if (q.ept_self.HasValue && q.ept_self.Value )//排除自己
|
||||||
@@ -215,9 +215,10 @@ public class FollowerController : ApiController
|
|||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
f_number = x.f_number,
|
f_number = x.f_number,
|
||||||
@@ -339,9 +340,9 @@ public class FollowerController : ApiController
|
|||||||
|
|
||||||
//int ccc = cc.Count();
|
//int ccc = cc.Count();
|
||||||
|
|
||||||
|
// 優化:使用子查詢在數據庫層面執行,避免載入所有家族成員 ID
|
||||||
|
// 生成 SQL: WHERE num IN (SELECT...) OR leader IN (SELECT...)
|
||||||
var qry = _db.followers.AsEnumerable().Where(f => cc.Any(x => x == f.num) || cc.Any(x => x == f.leader));
|
var qry = _db.followers.Where(f => cc.Contains(f.num) || (f.leader.HasValue && cc.Contains(f.leader.Value)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -359,11 +360,12 @@ public class FollowerController : ApiController
|
|||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||||
int i = 1;
|
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
int i = 1;
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -524,13 +526,14 @@ public class FollowerController : ApiController
|
|||||||
if (_follower > 0)
|
if (_follower > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
var qry = _db.followers_tablet.AsEnumerable().Where(x=>( x.f_num??0) == _follower);
|
var qry = _db.followers_tablet.Where(x=> x.f_num == _follower);
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -593,7 +596,7 @@ public class FollowerController : ApiController
|
|||||||
[Route("api/follower/tabletDelete/{id}")]
|
[Route("api/follower/tabletDelete/{id}")]
|
||||||
public void tabletDelete(int id)
|
public void tabletDelete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.followers_tablet.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.followers_tablet.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.followers_tablet.Remove(prod);
|
_db.followers_tablet.Remove(prod);
|
||||||
|
|||||||
184
web/App_Code/api/HandleBedInUsedController.cs
Normal file
184
web/App_Code/api/HandleBedInUsedController.cs
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
using Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Web.Http.Results;
|
||||||
|
using static GuaDanStatusCode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HandleBedInUsedController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class HandleBedInUsedController : ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public HandleBedInUsedController()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed/inuse/list")]
|
||||||
|
public IHttpActionResult Get([FromBody] UuidModel uuidModel)
|
||||||
|
{
|
||||||
|
//獲取已被預約或者正在入住的床位,如果有指定就會查詢指定條件,如果沒有指定就會返回所有
|
||||||
|
var query = _db.GuaDanOrderGuest
|
||||||
|
.Where(gd => gd.StatusCode == GuaDanStatusCode.Guadan.CheckedIn
|
||||||
|
|| gd.StatusCode == GuaDanStatusCode.Guadan.Booked).ToList();
|
||||||
|
if (uuidModel.bedUuid.HasValue)
|
||||||
|
{
|
||||||
|
// 優先按床位查詢
|
||||||
|
query = query.Where(g => g.BedUuid == uuidModel.bedUuid.Value).ToList();
|
||||||
|
}
|
||||||
|
else if (uuidModel.roomUuid.HasValue)
|
||||||
|
{
|
||||||
|
// 如果沒有 bed,但有 room
|
||||||
|
query = query.Where(g => g.RoomUuid == uuidModel.roomUuid.Value).ToList();
|
||||||
|
}
|
||||||
|
else if (uuidModel.regionUuid.HasValue)
|
||||||
|
{
|
||||||
|
// 如果只有 region
|
||||||
|
//query = query.Where(g => g.Room.RegionUuid == uuidModel.regionUuid.Value);
|
||||||
|
query = query.Where(g => IsRegionOrAncestor(g.Room, uuidModel.regionUuid.Value)).ToList();
|
||||||
|
|
||||||
|
}
|
||||||
|
var data = query.Select(g => new
|
||||||
|
{
|
||||||
|
g.BedUuid,
|
||||||
|
g.RoomUuid,
|
||||||
|
g.Room.RegionUuid,
|
||||||
|
g.GuaDanOrderNo,
|
||||||
|
g.RegionRoomBed.Name,
|
||||||
|
fullName = GetFullBedName(g.BedUuid.Value),
|
||||||
|
g.followers.u_name,
|
||||||
|
guadan_during = new { g.CheckInAt, g.CheckOutAt },
|
||||||
|
status = new { g.StatusCode, g.RegionRoomBedStatus.Name }
|
||||||
|
});
|
||||||
|
return Ok(data.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/bed/inuse/cancel/singlebed/booking")]
|
||||||
|
public IHttpActionResult CancelSingleBedBooking([FromBody] UuidModel uuidModel)
|
||||||
|
{
|
||||||
|
if (uuidModel?.bedUuid == null)
|
||||||
|
return BadRequest("床位ID不能為空");
|
||||||
|
|
||||||
|
using (var transaction = _db.Database.BeginTransaction())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 查詢符合條件的訂單
|
||||||
|
var orders = _db.GuaDanOrderGuest
|
||||||
|
.Where(g => g.BedUuid == uuidModel.bedUuid)
|
||||||
|
.Where(g => g.StatusCode == GuaDanStatusCode.Guadan.Booked || g.StatusCode == GuaDanStatusCode.Guadan.CheckedIn)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (!orders.Any())
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
// 更新狀態
|
||||||
|
foreach (var order in orders)
|
||||||
|
{
|
||||||
|
if (!StatusTransitionManager.CanTransition(order.StatusCode, GuaDanStatusCode.Guadan.Cancelled))
|
||||||
|
{
|
||||||
|
return BadRequest("當前狀態不能被取消");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
order.StatusCode = GuaDanStatusCode.Guadan.Cancelled; // 假設Cancelled是取消狀態
|
||||||
|
}
|
||||||
|
var schedules = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.TargetUuid == uuidModel.bedUuid)
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode == GuaDanStatusCode.Guadan.Booked
|
||||||
|
|| s.GuaDanOrderGuest.StatusCode == GuaDanStatusCode.Guadan.CheckedIn)
|
||||||
|
.ToList();
|
||||||
|
foreach (var schedule in schedules)
|
||||||
|
{
|
||||||
|
schedule.IsCancel = true;
|
||||||
|
}
|
||||||
|
_db.SaveChanges();
|
||||||
|
transaction.Commit();
|
||||||
|
|
||||||
|
return Ok(new { message = "取消成功", cancelledCount = orders.Count });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/bed/inuse/region/list")]
|
||||||
|
public IHttpActionResult GetRegionList()
|
||||||
|
{
|
||||||
|
var regions = _db.Region
|
||||||
|
.Select(r => new
|
||||||
|
{
|
||||||
|
r.Uuid,
|
||||||
|
r.Name,
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
return Ok(regions);
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/bed/inuse/room/list")]
|
||||||
|
public IHttpActionResult GetRoomList([FromUri] Guid? regionUuid = null)
|
||||||
|
{
|
||||||
|
var room = _db.Room.Where(r => !r.IsDeleted && r.IsActive.Value).ToList();
|
||||||
|
if (regionUuid != null)
|
||||||
|
{
|
||||||
|
room = room.Where(r => IsRegionOrAncestor(r, regionUuid.Value)).ToList();
|
||||||
|
}
|
||||||
|
var data = room.Select(r => new
|
||||||
|
{
|
||||||
|
r.Uuid,
|
||||||
|
r.Name,
|
||||||
|
fullName = r.Region.Name + "/" + r.Name,
|
||||||
|
}).ToList();
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
public string GetFullBedName(Guid bedUuid)
|
||||||
|
{
|
||||||
|
var bed = _db.RegionRoomBed.Find(bedUuid);
|
||||||
|
if (bed == null)
|
||||||
|
return "";
|
||||||
|
var name = bed.Name;
|
||||||
|
var room = bed.Room;
|
||||||
|
if (room == null)
|
||||||
|
return name;
|
||||||
|
name = room.Name + "/" + name;
|
||||||
|
|
||||||
|
var region = room?.Region;
|
||||||
|
while (region != null)
|
||||||
|
{
|
||||||
|
name = region.Name + "/" + name;
|
||||||
|
region = region.Region2; // 遞迴向上
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
bool IsRegionOrAncestor(Model.Room room, Guid regionUuid)
|
||||||
|
{
|
||||||
|
//判斷傳入的regionuuid是否是room的祖先
|
||||||
|
if (room.RegionUuid == regionUuid)
|
||||||
|
return true;
|
||||||
|
var region = room.Region;
|
||||||
|
while (region != null)
|
||||||
|
{
|
||||||
|
if (region.Uuid == regionUuid) return true;
|
||||||
|
region = region.Region2;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public class UuidModel
|
||||||
|
{
|
||||||
|
public Guid? regionUuid = null;
|
||||||
|
public Guid? roomUuid = null;
|
||||||
|
public Guid? bedUuid = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,9 +74,11 @@ public class ShuWenController : ApiController
|
|||||||
{
|
{
|
||||||
shuwen.ShuWenList = ProcessDesserts2(_db.pro_order_detail.Where(a => a.pro_order.activity_num == activitynum.Value).ToList());
|
shuwen.ShuWenList = ProcessDesserts2(_db.pro_order_detail.Where(a => a.pro_order.activity_num == activitynum.Value).ToList());
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
shuwen.IsGenerating = false;
|
||||||
|
_db.SaveChanges();
|
||||||
|
return BadRequest("生成舒文失败:" + ex.Message);
|
||||||
}
|
}
|
||||||
shuwen.IsGenerating = false;
|
shuwen.IsGenerating = false;
|
||||||
shuwen.UpdateTime = DateTime.Now;
|
shuwen.UpdateTime = DateTime.Now;
|
||||||
@@ -221,17 +223,19 @@ public class ShuWenController : ApiController
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/shuwen/download")]
|
[Route("api/shuwen/download")]
|
||||||
public HttpResponseMessage DownloadShuWenWord(int? activitynum)
|
public HttpResponseMessage DownloadShuWenWord(int? activitynum)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var data = _db.ShuWen.Where(a => a.ActivityNum == activitynum).FirstOrDefault();
|
var data = _db.ShuWen.Where(a => a.ActivityNum == activitynum).FirstOrDefault();
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
//return;
|
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "活動編號不能為空");
|
||||||
}
|
}
|
||||||
string json = data.ShuWenList;
|
string json = data.ShuWenList;
|
||||||
string ActivityName = _db.activities.Where(a => a.num == data.ActivityNum).FirstOrDefault().subject;
|
string ActivityName = _db.activities.Where(a => a.num == data.ActivityNum).FirstOrDefault().subject;
|
||||||
if (json == null)
|
if (json == null)
|
||||||
{
|
{
|
||||||
//return;
|
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "疏文列表为空,无法生成 Word");
|
||||||
}
|
}
|
||||||
string fileName = $"疏文名單_{DateTime.Now:yyyyMMddHHmmss}.docx";
|
string fileName = $"疏文名單_{DateTime.Now:yyyyMMddHHmmss}.docx";
|
||||||
|
|
||||||
@@ -251,6 +255,12 @@ public class ShuWenController : ApiController
|
|||||||
};
|
};
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void GenerateShuWenWord_OpenXml(string json, Stream outputStream, string ActivityName ="")
|
public void GenerateShuWenWord_OpenXml(string json, Stream outputStream, string ActivityName ="")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class accountingController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.accountings.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.accountings.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
var prod2 = prod.accounting_files;
|
var prod2 = prod.accounting_files;
|
||||||
@@ -89,12 +89,12 @@ public class accountingController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
|
|
||||||
var prod = _db.accountings.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
var prod = _db.accountings.Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
var prod2 = _db.accounting_files.AsEnumerable().Where(q => q.accounting_num.HasValue && getDelItem.Contains(q.accounting_num.Value)).ToList();
|
var prod2 = _db.accounting_files.Where(q => q.accounting_num.HasValue && getDelItem.Contains(q.accounting_num.Value)).ToList();
|
||||||
if (prod2.Count() > 0)
|
if (prod2.Count() > 0)
|
||||||
{
|
{
|
||||||
publicFun publicFun = new publicFun();
|
publicFun publicFun = new publicFun();
|
||||||
@@ -126,7 +126,7 @@ public class accountingController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.accounting q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.accounting q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.accountings.AsEnumerable();
|
var qry = _db.accountings.AsQueryable();
|
||||||
|
|
||||||
if (q.category.HasValue)
|
if (q.category.HasValue)
|
||||||
qry = qry.Where(o => o.category == q.category.Value);
|
qry = qry.Where(o => o.category == q.category.Value);
|
||||||
@@ -215,10 +215,12 @@ public class accountingController : BaseApiController
|
|||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.accounting.type>();
|
var tdesc = publicFun.enum_desc<Model.accounting.type>();
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
category = x.category,
|
category = x.category,
|
||||||
@@ -245,7 +247,7 @@ public class accountingController : BaseApiController
|
|||||||
total =(x.price ?? 0)+( x.tax?? 0),
|
total =(x.price ?? 0)+( x.tax?? 0),
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -259,7 +261,7 @@ public class accountingController : BaseApiController
|
|||||||
public IHttpActionResult GetTitleKindList([FromBody] Model.ViewModel.accounting_kind q, int page, int pageSize = 10,
|
public IHttpActionResult GetTitleKindList([FromBody] Model.ViewModel.accounting_kind q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.accounting_kind.AsEnumerable();
|
var qry = _db.accounting_kind.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -297,7 +299,7 @@ public class accountingController : BaseApiController
|
|||||||
public IHttpActionResult GetAccountKindList([FromBody] Model.ViewModel.accounting_kind2 q, int page, int pageSize = 10,
|
public IHttpActionResult GetAccountKindList([FromBody] Model.ViewModel.accounting_kind2 q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.accounting_kind2.AsEnumerable();
|
var qry = _db.accounting_kind2.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -341,15 +343,16 @@ public class accountingController : BaseApiController
|
|||||||
if (q.accounting_num.HasValue && q.accounting_num.Value > 0)
|
if (q.accounting_num.HasValue && q.accounting_num.Value > 0)
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var qry = _db.accounting_files.AsEnumerable();
|
var qry = _db.accounting_files.Where(o => o.accounting_num == q.accounting_num.Value);
|
||||||
qry = qry.Where(o => o.accounting_num == q.accounting_num.Value);
|
qry = qry.OrderByDescending(x => x.num);
|
||||||
qry.OrderByDescending(x => x.num);
|
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
//已有值
|
//已有值
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -357,7 +360,7 @@ public class accountingController : BaseApiController
|
|||||||
pic1 = x.pic1,
|
pic1 = x.pic1,
|
||||||
pic1_name = x.pic1_name,
|
pic1_name = x.pic1_name,
|
||||||
}),
|
}),
|
||||||
count = qry.Count(),
|
count = count,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
@@ -473,7 +476,7 @@ public class accountingController : BaseApiController
|
|||||||
[Route("api/accounting/DeleteFilesItem/{id}")]//刪除相關檔案
|
[Route("api/accounting/DeleteFilesItem/{id}")]//刪除相關檔案
|
||||||
public void DeleteFilesItem(int id)
|
public void DeleteFilesItem(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.accounting_files.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.accounting_files.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(prod.pic1))
|
if (!string.IsNullOrEmpty(prod.pic1))
|
||||||
|
|||||||
@@ -63,17 +63,17 @@ public class activityController : ApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.activities.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activities.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//刪除相關資料
|
//刪除相關資料
|
||||||
var prod2 = _db.activity_relating.AsEnumerable().Where(q => q.activity_num == id).ToList(); //相關項目
|
var prod2 = _db.activity_relating.Where(q => q.activity_num == id).ToList(); //相關項目
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
//查詢結果全部刪除
|
//查詢結果全部刪除
|
||||||
_db.activity_relating.RemoveRange(prod2);
|
_db.activity_relating.RemoveRange(prod2);
|
||||||
}
|
}
|
||||||
var prod3 = _db.activity_spares.AsEnumerable().Where(q => q.activity_num == id).ToList(); //備品項目
|
var prod3 = _db.activity_spares.Where(q => q.activity_num == id).ToList(); //備品項目
|
||||||
if (prod3.Count > 0)
|
if (prod3.Count > 0)
|
||||||
{
|
{
|
||||||
_db.activity_spares.RemoveRange(prod3);
|
_db.activity_spares.RemoveRange(prod3);
|
||||||
@@ -98,7 +98,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/DeleteItem/{id}")]
|
[Route("api/activity/DeleteItem/{id}")]
|
||||||
public void DeleteItem(int id)
|
public void DeleteItem(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.actItems.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.actItems.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
/*if (prod != null)
|
/*if (prod != null)
|
||||||
{
|
{
|
||||||
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => q.actItem_num == id).ToList(); //相關項目
|
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => q.actItem_num == id).ToList(); //相關項目
|
||||||
@@ -144,11 +144,11 @@ public class activityController : ApiController
|
|||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
||||||
|
|
||||||
var prod = _db.activities.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.activities.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
//var prod2 = _db.activity_relating.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.activity_num))).ToList();
|
//var prod2 = _db.activity_relating.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.activity_num))).ToList();
|
||||||
var prod2 = _db.activity_relating.AsEnumerable().Where(q => ids.Any(x => x == q.activity_num)).ToList();
|
var prod2 = _db.activity_relating.Where(q => ids.Contains(q.activity_num)).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
_db.activity_relating.RemoveRange(prod2);
|
_db.activity_relating.RemoveRange(prod2);
|
||||||
@@ -156,7 +156,7 @@ public class activityController : ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
//var prod3 = _db.activity_spares.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.activity_num))).ToList();
|
//var prod3 = _db.activity_spares.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.activity_num))).ToList();
|
||||||
var prod3 = _db.activity_spares.AsEnumerable().Where(q => ids.Any(x => x == q.activity_num)).ToList();
|
var prod3 = _db.activity_spares.Where(q => ids.Contains(q.activity_num)).ToList();
|
||||||
if (prod3.Count > 0)
|
if (prod3.Count > 0)
|
||||||
{
|
{
|
||||||
_db.activity_spares.RemoveRange(prod3);
|
_db.activity_spares.RemoveRange(prod3);
|
||||||
@@ -186,11 +186,11 @@ public class activityController : ApiController
|
|||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
||||||
var prod = _db.actItems.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.actItems.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.actItem_num))).ToList();
|
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.actItem_num))).ToList();
|
||||||
var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Any(x => x == q.actItem_num)).ToList();
|
var prod2 = _db.actItem_files.Where(q => ids.Contains(q.actItem_num)).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
_db.actItem_files.RemoveRange(prod2);
|
_db.actItem_files.RemoveRange(prod2);
|
||||||
@@ -281,10 +281,10 @@ public class activityController : ApiController
|
|||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
subject = x.subject,
|
subject = x.subject,
|
||||||
@@ -319,7 +319,7 @@ public class activityController : ApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
//var stockDt = _db.stocks.AsEnumerable(); ;//庫存
|
//var stockDt = _db.stocks.AsEnumerable(); ;//庫存
|
||||||
var fileDt = _db.files.AsEnumerable().Where(f => f.subject.Contains(q.fileTxt)).Select(f => f.num.ToString());//文件
|
var fileDt = _db.files.Where(f => f.subject.Contains(q.fileTxt)).Select(f => f.num.ToString());//文件
|
||||||
|
|
||||||
//每個品項在每個倉庫的結餘量
|
//每個品項在每個倉庫的結餘量
|
||||||
var stockDt = (
|
var stockDt = (
|
||||||
@@ -364,7 +364,7 @@ public class activityController : ApiController
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(q.kindTxt))
|
if (!string.IsNullOrEmpty(q.kindTxt))
|
||||||
qry = qry.Where(o => o.actItem_kind?.kind != null && o.actItem_kind.kind.Contains(q.kindTxt));
|
qry = qry.Where(o => o.actItem_kind != null && o.actItem_kind.kind != null && o.actItem_kind.kind.Contains(q.kindTxt));
|
||||||
if (q.category.HasValue && q.category.Value > 0)
|
if (q.category.HasValue && q.category.Value > 0)
|
||||||
qry = qry.Where(o => o.category == q.category.Value);
|
qry = qry.Where(o => o.category == q.category.Value);
|
||||||
if (!string.IsNullOrEmpty(q.categorys))
|
if (!string.IsNullOrEmpty(q.categorys))
|
||||||
@@ -410,10 +410,10 @@ public class activityController : ApiController
|
|||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
subject = x.subject,
|
subject = x.subject,
|
||||||
@@ -711,7 +711,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/DeleteFilesItem/{id}")]//刪除品項的相關文件
|
[Route("api/activity/DeleteFilesItem/{id}")]//刪除品項的相關文件
|
||||||
public void DeleteFilesItem(int id)
|
public void DeleteFilesItem(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.actItem_files.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.actItem_files.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -731,16 +731,15 @@ public class activityController : ApiController
|
|||||||
if (this_id > 0)
|
if (this_id > 0)
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var qry = _db.activity_kind_detail.AsEnumerable();
|
var qry = _db.activity_kind_detail.Where(o => o.activity_kind_num == this_id);
|
||||||
qry = qry.Where(o => o.activity_kind_num == this_id);
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
//已有值
|
//已有值
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -830,7 +829,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/DeleteActKindDetail/{id}")]//刪除活動分類的detail
|
[Route("api/activity/DeleteActKindDetail/{id}")]//刪除活動分類的detail
|
||||||
public void DeleteActKindDetail(int id)
|
public void DeleteActKindDetail(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.activity_kind_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activity_kind_detail.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -849,7 +848,7 @@ public class activityController : ApiController
|
|||||||
if (this_act_id > 0)
|
if (this_act_id > 0)
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var prod = _db.activities.AsEnumerable().Where(o => o.num == this_act_id).FirstOrDefault();
|
var prod = _db.activities.Where(o => o.num == this_act_id).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
int kind = prod.kind ?? 0; //分類
|
int kind = prod.kind ?? 0; //分類
|
||||||
@@ -927,13 +926,12 @@ public class activityController : ApiController
|
|||||||
if (kind > 0)
|
if (kind > 0)
|
||||||
{
|
{
|
||||||
int i = 1;
|
int i = 1;
|
||||||
var qry2 = _db.activity_kind_detail.AsEnumerable();
|
var qry2 = _db.activity_kind_detail.Where(o => o.activity_kind_num == kind);
|
||||||
qry2 = qry2.Where(o => o.activity_kind_num == kind);
|
|
||||||
var count2 = qry2.Count(); //pageSize = count2;//一次取回??
|
var count2 = qry2.Count(); //pageSize = count2;//一次取回??
|
||||||
if (pageSize > 0) qry2 = qry2.ToPagedList(page, pageSize);
|
var qry2List = (pageSize > 0) ? qry2.ToPagedList(page, pageSize).ToList() : qry2.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry2.Select(x => new
|
list = qry2List.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = 0,
|
num = 0,
|
||||||
@@ -992,7 +990,7 @@ public class activityController : ApiController
|
|||||||
public IHttpActionResult GetKindList([FromBody] Model.ViewModel.activity_kind q,
|
public IHttpActionResult GetKindList([FromBody] Model.ViewModel.activity_kind q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.activity_kind.AsEnumerable();
|
var qry = _db.activity_kind.AsQueryable();
|
||||||
if (q.num.HasValue && q.num > 0)
|
if (q.num.HasValue && q.num > 0)
|
||||||
qry = qry.Where(o => o.num == q.num);
|
qry = qry.Where(o => o.num == q.num);
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
@@ -1031,7 +1029,7 @@ public class activityController : ApiController
|
|||||||
{
|
{
|
||||||
if (id > 0)
|
if (id > 0)
|
||||||
{
|
{
|
||||||
var qry = _db.activity_kind.AsEnumerable();
|
var qry = _db.activity_kind.AsQueryable();
|
||||||
qry = qry.Where(o => o.num == id);
|
qry = qry.Where(o => o.num == id);
|
||||||
var prop3 = qry.FirstOrDefault();
|
var prop3 = qry.FirstOrDefault();
|
||||||
if (prop3 != null)
|
if (prop3 != null)
|
||||||
@@ -1151,7 +1149,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/DeleteRelatingData/{id}")]//刪除活動的相關資料
|
[Route("api/activity/DeleteRelatingData/{id}")]//刪除活動的相關資料
|
||||||
public void DeleteRelatingData(int id)
|
public void DeleteRelatingData(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.activity_relating.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activity_relating.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1169,25 +1167,22 @@ public class activityController : ApiController
|
|||||||
if (this_act_id > 0)
|
if (this_act_id > 0)
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var prod = _db.activities.AsEnumerable().Where(o => o.num == this_act_id).FirstOrDefault();
|
var prod = _db.activities.Where(o => o.num == this_act_id).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
int kind = prod.kind ?? 0; //分類
|
int kind = prod.kind ?? 0; //分類
|
||||||
|
|
||||||
var qry1 = _db.activity_spares.AsEnumerable();
|
var qry1 = _db.activity_spares.Where(o => o.activity_num == this_act_id).OrderBy(o => o.num);
|
||||||
qry1 = qry1.Where(o => o.activity_num == this_act_id);
|
|
||||||
|
|
||||||
qry1 = qry1.OrderBy(o => o.num);
|
|
||||||
|
|
||||||
|
|
||||||
var count = qry1.Count(); //pageSize = count;//一次取回??
|
var count = qry1.Count(); //pageSize = count;//一次取回??
|
||||||
int i = 1;
|
int i = 1;
|
||||||
if (pageSize > 0) qry1 = qry1.ToPagedList(page, pageSize);
|
var qry1List = (pageSize > 0) ? qry1.ToPagedList(page, pageSize).ToList() : qry1.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry1.Select(x => new
|
list = qry1List.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -1278,7 +1273,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/DeleteSparesData/{id}")]//刪除活動的備品資料
|
[Route("api/activity/DeleteSparesData/{id}")]//刪除活動的備品資料
|
||||||
public void DeleteSparesData(int id)
|
public void DeleteSparesData(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.activity_spares.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activity_spares.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1388,10 +1383,10 @@ public class activityController : ApiController
|
|||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.activity_check.keyin1>();
|
var tdesc = publicFun.enum_desc<Model.activity_check.keyin1>();
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
subject = x.activity?.subject,
|
subject = x.activity?.subject,
|
||||||
@@ -1416,7 +1411,7 @@ public class activityController : ApiController
|
|||||||
[Route("api/activity/DeleteCheck/{id}")]
|
[Route("api/activity/DeleteCheck/{id}")]
|
||||||
public void DeleteCheck(int id)
|
public void DeleteCheck(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.activity_check.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activity_check.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1439,7 +1434,7 @@ public class activityController : ApiController
|
|||||||
if (!string.IsNullOrEmpty(num[i]))
|
if (!string.IsNullOrEmpty(num[i]))
|
||||||
ids[i] = Convert.ToInt32(num[i]);
|
ids[i] = Convert.ToInt32(num[i]);
|
||||||
}
|
}
|
||||||
var prod = _db.activity_check.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.activity_check.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1458,7 +1453,7 @@ public class activityController : ApiController
|
|||||||
{
|
{
|
||||||
DateTime _now = DateTime.Now;
|
DateTime _now = DateTime.Now;
|
||||||
|
|
||||||
var qry = _db.activities.AsEnumerable();
|
var qry = _db.activities.AsQueryable();
|
||||||
|
|
||||||
if (q.reg_time1.HasValue)
|
if (q.reg_time1.HasValue)
|
||||||
qry = qry.Where(o => o.reg_time >= q.reg_time1.Value);
|
qry = qry.Where(o => o.reg_time >= q.reg_time1.Value);
|
||||||
@@ -1466,7 +1461,7 @@ public class activityController : ApiController
|
|||||||
qry = qry.Where(o => o.reg_time < Convert.ToDateTime(q.reg_time2.Value).AddDays(1));
|
qry = qry.Where(o => o.reg_time < Convert.ToDateTime(q.reg_time2.Value).AddDays(1));
|
||||||
|
|
||||||
|
|
||||||
qry = qry.Where(o => (_now >= o.startDate_solar && _now < o.endDate_lunar) || (_now < o.startDate_solar && o.dueDate?.Date.CompareTo(_now) <= 180));
|
qry = qry.Where(o => (_now >= o.startDate_solar && _now < o.endDate_lunar) || (_now < o.startDate_solar && o.dueDate.HasValue && o.dueDate.Value.Date.CompareTo(_now) <= 180));
|
||||||
|
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
@@ -1510,7 +1505,7 @@ public class activityController : ApiController
|
|||||||
public IHttpActionResult GetCategoryKindList([FromBody] Model.ViewModel.activity_category_kind q,
|
public IHttpActionResult GetCategoryKindList([FromBody] Model.ViewModel.activity_category_kind q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.activity_category_kind.AsEnumerable();
|
var qry = _db.activity_category_kind.AsQueryable();
|
||||||
if (q.num.HasValue && q.num > 0)
|
if (q.num.HasValue && q.num > 0)
|
||||||
qry = qry.Where(o => o.num == q.num);
|
qry = qry.Where(o => o.num == q.num);
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
@@ -1518,10 +1513,10 @@ public class activityController : ApiController
|
|||||||
qry = qry.OrderBy(O => O.kind).ThenBy(o => o.num);
|
qry = qry.OrderBy(O => O.kind).ThenBy(o => o.num);
|
||||||
|
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
kind = x.kind,
|
kind = x.kind,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class activity_kindController : ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.actItem_kind q,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.actItem_kind q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.actItem_kind.AsEnumerable();
|
var qry = _db.actItem_kind.AsQueryable();
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
if (!string.IsNullOrEmpty(q.status))
|
if (!string.IsNullOrEmpty(q.status))
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class adminUserController : ApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.admins.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.admins.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ public class adminUserController : ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.admin q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.admin q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.admins.AsEnumerable();
|
var qry = _db.admins.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.u_id))
|
if (!string.IsNullOrEmpty(q.u_id))
|
||||||
qry = qry.Where(o => o.u_id.Contains(q.u_id));
|
qry = qry.Where(o => o.u_id.Contains(q.u_id));
|
||||||
@@ -90,17 +90,15 @@ public class adminUserController : ApiController
|
|||||||
|
|
||||||
if(q.removeExist.HasValue && q.removeExist.Value)
|
if(q.removeExist.HasValue && q.removeExist.Value)
|
||||||
{
|
{
|
||||||
|
// 優化:使用子查詢在數據庫層面執行,避免載入所有會員的 admin_num
|
||||||
|
var usedAdminNums = _db.members.Select(b => b.admin_num);
|
||||||
if (q.num.HasValue && q.num.Value > 0)
|
if (q.num.HasValue && q.num.Value > 0)
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => (!(from b in _db.members.AsEnumerable()
|
qry = qry.Where(o => !usedAdminNums.Contains(o.num) || o.num == q.num.Value);
|
||||||
select b.admin_num)
|
|
||||||
.Contains(o.num)) || o.num == Convert.ToInt32(q.num.Value));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => (!(from b in _db.members.AsEnumerable()
|
qry = qry.Where(o => !usedAdminNums.Contains(o.num));
|
||||||
select b.admin_num)
|
|
||||||
.Contains(o.num)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,9 +112,12 @@ public class adminUserController : ApiController
|
|||||||
else
|
else
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
u_id = x.u_id,
|
u_id = x.u_id,
|
||||||
@@ -124,7 +125,7 @@ public class adminUserController : ApiController
|
|||||||
power = x.power,
|
power = x.power,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -44,19 +44,22 @@ public class appellationController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.appellation q,
|
public IHttpActionResult GetList([FromBody] Model.appellation q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.appellations.AsEnumerable();
|
var qry = _db.appellations.AsQueryable();
|
||||||
|
|
||||||
|
|
||||||
qry = qry.OrderBy(o => o.num);
|
qry = qry.OrderBy(o => o.num);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
title = x.title,
|
title = x.title,
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class bedController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(string id)
|
public void Delete(string id)
|
||||||
{
|
{
|
||||||
var prod = _db.bed_order.AsEnumerable().Where(q => q.bed_order_no == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.bed_order.Where(q => q.bed_order_no == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//刪除訂單明細
|
//刪除訂單明細
|
||||||
@@ -80,7 +80,7 @@ public class bedController : BaseApiController
|
|||||||
{
|
{
|
||||||
order_no = "ED" + DateTime.Now.ToString("yyMMdd");
|
order_no = "ED" + DateTime.Now.ToString("yyMMdd");
|
||||||
|
|
||||||
var qry = _db.companies.AsEnumerable();
|
var qry = _db.companies.AsQueryable();
|
||||||
var prod = qry.Where(q => q.num == 1).FirstOrDefault();
|
var prod = qry.Where(q => q.num == 1).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -157,16 +157,18 @@ public class bedController : BaseApiController
|
|||||||
public IHttpActionResult GetDetailList([FromBody] Model.bed_order q,
|
public IHttpActionResult GetDetailList([FromBody] Model.bed_order q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.bed_order_detail.AsEnumerable();
|
var qry = _db.bed_order_detail.Where(o => o.bed_order_no == q.bed_order_no);
|
||||||
qry = qry.Where(o => o.bed_order_no == q.bed_order_no);
|
|
||||||
|
|
||||||
qry = qry.OrderBy(o => o.checkIn_date ).ThenBy(o => o.num);
|
qry = qry.OrderBy(o => o.checkIn_date ).ThenBy(o => o.num);
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
var tdesc = publicFun.enum_desc<Model.bed_kind.bed_type>();
|
var tdesc = publicFun.enum_desc<Model.bed_kind.bed_type>();
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -197,7 +199,7 @@ public class bedController : BaseApiController
|
|||||||
},
|
},
|
||||||
license = x.license,
|
license = x.license,
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
@@ -250,7 +252,7 @@ public class bedController : BaseApiController
|
|||||||
[Route("api/bed/DeleteBedDetail/{id}")]//刪除detail
|
[Route("api/bed/DeleteBedDetail/{id}")]//刪除detail
|
||||||
public void DeleteBedDetail(int id)
|
public void DeleteBedDetail(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.bed_order_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.bed_order_detail.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class bed_kindController : ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.bed_kind q,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.bed_kind q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.bed_kind.AsEnumerable();
|
var qry = _db.bed_kind.AsQueryable();
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
if (!string.IsNullOrEmpty(q.sex))
|
if (!string.IsNullOrEmpty(q.sex))
|
||||||
@@ -60,16 +60,20 @@ public class bed_kindController : ApiController
|
|||||||
if (q.root.HasValue)
|
if (q.root.HasValue)
|
||||||
qry = qry.Where(o => o.root.Value == q.root.Value);
|
qry = qry.Where(o => o.root.Value == q.root.Value);
|
||||||
qry = qry.OrderBy(o => o.range).ThenBy(o => o.num);
|
qry = qry.OrderBy(o => o.range).ThenBy(o => o.num);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
kind = x.kind,
|
kind = x.kind,
|
||||||
sex = x.sex,
|
sex = x.sex,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
@@ -83,7 +87,7 @@ public class bed_kindController : ApiController
|
|||||||
var tdesc = publicFun.enum_desc<Model.bed_kind.bed_type>();
|
var tdesc = publicFun.enum_desc<Model.bed_kind.bed_type>();
|
||||||
//var tdesc2 = tdesc.ToArray().Select(x=>x.Value); //[0]單人床,[1]雙人床
|
//var tdesc2 = tdesc.ToArray().Select(x=>x.Value); //[0]單人床,[1]雙人床
|
||||||
//var tdesc3 = tdesc.ToArray().Select(x=>x.Key); //[0]1,[1]2
|
//var tdesc3 = tdesc.ToArray().Select(x=>x.Key); //[0]1,[1]2
|
||||||
var qry = _db.bed_kind_detail.AsEnumerable();
|
var qry = _db.bed_kind_detail.AsQueryable();
|
||||||
if (q.bed_kind_id.HasValue)
|
if (q.bed_kind_id.HasValue)
|
||||||
qry = qry.Where(o => o.bed_kind_id == q.bed_kind_id);
|
qry = qry.Where(o => o.bed_kind_id == q.bed_kind_id);
|
||||||
if (!string.IsNullOrEmpty(q.bed_name))
|
if (!string.IsNullOrEmpty(q.bed_name))
|
||||||
@@ -103,17 +107,19 @@ public class bed_kindController : ApiController
|
|||||||
if (q.inTime.HasValue )
|
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());//掛單表單明細
|
var bedDt = _db.bed_order_detail.Where(f => f.checkIn_date.HasValue && f.checkIn_date ==q.inTime.Value && f.bed_kind_detail_id.HasValue).Select(f => f.bed_kind_detail_id.Value).ToList();//掛單表單明細
|
||||||
qry = qry.Where(o => !bedDt.ToArray().Contains(o.num.ToString()));
|
qry = qry.Where(o => !bedDt.Contains(o.num));
|
||||||
|
|
||||||
}
|
}
|
||||||
qry = qry.OrderBy(o => o.bed_name);
|
qry = qry.OrderBy(o => o.bed_name);
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
if (pageSize > 0) qry = qry.ToPagedList(page, pageSize);
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -122,7 +128,7 @@ public class bed_kindController : ApiController
|
|||||||
bed_type_txt = x.bed_type.HasValue? tdesc[x.bed_type ?? 1] : "",
|
bed_type_txt = x.bed_type.HasValue? tdesc[x.bed_type ?? 1] : "",
|
||||||
demo = x.demo,
|
demo = x.demo,
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
@@ -186,7 +192,7 @@ public class bed_kindController : ApiController
|
|||||||
[Route("api/bed_kind/DeleteBedKindDetail/{id}")]//刪除分類的detail
|
[Route("api/bed_kind/DeleteBedKindDetail/{id}")]//刪除分類的detail
|
||||||
public void DeleteActKindDetail(int id)
|
public void DeleteActKindDetail(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.bed_kind_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.bed_kind_detail.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -44,22 +44,25 @@ public class countryController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.country q,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.country q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.countries.AsEnumerable();
|
var qry = _db.countries.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.keyword))
|
if (!string.IsNullOrEmpty(q.keyword))
|
||||||
qry = qry.Where(o => o.ID.Contains(q.keyword.Trim()) || o.name_en.Contains(q.keyword.Trim()) || o.name_zh.Contains(q.keyword.Trim()));
|
qry = qry.Where(o => o.ID.Contains(q.keyword.Trim()) || o.name_en.Contains(q.keyword.Trim()) || o.name_zh.Contains(q.keyword.Trim()));
|
||||||
|
|
||||||
qry = qry.OrderBy(o => o.range).ThenBy(o => o.name_en);
|
qry = qry.OrderBy(o => o.range).ThenBy(o => o.name_en);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = x.ID,
|
id = x.ID,
|
||||||
name_en = x.name_en,
|
name_en = x.name_en,
|
||||||
name_zh = x.name_zh,
|
name_zh = x.name_zh,
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,17 @@ public class familyMembersController : ApiController
|
|||||||
[Route("api/familymembers/follower/{followerId}")]
|
[Route("api/familymembers/follower/{followerId}")]
|
||||||
public IHttpActionResult GetByFollower(int followerId)
|
public IHttpActionResult GetByFollower(int followerId)
|
||||||
{
|
{
|
||||||
|
//var originalLazyLoading = _db.Configuration.LazyLoadingEnabled;
|
||||||
|
//var originalProxyCreation = _db.Configuration.ProxyCreationEnabled;
|
||||||
|
//
|
||||||
|
//_db.Configuration.LazyLoadingEnabled = false;
|
||||||
|
//_db.Configuration.ProxyCreationEnabled = false;
|
||||||
|
|
||||||
var familyMembers = _db.family_members.Where(fm => fm.follower_num == followerId).ToList();
|
var familyMembers = _db.family_members.Where(fm => fm.follower_num == followerId).ToList();
|
||||||
|
|
||||||
|
//_db.Configuration.LazyLoadingEnabled = originalLazyLoading;
|
||||||
|
//_db.Configuration.ProxyCreationEnabled = originalProxyCreation;
|
||||||
|
|
||||||
return Ok(familyMembers);
|
return Ok(familyMembers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
140
web/App_Code/api/guadanGuestQueryController.cs
Normal file
140
web/App_Code/api/guadanGuestQueryController.cs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
using Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// guadanGuestQueryController 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
public class guadanGuestQueryController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public guadanGuestQueryController()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/guadan/guest/query/list")]
|
||||||
|
public async Task<IHttpActionResult> GetList([FromBody] SearchGuestModel search)
|
||||||
|
{
|
||||||
|
var query = _db.GuaDanOrderGuest
|
||||||
|
.Where(guest => guest.StatusCode != "404");
|
||||||
|
if(search.SearchName != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.followers.u_name.Contains(search.SearchName));
|
||||||
|
}
|
||||||
|
if(search.searchCheckInDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.CheckInAt == search.searchCheckInDate);
|
||||||
|
}
|
||||||
|
if(search.searchCheckOutDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.CheckOutAt == search.searchCheckOutDate);
|
||||||
|
}
|
||||||
|
if(search.searchCheckInDateStart != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.CheckInAt >= search.searchCheckInDateStart);
|
||||||
|
}
|
||||||
|
if (search.searchCheckInDateEnd != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.CheckInAt <= search.searchCheckInDateEnd);
|
||||||
|
}
|
||||||
|
if (search.searchCheckOutDateStart != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.CheckOutAt >= search.searchCheckOutDateStart);
|
||||||
|
}
|
||||||
|
if (search.searchCheckOutDateEnd != null)
|
||||||
|
{
|
||||||
|
query = query.Where(guest => guest.CheckOutAt <= search.searchCheckOutDateEnd);
|
||||||
|
}
|
||||||
|
var totalCount = await query.CountAsync();
|
||||||
|
var pagedData = await query
|
||||||
|
.OrderByDescending(a => a.CheckInAt) // 可根据需要排序
|
||||||
|
.Skip((search.Page - 1) * search.PageSize)
|
||||||
|
.Take(search.PageSize)
|
||||||
|
.ToListAsync();
|
||||||
|
var data1 = pagedData.Select(a => new
|
||||||
|
{
|
||||||
|
name = a.followers != null ? a.followers.u_name : null,
|
||||||
|
checkindate = a.CheckInAt,
|
||||||
|
checkoutdate = a.CheckOutAt,
|
||||||
|
guadanorderno = a.GuaDanOrderNo,
|
||||||
|
roomName = GetRoomAndBedString(a.RegionRoomBed),
|
||||||
|
statusName = a.RegionRoomBedStatus.Name
|
||||||
|
}).ToList();
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
items = data1,
|
||||||
|
total = totalCount,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/guadan/guest/checkin/list")]
|
||||||
|
public async Task<IHttpActionResult> GetCheckInGuest([FromUri] DateTime date)
|
||||||
|
{
|
||||||
|
var today = DateTime.Now.Date;
|
||||||
|
var data = await _db.GuaDanOrderGuest
|
||||||
|
.Where(guest => guest.StatusCode == "402" || guest.StatusCode == "403")
|
||||||
|
.Where(guest => guest.RegionAndRoomAndBedSchedule
|
||||||
|
.Any(s => s.ScheduleDate == date.Date && s.ScheduleDate <= today) == true)
|
||||||
|
.Select(guest => new
|
||||||
|
{
|
||||||
|
name = guest.followers.u_name,
|
||||||
|
gender = guest.followers.sex,
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/guadan/guest/booking/list")]
|
||||||
|
public async Task<IHttpActionResult> GetBookingGuest([FromUri] DateTime date)
|
||||||
|
{
|
||||||
|
var data = await _db.GuaDanOrderGuest
|
||||||
|
.Where(guest => guest.StatusCode == "402" || guest.StatusCode == "401" || guest.StatusCode == "403")
|
||||||
|
.Where(guest => guest.RegionAndRoomAndBedSchedule.Any(s => s.ScheduleDate == date.Date) == true)
|
||||||
|
.Select(guest => new
|
||||||
|
{
|
||||||
|
name = guest.followers.u_name,
|
||||||
|
gender = guest.followers.sex,
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
return Ok(data);
|
||||||
|
}
|
||||||
|
public string GetRoomAndBedString(RegionRoomBed bed)
|
||||||
|
{
|
||||||
|
if (bed == null || bed.Room == null) return "";
|
||||||
|
var room = bed.Room;
|
||||||
|
var region = room.Region;
|
||||||
|
var name = room.Name + "/" + bed.Name;
|
||||||
|
if(region != null)
|
||||||
|
{
|
||||||
|
name = region.Name + "/" + name;
|
||||||
|
}
|
||||||
|
var parentRegion = region.Region2;
|
||||||
|
while (parentRegion != null)
|
||||||
|
{
|
||||||
|
name = parentRegion.Name + "/" + name;
|
||||||
|
parentRegion = parentRegion.Region2;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public class SearchGuestModel
|
||||||
|
{
|
||||||
|
public string SearchName = null;
|
||||||
|
public int Page = 1;
|
||||||
|
public int PageSize = 10;
|
||||||
|
public DateTime? searchCheckInDateStart = null;//入住日期的开始
|
||||||
|
public DateTime? searchCheckInDateEnd = null;//入住日期的结束
|
||||||
|
public DateTime? searchCheckOutDateStart = null;//退房日期的开始
|
||||||
|
public DateTime? searchCheckOutDateEnd = null;//退房日期的结束
|
||||||
|
public DateTime? searchCheckInDate = null;
|
||||||
|
public DateTime? searchCheckOutDate = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Model;
|
using Model;
|
||||||
|
using PagedList;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
@@ -6,20 +7,54 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
using static regionController;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// guadanOderController 的摘要描述
|
/// guadanOderController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class guadanOrderController: ApiController
|
public class guadanOrderController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
[HttpGet]
|
[HttpPost]
|
||||||
[Route("api/guadan/list")]
|
[Route("api/guadan/list")]
|
||||||
public async Task<IHttpActionResult> getGuadanList()
|
public async Task<IHttpActionResult> getGuadanList([FromBody] guadan_order_search_dto search)
|
||||||
{
|
{
|
||||||
var data = await _db.GuaDanOrder.OrderByDescending(b => b.CreatedAt)
|
var lastCheckoutTime = _db.GuadanTimeSetting.FirstOrDefault();
|
||||||
|
string lastCheckoutTimeStr = null;
|
||||||
|
if (lastCheckoutTime != null)
|
||||||
|
{
|
||||||
|
lastCheckoutTimeStr = lastCheckoutTime.LatestCheckOut;
|
||||||
|
}
|
||||||
|
var query = _db.GuaDanOrder
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
|
.Where(a => a.IsDeleted == false);
|
||||||
|
if(!string.IsNullOrEmpty(search.guaDanOrderNo))
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.GuaDanOrderNo == search.guaDanOrderNo);
|
||||||
|
}
|
||||||
|
if (search.guadanUser != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.BookerName == search.guadanUser);
|
||||||
|
}
|
||||||
|
if (search.startDate != null && search.endDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.StartDate >= search.startDate)
|
||||||
|
.Where(order => order.EndDate <= search.endDate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (search.startDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.StartDate == search.startDate);
|
||||||
|
}
|
||||||
|
else if (search.endDate != null)
|
||||||
|
{
|
||||||
|
query = query.Where(order => order.EndDate == search.endDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var total = query.Count();
|
||||||
|
var data1 = await query.ToListAsync();
|
||||||
|
var data = data1
|
||||||
|
.OrderByDescending(b => b.CreatedAt)
|
||||||
.Select(a => new
|
.Select(a => new
|
||||||
{
|
{
|
||||||
uuid = a.Uuid,
|
uuid = a.Uuid,
|
||||||
@@ -29,24 +64,65 @@ public class guadanOrderController: ApiController
|
|||||||
created_at = a.CreatedAt,
|
created_at = a.CreatedAt,
|
||||||
updated_at = a.UpdatedAt,
|
updated_at = a.UpdatedAt,
|
||||||
notes = a.Notes,
|
notes = a.Notes,
|
||||||
|
is_timeout = !string.IsNullOrEmpty(lastCheckoutTimeStr) &&
|
||||||
|
_db.GuaDanOrderGuest
|
||||||
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && !g.IsDeleted && g.StatusCode == GuaDanOrderGuest.STATUS_CHECKED_IN)
|
||||||
|
.ToList()
|
||||||
|
.Any(g =>
|
||||||
|
g.CheckOutAt.HasValue &&
|
||||||
|
DateTime.Parse(g.CheckOutAt.Value.ToString("yyyy-MM-dd") + " " + lastCheckoutTimeStr) < DateTime.Now
|
||||||
|
),
|
||||||
|
activity = _db.activities
|
||||||
|
.Where(act => act.num == a.ActivityNum)
|
||||||
|
.Select(act => new
|
||||||
|
{
|
||||||
|
subject = act.subject
|
||||||
|
})
|
||||||
|
.FirstOrDefault(),
|
||||||
bookerName = a.BookerName,
|
bookerName = a.BookerName,
|
||||||
guest_count = _db.GuaDanOrderGuest.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo).Count(),
|
guest_count = _db.GuaDanOrderGuest
|
||||||
}).ToListAsync();
|
.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false)
|
||||||
return Ok(data);
|
.Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.Count(),
|
||||||
|
guadan_status = _db.GuaDanOrderGuest
|
||||||
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
||||||
|
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.All(g => g.StatusCode == "401") ? new { code=501, name="預約" }:
|
||||||
|
_db.GuaDanOrderGuest
|
||||||
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
||||||
|
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.All(g => g.StatusCode == "403") ? new { code = 502, name = "全部退房" } :
|
||||||
|
_db.GuaDanOrderGuest
|
||||||
|
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
|
||||||
|
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
|
||||||
|
.Any(g => g.StatusCode == "402" && a.IsCancel == false) ? new { code = 503, name = "正在入住" } :
|
||||||
|
new { code = 504, name = "部分退房" }
|
||||||
|
})
|
||||||
|
.Skip((search.page - 1) * search.pageSize)
|
||||||
|
.Take(search.pageSize)
|
||||||
|
.ToList();
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
total,
|
||||||
|
data
|
||||||
|
});
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/guadan/getorderbyid")]
|
[Route("api/guadan/getorderbyid")]
|
||||||
public async Task<IHttpActionResult> getGuadanOrderById(string orderId)
|
public async Task<IHttpActionResult> getGuadanOrderById(string orderId)
|
||||||
{
|
{
|
||||||
var order = await _db.GuaDanOrder.Where(a => a.GuaDanOrderNo == orderId).FirstOrDefaultAsync();
|
var order = await _db.GuaDanOrder
|
||||||
|
.Where(a => a.GuaDanOrderNo == orderId)
|
||||||
|
.Where(a => a.IsCancel == false && a.IsDeleted == false)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
if (order == null)
|
if (order == null)
|
||||||
{
|
{
|
||||||
return BadRequest("未找到对应订单");
|
return BadRequest("未找到對應訂單");
|
||||||
}
|
}
|
||||||
var result = new
|
var result = new
|
||||||
{
|
{
|
||||||
order.admin,
|
order.admin,
|
||||||
order.follower,
|
order.followers,
|
||||||
StartDate = order.StartDate?.ToString("yyyy-MM-dd"),
|
StartDate = order.StartDate?.ToString("yyyy-MM-dd"),
|
||||||
EndDate = order.EndDate?.ToString("yyyy-MM-dd"),
|
EndDate = order.EndDate?.ToString("yyyy-MM-dd"),
|
||||||
order.CreateUser,
|
order.CreateUser,
|
||||||
@@ -59,6 +135,8 @@ public class guadanOrderController: ApiController
|
|||||||
order.BookerPhone,
|
order.BookerPhone,
|
||||||
order.IsDeleted,
|
order.IsDeleted,
|
||||||
order.Uuid,
|
order.Uuid,
|
||||||
|
order.ActivityNum,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@@ -71,9 +149,9 @@ public class guadanOrderController: ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("掛單資料不可為空");
|
return BadRequest("掛單資料不可為空");
|
||||||
}
|
}
|
||||||
if(model.Uuid.HasValue)
|
if (model.Uuid.HasValue)
|
||||||
{
|
{
|
||||||
return BadRequest("已存在对应挂单资料");
|
return BadRequest("已存在對應掛單資料");
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -99,6 +177,7 @@ public class guadanOrderController: ApiController
|
|||||||
BookerName = model.bookerName,
|
BookerName = model.bookerName,
|
||||||
BookerPhone = model.bookerPhone,
|
BookerPhone = model.bookerPhone,
|
||||||
Uuid = Guid.NewGuid(),
|
Uuid = Guid.NewGuid(),
|
||||||
|
ActivityNum = model.activityNum,
|
||||||
};
|
};
|
||||||
_db.GuaDanOrder.Add(guadanorder);
|
_db.GuaDanOrder.Add(guadanorder);
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
@@ -131,26 +210,30 @@ public class guadanOrderController: ApiController
|
|||||||
var order = await _db.GuaDanOrder.FindAsync(model.Uuid.Value);
|
var order = await _db.GuaDanOrder.FindAsync(model.Uuid.Value);
|
||||||
if (order == null)
|
if (order == null)
|
||||||
{
|
{
|
||||||
return BadRequest("未找到对应挂单资料");
|
return BadRequest("未找到對應掛單資料");
|
||||||
}
|
}
|
||||||
order.StartDate = model.startdate;
|
order.StartDate = model.startdate;
|
||||||
order.EndDate = model.enddate;
|
order.EndDate = model.enddate;
|
||||||
order.Notes = model.note;
|
order.Notes = model.note;
|
||||||
order.BookerName = model.bookerName;
|
order.BookerName = model.bookerName;
|
||||||
order.BookerPhone = model.bookerPhone;
|
order.BookerPhone = model.bookerPhone;
|
||||||
|
order.ActivityNum = model.activityNum;
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
return Ok(model);
|
return Ok(model);
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/guadan/delete")]
|
[Route("api/guadan/cancel")]
|
||||||
public async Task<IHttpActionResult> deleteGuadanOrder([FromUri] Guid uuid)
|
public async Task<IHttpActionResult> CancelGuadanOrder([FromUri] Guid uuid)
|
||||||
{
|
{
|
||||||
var guadan = await _db.GuaDanOrder.FindAsync(uuid);
|
var guadan = await _db.GuaDanOrder.FindAsync(uuid);
|
||||||
if (guadan == null)
|
if (guadan == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
if (_db.GuaDanOrderGuest.Any(a => (a.GuaDanOrderNo == guadan.GuaDanOrderNo) && a.StatusCode != "404"))
|
||||||
|
{
|
||||||
|
return BadRequest($"該掛單已經存在掛單蓮友,不能取消!");
|
||||||
|
}
|
||||||
using (var transaction = _db.Database.BeginTransaction())
|
using (var transaction = _db.Database.BeginTransaction())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -158,31 +241,27 @@ public class guadanOrderController: ApiController
|
|||||||
var guadanGuests = await _db.GuaDanOrderGuest
|
var guadanGuests = await _db.GuaDanOrderGuest
|
||||||
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var scheduleIds = _db.RegionAndRoomAndBedSchedule
|
|
||||||
.Where(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo)
|
|
||||||
.Where( b => b.IsActive == true)
|
|
||||||
.Select(c => c.GuaDanOrderNo)
|
|
||||||
.ToList();
|
|
||||||
if (guadanGuests.Any())
|
if (guadanGuests.Any())
|
||||||
{
|
{
|
||||||
_db.GuaDanOrderGuest.RemoveRange(guadanGuests);
|
foreach (var guest in guadanGuests)
|
||||||
|
{
|
||||||
|
guest.StatusCode = "404";
|
||||||
|
// 取消所有相關的排程
|
||||||
|
if (guest.RegionAndRoomAndBedSchedule != null && guest.RegionAndRoomAndBedSchedule.Any())
|
||||||
|
{
|
||||||
|
foreach (var schedule in guest.RegionAndRoomAndBedSchedule)
|
||||||
|
{
|
||||||
|
schedule.IsCancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
guadan.IsCancel = true;
|
||||||
if (scheduleIds.Any())
|
|
||||||
{
|
|
||||||
var schedules = await _db.RegionAndRoomAndBedSchedule
|
|
||||||
.Where(a => scheduleIds.Contains(a.GuaDanOrderNo))
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (schedules.Any())
|
|
||||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(schedules);
|
|
||||||
}
|
|
||||||
_db.GuaDanOrder.Remove(guadan);
|
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
transaction.Commit();
|
transaction.Commit();
|
||||||
|
|
||||||
return Ok(new { message = "删除成功" });
|
return Ok(new { message = "取消成功" });
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -200,7 +279,6 @@ public class guadanOrderController: ApiController
|
|||||||
public int guest_id { get; set; }
|
public int guest_id { get; set; }
|
||||||
public DateTime start_date { get; set; }
|
public DateTime start_date { get; set; }
|
||||||
public DateTime? end_date { get; set; }
|
public DateTime? end_date { get; set; }
|
||||||
public Guid? statusUuid { get; set; }
|
|
||||||
public int? create_user { get; set; }
|
public int? create_user { get; set; }
|
||||||
public DateTime created_at { get; set; }
|
public DateTime created_at { get; set; }
|
||||||
public DateTime updated_at { get; set; }
|
public DateTime updated_at { get; set; }
|
||||||
@@ -211,4 +289,14 @@ public class guadanOrderController: ApiController
|
|||||||
public RegionRoomBed bed { get; set; } = null;
|
public RegionRoomBed bed { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class guadan_order_search_dto
|
||||||
|
{
|
||||||
|
public DateTime? startDate { get; set; }
|
||||||
|
public DateTime? endDate { get; set; }
|
||||||
|
public string guadanUser { get; set; }
|
||||||
|
public int page { get; set; } = 1;
|
||||||
|
public int pageSize { get; set; } = 10;
|
||||||
|
public string guaDanOrderNo { get; set; } = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
using Model;
|
using DocumentFormat.OpenXml.Drawing;
|
||||||
|
using Model;
|
||||||
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
|
using System.Data.Entity.Infrastructure;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
@@ -11,7 +15,7 @@ using System.Web.Http;
|
|||||||
/// guadanOrderGuest 的摘要描述
|
/// guadanOrderGuest 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class guadanOrderGuestController: ApiController
|
public class guadanOrderGuestController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -25,12 +29,12 @@ public class guadanOrderGuestController: ApiController
|
|||||||
[Route("api/guadanorderguest/getbyorderno")]
|
[Route("api/guadanorderguest/getbyorderno")]
|
||||||
public async Task<IHttpActionResult> getByOrderNo(string orderNo)
|
public async Task<IHttpActionResult> getByOrderNo(string orderNo)
|
||||||
{
|
{
|
||||||
// 先查数据库,不做格式化
|
// 先查資料庫,不做格式化
|
||||||
var qry = await _db.GuaDanOrderGuest
|
var qry = await _db.GuaDanOrderGuest
|
||||||
.Where(a => a.GuaDanOrderNo == orderNo && a.IsDeleted == false)
|
.Where(a => a.GuaDanOrderNo == orderNo && a.IsDeleted == false && a.RegionRoomBedStatus.Code != "404")
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
// 拉到内存后再处理日期
|
// 拉到記憶體後再處理日期
|
||||||
var data = qry.Select(a => new guadan_order_guest_display_dto
|
var data = qry.Select(a => new guadan_order_guest_display_dto
|
||||||
{
|
{
|
||||||
Uuid = a.Uuid,
|
Uuid = a.Uuid,
|
||||||
@@ -42,27 +46,50 @@ public class guadanOrderGuestController: ApiController
|
|||||||
checkoutat = a.CheckOutAt.HasValue ? a.CheckOutAt.Value.ToString("yyyy-MM-dd") : null,
|
checkoutat = a.CheckOutAt.HasValue ? a.CheckOutAt.Value.ToString("yyyy-MM-dd") : null,
|
||||||
phone = null,
|
phone = null,
|
||||||
roomName = a.Room.Name,
|
roomName = a.Room.Name,
|
||||||
bedName = a.RegionRoomBed.Name,
|
bedName = GetBedString(a.RegionRoomBed),
|
||||||
orderNo = a.GuaDanOrderNo,
|
orderNo = a.GuaDanOrderNo,
|
||||||
follower = a.follower,
|
follower = a.followers == null ? null : new FollowerDto
|
||||||
statusUuid = a.statusUuid,
|
{
|
||||||
|
num = a.followers.num,
|
||||||
|
u_name = a.followers.u_name,
|
||||||
|
sex = a.followers.sex
|
||||||
|
},
|
||||||
|
statuscode = a.StatusCode,
|
||||||
statusName = a.RegionRoomBedStatus?.Name,
|
statusName = a.RegionRoomBedStatus?.Name,
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
public string GetBedString(RegionRoomBed bed)
|
||||||
|
{
|
||||||
|
if (bed == null)
|
||||||
|
return "";
|
||||||
|
var room = bed.Room;
|
||||||
|
var name = room.Name + "/" + bed.Name;
|
||||||
|
var region = room.Region;
|
||||||
|
name = region.Name + "/" + name;
|
||||||
|
var parentRegion = region.Region2;
|
||||||
|
while(parentRegion != null)
|
||||||
|
{
|
||||||
|
name = parentRegion.Name + "/" + name;
|
||||||
|
parentRegion = parentRegion.Region2;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/guadanorderguest/create")]
|
[Route("api/guadanorderguest/create")]
|
||||||
public async Task<IHttpActionResult> create([FromBody] guadan_order_guest_dto model)
|
public async Task<IHttpActionResult> create([FromBody] guadan_order_guest_dto model)
|
||||||
{
|
{
|
||||||
if (model == null)
|
if (model == null)
|
||||||
return BadRequest("");
|
return BadRequest("");
|
||||||
|
/*if(model.statuscode == null)
|
||||||
|
{
|
||||||
|
return BadRequest("狀態不能為空");
|
||||||
|
}*/
|
||||||
// 驗證床位與蓮友
|
// 驗證床位與蓮友
|
||||||
|
var bed = _db.RegionRoomBed.Find(model.bedUuid.Value);
|
||||||
if (model.followerNum.HasValue && model.bedUuid.HasValue)
|
if (model.followerNum.HasValue && model.bedUuid.HasValue)
|
||||||
{
|
{
|
||||||
var bed = _db.RegionRoomBed.Find(model.bedUuid.Value);
|
|
||||||
var follower = _db.followers.Find(model.followerNum.Value);
|
var follower = _db.followers.Find(model.followerNum.Value);
|
||||||
|
|
||||||
if (bed == null || follower == null)
|
if (bed == null || follower == null)
|
||||||
@@ -81,16 +108,16 @@ public class guadanOrderGuestController: ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!model.bedUuid.HasValue)
|
if (!model.bedUuid.HasValue)
|
||||||
return BadRequest("床位 UUID 不能为空");
|
return BadRequest("床位 UUID 不能為空");
|
||||||
if (!model.checkInAt.HasValue)
|
if (!model.checkInAt.HasValue)
|
||||||
return BadRequest("入住时间不能为空");
|
return BadRequest("入住時間不能為空");
|
||||||
|
|
||||||
// 長期占用處理:checkOutAt 可為 null
|
// 長期占用處理:checkOutAt 可為 null
|
||||||
DateTime? checkOut = model.checkOutAt.Value.Date;
|
DateTime? checkOut = model.checkOutAt.Value.Date;
|
||||||
|
|
||||||
if (checkOut.HasValue && model.checkInAt > checkOut)
|
if (checkOut.HasValue && model.checkInAt > checkOut)
|
||||||
return BadRequest("掛單結束時間不能再開始時間之前");
|
return BadRequest("掛單結束時間不能再開始時間之前");
|
||||||
if(model.checkInAt == model.checkOutAt)
|
if (model.checkInAt == model.checkOutAt)
|
||||||
{
|
{
|
||||||
return BadRequest("掛單結束時間和開始時間不能是同一天");
|
return BadRequest("掛單結束時間和開始時間不能是同一天");
|
||||||
}
|
}
|
||||||
@@ -103,8 +130,22 @@ public class guadanOrderGuestController: ApiController
|
|||||||
);
|
);
|
||||||
if (!bedIsCanUse)
|
if (!bedIsCanUse)
|
||||||
return BadRequest("床位在該時間段內已被占用");
|
return BadRequest("床位在該時間段內已被占用");
|
||||||
|
if (model.followerNum.HasValue)
|
||||||
|
{
|
||||||
|
if (_db.GuaDanOrderGuest.Any(a => a.FollowerNum == model.followerNum
|
||||||
|
&& a.GuaDanOrderNo == model.orderNo
|
||||||
|
&& a.StatusCode != "404"
|
||||||
|
))
|
||||||
|
return BadRequest("該蓮友已經在該掛單中");
|
||||||
|
}
|
||||||
|
//建立訂單的的時候,狀態只能是401或者402
|
||||||
|
var targetStatus = _db.RegionRoomBedStatus.Where(a => a.Code == GuaDanOrderGuest.STATUS_BOOKED).FirstOrDefault();
|
||||||
|
|
||||||
|
if (targetStatus == null)
|
||||||
|
{
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到目標狀態,請先建立對應狀態");
|
||||||
|
}
|
||||||
|
|
||||||
// 建立掛單
|
|
||||||
var guest = new GuaDanOrderGuest
|
var guest = new GuaDanOrderGuest
|
||||||
{
|
{
|
||||||
GuaDanOrderNo = model.orderNo,
|
GuaDanOrderNo = model.orderNo,
|
||||||
@@ -114,14 +155,9 @@ public class guadanOrderGuestController: ApiController
|
|||||||
CheckInAt = model.checkInAt?.Date,
|
CheckInAt = model.checkInAt?.Date,
|
||||||
CheckOutAt = checkOut,
|
CheckOutAt = checkOut,
|
||||||
Uuid = Guid.NewGuid(),
|
Uuid = Guid.NewGuid(),
|
||||||
statusUuid = model.statusUuid,
|
StatusCode = GuaDanOrderGuest.STATUS_BOOKED,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (model.followerNum.HasValue)
|
|
||||||
{
|
|
||||||
if (_db.GuaDanOrderGuest.Any(a => a.FollowerNum == model.followerNum && a.GuaDanOrderNo == model.orderNo))
|
|
||||||
return BadRequest("該蓮友已經在該掛單中");
|
|
||||||
}
|
|
||||||
|
|
||||||
_db.GuaDanOrderGuest.Add(guest);
|
_db.GuaDanOrderGuest.Add(guest);
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
@@ -140,12 +176,13 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單",
|
Description = "床位掛單",
|
||||||
ScheduleDate = scheduleDate,
|
ScheduleDate = scheduleDate,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
@@ -159,19 +196,17 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單(長期占用)",
|
Description = "床位掛單(長期占用)",
|
||||||
ScheduleDate = null,
|
ScheduleDate = null,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
await _db.SaveChangesAsync();
|
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,10 +236,10 @@ public class guadanOrderGuestController: ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!model.bedUuid.HasValue)
|
if (!model.bedUuid.HasValue)
|
||||||
return BadRequest("床位 UUID 不能为空");
|
return BadRequest("床位 UUID 不能為空");
|
||||||
|
|
||||||
if (!model.checkInAt.HasValue)
|
if (!model.checkInAt.HasValue)
|
||||||
return BadRequest("入住时间不能为空");
|
return BadRequest("入住時間不能為空");
|
||||||
|
|
||||||
// 長期占用處理
|
// 長期占用處理
|
||||||
DateTime? checkOut = model.checkOutAt?.Date;
|
DateTime? checkOut = model.checkOutAt?.Date;
|
||||||
@@ -234,18 +269,27 @@ public class guadanOrderGuestController: ApiController
|
|||||||
.AnyAsync();
|
.AnyAsync();
|
||||||
if (exists) return BadRequest("該蓮友已經在該掛單中");
|
if (exists) return BadRequest("該蓮友已經在該掛單中");
|
||||||
}
|
}
|
||||||
|
/*var targetStatus = _db.RegionRoomBedStatus.Find(model.statuscode);
|
||||||
|
if (targetStatus == null)
|
||||||
|
{
|
||||||
|
return BadRequest("目標狀態不存在");
|
||||||
|
}
|
||||||
|
if(!StatusTransitionManager.CanTransition(guest.StatusCode,targetStatus.Code))
|
||||||
|
{
|
||||||
|
return BadRequest("狀態的變化不合法");
|
||||||
|
}*/
|
||||||
// 更新掛單基本資料
|
// 更新掛單基本資料
|
||||||
guest.FollowerNum = model.followerNum;
|
guest.FollowerNum = model.followerNum;
|
||||||
guest.RoomUuid = model.roomUuid;
|
guest.RoomUuid = model.roomUuid;
|
||||||
guest.BedUuid = model.bedUuid;
|
guest.BedUuid = model.bedUuid;
|
||||||
guest.CheckInAt = model.checkInAt?.Date;
|
guest.CheckInAt = model.checkInAt?.Date;
|
||||||
guest.CheckOutAt = checkOut;
|
guest.CheckOutAt = checkOut;
|
||||||
guest.statusUuid = model.statusUuid;
|
//guest.StatusCode = model.statuscode;
|
||||||
|
//更新的時候不能更新狀態,狀態都用單獨的操作api控制
|
||||||
|
|
||||||
// 刪除原有每日排程
|
// 刪除原有每日排程
|
||||||
var oldSchedules = _db.RegionAndRoomAndBedSchedule
|
var oldSchedules = _db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo)
|
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo && s.TargetUuid == guest.BedUuid)
|
||||||
.ToList();
|
.ToList();
|
||||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(oldSchedules);
|
_db.RegionAndRoomAndBedSchedule.RemoveRange(oldSchedules);
|
||||||
|
|
||||||
@@ -262,12 +306,13 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單",
|
Description = "床位掛單",
|
||||||
ScheduleDate = date,
|
ScheduleDate = date,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
@@ -281,12 +326,13 @@ public class guadanOrderGuestController: ApiController
|
|||||||
Description = "床位掛單(長期占用)",
|
Description = "床位掛單(長期占用)",
|
||||||
ScheduleDate = null,
|
ScheduleDate = null,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
IsCancel = false,
|
||||||
TargetUuid = guest.BedUuid,
|
TargetUuid = guest.BedUuid,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo,
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
Uuid = Guid.NewGuid()
|
Uuid = Guid.NewGuid(),
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
_db.RegionAndRoomAndBedSchedule.Add(schedul);
|
||||||
}
|
}
|
||||||
@@ -296,27 +342,293 @@ public class guadanOrderGuestController: ApiController
|
|||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/guadanorderguest/delete")]
|
[Route("api/guadanorderguest/xuzhu")]
|
||||||
public async Task<IHttpActionResult> deleteGuadanGuest([FromUri] Guid uuid)
|
public async Task<IHttpActionResult> ExtendStay([FromBody] XuZhuModel model)
|
||||||
|
{
|
||||||
|
//續住方法
|
||||||
|
if (model == null)
|
||||||
|
return BadRequest("請求數據為空");
|
||||||
|
|
||||||
|
if (model.GuestUuid == Guid.Empty || model.GuestBedUuid == Guid.Empty)
|
||||||
|
return BadRequest("GuestUuid 或 GuestBedUuid 無效");
|
||||||
|
var guest = await _db.GuaDanOrderGuest.FindAsync(model.GuestUuid);
|
||||||
|
if (guest == null)
|
||||||
|
{
|
||||||
|
return BadRequest("掛單不存在");
|
||||||
|
}
|
||||||
|
if (guest.BedUuid != model.GuestBedUuid)
|
||||||
|
{
|
||||||
|
return BadRequest("床位不正確");
|
||||||
|
}
|
||||||
|
var bedIsCanUse = await RegionAndRoomAndBedSchedule.IsBedAvailableAsync(_db, model.GuestBedUuid, model.CurrentCheckoutDate, model.NewCheckoutDate);
|
||||||
|
if (!bedIsCanUse)
|
||||||
|
{
|
||||||
|
return BadRequest("該床位在續住時間段內被預定,無法續住");
|
||||||
|
}
|
||||||
|
|
||||||
|
var newStartDate = model.CurrentCheckoutDate.Date;
|
||||||
|
var newEndDate = model.NewCheckoutDate.Date.AddDays(-1);
|
||||||
|
if (newEndDate < newStartDate)
|
||||||
|
return BadRequest("續住日期區間無效");
|
||||||
|
for (var date = newStartDate; date <= newEndDate; date = date.AddDays(1))
|
||||||
|
{
|
||||||
|
var newSchedule = new RegionAndRoomAndBedSchedule
|
||||||
|
{
|
||||||
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
|
Uuid = Guid.NewGuid(),
|
||||||
|
TargetUuid = model.GuestBedUuid,
|
||||||
|
GuaDanOrderGuestUuid = model.GuestUuid,
|
||||||
|
ScheduleDate = date,
|
||||||
|
Title = "續住掛單", // 一天一條,開始和結束是同一天
|
||||||
|
Description = "續住掛單",
|
||||||
|
UseType = 30,
|
||||||
|
CreatedAt = DateTime.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
|
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||||
|
}
|
||||||
|
guest.CheckOutAt = model.NewCheckoutDate.Date;
|
||||||
|
await _db.SaveChangesAsync(); // 保存資料庫操作
|
||||||
|
return Ok(new { message = "續住成功" });
|
||||||
|
}
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/guadanorderguest/cancel")]
|
||||||
|
public async Task<IHttpActionResult> CancelGuadanGuest([FromUri] Guid uuid)
|
||||||
{
|
{
|
||||||
var guest = await _db.GuaDanOrderGuest.FindAsync(uuid);
|
var guest = await _db.GuaDanOrderGuest.FindAsync(uuid);
|
||||||
if (guest == null)
|
if (guest == null)
|
||||||
return BadRequest("未找到指定挂单资料");
|
return NotFound();
|
||||||
|
|
||||||
// 删除所有与该 guest 相关的排程(每日排程或長期占用)
|
if (guest.StatusCode == "404")
|
||||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
return BadRequest("該掛單已取消,無需再取消");
|
||||||
.Where(s => s.GuaDanOrderNo == guest.GuaDanOrderNo)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (schedules.Any())
|
if (!StatusTransitionManager.CanTransition(guest.StatusCode, "404"))
|
||||||
_db.RegionAndRoomAndBedSchedule.RemoveRange(schedules);
|
{
|
||||||
|
return BadRequest("當前狀態不能取消");
|
||||||
|
}
|
||||||
|
var cancelStatus = await _db.RegionRoomBedStatus
|
||||||
|
.FirstOrDefaultAsync(a => a.Code == "404");
|
||||||
|
if (cancelStatus == null)
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到取消狀態(Code=404),請先建立對應狀態");
|
||||||
|
//把狀態設置為取消
|
||||||
|
using (var tx = _db.Database.BeginTransaction())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 1) 更新 guest
|
||||||
|
guest.StatusCode = "404";
|
||||||
|
|
||||||
|
// 2) 取消相關排程(常見做法:只取消未來&未取消的)
|
||||||
|
var today = DateTime.Today;
|
||||||
|
|
||||||
|
var schedules = await _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuestUuid == guest.Uuid
|
||||||
|
&& s.IsCancel == false
|
||||||
|
//&& s.ScheduleDate >= today
|
||||||
|
)
|
||||||
|
// ✅ 只取消今天與未來的,能取消就代表未入住,
|
||||||
|
// 未入住就要全部取消,如果是入住後提前退房,
|
||||||
|
// 就要取消未來的,取消未來的時候要注意今日是否包含的問題
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var s in schedules)
|
||||||
|
{
|
||||||
|
s.IsCancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) 釋放占用資源(若有床位/房間占用紀錄)
|
||||||
|
if (guest.BedUuid != null)
|
||||||
|
{
|
||||||
|
// 先抓到目標狀態
|
||||||
|
var freeStatus = await _db.RegionRoomBedStatus
|
||||||
|
.FirstOrDefaultAsync(a => a.Code == "101");
|
||||||
|
|
||||||
|
if (freeStatus == null)
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到床位狀態 Code=101");
|
||||||
|
if (guest.RegionRoomBed != null)
|
||||||
|
{
|
||||||
|
guest.RegionRoomBed.StatusCode = freeStatus.Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_db.GuaDanOrderGuest.Remove(guest);
|
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
|
tx.Commit();
|
||||||
|
|
||||||
return Ok(new { message = "删除成功" });
|
return Ok(new
|
||||||
|
{
|
||||||
|
message = "取消成功",
|
||||||
|
guestUuid = guest.Uuid,
|
||||||
|
canceledSchedules = schedules.Count
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException)
|
||||||
|
{
|
||||||
|
tx.Rollback();
|
||||||
|
return StatusCode(HttpStatusCode.PreconditionFailed); // 或自訂訊息
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
tx.Rollback();
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/guadanorderguest/checkout")]
|
||||||
|
public IHttpActionResult CheckoutGuadanOrderGuest(Guid uuid)
|
||||||
|
{
|
||||||
|
DbContextTransaction transaction = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transaction = _db.Database.BeginTransaction(); // 開啟事務
|
||||||
|
|
||||||
|
// 1️⃣ 取得該筆掛單
|
||||||
|
var guest = _db.GuaDanOrderGuest
|
||||||
|
.Where(a => a.Uuid == uuid)
|
||||||
|
.Where(a => !a.IsDeleted && a.StatusCode != "404")
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (guest == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
// 2️⃣ 標記為已退房
|
||||||
|
var targetStatus = _db.RegionRoomBedStatus
|
||||||
|
.Where(a => a.Code == "403")
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (targetStatus == null)
|
||||||
|
return Content(HttpStatusCode.PreconditionFailed, "找不到退房狀態(Code=403),請先建立對應狀態");
|
||||||
|
|
||||||
|
if (!StatusTransitionManager.CanTransition(guest.StatusCode, targetStatus.Code))
|
||||||
|
return BadRequest("掛單狀態轉換不對");
|
||||||
|
|
||||||
|
if (!StatusTransitionManager.CanTransition(guest.RegionRoomBed.StatusCode, "101"))
|
||||||
|
return BadRequest("床位掛單狀態轉換不對");
|
||||||
|
|
||||||
|
guest.StatusCode = targetStatus.Code;
|
||||||
|
guest.RegionRoomBed.StatusCode = "101";
|
||||||
|
|
||||||
|
//更新未來排程為取消
|
||||||
|
var latestCheckoutStr = _db.GuadanTimeSetting
|
||||||
|
.Select(a => a.LatestCheckOut) // 字串 "HH:mm"
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
TimeSpan? latestCheckoutTime = null;
|
||||||
|
if (!string.IsNullOrEmpty(latestCheckoutStr))
|
||||||
|
{
|
||||||
|
// 嘗試解析字串
|
||||||
|
if (TimeSpan.TryParse(latestCheckoutStr, out var ts))
|
||||||
|
{
|
||||||
|
latestCheckoutTime = ts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var futureSchedules = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuestUuid == guest.Uuid);
|
||||||
|
if (latestCheckoutTime == null || DateTime.Now.TimeOfDay > latestCheckoutTime)
|
||||||
|
{
|
||||||
|
// 包含今天
|
||||||
|
futureSchedules = futureSchedules.Where(s => s.ScheduleDate > DateTime.Today);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 不包含今天
|
||||||
|
futureSchedules = futureSchedules.Where(s => s.ScheduleDate >= DateTime.Today);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var schedule in futureSchedules)
|
||||||
|
{
|
||||||
|
schedule.IsCancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4️⃣ 保存所有變更
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
// 5️⃣ 提交事務
|
||||||
|
transaction.Commit();
|
||||||
|
|
||||||
|
return Ok(new { message = "退房完成", guestUuid = guest.Uuid });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
transaction.Rollback(); // 回滾事務
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
transaction.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("api/guadanorderguest/checkin")]
|
||||||
|
public IHttpActionResult CheckinGuadanGuest([FromUri] Guid uuid)
|
||||||
|
{
|
||||||
|
if (uuid == Guid.Empty)
|
||||||
|
return BadRequest("uuid不能為空");
|
||||||
|
|
||||||
|
// 獲取掛單客人
|
||||||
|
var guest = _db.GuaDanOrderGuest
|
||||||
|
.Include(g => g.RegionRoomBedStatus) // 包含導航屬性
|
||||||
|
.FirstOrDefault(g => g.Uuid == uuid);
|
||||||
|
|
||||||
|
if (guest == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
string currentStatus = guest.StatusCode;
|
||||||
|
|
||||||
|
// 判斷狀態流轉是否合法
|
||||||
|
if (!StatusTransitionManager.CanTransition(currentStatus, GuaDanOrderGuest.STATUS_CHECKED_IN))
|
||||||
|
{
|
||||||
|
return BadRequest("當前狀態不允許入住");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 新增:檢查今天是否在排程表 ----------
|
||||||
|
var today = DateTime.Today;
|
||||||
|
bool hasScheduleToday = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Any(s => s.GuaDanOrderGuestUuid == guest.Uuid && s.ScheduleDate == today);
|
||||||
|
|
||||||
|
if (!hasScheduleToday)
|
||||||
|
{
|
||||||
|
return BadRequest("不在入住時間段內,無法入住");
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 更新狀態
|
||||||
|
guest.StatusCode = GuaDanOrderGuest.STATUS_CHECKED_IN;
|
||||||
|
|
||||||
|
// 如果需要,更新床位狀態,比如變為占用
|
||||||
|
if (guest.BedUuid != null)
|
||||||
|
{
|
||||||
|
var bed = _db.RegionRoomBed.FirstOrDefault(b => b.Uuid == guest.BedUuid);
|
||||||
|
if (bed == null)
|
||||||
|
{
|
||||||
|
return BadRequest("入住床位不存在");
|
||||||
|
}
|
||||||
|
if (StatusTransitionManager.CanTransition(bed.StatusCode, "102")) // 102 = 占用
|
||||||
|
{
|
||||||
|
bed.StatusCode = "102";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BadRequest($"當前床位狀態:{bed.RegionRoomBedStatus.Name} 不能入住");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (guest.BedUuid == null)
|
||||||
|
{
|
||||||
|
return BadRequest("入住床位不存在");
|
||||||
|
}
|
||||||
|
_db.SaveChanges();
|
||||||
|
|
||||||
|
return Ok(new { message = "入住成功", statusCode = guest.StatusCode });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class guadan_order_guest_dto
|
public class guadan_order_guest_dto
|
||||||
@@ -328,7 +640,7 @@ public class guadanOrderGuestController: ApiController
|
|||||||
public Guid? bedUuid { get; set; }
|
public Guid? bedUuid { get; set; }
|
||||||
public DateTime? checkInAt { get; set; }
|
public DateTime? checkInAt { get; set; }
|
||||||
public DateTime? checkOutAt { get; set; }
|
public DateTime? checkOutAt { get; set; }
|
||||||
public Guid? statusUuid { get; set; }
|
public string statuscode { get; set; }
|
||||||
}
|
}
|
||||||
public class guadan_order_guest_display_dto
|
public class guadan_order_guest_display_dto
|
||||||
{
|
{
|
||||||
@@ -337,17 +649,31 @@ public class guadanOrderGuestController: ApiController
|
|||||||
public string orderNo { get; set; }
|
public string orderNo { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public Guid? roomUuid { get; set; }
|
public Guid? roomUuid { get; set; }
|
||||||
public Guid? bedUuid { get;set; }
|
public Guid? bedUuid { get; set; }
|
||||||
public string checkinat { get;set; }
|
public string checkinat { get; set; }
|
||||||
public string checkoutat { get;set; }
|
public string checkoutat { get; set; }
|
||||||
public int? gender { get; set; }
|
public int? gender { get; set; }
|
||||||
public Guid? statusUuid { get; set; }
|
public string statuscode { get; set; }
|
||||||
public string statusName { get; set; }
|
public string statusName { get; set; }
|
||||||
public string phone { get; set; }
|
public string phone { get; set; }
|
||||||
public string note { get; set; }
|
public string note { get; set; }
|
||||||
public string roomName { get; set; }
|
public string roomName { get; set; }
|
||||||
public string bedName { get; set; }
|
public string bedName { get; set; }
|
||||||
public follower follower { get; set; }
|
public bool iscancel { get; set; }
|
||||||
|
public FollowerDto follower { get; set; }
|
||||||
|
}
|
||||||
|
public class FollowerDto
|
||||||
|
{
|
||||||
|
public int num { get; set; }
|
||||||
|
public string u_name { get; set; }
|
||||||
|
public string sex { get; set; }
|
||||||
|
}
|
||||||
|
public class XuZhuModel
|
||||||
|
{
|
||||||
|
public Guid GuestUuid { get; set; } // 不可為空
|
||||||
|
public Guid GuestBedUuid { get; set; } // 不可為空
|
||||||
|
public DateTime CurrentCheckoutDate { get; set; } // 當前退房時間
|
||||||
|
public DateTime NewCheckoutDate { get; set; } // 新退房時間
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,39 +21,49 @@ public class guadanStatisticsController: ApiController
|
|||||||
//挂单统计:房间,床位,挂单笔数,挂单人数的统计
|
//挂单统计:房间,床位,挂单笔数,挂单人数的统计
|
||||||
|
|
||||||
var now = DateTime.Now;
|
var now = DateTime.Now;
|
||||||
var roomCount = await _db.Room.Where(a => a.IsDeleted == false).CountAsync();
|
var guadanTotalCount = await _db.GuaDanOrder
|
||||||
var rooms = await _db.Room.Include(r => r.RegionRoomBed).ToListAsync();
|
.Where(a => a.IsDeleted == false)
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
var emptyRoomCount = rooms
|
.CountAsync();
|
||||||
.Where(r => r.RegionRoomBed.All(b => b.IsAvailableDuring(now, now, _db))) // 這裡就能用方法
|
var guadanCurrentCount = await _db.GuaDanOrderGuest
|
||||||
.Count();
|
.Where(guest => guest.StatusCode != "403")
|
||||||
var bedCount = await _db.RegionRoomBed.Where(a => a.IsDeleted == false).CountAsync();
|
.Where(guest => guest.StatusCode != "404")
|
||||||
var maleBedCount = await _db.RegionRoomBed.Where(a => a.IsDeleted == false && a.Gender == true).CountAsync();
|
.Select(guest => guest.GuaDanOrderNo)
|
||||||
var femaleBedCount = await _db.RegionRoomBed.Where(a => a.IsDeleted == false && a.Gender == false).CountAsync();
|
.Distinct()
|
||||||
|
.CountAsync();
|
||||||
var guadanTotalCount = await _db.GuaDanOrder.Where(a => a.IsDeleted == false).CountAsync();
|
var guadanPeopleTotal = await _db.GuaDanOrderGuest
|
||||||
var guadanPeopleTotal = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false).CountAsync();
|
.Where(a => a.IsDeleted == false)
|
||||||
var guadanPeopleMale = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false && a.follower.sex == "男眾").CountAsync();
|
.Where(guest => guest.StatusCode != "404")
|
||||||
var guadanPeopleFemale = await _db.GuaDanOrderGuest.Where(a => a.IsDeleted == false && a.follower.sex == "女眾").CountAsync();
|
.CountAsync();
|
||||||
dynamic bedCounts = await RegionAndRoomAndBedSchedule.GetAvailableBedCountsAsync(_db, DateTime.Now, DateTime.Now);
|
var guadanPeopleMale = await _db.GuaDanOrderGuest
|
||||||
var guadanCurrentCount = await _db.GuaDanOrder.Where(a => now < a.EndDate).CountAsync();
|
.Where(guest => guest.StatusCode != "404")
|
||||||
var guadanPeopleCurrent = await _db.GuaDanOrderGuest.Where( a => a.CheckOutAt > now).CountAsync();
|
.Where(a => a.IsDeleted == false && a.followers.sex == "男眾")
|
||||||
var guadanPeopleCurrentMale = await _db.GuaDanOrderGuest.Where(a => a.CheckOutAt > now && a.follower.sex == "男眾").CountAsync();
|
.CountAsync();
|
||||||
var guadanPeopleCurrentFemale = await _db.GuaDanOrderGuest.Where(a => a.CheckOutAt > now && a.follower.sex == "女眾").CountAsync();
|
var guadanPeopleFemale = await _db.GuaDanOrderGuest
|
||||||
|
.Where(guest => guest.StatusCode != "404")
|
||||||
|
.Where(a => a.IsDeleted == false && a.followers.sex == "女眾")
|
||||||
|
.CountAsync();
|
||||||
|
var guadanPeopleCurrent = await _db.GuaDanOrderGuest
|
||||||
|
.Where(a => a.IsDeleted == false)
|
||||||
|
.Where(guest => guest.StatusCode != "404")
|
||||||
|
.Where(guest => guest.StatusCode != "403")
|
||||||
|
.Where( a => a.CheckOutAt >= now.Date)
|
||||||
|
.CountAsync();
|
||||||
|
var guadanPeopleCurrentMale = await _db.GuaDanOrderGuest
|
||||||
|
.Where(a => a.IsDeleted == false)
|
||||||
|
.Where(guest => guest.StatusCode != "404")
|
||||||
|
.Where(guest => guest.StatusCode != "403")
|
||||||
|
.Where(a => a.CheckOutAt >= now.Date && a.followers.sex == "男眾")
|
||||||
|
.CountAsync();
|
||||||
|
var guadanPeopleCurrentFemale = await _db.GuaDanOrderGuest
|
||||||
|
.Where(a => a.IsDeleted == false)
|
||||||
|
.Where(guest => guest.StatusCode != "404")
|
||||||
|
.Where(guest => guest.StatusCode != "403")
|
||||||
|
.Where(a => a.CheckOutAt >= now.Date && a.followers.sex == "女眾")
|
||||||
|
.CountAsync();
|
||||||
|
|
||||||
var result = new
|
var result = new
|
||||||
{
|
{
|
||||||
roomStatistics = new
|
|
||||||
{
|
|
||||||
roomCount = roomCount,
|
|
||||||
emptyRoomCount = emptyRoomCount,
|
|
||||||
bedCount = bedCount,
|
|
||||||
maleBedCount = maleBedCount,
|
|
||||||
femaleBedCount = femaleBedCount,
|
|
||||||
emptyBedCount = bedCounts.male + bedCounts.female,
|
|
||||||
emptyMaleBedCount = bedCounts.male,
|
|
||||||
emptyFemaleBedCount = bedCounts.female
|
|
||||||
},
|
|
||||||
guadanStatistics = new
|
guadanStatistics = new
|
||||||
{
|
{
|
||||||
guadanTotalCount = guadanTotalCount, // 总挂单次数
|
guadanTotalCount = guadanTotalCount, // 总挂单次数
|
||||||
@@ -61,7 +71,7 @@ public class guadanStatisticsController: ApiController
|
|||||||
guadanPeopleTotal = guadanPeopleTotal, // 总挂单人数
|
guadanPeopleTotal = guadanPeopleTotal, // 总挂单人数
|
||||||
guadanPeopleMale = guadanPeopleMale,
|
guadanPeopleMale = guadanPeopleMale,
|
||||||
guadanPeopleFemale = guadanPeopleFemale,
|
guadanPeopleFemale = guadanPeopleFemale,
|
||||||
guadanPeopleCurrent = guadanPeopleCurrent, // 当前挂单人数
|
guadanPeopleCurrent = guadanPeopleCurrent, // 已預約掛單人數
|
||||||
guadanPeopleCurrentMale = guadanPeopleCurrentMale,
|
guadanPeopleCurrentMale = guadanPeopleCurrentMale,
|
||||||
guadanPeopleCurrentFemale = guadanPeopleCurrentFemale
|
guadanPeopleCurrentFemale = guadanPeopleCurrentFemale
|
||||||
}
|
}
|
||||||
|
|||||||
93
web/App_Code/api/guadanStatisticsTableController.cs
Normal file
93
web/App_Code/api/guadanStatisticsTableController.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// guadanStatisticsTable 的摘要描述
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[ezAuthorize]
|
||||||
|
public class guadanStatisticsTableController: ApiController
|
||||||
|
{
|
||||||
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
public guadanStatisticsTableController()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: 在這裡新增建構函式邏輯
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/guadan/guadanstatisticstable/list")]
|
||||||
|
public IHttpActionResult Get([FromUri] DateTime? start, [FromUri] DateTime? end)
|
||||||
|
{
|
||||||
|
// 如果兩個都為空,設定 start = 今天,end = 一個月後
|
||||||
|
if (!start.HasValue && !end.HasValue)
|
||||||
|
{
|
||||||
|
start = DateTime.Today;
|
||||||
|
end = DateTime.Today.AddMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有 start 沒有 end,就給 end 預設一個月後
|
||||||
|
if (start.HasValue && !end.HasValue)
|
||||||
|
{
|
||||||
|
end = start.Value.Date.AddMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有 end 沒有 start,就給 start 預設 end 的前一個月
|
||||||
|
if (!start.HasValue && end.HasValue)
|
||||||
|
{
|
||||||
|
start = end.Value.Date.AddMonths(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最後確保只取 date 部分
|
||||||
|
var startDate = start.Value.Date;
|
||||||
|
var endDate = end.Value.Date;
|
||||||
|
|
||||||
|
// 查詢資料庫時就用 date 型別對應
|
||||||
|
var statistics = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.IsCancel == false)
|
||||||
|
.Where(s => s.ScheduleDate >= startDate && s.ScheduleDate <= endDate)
|
||||||
|
.GroupBy(s => s.ScheduleDate)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
date = g.Key,
|
||||||
|
todaytotalbookers = g.Count(), // 该日期的总记录数
|
||||||
|
checkin = g.Key <= DateTime.Today
|
||||||
|
? g.Count(x => x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "402"
|
||||||
|
|| x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "403")
|
||||||
|
: 0,
|
||||||
|
checkinfemale = g.Key <= DateTime.Today
|
||||||
|
? g.Count(x => (x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "402"
|
||||||
|
|| x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "403")
|
||||||
|
&& x.GuaDanOrderGuest.followers.sex == "女眾")
|
||||||
|
: 0,
|
||||||
|
checkinmale = g.Key <= DateTime.Today
|
||||||
|
? g.Count(x => (x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "402"
|
||||||
|
|| x.GuaDanOrderGuest.RegionRoomBedStatus.Code == "403")
|
||||||
|
&& x.GuaDanOrderGuest.followers.sex == "男眾")
|
||||||
|
: 0,
|
||||||
|
bookfemale = g.Count(x => x.GuaDanOrderGuest.followers.sex == "女眾"),
|
||||||
|
bookmale = g.Count(x => x.GuaDanOrderGuest.followers.sex == "男眾")
|
||||||
|
})
|
||||||
|
.OrderBy(x => x.date)
|
||||||
|
.ToList();
|
||||||
|
var todayDate = DateTime.Today;
|
||||||
|
|
||||||
|
var bedcount = _db.RegionRoomBed
|
||||||
|
.Where(a => a.IsDeleted == false)
|
||||||
|
.Count();
|
||||||
|
var roomcount = _db.Room.Count();
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
bedcount,
|
||||||
|
roomcount,
|
||||||
|
statistics,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ using System.Web.Http;
|
|||||||
/// lianyouController 的摘要描述
|
/// lianyouController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class lianyouController: ApiController
|
public class lianyouController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
|
|
||||||
@@ -19,13 +19,34 @@ public class lianyouController: ApiController
|
|||||||
[Route("api/lianyou/getfollowers")]
|
[Route("api/lianyou/getfollowers")]
|
||||||
public async Task<IHttpActionResult> GetGuadanFollowers(int page, int pageSize, string searchName = null)
|
public async Task<IHttpActionResult> GetGuadanFollowers(int page, int pageSize, string searchName = null)
|
||||||
{
|
{
|
||||||
var qry = _db.followers.AsEnumerable();
|
// IQueryable 可讓 EF 在資料庫層面執行過濾和投影
|
||||||
if(searchName != null)
|
var qry = _db.followers.AsQueryable();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(searchName))
|
||||||
{
|
{
|
||||||
qry = qry.Where(a => (a.u_name ?? "").Contains(searchName) || (a.phone ?? "").Contains(searchName));
|
qry = qry.Where(a => (a.u_name ?? "").Contains(searchName) || (a.phone ?? "").Contains(searchName));
|
||||||
}
|
}
|
||||||
var count = qry.Count();
|
|
||||||
var data = qry.OrderBy(a => a.f_number).ToPagedList(page, pageSize);
|
var count = await qry.CountAsync();
|
||||||
return Ok(new {data = data, count = count});
|
|
||||||
|
// 投影到只需要的欄位
|
||||||
|
var projected = qry
|
||||||
|
.OrderBy(a => a.f_number)
|
||||||
|
.Select(a => new
|
||||||
|
{
|
||||||
|
num = a.num,
|
||||||
|
u_name = a.u_name,
|
||||||
|
phone = a.phone,
|
||||||
|
sex = a.sex,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 分頁
|
||||||
|
var data = projected
|
||||||
|
.Skip((page - 1) * pageSize)
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToList(); // 如果使用 EF Core 可用 ToListAsync()
|
||||||
|
|
||||||
|
return Ok(new { data = data, count = count });
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ public class memberController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.members.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.members.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrEmpty(prod.pic1))
|
if(!string.IsNullOrEmpty(prod.pic1))
|
||||||
@@ -79,7 +79,7 @@ public class memberController : BaseApiController
|
|||||||
[Route("api/member/DeleteCheck/{id}")]
|
[Route("api/member/DeleteCheck/{id}")]
|
||||||
public void DeleteCheck(int id) //刪除考勤資料
|
public void DeleteCheck(int id) //刪除考勤資料
|
||||||
{
|
{
|
||||||
var prod = _db.member_check.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.member_check.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.member_check.Remove(prod);
|
_db.member_check.Remove(prod);
|
||||||
@@ -93,9 +93,9 @@ public class memberController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
|
|
||||||
var prod = _db.members.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
var prod = _db.members.Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
publicFun publicFun = new publicFun();
|
publicFun publicFun = new publicFun();
|
||||||
@@ -107,8 +107,8 @@ public class memberController : BaseApiController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var prod2 = _db.member_check.AsEnumerable().Where(q => getDelItem.Contains(Convert.ToInt32(q.mem_num))).ToList();
|
var prod2 = _db.member_check.Where(q => q.mem_num.HasValue && getDelItem.Contains(q.mem_num.Value)).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count() > 0)
|
||||||
{
|
{
|
||||||
_db.member_check.RemoveRange(prod2);
|
_db.member_check.RemoveRange(prod2);
|
||||||
//_db.SaveChanges();
|
//_db.SaveChanges();
|
||||||
@@ -135,8 +135,8 @@ public class memberController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
var prod = _db.member_check.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.member_check.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
_db.member_check.RemoveRange(prod);
|
_db.member_check.RemoveRange(prod);
|
||||||
@@ -150,7 +150,7 @@ public class memberController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.member q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.member q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.members.AsEnumerable();
|
var qry = _db.members.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.u_name))
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||||
@@ -220,10 +220,11 @@ public class memberController : BaseApiController
|
|||||||
else
|
else
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
m_number = x.m_number,
|
m_number = x.m_number,
|
||||||
@@ -242,7 +243,7 @@ public class memberController : BaseApiController
|
|||||||
starttime = x.group_kind.HasValue ? x.member_group.starttime : (object)null,
|
starttime = x.group_kind.HasValue ? x.member_group.starttime : (object)null,
|
||||||
demo = x.demo,
|
demo = x.demo,
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -256,7 +257,7 @@ public class memberController : BaseApiController
|
|||||||
public IHttpActionResult GetCheckList([FromBody] Model.ViewModel.member_check q, int page, int pageSize = 10,
|
public IHttpActionResult GetCheckList([FromBody] Model.ViewModel.member_check q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.member_check.AsEnumerable();
|
var qry = _db.member_check.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.u_name))
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
qry = qry.Where(o => o.member.u_name.Contains(q.u_name));
|
qry = qry.Where(o => o.member.u_name.Contains(q.u_name));
|
||||||
@@ -317,9 +318,11 @@ public class memberController : BaseApiController
|
|||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.member.attendances.type>();
|
var tdesc = publicFun.enum_desc<Model.member.attendances.type>();
|
||||||
var tdesc2 = publicFun.enum_desc<Model.member.attendances.login>();
|
var tdesc2 = publicFun.enum_desc<Model.member.attendances.login>();
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
m_number = x.member.m_number,
|
m_number = x.member.m_number,
|
||||||
@@ -332,7 +335,7 @@ public class memberController : BaseApiController
|
|||||||
login_type_desc = tdesc2[x.login_type ?? 1]
|
login_type_desc = tdesc2[x.login_type ?? 1]
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -346,7 +349,7 @@ public class memberController : BaseApiController
|
|||||||
public IHttpActionResult GetGroupList([FromBody] Model.ViewModel.member_group q, int page, int pageSize = 10,
|
public IHttpActionResult GetGroupList([FromBody] Model.ViewModel.member_group q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.member_group.AsEnumerable();
|
var qry = _db.member_group.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -394,7 +397,7 @@ public class memberController : BaseApiController
|
|||||||
public IHttpActionResult GetTitleList([FromBody] Model.ViewModel.member_title q, int page, int pageSize = 10,
|
public IHttpActionResult GetTitleList([FromBody] Model.ViewModel.member_title q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.member_title.AsEnumerable();
|
var qry = _db.member_title.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class member_titleController : ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.member_title q,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.member_title q,
|
||||||
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.member_title.AsEnumerable();
|
var qry = _db.member_title.AsQueryable();
|
||||||
var ret = new { list = "", count = 0 };
|
var ret = new { list = "", count = 0 };
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ public class newsController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.news.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.news.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//刪除檔案
|
//刪除檔案
|
||||||
var prod2 = _db.news_files.AsEnumerable().Where(q => q.news_id == id).ToList();
|
var prod2 = _db.news_files.Where(q => q.news_id == id).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var item in prod2)
|
foreach (var item in prod2)
|
||||||
@@ -91,12 +91,12 @@ public class newsController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
|
|
||||||
var prod = _db.news.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
var prod = _db.news.Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
var prod2 = _db.news_files.AsEnumerable().Where(q => getDelItem.Contains(q.news_id)).ToList();
|
var prod2 = _db.news_files.Where(q => getDelItem.Contains(q.news_id)).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
publicFun publicFun = new publicFun();
|
publicFun publicFun = new publicFun();
|
||||||
@@ -139,7 +139,7 @@ public class newsController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.news q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.news q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false, bool top = false)
|
string sortBy = "", bool sortDesc = false, bool top = false)
|
||||||
{
|
{
|
||||||
var qry = _db.news.AsEnumerable();
|
var qry = _db.news.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
qry = qry.Where(o => o.subject.Contains(q.subject.Trim()));
|
qry = qry.Where(o => o.subject.Contains(q.subject.Trim()));
|
||||||
@@ -259,9 +259,12 @@ public class newsController : BaseApiController
|
|||||||
qry = qry.OrderByDescending(o => o.topping).ThenByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.topping).ThenByDescending(o => o.num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
subject = x.subject,
|
subject = x.subject,
|
||||||
@@ -282,7 +285,7 @@ public class newsController : BaseApiController
|
|||||||
topping = x.topping
|
topping = x.topping
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -298,7 +301,7 @@ public class newsController : BaseApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
var qry = _db.news_kind.AsEnumerable();
|
var qry = _db.news_kind.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -319,17 +322,18 @@ public class newsController : BaseApiController
|
|||||||
range = o.range,
|
range = o.range,
|
||||||
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qry2List = (pageSize > 0) ? qry2.ToPagedList(page, pageSize).ToList() : qry2.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry2.ToPagedList(page, pageSize).Select(x => new
|
list = qry2List.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
kind = new TreeView().RptDash(x.Level) + x.kind,
|
kind = new TreeView().RptDash(x.Level) + x.kind,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class orderController : ApiController
|
|||||||
{
|
{
|
||||||
if (id > 0)
|
if (id > 0)
|
||||||
{
|
{
|
||||||
var prod = _db.pro_order_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.pro_order_detail.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//刪除掛單表單
|
//刪除掛單表單
|
||||||
@@ -134,7 +134,7 @@ public class orderController : ApiController
|
|||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',');
|
var ids = nums.TrimEnd(',').Split(',');
|
||||||
|
|
||||||
var prod = _db.pro_order.AsEnumerable().Where(q => ids.Contains(q.order_no)).ToList();
|
var prod = _db.pro_order.Where(q => ids.Contains(q.order_no)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
var prod2 = _db.pro_order_detail.AsEnumerable().Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
|
var prod2 = _db.pro_order_detail.AsEnumerable().Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
|
||||||
@@ -201,7 +201,7 @@ public class orderController : ApiController
|
|||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
var qry = _db.pro_order.AsEnumerable();
|
var qry = _db.pro_order.AsQueryable();
|
||||||
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
||||||
|
|
||||||
|
|
||||||
@@ -220,32 +220,32 @@ public class orderController : ApiController
|
|||||||
if (!string.IsNullOrEmpty(q.address))
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(q.subject?.Trim()));
|
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(q.subject.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.u_name))
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(q.u_name?.Trim()));
|
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(q.u_name.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.introducerTxt))
|
if (!string.IsNullOrEmpty(q.introducerTxt))
|
||||||
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(q.introducerTxt?.Trim()));
|
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(q.introducerTxt.Trim()));
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.actItemTxt))
|
if (!string.IsNullOrEmpty(q.actItemTxt))
|
||||||
{
|
{
|
||||||
//qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num?.ToString())).Count() > 0);
|
//qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num?.ToString())).Count() > 0);
|
||||||
// qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.Any(x => x == f2.actItem_num)).Count() > 0);
|
// qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.Any(x => x == f2.actItem_num)).Count() > 0);
|
||||||
|
|
||||||
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(q.actItemTxt?.Trim())).Count() > 0);
|
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(q.actItemTxt.Trim())).Count() > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.country))
|
if (!string.IsNullOrEmpty(q.country))
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country == q.country);
|
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.country == q.country);
|
||||||
if (!string.IsNullOrEmpty(q.country2))
|
if (!string.IsNullOrEmpty(q.country2))
|
||||||
{
|
{
|
||||||
if (q.country2 == "1")
|
if (q.country2 == "1")
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country == "158");
|
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.country == "158");
|
||||||
}
|
}
|
||||||
else if (q.country2 == "2")
|
else if (q.country2 == "2")
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country != "158");
|
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.country != "158");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,16 +275,16 @@ public class orderController : ApiController
|
|||||||
else if (sortBy.Equals("u_name"))
|
else if (sortBy.Equals("u_name"))
|
||||||
{
|
{
|
||||||
if (sortDesc)
|
if (sortDesc)
|
||||||
qry = qry.OrderByDescending(o => o.follower?.u_name);
|
qry = qry.OrderByDescending(o => o.follower != null ? o.follower.u_name : "");
|
||||||
else
|
else
|
||||||
qry = qry.OrderBy(o => o.follower?.u_name);
|
qry = qry.OrderBy(o => o.follower != null ? o.follower.u_name : "");
|
||||||
}
|
}
|
||||||
else if (sortBy.Equals("subject"))
|
else if (sortBy.Equals("subject"))
|
||||||
{
|
{
|
||||||
if (sortDesc)
|
if (sortDesc)
|
||||||
qry = qry.OrderByDescending(o => o.activity?.subject);
|
qry = qry.OrderByDescending(o => o.activity != null ? o.activity.subject : "");
|
||||||
else
|
else
|
||||||
qry = qry.OrderBy(o => o.activity?.subject);
|
qry = qry.OrderBy(o => o.activity != null ? o.activity.subject : "");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
qry = qry.OrderByDescending(o => o.reg_time);
|
qry = qry.OrderByDescending(o => o.reg_time);
|
||||||
@@ -801,15 +801,15 @@ public class orderController : ApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
//家族 : 家長是我的人,跟我同家長的人,我的家長本人,我本人
|
//家族 : 家長是我的人,跟我同家長的人,我的家長本人,我本人
|
||||||
var cc = _db.followers.Where(x => x.num == _follower || x.leader == _follower).Select(x => x.num);
|
var ccList = _db.followers.Where(x => x.num == _follower || x.leader == _follower).Select(x => x.num).ToList();
|
||||||
var qry = _db.followers.AsEnumerable().Where(f => cc.Any(x => x == f.num) || cc.Any(x => x == f.leader));
|
var qry = _db.followers.Where(f => ccList.Contains(f.num) || (f.leader.HasValue && ccList.Contains(f.leader.Value)));
|
||||||
|
|
||||||
//未付款資料
|
//未付款資料
|
||||||
var unpayDt = _db.pro_order_detail.AsEnumerable();
|
var unpayDt = _db.pro_order_detail.AsQueryable();
|
||||||
var coDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
var coDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
||||||
|
|
||||||
//未付款訂單
|
//未付款訂單
|
||||||
var orderDt = _db.pro_order.AsEnumerable();
|
var orderDt = _db.pro_order.AsQueryable();
|
||||||
if (!string.IsNullOrEmpty(order_no))
|
if (!string.IsNullOrEmpty(order_no))
|
||||||
orderDt = orderDt.Where(x => x.order_no == order_no);
|
orderDt = orderDt.Where(x => x.order_no == order_no);
|
||||||
orderDt = orderDt.Where(x => coDt.Select(d => d.order_no).Contains(x.order_no));
|
orderDt = orderDt.Where(x => coDt.Select(d => d.order_no).Contains(x.order_no));
|
||||||
@@ -855,7 +855,7 @@ public class orderController : ApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
//未付款資料
|
//未付款資料
|
||||||
var unpayDt = _db.pro_order_detail.AsEnumerable();
|
var unpayDt = _db.pro_order_detail.AsQueryable();
|
||||||
unpayDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
unpayDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.order_no))
|
if (!string.IsNullOrEmpty(q.order_no))
|
||||||
@@ -1118,7 +1118,7 @@ public class orderController : ApiController
|
|||||||
[Route("api/order/DeleteRecordDetail/{id}")]//刪除收款註記
|
[Route("api/order/DeleteRecordDetail/{id}")]//刪除收款註記
|
||||||
public void DeleteRecordDetail(int id)
|
public void DeleteRecordDetail(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.pro_order_record.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.pro_order_record.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -22,99 +22,19 @@ public class orderdetailController:ApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.pro_order q, int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.pro_order q, int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
int activity_num = Convert.ToInt32(q.activity_num);
|
int activity_num = Convert.ToInt32(q.activity_num);
|
||||||
|
//現在的牌位預覽只會出現功德主,修改為所有人都會出現
|
||||||
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
||||||
var OrderList = _db.pro_order.Where(u => u.activity_num == activity_num).Select(j => j.order_no).ToList();
|
//var OrderList = _db.pro_order.Where(u => u.activity_num == activity_num).Select(j => j.order_no).ToList();
|
||||||
var gdzOrderList = _db.pro_order_detail.Where(o => OrderList.Contains(o.order_no) && o.print_id.Contains("主")).Select(o => o.order_no).Distinct().ToList();
|
//var gdzOrderList = _db.pro_order_detail.Where(o => OrderList.Contains(o.order_no) && o.print_id.Contains("主")).Select(o => o.order_no).Distinct().ToList();
|
||||||
var qry = _db.pro_order.Where(u => gdzOrderList.Contains(u.order_no)).AsEnumerable();
|
//var qry = _db.pro_order.Where(u => gdzOrderList.Contains(u.order_no)).AsEnumerable();
|
||||||
if (!string.IsNullOrEmpty(q.order_no))
|
var qry = _db.pro_order.Where( u => u.activity_num == activity_num).OrderByDescending(o => o.reg_time);
|
||||||
qry = qry.Where(o => o.order_no.Contains(q.order_no.Trim()));
|
|
||||||
if (!string.IsNullOrEmpty(q.keyin1))
|
|
||||||
qry = qry.Where(o => o.keyin1.Contains(q.keyin1));
|
|
||||||
if (q.f_num.HasValue && q.f_num > 0)
|
|
||||||
qry = qry.Where(o => o.f_num == q.f_num);
|
|
||||||
if (q.activity_num.HasValue && q.activity_num > 0)
|
|
||||||
qry = qry.Where(o => o.activity_num == q.activity_num);
|
|
||||||
if (q.up_time1.HasValue)
|
|
||||||
qry = qry.Where(o => o.up_time >= q.up_time1.Value);
|
|
||||||
if (q.up_time2.HasValue)
|
|
||||||
qry = qry.Where(o => o.up_time < Convert.ToDateTime(q.up_time2.Value).AddDays(1));
|
|
||||||
if (!string.IsNullOrEmpty(q.address))
|
|
||||||
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
|
||||||
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(q.subject?.Trim()));
|
|
||||||
if (!string.IsNullOrEmpty(q.u_name))
|
|
||||||
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(q.u_name?.Trim()));
|
|
||||||
if (!string.IsNullOrEmpty(q.introducerTxt))
|
|
||||||
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(q.introducerTxt?.Trim()));
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.actItemTxt))
|
|
||||||
{
|
|
||||||
//qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num?.ToString())).Count() > 0);
|
|
||||||
// qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.Any(x => x == f2.actItem_num)).Count() > 0);
|
|
||||||
|
|
||||||
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(q.actItemTxt?.Trim())).Count() > 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.country))
|
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country == q.country);
|
|
||||||
if (!string.IsNullOrEmpty(q.country2))
|
|
||||||
{
|
|
||||||
if (q.country2 == "1")
|
|
||||||
{
|
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country == "158");
|
|
||||||
}
|
|
||||||
else if (q.country2 == "2")
|
|
||||||
{
|
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country != "158");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (sortBy.Equals("order_no"))
|
|
||||||
{
|
|
||||||
if (sortDesc)
|
|
||||||
qry = qry.OrderByDescending(o => o.order_no);
|
|
||||||
else
|
|
||||||
qry = qry.OrderBy(o => o.order_no);
|
|
||||||
}
|
|
||||||
else if (sortBy.Equals("keyin1_txt"))
|
|
||||||
{
|
|
||||||
if (sortDesc)
|
|
||||||
qry = qry.OrderByDescending(o => o.keyin1);
|
|
||||||
else
|
|
||||||
qry = qry.OrderBy(o => o.keyin1);
|
|
||||||
}
|
|
||||||
else if (sortBy.Equals("up_time"))
|
|
||||||
{
|
|
||||||
if (sortDesc)
|
|
||||||
qry = qry.OrderByDescending(o => o.up_time);
|
|
||||||
else
|
|
||||||
qry = qry.OrderBy(o => o.up_time);
|
|
||||||
}
|
|
||||||
else if (sortBy.Equals("u_name"))
|
|
||||||
{
|
|
||||||
if (sortDesc)
|
|
||||||
qry = qry.OrderByDescending(o => o.follower?.u_name);
|
|
||||||
else
|
|
||||||
qry = qry.OrderBy(o => o.follower?.u_name);
|
|
||||||
}
|
|
||||||
else if (sortBy.Equals("subject"))
|
|
||||||
{
|
|
||||||
if (sortDesc)
|
|
||||||
qry = qry.OrderByDescending(o => o.activity?.subject);
|
|
||||||
else
|
|
||||||
qry = qry.OrderBy(o => o.activity?.subject);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
qry = qry.OrderByDescending(o => o.reg_time);
|
|
||||||
|
|
||||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
order_no = x.order_no,
|
order_no = x.order_no,
|
||||||
f_num = x.f_num,
|
f_num = x.f_num,
|
||||||
@@ -125,8 +45,12 @@ public class orderdetailController:ApiController
|
|||||||
up_time = x.up_time,
|
up_time = x.up_time,
|
||||||
keyin1_txt = Model.pro_order.keyin1_value_to_text(x.keyin1),
|
keyin1_txt = Model.pro_order.keyin1_value_to_text(x.keyin1),
|
||||||
//detail = x.pro_order_detail.Where(u => u.printed_files != null)
|
//detail = x.pro_order_detail.Where(u => u.printed_files != null)
|
||||||
detail = new { count = x.pro_order_detail.Where(u => u.actItem.act_bom.Count() == 0).Count(),
|
detail = new { count = x.pro_order_detail
|
||||||
actItem = x.pro_order_detail.Where(u => u.printed_files != null).FirstOrDefault()?.print_id }
|
.Where(u => (u.parent_num != null)
|
||||||
|
|| u.actItem.subject.Contains("牌")
|
||||||
|
|| !string.IsNullOrEmpty(u.f_num_tablet))
|
||||||
|
.Count(),
|
||||||
|
actItem = x.pro_order_detail.Where(u => u.printed_files != null).Select(u => u.print_id).FirstOrDefault() }
|
||||||
}),
|
}),
|
||||||
count = count
|
count = count
|
||||||
};
|
};
|
||||||
|
|||||||
250
web/App_Code/api/pivot01Controller.cs
Normal file
250
web/App_Code/api/pivot01Controller.cs
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Configuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// pivot01Controller - 法會報名統計分析 API
|
||||||
|
/// 設計理念:直接查詢 SQL VIEW,保持彈性與簡潔
|
||||||
|
/// </summary>
|
||||||
|
[ezAuthorize]
|
||||||
|
public class pivot01Controller : ApiController
|
||||||
|
{
|
||||||
|
// 連線字串
|
||||||
|
private readonly string _connectionString;
|
||||||
|
|
||||||
|
public pivot01Controller()
|
||||||
|
{
|
||||||
|
// 優先使用 shopConn 連線字串(純 SQL Server 連線字串)
|
||||||
|
var shopConnectionString = ConfigurationManager.ConnectionStrings["shopConn"]?.ConnectionString;
|
||||||
|
if (!string.IsNullOrEmpty(shopConnectionString))
|
||||||
|
{
|
||||||
|
// 移除不相容的 Provider 參數(包含 SQLOLEDB 和 SQLNCLI11)
|
||||||
|
_connectionString = shopConnectionString
|
||||||
|
.Replace("Provider=SQLOLEDB;", "")
|
||||||
|
.Replace("Provider=SQLNCLI11;", "")
|
||||||
|
.Replace(" Provider=SQLOLEDB", "")
|
||||||
|
.Replace(" Provider=SQLNCLI11", "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 備用方案:從 Entity Framework 連線字串中提取 SQL Server 連線字串
|
||||||
|
var efConnectionString = ConfigurationManager.ConnectionStrings["ezEntities"]?.ConnectionString;
|
||||||
|
if (!string.IsNullOrEmpty(efConnectionString))
|
||||||
|
{
|
||||||
|
// 解析 EF 連線字串,提取 provider connection string 部分
|
||||||
|
var startIndex = efConnectionString.IndexOf("provider connection string="") + "provider connection string="".Length;
|
||||||
|
var endIndex = efConnectionString.LastIndexOf(""");
|
||||||
|
if (startIndex > 0 && endIndex > startIndex)
|
||||||
|
{
|
||||||
|
_connectionString = efConnectionString.Substring(startIndex, endIndex - startIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("無法解析 Entity Framework 連線字串");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("找不到可用的資料庫連線字串");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 通用 VIEW 查詢方法
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 執行 SQL 查詢並回傳 DataTable
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sql">SQL 查詢語句</param>
|
||||||
|
/// <param name="parameters">參數陣列</param>
|
||||||
|
/// <returns>查詢結果 DataTable</returns>
|
||||||
|
private DataTable ExecuteSqlQuery(string sql, SqlParameter[] parameters = null)
|
||||||
|
{
|
||||||
|
var dataTable = new DataTable();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var connection = new SqlConnection(_connectionString))
|
||||||
|
using (var command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
// 設定逾時時間為 60 秒
|
||||||
|
command.CommandTimeout = 60;
|
||||||
|
|
||||||
|
// 加入參數
|
||||||
|
if (parameters != null && parameters.Length > 0)
|
||||||
|
{
|
||||||
|
command.Parameters.AddRange(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 開啟連線並執行查詢
|
||||||
|
connection.Open();
|
||||||
|
using (var adapter = new SqlDataAdapter(command))
|
||||||
|
{
|
||||||
|
adapter.Fill(dataTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SqlException ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"SQL 查詢錯誤: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"執行查詢時發生錯誤: {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DataTable 轉換為動態物件列表(保留中文欄位名)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dt">DataTable</param>
|
||||||
|
/// <returns>Dictionary 列表</returns>
|
||||||
|
private List<Dictionary<string, object>> DataTableToDictionary(DataTable dt)
|
||||||
|
{
|
||||||
|
var list = new List<Dictionary<string, object>>();
|
||||||
|
|
||||||
|
foreach (DataRow row in dt.Rows)
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<string, object>();
|
||||||
|
foreach (DataColumn col in dt.Columns)
|
||||||
|
{
|
||||||
|
// 保留原始欄位名稱(包含中文)
|
||||||
|
dict[col.ColumnName] = row[col] == DBNull.Value ? null : row[col];
|
||||||
|
}
|
||||||
|
list.Add(dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region API 端點
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GET /api/pivot01/activity_stats
|
||||||
|
/// 查詢法會統計(對應「法會統計」VIEW)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="year">查詢年份</param>
|
||||||
|
/// <returns>法會統計資料</returns>
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/pivot01/activity_stats")]
|
||||||
|
public IHttpActionResult GetActivityStats(int year)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 驗證年份參數
|
||||||
|
if (year < 1900 || year > 2100)
|
||||||
|
{
|
||||||
|
return BadRequest("年份參數不正確,請輸入 1900 ~ 2100 之間的年份");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 建立 SQL 查詢(包含當年度及無日期的法會)
|
||||||
|
string sql = @"
|
||||||
|
SELECT * FROM [法會統計]
|
||||||
|
WHERE (YEAR(開始日期) = @year OR 開始日期 IS NULL)
|
||||||
|
ORDER BY
|
||||||
|
CASE WHEN 開始日期 IS NULL THEN 1 ELSE 0 END,
|
||||||
|
開始日期 DESC,
|
||||||
|
結束日期 DESC
|
||||||
|
";
|
||||||
|
|
||||||
|
// 建立參數
|
||||||
|
var parameters = new[]
|
||||||
|
{
|
||||||
|
new SqlParameter("@year", SqlDbType.Int) { Value = year }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 執行查詢
|
||||||
|
var dataTable = ExecuteSqlQuery(sql, parameters);
|
||||||
|
var data = DataTableToDictionary(dataTable);
|
||||||
|
|
||||||
|
// 回應結果
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
success = true,
|
||||||
|
data = data,
|
||||||
|
message = "查詢成功",
|
||||||
|
rowCount = data.Count
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var errorResponse = new
|
||||||
|
{
|
||||||
|
success = false,
|
||||||
|
message = $"查詢失敗:{ex.Message}",
|
||||||
|
error = ex.ToString()
|
||||||
|
};
|
||||||
|
return Content(System.Net.HttpStatusCode.BadRequest, errorResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GET /api/pivot01/registration_details
|
||||||
|
/// 查詢報名明細(對應「報名明細查詢」VIEW)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="activityNum">法會編號(必填)</param>
|
||||||
|
/// <returns>報名明細資料</returns>
|
||||||
|
[HttpGet]
|
||||||
|
[Route("api/pivot01/registration_details")]
|
||||||
|
public IHttpActionResult GetRegistrationDetails(int? activityNum = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 驗證參數
|
||||||
|
if (!activityNum.HasValue || activityNum.Value <= 0)
|
||||||
|
{
|
||||||
|
return BadRequest("請提供有效的法會編號(activityNum)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 建立查詢 SQL
|
||||||
|
string sql = @"
|
||||||
|
SELECT * FROM [報名明細查詢]
|
||||||
|
WHERE 法會ID = @activityNum
|
||||||
|
ORDER BY 報名日期 DESC, 報名編號 DESC
|
||||||
|
";
|
||||||
|
|
||||||
|
// 建立參數
|
||||||
|
var parameters = new[]
|
||||||
|
{
|
||||||
|
new SqlParameter("@activityNum", SqlDbType.Int) { Value = activityNum.Value }
|
||||||
|
};
|
||||||
|
|
||||||
|
// 執行查詢
|
||||||
|
var dataTable = ExecuteSqlQuery(sql, parameters);
|
||||||
|
var data = DataTableToDictionary(dataTable);
|
||||||
|
|
||||||
|
// 回應結果
|
||||||
|
var result = new
|
||||||
|
{
|
||||||
|
success = true,
|
||||||
|
data = data,
|
||||||
|
message = "查詢成功",
|
||||||
|
rowCount = data.Count
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var errorResponse = new
|
||||||
|
{
|
||||||
|
success = false,
|
||||||
|
message = $"查詢失敗:{ex.Message}",
|
||||||
|
error = ex.ToString()
|
||||||
|
};
|
||||||
|
return Content(System.Net.HttpStatusCode.BadRequest, errorResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
1142
web/App_Code/api/pivotController.cs
Normal file
1142
web/App_Code/api/pivotController.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,7 @@ public class projectController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.projects.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.projects.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.project_sub.RemoveRange(prod.project_sub); //刪除活動資料
|
_db.project_sub.RemoveRange(prod.project_sub); //刪除活動資料
|
||||||
@@ -75,7 +75,7 @@ public class projectController : BaseApiController
|
|||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
||||||
var prod = _db.projects.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.projects.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
foreach (var item in prod)
|
foreach (var item in prod)
|
||||||
@@ -103,7 +103,7 @@ public class projectController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (id > 0)
|
if (id > 0)
|
||||||
{
|
{
|
||||||
var prod = _db.project_sub.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.project_sub.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.project_sub.Remove(prod);
|
_db.project_sub.Remove(prod);
|
||||||
@@ -117,7 +117,7 @@ public class projectController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.project q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.project q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.projects.AsEnumerable();
|
var qry = _db.projects.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
qry = qry.Where(o => o.subject.Contains(q.subject.Trim()));
|
qry = qry.Where(o => o.subject.Contains(q.subject.Trim()));
|
||||||
@@ -192,7 +192,7 @@ public class projectController : BaseApiController
|
|||||||
public IHttpActionResult GetKindList([FromBody] Model.ViewModel.project_kind q, int page, int pageSize = 10,
|
public IHttpActionResult GetKindList([FromBody] Model.ViewModel.project_kind q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.project_kind.AsEnumerable();
|
var qry = _db.project_kind.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -247,7 +247,7 @@ public class projectController : BaseApiController
|
|||||||
|
|
||||||
if (q.num.HasValue)
|
if (q.num.HasValue)
|
||||||
{
|
{
|
||||||
var qry = _db.project_sub.AsEnumerable();
|
var qry = _db.project_sub.AsQueryable();
|
||||||
|
|
||||||
qry = qry.Where(o => o.pro_id == q.num.Value);
|
qry = qry.Where(o => o.pro_id == q.num.Value);
|
||||||
|
|
||||||
@@ -337,11 +337,11 @@ public class projectController : BaseApiController
|
|||||||
public IHttpActionResult GetPatronizeList([FromBody] Model.ViewModel.pro_order_detail q, int page, int pageSize = 10,
|
public IHttpActionResult GetPatronizeList([FromBody] Model.ViewModel.pro_order_detail q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var projectDt = _db.projects.AsEnumerable(); ;//專案
|
var projectDt = _db.projects.AsQueryable(); ;//專案
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var qry = _db.pro_order_detail.AsEnumerable();
|
var qry = _db.pro_order_detail.AsQueryable();
|
||||||
qry = qry.Where(o => (int?)o.actItem.category == (int)Model.activity.category.Patronize);
|
qry = qry.Where(o => (int?)o.actItem.category == (int)Model.activity.category.Patronize);
|
||||||
|
|
||||||
if (q.f_num.HasValue)
|
if (q.f_num.HasValue)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
@@ -11,7 +12,7 @@ using System.Web.Routing;
|
|||||||
/// regionController 的摘要描述
|
/// regionController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class regionController: ApiController
|
public class regionController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public regionController()
|
public regionController()
|
||||||
@@ -39,8 +40,9 @@ public class regionController: ApiController
|
|||||||
var startDate = filter.StartDate.Date;
|
var startDate = filter.StartDate.Date;
|
||||||
var endDate = filter.EndDate.Date;
|
var endDate = filter.EndDate.Date;
|
||||||
|
|
||||||
var query = _db.Region
|
var query = _db.Region//區域狀態是否啟用這裡只設置了過濾了有客房的區域,是否要過濾所有
|
||||||
.Where(r => !r.IsDeleted)
|
.Where(r => !r.IsDeleted)
|
||||||
|
.Where(r => r.IsActive)
|
||||||
.Where(r => r.Room.Any());
|
.Where(r => r.Room.Any());
|
||||||
|
|
||||||
if (filter.Gender != null)
|
if (filter.Gender != null)
|
||||||
@@ -67,6 +69,7 @@ public class regionController: ApiController
|
|||||||
r.Uuid,
|
r.Uuid,
|
||||||
r.Name,
|
r.Name,
|
||||||
regionPath = r.Name,
|
regionPath = r.Name,
|
||||||
|
isStop = !IsRegionAvailable(r.Uuid),
|
||||||
Room = r.Room
|
Room = r.Room
|
||||||
.Where(room => filter.Gender == null || room.Gender == filter.Gender)
|
.Where(room => filter.Gender == null || room.Gender == filter.Gender)
|
||||||
.Where(room =>
|
.Where(room =>
|
||||||
@@ -95,17 +98,19 @@ public class regionController: ApiController
|
|||||||
bed.Name,
|
bed.Name,
|
||||||
bed.Gender,
|
bed.Gender,
|
||||||
bed.RoomUuid,
|
bed.RoomUuid,
|
||||||
bed.StatusUuid,
|
bed.StatusCode,
|
||||||
bed.IsActive,
|
bed.IsActive,
|
||||||
bed.IsDeleted,
|
bed.IsDeleted,
|
||||||
canuse = bed.IsAvailableDuring(startDate, endDate, _db),
|
canuse = bed.IsAvailableDuring(startDate, endDate, _db),
|
||||||
statusname = bed.RegionRoomBedStatus.Name,
|
statusname = bed.RegionRoomBedStatus.Name,
|
||||||
schedules = _db.RegionAndRoomAndBedSchedule
|
schedules = _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.IsCancel == false)
|
||||||
.Where(s => s.TargetUuid == bed.Uuid
|
.Where(s => s.TargetUuid == bed.Uuid
|
||||||
&& s.IsDeleted == false
|
&& s.IsDeleted == false
|
||||||
&& s.IsActive
|
|
||||||
&& (s.ScheduleDate == null
|
&& (s.ScheduleDate == null
|
||||||
|| (s.ScheduleDate >= startDate && s.ScheduleDate <= endDate)))
|
|| (s.ScheduleDate >= startDate)))
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403" && s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
|
.OrderBy(a => a.ScheduleDate)
|
||||||
.Select(s => new
|
.Select(s => new
|
||||||
{
|
{
|
||||||
s.Uuid,
|
s.Uuid,
|
||||||
@@ -113,7 +118,15 @@ public class regionController: ApiController
|
|||||||
s.UseType,
|
s.UseType,
|
||||||
s.Title,
|
s.Title,
|
||||||
s.Description,
|
s.Description,
|
||||||
s.GuaDanOrderNo
|
s.GuaDanOrderNo,
|
||||||
|
s.TargetUuid,
|
||||||
|
usename = _db.GuaDanOrderGuest
|
||||||
|
.Where(guest => guest.GuaDanOrderNo == s.GuaDanOrderNo)
|
||||||
|
.Where(guest => guest.BedUuid == s.TargetUuid)
|
||||||
|
.Select(guest => guest.followers.u_name)
|
||||||
|
.FirstOrDefault()
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
}),
|
}),
|
||||||
@@ -138,6 +151,30 @@ public class regionController: ApiController
|
|||||||
Summary = summary,
|
Summary = summary,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
public bool IsRegionAvailable(Guid regionUuid)
|
||||||
|
{
|
||||||
|
var current = _db.Region.FirstOrDefault(r => r.Uuid == regionUuid);
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
// 當前區域不可用就直接返回 false
|
||||||
|
if (!current.IsActive || current.IsDeleted)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 沒有父區域了,說明一路上都可用
|
||||||
|
if (!current.ParentUuid.HasValue)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 繼續往父區域走
|
||||||
|
current = _db.Region.FirstOrDefault(r => r.Uuid == current.ParentUuid.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 沒查到(極端情況,比如資料庫被改了)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 遞迴生成區域完整路徑
|
/// 遞迴生成區域完整路徑
|
||||||
@@ -183,7 +220,8 @@ public class regionController: ApiController
|
|||||||
IsActive = region.IsActive,
|
IsActive = region.IsActive,
|
||||||
RoomCount = region.RoomCount,
|
RoomCount = region.RoomCount,
|
||||||
BedDto = new List<BedDto>(),
|
BedDto = new List<BedDto>(),
|
||||||
Rooms = region.Room.Select(a => new RoomDto {
|
Rooms = region.Room.Select(a => new RoomDto
|
||||||
|
{
|
||||||
Uuid = a.Uuid,
|
Uuid = a.Uuid,
|
||||||
Name = a.Name,
|
Name = a.Name,
|
||||||
RegionUuid = a.RegionUuid,
|
RegionUuid = a.RegionUuid,
|
||||||
@@ -196,7 +234,7 @@ public class regionController: ApiController
|
|||||||
name = c.Name,
|
name = c.Name,
|
||||||
roomUuid = c.RoomUuid,
|
roomUuid = c.RoomUuid,
|
||||||
isactive = c.IsActive,
|
isactive = c.IsActive,
|
||||||
statusuuid = c.StatusUuid,
|
statuscode = c.StatusCode,
|
||||||
Gender = c.Gender,
|
Gender = c.Gender,
|
||||||
|
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
@@ -216,25 +254,25 @@ public class regionController: ApiController
|
|||||||
{
|
{
|
||||||
var allRegions = _db.Region.ToList();
|
var allRegions = _db.Region.ToList();
|
||||||
|
|
||||||
// 根区域
|
// 根區域
|
||||||
var rootRegions = allRegions
|
var rootRegions = allRegions
|
||||||
.Where(r => r.ParentUuid == null)
|
.Where(r => r.ParentUuid == null)
|
||||||
.OrderBy(r => r.SortOrder)
|
.OrderBy(r => r.SortOrder)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// 生成树并按性别过滤
|
// 生成樹並按性別過濾
|
||||||
var tree = rootRegions
|
var tree = rootRegions
|
||||||
.Select(r => BuildRegionDtoByGender(r, allRegions, request.IsMale))
|
.Select(r => BuildRegionDtoByGender(r, allRegions, request.IsMale))
|
||||||
.Where(r => r != null) // 去掉没有房间的区域
|
.Where(r => r != null) // 去掉沒有房間的區域
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return Ok(tree);
|
return Ok(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据性别过滤房间的 BuildRegionDto
|
// 根據性別過濾房間的 BuildRegionDto
|
||||||
private RegionDto BuildRegionDtoByGender(Region region, List<Region> allRegions, bool? gender)
|
private RegionDto BuildRegionDtoByGender(Region region, List<Region> allRegions, bool? gender)
|
||||||
{
|
{
|
||||||
// 过滤房间按性别
|
// 過濾房間按性別
|
||||||
var rooms = region.Room?
|
var rooms = region.Room?
|
||||||
.Where(a => !gender.HasValue || a.Gender == gender.Value)
|
.Where(a => !gender.HasValue || a.Gender == gender.Value)
|
||||||
.Select(a => new RoomDto
|
.Select(a => new RoomDto
|
||||||
@@ -251,19 +289,19 @@ public class regionController: ApiController
|
|||||||
name = c.Name,
|
name = c.Name,
|
||||||
roomUuid = c.RoomUuid,
|
roomUuid = c.RoomUuid,
|
||||||
isactive = c.IsActive,
|
isactive = c.IsActive,
|
||||||
statusuuid = c.StatusUuid
|
statuscode = c.StatusCode,
|
||||||
}).ToList()
|
}).ToList()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// 递归生成子区域
|
// 遞迴生成子區域
|
||||||
var children = allRegions
|
var children = allRegions
|
||||||
.Where(r => r.ParentUuid == region.Uuid)
|
.Where(r => r.ParentUuid == region.Uuid)
|
||||||
.Select(child => BuildRegionDtoByGender(child, allRegions, gender))
|
.Select(child => BuildRegionDtoByGender(child, allRegions, gender))
|
||||||
.Where(c => c != null) // 去掉没有房间的子区域
|
.Where(c => c != null) // 去掉沒有房間的子區域
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// 如果这个区域既没有房间也没有子区域,则返回 null
|
// 如果這個區域既沒有房間也沒有子區域,則返回 null
|
||||||
if (!rooms.Any() && !children.Any())
|
if (!rooms.Any() && !children.Any())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -285,10 +323,10 @@ public class regionController: ApiController
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 请求模型
|
// 請求模型
|
||||||
public class GenderRequest
|
public class GenderRequest
|
||||||
{
|
{
|
||||||
public bool? IsMale { get; set; } // true = 男, false = 女, null = 不过滤
|
public bool? IsMale { get; set; } // true = 男, false = 女, null = 不過濾
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RoomDto
|
public class RoomDto
|
||||||
@@ -303,11 +341,12 @@ public class regionController: ApiController
|
|||||||
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
public Nullable<System.DateTime> UpdatedAt { get; set; }
|
||||||
public List<BedDto> beds { get; set; }
|
public List<BedDto> beds { get; set; }
|
||||||
}
|
}
|
||||||
public class BedDto {
|
public class BedDto
|
||||||
|
{
|
||||||
public Guid Uuid { get; set; }
|
public Guid Uuid { get; set; }
|
||||||
public Guid? roomUuid { get; set; }
|
public Guid? roomUuid { get; set; }
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public Guid? statusuuid { get; set; }
|
public string statuscode { get; set; }
|
||||||
public bool isactive { get; set; }
|
public bool isactive { get; set; }
|
||||||
public bool Gender { get; set; }
|
public bool Gender { get; set; }
|
||||||
}
|
}
|
||||||
@@ -361,6 +400,28 @@ public class regionController: ApiController
|
|||||||
var region = _db.Region.FirstOrDefault(r => r.Uuid == dto.Uuid);
|
var region = _db.Region.FirstOrDefault(r => r.Uuid == dto.Uuid);
|
||||||
if (region == null)
|
if (region == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
if (dto.RoomCount < region.Room.Count())
|
||||||
|
{
|
||||||
|
return BadRequest("客房數量小於已存在的客房數量");
|
||||||
|
}
|
||||||
|
if (dto.IsActive == false)
|
||||||
|
{
|
||||||
|
var regionIds = GetAllRegionIds(region.Uuid);
|
||||||
|
var hasPendingBeds = _db.RegionRoomBed
|
||||||
|
.Where(b => regionIds.Contains(b.Room.RegionUuid))
|
||||||
|
.SelectMany(b => b.GuaDanOrderGuest)
|
||||||
|
.Any(g => !g.IsDeleted &&
|
||||||
|
(g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_BOOKED || // 預約中
|
||||||
|
g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_CHECKED_IN)); // 已入住
|
||||||
|
if (hasPendingBeds)
|
||||||
|
{
|
||||||
|
return Content(HttpStatusCode.BadRequest, new
|
||||||
|
{
|
||||||
|
code = "BED_IS_USED",
|
||||||
|
message = "該區域有床位正在掛單中,請先處理"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
region.Name = dto.Name;
|
region.Name = dto.Name;
|
||||||
region.Description = dto.Description;
|
region.Description = dto.Description;
|
||||||
region.SortOrder = dto.SortOrder;
|
region.SortOrder = dto.SortOrder;
|
||||||
@@ -399,6 +460,25 @@ public class regionController: ApiController
|
|||||||
return Ok(new { message = "刪除成功" });
|
return Ok(new { message = "刪除成功" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Guid> GetAllRegionIds(Guid regionUuid)
|
||||||
|
{
|
||||||
|
var regionIds = new List<Guid> { regionUuid };
|
||||||
|
|
||||||
|
var children = _db.Region
|
||||||
|
.Where(r => r.ParentUuid == regionUuid)
|
||||||
|
.Select(r => r.Uuid)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var childId in children)
|
||||||
|
{
|
||||||
|
regionIds.AddRange(GetAllRegionIds(childId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return regionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 遞迴刪除子節點
|
// 遞迴刪除子節點
|
||||||
private void DeleteRegionRecursive(Region region)
|
private void DeleteRegionRecursive(Region region)
|
||||||
{
|
{
|
||||||
@@ -421,7 +501,7 @@ public class regionController: ApiController
|
|||||||
[Route("api/region/regionwithroom")]
|
[Route("api/region/regionwithroom")]
|
||||||
public IHttpActionResult GetRegionWithRoom()
|
public IHttpActionResult GetRegionWithRoom()
|
||||||
{
|
{
|
||||||
//返回有房间的region
|
//返回有房間的region
|
||||||
var data = _db.Region.Where(a => a.Room.Count() > 0)
|
var data = _db.Region.Where(a => a.Room.Count() > 0)
|
||||||
.Select(r => new
|
.Select(r => new
|
||||||
{
|
{
|
||||||
@@ -431,7 +511,9 @@ public class regionController: ApiController
|
|||||||
r.Gender,
|
r.Gender,
|
||||||
rooms = r.Room.Select(room => new
|
rooms = r.Room.Select(room => new
|
||||||
{
|
{
|
||||||
room.Uuid, room.Name, room.RegionUuid
|
room.Uuid,
|
||||||
|
room.Name,
|
||||||
|
room.RegionUuid
|
||||||
}).ToList()
|
}).ToList()
|
||||||
}).ToList();
|
}).ToList();
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
@@ -440,7 +522,7 @@ public class regionController: ApiController
|
|||||||
[Route("api/room/roomwithbed")]
|
[Route("api/room/roomwithbed")]
|
||||||
public IHttpActionResult GetRoomWithBed(Guid? RegionUuid = null)
|
public IHttpActionResult GetRoomWithBed(Guid? RegionUuid = null)
|
||||||
{
|
{
|
||||||
//获取所有有床位的房间
|
//獲取所有有床位的房間
|
||||||
var query = _db.Room
|
var query = _db.Room
|
||||||
.Select(r => new
|
.Select(r => new
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
@@ -40,24 +41,23 @@ public class regionRoomBedController : ApiController
|
|||||||
.Where(a => a.RoomUuid == roomUuid)
|
.Where(a => a.RoomUuid == roomUuid)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// 取出所有相关排程
|
StartTime = StartTime.Date;
|
||||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
EndTime = EndTime?.Date;
|
||||||
.Where(b => b.IsDeleted == false && b.IsActive)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
var data = beds.Select(a =>
|
var data = beds.Select(a =>
|
||||||
{
|
{
|
||||||
// 在内存中处理日期比较
|
var bedSchedules = _db.RegionAndRoomAndBedSchedule
|
||||||
var bedSchedules = schedules
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403")
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
.Where(b => b.TargetUuid == a.Uuid
|
.Where(b => b.TargetUuid == a.Uuid
|
||||||
&& (b.ScheduleDate == null // 长期占用
|
&& (b.ScheduleDate == null
|
||||||
|| (b.ScheduleDate >= StartTime.Date && b.ScheduleDate <= EndTime.Value.Date)))
|
|| (b.ScheduleDate >= StartTime && b.ScheduleDate < EndTime)))
|
||||||
|
.ToList()
|
||||||
.Select(c => new
|
.Select(c => new
|
||||||
{
|
{
|
||||||
c.Uuid,
|
c.Uuid,
|
||||||
c.Description,
|
c.Description,
|
||||||
c.IsDeleted,
|
c.IsDeleted,
|
||||||
c.IsActive,
|
|
||||||
c.GuaDanOrderNo,
|
c.GuaDanOrderNo,
|
||||||
c.UseType,
|
c.UseType,
|
||||||
c.Title,
|
c.Title,
|
||||||
@@ -67,22 +67,51 @@ public class regionRoomBedController : ApiController
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
bool canUsed = !bedSchedules.Any();
|
bool canUsed = !bedSchedules.Any();
|
||||||
|
bool bedIsStop = IsBedStopped(a);
|
||||||
return new
|
return new
|
||||||
{
|
{
|
||||||
a.Uuid,
|
a.Uuid,
|
||||||
a.Name,
|
a.Name,
|
||||||
a.Gender,
|
a.Gender,
|
||||||
a.IsActive,
|
a.IsActive,
|
||||||
a.StatusUuid,
|
a.StatusCode,
|
||||||
a.RoomUuid,
|
a.RoomUuid,
|
||||||
canUsed,
|
canUsed,
|
||||||
|
bedIsStop,
|
||||||
schedule = bedSchedules
|
schedule = bedSchedules
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
|
public bool IsBedStopped(RegionRoomBed bed)
|
||||||
|
{
|
||||||
|
// 1️⃣ 床位本身不可用
|
||||||
|
if (!bed.IsActive || bed.IsDeleted)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// 2️⃣ 所属房间不可用
|
||||||
|
var room = bed.Room;
|
||||||
|
if (room == null || !room.IsActive.Value || room.IsDeleted)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// 3️⃣ 所属区域不可用
|
||||||
|
var region = room.Region;
|
||||||
|
while (region != null)
|
||||||
|
{
|
||||||
|
if (!region.IsActive || region.IsDeleted)
|
||||||
|
return true; // 有任意一级区域不可用就返回 true
|
||||||
|
|
||||||
|
if (!region.ParentUuid.HasValue)
|
||||||
|
break; // 到顶层了
|
||||||
|
|
||||||
|
region = _db.Region.FirstOrDefault(r => r.Uuid == region.ParentUuid.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4️⃣ 全部检查通过 → 床位可用
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/bed/create")]
|
[Route("api/region/bed/create")]
|
||||||
@@ -93,7 +122,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("當前客房不存在");
|
return BadRequest("當前客房不存在");
|
||||||
}
|
}
|
||||||
if(room.Gender != bed.Gender)
|
if (room.Gender != bed.Gender)
|
||||||
{
|
{
|
||||||
return BadRequest("床為性別和房間性別必須一致");
|
return BadRequest("床為性別和房間性別必須一致");
|
||||||
}
|
}
|
||||||
@@ -105,7 +134,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
Name = bed.Name,
|
Name = bed.Name,
|
||||||
RoomUuid = bed.RoomUuid,
|
RoomUuid = bed.RoomUuid,
|
||||||
StatusUuid = bed.StatusUuid,
|
StatusCode = bed.StatusCode,
|
||||||
IsActive = bed.IsActive,
|
IsActive = bed.IsActive,
|
||||||
Gender = bed.Gender,
|
Gender = bed.Gender,
|
||||||
Uuid = Guid.NewGuid(),
|
Uuid = Guid.NewGuid(),
|
||||||
@@ -114,10 +143,11 @@ public class regionRoomBedController : ApiController
|
|||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
|
|
||||||
//創建床位
|
//創建床位
|
||||||
return Ok(new {
|
return Ok(new
|
||||||
|
{
|
||||||
uuid = regionBed.Uuid,
|
uuid = regionBed.Uuid,
|
||||||
roomUuid = regionBed.RoomUuid,
|
roomUuid = regionBed.RoomUuid,
|
||||||
statusuuid = regionBed.StatusUuid,
|
statuscode = regionBed.StatusCode,
|
||||||
isactive = regionBed.IsActive,
|
isactive = regionBed.IsActive,
|
||||||
gender = regionBed.Gender,
|
gender = regionBed.Gender,
|
||||||
name = regionBed.Name,
|
name = regionBed.Name,
|
||||||
@@ -146,7 +176,21 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("床為性別和房間性別必須一致");
|
return BadRequest("床為性別和房間性別必須一致");
|
||||||
}
|
}
|
||||||
oldBed.StatusUuid = bed.StatusUuid;
|
if (bed.IsActive == false)
|
||||||
|
{
|
||||||
|
var hasPendingBeds = oldBed.GuaDanOrderGuest.Any(g => !g.IsDeleted &&
|
||||||
|
(g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_BOOKED || // 预约中
|
||||||
|
g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_CHECKED_IN));
|
||||||
|
if (hasPendingBeds)
|
||||||
|
{
|
||||||
|
return Content(HttpStatusCode.BadRequest, new
|
||||||
|
{
|
||||||
|
code = "BED_IS_USED",
|
||||||
|
message = "該床位正在掛單中,請先處理"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oldBed.StatusCode = bed.StatusCode;
|
||||||
oldBed.IsActive = bed.IsActive;
|
oldBed.IsActive = bed.IsActive;
|
||||||
oldBed.Name = bed.Name;
|
oldBed.Name = bed.Name;
|
||||||
oldBed.Gender = bed.Gender;
|
oldBed.Gender = bed.Gender;
|
||||||
@@ -157,25 +201,75 @@ public class regionRoomBedController : ApiController
|
|||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/bed/delete")]
|
[Route("api/region/bed/delete")]
|
||||||
public IHttpActionResult delete([FromUri] Guid uuid)
|
public IHttpActionResult Delete([FromUri] Guid uuid)
|
||||||
{
|
{
|
||||||
var bed = _db.RegionRoomBed.Find(uuid);
|
var bed = _db.RegionRoomBed.Find(uuid);
|
||||||
if (bed == null)
|
if (bed == null)
|
||||||
{
|
{
|
||||||
return BadRequest("未找到床位");
|
return BadRequest("未找到床位");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
_db.RegionRoomBed.Remove(bed);
|
_db.RegionRoomBed.Remove(bed);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
return Ok(new { message = "刪除成功" });
|
return Ok(new { message = "刪除成功" });
|
||||||
}
|
}
|
||||||
|
catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
|
||||||
|
{
|
||||||
|
// 判斷是否為外鍵關聯錯誤
|
||||||
|
if (ex.InnerException?.InnerException is System.Data.SqlClient.SqlException sqlEx &&
|
||||||
|
(sqlEx.Number == 547)) // 547 = SQL Server 外鍵違反錯誤碼
|
||||||
|
{
|
||||||
|
return BadRequest("刪除失敗:該床位已被使用或存在關聯資料,無法刪除。");
|
||||||
|
}
|
||||||
|
|
||||||
|
return InternalServerError(ex); // 其他資料庫錯誤
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return InternalServerError(ex); // 其他未預期錯誤
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("api/region/bed/getavailablebedcountbytime")]
|
[Route("api/region/bed/getavailablebedcountbytime")]
|
||||||
public async Task<IHttpActionResult> GetCanUseBedCountByTime(DateTime startTime, DateTime endTime)
|
public async Task<IHttpActionResult> GetCanUseBedCountByTime(DateTime startTime, DateTime endTime)
|
||||||
{
|
{
|
||||||
//获取某个时间段内可用床位数量
|
//获取某个时间段内可用床位数量
|
||||||
var counts = await RegionAndRoomAndBedSchedule.GetAvailableBedCountsAsync(_db, startTime, endTime);
|
var start = startTime.Date;
|
||||||
return Ok(counts);
|
var end = endTime.Date;
|
||||||
|
|
||||||
|
// 找出所有在日期範圍內被占用的床位
|
||||||
|
var busyBedUuids = await _db.RegionAndRoomAndBedSchedule
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "403")
|
||||||
|
.Where(s => s.GuaDanOrderGuest.StatusCode != "404")
|
||||||
|
.Where(a => a.IsCancel == false)
|
||||||
|
.Where(s => s.IsDeleted == false
|
||||||
|
&& (s.ScheduleDate == null // 長期占用
|
||||||
|
|| (s.ScheduleDate >= start && s.ScheduleDate < end)))
|
||||||
|
.Select(s => s.TargetUuid)
|
||||||
|
.Distinct()
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// 可用床位 = 所有床位 - 忙碌床位
|
||||||
|
var availableBeds = _db.RegionRoomBed
|
||||||
|
.Where(b => b.IsActive)
|
||||||
|
.Where(b => !busyBedUuids.Contains(b.Uuid));
|
||||||
|
|
||||||
|
var result = await availableBeds
|
||||||
|
.GroupBy(b => b.Gender)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
Gender = g.Key,
|
||||||
|
Count = g.Count()
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var male = result.Where(r => r.Gender == true).Select(r => r.Count).FirstOrDefault();
|
||||||
|
var female = result.Where(r => r.Gender == false).Select(r => r.Count).FirstOrDefault();
|
||||||
|
return Ok(new {male, female});
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
@@ -260,7 +354,7 @@ public class regionRoomBedController : ApiController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index < followers.Count)
|
if (index < followers.Count)
|
||||||
{
|
{
|
||||||
isAllallocation = false;
|
isAllallocation = false;
|
||||||
return;
|
return;
|
||||||
@@ -313,7 +407,7 @@ public class regionRoomBedController : ApiController
|
|||||||
{
|
{
|
||||||
// 先拉出床位相關排程到內存,避免 EF 不支援 .Date
|
// 先拉出床位相關排程到內存,避免 EF 不支援 .Date
|
||||||
var schedules = _db.RegionAndRoomAndBedSchedule
|
var schedules = _db.RegionAndRoomAndBedSchedule
|
||||||
.Where(s => s.IsDeleted == false && s.IsActive && s.TargetUuid == req.bedUuid)
|
.Where(s => s.IsDeleted == false && !s.IsCancel && s.TargetUuid == req.bedUuid)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
bool conflictExists = schedules.Any(s =>
|
bool conflictExists = schedules.Any(s =>
|
||||||
@@ -349,13 +443,14 @@ public class regionRoomBedController : ApiController
|
|||||||
RoomUuid = roomUuid,
|
RoomUuid = roomUuid,
|
||||||
CheckInAt = allocationStart,
|
CheckInAt = allocationStart,
|
||||||
CheckOutAt = allocationEnd,
|
CheckOutAt = allocationEnd,
|
||||||
|
StatusCode = "401",
|
||||||
};
|
};
|
||||||
_db.GuaDanOrderGuest.Add(guest);
|
_db.GuaDanOrderGuest.Add(guest);
|
||||||
|
|
||||||
// 新增每日排程
|
// 新增每日排程
|
||||||
if (allocationEnd.HasValue)
|
if (allocationEnd.HasValue)
|
||||||
{
|
{
|
||||||
for (var date = allocationStart; date <= allocationEnd.Value; date = date.AddDays(1))
|
for (var date = allocationStart; date < allocationEnd.Value; date = date.AddDays(1))
|
||||||
{
|
{
|
||||||
var newSchedule = new RegionAndRoomAndBedSchedule
|
var newSchedule = new RegionAndRoomAndBedSchedule
|
||||||
{
|
{
|
||||||
@@ -364,10 +459,11 @@ public class regionRoomBedController : ApiController
|
|||||||
ScheduleDate = date,
|
ScheduleDate = date,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
|
||||||
CreatedBy = "系统自动分配",
|
CreatedBy = "系统自动分配",
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
|
Title = "掛單",
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||||
}
|
}
|
||||||
@@ -382,10 +478,11 @@ public class regionRoomBedController : ApiController
|
|||||||
ScheduleDate = null,
|
ScheduleDate = null,
|
||||||
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
UseType = (int)RegionAndRoomAndBedSchedule.SchedulePurpose.Bed_Reservation,
|
||||||
IsDeleted = false,
|
IsDeleted = false,
|
||||||
IsActive = true,
|
|
||||||
CreatedBy = "系统自动分配",
|
CreatedBy = "系统自动分配",
|
||||||
CreatedAt = DateTime.Now,
|
CreatedAt = DateTime.Now,
|
||||||
GuaDanOrderNo = guest.GuaDanOrderNo
|
GuaDanOrderNo = guest.GuaDanOrderNo,
|
||||||
|
Title = "掛單",
|
||||||
|
GuaDanOrderGuestUuid = guest.Uuid,
|
||||||
};
|
};
|
||||||
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
_db.RegionAndRoomAndBedSchedule.Add(newSchedule);
|
||||||
}
|
}
|
||||||
@@ -406,7 +503,7 @@ public class regionRoomBedController : ApiController
|
|||||||
|
|
||||||
private bool BedIsCanUsed(RegionRoomBed bed, DateTime? StartTime, DateTime? EndTime)
|
private bool BedIsCanUsed(RegionRoomBed bed, DateTime? StartTime, DateTime? EndTime)
|
||||||
{
|
{
|
||||||
if(!bed.IsActive)
|
if (!bed.IsActive)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using System.Web.Http;
|
|||||||
/// regionRoomBedStatusController 的摘要描述
|
/// regionRoomBedStatusController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class regionRoomBedStatusController: ApiController
|
public class regionRoomBedStatusController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public regionRoomBedStatusController()
|
public regionRoomBedStatusController()
|
||||||
@@ -34,7 +34,6 @@ public class regionRoomBedStatusController: ApiController
|
|||||||
s.Code,
|
s.Code,
|
||||||
s.Name,
|
s.Name,
|
||||||
s.Description,
|
s.Description,
|
||||||
s.Uuid,
|
|
||||||
s.CategoryName
|
s.CategoryName
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -53,9 +52,9 @@ public class regionRoomBedStatusController: ApiController
|
|||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/bed/status/delete")]
|
[Route("api/region/bed/status/delete")]
|
||||||
public IHttpActionResult DeleteBedStatus([FromUri]Guid id)
|
public IHttpActionResult DeleteBedStatus([FromUri] string code)
|
||||||
{
|
{
|
||||||
var rt = _db.RegionRoomBedStatus.Find(id);
|
var rt = _db.RegionRoomBedStatus.Find(code);
|
||||||
if (rt == null)
|
if (rt == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.ServiceModel.Channels;
|
using System.ServiceModel.Channels;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
@@ -14,7 +15,7 @@ using static regionController;
|
|||||||
/// regionRoomController 的摘要描述
|
/// regionRoomController 的摘要描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ezAuthorize]
|
[ezAuthorize]
|
||||||
public class regionRoomController: ApiController
|
public class regionRoomController : ApiController
|
||||||
{
|
{
|
||||||
private Model.ezEntities _db = new Model.ezEntities();
|
private Model.ezEntities _db = new Model.ezEntities();
|
||||||
public regionRoomController()
|
public regionRoomController()
|
||||||
@@ -38,6 +39,15 @@ public class regionRoomController: ApiController
|
|||||||
{
|
{
|
||||||
return BadRequest("請輸入床位數量");
|
return BadRequest("請輸入床位數量");
|
||||||
}
|
}
|
||||||
|
var region = _db.Region.Find(room.RegionUuid);
|
||||||
|
if(region == null)
|
||||||
|
{
|
||||||
|
return BadRequest("未找到客房所屬的區域");
|
||||||
|
}
|
||||||
|
if(region.Room.Count() >= region.RoomCount)
|
||||||
|
{
|
||||||
|
return BadRequest("當前區域客房數量已經達到上限");
|
||||||
|
}
|
||||||
var newRoom = new Room();
|
var newRoom = new Room();
|
||||||
newRoom.Name = room.Name;
|
newRoom.Name = room.Name;
|
||||||
newRoom.RegionUuid = room.RegionUuid;
|
newRoom.RegionUuid = room.RegionUuid;
|
||||||
@@ -62,7 +72,7 @@ public class regionRoomController: ApiController
|
|||||||
name = c.Name,
|
name = c.Name,
|
||||||
roomUuid = c.RoomUuid,
|
roomUuid = c.RoomUuid,
|
||||||
isactive = c.IsActive,
|
isactive = c.IsActive,
|
||||||
statusuuid = c.StatusUuid,
|
statuscode = c.StatusCode,
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -86,10 +96,27 @@ public class regionRoomController: ApiController
|
|||||||
// 如果有不符合性別的床位,不能繼續操作
|
// 如果有不符合性別的床位,不能繼續操作
|
||||||
return BadRequest("房間中已有與房間性別不符的床位,無法操作");
|
return BadRequest("房間中已有與房間性別不符的床位,無法操作");
|
||||||
}
|
}
|
||||||
if(!room.BedCount.HasValue)
|
if (!room.BedCount.HasValue)
|
||||||
{
|
{
|
||||||
return BadRequest("請輸入床位數量");
|
return BadRequest("請輸入床位數量");
|
||||||
}
|
}
|
||||||
|
if (room.IsActive == false)
|
||||||
|
{
|
||||||
|
var hasPendingBeds = oldRoom.RegionRoomBed
|
||||||
|
.SelectMany(b => b.GuaDanOrderGuest)
|
||||||
|
.Any(g => !g.IsDeleted &&
|
||||||
|
(g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_BOOKED || // 预约中
|
||||||
|
g.RegionRoomBedStatus.Code == GuaDanOrderGuest.STATUS_CHECKED_IN)); // 已入住
|
||||||
|
if (hasPendingBeds)
|
||||||
|
{
|
||||||
|
return Content(HttpStatusCode.BadRequest, new
|
||||||
|
{
|
||||||
|
code = "BED_IS_USED",
|
||||||
|
message = "該房间有床位正在掛單中,請先處理"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
oldRoom.Name = room.Name;
|
oldRoom.Name = room.Name;
|
||||||
oldRoom.BedCount = room.BedCount;
|
oldRoom.BedCount = room.BedCount;
|
||||||
oldRoom.Gender = room.Gender;
|
oldRoom.Gender = room.Gender;
|
||||||
@@ -97,11 +124,15 @@ public class regionRoomController: ApiController
|
|||||||
oldRoom.IsActive = room.IsActive;
|
oldRoom.IsActive = room.IsActive;
|
||||||
oldRoom.RegionUuid = room.RegionUuid;
|
oldRoom.RegionUuid = room.RegionUuid;
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
return Ok(new { message = "更新成功"});
|
return Ok(new { message = "更新成功" });
|
||||||
}
|
}
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("api/region/room/delete")]
|
[Route("api/region/room/delete")]
|
||||||
public async Task<IHttpActionResult> deleteRoom([FromBody] Room rm)
|
public async Task<IHttpActionResult> deleteRoom([FromBody] Room rm)
|
||||||
|
{
|
||||||
|
using (var transaction = _db.Database.BeginTransaction())
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var room = await _db.Room.FindAsync(rm.Uuid);
|
var room = await _db.Room.FindAsync(rm.Uuid);
|
||||||
if (room == null) return BadRequest("房間不存在");
|
if (room == null) return BadRequest("房間不存在");
|
||||||
@@ -110,8 +141,32 @@ public class regionRoomController: ApiController
|
|||||||
_db.RegionRoomBed.RemoveRange(beds);
|
_db.RegionRoomBed.RemoveRange(beds);
|
||||||
|
|
||||||
_db.Room.Remove(room);
|
_db.Room.Remove(room);
|
||||||
|
|
||||||
await _db.SaveChangesAsync();
|
await _db.SaveChangesAsync();
|
||||||
|
transaction.Commit();
|
||||||
|
|
||||||
return Ok(new { message = "刪除成功" });
|
return Ok(new { message = "刪除成功" });
|
||||||
}
|
}
|
||||||
|
catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
|
||||||
|
// 判断是否为外键约束错误
|
||||||
|
if (ex.InnerException?.InnerException is System.Data.SqlClient.SqlException sqlEx &&
|
||||||
|
sqlEx.Number == 547) // 547 = 外键冲突
|
||||||
|
{
|
||||||
|
return BadRequest("房間或床位正在被使用,不能刪除");
|
||||||
|
}
|
||||||
|
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
return InternalServerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ public class stockController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.stocks.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.stocks.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
var prod2 = prod.stock_files;
|
var prod2 = prod.stock_files;
|
||||||
@@ -85,11 +85,11 @@ public class stockController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var getDelItem = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
var prod = _db.stocks.AsEnumerable().Where(q => getDelItem.Contains(q.num)).ToList();
|
var prod = _db.stocks.Where(q => getDelItem.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
var prod2 = _db.stock_files.AsEnumerable().Where(q => q.stock_num.HasValue && getDelItem.Contains(q.stock_num.Value)).ToList();
|
var prod2 = _db.stock_files.Where(q => q.stock_num.HasValue && getDelItem.Contains(q.stock_num.Value)).ToList();
|
||||||
if (prod2.Count() > 0)
|
if (prod2.Count() > 0)
|
||||||
{
|
{
|
||||||
publicFun publicFun = new publicFun();
|
publicFun publicFun = new publicFun();
|
||||||
@@ -114,7 +114,7 @@ public class stockController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.stock q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.stock q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.stocks.AsEnumerable();
|
var qry = _db.stocks.AsQueryable();
|
||||||
|
|
||||||
if (q.category.HasValue)
|
if (q.category.HasValue)
|
||||||
qry = qry.Where(o => o.category == q.category.Value);
|
qry = qry.Where(o => o.category == q.category.Value);
|
||||||
@@ -198,10 +198,12 @@ public class stockController : BaseApiController
|
|||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
var tdesc = publicFun.enum_desc<Model.stock.type>();
|
var tdesc = publicFun.enum_desc<Model.stock.type>();
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
category = x.category,
|
category = x.category,
|
||||||
@@ -230,7 +232,7 @@ public class stockController : BaseApiController
|
|||||||
price = x.price,
|
price = x.price,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -244,7 +246,7 @@ public class stockController : BaseApiController
|
|||||||
public IHttpActionResult GetKindList([FromBody] Model.ViewModel.stock_kind q, int page, int pageSize = 10,
|
public IHttpActionResult GetKindList([FromBody] Model.ViewModel.stock_kind q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.stock_kind.AsEnumerable();
|
var qry = _db.stock_kind.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -293,7 +295,7 @@ public class stockController : BaseApiController
|
|||||||
public IHttpActionResult GetReasonList([FromBody] Model.ViewModel.stock_reason q, int page, int pageSize = 10,
|
public IHttpActionResult GetReasonList([FromBody] Model.ViewModel.stock_reason q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.stock_reason.AsEnumerable();
|
var qry = _db.stock_reason.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -335,15 +337,16 @@ public class stockController : BaseApiController
|
|||||||
if (q.stock_num.HasValue && q.stock_num.Value>0)
|
if (q.stock_num.HasValue && q.stock_num.Value>0)
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var qry = _db.stock_files.AsEnumerable();
|
var qry = _db.stock_files.Where(o => o.stock_num == q.stock_num.Value);
|
||||||
qry = qry.Where(o => o.stock_num == q.stock_num.Value);
|
qry = qry.OrderByDescending(x => x.num);
|
||||||
qry.OrderByDescending(x => x.num);
|
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
//已有值
|
//已有值
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
id = i++,
|
id = i++,
|
||||||
num = x.num,
|
num = x.num,
|
||||||
@@ -351,7 +354,7 @@ public class stockController : BaseApiController
|
|||||||
pic1 = x.pic1,
|
pic1 = x.pic1,
|
||||||
pic1_name = x.pic1_name,
|
pic1_name = x.pic1_name,
|
||||||
}),
|
}),
|
||||||
count = qry.Count(),
|
count = count,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||||
@@ -466,7 +469,7 @@ public class stockController : BaseApiController
|
|||||||
[Route("api/stock/DeleteFilesItem/{id}")]//刪除相關檔案
|
[Route("api/stock/DeleteFilesItem/{id}")]//刪除相關檔案
|
||||||
public void DeleteFilesItem(int id)
|
public void DeleteFilesItem(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.stock_files.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.stock_files.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(prod.pic1))
|
if (!string.IsNullOrEmpty(prod.pic1))
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class supplierController : BaseApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.suppliers.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.suppliers.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(prod.pic1))
|
if (!string.IsNullOrEmpty(prod.pic1))
|
||||||
@@ -80,8 +80,8 @@ public class supplierController : BaseApiController
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(nums))
|
if (!string.IsNullOrEmpty(nums))
|
||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s));
|
var ids = nums.TrimEnd(',').Split(',').Select(s => int.Parse(s)).ToList();
|
||||||
var prod = _db.suppliers.AsEnumerable().Where(q => ids.Contains(q.num)).ToList();
|
var prod = _db.suppliers.Where(q => ids.Contains(q.num)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
publicFun publicFun = new publicFun();
|
publicFun publicFun = new publicFun();
|
||||||
@@ -113,7 +113,7 @@ public class supplierController : BaseApiController
|
|||||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.supplier q, int page, int pageSize = 10,
|
public IHttpActionResult GetList([FromBody] Model.ViewModel.supplier q, int page, int pageSize = 10,
|
||||||
string sortBy = "", bool sortDesc = false)
|
string sortBy = "", bool sortDesc = false)
|
||||||
{
|
{
|
||||||
var qry = _db.suppliers.AsEnumerable();
|
var qry = _db.suppliers.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.u_name))
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||||
@@ -159,9 +159,12 @@ public class supplierController : BaseApiController
|
|||||||
else
|
else
|
||||||
qry = qry.OrderByDescending(o => o.num);
|
qry = qry.OrderByDescending(o => o.num);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
list = qryList.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
u_name = x.u_name,
|
u_name = x.u_name,
|
||||||
@@ -176,7 +179,7 @@ public class supplierController : BaseApiController
|
|||||||
}).ToList(), x.kind) : "",
|
}).ToList(), x.kind) : "",
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,7 +195,7 @@ public class supplierController : BaseApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
var qry = _db.supplier_kind.AsEnumerable();
|
var qry = _db.supplier_kind.AsQueryable();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.kind))
|
if (!string.IsNullOrEmpty(q.kind))
|
||||||
qry = qry.Where(o => o.kind.Contains(q.kind));
|
qry = qry.Where(o => o.kind.Contains(q.kind));
|
||||||
@@ -205,17 +208,18 @@ public class supplierController : BaseApiController
|
|||||||
range = o.range,
|
range = o.range,
|
||||||
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
}).OrderBy(x => x.root).ThenBy(x => x.kind).ToList(), 0, 0);
|
||||||
|
|
||||||
|
var count = qry.Count();
|
||||||
|
var qry2List = (pageSize > 0) ? qry2.ToPagedList(page, pageSize).ToList() : qry2.ToList();
|
||||||
|
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
list = qry2.ToPagedList(page, pageSize).Select(x => new
|
list = qry2List.Select(x => new
|
||||||
{
|
{
|
||||||
num = x.num,
|
num = x.num,
|
||||||
kind = new TreeView().RptDash(x.Level) + x.kind,
|
kind = new TreeView().RptDash(x.Level) + x.kind,
|
||||||
|
|
||||||
}),
|
}),
|
||||||
count = qry.Count()
|
count = count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ public class transfer_registerController : ApiController
|
|||||||
x.draft,
|
x.draft,
|
||||||
follower = x.f_num != null ? _db.followers
|
follower = x.f_num != null ? _db.followers
|
||||||
.Where(f => f.num == x.f_num)
|
.Where(f => f.num == x.f_num)
|
||||||
.AsEnumerable()
|
.ToList()
|
||||||
.Select(f => new {
|
.Select(f => new {
|
||||||
f.num,
|
f.num,
|
||||||
f.u_name,
|
f.u_name,
|
||||||
@@ -399,6 +399,7 @@ public class transfer_registerController : ApiController
|
|||||||
[Route("api/transfer_register/follower_orders")]
|
[Route("api/transfer_register/follower_orders")]
|
||||||
public IHttpActionResult GetFollowerOrders(int f_num)
|
public IHttpActionResult GetFollowerOrders(int f_num)
|
||||||
{
|
{
|
||||||
|
// TODO: 優化建議 - 考慮加入分頁或日期範圍限制,避免單一信眾訂單過多時載入大量數據
|
||||||
// 取得該信眾的所有訂單及明細,並關聯活動名稱與品項名稱
|
// 取得該信眾的所有訂單及明細,並關聯活動名稱與品項名稱
|
||||||
var details = _db.pro_order
|
var details = _db.pro_order
|
||||||
.Where(o => o.f_num == f_num)
|
.Where(o => o.f_num == f_num)
|
||||||
@@ -417,7 +418,7 @@ public class transfer_registerController : ApiController
|
|||||||
d.demo,
|
d.demo,
|
||||||
reg_time = o.reg_time // 報名日期
|
reg_time = o.reg_time // 報名日期
|
||||||
}))
|
}))
|
||||||
.AsEnumerable()
|
.AsEnumerable() // 只在需要內存計算前轉換
|
||||||
.Select(x => new {
|
.Select(x => new {
|
||||||
x.order_no,
|
x.order_no,
|
||||||
x.activity_num,
|
x.activity_num,
|
||||||
@@ -481,7 +482,7 @@ public class transfer_registerController : ApiController
|
|||||||
x.draft,
|
x.draft,
|
||||||
follower = x.f_num != null ? _db.followers
|
follower = x.f_num != null ? _db.followers
|
||||||
.Where(f => f.num == x.f_num)
|
.Where(f => f.num == x.f_num)
|
||||||
.AsEnumerable()
|
.ToList()
|
||||||
.Select(f => new {
|
.Select(f => new {
|
||||||
f.num,
|
f.num,
|
||||||
f.u_name,
|
f.u_name,
|
||||||
@@ -817,7 +818,7 @@ public class transfer_registerController : ApiController
|
|||||||
tr.balance_act_item,
|
tr.balance_act_item,
|
||||||
balance_actitem_name = tr.balance_act_item != null ? _db.actItems.Where(a => a.num == tr.balance_act_item).Select(a => a.subject).FirstOrDefault() : ""
|
balance_actitem_name = tr.balance_act_item != null ? _db.actItems.Where(a => a.num == tr.balance_act_item).Select(a => a.subject).FirstOrDefault() : ""
|
||||||
})
|
})
|
||||||
.AsEnumerable()
|
.ToList()
|
||||||
.Select(tr => new
|
.Select(tr => new
|
||||||
{
|
{
|
||||||
tr.id,
|
tr.id,
|
||||||
@@ -1044,6 +1045,9 @@ public class transfer_registerController : ApiController
|
|||||||
[Route("api/transfer_register/activity_followers")]
|
[Route("api/transfer_register/activity_followers")]
|
||||||
public IHttpActionResult GetActivityFollowers(int activity_num)
|
public IHttpActionResult GetActivityFollowers(int activity_num)
|
||||||
{
|
{
|
||||||
|
// TODO: 性能優化 - 大型活動可能有數千筆訂單,建議:
|
||||||
|
// 1. 在數據庫層面先過濾出未完成沖帳項目(避免載入所有訂單)
|
||||||
|
// 2. 考慮加入 Take() 限制返回數量,或實作分頁
|
||||||
// 查詢該法會中有報名單且有未完成沖帳項目的信眾
|
// 查詢該法會中有報名單且有未完成沖帳項目的信眾
|
||||||
var followers = _db.pro_order
|
var followers = _db.pro_order
|
||||||
.Where(o => o.activity_num == activity_num)
|
.Where(o => o.activity_num == activity_num)
|
||||||
@@ -1054,7 +1058,7 @@ public class transfer_registerController : ApiController
|
|||||||
d.price,
|
d.price,
|
||||||
paid = d.pro_order_record.Select(r => r.price).DefaultIfEmpty(0).Sum()
|
paid = d.pro_order_record.Select(r => r.price).DefaultIfEmpty(0).Sum()
|
||||||
}))
|
}))
|
||||||
.AsEnumerable()
|
.AsEnumerable() // 只在需要內存計算前轉換
|
||||||
.Select(x => new {
|
.Select(x => new {
|
||||||
x.f_num,
|
x.f_num,
|
||||||
x.follower_name,
|
x.follower_name,
|
||||||
@@ -1104,7 +1108,7 @@ public class transfer_registerController : ApiController
|
|||||||
d.demo,
|
d.demo,
|
||||||
reg_time = o.reg_time // 報名日期
|
reg_time = o.reg_time // 報名日期
|
||||||
}))
|
}))
|
||||||
.AsEnumerable()
|
.ToList()
|
||||||
.Select(x => new {
|
.Select(x => new {
|
||||||
x.order_no,
|
x.order_no,
|
||||||
x.activity_num,
|
x.activity_num,
|
||||||
|
|||||||
@@ -55,17 +55,17 @@ public class apporderController : ApiController
|
|||||||
// DELETE api/<controller>/5
|
// DELETE api/<controller>/5
|
||||||
public void Delete(string id)
|
public void Delete(string id)
|
||||||
{
|
{
|
||||||
var prod = _db.pro_order.AsEnumerable().Where(q => q.order_no == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.pro_order.Where(q => q.order_no == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//刪除掛單表單
|
//刪除掛單表單
|
||||||
var prod3 = _db.bed_order.AsEnumerable().Where(q => q.order_no == id).ToList();
|
var prod3 = _db.bed_order.Where(q => q.order_no == id).ToList();
|
||||||
if (prod3.Count > 0)
|
if (prod3.Count > 0)
|
||||||
{
|
{
|
||||||
//刪除掛單明細
|
//刪除掛單明細
|
||||||
foreach (var item3 in prod3)
|
foreach (var item3 in prod3)
|
||||||
{
|
{
|
||||||
var prod4 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_order_no == item3.bed_order_no).ToList();
|
var prod4 = _db.bed_order_detail.Where(q => q.bed_order_no == item3.bed_order_no).ToList();
|
||||||
if (prod4.Count > 0)
|
if (prod4.Count > 0)
|
||||||
{
|
{
|
||||||
_db.bed_order_detail.RemoveRange(prod4); //查詢結果全部刪除
|
_db.bed_order_detail.RemoveRange(prod4); //查詢結果全部刪除
|
||||||
@@ -97,17 +97,17 @@ public class apporderController : ApiController
|
|||||||
{
|
{
|
||||||
if (id > 0)
|
if (id > 0)
|
||||||
{
|
{
|
||||||
var prod = _db.pro_order_detail.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.pro_order_detail.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
//刪除掛單表單
|
//刪除掛單表單
|
||||||
var prod3 = _db.bed_order.AsEnumerable().Where(q => q.order_no == prod.order_no).ToList();
|
var prod3 = _db.bed_order.Where(q => q.order_no == prod.order_no).ToList();
|
||||||
if (prod3.Count > 0) //count = 1
|
if (prod3.Count > 0) //count = 1
|
||||||
{
|
{
|
||||||
//刪除掛單明細
|
//刪除掛單明細
|
||||||
foreach (var item3 in prod3)
|
foreach (var item3 in prod3)
|
||||||
{
|
{
|
||||||
var prod4 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_order_no == item3.bed_order_no).ToList();
|
var prod4 = _db.bed_order_detail.Where(q => q.bed_order_no == item3.bed_order_no).ToList();
|
||||||
if (prod4.Count > 0)
|
if (prod4.Count > 0)
|
||||||
{
|
{
|
||||||
_db.bed_order_detail.RemoveRange(prod4); //查詢結果全部刪除
|
_db.bed_order_detail.RemoveRange(prod4); //查詢結果全部刪除
|
||||||
@@ -132,20 +132,20 @@ public class apporderController : ApiController
|
|||||||
{
|
{
|
||||||
var ids = nums.TrimEnd(',').Split(',');
|
var ids = nums.TrimEnd(',').Split(',');
|
||||||
|
|
||||||
var prod = _db.pro_order.AsEnumerable().Where(q => ids.Contains(q.order_no)).ToList();
|
var prod = _db.pro_order.Where(q => ids.Contains(q.order_no)).ToList();
|
||||||
if (prod.Count() > 0)
|
if (prod.Count() > 0)
|
||||||
{
|
{
|
||||||
var prod2 = _db.pro_order_detail.AsEnumerable().Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
|
var prod2 = _db.pro_order_detail.Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var item2 in prod2)
|
foreach (var item2 in prod2)
|
||||||
{
|
{
|
||||||
var prod3 = _db.bed_order.AsEnumerable().Where(q => q.order_no == item2.order_no && q.o_detail_id == item2.num).ToList();
|
var prod3 = _db.bed_order.Where(q => q.order_no == item2.order_no && q.o_detail_id == item2.num).ToList();
|
||||||
if (prod3.Count > 0)
|
if (prod3.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var item3 in prod3)
|
foreach (var item3 in prod3)
|
||||||
{
|
{
|
||||||
var prod4 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_order_no == item3.bed_order_no).ToList();
|
var prod4 = _db.bed_order_detail.Where(q => q.bed_order_no == item3.bed_order_no).ToList();
|
||||||
if (prod4.Count > 0)
|
if (prod4.Count > 0)
|
||||||
{
|
{
|
||||||
_db.bed_order_detail.RemoveRange(prod4);
|
_db.bed_order_detail.RemoveRange(prod4);
|
||||||
@@ -156,8 +156,8 @@ public class apporderController : ApiController
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//var prod32 = _db.bed_order.AsEnumerable().Where(q => q.order_no == item2.order_no && q.o_detail_id == item2.num).ToList();
|
//var prod32 = _db.bed_order.Where(q => q.order_no == item2.order_no && q.o_detail_id == item2.num).ToList();
|
||||||
//var prod42 = _db.bed_order_detail.AsEnumerable().Where(q => prod32.Select(qf => qf.order_no).ToArray().Contains(q.bed_order_no)).ToList();
|
//var prod42 = _db.bed_order_detail.Where(q => prod32.Select(qf => qf.order_no).ToArray().Contains(q.bed_order_no)).ToList();
|
||||||
//_db.bed_order_detail.RemoveRange(prod42);
|
//_db.bed_order_detail.RemoveRange(prod42);
|
||||||
//_db.bed_order.RemoveRange(prod32);
|
//_db.bed_order.RemoveRange(prod32);
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ public class apporderController : ApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
var qry = _db.pro_order.AsEnumerable();
|
var qry = _db.pro_order.AsEnumerable();
|
||||||
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
//var aIDt = _db.actItems.Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
||||||
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.order_no))
|
if (!string.IsNullOrEmpty(q.order_no))
|
||||||
@@ -218,32 +218,32 @@ public class apporderController : ApiController
|
|||||||
if (!string.IsNullOrEmpty(q.address))
|
if (!string.IsNullOrEmpty(q.address))
|
||||||
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.subject))
|
if (!string.IsNullOrEmpty(q.subject))
|
||||||
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(q.subject?.Trim()));
|
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(q.subject.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.u_name))
|
if (!string.IsNullOrEmpty(q.u_name))
|
||||||
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(q.u_name?.Trim()));
|
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(q.u_name.Trim()));
|
||||||
if (!string.IsNullOrEmpty(q.introducerTxt))
|
if (!string.IsNullOrEmpty(q.introducerTxt))
|
||||||
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(q.introducerTxt?.Trim()));
|
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(q.introducerTxt.Trim()));
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.actItemTxt))
|
if (!string.IsNullOrEmpty(q.actItemTxt))
|
||||||
{
|
{
|
||||||
//qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num?.ToString())).Count() > 0);
|
//qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num?.ToString())).Count() > 0);
|
||||||
// qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.Any(x => x == f2.actItem_num)).Count() > 0);
|
// qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.Any(x => x == f2.actItem_num)).Count() > 0);
|
||||||
|
|
||||||
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(q.actItemTxt?.Trim())).Count() > 0);
|
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(q.actItemTxt.Trim())).Count() > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.country))
|
if (!string.IsNullOrEmpty(q.country))
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country == q.country);
|
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.country == q.country);
|
||||||
if (!string.IsNullOrEmpty(q.country2))
|
if (!string.IsNullOrEmpty(q.country2))
|
||||||
{
|
{
|
||||||
if (q.country2 == "1")
|
if (q.country2 == "1")
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country == "158");
|
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.country == "158");
|
||||||
}
|
}
|
||||||
else if (q.country2 == "2")
|
else if (q.country2 == "2")
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.f_num != null && o.follower?.country != "158");
|
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.country != "158");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,11 +317,11 @@ public class apporderController : ApiController
|
|||||||
if (!string.IsNullOrEmpty( order_no ))
|
if (!string.IsNullOrEmpty( order_no ))
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var prod = _db.pro_order.AsEnumerable().Where(o => o.order_no == order_no).FirstOrDefault();
|
var prod = _db.pro_order.Where(o => o.order_no == order_no).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
int activity = prod.activity_num.HasValue ? prod.activity_num.Value : 0; //活動
|
int activity = prod.activity_num.HasValue ? prod.activity_num.Value : 0; //活動
|
||||||
var bedDt = _db.bed_order_detail.AsEnumerable().Where(b=>b.bed_order.order_no== order_no ); ;//掛單明細
|
var bedDt = _db.bed_order_detail.Where(b=>b.bed_order.order_no== order_no ); ;//掛單明細
|
||||||
|
|
||||||
|
|
||||||
//var qry1 = _db.pro_order_detail.AsEnumerable();
|
//var qry1 = _db.pro_order_detail.AsEnumerable();
|
||||||
@@ -435,7 +435,7 @@ public class apporderController : ApiController
|
|||||||
if (activity > 0)
|
if (activity > 0)
|
||||||
{
|
{
|
||||||
i = 1;
|
i = 1;
|
||||||
var qry2 = _db.activity_relating.AsEnumerable();
|
var qry2 = _db.activity_relating.AsQueryable();
|
||||||
qry2 = qry2.Where(o => o.activity_num == activity);
|
qry2 = qry2.Where(o => o.activity_num == activity);
|
||||||
|
|
||||||
if (q.actItem_kind_num.HasValue)
|
if (q.actItem_kind_num.HasValue)
|
||||||
@@ -690,14 +690,14 @@ public class apporderController : ApiController
|
|||||||
|
|
||||||
//家族 : 家長是我的人,跟我同家長的人,我的家長本人,我本人
|
//家族 : 家長是我的人,跟我同家長的人,我的家長本人,我本人
|
||||||
var cc = _db.followers.Where(x => x.num == _follower || x.leader == _follower).Select(x => x.num);
|
var cc = _db.followers.Where(x => x.num == _follower || x.leader == _follower).Select(x => x.num);
|
||||||
var qry = _db.followers.AsEnumerable().Where(f => cc.Any(x => x == f.num) || cc.Any(x => x == f.leader));
|
var qry = _db.followers.Where(f => cc.Any(x => x == f.num) || cc.Any(x => x == f.leader));
|
||||||
|
|
||||||
//未付款資料
|
//未付款資料
|
||||||
var unpayDt = _db.pro_order_detail.AsEnumerable();
|
var unpayDt = _db.pro_order_detail.AsQueryable();
|
||||||
var coDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
var coDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
||||||
|
|
||||||
//未付款訂單
|
//未付款訂單
|
||||||
var orderDt = _db.pro_order.AsEnumerable();
|
var orderDt = _db.pro_order.AsQueryable();
|
||||||
if (!string.IsNullOrEmpty(order_no))
|
if (!string.IsNullOrEmpty(order_no))
|
||||||
orderDt = orderDt.Where(x => x.order_no == order_no);
|
orderDt = orderDt.Where(x => x.order_no == order_no);
|
||||||
orderDt = orderDt.Where(x => coDt.Select(d => d.order_no).Contains(x.order_no));
|
orderDt = orderDt.Where(x => coDt.Select(d => d.order_no).Contains(x.order_no));
|
||||||
@@ -737,7 +737,7 @@ public class apporderController : ApiController
|
|||||||
{
|
{
|
||||||
|
|
||||||
//未付款資料
|
//未付款資料
|
||||||
var unpayDt = _db.pro_order_detail.AsEnumerable();
|
var unpayDt = _db.pro_order_detail.AsQueryable();
|
||||||
unpayDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
unpayDt = unpayDt.Where(x => x.keyin1 == (int)Model.pro_order.detailKeyin1.Collection);//只列出報名狀態為"收款中"的項目
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(q.order_no))
|
if (!string.IsNullOrEmpty(q.order_no))
|
||||||
@@ -865,10 +865,10 @@ public class apporderController : ApiController
|
|||||||
if (u_name >0 && (!string.IsNullOrEmpty(q.order_no)))
|
if (u_name >0 && (!string.IsNullOrEmpty(q.order_no)))
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var prod = _db.pro_order.AsEnumerable().Where(o => o.f_num == u_name && o.order_no != q.order_no).ToList();
|
var prod = _db.pro_order.Where(o => o.f_num == u_name && o.order_no != q.order_no).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
var qry = _db.pro_order_detail.AsEnumerable().Where(o => prod.Any(x => x.order_no==o.order_no) );
|
var qry = _db.pro_order_detail.Where(o => prod.Any(x => x.order_no==o.order_no) );
|
||||||
int i = 1;
|
int i = 1;
|
||||||
var ret = new
|
var ret = new
|
||||||
{
|
{
|
||||||
@@ -942,7 +942,7 @@ public class apporderController : ApiController
|
|||||||
if (detail_num > 0 )
|
if (detail_num > 0 )
|
||||||
{
|
{
|
||||||
//檢查
|
//檢查
|
||||||
var prod = _db.pro_order_record.AsEnumerable().Where(o => o.detail_num == detail_num )
|
var prod = _db.pro_order_record.Where(o => o.detail_num == detail_num )
|
||||||
.OrderByDescending(o=>o.pay_date).ToList();
|
.OrderByDescending(o=>o.pay_date).ToList();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
var ret = new
|
var ret = new
|
||||||
@@ -979,7 +979,7 @@ public class apporderController : ApiController
|
|||||||
[Route("api/apporder/DeleteRecordDetail/{id}")]//刪除收款註記
|
[Route("api/apporder/DeleteRecordDetail/{id}")]//刪除收款註記
|
||||||
public void DeleteRecordDetail(int id)
|
public void DeleteRecordDetail(int id)
|
||||||
{
|
{
|
||||||
var prod = _db.pro_order_record.AsEnumerable().Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.pro_order_record.Where(q => q.num == id).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -995,8 +995,8 @@ public class apporderController : ApiController
|
|||||||
{
|
{
|
||||||
if (item.detail_num > 0)
|
if (item.detail_num > 0)
|
||||||
{
|
{
|
||||||
float total = _db.pro_order_detail.AsEnumerable().Where(x => x.num == item.detail_num).Select(x => x.price.Value * x.qty.Value).Sum();
|
float total = _db.pro_order_detail.Where(x => x.num == item.detail_num).Select(x => x.price.Value * x.qty.Value).Sum();
|
||||||
float pay = _db.pro_order_record.AsEnumerable().Where(x => x.detail_num == item.detail_num).Select(x => x.price.Value).Sum();
|
float pay = _db.pro_order_record.Where(x => x.detail_num == item.detail_num).Select(x => x.price.Value).Sum();
|
||||||
|
|
||||||
if (pay + item.price.Value <= total)
|
if (pay + item.price.Value <= total)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -130,7 +130,8 @@ public partial class admin_hr_import : MyWeb.config
|
|||||||
);
|
);
|
||||||
sd2.AppendChild(tr);
|
sd2.AppendChild(tr);
|
||||||
//查詢要匯出的資料
|
//查詢要匯出的資料
|
||||||
var list = _db.member_group.AsEnumerable().ToList();
|
// TODO: REVIEW - member_group 為固定少量資料表,ToList() 可接受
|
||||||
|
var list = _db.member_group.ToList();
|
||||||
if (list.Count > 0)
|
if (list.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var item in list)
|
foreach (var item in list)
|
||||||
@@ -178,7 +179,8 @@ public partial class admin_hr_import : MyWeb.config
|
|||||||
);
|
);
|
||||||
sd3.AppendChild(tr);
|
sd3.AppendChild(tr);
|
||||||
//查詢要匯出的資料
|
//查詢要匯出的資料
|
||||||
var list2 = _db.member_title.AsEnumerable().ToList();
|
// TODO: REVIEW - member_title 為固定少量資料表,ToList() 可接受
|
||||||
|
var list2 = _db.member_title.ToList();
|
||||||
if (list2.Count > 0)
|
if (list2.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var item in list2)
|
foreach (var item in list2)
|
||||||
@@ -229,10 +231,16 @@ public partial class admin_hr_import : MyWeb.config
|
|||||||
startRowNumber += 1;
|
startRowNumber += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fDt = _db.followers.AsEnumerable().ToList(); //信眾
|
// TODO: REVIEW - 整表載入性能評估:
|
||||||
var aDt = _db.admins.AsEnumerable().ToList(); //後台系統
|
// - followers (信眾) ⚠️ 會成長!若超過 1000 筆需優化為按需載入(先掃描 Excel 收集編號)
|
||||||
var gDt = _db.member_group.AsEnumerable().Select(x => x.num).ToList(); //組別
|
// - admins (管理員) ✓ 通常少量,ToList() 可接受
|
||||||
var tDt = _db.member_title.AsEnumerable().Select(x => x.num).ToList(); //職稱
|
// - member_group (組別) ✓ 固定少量,可接受
|
||||||
|
// - member_title (職稱) ✓ 固定少量,可接受
|
||||||
|
// 優化方案:先掃描 Excel → 只載入需要的編號 → 使用 Dictionary 加速查找(O(1) vs O(n))
|
||||||
|
var fDt = _db.followers.ToList(); //信眾
|
||||||
|
var aDt = _db.admins.ToList(); //後台系統
|
||||||
|
var gDt = _db.member_group.Select(x => x.num).ToList(); //組別
|
||||||
|
var tDt = _db.member_title.Select(x => x.num).ToList(); //職稱
|
||||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||||
|
|
||||||
for (int currentRow = startRowNumber; currentRow <= endRowNumber; currentRow++)
|
for (int currentRow = startRowNumber; currentRow <= endRowNumber; currentRow++)
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
if (!isStrNull(Request["num"]))
|
if (!isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var qry = _db.member_group.AsEnumerable();
|
|
||||||
var prod = _db.member_group.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
var prod = _db.member_group.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -70,7 +69,6 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
protected void TreeTopology()
|
protected void TreeTopology()
|
||||||
{
|
{
|
||||||
var qry = _db.member_group.AsEnumerable();
|
|
||||||
var prod = _db.member_group.ToList();
|
var prod = _db.member_group.ToList();
|
||||||
//treeDt = prod.CopyToDataTable();
|
//treeDt = prod.CopyToDataTable();
|
||||||
|
|
||||||
@@ -235,7 +233,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.member_group.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.member_group.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -281,7 +279,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
del_product(num);
|
del_product(num);
|
||||||
|
|
||||||
|
|
||||||
var prod = _db.member_group.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.member_group.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.member_group.Remove(prod);
|
_db.member_group.Remove(prod);
|
||||||
@@ -302,7 +300,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.member_group.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.member_group.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -319,7 +317,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
var prod = _db.members.AsEnumerable().Where(q => q.group_kind == num).ToList();
|
var prod = _db.members.Where(q => q.group_kind == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
//清空組別分類
|
//清空組別分類
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
if (!isStrNull(Request["num"]))
|
if (!isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var qry = _db.member_title.AsEnumerable();
|
|
||||||
var prod = _db.member_title.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
var prod = _db.member_title.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -207,7 +206,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.member_title.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.member_title.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -248,7 +247,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
int num = Val(Request["num"]);
|
int num = Val(Request["num"]);
|
||||||
del_product(num);
|
del_product(num);
|
||||||
|
|
||||||
var prod = _db.member_title.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.member_title.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.member_title.Remove(prod);
|
_db.member_title.Remove(prod);
|
||||||
@@ -269,7 +268,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.member_title.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.member_title.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -286,7 +285,7 @@ public partial class admin_hr_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
var prod = _db.members.AsEnumerable().Where(q => q.title_kind == num).ToList();
|
var prod = _db.members.Where(q => q.title_kind == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
//清空分類
|
//清空分類
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public partial class admin_accounting_kind_reg : MyWeb.config
|
|||||||
if (!isStrNull(Request["num"]))
|
if (!isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
var prod = _db.accounting_kind.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
||||||
|
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -215,7 +215,7 @@ public partial class admin_accounting_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.accounting_kind.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -254,7 +254,7 @@ public partial class admin_accounting_kind_reg : MyWeb.config
|
|||||||
int num = Val(Request["num"]);
|
int num = Val(Request["num"]);
|
||||||
del_product(num);
|
del_product(num);
|
||||||
|
|
||||||
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.accounting_kind.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.accounting_kind.Remove(prod);
|
_db.accounting_kind.Remove(prod);
|
||||||
@@ -272,7 +272,7 @@ public partial class admin_accounting_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.accounting_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.accounting_kind.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -291,7 +291,7 @@ public partial class admin_accounting_kind_reg : MyWeb.config
|
|||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
|
|
||||||
var prod = _db.accountings.AsEnumerable().Where(q => q.kind == num).ToList();
|
var prod = _db.accountings.Where(q => q.kind == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
////查詢結果全部刪除
|
////查詢結果全部刪除
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public partial class admin_accounting_kind_reg2 : MyWeb.config
|
|||||||
if (!isStrNull(Request["num"]))
|
if (!isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.num == _num).FirstOrDefault();
|
var prod = _db.accounting_kind2.Where(q => q.num == _num).FirstOrDefault();
|
||||||
|
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -228,7 +228,7 @@ public partial class admin_accounting_kind_reg2 : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.accounting_kind2.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -271,7 +271,7 @@ public partial class admin_accounting_kind_reg2 : MyWeb.config
|
|||||||
int num = Val(Request["num"]);
|
int num = Val(Request["num"]);
|
||||||
del_product(num);
|
del_product(num);
|
||||||
|
|
||||||
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.accounting_kind2.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.accounting_kind2.Remove(prod);
|
_db.accounting_kind2.Remove(prod);
|
||||||
@@ -288,7 +288,7 @@ public partial class admin_accounting_kind_reg2 : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.accounting_kind2.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.accounting_kind2.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -306,7 +306,7 @@ public partial class admin_accounting_kind_reg2 : MyWeb.config
|
|||||||
|
|
||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
var prod = _db.accountings.AsEnumerable().Where(q => q.kind2 == num).ToList();
|
var prod = _db.accountings.Where(q => q.kind2 == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
////查詢結果全部刪除
|
////查詢結果全部刪除
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public partial class admin_activity_itemKind : MyWeb.config
|
|||||||
if (!isStrNull(Request["num"]))
|
if (!isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
var prod = _db.actItem_kind.Where(q => q.num == _num).OrderBy(q => q.kind).FirstOrDefault();
|
||||||
|
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -214,7 +214,7 @@ public partial class admin_activity_itemKind : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.actItem_kind.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -252,7 +252,7 @@ public partial class admin_activity_itemKind : MyWeb.config
|
|||||||
|
|
||||||
int num = Val(Request["num"]);
|
int num = Val(Request["num"]);
|
||||||
del_product(num);
|
del_product(num);
|
||||||
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.actItem_kind.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ public partial class admin_activity_itemKind : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.actItem_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.actItem_kind.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -289,7 +289,7 @@ public partial class admin_activity_itemKind : MyWeb.config
|
|||||||
|
|
||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
var prod = _db.actItems.AsEnumerable().Where(q => q.kind == num).ToList();
|
var prod = _db.actItems.Where(q => q.kind == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
//清空分類
|
//清空分類
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public partial class admin_activity_kind_reg : MyWeb.config
|
|||||||
{
|
{
|
||||||
_this_id = ValString(Request["num"]);
|
_this_id = ValString(Request["num"]);
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = _db.activity_kind.AsEnumerable().Where(q => q.num == _num).OrderBy(q=>q.kind).FirstOrDefault();
|
var prod = _db.activity_kind.Where(q => q.num == _num).OrderBy(q=>q.kind).FirstOrDefault();
|
||||||
|
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -230,7 +230,7 @@ public partial class admin_activity_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.activity_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.activity_kind.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -284,7 +284,7 @@ public partial class admin_activity_kind_reg : MyWeb.config
|
|||||||
{
|
{
|
||||||
int num = Val(Request["num"]);
|
int num = Val(Request["num"]);
|
||||||
del_product(num);
|
del_product(num);
|
||||||
var prod = _db.activity_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activity_kind.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.activity_kind.Remove(prod);
|
_db.activity_kind.Remove(prod);
|
||||||
@@ -301,7 +301,7 @@ public partial class admin_activity_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.activity_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.activity_kind.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -317,7 +317,7 @@ public partial class admin_activity_kind_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
var prod = _db.activities.AsEnumerable().Where(q => q.kind == num).ToList();
|
var prod = _db.activities.Where(q => q.kind == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
//清空分類
|
//清空分類
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public partial class admin_activity_kind_reg2 : MyWeb.config
|
|||||||
if (!isStrNull(Request["num"]))
|
if (!isStrNull(Request["num"]))
|
||||||
{
|
{
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.num == _num).Where(q => q.num == _num).FirstOrDefault();
|
var prod = _db.activity_category_kind.Where(q => q.num == _num).FirstOrDefault();
|
||||||
|
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -208,7 +208,7 @@ public partial class admin_activity_kind_reg2 : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.activity_category_kind.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -247,7 +247,7 @@ public partial class admin_activity_kind_reg2 : MyWeb.config
|
|||||||
|
|
||||||
del_product(num);
|
del_product(num);
|
||||||
|
|
||||||
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.activity_category_kind.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.activity_category_kind.Remove(prod);
|
_db.activity_category_kind.Remove(prod);
|
||||||
@@ -265,7 +265,7 @@ public partial class admin_activity_kind_reg2 : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.activity_category_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.activity_category_kind.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -284,7 +284,7 @@ public partial class admin_activity_kind_reg2 : MyWeb.config
|
|||||||
public void del_product(int num) //刪除訊息
|
public void del_product(int num) //刪除訊息
|
||||||
{
|
{
|
||||||
//EF Model 資料庫拉關聯 , 故刪除類型前,一定要先刪除訊息,否則關聯會出錯
|
//EF Model 資料庫拉關聯 , 故刪除類型前,一定要先刪除訊息,否則關聯會出錯
|
||||||
var prod = _db.activities.AsEnumerable().Where(q => q.category_kind == num).ToList();
|
var prod = _db.activities.Where(q => q.category_kind == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
:server-items-length="activity_statistics.totalItems"
|
:server-items-length="activity_statistics.totalItems"
|
||||||
:items="activity_statistics.items">
|
:items="activity_statistics.items">
|
||||||
<template #item.detail_btn="{item}">
|
<template #item.detail_btn="{item}">
|
||||||
<a :href="'activity.aspx?num='+item.id" class="btn btn-outline-secondary btn-sm" target="_blank">詳細統計</a>
|
<a :href="'statistics.aspx?num='+item.id + '&activity_name=' + encodeURIComponent(item.activity_name)" class="btn btn-outline-secondary btn-sm" target="_blank">詳細統計</a>
|
||||||
</template>
|
</template>
|
||||||
<template #item.duetime="{item}">
|
<template #item.duetime="{item}">
|
||||||
{{item.startdate|timeString("YYYY/MM/DD")}}-{{item.enddate|timeString("YYYY/MM/DD")}}
|
{{item.startdate|timeString("YYYY/MM/DD")}}-{{item.enddate|timeString("YYYY/MM/DD")}}
|
||||||
|
|||||||
186
web/admin/activity/statistics/statistics.aspx
Normal file
186
web/admin/activity/statistics/statistics.aspx
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="statistics.aspx.cs" Inherits="admin_activity_statistics_statistics" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
<div class="ms-5">
|
||||||
|
<span>
|
||||||
|
活動名稱: {{ activity_name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="me-5">
|
||||||
|
<button class="btn btn-primary" type="button">匯出表格資料</button>
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div id="content" class="container-fluid">
|
||||||
|
<div class="card shadow-sm my-2" id="sec2">
|
||||||
|
<div class="card-header py-0">
|
||||||
|
<nav class="navbar py-0">
|
||||||
|
<div class="nav nav-tabs">
|
||||||
|
<button class="nav-link active" id="sec2-tab1" data-bs-toggle="tab" data-bs-target="#sec2-page1"
|
||||||
|
type="button" role="tab" aria-controls="home" aria-selected="true">
|
||||||
|
活動統計總表</button>
|
||||||
|
<button class="nav-link" id="sec2-tab2" data-bs-toggle="tab" data-bs-target="#sec2-page2"
|
||||||
|
type="button" role="tab" aria-controls="profile" aria-selected="false">
|
||||||
|
活動統計數量明細 </button>
|
||||||
|
<button class="nav-link" id="sec2-tab3" data-bs-toggle="tab" data-bs-target="#sec2-page3"
|
||||||
|
type="button" role="tab" aria-controls="profile" aria-selected="false">
|
||||||
|
活動統計報名人明細 </button>
|
||||||
|
<button class="nav-link" id="sec2-tab4" data-bs-toggle="tab" data-bs-target="#sec2-page4"
|
||||||
|
type="button" role="tab" aria-controls="profile" aria-selected="false">
|
||||||
|
活動牌位明細</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="tab-content" id="myTabContent">
|
||||||
|
<div class="tab-pane fade show active noedit p-4" id="sec2-page1" role="tabpanel" aria-labelledby="sec2-tab1">
|
||||||
|
<h5 class="mb-4"> {{ activity_name }}(截至 {{summaryStats?.reportDate }})</h5>
|
||||||
|
<!-- 基本資訊 + 功德金 統計 -->
|
||||||
|
<table class="table table-bordered table-sm w-auto mb-4">
|
||||||
|
<tbody>
|
||||||
|
<!-- 基本資訊 -->
|
||||||
|
<tr class="table-primary">
|
||||||
|
<th colspan="4">基本資訊</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>類別</th>
|
||||||
|
<td>報名人數</td>
|
||||||
|
<td>男眾人數</td>
|
||||||
|
<td>女眾人數</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>數量</th>
|
||||||
|
<td>{{ summaryStats?.totalApplicants }}</td>
|
||||||
|
<td>{{ summaryStats?.maleApplicants }}</td>
|
||||||
|
<td>{{ summaryStats?.femaleApplicants }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table class="table table-bordered table-sm w-auto mb-4">
|
||||||
|
<tbody>
|
||||||
|
<!-- 功德金 -->
|
||||||
|
<tr class="table-primary">
|
||||||
|
<th colspan="4">功德金統計</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>類別</th>
|
||||||
|
<td>總功德金</td>
|
||||||
|
<td>已收</td>
|
||||||
|
<td>未收</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>金額</th>
|
||||||
|
<td>{{ summaryStats?.donation.total }}</td>
|
||||||
|
<td>{{ summaryStats?.donation.received }}</td>
|
||||||
|
<td>{{ summaryStats?.donation.unreceived }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<!-- 功德項目 -->
|
||||||
|
<table class="table table-bordered table-sm w-auto mb-4">
|
||||||
|
<tbody>
|
||||||
|
<tr class="table-primary">
|
||||||
|
<th colspan="100%">功德項目</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>功德項目</th>
|
||||||
|
<td v-for="(item, index) in summaryStats?.items" :key="'name-' + index">
|
||||||
|
{{ item.name }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>人數</th>
|
||||||
|
<td v-for="(item, index) in summaryStats?.items" :key="'count-' + index">
|
||||||
|
{{ item.count }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- 牌位數量 -->
|
||||||
|
<table class="table table-bordered table-sm w-auto">
|
||||||
|
<tbody>
|
||||||
|
<tr class="table-primary">
|
||||||
|
<th colspan="100%">牌位數量</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>牌位名稱</th>
|
||||||
|
<td v-for="(plaque, index) in summaryStats?.plaques" :key="'plaque-name-' + index">
|
||||||
|
{{ plaque.name }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>數量</th>
|
||||||
|
<td v-for="(plaque, index) in summaryStats?.plaques" :key="'plaque-count-' + index">
|
||||||
|
{{ plaque.count }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane fade" id="sec2-page2" role="tabpanel" aria-labelledby="sec2-tab2">
|
||||||
|
sec2-page2
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="sec2-page3" role="tabpanel" aria-labelledby="sec2-tab3">
|
||||||
|
sec2-page3
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="sec2-page4" role="tabpanel" aria-labelledby="sec2-tab4">
|
||||||
|
sec2-page4
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activity_num: '<%= Request["num"] %>',
|
||||||
|
activity_name: '<%= Request["activity_name"] %>',
|
||||||
|
summaryStats: null, //匯總統計(總覽)
|
||||||
|
quantityDetails: [], // 數量明細(分類數量)
|
||||||
|
applicantList: [], // 報名人清單
|
||||||
|
plaqueList: [], //牌位清單
|
||||||
|
loadingSummary: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchSummaryStats() {
|
||||||
|
//獲取匯總明細
|
||||||
|
this.loadingSummary = true;
|
||||||
|
|
||||||
|
axios.get(HTTP_HOST + 'api/activity/statistics/summary',
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
activity_num: this.activity_num
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
.then(res => {
|
||||||
|
this.summaryStats = res.data;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loadingSummary = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetchSummaryStats(); // 頁面載入時就獲取
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</asp:Content>
|
||||||
|
|
||||||
14
web/admin/activity/statistics/statistics.aspx.cs
Normal file
14
web/admin/activity/statistics/statistics.aspx.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_activity_statistics_statistics : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
908
web/admin/ancestraltablet/ancestraltabletarea/index.aspx
Normal file
908
web/admin/ancestraltablet/ancestraltabletarea/index.aspx
Normal file
@@ -0,0 +1,908 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletarea_index" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
<nav class="mb-2 ps-3">
|
||||||
|
<button class="btn btn-primary me-2" type="button" @click="showNewtAreadialogMethod">
|
||||||
|
<i class="mdi mdi-plus"></i> 新增區域
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-secondary me-2" @click="expandAll" type="button">
|
||||||
|
<i class="mdi mdi-arrow-expand-all"></i> 全部展開
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-secondary" @click="collapseAll" type="button">
|
||||||
|
<i class="mdi mdi-arrow-collapse-all"></i> 全部收起
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
<nav>
|
||||||
|
<button type="button" class="btn btn-primary" @click="toggleAreaData">
|
||||||
|
{{ showAreaDataFlag ? '隱藏區域資料' : '顯示區域資料' }}
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 col-lg-3">
|
||||||
|
<div class="card shadow-sm my-2">
|
||||||
|
<div class="card-header">神主牌區域列表</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<ul class="tree">
|
||||||
|
<li v-for="area in ancestral_tablet_areas" :key="area.AreaId">
|
||||||
|
<region-item
|
||||||
|
:item="area"
|
||||||
|
:selected-id="currentSelectAreaId"
|
||||||
|
@select-area="selectAreaMethod"
|
||||||
|
:expand-all="expandAllFlag"
|
||||||
|
:collapse-all="collapseAllFlag"
|
||||||
|
@clear-expand-all="expandAllFlag = false"
|
||||||
|
@clear-collapse-all="collapseAllFlag = false"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4 col-lg-9" v-if="currentSelectArea && showAreaDataFlag">
|
||||||
|
<div class="card shadow-sm my-2"style="position: sticky; top: 20px;">
|
||||||
|
<div class="card-header" style="display: flex; justify-content: space-between; align-items: center;">
|
||||||
|
<div>
|
||||||
|
<span class="fw-bold">
|
||||||
|
{{ ' ' + currentSelectArea?.areaName + ' ' }}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
資料
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button class="btn btn-primary" type="button" @click="showEidtAreadialogMethod">
|
||||||
|
編輯
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域名稱</label>
|
||||||
|
<input v-model="currentSelectArea.areaName" type="text" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域編號</label>
|
||||||
|
<input v-model="currentSelectArea.areaCode" type="text" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>上層區域(可選)</label>
|
||||||
|
<input v-model="currentSelectArea.parentAreaId" type="text" class="form-control" readonly />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域類型(可空)</label>
|
||||||
|
<input v-model="currentSelectArea.areaType" type="text" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>價格</label>
|
||||||
|
<input v-model="currentSelectArea.price" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>排序</label>
|
||||||
|
<input v-model="currentSelectArea.sortOrder" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<div style="display: flex; align-items: center; height: 100%; margin-top: 8px;">
|
||||||
|
<input
|
||||||
|
v-model="currentSelectArea.isDisabled"
|
||||||
|
type="checkbox"
|
||||||
|
disabled
|
||||||
|
id="disabledToggle"
|
||||||
|
style="width: 20px; height: 20px; margin-right: 8px; cursor: pointer;"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="disabledToggle"
|
||||||
|
style="font-weight: bold; font-size: 14px; color: #333; margin: 0;"
|
||||||
|
>
|
||||||
|
是否停用
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<label>描述</label>
|
||||||
|
<textarea v-model="currentSelectArea.description" rows="3" class="form-control" readonly></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4 col-lg-9" v-if="currentSelectArea">
|
||||||
|
<div class="card shadow-sm my-2" style="flex: 1 1 auto; min-height: 0; overflow: auto;">
|
||||||
|
<div class="card-header" style="display: flex; justify-content: space-between; align-items: center;background-color: #ffc107;">
|
||||||
|
<div>
|
||||||
|
{{currentSelectArea.areaName + ' - ' + '神主牌位置'}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<v-btn color="primary" @click="openNewPositionDialogMethod">批次新增神主牌位置</v-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="grid-container">
|
||||||
|
<div
|
||||||
|
v-for="pos in positions"
|
||||||
|
:key="pos.positionCode"
|
||||||
|
class="grid-item"
|
||||||
|
:class="'status-' + pos.statusCode"
|
||||||
|
:style="{ gridRow: pos.rowNo, gridColumn: pos.columnNo }"
|
||||||
|
>
|
||||||
|
<div class="position-name">{{ pos.positionName }}</div>
|
||||||
|
<div class="position-content">
|
||||||
|
<!-- 這裡可以放更多資訊,比如價格或狀態 -->
|
||||||
|
<!-- 例如:價格: {{ pos.price }} -->
|
||||||
|
<v-btn small @click="editPositionMethod(pos)">修改</v-btn>
|
||||||
|
<v-btn small @click="deletePositionMethod(pos)">刪除</v-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 新增區域彈出視窗 -->
|
||||||
|
<div>
|
||||||
|
<v-dialog v-model="showNewAreadialogFlag" max-width="1200px">
|
||||||
|
<v-card
|
||||||
|
style="min-height: 50vh; max-height: 80vh; overflow-y: auto;"
|
||||||
|
>
|
||||||
|
<v-card-title>
|
||||||
|
<span class="headline">新增區域</span>
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域名稱</label>
|
||||||
|
<input v-model="newArea.areaName" type="text" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域編號</label>
|
||||||
|
<input v-model="newArea.areaCode" type="text" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>上層區域(可選)</label>
|
||||||
|
<select v-model="newArea.parentAreaId" class="form-control" >
|
||||||
|
<option value="">請選擇</option>
|
||||||
|
<!-- 手動添加選項 -->
|
||||||
|
<option v-for="r in flatAreas"
|
||||||
|
:value="r.areaId"
|
||||||
|
:disabled="disabledParentOptions.includes(r.areaId)">{{ r.areaName }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域類型(可空)</label>
|
||||||
|
<input type="text" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>價格</label>
|
||||||
|
<input v-model="newArea.price" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>排序</label>
|
||||||
|
<input v-model="newArea.sortOrder" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<div style="display: flex; align-items: center; height: 100%; margin-top: 8px;">
|
||||||
|
<input
|
||||||
|
v-model="newArea.isDisabled"
|
||||||
|
type="checkbox"
|
||||||
|
style="width: 20px; height: 20px; margin-right: 8px; cursor: pointer;"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="disabledToggle"
|
||||||
|
style="font-weight: bold; font-size: 14px; color: #333; margin: 0;"
|
||||||
|
>
|
||||||
|
是否停用
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<label>描述</label>
|
||||||
|
<textarea v-model="newArea.description" rows="3" class="form-control" ></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="grey" text @click="closeNewAreadialogMethod">取消</v-btn>
|
||||||
|
<v-btn color="primary" @click="createNewAreaMethod">確定新增</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
<!-- 編輯區域彈出視窗 -->
|
||||||
|
<div>
|
||||||
|
<v-dialog v-model="showEidtAreadialogFlag" max-width="1200px">
|
||||||
|
<v-card
|
||||||
|
style="min-height: 50vh; max-height: 80vh; overflow-y: auto;"
|
||||||
|
>
|
||||||
|
<v-card-title>
|
||||||
|
<span class="headline">編輯區域</span>
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域名稱</label>
|
||||||
|
<input v-model="editArea.areaName" type="text" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域編號</label>
|
||||||
|
<input v-model="editArea.areaCode" type="text" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>上層區域(可選)</label>
|
||||||
|
<select v-model="editArea.parentAreaId" class="form-control" >
|
||||||
|
<option value="">請選擇</option>
|
||||||
|
<!-- 手動添加選項 -->
|
||||||
|
<option v-for="r in flatAreas"
|
||||||
|
:value="r.areaId"
|
||||||
|
:disabled="disabledParentOptions.includes(r.areaId)">{{ r.areaName }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>區域類型(可空)</label>
|
||||||
|
<input v-model="editArea.areaType" type="text" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>價格</label>
|
||||||
|
<input v-model="editArea.price" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<label>排序</label>
|
||||||
|
<input v-model="editArea.sortOrder" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-6">
|
||||||
|
<div style="display: flex; align-items: center; height: 100%; margin-top: 8px;">
|
||||||
|
<input
|
||||||
|
v-model="editArea.isDisabled"
|
||||||
|
type="checkbox"
|
||||||
|
id="disabledToggle1"
|
||||||
|
style="width: 20px; height: 20px; margin-right: 8px; cursor: pointer;"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="disabledToggle"
|
||||||
|
style="font-weight: bold; font-size: 14px; color: #333; margin: 0;"
|
||||||
|
>
|
||||||
|
是否停用
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 mt-3">
|
||||||
|
<label>描述</label>
|
||||||
|
<textarea v-model="editArea.description" rows="3" class="form-control" ></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="grey" text @click="closeEidtAreadialogMethod">取消</v-btn>
|
||||||
|
<v-btn color="primary" @click="editAreaMethod">送出修改</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
<!-- 批次新增神主牌彈出視窗 -->
|
||||||
|
<div>
|
||||||
|
<!-- 彈出視窗組件 -->
|
||||||
|
<v-dialog v-model="showNewPositionDialogFlag" max-width="800px">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
批次新增神主牌位置
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn icon @click="closeNewPositionDialogMethod">
|
||||||
|
<v-icon>mdi-close</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<div class="card p-3 mt-4">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col">
|
||||||
|
<label>起始行</label>
|
||||||
|
<input v-model.number="batchPositionForm.startRow" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label>起始列</label>
|
||||||
|
<input v-model.number="batchPositionForm.startCol" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label>行數</label>
|
||||||
|
<input v-model.number="batchPositionForm.rows" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label>列數</label>
|
||||||
|
<input v-model.number="batchPositionForm.cols" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col">
|
||||||
|
<label>價格</label>
|
||||||
|
<input v-model.number="batchPositionForm.price" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label>狀態</label>
|
||||||
|
<select v-model="batchPositionForm.status" class="form-control">
|
||||||
|
<option v-for="s in statusList" :key="s.statusCode" :value="s.statusCode">
|
||||||
|
{{ s.statusName }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label>Name模板</label>
|
||||||
|
<input v-model="batchPositionForm.nameTemplate" class="form-control" placeholder="如:神位編號{code}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Code起始值</label>
|
||||||
|
<input v-model.number="batchPositionForm.startCode" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label>Code長度</label>
|
||||||
|
<input v-model.number="batchPositionForm.codeLength" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="previewPositions.length">
|
||||||
|
<h3>預覽新增位置</h3>
|
||||||
|
<ul>
|
||||||
|
<li v-for="pos in previewPositions" :key="pos.PositionCode">
|
||||||
|
{{ pos.PositionCode }} - {{ pos.PositionName }} (行: {{ pos.RowNo }}, 列: {{ pos.ColumnNo }})
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions class="justify-end">
|
||||||
|
<v-btn color="primary" @click="generatePositionsMethod">生成預覽</v-btn>
|
||||||
|
<v-btn color="pirmary" @click="clearPreviewPositionsMethod">清除預覽</v-btn>
|
||||||
|
<v-btn color="primary" @click="confirmAddPositionsMethod">確認新增</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
<!-- 編輯牌位位置彈出視窗 -->
|
||||||
|
<div v-if="currentEditPosition">
|
||||||
|
<v-dialog v-model="editPositionFormVisible" max-width="500">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="text-h6">
|
||||||
|
編輯位置:{{ currentEditPosition?.positionName || '未選擇' }}
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<div class="form-row">
|
||||||
|
<label>位置名稱:</label>
|
||||||
|
<input v-model="currentEditPosition.positionName" class="form-control" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<label>價格:</label>
|
||||||
|
<input v-model="currentEditPosition.price" type="number" class="form-control" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<label>狀態:</label>
|
||||||
|
<select v-model="currentEditPosition.statusCode" class="form-control">
|
||||||
|
<option v-for="s in statusList" :key="s.statusCode" :value="s.statusCode">
|
||||||
|
{{ s.statusName }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="primary" @click="saveEditPositionMethod">保存</v-btn>
|
||||||
|
<v-btn text @click="editPositionFormVisible = false">取消</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
Vue.component('region-item', {
|
||||||
|
props: ['item', 'selectedId', 'expandAll', 'collapseAll'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expanded: false, // 預設全部收起
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expandAll(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.expanded = true;
|
||||||
|
// 執行完後發事件通知父組件清除標誌
|
||||||
|
this.$nextTick(() => this.$emit('clear-expand-all'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapseAll(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.expanded = false;
|
||||||
|
this.$nextTick(() => this.$emit('clear-collapse-all'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasChildren() {
|
||||||
|
return this.item.children && this.item.children.length > 0;
|
||||||
|
},
|
||||||
|
icon() {
|
||||||
|
// 無論有無子節點,皆可點擊展開/收起
|
||||||
|
return this.expanded ? '▼' : '▶';
|
||||||
|
},
|
||||||
|
isSelected() {
|
||||||
|
return this.item.areaId === this.selectedId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.expanded = !this.expanded;
|
||||||
|
},
|
||||||
|
select() {
|
||||||
|
this.$emit('select-area', this.item);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div>
|
||||||
|
<span class="toggle-icon" @click="toggle">{{ icon }}</span>
|
||||||
|
<span @click="select"
|
||||||
|
class="region-item-label"
|
||||||
|
:class="{ 'selected': isSelected }">
|
||||||
|
{{ item.areaName }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 子區域列表 -->
|
||||||
|
<ul v-if="hasChildren && expanded">
|
||||||
|
<li v-for="child in item.children" :key="child.areaId">
|
||||||
|
<region-item
|
||||||
|
:item="child"
|
||||||
|
:selected-id="selectedId"
|
||||||
|
:expand-all="expandAll"
|
||||||
|
:collapse-all="collapseAll"
|
||||||
|
@select-area="$emit('select-area', $event)"
|
||||||
|
@clear-expand-all="$emit('clear-expand-all')"
|
||||||
|
@clear-collapse-all="$emit('clear-collapse-all')"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
});
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandAllFlag: false, // 控制全部展開
|
||||||
|
collapseAllFlag: false, // 控制全部收起
|
||||||
|
ancestral_tablet_areas: [], //神主牌區域列表
|
||||||
|
currentSelectArea: null,
|
||||||
|
currentSelectAreaId: null,
|
||||||
|
showEidtAreadialogFlag: false,
|
||||||
|
showNewAreadialogFlag: false,
|
||||||
|
showAreaDataFlag: false,//是否顯示區域資料
|
||||||
|
flatAreas: [],//所有區域展平
|
||||||
|
disabledParentOptions: [],//某個區域禁止選擇作為父區域的函數
|
||||||
|
newArea: {
|
||||||
|
areaId: null, // 自增主鍵,新增時通常為 null
|
||||||
|
areaName: null, // 區域名稱,必填
|
||||||
|
areaCode: null, // 區域編號,必填
|
||||||
|
parentAreaId: null, // 上層區域 ID,可為 null
|
||||||
|
areaType: null, // 區域類型,可空
|
||||||
|
price: null, // 價格,可空
|
||||||
|
sortOrder: null, // 排序,可空
|
||||||
|
description: null, // 區域描述
|
||||||
|
isDisabled: null
|
||||||
|
},
|
||||||
|
editArea: {
|
||||||
|
areaId: null, // 自增主鍵,新增時通常為 null
|
||||||
|
areaName: null, // 區域名稱,必填
|
||||||
|
areaCode: null, // 區域編號,必填
|
||||||
|
parentAreaId: null, // 上層區域 ID,可為 null
|
||||||
|
areaType: null, // 區域類型,可空
|
||||||
|
price: null, // 價格,可空
|
||||||
|
sortOrder: null, // 排序,可空
|
||||||
|
description: null, // 區域描述
|
||||||
|
isDisabled: null
|
||||||
|
},
|
||||||
|
statusList: [],
|
||||||
|
//--------------------------------神主牌位置變數
|
||||||
|
showNewPositionDialogFlag: false,//控制是否顯示批次新增神主牌彈出視窗
|
||||||
|
editPositionFormVisible: false, // 控制是否顯示編輯彈出視窗
|
||||||
|
currentEditPosition: null, // 儲存當前正在編輯的位置資訊
|
||||||
|
batchPositionForm: {
|
||||||
|
startRow: 1,
|
||||||
|
startCol: 1,
|
||||||
|
rows: 5,
|
||||||
|
cols: 10,
|
||||||
|
price: 0,
|
||||||
|
status: 'available',
|
||||||
|
nameTemplate: '神位{code}',
|
||||||
|
startCode: 1,
|
||||||
|
codeLength: 3
|
||||||
|
},
|
||||||
|
positions: [],
|
||||||
|
// 預覽數據
|
||||||
|
previewPositions: [],
|
||||||
|
//--------------------------------神主牌位置變數
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectAreaMethod(area) {
|
||||||
|
this.currentSelectAreaId = area.areaId;
|
||||||
|
this.currentSelectArea = area;
|
||||||
|
const node = this.findRegionById(this.ancestral_tablet_areas, area.areaId);
|
||||||
|
this.disabledParentOptions = this.getAllDescendants(node);
|
||||||
|
this.loadTabletPositionsMethod(area.areaId);
|
||||||
|
},
|
||||||
|
showEidtAreadialogMethod() {
|
||||||
|
this.showEidtAreadialogFlag = true;
|
||||||
|
if (this.currentSelectArea) {
|
||||||
|
this.editArea = {
|
||||||
|
areaId: this.currentSelectArea?.areaId,
|
||||||
|
areaName: this.currentSelectArea?.areaName,
|
||||||
|
areaCode: this.currentSelectArea?.areaCode,
|
||||||
|
parentAreaId: this.currentSelectArea?.parentAreaId ?? null,
|
||||||
|
areaType: this.currentSelectArea?.areaType ?? null,
|
||||||
|
price: this.currentSelectArea?.price ?? null,
|
||||||
|
sortOrder: this.currentSelectArea?.sortOrder ?? null,
|
||||||
|
description: this.currentSelectArea?.description ?? null,
|
||||||
|
isDisabled: this.currentSelectArea?.isDisabled ?? true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
closeEidtAreadialogMethod() {
|
||||||
|
this.showEidtAreadialogFlag = false;
|
||||||
|
this.resetEditArea();
|
||||||
|
},
|
||||||
|
showNewtAreadialogMethod() {
|
||||||
|
this.showNewAreadialogFlag = true;
|
||||||
|
},
|
||||||
|
closeNewAreadialogMethod() {
|
||||||
|
this.showNewAreadialogFlag = false;
|
||||||
|
this.resetNewArea();
|
||||||
|
},
|
||||||
|
createNewAreaMethod() {
|
||||||
|
//新建區域
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/area/create', this.newArea)
|
||||||
|
.then(response => {
|
||||||
|
this.closeEidtAreadialogMethod();
|
||||||
|
this.getAreaListMethod();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('失敗:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
editAreaMethod() {
|
||||||
|
//修改區域資料
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/area/edit', this.editArea)
|
||||||
|
.then(response => {
|
||||||
|
this.currentSelectArea = response.data.area;
|
||||||
|
this.getAreaListMethod();
|
||||||
|
this.closeEidtAreadialogMethod();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('失敗:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
resetNewArea() {
|
||||||
|
this.newArea = {
|
||||||
|
areaId: null,
|
||||||
|
areaName: null,
|
||||||
|
areaCode: null,
|
||||||
|
parentAreaId: null,
|
||||||
|
areaType: null,
|
||||||
|
price: null,
|
||||||
|
sortOrder: null,
|
||||||
|
description: null,
|
||||||
|
isDisabled: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
resetEditArea() {
|
||||||
|
this.editArea = {
|
||||||
|
areaId: null,
|
||||||
|
areaName: null,
|
||||||
|
areaCode: null,
|
||||||
|
parentAreaId: null,
|
||||||
|
areaType: null,
|
||||||
|
price: null,
|
||||||
|
sortOrder: null,
|
||||||
|
description: null,
|
||||||
|
isDisabled: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getAreaListMethod() {
|
||||||
|
//獲取區域列表
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/area/getlist')
|
||||||
|
.then(res => {
|
||||||
|
this.ancestral_tablet_areas = res.data
|
||||||
|
this.flatAreas = this.flattenAreas(res.data);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
expandAll() {
|
||||||
|
this.expandAllFlag = true;
|
||||||
|
this.collapseAllFlag = false;
|
||||||
|
},
|
||||||
|
collapseAll() {
|
||||||
|
this.collapseAllFlag = true;
|
||||||
|
this.expandAllFlag = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
//區域展開是否可以被選擇作為上級區域相關函數
|
||||||
|
flattenAreas(data, list = []) {
|
||||||
|
data.forEach(item => {
|
||||||
|
list.push({ areaId: item.areaId, areaName: item.areaName });
|
||||||
|
if (item.children && item.children.length) {
|
||||||
|
this.flattenAreas(item.children, list);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
findRegionById(list, areaId) {
|
||||||
|
for (const item of list) {
|
||||||
|
if (item.areaId === areaId) return item;
|
||||||
|
if (item.children) {
|
||||||
|
const found = this.findRegionById(item.children, areaId);
|
||||||
|
if (found) return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
getAllDescendants(node) {
|
||||||
|
//尋找某個區域的所有子區域
|
||||||
|
const ids = [];
|
||||||
|
const dfs = (n) => {
|
||||||
|
ids.push(n.areaId);
|
||||||
|
if (n.children) {
|
||||||
|
n.children.forEach(child => dfs(child));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs(node);
|
||||||
|
return ids;
|
||||||
|
},
|
||||||
|
toggleAreaData() {
|
||||||
|
this.showAreaDataFlag = !this.showAreaDataFlag;
|
||||||
|
},
|
||||||
|
//--------------------------------神主牌位置相關函數
|
||||||
|
padCodeMethod(codeNum, length) {
|
||||||
|
return codeNum.toString().padStart(length, '0');
|
||||||
|
},
|
||||||
|
loadTabletPositionsMethod(areaId) {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/area/position/getlist', {
|
||||||
|
params: {
|
||||||
|
areaId: areaId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
this.positions = response.data;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('失敗:', error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
generatePositionsMethod() {
|
||||||
|
const form = this.batchPositionForm;
|
||||||
|
const positions = [];
|
||||||
|
let codeCounter = form.startCode;
|
||||||
|
|
||||||
|
for (let i = 0; i < form.rows; i++) {
|
||||||
|
for (let j = 0; j < form.cols; j++) {
|
||||||
|
const row = form.startRow + i;
|
||||||
|
const col = form.startCol + j;
|
||||||
|
const paddedCode = this.padCodeMethod(codeCounter, form.codeLength);
|
||||||
|
const positionCode = paddedCode;
|
||||||
|
const positionName = form.nameTemplate.replace('{code}', paddedCode);
|
||||||
|
|
||||||
|
positions.push({
|
||||||
|
AreaId: this.currentSelectArea.areaId,
|
||||||
|
RowNo: row,
|
||||||
|
ColumnNo: col,
|
||||||
|
PositionCode: positionCode,
|
||||||
|
PositionName: positionName,
|
||||||
|
Price: form.price,
|
||||||
|
StatusCode: form.status,
|
||||||
|
Description: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
codeCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.previewPositions = positions; // 先賦值預覽,不發請求
|
||||||
|
},
|
||||||
|
async confirmAddPositionsMethod() {
|
||||||
|
if (this.previewPositions.length === 0) {
|
||||||
|
alert('請先生成預覽數據');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 調用後端批次新增介面
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
`${HTTP_HOST}api/ancestraltablet/position/batchcreate`,
|
||||||
|
this.previewPositions
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果後端成功響應(HTTP 200/201)
|
||||||
|
alert('批次新增成功');
|
||||||
|
this.loadTabletPositionsMethod(this.currentSelectArea.areaId); // 刷新數據
|
||||||
|
} catch (error) {
|
||||||
|
// 捕獲錯誤響應(如500、400等)
|
||||||
|
console.error('批次新增失敗', error);
|
||||||
|
|
||||||
|
let msg = '批次新增失敗';
|
||||||
|
if (error.response && error.response.data && error.response.data.exceptionMessage) {
|
||||||
|
msg += `:${error.response.data.exceptionMessage}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(msg);
|
||||||
|
}
|
||||||
|
this.previewPositions = []; // 清空預覽
|
||||||
|
},
|
||||||
|
clearPreviewPositionsMethod() {
|
||||||
|
this.previewPositions = [];
|
||||||
|
},
|
||||||
|
openNewPositionDialogMethod() {
|
||||||
|
this.showNewPositionDialogFlag = true;
|
||||||
|
this.batchPositionForm.price = this.currentSelectArea.price
|
||||||
|
},
|
||||||
|
closeNewPositionDialogMethod() {
|
||||||
|
this.showNewPositionDialogFlag = false;
|
||||||
|
this.previewPositions = [];
|
||||||
|
},
|
||||||
|
editPositionMethod(position) {
|
||||||
|
// 彈出編輯表單、打開模態框或跳轉到編輯頁面
|
||||||
|
this.currentEditPosition = position;
|
||||||
|
this.editPositionFormVisible = true;
|
||||||
|
},
|
||||||
|
async saveEditPositionMethod() {
|
||||||
|
try {
|
||||||
|
await axios.post(`${HTTP_HOST}api/ancestraltablet/position/edit`, this.currentEditPosition);
|
||||||
|
this.$message?.success?.('保存成功') || alert('保存成功');
|
||||||
|
this.editPositionFormVisible = false;
|
||||||
|
this.loadTabletPositionsMethod(this.currentSelectArea.areaId);
|
||||||
|
this.currentEditPosition = null
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
this.$message?.error?.('保存失敗') || alert('保存失敗');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async deletePositionMethod(position) {
|
||||||
|
if (confirm(`確定要刪除【${position.positionName}】嗎?`)) {
|
||||||
|
try {
|
||||||
|
await axios.delete(`${HTTP_HOST}api/ancestraltablet/position/delete/${position.positionId}`);
|
||||||
|
this.$message?.success?.('刪除成功'); // 如果用的是 Element Plus 或其他 UI 框架
|
||||||
|
this.loadTabletPositionsMethod(this.currentSelectArea.areaId); // 刷新數據
|
||||||
|
} catch (error) {
|
||||||
|
console.error('刪除失敗', error);
|
||||||
|
this.$message?.error?.('刪除失敗,請檢查網路或稍後再試');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//--------------------------------神主牌位置相關函數
|
||||||
|
async loadStatusList() {
|
||||||
|
//獲取狀態列表
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${HTTP_HOST}api/ancestraltablet/status/list`);
|
||||||
|
this.statusList = response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('獲取狀態列表失敗', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getAreaListMethod();
|
||||||
|
this.loadStatusList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.tree, .tree ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
.toggle-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
width: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
.region-item-label {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.region-item-label.selected {
|
||||||
|
background-color: #eaf4ff;
|
||||||
|
color: #0d6efd;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(10, 120px); /* 6列 */
|
||||||
|
grid-auto-rows: 100px; /* 行高 */
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
/* 可用(綠色) */
|
||||||
|
.status-available {
|
||||||
|
background-color: #d4edda;
|
||||||
|
border-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 維護中(黃色) */
|
||||||
|
.status-maintenance {
|
||||||
|
background-color: #fff3cd;
|
||||||
|
border-color: #ffc107;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 預訂中(藍色) */
|
||||||
|
.status-reserved {
|
||||||
|
background-color: #cce5ff;
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 已使用(灰色) */
|
||||||
|
.status-used {
|
||||||
|
background-color: #e2e3e5;
|
||||||
|
border-color: #6c757d;
|
||||||
|
}
|
||||||
|
.grid-item {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 1px 1px 3px rgba(0,0,0,0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-name {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</asp:Content>
|
||||||
14
web/admin/ancestraltablet/ancestraltabletarea/index.aspx.cs
Normal file
14
web/admin/ancestraltablet/ancestraltabletarea/index.aspx.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletarea_index : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
569
web/admin/ancestraltablet/ancestraltabletposition/index.aspx
Normal file
569
web/admin/ancestraltablet/ancestraltabletposition/index.aspx
Normal file
@@ -0,0 +1,569 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletposition_index" %>
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
<nav class="mb-2 ps-3">
|
||||||
|
<button class="btn btn-secondary me-2" @click="expandAll" type="button">
|
||||||
|
<i class="mdi mdi-arrow-expand-all"></i> 全部展開
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-secondary" @click="collapseAll" type="button">
|
||||||
|
<i class="mdi mdi-arrow-collapse-all"></i> 全部收起
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 col-lg-2">
|
||||||
|
<div class="card shadow-sm my-2">
|
||||||
|
<div class="card-header">神主牌區域列表</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<ul class="tree">
|
||||||
|
<li v-for="area in ancestral_tablet_areas" :key="area.AreaId">
|
||||||
|
<region-item
|
||||||
|
:item="area"
|
||||||
|
:selected-id="currentSelectAreaId"
|
||||||
|
@select-area="selectAreaMethod"
|
||||||
|
:expand-all="expandAllFlag"
|
||||||
|
:collapse-all="collapseAllFlag"
|
||||||
|
@clear-expand-all="expandAllFlag = false"
|
||||||
|
@clear-collapse-all="collapseAllFlag = false"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4 col-lg-10" v-if="currentSelectArea">
|
||||||
|
<div class="card shadow-sm my-2" style="position: sticky; top: 20px; display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;">
|
||||||
|
<div class="card-header" style="display: flex; justify-content: space-between; align-items: center;background-color: #ffc107;">
|
||||||
|
<div>
|
||||||
|
{{currentSelectArea.areaName + ' - ' + '神主牌位置'}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" style="flex: 1 1 auto; min-height: 0; overflow: auto;">
|
||||||
|
<div class="grid-container">
|
||||||
|
<div
|
||||||
|
v-for="pos in positions"
|
||||||
|
:key="pos.positionCode"
|
||||||
|
class="grid-item"
|
||||||
|
:class="'status-' + pos.statusCode"
|
||||||
|
:style="{ gridRow: pos.rowNo, gridColumn: pos.columnNo }"
|
||||||
|
>
|
||||||
|
<div class="position-name">{{ pos.positionName }}</div>
|
||||||
|
<div class="position-content">
|
||||||
|
<span v-if="pos.statusCode == 'maintenance'">維護中</span>
|
||||||
|
<v-btn v-else-if="!pos.ancestralTabletRegistrant" @click="showCreatePWMethod(pos)">登記</v-btn>
|
||||||
|
<!-- 已預訂 -->
|
||||||
|
<div v-else>
|
||||||
|
<div>登記人:{{ pos.ancestralTabletRegistrant?.name }}</div>
|
||||||
|
<div>登記日期:{{ pos.ancestralTabletRegistrant?.registerDate|timeString('YYYY/MM/DD') }}</div>
|
||||||
|
<v-btn small color="btn-primary" @click="showEditPWMethod(pos)">
|
||||||
|
詳細資訊
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
</>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已使用 -->
|
||||||
|
<div v-else-if="pos.statusCode === 'used'">
|
||||||
|
<div>已使用</div>
|
||||||
|
<div v-if="pos.usedBy">使用人:{{ pos.usedBy }}</div>
|
||||||
|
<div v-if="pos.usedDate">使用日期:{{ pos.usedDate|timeString('YYYY/MM/DD') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 登記資料彈出視窗 -->
|
||||||
|
<div>
|
||||||
|
<v-dialog v-model="showCreatePWFlag" max-width="800">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="headline">登記資料({{'位置: ' + selectedPos?.positionName}})</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<!-- 登記人資料 -->
|
||||||
|
<hr />
|
||||||
|
<h5>登記人資料</h5>
|
||||||
|
<label>姓名:
|
||||||
|
<input class="form-control" type="text" v-model="form.createRegister.name" />
|
||||||
|
</label><br />
|
||||||
|
<label>電話:
|
||||||
|
<input class="form-control" type="text" v-model="form.createRegister.phone" />
|
||||||
|
</label><br />
|
||||||
|
<label>住址:
|
||||||
|
<input class="form-control" type="text" v-model="form.createRegister.address" />
|
||||||
|
</label><br />
|
||||||
|
<label>費用:
|
||||||
|
<input class="form-control" v-model="form.createRegister.price" />
|
||||||
|
</label><br />
|
||||||
|
<label>登記時間:
|
||||||
|
<input class="form-control" type="date" v-model="form.createRegister.registerDate" />
|
||||||
|
</label><br />
|
||||||
|
<label>開始時間:
|
||||||
|
<input class="form-control" type="date" v-model="form.createRegister.startDate" />
|
||||||
|
</label><br />
|
||||||
|
<label>結束時間:
|
||||||
|
<input class="form-control" type="date" v-model="form.createRegister.endDate" />
|
||||||
|
</label><br />
|
||||||
|
<label>長期有效:
|
||||||
|
<input type="checkbox" v-model="form.createRegister.isLongTerm" />
|
||||||
|
</label><br />
|
||||||
|
<label>是否啟用:
|
||||||
|
<input type="checkbox" v-model="form.createRegister.isActive" />
|
||||||
|
</label><br />
|
||||||
|
<div class="mt-2 mb-4">
|
||||||
|
<button
|
||||||
|
v-if="!form.createRegister.registrantCode"
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
@click="saveRegistrantMethod">
|
||||||
|
保存登記人
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-else
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="button"
|
||||||
|
@click="updateRegistrantMethod">
|
||||||
|
送出修改
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 牌位資料 -->
|
||||||
|
<hr />
|
||||||
|
<h5>牌位資料</h5>
|
||||||
|
<label>牌位標題:
|
||||||
|
<input class="form-control" type="text" v-model="form.createPositionRecord.npTitle" />
|
||||||
|
</label><br />
|
||||||
|
<label>立牌時間:
|
||||||
|
<input class="form-control" type="date" v-model="form.createPositionRecord.npStandDate" />
|
||||||
|
</label><br />
|
||||||
|
<label>陽上:
|
||||||
|
<input class="form-control" type="text" v-model="form.createPositionRecord.npYangShang" />
|
||||||
|
</label><br />
|
||||||
|
<label>內牌內容:</label>
|
||||||
|
<textarea
|
||||||
|
class="form-control"
|
||||||
|
rows="4"
|
||||||
|
v-model="form.createPositionRecord.wpContent"
|
||||||
|
style="width: 100%; box-sizing: border-box;"
|
||||||
|
></textarea><br />
|
||||||
|
<div class="mt-2 mb-2">
|
||||||
|
<button v-if="form.createPositionRecord.recordId == null" class="btn btn-primary" type="button" @click="saveCreatePositionRecordMethod">保存牌位</button>
|
||||||
|
<button v-else type="button" class="btn btn-primary" @click="updateCreatePositionRecordMethod">
|
||||||
|
送出修改
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<button class="btn btn-secondary" type="button" @click="closePWDialogMethod">關閉</button>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
Vue.component('region-item', {
|
||||||
|
props: ['item', 'selectedId', 'expandAll', 'collapseAll'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expanded: false, // 預設全部收起
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expandAll(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.expanded = true;
|
||||||
|
// 執行完後發事件通知父組件清除標誌
|
||||||
|
this.$nextTick(() => this.$emit('clear-expand-all'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
collapseAll(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.expanded = false;
|
||||||
|
this.$nextTick(() => this.$emit('clear-collapse-all'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasChildren() {
|
||||||
|
return this.item.children && this.item.children.length > 0;
|
||||||
|
},
|
||||||
|
icon() {
|
||||||
|
// 無論有無子節點,皆可點擊展開/收起
|
||||||
|
return this.expanded ? '▼' : '▶';
|
||||||
|
},
|
||||||
|
isSelected() {
|
||||||
|
return this.item.areaId === this.selectedId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.expanded = !this.expanded;
|
||||||
|
},
|
||||||
|
select() {
|
||||||
|
this.$emit('select-area', this.item);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div>
|
||||||
|
<span class="toggle-icon" @click="toggle">{{ icon }}</span>
|
||||||
|
<span @click="select"
|
||||||
|
class="region-item-label"
|
||||||
|
:class="{ 'selected': isSelected }">
|
||||||
|
{{ item.areaName }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- 子區域列表 -->
|
||||||
|
<ul v-if="hasChildren && expanded">
|
||||||
|
<li v-for="child in item.children" :key="child.areaId">
|
||||||
|
<region-item
|
||||||
|
:item="child"
|
||||||
|
:selected-id="selectedId"
|
||||||
|
:expand-all="expandAll"
|
||||||
|
:collapse-all="collapseAll"
|
||||||
|
@select-area="$emit('select-area', $event)"
|
||||||
|
@clear-expand-all="$emit('clear-expand-all')"
|
||||||
|
@clear-collapse-all="$emit('clear-collapse-all')"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
});
|
||||||
|
Vue.filter('timeString', function (value, myFormat) {
|
||||||
|
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||||
|
});
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandAllFlag: false, // 控制全部展開
|
||||||
|
collapseAllFlag: false, // 控制全部收起
|
||||||
|
ancestral_tablet_areas: [], //神主牌區域列表
|
||||||
|
currentSelectArea: null,
|
||||||
|
currentSelectAreaId: null,
|
||||||
|
statusList: [],
|
||||||
|
//--------------------------------神主牌位置變數
|
||||||
|
positions: [],
|
||||||
|
selectedPos: null, //點擊登記的的pos
|
||||||
|
showCreatePWFlag: false, //控制是否打開登記神主牌位資料彈出視窗
|
||||||
|
form: {
|
||||||
|
createRegister: {
|
||||||
|
//新增登記人form
|
||||||
|
registrantCode: null, // 登記編號
|
||||||
|
positionId: null,
|
||||||
|
name: null,
|
||||||
|
phone: null,
|
||||||
|
address: null,
|
||||||
|
registerDate: null,
|
||||||
|
price: null,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
isLongTerm: false,
|
||||||
|
isActive: true,
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
createPositionRecord: {
|
||||||
|
//新增牌位登記form
|
||||||
|
recordId: null, // 自增主鍵,前端一般不用填
|
||||||
|
registrantCode: null, // 外鍵,關聯登記人編號
|
||||||
|
npTitle: null,
|
||||||
|
npStandDate: null,
|
||||||
|
npYangShang: null,
|
||||||
|
wpContent: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//--------------------------------神主牌位置變數
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectAreaMethod(area) {
|
||||||
|
this.currentSelectAreaId = area.areaId;
|
||||||
|
this.currentSelectArea = area;
|
||||||
|
this.loadTabletPositionsMethod(area.areaId);
|
||||||
|
},
|
||||||
|
getAreaListMethod() {
|
||||||
|
//獲取區域列表
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/area/getlist')
|
||||||
|
.then(res => {
|
||||||
|
this.ancestral_tablet_areas = res.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
expandAll() {
|
||||||
|
this.expandAllFlag = true;
|
||||||
|
this.collapseAllFlag = false;
|
||||||
|
},
|
||||||
|
collapseAll() {
|
||||||
|
this.collapseAllFlag = true;
|
||||||
|
this.expandAllFlag = false;
|
||||||
|
},
|
||||||
|
//--------------------------------神主牌位置相關函數
|
||||||
|
loadTabletPositionsMethod(areaId) {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/position/getlist', {
|
||||||
|
params: {
|
||||||
|
areaId: areaId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
this.positions = response.data;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('失敗:', error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showCreatePWMethod(pos) {
|
||||||
|
//打開新增彈出視窗
|
||||||
|
this.selectedPos = pos;
|
||||||
|
this.showCreatePWFlag = true;
|
||||||
|
this.form.createRegister.positionId = pos.positionId
|
||||||
|
this.form.createRegister.price = pos.price
|
||||||
|
},
|
||||||
|
showEditPWMethod(pos) {
|
||||||
|
//打開編輯彈出視窗
|
||||||
|
this.selectedPos = pos;
|
||||||
|
const registrant = pos.ancestralTabletRegistrant;
|
||||||
|
|
||||||
|
if (registrant) {
|
||||||
|
this.form.createRegister.registrantCode = registrant.registrantCode;
|
||||||
|
this.form.createRegister.positionId = pos.positionId;
|
||||||
|
this.form.createRegister.name = registrant.name;
|
||||||
|
this.form.createRegister.phone = registrant.phone;
|
||||||
|
this.form.createRegister.address = registrant.address;
|
||||||
|
this.form.createRegister.registerDate = registrant.registerDate
|
||||||
|
? registrant.registerDate?.split('T')[0]
|
||||||
|
: '';
|
||||||
|
this.form.createRegister.price = registrant.price;
|
||||||
|
this.form.createRegister.startDate = registrant.startDate ? registrant.startDate?.split('T')[0]
|
||||||
|
: '';
|
||||||
|
this.form.createRegister.endDate = registrant.endDate ? registrant.endDate?.split('T')[0]
|
||||||
|
: '';
|
||||||
|
this.form.createRegister.isLongTerm = registrant.isLongTerm;
|
||||||
|
this.form.createRegister.isActive = registrant.isActive;
|
||||||
|
this.form.createPositionRecord.registrantCode = registrant.registrantCode;
|
||||||
|
this.showCreatePWFlag = true;
|
||||||
|
if (registrant.tabletRecord) {
|
||||||
|
this.form.createPositionRecord.recordId = registrant.tabletRecord.recordId;
|
||||||
|
this.form.createPositionRecord.registrantCode = registrant.tabletRecord.registrantCode;
|
||||||
|
this.form.createPositionRecord.npTitle = registrant.tabletRecord.npTitle;
|
||||||
|
this.form.createPositionRecord.npStandDate = registrant.tabletRecord.npStandDate ? registrant.tabletRecord.npStandDate.split('T')[0]
|
||||||
|
: '';
|
||||||
|
this.form.createPositionRecord.npYangShang = registrant.tabletRecord.npYangShang;
|
||||||
|
this.form.createPositionRecord.wpContent = registrant.tabletRecord.wpContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closePWDialogMethod(pos) {
|
||||||
|
//關閉編輯彈出視窗
|
||||||
|
this.selectedPos = null;
|
||||||
|
|
||||||
|
// 重設登記人欄位
|
||||||
|
this.form.createRegister = {
|
||||||
|
registrantCode: null,
|
||||||
|
positionId: null,
|
||||||
|
name: null,
|
||||||
|
phone: null,
|
||||||
|
address: null,
|
||||||
|
registerDate: null,
|
||||||
|
price: null,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
isLongTerm: false,
|
||||||
|
isActive: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清空牌位記錄
|
||||||
|
this.form.createPositionRecord = {
|
||||||
|
recordId: null,
|
||||||
|
registrantCode: null,
|
||||||
|
npTitle: null,
|
||||||
|
npStandDate: null,
|
||||||
|
npYangShang: null,
|
||||||
|
wpContent: null
|
||||||
|
};
|
||||||
|
|
||||||
|
this.showCreatePWFlag = false;
|
||||||
|
},
|
||||||
|
//--------------------------------神主牌位置相關函數
|
||||||
|
//--------------------------------登記人相關函數 start
|
||||||
|
async saveRegistrantMethod() {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(HTTP_HOST + 'api/ancestraltablet/registrant/create', this.form.createRegister);
|
||||||
|
console.log('保存成功', response.data);
|
||||||
|
|
||||||
|
// 可選:提示用戶、關閉對話框、刷新數據等
|
||||||
|
this.$toast?.success('登記人保存成功'); // 取決於你是否使用 toast 插件
|
||||||
|
this.form.createRegister.registrantCode = response.data.registrantCode
|
||||||
|
this.form.createPositionRecord.registrantCode = response.data.registrantCode
|
||||||
|
this.loadTabletPositionsMethod(this.selectedPos.areaId)
|
||||||
|
alert("修改成功")
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存失敗', error);
|
||||||
|
this.$toast?.error('登記人保存失敗');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateRegistrantMethod() {
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/registrant/update', this.form.createRegister)
|
||||||
|
.then(response => {
|
||||||
|
console.log('登記人更新成功:', response.data);
|
||||||
|
this.$toast?.success?.('登記人更新成功'); // 可選:使用 toast 彈出提示
|
||||||
|
//this.showCreatePWFlag = false; // 關閉彈出視窗
|
||||||
|
// 可選:刷新列表等
|
||||||
|
this.loadTabletPositionsMethod(this.selectedPos.areaId)
|
||||||
|
alert("修改成功")
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('更新登記人失敗:', error);
|
||||||
|
this.$toast?.error?.('更新失敗,請檢查數據');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//--------------------------------登記人相關函數 end
|
||||||
|
|
||||||
|
//--------------------------------牌位資料相關函數 Start
|
||||||
|
saveCreatePositionRecordMethod() {
|
||||||
|
// 校驗必須欄位
|
||||||
|
if (!this.form.createPositionRecord.registrantCode) {
|
||||||
|
alert('請先填寫登記人資料並且送出保存!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/pw/create', this.form.createPositionRecord)
|
||||||
|
.then(res => {
|
||||||
|
if (res.data && res.data.message) {
|
||||||
|
alert(res.data.message);
|
||||||
|
} else {
|
||||||
|
alert('保存成功');
|
||||||
|
}
|
||||||
|
// 成功後可以關閉彈出視窗或清空表單
|
||||||
|
//this.showCreatePWFlag = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('保存失敗:', err);
|
||||||
|
alert('保存失敗,請檢查伺服器日誌');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateCreatePositionRecordMethod() {
|
||||||
|
// 校驗必須欄位
|
||||||
|
if (!this.form.createPositionRecord.recordId) {
|
||||||
|
alert('不存在牌位資料,無法更新');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/pw/update', this.form.createPositionRecord)
|
||||||
|
.then(res => {
|
||||||
|
if (res.data && res.data.message) {
|
||||||
|
alert(res.data.message);
|
||||||
|
} else {
|
||||||
|
alert('牌位資料更新成功');
|
||||||
|
}
|
||||||
|
// 成功後可以關閉彈出視窗或清空表單
|
||||||
|
//this.showCreatePWFlag = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
alert('更新失敗:', err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//--------------------------------牌位資料相關函數 end
|
||||||
|
async loadStatusList() {
|
||||||
|
//獲取狀態列表
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${HTTP_HOST}api/ancestraltablet/status/list`);
|
||||||
|
this.statusList = response.data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('獲取狀態列表失敗', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getAreaListMethod();
|
||||||
|
this.loadStatusList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.tree, .tree ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
.toggle-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
width: 1rem;
|
||||||
|
display: inline-block;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
.region-item-label {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.region-item-label.selected {
|
||||||
|
background-color: #eaf4ff;
|
||||||
|
color: #0d6efd;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(10, 150px); /* 6列 */
|
||||||
|
grid-auto-rows: 150px; /* 行高 */
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
/* 可用(綠色) */
|
||||||
|
.status-available {
|
||||||
|
background-color: #d4edda;
|
||||||
|
border-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 維護中(黃色) */
|
||||||
|
.status-maintenance {
|
||||||
|
background-color: #fff3cd;
|
||||||
|
border-color: #ffc107;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 已使用(灰色) */
|
||||||
|
.status-used {
|
||||||
|
background-color: #e2e3e5;
|
||||||
|
border-color: #6c757d;
|
||||||
|
}
|
||||||
|
.grid-item {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 1px 1px 3px rgba(0,0,0,0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-name {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</asp:Content>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletposition_index : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
126
web/admin/ancestraltablet/ancestraltabletstatistics/index.aspx
Normal file
126
web/admin/ancestraltablet/ancestraltabletstatistics/index.aspx
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletstatistics_index" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="title">區域牌位統計</h2>
|
||||||
|
<table class="stats-table" border="1" cellspacing="0" cellpadding="5">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>區域編號</th>
|
||||||
|
<th>區域名稱</th>
|
||||||
|
<th>總位置數</th>
|
||||||
|
<th>可用位置數</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="area in areas" :key="area.areaId">
|
||||||
|
<td>{{ area.areaId }}</td>
|
||||||
|
<td>{{ area.areaName }}</td>
|
||||||
|
<td>{{ area.totalPositions }}</td>
|
||||||
|
<td>{{ area.availableCount }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
areas: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getAncestralTabletPositionsStatisticsMethod() {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/statistics/positions/availablepositions')
|
||||||
|
.then((res) => {
|
||||||
|
this.areas = res.data
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getAncestralTabletPositionsStatisticsMethod()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 50px auto;
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 25px 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
||||||
|
font-family: "Microsoft YaHei", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-table th {
|
||||||
|
background-color: #1976d2;
|
||||||
|
color: #fff;
|
||||||
|
padding: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-table td {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 奇偶行區分 */
|
||||||
|
.stats-table tbody tr:nth-child(odd) {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滑鼠懸停高亮 */
|
||||||
|
.stats-table tbody tr:hover {
|
||||||
|
background-color: #e3f2fd;
|
||||||
|
transition: 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 響應式支持 */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.stats-table th, .stats-table td {
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</asp:Content>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletstatistics_index : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
15
web/admin/ancestraltablet/ancestraltabletuselist/create.aspx
Normal file
15
web/admin/ancestraltablet/ancestraltabletuselist/create.aspx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="create.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletuselist_create" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div>
|
||||||
|
這是新增頁面
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletuselist_create : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
99
web/admin/ancestraltablet/ancestraltabletuselist/detail.aspx
Normal file
99
web/admin/ancestraltablet/ancestraltabletuselist/detail.aspx
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="detail.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletuselist_detail" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
<nav>
|
||||||
|
<a :href="'edit.aspx?registrantCode=' + registrantCode" class="btn btn-primary">修改資料</a>
|
||||||
|
</nav>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div>
|
||||||
|
{{registrantCode}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="card">
|
||||||
|
<h2>登記人資訊</h2>
|
||||||
|
<p><strong>登記編碼:</strong> {{ registrant.registrantCode }}</p>
|
||||||
|
<p><strong>姓名:</strong> {{ registrant.name }}</p>
|
||||||
|
<p><strong>電話:</strong> {{ registrant.phone }}</p>
|
||||||
|
<p><strong>地址:</strong> {{ registrant.address }}</p>
|
||||||
|
<p><strong>登記日期:</strong> {{ formatDate(registrant.registerDate) }}</p>
|
||||||
|
<div style="border: 1px solid #007bff; background-color: #f0f8ff; padding: 10px 15px; border-radius: 5px; display: flex; flex-direction: column; gap: 5px; max-width: 400px; margin-bottom: 10px;">
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: bold; margin-right: 5px;">已選擇位置:</label>
|
||||||
|
<span>{{ registrant?.positionName || '未選擇' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p><strong>價格:</strong> {{ registrant.price }}</p>
|
||||||
|
<p><strong>開始日期:</strong> {{ formatDate(registrant.startDate) }}</p>
|
||||||
|
<p><strong>結束日期:</strong> {{ formatDate(registrant.endDate) }}</p>
|
||||||
|
<p><strong>是否長期:</strong> {{ registrant.isLongTerm ? '是' : '否' }}</p>
|
||||||
|
<p><strong>是否啟用:</strong> {{ registrant.isActive ? '是' : '否' }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" v-if="registrant.tabletRecord">
|
||||||
|
<h2>牌位資料</h2>
|
||||||
|
<p><strong>記錄ID:</strong> {{ registrant.tabletRecord.recordId }}</p>
|
||||||
|
<p><strong>登記編碼:</strong> {{ registrant.tabletRecord.registrantCode }}</p>
|
||||||
|
|
||||||
|
<p><strong>牌位標題:</strong> {{ registrant.tabletRecord.npTitle }}</p>
|
||||||
|
<p><strong>立牌日期:</strong> {{ formatDate(registrant.tabletRecord.npStandDate) }}</p>
|
||||||
|
<p><strong>陽上:</strong> {{ registrant.tabletRecord.npYangShang }}</p>
|
||||||
|
<p><strong>內牌內容:</strong> {{ registrant.tabletRecord.wpContent }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" v-else>
|
||||||
|
<h2>牌位資料</h2>
|
||||||
|
<p>暫無牌位資料</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
registrantCode: '<%=Request.QueryString["registrantCode"]%>',
|
||||||
|
registrant: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatDate(dateStr) {
|
||||||
|
if (!dateStr) return "";
|
||||||
|
const date = new Date(dateStr);
|
||||||
|
return date.toLocaleDateString();
|
||||||
|
},
|
||||||
|
getRegistrantByCodeMethod(code) {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/registrant/getbycode', {
|
||||||
|
params: {
|
||||||
|
registrantCode: code
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((res => {
|
||||||
|
this.registrant = res.data
|
||||||
|
}))
|
||||||
|
.catch((error => {
|
||||||
|
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.card {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</asp:Content>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletuselist_detail : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
419
web/admin/ancestraltablet/ancestraltabletuselist/edit.aspx
Normal file
419
web/admin/ancestraltablet/ancestraltabletuselist/edit.aspx
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="edit.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletuselist_edit" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
<nav>
|
||||||
|
<a :href="'detail.aspx?registrantCode=' + registrantCode" class="btn btn-secondary">返回詳情</a>
|
||||||
|
</nav>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
<div>
|
||||||
|
<!-- 登記人資料編輯區域 -->
|
||||||
|
<div class="card">
|
||||||
|
<h2>編輯登記人資訊</h2>
|
||||||
|
<label>登記編碼:</label>
|
||||||
|
<input type="text" v-model="registrant.registrantCode" class="form-control" disabled />
|
||||||
|
|
||||||
|
<label>姓名:</label>
|
||||||
|
<input type="text" v-model="registrant.name" class="form-control" />
|
||||||
|
|
||||||
|
<label>電話:</label>
|
||||||
|
<input type="text" v-model="registrant.phone" class="form-control" />
|
||||||
|
|
||||||
|
<label>地址:</label>
|
||||||
|
<input type="text" v-model="registrant.address" class="form-control" />
|
||||||
|
|
||||||
|
<label>登記日期:</label>
|
||||||
|
<input type="date" v-model="registrant.registerDate" class="form-control" />
|
||||||
|
<div class="mt-4" style="border: 1px solid #007bff; background-color: #f0f8ff; padding: 10px 15px; border-radius: 5px; display: flex; flex-direction: column; gap: 5px; max-width: 400px; margin-bottom: 10px;">
|
||||||
|
<div>
|
||||||
|
<label style="font-weight: bold; margin-right: 5px;">已選擇位置:</label>
|
||||||
|
<span>{{ registrant?.positionName || '未選擇' }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="newPositionId">
|
||||||
|
<label style="font-weight: bold; margin-right: 5px;">新選擇位置:</label>
|
||||||
|
<span>{{ this.newPositionEntity?.positionName }}</span>
|
||||||
|
</div>
|
||||||
|
<button type="button" @click="isShowPositionDialog=true"
|
||||||
|
style="align-self: flex-start; padding: 5px 10px; background-color: #007bff; color: #fff; border: none; border-radius: 3px; cursor: pointer;"
|
||||||
|
>
|
||||||
|
{{registrant?.positionId ? '更換位置' : '選擇位置'}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<label>價格:</label>
|
||||||
|
<input type="number" v-model="registrant.price" class="form-control" />
|
||||||
|
|
||||||
|
<label>開始日期:</label>
|
||||||
|
<input type="date" v-model="registrant.startDate" class="form-control" />
|
||||||
|
|
||||||
|
<label>結束日期:</label>
|
||||||
|
<input type="date" v-model="registrant.endDate" class="form-control" />
|
||||||
|
|
||||||
|
<div class="mt-3" style="display:flex; align-items:center; gap:15px; margin-bottom:10px; font-family:Arial, sans-serif;">
|
||||||
|
<label style="font-weight:500;">是否長期:</label>
|
||||||
|
<input type="checkbox" v-model="registrant.isLongTerm" style="width:16px; height:16px; cursor:pointer;" />
|
||||||
|
<span>是</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display:flex; align-items:center; gap:15px; margin-bottom:10px; font-family:Arial, sans-serif;">
|
||||||
|
<label style="font-weight:500;">是否啟用:</label>
|
||||||
|
<input type="checkbox" v-model="registrant.isActive" style="width:16px; height:16px; cursor:pointer;" />
|
||||||
|
<span>是</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-primary mt-2" @click="updateRegistrant">保存登記資料</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 牌位資料區域 -->
|
||||||
|
<div class="card" v-if="registrant.tabletRecord">
|
||||||
|
<h2>編輯牌位資料</h2>
|
||||||
|
<label>記錄ID:</label>
|
||||||
|
<input type="text" v-model="registrant.tabletRecord.recordId" class="form-control" disabled />
|
||||||
|
|
||||||
|
<label>登記編碼 (外鍵):</label>
|
||||||
|
<input type="text" v-model="registrant.tabletRecord.registrantCode" class="form-control" disabled />
|
||||||
|
|
||||||
|
|
||||||
|
<label>牌位標題:</label>
|
||||||
|
<input type="text" v-model="registrant.tabletRecord.npTitle" class="form-control" />
|
||||||
|
|
||||||
|
<label>立牌日期:</label>
|
||||||
|
<input type="date" v-model="registrant.tabletRecord.npStandDate" class="form-control" />
|
||||||
|
|
||||||
|
<label>陽上:</label>
|
||||||
|
<input type="text" v-model="registrant.tabletRecord.npYangShang" class="form-control" />
|
||||||
|
|
||||||
|
<label>內牌內容:</label>
|
||||||
|
<textarea v-model="registrant.tabletRecord.wpContent" class="form-control"></textarea>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-success mt-2" @click="updateTabletRecord">保存牌位資料</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card" v-else>
|
||||||
|
<h2>牌位資料</h2>
|
||||||
|
<p>暫無牌位資料</p>
|
||||||
|
<button type="button" class="btn btn-primary" @click="createTabletRecordForm">新增牌位資料</button>
|
||||||
|
|
||||||
|
<div v-if="creatingTablet" class="mt-3">
|
||||||
|
<label>牌位標題:</label>
|
||||||
|
<input type="text" v-model="newTablet.npTitle" class="form-control" />
|
||||||
|
|
||||||
|
<label>立牌日期:</label>
|
||||||
|
<input type="date" v-model="newTablet.npStandDate" class="form-control" />
|
||||||
|
|
||||||
|
<label>陽上:</label>
|
||||||
|
<input type="text" v-model="newTablet.npYangShang" class="form-control" />
|
||||||
|
|
||||||
|
<label>牌位內容:</label>
|
||||||
|
<textarea v-model="newTablet.wpContent" class="form-control"></textarea>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-success mt-2" @click="createTabletRecord">保存新增</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<v-dialog v-model="isShowPositionDialog" persistent
|
||||||
|
width="80%"
|
||||||
|
height="80%">
|
||||||
|
<v-card style="
|
||||||
|
width: 80vw;
|
||||||
|
height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
">
|
||||||
|
<v-card-title
|
||||||
|
style="display: flex; align-items: center; font-weight: 600; font-size: 18px;"
|
||||||
|
>
|
||||||
|
<span>選擇位置:</span>
|
||||||
|
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
style="
|
||||||
|
flex: 0 0 200px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
"
|
||||||
|
v-model="selectedArea"
|
||||||
|
@focus="e => e.target.style.borderColor = '#007bff'"
|
||||||
|
@blur="e => e.target.style.borderColor = '#ccc'"
|
||||||
|
@change="onAreaChange"
|
||||||
|
>
|
||||||
|
<option value="">請選擇區域</option>
|
||||||
|
<option v-for="area in areaList" :value="area.areaId" :key="area.areaId">{{area.areaName}}</option>
|
||||||
|
</select>
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text style="flex: 1; overflow: auto;">
|
||||||
|
<div class="grid-container">
|
||||||
|
<div
|
||||||
|
v-for="pos in positionList"
|
||||||
|
:key="pos.positionId"
|
||||||
|
class="grid-item"
|
||||||
|
:class="'status-' + (pos.isCanUse? 'canuse':'cannotuse')"
|
||||||
|
:style="{ gridRow: pos.rowNo, gridColumn: pos.columnNo }"
|
||||||
|
>
|
||||||
|
<div class="position-name">{{ pos.positionName }}</div>
|
||||||
|
<div class="position-content">
|
||||||
|
<button type="button" v-if="pos.isCanUse"
|
||||||
|
class="btn btn-primary"
|
||||||
|
@click="chooseNewPositionMethod(pos)"
|
||||||
|
>選擇</button>
|
||||||
|
<span v-else>已被使用</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<div class="me-5">新位置:{{newPositionEntity?.positionName}}</div>
|
||||||
|
<v-btn color="primary" @click="saveChoosePositionMethod">確定</v-btn>
|
||||||
|
<v-btn color="grey" @click="cancelChoosePositionMethod">取消</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
registrantCode: '<%=Request.QueryString["registrantCode"]%>',
|
||||||
|
registrant: {},
|
||||||
|
creatingTablet: false,
|
||||||
|
newPositionId: null,
|
||||||
|
newPositionEntity: null,
|
||||||
|
newTablet: {
|
||||||
|
//新增牌位登記form
|
||||||
|
recordId: null, // 自增主鍵,前端一般不用填
|
||||||
|
registrantCode: null, // 外鍵,關聯登記人編號
|
||||||
|
npTitle: null,
|
||||||
|
npStandDate: null,
|
||||||
|
npYangShang: null,
|
||||||
|
wpContent: null,
|
||||||
|
},
|
||||||
|
positionList: [],//選擇神位位置的時候獲取的位置列表
|
||||||
|
isShowPositionDialog: false,
|
||||||
|
selectedArea: "",
|
||||||
|
areaList: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatDate(dateStr) {
|
||||||
|
if (!dateStr) return "";
|
||||||
|
return dateStr.split('T')[0];
|
||||||
|
},
|
||||||
|
getRegistrantByCodeMethod(code) {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/registrant/getbycode', {
|
||||||
|
params: {
|
||||||
|
registrantCode: code
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((res => {
|
||||||
|
const data = res.data;
|
||||||
|
|
||||||
|
// 格式化登記日期欄位
|
||||||
|
if (data.registerDate) data.registerDate = this.formatDate(data.registerDate);
|
||||||
|
if (data.startDate) data.startDate = this.formatDate(data.startDate);
|
||||||
|
if (data.endDate) data.endDate = this.formatDate(data.endDate);
|
||||||
|
|
||||||
|
// 格式化牌位日期欄位
|
||||||
|
if (data.tabletRecord && data.tabletRecord.npStandDate)
|
||||||
|
data.tabletRecord.npStandDate = this.formatDate(data.tabletRecord.npStandDate);
|
||||||
|
|
||||||
|
this.registrant = data;
|
||||||
|
}))
|
||||||
|
.catch((error => {
|
||||||
|
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
// 更新登記資料
|
||||||
|
updateRegistrant() {
|
||||||
|
const newPositionId = this.newPositionId; // 假設 newPositionId 存在組件裡
|
||||||
|
|
||||||
|
// 如果 newPositionId 不為空,則更新 registrant.PositionId
|
||||||
|
if (newPositionId != null && newPositionId !== '') {
|
||||||
|
this.registrant.PositionId = newPositionId;
|
||||||
|
}
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/registrant/update', this.registrant)
|
||||||
|
.then(() => {
|
||||||
|
alert('登記資料已保存!')
|
||||||
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
||||||
|
this.newPositionId = null;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
alert('保存失敗!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新牌位資料
|
||||||
|
updateTabletRecord() {
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/pw/update', this.registrant.tabletRecord)
|
||||||
|
.then(() => alert('牌位資料已更新!'))
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
alert('保存失敗!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 顯示新增牌位表單
|
||||||
|
createTabletRecordForm() {
|
||||||
|
this.creatingTablet = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增牌位資料
|
||||||
|
createTabletRecord() {
|
||||||
|
const data = {
|
||||||
|
...this.newTablet,
|
||||||
|
registrantCode: this.registrant.registrantCode,
|
||||||
|
};
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/pw/create', data)
|
||||||
|
.then(() => {
|
||||||
|
alert('牌位資料已新增!');
|
||||||
|
this.creatingTablet = false;
|
||||||
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
alert('新增失敗!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getPositionList(areaId) {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/position/shortlist',
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
areaId: areaId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
this.positionList = res.data
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getArea() {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/area/getereawithposition')
|
||||||
|
.then((res) => {
|
||||||
|
this.areaList = res.data;
|
||||||
|
})
|
||||||
|
.catch();
|
||||||
|
},
|
||||||
|
onAreaChange() {
|
||||||
|
//獲取有神位的區域
|
||||||
|
if (!this.selectedArea) {
|
||||||
|
this.positionList = [];
|
||||||
|
return; // 如果沒有選擇,不請求
|
||||||
|
}
|
||||||
|
this.getPositionList(this.selectedArea)
|
||||||
|
|
||||||
|
},
|
||||||
|
chooseNewPositionMethod(newPos) {
|
||||||
|
this.newPositionEntity = newPos
|
||||||
|
},
|
||||||
|
closeChoosePositionDialogMethod() {
|
||||||
|
this.isShowPositionDialog = false;
|
||||||
|
this.selectedArea = "";
|
||||||
|
this.positionList = [];
|
||||||
|
},
|
||||||
|
cancelChoosePositionMethod() {
|
||||||
|
this.newPositionEntity = null;
|
||||||
|
this.closeChoosePositionDialogMethod()
|
||||||
|
},
|
||||||
|
saveChoosePositionMethod() {
|
||||||
|
this.newPositionId = this.newPositionEntity.positionId
|
||||||
|
this.closeChoosePositionDialogMethod()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getRegistrantByCodeMethod(this.registrantCode);
|
||||||
|
this.getArea()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.card {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 900px;
|
||||||
|
min-width: 300px; /* 最小寬度防止太窄 */
|
||||||
|
margin: 0 auto; /* 居中 */
|
||||||
|
}
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(10, 150px); /* 6列 */
|
||||||
|
grid-auto-rows: 150px; /* 行高 */
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.status-available {
|
||||||
|
background-color: #d4edda;
|
||||||
|
border-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 維護中(黃色) */
|
||||||
|
.status-maintenance {
|
||||||
|
background-color: #fff3cd;
|
||||||
|
border-color: #ffc107;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 已使用(灰色) */
|
||||||
|
.status-used {
|
||||||
|
background-color: #e2e3e5;
|
||||||
|
border-color: #6c757d;
|
||||||
|
}
|
||||||
|
/* 可以使用(綠色) */
|
||||||
|
.status-canuse {
|
||||||
|
background-color: #d4edda; /* 淺綠色背景 */
|
||||||
|
border-color: #28a745; /* 綠色邊框 */
|
||||||
|
color: #155724; /* 深綠色文字 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 不能使用(紅色) */
|
||||||
|
.status-cannotuse {
|
||||||
|
background-color: #f8d7da; /* 淺紅色背景 */
|
||||||
|
border-color: #dc3545; /* 紅色邊框 */
|
||||||
|
color: #721c24; /* 深紅文字 */
|
||||||
|
}
|
||||||
|
.grid-item {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 1px 1px 3px rgba(0,0,0,0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-name {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.position-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</asp:Content>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletuselist_edit : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
192
web/admin/ancestraltablet/ancestraltabletuselist/index.aspx
Normal file
192
web/admin/ancestraltablet/ancestraltabletuselist/index.aspx
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_ancestraltablet_ancestraltabletuselist_index" %>
|
||||||
|
|
||||||
|
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||||
|
<nav>
|
||||||
|
<!--
|
||||||
|
<a :href="'create.aspx'" class="btn btn-primary">
|
||||||
|
新增使用申請
|
||||||
|
</a>
|
||||||
|
-->
|
||||||
|
<div style="display: inline">
|
||||||
|
<span>
|
||||||
|
查詢條件 :
|
||||||
|
</span>
|
||||||
|
<input v-model="search.registrantUserName" class="form-control" style="display:inline-block; width: auto;"
|
||||||
|
placeholder="請輸入登記人"
|
||||||
|
/>
|
||||||
|
<button type="button" class="btn btn-primary" @click="handleSearch">搜尋</button>
|
||||||
|
<button type="button" class="btn btn-primary" @click="clearSearch">清除條件</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||||
|
神主牌使用記錄
|
||||||
|
<div>
|
||||||
|
<v-data-table
|
||||||
|
:items="registrantList"
|
||||||
|
:headers="headers"
|
||||||
|
hide-default-footer>
|
||||||
|
<template #item.registerdate="{item}">
|
||||||
|
{{item.registerDate |timeString('YYYY-MM-DD')}}
|
||||||
|
</template>
|
||||||
|
<template #item.startdate="{item}">
|
||||||
|
{{item.startDate |timeString('YYYY-MM-DD')}}
|
||||||
|
</template>
|
||||||
|
<template #item.enddate="{item}">
|
||||||
|
{{item.endDate |timeString('YYYY-MM-DD')}}
|
||||||
|
</template>
|
||||||
|
<template #item.createdat="{item}">
|
||||||
|
{{item.createdAt |timeString('YYYY-MM-DD HH:MM')}}
|
||||||
|
</template>
|
||||||
|
<template #item.islongterm="{item}">
|
||||||
|
{{item.isLongTerm ? "是": "否"}}
|
||||||
|
</template>
|
||||||
|
<template #item.isactive="{item}">
|
||||||
|
{{item.isActive ? "是" : "否"}}
|
||||||
|
</template>
|
||||||
|
<template #item.actions="{item}">
|
||||||
|
<a :href="'detail.aspx?registrantCode=' + item.registrantCode" class="btn btn-primary">詳細資訊</a>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
<v-container>
|
||||||
|
<v-row class="align-baseline" wrap="false">
|
||||||
|
<v-col cols="12" md="8">
|
||||||
|
<v-pagination
|
||||||
|
v-model="options.page"
|
||||||
|
:length="pageCount">
|
||||||
|
</v-pagination>
|
||||||
|
</v-col>
|
||||||
|
<v-col class="text-truncate text-right" cols="12" md="2">
|
||||||
|
共 {{ total }} 筆, 頁數:
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6" md="1">
|
||||||
|
<v-text-field
|
||||||
|
v-model="options.page"
|
||||||
|
type="number"
|
||||||
|
hide-details
|
||||||
|
dense
|
||||||
|
min="1"
|
||||||
|
:max="pageCount"
|
||||||
|
@input="options.page = parseInt($event, 10)"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
<!-- 每頁條數選擇 -->
|
||||||
|
<v-col cols="12" md="1">
|
||||||
|
<v-select
|
||||||
|
v-model="options.itemsPerPage"
|
||||||
|
:items="[5, 10, 20, 50]"
|
||||||
|
label="每頁條數"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
style="width: 100px;"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</div>
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||||
|
</asp:Content>
|
||||||
|
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||||
|
<script>
|
||||||
|
Vue.filter('timeString', function (value, myFormat) {
|
||||||
|
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||||
|
});
|
||||||
|
new Vue({
|
||||||
|
el: "#app",
|
||||||
|
vuetify: new Vuetify(vuetify_options),
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
registrantList: [],
|
||||||
|
headers: [
|
||||||
|
{ text: '登記編號', value: 'registrantCode' },
|
||||||
|
{ text: '姓名', value: 'name' },
|
||||||
|
{ text: '電話', value: 'phone' },
|
||||||
|
{ text: '住址', value: 'address' },
|
||||||
|
{ text: '登記日期', value: 'registerdate' },
|
||||||
|
{ text: '費用', value: 'price' },
|
||||||
|
{ text: '牌位編號', value: 'positionId' },
|
||||||
|
{ text: '開始時間', value: 'startdate' },
|
||||||
|
{ text: '結束時間', value: 'enddate' },
|
||||||
|
{ text: '是否長期', value: 'islongterm' },
|
||||||
|
{ text: '是否有效', value: 'isactive' },
|
||||||
|
{ text: '創建時間', value: 'createdat' },
|
||||||
|
{ text: '', value: 'actions' },
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
page: 1, // 當前頁
|
||||||
|
itemsPerPage: 10, // 每頁條數
|
||||||
|
sortBy: [],
|
||||||
|
sortDesc: []
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
registrantUserName: null,
|
||||||
|
},
|
||||||
|
total: 0,
|
||||||
|
loading: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getRegistrantListMethod() {
|
||||||
|
axios.get(HTTP_HOST + 'api/ancestraltablet/registrant/getlist')
|
||||||
|
.then((res) => {
|
||||||
|
this.registrantList = res.data;
|
||||||
|
}).catch((error) => {
|
||||||
|
alert("載入失敗")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getRegistrantListByPageMethod() {
|
||||||
|
if (this.loading) return;
|
||||||
|
this.loading = true;
|
||||||
|
axios.post(HTTP_HOST + 'api/ancestraltablet/registrant/getlistbypage', {
|
||||||
|
page: this.options.page,
|
||||||
|
pageSize: this.options.itemsPerPage,
|
||||||
|
searchName: this.search.registrantUserName
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
this.registrantList = res.data.data;
|
||||||
|
this.total = res.data.total;
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetTableOptions() {
|
||||||
|
this.options = {
|
||||||
|
page: 1,
|
||||||
|
itemsPerPage: 10,
|
||||||
|
sortBy: [],
|
||||||
|
sortDesc: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
clearSearch() {
|
||||||
|
this.search.registrantUserName = null;
|
||||||
|
this.resetTableOptions();
|
||||||
|
},
|
||||||
|
handleSearch() {
|
||||||
|
this.resetTableOptions();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
options: {
|
||||||
|
handler() {
|
||||||
|
this.getRegistrantListByPageMethod();
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getRegistrantListByPageMethod()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pageCount() {
|
||||||
|
return Math.ceil(this.total / this.options.itemsPerPage)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</asp:Content>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.UI;
|
||||||
|
using System.Web.UI.WebControls;
|
||||||
|
|
||||||
|
public partial class admin_ancestraltablet_ancestraltabletuselist_index : MyWeb.config
|
||||||
|
{
|
||||||
|
protected void Page_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ public partial class admin_bed_kind_reg : MyWeb.config
|
|||||||
{
|
{
|
||||||
_this_id = ValString(Request["num"]);
|
_this_id = ValString(Request["num"]);
|
||||||
int _num = Val(Request["num"]);
|
int _num = Val(Request["num"]);
|
||||||
var prod = _db.bed_kind.AsEnumerable().Where(q => q.num == _num).FirstOrDefault();
|
var prod = _db.bed_kind.Where(q => q.num == _num).FirstOrDefault();
|
||||||
|
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
@@ -250,7 +250,7 @@ public partial class admin_bed_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var prod = _db.bed_kind.AsEnumerable().Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
var prod = _db.bed_kind.Where(q => q.root == root).OrderByDescending(q => q.range).FirstOrDefault();
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
if (prod.range.HasValue)
|
if (prod.range.HasValue)
|
||||||
range = prod.range.Value + 1;
|
range = prod.range.Value + 1;
|
||||||
@@ -293,7 +293,7 @@ public partial class admin_bed_kind_reg : MyWeb.config
|
|||||||
{
|
{
|
||||||
int num = Val(Request["num"]);
|
int num = Val(Request["num"]);
|
||||||
del_product(num);
|
del_product(num);
|
||||||
var prod = _db.bed_kind.AsEnumerable().Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
var prod = _db.bed_kind.Where(q => q.num == num).FirstOrDefault(); //刪除該筆資料
|
||||||
if (prod != null)
|
if (prod != null)
|
||||||
{
|
{
|
||||||
_db.bed_kind.Remove(prod);
|
_db.bed_kind.Remove(prod);
|
||||||
@@ -310,7 +310,7 @@ public partial class admin_bed_kind_reg : MyWeb.config
|
|||||||
|
|
||||||
public void Del_Ohter_Items(int d_num)
|
public void Del_Ohter_Items(int d_num)
|
||||||
{
|
{
|
||||||
var prod = _db.bed_kind.AsEnumerable().Where(q => q.root == d_num).ToList();
|
var prod = _db.bed_kind.Where(q => q.root == d_num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var row in prod)
|
foreach (var row in prod)
|
||||||
@@ -327,14 +327,14 @@ public partial class admin_bed_kind_reg : MyWeb.config
|
|||||||
public void del_product(int num)
|
public void del_product(int num)
|
||||||
{
|
{
|
||||||
//床位資料
|
//床位資料
|
||||||
var prod = _db.bed_kind_detail.AsEnumerable().Where(q => q.bed_kind_id == num).ToList();
|
var prod = _db.bed_kind_detail.Where(q => q.bed_kind_id == num).ToList();
|
||||||
if (prod.Count > 0)
|
if (prod.Count > 0)
|
||||||
{
|
{
|
||||||
//清空分類
|
//清空分類
|
||||||
foreach (var item in prod)
|
foreach (var item in prod)
|
||||||
{
|
{
|
||||||
//掛單資料
|
//掛單資料
|
||||||
var prod2 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_kind_detail_id == item.num).ToList();
|
var prod2 = _db.bed_order_detail.Where(q => q.bed_kind_detail_id == item.num).ToList();
|
||||||
if (prod2.Count > 0)
|
if (prod2.Count > 0)
|
||||||
{
|
{
|
||||||
//清空分類
|
//清空分類
|
||||||
@@ -349,7 +349,7 @@ public partial class admin_bed_kind_reg : MyWeb.config
|
|||||||
}
|
}
|
||||||
|
|
||||||
//掛單資料
|
//掛單資料
|
||||||
var prod3 = _db.bed_order_detail.AsEnumerable().Where(q => q.bed_kind1 == num || q.bed_kind2 == num).ToList();
|
var prod3 = _db.bed_order_detail.Where(q => q.bed_kind1 == num || q.bed_kind2 == num).ToList();
|
||||||
if (prod3.Count > 0)
|
if (prod3.Count > 0)
|
||||||
{
|
{
|
||||||
//清空分類
|
//清空分類
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public partial class admin_follower_index : MyWeb.config
|
|||||||
//國籍
|
//國籍
|
||||||
s_country.Items.Clear();
|
s_country.Items.Clear();
|
||||||
s_country.Items.Add(new ListItem("請選擇", ""));
|
s_country.Items.Add(new ListItem("請選擇", ""));
|
||||||
var qry =_db.countries.AsEnumerable().OrderBy(x => x.range).ThenBy(x => x.name_en).ToList();
|
var qry =_db.countries.OrderBy(x => x.range).ThenBy(x => x.name_en).ToList();
|
||||||
if (qry.Count > 0)
|
if (qry.Count > 0)
|
||||||
{
|
{
|
||||||
foreach(var x in qry)
|
foreach(var x in qry)
|
||||||
@@ -222,7 +222,7 @@ public partial class admin_follower_index : MyWeb.config
|
|||||||
{
|
{
|
||||||
|
|
||||||
//查詢要匯出的資料
|
//查詢要匯出的資料
|
||||||
var qry = _db.followers.AsEnumerable();
|
var qry = _db.followers.AsQueryable();
|
||||||
|
|
||||||
//紀錄匯出條件
|
//紀錄匯出條件
|
||||||
if (!isStrNull(s_f_number.Value))
|
if (!isStrNull(s_f_number.Value))
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
|||||||
|
|
||||||
//紀錄匯出條件
|
//紀錄匯出條件
|
||||||
string _query = "";
|
string _query = "";
|
||||||
var qry = _db.followers.AsEnumerable();
|
var qry = _db.followers.AsQueryable();
|
||||||
if (!string.IsNullOrEmpty(Request["f_number"]))
|
if (!string.IsNullOrEmpty(Request["f_number"]))
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.f_number.Contains(Request["f_number"].Trim()));
|
qry = qry.Where(o => o.f_number.Contains(Request["f_number"].Trim()));
|
||||||
@@ -57,7 +57,7 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
|||||||
if (!string.IsNullOrEmpty(Request["country"]))
|
if (!string.IsNullOrEmpty(Request["country"]))
|
||||||
{
|
{
|
||||||
qry = qry.Where(o => o.country == Request["country"]);
|
qry = qry.Where(o => o.country == Request["country"]);
|
||||||
_query += "國家:" + (_db.countries.AsEnumerable().Where(x => x.ID == Request["country"].ToString()).Select(x => x.name_zh).FirstOrDefault()??"" )+ "\n";
|
_query += "國家:" + (_db.countries.Where(x => x.ID == Request["country"].ToString()).Select(x => x.name_zh).FirstOrDefault()??"" )+ "\n";
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(Request["country2"]))
|
if (!string.IsNullOrEmpty(Request["country2"]))
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,7 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
|||||||
qry = qry.Where(o => o.country != "158");
|
qry = qry.Where(o => o.country != "158");
|
||||||
|
|
||||||
}
|
}
|
||||||
_query += "國家:" + (_db.countries.AsEnumerable().Where(x => x.ID == Request["country2"].ToString()).Select(x => x.name_zh).FirstOrDefault()??"") + "\n";
|
_query += "國家:" + (_db.countries.Where(x => x.ID == Request["country2"].ToString()).Select(x => x.name_zh).FirstOrDefault()??"") + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//管理報表
|
//管理報表
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ public partial class admin_follower_reg : MyWeb.config
|
|||||||
|
|
||||||
if (prod.birthday.HasValue)
|
if (prod.birthday.HasValue)
|
||||||
{
|
{
|
||||||
Literal1.Text = publicFun.chagenDate(prod.birthday.Value);
|
Literal1.Text = publicFun.chagenDate(prod.birthday.Value); //農曆生日
|
||||||
Literal2.Text = Model.follower.chagenSign(prod.birthday.Value);
|
Literal2.Text = Model.follower.chagenSign(prod.birthday.Value); //生肖
|
||||||
}
|
}
|
||||||
if (prod.leader.HasValue)
|
if (prod.leader.HasValue)
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user