2 Commits

Author SHA1 Message Date
a6aa35176c Merge branch 'main' of https://git.17888.com.tw/yiming/17168ERP 2025-10-19 22:00:45 +08:00
7d57e292fe update doc 2025-10-13 00:04:59 +08:00
42 changed files with 854 additions and 4509 deletions

26
data/memo/report-view.md Normal file
View 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
View 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
View 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
```

View File

@@ -1,11 +0,0 @@
資料字典:
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權限添加到相應的管理員帳號

View File

@@ -89,11 +89,6 @@ 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)
{ {

View File

@@ -523,139 +523,6 @@ 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")]
@@ -990,12 +857,6 @@ 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; }
@@ -1013,8 +874,6 @@ namespace Model
public virtual admin admin { get; set; } public virtual admin admin { get; set; }
public virtual follower followers { 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
@@ -1039,7 +898,6 @@ namespace Model
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 string StatusCode { get; set; } public string StatusCode { get; set; }
public Nullable<System.Guid> OrderUuid { get; set; }
public virtual follower followers { get; set; } public virtual follower followers { get; set; }
public virtual RegionRoomBed RegionRoomBed { get; set; } public virtual RegionRoomBed RegionRoomBed { get; set; }
@@ -1047,7 +905,6 @@ namespace Model
public virtual RegionRoomBedStatus RegionRoomBedStatus { get; set; } public virtual RegionRoomBedStatus RegionRoomBedStatus { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<RegionAndRoomAndBedSchedule> RegionAndRoomAndBedSchedule { get; set; } public virtual ICollection<RegionAndRoomAndBedSchedule> RegionAndRoomAndBedSchedule { get; set; }
public virtual GuaDanOrder GuaDanOrder { get; set; }
} }
} }
namespace Model namespace Model

View File

@@ -254,74 +254,6 @@
<Property Name="word" Type="nvarchar(max)" /> <Property Name="word" Type="nvarchar(max)" />
<Property Name="systems" Type="int" /> <Property Name="systems" Type="int" />
</EntityType> </EntityType>
<EntityType Name="AncestralTabletArea">
<Key>
<PropertyRef Name="AreaId" />
</Key>
<Property Name="AreaId" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="AreaName" Type="nvarchar" MaxLength="10" Nullable="false" />
<Property Name="AreaCode" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="ParentAreaId" Type="int" />
<Property Name="AreaType" Type="nvarchar" MaxLength="10" />
<Property Name="Price" Type="int" />
<Property Name="SortOrder" Type="int" />
<Property Name="IsDisabled" Type="bit" Nullable="false" />
<Property Name="Description" Type="nvarchar" MaxLength="200" />
</EntityType>
<EntityType Name="AncestralTabletPosition">
<Key>
<PropertyRef Name="PositionId" />
</Key>
<Property Name="PositionId" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="AreaId" Type="int" Nullable="false" />
<Property Name="PositionCode" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="PositionName" Type="nvarchar" MaxLength="50" />
<Property Name="Price" Type="int" />
<Property Name="StatusCode" Type="nvarchar" MaxLength="20" />
<Property Name="Description" Type="nvarchar" MaxLength="200" />
<Property Name="RowNo" Type="int" />
<Property Name="ColumnNo" Type="int" />
</EntityType>
<EntityType Name="AncestralTabletPositionRecord">
<Key>
<PropertyRef Name="RecordId" />
</Key>
<Property Name="RecordId" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="RegistrantCode" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="NPTitle" Type="nvarchar" MaxLength="30" />
<Property Name="NPStandDate" Type="date" Nullable="false" />
<Property Name="NPYangShang" Type="nvarchar" MaxLength="20" />
<Property Name="WPContent" Type="nvarchar" MaxLength="1000" />
<Property Name="CreatedAt" Type="datetime" Nullable="false" />
<Property Name="UpdatedAt" Type="datetime" />
</EntityType>
<EntityType Name="AncestralTabletRegistrant">
<Key>
<PropertyRef Name="RegistrantCode" />
</Key>
<Property Name="RegistrantCode" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="Name" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="Phone" Type="nvarchar" MaxLength="50" />
<Property Name="Address" Type="nvarchar" MaxLength="60" />
<Property Name="RegisterDate" Type="date" Nullable="false" />
<Property Name="Price" Type="int" />
<Property Name="PositionId" Type="int" />
<Property Name="StartDate" Type="date" Nullable="false" />
<Property Name="EndDate" Type="date" />
<Property Name="IsLongTerm" Type="bit" Nullable="false" />
<Property Name="IsActive" Type="bit" Nullable="false" />
<Property Name="CreatedAt" Type="datetime" Nullable="false" />
<Property Name="UpdatedAt" Type="datetime" />
<Property Name="IsEnd" Type="bit" Nullable="false" />
</EntityType>
<EntityType Name="AncestralTabletStatus">
<Key>
<PropertyRef Name="StatusCode" />
</Key>
<Property Name="StatusCode" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="StatusName" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="StatusType" Type="nvarchar" MaxLength="20" Nullable="false" />
</EntityType>
<EntityType Name="appellation"> <EntityType Name="appellation">
<Key> <Key>
<PropertyRef Name="num" /> <PropertyRef Name="num" />
@@ -522,7 +454,6 @@
<Property Name="CheckInAt" Type="date" /> <Property Name="CheckInAt" Type="date" />
<Property Name="CheckOutAt" Type="date" /> <Property Name="CheckOutAt" Type="date" />
<Property Name="StatusCode" Type="nvarchar" MaxLength="20" Nullable="false" /> <Property Name="StatusCode" Type="nvarchar" MaxLength="20" Nullable="false" />
<Property Name="OrderUuid" Type="uniqueidentifier" />
</EntityType> </EntityType>
<EntityType Name="GuadanTimeSetting"> <EntityType Name="GuadanTimeSetting">
<Key> <Key>
@@ -979,18 +910,6 @@
<Property Name="balance_act_item" Type="int" /> <Property Name="balance_act_item" Type="int" />
<Property Name="balance_pro_order_detail" Type="int" /> <Property Name="balance_pro_order_detail" Type="int" />
</EntityType> </EntityType>
<Association Name="FK__Ancestral__Regis__5A1A5A11">
<End Role="AncestralTabletRegistrant" Type="Self.AncestralTabletRegistrant" Multiplicity="1" />
<End Role="AncestralTabletPositionRecord" Type="Self.AncestralTabletPositionRecord" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletRegistrant">
<PropertyRef Name="RegistrantCode" />
</Principal>
<Dependent Role="AncestralTabletPositionRecord">
<PropertyRef Name="RegistrantCode" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_accounting_accounting_kind"> <Association Name="FK_accounting_accounting_kind">
<End Role="accounting_kind" Type="Self.accounting_kind" Multiplicity="0..1" /> <End Role="accounting_kind" Type="Self.accounting_kind" Multiplicity="0..1" />
<End Role="accounting" Type="Self.accounting" Multiplicity="*" /> <End Role="accounting" Type="Self.accounting" Multiplicity="*" />
@@ -1259,18 +1178,6 @@
</Dependent> </Dependent>
</ReferentialConstraint> </ReferentialConstraint>
</Association> </Association>
<Association Name="FK_AncestralTabletArea_Parent">
<End Role="AncestralTabletArea" Type="Self.AncestralTabletArea" Multiplicity="0..1" />
<End Role="AncestralTabletArea1" Type="Self.AncestralTabletArea" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletArea">
<PropertyRef Name="AreaId" />
</Principal>
<Dependent Role="AncestralTabletArea1">
<PropertyRef Name="ParentAreaId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_bed_kind_detail_bed_kind"> <Association Name="FK_bed_kind_detail_bed_kind">
<End Role="bed_kind" Type="Self.bed_kind" Multiplicity="0..1" /> <End Role="bed_kind" Type="Self.bed_kind" Multiplicity="0..1" />
<End Role="bed_kind_detail" Type="Self.bed_kind_detail" Multiplicity="*" /> <End Role="bed_kind_detail" Type="Self.bed_kind_detail" Multiplicity="*" />
@@ -1465,18 +1372,6 @@
</Dependent> </Dependent>
</ReferentialConstraint> </ReferentialConstraint>
</Association> </Association>
<Association Name="FK_GuaDanOrderGuest_Order">
<End Role="GuaDanOrder" Type="Self.GuaDanOrder" Multiplicity="0..1" />
<End Role="GuaDanOrderGuest" Type="Self.GuaDanOrderGuest" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="GuaDanOrder">
<PropertyRef Name="Uuid" />
</Principal>
<Dependent Role="GuaDanOrderGuest">
<PropertyRef Name="OrderUuid" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_GuaDanOrderGuest_RoomUuid"> <Association Name="FK_GuaDanOrderGuest_RoomUuid">
<End Role="Room" Type="Self.Room" Multiplicity="0..1" /> <End Role="Room" Type="Self.Room" Multiplicity="0..1" />
<End Role="GuaDanOrderGuest" Type="Self.GuaDanOrderGuest" Multiplicity="*" /> <End Role="GuaDanOrderGuest" Type="Self.GuaDanOrderGuest" Multiplicity="*" />
@@ -1611,30 +1506,6 @@
</Dependent> </Dependent>
</ReferentialConstraint> </ReferentialConstraint>
</Association> </Association>
<Association Name="FK_Position_Area">
<End Role="AncestralTabletArea" Type="Self.AncestralTabletArea" Multiplicity="1" />
<End Role="AncestralTabletPosition" Type="Self.AncestralTabletPosition" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletArea">
<PropertyRef Name="AreaId" />
</Principal>
<Dependent Role="AncestralTabletPosition">
<PropertyRef Name="AreaId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Position_Status">
<End Role="AncestralTabletStatus" Type="Self.AncestralTabletStatus" Multiplicity="0..1" />
<End Role="AncestralTabletPosition" Type="Self.AncestralTabletPosition" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletStatus">
<PropertyRef Name="StatusCode" />
</Principal>
<Dependent Role="AncestralTabletPosition">
<PropertyRef Name="StatusCode" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_pro_order_activity"> <Association Name="FK_pro_order_activity">
<End Role="activity" Type="Self.activity" Multiplicity="0..1" /> <End Role="activity" Type="Self.activity" Multiplicity="0..1" />
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" /> <End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
@@ -1847,18 +1718,6 @@
</Dependent> </Dependent>
</ReferentialConstraint> </ReferentialConstraint>
</Association> </Association>
<Association Name="FK_Registrant_Position">
<End Role="AncestralTabletPosition" Type="Self.AncestralTabletPosition" Multiplicity="0..1" />
<End Role="AncestralTabletRegistrant" Type="Self.AncestralTabletRegistrant" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletPosition">
<PropertyRef Name="PositionId" />
</Principal>
<Dependent Role="AncestralTabletRegistrant">
<PropertyRef Name="PositionId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Room_Region"> <Association Name="FK_Room_Region">
<End Role="Region" Type="Self.Region" Multiplicity="1" /> <End Role="Region" Type="Self.Region" Multiplicity="1" />
<End Role="Room" Type="Self.Room" Multiplicity="*" /> <End Role="Room" Type="Self.Room" Multiplicity="*" />
@@ -2107,11 +1966,6 @@
<EntitySet Name="admin" EntityType="Self.admin" Schema="dbo" store:Type="Tables" /> <EntitySet Name="admin" EntityType="Self.admin" Schema="dbo" store:Type="Tables" />
<EntitySet Name="admin_group" EntityType="Self.admin_group" Schema="dbo" store:Type="Tables" /> <EntitySet Name="admin_group" EntityType="Self.admin_group" Schema="dbo" store:Type="Tables" />
<EntitySet Name="admin_log" EntityType="Self.admin_log" Schema="dbo" store:Type="Tables" /> <EntitySet Name="admin_log" EntityType="Self.admin_log" Schema="dbo" store:Type="Tables" />
<EntitySet Name="AncestralTabletArea" EntityType="Self.AncestralTabletArea" Schema="dbo" store:Type="Tables" />
<EntitySet Name="AncestralTabletPosition" EntityType="Self.AncestralTabletPosition" Schema="dbo" store:Type="Tables" />
<EntitySet Name="AncestralTabletPositionRecord" EntityType="Self.AncestralTabletPositionRecord" Schema="dbo" store:Type="Tables" />
<EntitySet Name="AncestralTabletRegistrant" EntityType="Self.AncestralTabletRegistrant" Schema="dbo" store:Type="Tables" />
<EntitySet Name="AncestralTabletStatus" EntityType="Self.AncestralTabletStatus" Schema="dbo" store:Type="Tables" />
<EntitySet Name="appellation" EntityType="Self.appellation" Schema="dbo" store:Type="Tables" /> <EntitySet Name="appellation" EntityType="Self.appellation" Schema="dbo" store:Type="Tables" />
<EntitySet Name="bed_kind" EntityType="Self.bed_kind" Schema="dbo" store:Type="Tables" /> <EntitySet Name="bed_kind" EntityType="Self.bed_kind" Schema="dbo" store:Type="Tables" />
<EntitySet Name="bed_kind_detail" EntityType="Self.bed_kind_detail" Schema="dbo" store:Type="Tables" /> <EntitySet Name="bed_kind_detail" EntityType="Self.bed_kind_detail" Schema="dbo" store:Type="Tables" />
@@ -2156,10 +2010,6 @@
<EntitySet Name="supplier" EntityType="Self.supplier" Schema="dbo" store:Type="Tables" /> <EntitySet Name="supplier" EntityType="Self.supplier" Schema="dbo" store:Type="Tables" />
<EntitySet Name="supplier_kind" EntityType="Self.supplier_kind" Schema="dbo" store:Type="Tables" /> <EntitySet Name="supplier_kind" EntityType="Self.supplier_kind" Schema="dbo" store:Type="Tables" />
<EntitySet Name="transfer_register" EntityType="Self.transfer_register" Schema="dbo" store:Type="Tables" /> <EntitySet Name="transfer_register" EntityType="Self.transfer_register" Schema="dbo" store:Type="Tables" />
<AssociationSet Name="FK__Ancestral__Regis__5A1A5A11" Association="Self.FK__Ancestral__Regis__5A1A5A11">
<End Role="AncestralTabletRegistrant" EntitySet="AncestralTabletRegistrant" />
<End Role="AncestralTabletPositionRecord" EntitySet="AncestralTabletPositionRecord" />
</AssociationSet>
<AssociationSet Name="FK_accounting_accounting_kind" Association="Self.FK_accounting_accounting_kind"> <AssociationSet Name="FK_accounting_accounting_kind" Association="Self.FK_accounting_accounting_kind">
<End Role="accounting_kind" EntitySet="accounting_kind" /> <End Role="accounting_kind" EntitySet="accounting_kind" />
<End Role="accounting" EntitySet="accounting" /> <End Role="accounting" EntitySet="accounting" />
@@ -2244,10 +2094,6 @@
<End Role="admin_group" EntitySet="admin_group" /> <End Role="admin_group" EntitySet="admin_group" />
<End Role="admin" EntitySet="admin" /> <End Role="admin" EntitySet="admin" />
</AssociationSet> </AssociationSet>
<AssociationSet Name="FK_AncestralTabletArea_Parent" Association="Self.FK_AncestralTabletArea_Parent">
<End Role="AncestralTabletArea" EntitySet="AncestralTabletArea" />
<End Role="AncestralTabletArea1" EntitySet="AncestralTabletArea" />
</AssociationSet>
<AssociationSet Name="FK_bed_kind_detail_bed_kind" Association="Self.FK_bed_kind_detail_bed_kind"> <AssociationSet Name="FK_bed_kind_detail_bed_kind" Association="Self.FK_bed_kind_detail_bed_kind">
<End Role="bed_kind" EntitySet="bed_kind" /> <End Role="bed_kind" EntitySet="bed_kind" />
<End Role="bed_kind_detail" EntitySet="bed_kind_detail" /> <End Role="bed_kind_detail" EntitySet="bed_kind_detail" />
@@ -2312,10 +2158,6 @@
<End Role="followers" EntitySet="followers" /> <End Role="followers" EntitySet="followers" />
<End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" /> <End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" />
</AssociationSet> </AssociationSet>
<AssociationSet Name="FK_GuaDanOrderGuest_Order" Association="Self.FK_GuaDanOrderGuest_Order">
<End Role="GuaDanOrder" EntitySet="GuaDanOrder" />
<End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" />
</AssociationSet>
<AssociationSet Name="FK_GuaDanOrderGuest_RoomUuid" Association="Self.FK_GuaDanOrderGuest_RoomUuid"> <AssociationSet Name="FK_GuaDanOrderGuest_RoomUuid" Association="Self.FK_GuaDanOrderGuest_RoomUuid">
<End Role="Room" EntitySet="Room" /> <End Role="Room" EntitySet="Room" />
<End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" /> <End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" />
@@ -2360,14 +2202,6 @@
<End Role="news_kind" EntitySet="news_kind" /> <End Role="news_kind" EntitySet="news_kind" />
<End Role="news" EntitySet="news" /> <End Role="news" EntitySet="news" />
</AssociationSet> </AssociationSet>
<AssociationSet Name="FK_Position_Area" Association="Self.FK_Position_Area">
<End Role="AncestralTabletArea" EntitySet="AncestralTabletArea" />
<End Role="AncestralTabletPosition" EntitySet="AncestralTabletPosition" />
</AssociationSet>
<AssociationSet Name="FK_Position_Status" Association="Self.FK_Position_Status">
<End Role="AncestralTabletStatus" EntitySet="AncestralTabletStatus" />
<End Role="AncestralTabletPosition" EntitySet="AncestralTabletPosition" />
</AssociationSet>
<AssociationSet Name="FK_pro_order_activity" Association="Self.FK_pro_order_activity"> <AssociationSet Name="FK_pro_order_activity" Association="Self.FK_pro_order_activity">
<End Role="activity" EntitySet="activity" /> <End Role="activity" EntitySet="activity" />
<End Role="pro_order" EntitySet="pro_order" /> <End Role="pro_order" EntitySet="pro_order" />
@@ -2436,10 +2270,6 @@
<End Role="RegionRoomBedStatus" EntitySet="RegionRoomBedStatus" /> <End Role="RegionRoomBedStatus" EntitySet="RegionRoomBedStatus" />
<End Role="RegionRoomBed" EntitySet="RegionRoomBed" /> <End Role="RegionRoomBed" EntitySet="RegionRoomBed" />
</AssociationSet> </AssociationSet>
<AssociationSet Name="FK_Registrant_Position" Association="Self.FK_Registrant_Position">
<End Role="AncestralTabletPosition" EntitySet="AncestralTabletPosition" />
<End Role="AncestralTabletRegistrant" EntitySet="AncestralTabletRegistrant" />
</AssociationSet>
<AssociationSet Name="FK_Room_Region" Association="Self.FK_Room_Region"> <AssociationSet Name="FK_Room_Region" Association="Self.FK_Room_Region">
<End Role="Region" EntitySet="Region" /> <End Role="Region" EntitySet="Region" />
<End Role="Room" EntitySet="Room" /> <End Role="Room" EntitySet="Room" />
@@ -4518,35 +4348,6 @@
<End Role="RegionRoomBedStatus" EntitySet="RegionRoomBedStatus" /> <End Role="RegionRoomBedStatus" EntitySet="RegionRoomBedStatus" />
<End Role="RegionRoomBed" EntitySet="RegionRoomBed" /> <End Role="RegionRoomBed" EntitySet="RegionRoomBed" />
</AssociationSet> </AssociationSet>
<EntitySet Name="AncestralTabletArea" EntityType="Model.AncestralTabletArea" />
<EntitySet Name="AncestralTabletPosition" EntityType="Model.AncestralTabletPosition" />
<EntitySet Name="AncestralTabletPositionRecord" EntityType="Model.AncestralTabletPositionRecord" />
<EntitySet Name="AncestralTabletRegistrant" EntityType="Model.AncestralTabletRegistrant" />
<EntitySet Name="AncestralTabletStatus" EntityType="Model.AncestralTabletStatus" />
<AssociationSet Name="FK_AncestralTabletArea_Parent" Association="Model.FK_AncestralTabletArea_Parent">
<End Role="AncestralTabletArea" EntitySet="AncestralTabletArea" />
<End Role="AncestralTabletArea1" EntitySet="AncestralTabletArea" />
</AssociationSet>
<AssociationSet Name="FK_Position_Area" Association="Model.FK_Position_Area">
<End Role="AncestralTabletArea" EntitySet="AncestralTabletArea" />
<End Role="AncestralTabletPosition" EntitySet="AncestralTabletPosition" />
</AssociationSet>
<AssociationSet Name="FK_Position_Status" Association="Model.FK_Position_Status">
<End Role="AncestralTabletStatus" EntitySet="AncestralTabletStatus" />
<End Role="AncestralTabletPosition" EntitySet="AncestralTabletPosition" />
</AssociationSet>
<AssociationSet Name="FK_Registrant_Position" Association="Model.FK_Registrant_Position">
<End Role="AncestralTabletPosition" EntitySet="AncestralTabletPosition" />
<End Role="AncestralTabletRegistrant" EntitySet="AncestralTabletRegistrant" />
</AssociationSet>
<AssociationSet Name="FK__Ancestral__Regis__5A1A5A11" Association="Model.FK__Ancestral__Regis__5A1A5A11">
<End Role="AncestralTabletRegistrant" EntitySet="AncestralTabletRegistrant" />
<End Role="AncestralTabletPositionRecord" EntitySet="AncestralTabletPositionRecord" />
</AssociationSet>
<AssociationSet Name="FK_GuaDanOrderGuest_Order" Association="Model.FK_GuaDanOrderGuest_Order">
<End Role="GuaDanOrder" EntitySet="GuaDanOrder" />
<End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" />
</AssociationSet>
</EntityContainer> </EntityContainer>
<ComplexType Name="sp_helpdiagramdefinition_Result"> <ComplexType Name="sp_helpdiagramdefinition_Result">
<Property Type="Int32" Name="version" Nullable="true" /> <Property Type="Int32" Name="version" Nullable="true" />
@@ -4840,7 +4641,6 @@
<Property Name="IsCancel" Type="Boolean" Nullable="false" /> <Property Name="IsCancel" Type="Boolean" Nullable="false" />
<NavigationProperty Name="admin" Relationship="Model.FK_GuaDanOrder_Admin_CreateUser" FromRole="GuaDanOrder" ToRole="admin" /> <NavigationProperty Name="admin" Relationship="Model.FK_GuaDanOrder_Admin_CreateUser" FromRole="GuaDanOrder" ToRole="admin" />
<NavigationProperty Name="followers" Relationship="Model.FK_GuaDanOrder_Followers" FromRole="GuaDanOrder" ToRole="follower" /> <NavigationProperty Name="followers" Relationship="Model.FK_GuaDanOrder_Followers" FromRole="GuaDanOrder" ToRole="follower" />
<NavigationProperty Name="GuaDanOrderGuest" Relationship="Model.FK_GuaDanOrderGuest_Order" FromRole="GuaDanOrder" ToRole="GuaDanOrderGuest" />
</EntityType> </EntityType>
<EntityType Name="GuaDanOrderGuest"> <EntityType Name="GuaDanOrderGuest">
<Key> <Key>
@@ -4860,8 +4660,6 @@
<NavigationProperty Name="Room" Relationship="Model.FK_GuaDanOrderGuest_RoomUuid" FromRole="GuaDanOrderGuest" ToRole="Room" /> <NavigationProperty Name="Room" Relationship="Model.FK_GuaDanOrderGuest_RoomUuid" FromRole="GuaDanOrderGuest" ToRole="Room" />
<NavigationProperty Name="RegionRoomBedStatus" Relationship="Model.FK_GuaDanOrderGuest_StatusCode" FromRole="GuaDanOrderGuest" ToRole="RegionRoomBedStatus" /> <NavigationProperty Name="RegionRoomBedStatus" Relationship="Model.FK_GuaDanOrderGuest_StatusCode" FromRole="GuaDanOrderGuest" ToRole="RegionRoomBedStatus" />
<NavigationProperty Name="RegionAndRoomAndBedSchedule" Relationship="Model.FK_Schedule_GuaDanOrderGuest" FromRole="GuaDanOrderGuest" ToRole="RegionAndRoomAndBedSchedule" /> <NavigationProperty Name="RegionAndRoomAndBedSchedule" Relationship="Model.FK_Schedule_GuaDanOrderGuest" FromRole="GuaDanOrderGuest" ToRole="RegionAndRoomAndBedSchedule" />
<Property Name="OrderUuid" Type="Guid" />
<NavigationProperty Name="GuaDanOrder" Relationship="Model.FK_GuaDanOrderGuest_Order" FromRole="GuaDanOrderGuest" ToRole="GuaDanOrder" />
</EntityType> </EntityType>
<EntityType Name="GuadanTimeSetting"> <EntityType Name="GuadanTimeSetting">
<Key> <Key>
@@ -5114,156 +4912,6 @@
</Dependent> </Dependent>
</ReferentialConstraint> </ReferentialConstraint>
</Association> </Association>
<EntityType Name="AncestralTabletArea">
<Key>
<PropertyRef Name="AreaId" />
</Key>
<Property Name="AreaId" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="AreaName" Type="String" Nullable="false" MaxLength="10" FixedLength="false" Unicode="true" />
<Property Name="AreaCode" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="ParentAreaId" Type="Int32" />
<Property Name="AreaType" Type="String" MaxLength="10" FixedLength="false" Unicode="true" />
<Property Name="Price" Type="Int32" />
<Property Name="SortOrder" Type="Int32" />
<Property Name="IsDisabled" Type="Boolean" Nullable="false" />
<Property Name="Description" Type="String" MaxLength="200" FixedLength="false" Unicode="true" />
<NavigationProperty Name="AncestralTabletArea1" Relationship="Model.FK_AncestralTabletArea_Parent" FromRole="AncestralTabletArea" ToRole="AncestralTabletArea1" />
<NavigationProperty Name="AncestralTabletArea2" Relationship="Model.FK_AncestralTabletArea_Parent" FromRole="AncestralTabletArea1" ToRole="AncestralTabletArea" />
<NavigationProperty Name="AncestralTabletPosition" Relationship="Model.FK_Position_Area" FromRole="AncestralTabletArea" ToRole="AncestralTabletPosition" />
</EntityType>
<EntityType Name="AncestralTabletPosition">
<Key>
<PropertyRef Name="PositionId" />
</Key>
<Property Name="PositionId" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="AreaId" Type="Int32" Nullable="false" />
<Property Name="PositionCode" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="PositionName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Price" Type="Int32" />
<Property Name="StatusCode" Type="String" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="Description" Type="String" MaxLength="200" FixedLength="false" Unicode="true" />
<Property Name="RowNo" Type="Int32" />
<Property Name="ColumnNo" Type="Int32" />
<NavigationProperty Name="AncestralTabletArea" Relationship="Model.FK_Position_Area" FromRole="AncestralTabletPosition" ToRole="AncestralTabletArea" />
<NavigationProperty Name="AncestralTabletStatus" Relationship="Model.FK_Position_Status" FromRole="AncestralTabletPosition" ToRole="AncestralTabletStatus" />
<NavigationProperty Name="AncestralTabletRegistrant" Relationship="Model.FK_Registrant_Position" FromRole="AncestralTabletPosition" ToRole="AncestralTabletRegistrant" />
</EntityType>
<EntityType Name="AncestralTabletPositionRecord">
<Key>
<PropertyRef Name="RecordId" />
</Key>
<Property Name="RecordId" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="RegistrantCode" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="NPTitle" Type="String" MaxLength="30" FixedLength="false" Unicode="true" />
<Property Name="NPStandDate" Type="DateTime" Nullable="false" Precision="0" />
<Property Name="NPYangShang" Type="String" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="WPContent" Type="String" MaxLength="1000" FixedLength="false" Unicode="true" />
<Property Name="CreatedAt" Type="DateTime" Nullable="false" Precision="3" />
<Property Name="UpdatedAt" Type="DateTime" Precision="3" />
<NavigationProperty Name="AncestralTabletRegistrant" Relationship="Model.FK__Ancestral__Regis__5A1A5A11" FromRole="AncestralTabletPositionRecord" ToRole="AncestralTabletRegistrant" />
</EntityType>
<EntityType Name="AncestralTabletRegistrant">
<Key>
<PropertyRef Name="RegistrantCode" />
</Key>
<Property Name="RegistrantCode" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="Name" Type="String" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Phone" Type="String" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Name="Address" Type="String" MaxLength="60" FixedLength="false" Unicode="true" />
<Property Name="RegisterDate" Type="DateTime" Nullable="false" Precision="0" />
<Property Name="Price" Type="Int32" />
<Property Name="PositionId" Type="Int32" />
<Property Name="StartDate" Type="DateTime" Nullable="false" Precision="0" />
<Property Name="EndDate" Type="DateTime" Precision="0" />
<Property Name="IsLongTerm" Type="Boolean" Nullable="false" />
<Property Name="IsActive" Type="Boolean" Nullable="false" />
<Property Name="CreatedAt" Type="DateTime" Nullable="false" Precision="3" />
<Property Name="UpdatedAt" Type="DateTime" Precision="3" />
<Property Name="IsEnd" Type="Boolean" Nullable="false" />
<NavigationProperty Name="AncestralTabletPosition" Relationship="Model.FK_Registrant_Position" FromRole="AncestralTabletRegistrant" ToRole="AncestralTabletPosition" />
<NavigationProperty Name="AncestralTabletPositionRecord" Relationship="Model.FK__Ancestral__Regis__5A1A5A11" FromRole="AncestralTabletRegistrant" ToRole="AncestralTabletPositionRecord" />
</EntityType>
<EntityType Name="AncestralTabletStatus">
<Key>
<PropertyRef Name="StatusCode" />
</Key>
<Property Name="StatusCode" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="StatusName" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="StatusType" Type="String" Nullable="false" MaxLength="20" FixedLength="false" Unicode="true" />
<NavigationProperty Name="AncestralTabletPosition" Relationship="Model.FK_Position_Status" FromRole="AncestralTabletStatus" ToRole="AncestralTabletPosition" />
</EntityType>
<Association Name="FK_AncestralTabletArea_Parent">
<End Type="Model.AncestralTabletArea" Role="AncestralTabletArea" Multiplicity="0..1" />
<End Type="Model.AncestralTabletArea" Role="AncestralTabletArea1" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletArea">
<PropertyRef Name="AreaId" />
</Principal>
<Dependent Role="AncestralTabletArea1">
<PropertyRef Name="ParentAreaId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Position_Area">
<End Type="Model.AncestralTabletArea" Role="AncestralTabletArea" Multiplicity="1" />
<End Type="Model.AncestralTabletPosition" Role="AncestralTabletPosition" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletArea">
<PropertyRef Name="AreaId" />
</Principal>
<Dependent Role="AncestralTabletPosition">
<PropertyRef Name="AreaId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Position_Status">
<End Type="Model.AncestralTabletStatus" Role="AncestralTabletStatus" Multiplicity="0..1" />
<End Type="Model.AncestralTabletPosition" Role="AncestralTabletPosition" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletStatus">
<PropertyRef Name="StatusCode" />
</Principal>
<Dependent Role="AncestralTabletPosition">
<PropertyRef Name="StatusCode" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Registrant_Position">
<End Type="Model.AncestralTabletPosition" Role="AncestralTabletPosition" Multiplicity="0..1" />
<End Type="Model.AncestralTabletRegistrant" Role="AncestralTabletRegistrant" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletPosition">
<PropertyRef Name="PositionId" />
</Principal>
<Dependent Role="AncestralTabletRegistrant">
<PropertyRef Name="PositionId" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK__Ancestral__Regis__5A1A5A11">
<End Type="Model.AncestralTabletRegistrant" Role="AncestralTabletRegistrant" Multiplicity="1" />
<End Type="Model.AncestralTabletPositionRecord" Role="AncestralTabletPositionRecord" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="AncestralTabletRegistrant">
<PropertyRef Name="RegistrantCode" />
</Principal>
<Dependent Role="AncestralTabletPositionRecord">
<PropertyRef Name="RegistrantCode" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_GuaDanOrderGuest_Order">
<End Type="Model.GuaDanOrder" Role="GuaDanOrder" Multiplicity="0..1" />
<End Type="Model.GuaDanOrderGuest" Role="GuaDanOrderGuest" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="GuaDanOrder">
<PropertyRef Name="Uuid" />
</Principal>
<Dependent Role="GuaDanOrderGuest">
<PropertyRef Name="OrderUuid" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema> </Schema>
</edmx:ConceptualModels> </edmx:ConceptualModels>
<!-- C-S mapping content --> <!-- C-S mapping content -->
@@ -6125,7 +5773,6 @@
<EntitySetMapping Name="GuaDanOrderGuest"> <EntitySetMapping Name="GuaDanOrderGuest">
<EntityTypeMapping TypeName="Model.GuaDanOrderGuest"> <EntityTypeMapping TypeName="Model.GuaDanOrderGuest">
<MappingFragment StoreEntitySet="GuaDanOrderGuest"> <MappingFragment StoreEntitySet="GuaDanOrderGuest">
<ScalarProperty Name="OrderUuid" ColumnName="OrderUuid" />
<ScalarProperty Name="StatusCode" ColumnName="StatusCode" /> <ScalarProperty Name="StatusCode" ColumnName="StatusCode" />
<ScalarProperty Name="CheckOutAt" ColumnName="CheckOutAt" /> <ScalarProperty Name="CheckOutAt" ColumnName="CheckOutAt" />
<ScalarProperty Name="CheckInAt" ColumnName="CheckInAt" /> <ScalarProperty Name="CheckInAt" ColumnName="CheckInAt" />
@@ -6238,79 +5885,6 @@
</MappingFragment> </MappingFragment>
</EntityTypeMapping> </EntityTypeMapping>
</EntitySetMapping> </EntitySetMapping>
<EntitySetMapping Name="AncestralTabletArea">
<EntityTypeMapping TypeName="Model.AncestralTabletArea">
<MappingFragment StoreEntitySet="AncestralTabletArea">
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="IsDisabled" ColumnName="IsDisabled" />
<ScalarProperty Name="SortOrder" ColumnName="SortOrder" />
<ScalarProperty Name="Price" ColumnName="Price" />
<ScalarProperty Name="AreaType" ColumnName="AreaType" />
<ScalarProperty Name="ParentAreaId" ColumnName="ParentAreaId" />
<ScalarProperty Name="AreaCode" ColumnName="AreaCode" />
<ScalarProperty Name="AreaName" ColumnName="AreaName" />
<ScalarProperty Name="AreaId" ColumnName="AreaId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="AncestralTabletPosition">
<EntityTypeMapping TypeName="Model.AncestralTabletPosition">
<MappingFragment StoreEntitySet="AncestralTabletPosition">
<ScalarProperty Name="ColumnNo" ColumnName="ColumnNo" />
<ScalarProperty Name="RowNo" ColumnName="RowNo" />
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="StatusCode" ColumnName="StatusCode" />
<ScalarProperty Name="Price" ColumnName="Price" />
<ScalarProperty Name="PositionName" ColumnName="PositionName" />
<ScalarProperty Name="PositionCode" ColumnName="PositionCode" />
<ScalarProperty Name="AreaId" ColumnName="AreaId" />
<ScalarProperty Name="PositionId" ColumnName="PositionId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="AncestralTabletPositionRecord">
<EntityTypeMapping TypeName="Model.AncestralTabletPositionRecord">
<MappingFragment StoreEntitySet="AncestralTabletPositionRecord">
<ScalarProperty Name="UpdatedAt" ColumnName="UpdatedAt" />
<ScalarProperty Name="CreatedAt" ColumnName="CreatedAt" />
<ScalarProperty Name="WPContent" ColumnName="WPContent" />
<ScalarProperty Name="NPYangShang" ColumnName="NPYangShang" />
<ScalarProperty Name="NPStandDate" ColumnName="NPStandDate" />
<ScalarProperty Name="NPTitle" ColumnName="NPTitle" />
<ScalarProperty Name="RegistrantCode" ColumnName="RegistrantCode" />
<ScalarProperty Name="RecordId" ColumnName="RecordId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="AncestralTabletRegistrant">
<EntityTypeMapping TypeName="Model.AncestralTabletRegistrant">
<MappingFragment StoreEntitySet="AncestralTabletRegistrant">
<ScalarProperty Name="IsEnd" ColumnName="IsEnd" />
<ScalarProperty Name="UpdatedAt" ColumnName="UpdatedAt" />
<ScalarProperty Name="CreatedAt" ColumnName="CreatedAt" />
<ScalarProperty Name="IsActive" ColumnName="IsActive" />
<ScalarProperty Name="IsLongTerm" ColumnName="IsLongTerm" />
<ScalarProperty Name="EndDate" ColumnName="EndDate" />
<ScalarProperty Name="StartDate" ColumnName="StartDate" />
<ScalarProperty Name="PositionId" ColumnName="PositionId" />
<ScalarProperty Name="Price" ColumnName="Price" />
<ScalarProperty Name="RegisterDate" ColumnName="RegisterDate" />
<ScalarProperty Name="Address" ColumnName="Address" />
<ScalarProperty Name="Phone" ColumnName="Phone" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="RegistrantCode" ColumnName="RegistrantCode" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="AncestralTabletStatus">
<EntityTypeMapping TypeName="Model.AncestralTabletStatus">
<MappingFragment StoreEntitySet="AncestralTabletStatus">
<ScalarProperty Name="StatusType" ColumnName="StatusType" />
<ScalarProperty Name="StatusName" ColumnName="StatusName" />
<ScalarProperty Name="StatusCode" ColumnName="StatusCode" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping> </EntityContainerMapping>
</Mapping> </Mapping>
</edmx:Mappings> </edmx:Mappings>

View File

@@ -151,17 +151,6 @@
<AssociationConnector Association="Model.FK_Room_Region" /> <AssociationConnector Association="Model.FK_Room_Region" />
<AssociationConnector Association="Model.FK_RegionRoomBed_RoomUuid" /> <AssociationConnector Association="Model.FK_RegionRoomBed_RoomUuid" />
<AssociationConnector Association="Model.FK_RegionRoomBed_StatusCode" /> <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>

View File

@@ -1,180 +0,0 @@
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);
}
}

View File

@@ -1,184 +0,0 @@
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; }
}
}

View File

@@ -1,361 +0,0 @@
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; }
}
}

View File

@@ -1,38 +0,0 @@
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);
}
}

View File

@@ -1,29 +0,0 @@
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);
}
}

View File

@@ -66,7 +66,6 @@ public class guadanGuestQueryController: ApiController
checkoutdate = a.CheckOutAt, checkoutdate = a.CheckOutAt,
guadanorderno = a.GuaDanOrderNo, guadanorderno = a.GuaDanOrderNo,
roomName = GetRoomAndBedString(a.RegionRoomBed), roomName = GetRoomAndBedString(a.RegionRoomBed),
statusName = a.RegionRoomBedStatus.Name
}).ToList(); }).ToList();
return Ok(new return Ok(new
{ {

View File

@@ -7,6 +7,8 @@ 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>
@@ -18,19 +20,10 @@ public class guadanOrderController : ApiController
[Route("api/guadan/list")] [Route("api/guadan/list")]
public async Task<IHttpActionResult> getGuadanList([FromBody] guadan_order_search_dto search) public async Task<IHttpActionResult> getGuadanList([FromBody] guadan_order_search_dto search)
{ {
var lastCheckoutTime = _db.GuadanTimeSetting.FirstOrDefault();
string lastCheckoutTimeStr = null;
if (lastCheckoutTime != null)
{
lastCheckoutTimeStr = lastCheckoutTime.LatestCheckOut;
}
var query = _db.GuaDanOrder var query = _db.GuaDanOrder
.Where(a => a.IsCancel == false) .Where(a => a.IsCancel == false)
.Where(a => a.IsDeleted == false); .Where(a => a.IsDeleted == false);
if(!string.IsNullOrEmpty(search.guaDanOrderNo))
{
query = query.Where(order => order.GuaDanOrderNo == search.guaDanOrderNo);
}
if (search.guadanUser != null) if (search.guadanUser != null)
{ {
query = query.Where(order => order.BookerName == search.guadanUser); query = query.Where(order => order.BookerName == search.guadanUser);
@@ -52,8 +45,7 @@ public class guadanOrderController : ApiController
} }
} }
var total = query.Count(); var total = query.Count();
var data1 = await query.ToListAsync(); var data = await query
var data = data1
.OrderByDescending(b => b.CreatedAt) .OrderByDescending(b => b.CreatedAt)
.Select(a => new .Select(a => new
{ {
@@ -64,14 +56,6 @@ 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 activity = _db.activities
.Where(act => act.num == a.ActivityNum) .Where(act => act.num == a.ActivityNum)
.Select(act => new .Select(act => new
@@ -84,23 +68,23 @@ public class guadanOrderController : ApiController
.Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false) .Where(c => c.GuaDanOrderNo == a.GuaDanOrderNo && c.IsDeleted == false)
.Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED) .Where(c => c.RegionRoomBedStatus.Code != GuaDanOrderGuest.STATUS_CANCELLED)
.Count(), .Count(),
guadan_status = _db.GuaDanOrderGuest statusName = _db.GuaDanOrderGuest
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false) .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED) .Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
.All(g => g.StatusCode == "401") ? new { code=501, name="預約" }: .All(g => g.StatusCode == "401") ? "預約" :
_db.GuaDanOrderGuest _db.GuaDanOrderGuest
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false) .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED) .Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
.All(g => g.StatusCode == "403") ? new { code = 502, name = "全部退房" } : .All(g => g.StatusCode == "403") ? "全部退房" :
_db.GuaDanOrderGuest _db.GuaDanOrderGuest
.Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false) .Where(g => g.GuaDanOrderNo == a.GuaDanOrderNo && a.IsDeleted == false)
.Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED) .Where(g => g.StatusCode != GuaDanOrderGuest.STATUS_CANCELLED)
.Any(g => g.StatusCode == "402" && a.IsCancel == false) ? new { code = 503, name = "正在入住" } : .Any(g => g.StatusCode == "402" && a.IsCancel == false) ? "正在入住" :
new { code = 504, name = "部分退房" } "部分退房"
}) })
.Skip((search.page - 1) * search.pageSize) .Skip((search.page - 1) * search.pageSize)
.Take(search.pageSize) .Take(search.pageSize)
.ToList(); .ToListAsync();
return Ok(new return Ok(new
{ {
total, total,
@@ -230,7 +214,7 @@ public class guadanOrderController : ApiController
{ {
return NotFound(); return NotFound();
} }
if (_db.GuaDanOrderGuest.Any(a => (a.GuaDanOrderNo == guadan.GuaDanOrderNo) && a.StatusCode != "404")) if (_db.GuaDanOrderGuest.Any(a => a.GuaDanOrderNo == guadan.GuaDanOrderNo))
{ {
return BadRequest($"該掛單已經存在掛單蓮友,不能取消!"); return BadRequest($"該掛單已經存在掛單蓮友,不能取消!");
} }
@@ -296,7 +280,6 @@ public class guadanOrderController : ApiController
public string guadanUser { get; set; } public string guadanUser { get; set; }
public int page { get; set; } = 1; public int page { get; set; } = 1;
public int pageSize { get; set; } = 10; public int pageSize { get; set; } = 10;
public string guaDanOrderNo { get; set; } = null;
} }
} }

View File

@@ -1,908 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1,569 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1,126 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1,15 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1,99 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1,419 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1,192 +0,0 @@
<%@ 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>

View File

@@ -1,14 +0,0 @@
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)
{
}
}

View File

@@ -1084,7 +1084,7 @@
newCheckoutDate: this.guadanguest.xuzhu.newCheckoutDate newCheckoutDate: this.guadanguest.xuzhu.newCheckoutDate
}; };
axios.post(HTTP_HOST + 'api/guadanorderguest/xuzhu', payload) axios.post('/api/guadanorderguest/xuzhu', payload)
.then((res) => { .then((res) => {
this.$refs.messageModal.open({ this.$refs.messageModal.open({
title: '续住成功', title: '续住成功',
@@ -1113,13 +1113,13 @@
}, },
//续住相關方法--------------------end //续住相關方法--------------------end
getActivityList() { getActivityList() {
axios.post(HTTP_HOST + 'api/activity/GetList?page=1&pageSize=500', { kind: 0, subject: "" }) axios.post('/api/activity/GetList?page=1&pageSize=500', { kind: 0, subject: "" })
.then((res) => { .then((res) => {
this.activityList = res.data.list this.activityList = res.data.list
}) })
}, },
getavailablebedcountbytime(startTime, endTime) { getavailablebedcountbytime(startTime, endTime) {
axios.get(HTTP_HOST + 'api/region/bed/getavailablebedcountbytime', { axios.get('/api/region/bed/getavailablebedcountbytime', {
params: { params: {
startTime: startTime, startTime: startTime,
endTime: endTime endTime: endTime
@@ -1141,7 +1141,7 @@
}, },
confirmAllocation() { confirmAllocation() {
//確認分配 //確認分配
axios.post(HTTP_HOST + 'api/region/bed/confirmallocation', { axios.post('/api/region/bed/confirmallocation', {
preBeds: this.automaticBedAllocation.preBeds, preBeds: this.automaticBedAllocation.preBeds,
orderNo: this.guadanorder.order_form.orderNo, orderNo: this.guadanorder.order_form.orderNo,
checkInAt: this.guadanorder.order_form.startdate, checkInAt: this.guadanorder.order_form.startdate,
@@ -1169,7 +1169,7 @@
CheckInAt: this.guadanorder.order_form.startdate || new Date(), // 入住時間 CheckInAt: this.guadanorder.order_form.startdate || new Date(), // 入住時間
CheckOutAt: this.guadanorder.order_form.enddate || null // 退房時間,可為空 CheckOutAt: this.guadanorder.order_form.enddate || null // 退房時間,可為空
}; };
axios.post(HTTP_HOST + 'api/region/bed/preallocation', payload) axios.post('/api/region/bed/preallocation', payload)
.then(res => { .then(res => {
this.automaticBedAllocation.preBeds = res.data.data; this.automaticBedAllocation.preBeds = res.data.data;
}) })
@@ -1217,7 +1217,7 @@
getMultiSelectFollowers: function () { getMultiSelectFollowers: function () {
var fm = this.automaticBedAllocation.followerModal; var fm = this.automaticBedAllocation.followerModal;
var self = this; var self = this;
axios.post(HTTP_HOST + 'api/lianyou/getfollowers', null, { axios.post('/api/lianyou/getfollowers', null, {
params: { params: {
page: fm.page, page: fm.page,
pageSize: fm.pageSize, pageSize: fm.pageSize,
@@ -1288,7 +1288,7 @@
}, },
getGuadanOrderById() { getGuadanOrderById() {
if (this.guadanorder.order_form.uuid) { if (this.guadanorder.order_form.uuid) {
axios.get(HTTP_HOST + 'api/guadan/getorderbyid', { axios.get('/api/guadan/getorderbyid', {
params: { params: {
orderId: this.guadanorder.order_form.uuid orderId: this.guadanorder.order_form.uuid
} }
@@ -1307,7 +1307,7 @@
}, },
getGuadanOrderGuestByOrderNo() { getGuadanOrderGuestByOrderNo() {
if (this.guadanorder.order_form.orderNo) { if (this.guadanorder.order_form.orderNo) {
axios.get(HTTP_HOST + 'api/guadanorderguest/getbyorderno', { axios.get('/api/guadanorderguest/getbyorderno', {
params: { params: {
orderNo: this.guadanorder.order_form.orderNo orderNo: this.guadanorder.order_form.orderNo
} }
@@ -1317,7 +1317,7 @@
} }
}, },
getGuadanOrderStatus() { getGuadanOrderStatus() {
axios.get(HTTP_HOST + 'api/region/guadan/status/list') axios.get('/api/region/guadan/status/list')
.then((res) => { .then((res) => {
this.guadanorder.status_items = res.data; this.guadanorder.status_items = res.data;
}) })
@@ -1326,7 +1326,7 @@
if (!this.validateOrderForm()) { if (!this.validateOrderForm()) {
return; return;
} }
axios.post(HTTP_HOST + 'api/guadan/create', this.guadanorder.order_form) axios.post('/api/guadan/create', this.guadanorder.order_form)
.then((res => { .then((res => {
this.$refs.messageModal.open({ this.$refs.messageModal.open({
title: '掛單提示', title: '掛單提示',
@@ -1350,7 +1350,7 @@
if (!this.validateOrderForm()) { if (!this.validateOrderForm()) {
return; return;
} }
axios.post(HTTP_HOST + 'api/guadan/update', this.guadanorder.order_form) axios.post('/api/guadan/update', this.guadanorder.order_form)
.then((res => { .then((res => {
this.$refs.messageModal.open({ this.$refs.messageModal.open({
title: '掛單提示', title: '掛單提示',
@@ -1495,13 +1495,13 @@
}, },
createCheckInGuest() { createCheckInGuest() {
return axios.post(HTTP_HOST + 'api/guadanorderguest/create', this.checkInGuest.inGuest) return axios.post('/api/guadanorderguest/create', this.checkInGuest.inGuest)
}, },
checkBedAndFollower() { checkBedAndFollower() {
this.checkInGuest.inGuest this.checkInGuest.inGuest
}, },
getGuadanGuestStatus() { getGuadanGuestStatus() {
axios.get(HTTP_HOST + 'api/region/bed/status/list') axios.get('/api/region/bed/status/list')
.then((res) => { .then((res) => {
this.checkInGuest.status = res.data.filter(item => item.category === 4 && item.code != '404'); this.checkInGuest.status = res.data.filter(item => item.category === 4 && item.code != '404');
}) })
@@ -1524,7 +1524,7 @@
pageSize: itemsPerPage, pageSize: itemsPerPage,
searchName: this.selectGuestModal.searchNameOrPhone searchName: this.selectGuestModal.searchNameOrPhone
}; };
axios.post(HTTP_HOST + 'api/lianyou/getfollowers', null, { axios.post('/api/lianyou/getfollowers', null, {
params: params params: params
}).then((res) => { }).then((res) => {
this.selectGuestModal.items = res.data.data this.selectGuestModal.items = res.data.data
@@ -1559,7 +1559,7 @@
}, },
async saveEditGuadanOrderGuest() { async saveEditGuadanOrderGuest() {
try { try {
const res = await axios.post(HTTP_HOST + 'api/guadanorderguest/update', this.checkInGuest.inGuest) const res = await axios.post('/api/guadanorderguest/update', this.checkInGuest.inGuest)
this.getGuadanOrderGuestByOrderNo(); this.getGuadanOrderGuestByOrderNo();
this.closeCheckInModal(); this.closeCheckInModal();
} catch (error) { } catch (error) {
@@ -1570,7 +1570,7 @@
}, },
deleteGuadanOrderGuest(guest) { deleteGuadanOrderGuest(guest) {
axios.post(HTTP_HOST + 'api/guadanorderguest/cancel?uuid=' + guest.uuid) axios.post('/api/guadanorderguest/cancel?uuid=' + guest.uuid)
.then((res) => { .then((res) => {
this.guadanguest.items = this.guadanguest.items.filter(i => i.uuid != guest.uuid); this.guadanguest.items = this.guadanguest.items.filter(i => i.uuid != guest.uuid);
}).catch((error) => { }).catch((error) => {
@@ -1628,7 +1628,7 @@
//床位選擇相關方法----------------start //床位選擇相關方法----------------start
async loadRegions() { async loadRegions() {
const res = await axios.post(HTTP_HOST + 'api/region/getRegionList'); const res = await axios.post('/api/region/getRegionList');
this.region_modal.regions = res.data; this.region_modal.regions = res.data;
}, },
async loadRegionsByGender() { async loadRegionsByGender() {
@@ -1643,7 +1643,7 @@
} }
} }
const res = await axios.post(HTTP_HOST + 'api/region/getRegionListByGender', { const res = await axios.post('/api/region/getRegionListByGender', {
IsMale: isMale IsMale: isMale
}); });
@@ -1660,7 +1660,7 @@
this.region_modal.selectedType = 'room'; this.region_modal.selectedType = 'room';
this.region_modal.currentSelectBeds = room.beds; this.region_modal.currentSelectBeds = room.beds;
if (this.checkInGuest.inGuest.checkInAt && this.checkInGuest.inGuest.checkOutAt) { if (this.checkInGuest.inGuest.checkInAt && this.checkInGuest.inGuest.checkOutAt) {
axios.get(HTTP_HOST + 'api/region/room/bed/list', { axios.get('/api/region/room/bed/list', {
params: { params: {
roomUuid: room.uuid, roomUuid: room.uuid,
StartTime: this.checkInGuest.inGuest.checkInAt, StartTime: this.checkInGuest.inGuest.checkInAt,
@@ -1678,7 +1678,7 @@
}, },
GetRegionRoomBedListByRoomId(roomUuid) { GetRegionRoomBedListByRoomId(roomUuid) {
if (this.checkInGuest.inGuest.checkInAt && this.checkInGuest.inGuest.checkOutAt) { if (this.checkInGuest.inGuest.checkInAt && this.checkInGuest.inGuest.checkOutAt) {
axios.get(HTTP_HOST + 'api/region/bed/list') axios.get('/api/region/bed/list')
.then((res) => { .then((res) => {
}) })

View File

@@ -74,7 +74,7 @@
</v-pagination> </v-pagination>
</v-col> </v-col>
<v-col class="text-truncate text-right" cols="12" md="2"> <v-col class="text-truncate text-right" cols="12" md="2">
共 {{ total }} 筆, 頁數: 共 {{ }} 筆, 頁數:
</v-col> </v-col>
<v-col cols="6" md="1"> <v-col cols="6" md="1">
<v-text-field <v-text-field
@@ -162,7 +162,6 @@ button:hover {
{ text: '入住日期', value: 'checkindate' }, { text: '入住日期', value: 'checkindate' },
{ text: '退房日期', value: 'checkoutdate' }, { text: '退房日期', value: 'checkoutdate' },
{ text: '房間號', value: 'roomName' }, { text: '房間號', value: 'roomName' },
{ text: '狀態', value: 'statusName'},
], ],
guests: [], // 表格數據 guests: [], // 表格數據
@@ -198,7 +197,7 @@ button:hover {
} }
if (this.loading) return; if (this.loading) return;
this.loading = true; this.loading = true;
axios.post(HTTP_HOST + 'api/guadan/guest/query/list', axios.post('/api/guadan/guest/query/list',
{ {
page: this.options.page, page: this.options.page,
pageSize: this.options.itemsPerPage, pageSize: this.options.itemsPerPage,

View File

@@ -7,8 +7,6 @@
<a href="create.aspx" class="btn btn-primary" >新建掛單</a> <a href="create.aspx" class="btn btn-primary" >新建掛單</a>
</nav> </nav>
<div class="d-flex align-items-center gap-3"> <div class="d-flex align-items-center gap-3">
<label class="mb-0">掛單單號</label>
<input class="form-control w-auto" style="width:150px;" v-model="search.guaDanOrderNo" />
<label class="mb-0">掛單登記人</label> <label class="mb-0">掛單登記人</label>
<input class="form-control w-auto" style="width:150px;" v-model="search.guadanUser" /> <input class="form-control w-auto" style="width:150px;" v-model="search.guadanUser" />
@@ -30,21 +28,10 @@
<v-data-table <v-data-table
:items="items" :items="items"
:headers="headers" :headers="headers"
:item-class="item => item.is_timeout ? 'row-timeout' : ''"
hide-default-footer> hide-default-footer>
<template #item.actions="{item}"> <template #item.actions="{item}">
<a :href="'view.aspx?orderId='+item.guaDanOrderNo" class="btn btn-primary">查看</a> <a :href="'create.aspx?orderId='+item.guaDanOrderNo" class="btn btn-secondary">編輯</a>
<a :href="'create.aspx?orderId='+item.guaDanOrderNo" class="btn btn-secondary" <a class="btn btn-outline-danger" @click="deleteGuadanOrder(item)">取消</a>
:style="item.guadan_status?.code == 502 ? 'pointer-events: none; opacity: 0.5; cursor: not-allowed;' : ''">編輯</a>
<a
class="btn btn-outline-danger"
href="#"
:style="item.guest_count != 0 ? 'pointer-events: none; opacity: 0.5; cursor: not-allowed;' : ''"
@click.prevent="item.guest_count != 0 ? null : deleteGuadanOrder(item)"
>
取消
</a>
</template> </template>
<template #item.room="{item}"> <template #item.room="{item}">
{{item.room.name}} {{item.room.name}}
@@ -52,8 +39,8 @@
<template #item.bed="{item}"> <template #item.bed="{item}">
{{item.bed.name}} {{item.bed.name}}
</template> </template>
<template #item.guadan_status="{item}"> <template #item.status="{item}">
{{item.guadan_status?.name}} {{item.status}}
</template> </template>
<template #item.start_date="{item}"> <template #item.start_date="{item}">
{{item.start_date | timeString('YYYY/MM/DD')}} {{item.start_date | timeString('YYYY/MM/DD')}}
@@ -67,45 +54,42 @@
<template #item.activity="{item}"> <template #item.activity="{item}">
{{item.activity?.subject}} {{item.activity?.subject}}
</template> </template>
<template #item.is_timeout="{item}">
{{item.is_timeout ? '已超時': '否'}}
</template>
</v-data-table> </v-data-table>
<v-container> <v-container>
<v-row class="align-baseline" wrap="false"> <v-row class="align-baseline" wrap="false">
<v-col cols="12" md="8"> <v-col cols="12" md="8">
<v-pagination <v-pagination
v-model="options.page" v-model="options.page"
:length="pageCount"> :length="pageCount">
</v-pagination> </v-pagination>
</v-col> </v-col>
<v-col class="text-truncate text-right" cols="12" md="2"> <v-col class="text-truncate text-right" cols="12" md="2">
共 {{ total }} 筆, 頁數: 共 {{ total }} 筆, 頁數:
</v-col> </v-col>
<v-col cols="6" md="1"> <v-col cols="6" md="1">
<v-text-field <v-text-field
v-model="options.page" v-model="options.page"
type="number" type="number"
hide-details hide-details
dense dense
min="1" min="1"
:max="pageCount" :max="pageCount"
@input="options.page = parseInt($event, 10)" @input="options.page = parseInt($event, 10)"
></v-text-field> ></v-text-field>
</v-col> </v-col>
<!-- 每頁條數選擇 --> <!-- 每页条数选择 -->
<v-col cols="12" md="1"> <v-col cols="12" md="1">
<v-select <v-select
v-model="options.itemsPerPage" v-model="options.itemsPerPage"
:items="[5, 10, 20, 50]" :items="[5, 10, 20, 50]"
label="每頁條數" label="每頁條數"
dense dense
hide-details hide-details
style="width: 100px;" style="width: 100px;"
></v-select> ></v-select>
</v-col> </v-col>
</v-row> </v-row>
</v-container> </v-container>
</div> </div>
<!-- 更新修改確認彈出視窗 --> <!-- 更新修改確認彈出視窗 -->
<message-modal ref="messageModal"></message-modal> <message-modal ref="messageModal"></message-modal>
@@ -113,6 +97,7 @@
<confirm-modal ref="confirmModal"></confirm-modal> <confirm-modal ref="confirmModal"></confirm-modal>
</asp:Content> </asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server"> <asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
<div>test</div>
</asp:Content> </asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server"> <asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
<script> <script>
@@ -126,15 +111,13 @@
return { return {
items: [], items: [],
headers: [ headers: [
{ text: '登記掛單蓮友', value: 'bookerName' }, { text: '登记挂单莲友', value: 'bookerName' },
{ text: '掛單單號', value: 'guaDanOrderNo'},
{ text: '起始日期', value: 'start_date', align: 'center' }, { text: '起始日期', value: 'start_date', align: 'center' },
{ text: '結束日期', value: 'end_date', align: 'center' }, { text: '結束日期', value: 'end_date', align: 'center' },
{ text: '掛單人數', value: 'guest_count' }, { text: '掛單人數', value: 'guest_count' },
{ text: '狀態', value: 'guadan_status', align: 'center' }, { text: '狀態', value: 'statusName', align: 'center' },
{ text: '建立時間', value: 'created_at', align: 'center' }, { text: '建立時間', value: 'created_at', align: 'center' },
{ text: '關聯活動', value: 'activity', align: 'center' }, { text: '關聯活動', value: 'activity', align: 'center' },
{ text: '超時退房', value: 'is_timeout', align: 'center' },
{ text: '操作', value: 'actions', align: 'center' } { text: '操作', value: 'actions', align: 'center' }
], ],
options: { options: {
@@ -147,7 +130,6 @@
startDate: null, startDate: null,
endDate: null, endDate: null,
guadanUser: null, guadanUser: null,
guaDanOrderNo: null,
}, },
total: 0, total: 0,
loading: false, loading: false,
@@ -164,12 +146,6 @@
}; };
}, },
handleSearch() { handleSearch() {
let orderNo = this.search.guaDanOrderNo;
if (orderNo) {
orderNo = orderNo.replace(/\s+/g, '');
this.search.guaDanOrderNo = orderNo;
}
const val = this.search.guadanUser; const val = this.search.guadanUser;
// 驗證是否包含空格 // 驗證是否包含空格
@@ -193,16 +169,14 @@
this.search.startDate = null; this.search.startDate = null;
this.search.endDate = null; this.search.endDate = null;
this.search.guadanUser = null; this.search.guadanUser = null;
this.search.guaDanOrderNo = null;
this.resetTableOptions(); this.resetTableOptions();
}, },
getGuadanOrder() { getGuadanOrder() {
if (this.loading) return; if (this.loading) return;
axios.post(HTTP_HOST + 'api/guadan/list', { axios.post('/api/guadan/list', {
startDate: this.search.startDate, startDate: this.search.startDate,
endDate: this.search.endDate, endDate: this.search.endDate,
guadanUser: this.search.guadanUser, guadanUser: this.search.guadanUser,
guaDanOrderNo: this.search.guaDanOrderNo,
page: this.options.page, page: this.options.page,
pageSize: this.options.itemsPerPage pageSize: this.options.itemsPerPage
}) })
@@ -219,7 +193,7 @@
this.$refs.confirmModal.open({ this.$refs.confirmModal.open({
message: '確認取消掛單?', message: '確認取消掛單?',
onConfirm: () => { onConfirm: () => {
axios.post(HTTP_HOST + 'api/guadan/cancel', null, { axios.post('/api/guadan/cancel', null, {
params: { params: {
uuid: order.uuid uuid: order.uuid
} }
@@ -256,10 +230,5 @@
} }
}); });
</script> </script>
<style> </asp:Content>
.row-timeout {
background-color: #ffdddd !important;
}
</style>
</asp:Content>

View File

@@ -326,7 +326,7 @@
saveAs(new Blob([wbout], { type: "application/octet-stream" }), "statistics.xlsx"); saveAs(new Blob([wbout], { type: "application/octet-stream" }), "statistics.xlsx");
}, },
GetGuadanStatistics() { GetGuadanStatistics() {
axios.get(HTTP_HOST + 'api/guadanStatistics/GetGuadanStatistics') axios.get('/api/guadanStatistics/GetGuadanStatistics')
.then((res) => { .then((res) => {
this.guadanStatistics = res.data.guadanStatistics; this.guadanStatistics = res.data.guadanStatistics;
}) })

View File

@@ -1,539 +0,0 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="view.aspx.cs" Inherits="admin_guadan_view" %>
<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">
<fieldset class="border rounded p-4 mb-5 shadow-sm bg-white">
<legend class="w-auto px-3 font-weight-bold text-primary">掛單資訊</legend>
<!-- 🟢 區塊一:掛單資訊 -->
<div class="border rounded p-3 bg-white shadow-sm" style="pointer-events: none; user-select: none; background: #1c5bd9; padding: 5px;">
<h6 class="text-secondary mb-3">📝掛單資訊</h6>
<div class="form-group row mt-3">
<label class="col-sm-2 col-form-label text-center">掛單單號(不可修改)</label>
<div class="col-sm-4 text-left">
<input class="form-control" v-model="guadanorder.order_form.orderNo" readonly />
</div>
<label class="col-sm-2 col-form-label text-center">關聯活動</label>
<div class="col-sm-4">
<select class="form-control" v-model="guadanorder.order_form.activityNum" >
<option :value="null">未關聯</option>
<option v-for="activity in activityList" :key="activity.num" :value="activity.num">
{{activity.subject}}
</option>
</select>
</div>
</div>
<div class="form-group row mt-3">
<label class="col-sm-2 col-form-label text-center">
預約開始日期
</label>
<div class="col-sm-4 text-left">
<input class="form-control" type="date" v-model="guadanorder.order_form.startdate" />
</div>
<label class="col-sm-2 col-form-label text-center">
預約結束日期
</label>
<div class="col-sm-4">
<input class="form-control" type="date" v-model="guadanorder.order_form.enddate" />
</div>
</div>
<div class="form-group row mt-3">
<label class="col-sm-2 col-form-label text-center">預定人姓名</label>
<div class="col-sm-4">
<input class="form-control" v-model="guadanorder.order_form.bookerName" />
</div>
<label class="col-sm-2 col-form-label text-center">預定人電話</label>
<div class="col-sm-4">
<input class="form-control" v-model="guadanorder.order_form.bookerPhone" />
</div>
</div>
<div class="form-group row mt-3">
<label class="col-sm-2 col-form-label text-center">備註</label>
<div class="col-sm-4">
<textarea class="form-control" v-model="guadanorder.order_form.note"></textarea>
</div>
</div>
</div>
</fieldset>
<fieldset class="border rounded p-4 mb-5 shadow-sm bg-white">
<!-- 表格標題緊貼表格上方,居中 -->
<div class="d-flex align-items-center mb-3">
<!-- 中間標題flex-grow撐開居中 -->
<div class="flex-grow-1 text-center">
<h5 class="text-primary fw-bold mb-0">
<i class="bi bi-people-fill me-2"></i>掛單蓮友
</h5>
</div>
</div>
<!-- v-data-table 表格 -->
<v-data-table :headers="guadanguest.headers" :items="guadanguest.items" class="elevation-1 rounded" dense>
<template #item.checkinat="{item}">
{{item.checkinat |timeString('YYYY-MM-DD')}}
</template>
<template #item.checkoutat="{item}">
{{item.checkoutat |timeString('YYYY-MM-DD')}}
</template>
<template v-slot:item.name="{item}">
{{item.follower?.u_name}}
</template>
<template v-slot:item.sex="{item}">
{{item.follower?.sex}}
</template>
</v-data-table>
</fieldset>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
<style>
/* 調整 fieldset 風格 */
fieldset {
border: 1px solid #dee2e6;
border-radius: 0.5rem;
background-color: #fff;
}
legend {
font-size: 1.25rem;
font-weight: 700;
color: #0d6efd;
width: auto;
padding: 0 0.75rem;
}
.form-group label {
font-weight: 600;
}
/* 按鈕置右 */
.text-right {
text-align: right;
}
/* 選擇床位相關 */
.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;
}
.selected-room {
background-color: #cce5ff;
font-weight: bold;
}
/* 選擇床位相關 */
</style>
<script>
Vue.component('region-item', {
props: ['item', 'selectedId', 'selectedType', 'expandAll', 'collapseAll'],
data() {
return {
expanded: false, // 預設全部收起
selectedRoomId: null,
}
},
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.selectedType === 'region' && this.item.uuid === this.selectedId;
}
},
methods: {
toggle() {
this.expanded = !this.expanded;
},
select() {
this.$emit('select-region', this.item);
},
selectRoom(room) {
this.selectedRoomId = room.uuid;
this.$emit('select-room', room); // 可以發事件給父組件
}
},
template: `
<div>
<span class="toggle-icon" @click="toggle">{{ icon }}</span>
<span @click="select"
class="region-item-label"
:class="{ 'selected': isSelected }">
{{ item.rooms.length>0 ? (item.name + '(' + item.rooms.length + '房)'): item.name }}
</span>
<!-- 子區域列表 -->
<ul v-if="hasChildren && expanded">
<li v-for="(child, index) in item.children" :key="child.id + '-' + index">
<region-item
:item="child"
:selected-id="selectedId"
:selected-type="selectedType"
:expand-all="expandAll"
:collapse-all="collapseAll"
@select-region="$emit('select-region', $event)"
@select-room="$emit('select-room', $event)"
@clear-expand-all="$emit('clear-expand-all')"
@clear-collapse-all="$emit('clear-collapse-all')"
/>
</li>
</ul>
<!-- 客房列表:無論是否有子區域,只要展開就顯示 -->
<ul v-if="item.rooms && item.rooms.length > 0 && expanded">
<li v-for="room in item.rooms" :key="'room-' + room.uuid"
@click="selectRoom(room)"
:class="{ 'selected-room': selectedType === 'room' && selectedId === room.uuid }"
style="cursor: pointer;">
<span class="bed-label">
🛏️ {{ room.name + ' (' + room.beds.length + '床) ' + (room.gender === true ? '(男客房)' : room.gender === false ? '(女客房)' : '') }}
</span>
</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 {
activityList: [],
availableBedCount: {
male: 0,
female: 0,
},
guadanorder: {
order_form: {
uuid: '<%= Request.QueryString["orderid"] %>' || null,
startdate: null,
enddate: null,
note: null,
orderNo: null,
bookerName: null,
bookerPhone: null,
bookerFollowerNum: null,
activityNum: null,
},
status_items: [],
},
guadanguest: {
guest: {
uuid: null, // int?
fullName: '', // string
gender: null, // int?
phone: '', // string
idNumber: '', // string
birthday: null, // Date (建議用 date picker)
email: '', // string
address: '', // string
emergencyContact: '', // string
emergencyPhone: '', // string
status: null, // int?
notes: '' // string
},
headers: [{
text: '姓名',
value: 'name'
},
{
text: '性別',
value: 'sex'
},
{
text: '掛單開始時間',
value: 'checkinat'
},
{
text: '掛單結束時間',
value: 'checkoutat'
},
{
text: '床位',
value: 'bedName'
},
{
text: '狀態',
value: 'statusName'
},
{
text: '備註',
value: 'note'
},
{
text: '',
value: 'actions'
},
],
items: [],
showCreateGuestModal: false,
xuzhu: {
showXuzhuGuestModal: false,
currentCheckoutDate: null,
newCheckoutDate: null,
guestUuid: null,
guestBedUuid: null,
}
},
checkInGuest: {
showSelectGuadanOrderGuest: false,
isEdit: false,
inGuest: {
uuid: null,
orderNo: null,
followerNum: null,
roomUuid: null,
bedUuid: null,
checkInAt: null,
checkOutAt: null,
statuscode: null,
},
status: [],
},
region_modal: {
regions: [],
currentSelectRegion: null,
currentSelectRoom: null,
currentSelectBeds: [],
currentSelectBed: null,
showSelectBedModal: false,
selectedId: null, // 被選中項目ID
selectedType: null, // 'region' 或 'room'
expandAllFlag: false, // 控制全部展開
collapseAllFlag: false, // 控制全部收起
currentSelectBedText: null,
},
selectGuestModal: {
showSelectGuestModal: false,
currentSelectedGuest: null,
fullNameText: null,
headers: [{
text: '姓名',
value: 'u_name'
},
{
text: '電話',
value: 'phone'
},
{
text: '',
value: 'actions'
},
],
items: [],
options: { //v-data-table參數
page: 1,
itemsPerPage: 10,
sortBy: [],
sortDesc: [],
multiSort: false,
},
page: 1,
pageSize: 10,
count: 0,
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
},
searchNameOrPhone: null,
},
automaticBedAllocation: {
showModal: false,
// 蓮友選擇彈出視窗
followerModal: {
showModal: false,
followerList: [],
selectedFollowerItems: [],
page: 1,
pageSize: 10,
totalCount: 0,
searchNameOrPhone: '',
headers: [
{ text: '姓名', value: 'u_name' },
{ text: '電話', value: 'phone' },
{ text: '操作', value: 'actions', sortable: false }
],
},
// 已選擇的待分配列表
selectedFollowers: [],
preBeds: [],
headers: [
{ text: '姓名', value: 'u_name' },
{ text: '電話', value: 'phone' },
{ text: '性別', value: 'sex' },
{ text: '預分配床位', value: 'prebed' },
{ text: '', value: 'actions' }
],
},
}
},
methods: {
getActivityList() {
axios.post(HTTP_HOST + 'api/activity/GetList?page=1&pageSize=500', { kind: 0, subject: "" })
.then((res) => {
this.activityList = res.data.list
})
},
//掛單相關方法-------------------start
validateOrderForm() {
if (!this.guadanorder.order_form.startdate) {
this.$refs.messageModal.open({
message: '請輸入必填資訊'
});
return false;
}
if (!this.guadanorder.order_form.enddate) {
this.$refs.messageModal.open({
message: '請輸入必填資訊'
});
return false;
}
if (!this.guadanorder.order_form.bookerName) {
this.$refs.messageModal.open({
message: '請輸入姓名'
});
return false;
}
if (this.guadanorder.order_form.bookerPhone && !/^\d{2,4}-?\d{3,4}-?\d{3,4}$/.test(this.guadanorder.order_form.bookerPhone)) {
this.$refs.messageModal.open({
message: '電話輸入有誤'
});
return false;
}
return true;
},
getGuadanOrderById() {
if (this.guadanorder.order_form.uuid) {
axios.get(HTTP_HOST + 'api/guadan/getorderbyid', {
params: {
orderId: this.guadanorder.order_form.uuid
}
}).then((res) => {
this.guadanorder.order_form.note = res.data.notes;
this.guadanorder.order_form.startdate = res.data.startDate;
this.guadanorder.order_form.enddate = res.data.endDate;
this.guadanorder.order_form.orderNo = res.data.guaDanOrderNo;
this.guadanorder.order_form.bookerName = res.data.bookerName;
this.guadanorder.order_form.bookerPhone = res.data.bookerPhone;
this.guadanorder.order_form.bookerFollowerNum = res.data.bookerFollowerNum;
this.guadanorder.order_form.uuid = res.data.uuid;
this.guadanorder.order_form.activityNum = res.data.activityNum;
})
}
},
getGuadanOrderGuestByOrderNo() {
if (this.guadanorder.order_form.orderNo) {
axios.get(HTTP_HOST + 'api/guadanorderguest/getbyorderno', {
params: {
orderNo: this.guadanorder.order_form.orderNo
}
}).then((res => {
this.guadanguest.items = res.data;
}))
}
},
//掛單相關方法-------------------end
},
watch: {
'guadanorder.order_form.orderNo'(newValue, oldValue) {
if (newValue) {
this.getGuadanOrderGuestByOrderNo();
}
},
'selectGuestModal.options': {
handler() {
this.getGuadanFollowers();
},
deep: true
},
// 分頁變化時自動刷新
'automaticBedAllocation.followerModal.page': function () {
this.getMultiSelectFollowers();
},
'automaticBedAllocation.followerModal.pageSize': function () {
this.getMultiSelectFollowers();
}
},
mounted() {
if (this.guadanorder.order_form.uuid) {
this.getGuadanOrderById();
this.getGuadanOrderGuestByOrderNo();
}
this.getActivityList();
},
computed: {
pageCount() {
return Math.ceil(this.selectGuestModal.count / this.selectGuestModal.pageSize)
},
pageCount2: function () {
var fm = this.automaticBedAllocation.followerModal;
return Math.ceil(fm.totalCount / fm.pageSize) || 1;
}
},
});
</script>
</asp:Content>

