7 Commits

Author SHA1 Message Date
EnChia b866a3c454 1. 隱藏信眾資料牌位標題
2. 刪除品項的料號欄位
3. 更新資料庫修改紀錄
2026-05-12 17:52:43 +08:00
EnChia ca9548494c 更新 資料庫修改紀錄.txt 2026-05-11 09:38:14 +08:00
EnChia e201426e5f 更新 資料庫修改紀錄.md 2026-05-11 01:34:50 +00:00
EnChia 46494547db 將全年報名移至獨立頁籤,並新增未報名品項名單列印功能 2026-05-11 09:11:22 +08:00
EnChia 9a7c30bd21 1. 更新法會活動品項中的牌位陽上與超度人數限制功能 2026-05-04 13:48:51 +08:00
EnChia 29f2902119 1. 更新法會活動品項中的牌位陽上與超度人數限制功能 2026-05-04 13:44:16 +08:00
EnChia 11a8c3e932 1. 新增法會活動品項:牌位陽上與超度人數限制功能
2. 信眾資料新增全年性選項以及開始參加活動日期,自動報名並代入前一次的報名資料(品項)
2026-05-04 11:43:57 +08:00
18 changed files with 1919 additions and 134 deletions
+1
View File
@@ -94,6 +94,7 @@ namespace Model
public virtual DbSet<AncestralTabletRegistrant> AncestralTabletRegistrant { get; set; }
public virtual DbSet<AncestralTabletStatus> AncestralTabletStatus { get; set; }
public virtual DbSet<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
public virtual DbSet<auto_enroll> auto_enroll { get; set; }
public virtual int pager_eztrust(Nullable<int> startRowIndex, Nullable<int> pageSize, string tableName, string columnName, string sqlWhere, string orderBy, ObjectParameter rowCount)
{
+35
View File
@@ -406,6 +406,10 @@ namespace Model
public Nullable<float> price { get; set; }
public Nullable<int> qty { get; set; }
public Nullable<System.DateTime> reg_time { get; set; }
public Nullable<bool> has_yang_limit { get; set; }
public Nullable<bool> has_chao_limit { get; set; }
public Nullable<int> yang_limit_count { get; set; }
public Nullable<int> chao_limit_count { get; set; }
public virtual actItem actItem { get; set; }
public virtual activity activity { get; set; }
@@ -677,6 +681,31 @@ namespace Model
using System;
using System.Collections.Generic;
public partial class auto_enroll
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public auto_enroll()
{
this.pro_order = new HashSet<pro_order>();
}
public int num { get; set; }
public int f_num { get; set; }
public System.DateTime start_date { get; set; }
public System.DateTime end_date { get; set; }
public string receipt_title { get; set; }
public string receipt_address { get; set; }
public virtual follower followers { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<pro_order> pro_order { get; set; }
}
}
namespace Model
{
using System;
using System.Collections.Generic;
public partial class bed_kind
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
@@ -803,6 +832,7 @@ namespace Model
public string smtp_def { get; set; }
public string use_sender { get; set; }
public string bed_order_no { get; set; }
public string last_auto_order_no { get; set; }
}
}
namespace Model
@@ -904,6 +934,7 @@ namespace Model
this.transfer_register1 = new HashSet<transfer_register>();
this.GuaDanOrder = new HashSet<GuaDanOrder>();
this.GuaDanOrderGuest = new HashSet<GuaDanOrderGuest>();
this.auto_enroll = new HashSet<auto_enroll>();
}
public int num { get; set; }
@@ -968,6 +999,8 @@ namespace Model
public virtual ICollection<GuaDanOrder> GuaDanOrder { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<GuaDanOrderGuest> GuaDanOrderGuest { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<auto_enroll> auto_enroll { get; set; }
}
}
namespace Model
@@ -1341,6 +1374,7 @@ namespace Model
public Nullable<int> introducer { get; set; }
public Nullable<bool> send_receipt { get; set; }
public string receipt_title { get; set; }
public Nullable<int> au_num { get; set; }
public virtual activity activity { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
@@ -1349,6 +1383,7 @@ namespace Model
public virtual follower follower1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<pro_order_detail> pro_order_detail { get; set; }
public virtual auto_enroll auto_enroll { get; set; }
}
}
namespace Model
+124
View File
@@ -190,6 +190,10 @@
<Property Name="price" Type="real" />
<Property Name="qty" Type="int" />
<Property Name="reg_time" Type="datetime" />
<Property Name="has_yang_limit" Type="bit" />
<Property Name="has_chao_limit" Type="bit" />
<Property Name="yang_limit_count" Type="int" />
<Property Name="chao_limit_count" Type="int" />
</EntityType>
<EntityType Name="activity_spares">
<Key>
@@ -330,6 +334,17 @@
<Property Name="num" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="title" Type="nvarchar" MaxLength="10" />
</EntityType>
<EntityType Name="auto_enroll">
<Key>
<PropertyRef Name="num" />
</Key>
<Property Name="num" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="f_num" Type="int" Nullable="false" />
<Property Name="start_date" Type="date" Nullable="false" />
<Property Name="end_date" Type="date" Nullable="false" />
<Property Name="receipt_title" Type="nvarchar(max)" />
<Property Name="receipt_address" Type="nchar" MaxLength="200" />
</EntityType>
<EntityType Name="bed_kind">
<Key>
<PropertyRef Name="num" />
@@ -401,6 +416,7 @@
<Property Name="smtp_def" Type="nvarchar" MaxLength="1" />
<Property Name="use_sender" Type="nvarchar" MaxLength="1" />
<Property Name="bed_order_no" Type="nvarchar" MaxLength="20" />
<Property Name="last_auto_order_no" Type="nvarchar" MaxLength="20" />
</EntityType>
<EntityType Name="country">
<Key>
@@ -697,6 +713,7 @@
<Property Name="introducer" Type="int" />
<Property Name="send_receipt" Type="bit" />
<Property Name="receipt_title" Type="nvarchar(max)" />
<Property Name="au_num" Type="int" />
</EntityType>
<EntityType Name="pro_order_detail">
<Key>
@@ -1265,6 +1282,18 @@
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_auto_enroll_followers">
<End Role="followers" Type="Self.followers" Multiplicity="1" />
<End Role="auto_enroll" Type="Self.auto_enroll" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="followers">
<PropertyRef Name="num" />
</Principal>
<Dependent Role="auto_enroll">
<PropertyRef Name="f_num" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_bed_kind_detail_bed_kind">
<End Role="bed_kind" Type="Self.bed_kind" Multiplicity="0..1" />
<End Role="bed_kind_detail" Type="Self.bed_kind_detail" Multiplicity="*" />
@@ -1643,6 +1672,18 @@
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_pro_order_auto_enroll">
<End Role="auto_enroll" Type="Self.auto_enroll" Multiplicity="0..1" />
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="auto_enroll">
<PropertyRef Name="num" />
</Principal>
<Dependent Role="pro_order">
<PropertyRef Name="au_num" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_pro_order_detail_actItem">
<End Role="actItem" Type="Self.actItem" Multiplicity="0..1">
<OnDelete Action="Cascade" />
@@ -2113,6 +2154,7 @@
<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="auto_enroll" EntityType="Self.auto_enroll" 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_order" EntityType="Self.bed_order" Schema="dbo" store:Type="Tables" />
@@ -2244,6 +2286,10 @@
<End Role="AncestralTabletArea" EntitySet="AncestralTabletArea" />
<End Role="AncestralTabletArea1" EntitySet="AncestralTabletArea" />
</AssociationSet>
<AssociationSet Name="FK_auto_enroll_followers" Association="Self.FK_auto_enroll_followers">
<End Role="followers" EntitySet="followers" />
<End Role="auto_enroll" EntitySet="auto_enroll" />
</AssociationSet>
<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_detail" EntitySet="bed_kind_detail" />
@@ -2368,6 +2414,10 @@
<End Role="activity" EntitySet="activity" />
<End Role="pro_order" EntitySet="pro_order" />
</AssociationSet>
<AssociationSet Name="FK_pro_order_auto_enroll" Association="Self.FK_pro_order_auto_enroll">
<End Role="auto_enroll" EntitySet="auto_enroll" />
<End Role="pro_order" EntitySet="pro_order" />
</AssociationSet>
<AssociationSet Name="FK_pro_order_detail_actItem" Association="Self.FK_pro_order_detail_actItem">
<End Role="actItem" EntitySet="actItem" />
<End Role="pro_order_detail" EntitySet="pro_order_detail" />
@@ -2729,6 +2779,10 @@
<Property Name="reg_time" Type="DateTime" Precision="3" />
<NavigationProperty Name="actItem" Relationship="Self.FK_activity_relating_actItem" FromRole="activity_relating" ToRole="actItem" />
<NavigationProperty Name="activity" Relationship="Self.FK_activity_relating_activity" FromRole="activity_relating" ToRole="activity" />
<Property Name="has_yang_limit" Type="Boolean" />
<Property Name="has_chao_limit" Type="Boolean" />
<Property Name="yang_limit_count" Type="Int32" />
<Property Name="chao_limit_count" Type="Int32" />
</EntityType>
<EntityType Name="activity_spares">
<Key>
@@ -2892,6 +2946,7 @@
<Property Name="smtp_def" Type="String" MaxLength="1" FixedLength="false" Unicode="true" />
<Property Name="use_sender" Type="String" MaxLength="1" FixedLength="false" Unicode="true" />
<Property Name="bed_order_no" Type="String" MaxLength="20" FixedLength="false" Unicode="true" />
<Property Name="last_auto_order_no" Type="String" MaxLength="20" FixedLength="false" Unicode="true" />
</EntityType>
<EntityType Name="country">
<Key>
@@ -2970,6 +3025,7 @@
<NavigationProperty Name="GuaDanOrder" Relationship="Model.FK_GuaDanOrder_Followers" FromRole="follower" ToRole="GuaDanOrder" />
<Property Name="search_keywords" Type="String" MaxLength="Max" FixedLength="false" Unicode="false" />
<NavigationProperty Name="GuaDanOrderGuest" Relationship="Model.FK_GuaDanOrderGuest_FOLLOWERS" FromRole="follower" ToRole="GuaDanOrderGuest" />
<NavigationProperty Name="auto_enroll" Relationship="Model.FK_auto_enroll_followers" FromRole="follower" ToRole="auto_enroll" />
</EntityType>
<EntityType Name="followers_tablet">
<Key>
@@ -3148,6 +3204,8 @@
<NavigationProperty Name="pro_order_detail" Relationship="Self.FK_pro_order_detail_pro_order" FromRole="pro_order" ToRole="pro_order_detail" />
<Property Name="send_receipt" Type="Boolean" />
<Property Name="receipt_title" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
<Property Name="au_num" Type="Int32" />
<NavigationProperty Name="auto_enroll" Relationship="Model.FK_pro_order_auto_enroll" FromRole="pro_order" ToRole="auto_enroll" />
</EntityType>
<EntityType Name="pro_order_detail">
<Key>
@@ -4545,6 +4603,15 @@
<End Role="GuaDanOrderGuest" EntitySet="GuaDanOrderGuest" />
<End Role="RegionAndRoomAndBedSchedule" EntitySet="RegionAndRoomAndBedSchedule" />
</AssociationSet>
<EntitySet Name="auto_enroll" EntityType="Model.auto_enroll" />
<AssociationSet Name="FK_auto_enroll_followers" Association="Model.FK_auto_enroll_followers">
<End Role="follower" EntitySet="followers" />
<End Role="auto_enroll" EntitySet="auto_enroll" />
</AssociationSet>
<AssociationSet Name="FK_pro_order_auto_enroll" Association="Model.FK_pro_order_auto_enroll">
<End Role="auto_enroll" EntitySet="auto_enroll" />
<End Role="pro_order" EntitySet="pro_order" />
</AssociationSet>
</EntityContainer>
<ComplexType Name="sp_helpdiagramdefinition_Result">
<Property Type="Int32" Name="version" Nullable="true" />
@@ -5262,6 +5329,45 @@
</Dependent>
</ReferentialConstraint>
</Association>
<EntityType Name="auto_enroll">
<Key>
<PropertyRef Name="num" />
</Key>
<Property Name="num" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="f_num" Type="Int32" Nullable="false" />
<Property Name="start_date" Type="DateTime" Precision="0" Nullable="false" />
<Property Name="end_date" Type="DateTime" Precision="0" Nullable="false" />
<Property Name="receipt_title" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
<Property Name="receipt_address" Type="String" MaxLength="200" FixedLength="true" Unicode="true" />
<NavigationProperty Name="followers" Relationship="Model.FK_auto_enroll_followers" FromRole="auto_enroll" ToRole="follower" />
<NavigationProperty Name="pro_order" Relationship="Model.FK_pro_order_auto_enroll" FromRole="auto_enroll" ToRole="pro_order" />
</EntityType>
<Association Name="FK_auto_enroll_followers">
<End Type="Model.follower" Role="follower" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
<End Type="Model.auto_enroll" Role="auto_enroll" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="follower">
<PropertyRef Name="num" />
</Principal>
<Dependent Role="auto_enroll">
<PropertyRef Name="f_num" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_pro_order_auto_enroll">
<End Type="Model.auto_enroll" Role="auto_enroll" Multiplicity="0..1" />
<End Type="Model.pro_order" Role="pro_order" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="auto_enroll">
<PropertyRef Name="num" />
</Principal>
<Dependent Role="pro_order">
<PropertyRef Name="au_num" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
@@ -5445,6 +5551,10 @@
<EntitySetMapping Name="activity_relating">
<EntityTypeMapping TypeName="Model.activity_relating">
<MappingFragment StoreEntitySet="activity_relating">
<ScalarProperty Name="chao_limit_count" ColumnName="chao_limit_count" />
<ScalarProperty Name="yang_limit_count" ColumnName="yang_limit_count" />
<ScalarProperty Name="has_chao_limit" ColumnName="has_chao_limit" />
<ScalarProperty Name="has_yang_limit" ColumnName="has_yang_limit" />
<ScalarProperty Name="num" ColumnName="num" />
<ScalarProperty Name="activity_num" ColumnName="activity_num" />
<ScalarProperty Name="actItem_num" ColumnName="actItem_num" />
@@ -5584,6 +5694,7 @@
<EntitySetMapping Name="companies">
<EntityTypeMapping TypeName="Model.company">
<MappingFragment StoreEntitySet="company">
<ScalarProperty Name="last_auto_order_no" ColumnName="last_auto_order_no" />
<ScalarProperty Name="num" ColumnName="num" />
<ScalarProperty Name="com_name" ColumnName="com_name" />
<ScalarProperty Name="com_mail" ColumnName="com_mail" />
@@ -5818,6 +5929,7 @@
<EntitySetMapping Name="pro_order">
<EntityTypeMapping TypeName="Model.pro_order">
<MappingFragment StoreEntitySet="pro_order">
<ScalarProperty Name="au_num" ColumnName="au_num" />
<ScalarProperty Name="receipt_title" ColumnName="receipt_title" />
<ScalarProperty Name="send_receipt" ColumnName="send_receipt" />
<ScalarProperty Name="order_no" ColumnName="order_no" />
@@ -6311,6 +6423,18 @@
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="auto_enroll">
<EntityTypeMapping TypeName="Model.auto_enroll">
<MappingFragment StoreEntitySet="auto_enroll">
<ScalarProperty Name="receipt_address" ColumnName="receipt_address" />
<ScalarProperty Name="receipt_title" ColumnName="receipt_title" />
<ScalarProperty Name="end_date" ColumnName="end_date" />
<ScalarProperty Name="start_date" ColumnName="start_date" />
<ScalarProperty Name="f_num" ColumnName="f_num" />
<ScalarProperty Name="num" ColumnName="num" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
+3
View File
@@ -162,6 +162,9 @@
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_RoomUuid" />
<AssociationConnector Association="Model.FK_GuaDanOrderGuest_StatusCode" />
<AssociationConnector Association="Model.FK_Schedule_GuaDanOrderGuest" />
<EntityTypeShape EntityType="Model.auto_enroll" Width="1.5" PointX="5.25" PointY="37.875" />
<AssociationConnector Association="Model.FK_auto_enroll_followers" />
<AssociationConnector Association="Model.FK_pro_order_auto_enroll" />
</Diagram>
</edmx:Diagrams>
</edmx:Designer>
+361 -7
View File
@@ -1,15 +1,20 @@
using System;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Office2010.Excel;
using Model;
using MyWeb;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using PagedList;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using PagedList;
using Newtonsoft.Json;
using System.Collections;
using DocumentFormat.OpenXml.Office2010.Excel;
using MyWeb;
using System.Data.Entity;
using System.Web.Razor.Tokenizer;
// api/Follower
//[ezAuthorize(Roles = "admin")]//群組:*
@@ -531,6 +536,203 @@ public class FollowerController : ApiController
}
[HttpGet]
[Route("api/follower/GetAutoEnrollList/{id}")]
public IHttpActionResult GetAutoEnrollList(int id)
{
var prod = _db.auto_enroll.Where(q => q.f_num == id).ToList();
var ret = new
{
list = prod.Select(x => new
{
num = x.num,
auto_enroll_start_date = x.start_date.ToString("yyyy-MM-dd"),
auto_enroll_end_date = x.end_date.ToString("yyyy-MM-dd"),
auto_enroll_receipt_title = x.receipt_title?? "",
auto_enroll_receipt_address = x.receipt_address?? "",
}),
};
return Ok(ret);
}
[HttpPost]
[Route("api/follower/SaveAutoEnrollList")]
public IHttpActionResult SaveAutoEnrollList([FromBody] Model.auto_enroll item)
{
Model.auto_enroll autoEnroll;
if (item.num == 0)
{
// ===== 新增 =====
autoEnroll = new Model.auto_enroll()
{
f_num = item.f_num,
start_date = item.start_date,
end_date = item.end_date,
receipt_title = string.IsNullOrEmpty(item.receipt_title) ? null : item.receipt_title.Trim(),
receipt_address = string.IsNullOrEmpty(item.receipt_address) ? null : item.receipt_address.Trim(),
}
;
_db.auto_enroll.Add(autoEnroll);
_db.SaveChanges();
CreateOrdersForActivities(item.f_num, autoEnroll.num, item.start_date, item.end_date, item.receipt_title, item.receipt_address);
}
else
{
// ===== 更新 =====
autoEnroll = _db.auto_enroll.Where(q => q.num == item.num).FirstOrDefault();
if (autoEnroll == null) return NotFound();
autoEnroll.start_date = item.start_date;
autoEnroll.end_date = item.end_date;
autoEnroll.receipt_title = item.receipt_title?.Trim() ?? null;
autoEnroll.receipt_address = item.receipt_address?.Trim() ?? null;
_db.SaveChanges();
CreateOrdersForActivities(item.f_num, autoEnroll.num, item.start_date, item.end_date, item.receipt_title, item.receipt_address);
}
try
{
var ret = new
{
num = autoEnroll.num,
start_date = autoEnroll.start_date.ToString("yyyy-MM-dd"),
end_date = autoEnroll.end_date.ToString("yyyy-MM-dd"),
receipt_title = autoEnroll.receipt_title,
receipt_address = autoEnroll.receipt_address,
};
return Ok(ret);
}
catch(Exception ex)
{
return InternalServerError(ex);
}
}
[HttpPost]
[Route("api/follower/GetAffectedOrders")]
public IHttpActionResult GetAffectedOrders([FromBody] Model.auto_enroll item, bool is_delete = false)
{
if (item == null) return BadRequest();
try
{
IQueryable<pro_order> query = _db.pro_order
.Where(o => o.f_num == item.f_num
&& o.order_no.StartsWith("AU")
&& o.au_num == item.num);
if (is_delete)
{
// 刪除:查期間內所有自動報名訂單
query = query.Where(o =>
o.activity.startDate_solar >= item.start_date &&
o.activity.startDate_solar <= item.end_date
);
}
else
{
// 修改:查不在新範圍內的訂單
query = query.Where(o =>
o.activity.startDate_solar < item.start_date ||
o.activity.startDate_solar > item.end_date
);
}
var rawOrders = query.Select(o => new
{
o.order_no,
o.activity.subject,
o.activity.startDate_solar
}).ToList();
var affectedOrders = rawOrders.Select(o => new
{
order_no = o.order_no,
activityname = o.subject,
activitydate = o.startDate_solar?.ToString("yyyy/MM/dd") ?? ""
}).ToList();
return Ok(new
{
count = affectedOrders.Count,
list = affectedOrders
});
}
catch (Exception ex)
{
return InternalServerError(ex.GetBaseException());
}
}
[HttpDelete]
[Route("api/follower/DeleteAutoEnroll/{id}")]
public IHttpActionResult DeleteAutoEnroll(int id)
{
try
{
var prod = _db.auto_enroll.Where(q => q.num == id).FirstOrDefault();
if (prod != null)
{
_db.auto_enroll.Remove(prod);
_db.SaveChanges();
return Ok();
}
else return NotFound();
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet]
[Route("api/follower/GetUnfilledActivityOrders/{id}")]
public IHttpActionResult GetUnfilledActivityOrders(int id, int page, int pageSize = 10, string sortBy = "", bool sortDesc = false)
{
try
{
var config = _db.auto_enroll.FirstOrDefault(x => x.num == id);
if (config == null) return NotFound();
var query = from o in _db.pro_order
join a in _db.activities on o.activity_num equals a.num
where o.f_num == config.f_num
&& a.startDate_solar >= config.start_date
&& a.startDate_solar <= config.end_date
&& !_db.pro_order_detail.Any(d => d.order_no == o.order_no)
select new { o, a };
int totalCount = query.Count();
var pagedData = query
.OrderByDescending(x => x.o.order_no)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToList()
.Select(x => new {
order_no = x.o.order_no,
startdate = x.a.startDate_solar?.ToString("yyyy/MM/dd") ?? "",
enddate = x.a.endDate_solar?.ToString("yyyy/MM/dd") ?? "",
activityname = x.a.subject,
category = x.a.activity_category_kind?.kind ?? ""
});
return Ok(new
{
list = pagedData,
count = totalCount,
page = page,
pageSize = pageSize
});
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPost]
[Route("api/follower/GetTabletList")]
@@ -672,6 +874,31 @@ public class FollowerController : ApiController
return Ok(data);
}
[HttpPost]
[Route("api/follower/pending_orders")]
public IHttpActionResult GetPendingOrders(int id, string targetDate)
{
DateTime today = DateTime.Today;
if (!DateTime.TryParse(targetDate, out DateTime limitDate))
{
limitDate = new DateTime(2099, 12, 31);
}
var orderrecord = _db.pro_order
.Where(x => x.f_num == id && x.activity.startDate_solar >= today && x.activity.startDate_solar < limitDate)
.Include(x => x.activity)
.ToList();
var data = new
{
list = orderrecord.Select(x => new
{
orderno = x.order_no,
activitydate = x.activity.startDate_solar.Value.ToString("yyyy/MM/dd"),
activityname = x.activity.subject,
})
};
return Ok(data);
}
[HttpPost]
[Route("api/follower/totalorderamount")]
public IHttpActionResult GetTotalOrderCount(int id)
{
@@ -707,5 +934,132 @@ public class FollowerController : ApiController
};
return Ok(data);
}
private void CreateOrdersForActivities(int f_num, int au_num, DateTime start_date, DateTime end_date, string receipt_title, string receipt_address)
{
var follower = _db.followers.Where(x => x.num == f_num).FirstOrDefault();
var activities = _db.activities
.Where(x =>
x.startDate_solar >= start_date &&
x.startDate_solar <= end_date
)
.ToList();
foreach (var activity in activities)
{
var existOrder = _db.pro_order
.Where(o => o.activity_num == activity.num && o.f_num == f_num)
.FirstOrDefault();
if (existOrder != null) {
existOrder.au_num = au_num;
_db.SaveChanges();
continue;
}
string newOrderNo = AutoOrderService.CreateAutoOrderNumber(_db);
string finalPhone = follower?.cellphone ?? follower?.phone ?? "";
var newOrder = new pro_order
{
order_no = newOrderNo,
up_time = DateTime.Now,
reg_time = DateTime.Now,
keyin1 = "A01",
f_num = f_num,
au_num = au_num,
phone = finalPhone,
address = string.IsNullOrEmpty(receipt_address) ? "" : receipt_address,
activity_num = activity.num,
receipt_title = receipt_title ?? "",
demo = "",
customize_data = "",
};
_db.pro_order.Add(newOrder);
// 抓取同活動分類的上一筆訂單,複製品項
var latestOrder = _db.pro_order
.Where(o =>
o.f_num == f_num &&
o.activity.kind == activity.kind &&
o.order_no != newOrderNo &&
_db.pro_order_detail.Any(d => d.order_no == o.order_no)
)
.OrderByDescending(o => o.order_no)
.FirstOrDefault();
if (latestOrder != null)
{
var prevDetails = _db.pro_order_detail
.Where(d => d.order_no == latestOrder.order_no)
.ToList();
foreach (var detail in prevDetails)
{
var newDetail = new pro_order_detail
{
order_no = newOrderNo,
actItem_num = detail.actItem_num,
parent_num = detail.parent_num,
print_id = detail.print_id,
f_num = detail.f_num,
f_num_tablet = detail.f_num_tablet,
address = detail.address,
from_id = detail.from_id,
from_id_tablet = detail.from_id_tablet,
bed_type = detail.bed_type,
qty = detail.qty,
price = detail.price,
start_date = DateTime.Today,
pay = detail.pay,
keyin1 = detail.keyin1,
demo = detail.demo,
customize_data = detail.customize_data,
printed_files = detail.printed_files,
UpdateTime = DateTime.Now,
};
_db.pro_order_detail.Add(newDetail);
}
}
}
_db.SaveChanges();
}
}
public static class AutoOrderService
{
private static readonly object _lock = new object();
public static string CreateAutoOrderNumber(Model.ezEntities _db)
{
lock (_lock)
{
string prefix = "AU" + DateTime.Now.ToString("yyMMdd");
var company = _db.companies.FirstOrDefault(q => q.num == 1);
if (company == null) return "";
string order_no;
if (!string.IsNullOrEmpty(company.last_auto_order_no) && company.last_auto_order_no.StartsWith(prefix))
{
string serialStr = company.last_auto_order_no.Replace(prefix, "");
int nextSerial = int.Parse(serialStr) + 1;
order_no = prefix + nextSerial.ToString("0000");
}
else
{
order_no = prefix + "0001";
}
company.last_auto_order_no = order_no;
_db.SaveChanges();
return order_no;
}
}
}
+148 -3
View File
@@ -7,6 +7,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -802,7 +803,7 @@ public class activityController : ApiController
//已有值
var count = qry.Count(); //pageSize = count;//一次取回??
var qryList = (pageSize > 0) ? qry.OrderBy(a=>a.num).ToPagedList(page, pageSize).ToList() : qry.ToList();
var qryList = (pageSize > 0) ? qry.OrderBy(a => a.num).ToPagedList(page, pageSize).ToList() : qry.ToList();
var ret = new
{
list = qryList.Select(x => new
@@ -958,6 +959,10 @@ public class activityController : ApiController
},
price = x.price ?? 0,
qty = x.qty ?? 0,
has_yang_limit = x.has_yang_limit ?? false,
has_chao_limit = x.has_yang_limit ?? false,
yang_limit_count = x.yang_limit_count ?? 0,
chao_limit_count = x.chao_limit_count ?? 0,
files = x.actItem?.actItem_files.Select(f => new
{
num = f.file.num,
@@ -1175,6 +1180,10 @@ public class activityController : ApiController
if (item.qty.HasValue) { _data.qty = item.qty.Value; }
else { _data.qty = null; }
_data.reg_time = DateTime.Now;
if (item.has_yang_limit.HasValue) { _data.has_yang_limit = item.has_yang_limit; }
if (item.yang_limit_count >= 0) { _data.yang_limit_count = item.yang_limit_count.Value; }
if (item.has_chao_limit.HasValue) { _data.has_chao_limit = item.has_chao_limit; }
if (item.chao_limit_count >= 0) { _data.chao_limit_count = item.chao_limit_count.Value; }
_db.SaveChanges();
var ret = _data.num;
@@ -1195,6 +1204,10 @@ public class activityController : ApiController
if (item.qty.HasValue) { _data.qty = item.qty.Value; }
else { _data.qty = null; }
_data.reg_time = DateTime.Now;
if (item.has_yang_limit.HasValue) { _data.has_yang_limit = item.has_yang_limit; }
if (item.yang_limit_count >= 0) { _data.yang_limit_count = item.yang_limit_count.Value; }
if (item.has_chao_limit.HasValue) { _data.has_chao_limit = item.has_chao_limit; }
if (item.chao_limit_count >= 0) { _data.chao_limit_count = item.chao_limit_count.Value; }
_db.activity_relating.Add(_data);
_db.SaveChanges();
@@ -1547,13 +1560,13 @@ public class activityController : ApiController
var r1 = qry.ToList();
var r2 = r1.Select(x => new { num = x.num, subject = x.subject });
var count = qry.Count();
// 計算昨天和今天的日期範圍
var yesterdayStart = _now.Date.AddDays(-1);
var yesterdayEnd = _now.Date;
var todayStart = _now.Date;
var todayEnd = _now.Date.AddDays(1);
var ret = new
{
list = r1.Select(x => new
@@ -1607,4 +1620,136 @@ public class activityController : ApiController
return Ok(ret);
}
[HttpGet]
[Route("api/activity/GetUnfilledOrdersByActivity/{num}")]
public IHttpActionResult GetUnfilledOrdersByActivity(int num)
{
try
{
var activityExists = _db.activities.Any(a => a.num == num);
if (!activityExists) return NotFound();
var query = from o in _db.pro_order
join f in _db.followers on o.f_num equals f.num into fg
from f in fg.DefaultIfEmpty()
where o.activity_num == num
&& !_db.pro_order_detail.Any(d => d.order_no == o.order_no)
select new { o, f };
MyWeb.encrypt encrypt = new MyWeb.encrypt();
var unfilledOrders = query.ToList().Select(x => new
{
order_no = x.o.order_no,
f_number = x.f.f_number,
u_name = x.f != null ? x.f.u_name : "未知",
phone = !string.IsNullOrEmpty(x.f.cellphone) ? encrypt.DecryptAutoKey(x.f.cellphone) : (encrypt.DecryptAutoKey(x.f.phone) ?? ""),
order_date = x.o.reg_time.HasValue ? x.o.reg_time.Value.ToString("yyyy/MM/dd") : "",
}).ToList();
return Ok(new
{
list = unfilledOrders,
count = unfilledOrders.Count
});
}
catch (Exception ex)
{
return InternalServerError(ex.GetBaseException());
}
}
[HttpPost]
[Route("api/activity/TriggerAutoEnroll/{activity_num}")]
public IHttpActionResult TriggerAutoEnroll(int activity_num)
{
try
{
var activity = _db.activities.FirstOrDefault(a => a.num == activity_num);
if (activity == null) return NotFound();
if (!activity.startDate_solar.HasValue) return BadRequest("該活動沒有設定開始日期,無法執行自動報名。");
DateTime actDate = activity.startDate_solar.Value;
var validConfigs = _db.auto_enroll
.Where(ae => actDate >= ae.start_date && actDate <= ae.end_date)
.ToList();
int successCount = 0;
foreach (var config in validConfigs)
{
if (_db.pro_order.Any(o => o.activity_num == activity_num && o.f_num == config.f_num))
continue;
var follower = _db.followers.FirstOrDefault(f => f.num == config.f_num);
string newOrderNo = AutoOrderService.CreateAutoOrderNumber(_db);
var newOrder = new pro_order
{
order_no = newOrderNo,
up_time = DateTime.Now,
reg_time = DateTime.Now,
keyin1 = "A01",
f_num = config.f_num,
au_num = config.num,
phone = follower?.cellphone ?? follower?.phone ?? "",
address = config.receipt_address ?? "",
activity_num = activity_num,
receipt_title = config.receipt_title ?? "",
demo = "系統於新增活動時自動報名",
};
_db.pro_order.Add(newOrder);
CopyLatestOrderDetails(newOrderNo, config.f_num, (int)activity.kind);
successCount++;
}
_db.SaveChanges();
return Ok(new
{
message = $"自動報名執行完畢,共為 {successCount} 位信眾完成報名。",
count = successCount
});
}
catch (Exception ex)
{
return InternalServerError(ex.GetBaseException());
}
}
private void CopyLatestOrderDetails(string newOrderNo, int f_num, int activityKind)
{
var latestOrder = _db.pro_order
.Where(o => o.f_num == f_num && o.activity.kind == activityKind && _db.pro_order_detail.Any(d => d.order_no == o.order_no))
.OrderByDescending(o => o.order_no)
.FirstOrDefault();
if (latestOrder != null)
{
var prevDetails = _db.pro_order_detail.Where(d => d.order_no == latestOrder.order_no).ToList();
foreach (var detail in prevDetails)
{
_db.pro_order_detail.Add(new pro_order_detail
{
order_no = newOrderNo,
actItem_num = detail.actItem_num,
parent_num = detail.parent_num,
print_id = detail.print_id,
f_num = detail.f_num,
f_num_tablet = detail.f_num_tablet,
address = detail.address,
from_id = detail.from_id,
from_id_tablet = detail.from_id_tablet,
qty = detail.qty,
price = detail.price,
start_date = DateTime.Today,
pay = 0,
UpdateTime = DateTime.Now
});
}
}
}
}
+93 -74
View File
@@ -7,6 +7,8 @@ using System;
using System.Activities.Expressions;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Diagnostics;
using System.IdentityModel.Metadata;
using System.Linq;
@@ -351,7 +353,7 @@ public class orderController : ApiController
//var qry1 = _db.pro_order_detail.AsEnumerable();
//qry1 = qry1.Where(o => o.order_no == order_no);
//var qry1 = prod.pro_order_detail.AsEnumerable();
var qry1 = prod.pro_order_detail.AsQueryable();
var qry1 = prod.pro_order_detail.AsQueryable().Include(o => o.pro_order.activity.activity_relating);
//if (!string.IsNullOrEmpty(q.subject))
// qry = qry.Where(o => o.subject.Contains(q.subject));
@@ -380,7 +382,7 @@ public class orderController : ApiController
qry1 = qry1.OrderByDescending(o => o.num);
}
var tdesc = publicFun.enum_desc<Model.pro_order.detailKeyin1>();
int i = 1;
@@ -390,82 +392,91 @@ public class orderController : ApiController
(List<pro_order_detail>)qry1_list.ToPagedList(page, pageSize);
var count = qry1_list.Count();
var ret = new
{
list = qry1_list.Select(x => new
{
id = i++,
num = x.num,
order_no = x.order_no,
actitem_num_selected = new
list = qry1_list.Select(x => {
var tmpActivityRelating = x.pro_order?.activity?.activity_relating?.Where(a => a.actItem_num == x.actItem_num).FirstOrDefault();
return new
{
text = x.actItem_num.HasValue ? x.actItem.subject : "",
val = x.actItem_num.HasValue ? x.actItem_num.Value : 0,
},
parent_num = x.parent_num,
f_num_selected = new
{
text = x.f_num.HasValue ? x.follower.u_name : "",
val = x.f_num.HasValue ? x.f_num.Value : 0,
},
f_num_tablet = x.f_num_tablet,
print_id = x.print_id,
address = x.address,
due_date = x.due_date,
start_date = x.start_date,
extend_date = x.extend_date,
from_id_selected = new
{
text = x.from_id.HasValue ? x.follower1.u_name : "",
val = x.from_id.HasValue ? x.from_id : 0,
},
from_id_tablet = x.from_id_tablet,
price = x.price ?? 0,
qty = x.qty ?? 0,
writeBedQty = bedDt.Where(b => b.bed_order.o_detail_id.Value == x.num && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count(), //已劃數量
notBedQty = bedDt.Where(b => b.bed_order.o_detail_id.Value == x.num && (!b.checkIn_date.HasValue || !b.bed_kind_detail_id.HasValue)).Count(), //未劃數量
//total = x.total.HasValue ? x.total.Value : 0,
category = x.actItem?.category,
//pay = x.pay ?? 0,
pay = x.pro_order_record.Select(c => c.price).Sum(),
pay_date = x.pay_date,
keyin1_selected = new
{
text = tdesc[x.keyin1.HasValue && x.keyin1.Value > 0 ? x.keyin1.Value : 1],
val = x.keyin1,
},
demo = x.demo,
files = x.actItem?.actItem_files.Select(f => new
{
num = f.file.num,
subject = f.file.subject,
word = f.file.word,
cuz_column = f.file.customize_data ?? "", //??
paperset = f.file.paperset ?? "",
}),
customize_data = x.customize_data ?? "",
customize_data_comb = new
{
from_id_cuz_data = "",
activity_cuz_data = "",
actitem_cuz_data = "",
order_cuz_data = "",
},
printed_files = x.printed_files ?? "",
isPackage = (x.actItem.act_bom
.Any(ab => ab.package_num == null && ab.item_num != null)
? 1 : 0),
bom_order = (x.actItem.act_bom
.Any(ab => ab.package_num == null && ab.item_num != null)
? x.num.ToString()
: (x.parent_num.ToString() + x.num.ToString())
),
//cash_record = x.pro_order_record.Select( c => new {
// c,
// //pay_kind = tdesc2[c.payment.HasValue && x.keyin1.Value > 0 ? x.keyin1.Value : 1],
//}),
has_yang_limit = tmpActivityRelating?.has_yang_limit ?? false,
has_chao_limit = tmpActivityRelating?.has_chao_limit ?? false,
yang_limit_count = tmpActivityRelating?.yang_limit_count ?? 0,
chao_limit_count = tmpActivityRelating?.chao_limit_count ?? 0,
id = i++,
num = x.num,
order_no = x.order_no,
actitem_num_selected = new
{
text = x.actItem_num.HasValue ? x.actItem.subject : "",
val = x.actItem_num.HasValue ? x.actItem_num.Value : 0,
},
parent_num = x.parent_num,
f_num_selected = new
{
text = x.f_num.HasValue ? x.follower.u_name : "",
val = x.f_num.HasValue ? x.f_num.Value : 0,
},
f_num_tablet = x.f_num_tablet,
print_id = x.print_id,
address = x.address,
due_date = x.due_date,
start_date = x.start_date,
extend_date = x.extend_date,
from_id_selected = new
{
text = x.from_id.HasValue ? x.follower1.u_name : "",
val = x.from_id.HasValue ? x.from_id : 0,
},
from_id_tablet = x.from_id_tablet,
price = x.price ?? 0,
qty = x.qty ?? 0,
writeBedQty = bedDt.Where(b => b.bed_order.o_detail_id.Value == x.num && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count(), //已劃數量
notBedQty = bedDt.Where(b => b.bed_order.o_detail_id.Value == x.num && (!b.checkIn_date.HasValue || !b.bed_kind_detail_id.HasValue)).Count(), //未劃數量
//total = x.total.HasValue ? x.total.Value : 0,
category = x.actItem?.category,
//pay = x.pay ?? 0,
pay = x.pro_order_record.Select(c => c.price).Sum(),
pay_date = x.pay_date,
keyin1_selected = new
{
text = tdesc[x.keyin1.HasValue && x.keyin1.Value > 0 ? x.keyin1.Value : 1],
val = x.keyin1,
},
demo = x.demo,
files = x.actItem?.actItem_files.Select(f => new
{
num = f.file.num,
subject = f.file.subject,
word = f.file.word,
cuz_column = f.file.customize_data ?? "", //??
paperset = f.file.paperset ?? "",
}),
customize_data = x.customize_data ?? "",
customize_data_comb = new
{
from_id_cuz_data = "",
activity_cuz_data = "",
actitem_cuz_data = "",
order_cuz_data = "",
},
printed_files = x.printed_files ?? "",
isPackage = (x.actItem.act_bom
.Any(ab => ab.package_num == null && ab.item_num != null)
? 1 : 0),
bom_order = (x.actItem.act_bom
.Any(ab => ab.package_num == null && ab.item_num != null)
? x.num.ToString()
: (x.parent_num.ToString() + x.num.ToString())
),
//cash_record = x.pro_order_record.Select( c => new {
// c,
// //pay_kind = tdesc2[c.payment.HasValue && x.keyin1.Value > 0 ? x.keyin1.Value : 1],
//}),
})
};
})
.ToList()
.OrderByDescending(x => (x.isPackage + (x.parent_num == null ? 0 : 1)))
//.ThenBy(x => (x.parent_num == null ? 1 : 2)) // Top-level items first
@@ -511,6 +522,10 @@ public class orderController : ApiController
text = ar.actItem.subject,
val = ar.actItem_num,
},
has_yang_limit = ar.has_yang_limit ?? false,
has_chao_limit = ar.has_chao_limit ?? false,
yang_limit_count = ar.yang_limit_count ?? 0,
chao_limit_count = ar.chao_limit_count ?? 0,
parent_num = q.num,
f_num_selected = new
{
@@ -591,6 +606,10 @@ public class orderController : ApiController
text = x.actItem.subject,
val = x.actItem.num,
},
has_yang_limit = x.has_yang_limit,
has_chao_limit = x.has_chao_limit,
yang_limit_count = x.yang_limit_count,
chao_limit_count = x.chao_limit_count,
f_num_selected = new
{
text = "",
+1 -4
View File
@@ -604,10 +604,7 @@
</div>
</div>
<div class="row mb-1 label-sm-right">
<label class="col-sm-2 col-form-label">料號</label>
<div class="col-sm-4">
<asp:TextBox ID="PARTNO" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入料號"></asp:TextBox>
</div>
<label class="col-sm-2 col-form-label">項目名稱 *</label>
<div class="col-sm-4">
<asp:TextBox ID="subject" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入品項名稱"></asp:TextBox>
+1 -4
View File
@@ -42,7 +42,6 @@ public partial class admin_activity_item_reg : MyWeb.config
BuildKind();
subject.Text = prod.subject;
print_init.Text = prod.print_init;
PARTNO.Text = prod.partno;
//kind.SelectedValue = prod.kind.ToString();
if (prod.kind.HasValue)
{
@@ -120,8 +119,7 @@ public partial class admin_activity_item_reg : MyWeb.config
Model.actItem actItem = new Model.actItem();//新增
int maxSort = _db.actItems.Max(x => (int?)x.sort_order) ?? 0;
actItem.subject = subject.Text;
actItem.print_init = print_init.Text;
actItem.partno = PARTNO.Text;
actItem.print_init = print_init.Text;
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
@@ -169,7 +167,6 @@ public partial class admin_activity_item_reg : MyWeb.config
{
actItem.subject = subject.Text;
actItem.print_init = print_init.Text;
actItem.partno = PARTNO.Text;
//if (!isStrNull(kind.SelectedValue)) { actItem.kind = Val(kind.SelectedValue); } else { actItem.kind = null; }
if (!isStrNull(category.SelectedValue)) { actItem.category = Val(category.SelectedValue); } else { actItem.category = null; }
if (!isStrNull(kind.Value)) { actItem.kind = Val(kind.Value); } else { actItem.kind = null; }
+223 -2
View File
@@ -165,6 +165,8 @@
{ text: '* 品項名稱', value: 'act_item_selected.text', sortable: false },
{ text: '預設金額', value: 'price', sortable: false },
{ text: '數量', value: 'qty', sortable: false },
{ text: '陽上/祈福人數限制', value: 'limit_yang', sortable: false },
{ text: '超渡人數限制', value: 'limit_chao', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "200px" },
],
footersDetail: {
@@ -191,6 +193,10 @@
price: 0,
qty: 0,
files: [],
has_yang_limit: false,
has_chao_limit: false,
yang_limit_count: 0,
chao_limit_count: 0,
},
defaultItem: {
id: 0,
@@ -203,6 +209,10 @@
price: 0,
qty: 0,
files: [],
has_yang_limit: false,
has_chao_limit: false,
yang_limit_count: 0,
chao_limit_count: 0,
},
//列印
data_table: {
@@ -267,10 +277,25 @@
order_dialog: {
show: false,
},
unfilled_list: {
loading: false,
search: '',
headers: [
{ text: '訂單編號', value: 'order_no' },
{ text: '信眾編號', value: 'f_number' },
{ text: '信眾姓名', value: 'u_name' },
{ text: '聯絡電話', value: 'phone' },
{ text: '建立日期', value: 'order_date' },
],
items: [
{ order_no: "D", member_name: "S", order_date:"2025-12-07"}
],
},
}
},
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1
this.loadUnfilledList();
//console.log("mounted");
},
watch: {
@@ -434,9 +459,8 @@
this.close();
},
spliceNullData() {
//if new data ,then splice it
if (this.editedItem.num == 0) {
if (this.editedItem.num == 0) {
for (var i = 0; i < this.desserts.map(x => x.id).length; i++) {
if (this.desserts[i].id == this.editedItem.id) {
this.desserts.splice(i, 1); break;
@@ -482,6 +506,10 @@
actItem_num: this.editedItem.act_item_selected.val,
price: this.editedItem.price,
qty: this.editedItem.qty,
has_yang_limit: this.editedItem.has_yang_limit,
has_chao_limit: this.editedItem.has_chao_limit,
yang_limit_count: this.editedItem.yang_limit_count,
chao_limit_count: this.editedItem.chao_limit_count,
}
axios
.post(HTTP_HOST + 'api/activity/SaveRelatingData', pro_order_detail)
@@ -808,6 +836,113 @@
const _date = $('#<%= startDate_solar.ClientID%>').val();
return _subject + " " + _date;
},
loadUnfilledList() {
if (!this.this_id) return;
this.unfilled_list.loading = true;
axios.get(HTTP_HOST + 'api/activity/GetUnfilledOrdersByActivity/' + this.this_id)
.then(response => {
this.unfilled_list.items = response.data.list || [];
})
.catch(error => {
console.log(error);
this.snackbar.text = "名單載入失敗:" + error;
this.snackbar.show = true;
})
.finally(() => {
this.unfilled_list.loading = false;
});
},
async printUnfilledList() {
if (!this.this_id) return;
try {
const response = await axios.get(
HTTP_HOST + `api/activity/GetUnfilledOrdersByActivity/${this.this_id}`,
{ params: { page: 1, pageSize: 99999 } }
);
const allItems = response.data.list || [];
if (allItems.length === 0) {
this.snackbar.text = "目前沒有未填寫品項的資料可供列印!";
this.snackbar.show = true;
return;
}
const activityTitle = this.titleword();
const rows = allItems.map(item => `
<tr>
<td>${item.order_no}</td>
<td>${item.f_number || ''}</td>
<td>${item.u_name}</td>
<td>${item.phone}</td>
<td>${item.order_date}</td>
</tr>
`).join('');
const win = window.open('', '_blank');
win.document.write(`
<html>
<head>
<title>未填寫品項名單 - ${activityTitle}</title>
<style>
body { font-family: "Microsoft JhengHei", Arial, sans-serif; padding: 20px; color: #000; }
.header-container { text-align: center; margin-bottom: 30px; }
h2 { margin-bottom: 5px; font-size: 24px; }
h4 { margin-top: 0; color: #333; font-weight: normal; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #000; padding: 10px 8px; text-align: left; font-size: 14px; }
th { background-color: #eee; font-weight: bold; }
.text-center { text-align: center; }
@media print {
@page { margin: 1.5cm; }
button { display: none; }
}
</style>
</head>
<body>
<div class="header-container">
<h2>尚未報名品項之信眾清單</h2>
<h4>活動名稱:${activityTitle}</h4>
</div>
<table>
<thead>
<tr>
<th width="18%">訂單編號</th>
<th width="15%">信眾編號</th>
<th width="20%">信眾姓名</th>
<th width="20%">聯絡電話</th>
<th width="27%">建單日期</th>
</tr>
</thead>
<tbody>${rows}</tbody>
</table>
<div style="margin-top: 20px; text-align: right; font-size: 12px;">
列印時間:${new Date().toLocaleString()}
</div>
</body>
</html>
`);
win.document.close();
// 確保內容載入完成後再呼叫列印
setTimeout(() => {
win.print();
win.close();
}, 300);
} catch (error) {
console.error("列印出錯:", error);
this.snackbar.text = "讀取列印資料失敗:" + error;
this.snackbar.show = true;
}
}
},
computed: {
},
@@ -847,6 +982,10 @@
<button v-if="this_id!=''" class="nav-link" id="sec2-tab3" data-bs-toggle="tab" data-bs-target="#sec2-page3"
type="button" role="tab" aria-controls="profile" aria-selected="false">
備品項目</button>
<button v-if="this_id!=''" class="nav-link" id="sec2-tab4" data-bs-toggle="tab" data-bs-target="#sec2-page4"
type="button" role="tab" aria-controls="profile" aria-selected="false" @click="loadUnfilledList">
未填寫名單
</button>
</div>
</nav>
</div>
@@ -1019,6 +1158,54 @@
<v-text-field v-model="editedItem.qty" :hide-details="true" dense single-line v-if="item.id === editedItem.id" ></v-text-field>
<span v-else>{{item.qty}}</span>
</template>
<template v-slot:item.limit_yang="{ item }">
<div class="d-flex align-center">
<v-text-field v-model="editedItem.yang_limit_count" v-if="item.id === editedItem.id"
type="number"
dense
:hide-details="true"
single-line
:disabled="!editedItem.has_yang_limit"
suffix="人" >
</v-text-field>
<v-checkbox v-if="item.id === editedItem.id"
v-model="editedItem.has_yang_limit"
label="不限"
hide-details
class="ml-2 mt-0"
:true-value="false"
:false-value="true"
:disabled="item.id !== editedItem.id">
</v-checkbox>
<span v-if="item.id !== editedItem.id && !item.has_yang_limit">不限</span>
<span v-if="item.id !== editedItem.id && item.has_yang_limit">{{item.yang_limit_count}} 人</span>
</div>
</template>
<template v-slot:item.limit_chao="{ item }">
<div class="d-flex align-center">
<v-text-field v-model="editedItem.chao_limit_count" v-if="item.id === editedItem.id"
type="number"
dense
:hide-details="true"
single-line
:disabled="!editedItem.has_chao_limit"
suffix="人" >
</v-text-field>
<v-checkbox v-if="item.id === editedItem.id"
v-model="editedItem.has_chao_limit"
label="不限"
hide-details
class="ml-2 mt-0"
:true-value="false"
:false-value="true"
:disabled="item.id !== editedItem.id">
</v-checkbox>
<span v-if="item.id !== editedItem.id && !item.has_chao_limit">不限</span>
<span v-if="item.id !== editedItem.id && item.has_chao_limit">{{item.chao_limit_count}} 人</span>
</div>
</template>
<template v-slot:item.actions="{ item }">
<template v-if="item.id === editedItem.id">
<v-icon color="red" class="mr-2" @click="cancel">
@@ -1128,6 +1315,40 @@
</div>
<div class="tab-pane fade" id="sec2-page4" role="tabpanel" aria-labelledby="sec2-tab4" v-if="this_id!=''">
<v-card class="mx-auto" outlined id="print-unfilled-area">
<v-data-table
:headers="unfilled_list.headers"
:items="unfilled_list.items"
:loading="unfilled_list.loading"
:search="unfilled_list.search"
class="elevation-1"
fixed-header
height="350px">
<template v-slot:top>
<v-toolbar flat color="white" class="d-print-none">
<div class="d-flex w-100">
<v-text-field
v-model="unfilled_list.search"
append-icon="mdi-magnify"
label="搜尋姓名或訂單號"
dense outlined single-line hide-details>
</v-text-field>
<v-btn color="primary" class="ml-2 white--text" @click="printUnfilledList">
<v-icon left>mdi-printer</v-icon>列印所有名單
</v-btn>
</div>
</v-toolbar>
</template>
<template v-slot:item.status="{ item }">
<v-chip small color="error">未選品項</v-chip>
</template>
</v-data-table>
</v-card>
</div>
</div>
</asp:Panel>
</div>
+113 -3
View File
@@ -235,6 +235,36 @@ public partial class admin_activity_reg : MyWeb.config
#endregion
#region
protected string createOrderNumber()
{
Application.Lock();
string order_no = "AA" + DateTime.Now.ToString("yyMMdd");
var qry = _db.companies.AsQueryable();
//var prod = qry.Where(q => q.last_order_no.Contains(order_no)).FirstOrDefault();
var prod = qry.Where(q => q.num == 1).FirstOrDefault();
if (prod != null)
{
if (!isStrNull(prod.last_order_no) && prod.last_order_no.Contains(order_no))
{
int tmp = Convert.ToInt32(prod.last_order_no.Replace(order_no, "")) + 1;
order_no = order_no + tmp.ToString("0000");
}
else
{
order_no = order_no + "0001";
}
prod.last_order_no = order_no;
_db.SaveChanges();
}
else
order_no = "";
Application.UnLock();
return order_no;
}
protected void add_Click(object sender, EventArgs e)
{
@@ -290,9 +320,10 @@ public partial class admin_activity_reg : MyWeb.config
int _id = activity.num;
if (_id > 0)
{
RunAutoEnroll(_id);
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Insert, subject.Text);
Response.Redirect("index.aspx");
}
else
@@ -367,6 +398,8 @@ public partial class admin_activity_reg : MyWeb.config
activity.category_kind = Val(category_kind.Value);
_db.SaveChanges();
RunAutoEnroll(activity.num);
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Activity, (int)Model.admin_log.Status.Update, subject.Text);
}
@@ -386,8 +419,85 @@ public partial class admin_activity_reg : MyWeb.config
}
}
private void RunAutoEnroll(int activityNum)
{
var activity = _db.activities.FirstOrDefault(a => a.num == activityNum);
if (activity == null || !activity.startDate_solar.HasValue) return;
DateTime actDate = activity.startDate_solar.Value;
var validConfigs = _db.auto_enroll
.Where(ae => actDate >= ae.start_date && actDate <= ae.end_date)
.ToList();
foreach (var config in validConfigs)
{
if (_db.pro_order.Any(o => o.activity_num == activity.num && o.f_num == config.f_num))
continue;
var follower = _db.followers.FirstOrDefault(f => f.num == config.f_num);
if (follower == null) continue;
string newOrderNo = AutoOrderService.CreateAutoOrderNumber(_db);
Model.pro_order proOrder = new Model.pro_order
{
order_no = newOrderNo,
up_time = DateTime.Now,
reg_time = DateTime.Now,
keyin1 = "A01",
f_num = follower.num,
au_num = config.num,
phone = !string.IsNullOrEmpty(follower.cellphone) ? follower.cellphone : (follower.phone ?? ""),
activity_num = activity.num,
address = config.receipt_address ?? "",
receipt_title = config.receipt_title ?? "",
demo = "",
customize_data = ""
};
_db.pro_order.Add(proOrder);
CopyLatestOrderDetails(newOrderNo, config.f_num, (int)activity.kind);
}
_db.SaveChanges();
}
private void CopyLatestOrderDetails(string newOrderNo, int f_num, int activityKind)
{
var latestOrder = _db.pro_order
.Where(o => o.f_num == f_num && o.activity.kind == activityKind && _db.pro_order_detail.Any(d => d.order_no == o.order_no))
.OrderByDescending(o => o.order_no)
.FirstOrDefault();
if (latestOrder != null)
{
var prevDetails = _db.pro_order_detail.Where(d => d.order_no == latestOrder.order_no).ToList();
foreach (var detail in prevDetails)
{
Model.pro_order_detail newDetail = new Model.pro_order_detail
{
order_no = newOrderNo,
actItem_num = detail.actItem_num,
parent_num = detail.parent_num,
print_id = detail.print_id,
f_num = detail.f_num,
f_num_tablet = detail.f_num_tablet,
address = detail.address,
from_id = detail.from_id,
from_id_tablet = detail.from_id_tablet,
qty = detail.qty,
price = detail.price,
start_date = DateTime.Today,
pay = 0,
UpdateTime = DateTime.Now
};
_db.pro_order_detail.Add(newDetail);
}
}
}
#endregion
}
+598 -5
View File
@@ -116,6 +116,7 @@
vuetify: new Vuetify(vuetify_options),
data() {
return {
last_confirmed_date: '',
tabArray: tabtmp,
tabArray2: "",
follower_id: '<%= Request["num"] %>',
@@ -124,6 +125,20 @@
multiSort: false,
//itemsPerPage: -1,
},
confirm_dialog: {
show: false,
headers: [
{ text: '活動日期', value: 'activitydate' },
{ text: '活動名稱', value: 'activityname'},
],
title: '',
desc: '',
orders: [],
pendingData: null,
pendingDeleteItem: null,
btn_cancel_text: '', // 「取消報名」按鈕文字
btn_keep_text: '' // 「保留活動」按鈕文字
},
search_dialog: {
controls: {
search1: {
@@ -454,6 +469,56 @@
{ text: '', value: 'actions', sortable: false, width: "100px" },
],
},
// 全年報名表格
auto_enroll: {
headers: [
{ text: '開始日期(西元)', value: 'auto_enroll_start_date', sortable: false },
{ text: '結束日期(西元)', value: 'auto_enroll_end_date', sortable: false },
{ text: '收據抬頭', value: 'auto_enroll_receipt_title', sortable: false },
{ text: '收據地址', value: 'auto_enroll_receipt_address', sortable: false },
{ text: '狀態', value: 'auto_enroll_status', sortable: false },
{ text: '', value: 'actions', sortable: false, width: "150px" },
],
items: [],
editedIndex: -1,
editedItem: {
num: 0,
auto_enroll_start_date: '',
auto_enroll_end_date: '',
auto_enroll_receipt_title: '',
auto_enroll_receipt_address: '',
},
defaultItem: {
num: 0,
auto_enroll_start_date: '',
auto_enroll_end_date: '',
auto_enroll_receipt_title: '',
auto_enroll_receipt_address: '',
},
search:""
},
unfilled_dialog: {
show: false,
headers: [
{ text: '報名單號', value: 'order_no', sortable: false },
{ text: '活動分類', value: 'category', sortable: false },
{ text: '活動名稱', value: 'activityname', sortable: false },
{ text: '開始日期', value: 'startdate', sortable: false },
{ text: '結束日期', value: 'enddate', sortable: false },
],
items: [],
footer: {
showFirstLastPage: true,
disableItemsPerPage: true,
itemsPerPageAllText: '',
itemsPerPageText: '',
current_item: null,
},
count: 0,
page: 1,
pageSize: 10,
loading: false,
},
cityOptions: [], // 城市選項
areaOptions: {}, // 區域選項
//天干地支:甲子, 乙丑...
@@ -485,7 +550,7 @@
]
}
},
mounted() {//一開始就載入
mounted() {
this.search_dialog.current = this.search_dialog.controls.search1 ///default
//console.log("mounted");
//this.initialize();
@@ -494,6 +559,7 @@
this.getFamilyMembers();
this.getCityOptions();
this.onCityChange();
this.initAutoEnroll();
},
watch: {
options: {
@@ -537,6 +603,323 @@
}
},
methods: {
initAutoEnroll() {
if (this.follower_id != '') {
axios.get(HTTP_HOST + `api/follower/GetAutoEnrollList/${this.follower_id}`)
.then(response => {
this.auto_enroll.items = response.data.list.map(item => ({
...item,
id: item.num
}));
})
}
},
// 取得報名狀態
getEnrollStatus(item) {
const today = new Date();
today.setHours(0, 0, 0, 0);
const start = new Date(item.auto_enroll_start_date);
const end = new Date(item.auto_enroll_end_date);
if (today < start) return { label: '未開始', color: 'blue lighten-4', textColor: 'blue darken-3' };
if (today > end) return { label: '已結束', color: 'grey lighten-2', textColor: 'grey darken-2' };
return { label: '報名中', color: 'green lighten-4', textColor: 'green darken-3' };
},
// 新增
auto_enroll_add() {
if (this.auto_enroll.editedIndex !== -1) return;
const newItem = {
...this.auto_enroll.defaultItem,
id: -Date.now()
};
this.auto_enroll.items.unshift(newItem);
this.auto_enroll.editedItem = { ...newItem };
this.auto_enroll.editedIndex = 0;
},
// 編輯
auto_enroll_edit(item) {
this.auto_enroll.editedIndex = this.auto_enroll.items.indexOf(item);
this.auto_enroll.editedItem = { ...item };
},
// 取消
auto_enroll_cancel() {
// 若是新增的空白列,取消時移除
const item = this.auto_enroll.items[this.auto_enroll.editedIndex];
if (item && !item.auto_enroll_start_date && !item.auto_enroll_end_date) {
this.auto_enroll.items.splice(this.auto_enroll.editedIndex, 1);
}
this.auto_enroll.editedItem = { ...this.auto_enroll.defaultItem };
this.auto_enroll.editedIndex = -1;
},
// 儲存
auto_enroll_save() {
const { id, num, auto_enroll_start_date, auto_enroll_end_date, auto_enroll_receipt_title, auto_enroll_receipt_address } = this.auto_enroll.editedItem;
if (!auto_enroll_start_date || !auto_enroll_end_date) {
alert('請填寫開始與結束日期');
return;
}
if (auto_enroll_start_date > auto_enroll_end_date) {
alert('開始日期不可晚於結束日期');
return;
}
// 檢查是否與其他列日期重疊
const isOverlap = this.auto_enroll.items.some(item => {
if (item.id === id) return false; // 跳過自己
const existStart = item.auto_enroll_start_date;
const existEnd = item.auto_enroll_end_date;
return auto_enroll_start_date <= existEnd && auto_enroll_end_date >= existStart;
});
if (isOverlap) {
alert('此報名期間與現有資料重疊,請重新確認日期');
return;
}
var auto_enroll =
{
num: num,
f_num: Number('<%= Request["num"] %>'),
start_date: auto_enroll_start_date,
end_date: auto_enroll_end_date,
receipt_title: auto_enroll_receipt_title,
receipt_address: auto_enroll_receipt_address,
}
this.open_confirm_dialog(auto_enroll);
//axios.post(HTTP_HOST + 'api/follower/SaveAutoEnrollList', auto_enroll)
// .then(response => {
// const savedData = response.data;
// const updatedItem = {
// ...this.auto_enroll.editedItem,
// num: Number(savedData.num),
// id: Number(savedData.num),
// auto_enroll_start_date: savedData.start_date,
// auto_enroll_end_date: savedData.end_date,
// auto_enroll_receipt_title: savedData.receipt_title,
// auto_enroll_receipt_address: savedData.receipt_address,
// };
// this.$set(this.auto_enroll.items, this.auto_enroll.editedIndex, updatedItem);
// this.auto_enroll.editedItem = { ...this.auto_enroll.defaultItem };
// this.auto_enroll.editedIndex = -1;
// })
},
// 刪除
auto_enroll_delete(item) {
// 先查受影響訂單
axios.post(HTTP_HOST + 'api/follower/GetAffectedOrders', {
num: item.num,
f_num: Number('<%= Request["num"] %>'),
start_date: item.auto_enroll_start_date,
end_date: item.auto_enroll_end_date,
}, {
params: { is_delete: true }
})
.then(response => {
this.confirm_dialog.pendingData = null;
this.confirm_dialog.pendingDeleteItem = item;
if (response.data.list.length > 0) {
this.confirm_dialog.orders = response.data.list;
this.confirm_dialog.title = "刪除全年報名";
this.confirm_dialog.desc = "刪除後,以下已報名的活動是否一併取消?";
this.confirm_dialog.btn_keep_text = "保留現有活動";
this.confirm_dialog.btn_cancel_text = "取消全部活動";
this.confirm_dialog.show = true;
} else {
this.doDelete(item);
}
})
},
doDelete(item) {
axios.delete(HTTP_HOST + `api/follower/DeleteAutoEnroll/${item.num}`)
.then(() => {
const index = this.auto_enroll.items.indexOf(item);
this.auto_enroll.items.splice(index, 1);
this.confirm_dialog.pendingDeleteItem = null; // 清空暫存
})
.catch(error => {
console.log("刪除失敗", error);
this.snackbar.text = "刪除失敗:" + error;
this.snackbar.show = true;
})
},
// 顯示尚未填寫項目的活動
unfilled_dialog_show(item) {
this.unfilled_dialog.current_item = item;
this.unfilled_dialog.page = 1;
this.unfilled_dialog.show = true;
this.unfilled_dialog_load();
},
unfilled_dialog_load() {
const item = this.unfilled_dialog.current_item;
const { page, pageSize, sortBy, sortDesc } = this.unfilled_dialog;
this.unfilled_dialog.loading = true;
axios
.get(HTTP_HOST + `api/follower/GetUnfilledActivityOrders/${item.num}`, {
params: {
page,
pageSize,
sortBy: Array.isArray(sortBy) ? sortBy[0] : sortBy,
sortDesc: Array.isArray(sortDesc) ? sortDesc[0] : sortDesc
}
})
.then(response => {
this.unfilled_dialog.items = response.data.list;
this.unfilled_dialog.count = response.data.count;
})
.finally(() => {
this.unfilled_dialog.loading = false;
});
},
// 列印
async exportUnfilledOrders() {
const item = this.unfilled_dialog.current_item;
// 取得全部資料
const response = await axios.get(
HTTP_HOST + `api/follower/GetUnfilledActivityOrders/${item.num}`,
{ params: { page: 1, pageSize: 99999 } }
);
const allItems = response.data.list;
const fullTitle = this.titleword();
const infoParts = fullTitle.split(' ');
const followerNum = infoParts[0] || "未知編號";
const followerName = infoParts[1] ? infoParts[1].split('')[0] : "未知姓名";
const rows = allItems.map(item => `
<tr>
<td>${item.order_no}</td>
<td>${item.category}</td>
<td>${item.activityname}</td>
<td>${item.startdate?.substring(0, 10)}</td>
<td>${item.enddate?.substring(0, 10)}</td>
</tr>
`).join('');
const win = window.open('', '_blank');
win.document.write(`
<html>
<head>
<title>未填寫品項活動 - ${followerName}</title>
<style>
body { font-family: "Microsoft JhengHei", Arial, sans-serif; padding: 20px; }
h2 { text-align: center; margin-bottom: 10px; }
.info-header { text-align: center; margin-bottom: 20px; font-size: 16px; border-bottom: 1px solid #eee; padding-bottom: 10px; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid #666; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h2>未填寫品項之活動清單</h2>
<div class="info-header">
信眾編號:<strong>${followerNum}</strong> &nbsp;&nbsp;
信眾姓名:<strong>${followerName}</strong>
</div>
<table>
<thead>
<tr>
<th>報名單號</th>
<th>活動分類</th>
<th>活動名稱</th>
<th>開始日期</th>
<th>結束日期</th>
</tr>
</thead>
<tbody>${rows}</tbody>
</table>
</body>
</html>
`);
win.document.close();
win.print();
win.close();
},
syncAddress() {
const sourceAddr = document.getElementById('<%=address.ClientID%>').value;
this.auto_enroll_config.receipt_address = sourceAddr;
},
open_confirm_dialog(auto_enroll) {
if (auto_enroll.num == 0) {
this.doSave(auto_enroll);
return;
}
// 受影響訂單
axios.post(HTTP_HOST + 'api/follower/GetAffectedOrders', auto_enroll)
.then(response => {
this.confirm_dialog.pendingData = auto_enroll;
if (response.data.list.length > 0) {
this.confirm_dialog.orders = response.data.list;
this.confirm_dialog.title = "受影響的已報名活動";
this.confirm_dialog.desc = "修改報名期間後,以下活動將不在新範圍內,是否一併取消?";
this.confirm_dialog.btn_keep_text = "保留現有活動";
this.confirm_dialog.btn_cancel_text = "取消全部活動";
this.confirm_dialog.show = true;
} else {
this.doSave(auto_enroll);
}
})
},
doSave(auto_enroll) {
axios.post(HTTP_HOST + 'api/follower/SaveAutoEnrollList', auto_enroll)
.then(response => {
const savedData = response.data;
const updatedItem = {
...this.auto_enroll.editedItem,
num: Number(savedData.num),
id: Number(savedData.num),
auto_enroll_start_date: savedData.start_date,
auto_enroll_end_date: savedData.end_date,
auto_enroll_receipt_title: savedData.receipt_title,
auto_enroll_receipt_address: savedData.receipt_address,
};
this.$set(this.auto_enroll.items, this.auto_enroll.editedIndex, updatedItem);
this.auto_enroll.editedItem = { ...this.auto_enroll.defaultItem };
this.auto_enroll.editedIndex = -1;
this.confirm_dialog.pendingData = null;
})
},
close_confirm_dialog() {
this.confirm_dialog.show = false;
},
keep_auto_enroll_order() {
this.confirm_dialog.show = false;
if (this.confirm_dialog.pendingData) {
this.doSave(this.confirm_dialog.pendingData);
} else if (this.confirm_dialog.pendingDeleteItem) {
this.doDelete(this.confirm_dialog.pendingDeleteItem);
}
},
delete_auto_enroll_order() {
this.confirm_dialog.show = false;
const orderNos = this.confirm_dialog.orders.map(o => o.order_no);
if (orderNos.length === 0) return;
const numsString = orderNos.join(',')
axios.delete(HTTP_HOST + `api/order/DeleteAll/${numsString}`)
.then(() => {
if (this.confirm_dialog.pendingData) {
this.doSave(this.confirm_dialog.pendingData);
} else if (this.confirm_dialog.pendingDeleteItem) {
this.doDelete(this.confirm_dialog.pendingDeleteItem);
}
})
.catch(error => {
console.log("刪除訂單失敗", error);
this.snackbar.text = "刪除訂單失敗:" + error;
this.snackbar.show = true;
})
},
search_show(curr) {
console.log("btn_click:", curr, curr.api_url);
this.search_dialog.current = curr;
@@ -1335,7 +1718,7 @@
}
});
}
</script>
</asp:Content>
@@ -1378,8 +1761,11 @@
type="button" role="tab" aria-controls="profile" aria-selected="false" v-if="lists.length > 0">
未付款紀錄 </button>
<button class="nav-link" id="sec2-tab4" data-bs-toggle="tab" data-bs-target="#sec2-page4"
type="button" role="tab" aria-controls="profile" aria-selected="false">
type="button" role="tab" aria-controls="profile" aria-selected="false" display="none">
牌位標題 </button>
<button class="nav-link" id="sec2-tab5" data-bs-toggle="tab" data-bs-target="#sec2-page5"
type="button" role="tab" aria-controls="profile" aria-selected="false">
全年報名 </button>
</div>
</nav>
</div>
@@ -1589,7 +1975,6 @@
</template>
</div>
</div>
<div class="row mb-1">
<label class="col-form-label">備註</label>
@@ -1978,9 +2363,176 @@
</v-data-table>
</v-card>
</div>
<div class="tab-pane fade" id="sec2-page5" role="tabpanel" aria-labelledby="sec2-tab5" >
<v-card class="mx-auto" outlined v-if="follower_id!=''">
<v-data-table class="elevation-1" fixed-header
:headers="auto_enroll.headers"
:items="auto_enroll.items"
:search="auto_enroll.search">
<v-divider inset></v-divider>
<template v-slot:top>
<v-toolbar flat color="transparent" class="row ms-0">
<div class="col-12 col-md-10 d-flex">
<v-text-field
v-model="auto_enroll.search"
append-icon="mdi-magnify"
label="查詢"
dense
outlined
single-line
hide-details>
</v-text-field>
<v-btn
color="primary"
class="ml-2 white--text "
title="新增全年報名"
@click="auto_enroll_add">
<v-icon dark>mdi-plus</v-icon>新增
</v-btn>
</div>
</v-toolbar>
</template>
<!-- 編輯中 -->
<template v-slot:item.auto_enroll_start_date="{ item }">
<template v-if="item.id === auto_enroll.editedItem.id">
<v-text-field
v-model="auto_enroll.editedItem.auto_enroll_start_date"
type="date"
dense
hide-details
outlined>
</v-text-field>
</template>
<template v-else>
{{ item.auto_enroll_start_date }}
</template>
</template>
<template v-slot:item.auto_enroll_end_date="{ item }">
<template v-if="item.id === auto_enroll.editedItem.id">
<v-text-field
v-model="auto_enroll.editedItem.auto_enroll_end_date"
type="date"
dense
hide-details
outlined>
</v-text-field>
</template>
<template v-else>
{{ item.auto_enroll_end_date }}
</template>
</template>
<template v-slot:item.auto_enroll_receipt_title="{ item }">
<template v-if="item.id === auto_enroll.editedItem.id">
<v-text-field
v-model="auto_enroll.editedItem.auto_enroll_receipt_title"
dense
hide-details
outlined
placeholder="請輸入收據抬頭">
</v-text-field>
</template>
<template v-else>
{{ item.auto_enroll_receipt_title }}
</template>
</template>
<template v-slot:item.auto_enroll_receipt_address="{ item }">
<template v-if="item.id === auto_enroll.editedItem.id">
<v-text-field
v-model="auto_enroll.editedItem.auto_enroll_receipt_address"
dense
hide-details
outlined
placeholder="請輸入收據地址">
</v-text-field>
</template>
<template v-else>
{{ item.auto_enroll_receipt_address }}
</template>
</template>
<!-- 狀態欄位 -->
<template v-slot:item.auto_enroll_status="{ item }">
<v-chip
small
:color="getEnrollStatus(item).color"
:text-color="getEnrollStatus(item).textColor"
class="font-weight-medium">
{{ getEnrollStatus(item).label }}
</v-chip>
</template>
<!-- 操作欄位 -->
<template v-slot:item.actions="{ item }">
<template v-if="item.id === auto_enroll.editedItem.id">
<v-icon color="red" class="mr-2" @click="auto_enroll_cancel">
mdi-window-close
</v-icon>
<v-icon color="green" class="mr-2" @click="auto_enroll_save">
mdi-content-save
</v-icon>
</template>
<template v-else>
<v-icon color="green" class="mr-2" @click="auto_enroll_edit(item)">
mdi-pencil
</v-icon>
<v-icon color="red" class="mr-2" @click="auto_enroll_delete(item)">
mdi-delete
</v-icon>
<v-icon color="blue" class="mr-2" @click="unfilled_dialog_show(item)" title="查看未填寫品項活動">
mdi-file-find
</v-icon>
</template>
</template>
</v-data-table>
</v-card>
</div>
</div>
</asp:Panel>
</div>
<!-- 顯示沒有品項的活動 -->
<v-dialog v-model="unfilled_dialog.show" max-width="900px">
<v-card>
<v-card-title class="headline grey lighten-2">
未填寫品項的活動
<v-spacer></v-spacer>
<v-btn icon @click="unfilled_dialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text>
<v-data-table
:headers="unfilled_dialog.headers"
:items="unfilled_dialog.items"
:footer-props="unfilled_dialog.footer"
:items-per-page="unfilled_dialog.pageSize"
:server-items-length="unfilled_dialog.count"
:page.sync="unfilled_dialog.page"
:loading="unfilled_dialog.loading"
@update:page="unfilled_dialog_load"
>
</v-data-table>
</v-card-text>
<v-card-actions class="justify-center pb-6">
<v-btn
color="primary"
:disabled="unfilled_dialog.items.length == 0"
class="px-4"
@click="exportUnfilledOrders">
<v-icon left>mdi-printer</v-icon>
列印
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!-- Family Member Dialog -->
<v-dialog v-model="family.dialog" max-width="600px">
<v-card>
@@ -2123,7 +2675,7 @@
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
查詢:{{search_dialog.current.title}}
<v-btn icon @click="search_dialog.show=false"><v-icon>mdi-close</v-icon></v-btn>
<v-btn icon @click="search_dialog.show=false;"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text >
<v-row>
@@ -2173,6 +2725,47 @@
</v-btn>
</template>
</v-snackbar>
<v-dialog v-model="confirm_dialog.show" max-width="500px" persistent>
<v-card>
<v-card-title class="justify-space-between grey lighten-2">
<span>{{ confirm_dialog.title }}</span>
<v-btn icon @click="close_confirm_dialog"><v-icon>mdi-close</v-icon></v-btn>
</v-card-title>
<v-card-text class="pt-4">
<p class="body-1">{{ confirm_dialog.desc }}</p>
<v-data-table
:headers="confirm_dialog.headers"
:items="confirm_dialog.orders"
:items-per-page="10"
class="elevation-1 grey lighten-5"
:footer-props="{
'items-per-page-text': '每頁顯示',
'items-per-page-options': [5, 10]
}"
>
<template v-slot:item.activitydate="{ item }">
<span>{{ item.activitydate }}</span>
</template>
</v-data-table>
</v-card-text>
<v-divider class="pa-0 ma-0"></v-divider>
<v-card-actions class="pa-4 justify-end">
<v-btn color="primary" @click="keep_auto_enroll_order">
{{ confirm_dialog.btn_keep_text }}
</v-btn>
<v-btn color="red" dark @click="delete_auto_enroll_order">
{{ confirm_dialog.btn_cancel_text }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</asp:Content>
+48 -21
View File
@@ -11,9 +11,11 @@ using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using static Model.activity_check;
public partial class admin_follower_reg : MyWeb.config
{
@@ -142,7 +144,7 @@ public partial class admin_follower_reg : MyWeb.config
country.Value = prod.country.ToString();
}
if (prod.reg_time.HasValue)
{
{
timePanel1.Visible = true;
reg_time.Text= prod.reg_time.Value.ToString("yyyy/MM/dd HH:mm:ss");
}
@@ -153,7 +155,6 @@ public partial class admin_follower_reg : MyWeb.config
modify_time.Text = prod.admin_log;
}
edit.Visible = true;
goback.Visible = true;
add.Visible = false;
@@ -178,10 +179,39 @@ public partial class admin_follower_reg : MyWeb.config
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
}
#region
protected string createOrderNumber()
{
Application.Lock();
string order_no = "AA" + DateTime.Now.ToString("yyMMdd");
var qry = _db.companies.AsQueryable();
//var prod = qry.Where(q => q.last_order_no.Contains(order_no)).FirstOrDefault();
var prod = qry.Where(q => q.num == 1).FirstOrDefault();
if (prod != null)
{
if (!isStrNull(prod.last_order_no) && prod.last_order_no.Contains(order_no))
{
int tmp = Convert.ToInt32(prod.last_order_no.Replace(order_no, "")) + 1;
order_no = order_no + tmp.ToString("0000");
}
else
{
order_no = order_no + "0001";
}
prod.last_order_no = order_no;
_db.SaveChanges();
}
else
order_no = "";
Application.UnLock();
return order_no;
}
protected void add_Click(object sender, EventArgs e)
{
if (Page.IsValid) {
@@ -205,7 +235,7 @@ public partial class admin_follower_reg : MyWeb.config
{
ObjValue.SetValue(followers, selectDate(textBox));
}
else if (!isStrNull(((TextBox)obj).Attributes["data-encrypt"])
else if (!isStrNull(((TextBox)obj).Attributes["data-encrypt"])
&& ValString(textBox.Attributes["data-encrypt"]).Equals("Y"))
{
ObjValue.SetValue(followers, encrypt.EncryptAutoKey(textBox.Text.Trim()));
@@ -257,9 +287,9 @@ public partial class admin_follower_reg : MyWeb.config
Model.admin_log admin_log = new Model.admin_log();
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Follower, (int)Model.admin_log.Status.Insert, f_number.Text + u_name.Text);
Session["LastAddedID"] = followers.f_number;
Response.Redirect("index.aspx");
}
else
@@ -279,8 +309,8 @@ public partial class admin_follower_reg : MyWeb.config
L_msg.Type = alert_type.danger;
L_msg.Text = "信眾編號重複";
}
}
}
}
#endregion
@@ -318,10 +348,7 @@ public partial class admin_follower_reg : MyWeb.config
}
else
ObjValue.SetValue(followers, null);
}
}
followers.identity_type = Val(identity_type.SelectedValue);
@@ -397,16 +424,16 @@ public partial class admin_follower_reg : MyWeb.config
L_msg.Type = alert_type.danger;
L_msg.Text = "查無資料";
}
/*
if (chk_pro_num(f_number.Text, Val(Request["num"])))
{
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "信眾編號重複";
}
*/
/*
if (chk_pro_num(f_number.Text, Val(Request["num"])))
{
}
else
{
L_msg.Type = alert_type.danger;
L_msg.Text = "信眾編號重複";
}
*/
}
}
+1 -2
View File
@@ -783,7 +783,6 @@
this.desserts_count = response.data.list !== undefined ? response.data.count : 0
this.calutotalPrice();
this.disableButton = false;
})
.catch(
error => console.log(error)
@@ -840,7 +839,7 @@
// 顯示對話框
this.tablet_edit.show = true;
// 立即恢復數據
this.editedItem = $.extend(true, {}, currentData);
this.editedItem = $.extend(true, {}, currentData);
} catch (error) {
console.error('Error in editTablet:', error);
}
+25
View File
@@ -147,6 +147,14 @@
</v-col>
<v-col cols="auto" class="ml-4">
<span class="subtitle-2 grey--text text--darken-1">超渡-已選</span>
<v-chip v-if="tabletItem.has_chao_limit"
x-small
class="ml-2 px-2"
:color="family_deceased_Y_selected.length > tabletItem.chao_limit_count ? 'error' : 'grey lighten-1'"
:dark="family_deceased_Y_selected.length > tabletItem.chao_limit_count"
label>
{{ family_deceased_Y_selected.length }} / {{ tabletItem.chao_limit_count }}
</v-chip>
</v-col>
<v-spacer></v-spacer>
<v-col cols="auto">
@@ -237,6 +245,14 @@
</v-col>
<v-col cols="auto" :class="{'ml-4': item_type==='A'}">
<span class="subtitle-2 grey--text text--darken-1">陽上/祈福-已選</span>
<v-chip v-if="tabletItem.has_yang_limit"
x-small
class="ml-2 px-2"
:color="family_deceased_N_selected.length > tabletItem.yang_limit_count ? 'error' : 'grey lighten-1'"
:dark="family_deceased_N_selected.length > tabletItem.yang_limit_count"
label>
{{ family_deceased_N_selected.length }} / {{ tabletItem.yang_limit_count }}
</v-chip>
</v-col>
<v-spacer></v-spacer>
<v-col cols="auto">
@@ -700,6 +716,15 @@
saveData() {
// 其它資料欄位, 不應在這裡修改
// 應該在進來的時候, 就已經修改(insert)好了
if (this.tabletItem.has_chao_limit && this.family_deceased_Y_selected.length > this.tabletItem.chao_limit_count) {
alert(`超渡人數超過限制!(上限 ${this.tabletItem.chao_limit_count} 人)`);
return; // 阻斷存檔
}
if (this.tabletItem.has_yang_limit && this.family_deceased_N_selected.length > this.tabletItem.yang_limit_count) {
alert(`陽上人數超過限制!(上限 ${this.tabletItem.yang_limit_count} 人)`);
return; // 阻斷存檔
}
let tablet_data = {};
if (this.item_type === 'B') {// B:超渡, 超薦.....
tablet_data = {
+2 -2
View File
@@ -42,8 +42,8 @@
<add key="UseSearchKeywords" value="true" />
<!--網站的簡稱,用來區別session和cookie-->
<add key="SC" value="erp17168" />
<!--是否啟用信眾自動編號 (true=啟用, false=停用)-->
<add key="IsAutoNumbering" value="true" />
<!--是否啟用信眾自動編號 (true=啟用, false=停用)-->
<add key="IsAutoNumbering" value="true" />
</appSettings>
<connectionStrings>
<!--SQL用-->
+102
View File
@@ -0,0 +1,102 @@
## FK 規則更新
| FK 名稱 | 更新內容 |
| - | - |
| FK_act_bom_actItem1| 刪除規則設為 cascade |
| FK_pro_order_followers | 刪除規則設為 cascade |
| FK_pro_order_activity | 刪除規則設為 cascade |
| FK_pro_order_detail_pro_order | 刪除規則設為 cascade |
| FK_pro_order_detail_followers | 刪除規則設為 沒有動作 |
| FK_activity_relating_activity | 刪除規則設為 cascade |
| FK_pro_order_auto_enroll | 刪除規則設為 NULL |
## 資料表欄位更新
| 資料表 | 新增欄位 | 備註 |
| - | - | - |
| actitem | 加上 sort_order (int) 欄位位 | |
| activity_relating | 加上 has_yang_limit(bit) 欄位 | |
| activity_relating | 加上 has_chao_limit(bit) 欄位 | |
| activity_relating | 加上 yang_limit_count (int) 欄位 | |
| activity_relating | 加上 chao_limit_count (int) 欄位 | |
| company | 加上 last_auto_order_no (nvarchar(20)) 欄位 | |
| pro_order | 加上 au_num (int) 欄位 | 需建立 FK 限制 (見下方 SQL) |
- 更新 actitem 資料表
```language
ALTER TABLE actitem
ADD sort_order int NULL;
```
- 更新 activity_relating 資料表
```language
ALTER TABLE activity_relating
ADD has_yang_limit bit NULL,
has_chao_limit bit NULL,
yang_limit_count int NULL,
chao_limit_count int NULL;
```
- 更新 company 資料表
```language
ALTER TABLE company
ADD last_auto_order_no nvarchar(20) NULL;
```
- 更新 pro_order 資料表及外鍵限制
```language
-- 新增欄位
ALTER TABLE pro_order
ADD au_num int NULL;
-- 建立外鍵限制 (FK_pro_order_auto_enroll)
ALTER TABLE pro_order
ADD CONSTRAINT FK_pro_order_auto_enroll
FOREIGN KEY (au_num) REFERENCES auto_enroll(num);
```
## 新增資料表 auto_enroll
| 欄位名稱 | 資料類型 | 允許 Null | 備註 |
| - | - | - | - |
| num | int | 否 | PK, 識別規格 (Identity) |
| f_num | int | 否 | FK (連至 followers.num) |
| start_date | date | 是 | |
| end_date | date | 是 | |
| receipt_title | nvarchar(MAX) | 是 | |
| receipt_address | nchar(200) | 否 | |
- 建立資料表 auto_enroll
```language
CREATE TABLE [dbo].[auto_enroll] (
[num] int IDENTITY(1,1) NOT NULL,
[f_num] int NOT NULL,
[start_date] date NULL,
[end_date] date NULL,
[receipt_title] nvarchar(MAX) NULL,
[receipt_address] nchar(200) NOT NULL,
CONSTRAINT [PK_auto_enroll] PRIMARY KEY CLUSTERED ([num] ASC)
);
```
- 設定外鍵限制
```language
ALTER TABLE [dbo].[auto_enroll]
ADD CONSTRAINT FK_auto_enroll_followers
FOREIGN KEY (f_num) REFERENCES followers(num);
```
### 資料表相關設定 (SQL)
- 設定主鍵
```language
ALTER TABLE [dbo].[auto_enroll]
ADD CONSTRAINT PK_auto_enroll PRIMARY KEY (num);
```
- 設定外鍵
```language
ALTER TABLE auto_enroll
ADD CONSTRAINT FK_auto_enroll_followers
FOREIGN KEY (f_num) REFERENCES followers(num);
```
- Model.edmx 設定
- num 識別規格設為 是
- Model.edmx auto_enroll.num 屬性 StoreGeneratedPattern 設為 Identity
+40 -7
View File
@@ -1,8 +1,41 @@
FK_act_bom_actItem1 刪除規則設為 cascade
FK_pro_order_followers 刪除規則設為 cascade
FK_pro_order_activity 刪除規則設為 cascade
FK_pro_order_detail_pro_order 刪除規則設為 cascade
FK_pro_order_detail_followers 刪除規則設為 沒有動作
FK_activity_relating_activity 刪除規則設為 cascade
FK 規則更新
FK_act_bom_actItem1 刪除規則設為 cascade
FK_pro_order_followers 刪除規則設為 cascade
FK_pro_order_activity 刪除規則設為 cascade
FK_pro_order_detail_pro_order 刪除規則設為 cascade
FK_pro_order_detail_followers 刪除規則設為 沒有動作
FK_activity_relating_activity 刪除規則設為 cascade
FK_pro_order_auto_enroll 刪除規則設為 NULL
------------------------------------------------------------
資料表欄位更新
actitem 加上 sort_order(int) 欄位
activity_relating 加上 has_yang_limit(bit) 欄位
activity_relating 加上 has_chao_limit(bit) 欄位
activity_relating 加上 yang_limit_count(int) 欄位
activity_relating 加上 chao_limit_count(int) 欄位
company 加上 last_auto_order_no(nvarchar(20)) 欄位
pro_order 加上 au_num(int) 欄位 並加上 constraint
ALTER TABLE pro_order
ADD CONSTRAINT FK_pro_order_auto_enroll
FOREIGN KEY (au_num) REFERENCES auto_enroll(num);
------------------------------------------------------------
新增資料表 auto_enroll
num int 不允許 Null
f_num int 不允許 Null
start_date date 允許 Null
end_date date 允許 Null
receipt_title nvarchar(MAX) 允許 Null
receipt_address nchar(200) 不允許 Null
actitem 加上 sort_order(int) 欄位
設定主鍵
ALTER TABLE [dbo].[auto_enroll]
ADD CONSTRAINT PK_auto_enroll PRIMARY KEY (num);
設定外鍵
ALTER TABLE auto_enroll
ADD CONSTRAINT FK_auto_enroll_followers
FOREIGN KEY (f_num) REFERENCES followers(num);
Model.edmx 設定
1. num 識別規格設為 是
2. Model.edmx auto_enroll.num 屬性 StoreGeneratedPattern 設為 Identity