View File

@@ -1,14 +0,0 @@
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_guadan_view : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}

View File

@@ -58,7 +58,7 @@
}, },
methods: { methods: {
getStatusList() { getStatusList() {
axios.get(HTTP_HOST + 'api/region/bed/status/list') axios.get('/api/region/bed/status/list')
.then((res) => { .then((res) => {
this.items = res.data this.items = res.data
this.loading = false; this.loading = false;
@@ -73,7 +73,7 @@
}) })
}, },
deleteStatus(item) { deleteStatus(item) {
axios.post(HTTP_HOST + 'api/region/bed/status/delete', null, { axios.post('/api/region/bed/status/delete', null, {
params: { code: item.code } params: { code: item.code }
}) })
.then(() => { .then(() => {

View File

@@ -316,7 +316,7 @@
unoccupied: this.filter.unoccupied, unoccupied: this.filter.unoccupied,
gender: this.filter.Gender, gender: this.filter.Gender,
}; };
axios.post(HTTP_HOST + 'api/region/list', payload) axios.post('/api/region/list', payload)
.then((res) => { .then((res) => {
this.regions = res.data.regions; this.regions = res.data.regions;
this.summary = res.data.summary; // 保存後端統計 this.summary = res.data.summary; // 保存後端統計
@@ -347,7 +347,7 @@
console.log(this.filter.Gender); console.log(this.filter.Gender);
}, },
getRegionWithRoom() { getRegionWithRoom() {
axios.get(HTTP_HOST + 'api/region/regionwithroom') axios.get('/api/region/regionwithroom')
.then((res) => { .then((res) => {
this.filter.areas = res.data; this.filter.areas = res.data;
}) })

View File

@@ -578,7 +578,7 @@
this.expandAllFlag = false; this.expandAllFlag = false;
}, },
async loadRegions() { async loadRegions() {
const res = await axios.post(HTTP_HOST + 'api/region/getRegionList'); const res = await axios.post('/api/region/getRegionList');
this.regions = res.data; this.regions = res.data;
this.flatRegions = this.flatten(res.data); this.flatRegions = this.flatten(res.data);
if (this.currentSelectRoom) { if (this.currentSelectRoom) {
@@ -586,7 +586,7 @@
} }
}, },
loadRegionType() { loadRegionType() {
axios.post(HTTP_HOST + 'api/region/getRegionType') axios.post('/api/region/getRegionType')
.then(res => { .then(res => {
this.regionTypes = res.data this.regionTypes = res.data
}); });
@@ -799,7 +799,7 @@
}); });
}, },
confirmDeleteBed(bed) { confirmDeleteBed(bed) {
axios.post(HTTP_HOST + 'api/region/bed/delete', null, { axios.post('/api/region/bed/delete', null, {
params: { uuid: bed.uuid } params: { uuid: bed.uuid }
}) // 假設後端吃的是 id }) // 假設後端吃的是 id
.then(() => { .then(() => {
@@ -840,7 +840,7 @@
async saveEditBed() { async saveEditBed() {
try { try {
await axios.post(HTTP_HOST + 'api/region/bed/update', this.room_bed.newBedForm); await axios.post('/api/region/bed/update', this.room_bed.newBedForm);
this.room_bed.showBedModal = false; this.room_bed.showBedModal = false;
const updated = this.room_bed.newBedForm; const updated = this.room_bed.newBedForm;
@@ -882,7 +882,7 @@
}, },
getBedStatus() { getBedStatus() {
//獲取床位狀態 //獲取床位狀態
axios.get(HTTP_HOST + 'api/region/bed/status/list') axios.get('/api/region/bed/status/list')
.then((res) => { .then((res) => {
this.room_bed.bed_status = res.data; this.room_bed.bed_status = res.data;
}) })
@@ -907,7 +907,7 @@
}); });
return; return;
} }
axios.post(HTTP_HOST + 'api/region/room/create', this.room.room_form) axios.post('/api/region/room/create', this.room.room_form)
.then((res) => { .then((res) => {
this.room.showCreateRoomDialog = false; this.room.showCreateRoomDialog = false;
this.currentSelectRegion.rooms.push(res.data); this.currentSelectRegion.rooms.push(res.data);
@@ -924,7 +924,7 @@
}, },
async roomUpdate() { async roomUpdate() {
try { try {
const res = await axios.post(HTTP_HOST + 'api/region/room/update', this.room.room_form); const res = await axios.post('/api/region/room/update', this.room.room_form);
this.$refs.messageModal.open({ this.$refs.messageModal.open({
message: '客房資料更新成功' message: '客房資料更新成功'
}); });
@@ -950,7 +950,7 @@
}, },
roomDelete() { roomDelete() {
axios.post(HTTP_HOST + 'api/region/room/delete', { uuid: this.currentSelectRoom.uuid }) axios.post('/api/region/room/delete', { uuid: this.currentSelectRoom.uuid })
.then((res) => { .then((res) => {
const region = this.findRegionById(this.regions, this.currentSelectRoom.regionUuid)//當前room所在的region const region = this.findRegionById(this.regions, this.currentSelectRoom.regionUuid)//當前room所在的region
if (region) { if (region) {

View File

@@ -61,7 +61,7 @@
}, },
methods: { methods: {
getRegionTypeList() { getRegionTypeList() {
axios.post(HTTP_HOST + 'api/regiontype/getreiontypelist') axios.post('/api/regiontype/getreiontypelist')
.then((res) => { .then((res) => {
this.items = res.data; this.items = res.data;
}) })
@@ -71,7 +71,7 @@
'title': '刪除提示', 'title': '刪除提示',
'message': `確定要刪除 ${item.name} ?`, 'message': `確定要刪除 ${item.name} ?`,
onConfirm: () => { onConfirm: () => {
axios.post(HTTP_HOST + 'api/regiontype/delete',null, { axios.post('/api/regiontype/delete',null, {
params: { uuid: item.uuid } params: { uuid: item.uuid }
}) })
.then(() => { .then(() => {