Compare commits
20 Commits
dapper
..
a14fef3841
| Author | SHA1 | Date | |
|---|---|---|---|
| a14fef3841 | |||
| 08d8e27bc9 | |||
| 8affaaf344 | |||
| 5abdad74bb | |||
| 251c52311d | |||
| a3a9968e62 | |||
| 2b9e266eb0 | |||
| 669b29d183 | |||
| a58e6ac7ac | |||
| 889e5679aa | |||
| 2724173216 | |||
| ccc188013b | |||
| 77f642b2d2 | |||
| 9fa8ef90cf | |||
| a1751e4b99 | |||
| 07e29c32aa | |||
| 3c5617b403 | |||
| 50c2203ebf | |||
| 7644df57d0 | |||
| aa5941a324 |
Generated
+1
-1
@@ -1,4 +1,4 @@
|
||||
// 已啟用模型 'C:\project\17168ERP\web\App_Code\Model\Model.edmx' 的 T4 程式碼產生。
|
||||
// 已啟用模型 'D:\17168ERP\web\App_Code\Model\Model.edmx' 的 T4 程式碼產生。
|
||||
// 若要啟用舊版程式碼產生,請將 [程式碼產生策略] 設計工具屬性的值
|
||||
//變更為 [舊版 ObjectContext]。當模型在設計工具中開啟時,這個屬性便可
|
||||
//以在 [屬性] 視窗中使用。
|
||||
|
||||
@@ -187,6 +187,7 @@ namespace Model
|
||||
public string pageSize { get; set; }
|
||||
public string printSize { get; set; }
|
||||
public string defaultStyle { get; set; }
|
||||
public Nullable<int> sort_order { get; set; }
|
||||
|
||||
public virtual actItem_kind actItem_kind { get; set; }
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<Property Name="pageSize" Type="varchar" MaxLength="50" />
|
||||
<Property Name="printSize" Type="varchar" MaxLength="50" />
|
||||
<Property Name="defaultStyle" Type="varchar" MaxLength="50" />
|
||||
<Property Name="sort_order" Type="int" />
|
||||
</EntityType>
|
||||
<EntityType Name="actItem_files">
|
||||
<Key>
|
||||
@@ -607,8 +608,8 @@
|
||||
</Key>
|
||||
<Property Name="num" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
|
||||
<Property Name="kind" Type="nvarchar" MaxLength="100" />
|
||||
<Property Name="starttime" Type="time" Precision="0" />
|
||||
<Property Name="offtime" Type="time" Precision="0" />
|
||||
<Property Name="starttime" Type="time" Precision="7" />
|
||||
<Property Name="offtime" Type="time" Precision="7" />
|
||||
<Property Name="resttime" Type="int" />
|
||||
<Property Name="root" Type="int" />
|
||||
<Property Name="range" Type="int" />
|
||||
@@ -1083,7 +1084,9 @@
|
||||
</ReferentialConstraint>
|
||||
</Association>
|
||||
<Association Name="FK_act_bom_actItem1">
|
||||
<End Role="actItem" Type="Self.actItem" Multiplicity="0..1" />
|
||||
<End Role="actItem" Type="Self.actItem" Multiplicity="0..1">
|
||||
<OnDelete Action="Cascade" />
|
||||
</End>
|
||||
<End Role="act_bom" Type="Self.act_bom" Multiplicity="*" />
|
||||
<ReferentialConstraint>
|
||||
<Principal Role="actItem">
|
||||
@@ -1203,7 +1206,9 @@
|
||||
</ReferentialConstraint>
|
||||
</Association>
|
||||
<Association Name="FK_activity_relating_activity">
|
||||
<End Role="activity" Type="Self.activity" Multiplicity="1" />
|
||||
<End Role="activity" Type="Self.activity" Multiplicity="1">
|
||||
<OnDelete Action="Cascade" />
|
||||
</End>
|
||||
<End Role="activity_relating" Type="Self.activity_relating" Multiplicity="*" />
|
||||
<ReferentialConstraint>
|
||||
<Principal Role="activity">
|
||||
@@ -1629,7 +1634,9 @@
|
||||
</ReferentialConstraint>
|
||||
</Association>
|
||||
<Association Name="FK_pro_order_activity">
|
||||
<End Role="activity" Type="Self.activity" Multiplicity="0..1" />
|
||||
<End Role="activity" Type="Self.activity" Multiplicity="0..1">
|
||||
<OnDelete Action="Cascade" />
|
||||
</End>
|
||||
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
|
||||
<ReferentialConstraint>
|
||||
<Principal Role="activity">
|
||||
@@ -1679,7 +1686,9 @@
|
||||
</ReferentialConstraint>
|
||||
</Association>
|
||||
<Association Name="FK_pro_order_detail_pro_order">
|
||||
<End Role="pro_order" Type="Self.pro_order" Multiplicity="1" />
|
||||
<End Role="pro_order" Type="Self.pro_order" Multiplicity="1">
|
||||
<OnDelete Action="Cascade" />
|
||||
</End>
|
||||
<End Role="pro_order_detail" Type="Self.pro_order_detail" Multiplicity="*" />
|
||||
<ReferentialConstraint>
|
||||
<Principal Role="pro_order">
|
||||
@@ -1691,7 +1700,9 @@
|
||||
</ReferentialConstraint>
|
||||
</Association>
|
||||
<Association Name="FK_pro_order_followers">
|
||||
<End Role="followers" Type="Self.followers" Multiplicity="0..1" />
|
||||
<End Role="followers" Type="Self.followers" Multiplicity="0..1">
|
||||
<OnDelete Action="Cascade" />
|
||||
</End>
|
||||
<End Role="pro_order" Type="Self.pro_order" Multiplicity="*" />
|
||||
<ReferentialConstraint>
|
||||
<Principal Role="followers">
|
||||
@@ -2604,6 +2615,7 @@
|
||||
<Property Name="pageSize" Type="String" MaxLength="50" FixedLength="false" Unicode="false" />
|
||||
<Property Name="printSize" Type="String" MaxLength="50" FixedLength="false" Unicode="false" />
|
||||
<Property Name="defaultStyle" Type="String" MaxLength="50" FixedLength="false" Unicode="false" />
|
||||
<Property Name="sort_order" Type="Int32" ConcurrencyMode="None" />
|
||||
</EntityType>
|
||||
<EntityType Name="actItem_files">
|
||||
<Key>
|
||||
@@ -3053,8 +3065,8 @@
|
||||
</Key>
|
||||
<Property Name="num" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
|
||||
<Property Name="kind" Type="String" MaxLength="100" FixedLength="false" Unicode="true" />
|
||||
<Property Name="starttime" Type="Time" Precision="0" />
|
||||
<Property Name="offtime" Type="Time" Precision="0" />
|
||||
<Property Name="starttime" Type="Time" Precision="7" />
|
||||
<Property Name="offtime" Type="Time" Precision="7" />
|
||||
<Property Name="resttime" Type="Int32" />
|
||||
<Property Name="root" Type="Int32" />
|
||||
<Property Name="range" Type="Int32" />
|
||||
@@ -5326,6 +5338,7 @@
|
||||
<EntitySetMapping Name="actItems">
|
||||
<EntityTypeMapping TypeName="Model.actItem">
|
||||
<MappingFragment StoreEntitySet="actItem">
|
||||
<ScalarProperty Name="sort_order" ColumnName="sort_order" />
|
||||
<ScalarProperty Name="defaultStyle" ColumnName="defaultStyle" />
|
||||
<ScalarProperty Name="printSize" ColumnName="printSize" />
|
||||
<ScalarProperty Name="pageSize" ColumnName="pageSize" />
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<EntityTypeShape EntityType="Model.accounting_files" Width="1.5" PointX="15.75" PointY="27.75" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.accounting_kind" Width="1.5" PointX="11.25" PointY="27.625" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.accounting_kind2" Width="1.5" PointX="13.5" PointY="11.25" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.actItem" Width="1.5" PointX="9.25" PointY="7.875" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.actItem" Width="1.5" PointX="8.375" PointY="27.25" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.actItem_files" Width="1.5" PointX="16.5" PointY="5.875" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.actItem_kind" Width="1.5" PointX="6.125" PointY="7.875" IsExpanded="true" />
|
||||
<EntityTypeShape EntityType="Model.activity" Width="1.5" PointX="3" PointY="8.875" IsExpanded="true" />
|
||||
|
||||
@@ -32,6 +32,9 @@ namespace Model.ViewModel
|
||||
public string subject { get; set; }
|
||||
public int? num { get; set; }
|
||||
public string is_reconcile { get; set; }
|
||||
public string up_time1 { get; set; }
|
||||
public string up_time2 { get; set; }
|
||||
public string deadline { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Model.ViewModel
|
||||
public string country { get; set; }
|
||||
public string country2 { get; set; }
|
||||
public string phone_idcode { get; set; } // 電話/證號搜尋欄位
|
||||
public string cellphone { get; set; }
|
||||
}
|
||||
public class followers_tablet
|
||||
{
|
||||
|
||||
@@ -41,6 +41,13 @@ namespace Model.ViewModel
|
||||
public string country { get; set; }
|
||||
public string country2 { get; set; }
|
||||
|
||||
public List<pro_order_detail> details { get; set; }
|
||||
|
||||
public follower f_user { get; set; }
|
||||
|
||||
public List<string> orders { get; set; }
|
||||
public Nullable<int> old_activity_num { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class pro_order_detail
|
||||
@@ -83,6 +90,11 @@ namespace Model.ViewModel
|
||||
public string follower_name { get; set; }
|
||||
public string full_description { get; set; }
|
||||
public string order_info { get; set; }
|
||||
public string style { get; set; }
|
||||
public int? change_item_num { get; set; }
|
||||
|
||||
public List<family_members> mid_items { get; set; }
|
||||
public List<family_members> left_items { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Model.ViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// statistic 的摘要描述
|
||||
/// </summary>
|
||||
public class statistic
|
||||
{
|
||||
public statistic()
|
||||
{
|
||||
//
|
||||
// TODO: 在這裡新增建構函式邏輯
|
||||
//
|
||||
}
|
||||
public int id { get; set; }
|
||||
public int num { get; set; }
|
||||
public int kind { get; set; }
|
||||
|
||||
public string kindName { get; set; }
|
||||
public string order_no { get; set; }
|
||||
public string subject { get; set; }
|
||||
public string u_name { get; set; }
|
||||
public string pay_type { get; set; }
|
||||
public decimal amount { get; set; }
|
||||
|
||||
public float price { get; set; }
|
||||
public string pay_mode { get; set; }
|
||||
public string status { get; set; }
|
||||
public int f_num { get; set; }
|
||||
public int acc_num { get; set; }
|
||||
public int acc_kind { get; set; }
|
||||
public decimal check_amount { get; set; }
|
||||
public decimal remain_amount { get; set; }
|
||||
|
||||
public string check_status { get; set; }
|
||||
public int actItem_num { get; set; }
|
||||
public string draft { get; set; }
|
||||
public int qty { get; set; }
|
||||
public int d_num { get; set; }
|
||||
|
||||
public string s_date { get; set; }
|
||||
public string e_date { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,7 +28,7 @@ namespace MyWeb
|
||||
public AdmItem info { get; set; }
|
||||
|
||||
//定義欄位cookie==================start
|
||||
public class AdmItem
|
||||
public class AdmItem
|
||||
{
|
||||
public int num { get; set; }
|
||||
public string u_id { get; set; }
|
||||
|
||||
@@ -103,17 +103,18 @@ public class FollowerController : ApiController
|
||||
{
|
||||
foreach (var item in prod)
|
||||
{
|
||||
foreach (var item2 in item.pro_order_detail1)
|
||||
item2.from_id = null; //清空訂單明細的陽上報恩者from_id //f_num設定串聯刪除
|
||||
//foreach (var item2 in item.pro_order_detail1)
|
||||
// item2.from_id = null; //清空訂單明細的陽上報恩者from_id //f_num設定串聯刪除
|
||||
|
||||
foreach (var item2 in item.pro_order)
|
||||
item2.introducer = null;
|
||||
//foreach (var item2 in item.pro_order)
|
||||
// item2.introducer = null;
|
||||
|
||||
item.leader = null;//清空leader
|
||||
//item.leader = null;//清空leader
|
||||
_db.followers.RemoveRange(prod);
|
||||
|
||||
}
|
||||
|
||||
_db.followers.RemoveRange(prod);
|
||||
//_db.followers.RemoveRange(prod);
|
||||
_db.SaveChanges();
|
||||
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
@@ -136,6 +137,198 @@ public class FollowerController : ApiController
|
||||
var count = _db.followers.Count();
|
||||
return count;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/follower/GetFollowerNew")]
|
||||
public IHttpActionResult GetFollowerNew([FromBody] Model.ViewModel.follower q)
|
||||
{
|
||||
|
||||
////var qry = _db.followers.Where(a => a.IsDel == false).AsQueryable();////不確定是否新增欄位? 先註解
|
||||
var qry = _db.followers.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(q.f_number))
|
||||
qry = qry.Where(o => o.f_number.Contains(q.f_number.Trim()));
|
||||
if (!string.IsNullOrEmpty(q.u_name))
|
||||
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||
if (q.birthday.HasValue)
|
||||
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
||||
if (q.birthday2.HasValue)
|
||||
{
|
||||
var tmpBirthday2 = Convert.ToDateTime(q.birthday2.Value).AddDays(1);
|
||||
qry = qry.Where(o => o.birthday < tmpBirthday2);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.address))
|
||||
qry = qry.Where(o => o.address != null && o.address.Contains(q.address.Trim()));
|
||||
//if (q.num.HasValue && q.num.Value>0)
|
||||
// qry = qry.Where(o => o.num==q.num.Value);
|
||||
if (q.ept_self.HasValue && q.ept_self.Value)//排除自己
|
||||
{
|
||||
qry = qry.Where(o => o.num != q.num.Value);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.country))
|
||||
qry = qry.Where(o => o.country == q.country);
|
||||
if (!string.IsNullOrEmpty(q.country2))
|
||||
{
|
||||
if (q.country2 == "1")
|
||||
{
|
||||
qry = qry.Where(o => o.country == "158");
|
||||
}
|
||||
else if (q.country2 == "2")
|
||||
{
|
||||
qry = qry.Where(o => o.country != "158");
|
||||
|
||||
}
|
||||
}
|
||||
//if (!string.IsNullOrEmpty(q.phone_idcode)){
|
||||
// MyWeb.encrypt enc = new MyWeb.encrypt();
|
||||
// qry = qry.Where(o => o.phone ==enc.DecryptAutoKey(q.phone_idcode) || o.cellphone==enc.DecryptAutoKey(q.phone_idcode));
|
||||
//}
|
||||
|
||||
// 電話/證號搜尋 (使用 search_keywords HEX 編碼)
|
||||
if (!string.IsNullOrEmpty(q.phone_idcode) && GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
MyWeb.encrypt enc = new MyWeb.encrypt();
|
||||
string hexSearch = enc.ConvertToHex(q.phone_idcode.Trim());
|
||||
if (!string.IsNullOrEmpty(hexSearch))
|
||||
{
|
||||
qry = qry.Where(o => o.search_keywords != null && o.search_keywords.Contains(hexSearch));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
|
||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||
var ret = new
|
||||
{
|
||||
list = qry.AsEnumerable().Select(x => new
|
||||
{
|
||||
num = x.num,
|
||||
f_number = x.f_number,
|
||||
u_name = x.u_name,
|
||||
sex = x.sex,
|
||||
birthday = x.birthday, //?.ToString("yyyy/MM/dd"),
|
||||
birthday2 = publicFun.chagenDate(x.birthday), //?.ToString("yyyy/MM/dd"),
|
||||
sign = Model.follower.chagenSign(x.birthday), //NULL??
|
||||
sexagenary = Model.follower.sexagenary(x.birthday),
|
||||
identity_type = x.identity_type,
|
||||
identity_type_desc = tdesc[x.identity_type ?? 1],//TryGetValue..
|
||||
id_code = x.id_code,
|
||||
id_codeDes = encrypt.DecryptAutoKey(x.id_code),
|
||||
passport = x.passport,
|
||||
passportDes = encrypt.DecryptAutoKey(x.passport),
|
||||
phone = x.phone,
|
||||
phoneDes = encrypt.DecryptAutoKey(x.phone), //--MyWeb.function X
|
||||
refugedate = x.refugedate,
|
||||
refuge_name = x.refuge_name,
|
||||
email = x.email,
|
||||
address = x.address,
|
||||
cellphone = x.cellphone,
|
||||
cellphoneDes = encrypt.DecryptAutoKey(x.cellphone),
|
||||
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
|
||||
if (ret.list == null) {
|
||||
return Ok(new {result="N",message="查無信眾"});
|
||||
} //throw new HttpResponseException(HttpStatusCode);
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/follower/GetFollower")]
|
||||
public IHttpActionResult GetFollower([FromBody] Model.ViewModel.follower q)
|
||||
{
|
||||
|
||||
////var qry = _db.followers.Where(a => a.IsDel == false).AsQueryable();////不確定是否新增欄位? 先註解
|
||||
var qry = _db.followers.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(q.f_number))
|
||||
qry = qry.Where(o => o.f_number.Contains(q.f_number.Trim()));
|
||||
if (!string.IsNullOrEmpty(q.u_name))
|
||||
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||
if (q.birthday.HasValue)
|
||||
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
||||
if (q.birthday2.HasValue)
|
||||
{
|
||||
var tmpBirthday2 = Convert.ToDateTime(q.birthday2.Value).AddDays(1);
|
||||
qry = qry.Where(o => o.birthday < tmpBirthday2);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.address))
|
||||
qry = qry.Where(o => o.address != null && o.address.Contains(q.address.Trim()));
|
||||
//if (q.num.HasValue && q.num.Value>0)
|
||||
// qry = qry.Where(o => o.num==q.num.Value);
|
||||
if (q.ept_self.HasValue && q.ept_self.Value)//排除自己
|
||||
{
|
||||
qry = qry.Where(o => o.num != q.num.Value);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.country))
|
||||
qry = qry.Where(o => o.country == q.country);
|
||||
if (!string.IsNullOrEmpty(q.country2))
|
||||
{
|
||||
if (q.country2 == "1")
|
||||
{
|
||||
qry = qry.Where(o => o.country == "158");
|
||||
}
|
||||
else if (q.country2 == "2")
|
||||
{
|
||||
qry = qry.Where(o => o.country != "158");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 電話/證號搜尋 (使用 search_keywords HEX 編碼)
|
||||
if (!string.IsNullOrEmpty(q.phone_idcode) && GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
MyWeb.encrypt enc = new MyWeb.encrypt();
|
||||
string hexSearch = enc.ConvertToHex(q.phone_idcode.Trim());
|
||||
if (!string.IsNullOrEmpty(hexSearch))
|
||||
{
|
||||
qry = qry.Where(o => o.search_keywords != null && o.search_keywords.Contains(hexSearch));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
|
||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||
var ret = new
|
||||
{
|
||||
list = qry.AsEnumerable().Select(x => new
|
||||
{
|
||||
num = x.num,
|
||||
f_number = x.f_number,
|
||||
u_name = x.u_name,
|
||||
sex = x.sex,
|
||||
birthday = x.birthday, //?.ToString("yyyy/MM/dd"),
|
||||
birthday2 = publicFun.chagenDate(x.birthday), //?.ToString("yyyy/MM/dd"),
|
||||
sign = Model.follower.chagenSign(x.birthday), //NULL??
|
||||
sexagenary = Model.follower.sexagenary(x.birthday),
|
||||
identity_type = x.identity_type,
|
||||
identity_type_desc = tdesc[x.identity_type ?? 1],//TryGetValue..
|
||||
id_code=x.id_code,
|
||||
id_codeDes=encrypt.DecryptAutoKey(x.id_code),
|
||||
passport=x.passport,
|
||||
passportDes=encrypt.DecryptAutoKey(x.passport),
|
||||
phone = x.phone,
|
||||
phoneDes = encrypt.DecryptAutoKey(x.phone), //--MyWeb.function X
|
||||
refugedate = x.refugedate,
|
||||
refuge_name = x.refuge_name,
|
||||
email = x.email,
|
||||
address = x.address,
|
||||
cellphone = x.cellphone,
|
||||
cellphoneDes = encrypt.DecryptAutoKey(x.cellphone),
|
||||
|
||||
}).FirstOrDefault()
|
||||
};
|
||||
|
||||
|
||||
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/follower/GetList")]
|
||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.follower q,
|
||||
@@ -150,8 +343,10 @@ public class FollowerController : ApiController
|
||||
qry = qry.Where(o => o.u_name.Contains(q.u_name.Trim()));
|
||||
if (q.birthday.HasValue)
|
||||
qry = qry.Where(o => o.birthday >= q.birthday.Value);
|
||||
if (q.birthday2.HasValue)
|
||||
qry = qry.Where(o => o.birthday < Convert.ToDateTime(q.birthday2.Value).AddDays(1));
|
||||
if (q.birthday2.HasValue) {
|
||||
var tmpBirthday2 = Convert.ToDateTime(q.birthday2.Value).AddDays(1);
|
||||
qry = qry.Where(o => o.birthday < tmpBirthday2);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.address))
|
||||
qry = qry.Where(o => o.address !=null && o.address.Contains(q.address.Trim()));
|
||||
//if (q.num.HasValue && q.num.Value>0)
|
||||
@@ -173,7 +368,7 @@ public class FollowerController : ApiController
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 電話/證號搜尋 (使用 search_keywords HEX 編碼)
|
||||
if (!string.IsNullOrEmpty(q.phone_idcode) && GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
@@ -655,8 +850,10 @@ public class FollowerController : ApiController
|
||||
list = orderrecord.Select(x => new
|
||||
{
|
||||
orderno = x.order_no,
|
||||
startdate = x.reg_time,
|
||||
endtime = x.up_time,
|
||||
//startdate = x.reg_time,
|
||||
//endtime = x.up_time,
|
||||
startdate = x.activity.startDate_solar,
|
||||
enddate = x.activity.endDate_solar,
|
||||
pwcount = x.pro_order_detail.Where(a => a.actItem.act_bom.Where(b => b.item_num == a.actItem_num && b.package_num == null).Count() == 0).Count(),
|
||||
amount = x.pro_order_detail.Select(o => (float?)o.price).Sum(),
|
||||
activityname = x.activity.subject,
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
using System;
|
||||
using DocumentFormat.OpenXml.Drawing.Spreadsheet;
|
||||
using Model;
|
||||
using Newtonsoft.Json;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using PagedList;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using PagedList;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections;
|
||||
using System.Web.Services;
|
||||
using static TreeView;
|
||||
using System.Data.Entity;
|
||||
|
||||
// api/activity
|
||||
//[ezAuthorize(Roles = "admin")]//群組:*
|
||||
@@ -126,6 +130,12 @@ public class activityController : ApiController
|
||||
if (prod != null)
|
||||
{
|
||||
////prod.IsDel = true; ////不確定是否新增欄位? 先註解
|
||||
|
||||
// 先刪除子項目
|
||||
var prod2 = _db.act_bom.Where(q => q.package_num == prod.num).ToList();
|
||||
_db.act_bom.RemoveRange(prod2);
|
||||
|
||||
_db.actItems.Remove(prod);
|
||||
_db.SaveChanges();
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
MyWeb.admin admin = new MyWeb.admin();//api裡不可以用MyWeb
|
||||
@@ -190,12 +200,18 @@ public class activityController : ApiController
|
||||
if (prod.Count() > 0)
|
||||
{
|
||||
//var prod2 = _db.actItem_files.AsEnumerable().Where(q => ids.Contains(Convert.ToInt32(q.actItem_num))).ToList();
|
||||
var prod2 = _db.actItem_files.Where(q => ids.Contains(q.actItem_num)).ToList();
|
||||
if (prod2.Count > 0)
|
||||
{
|
||||
_db.actItem_files.RemoveRange(prod2);
|
||||
//_db.SaveChanges();
|
||||
}
|
||||
//var prod2 = _db.actItem_files.Where(q => ids.Contains(q.actItem_num)).ToList();
|
||||
//if (prod2.Count > 0)
|
||||
//{
|
||||
// _db.actItem_files.RemoveRange(prod2);
|
||||
// //_db.SaveChanges();
|
||||
//}
|
||||
|
||||
// 先刪除子項目
|
||||
var parentBoms = _db.act_bom.Where(q => q.item_num.HasValue && ids.Contains(q.item_num.Value)).ToList();
|
||||
var parentIds = parentBoms.Select(x => x.num).ToList(); // 取得母件 id
|
||||
var childBoms = _db.act_bom.Where(q => q.package_num.HasValue && parentIds.Contains(q.package_num.Value)).ToList();
|
||||
_db.act_bom.RemoveRange(childBoms);
|
||||
|
||||
_db.actItems.RemoveRange(prod);
|
||||
_db.SaveChanges();
|
||||
@@ -219,6 +235,149 @@ public class activityController : ApiController
|
||||
var count = _db.activities.Count();
|
||||
return count;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/activity/CopyActivity")]
|
||||
public IHttpActionResult CopyActivity([FromBody] Model.ViewModel.activity act)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = _db.activities.Where(x => x.num == act.num).AsNoTracking().FirstOrDefault();
|
||||
var relations = _db.activity_relating.AsNoTracking().Where(x => x.activity_num == act.num).AsNoTracking().ToList();
|
||||
|
||||
activity.num = 0;
|
||||
activity.subject = act.subject;
|
||||
activity.startDate_solar = DateTime.Parse(act.up_time1);
|
||||
activity.endDate_solar = DateTime.Parse(act.up_time2);
|
||||
activity.dueDate = DateTime.Parse(act.deadline);
|
||||
_db.activities.Add(activity);
|
||||
_db.SaveChanges();
|
||||
foreach (var item in relations)
|
||||
{
|
||||
item.num = 0;
|
||||
item.activity_num = activity.num;
|
||||
item.reg_time = DateTime.Now;
|
||||
_db.activity_relating.Add(item);
|
||||
}
|
||||
|
||||
_db.SaveChanges();
|
||||
|
||||
return Ok(new { result = "Y", message =$"完成 {activity.num} " });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new {result="N",message=ex.Message});
|
||||
// throw;
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/activity/GetListNew")]
|
||||
public IHttpActionResult GetListNew([FromBody] Model.ViewModel.activity q, int page, int pageSize = 10,
|
||||
string sortBy = "", bool sortDesc = false)
|
||||
{
|
||||
var qry = _db.activities.AsQueryable();
|
||||
if (!string.IsNullOrEmpty(q.subject))
|
||||
qry = qry.Where(o => o.subject.Contains(q.subject));
|
||||
if (q.kind.HasValue && q.kind > 0)
|
||||
{
|
||||
var _subKinds = new TreeView().subKinds(_db.activity_kind.Select(o => new TreeItem()
|
||||
{
|
||||
num = o.num,
|
||||
root = o.root,
|
||||
}).ToList(), q.kind.Value);
|
||||
|
||||
//qry = qry.Where(o => o.kind == q.kind);
|
||||
qry = qry.Where(o => o.kind == q.kind.Value || _subKinds.Any(s => s == o.kind));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.up_time1))
|
||||
{
|
||||
var s = DateTime.Parse(q.up_time1);
|
||||
qry = qry.Where(o => o.startDate_solar <=s&&o.endDate_solar>=s);
|
||||
}
|
||||
|
||||
//if (!string.IsNullOrEmpty(q.up_time2))
|
||||
//{
|
||||
// var end = DateTime.Parse(q.up_time2);
|
||||
// qry = qry.Where(o => o.endDate_solar<=end);
|
||||
//}
|
||||
|
||||
if (!string.IsNullOrEmpty(q.kindTxt))
|
||||
qry = qry.Where(o => o.activity_kind.kind.Contains(q.kindTxt));
|
||||
|
||||
if (sortBy.Equals("subject"))
|
||||
{
|
||||
if (sortDesc)
|
||||
qry = qry.OrderByDescending(o => o.subject);
|
||||
else
|
||||
qry = qry.OrderBy(o => o.subject);
|
||||
}
|
||||
else if (sortBy.Equals("kind"))
|
||||
{
|
||||
if (sortDesc)
|
||||
qry = qry.OrderByDescending(o => o.kind);
|
||||
else
|
||||
qry = qry.OrderBy(o => o.kind);
|
||||
}
|
||||
else if (sortBy.Equals("startDate_solar"))
|
||||
{
|
||||
if (sortDesc)
|
||||
qry = qry.OrderByDescending(o => o.startDate_solar);
|
||||
else
|
||||
qry = qry.OrderBy(o => o.startDate_solar);
|
||||
}
|
||||
else if (sortBy.Equals("endDate_solar"))
|
||||
{
|
||||
if (sortDesc)
|
||||
qry = qry.OrderByDescending(o => o.endDate_solar);
|
||||
else
|
||||
qry = qry.OrderBy(o => o.endDate_solar);
|
||||
}
|
||||
else if (sortBy.Equals("dueDate"))
|
||||
{
|
||||
if (sortDesc)
|
||||
qry = qry.OrderByDescending(o => o.dueDate);
|
||||
else
|
||||
qry = qry.OrderBy(o => o.dueDate);
|
||||
}
|
||||
else
|
||||
qry = qry.OrderByDescending(o => o.num);
|
||||
|
||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
|
||||
|
||||
var ret = new
|
||||
{
|
||||
list = qryList.Select(x => new
|
||||
{
|
||||
num = x.num,
|
||||
subject = x.subject,
|
||||
kind = x.kind,
|
||||
kindTxt = x.kind.HasValue ? x.activity_kind.kind : "",
|
||||
kindsTxt = x.kind.HasValue ? new TreeView().kindText(_db.activity_kind.Select(o => new TreeItem()
|
||||
{
|
||||
kind = o.kind,
|
||||
num = o.num,
|
||||
root = o.root,
|
||||
}).ToList(), x.kind) : "",
|
||||
startDate_solar = x.startDate_solar,
|
||||
endDate_solar = x.endDate_solar,
|
||||
startDate_lunar = x.startDate_lunar,
|
||||
endDate_lunar = x.endDate_lunar,
|
||||
dueDate = x.dueDate,
|
||||
orderCounts = _db.pro_order.Where(y => y.activity_num == x.num).Count(),
|
||||
}),
|
||||
count = count,
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
if (ret.list == null) throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/activity/GetList")]
|
||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.activity q, int page, int pageSize = 10,
|
||||
@@ -314,6 +473,36 @@ public class activityController : ApiController
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
public class SortOrderRequest
|
||||
{
|
||||
public List<int> ids { get; set; }
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/activity/SaveItemList")]
|
||||
public IHttpActionResult UpdateSortOrder([FromBody] SortOrderRequest request)
|
||||
{
|
||||
if (request == null || request.ids == null) return BadRequest();
|
||||
|
||||
using (Model.ezEntities _db = new Model.ezEntities())
|
||||
{
|
||||
int totalCount = request.ids.Count;
|
||||
|
||||
for (int i = 0; i < totalCount; i++)
|
||||
{
|
||||
int id = request.ids[i];
|
||||
var item = _db.actItems.FirstOrDefault(x => x.num == id);
|
||||
if (item != null)
|
||||
{
|
||||
// 改成總數減去索引,這樣第一筆 (i=0) 會拿到最大的數字
|
||||
item.sort_order = totalCount - i;
|
||||
}
|
||||
}
|
||||
_db.SaveChanges();
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/activity/GetItemList")]
|
||||
public IHttpActionResult GetItemList([FromBody] Model.ViewModel.actItem q, int page, int pageSize = 10,
|
||||
@@ -418,8 +607,14 @@ public class activityController : ApiController
|
||||
else
|
||||
qry = qry.OrderBy(o => o.status);
|
||||
}
|
||||
else
|
||||
else if (sortBy.Equals("num"))
|
||||
{
|
||||
qry = qry.OrderByDescending(o => o.num);
|
||||
}
|
||||
else
|
||||
{
|
||||
qry = qry.OrderByDescending(o => o.sort_order);
|
||||
}
|
||||
|
||||
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||
@@ -905,6 +1100,7 @@ public class activityController : ApiController
|
||||
{
|
||||
text = x.actItem?.subject,
|
||||
val = x.actItem_num,
|
||||
style=x.actItem.defaultStyle
|
||||
},
|
||||
price = x.price ?? 0,
|
||||
qty = x.qty ?? 0,
|
||||
@@ -956,6 +1152,7 @@ public class activityController : ApiController
|
||||
{
|
||||
text = x.actItem?.subject,
|
||||
val = x.actItem_num,
|
||||
style=x.actItem.defaultStyle
|
||||
},
|
||||
price = x.price ?? 0,
|
||||
qty = x.qty ?? 0,
|
||||
@@ -1303,7 +1500,7 @@ public class activityController : ApiController
|
||||
[Route("api/activity/OrderCheckIn")]
|
||||
public IHttpActionResult OrderCheckIn([FromBody] Model.activity_check item)
|
||||
{
|
||||
if (item.f_num.HasValue && item.activity_num.HasValue && item.qty.HasValue && item.status.HasValue)
|
||||
if (item.f_num.HasValue && item.activity_num.HasValue && item.status.HasValue)
|
||||
{
|
||||
//同一天不能簽到兩次以上
|
||||
Model.activity_check check = _db.activity_check
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
using System;
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using Model;
|
||||
using MyWeb;
|
||||
using Newtonsoft.Json;
|
||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using PagedList;
|
||||
using System;
|
||||
using System.Activities.Expressions;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Entity;
|
||||
using System.Diagnostics;
|
||||
using System.IdentityModel.Metadata;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Web.Helpers;
|
||||
using System.Web.Http;
|
||||
using PagedList;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections;
|
||||
using static TreeView;
|
||||
using Model;
|
||||
using System.IdentityModel.Metadata;
|
||||
using MyWeb;
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
|
||||
|
||||
// api/order
|
||||
@@ -200,13 +207,233 @@ public class orderController : ApiController
|
||||
var count = _db.pro_order.Count();
|
||||
return count;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/order/BatchSave")]
|
||||
public IHttpActionResult BatchSave([FromBody] Model.ViewModel.pro_order po)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = _db.pro_order.AsNoTracking().Where(x => x.activity_num == po.old_activity_num).AsQueryable();
|
||||
query = query.Include(x => x.pro_order_detail).AsNoTracking();
|
||||
query = query.Where(x => po.orders.Contains(x.order_no));
|
||||
var list = query.ToList();
|
||||
List<Model.pro_order> orders = new List<Model.pro_order>();
|
||||
List<Model.pro_order_detail> order_details = new List<pro_order_detail>();
|
||||
|
||||
var act=_db.activities.Where(x=>x.num==po.activity_num).FirstOrDefault();
|
||||
var hasList = _db.pro_order.AsNoTracking().Where(x => x.activity_num == po.activity_num).AsNoTracking().ToList();
|
||||
List<int> rp=new List<int>();
|
||||
//要檢查是否已經報名
|
||||
foreach (var item in list)
|
||||
{
|
||||
var already=hasList.Where(x => x.f_num == item.f_num).FirstOrDefault();
|
||||
if (already != null&&!string.IsNullOrEmpty(already.order_no))
|
||||
{
|
||||
rp.Add((int)already.f_num);
|
||||
continue;
|
||||
}
|
||||
//Model.pro_order order = new Model.pro_order();
|
||||
//order.phone = item.phone;
|
||||
//order.follower1 = item.follower1;
|
||||
//order.address = item.address;
|
||||
//order.activity_num = po.activity_num;
|
||||
//order.up_time = DateTime.Now;
|
||||
//order.reg_time = DateTime.Now;
|
||||
////order.follower = item.follower;//加了會去寫followers
|
||||
//order.f_num = item.f_num;
|
||||
//order.keyin1 = item.keyin1;
|
||||
//order.introducer = item.introducer;
|
||||
//order.send_receipt = item.send_receipt;
|
||||
//order.receipt_title = item.receipt_title;
|
||||
//order.order_no = createOrderNumber();
|
||||
item.reg_time= DateTime.Now;
|
||||
item.up_time= DateTime.Now;
|
||||
item.order_no= createOrderNumber();
|
||||
item.activity_num= po.activity_num;
|
||||
|
||||
_db.pro_order.Add(item);
|
||||
orders.Add(item);
|
||||
foreach (var detail in item.pro_order_detail)
|
||||
{
|
||||
//Model.pro_order_detail order_detail = new Model.pro_order_detail();
|
||||
//order_detail.order_no = order.order_no;
|
||||
//order_detail.actItem_num = detail.actItem_num;
|
||||
//order_detail.parent_num = detail.parent_num;
|
||||
//order_detail.print_id = detail.print_id;
|
||||
//order_detail.f_num = detail.f_num;
|
||||
//order_detail.f_num_tablet = detail.f_num_tablet;
|
||||
//order_detail.from_id = detail.from_id;
|
||||
//order_detail.from_id_tablet = detail.from_id_tablet;
|
||||
//order_detail.price = detail.price;
|
||||
//order_detail.qty = detail.qty;
|
||||
//order_detail.printed_files = detail.printed_files;
|
||||
//order_detail.style = detail.style;
|
||||
//order_detail.UpdateTime=DateTime.Now;
|
||||
//order_details.Add(order_detail);
|
||||
detail.order_no=item.order_no;
|
||||
detail.UpdateTime= DateTime.Now;
|
||||
detail.start_date= act.startDate_solar;
|
||||
detail.due_date= act.endDate_solar;
|
||||
_db.pro_order_detail.Add(detail);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//_db.pro_order.AddRange(orders);
|
||||
//_db.SaveChanges();
|
||||
//_db.pro_order_detail.AddRange(order_details);
|
||||
_db.SaveChanges();
|
||||
return Ok(new {result="Y",message="完成",data=rp});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { result = "Y",message=ex.Message+ex.StackTrace });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/order/AddOrderWithDetail")]
|
||||
public IHttpActionResult AddOrderWithDetail([FromBody] Model.ViewModel.pro_order q)
|
||||
{
|
||||
try
|
||||
{
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
//先塞信眾
|
||||
Model.follower follower = new Model.follower();
|
||||
follower.u_name = q.f_user.u_name;
|
||||
follower.phone = encrypt.EncryptAutoKey(q.f_user.phone);
|
||||
follower.cellphone = encrypt.EncryptAutoKey(q.f_user.cellphone);
|
||||
follower.country = q.f_user.country;
|
||||
follower.id_code = q.f_user.id_code;
|
||||
follower.sex = q.f_user.sex;
|
||||
follower.identity_type = q.f_user.identity_type;
|
||||
follower.birthday = q.f_user.birthday;
|
||||
string sex = q.f_user.sex;
|
||||
follower.f_number = Model.follower.generate_f_number(sex);
|
||||
_db.followers.Add(follower);
|
||||
_db.SaveChanges();
|
||||
int _id = follower.num;//取回信眾的sql server自動編號
|
||||
Hashtable ht= new Hashtable();
|
||||
//再塞親友
|
||||
foreach (var detail in q.details)
|
||||
{
|
||||
//要考慮相同名字只能塞一次,下一個遇到要幫他塞回num
|
||||
foreach (var mid in detail.mid_items)
|
||||
{
|
||||
if (ht.ContainsKey(mid.fam_name))
|
||||
{
|
||||
mid.num = int.Parse(ht[mid.fam_name].ToString());
|
||||
continue;
|
||||
}
|
||||
Model.family_members fam = new Model.family_members();
|
||||
fam.follower_num = _id;
|
||||
fam.fam_name = mid.fam_name;
|
||||
fam.deceased = mid.deceased;
|
||||
_db.family_members.Add(fam);
|
||||
_db.SaveChanges();
|
||||
|
||||
mid.num = fam.num;
|
||||
ht.Add(mid.fam_name, fam.num);
|
||||
}
|
||||
foreach (var left in detail.left_items)
|
||||
{
|
||||
if (ht.ContainsKey(left.fam_name))
|
||||
{
|
||||
left.num =int.Parse( ht[left.fam_name].ToString());
|
||||
continue;
|
||||
}
|
||||
Model.family_members fam = new Model.family_members();
|
||||
fam.follower_num = _id;
|
||||
fam.fam_name = left.fam_name;
|
||||
fam.deceased = left.deceased;
|
||||
_db.family_members.Add(fam);
|
||||
_db.SaveChanges();
|
||||
left.num = fam.num;
|
||||
ht.Add(left.fam_name, fam.num);
|
||||
}
|
||||
}
|
||||
|
||||
//再來報名主檔
|
||||
Model.pro_order order = new Model.pro_order();
|
||||
order.order_no = createOrderNumber();
|
||||
order.up_time = DateTime.Now;
|
||||
order.reg_time = DateTime.Now;
|
||||
order.keyin1 = "A01";
|
||||
order.f_num = _id;
|
||||
order.phone = !string.IsNullOrEmpty(q.f_user.phone)?
|
||||
encrypt.EncryptAutoKey(q.f_user.phone): encrypt.EncryptAutoKey(q.f_user.cellphone);
|
||||
order.activity_num = q.activity_num;
|
||||
order.address = q.f_user.address;
|
||||
order.demo = "";
|
||||
order.send_receipt=false;
|
||||
_db.pro_order.Add(order);
|
||||
//最後功德項目
|
||||
foreach (var detail in q.details)
|
||||
{
|
||||
Model.pro_order_detail o_detail = new Model.pro_order_detail();
|
||||
o_detail.order_no = order.order_no;
|
||||
o_detail.actItem_num = detail.actItem_num;
|
||||
o_detail.price = detail.price;
|
||||
o_detail.qty = detail.qty;
|
||||
o_detail.printed_files = detail.printed_files;
|
||||
o_detail.style = detail.style;
|
||||
Newtonsoft.Json.Linq.JArray mid_items = new Newtonsoft.Json.Linq.JArray();
|
||||
foreach (var data in detail.mid_items)
|
||||
{
|
||||
Newtonsoft.Json.Linq.JObject item = new Newtonsoft.Json.Linq.JObject();
|
||||
item["num"] = data.num;
|
||||
item["fam_name"] = data.fam_name;
|
||||
item["fam_gender"] = "";
|
||||
item["deceased"] = data.deceased;
|
||||
item["fam_title"] = "";
|
||||
item["option_break"] = false;
|
||||
item["IsShuWen"] = false;
|
||||
mid_items.Add(item);
|
||||
}
|
||||
|
||||
Newtonsoft.Json.Linq.JArray left_items = new Newtonsoft.Json.Linq.JArray();
|
||||
foreach (var data in detail.left_items)
|
||||
{
|
||||
Newtonsoft.Json.Linq.JObject item = new Newtonsoft.Json.Linq.JObject();
|
||||
item["num"] = data.num;
|
||||
item["fam_name"] = data.fam_name;
|
||||
item["fam_gender"] = "";
|
||||
item["deceased"] = data.deceased;
|
||||
item["fam_title"] = "";
|
||||
item["option_break"] = false;
|
||||
item["IsShuWen"] = false;
|
||||
left_items.Add(item);
|
||||
}
|
||||
Newtonsoft.Json.Linq.JObject tablet = new Newtonsoft.Json.Linq.JObject();
|
||||
tablet["mid_items"] = mid_items;
|
||||
tablet["left_items"] = left_items;
|
||||
o_detail.f_num_tablet = tablet.ToString();
|
||||
_db.pro_order_detail.Add(o_detail);
|
||||
}
|
||||
_db.SaveChanges();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
result = "Y",message="報名成功"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new
|
||||
{
|
||||
result = "N",message=ex.Message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/order/GetList")]
|
||||
public IHttpActionResult GetList([FromBody] Model.ViewModel.pro_order q, int page, int pageSize = 10,
|
||||
string sortBy = "", bool sortDesc = false)
|
||||
{
|
||||
|
||||
var qry = _db.pro_order.AsQueryable();
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
var qry = _db.pro_order.Include("activity").Include("activity.activity_check").AsQueryable();
|
||||
//var aIDt = _db.actItems.AsEnumerable().Where(f => f.subject.Contains(q.actItemTxt.Trim())).Select(f => f.num);//品項
|
||||
|
||||
|
||||
@@ -221,7 +448,10 @@ public class orderController : ApiController
|
||||
if (q.up_time1.HasValue)
|
||||
qry = qry.Where(o => o.up_time >= q.up_time1.Value);
|
||||
if (q.up_time2.HasValue)
|
||||
qry = qry.Where(o => o.up_time < Convert.ToDateTime(q.up_time2.Value).AddDays(1));
|
||||
{
|
||||
var tmp_up_time2 = Convert.ToDateTime(q.up_time2.Value).AddDays(1);
|
||||
qry = qry.Where(o => o.up_time < tmp_up_time2);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(q.address))
|
||||
qry = qry.Where(o => o.address.Contains(q.address.Trim()));
|
||||
if (!string.IsNullOrEmpty(q.subject))
|
||||
@@ -255,6 +485,21 @@ public class orderController : ApiController
|
||||
}
|
||||
}
|
||||
|
||||
if (q.f_user!=null&&!string.IsNullOrEmpty(q.f_user.u_name)) {
|
||||
qry = qry.Where(o => o.f_num != null && o.follower != null && o.follower.u_name ==q.f_user.u_name);
|
||||
}
|
||||
if (q.f_user != null && !string.IsNullOrEmpty(q.f_user.phone))
|
||||
{
|
||||
qry = qry.Where(o => o.f_num != null && o.follower != null && encrypt.DecryptAutoKey(o.follower.phone) == q.f_user.phone);
|
||||
}
|
||||
if (q.f_user != null && !string.IsNullOrEmpty(q.f_user.cellphone))
|
||||
{
|
||||
qry = qry.Where(o => o.f_num != null && o.follower != null && encrypt.DecryptAutoKey(o.follower.cellphone) == q.f_user.cellphone);
|
||||
}
|
||||
if (q.f_user != null && !string.IsNullOrEmpty(q.f_user.id_code))
|
||||
{
|
||||
qry = qry.Where(o => o.f_num != null && o.follower != null && encrypt.DecryptAutoKey(o.follower.id_code) == q.f_user.id_code);
|
||||
}
|
||||
|
||||
if (sortBy.Equals("order_no"))
|
||||
{
|
||||
@@ -291,10 +536,23 @@ public class orderController : ApiController
|
||||
else
|
||||
qry = qry.OrderBy(o => o.activity != null ? o.activity.subject : "");
|
||||
}
|
||||
else if(sortBy.Equals("status"))
|
||||
{
|
||||
if (sortDesc)
|
||||
qry = qry.OrderByDescending(o => o.activity.activity_check.FirstOrDefault(a => o.activity_num == a.activity_num && o.f_num == a.f_num).status ?? 0);
|
||||
else
|
||||
qry = qry.OrderBy(o => o.activity.activity_check.FirstOrDefault(a => o.activity_num == a.activity_num && o.f_num == a.f_num).status ?? 0);
|
||||
}
|
||||
else
|
||||
qry = qry.OrderByDescending(o => o.reg_time);
|
||||
|
||||
var count = qry.Count(); //pageSize = count;//一次取回??
|
||||
if (pageSize==-1)
|
||||
{
|
||||
pageSize = count;
|
||||
}
|
||||
if(pageSize==0)
|
||||
pageSize = 10;
|
||||
var ret = new
|
||||
{
|
||||
list = qry.ToPagedList(page, pageSize).Select(x => new
|
||||
@@ -307,6 +565,7 @@ public class orderController : ApiController
|
||||
keyin1 = x.keyin1,
|
||||
up_time = x.up_time,
|
||||
keyin1_txt = Model.pro_order.keyin1_value_to_text(x.keyin1),
|
||||
status = x.activity.activity_check.FirstOrDefault(a => x.activity_num == a.activity_num && x.f_num == a.f_num)?.status ?? 0,
|
||||
}),
|
||||
count = count
|
||||
};
|
||||
@@ -316,7 +575,7 @@ public class orderController : ApiController
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[HttpPost,HttpGet]
|
||||
[Route("api/order/GetItemList")]
|
||||
public IHttpActionResult GetItemList([FromBody] Model.ViewModel.pro_order_detail q, int page, int pageSize = 10,
|
||||
string sortBy = "", bool sortDesc = false)
|
||||
@@ -338,7 +597,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));
|
||||
@@ -379,13 +638,19 @@ public class orderController : ApiController
|
||||
|
||||
var ret = new
|
||||
{
|
||||
list = qry1_list.Select(x => 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
|
||||
{
|
||||
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,
|
||||
},
|
||||
@@ -499,6 +764,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
|
||||
{
|
||||
@@ -579,6 +848,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 = "",
|
||||
@@ -663,11 +936,112 @@ public class orderController : ApiController
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/order/SaveWithDetails")]
|
||||
public IHttpActionResult SaveWithDetails([FromBody] Model.ViewModel.pro_order item)
|
||||
{
|
||||
try
|
||||
{
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
Model.pro_order new_pro_order = new Model.pro_order();//新增
|
||||
|
||||
new_pro_order.order_no = createOrderNumber();
|
||||
var details = item.details;
|
||||
var last_order_no = details[0].order_no;
|
||||
//撈前次報名的資料塞進去
|
||||
var last_order = _db.pro_order.Where(x => x.order_no == last_order_no).FirstOrDefault();
|
||||
if (last_order != null)
|
||||
{
|
||||
|
||||
new_pro_order.up_time = DateTime.Now;
|
||||
new_pro_order.reg_time = DateTime.Now;
|
||||
new_pro_order.phone = last_order.phone;
|
||||
new_pro_order.address = last_order.address;
|
||||
new_pro_order.keyin1 = last_order.keyin1;
|
||||
new_pro_order.f_num = item.f_num;
|
||||
new_pro_order.activity_num = item.activity_num;
|
||||
new_pro_order.demo = last_order.demo;
|
||||
new_pro_order.customize_data = last_order.customize_data;
|
||||
new_pro_order.send_receipt = last_order.send_receipt;
|
||||
new_pro_order.receipt_title = last_order.receipt_title;
|
||||
_db.pro_order.Add(new_pro_order);
|
||||
|
||||
|
||||
foreach (var item1 in details)
|
||||
{//如果item1 change_item_num 有值且不為0,表示要複製過來
|
||||
var last_detail = _db.pro_order_detail.Where(x => x.num == item1.num).FirstOrDefault();
|
||||
var detail = new pro_order_detail();
|
||||
detail.order_no = new_pro_order.order_no;
|
||||
detail.actItem_num = (item1.change_item_num!=null&&item1.change_item_num!=0)?item1.change_item_num: last_detail.actItem_num;
|
||||
detail.f_num_tablet = last_detail.f_num_tablet;
|
||||
detail.from_id = (item1.change_item_num != null && item1.change_item_num != 0) ? item.f_num: last_detail.from_id;
|
||||
detail.price = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.price : last_detail.price;
|
||||
detail.qty = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.qty : last_detail.qty;
|
||||
detail.printed_files = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.printed_files : last_detail.printed_files;
|
||||
detail.style = (item1.change_item_num != null && item1.change_item_num != 0) ? item1.style : last_detail.style;
|
||||
detail.UpdateTime = DateTime.Now;
|
||||
detail.start_date = DateTime.Now;//這兩個要用活動的
|
||||
detail.due_date = DateTime.Now;//
|
||||
_db.pro_order_detail.Add(detail);
|
||||
}
|
||||
_db.SaveChanges();
|
||||
return Ok(new
|
||||
{
|
||||
result = "Y",
|
||||
message = "報名成功"
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return Ok(new
|
||||
{
|
||||
result = "N",
|
||||
message = "沒有勾選任何功德項目"
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new
|
||||
{
|
||||
result = "N",
|
||||
message = ex.Message+ex.InnerException+ex.StackTrace
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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 (!string.IsNullOrEmpty(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;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/order/SaveDetailData")]
|
||||
@@ -684,7 +1058,7 @@ public class orderController : ApiController
|
||||
.Where(q => q.num == item.num)
|
||||
.FirstOrDefault();//修改
|
||||
if (order != null)
|
||||
{
|
||||
{
|
||||
order.actItem_num = (item.actItem_num.HasValue && item.actItem_num.Value > 0)
|
||||
? item.actItem_num : null;
|
||||
order.f_num = (item.f_num.HasValue && item.f_num.Value > 0)
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
using System;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using MINOM.COM.Utility;
|
||||
using Model.ViewModel;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NPOI.SS.UserModel;
|
||||
using OfficeOpenXml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
@@ -135,4 +145,221 @@ public class statisticsController: ApiController
|
||||
};
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("api/statistics/GetStatistic")]
|
||||
public IHttpActionResult GetStatistic(string statistic_mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
var drafts = (from a in _db.transfer_register
|
||||
select a).ToList();
|
||||
|
||||
string rootPath = HttpRuntime.AppDomainAppPath;
|
||||
string name = $"output{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
|
||||
string fileName = Path.Combine(new string[] { rootPath, "rpt", name });
|
||||
|
||||
var file = new FileInfo($"{fileName}"); // 檔案路徑
|
||||
using (var excel = new ExcelPackage())
|
||||
{
|
||||
LogUtility log = new LogUtility();
|
||||
// 建立分頁
|
||||
var ws = excel.Workbook.Worksheets.Add("MySheet");
|
||||
var data = (from a in _db.activities
|
||||
join b in _db.pro_order on a.num equals b.activity_num
|
||||
join c in _db.pro_order_detail on b.order_no equals c.order_no
|
||||
//join d in _db.activity_relating on a.num equals d.activity_num
|
||||
join f in _db.actItems on c.actItem_num equals f.num
|
||||
select new
|
||||
{
|
||||
a.num,
|
||||
a.subject,
|
||||
b.order_no,
|
||||
b.f_num,
|
||||
order_detail_num = c.num,
|
||||
c.actItem_num,
|
||||
item_subject = f.subject,
|
||||
c.qty,
|
||||
c.price
|
||||
}).ToList();
|
||||
|
||||
int i = 0;
|
||||
i++;
|
||||
if (statistic_mode == "01")
|
||||
{
|
||||
ws.Cells[i, 1].Value = "序號";
|
||||
ws.Cells[i, 2].Value = "法會名稱";
|
||||
ws.Cells[i, 3].Value = "功德項目";
|
||||
ws.Cells[i, 4].Value = "數量";
|
||||
ws.Cells[i, 5].Value = "單價";
|
||||
ws.Cells[i, 6].Value = "小計";
|
||||
ws.Cells[i, 7].Value = "實收";
|
||||
ws.Cells[i, 8].Value = "應收";
|
||||
ws.Cells[i, 9].Value = "應付";
|
||||
i++;
|
||||
var list = data.GroupBy(x => new { x.num, x.subject, x.actItem_num, x.item_subject }).Select(y =>
|
||||
new
|
||||
{
|
||||
y.Key.num,
|
||||
y.Key.subject,
|
||||
y.Key.actItem_num,
|
||||
y.Key.item_subject,
|
||||
qty = y.Where(q => q.num == y.Key.num && q.actItem_num == y.Key.actItem_num).Select(q => q.qty).Sum(),
|
||||
price = y.Where(p => p.num == y.Key.num && p.actItem_num == y.Key.actItem_num).Select(p => p.price).FirstOrDefault()
|
||||
}).ToList();
|
||||
foreach (var item in list)
|
||||
{
|
||||
ws.Cells[i, 1].Value = i - 1;
|
||||
ws.Cells[i, 2].Value = item.subject;
|
||||
ws.Cells[i, 3].Value = item.item_subject;
|
||||
ws.Cells[i, 4].Value = item.qty.Value;
|
||||
ws.Cells[i, 5].Value = item.price.Value;
|
||||
ws.Cells[i, 6].Formula = $"=D{i}*E{i}";
|
||||
|
||||
var draftList = (from a in drafts
|
||||
where a.activity_num == item.num
|
||||
select a).ToList();
|
||||
decimal payed = 0;
|
||||
foreach (var items in draftList)
|
||||
{
|
||||
if (items.draft != null)
|
||||
{
|
||||
if (items.draft .StartsWith("["))
|
||||
{
|
||||
var jj = JsonConvert.DeserializeObject<JArray>(items.draft);
|
||||
log.writeLogPath(jj.ToString());
|
||||
foreach (var j in jj)
|
||||
{
|
||||
if (item.subject == j["activity_name"].ToString() &&
|
||||
item.item_subject == j["actitem_name"].ToString())
|
||||
{
|
||||
payed = payed + decimal.Parse(j["reconcile"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var jj = JsonConvert.DeserializeObject<JObject>(items.draft);
|
||||
foreach (var j in jj["pro_order_detail_items"])
|
||||
{
|
||||
if (item.subject == j["activity_name"].ToString() &&
|
||||
item.item_subject == j["actitem_name"].ToString())
|
||||
{
|
||||
payed = payed + decimal.Parse(j["reconcile"].ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ws.Cells[i, 7].Value = payed;
|
||||
ws.Cells[i, 8].Formula = $"=if(F{i}>G{i},F{i}-G{i},0)";
|
||||
ws.Cells[i, 9].Formula = $"=if(F{i}<G{i},G{i}-F{i},0)";
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
else if (statistic_mode == "02")
|
||||
{
|
||||
var list = (from a in _db.pro_order
|
||||
join b in _db.pro_order_detail on a.order_no equals b.order_no
|
||||
join c in _db.followers on a.f_num equals c.num
|
||||
join d in _db.activities on a.activity_num equals d.num
|
||||
select new
|
||||
{
|
||||
a.order_no,
|
||||
a.f_num,
|
||||
a.activity_num,
|
||||
b.qty,
|
||||
b.price,
|
||||
c.u_name
|
||||
}).ToList();
|
||||
ws.Cells[i, 1].Value = "序號";
|
||||
ws.Cells[i, 2].Value = "信眾編號";
|
||||
ws.Cells[i, 3].Value = "信眾姓名";
|
||||
ws.Cells[i, 4].Value = "總金額";
|
||||
ws.Cells[i, 5].Value = "實收";
|
||||
ws.Cells[i, 6].Value = "應收";
|
||||
ws.Cells[i, 7].Value = "應付";
|
||||
i++;
|
||||
var g = list.GroupBy(y => new { y.f_num, y.u_name }).Select(y => new
|
||||
{
|
||||
y.Key.f_num,
|
||||
y.Key.u_name,
|
||||
total = y.Where(x => x.f_num == y.Key.f_num).Select(x => x.price * x.qty).Sum()
|
||||
});
|
||||
foreach (var item in g)
|
||||
{
|
||||
ws.Cells[i, 1].Value = i - 1;
|
||||
ws.Cells[i, 2].Value = item.f_num;
|
||||
ws.Cells[i, 3].Value = item.u_name;
|
||||
ws.Cells[i, 4].Value = item.total;
|
||||
var dd = (from a in drafts
|
||||
where a.f_num == item.f_num
|
||||
select a).ToList();
|
||||
decimal payed = 0;
|
||||
foreach (var d in dd)
|
||||
{
|
||||
payed = payed + (decimal)d.check_amount;// -(decimal)d.remain_amount;
|
||||
}
|
||||
ws.Cells[i, 5].Value = payed;
|
||||
ws.Cells[i, 6].Formula = $"=if(D{i}>E{i},D{i}-E{i},0)";
|
||||
ws.Cells[i, 7].Formula = $"=if(D{i}<E{i},E{i}-D{i},0)";
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (statistic_mode == "03")
|
||||
{
|
||||
var list = (from a in _db.activities
|
||||
join b in _db.pro_order on a.num equals b.activity_num
|
||||
join c in _db.pro_order_detail on b.order_no equals c.order_no
|
||||
join d in _db.followers on b.f_num equals d.num
|
||||
select new
|
||||
{
|
||||
a.num,a.subject,b.order_no,order_detail_num=c.num,
|
||||
b.f_num,d.u_name,c.price,c.qty
|
||||
}).ToList();
|
||||
ws.Cells[i, 1].Value = "序號";
|
||||
ws.Cells[i, 2].Value = "法會名稱";
|
||||
ws.Cells[i, 3].Value = "信眾姓名";
|
||||
ws.Cells[i, 4].Value = "總金額";
|
||||
ws.Cells[i, 5].Value = "實收";
|
||||
ws.Cells[i, 6].Value = "應收";
|
||||
ws.Cells[i, 7].Value = "應付";
|
||||
i++;
|
||||
var g = list.GroupBy(y => new { y.num, y.subject, y.f_num, y.u_name }).Select(y=>new
|
||||
{
|
||||
y.Key.num,y.Key.subject,y.Key.f_num,y.Key.u_name,
|
||||
total=y.Where(x=>x.num==y.Key.num&&x.f_num==y.Key.f_num).Select(x=>x.price*x.qty).Sum()
|
||||
});
|
||||
foreach (var item in g)
|
||||
{
|
||||
ws.Cells[i, 1].Value = i - 1;
|
||||
ws.Cells[i, 2].Value = item.subject;
|
||||
ws.Cells[i, 3].Value = item.u_name;
|
||||
ws.Cells[i, 4].Value = item.total;
|
||||
var dd = drafts.Where (y=>y.activity_num==item.num&&y.f_num==item.f_num).
|
||||
Select(y => new { y.check_amount, y.remain_amount }).ToList();
|
||||
|
||||
ws.Cells[i, 5].Value = dd.Sum(y=>y.check_amount);
|
||||
ws.Cells[i, 6].Formula = $"=if(D{i}>E{i},D{i}-E{i},0)";
|
||||
ws.Cells[i, 7].Formula = $"=if(D{i}<E{i},E{i}-D{i},0)";
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 儲存 Excel
|
||||
excel.SaveAs(file);
|
||||
}
|
||||
|
||||
return Ok(new { result = "Y", filename = $"rpt/{name}" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Ok(new { result = "N", message = ex.Message});
|
||||
//return BadRequest($"{ex.Message}{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using System.Collections;
|
||||
using MyWeb;
|
||||
using System.Web.WebPages;
|
||||
using System.Data.Entity;
|
||||
using Model;
|
||||
|
||||
[ezAuthorize]
|
||||
public class transfer_registerController : ApiController
|
||||
@@ -269,6 +270,7 @@ public class transfer_registerController : ApiController
|
||||
public string check_memo { get; set; }
|
||||
public string draft { get; set; }
|
||||
public int? acc_kind { get; set; } // 新增關聯欄位
|
||||
public int? kind { get; set; }
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
@@ -315,7 +317,7 @@ public class transfer_registerController : ApiController
|
||||
{
|
||||
uptime = dto.check_date,
|
||||
category = 1, // 收入
|
||||
kind = 27, // 固定值:法會收入/功德項目
|
||||
kind = dto.kind,//27, // 固定值:法會收入/功德項目
|
||||
kind2 = dto.acc_num,
|
||||
price = (float)(dto.check_amount ?? 0),
|
||||
tax = 0,
|
||||
@@ -346,6 +348,7 @@ public class transfer_registerController : ApiController
|
||||
item.check_memo = dto.check_memo;
|
||||
item.draft = dto.draft;
|
||||
item.acc_kind = dto.acc_kind;
|
||||
|
||||
}
|
||||
}
|
||||
_db.SaveChanges();
|
||||
@@ -958,7 +961,10 @@ public class transfer_registerController : ApiController
|
||||
activity_name = x.activity != null ? x.activity.subject : "",
|
||||
activity_num = x.activity_num,
|
||||
acc_name = x.acc_num != null ? _db.accounting_kind2.Where(a => a.num == x.acc_num).Select(a => a.kind).FirstOrDefault() : "",
|
||||
|
||||
price_totals=_db.pro_order_detail.
|
||||
Where(a => _db.pro_order.Where (po=>po.f_num==x.f_num&&po.activity_num==x.activity_num).
|
||||
Select(po => po.order_no).Any(p=>p.Equals(a.order_no))).Sum(a => a.price*a.qty),
|
||||
pay_totals=_db.transfer_register.Where(a=>a.activity_num==x.activity_num&&a.f_num==x.f_num).Sum(a=>a.check_amount),
|
||||
// pro_order_record 資訊 (透過 transfer_id 關聯)
|
||||
pro_order_records = x.pro_order_record.Select(pr => new {
|
||||
pr.num,
|
||||
@@ -1274,4 +1280,23 @@ public class transfer_registerController : ApiController
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//select ord.order_no, ord.activity_num, ord.f_num, ord.u_name, ord.totals as cost, isnull(reg.totals, 0) totals
|
||||
//from (
|
||||
//select o.order_no, o.activity_num, o.f_num, o.u_name, sum(o.totals) as totals from (
|
||||
//select a.order_no, a.f_num, d.u_name, a.activity_num, b.num, b.f_num_tablet,
|
||||
//b.price, b.qty, totals = b.price * b.qty, c.kind, c.subject
|
||||
//from pro_order a
|
||||
//left join pro_order_detail b on a.order_no=b.order_no
|
||||
//left join actItem c on b.actItem_num=c.num
|
||||
//left join followers d on a.f_num=d.num )o
|
||||
//group by o.order_no, o.activity_num, o.f_num, o.u_name) ord
|
||||
//left join (
|
||||
//select a.activity_num, a.f_num, sum(a.amount) totals from transfer_register a
|
||||
//where status='2' and check_status='99'
|
||||
//group by a.activity_num, a.f_num
|
||||
//) reg on ord.activity_num=reg.activity_num and ord.f_num=reg.f_num
|
||||
@@ -8,13 +8,14 @@
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<PublishProvider>FileSystem</PublishProvider>
|
||||
<PublishUrl>C:\17168web</PublishUrl>
|
||||
<PublishUrl>D:\17168web</PublishUrl>
|
||||
<WebPublishMethod>FileSystem</WebPublishMethod>
|
||||
<_TargetId>Folder</_TargetId>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<PrecompileBeforePublish>true</PrecompileBeforePublish>
|
||||
<EnableUpdateable>true</EnableUpdateable>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<WDPMergeOption>DonotMerge</WDPMergeOption>
|
||||
<WDPMergeOption>CreateSeparateAssembly</WDPMergeOption>
|
||||
<UseFixedNames>true</UseFixedNames>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -16,6 +16,8 @@
|
||||
<asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound">
|
||||
<ItemTemplate>
|
||||
<a class="nav-link" href="<%#ResolveUrl(ValString(Eval("url"))) %>"
|
||||
onclick="sessionStorage.removeItem('member_list_cache'); sessionStorage.removeItem('member_query_params');
|
||||
sessionStorage.removeItem('order_list_cache'); sessionStorage.removeItem('order_query_params');"
|
||||
target="<%#(ValString(Eval("target"))=="B"?"_blank":"_self") %>">
|
||||
<%#Eval("title") %></a>
|
||||
</ItemTemplate>
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
|
||||
<style>
|
||||
.v-dialog{
|
||||
width:80% !important;
|
||||
}
|
||||
</style>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
|
||||
<div class="mb-2 mb-sm-0">
|
||||
@@ -53,7 +58,19 @@
|
||||
search: {
|
||||
kind: 0,
|
||||
subject: '',
|
||||
}
|
||||
},
|
||||
signData: {
|
||||
subject: "",
|
||||
up_time1: "",
|
||||
up_time2: "",
|
||||
deadline: "",
|
||||
num:null
|
||||
},
|
||||
startmenu: false,
|
||||
endmenu: false,
|
||||
deadmenu: false,
|
||||
copy_dialog: { show: false, show_confirm: false, message: "" },
|
||||
message_dialog: { show: false, show_confirm: false, message: "" },
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -84,6 +101,30 @@
|
||||
editItem(item) {
|
||||
console.log("edit", item);
|
||||
},
|
||||
copyItem(item) {
|
||||
|
||||
this.signData.num=item.num
|
||||
this.copy_dialog.show = true
|
||||
},
|
||||
gotoCopy() {
|
||||
if (this.signData.subject == "" || this.signData.up_time1 == "" || this.signData.up_time2 == "" || this.signData.deadline == "") {
|
||||
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message = "所有欄位都必須填寫"
|
||||
return false;
|
||||
}
|
||||
axios
|
||||
.post(HTTP_HOST + "api/activity/CopyActivity", this.signData)
|
||||
.then(response => {
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message = response.data.message
|
||||
if (response.data.result === "Y") {
|
||||
this.copy_dialog.show = false;
|
||||
}
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
|
||||
},
|
||||
deleteItem(item) {
|
||||
if (confirm('是否確定刪除此筆資料?')) {
|
||||
const index = this.data_table.list.indexOf(item)
|
||||
@@ -166,6 +207,7 @@
|
||||
</template>
|
||||
<template #item.slot_btn="{ item }">
|
||||
<a :href="'reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
||||
<a @click="copyItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>複製</a>
|
||||
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
|
||||
</template>
|
||||
</v-data-table>
|
||||
@@ -194,6 +236,85 @@
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
<v-dialog v-model="message_dialog.show" class="dialog_width">
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ message_dialog.message }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="message_dialog.show=false" v-if="!message_dialog.show_confirm">關閉</v-btn>
|
||||
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
<v-dialog v-model="copy_dialog.show" class="dialog_width">
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<v-text-field v-model="signData.subject"
|
||||
label="請輸入法會名稱"></v-text-field>
|
||||
|
||||
<v-menu v-model="startmenu"
|
||||
:close-on-content-click="false"
|
||||
:nudge-right="40"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="signData.up_time1"
|
||||
label="開始日期"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="signData.up_time1"
|
||||
@input="startmenu = false"></v-date-picker>
|
||||
</v-menu>
|
||||
<v-menu v-model="endmenu"
|
||||
:close-on-content-click="false"
|
||||
:nudge-right="40"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="signData.up_time2"
|
||||
label="結束日期"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="signData.up_time2"
|
||||
@input="endmenu = false"></v-date-picker>
|
||||
</v-menu>
|
||||
<v-menu v-model="deadmenu"
|
||||
:close-on-content-click="false"
|
||||
:nudge-right="40"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="signData.deadline"
|
||||
label="報名截止日"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="signData.deadline"
|
||||
@input="deadmenu = false"></v-date-picker>
|
||||
</v-menu>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="copy_dialog.show=false">關閉</v-btn>
|
||||
<v-btn @click.prevent="gotoCopy()">確認</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
<div id="print_data">
|
||||
</div>
|
||||
</asp:Content>
|
||||
|
||||
+216
-115
@@ -7,19 +7,20 @@
|
||||
<div class="mb-2 mb-sm-0">
|
||||
<ul class="nav ps-0">
|
||||
<li class="nav-item pe-3">
|
||||
<select class="form-select" v-model="search.kind" @change="btn_search">
|
||||
<select class="form-select" v-model="search.kind" @change="btn_search" :disabled="isEditing">
|
||||
<option value="">選擇分類</option>
|
||||
<option v-for="item in itemKindList" :value="item.num">{{item.kind}}</option>
|
||||
</select>
|
||||
</li>
|
||||
<li class="nav-item pe-1">
|
||||
<a href="item_reg.aspx" class="btn btn-primary">
|
||||
<a href="item_reg.aspx" class="btn btn-primary" :class="{ 'disabled': isEditing }" >
|
||||
<i class="mdi mdi-plus"></i>新增
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item pe-1">
|
||||
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item pe-1">
|
||||
<a @click="deleteAll" class="btn btn-outline-danger" title="刪除勾選的資料" :class="{ 'disabled': isEditing }" ><i class="mdi mdi-trash-can"></i> 刪除勾選</a>
|
||||
</li>
|
||||
</ul>
|
||||
<%-- <div class="input-group mb-3" data-search-control="search1" @click="search_show(search_dialog.controls.search1)">
|
||||
<input class="form-control search-text" type="text" readonly
|
||||
@@ -29,26 +30,31 @@
|
||||
<i class="mdi mdi-view-list-outline"></i>
|
||||
</button>
|
||||
</div>--%>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div class="">
|
||||
|
||||
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
|
||||
<a v-if="!isEditing" @click="editClick" class="btn btn-outline-secondary" title="編輯排列順序"><i class="mdi mdi-swap-vertical"></i> 編輯排列順序</a>
|
||||
<a v-else @click="editClick" class="btn btn-outline-secondary" title="完成編輯排列順序"><i class="mdi mdi-swap-vertical"></i> 完成編輯</a>
|
||||
<div :style="isEditing ? 'pointer-events: none; opacity: 0.5;' : ''" style="display:inline-block;">
|
||||
|
||||
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click" ><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
|
||||
|
||||
</div>
|
||||
</div> </div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script>
|
||||
<script>
|
||||
Vue.filter('timeString', function (value, myFormat) {
|
||||
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||
});
|
||||
|
||||
let VueApp=new Vue({
|
||||
let VueApp = new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(vuetify_options),
|
||||
data() {
|
||||
return {
|
||||
isEditing: false,
|
||||
options: { multiSort: false },
|
||||
data_table: {
|
||||
loading: true,
|
||||
@@ -63,20 +69,20 @@
|
||||
{ text: '項目分類', value: 'kindsTxt' },
|
||||
{ text: '類別', value: 'categoryTxt' },
|
||||
{ text: '預設金額', value: 'price' },
|
||||
{ text: '庫存狀態', value: 'stock' },
|
||||
{ text: '庫存狀態', value: 'stock' },
|
||||
{ text: '停用', value: 'status' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
|
||||
|
||||
|
||||
],
|
||||
footer:{
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
itemsPerPageOptions:[5,10,20,30],
|
||||
itemsPerPageOptions: [5, 10, 20, 30],
|
||||
},
|
||||
},
|
||||
search: {
|
||||
kind: '',
|
||||
subject: '',
|
||||
selltime1:'',
|
||||
selltime1: '',
|
||||
selltime2: '',
|
||||
uptime1: '',
|
||||
uptime2: '',
|
||||
@@ -98,7 +104,7 @@
|
||||
{ id: 'kind', title: '品項分類', value: '' },
|
||||
],
|
||||
selected: {},
|
||||
select(t,data) {
|
||||
select(t, data) {
|
||||
data.search.kind = t.num;
|
||||
data.btn_search()
|
||||
console.log("select search1", t);
|
||||
@@ -120,9 +126,9 @@
|
||||
}, snackbar: {
|
||||
show: false,
|
||||
text: "",
|
||||
}, itemKindList:{
|
||||
}, itemKindList: {
|
||||
num: 0,
|
||||
kind:''
|
||||
kind: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -149,9 +155,9 @@
|
||||
if (!isNaN(actItemPage) && actItemPage !== 1) {
|
||||
this.options.page = actItemPage;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
methods: {
|
||||
initKindList() {
|
||||
axios
|
||||
//.get(HTTP_HOST + 'api/activity_kind')
|
||||
@@ -174,26 +180,45 @@
|
||||
|
||||
},
|
||||
getDefault(clearpage = false) {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||
page: clearpage ? '1' :page, pageSize: itemsPerPage
|
||||
};
|
||||
this.data_table.loading = true
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/GetItemList', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
editItem(item) {
|
||||
console.log("edit", item);
|
||||
if (this.isEditing) {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: "sort_order", sortDesc: sortDesc[0],
|
||||
page: clearpage ? '1' : page, pageSize: 0
|
||||
};
|
||||
this.data_table.loading = true
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/GetItemList', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
else {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||
page: clearpage ? '1' : page, pageSize: itemsPerPage
|
||||
};
|
||||
this.data_table.loading = true
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/GetItemList', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
|
||||
},
|
||||
deleteItem(item) {
|
||||
|
||||
editItem(item) {
|
||||
console.log("edit", item);
|
||||
},
|
||||
deleteItem(item) {
|
||||
|
||||
if (confirm('是否確定刪除此筆資料?')) {
|
||||
const index = this.data_table.list.indexOf(item)
|
||||
if (index != -1) {
|
||||
@@ -203,7 +228,7 @@
|
||||
this.getDefault();
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
deleteAll() {
|
||||
@@ -225,100 +250,155 @@
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
},
|
||||
btn_search() {
|
||||
editClick() {
|
||||
if (this.isEditing) {
|
||||
this.isEditing = false;
|
||||
const sortedIds = this.data_table.list.map(item => item.num);
|
||||
axios.post(HTTP_HOST + 'api/activity/SaveItemList', { ids: sortedIds })
|
||||
.then(response => {
|
||||
this.isEditing = false;
|
||||
this.getDefault();
|
||||
})
|
||||
.catch(error => {
|
||||
alert("儲存排序失敗:" + error);
|
||||
})
|
||||
.finally(() => {
|
||||
this.data_table.loading = false;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
this.isEditing = true;
|
||||
this.getDefault()
|
||||
}
|
||||
},
|
||||
btn_search() {
|
||||
this.getDefault(true)
|
||||
},
|
||||
btn_all() {
|
||||
clearObjProps(this.search);
|
||||
this.btn_search()
|
||||
},
|
||||
//===
|
||||
search_show(curr) {
|
||||
//console.log("btn_click:", curr, curr.api_url);
|
||||
this.search_dialog.current = curr;
|
||||
this.search_clear()
|
||||
//this.search_get()//清除完自動會重抓, 故取消
|
||||
this.search_dialog.show = true;
|
||||
},
|
||||
search_clear() {
|
||||
if (!this.search_dialog.current.keys) return;
|
||||
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
|
||||
this.search_get()
|
||||
},
|
||||
search_get() {
|
||||
if (!this.search_dialog.current.keys) return;
|
||||
let api_url = this.search_dialog.current.api_url;
|
||||
let keys = this.search_dialog.current.keys;
|
||||
//const { page, itemsPerPage } = this.options
|
||||
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
this.search_dialog.page = this.options.page ?? 1
|
||||
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
|
||||
var search = {};//post body
|
||||
keys.forEach((t, i) => {
|
||||
search[t.id] = t.value;
|
||||
});
|
||||
},
|
||||
//===
|
||||
search_show(curr) {
|
||||
//console.log("btn_click:", curr, curr.api_url);
|
||||
this.search_dialog.current = curr;
|
||||
this.search_clear()
|
||||
//this.search_get()//清除完自動會重抓, 故取消
|
||||
this.search_dialog.show = true;
|
||||
},
|
||||
search_clear() {
|
||||
if (!this.search_dialog.current.keys) return;
|
||||
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' })
|
||||
this.search_get()
|
||||
},
|
||||
search_get() {
|
||||
if (!this.search_dialog.current.keys) return;
|
||||
let api_url = this.search_dialog.current.api_url;
|
||||
let keys = this.search_dialog.current.keys;
|
||||
//const { page, itemsPerPage } = this.options
|
||||
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
this.search_dialog.page = this.options.page ?? 1
|
||||
let params = { page: this.search_dialog.page, pageSize: 10 };//url params
|
||||
var search = {};//post body
|
||||
keys.forEach((t, i) => {
|
||||
search[t.id] = t.value;
|
||||
});
|
||||
|
||||
console.log("search_get", api_url, search, params, this.options);
|
||||
this.search_dialog.loading = true
|
||||
axios.post(api_url, search, { params: params })
|
||||
.then(response => {
|
||||
this.search_dialog.list = response.data.list
|
||||
this.search_dialog.count = response.data.count
|
||||
this.search_dialog.loading = false
|
||||
console.log("search_get", api_url, search, params, this.options);
|
||||
this.search_dialog.loading = true
|
||||
axios.post(api_url, search, { params: params })
|
||||
.then(response => {
|
||||
this.search_dialog.list = response.data.list
|
||||
this.search_dialog.count = response.data.count
|
||||
this.search_dialog.loading = false
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
this.search_dialog.list = []
|
||||
this.search_dialog.count = 0
|
||||
this.search_dialog.loading = false
|
||||
this.snackbar.text = "錯誤:" + error
|
||||
this.snackbar.show = true
|
||||
})
|
||||
},
|
||||
search_headers() {
|
||||
if (!this.search_dialog.current.columns) return;
|
||||
r = [];
|
||||
this.search_dialog.current.columns.forEach((t, i) => {
|
||||
r.push({
|
||||
text: t.title,
|
||||
align: 'start',
|
||||
sortable: false,
|
||||
value: t.id,
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
this.search_dialog.list = []
|
||||
this.search_dialog.count = 0
|
||||
this.search_dialog.loading = false
|
||||
this.snackbar.text = "錯誤:" + error
|
||||
this.snackbar.show = true
|
||||
})
|
||||
},
|
||||
search_headers() {
|
||||
if (!this.search_dialog.current.columns) return;
|
||||
r = [];
|
||||
this.search_dialog.current.columns.forEach((t, i) => {
|
||||
r.push({
|
||||
text: t.title,
|
||||
align: 'start',
|
||||
sortable: false,
|
||||
value: t.id,
|
||||
})
|
||||
})
|
||||
return r
|
||||
},
|
||||
search_select(row) {
|
||||
let curr = this.search_dialog.current;
|
||||
let target = $(`[data-search-control=${curr.id}]`);
|
||||
curr.selected = row;
|
||||
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
|
||||
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
|
||||
if (curr.select instanceof Function) {
|
||||
curr.select(row,this);
|
||||
}
|
||||
this.search_dialog.show = false;
|
||||
},
|
||||
return r
|
||||
},
|
||||
search_select(row) {
|
||||
let curr = this.search_dialog.current;
|
||||
let target = $(`[data-search-control=${curr.id}]`);
|
||||
curr.selected = row;
|
||||
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
|
||||
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
|
||||
if (curr.select instanceof Function) {
|
||||
curr.select(row, this);
|
||||
}
|
||||
this.search_dialog.show = false;
|
||||
},
|
||||
saveOrder(event) {
|
||||
const movedItem = this.data_table.list.splice(event.oldIndex, 1)[0];
|
||||
this.data_table.list.splice(event.newIndex, 0, movedItem);
|
||||
},
|
||||
|
||||
},
|
||||
computed: {
|
||||
pageCount() {
|
||||
return Math.ceil(this.data_table.count / this.data_table.pageSize)
|
||||
},
|
||||
computedHeaders() {
|
||||
return this.data_table.header.map(h => {
|
||||
if (h.value === 'slot_btn') {
|
||||
return { ...h, sortable: false };
|
||||
}
|
||||
|
||||
return {
|
||||
...h,
|
||||
sortable: this.isEditing ? false : (h.sortable !== false)
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
currency: function (value) {
|
||||
return value == null || value == "" ? "" :
|
||||
('$' + parseFloat(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,").replace(".00", ""));
|
||||
},
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
sortableDataTable: {
|
||||
bind(el, binding, vnode) {
|
||||
const options = {
|
||||
animation: 150,
|
||||
onUpdate: function (event) {
|
||||
vnode.child.$emit('sorted', event)
|
||||
}
|
||||
}
|
||||
Sortable.create(el.getElementsByTagName('tbody')[0], options)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
||||
<div id="content" class="container-fluid">
|
||||
<v-data-table
|
||||
<v-data-table
|
||||
v-sortable-data-table
|
||||
@sorted="saveOrder"
|
||||
:headers="computedHeaders"
|
||||
v-model="data_table.selected"
|
||||
:items="data_table.list"
|
||||
:search-props="search"
|
||||
@@ -332,8 +412,29 @@
|
||||
show-select
|
||||
hide-default-footer
|
||||
:page.sync="data_table.page"
|
||||
:items-per-page.sync="data_table.pageSize"
|
||||
:items-per-page.sync= "isEditing ? -1 :data_table.pageSize"
|
||||
class="elevation-1">
|
||||
<template v-slot:header.data-table-select="{ on, props }">
|
||||
<v-simple-checkbox
|
||||
v-if="!isEditing"
|
||||
v-bind="props"
|
||||
v-on="on"
|
||||
></v-simple-checkbox>
|
||||
|
||||
<v-icon v-else small>mdi-swap-vertical</v-icon>
|
||||
</template>
|
||||
<template v-slot:item.data-table-select="{ item, isSelected, select }">
|
||||
<v-simple-checkbox
|
||||
v-if="!isEditing"
|
||||
:value="isSelected"
|
||||
@input="select($event)"
|
||||
></v-simple-checkbox>
|
||||
|
||||
<div v-else class="handle" style="cursor: grab;">
|
||||
<v-icon color="grey darken-1">mdi-drag-vertical</v-icon>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item.price="{ item }" >
|
||||
{{item.price | currency }}
|
||||
</template>
|
||||
@@ -352,12 +453,12 @@
|
||||
</template>
|
||||
|
||||
|
||||
<template #item.slot_btn="{ item }">
|
||||
<a :href="'item_reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
||||
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
|
||||
<template #item.slot_btn="{ item }" >
|
||||
<a v-if="!isEditing" :href="'item_reg.aspx?num='+item.num" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
||||
<a v-if="!isEditing" @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
|
||||
</template>
|
||||
</v-data-table>
|
||||
<v-container>
|
||||
<v-container v-if="!isEditing">
|
||||
<v-row class="align-baseline" wrap>
|
||||
<v-col cols="12" md="9">
|
||||
<v-pagination
|
||||
|
||||
@@ -148,7 +148,7 @@ public partial class admin_activity_index2 : MyWeb.config
|
||||
}
|
||||
|
||||
var tdesc = publicFun.enum_desc<Model.activity.category>();
|
||||
qry = qry.OrderByDescending(o => o.num);
|
||||
qry = qry.OrderByDescending(o => o.sort_order);
|
||||
var list = qry.ToList();
|
||||
if (list.Count > 0)
|
||||
{
|
||||
|
||||
@@ -199,19 +199,24 @@
|
||||
val: 0
|
||||
},
|
||||
},
|
||||
style_datas: [],
|
||||
paper_datas: [],
|
||||
defaultStyle: "",
|
||||
paperID: "",
|
||||
printID:""
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.search_dialog.current = this.search_dialog.controls.search1
|
||||
//console.log("mounted");
|
||||
this.initialize()
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler() {
|
||||
//console.log("watch1", this.search_dialog, this.search_dialog.page);
|
||||
this.search_get()
|
||||
console.log("watch2", this.search_dialog, this.search_dialog.page);
|
||||
},
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
optionsDetail: {
|
||||
@@ -248,7 +253,6 @@
|
||||
if (this.this_id == "")
|
||||
search['status'] = "Y";//啟用
|
||||
}
|
||||
console.log("search_get", api_url, search, params, this.options);
|
||||
this.search_dialog.loading = true
|
||||
axios.post(api_url, search, { params: params })
|
||||
.then(response => {
|
||||
@@ -289,7 +293,7 @@
|
||||
else {
|
||||
|
||||
}
|
||||
console.log("search_select", row, editem);
|
||||
|
||||
//debugger;
|
||||
target.children("input.search-text").val(curr.selected[curr.text_prop])//text
|
||||
target.children("input:hidden").val(curr.selected[curr.value_prop])//value
|
||||
@@ -336,46 +340,19 @@
|
||||
)
|
||||
}
|
||||
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/tablet/GetPaperSize', {})
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
if (response.status == "200") {
|
||||
let data = response.data;
|
||||
if (data.result == "Y") {
|
||||
data.data.forEach(x => {
|
||||
this.paperlist.push({ name: x.paperName, id: x.paperID, width: x.width, height: x.height })
|
||||
$('#<%= ddlPageSize.ClientID %>').append(`<option value="${x.paperID}">${x.paperName}</option>`);
|
||||
$('#<%= ddlPrintSize.ClientID %>').append(`<option value="${x.paperID}">${x.paperName}</option>`);
|
||||
});
|
||||
|
||||
$('#<%= ddlPageSize.ClientID %>').val($("#<%= hidPageSize.ClientID %>").val())
|
||||
$('#<%= ddlPrintSize.ClientID %>').val($("#<%= hidPrintSize.ClientID %>").val())
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(
|
||||
error => console.log(error)
|
||||
)
|
||||
this.paper_datas.length = 0
|
||||
this.style_datas.length = 0
|
||||
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/tablet/GetStyleData', {})
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
if (response.status == "200") {
|
||||
let data = response.data;
|
||||
if (data.result == "Y") {
|
||||
data.data.forEach(x => {
|
||||
if (x.styleID != "000001") {
|
||||
this.stylelist.push({ styleID: x.styleID, name: x.name })
|
||||
$('#<%= ddlDefaultStyle.ClientID %>').append(`<option value="${x.styleID}">${x.name}</option>`);
|
||||
//$("#defaultStyle").append(`<option value="${x.styleID}">${x.name}</option>`);
|
||||
}
|
||||
});
|
||||
$('#<%= ddlDefaultStyle.ClientID %>').val($("#<%= hidDefaultStyle.ClientID %>").val())
|
||||
}
|
||||
}
|
||||
})
|
||||
this.style_datas = data.data
|
||||
this.defaultStyle=$("#<%=hidDefaultStyle.ClientID %>").val()
|
||||
}
|
||||
}})
|
||||
.catch(
|
||||
error => console.log(error)
|
||||
)
|
||||
@@ -492,7 +469,7 @@
|
||||
bom_editItem(item) {
|
||||
this.bom_editedIndex = this.bom_list.indexOf(item);
|
||||
this.bom_editedItem = $.extend(true, {}, item);
|
||||
console.log("bom_editItem:", this.bom_editedIndex, this.bom_editedItem);
|
||||
|
||||
//debugger;
|
||||
},
|
||||
bom_deleteItem(item) {
|
||||
@@ -572,13 +549,13 @@
|
||||
}
|
||||
},
|
||||
changeSel(selType) {
|
||||
if (selType=="ddlPageSize") {
|
||||
$("#<%= hidPageSize.ClientID %>").val($("#<%= ddlPageSize.ClientID %>").val())
|
||||
} else if (selType == "ddlPrintSize") {
|
||||
$("#<%= hidPrintSize.ClientID %>").val($("#<%=ddlPrintSize.ClientID %>").val())
|
||||
} else if (selType == "ddlDefaultStyle") {
|
||||
$("#<%= hidDefaultStyle.ClientID %>").val($("#<%= ddlDefaultStyle.ClientID %>").val())
|
||||
}
|
||||
let style = this.style_datas.find(x => x.styleID == this.defaultStyle)
|
||||
this.paperID = style.paperSize
|
||||
this.printID = style.printSize
|
||||
$("#<%= hidPageSize.ClientID %>").val(this.paperID)
|
||||
$("#<%=hidPrintSize.ClientID %>").val(this.printID)
|
||||
$("#<%=hidDefaultStyle.ClientID %>").val(this.defaultStyle)
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -659,47 +636,43 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-form-label">料號</label>
|
||||
<%-- <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>
|
||||
</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>
|
||||
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="subject" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
|
||||
</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="print_init" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入牌位編號開頭"></asp:TextBox>
|
||||
</div>
|
||||
<asp:TextBox ID="print_init" MaxLength="20" runat="server" CssClass="form-control" placeholder="請輸入牌位編號開頭"></asp:TextBox>
|
||||
</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="price" MaxLength="7" runat="server" CssClass="form-control" placeholder="請輸入預設金額"></asp:TextBox>
|
||||
<asp:RegularExpressionValidator ControlToValidate="price" Display="Dynamic" SetFocusOnError="true" ErrorMessage="只能輸入數字" ID="RegularExpressionValidator3" runat="server" ValidationExpression="^(-?\d+)(\.\d+)?$" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-form-label">預設頁面尺寸</label>
|
||||
<div class="col-sm-4">
|
||||
<select ID="ddlPageSize" runat="server" onchange="VueApp.changeSel('ddlPageSize')"></select>
|
||||
<asp:HiddenField ID="hidPageSize" runat="server" />
|
||||
</div>
|
||||
<label class="col-sm-2 col-form-label">預設列印尺寸</label>
|
||||
|
||||
<label class="col-sm-2 col-form-label">預設版型</label>
|
||||
<div class="col-sm-4">
|
||||
<select ID="ddlPrintSize" runat="server" onchange="VueApp.changeSel('ddlPrintSize')"></select>
|
||||
<asp:HiddenField ID="hidPrintSize" runat="server" />
|
||||
<v-select
|
||||
:items="style_datas"
|
||||
|
||||
item-text="name" @change="changeSel('ddlDefaultStyle')"
|
||||
item-value="styleID" v-model="defaultStyle">
|
||||
</v-select>
|
||||
<%-- <select ID="ddlDefaultStyle" runat="server"
|
||||
onchange="VueApp.changeSel('ddlDefaultStyle')"></select>--%>
|
||||
<asp:HiddenField ID="hidDefaultStyle" runat="server" />
|
||||
<asp:HiddenField ID="hidPrintSize" runat="server" />
|
||||
<asp:HiddenField ID="hidPageSize" runat="server" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-form-label">預設版型</label>
|
||||
<div class="col-sm-4">
|
||||
<select ID="ddlDefaultStyle" runat="server" onchange="VueApp.changeSel('ddlDefaultStyle')"></select>
|
||||
<asp:HiddenField ID="hidDefaultStyle" runat="server" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<asp:UpdatePanel ID="UpdatePanel1" runat="server" class="row mb-1 label-sm-right">
|
||||
<ContentTemplate>
|
||||
@@ -734,12 +707,12 @@
|
||||
<asp:TextBox ID="demo" runat="server" CssClass="ckeditor" TextMode="MultiLine"></asp:TextBox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<%-- <div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-form-label">自定義欄位預設值</label>
|
||||
<div class="col-sm-10">
|
||||
<asp:TextBox ID="customize_data" runat="server" Rows="3" TextMode="MultiLine" CssClass="form-control" placeholder="一行輸入一個定義欄位預設值,如: $品名:醬油 $金額:100" ToolTip="一行輸入一個定義欄位預設值,格式: $變數名稱:值"></asp:TextBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>--%>
|
||||
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-form-label">狀態 *</label>
|
||||
@@ -909,7 +882,7 @@
|
||||
</v-card-title>
|
||||
<v-card-text >
|
||||
<v-row>
|
||||
<v-col v-for="item in search_dialog.current.keys"
|
||||
<v-col v-for="item in search_dialog.current.keys" :key="item.value"
|
||||
:cols="search_dialog.current.keys.length>1?6:12" >
|
||||
<v-text-field v-model="item.value" :label="item.title" v-if="item.visible===undefined || item.visible==true "></v-text-field>
|
||||
</v-col>
|
||||
|
||||
@@ -42,21 +42,21 @@ public partial class admin_activity_item_reg : MyWeb.config
|
||||
BuildKind();
|
||||
subject.Text = prod.subject;
|
||||
print_init.Text = prod.print_init;
|
||||
PARTNO.Text = prod.partno;
|
||||
//PARTNO.Text = prod.partno;
|
||||
//kind.SelectedValue = prod.kind.ToString();
|
||||
if (!isStrNull(prod.pageSize))
|
||||
{
|
||||
ddlPageSize.Value = prod.pageSize.ToString();
|
||||
//ddlPageSize.Value = prod.pageSize.ToString();
|
||||
hidPageSize.Value = prod.pageSize.ToString();
|
||||
}
|
||||
if (!isStrNull(prod.printSize))
|
||||
{
|
||||
ddlPrintSize.Value = prod.printSize.ToString();
|
||||
//ddlPrintSize.Value = prod.printSize.ToString();
|
||||
hidPrintSize.Value = prod.printSize.ToString();
|
||||
}
|
||||
if (!isStrNull(prod.defaultStyle))
|
||||
{
|
||||
ddlDefaultStyle.Value = prod.defaultStyle.ToString();
|
||||
//ddlDefaultStyle.Value = prod.defaultStyle.ToString();
|
||||
hidDefaultStyle.Value = prod.defaultStyle.ToString();
|
||||
}
|
||||
if (prod.kind.HasValue)
|
||||
@@ -78,7 +78,7 @@ public partial class admin_activity_item_reg : MyWeb.config
|
||||
if (prod.cycle.HasValue)
|
||||
cycle.Text = prod.cycle.Value.ToString();
|
||||
|
||||
customize_data.Text = prod.customize_data?.ToString();
|
||||
//customize_data.Text = prod.customize_data?.ToString();
|
||||
|
||||
|
||||
edit.Visible = true;
|
||||
@@ -133,20 +133,21 @@ public partial class admin_activity_item_reg : MyWeb.config
|
||||
L_msg.Text = "";
|
||||
|
||||
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;
|
||||
if (!isStrNull(ddlPageSize.Value))
|
||||
//actItem.partno = PARTNO.Text;
|
||||
if (!isStrNull(hidPageSize.Value))
|
||||
{
|
||||
actItem.pageSize = ddlPageSize.Value;
|
||||
actItem.pageSize = hidPageSize.Value;
|
||||
}
|
||||
if (!isStrNull(ddlPrintSize.Value))
|
||||
if (!isStrNull(hidPrintSize.Value))
|
||||
{
|
||||
actItem.printSize = ddlPrintSize.Value;
|
||||
actItem.printSize = hidPrintSize.Value;
|
||||
}
|
||||
if (!isStrNull(ddlDefaultStyle.Value))
|
||||
if (!isStrNull(hidDefaultStyle.Value))
|
||||
{
|
||||
actItem.defaultStyle = (ddlDefaultStyle.Value);
|
||||
actItem.defaultStyle = (hidDefaultStyle.Value);
|
||||
}
|
||||
//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; }
|
||||
@@ -157,7 +158,8 @@ public partial class admin_activity_item_reg : MyWeb.config
|
||||
actItem.extend = extend.Checked ? "Y" : "N";
|
||||
actItem.is_reconcile = is_reconcile_item.Checked ? "Y" : "N";
|
||||
actItem.demo = demo.Text;
|
||||
actItem.customize_data = customize_data.Text;
|
||||
//actItem.customize_data = customize_data.Text;
|
||||
actItem.sort_order = maxSort + 1;
|
||||
|
||||
_db.actItems.Add(actItem);
|
||||
_db.SaveChanges();
|
||||
@@ -194,7 +196,7 @@ public partial class admin_activity_item_reg : MyWeb.config
|
||||
{
|
||||
actItem.subject = subject.Text;
|
||||
actItem.print_init = print_init.Text;
|
||||
actItem.partno = PARTNO.Text;
|
||||
//actItem.partno = PARTNO.Text;
|
||||
if (!isStrNull(hidPageSize.Value))
|
||||
{
|
||||
actItem.pageSize = hidPageSize.Value;
|
||||
@@ -216,7 +218,7 @@ public partial class admin_activity_item_reg : MyWeb.config
|
||||
actItem.extend = extend.Checked ? "Y" : "N";
|
||||
actItem.is_reconcile = is_reconcile_item.Checked ? "Y" : "N";
|
||||
actItem.demo = demo.Text;
|
||||
actItem.customize_data = customize_data.Text;
|
||||
//actItem.customize_data = customize_data.Text;
|
||||
|
||||
_db.SaveChanges();
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
|
||||
+241
-20
@@ -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,23 @@
|
||||
order_dialog: {
|
||||
show: false,
|
||||
},
|
||||
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: {
|
||||
@@ -482,6 +505,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)
|
||||
@@ -886,6 +913,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: {
|
||||
},
|
||||
@@ -905,12 +1039,12 @@
|
||||
<div class="">
|
||||
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
|
||||
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
|
||||
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||
<asp:Button ID="goback" runat="server" Text="取消" Visible="true" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
||||
<div id="content" class="container-md">
|
||||
<div id="content" class="container-lg">
|
||||
|
||||
<div class="card shadow-sm my-2" id="sec2">
|
||||
<div class="card-header py-0">
|
||||
@@ -922,9 +1056,13 @@
|
||||
<button v-if="this_id!=''" class="nav-link" id="sec2-tab2" data-bs-toggle="tab" data-bs-target="#sec2-page2"
|
||||
type="button" role="tab" aria-controls="profile" aria-selected="false">
|
||||
{{this_category_kindTxt}}項目</button>
|
||||
<button v-if="this_id!=''" class="nav-link" id="sec2-tab3" data-bs-toggle="tab" data-bs-target="#sec2-page3"
|
||||
<%-- <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>--%>
|
||||
<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>
|
||||
@@ -936,13 +1074,13 @@
|
||||
</div>
|
||||
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動名稱 *</label>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動(法會)名稱 *</label>
|
||||
<div class="col-sm-10 col-lg-3">
|
||||
<asp:TextBox ID="subject" MaxLength="100" runat="server" CssClass="form-control" placeholder="請輸入活動名稱"></asp:TextBox>
|
||||
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="subject" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
|
||||
</div>
|
||||
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動主類型 *</label>
|
||||
<%-- <label class="col-sm-2 col-lg-1 col-form-label">活動主類型 *</label>
|
||||
<div class="col-sm-10 col-lg-3" >
|
||||
<div class="input-group mb-3" data-search-control="search4" @click="search_show(search_dialog.controls.search4)" >
|
||||
<input class="form-control search-text" type="text" readonly
|
||||
@@ -953,14 +1091,14 @@
|
||||
</button>
|
||||
</div>
|
||||
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" ControlToValidate="category_kind_txt" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
|
||||
</div>
|
||||
</div>--%>
|
||||
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動詳細分類 *</label>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動(法會)分類 *</label>
|
||||
<div class="col-sm-10 col-lg-3">
|
||||
<asp:PlaceHolder ID="kindPH" runat="server">
|
||||
<div class="input-group mb-3" data-search-control="search1" @click="this_id=='' && search_show(search_dialog.controls.search1)">
|
||||
<input class="form-control search-text" type="text" readonly
|
||||
id="kind_txt" runat="server" placeholder="活動詳細分類" value="">
|
||||
id="kind_txt" runat="server" placeholder="活動(法會)分類" value="">
|
||||
<asp:HiddenField ID="kind" runat="server" Value="" />
|
||||
<button class="btn btn-outline-secondary" type="button">
|
||||
<i class="mdi mdi-view-list-outline"></i>
|
||||
@@ -970,13 +1108,19 @@
|
||||
</asp:PlaceHolder>
|
||||
<asp:Literal ID="kind_txt2" runat="server"></asp:Literal>
|
||||
</div>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">報名截止日 *</label>
|
||||
<div class="col-sm-4 col-lg-3">
|
||||
<asp:TextBox ID="dueDate" TextMode="Date" runat="server" CssClass="form-control"></asp:TextBox>
|
||||
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" ControlToValidate="dueDate" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">牌位編號開頭</label>
|
||||
<div class="col-sm-10 col-lg-3">
|
||||
<asp:TextBox ID="print_init" MaxLength="50" runat="server" CssClass="form-control" placeholder="請輸入牌位編號開頭"></asp:TextBox>
|
||||
</div>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動地點</label>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">活動(法會)地點</label>
|
||||
<div class="col-sm-10 col-lg-3">
|
||||
<asp:TextBox ID="address" MaxLength="200" runat="server" CssClass="form-control" placeholder="請輸入活動地址"></asp:TextBox>
|
||||
</div>
|
||||
@@ -986,7 +1130,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 label-sm-right">
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">開始日期(西元)</label>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">開始日期(西元)*</label>
|
||||
<div class="col-sm-4 col-lg-3">
|
||||
<asp:TextBox ID="startDate_solar" TextMode="Date" runat="server" CssClass="form-control" onchange="chagenDate(this)"></asp:TextBox>
|
||||
</div>
|
||||
@@ -1003,7 +1147,7 @@
|
||||
|
||||
<div class="row mb-1 label-sm-right">
|
||||
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">結束日期(西元)</label>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">結束日期(西元)*</label>
|
||||
<div class="col-sm-4 col-lg-3">
|
||||
<asp:TextBox ID="endDate_solar" TextMode="Date" runat="server" CssClass="form-control" onchange="chagenDate(this)"></asp:TextBox>
|
||||
</div>
|
||||
@@ -1011,12 +1155,7 @@
|
||||
<div class="col-sm-4 col-lg-3 lunar pt-2">
|
||||
<asp:Literal ID="endDate_lunar" runat="server"></asp:Literal>
|
||||
</div>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">報名截止日 *</label>
|
||||
<div class="col-sm-4 col-lg-3">
|
||||
<asp:TextBox ID="dueDate" TextMode="Date" runat="server" CssClass="form-control"></asp:TextBox>
|
||||
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" ControlToValidate="dueDate" runat="server" ErrorMessage="必填!" Display="Dynamic" SetFocusOnError="true"></asp:RequiredFieldValidator>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1043,12 +1182,12 @@
|
||||
<asp:TextBox ID="demo" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入備註"></asp:TextBox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<%-- <div class="row mb-1">
|
||||
<label class="col-form-label">自定義欄位預設值</label>
|
||||
<div class="">
|
||||
<asp:TextBox ID="customize_data" runat="server" Rows="3" TextMode="MultiLine" CssClass="form-control" placeholder="一行輸入一個定義欄位預設值,如: $活動:OO年法會 $地點:台中市OO區OO路" ToolTip="一行輸入一個定義欄位預設值,格式: $變數名稱:值"></asp:TextBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>--%>
|
||||
<div class="row mb-1">
|
||||
<asp:Panel ID="timePanel1" runat="server" CssClass="col-12 text-right text-primary" Visible="false">建檔時間:<asp:Literal ID="reg_time" runat="server"></asp:Literal></asp:Panel>
|
||||
</div>
|
||||
@@ -1097,6 +1236,53 @@
|
||||
<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">
|
||||
@@ -1206,6 +1392,41 @@
|
||||
|
||||
|
||||
</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>
|
||||
</div>
|
||||
</asp:Panel>
|
||||
</div>
|
||||
|
||||
+149
-11
@@ -78,8 +78,8 @@ public partial class admin_activity_reg : MyWeb.config
|
||||
if (prod.category_kind.HasValue)
|
||||
{
|
||||
_category_kindTxt = prod.activity_category_kind.kind;
|
||||
category_kind_txt.Value = prod.activity_category_kind.kind;
|
||||
category_kind.Value = prod.category_kind.Value.ToString();
|
||||
//category_kind_txt.Value = prod.activity_category_kind.kind;
|
||||
//category_kind.Value = prod.category_kind.Value.ToString();
|
||||
}
|
||||
if (prod.startDate_solar.HasValue)
|
||||
{
|
||||
@@ -235,7 +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)
|
||||
{
|
||||
if (Page.IsValid) {
|
||||
@@ -254,7 +283,7 @@ public partial class admin_activity_reg : MyWeb.config
|
||||
{
|
||||
if (textBox.TextMode == TextBoxMode.Date)
|
||||
ObjValue.SetValue(activity, selectDate(textBox));
|
||||
|
||||
|
||||
else
|
||||
ObjValue.SetValue(activity, ((TextBox)obj).Text.Trim());
|
||||
}
|
||||
@@ -281,7 +310,6 @@ public partial class admin_activity_reg : MyWeb.config
|
||||
// printInit 欄位
|
||||
//var printInitValue = printInit.Text.Trim();
|
||||
//activity.print_init = !string.IsNullOrEmpty(printInitValue) ? printInitValue : null;
|
||||
|
||||
activity.kind = Val(kind.Value);
|
||||
activity.category_kind = Val(category_kind.Value);
|
||||
activity.reg_time = DateTime.Now;
|
||||
@@ -290,15 +318,37 @@ 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 if (activity.startDate_solar == null || activity.endDate_solar == null)
|
||||
{
|
||||
L_msg.Type = alert_type.danger;
|
||||
L_msg.Text = "開始、結束日期必須填寫";
|
||||
}
|
||||
else
|
||||
{
|
||||
L_msg.Type = alert_type.danger;
|
||||
L_msg.Text = "Error";
|
||||
activity.kind = Val(kind.Value);
|
||||
//activity.category_kind = Val(category_kind.Value);
|
||||
activity.reg_time = DateTime.Now;
|
||||
_db.activities.Add(activity);
|
||||
_db.SaveChanges();
|
||||
int _id = activity.num;
|
||||
if (_id > 0)
|
||||
{
|
||||
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
|
||||
{
|
||||
L_msg.Type = alert_type.danger;
|
||||
L_msg.Text = "Error";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -363,12 +413,22 @@ public partial class admin_activity_reg : MyWeb.config
|
||||
// printInit 欄位
|
||||
//var printInitValue = printInit.Text.Trim();
|
||||
//activity.print_init = !string.IsNullOrEmpty(printInitValue) ? printInitValue : null;
|
||||
if (activity.startDate_solar == null || activity.endDate_solar == null)
|
||||
{
|
||||
L_msg.Type = alert_type.danger;
|
||||
L_msg.Text = "開始、結束日期必須填寫";
|
||||
}
|
||||
else
|
||||
{
|
||||
//activity.category_kind = Val(category_kind.Value);
|
||||
activity.category_kind = Val(category_kind.Value);
|
||||
_db.SaveChanges();
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -385,6 +445,84 @@ 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
|
||||
|
||||
|
||||
@@ -0,0 +1,868 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-warning white--text text-center">
|
||||
<h5 class="mb-0">餘額核銷 - 處理剩餘金額</h5>
|
||||
<button class="btn btn-default ms-auto"><i class="mdi mdi-close"></i></button>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1 balance-reconcile-table"
|
||||
item-key="id">
|
||||
<template v-slot:item.follower="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">
|
||||
<a :href="`../follower/reg.aspx?num=${item.f_num}`"
|
||||
target="_blank"
|
||||
class="text-decoration-none"
|
||||
:title="`查看 ${item.follower} 的詳細資料`">
|
||||
{{ item.follower }}
|
||||
<v-icon small color="primary" class="ml-1">mdi-open-in-new</v-icon>
|
||||
</a>
|
||||
</div>
|
||||
<div class="caption text--secondary" v-if="item.phone">
|
||||
{{ item.phone }}
|
||||
</div>
|
||||
<div class="caption text--secondary" v-if="item.phone2">
|
||||
{{ item.phone2 }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.bank_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.acc_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.check_date | date }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.amount_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-primary">
|
||||
已入帳:{{ item.check_amount }}
|
||||
</div>
|
||||
<div class="text-success">
|
||||
已沖帳:{{ item.check_amount - item.remain_amount }}
|
||||
</div>
|
||||
<div class="text-warning font-weight-bold">
|
||||
待核銷:{{ item.remain_amount }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.detail_info="{ item }">
|
||||
<v-btn color="info"
|
||||
outlined
|
||||
@click="showDetailDialog(item)">
|
||||
<v-icon small class="mr-1">mdi-information-outline</v-icon>
|
||||
詳細
|
||||
</v-btn>
|
||||
</template>
|
||||
<!-- 選取項目欄位 -->
|
||||
<template v-slot:item.select_items="{ item }">
|
||||
<div style="min-width: 200px;">
|
||||
<v-text-field v-model="item.selected_items_text"
|
||||
placeholder="項目名稱"
|
||||
dense
|
||||
outlined
|
||||
readonly
|
||||
hide-details
|
||||
style="font-size: 12px;">
|
||||
<template v-slot:append>
|
||||
<v-btn small
|
||||
color="primary"
|
||||
icon
|
||||
@click="showItemSelectDialog(item)"
|
||||
style="margin-right: -8px;">
|
||||
<v-icon small>mdi-table</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 狀態與操作欄位 -->
|
||||
<template v-slot:item.status_action="{ item }">
|
||||
<div style="min-width: 280px;">
|
||||
<v-row no-gutters>
|
||||
<v-col cols="6" class="pr-1">
|
||||
<v-select v-model="item.new_status"
|
||||
:items="statusOptions"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
placeholder="狀態"
|
||||
style="font-size: 12px;"></v-select>
|
||||
</v-col>
|
||||
<v-col cols="6" class="pl-1">
|
||||
<v-btn color="primary"
|
||||
block
|
||||
@click="processBalance(item)"
|
||||
:disabled="!canUpdate(item)">
|
||||
更新狀態
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row no-gutters class="mt-2">
|
||||
<v-col cols="12">
|
||||
<v-text-field v-model="item.verify_note"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
placeholder="核對記錄"
|
||||
style="font-size: 12px;"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<!-- 餘額處理對話框 -->
|
||||
<v-dialog v-model="dialog.show" max-width="800px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="warning" class="mr-2">mdi-cash-multiple</v-icon>
|
||||
餘額處理
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="dialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="pb-0">
|
||||
<div v-if="dialog.selected">
|
||||
<v-row class="my-3">
|
||||
<v-col cols="12" md="6">
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">信眾:</span>
|
||||
{{ dialog.selected.follower }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">入帳銀行:</span>
|
||||
{{ dialog.selected.acc_name }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">入帳日期:</span>
|
||||
{{ dialog.selected.check_date | date }}
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">入帳金額:</span>
|
||||
<span class="text-primary">{{ dialog.selected.check_amount | currency }}</span>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">剩餘金額:</span>
|
||||
<span class="text-warning font-weight-bold">{{ dialog.selected.remain_amount | currency }}</span>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">狀態:</span>
|
||||
<v-chip small color="warning" text-color="white">
|
||||
{{ getStatusText(dialog.selected.check_status) }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- 歷史沖帳記錄 -->
|
||||
<v-divider class="my-3"></v-divider>
|
||||
<h6 class="mb-3">
|
||||
<v-icon color="info" class="mr-1">mdi-history</v-icon>
|
||||
歷史沖帳記錄
|
||||
</h6>
|
||||
<v-data-table :headers="dialog.historyHeaders"
|
||||
:items="dialog.historyItems"
|
||||
class="elevation-1 mb-4"
|
||||
hide-default-footer
|
||||
:disable-pagination="true"
|
||||
dense>
|
||||
<template v-slot:item.reconcile_amount="{ item }">
|
||||
<span>{{ item.reconcile_amount | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.reconcile_date="{ item }">
|
||||
<span>{{ item.reconcile_date | date }}</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
|
||||
<!-- 餘額處理選項 -->
|
||||
<v-divider class="my-3"></v-divider>
|
||||
<h6 class="mb-3">
|
||||
<v-icon color="warning" class="mr-1">mdi-cash-multiple</v-icon>
|
||||
餘額處理方式
|
||||
</h6>
|
||||
<v-radio-group v-model="dialog.balanceAction" class="mt-0">
|
||||
<v-radio label="轉入下次活動"
|
||||
value="transfer"
|
||||
color="primary"></v-radio>
|
||||
<v-radio label="現金退費"
|
||||
value="refund_cash"
|
||||
color="success"></v-radio>
|
||||
<v-radio label="銀行轉帳退費"
|
||||
value="refund_bank"
|
||||
color="success"></v-radio>
|
||||
<v-radio label="結餘處理"
|
||||
value="balance_off"
|
||||
color="grey"></v-radio>
|
||||
</v-radio-group>
|
||||
|
||||
<!-- 處理說明 -->
|
||||
<v-textarea v-model="dialog.memo"
|
||||
label="處理說明"
|
||||
outlined
|
||||
rows="3"
|
||||
placeholder="請輸入處理說明..."
|
||||
class="mt-3"></v-textarea>
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions class="pa-4">
|
||||
<div v-if="dialog.errorMessage" class="text-danger">
|
||||
❌ {{ dialog.errorMessage }}
|
||||
</div>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="grey" text @click="dialog.show = false">取消</v-btn>
|
||||
<v-btn color="warning"
|
||||
@click="confirmBalance"
|
||||
:disabled="!dialog.balanceAction || dialog.loading"
|
||||
:loading="dialog.loading">
|
||||
確認處理
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
|
||||
|
||||
<!-- 詳細資訊對話框 -->
|
||||
<v-dialog v-model="detailDialog.show" max-width="900px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="info" class="mr-2">mdi-information-outline</v-icon>
|
||||
詳細資訊
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="detailDialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-tabs v-model="detailDialog.tab" background-color="grey lighten-4">
|
||||
<v-tab>
|
||||
<v-icon small class="mr-2">mdi-information</v-icon>
|
||||
基本資訊
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
<v-icon small class="mr-2">mdi-table</v-icon>
|
||||
沖帳明細
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
<v-icon small class="mr-2">mdi-image</v-icon>
|
||||
證明圖片
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
||||
<v-tabs-items v-model="detailDialog.tab">
|
||||
<!-- Tab 1: 基本資訊 -->
|
||||
<v-tab-item>
|
||||
<v-card-text>
|
||||
<div v-if="detailDialog.selected">
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-primary">
|
||||
<v-icon color="primary" small class="mr-1">mdi-account</v-icon>
|
||||
匯款人資訊
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">姓名:</span>
|
||||
{{ detailDialog.selected.name }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">支付方式:</span>
|
||||
{{ payTypeText[detailDialog.selected.pay_type] || detailDialog.selected.pay_type }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">帳號後5碼:</span>
|
||||
{{ detailDialog.selected.account_last5 || '-' }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">支付型態:</span>
|
||||
{{ detailDialog.selected.pay_mode }}
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-success">
|
||||
<v-icon color="success" small class="mr-1">mdi-cash</v-icon>
|
||||
入帳資訊
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
<div class="font-weight-bold">{{ detailDialog.selected.acc_name }}</div>
|
||||
<div class="caption text--secondary">{{ detailDialog.selected.check_date | date }}</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold text-primary">已入帳:{{ detailDialog.selected.check_amount }}</span>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="text-success">已沖帳:{{ detailDialog.selected.check_amount - detailDialog.selected.remain_amount }}</span>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="text-warning font-weight-bold">待核銷:{{ detailDialog.selected.remain_amount }}</span>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-divider class="my-4"></v-divider>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-purple">
|
||||
<v-icon color="purple" small class="mr-1">mdi-calendar-check</v-icon>
|
||||
活動資訊
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">活動名稱:</span>
|
||||
{{ detailDialog.selected.activity_name || '-' }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">開始日期:</span>
|
||||
{{ detailDialog.selected.activity_start_date | date }}
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-info">
|
||||
<v-icon color="info" small class="mr-1">mdi-clipboard-check</v-icon>
|
||||
核對記錄
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">核對記錄:</span>
|
||||
{{ detailDialog.selected.verify_note || '-' }}
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<span class="font-weight-bold">帳簿備註:</span>
|
||||
{{ detailDialog.selected.check_memo || '-' }}
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
|
||||
<!-- Tab 2: 沖帳明細表格 -->
|
||||
<v-tab-item>
|
||||
<v-card-text>
|
||||
<div v-if="detailDialog.selected">
|
||||
<v-data-table :headers="detailDialog.reconcileHeaders"
|
||||
:items="detailDialog.reconcileItems"
|
||||
class="elevation-1"
|
||||
hide-default-footer
|
||||
:disable-pagination="true">
|
||||
<template v-slot:item.reconcile="{ item }">
|
||||
<span class="font-weight-bold text-success">{{ item.reconcile | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.register_date="{ item }">
|
||||
<span>{{ item.register_date | date }}</span>
|
||||
</template>
|
||||
<template v-slot:item.price="{ item }">
|
||||
<span>{{ item.price | currency }}</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
|
||||
<!-- Tab 3: 證明圖片 -->
|
||||
<v-tab-item>
|
||||
<v-card-text>
|
||||
<div v-if="detailDialog.selected">
|
||||
<div v-if="detailDialog.selected.proof_img">
|
||||
<h6 class="mb-3 text-orange">
|
||||
<v-icon color="orange" small class="mr-1">mdi-image</v-icon>
|
||||
證明圖片
|
||||
</h6>
|
||||
<div class="text-center">
|
||||
<img :src="detailDialog.selected.proof_img"
|
||||
alt="證明圖片"
|
||||
style="max-width: 100%; max-height: 500px;"
|
||||
class="elevation-3" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-center py-5">
|
||||
<v-icon size="64" color="grey lighten-2">mdi-image-off</v-icon>
|
||||
<div class="mt-3 text--secondary">無證明圖片</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 活動品項選擇對話框 -->
|
||||
<v-dialog v-model="search_dialog.show" max-width="700px">
|
||||
<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-card-title>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
|
||||
<v-col v-for="item in search_dialog.current.keys"
|
||||
:cols="search_dialog.current.keys.length>1?6:12">
|
||||
<v-text-field v-model="item.value" :label="item.title" v-if="item.visible===undefined || item.visible==true "></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="4" md="3">
|
||||
<v-checkbox v-model="search_is_reconcile"
|
||||
label="核銷項目"
|
||||
:true-value="'Y'"
|
||||
:false-value="''"
|
||||
hide-details
|
||||
@change="search_get"></v-checkbox>
|
||||
</v-col>
|
||||
<v-col cols="12" class="text-end">
|
||||
<v-btn color="primary" elevation="0" @click="search_get()">查詢</v-btn>
|
||||
<v-btn elevation="0" @click="search_clear()">清除條件</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-data-table :headers="search_headers()"
|
||||
:items="search_dialog.list"
|
||||
:footer-props="search_dialog.footer"
|
||||
:items-per-page="10"
|
||||
:server-items-length="search_dialog.count"
|
||||
:page.sync="search_dialog.page"
|
||||
:options.sync="options"
|
||||
@click:row="search_select"
|
||||
:loading="search_dialog.loading"></v-data-table>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
headers: [
|
||||
{ text: '信眾', value: 'follower' },
|
||||
{ text: '入帳帳戶/日期', value: 'bank_info' },
|
||||
{ text: '金額', value: 'amount_info' },
|
||||
{ text: '詳細資訊', value: 'detail_info', sortable: false },
|
||||
{ text: '選取項目', value: 'select_items', sortable: false, width: '200px' },
|
||||
{ text: '狀態 | 核對記錄', value: 'status_action', sortable: false, width: '280px' }
|
||||
],
|
||||
items: [],
|
||||
dialog: {
|
||||
show: false,
|
||||
selected: null,
|
||||
balanceAction: null,
|
||||
memo: '',
|
||||
loading: false,
|
||||
errorMessage: '',
|
||||
historyHeaders: [
|
||||
{ text: '法會', value: 'activity_name' },
|
||||
{ text: '項目', value: 'item_name' },
|
||||
{ text: '沖帳金額', value: 'reconcile_amount' },
|
||||
{ text: '沖帳日期', value: 'reconcile_date' }
|
||||
],
|
||||
historyItems: [
|
||||
{
|
||||
activity_name: '2025新春法會',
|
||||
item_name: '護持金',
|
||||
reconcile_amount: 12000,
|
||||
reconcile_date: '2025-01-15T00:00:00'
|
||||
}
|
||||
]
|
||||
},
|
||||
detailDialog: {
|
||||
show: false,
|
||||
selected: null,
|
||||
tab: 0,
|
||||
reconcileHeaders: [
|
||||
{ text: '法會活動', value: 'activity_name' },
|
||||
{ text: '報名項目', value: 'actitem_name' },
|
||||
{ text: '原始金額', value: 'price' },
|
||||
{ text: '沖帳金額', value: 'reconcile' },
|
||||
{ text: '報名日期', value: 'register_date' },
|
||||
{ text: '訂單編號', value: 'order_no' }
|
||||
],
|
||||
reconcileItems: []
|
||||
},
|
||||
statusOptions: [
|
||||
{ text: '沖帳有剩餘', value: '90' },
|
||||
{ text: '未聯絡', value: '91' },
|
||||
{ text: '已聯絡', value: '92' },
|
||||
{ text: '餘額核銷', value: '95' }
|
||||
],
|
||||
search_dialog: {
|
||||
controls: {
|
||||
search5: {
|
||||
id: 'search5',
|
||||
title: '活動品項',
|
||||
text_prop: 'subject',
|
||||
value_prop: 'num',
|
||||
keys: [
|
||||
{ id: 'subject', title: '項目名稱', value: '' },
|
||||
{ id: 'kindTxt', title: '項目分類' },
|
||||
{ id: 'num', visible: false },
|
||||
],
|
||||
api_url: '../../api/activity/GetOrderList',
|
||||
columns: [
|
||||
{ id: 'subject', title: '項目名稱' },
|
||||
{ id: 'kindTxt', title: '項目分類' },
|
||||
{ id: 'price', title: '價格' },
|
||||
],
|
||||
selected: {},
|
||||
currentRow: null, // 儲存當前正在編輯的行
|
||||
select(vueInstance, selectedItem) {
|
||||
// 當選擇項目時的處理邏輯
|
||||
if (this.currentRow) {
|
||||
// 將選中的 actItem 的 num 儲存到 balance_act_item 欄位
|
||||
this.currentRow.balance_act_item = selectedItem.num;
|
||||
// 顯示項目名稱給用戶看
|
||||
this.currentRow.selected_items_text = selectedItem.subject;
|
||||
// 如果有價格,也可以顯示
|
||||
if (selectedItem.price) {
|
||||
this.currentRow.selected_items_text += ` (NT$${Number(selectedItem.price).toLocaleString()})`;
|
||||
}
|
||||
console.log('已選擇項目:', selectedItem.subject, '項目編號:', selectedItem.num);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
show: false,
|
||||
current: {},
|
||||
list: [],
|
||||
count: 0,
|
||||
page: 1,
|
||||
loading: false,
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
disableItemsPerPage: true,
|
||||
itemsPerPageAllText: '',
|
||||
itemsPerPageText: '',
|
||||
},
|
||||
},
|
||||
options: {},
|
||||
payTypeText: {
|
||||
1: '現金',
|
||||
2: '匯款',
|
||||
3: '支票'
|
||||
},
|
||||
search_is_reconcile: "Y",
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadTableData();
|
||||
this.search_dialog.current = this.search_dialog.controls.search5; // 設定預設搜尋控制項
|
||||
},
|
||||
filters: {
|
||||
currency(val) {
|
||||
if (!val) return '0';
|
||||
return Number(val).toLocaleString();
|
||||
},
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
const date = new Date(val);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 使用全域 DraftUtils 工具函數
|
||||
loadTableData() {
|
||||
this.loading = true;
|
||||
axios.get('../../api/transfer_register/balance_reconcile_list')
|
||||
.then(res => {
|
||||
this.items = res.data.map(item => ({
|
||||
...item,
|
||||
// 初始化表單欄位
|
||||
selected_items_text: item.balance_act_item ? (item.balance_actitem_name || '已選擇項目') : '', // 如果已有選中項目,顯示項目名稱
|
||||
new_status: item.check_status,
|
||||
balance_act_item: item.balance_act_item, // 保持現有的選中項目
|
||||
verify_note: item.verify_note || '' // 初始化核對記錄欄位
|
||||
}));
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('載入資料失敗:', err);
|
||||
alert('載入資料失敗,請重新整理頁面');
|
||||
this.items = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
getStatusColor(status) {
|
||||
switch (status) {
|
||||
case '90': return 'warning';
|
||||
case '99': return 'success';
|
||||
default: return 'grey';
|
||||
}
|
||||
},
|
||||
getStatusText(status) {
|
||||
switch (status) {
|
||||
case '90': return '沖帳有剩餘';
|
||||
case '91': return '未聯絡';
|
||||
case '92': return '已聯絡';
|
||||
case '95': return '餘額核銷';
|
||||
case '99': return '沖帳完成';
|
||||
default: return '未知狀態';
|
||||
}
|
||||
},
|
||||
showBalanceDialog(item) {
|
||||
this.dialog.selected = item;
|
||||
this.dialog.balanceAction = null;
|
||||
this.dialog.memo = '';
|
||||
this.dialog.errorMessage = '';
|
||||
this.dialog.show = true;
|
||||
|
||||
// 載入歷史記錄
|
||||
if (item.draft) {
|
||||
const detailItems = window.DraftUtils.getDraftField(item.draft, 'pro_order_detail_items');
|
||||
if (detailItems && Array.isArray(detailItems)) {
|
||||
this.dialog.historyItems = detailItems.map(item => ({
|
||||
activity_name: item.activity_name || '未知活動',
|
||||
item_name: item.actitem_name || '未知項目',
|
||||
reconcile_amount: item.reconcile || 0,
|
||||
reconcile_date: item.register_date || '2025-01-15T00:00:00'
|
||||
}));
|
||||
} else {
|
||||
this.dialog.historyItems = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
confirmBalance() {
|
||||
if (!this.dialog.balanceAction) {
|
||||
this.dialog.errorMessage = '請選擇處理方式';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.dialog.memo.trim()) {
|
||||
this.dialog.errorMessage = '請輸入處理說明';
|
||||
return;
|
||||
}
|
||||
|
||||
this.dialog.loading = true;
|
||||
this.dialog.errorMessage = '';
|
||||
|
||||
// 模擬 API 調用
|
||||
setTimeout(() => {
|
||||
alert(`餘額處理完成:${this.getActionText(this.dialog.balanceAction)}`);
|
||||
this.dialog.show = false;
|
||||
this.dialog.loading = false;
|
||||
// 這裡之後會重新載入資料
|
||||
}, 1500);
|
||||
},
|
||||
getActionText(action) {
|
||||
switch (action) {
|
||||
case 'transfer': return '轉入下次活動';
|
||||
case 'refund_cash': return '現金退費';
|
||||
case 'refund_bank': return '銀行轉帳退費';
|
||||
case 'balance_off': return '結餘處理';
|
||||
default: return '未知操作';
|
||||
}
|
||||
},
|
||||
showDetailDialog(item) {
|
||||
this.detailDialog.selected = item;
|
||||
this.detailDialog.tab = 0; // 重置到第一個tab
|
||||
|
||||
// 解析沖帳明細 JSON 並轉為表格資料
|
||||
this.loadReconcileItems(item.draft, item.id);
|
||||
|
||||
this.detailDialog.show = true;
|
||||
},
|
||||
async loadReconcileItems(draft, transferRegisterId) {
|
||||
this.detailDialog.reconcileItems = [];
|
||||
|
||||
if (!draft) return;
|
||||
|
||||
const detailItems = window.DraftUtils.getDraftField(draft, 'pro_order_detail_items');
|
||||
if (detailItems && Array.isArray(detailItems)) {
|
||||
// 使用新格式的 pro_order_detail_items
|
||||
this.detailDialog.reconcileItems = detailItems.map((item, index) => {
|
||||
return {
|
||||
pro_order_detail_num: item.pro_order_detail_num,
|
||||
activity_name: item.activity_name || '未知活動',
|
||||
actitem_name: item.actitem_name || '未知項目',
|
||||
price: item.price || 0,
|
||||
reconcile: item.reconcile,
|
||||
register_date: item.register_date,
|
||||
order_no: item.order_no || ''
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// 如果沒有詳細資料,嘗試使用 API 取得資料
|
||||
try {
|
||||
const response = await axios.get(`../../api/transfer_register/reconcile_detail?transfer_register_id=${transferRegisterId}`);
|
||||
this.detailDialog.reconcileItems = response.data;
|
||||
} catch (error) {
|
||||
console.error('載入沖帳明細失敗:', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
search_show(curr) {
|
||||
this.search_dialog.current = curr;
|
||||
this.search_clear();
|
||||
this.search_dialog.show = true;
|
||||
},
|
||||
search_clear() {
|
||||
if (!this.search_dialog.current.keys) return;
|
||||
this.search_dialog.current.keys.forEach((t, i) => { t.value = '' });
|
||||
this.search_get();
|
||||
},
|
||||
search_get() {
|
||||
if (!this.search_dialog.current.keys) return;
|
||||
let api_url = this.search_dialog.current.api_url;
|
||||
let keys = this.search_dialog.current.keys;
|
||||
|
||||
this.search_dialog.page = this.options.page ?? 1;
|
||||
let params = { page: this.search_dialog.page, pageSize: 10 };
|
||||
var search = {};
|
||||
keys.forEach((t, i) => {
|
||||
search[t.id] = t.value;
|
||||
});
|
||||
|
||||
// 只有活動品項 Dialog 查詢時才帶 is_reconcile
|
||||
if (this.search_dialog.current.id === 'search5' && this.search_is_reconcile === 'Y') {
|
||||
search.is_reconcile = 'Y';
|
||||
}
|
||||
|
||||
console.log("search_get", api_url, search, params, this.options);
|
||||
this.search_dialog.loading = true;
|
||||
|
||||
axios.post(api_url, search, { params: params })
|
||||
.then(response => {
|
||||
this.search_dialog.list = response.data.list;
|
||||
this.search_dialog.count = response.data.count;
|
||||
this.search_dialog.loading = false;
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
this.search_dialog.list = [];
|
||||
this.search_dialog.count = 0;
|
||||
this.search_dialog.loading = false;
|
||||
alert("錯誤:" + error);
|
||||
});
|
||||
},
|
||||
search_headers() {
|
||||
if (!this.search_dialog.current.columns) return;
|
||||
let r = [];
|
||||
this.search_dialog.current.columns.forEach((t, i) => {
|
||||
r.push({
|
||||
text: t.title,
|
||||
width: t.width,
|
||||
align: 'start',
|
||||
sortable: false,
|
||||
value: t.id,
|
||||
});
|
||||
});
|
||||
return r;
|
||||
},
|
||||
search_select(row) {
|
||||
let curr = this.search_dialog.current;
|
||||
curr.selected = row;
|
||||
|
||||
if (curr.select instanceof Function) {
|
||||
curr.select(this, row);
|
||||
}
|
||||
this.search_dialog.show = false;
|
||||
console.log('Selected row:', row);
|
||||
},
|
||||
showItemSelectDialog(item) {
|
||||
// 設定當前正在編輯的行
|
||||
this.search_dialog.controls.search5.currentRow = item;
|
||||
this.search_dialog.current = this.search_dialog.controls.search5;
|
||||
this.search_is_reconcile = "Y"; // 預設勾選
|
||||
this.search_clear();
|
||||
this.search_get(); // Dialog 一打開就查詢
|
||||
this.search_dialog.show = true;
|
||||
},
|
||||
processBalance(item) {
|
||||
if (!item.new_status) {
|
||||
alert('請選擇狀態');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item.balance_act_item) {
|
||||
alert('請先選擇項目');
|
||||
return;
|
||||
}
|
||||
|
||||
// 準備更新資料
|
||||
const updateData = {
|
||||
id: item.id,
|
||||
check_status: item.new_status,
|
||||
balance_act_item: item.balance_act_item,
|
||||
verify_note: item.verify_note || ''
|
||||
};
|
||||
|
||||
// 發送到後端更新
|
||||
axios.post('../../api/transfer_register/update_balance', updateData)
|
||||
.then(response => {
|
||||
const statusText = this.statusOptions.find(opt => opt.value === item.new_status)?.text || '';
|
||||
alert(`核銷餘額處理完成\n信眾:${item.follower}\n狀態:${statusText}\n項目:${item.selected_items_text}`);
|
||||
|
||||
// 如果狀態是「餘額核銷」(95),則從表格中移除該列
|
||||
if (item.new_status === '95') {
|
||||
const index = this.items.findIndex(i => i.id === item.id);
|
||||
if (index !== -1) {
|
||||
this.items.splice(index, 1);
|
||||
}
|
||||
} else {
|
||||
// 如果狀態不是「餘額核銷」,則只更新該列的狀態
|
||||
const index = this.items.findIndex(i => i.id === item.id);
|
||||
if (index !== -1) {
|
||||
this.items[index].check_status = item.new_status;
|
||||
this.items[index].verify_note = item.verify_note || '';
|
||||
this.items[index].balance_act_item = item.balance_act_item;
|
||||
// 確保 selected_items_text 也得到更新
|
||||
this.items[index].selected_items_text = item.selected_items_text;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新失敗:', error);
|
||||
alert('更新失敗,請重試');
|
||||
});
|
||||
},
|
||||
canUpdate(item) {
|
||||
// 所有狀態都必須選取項目才可按
|
||||
if (!item.balance_act_item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 狀態為「餘額核銷」時,必須選取項目才可按
|
||||
if (item.new_status === '95') {
|
||||
return true;
|
||||
}
|
||||
// 狀態為「未聯絡」或「已聯絡」時,皆可按
|
||||
if (item.new_status === '91' || item.new_status === '92') {
|
||||
return true;
|
||||
}
|
||||
// 其他狀態不可按
|
||||
return false;
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.code-textarea textarea {
|
||||
font-family: 'Courier New', monospace !important;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
/* 增加表格每列高度,讓內容不擁擠 */
|
||||
.v-data-table.balance-reconcile-table .v-data-table__wrapper tr {
|
||||
}
|
||||
|
||||
.v-data-table.balance-reconcile-table .v-data-table__wrapper td {
|
||||
min-height: 110px !important;
|
||||
height: 110px !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-info white--text text-center">
|
||||
<h5 class="mb-0">餘額核銷查詢</h5>
|
||||
<button class="btn btn-default ms-auto"><i class="mdi mdi-close"></i></button>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row class="mb-0 mt-4">
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="query.start_date" label="起始日" type="date" dense outlined></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="query.end_date" label="結束日" type="date" dense outlined></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<v-text-field v-model="query.activity_name" label="法會" dense outlined readonly>
|
||||
<template v-slot:append>
|
||||
<v-btn icon @click="showActivityDialog"><v-icon>mdi-magnify</v-icon></v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<v-text-field v-model="query.follower_name" label="信眾" dense outlined readonly>
|
||||
<template v-slot:append>
|
||||
<v-btn icon @click="showFollowerDialog"><v-icon>mdi-magnify</v-icon></v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2" class="d-flex justify-end">
|
||||
<v-btn color="primary" class="mr-2" @click="search">查詢</v-btn>
|
||||
<v-btn color="grey" @click="reset">重設</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1 balance-reconcile-table"
|
||||
item-key="id"
|
||||
:footer-props="{ 'items-per-page-options': [10, 20, 50] }">
|
||||
<template v-slot:item.follower="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.follower }}</div>
|
||||
<div class="caption text--secondary" v-if="item.phone">{{ item.phone }}</div>
|
||||
<div class="caption text--secondary" v-if="item.phone2">{{ item.phone2 }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.bank_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.acc_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.check_date | date }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.amount_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-primary">入帳金額:{{ item.check_amount || 0 }}</div>
|
||||
<div class="text-success">核銷金額:{{ (item.remain_amount || 0) }}</div>
|
||||
<!-- 狀態95不會有待核銷,不顯示這一行 -->
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.remain_amount="{ item }">
|
||||
<div class="text-success">{{ item.remain_amount || 0 }}</div>
|
||||
</template>
|
||||
<template v-slot:item.select_items="{ item }">
|
||||
<div style="min-width: 120px;">
|
||||
{{ item.balance_actitem_name || '未選擇項目' }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.detail_info="{ item }">
|
||||
<v-btn color="info" outlined @click="showDetailDialog(item)">
|
||||
<v-icon small class="mr-1">mdi-information-outline</v-icon> 詳細
|
||||
</v-btn>
|
||||
</template>
|
||||
<template v-slot:item.verify_note="{ item }">
|
||||
<div style="white-space: pre-line;">{{ item.verify_note }}</div>
|
||||
</template>
|
||||
<template v-slot:item.check_date="{ item }">
|
||||
<span>{{ item.check_date | date }}</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<!-- 法會選取 Dialog -->
|
||||
<v-dialog v-model="activityDialog.show" max-width="700px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-table</v-icon>
|
||||
選擇法會
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="activityDialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<v-text-field v-model="activityDialog.search" label="搜尋法會" dense outlined @keyup.enter="searchActivity"></v-text-field>
|
||||
<v-data-table :headers="activityDialog.headers"
|
||||
:items="activityDialog.items"
|
||||
:loading="activityDialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1 mt-2"
|
||||
@click:row="selectActivity"
|
||||
hide-default-footer></v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 信眾選取 Dialog -->
|
||||
<v-dialog v-model="followerDialog.show" max-width="700px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-account</v-icon>
|
||||
選擇信眾
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="followerDialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<v-text-field v-model="followerDialog.search" label="搜尋信眾" dense outlined @keyup.enter="searchFollower"></v-text-field>
|
||||
<v-data-table :headers="followerDialog.headers"
|
||||
:items="followerDialog.items"
|
||||
:loading="followerDialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1 mt-2"
|
||||
@click:row="selectFollower"
|
||||
hide-default-footer></v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 詳細資訊對話框 -->
|
||||
<v-dialog v-model="dialog.show" max-width="900px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="info" class="mr-2">mdi-information-outline</v-icon>
|
||||
詳細資訊
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="dialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<div v-if="dialog.selected">
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-primary">匯款人資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">姓名:</span>{{ dialog.selected.name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">電話:</span>{{ dialog.selected.phone }}</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-success">入帳資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳帳戶:</span>{{ dialog.selected.acc_name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳日期:</span>{{ dialog.selected.check_date | date }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳金額:</span>{{ dialog.selected.check_amount }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider class="my-4"></v-divider>
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-purple">活動資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">活動名稱:</span>{{ dialog.selected.activity_name || '-' }}</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-info">核對記錄</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">核對記錄:</span>{{ dialog.selected.verify_note || '-' }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.v-data-table.balance-reconcile-table .v-data-table__wrapper tbody tr {
|
||||
min-height: 90px !important;
|
||||
height: 90px !important;
|
||||
}
|
||||
|
||||
.v-data-table.balance-reconcile-table .v-data-table__wrapper tbody td {
|
||||
min-height: 90px !important;
|
||||
height: 90px !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
query: {
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
activity_num: '',
|
||||
activity_name: '',
|
||||
follower_num: '',
|
||||
follower_name: ''
|
||||
},
|
||||
headers: [
|
||||
{ text: '信眾', value: 'follower' },
|
||||
{ text: '入帳帳戶/日期', value: 'bank_info' },
|
||||
{ text: '核銷日期', value: 'check_date', sortable: true, width: '120px' },
|
||||
{ text: '核銷項目', value: 'select_items', sortable: false, width: '120px' },
|
||||
{ text: '核銷金額', value: 'reconcile_amount', sortable: false, width: '120px' },
|
||||
{ text: '詳細資訊', value: 'detail_info', sortable: false },
|
||||
// { text: '狀態', value: 'status', sortable: false, width: '100px' }, // 移除狀態欄
|
||||
{ text: '核對記錄', value: 'verify_note', sortable: false, width: '180px' },
|
||||
],
|
||||
items: [],
|
||||
dialog: {
|
||||
show: false,
|
||||
selected: null
|
||||
},
|
||||
activityDialog: {
|
||||
show: false,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '名稱', value: 'subject' }
|
||||
]
|
||||
},
|
||||
followerDialog: {
|
||||
show: false,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '姓名', value: 'u_name' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
const date = new Date(val);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 使用全域 DraftUtils 工具函數
|
||||
search() {
|
||||
this.loading = true;
|
||||
// 串接查詢 API,帶入所有查詢條件
|
||||
axios.get('../../api/transfer_register/balance_reconcile_query', { params: this.query })
|
||||
.then(res => { this.items = res.data; })
|
||||
.catch(() => { this.items = []; })
|
||||
.finally(() => { this.loading = false; });
|
||||
},
|
||||
reset() {
|
||||
this.query.start_date = '';
|
||||
this.query.end_date = '';
|
||||
this.query.activity_num = '';
|
||||
this.query.activity_name = '';
|
||||
this.query.follower_num = '';
|
||||
this.query.follower_name = '';
|
||||
this.items = [];
|
||||
},
|
||||
showDetailDialog(item) {
|
||||
this.dialog.selected = item;
|
||||
this.dialog.show = true;
|
||||
},
|
||||
showActivityDialog() {
|
||||
this.activityDialog.show = true;
|
||||
this.searchActivity();
|
||||
},
|
||||
searchActivity() {
|
||||
this.activityDialog.loading = true;
|
||||
axios.get('../../api/activity', { params: { keyword: this.activityDialog.search } })
|
||||
.then(res => { this.activityDialog.items = res.data; })
|
||||
.catch(() => { this.activityDialog.items = []; })
|
||||
.finally(() => { this.activityDialog.loading = false; });
|
||||
},
|
||||
selectActivity(row) {
|
||||
this.query.activity_num = row.num;
|
||||
this.query.activity_name = row.subject;
|
||||
this.activityDialog.show = false;
|
||||
},
|
||||
showFollowerDialog() {
|
||||
this.followerDialog.show = true;
|
||||
this.searchFollower();
|
||||
},
|
||||
searchFollower() {
|
||||
this.followerDialog.loading = true;
|
||||
axios.post('../../api/follower/GetList', { u_name: this.followerDialog.search }, { params: { page: 1, pageSize: 10 } })
|
||||
.then(res => { this.followerDialog.items = res.data.list; })
|
||||
.catch(() => { this.followerDialog.items = []; })
|
||||
.finally(() => { this.followerDialog.loading = false; });
|
||||
},
|
||||
selectFollower(row) {
|
||||
this.query.follower_num = row.num;
|
||||
this.query.follower_name = row.u_name;
|
||||
this.followerDialog.show = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,657 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h5 class="mb-0">共同 - 沖帳流程</h5>
|
||||
<button class="btn btn-default ms-auto"><i class="mdi mdi-close"></i></button>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1"
|
||||
item-key="id">
|
||||
<template v-slot:item.follower="{ item }">
|
||||
<span :title="item.f_num">{{ item.follower }}</span>
|
||||
</template>
|
||||
<template v-slot:item.activity_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.activity_name }}</div>
|
||||
<div class="caption text--secondary">
|
||||
<span v-if="hasFollowerList(item.draft)" style="margin-right: 4px;">👥</span>
|
||||
{{ item.acc_name }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.check_date="{ item }">
|
||||
<span>{{ item.check_date | date }}</span>
|
||||
</template>
|
||||
<template v-slot:item.check_memo="{ item }">
|
||||
<span>{{ item.check_memo }}</span>
|
||||
</template>
|
||||
<template v-slot:item.verify_note="{ item }">
|
||||
<span>{{ item.verify_note }}</span>
|
||||
</template>
|
||||
<template v-slot:item.follower_selection="{ item }">
|
||||
<div>
|
||||
<v-btn small
|
||||
color="primary"
|
||||
outlined
|
||||
@click="showFollowerSelection(item)"
|
||||
class="mb-1">
|
||||
<v-icon left small>mdi-account-multiple</v-icon>
|
||||
選擇支付人
|
||||
</v-btn>
|
||||
<div v-if="hasFollowerList(item.draft)" class="caption text-success mt-1">
|
||||
<v-icon small color="success">mdi-check-circle</v-icon>
|
||||
已選擇 {{ getFollowerCount(item.draft) }} 位
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn small
|
||||
color="success"
|
||||
@click="showGroupReconcileDialog(item)"
|
||||
:disabled="!hasFollowerList(item.draft)">
|
||||
<v-icon left small>mdi-receipt</v-icon>
|
||||
{{ hasFollowerList(item.draft) ? '共同沖帳' : '請先選擇支付人' }}
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<!-- 選擇共同支付人對話框 -->
|
||||
<v-dialog v-model="followerDialog.show" max-width="800px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-account-multiple</v-icon>
|
||||
選擇共同支付人
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="followerDialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<div v-if="followerDialog.selected">
|
||||
<h6 class="mb-3">法會:{{ followerDialog.selected.activity_name }}</h6>
|
||||
<v-text-field v-model="followerDialog.search"
|
||||
label="搜尋信眾"
|
||||
dense
|
||||
outlined
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
@input="searchActivityFollowers"></v-text-field>
|
||||
<v-data-table :headers="followerDialog.headers"
|
||||
:items="followerDialog.items"
|
||||
:loading="followerDialog.loading"
|
||||
item-key="f_num"
|
||||
class="elevation-1 mt-2"
|
||||
show-select
|
||||
v-model="followerDialog.selectedFollowers"
|
||||
hide-default-footer
|
||||
:disable-pagination="true">
|
||||
<template v-slot:item.follower_name="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.follower_name }}</div>
|
||||
<div class="caption text--secondary">編號: {{ item.f_num }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.total_due="{ item }">
|
||||
<span class="text-danger">{{ item.total_due | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.item_count="{ item }">
|
||||
<span class="text-info">{{ item.item_count }} 項</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions class="pa-4">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="grey" @click="followerDialog.show = false">取消</v-btn>
|
||||
<v-btn color="primary" @click="confirmFollowerSelection" :disabled="followerDialog.selectedFollowers.length === 0">
|
||||
確認選擇 ({{ followerDialog.selectedFollowers.length }})
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 共同沖帳明細對話框 -->
|
||||
<v-dialog v-model="reconcileDialog.show" max-width="1200px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="success" class="mr-2">mdi-receipt</v-icon>
|
||||
共同沖帳明細
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="reconcileDialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="mb-0 pb-0">
|
||||
<div v-if="reconcileDialog.selected">
|
||||
<div class="row my-2">
|
||||
<h6 class="col">共同支付人:{{ getSelectedFollowersText() }}</h6>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">入帳金額:</span>
|
||||
<span class="text-primary">{{ reconcileDialog.selected.check_amount | currency }}</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">已沖金額:</span>
|
||||
<span :class="{'text-danger': isOverPaid, 'text-dark': !isOverPaid}">{{ sumReconcile | currency }}</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">未繳餘款:</span>
|
||||
<span class="text-danger">{{ remainDue | currency }}</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">入帳後餘額:</span>
|
||||
<span class="text-success">{{ overPaid | currency }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<v-data-table :headers="reconcileDialog.headers"
|
||||
:items="reconcileDialog.items"
|
||||
class="elevation-1 mt-3"
|
||||
hide-default-footer
|
||||
:disable-pagination="true">
|
||||
<template v-slot:item.follower_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-primary">{{ item.follower_name }}</div>
|
||||
<div class="text-muted" style="font-size:12px;">{{ item.order_no }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.activity_name="{ item }">
|
||||
<div>
|
||||
<div>{{ item.activity_name }}</div>
|
||||
<div class="text-muted" style="font-size:12px;">{{ item.reg_time | date }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.paid="{ item }">
|
||||
<span>{{ item.paid | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.due="{ item }">
|
||||
<span>{{ item.due | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.reconcile="{ item, index }">
|
||||
<v-text-field v-model="item.reconcile"
|
||||
type="number"
|
||||
dense
|
||||
outlined
|
||||
hide-details="auto"
|
||||
:rules="[
|
||||
v=>
|
||||
!isNaN(Number(v)) || '請輸入數字',
|
||||
v => Number(v) >= 0 || '不可小於 0',
|
||||
v => Number(v) <= Number(item.due) || `不可大於待繳金額 ${item.due}`
|
||||
]"
|
||||
@blur="validateAndUpdateReconcile($event.target.value, item, index)"
|
||||
>
|
||||
</v-text-field>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions class="pa-4">
|
||||
<div>
|
||||
<div v-if="hasUnallocated && remainDue > 0" class="text-dark mb-2">
|
||||
⚠️ 尚有未分配的入帳金額,請確認是否全部分配
|
||||
</div>
|
||||
<div v-if="hasUnallocated && remainDue === 0" class="text-info mb-2">
|
||||
ℹ️ 已無未繳項目,剩餘入帳金額將成為餘額
|
||||
</div>
|
||||
<div v-if="!canConfirm && buttonErrorMessage" class="text-danger">
|
||||
❌ {{ buttonErrorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="info" @click="redistributeReconcile" class="mr-2">重新分配</v-btn>
|
||||
<v-btn color="orange" @click="saveDraft" class="mr-2">暫存</v-btn>
|
||||
<v-btn color="primary" @click="confirmGroupReconcile" :disabled="!canConfirm">確認沖帳</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
if (typeof window.DraftUtils === 'undefined') {
|
||||
console.warn('DraftUtils 未載入,使用備用方案');
|
||||
window.DraftUtils = {
|
||||
hasFollowerList: function (draft) { return false; },
|
||||
getFollowerList: function (draft) { return []; },
|
||||
updateFollowerList: function (draft, list) {
|
||||
return { follower_list: list };
|
||||
},
|
||||
getDraftField: function (draft, field) { return null; },
|
||||
updateDraftField: function (draft, field, value) {
|
||||
return { [field]: value };
|
||||
}
|
||||
};
|
||||
}
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
headers: [
|
||||
{ text: '匯款人', value: 'follower' },
|
||||
{ text: '法會/入帳帳戶', value: 'activity_info' },
|
||||
{ text: '入帳日期', value: 'check_date' },
|
||||
{ text: '帳簿備註', value: 'check_memo' },
|
||||
{ text: '入帳金額', value: 'check_amount' },
|
||||
{ text: '核對記錄', value: 'verify_note' },
|
||||
{ text: '選擇共同支付人', value: 'follower_selection', sortable: false },
|
||||
{ text: '共同沖帳', value: 'actions', sortable: false }
|
||||
],
|
||||
items: [],
|
||||
followerDialog: {
|
||||
show: false,
|
||||
selected: null,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
selectedFollowers: [],
|
||||
headers: [
|
||||
{ text: '信眾', value: 'follower_name' },
|
||||
{ text: '待繳金額', value: 'total_due' },
|
||||
{ text: '項目數', value: 'item_count' }
|
||||
]
|
||||
},
|
||||
reconcileDialog: {
|
||||
show: false,
|
||||
selected: null,
|
||||
headers: [
|
||||
{ text: '信眾/報名單號', value: 'follower_info' },
|
||||
{ text: '法會/報名日期', value: 'activity_name' },
|
||||
{ text: '項目', value: 'actitem_name' },
|
||||
{ text: '應繳金額', value: 'price', sortable: false },
|
||||
{ text: '已繳金額', value: 'paid', sortable: false },
|
||||
{ text: '待繳金額', value: 'due', sortable: false },
|
||||
{ text: '沖帳金額', value: 'reconcile', sortable: false }
|
||||
],
|
||||
items: [],
|
||||
loading: false,
|
||||
errorMessage: ''
|
||||
},
|
||||
hasUnallocated: false,
|
||||
draftDataChanged: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sumReconcile() {
|
||||
return this.reconcileDialog.items.reduce((sum, item) => sum + (Number(item.reconcile) || 0), 0);
|
||||
},
|
||||
remainDue() {
|
||||
const totalDue = this.reconcileDialog.items.reduce((sum, item) => sum + (Number(item.due) || 0), 0);
|
||||
return totalDue - this.sumReconcile;
|
||||
},
|
||||
overPaid() {
|
||||
if (!this.reconcileDialog.selected) return 0;
|
||||
return this.reconcileDialog.selected.check_amount - this.sumReconcile;
|
||||
},
|
||||
isOverPaid() {
|
||||
if (!this.reconcileDialog.selected) return false;
|
||||
return this.sumReconcile > this.reconcileDialog.selected.check_amount;
|
||||
},
|
||||
canConfirm() {
|
||||
if (!this.reconcileDialog.selected) return false;
|
||||
|
||||
const hasReconcile = this.reconcileDialog.items.some(item => Number(item.reconcile) > 0);
|
||||
if (!hasReconcile) return false;
|
||||
|
||||
const validAmounts = this.reconcileDialog.items.every(item => {
|
||||
const amount = Number(item.reconcile) || 0;
|
||||
return amount >= 0 && amount <= Number(item.due);
|
||||
});
|
||||
if (!validAmounts) return false;
|
||||
|
||||
if (this.sumReconcile > this.reconcileDialog.selected.check_amount) return false;
|
||||
|
||||
if (this.hasUnallocated && this.remainDue > 0) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
buttonErrorMessage() {
|
||||
if (!this.reconcileDialog.selected) return '';
|
||||
|
||||
const hasReconcile = this.reconcileDialog.items.some(item => Number(item.reconcile) > 0);
|
||||
if (!hasReconcile) return '請至少輸入一筆沖帳金額';
|
||||
|
||||
const invalidItem = this.reconcileDialog.items.find(item => {
|
||||
const amount = Number(item.reconcile) || 0;
|
||||
return amount < 0 || amount > Number(item.due);
|
||||
});
|
||||
if (invalidItem) return '沖帳金額超出可沖帳範圍';
|
||||
|
||||
if (this.sumReconcile > this.reconcileDialog.selected.check_amount) {
|
||||
return '已沖金額不可大於入帳金額';
|
||||
}
|
||||
|
||||
if (this.hasUnallocated && this.remainDue > 0) {
|
||||
return '尚有未繳項目,請將入帳金額完全分配';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadTableData();
|
||||
},
|
||||
filters: {
|
||||
currency(val) {
|
||||
if (!val) return '0';
|
||||
return Number(val).toLocaleString();
|
||||
},
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
const date = new Date(val);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 檢查是否有 follower_list
|
||||
hasFollowerList(draft) {
|
||||
return window.DraftUtils && window.DraftUtils.hasFollowerList && window.DraftUtils.hasFollowerList(draft);
|
||||
},
|
||||
// 取得已選擇的支付人數量
|
||||
getFollowerCount(draft) {
|
||||
if (!window.DraftUtils || !window.DraftUtils.getFollowerList) return 0;
|
||||
const followerList = window.DraftUtils.getFollowerList(draft);
|
||||
return followerList ? followerList.length : 0;
|
||||
},
|
||||
loadTableData() {
|
||||
this.loading = true;
|
||||
axios.get('../../api/transfer_register/group_reconcile_list')
|
||||
.then(res => {
|
||||
this.items = res.data;
|
||||
})
|
||||
.catch(() => {
|
||||
this.items = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
showGroupReconcileDialog(item) {
|
||||
// 檢查是否已有選擇的共同支付人
|
||||
const followerList = window.DraftUtils.getFollowerList(item.draft);
|
||||
if (followerList && followerList.length > 0) {
|
||||
// 直接顯示沖帳明細
|
||||
this.showReconcileDetail(item, followerList);
|
||||
} else {
|
||||
// 先選擇共同支付人
|
||||
this.showFollowerSelection(item);
|
||||
}
|
||||
},
|
||||
showFollowerSelection(item) {
|
||||
this.followerDialog.selected = item;
|
||||
this.followerDialog.selectedFollowers = [];
|
||||
this.followerDialog.items = [];
|
||||
this.followerDialog.show = true;
|
||||
this.searchActivityFollowers();
|
||||
},
|
||||
searchActivityFollowers() {
|
||||
if (!this.followerDialog.selected || !this.followerDialog.selected.activity_num) return;
|
||||
|
||||
this.followerDialog.loading = true;
|
||||
axios.get('../../api/transfer_register/activity_followers', {
|
||||
params: { activity_num: this.followerDialog.selected.activity_num }
|
||||
})
|
||||
.then(res => {
|
||||
let items = res.data;
|
||||
// 如果有搜尋關鍵字,過濾結果
|
||||
if (this.followerDialog.search && this.followerDialog.search.trim()) {
|
||||
const keyword = this.followerDialog.search.trim().toLowerCase();
|
||||
items = items.filter(item =>
|
||||
item.follower_name.toLowerCase().includes(keyword)
|
||||
);
|
||||
}
|
||||
this.followerDialog.items = items;
|
||||
})
|
||||
.catch(() => {
|
||||
this.followerDialog.items = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.followerDialog.loading = false;
|
||||
});
|
||||
},
|
||||
confirmFollowerSelection() {
|
||||
if (this.followerDialog.selectedFollowers.length === 0) {
|
||||
alert('請選擇至少一位共同支付人');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.followerDialog.selected) {
|
||||
alert('系統錯誤:未選擇記錄');
|
||||
return;
|
||||
}
|
||||
|
||||
// 儲存選擇的共同支付人到 draft
|
||||
const followerList = this.followerDialog.selectedFollowers.map(f => ({
|
||||
f_num: f.f_num,
|
||||
f_name: f.follower_name,
|
||||
activity_num: this.followerDialog.selected.activity_num
|
||||
}));
|
||||
|
||||
const draftData = window.DraftUtils.updateFollowerList(this.followerDialog.selected.draft, followerList);
|
||||
this.updateFollowerDraftToDB(this.followerDialog.selected.id, draftData)
|
||||
.then(() => {
|
||||
this.followerDialog.selected.draft = JSON.stringify(draftData);
|
||||
this.followerDialog.show = false;
|
||||
// 重新載入資料以更新顯示
|
||||
this.loadTableData();
|
||||
// 顯示沖帳明細
|
||||
this.showReconcileDetail(this.followerDialog.selected, followerList);
|
||||
})
|
||||
.catch(err => {
|
||||
alert('儲存失敗,請重試');
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
showReconcileDetail(item, followerList) {
|
||||
this.reconcileDialog.selected = item;
|
||||
this.reconcileDialog.items = [];
|
||||
this.reconcileDialog.show = true;
|
||||
|
||||
// 取得所選信眾的訂單明細
|
||||
const fNums = followerList.map(f => f.f_num).join(',');
|
||||
axios.get('../../api/transfer_register/group_follower_orders', {
|
||||
params: {
|
||||
activity_num: item.activity_num,
|
||||
f_nums: fNums
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
this.reconcileDialog.items = res.data.map(item => ({
|
||||
...item,
|
||||
reconcile: 0 // 初始化沖帳金額
|
||||
}));
|
||||
this.autoDistributeReconcile();
|
||||
})
|
||||
.catch(() => {
|
||||
this.reconcileDialog.items = [];
|
||||
this.updateSumReconcile();
|
||||
});
|
||||
},
|
||||
getSelectedFollowersText() {
|
||||
if (!this.reconcileDialog.selected) return '';
|
||||
const followerList = window.DraftUtils.getFollowerList(this.reconcileDialog.selected.draft);
|
||||
return followerList.map(f => f.f_name).join('、');
|
||||
},
|
||||
autoDistributeReconcile() {
|
||||
// 先進先出分配沖帳金額
|
||||
let remainAmount = this.reconcileDialog.selected ? this.reconcileDialog.selected.check_amount : 0;
|
||||
|
||||
// 先將所有項目的 reconcile 清為 0
|
||||
this.reconcileDialog.items.forEach(item => {
|
||||
this.$set(item, 'reconcile', 0);
|
||||
});
|
||||
|
||||
// 依報名日期排序(先進先出)
|
||||
const sortedItems = [...this.reconcileDialog.items].sort((a, b) =>
|
||||
new Date(a.reg_time) - new Date(b.reg_time)
|
||||
);
|
||||
|
||||
// 逐項分配
|
||||
sortedItems.forEach(item => {
|
||||
if (remainAmount > 0) {
|
||||
const canPay = Math.min(item.due, remainAmount);
|
||||
const originalItem = this.reconcileDialog.items.find(i => i === item);
|
||||
if (originalItem) {
|
||||
this.$set(originalItem, 'reconcile', canPay);
|
||||
}
|
||||
remainAmount -= canPay;
|
||||
}
|
||||
});
|
||||
|
||||
this.updateSumReconcile();
|
||||
},
|
||||
redistributeReconcile() {
|
||||
this.autoDistributeReconcile();
|
||||
},
|
||||
updateSumReconcile() {
|
||||
const maxTotal = this.reconcileDialog.selected ? (this.reconcileDialog.selected.check_amount || 0) : 0;
|
||||
this.hasUnallocated = maxTotal > this.sumReconcile;
|
||||
},
|
||||
saveDraft() {
|
||||
try {
|
||||
// 組成新的資料
|
||||
const followerList = window.DraftUtils.getFollowerList(this.reconcileDialog.selected.draft);
|
||||
const reconcileData = this.reconcileDialog.items
|
||||
.filter(item => Number(item.reconcile) > 0)
|
||||
.map(item => ({
|
||||
f_num: item.f_num,
|
||||
follower_name: item.follower_name,
|
||||
pro_order_detail_num: item.num,
|
||||
reconcile: Number(item.reconcile)
|
||||
}));
|
||||
|
||||
const draftData = {
|
||||
transfer_draft: [],
|
||||
pro_order_detail_items: reconcileData,
|
||||
follower_list: followerList
|
||||
};
|
||||
|
||||
this.updateDraftToDB(this.reconcileDialog.selected.id, draftData)
|
||||
.then(() => {
|
||||
alert('暫存成功!');
|
||||
this.reconcileDialog.selected.draft = JSON.stringify(draftData);
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
alert('暫存失敗:資料格式錯誤');
|
||||
}
|
||||
},
|
||||
updateFollowerDraftToDB(id, draftData) {
|
||||
const selectedItem = this.followerDialog.selected;
|
||||
const updateData = {
|
||||
id: id,
|
||||
activity_num: selectedItem.activity_num,
|
||||
name: selectedItem.name,
|
||||
phone: selectedItem.phone,
|
||||
pay_type: selectedItem.pay_type,
|
||||
account_last5: selectedItem.account_last5,
|
||||
amount: selectedItem.amount,
|
||||
pay_mode: selectedItem.pay_mode,
|
||||
note: selectedItem.note,
|
||||
proof_img: selectedItem.proof_img,
|
||||
status: selectedItem.status,
|
||||
f_num_match: selectedItem.f_num_match,
|
||||
f_num: selectedItem.f_num,
|
||||
acc_num: selectedItem.acc_num,
|
||||
check_date: selectedItem.check_date,
|
||||
check_amount: selectedItem.check_amount,
|
||||
check_memo: selectedItem.check_memo,
|
||||
check_status: selectedItem.check_status,
|
||||
acc_kind: selectedItem.acc_kind,
|
||||
member_num: selectedItem.member_num,
|
||||
verify_time: selectedItem.verify_time,
|
||||
verify_note: selectedItem.verify_note,
|
||||
draft: JSON.stringify(draftData)
|
||||
};
|
||||
|
||||
return axios.put(`../../api/transfer_register/${id}`, updateData);
|
||||
},
|
||||
updateDraftToDB(id, draftData) {
|
||||
const updateData = {
|
||||
id: id,
|
||||
activity_num: this.reconcileDialog.selected.activity_num,
|
||||
name: this.reconcileDialog.selected.name,
|
||||
phone: this.reconcileDialog.selected.phone,
|
||||
pay_type: this.reconcileDialog.selected.pay_type,
|
||||
account_last5: this.reconcileDialog.selected.account_last5,
|
||||
amount: this.reconcileDialog.selected.amount,
|
||||
pay_mode: this.reconcileDialog.selected.pay_mode,
|
||||
note: this.reconcileDialog.selected.note,
|
||||
proof_img: this.reconcileDialog.selected.proof_img,
|
||||
status: this.reconcileDialog.selected.status,
|
||||
f_num_match: this.reconcileDialog.selected.f_num_match,
|
||||
f_num: this.reconcileDialog.selected.f_num,
|
||||
acc_num: this.reconcileDialog.selected.acc_num,
|
||||
check_date: this.reconcileDialog.selected.check_date,
|
||||
check_amount: this.reconcileDialog.selected.check_amount,
|
||||
check_memo: this.reconcileDialog.selected.check_memo,
|
||||
check_status: this.reconcileDialog.selected.check_status,
|
||||
acc_kind: this.reconcileDialog.selected.acc_kind,
|
||||
member_num: this.reconcileDialog.selected.member_num,
|
||||
verify_time: this.reconcileDialog.selected.verify_time,
|
||||
verify_note: this.reconcileDialog.selected.verify_note,
|
||||
draft: JSON.stringify(draftData)
|
||||
};
|
||||
|
||||
return axios.put(`../../api/transfer_register/${id}`, updateData);
|
||||
},
|
||||
confirmGroupReconcile() {
|
||||
if (!this.canConfirm) return;
|
||||
|
||||
this.reconcileDialog.loading = true;
|
||||
const overPayment = this.reconcileDialog.selected.check_amount - this.sumReconcile;
|
||||
const postData = {
|
||||
transfer_register_id: this.reconcileDialog.selected.id,
|
||||
details: this.reconcileDialog.items
|
||||
.filter(item => item.reconcile > 0)
|
||||
.map(item => ({
|
||||
f_num: item.f_num,
|
||||
pro_order_detail_num: item.num,
|
||||
amount: Number(item.reconcile),
|
||||
reg_time: new Date().toISOString()
|
||||
})),
|
||||
over_payment: overPayment
|
||||
};
|
||||
|
||||
axios.post('../../api/transfer_register/group_reconcile', postData)
|
||||
.then(res => {
|
||||
const message = res.data && res.data.message ? res.data.message : '共同沖帳完成';
|
||||
alert(message);
|
||||
|
||||
this.reconcileDialog.show = false;
|
||||
this.loadTableData(); // 重新載入清單
|
||||
})
|
||||
.catch(err => {
|
||||
let errorMessage = '沖帳失敗,請聯繫系統管理員';
|
||||
if (err.response && err.response.data) {
|
||||
if (typeof err.response.data === 'string') {
|
||||
errorMessage = err.response.data;
|
||||
} else if (err.response.data.message) {
|
||||
errorMessage = err.response.data.message;
|
||||
}
|
||||
}
|
||||
alert(errorMessage);
|
||||
})
|
||||
.finally(() => {
|
||||
this.reconcileDialog.loading = false;
|
||||
});
|
||||
},
|
||||
validateAndUpdateReconcile(value, item, index) {
|
||||
let numValue = Number(value);
|
||||
if (isNaN(numValue)) {
|
||||
numValue = 0;
|
||||
}
|
||||
numValue = Math.round(numValue);
|
||||
|
||||
this.$set(item, 'reconcile', numValue);
|
||||
this.updateSumReconcile();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,300 @@
|
||||
<%@ Page Title="匯款/沖帳管理" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="index.aspx.cs" Inherits="admin_bill_index" %>
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
|
||||
<link rel="stylesheet" href="../../js/_bootstrap-icons-1.8.1/bootstrap-icons.css">
|
||||
<style>
|
||||
.function-icon {
|
||||
font-size: 2em;
|
||||
line-height: 1;
|
||||
align-content: center;
|
||||
}
|
||||
.external-link-icon {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.modify_modal{
|
||||
width:calc(100vw-20%);
|
||||
background-color:white;
|
||||
opacity:0;
|
||||
}
|
||||
</style>
|
||||
<script src="/js//httpVueLoader.js"></script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
|
||||
<h2 class="mb-3">匯款/沖帳管理</h2>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
<v-container>
|
||||
<div id="content" class="container py-4">
|
||||
<div class="row">
|
||||
<!-- 第一欄:匯款登錄與核對 -->
|
||||
<div class="col-lg-4 mb-4">
|
||||
<h5 class="text-primary mb-3">
|
||||
<i class="bi bi-upload"></i> 匯款登錄與核對
|
||||
</h5>
|
||||
<div class="list-group">
|
||||
<a @click="show_register()" class="list-group-item list-group-item-action" >
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-plus-circle text-success me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>
|
||||
登錄匯款資料
|
||||
<i class="bi bi-box-arrow-up-right text-muted ms-1 external-link-icon"></i>
|
||||
</div>
|
||||
<small class="text-muted">報名者自行填寫匯款相關資訊</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-primary">報名者</span>
|
||||
</div>
|
||||
</a>
|
||||
<a @click="show_verify()" class="list-group-item list-group-item-action d-none">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-person-check text-info me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>出納核對匯款人</div>
|
||||
<small class="text-muted">核對匯款人身份與報名資料</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-info">出納</span>
|
||||
</div>
|
||||
</a>
|
||||
<a @click="show_verify()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-person-check text-info me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>出納核對匯款人</div>
|
||||
<small class="text-muted">初步核對匯款人身份資料</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-info">出納</span>
|
||||
</div>
|
||||
</a>
|
||||
<%-- <a href="verify2.aspx" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-currency-dollar text-warning me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>出納核對金額(階段2)</div>
|
||||
<small class="text-muted">核對匯款金額與入帳資料</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-warning text-dark">出納</span>
|
||||
</div>
|
||||
</a>--%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二欄:沖帳流程 -->
|
||||
<div class="col-lg-4 mb-4">
|
||||
<h5 class="text-primary mb-3">
|
||||
<i class="bi bi-receipt"></i> 沖帳流程
|
||||
</h5>
|
||||
<div class="list-group">
|
||||
<a @click="personal_reconcile()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-person text-primary me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>個人-沖帳流程</div>
|
||||
<small class="text-muted">處理個人匯款的沖帳作業</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-success">會計</span>
|
||||
</div>
|
||||
</a>
|
||||
<a @click="group_reconcile()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-people text-success me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>共同-沖帳流程</div>
|
||||
<small class="text-muted">處理多人共同支付的沖帳作業</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-success">會計</span>
|
||||
</div>
|
||||
</a>
|
||||
<a @click="balance_reconcile()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-calculator text-danger me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>餘額核銷</div>
|
||||
<small class="text-muted">處理沖帳後剩餘金額的核銷</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-danger">會計</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第三欄:查詢功能 -->
|
||||
<div class="col-lg-4 mb-4">
|
||||
<h5 class="text-primary mb-3">
|
||||
<i class="bi bi-search"></i> 查詢功能
|
||||
</h5>
|
||||
<div class="list-group">
|
||||
<a @click="verify_query()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-journal-check text-info me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>沖帳查詢</div>
|
||||
<small class="text-muted">查詢所有沖帳記錄與明細</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-info">會計</span>
|
||||
</div>
|
||||
</a>
|
||||
<a @click="balance_query()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-file-text text-secondary me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>餘額核銷查詢</div>
|
||||
<small class="text-muted">查詢已完成的餘額核銷記錄</small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-secondary">會計</span>
|
||||
</div>
|
||||
</a>
|
||||
<a @click="statistic_query()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-file-spreadsheet text-secondary me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>統計報表</div>
|
||||
<small class="text-muted"></small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-secondary">會計</span>
|
||||
</div>
|
||||
</a>
|
||||
<%-- <a @click="balance_query()" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="d-flex">
|
||||
<i class="bi bi-file-spreadsheet text-secondary me-3 function-icon"></i>
|
||||
<div>
|
||||
<div>帳務查詢</div>
|
||||
<small class="text-muted"></small>
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge bg-secondary">會計</span>
|
||||
</div>
|
||||
</a>--%>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 統計資訊 -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="alert alert-info">
|
||||
<h6 class="alert-heading">
|
||||
<i class="bi bi-info-circle"></i> 系統說明
|
||||
</h6>
|
||||
<ul class="mb-0">
|
||||
<li><strong>匯款登錄與核對</strong>:處理報名者匯款資料的登錄與出納核對作業</li>
|
||||
<li><strong>沖帳流程</strong>:處理個人與共同支付的沖帳作業,以及剩餘金額的核銷</li>
|
||||
<li><strong>查詢功能</strong>:提供各類沖帳記錄的查詢與統計功能</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<v-dialog v-model="modify_dialog.show" class="modify_modal">
|
||||
<template>
|
||||
|
||||
<keep-alive>
|
||||
<component :is="currentView" @close-dialog="modify_dialog.show=false"></component>
|
||||
</keep-alive>
|
||||
|
||||
</template>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</asp:Content>
|
||||
|
||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
||||
<script src="../transfer/draft-utils.js"></script>
|
||||
<script>
|
||||
|
||||
let VueApp = new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(vuetify_options),
|
||||
data() {
|
||||
return {
|
||||
modify_dialog: {
|
||||
show:false
|
||||
},
|
||||
externalHtml: "",
|
||||
currentView:null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
//this.loadActivities();
|
||||
|
||||
},
|
||||
components: {
|
||||
'register-component': httpVueLoader('./register.vue'),
|
||||
'verify-component': httpVueLoader('./verify.vue'),
|
||||
'group-component': httpVueLoader('./group_reconcile.vue'),
|
||||
'personal-component': httpVueLoader('./personal_reconcile.vue'),
|
||||
'balance-component': httpVueLoader('./balance_reconcile.vue'),
|
||||
'verify_query-component': httpVueLoader('./verify_order_record_query.vue'),
|
||||
'balance_query-component': httpVueLoader('./balance_reconcile_query.vue'),
|
||||
'statistic_query-component': httpVueLoader('./statistic.vue'),
|
||||
},
|
||||
|
||||
methods: {
|
||||
async statistic_query(){
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'statistic_query-component'
|
||||
},
|
||||
async balance_query() {
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'balance_query-component'
|
||||
},
|
||||
async verify_query(){
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'verify_query-component'
|
||||
},
|
||||
async balance_reconcile() {
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'balance-component'
|
||||
},
|
||||
async personal_reconcile() {
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'personal-component'
|
||||
},
|
||||
async group_reconcile() {
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'group-component'
|
||||
},
|
||||
async show_verify() {
|
||||
this.modify_dialog.show = true
|
||||
this.currentView = 'verify-component'
|
||||
},
|
||||
async show_register() {
|
||||
this.modify_dialog.show = true
|
||||
this.currentView ='register-component'
|
||||
},
|
||||
loadActivities() {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
axios.get(`../../api/activity?endDate<=${today}`)
|
||||
.then(response => {
|
||||
this.activities = response.data;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('載入活動列表失敗:', error);
|
||||
alert('載入活動列表失敗,請重新整理頁面');
|
||||
});
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</asp:Content>
|
||||
@@ -0,0 +1,15 @@
|
||||
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_bill_index : MyWeb.config
|
||||
{
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,510 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h5 class="mb-0">個人 - 沖帳流程</h5>
|
||||
<button class="btn btn-default ms-auto" ><i class="mdi mdi-close"></i></button>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1"
|
||||
item-key="id">
|
||||
<template v-slot:item.follower="{ item }">
|
||||
<span :title="item.f_num">{{ item.follower }}</span>
|
||||
</template>
|
||||
<template v-slot:item.acc_name="{ item }">
|
||||
<span>
|
||||
<span v-if="hasTransferDraft(item.draft)" style="margin-right: 4px;">📝</span>{{ item.acc_name }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-slot:item.check_date="{ item }">
|
||||
<span>{{ item.check_date | date }}</span>
|
||||
</template>
|
||||
<template v-slot:item.check_memo="{ item }">
|
||||
<span>{{ item.check_memo }}</span>
|
||||
</template>
|
||||
<template v-slot:item.check_status="{ item }">
|
||||
<span>{{ item.check_status }}</span>
|
||||
</template>
|
||||
<template v-slot:item.verify_note="{ item }">
|
||||
<span>{{ item.verify_note }}</span>
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn small
|
||||
color="success"
|
||||
@click="showReconcileDialog(item)">
|
||||
沖帳
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
|
||||
<!-- 沖帳明細對話框 -->
|
||||
<v-dialog v-model="dialog.show" max-width="960px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<span v-if="dialog.selected && hasTransferDraft(dialog.selected.draft)" style="margin-right: 8px;">📝</span>沖帳明細
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="dialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="mb-0 pb-0">
|
||||
<div v-if="dialog.selected">
|
||||
<div class="row my-2">
|
||||
<h6 class="col">信眾:{{ dialog.selected.follower }}</h6>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">入帳金額:</span>
|
||||
<span class="text-primary">{{ dialog.selected.check_amount | currency }}</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">已沖金額:</span>
|
||||
<span :class="{'text-danger': isOverPaid, 'text-dark': !isOverPaid}">{{ sumReconcile | currency }}</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">未繳餘款:</span>
|
||||
<span class="text-danger">{{ remainDue | currency }}</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold">入帳後餘額:</span>
|
||||
<span class="text-success">{{ overPaid | currency }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<v-data-table :headers="dialog.headers"
|
||||
:items="dialog.items"
|
||||
class="elevation-1 mt-3"
|
||||
hide-default-footer
|
||||
:disable-pagination="true">
|
||||
<template v-slot:item.activity_name="{ item }">
|
||||
<div>
|
||||
<div>{{ item.activity_name }}</div>
|
||||
<div class="text-muted" style="font-size:12px;">{{ item.order_no }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.paid="{ item }">
|
||||
<span>{{ item.paid | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.due="{ item }">
|
||||
<span>{{ item.due | currency }}</span>
|
||||
</template>
|
||||
<template v-slot:item.reg_time="{ item }">
|
||||
<span>{{ item.reg_time | date }}</span>
|
||||
</template>
|
||||
<template v-slot:item.reconcile="{ item, index }">
|
||||
<v-text-field v-model="item.reconcile"
|
||||
type="number"
|
||||
dense
|
||||
outlined
|
||||
hide-details="auto"
|
||||
:rules="[
|
||||
v=>
|
||||
!isNaN(Number(v)) || '請輸入數字',
|
||||
v => Number(v) >= 0 || '不可小於 0',
|
||||
v => Number(v) <= Number(item.due) || `不可大於待繳金額 ${item.due}`
|
||||
]"
|
||||
@blur="validateAndUpdateReconcile($event.target.value, item, index)"
|
||||
>
|
||||
</v-text-field>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions class="pa-4">
|
||||
<div>
|
||||
<div v-if="hasUnallocated && remainDue > 0" class="text-dark mb-2">
|
||||
⚠️ 尚有未分配的入帳金額,請確認是否全部分配
|
||||
</div>
|
||||
<div v-if="hasUnallocated && remainDue === 0" class="text-info mb-2">
|
||||
ℹ️ 已無未繳項目,剩餘入帳金額將成為餘額
|
||||
</div>
|
||||
<div v-if="!canConfirm && buttonErrorMessage" class="text-danger">
|
||||
❌ {{ buttonErrorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="info" @click="redistributeReconcile" class="mr-2">重新分配</v-btn>
|
||||
<v-btn color="orange" @click="saveDraft" class="mr-2">暫存</v-btn>
|
||||
<v-btn color="primary" @click="confirmReconcile" :disabled="!canConfirm">確認沖帳</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
if (typeof window.DraftUtils === 'undefined') {
|
||||
console.warn('DraftUtils 未載入,使用備用方案');
|
||||
window.DraftUtils = {
|
||||
hasTransferDraft: function (draft) { return false; },
|
||||
getDraftField: function (draft, field) { return null; },
|
||||
updateDraftField: function (draft, field, value) {
|
||||
return { [field]: value };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
headers: [
|
||||
//{ text: '信眾#', value: 'f_num' },
|
||||
{ text: '信眾', value: 'follower' },
|
||||
{ text: '入帳銀行/帳戶', value: 'acc_name' },
|
||||
{ text: '入帳日期', value: 'check_date' },
|
||||
{ text: '帳簿備註', value: 'check_memo' },
|
||||
{ text: '入帳金額', value: 'check_amount' },
|
||||
//{ text: '狀態', value: 'check_status' },
|
||||
{ text: '核對記錄', value: 'verify_note' },
|
||||
{ text: '沖帳', value: 'actions', sortable: false }
|
||||
],
|
||||
items: [],
|
||||
dialog: {
|
||||
show: false,
|
||||
selected: null,
|
||||
headers: [
|
||||
{ text: '法會/報名單號', value: 'activity_name' },
|
||||
{ text: '報名日期', value: 'reg_time' },
|
||||
{ text: '項目', value: 'actitem_name' },
|
||||
{ text: '應繳金額', value: 'price', sortable: false },
|
||||
{ text: '已繳金額', value: 'paid', sortable: false },
|
||||
{ text: '待繳金額', value: 'due', sortable: false },
|
||||
{ text: '沖帳金額', value: 'reconcile', sortable: false }
|
||||
],
|
||||
items: [],
|
||||
loading: false,
|
||||
errorMessage: ''
|
||||
},
|
||||
hasUnallocated: false,
|
||||
draftDataChanged: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sumReconcile() {
|
||||
return this.dialog.items.reduce((sum, item) => sum + (Number(item.reconcile) || 0), 0);
|
||||
},
|
||||
remainDue() {
|
||||
const totalDue = this.dialog.items.reduce((sum, item) => sum + (Number(item.due) || 0), 0);
|
||||
return totalDue - this.sumReconcile;
|
||||
},
|
||||
overPaid() {
|
||||
if (!this.dialog.selected) return 0;
|
||||
return this.dialog.selected.check_amount - this.sumReconcile;
|
||||
},
|
||||
isOverPaid() {
|
||||
if (!this.dialog.selected) return false;
|
||||
return this.sumReconcile > this.dialog.selected.check_amount;
|
||||
},
|
||||
canConfirm() {
|
||||
if (!this.dialog.selected) return false;
|
||||
|
||||
const hasReconcile = this.dialog.items.some(item => Number(item.reconcile) > 0);
|
||||
if (!hasReconcile) return false;
|
||||
|
||||
const validAmounts = this.dialog.items.every(item => {
|
||||
const amount = Number(item.reconcile) || 0;
|
||||
return amount >= 0 && amount <= Number(item.due);
|
||||
});
|
||||
if (!validAmounts) return false;
|
||||
|
||||
if (this.sumReconcile > this.dialog.selected.check_amount) return false;
|
||||
|
||||
// 有未分配金額時,只有在還有未繳餘款的情況下才禁用按鈕
|
||||
// 如果未繳餘款為 0,表示沒有更多項目可沖帳,應允許確認
|
||||
if (this.hasUnallocated && this.remainDue > 0) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
buttonErrorMessage() {
|
||||
if (!this.dialog.selected) return '';
|
||||
|
||||
const hasReconcile = this.dialog.items.some(item => Number(item.reconcile) > 0);
|
||||
if (!hasReconcile) return '請至少輸入一筆沖帳金額';
|
||||
|
||||
const invalidItem = this.dialog.items.find(item => {
|
||||
const amount = Number(item.reconcile) || 0;
|
||||
return amount < 0 || amount > Number(item.due);
|
||||
});
|
||||
if (invalidItem) return '沖帳金額超出可沖帳範圍';
|
||||
|
||||
if (this.sumReconcile > this.dialog.selected.check_amount) {
|
||||
return '已沖金額不可大於入帳金額';
|
||||
}
|
||||
|
||||
if (this.hasUnallocated && this.remainDue > 0) {
|
||||
return '尚有未繳項目,請將入帳金額完全分配';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadTableData();
|
||||
},
|
||||
filters: {
|
||||
currency(val) {
|
||||
if (!val) return '0';
|
||||
return Number(val).toLocaleString();
|
||||
},
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
const date = new Date(val);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 檢查是否有 DraftUtils 可用
|
||||
hasTransferDraft(draft) {
|
||||
return window.DraftUtils && window.DraftUtils.hasTransferDraft && window.DraftUtils.hasTransferDraft(draft);
|
||||
},
|
||||
// 使用全域 DraftUtils 工具函數
|
||||
showError(message) {
|
||||
this.dialog.errorMessage = message;
|
||||
},
|
||||
clearError() {
|
||||
this.dialog.errorMessage = '';
|
||||
},
|
||||
loadTableData() {
|
||||
this.loading = true;
|
||||
axios.get('../../api/transfer_register/personal_reconcile_list')
|
||||
.then(res => {
|
||||
this.items = res.data;
|
||||
})
|
||||
.catch(() => {
|
||||
this.items = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
showReconcileDialog(item) {
|
||||
this.dialog.selected = item;
|
||||
this.dialog.items = [];
|
||||
this.dialog.show = true;
|
||||
// 依 f_num 呼叫 API 取得訂單明細
|
||||
if (item.f_num) {
|
||||
axios.get('../../api/transfer_register/follower_orders', { params: { f_num: item.f_num } })
|
||||
.then(res => {
|
||||
this.dialog.items = res.data;
|
||||
this.loadFromDraftOrAutoDistribute();
|
||||
})
|
||||
.catch(() => {
|
||||
this.dialog.items = [];
|
||||
this.updateSumReconcile();
|
||||
});
|
||||
} else {
|
||||
this.dialog.items = [];
|
||||
this.updateSumReconcile();
|
||||
}
|
||||
},
|
||||
autoDistributeReconcile() {
|
||||
// 先進先出分配沖帳金額
|
||||
let remainAmount = this.dialog.selected ? this.dialog.selected.check_amount : 0;
|
||||
|
||||
// 先將所有項目的 reconcile 清為 0
|
||||
this.dialog.items.forEach(item => {
|
||||
this.$set(item, 'reconcile', 0);
|
||||
});
|
||||
|
||||
// 依報名日期排序(先進先出)
|
||||
const sortedItems = [...this.dialog.items].sort((a, b) =>
|
||||
new Date(a.reg_time) - new Date(b.reg_time)
|
||||
);
|
||||
|
||||
// 逐項分配
|
||||
sortedItems.forEach(item => {
|
||||
if (remainAmount > 0) {
|
||||
const canPay = Math.min(item.due, remainAmount);
|
||||
const originalItem = this.dialog.items.find(i => i === item);
|
||||
if (originalItem) {
|
||||
this.$set(originalItem, 'reconcile', canPay);
|
||||
}
|
||||
remainAmount -= canPay;
|
||||
}
|
||||
});
|
||||
|
||||
this.updateSumReconcile();
|
||||
},
|
||||
redistributeReconcile() {
|
||||
// 重新依先進先出原則分配沖帳金額
|
||||
this.autoDistributeReconcile();
|
||||
},
|
||||
updateSumReconcile() {
|
||||
// 只更新 hasUnallocated 狀態
|
||||
const maxTotal = this.dialog.selected ? (this.dialog.selected.check_amount || 0) : 0;
|
||||
this.hasUnallocated = maxTotal > this.sumReconcile;
|
||||
},
|
||||
loadFromDraftOrAutoDistribute() {
|
||||
const draft = this.dialog.selected ? this.dialog.selected.draft : null;
|
||||
|
||||
if (draft && draft.trim() && window.DraftUtils && window.DraftUtils.getDraftField) {
|
||||
const transferDraft = window.DraftUtils.getDraftField(draft, 'transfer_draft');
|
||||
if (transferDraft && Array.isArray(transferDraft)) {
|
||||
this.loadFromDraft(transferDraft);
|
||||
} else {
|
||||
this.autoDistributeReconcile();
|
||||
}
|
||||
} else {
|
||||
this.autoDistributeReconcile();
|
||||
}
|
||||
},
|
||||
loadFromDraft(draftData) {
|
||||
this.draftDataChanged = false;
|
||||
|
||||
// 先將所有項目的 reconcile 設為 0
|
||||
this.dialog.items.forEach(item => {
|
||||
this.$set(item, 'reconcile', 0);
|
||||
});
|
||||
|
||||
// 從 draft 資料填入沖帳金額
|
||||
draftData.forEach(draftItem => {
|
||||
const matchedItem = this.dialog.items.find(item =>
|
||||
item.num === draftItem.pro_order_detail_num
|
||||
);
|
||||
|
||||
if (matchedItem) {
|
||||
this.$set(matchedItem, 'reconcile', draftItem.reconcile || 0);
|
||||
} else {
|
||||
// 找不到對應的項目,標記資料已改動
|
||||
this.draftDataChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
this.updateSumReconcile();
|
||||
|
||||
// 如果有資料改動,提醒用戶
|
||||
if (this.draftDataChanged) {
|
||||
setTimeout(() => {
|
||||
alert('資料已改動,請注意金額一致性');
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
saveDraft() {
|
||||
try {
|
||||
// 組成新的 transfer_draft 資料
|
||||
const transferDraftData = this.dialog.items
|
||||
.filter(item => Number(item.reconcile) > 0)
|
||||
.map(item => ({
|
||||
pro_order_detail_num: item.num,
|
||||
reconcile: Number(item.reconcile)
|
||||
}));
|
||||
|
||||
// 使用工具函數安全地更新 draft 物件
|
||||
const currentDraft = this.dialog.selected.draft || '';
|
||||
let draftJson = '';
|
||||
|
||||
if (window.DraftUtils && window.DraftUtils.updateDraftField) {
|
||||
const newDraftObj = window.DraftUtils.updateDraftField(currentDraft, 'transfer_draft', transferDraftData);
|
||||
draftJson = JSON.stringify(newDraftObj);
|
||||
} else {
|
||||
// 如果 DraftUtils 不可用,使用簡單的格式
|
||||
draftJson = JSON.stringify({ transfer_draft: transferDraftData });
|
||||
}
|
||||
|
||||
// 更新 draft 欄位
|
||||
const updateData = {
|
||||
id: this.dialog.selected.id,
|
||||
activity_num: this.dialog.selected.activity_num,
|
||||
name: this.dialog.selected.name,
|
||||
phone: this.dialog.selected.phone,
|
||||
pay_type: this.dialog.selected.pay_type,
|
||||
account_last5: this.dialog.selected.account_last5,
|
||||
amount: this.dialog.selected.amount,
|
||||
pay_mode: this.dialog.selected.pay_mode,
|
||||
note: this.dialog.selected.note,
|
||||
proof_img: this.dialog.selected.proof_img,
|
||||
status: this.dialog.selected.status,
|
||||
f_num_match: this.dialog.selected.f_num_match,
|
||||
f_num: this.dialog.selected.f_num,
|
||||
acc_num: this.dialog.selected.acc_num,
|
||||
check_date: this.dialog.selected.check_date,
|
||||
check_amount: this.dialog.selected.check_amount,
|
||||
check_memo: this.dialog.selected.check_memo,
|
||||
check_status: this.dialog.selected.check_status,
|
||||
acc_kind: this.dialog.selected.acc_kind,
|
||||
member_num: this.dialog.selected.member_num,
|
||||
verify_time: this.dialog.selected.verify_time,
|
||||
verify_note: this.dialog.selected.verify_note,
|
||||
draft: draftJson // 更新 draft 欄位
|
||||
};
|
||||
|
||||
axios.put(`../../api/transfer_register/${this.dialog.selected.id}`, updateData)
|
||||
.then(() => {
|
||||
alert('暫存成功!');
|
||||
// 更新本地資料
|
||||
this.dialog.selected.draft = draftJson;
|
||||
})
|
||||
.catch(err => {
|
||||
alert('暫存失敗:' + (err.response?.data?.message || err.message));
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
alert('暫存失敗:資料格式錯誤');
|
||||
}
|
||||
},
|
||||
confirmReconcile() {
|
||||
if (!this.canConfirm) {
|
||||
this.showError(this.buttonErrorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dialog.loading = true;
|
||||
const over_payment = this.dialog.selected.check_amount - this.sumReconcile;
|
||||
const postData = {
|
||||
transfer_register_id: this.dialog.selected.id,
|
||||
details: this.dialog.items
|
||||
.filter(item => item.reconcile > 0)
|
||||
.map(item => ({
|
||||
pro_order_detail_num: item.num,
|
||||
amount: Number(item.reconcile),
|
||||
reg_time: new Date().toISOString(),
|
||||
demo: `${this.dialog.selected.check_memo || ''}`
|
||||
})),
|
||||
over_payment: over_payment
|
||||
};
|
||||
|
||||
axios.post('../../api/transfer_register/reconcile', postData)
|
||||
.then(res => {
|
||||
// 顯示成功訊息
|
||||
const message = res.data && res.data.message ? res.data.message : '沖帳完成';
|
||||
msgtop(message, 'success');
|
||||
|
||||
this.dialog.show = false;
|
||||
this.loadTableData(); // 重新載入清單
|
||||
})
|
||||
.catch(err => {
|
||||
let errorMessage = '沖帳失敗,請聯繫系統管理員';
|
||||
if (err.response && err.response.data) {
|
||||
if (typeof err.response.data === 'string') {
|
||||
errorMessage = err.response.data;
|
||||
} else if (err.response.data.message) {
|
||||
errorMessage = err.response.data.message;
|
||||
if (err.response.data.exceptionMessage) {
|
||||
errorMessage += `\\n${err.response.data.exceptionMessage}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
alert(errorMessage);
|
||||
})
|
||||
.finally(() => {
|
||||
this.dialog.loading = false;
|
||||
});
|
||||
},
|
||||
validateAndUpdateReconcile(value, item, index) {
|
||||
let numValue = Number(value);
|
||||
if (isNaN(numValue)) {
|
||||
numValue = 0;
|
||||
}
|
||||
numValue = Math.round(numValue);
|
||||
|
||||
this.$set(item, 'reconcile', numValue);
|
||||
this.updateSumReconcile();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-8 col-lg-6">
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-primary text-white text-center">
|
||||
<h4 class="mb-0">登錄匯款資料</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="transferForm" @submit.prevent="submitForm" enctype="multipart/form-data" autocomplete="off">
|
||||
<!-- 法會名稱 -->
|
||||
<div class="mb-3">
|
||||
<label for="activity_num" class="form-label">法會名稱 <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="activity_num" v-model="formData.activity_num" required>
|
||||
<option value="">請選擇</option>
|
||||
<option v-for="activity in activities" :key="activity.num" :value="activity.num">
|
||||
{{activity.subject}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- 姓名 -->
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">姓名 <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="name" v-model="formData.name" required maxlength="50" placeholder="請輸入姓名" @blur="onNameBlur">
|
||||
</div>
|
||||
<!-- 電話 -->
|
||||
<div class="mb-3">
|
||||
<label for="phone" class="form-label">電話 <span class="text-danger">*</span></label>
|
||||
<input type="tel" class="form-control" id="phone" v-model="formData.phone" required maxlength="30" placeholder="請輸入聯絡電話">
|
||||
</div>
|
||||
<!-- 支付方式 -->
|
||||
<div class="mb-3">
|
||||
<label for="pay_type" class="form-label">支付方式 <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="pay_type" v-model="formData.pay_type" required>
|
||||
<option value="">請選擇</option>
|
||||
<option v-for="(desc, value) in payTypes" :key="value" :value="value">
|
||||
{{desc}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- 帳號後五碼 -->
|
||||
<div class="mb-3">
|
||||
<label for="account_last5" class="form-label">帳號後五碼(若無免填)</label>
|
||||
<input type="text" class="form-control" id="account_last5" v-model="formData.account_last5" maxlength="10" placeholder="如有匯款請填寫">
|
||||
</div>
|
||||
<!-- 支付金額 -->
|
||||
<div class="mb-3">
|
||||
<label for="amount" class="form-label">支付金額 <span class="text-danger">*</span></label>
|
||||
<input type="number" class="form-control" id="amount" v-model="formData.amount" required min="1" step="1" placeholder="請輸入金額">
|
||||
</div>
|
||||
<!-- 支付型態 -->
|
||||
<div class="mb-3">
|
||||
<label class="form-label">支付型態 <span class="text-danger">*</span></label>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="pay_mode" id="pay_mode1" value="個人" v-model="formData.pay_mode" checked>
|
||||
<label class="form-check-label" for="pay_mode1">個人支付</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="pay_mode" id="pay_mode2" value="共同" v-model="formData.pay_mode">
|
||||
<label class="form-check-label" for="pay_mode2">共同支付</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 備註 -->
|
||||
<div class="mb-3">
|
||||
<label for="note" class="form-label">備註</label>
|
||||
<textarea class="form-control" id="note" v-model="formData.note" rows="2" maxlength="200" placeholder="如有分攤人名、金額、項目等請說明"></textarea>
|
||||
</div>
|
||||
<!-- 憑證上傳 -->
|
||||
<div class="mb-3">
|
||||
<label for="proof_img" class="form-label">上傳匯款憑證(可拍照)</label>
|
||||
<input class="form-control" type="file" id="proof_img" @change="handleFileUpload" accept="image/*" capture="environment">
|
||||
</div>
|
||||
<!-- 送出/關閉 -->
|
||||
<div class="d-grid gap-2">
|
||||
<button type="submit" class="btn btn-primary btn-lg" :disabled="isSubmitting || !canSubmit">
|
||||
{{ isSubmitting ? '處理中...' : '送出資料' }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary" @click="closeWindow">離開</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-3 text-muted small">
|
||||
<ul>
|
||||
<li>如一位組頭幫多人匯款,請在備註欄分拆明細(人名、金額、項目等)。</li>
|
||||
<li>送出後直接新增記錄,不顯示查核。</li>
|
||||
<li>如無姓名/電話資料,系統會提示。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
// 1. 移除 el: '#register'
|
||||
// 2. data 必須改成 function 形式
|
||||
data() {
|
||||
return {
|
||||
activities: [],
|
||||
formData: {
|
||||
activity_num: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
pay_type: '',
|
||||
account_last5: '',
|
||||
amount: '',
|
||||
pay_mode: '個人',
|
||||
note: '',
|
||||
proof_img: null
|
||||
},
|
||||
payTypes: {
|
||||
'1': '現金',
|
||||
'2': '匯款',
|
||||
'3': '支票'
|
||||
},
|
||||
isSubmitting: false,
|
||||
canSubmit: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.loadActivities();
|
||||
},
|
||||
methods: {
|
||||
loadActivities() {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
axios.get(`../../api/activity?endDate=${today}`)
|
||||
.then(response => {
|
||||
this.activities = response.data;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('載入活動列表失敗:', error);
|
||||
alert('載入活動列表失敗,請重新整理頁面');
|
||||
});
|
||||
},
|
||||
handleFileUpload(event) {
|
||||
this.formData.proof_img = event.target.files[0];
|
||||
},
|
||||
submitForm() {
|
||||
if (this.isSubmitting || !this.canSubmit) return;
|
||||
this.isSubmitting = true;
|
||||
|
||||
const formData = new FormData();
|
||||
Object.keys(this.formData).forEach(key => {
|
||||
if (this.formData[key] !== null) {
|
||||
formData.append(key, this.formData[key]);
|
||||
}
|
||||
});
|
||||
|
||||
axios.post('../../api/transfer_register', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
alert('資料已成功送出!');
|
||||
this.formData = {
|
||||
activity_num: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
pay_type: '',
|
||||
account_last5: '',
|
||||
amount: '',
|
||||
pay_mode: '個人',
|
||||
note: '',
|
||||
proof_img: null
|
||||
};
|
||||
this.canSubmit = false;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('送出失敗:', error);
|
||||
// 增加錯誤保護,避免 response.data.message 不存在時報錯
|
||||
const errorMsg = error.response && error.response.data && error.response.data.message
|
||||
? error.response.data.message
|
||||
: '請檢查網路連線或系統狀態';
|
||||
alert('送出失敗 :' + errorMsg);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isSubmitting = false;
|
||||
});
|
||||
},
|
||||
closeWindow() {
|
||||
// 3. 修正關閉邏輯:因為現在是開在 Dialog 裡,window.close() 關不掉
|
||||
// 改為觸發一個事件,通知父層 (index.aspx) 把彈跳視窗關掉
|
||||
this.$emit('close-dialog');
|
||||
},
|
||||
onNameBlur() {
|
||||
this.canSubmit = !!this.formData.name.trim();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,382 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h5 class="mb-0">帳務查詢</h5>
|
||||
<button class="btn btn-default ms-auto"><i class="mdi mdi-close"></i></button>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row class="mb-0 mt-4">
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="query.start_date" label="起始日" type="date" dense outlined></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="query.end_date" label="結束日" type="date" dense outlined></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<v-text-field v-model="query.activity_name" label="法會" dense outlined readonly>
|
||||
<template v-slot:append>
|
||||
<v-btn icon @click="showActivityDialog"><v-icon>mdi-magnify</v-icon></v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<v-text-field v-model="query.follower_name" label="信眾" dense outlined readonly>
|
||||
<template v-slot:append>
|
||||
<v-btn icon @click="showFollowerDialog"><v-icon>mdi-magnify</v-icon></v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2" class="d-flex justify-end">
|
||||
<v-btn color="primary" class="mr-2" @click="search">查詢</v-btn>
|
||||
<v-btn color="grey" @click="reset">重設</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1 verify-query-table"
|
||||
item-key="transfer_id"
|
||||
:footer-props="{ 'items-per-page-options': [10, 20, 50] }"
|
||||
:expanded.sync="expanded"
|
||||
show-expand>
|
||||
<template v-slot:item.follower="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.follower }}</div>
|
||||
<div class="caption text--secondary">{{ item.transfer_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.transfer_phone }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.activity_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.activity_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.acc_name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.transfer_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-primary">應收總額:{{ item.price_totals | currency }}</div>
|
||||
<div class="font-weight-bold text-primary">入帳金額:{{ item.transfer_check_amount | currency }}</div>
|
||||
<div class="text-success">沖帳日期:{{ item.transfer_check_date | date }}</div>
|
||||
<div v-if="item.transfer_remain_amount > 0" class="text-warning">
|
||||
剩餘金額:{{ item.transfer_remain_amount | currency }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.status_info="{ item }">
|
||||
<div>
|
||||
<v-chip small :color="getStatusColor(item.transfer_check_status)" text-color="white">
|
||||
{{ getStatusText(item.transfer_check_status) }}
|
||||
</v-chip>
|
||||
<div class="caption text--secondary mt-1">{{ item.transfer_check_memo }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn color="info" outlined small @click="showDetailDialog(item)">
|
||||
<v-icon small class="mr-1">mdi-information-outline</v-icon> 詳細
|
||||
</v-btn>
|
||||
</template>
|
||||
<template v-slot:expanded-item="{ headers, item }">
|
||||
<td :colspan="headers.length">
|
||||
<div class="pa-4">
|
||||
<h6 class="mb-3 text-primary">
|
||||
<v-icon color="primary" small class="mr-1">mdi-receipt</v-icon>
|
||||
沖帳明細
|
||||
</h6>
|
||||
<v-data-table :headers="detailHeaders"
|
||||
:items="item.pro_order_records"
|
||||
class="elevation-1"
|
||||
hide-default-footer
|
||||
:disable-pagination="true"
|
||||
dense>
|
||||
<template v-slot:item.order_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.pro_order_detail?.pro_order?.order_no }}</div>
|
||||
<div class="caption text--secondary">{{ item.pro_order_detail?.actitem_name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.payment_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.payment_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.bank_code }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.amount_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-success">{{ item.price | currency }}</div>
|
||||
<div class="caption text--secondary">{{ item.pay_date | date }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.memo="{ item }">
|
||||
<div style="white-space: pre-line;">{{ item.reconcile_memo }}</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<!-- 法會選取 Dialog -->
|
||||
<v-dialog v-model="activityDialog.show" max-width="700px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-table</v-icon>
|
||||
選擇法會
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="activityDialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<v-text-field v-model="activityDialog.search" label="搜尋法會" dense outlined @keyup.enter="searchActivity"></v-text-field>
|
||||
<v-data-table :headers="activityDialog.headers"
|
||||
:items="activityDialog.items"
|
||||
:loading="activityDialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1 mt-2"
|
||||
@click:row="selectActivity"
|
||||
hide-default-footer></v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 信眾選取 Dialog -->
|
||||
<v-dialog v-model="followerDialog.show" max-width="700px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-account</v-icon>
|
||||
選擇信眾
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="followerDialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<v-text-field v-model="followerDialog.search" label="搜尋信眾" dense outlined @keyup.enter="searchFollower"></v-text-field>
|
||||
<v-data-table :headers="followerDialog.headers"
|
||||
:items="followerDialog.items"
|
||||
:loading="followerDialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1 mt-2"
|
||||
@click:row="selectFollower"
|
||||
hide-default-footer></v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 詳細資訊對話框 -->
|
||||
<v-dialog v-model="dialog.show" max-width="900px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="info" class="mr-2">mdi-information-outline</v-icon>
|
||||
詳細資訊
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="dialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<div v-if="dialog.selected">
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-primary">匯款人資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">姓名:</span>{{ dialog.selected.transfer_name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">電話:</span>{{ dialog.selected.transfer_phone }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">信眾:</span>{{ dialog.selected.follower }}</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-success">入帳資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳帳戶:</span>{{ dialog.selected.acc_name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳日期:</span>{{ dialog.selected.transfer_check_date | date }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳金額:</span>{{ dialog.selected.transfer_check_amount | currency }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">應收總額:</span>{{ dialog.selected.price_totals | currency }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider class="my-4"></v-divider>
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-purple">活動資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">活動名稱:</span>{{ dialog.selected.activity_name || '-' }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">支付方式:</span>{{ payTypeText[dialog.selected.transfer_pay_type] || dialog.selected.transfer_pay_type }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">帳號後5碼:</span>{{ dialog.selected.transfer_account_last5 || '-' }}</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-info">核對記錄</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">核對記錄:</span>{{ dialog.selected.transfer_verify_note || '-' }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">帳簿備註:</span>{{ dialog.selected.transfer_check_memo || '-' }}</div>
|
||||
<div v-if="dialog.selected.transfer_proof_img" class="mb-2">
|
||||
<span class="font-weight-bold">證明圖片:</span>
|
||||
<a :href="'../../upload/transfer_proof/' + dialog.selected.transfer_proof_img" target="_blank">查看相片</a>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
expanded: [],
|
||||
query: {
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
activity_num: '',
|
||||
activity_name: '',
|
||||
follower_num: '',
|
||||
follower_name: ''
|
||||
},
|
||||
headers: [
|
||||
{ text: '信眾/匯款人', value: 'follower' },
|
||||
{ text: '法會/入帳帳戶', value: 'activity_info' },
|
||||
{ text: '入帳資訊', value: 'transfer_info' },
|
||||
{ text: '狀態/備註', value: 'status_info' },
|
||||
{ text: '操作', value: 'actions', sortable: false }
|
||||
],
|
||||
detailHeaders: [
|
||||
{ text: '訂單/項目', value: 'order_info' },
|
||||
{ text: '付款機構', value: 'payment_info' },
|
||||
{ text: '沖帳金額/日期', value: 'amount_info' },
|
||||
{ text: '備註', value: 'memo' }
|
||||
],
|
||||
items: [],
|
||||
dialog: {
|
||||
show: false,
|
||||
selected: null
|
||||
},
|
||||
activityDialog: {
|
||||
show: false,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '名稱', value: 'subject' }
|
||||
]
|
||||
},
|
||||
followerDialog: {
|
||||
show: false,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '姓名', value: 'u_name' }
|
||||
]
|
||||
},
|
||||
payTypeText: {
|
||||
1: '現金',
|
||||
2: '匯款',
|
||||
3: '支票'
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
currency(val) {
|
||||
if (!val) return '0';
|
||||
return Number(val).toLocaleString();
|
||||
},
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
const date = new Date(val);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.loading = true;
|
||||
// 串接查詢 API,帶入所有查詢條件
|
||||
axios.get('../../api/transfer_register/verify_order_record_query', { params: this.query })
|
||||
.then(res => {
|
||||
this.items = res.data;
|
||||
this.expanded = []; // 重置展開狀態
|
||||
})
|
||||
.catch(() => {
|
||||
this.items = [];
|
||||
this.expanded = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
reset() {
|
||||
this.query.start_date = '';
|
||||
this.query.end_date = '';
|
||||
this.query.activity_num = '';
|
||||
this.query.activity_name = '';
|
||||
this.query.follower_num = '';
|
||||
this.query.follower_name = '';
|
||||
this.items = [];
|
||||
this.expanded = [];
|
||||
},
|
||||
showDetailDialog(item) {
|
||||
this.dialog.selected = item;
|
||||
this.dialog.show = true;
|
||||
},
|
||||
showActivityDialog() {
|
||||
this.activityDialog.show = true;
|
||||
this.searchActivity();
|
||||
},
|
||||
searchActivity() {
|
||||
this.activityDialog.loading = true;
|
||||
axios.get('../../api/activity', { params: { keyword: this.activityDialog.search } })
|
||||
.then(res => { this.activityDialog.items = res.data; })
|
||||
.catch(() => { this.activityDialog.items = []; })
|
||||
.finally(() => { this.activityDialog.loading = false; });
|
||||
},
|
||||
selectActivity(row) {
|
||||
this.query.activity_num = row.num;
|
||||
this.query.activity_name = row.subject;
|
||||
this.activityDialog.show = false;
|
||||
},
|
||||
showFollowerDialog() {
|
||||
this.followerDialog.show = true;
|
||||
this.searchFollower();
|
||||
},
|
||||
searchFollower() {
|
||||
this.followerDialog.loading = true;
|
||||
axios.post('../..../..../../api/follower/GetList', { u_name: this.followerDialog.search }, { params: { page: 1, pageSize: 10 } })
|
||||
.then(res => { this.followerDialog.items = res.data.list; })
|
||||
.catch(() => { this.followerDialog.items = []; })
|
||||
.finally(() => { this.followerDialog.loading = false; });
|
||||
},
|
||||
selectFollower(row) {
|
||||
this.query.follower_num = row.num;
|
||||
this.query.follower_name = row.u_name;
|
||||
this.followerDialog.show = false;
|
||||
},
|
||||
getStatusColor(status) {
|
||||
switch (status) {
|
||||
case '90': return 'warning';
|
||||
case '99': return 'success';
|
||||
default: return 'grey';
|
||||
}
|
||||
},
|
||||
getStatusText(status) {
|
||||
switch (status) {
|
||||
case '90': return '沖帳有剩餘';
|
||||
case '99': return '沖帳完成';
|
||||
default: return '未知狀態';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.v-data-table.verify-query-table .v-data-table__wrapper tbody tr {
|
||||
min-height: 90px !important;
|
||||
height: 90px !important;
|
||||
}
|
||||
|
||||
.v-data-table.verify-query-table .v-data-table__wrapper tbody td {
|
||||
min-height: 90px !important;
|
||||
height: 90px !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="container-fluid">
|
||||
<v-card>
|
||||
<v-card-title class="bg-success white--text text-center">
|
||||
<h5 class="mb-0">統計報表</h5>
|
||||
<v-spacer></v-spacer>
|
||||
<!--<v-btn color="primary" @click="submitData">確認送出</v-btn>-->
|
||||
<v-btn color="primary" class="ml-2" @click="closeWindow">關閉</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="2" md="2">
|
||||
<v-select :items="category"
|
||||
label="統計分類"
|
||||
item-text="name"
|
||||
item-value="id" v-model="category_id">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="法會時間(起)" v-model="query.s_date"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="法會時間(迄)" v-model="query.e_date"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-btn @click.prevent="getRpt()" :disabled="isdisabled">
|
||||
匯出
|
||||
</v-btn>
|
||||
<img src="/admin/images/loading.gif" v-show="isloading"/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-dialog v-model="message_dialog.show" class="dialog_width">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ message_dialog.message }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="message_dialog.show=false" v-if="!message_dialog.show_confirm">關閉</v-btn>
|
||||
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
message_dialog: { show: false, show_confirm: false, message: "" },
|
||||
category: [
|
||||
{ id: "01", name: "依法會+功德項目", selected: "" },
|
||||
{ id: "02", name: "依信眾", selected: "" },
|
||||
{ id: "03", name: "依法會+信眾", selected: "" },
|
||||
],
|
||||
category_id: "",
|
||||
isdisabled: false,
|
||||
isloading: false,
|
||||
query: {s_date:"",e_date:""}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closeWindow() {
|
||||
this.$emit('close-dialog');
|
||||
},
|
||||
getRpt() {
|
||||
if (this.category_id == "") {
|
||||
this.message_dialog.message = "請選擇統計類型";
|
||||
this.message_dialog.show = true;
|
||||
return false;
|
||||
}
|
||||
const params = { statistic_mode: this.category_id }
|
||||
const search = {
|
||||
num: 0, kind: 0, kindName: "", order_no: "", u_name: "", pay_type: "", subject: "", amount: 0, price: 0, pay_mode: "", status: "",
|
||||
acc_num: 0, f_num: 0, acc_kind: 0, check_amount: 0, remain_amount: 0, check_status: "", actItem_num: 0, draft: "", d_nnum: 0
|
||||
}
|
||||
this.isdisabled = true;
|
||||
this.isloading = true;
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/statistics/GetStatistic', search, { params: params })
|
||||
.then(response => {
|
||||
if (response.data.result == "N") {
|
||||
this.message_dialog.message = response.data.message;
|
||||
this.message_dialog.show = true;
|
||||
} else if (response.data.result == "Y") {
|
||||
const link = document.createElement('a');
|
||||
link.href = HTTP_HOST + "/" + response.data.filename;
|
||||
link.target = "_blank";
|
||||
|
||||
// 5. Specify the filename for the download
|
||||
//link.setAttribute('download', 'my-downloaded-file.pdf');
|
||||
|
||||
// 6. Append link to the body, click it, and remove it immediately
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
// 7. Free up memory by revoking the object URL
|
||||
//window.URL.revokeObjectURL(blobUrl);
|
||||
//window.open(HTTP_HOST +"/" +response.data.filename, "_blank");
|
||||
}
|
||||
this.isdisabled = false;
|
||||
this.isloading = false;
|
||||
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.v-dialog {
|
||||
width: 80% !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,461 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-success white--text text-center">
|
||||
<h5 class="mb-0">出納核對匯款人</h5>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" @click="submitData">確認送出</v-btn>
|
||||
<v-btn color="primary" class="ml-2" @click="closeWindow">關閉</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1 mt-3"
|
||||
item-key="id"
|
||||
:expanded.sync="expanded"
|
||||
show-expand>
|
||||
<template v-slot:item.info="{ item }">
|
||||
<div>
|
||||
<div><span class="text-muted">姓名:</span>{{ item.name }}</div>
|
||||
<div><span class="text-muted">電話:</span>{{ item.phone }}</div>
|
||||
<div><span class="text-muted">法會:</span>{{ getActivityName(item.activity_num) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.f_num="{ item }">
|
||||
<span v-if="item.f_num && item.follower">
|
||||
<a :href="'/admin/follower/reg.aspx?num=' + item.follower.num"
|
||||
class="text-success"
|
||||
target="_blank">
|
||||
{{ item.follower.u_name }}(F{{ item.f_num }})
|
||||
</a>
|
||||
<div class="small text-muted">
|
||||
電話:{{ item.follower.phone }}<br>
|
||||
手機:{{ item.follower.cellphone }}
|
||||
</div>
|
||||
</span>
|
||||
<span v-else class="text-danger">未自動比對</span>
|
||||
</template>
|
||||
|
||||
<template v-slot:expanded-item="{ headers, item }">
|
||||
<td :colspan="headers.length">
|
||||
<div class="pa-4">
|
||||
<h6 class="mb-3 text-primary">
|
||||
<v-icon color="primary" small class="mr-1">mdi-receipt</v-icon>
|
||||
沖帳明細
|
||||
</h6>
|
||||
<v-container>
|
||||
<v-row class="font-weight-bold grey--text text--darken-2">
|
||||
<v-col>*入帳銀行/帳戶 | 支付資訊/帳號後5碼</v-col>
|
||||
<v-col>*入帳日期</v-col>
|
||||
<v-col>*入帳金額</v-col>
|
||||
<v-col>*收支項目</v-col>
|
||||
<!--<v-col>備註/狀態 | 核對記錄</v-col>-->
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<div class="mb-2">
|
||||
<span class="badge bg-primary me-1" title="支付方式">{{ payTypeText[item.pay_type] || item.pay_type }}</span>
|
||||
<span class="badge bg-secondary" title="型態:個人/共同">{{ item.pay_mode }}</span>
|
||||
<span class="font-weight-bold text-primary" title="帳號後5碼">{{ item.account_last5 }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<v-select :items="bankOptions"
|
||||
v-model="item.acc_num"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
style="max-width: 200px"></v-select>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<div class="mb-2">
|
||||
<span class="text-muted small">登記日期:</span>
|
||||
<span class="font-weight-bold error--text"
|
||||
style="cursor:pointer"
|
||||
@click="$set(item, 'check_date', item.create_time ? item.create_time.split('T')[0] : '')"
|
||||
title="點擊帶入日期">
|
||||
{{ item.create_time | date }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<v-text-field v-model="item.check_date"
|
||||
type="date"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
style="max-width: 140px"></v-text-field>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<div class="mb-2">
|
||||
<span class="text-muted small">金額:</span>
|
||||
<span class="font-weight-bold error--text"
|
||||
style="cursor:pointer"
|
||||
@click="$set(item, 'check_amount', item.amount)"
|
||||
title="點擊帶入金額">
|
||||
{{ item.amount | currency }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<v-text-field v-model="item.check_amount"
|
||||
type="number"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
style="max-width: 100px"></v-text-field>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<div class="mb-2">
|
||||
<span class="badge bg-primary me-1" title="支付方式">收支項目</span>
|
||||
</div>
|
||||
<div>
|
||||
<v-select :items="accountingKinds"
|
||||
v-model="item.kind"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
style="max-width: 200px"></v-select>
|
||||
</div>
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn small outlined color="primary" @click="openFollowerDialog(item)">選擇信眾</v-btn>
|
||||
</template>
|
||||
<template v-slot:item.check_memo="{ item }">
|
||||
<div class="d-flex align-center my-2" style="min-width: 300px">
|
||||
<v-text-field v-model="item.check_memo"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
class="mr-2"
|
||||
style="width: 180px"
|
||||
placeholder="帳簿備註"></v-text-field>
|
||||
<v-select :items="checkStatusOptions"
|
||||
v-model="item.check_status"
|
||||
item-text="text"
|
||||
item-value="value"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
style="width: 110px"
|
||||
:menu-props="{ contentClass: 'mini-dropdown', maxHeight: 200 }"></v-select>
|
||||
</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-dialog v-model="follower_dialog.show" max-width="800px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
選擇信眾
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="follower_dialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="pt-4">
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-text-field v-model="follower_dialog.search"
|
||||
label="搜尋信眾 (按 Enter 搜尋)"
|
||||
prepend-icon="mdi-magnify"
|
||||
@keyup.enter="searchFollowers"
|
||||
clearable></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-data-table :headers="follower_dialog.headers"
|
||||
:items="follower_dialog.items"
|
||||
:loading="follower_dialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1"
|
||||
@click:row="selectFollower">
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn small color="primary" @click.stop="selectFollower(item)">
|
||||
選擇
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
|
||||
<v-snackbar v-model="snackbar.show" :timeout="3000" top color="error">
|
||||
{{ snackbar.text }}
|
||||
<template v-slot:action="{ attrs }">
|
||||
<v-btn dark text v-bind="attrs" @click="snackbar.show = false">關閉</v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
// 【修正點3】補上 snackbar 的資料定義
|
||||
snackbar: {
|
||||
show: false,
|
||||
text: ''
|
||||
},
|
||||
headers: [
|
||||
{ text: '匯款人資訊', value: 'info' },
|
||||
{ text: '對應信眾', value: 'f_num' },
|
||||
{ text: '選擇信眾', value: 'actions', sortable: false },
|
||||
{ text: '備註/狀態 | 核對記錄', value: 'check_memo' }
|
||||
//{ text: '狀態 | 核對記錄', value: 'status' },
|
||||
],
|
||||
// detailHeaders 可保留供其他地方參考,但不應放入 expanded 插槽變數中
|
||||
detailHeaders: [
|
||||
{ text: '匯款人資訊', value: 'info' },
|
||||
{ text: '匯款備註/相片', value: 'note' },
|
||||
{ text: '*入帳銀行/帳戶 | 支付資訊/帳號後5碼', value: 'acc_num' },
|
||||
{ text: '*入帳日期', value: 'check_date' },
|
||||
{ text: '*入帳金額', value: 'check_amount' },
|
||||
{ text: '*收支項目', value: 'kind' },
|
||||
{ text: '備註/狀態 | 核對記錄', value: 'check_memo' }
|
||||
],
|
||||
items: [],
|
||||
bankOptions: [],
|
||||
accountingKinds: [],
|
||||
checkStatusOptions: [
|
||||
{ text: '', value: '' },
|
||||
{ text: '未核對', value: '1' },
|
||||
{ text: '核對', value: '2' },
|
||||
{ text: '金額不符', value: '3' },
|
||||
{ text: '其他問題', value: '4' },
|
||||
{ text: '作廢', value: '5' }
|
||||
],
|
||||
payTypeText: {
|
||||
1: '現金',
|
||||
2: '匯款',
|
||||
3: '支票'
|
||||
},
|
||||
activities: [],
|
||||
expanded: [],
|
||||
loading: false,
|
||||
statusOptions: [
|
||||
{ text: '', value: '' },
|
||||
{ text: '待確認', value: '1' },
|
||||
{ text: '確認', value: '2' },
|
||||
{ text: '作廢', value: '3' }
|
||||
],
|
||||
follower_dialog: {
|
||||
show: false,
|
||||
loading: false,
|
||||
search: '',
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '姓名', value: 'u_name' },
|
||||
{ text: '地址', value: 'address' },
|
||||
// 【修正點2】補上操作欄位定義,這樣按鈕才出得來
|
||||
{ text: '操作', value: 'actions', sortable: false }
|
||||
],
|
||||
items: [],
|
||||
selected: null,
|
||||
current_item: null
|
||||
}
|
||||
};
|
||||
},
|
||||
filters: {
|
||||
currency(val) {
|
||||
if (!val) return '';
|
||||
return Number(val).toLocaleString();
|
||||
},
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
return val.split('T')[0];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getActivityName(num) {
|
||||
const act = this.activities.find(a => a.num === num);
|
||||
return act ? act.subject : '';
|
||||
},
|
||||
openFollowerDialog(item) {
|
||||
this.follower_dialog.current_item = item;
|
||||
this.follower_dialog.show = true;
|
||||
// 若開啟時已有關鍵字,可以自動帶入搜尋
|
||||
// this.searchFollowers();
|
||||
},
|
||||
async searchFollowers() {
|
||||
if (!this.follower_dialog.search) return;
|
||||
|
||||
this.follower_dialog.loading = true;
|
||||
try {
|
||||
const response = await axios.post(HTTP_HOST + 'api/follower/GetList', {
|
||||
f_number: this.follower_dialog.search,
|
||||
u_name: this.follower_dialog.search
|
||||
}, {
|
||||
params: {
|
||||
page: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
});
|
||||
this.follower_dialog.items = response.data.list || [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching followers:', error);
|
||||
this.snackbar.text = "查詢信眾失敗,請確認網路或 API 狀態";
|
||||
this.snackbar.show = true;
|
||||
} finally {
|
||||
this.follower_dialog.loading = false;
|
||||
}
|
||||
},
|
||||
async selectFollower(follower) {
|
||||
if (this.follower_dialog.current_item) {
|
||||
try {
|
||||
this.follower_dialog.show = false;
|
||||
|
||||
const selectedFollower = this.follower_dialog.items.find(item => item.num === follower.num);
|
||||
|
||||
if (selectedFollower) {
|
||||
this.follower_dialog.current_item.f_num = follower.num;
|
||||
this.follower_dialog.current_item.follower = {
|
||||
num: selectedFollower.num,
|
||||
u_name: selectedFollower.u_name,
|
||||
address: selectedFollower.address || '',
|
||||
phone: selectedFollower.phoneDes || '',
|
||||
cellphone: selectedFollower.cellphoneDes || ''
|
||||
};
|
||||
} else {
|
||||
throw new Error('找不到信眾詳細資料');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('取得信眾詳細資料失敗:', error);
|
||||
this.snackbar.text = '取得信眾詳細資料失敗,請重試';
|
||||
this.snackbar.show = true;
|
||||
|
||||
this.follower_dialog.current_item.f_num = follower.num;
|
||||
this.follower_dialog.current_item.follower = {
|
||||
num: follower.num,
|
||||
u_name: follower.u_name,
|
||||
address: follower.address || '',
|
||||
phone: '',
|
||||
cellphone: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
async loadData() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const actRes = await axios.get('../../api/activity');
|
||||
this.activities = actRes.data;
|
||||
|
||||
const res = await axios.get('../../api/transfer_register/pending');
|
||||
this.items = res.data.map(item => ({
|
||||
...item,
|
||||
status: item.status ? String(item.status) : ''
|
||||
}));
|
||||
|
||||
const bankRes = await axios.post('../../api/accounting/GetAccountKindList', {}, { params: { page: 1, pageSize: 1000 } });
|
||||
this.bankOptions = bankRes.data.list.map(x => ({
|
||||
text: x.kind + (x.bank_name ? ' - ' + x.bank_name : '') + (x.bank_id ? ' (' + x.bank_id + ')' : ''),
|
||||
value: x.num
|
||||
}));
|
||||
|
||||
const kindRes = await axios.post('../../api/accounting/GetTitleKindList', {}, { params: { page: 1, pageSize: 1000 } });
|
||||
this.accountingKinds = kindRes.data.list.map(x => ({
|
||||
text: x.kind,
|
||||
value: x.num
|
||||
}));
|
||||
} catch (e) {
|
||||
console.error('載入資料失敗:', e);
|
||||
this.snackbar.text = '載入資料失敗';
|
||||
this.snackbar.show = true;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async saveData() {
|
||||
const updateList = this.items.map(item => ({
|
||||
id: item.id,
|
||||
f_num: item.f_num,
|
||||
status: item.status ? String(item.status) : '',
|
||||
verify_note: item.verify_note
|
||||
// 備註:依您的原本邏輯,這裡並未傳送 check_date, check_amount 等欄位,若後端 API 需要這些沖帳資訊,請在這裡一併補上。
|
||||
}));
|
||||
|
||||
try {
|
||||
const res = await axios.post('../../api/transfer_register/batch_update', updateList);
|
||||
if (res.data && res.data.success) {
|
||||
alert('儲存成功!');
|
||||
await this.loadData();
|
||||
} else {
|
||||
alert('儲存失敗,請重試!!');
|
||||
}
|
||||
} catch (e) {
|
||||
alert('儲存失敗,請重試:' + e.message);
|
||||
}
|
||||
},
|
||||
async submitData() {
|
||||
// 檢查必填欄位 - 入帳銀行/帳戶
|
||||
const missingAccNum = this.items.filter(item => !item.acc_num);
|
||||
if (missingAccNum.length > 0) {
|
||||
alert('請選擇入帳銀行/帳戶!有 ' + missingAccNum.length + ' 筆資料未選擇。');
|
||||
return;
|
||||
}
|
||||
|
||||
// 檢查必填欄位 - 入帳日期
|
||||
const missingCheckDate = this.items.filter(item => !item.check_date);
|
||||
if (missingCheckDate.length > 0) {
|
||||
alert('請填寫入帳日期!有 ' + missingCheckDate.length + ' 筆資料未填寫。');
|
||||
return;
|
||||
}
|
||||
|
||||
// 檢查必填欄位 - 入帳金額
|
||||
const missingCheckAmount = this.items.filter(item => !item.check_amount || item.check_amount <= 0);
|
||||
if (missingCheckAmount.length > 0) {
|
||||
alert('請填寫入帳金額!有 ' + missingCheckAmount.length + ' 筆資料未填寫或金額無效。');
|
||||
return;
|
||||
}
|
||||
|
||||
// 組出要更新的資料
|
||||
const updateList = this.items.map(item => ({
|
||||
id: item.id,
|
||||
f_num: item.f_num,
|
||||
status: '2',
|
||||
check_status: item.check_status ? String(item.check_status) : '',
|
||||
verify_note: item.verify_note,
|
||||
acc_num: item.acc_num,
|
||||
check_date: item.check_date,
|
||||
check_amount: item.check_amount,
|
||||
check_memo: item.check_memo,
|
||||
kind: item.kind,
|
||||
verify_note: item.verify_note
|
||||
}));
|
||||
try {
|
||||
const res = await axios.post('../../api/transfer_register/batch_update', updateList);
|
||||
if (res.data && res.data.success) {
|
||||
alert('送出成功!');
|
||||
// 重新載入資料
|
||||
await this.loadData();
|
||||
} else {
|
||||
alert('送出失敗,請重試 :' + res.data.message);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('送出失敗:', e);
|
||||
alert('送出失敗,請再試一次!');
|
||||
}
|
||||
},
|
||||
closeWindow() {
|
||||
this.$emit('close-dialog');
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadData();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,382 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h5 class="mb-0">沖帳查詢</h5>
|
||||
<button class="btn btn-default ms-auto"><i class="mdi mdi-close"></i></button>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row class="mb-0 mt-4">
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="query.start_date" label="起始日" type="date" dense outlined></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="query.end_date" label="結束日" type="date" dense outlined></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<v-text-field v-model="query.activity_name" label="法會" dense outlined readonly>
|
||||
<template v-slot:append>
|
||||
<v-btn icon @click="showActivityDialog"><v-icon>mdi-magnify</v-icon></v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="3">
|
||||
<v-text-field v-model="query.follower_name" label="信眾" dense outlined readonly>
|
||||
<template v-slot:append>
|
||||
<v-btn icon @click="showFollowerDialog"><v-icon>mdi-magnify</v-icon></v-btn>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2" class="d-flex justify-end">
|
||||
<v-btn color="primary" class="mr-2" @click="search">查詢</v-btn>
|
||||
<v-btn color="grey" @click="reset">重設</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-data-table :headers="headers"
|
||||
:items="items"
|
||||
:loading="loading"
|
||||
loading-text="載入中..."
|
||||
class="elevation-1 verify-query-table"
|
||||
item-key="transfer_id"
|
||||
:footer-props="{ 'items-per-page-options': [10, 20, 50] }"
|
||||
:expanded.sync="expanded"
|
||||
show-expand>
|
||||
<template v-slot:item.follower="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.follower }}</div>
|
||||
<div class="caption text--secondary">{{ item.transfer_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.transfer_phone }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.activity_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.activity_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.acc_name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.transfer_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-primary">應收總額:{{ item.price_totals | currency }}</div>
|
||||
<div class="font-weight-bold text-primary">入帳金額:{{ item.transfer_check_amount | currency }}</div>
|
||||
<div class="text-success">沖帳日期:{{ item.transfer_check_date | date }}</div>
|
||||
<div v-if="item.transfer_remain_amount > 0" class="text-warning">
|
||||
剩餘金額:{{ item.transfer_remain_amount | currency }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.status_info="{ item }">
|
||||
<div>
|
||||
<v-chip small :color="getStatusColor(item.transfer_check_status)" text-color="white">
|
||||
{{ getStatusText(item.transfer_check_status) }}
|
||||
</v-chip>
|
||||
<div class="caption text--secondary mt-1">{{ item.transfer_check_memo }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn color="info" outlined small @click="showDetailDialog(item)">
|
||||
<v-icon small class="mr-1">mdi-information-outline</v-icon> 詳細
|
||||
</v-btn>
|
||||
</template>
|
||||
<template v-slot:expanded-item="{ headers, item }">
|
||||
<td :colspan="headers.length">
|
||||
<div class="pa-4">
|
||||
<h6 class="mb-3 text-primary">
|
||||
<v-icon color="primary" small class="mr-1">mdi-receipt</v-icon>
|
||||
沖帳明細
|
||||
</h6>
|
||||
<v-data-table :headers="detailHeaders"
|
||||
:items="item.pro_order_records"
|
||||
class="elevation-1"
|
||||
hide-default-footer
|
||||
:disable-pagination="true"
|
||||
dense>
|
||||
<template v-slot:item.order_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.pro_order_detail?.pro_order?.order_no }}</div>
|
||||
<div class="caption text--secondary">{{ item.pro_order_detail?.actitem_name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.payment_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold">{{ item.payment_name }}</div>
|
||||
<div class="caption text--secondary">{{ item.bank_code }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.amount_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-success">{{ item.price | currency }}</div>
|
||||
<div class="caption text--secondary">{{ item.pay_date | date }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.memo="{ item }">
|
||||
<div style="white-space: pre-line;">{{ item.reconcile_memo }}</div>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</div>
|
||||
</td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<!-- 法會選取 Dialog -->
|
||||
<v-dialog v-model="activityDialog.show" max-width="700px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-table</v-icon>
|
||||
選擇法會
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="activityDialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<v-text-field v-model="activityDialog.search" label="搜尋法會" dense outlined @keyup.enter="searchActivity"></v-text-field>
|
||||
<v-data-table :headers="activityDialog.headers"
|
||||
:items="activityDialog.items"
|
||||
:loading="activityDialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1 mt-2"
|
||||
@click:row="selectActivity"
|
||||
hide-default-footer></v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 信眾選取 Dialog -->
|
||||
<v-dialog v-model="followerDialog.show" max-width="700px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="primary" class="mr-2">mdi-account</v-icon>
|
||||
選擇信眾
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="followerDialog.show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text class="mt-4">
|
||||
<v-text-field v-model="followerDialog.search" label="搜尋信眾" dense outlined @keyup.enter="searchFollower"></v-text-field>
|
||||
<v-data-table :headers="followerDialog.headers"
|
||||
:items="followerDialog.items"
|
||||
:loading="followerDialog.loading"
|
||||
item-key="num"
|
||||
class="elevation-1 mt-2"
|
||||
@click:row="selectFollower"
|
||||
hide-default-footer></v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 詳細資訊對話框 -->
|
||||
<v-dialog v-model="dialog.show" max-width="900px">
|
||||
<v-card>
|
||||
<v-card-title class="grey lighten-2">
|
||||
<v-icon color="info" class="mr-2">mdi-information-outline</v-icon>
|
||||
詳細資訊
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="dialog.show = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<div v-if="dialog.selected">
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-primary">匯款人資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">姓名:</span>{{ dialog.selected.transfer_name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">電話:</span>{{ dialog.selected.transfer_phone }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">信眾:</span>{{ dialog.selected.follower }}</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-success">入帳資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳帳戶:</span>{{ dialog.selected.acc_name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳日期:</span>{{ dialog.selected.transfer_check_date | date }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳金額:</span>{{ dialog.selected.transfer_check_amount | currency }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">應收總額:</span>{{ dialog.selected.price_totals | currency }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider class="my-4"></v-divider>
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-purple">活動資訊</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">活動名稱:</span>{{ dialog.selected.activity_name || '-' }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">支付方式:</span>{{ payTypeText[dialog.selected.transfer_pay_type] || dialog.selected.transfer_pay_type }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">帳號後5碼:</span>{{ dialog.selected.transfer_account_last5 || '-' }}</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<h6 class="mb-3 text-info">核對記錄</h6>
|
||||
<div class="mb-2"><span class="font-weight-bold">核對記錄:</span>{{ dialog.selected.transfer_verify_note || '-' }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">帳簿備註:</span>{{ dialog.selected.transfer_check_memo || '-' }}</div>
|
||||
<div v-if="dialog.selected.transfer_proof_img" class="mb-2">
|
||||
<span class="font-weight-bold">證明圖片:</span>
|
||||
<a :href="'../../upload/transfer_proof/' + dialog.selected.transfer_proof_img" target="_blank">查看相片</a>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-container>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
expanded: [],
|
||||
query: {
|
||||
start_date: '',
|
||||
end_date: '',
|
||||
activity_num: '',
|
||||
activity_name: '',
|
||||
follower_num: '',
|
||||
follower_name: ''
|
||||
},
|
||||
headers: [
|
||||
{ text: '信眾/匯款人', value: 'follower' },
|
||||
{ text: '法會/入帳帳戶', value: 'activity_info' },
|
||||
{ text: '入帳資訊', value: 'transfer_info' },
|
||||
{ text: '狀態/備註', value: 'status_info' },
|
||||
{ text: '操作', value: 'actions', sortable: false }
|
||||
],
|
||||
detailHeaders: [
|
||||
{ text: '訂單/項目', value: 'order_info' },
|
||||
{ text: '付款機構', value: 'payment_info' },
|
||||
{ text: '沖帳金額/日期', value: 'amount_info' },
|
||||
{ text: '備註', value: 'memo' }
|
||||
],
|
||||
items: [],
|
||||
dialog: {
|
||||
show: false,
|
||||
selected: null
|
||||
},
|
||||
activityDialog: {
|
||||
show: false,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '名稱', value: 'subject' }
|
||||
]
|
||||
},
|
||||
followerDialog: {
|
||||
show: false,
|
||||
search: '',
|
||||
loading: false,
|
||||
items: [],
|
||||
headers: [
|
||||
{ text: '編號', value: 'num' },
|
||||
{ text: '姓名', value: 'u_name' }
|
||||
]
|
||||
},
|
||||
payTypeText: {
|
||||
1: '現金',
|
||||
2: '匯款',
|
||||
3: '支票'
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
currency(val) {
|
||||
if (!val) return '0';
|
||||
return Number(val).toLocaleString();
|
||||
},
|
||||
date(val) {
|
||||
if (!val) return '';
|
||||
const date = new Date(val);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.loading = true;
|
||||
// 串接查詢 API,帶入所有查詢條件
|
||||
axios.get('../../api/transfer_register/verify_order_record_query', { params: this.query })
|
||||
.then(res => {
|
||||
this.items = res.data;
|
||||
this.expanded = []; // 重置展開狀態
|
||||
})
|
||||
.catch(() => {
|
||||
this.items = [];
|
||||
this.expanded = [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
reset() {
|
||||
this.query.start_date = '';
|
||||
this.query.end_date = '';
|
||||
this.query.activity_num = '';
|
||||
this.query.activity_name = '';
|
||||
this.query.follower_num = '';
|
||||
this.query.follower_name = '';
|
||||
this.items = [];
|
||||
this.expanded = [];
|
||||
},
|
||||
showDetailDialog(item) {
|
||||
this.dialog.selected = item;
|
||||
this.dialog.show = true;
|
||||
},
|
||||
showActivityDialog() {
|
||||
this.activityDialog.show = true;
|
||||
this.searchActivity();
|
||||
},
|
||||
searchActivity() {
|
||||
this.activityDialog.loading = true;
|
||||
axios.get('../../api/activity', { params: { keyword: this.activityDialog.search } })
|
||||
.then(res => { this.activityDialog.items = res.data; })
|
||||
.catch(() => { this.activityDialog.items = []; })
|
||||
.finally(() => { this.activityDialog.loading = false; });
|
||||
},
|
||||
selectActivity(row) {
|
||||
this.query.activity_num = row.num;
|
||||
this.query.activity_name = row.subject;
|
||||
this.activityDialog.show = false;
|
||||
},
|
||||
showFollowerDialog() {
|
||||
this.followerDialog.show = true;
|
||||
this.searchFollower();
|
||||
},
|
||||
searchFollower() {
|
||||
this.followerDialog.loading = true;
|
||||
axios.post('../..../..../../api/follower/GetList', { u_name: this.followerDialog.search }, { params: { page: 1, pageSize: 10 } })
|
||||
.then(res => { this.followerDialog.items = res.data.list; })
|
||||
.catch(() => { this.followerDialog.items = []; })
|
||||
.finally(() => { this.followerDialog.loading = false; });
|
||||
},
|
||||
selectFollower(row) {
|
||||
this.query.follower_num = row.num;
|
||||
this.query.follower_name = row.u_name;
|
||||
this.followerDialog.show = false;
|
||||
},
|
||||
getStatusColor(status) {
|
||||
switch (status) {
|
||||
case '90': return 'warning';
|
||||
case '99': return 'success';
|
||||
default: return 'grey';
|
||||
}
|
||||
},
|
||||
getStatusText(status) {
|
||||
switch (status) {
|
||||
case '90': return '沖帳有剩餘';
|
||||
case '99': return '沖帳完成';
|
||||
default: return '未知狀態';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.v-data-table.verify-query-table .v-data-table__wrapper tbody tr {
|
||||
min-height: 90px !important;
|
||||
height: 90px !important;
|
||||
}
|
||||
|
||||
.v-data-table.verify-query-table .v-data-table__wrapper tbody td {
|
||||
min-height: 90px !important;
|
||||
height: 90px !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
</style>
|
||||
@@ -260,7 +260,7 @@ public partial class admin_follower_import : MyWeb.config
|
||||
follower.introducer = ValString(sheet.Cells[currentRow, 17].Text.Trim());
|
||||
|
||||
//檢查國籍代碼是否存在
|
||||
var country = _country.Where(x => x.name_zh == ValString(sheet.Cells[currentRow, 18].Text.Trim())).FirstOrDefault();
|
||||
var country = _country.Where(x => x.name_zh == ValString(sheet.Cells[currentRow, 18].Text.Trim())).FirstOrDefault();
|
||||
if(country != null)
|
||||
{
|
||||
//follower.country = ValString(sheet.Cells[currentRow, 18].Text.Trim());
|
||||
|
||||
+146
-20
@@ -13,10 +13,12 @@
|
||||
<a @click="print_dialog.show=true" class="btn btn-outline-primary btn-print" target="_blank">
|
||||
<i class="mdi mdi-printer"></i>列印管理報表
|
||||
</a>
|
||||
<a @click="goPrint" class="btn btn-outline-primary btn-print" target="_blank">
|
||||
<a @click="goPrint" class="btn btn-outline-primary btn-print" :class="{ 'disabled': data_table.list.length === 0 }" target="_blank">
|
||||
<i class="mdi mdi-printer"></i>列印查詢資料
|
||||
</a>
|
||||
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
|
||||
<div :style="data_table.list.length === 0 ? 'pointer-events: none; opacity: 0.5;' : ''" style="display:inline-block;">
|
||||
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="export_Click"><span class="fa-solid fa-file-excel"></span> 匯出查詢資料(Excel)</asp:LinkButton>
|
||||
</div>
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
||||
@@ -24,11 +26,13 @@
|
||||
Vue.filter('timeString', function (value, myFormat) {
|
||||
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
|
||||
});
|
||||
let VueApp=new Vue({
|
||||
let VueApp = new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(vuetify_options),
|
||||
data() {
|
||||
return {
|
||||
isSearched: false,
|
||||
print_error_msg: '',
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
data_table: {
|
||||
@@ -38,10 +42,10 @@
|
||||
singleSelect: false,
|
||||
count: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 10,
|
||||
header: [
|
||||
{ text: '信眾編號', value: 'f_number', align: 'start' },
|
||||
{ text: '信眾姓名', value: 'u_name'},
|
||||
{ text: '信眾姓名', value: 'u_name' },
|
||||
{ text: '身分別', value: 'identity_type_desc' },
|
||||
{ text: '性別', value: 'sex' },
|
||||
{ text: '生日', value: 'birthday' },
|
||||
@@ -49,9 +53,9 @@
|
||||
{ text: '', value: 'slot', sortable: false },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' },
|
||||
],
|
||||
footer:{
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
pageSizeOptions:[5,10,20,30],
|
||||
pageSizeOptions: [5, 10, 20, 30],
|
||||
},
|
||||
},
|
||||
search: {
|
||||
@@ -60,7 +64,7 @@
|
||||
sex: '',
|
||||
//birthday: new Date().toISOString().split('T')[0],
|
||||
//birthday2: new Date().toISOString().split('T')[0]
|
||||
birthday:'',
|
||||
birthday: '',
|
||||
birthday2: '',
|
||||
address: '',
|
||||
country: '',
|
||||
@@ -69,14 +73,14 @@
|
||||
/*注意這邊的參數不能跟下方print_search重複*/
|
||||
},
|
||||
//列印管理報表
|
||||
print_conditions:'yy',
|
||||
print_conditions: 'yy',
|
||||
print_search: {
|
||||
year: '',
|
||||
month: '',
|
||||
season: '',
|
||||
season: '',
|
||||
},
|
||||
select_items: {
|
||||
month: [{
|
||||
month: [{
|
||||
text: "請選擇",
|
||||
val: 0
|
||||
},],
|
||||
@@ -126,13 +130,18 @@
|
||||
itemsPerPageText: '',
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler() {
|
||||
this.getList()
|
||||
handler() {
|
||||
if (this.isSearched) {
|
||||
this.getList()
|
||||
}
|
||||
else {
|
||||
this.data_table.loading = false;
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
@@ -141,23 +150,101 @@
|
||||
this.search_get()
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
}, mounted() {
|
||||
}
|
||||
}, mounted() {
|
||||
const printResult = document.getElementById('<%= hid_err_msg.ClientID %>').value;
|
||||
document.getElementById('<%= hid_err_msg.ClientID %>').value = '';
|
||||
window._printResult = printResult
|
||||
|
||||
this.search_dialog.current = this.search_dialog.controls.search1 ///default
|
||||
this.initPrintSearch();
|
||||
|
||||
const navEntries = performance.getEntriesByType("navigation");
|
||||
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
let params = url.searchParams;
|
||||
if (params.get('dirty') === '1') { // 資料有更新時執行 getlist
|
||||
this.search = JSON.parse(sessionStorage.getItem("member_query_params"));
|
||||
this.getList();
|
||||
|
||||
params.delete('dirty');
|
||||
window.history.replaceState({}, '', url.pathname + url.search);
|
||||
}
|
||||
|
||||
if (isReload) {
|
||||
sessionStorage.removeItem("followerpage");
|
||||
sessionStorage.removeItem("member_list_cache");
|
||||
sessionStorage.removeItem("member_query_params");
|
||||
}
|
||||
else if ("<%=lastAddedID%>" !== "") {
|
||||
const newQuery = { f_number: '<%=lastAddedID%>' };
|
||||
sessionStorage.setItem('member_query_params', JSON.stringify(newQuery));
|
||||
this.search = newQuery;
|
||||
this.isSearched = true;
|
||||
}
|
||||
else {
|
||||
const savedPage = parseInt(sessionStorage.getItem('followerpage'));
|
||||
const savedData = sessionStorage.getItem("member_list_cache");
|
||||
const savedQuery = JSON.parse(sessionStorage.getItem("member_query_params"));
|
||||
if (savedQuery) {
|
||||
this.search = savedQuery;
|
||||
this.isSearched = true;
|
||||
}
|
||||
if (savedPage) {
|
||||
this.options.page = savedPage;
|
||||
}
|
||||
if (savedData && savedData !== "undefined") {
|
||||
this.data_table = JSON.parse(savedData);
|
||||
this.isSearched = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (printResult === 'nodata' || printResult === 'success') {
|
||||
this.$nextTick(() => {
|
||||
this.print_search.year = parseInt(document.getElementById('<%= hid_print_year.ClientID %>').value) || this.print_search.year;
|
||||
this.print_search.month = parseInt(document.getElementById('<%= hid_print_month.ClientID %>').value) || this.print_search.month;
|
||||
this.print_search.season = parseInt(document.getElementById('<%= hid_print_season.ClientID %>').value) || this.print_search.season;
|
||||
this.print_conditions = document.getElementById('<%= hid_print_mode.ClientID %>').value || 'yy';
|
||||
this.print_dialog.show = true;
|
||||
if (printResult === 'nodata') {
|
||||
this.print_error_msg = "查無資料,請重新選擇區間";
|
||||
}
|
||||
});
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
// 清空 URL
|
||||
const cleanUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
window.history.replaceState({}, '', cleanUrl);
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
triggerManagementExport(mode) {
|
||||
this.print_dialog.show = false;
|
||||
this.print_error_msg = "";
|
||||
if (this.print_search.year == '') {
|
||||
msgbox('請輸入年份');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('<%= hid_print_mode.ClientID %>').value = this.print_conditions;
|
||||
document.getElementById('<%= hid_print_year.ClientID %>').value = this.print_search.year;
|
||||
if (this.print_conditions == 'mm') {
|
||||
document.getElementById('<%= hid_print_month.ClientID %>').value = this.print_search.month;
|
||||
}
|
||||
else if (this.print_conditions == 'ss') {
|
||||
document.getElementById('<%= hid_print_season.ClientID %>').value = this.print_search.season;
|
||||
}
|
||||
|
||||
if (mode === 'print') {
|
||||
document.getElementById('<%= print_management.ClientID %>').click();
|
||||
}
|
||||
else if (mode === "excel") {
|
||||
document.getElementById('<%= excel_management.ClientID %>').click();
|
||||
}
|
||||
},
|
||||
search_show(curr) {
|
||||
//console.log("btn_click:", curr, curr.api_url);
|
||||
this.search_dialog.current = curr;
|
||||
@@ -228,6 +315,7 @@
|
||||
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
|
||||
},
|
||||
getList(clearpage = false) {
|
||||
console.log("do getlist")
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||
@@ -241,6 +329,9 @@
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
|
||||
const dataToStore = JSON.stringify(this.data_table);
|
||||
sessionStorage.setItem("member_list_cache", dataToStore);
|
||||
})
|
||||
.catch(
|
||||
error => console.log(error)
|
||||
@@ -262,7 +353,7 @@
|
||||
const index = this.data_table.list.indexOf(item)
|
||||
if (index != -1) {
|
||||
axios
|
||||
.delete(HTTP_HOST + 'api/follower/' + item.num)
|
||||
.delete(HTTP_HOST + 'api/follower/Delete/' + item.num)
|
||||
.then(response => {
|
||||
this.getList();
|
||||
})
|
||||
@@ -282,18 +373,23 @@
|
||||
//}
|
||||
//this.data_table.selected = [];
|
||||
//this.data_table.count = this.data_table.list.length
|
||||
location.reload();
|
||||
//location.reload();
|
||||
this.getList();
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
},
|
||||
btn_search() {
|
||||
this.isSearched = true;
|
||||
sessionStorage.setItem("member_query_params", JSON.stringify(this.search));
|
||||
this.getList(true)
|
||||
bootstrap.Offcanvas.getInstance(document.getElementById("offcanvasRight")).hide()
|
||||
},
|
||||
btn_all() {
|
||||
this.isSearched = false;
|
||||
clearObjProps(this.search);
|
||||
this.btn_search()
|
||||
sessionStorage.setItem("member_query_params", JSON.stringify(this.search));
|
||||
//this.btn_search()
|
||||
},
|
||||
goPrint() {
|
||||
//debugger;
|
||||
@@ -309,6 +405,7 @@
|
||||
//列印管理報表
|
||||
print_close() {
|
||||
this.print_dialog.show = false;
|
||||
this.print_error_msg = "";
|
||||
}
|
||||
,
|
||||
initPrintSearch() {
|
||||
@@ -391,10 +488,31 @@
|
||||
$('#country2').val('');
|
||||
VueApp.search.country2 = '';
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
// 判斷是否彈出 search dialog
|
||||
let hasSearchResult = sessionStorage.getItem("member_list_cache") !== null;
|
||||
|
||||
if (!hasSearchResult && window._printResult === '') {
|
||||
let $btn = $("a[data-bs-target='#offcanvasRight'][href='#search_panel']");
|
||||
$btn.click();
|
||||
let el = document.getElementById('offcanvasRight');
|
||||
let offcanvas = bootstrap.Offcanvas.getOrCreateInstance(el);
|
||||
offcanvas.show();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
||||
<asp:HiddenField ID="hid_err_msg" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_year" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_month" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_season" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_mode" runat="server" />
|
||||
<asp:HiddenField ID="hid_qry" runat="server" />
|
||||
<asp:LinkButton ID="excel_management" runat="server" OnClick="export_Click" style="display:none;" />
|
||||
<asp:LinkButton ID="print_management" runat="server" OnClick="export_Click" style="display:none;" />
|
||||
<div id="content" class="container-fluid">
|
||||
<v-data-table
|
||||
v-model="data_table.selected"
|
||||
@@ -508,9 +626,17 @@
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<div v-if="print_error_msg" class="red--text mt-2 text-center" style="font-weight: bold;">
|
||||
{{ print_error_msg }}
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row densee class="pt-3" >
|
||||
<v-col :cols="12" class="pt-3 text-center" >
|
||||
<v-btn class="ma-2" color="primary" dark @click="goPrint2" > 列印 </v-btn>
|
||||
<v-btn class="ma-2" color="primary" dark @click="triggerManagementExport('print')" > 列印 </v-btn>
|
||||
<v-btn class="ma-2" color="primary" dark @click="triggerManagementExport('excel')"> 匯出 Excel </v-btn>
|
||||
<v-btn class="ma-2" color="green" dark @click="print_close" > 取消 </v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
+294
-183
@@ -1,17 +1,20 @@
|
||||
using System;
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.OleDb;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interop;
|
||||
using static TreeView;
|
||||
|
||||
|
||||
@@ -19,16 +22,22 @@ public partial class admin_follower_index : MyWeb.config
|
||||
{
|
||||
public int page = 1;
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
protected string lastAddedID;
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
|
||||
if (!IsPostBack)
|
||||
{
|
||||
if (Session["LastAddedID"] != null)
|
||||
{
|
||||
lastAddedID = Session["LastAddedID"].ToString();
|
||||
Session.Remove("LastAddedID");
|
||||
}
|
||||
BuildKind();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,10 +51,10 @@ public partial class admin_follower_index : MyWeb.config
|
||||
//國籍
|
||||
s_country.Items.Clear();
|
||||
s_country.Items.Add(new ListItem("請選擇", ""));
|
||||
var qry =_db.countries.OrderBy(x => x.range).ThenBy(x => x.name_en).ToList();
|
||||
var qry = _db.countries.OrderBy(x => x.range).ThenBy(x => x.name_en).ToList();
|
||||
if (qry.Count > 0)
|
||||
{
|
||||
foreach(var x in qry)
|
||||
{
|
||||
foreach (var x in qry)
|
||||
s_country.Items.Add(new ListItem(x.name_zh, x.ID));
|
||||
}
|
||||
|
||||
@@ -68,208 +77,310 @@ public partial class admin_follower_index : MyWeb.config
|
||||
#endregion
|
||||
|
||||
|
||||
#region 匯出Excel
|
||||
#region 匯出
|
||||
|
||||
protected void excel_Click(object sender, EventArgs e)
|
||||
protected void export_Click(object sender, EventArgs e)
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
|
||||
|
||||
LinkButton btn = sender as LinkButton;
|
||||
if (btn == null) return;
|
||||
bool isPrintMode = (btn.ID == "print_management");
|
||||
bool isExcelMode = (btn.ID == "excel_management" || btn.ID == "excel");
|
||||
bool isManagementMode = (btn.ID == "excel_management" || btn.ID == "print_management");
|
||||
|
||||
//查詢要匯出的資料
|
||||
string _query = ""; // 紀錄匯出條件
|
||||
var list = searchData(ref _query, isManagementMode);
|
||||
|
||||
if (isExcelMode)
|
||||
{
|
||||
var wb = doc.AddWorkbookPart();
|
||||
wb.Workbook = new Workbook();
|
||||
var sheets = wb.Workbook.AppendChild(new Sheets());
|
||||
|
||||
//建立第一個頁籤
|
||||
var ws = wb.AddNewPart<WorksheetPart>();
|
||||
ws.Worksheet = new Worksheet();
|
||||
sheets.Append(new Sheet()
|
||||
{
|
||||
Id = wb.GetIdOfPart(ws),
|
||||
SheetId = 1,
|
||||
Name = "信眾資料"
|
||||
});
|
||||
|
||||
//設定欄寬
|
||||
var cu = new Columns();
|
||||
cu.Append(
|
||||
new Column { Min = 1, Max = 2, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 3, Max = 3, Width = 10, CustomWidth = true },
|
||||
new Column { Min = 4, Max = 11, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 12, Max = 12, Width = 25, CustomWidth = true },
|
||||
new Column { Min = 13, Max = 13, Width = 8, CustomWidth = true },
|
||||
new Column { Min = 14, Max = 14, Width = 35, CustomWidth = true },
|
||||
new Column { Min = 15, Max = 16, Width = 15, CustomWidth = true }
|
||||
);
|
||||
ws.Worksheet.Append(cu);
|
||||
|
||||
//建立資料頁
|
||||
var sd = new SheetData();
|
||||
ws.Worksheet.AppendChild(sd);
|
||||
|
||||
//第一列資料
|
||||
var tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue("信眾編號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("信眾姓名"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("性別"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("身分別"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("生日(國曆)"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("聯絡電話"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("手機號碼"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("皈依道場"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("皈依法名"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("皈依日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("加入日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("緊急連絡人"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("緊急連絡人電話"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("血型"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("國籍"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("收件地址"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("介紹人"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("LINE帳號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("其它社群帳號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("建檔日期"), DataType = CellValues.String }
|
||||
,new Cell() { CellValue = new CellValue("身分證號"), DataType = CellValues.String }
|
||||
//,new Cell() { CellValue = new CellValue("SHA"), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
//查詢要匯出的資料
|
||||
|
||||
//紀錄匯出條件
|
||||
string _query = "";
|
||||
|
||||
var list = searchData(ref _query);
|
||||
if (list.Count > 0)
|
||||
{
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
Model.country country = new Model.country();
|
||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||
foreach (var item in list)
|
||||
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
|
||||
{
|
||||
//新增資料列
|
||||
tr = new Row();
|
||||
string s1, s2, sha;
|
||||
s1= encrypt.DecryptAutoKey(item.phone);
|
||||
s2= encrypt.DecryptAutoKey(item.id_code);
|
||||
sha = encrypt.followerHash(s1, s2);
|
||||
var wb = doc.AddWorkbookPart();
|
||||
wb.Workbook = new Workbook();
|
||||
var sheets = wb.Workbook.AppendChild(new Sheets());
|
||||
|
||||
//建立第一個頁籤
|
||||
var ws = wb.AddNewPart<WorksheetPart>();
|
||||
ws.Worksheet = new Worksheet();
|
||||
sheets.Append(new Sheet()
|
||||
{
|
||||
Id = wb.GetIdOfPart(ws),
|
||||
SheetId = 1,
|
||||
Name = "信眾資料"
|
||||
});
|
||||
|
||||
//設定欄寬
|
||||
var cu = new Columns();
|
||||
cu.Append(
|
||||
new Column { Min = 1, Max = 2, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 3, Max = 3, Width = 10, CustomWidth = true },
|
||||
new Column { Min = 4, Max = 11, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 12, Max = 12, Width = 25, CustomWidth = true },
|
||||
new Column { Min = 13, Max = 13, Width = 8, CustomWidth = true },
|
||||
new Column { Min = 14, Max = 14, Width = 35, CustomWidth = true },
|
||||
new Column { Min = 15, Max = 16, Width = 15, CustomWidth = true }
|
||||
);
|
||||
ws.Worksheet.Append(cu);
|
||||
|
||||
//建立資料頁
|
||||
var sd = new SheetData();
|
||||
ws.Worksheet.AppendChild(sd);
|
||||
|
||||
//第一列資料
|
||||
var tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(item.f_number), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.u_name), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.sex), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(!isStrNull(item.identity_type)? tdesc[item.identity_type ?? 1] :""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.birthday.HasValue ? ValDate(item.birthday.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.phone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.cellphone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.refuge_area), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.refuge_name), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.refugedate.HasValue ? ValDate(item.refugedate.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.join_date.HasValue ? ValDate(item.join_date.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.contactor), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.contactor_phone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.blood), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(!isStrNull(item.country) ? item.country1.name_zh : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.address), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.introducer), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.socialid1), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.socialid2), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.reg_time.HasValue ? ValDate(item.reg_time.Value).ToString("yyyy/MM/dd HH:mm:ss") : ""), DataType = CellValues.String }
|
||||
,new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.id_code)), DataType = CellValues.String }
|
||||
//, new Cell() { CellValue = new CellValue(sha), DataType = CellValues.String }
|
||||
);
|
||||
new Cell() { CellValue = new CellValue("信眾編號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("信眾姓名"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("性別"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("身分別"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("生日(國曆)"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("聯絡電話"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("手機號碼"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("皈依道場"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("皈依法名"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("皈依日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("加入日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("緊急連絡人"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("緊急連絡人電話"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("血型"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("國籍"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("收件地址"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("介紹人"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("LINE帳號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("其它社群帳號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("建檔日期"), DataType = CellValues.String }
|
||||
, new Cell() { CellValue = new CellValue("身分證號"), DataType = CellValues.String }
|
||||
//,new Cell() { CellValue = new CellValue("SHA"), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
Model.country country = new Model.country();
|
||||
var tdesc = publicFun.enum_desc<Model.follower.type>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
//新增資料列
|
||||
tr = new Row();
|
||||
string s1, s2, sha;
|
||||
s1 = encrypt.DecryptAutoKey(item.phone);
|
||||
s2 = encrypt.DecryptAutoKey(item.id_code);
|
||||
sha = encrypt.followerHash(s1, s2);
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(item.f_number), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.u_name), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.sex), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(!isStrNull(item.identity_type) ? tdesc[item.identity_type ?? 1] : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.birthday.HasValue ? ValDate(item.birthday.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.phone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.cellphone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.refuge_area), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.refuge_name), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.refugedate.HasValue ? ValDate(item.refugedate.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.join_date.HasValue ? ValDate(item.join_date.Value).ToString("yyyy/MM/dd") : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.contactor), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.contactor_phone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.blood), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(!isStrNull(item.country) ? item.country1.name_zh : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.address), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.introducer), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.socialid1), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.socialid2), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.reg_time.HasValue ? ValDate(item.reg_time.Value).ToString("yyyy/MM/dd HH:mm:ss") : ""), DataType = CellValues.String }
|
||||
, new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.id_code)), DataType = CellValues.String }
|
||||
//, new Cell() { CellValue = new CellValue(sha), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
}
|
||||
|
||||
//空一列
|
||||
tr = new Row();
|
||||
sd.AppendChild(tr);
|
||||
|
||||
//匯出資訊
|
||||
string _data = "匯出時間 : " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
_data += " " + admin.info.u_id;
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
_data = "匯出條件 : " + (!isStrNull(_query) ? _query : "-");
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
|
||||
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.Excel, admin_log.LogViewBtn(list.Select(x => x.f_number + x.u_name).ToList()));
|
||||
|
||||
|
||||
}
|
||||
HttpContext.Current.Response.Clear();
|
||||
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=信眾_data.xlsx");
|
||||
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
|
||||
HttpContext.Current.Response.End();
|
||||
|
||||
//空一列
|
||||
tr = new Row();
|
||||
sd.AppendChild(tr);
|
||||
|
||||
//匯出資訊
|
||||
string _data = "匯出時間 : " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
_data += " " + admin.info.u_id;
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
_data = "匯出條件 : " + (!isStrNull(_query) ? _query : "-");
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
|
||||
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.Excel, admin_log.LogViewBtn(list.Select(x => x.f_number + x.u_name).ToList()));
|
||||
|
||||
hid_err_msg.Value = "success";
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptMsg2("查無資料");
|
||||
//ScriptMsg2("查無資料");
|
||||
hid_err_msg.Value = "nodata";
|
||||
}
|
||||
}
|
||||
else if (isPrintMode)
|
||||
{
|
||||
string urlParams = "";
|
||||
int selYear = !string.IsNullOrEmpty(hid_print_year.Value) ? int.Parse(hid_print_year.Value) : 0;
|
||||
int selMonth = !string.IsNullOrEmpty(hid_print_month.Value) ? int.Parse(hid_print_month.Value) : 0;
|
||||
int selSeason = !string.IsNullOrEmpty(hid_print_season.Value) ? int.Parse(hid_print_season.Value) : 0;
|
||||
string selMode = !string.IsNullOrEmpty(hid_print_mode.Value) ? hid_print_mode.Value : "";
|
||||
|
||||
var qry = _db.followers.AsQueryable();
|
||||
if (selYear > 0)
|
||||
{
|
||||
urlParams += "&year=" + selYear;
|
||||
}
|
||||
if (selMode == "mm" && selMonth > 0)
|
||||
{
|
||||
urlParams += "&month=" + selMonth;
|
||||
}
|
||||
else if (selMode == "ss" && selSeason > 0)
|
||||
{
|
||||
urlParams += "&season=" + selSeason;
|
||||
}
|
||||
|
||||
HttpContext.Current.Response.Clear();
|
||||
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=信眾_data.xlsx");
|
||||
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
|
||||
HttpContext.Current.Response.End();
|
||||
if (list.Count > 0)
|
||||
{
|
||||
hid_err_msg.Value = "success";
|
||||
hid_print_year.Value = selYear.ToString();
|
||||
hid_print_month.Value = selMonth.ToString();
|
||||
hid_print_season.Value = selSeason.ToString();
|
||||
hid_print_mode.Value = selMode;
|
||||
|
||||
string script = $@"window.open('print.aspx?{urlParams}&mode={selMode}', '列印信眾資料', 'noopener,noreferrer');";
|
||||
ScriptManager.RegisterStartupScript(this, GetType(), "ExecutePrint", script, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_err_msg.Value = "nodata";
|
||||
}
|
||||
}
|
||||
}
|
||||
protected List<Model.follower> searchData(ref string _query)
|
||||
protected List<Model.follower> searchData(ref string _query, bool isManagementMode = false)
|
||||
{
|
||||
|
||||
//查詢要匯出的資料
|
||||
var qry = _db.followers.AsQueryable();
|
||||
|
||||
//紀錄匯出條件
|
||||
if (!isStrNull(s_f_number.Value))
|
||||
// 管理報表
|
||||
if (isManagementMode)
|
||||
{
|
||||
qry = qry.Where(o => o.f_number.Contains(s_f_number.Value.Trim()));
|
||||
|
||||
_query += "信眾編號:" + s_f_number.Value.Trim() + "\n";
|
||||
|
||||
}
|
||||
int selYear = !string.IsNullOrEmpty(hid_print_year.Value) ? int.Parse(hid_print_year.Value) : 0;
|
||||
int selMonth = !string.IsNullOrEmpty(hid_print_month.Value) ? int.Parse(hid_print_month.Value) : 0;
|
||||
int selSeason = !string.IsNullOrEmpty(hid_print_season.Value) ? int.Parse(hid_print_season.Value) : 0;
|
||||
string selMode = !string.IsNullOrEmpty(hid_print_mode.Value) ? hid_print_mode.Value : "";
|
||||
|
||||
if (!isStrNull(s_u_name.Value))
|
||||
{
|
||||
qry = qry.Where(o => o.u_name.Contains(s_u_name.Value.Trim()));
|
||||
|
||||
_query += "信眾姓名:" + s_u_name.Value.Trim() + "\n";
|
||||
|
||||
}
|
||||
if (!isStrNull(s_address.Value))
|
||||
{
|
||||
qry = qry.Where(o => o.address.Contains(s_address.Value.Trim()));
|
||||
_query += "地址:" + s_u_name.Value.Trim() + "\n";
|
||||
}
|
||||
|
||||
// 電話/證號搜尋 (使用 search_keywords HEX 編碼)
|
||||
if (!isStrNull(s_phone_idcode.Value) && GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
string hexSearch = encrypt.ConvertToHex(s_phone_idcode.Value.Trim());
|
||||
if (!string.IsNullOrEmpty(hexSearch))
|
||||
if (selYear > 0)
|
||||
{
|
||||
qry = qry.Where(o => o.search_keywords != null && o.search_keywords.Contains(hexSearch));
|
||||
_query += "電話/證號:" + s_phone_idcode.Value.Trim() + "\n";
|
||||
qry = qry.Where(o => o.join_date.HasValue && o.join_date.Value.Year == selYear);
|
||||
_query += "年份:" + selYear + "\n";
|
||||
}
|
||||
if (selMode == "mm" && selMonth > 0)
|
||||
{
|
||||
qry = qry.Where(o => o.join_date.HasValue && o.join_date.Value.Month == selMonth);
|
||||
_query += "月份:" + selMonth + "\n";
|
||||
}
|
||||
else if (selMode == "ss" && selSeason > 0)
|
||||
{
|
||||
if (selSeason == 1)
|
||||
{
|
||||
qry = qry.Where(o => o.join_date.HasValue)
|
||||
.Where(o => o.join_date.Value.Month == 1 || o.join_date.Value.Month == 2 || o.join_date.Value.Month == 3);
|
||||
}
|
||||
else if (selSeason == 2)
|
||||
{
|
||||
qry = qry.Where(o => o.join_date.HasValue)
|
||||
.Where(o => o.join_date.Value.Month == 4 || o.join_date.Value.Month == 5 || o.join_date.Value.Month == 6);
|
||||
}
|
||||
else if (selSeason == 3)
|
||||
{
|
||||
qry = qry.Where(o => o.join_date.HasValue)
|
||||
.Where(o => o.join_date.Value.Month == 7 || o.join_date.Value.Month == 8 || o.join_date.Value.Month == 9);
|
||||
}
|
||||
else if (selSeason == 4)
|
||||
{
|
||||
qry = qry.Where(o => o.join_date.HasValue)
|
||||
.Where(o => o.join_date.Value.Month == 10 || o.join_date.Value.Month == 11 || o.join_date.Value.Month == 12);
|
||||
}
|
||||
|
||||
_query += "季度:" + selSeason + "\n";
|
||||
}
|
||||
|
||||
qry = qry.OrderByDescending(o => o.num);
|
||||
return qry.ToList();
|
||||
}
|
||||
|
||||
if (!isStrNull(s_birthday.Value) && isDate(s_birthday.Value))
|
||||
else
|
||||
// 匯出查詢資料
|
||||
{
|
||||
qry = qry.Where(o => o.birthday >= ValDate(s_birthday.Value));
|
||||
_query += "生日(起):" + s_birthday.Value.Trim() + "\n";
|
||||
//紀錄匯出條件
|
||||
if (!isStrNull(s_f_number.Value))
|
||||
{
|
||||
qry = qry.Where(o => o.f_number.Contains(s_f_number.Value.Trim()));
|
||||
|
||||
_query += "信眾編號:" + s_f_number.Value.Trim() + "\n";
|
||||
|
||||
}
|
||||
|
||||
if (!isStrNull(s_u_name.Value))
|
||||
{
|
||||
qry = qry.Where(o => o.u_name.Contains(s_u_name.Value.Trim()));
|
||||
|
||||
_query += "信眾姓名:" + s_u_name.Value.Trim() + "\n";
|
||||
|
||||
}
|
||||
if (!isStrNull(s_address.Value))
|
||||
{
|
||||
qry = qry.Where(o => o.address.Contains(s_address.Value.Trim()));
|
||||
_query += "地址:" + s_address.Value.Trim() + "\n";
|
||||
}
|
||||
|
||||
// 電話/證號搜尋 (使用 search_keywords HEX 編碼)
|
||||
if (!isStrNull(s_phone_idcode.Value) && GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
string hexSearch = encrypt.ConvertToHex(s_phone_idcode.Value.Trim());
|
||||
if (!string.IsNullOrEmpty(hexSearch))
|
||||
{
|
||||
qry = qry.Where(o => o.search_keywords != null && o.search_keywords.Contains(hexSearch));
|
||||
_query += "電話/證號:" + s_phone_idcode.Value.Trim() + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStrNull(s_birthday.Value) && isDate(s_birthday.Value))
|
||||
{
|
||||
var tmp_s_birthday = ValDate(s_birthday.Value);
|
||||
qry = qry.Where(o => o.birthday >= tmp_s_birthday);
|
||||
_query += "生日(起):" + s_birthday.Value.Trim() + "\n";
|
||||
}
|
||||
if (!isStrNull(s_birthday2.Value) && isDate(s_birthday2.Value))
|
||||
{
|
||||
var tmp_s_birthday2 = Convert.ToDateTime(s_birthday2.Value).AddDays(1);
|
||||
qry = qry.Where(o => o.birthday < tmp_s_birthday2);
|
||||
_query += "生日(訖):" + s_birthday2.Value.Trim() + "\n";
|
||||
}
|
||||
qry = qry.OrderByDescending(o => o.num);
|
||||
return qry.ToList();
|
||||
}
|
||||
if (!isStrNull(s_birthday2.Value) && isDate(s_birthday2.Value))
|
||||
{
|
||||
qry = qry.Where(o => o.birthday < Convert.ToDateTime(s_birthday2.Value).AddDays(1));
|
||||
_query += "生日(訖):" + s_birthday2.Value.Trim() + "\n";
|
||||
}
|
||||
qry = qry.OrderByDescending(o => o.num);
|
||||
return qry.ToList();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<span>信眾姓名:</span><asp:Literal runat="server" ID="username"></asp:Literal>
|
||||
</div>
|
||||
</div>
|
||||
<a href="index.aspx" class="btn btn-outline-secondary">返回</a>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||
<div class="container-fluid">
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
|
||||
<div class="ms-3">
|
||||
<span>信眾姓名:</span><asp:Literal runat="server" ID="username"></asp:Literal>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ms-3">
|
||||
<span>信眾姓名:</span><asp:Literal runat="server" ID="username"></asp:Literal>
|
||||
</div>
|
||||
</div>
|
||||
<a href="order_record.aspx?userid=<%=Request["userid"] %>" class="btn btn-outline-secondary">返回</a>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||
<div class="container-fluid">
|
||||
|
||||
@@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Vml.Office;
|
||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Information;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
@@ -26,7 +27,7 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
//紀錄匯出條件
|
||||
string _query = "";
|
||||
var qry = _db.followers.AsQueryable();
|
||||
|
||||
|
||||
// ❌ 錯誤寫法: qry = qry.Where(o => o.f_number.Contains(Request["f_number"].Trim()));
|
||||
// LINQ to Entities 無法轉換 Request[] 方法,必須先轉換為變數再使用
|
||||
string fNumberParam = Request["f_number"]?.Trim();
|
||||
@@ -60,7 +61,8 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
if (!string.IsNullOrEmpty(Request["birthday2"]))
|
||||
{
|
||||
DateTime birthday2Param = Convert.ToDateTime(Request["birthday2"].Trim());
|
||||
qry = qry.Where(o => o.birthday < birthday2Param.AddDays(1));
|
||||
var tmpBirthday2Param = birthday2Param.AddDays(1);
|
||||
qry = qry.Where(o => o.birthday < tmpBirthday2Param);
|
||||
_query += "生日(訖):" + birthday2Param.ToString("yyyy/MM/dd") + "\n";
|
||||
}
|
||||
// ❌ 錯誤寫法: _db.countries.Where(x => x.ID == Request["country"].ToString())
|
||||
@@ -85,7 +87,19 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
}
|
||||
_query += "國家:" + (_db.countries.Where(x => x.ID == country2Id).Select(x => x.name_zh).FirstOrDefault() ?? "") + "\n";
|
||||
}
|
||||
|
||||
|
||||
string phone_ipcode = Request["phone_idcode"]?.ToString();
|
||||
if (!string.IsNullOrEmpty(phone_ipcode) && GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
string hexSearch = encrypt.ConvertToHex(phone_ipcode.Trim());
|
||||
if (!string.IsNullOrEmpty(hexSearch))
|
||||
{
|
||||
qry = qry.Where(o => o.search_keywords != null && o.search_keywords.Contains(hexSearch));
|
||||
_query += "電話/證號:" + phone_ipcode.Trim() + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
//管理報表
|
||||
if (!string.IsNullOrEmpty(Request["year"]))
|
||||
{
|
||||
|
||||
+55
-35
@@ -190,7 +190,7 @@
|
||||
text_prop: 'name_zh',
|
||||
value_prop: 'id',
|
||||
keys: [
|
||||
{ id: 'keyword', title: '關鍵字' },
|
||||
{ id: 'keyword', title: '關鍵字' },
|
||||
],
|
||||
api_url: HTTP_HOST + 'api/country/GetList',
|
||||
columns: [
|
||||
@@ -208,11 +208,11 @@
|
||||
title: '稱謂',
|
||||
text_prop: 'title',
|
||||
value_prop: 'num',
|
||||
keys: [
|
||||
keys: [
|
||||
],
|
||||
api_url: HTTP_HOST + 'api/appellation/GetList',
|
||||
columns: [
|
||||
{ id: 'title', title: '稱謂' },
|
||||
{ id: 'title', title: '稱謂' },
|
||||
],
|
||||
selected: {},
|
||||
select(item, index, t) {
|
||||
@@ -230,7 +230,7 @@
|
||||
{ id: 'f_number', title: '編號' },
|
||||
{ id: 'u_name', title: '姓名' },
|
||||
{ id: 'address', title: '地址' },
|
||||
{ id: 'onlyfamily', title: '只查親屬'},
|
||||
{ id: 'onlyfamily', title: '只查親屬' },
|
||||
],
|
||||
api_url: HTTP_HOST + 'api/follower/GetList',
|
||||
columns: [
|
||||
@@ -241,7 +241,7 @@
|
||||
selected: {},
|
||||
select(item, index, t) {
|
||||
console.log("select search5", t);
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -314,10 +314,10 @@
|
||||
birthday: '',
|
||||
phoneDes: '',
|
||||
demo: '',
|
||||
appellation_id_selected :
|
||||
appellation_id_selected:
|
||||
{
|
||||
text : '',
|
||||
val : 0,
|
||||
text: '',
|
||||
val: 0,
|
||||
},
|
||||
|
||||
},
|
||||
@@ -372,33 +372,33 @@
|
||||
],
|
||||
tabletsDetail: { multiSort: false },
|
||||
tabletTable: {
|
||||
Loading:true,
|
||||
Loading: true,
|
||||
disableButton: true,
|
||||
searchDetail: '',
|
||||
headersDetail: [
|
||||
{ text: '超渡/陽上', value: 'type', sortable: false, width: "100px" },
|
||||
{ text: '* 牌位標題', value: 'title', sortable: true },
|
||||
{ text: '超渡/陽上', value: 'type', sortable: false, width: "100px" },
|
||||
{ text: '* 牌位標題', value: 'title', sortable: true },
|
||||
{ text: '', value: 'actions', sortable: false, width: "100px" },
|
||||
],
|
||||
],
|
||||
desserts: [],
|
||||
desserts_count: 0,
|
||||
editedIndex: -1,
|
||||
editedItem: {
|
||||
id: 0,
|
||||
num: 0,
|
||||
f_num: 0,
|
||||
title: '',
|
||||
num: 0,
|
||||
f_num: 0,
|
||||
title: '',
|
||||
},
|
||||
defaultItem: {
|
||||
id: 0,
|
||||
num: 0,
|
||||
f_num: 0,
|
||||
num: 0,
|
||||
f_num: 0,
|
||||
type: this.selectedTabletType,
|
||||
title:'',
|
||||
title: '',
|
||||
},
|
||||
},
|
||||
//新:家人
|
||||
family:{
|
||||
family: {
|
||||
dialog: false,
|
||||
isEditing: false,
|
||||
is_tw: true,
|
||||
@@ -420,8 +420,8 @@
|
||||
chinese_year: "",
|
||||
zodiac: "",
|
||||
birth_time: "",
|
||||
city:"",
|
||||
area:"",
|
||||
city: "",
|
||||
area: "",
|
||||
address: "",
|
||||
phone: "",
|
||||
mobile: "",
|
||||
@@ -440,8 +440,8 @@
|
||||
chinese_year: "",
|
||||
zodiac: "",
|
||||
birth_time: "",
|
||||
city:"",
|
||||
area:"",
|
||||
city: "",
|
||||
area: "",
|
||||
address: "",
|
||||
phone: "",
|
||||
mobile: "",
|
||||
@@ -458,11 +458,11 @@
|
||||
areaOptions: {}, // 區域選項
|
||||
//天干地支:甲子, 乙丑...
|
||||
chineseYears: [
|
||||
'甲子', '乙丑', '丙寅', '丁卯', '戊辰', '己巳', '庚午', '辛未', '壬申', '癸酉',
|
||||
'甲戌', '乙亥', '丙子', '丁丑', '戊寅', '己卯', '庚辰', '辛巳', '壬午', '癸未',
|
||||
'甲申', '乙酉', '丙戌', '丁亥', '戊子', '己丑', '庚寅', '辛卯', '壬辰', '癸巳',
|
||||
'甲午', '乙未', '丙申', '丁酉', '戊戌', '己亥', '庚子', '辛丑', '壬寅', '癸卯',
|
||||
'甲辰', '乙巳', '丙午', '丁未', '戊申', '己酉', '庚戌', '辛亥', '壬子', '癸丑',
|
||||
'甲子', '乙丑', '丙寅', '丁卯', '戊辰', '己巳', '庚午', '辛未', '壬申', '癸酉',
|
||||
'甲戌', '乙亥', '丙子', '丁丑', '戊寅', '己卯', '庚辰', '辛巳', '壬午', '癸未',
|
||||
'甲申', '乙酉', '丙戌', '丁亥', '戊子', '己丑', '庚寅', '辛卯', '壬辰', '癸巳',
|
||||
'甲午', '乙未', '丙申', '丁酉', '戊戌', '己亥', '庚子', '辛丑', '壬寅', '癸卯',
|
||||
'甲辰', '乙巳', '丙午', '丁未', '戊申', '己酉', '庚戌', '辛亥', '壬子', '癸丑',
|
||||
'甲寅', '乙卯', '丙辰', '丁巳', '戊午', '己未', '庚申', '辛酉', '壬戌', '癸亥'
|
||||
],
|
||||
//生肖
|
||||
@@ -585,7 +585,7 @@
|
||||
this.search_dialog.list = response.data.list
|
||||
this.search_dialog.count = response.data.count
|
||||
this.search_dialog.loading = false
|
||||
|
||||
console.log(this.search_dialog.list)
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
@@ -1318,13 +1318,32 @@
|
||||
$('.tab-pane,.edit_Click').removeClass('pe-none'); // 移除 pe-none 類,允許編輯
|
||||
}
|
||||
});
|
||||
|
||||
let isComposing = false;
|
||||
const cellphoneInput = document.querySelector('[id$="cellphone"]');
|
||||
if (cellphoneInput) {
|
||||
cellphoneInput.addEventListener('compositionstart', () => {
|
||||
isComposing = true;
|
||||
});
|
||||
cellphoneInput.addEventListener('compositionend', (e) => {
|
||||
isComposing = false;
|
||||
formatCellphone(e.target);
|
||||
});
|
||||
cellphoneInput.addEventListener('input', (e) => {
|
||||
if (!isComposing) {
|
||||
formatCellphone(e.target);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="page_nav" runat="Server">
|
||||
<div class="scroll-nav nav nav-tabs mb-2 mb-sm-0 d-none d-sm-flex">
|
||||
<template v-if="follower_id !='' "> {{titleword()}} </template>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="">
|
||||
<div class="form-check me-3 d-none" id="editCheckboxContainer">
|
||||
<input class="form-check-input" type="checkbox" id="editCheckbox">
|
||||
<label class="form-check-label" for="editCheckbox">
|
||||
@@ -1332,8 +1351,8 @@
|
||||
</label>
|
||||
</div>
|
||||
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary edit_Click noedit" />
|
||||
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary edit_Click noedit" />
|
||||
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||
<asp:Button ID="edit" runat="server" Text="儲存" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary edit_Click noedit" />
|
||||
<asp:Button ID="goback" runat="server" Text="取消" Visible="true" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
@@ -1412,7 +1431,7 @@
|
||||
</div>
|
||||
<label class="col-sm-2 col-lg-1 col-form-label">手機號碼<asp:Literal ID="cellphoneReqStar" runat="server" Text=" *"></asp:Literal></label>
|
||||
<div class="col-sm-10 col-lg-3">
|
||||
<asp:TextBox ID="cellphone" MaxLength="12" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="聯絡電話與手機號碼請至少填寫一項" oninput="formatCellphone(this)"></asp:TextBox>
|
||||
<asp:TextBox ID="cellphone" MaxLength="12" runat="server" CssClass="form-control" data-encrypt="Y" placeholder="聯絡電話與手機號碼請至少填寫一項"></asp:TextBox>
|
||||
<asp:RegularExpressionValidator ControlToValidate="cellphone" Display="Dynamic" ErrorMessage="格式有誤" ID="RegularExpressionValidator2" runat="server" SetFocusOnError="true" ValidationExpression="^09\d{2}-?\d{3}-?\d{3}$" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -1578,12 +1597,12 @@
|
||||
<asp:TextBox ID="demo" runat="server" Rows="5" TextMode="MultiLine" CssClass="form-control" placeholder="請輸入備註"></asp:TextBox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<%-- <div class="row mb-1">
|
||||
<label class="col-form-label">自定義欄位預設值</label>
|
||||
<div class="">
|
||||
<asp:TextBox ID="customize_data" runat="server" Rows="3" TextMode="MultiLine" CssClass="form-control" placeholder="一行輸入一個定義欄位預設值,如: $姓名:王OO $聯絡電話:0987654321" ToolTip="一行輸入一個定義欄位預設值,格式: $變數名稱:值"></asp:TextBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>--%>
|
||||
<div class="row mb-1">
|
||||
<asp:Panel ID="timePanel1" runat="server" CssClass="col-12 text-right text-primary" Visible="false">建檔時間:<asp:Literal ID="reg_time" runat="server"></asp:Literal></asp:Panel>
|
||||
<asp:Panel ID="timePanel2" runat="server" CssClass="col-12 text-right text-primary" Visible="false">最後修改時間:<asp:Literal ID="modify_time" runat="server"></asp:Literal></asp:Panel>
|
||||
@@ -2155,4 +2174,5 @@
|
||||
</template>
|
||||
</v-snackbar>
|
||||
</div>
|
||||
|
||||
</asp:Content>
|
||||
@@ -1,34 +1,44 @@
|
||||
using System;
|
||||
using Model;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.Entity;
|
||||
using System.Data.OleDb;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using Model;
|
||||
|
||||
public partial class admin_follower_reg : MyWeb.config
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
public ArrayList _tmp = new ArrayList();
|
||||
public bool isDataChanged = false;
|
||||
public bool isAutoNumbering = ConfigurationManager.AppSettings["IsAutoNumbering"].ToString() == "true" ? true : false;
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
CallAjax();
|
||||
|
||||
if (!IsPostBack)
|
||||
{
|
||||
{
|
||||
|
||||
InitEnumsOptions<Model.follower.type>(identity_type); //身分別
|
||||
//var qry = _db.followers.AsEnumerable();
|
||||
var qry = _db.followers.AsQueryable();
|
||||
|
||||
var qry = _db.followers.AsQueryable();
|
||||
|
||||
if (isStrNull(Request["num"]))
|
||||
{
|
||||
if (!isAutoNumbering)
|
||||
{
|
||||
f_number.ReadOnly = false;
|
||||
}
|
||||
|
||||
if (!isStrNull(Request["leader"]))
|
||||
{
|
||||
int _num = Val(Request["leader"]);
|
||||
@@ -50,9 +60,14 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
//預設國籍
|
||||
country.Value = "158";
|
||||
country_txt.Value = "中華民國(台灣)";
|
||||
|
||||
// 預設加入日期
|
||||
join_date.Text = DateTime.Now.ToString("yyyy-MM-dd");
|
||||
}
|
||||
else
|
||||
{
|
||||
f_number.ReadOnly = true;
|
||||
|
||||
int _num = Val(Request["num"]);
|
||||
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
|
||||
if (prod != null)
|
||||
@@ -206,8 +221,11 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
}
|
||||
}
|
||||
}
|
||||
// 使用新的 generate_f_number 方法,已內建重號檢查和重試機制
|
||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
||||
if (isAutoNumbering)
|
||||
{
|
||||
// 使用新的 generate_f_number 方法,已內建重號檢查和重試機制
|
||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
||||
}
|
||||
followers.identity_type = Val(identity_type.SelectedValue);
|
||||
if(!isStrNull(leader.Value)) followers.leader = Val(leader.Value);
|
||||
if (!isStrNull(country.Value)) followers.country = country.Value;
|
||||
@@ -226,8 +244,21 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
_db.followers.Add(followers);
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
int _id = followers.num;
|
||||
|
||||
//應該要自動將此人設為第一個親友資料,不然牌位燈打時又要再做一次
|
||||
family_members fm=new family_members();
|
||||
fm.follower_num = _id;
|
||||
fm.fam_name = followers.u_name;
|
||||
fm.fam_gender=followers.sex;
|
||||
fm.deceased = false;
|
||||
fm.birthdate = followers.birthday;
|
||||
|
||||
_db.family_members.Add(fm);
|
||||
_db.SaveChanges();
|
||||
|
||||
|
||||
if (_id > 0)
|
||||
{
|
||||
// 如果啟用 search_keywords 功能,生成並更新 search_keywords
|
||||
@@ -239,7 +270,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
|
||||
@@ -282,7 +315,7 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
try
|
||||
{
|
||||
foreach (Control obj in cardBodyPanel.Controls)
|
||||
{
|
||||
{
|
||||
if (obj is TextBox)
|
||||
{
|
||||
var ObjValue = followers.GetType().GetProperty(obj.ID);
|
||||
@@ -300,7 +333,7 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
ObjValue.SetValue(followers, null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -310,22 +343,60 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
followers.sex = sex.SelectedValue;
|
||||
followers.blood = blood.SelectedValue;
|
||||
followers.tab = tab.Value.Trim(',');
|
||||
followers.admin_log = admin.info.u_id + " " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
//followers.admin_log = admin.info.u_id + " " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
followers.follower_hash = encrypt.followerHash(followers.phone, followers.id_code);
|
||||
|
||||
|
||||
// 如果啟用 search_keywords 功能,生成並更新 search_keywords
|
||||
if (GlobalVariables.UseSearchKeywords)
|
||||
{
|
||||
followers.search_keywords = encrypt.GenerateSearchKeywords(followers);
|
||||
}
|
||||
|
||||
_db.SaveChanges();
|
||||
|
||||
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.Update, f_number.Text + u_name.Text);
|
||||
// 檢查是否有修改資料
|
||||
var entry = _db.Entry(followers);
|
||||
this.isDataChanged = entry.CurrentValues.PropertyNames.Any(name =>
|
||||
{
|
||||
if (name == "admin_log" || name == "follower_hash")
|
||||
return false;
|
||||
|
||||
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
|
||||
var originalVal = entry.OriginalValues[name]?.ToString();
|
||||
var currentVal = entry.CurrentValues[name]?.ToString();
|
||||
|
||||
// 針對加密欄位進行特殊處理
|
||||
bool isEncryptedField = (name == "phone" || name == "id_code");
|
||||
|
||||
if (isEncryptedField)
|
||||
{
|
||||
string originalPlain = !string.IsNullOrEmpty(originalVal) ? encrypt.DecryptAutoKey(originalVal) : "";
|
||||
string currentPlain = !string.IsNullOrEmpty(currentVal) ? encrypt.DecryptAutoKey(currentVal) : "";
|
||||
return originalPlain.Trim() != currentPlain.Trim();
|
||||
}
|
||||
|
||||
return !object.Equals(originalVal, currentVal);
|
||||
});
|
||||
|
||||
if (this.isDataChanged)
|
||||
{
|
||||
followers.admin_log = admin.info.u_id + " " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.State = EntityState.Unchanged;
|
||||
}
|
||||
|
||||
int isDataSaved = _db.SaveChanges();
|
||||
if (isDataSaved > 0)
|
||||
{
|
||||
//L_msg.Type = alert_type.success;
|
||||
//L_msg.Text = "修改成功";
|
||||
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.Update, f_number.Text + u_name.Text);
|
||||
Response.Redirect("index.aspx?dirty=1&page=" + Convert.ToString(Request["page"]));
|
||||
}
|
||||
else
|
||||
{
|
||||
Response.Redirect("index.aspx?page=" + Convert.ToString(Request["page"]));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -339,7 +410,7 @@ 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"])))
|
||||
{
|
||||
}
|
||||
@@ -349,7 +420,7 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
L_msg.Text = "信眾編號重複";
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
+32
-1
@@ -85,7 +85,7 @@
|
||||
<label for="u_gauth"><i class="mdi mdi-key-variant"></i> Google Authenticator 驗證碼</label>
|
||||
</div>
|
||||
<div class="mt-4 mb-0 d-grid gap-2">
|
||||
<asp:LinkButton ID="Button1" runat="server" OnClick="Button1_Click"
|
||||
<asp:LinkButton ID="Button1" runat="server" OnClick="Button1_Click"
|
||||
CssClass="btn btn-primary rounded-pill">
|
||||
<i class="mdi mdi-login"></i> 登入</asp:LinkButton>
|
||||
<asp:LinkButton ID="DesignModeButton" runat="server" OnClick="DesignModeButton_Click"
|
||||
@@ -105,5 +105,36 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.content_box -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var accountInput = document.getElementById('<%= u_id.ClientID %>');
|
||||
var passwordInput = document.getElementById('<%= u_password.ClientID %>');
|
||||
var chkInput = document.getElementById('<%= chknum.ClientID %>');
|
||||
var btn = document.getElementById('<%= Button1.ClientID %>');
|
||||
|
||||
accountInput.addEventListener('keypress', function (e){
|
||||
if (e.keyCode === 13) {
|
||||
$("#<%= u_password.ClientID %>").focus();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
passwordInput.addEventListener('keypress', function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
$("#<%= chknum.ClientID %>").focus();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
var triggerLogin = function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
btn.click();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
if (chkInput) chkInput.addEventListener('keypress', triggerLogin);
|
||||
});
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
|
||||
@@ -93,14 +93,14 @@
|
||||
</select>
|
||||
<label for="printSize" style="color: black">列印尺寸</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<%--<div class="form-floating mb-3">
|
||||
<select class="form-select form-select-sm mb-2 " onchange="Designer.changePrintMode()" id="printMode">
|
||||
<option value="">請選擇</option>
|
||||
<option value="combine">合併</option>
|
||||
<option value="origin">原尺寸</option>
|
||||
</select>
|
||||
<label for="printMode" style="color: black">列印模式</label>
|
||||
</div>
|
||||
</div>--%>
|
||||
<%-- <div class="form-floating mb-3">
|
||||
<input type="number" id="rosterLimit" onchange="Designer.changeRosterLimit()" class="form-control form-control-sm mb-2">
|
||||
<label class="small" for="rosterLimit" style="color: black;">正名上限</label>
|
||||
@@ -114,7 +114,7 @@
|
||||
<span class="btn btn-sm btn-outline-info w-100 mb-2" onclick="Designer.saveStyle()">存檔</span>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span class="btn btn-sm btn-outline-info w-100 mb-2" onclick="Designer.print()">預覽列印</span>
|
||||
<%--<span class="btn btn-sm btn-outline-info w-100 mb-2" onclick="Designer.print()">預覽列印</span>--%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -237,10 +237,10 @@
|
||||
allSize: [
|
||||
],
|
||||
bg: [
|
||||
{ name: "黃1", path: "../../admin/print/html/tablet-1_new.svg" },
|
||||
{ name: "黃2", path: "../../admin/print/html/tablet-1B_new.svg" },
|
||||
{ name: "紅1", path: "../../admin/print/html/tablet-2.svg" },
|
||||
{ name: "紅2", path: "../../admin/print/html/tablet-2B.svg" }
|
||||
{ name: "超薦1", path: "../../admin/print/html/tablet-1_new.svg" },
|
||||
{ name: "超薦2", path: "../../admin/print/html/tablet-1B_new.svg" },
|
||||
{ name: "消災1", path: "../../admin/print/html/tablet-2.svg" },
|
||||
{ name: "消災2", path: "../../admin/print/html/tablet-2B.svg" }
|
||||
],
|
||||
allStyle: [
|
||||
],
|
||||
@@ -603,7 +603,8 @@
|
||||
if (paperSize == "newsize") {
|
||||
$("#sizeDiv").attr("style", "display:");
|
||||
} else {
|
||||
// console.log("paperSize:", paperSize);
|
||||
// console.log("paperSize:", paperSize);
|
||||
$("#sizeDiv").attr("style", "display:none;");
|
||||
let size = this.allSize.find(x => x.id == paperSize)
|
||||
$(".tablet-paper").css({
|
||||
"background-color": "white",
|
||||
@@ -641,6 +642,7 @@
|
||||
bindEvents() {
|
||||
// 文字變更連動渲染
|
||||
//$('#rosterLimit').on('input', (e) =>this.)
|
||||
console.log("OOQ");
|
||||
$('#inp-text').on('input', (e) => this.updateActive('text', $(e.target).val()));
|
||||
$('#inp-size').on('input', (e) => this.updateActive('fontSize', $(e.target).val()));
|
||||
$('#width').on('input', (e) => this.updateActive('width', $(e.target).val()))
|
||||
@@ -671,12 +673,12 @@
|
||||
render() {
|
||||
$(".tablet-paper").empty();
|
||||
//const $canvas = $('#canvas').empty();
|
||||
const roster = this.elements.find(e => e.type === 'roster');
|
||||
const names = roster ? roster.text.split('\n').filter(s => s.trim()) : [];
|
||||
const pages = Math.max(1, Math.ceil(names.length / this.rosterLimit));
|
||||
|
||||
//const roster = this.elements.find(e => e.type === 'roster');
|
||||
|
||||
let style = this.allStyle.find(x => x.styleID == this.styleID);
|
||||
let size = this.allSize.find(x => x.id == style.paperSize);
|
||||
console.log(this.paper, size);
|
||||
//console.log(this.paper, size);
|
||||
//for (let p = 0; p < pages; p++) {
|
||||
// const $paper = $('<div class="tablet-paper"></div>')
|
||||
// .css({ "background-color": "red", width: this.paper.width + 'mm', height: this.paper.height + 'mm' });
|
||||
@@ -687,9 +689,14 @@
|
||||
position: "absolute"
|
||||
});
|
||||
//const slice = names.slice(p * this.rosterLimit, (p + 1) * this.rosterLimit);
|
||||
const slice = names.slice(0 * this.rosterLimit, (0 + 1) * this.rosterLimit);
|
||||
//const roster = this.elements.find(e => e.id === this.styleID);
|
||||
let self = this;
|
||||
|
||||
this.elements.forEach(el => {
|
||||
$paper.append(this.createEl(el, slice));
|
||||
const names = el.text.split('\n').filter(s => s.trim());
|
||||
const pages = Math.max(1, Math.ceil(names.length / self.rosterLimit));
|
||||
const slice = names.slice(0 * self.rosterLimit, (0 + 1) * self.rosterLimit);
|
||||
$paper.append(self.createEl(el, slice));
|
||||
});
|
||||
//$canvas.append($paper);
|
||||
//}
|
||||
@@ -722,6 +729,7 @@
|
||||
html = this.renderNameList(slice, el);
|
||||
}
|
||||
else if (el.id === 'alive') {
|
||||
console.log("createEl:",slice,el)
|
||||
html = this.renderLiveList(slice, el);
|
||||
}
|
||||
else {
|
||||
@@ -772,6 +780,8 @@
|
||||
});
|
||||
},
|
||||
renderLiveList(names, el) {
|
||||
console.log("renderLiveList:",names);
|
||||
//$("#imp-text").updateActive("text",names)
|
||||
let $namelist = $(`<div class='liveList'></div>`).css({
|
||||
"writing-mode": "vertical rl",
|
||||
display: "flex",
|
||||
@@ -795,6 +805,8 @@
|
||||
return $namelist;
|
||||
},
|
||||
renderLiveSpan(name, el) {
|
||||
console.log("renderLiveSpan:", name, el
|
||||
);
|
||||
return $(`<span>${name}</span>`).css({
|
||||
display: "block",
|
||||
"min-height": `${el.textHeight}px`,
|
||||
@@ -869,8 +881,11 @@
|
||||
},
|
||||
|
||||
select(id) {
|
||||
console.log("QQ:",id);
|
||||
this.activeId = id;
|
||||
console.log("QQ:",this.elements);
|
||||
const el = this.elements.find(x => x.id === id);
|
||||
const el1 = this.elements.find(x => x.id === "titletriangle");
|
||||
$('#attr-box').removeClass('d-none');
|
||||
$('#inp-text').val(el.text);
|
||||
$('#inp-size').val(el.style.fontSize);
|
||||
@@ -889,6 +904,7 @@
|
||||
},
|
||||
|
||||
updateActive(key, val) {
|
||||
console.log("updateActive:",key, val)
|
||||
const el = this.elements.find(x => x.id === this.activeId);
|
||||
|
||||
if (key === 'fontSize') el.style.fontSize = parseFloat(val);
|
||||
@@ -1049,7 +1065,7 @@
|
||||
let master = {
|
||||
styleID: this.styleID, styleName: $("#styleName").val(), paperSize: $("#paperSize").val(),
|
||||
backendImg: $("#backendInp").val(), printSize: $("#printSize").val(), printMode: $("#printMode").val(),
|
||||
orientation: $("#paperOrientation").val(), printPageCount: $("#perpage").val(), rosterLimit: $("#rosterLimit").val(),
|
||||
orientation: $("#paperOrientation").val(), printPageCount: $("#perpage").val(), rosterLimit: 8,
|
||||
detail: detail
|
||||
}
|
||||
console.log(master);
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
<ul class="collapsible_item">
|
||||
<asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound">
|
||||
<ItemTemplate>
|
||||
<li><a class="menu" href="<%#ResolveUrl(ValString(Eval("url"))) %>"
|
||||
<li><a class="menu" href="<%#ResolveUrl(ValString(Eval("url"))) %>"
|
||||
target="<%#(ValString(Eval("target"))=="B"?"_blank":"_self") %>"><%#Eval("title") %></a></li>
|
||||
</ItemTemplate>
|
||||
</asp:Repeater>
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<div class="container-fluid">
|
||||
<v-expansion-panels accordion>
|
||||
<v-expansion-panel v-for="(item,i) in 1"
|
||||
:key="i">
|
||||
<v-expansion-panel-header>查詢條件</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<v-row>
|
||||
<!-- <v-col cols="2" md="2">-->
|
||||
|
||||
<!--<v-text-field label="法會分類">
|
||||
|
||||
</v-text-field>-->
|
||||
<!--</v-col>-->
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="法會名稱" v-model="search.subject">
|
||||
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<!--<v-text-field label="開始日期" v-model="search.uptime1">
|
||||
|
||||
</v-text-field>-->
|
||||
<v-menu v-model="startmenu"
|
||||
:close-on-content-click="false"
|
||||
:nudge-right="40"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="search.up_time1"
|
||||
label="法會日期"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="search.up_time1"
|
||||
@input="startmenu = false"></v-date-picker>
|
||||
</v-menu>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-btn @click.prevent="getDefault()">查詢</v-btn>
|
||||
<v-btn @click.prevent="clearSearch()">清空條件</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
<v-data-table v-model="data_table.selected"
|
||||
:items="data_table.list"
|
||||
item-key="order_no"
|
||||
:options.sync="options"
|
||||
:headers="data_table.header"
|
||||
:footer-props="data_table.footer"
|
||||
:server-items-length="data_table.count"
|
||||
:loading="data_table.loading"
|
||||
:single-select="data_table.singleSelect"
|
||||
hide-default-footer
|
||||
:page.sync="data_table.page"
|
||||
:items-per-page.sync="data_table.pageSize"
|
||||
class="elevation-1">
|
||||
<template #item.up_time="{ item }">
|
||||
{{ item.up_time|timeString('YYYY/MM/DD') }}
|
||||
</template>
|
||||
<template #item.u_name="{ item }">
|
||||
<a v-if="item.f_num != null && item.activity_num != null" @click="checkInMsg(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-account-check"></i>報到</a>
|
||||
{{ item.u_name }}
|
||||
</template>
|
||||
<template #item.slot_btn="{ item }">
|
||||
<a @click="gotoSignup(item)" class="btn btn-outline-secondary btn-sm">報名</a>
|
||||
<a @click="gotoBatchSignup(item)" class="btn btn-outline-secondary btn-sm">批次報名</a>
|
||||
<a @click="gotoSignupList(item)" class="btn btn-outline-secondary btn-sm">明細</a>
|
||||
|
||||
</template>
|
||||
</v-data-table>
|
||||
<v-container class="container-fluid">
|
||||
<v-row class="align-baseline" wrap>
|
||||
<v-col cols="12" md="9">
|
||||
<v-pagination v-model="data_table.page"
|
||||
:length="pageCount">
|
||||
</v-pagination>
|
||||
</v-col>
|
||||
<v-col class="text-truncate text-right" cols="12" md="2">
|
||||
共 {{ data_table.count }} 筆, 頁數:
|
||||
</v-col>
|
||||
<v-col cols="6" md="1">
|
||||
<v-text-field v-model="data_table.page"
|
||||
type="number"
|
||||
hide-details
|
||||
dense
|
||||
min="1"
|
||||
:max="pageCount"
|
||||
@input="data_table.page = parseInt($event, 10)"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
module.exports = {
|
||||
props: ['formData'],
|
||||
data() {
|
||||
return {
|
||||
this_act:'',
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
startmenu: false,
|
||||
endmenu: false,
|
||||
itemKindList:[],
|
||||
data_table: {
|
||||
loading: true,
|
||||
list: [],
|
||||
selected: [],
|
||||
singleSelect: false,
|
||||
count: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
header: [
|
||||
{ text: '活動分類', value: 'kindsTxt' },
|
||||
{ text: '活動名稱', value: 'subject' },
|
||||
{ text: '開始日期', value: 'startDate_solar' },
|
||||
{ text: '結束日期', value: 'endDate_solar', align: 'start' },
|
||||
{ text: '報名人數', value: 'orderCounts' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
|
||||
],
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
itemsPerPageOptions: [5, 10, 20, 30],
|
||||
},
|
||||
},
|
||||
select_act_list: [],
|
||||
select_items: {
|
||||
month: [{
|
||||
text: "請選擇",
|
||||
val: 0
|
||||
},],
|
||||
season: [{
|
||||
text: "請選擇",
|
||||
val: 0
|
||||
},],
|
||||
},
|
||||
search: {
|
||||
keyin1: '',
|
||||
order_no: '',
|
||||
subject: '',
|
||||
u_name: '',
|
||||
up_time1: '',
|
||||
up_time2: '',
|
||||
actItemTxt: '',
|
||||
introducerTxt: '',
|
||||
activity_num: '',
|
||||
country: '',
|
||||
country2: '',
|
||||
hasPrice: '',
|
||||
},
|
||||
keyin1_items: [//狀態
|
||||
//{
|
||||
//text: "請選擇",
|
||||
//val: 0
|
||||
//},
|
||||
],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const navEntries = performance.getEntriesByType("navigation");
|
||||
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
|
||||
if (isReload) {
|
||||
sessionStorage.removeItem("orderpage");
|
||||
}
|
||||
else {
|
||||
const savedPage = parseInt(sessionStorage.getItem('orderpage'));
|
||||
if (savedPage) {
|
||||
this.options.page = savedPage;
|
||||
}
|
||||
}
|
||||
this.initKindList()
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler() {
|
||||
this.getDefault()
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
search_options: {
|
||||
handler() {
|
||||
this.search_get()
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initKindList() {
|
||||
axios
|
||||
//.get(HTTP_HOST + 'api/activity_kind')
|
||||
.get(HTTP_HOST + 'api/actItem_kind/GetAll')
|
||||
.then(response => {
|
||||
this.itemKindList = response.data
|
||||
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
clearSearch() {
|
||||
this.search.subject = ""
|
||||
this.search.up_time1=""
|
||||
},
|
||||
gotoBatchSignup(item) {
|
||||
this.$emit('custom-event', { action: 'batchSign', item: item });
|
||||
},
|
||||
gotoSignup(item) {
|
||||
this.$emit('custom-event', { action: 'add', item: item });
|
||||
},
|
||||
gotoSignupList(item) {
|
||||
this.$emit('custom-event', { action:'detail', item:item });
|
||||
},
|
||||
getDetail(clearpage = false) {
|
||||
//console.log("test");
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||
page: clearpage ? '1' : page, pageSize: itemsPerPage
|
||||
};
|
||||
this.detail_table.loading = true
|
||||
sessionStorage.setItem('orderpage', clearpage ? '1' : page);
|
||||
axios
|
||||
//.post(HTTP_HOST + 'api/order/GetList', this.search, { params: params })
|
||||
.post(HTTP_HOST + 'api/order/GetList', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.detail_table.list = response.data.list
|
||||
this.detail_table.count = response.data.count;
|
||||
this.detail_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
getDefault(clearpage = false) {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||
page: clearpage ? '1' : page, pageSize: itemsPerPage
|
||||
};
|
||||
this.data_table.loading = true
|
||||
sessionStorage.setItem('orderpage', clearpage ? '1' : page);
|
||||
axios
|
||||
//.post(HTTP_HOST + 'api/order/GetList', this.search, { params: params })
|
||||
.post(HTTP_HOST + 'api/activity/GetListNew', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
editItem(item) {
|
||||
console.log("edit", item);
|
||||
},
|
||||
btn_search() {
|
||||
this.this_act = '';
|
||||
this.search.activity_num = '';
|
||||
|
||||
this.getDefault(true)
|
||||
},
|
||||
btn_all() {
|
||||
this.this_act = '';
|
||||
this.search.activity_num = '';
|
||||
clearObjProps(this.search);
|
||||
this.btn_search()
|
||||
},
|
||||
initActivity() {
|
||||
axios.get(HTTP_HOST + 'api/activity')
|
||||
.then(response => {
|
||||
this.select_act_list = response.data
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageCount() {
|
||||
return Math.ceil(this.data_table.count / this.data_table.pageSize)
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div class="container-fluid">
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<v-expansion-panels accordion>
|
||||
<v-expansion-panel v-for="(item,i) in 1"
|
||||
:key="i">
|
||||
<v-expansion-panel-header color="#006fc9"
|
||||
class="white--text">
|
||||
<v-row>
|
||||
<v-col cols="10" md="10">
|
||||
<label>查詢條件</label>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-btn @click.prevent='fast_signup' class="ms-auto">快速報名</v-btn>
|
||||
<v-btn @click.prevent="back01()" class="ms-auto">返回</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<v-row>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="姓名" v-model="search.u_name">
|
||||
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="電話" v-model="search.phone">
|
||||
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="行動電話" v-model="search.cellphone">
|
||||
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field label="身分證號" v-model="search.id_code">
|
||||
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-btn @click.prevent="getDetail()">查詢</v-btn>
|
||||
<v-btn @click.prevent="clearSearch()">清空條件</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-data-table v-model="detail_table.selected"
|
||||
:items="detail_table.list"
|
||||
:search-props="search"
|
||||
item-key="order_no"
|
||||
:options.sync="options"
|
||||
:headers="detail_table.header"
|
||||
:footer-props="detail_table.footer"
|
||||
:server-items-length="detail_table.count"
|
||||
:loading="detail_table.loading"
|
||||
:single-select="detail_table.singleSelect"
|
||||
hide-default-footer
|
||||
:page.sync="detail_table.page"
|
||||
:items-per-page.sync="detail_table.pageSize"
|
||||
class="elevation-1">
|
||||
<template #item.slot_btn="{ item }">
|
||||
<!--<a :href="'reg.aspx?order_no='+item.order_no" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
||||
<a @click="$root.currentView='step-three';$root.selected_order=item.order_no" class="btn btn-outline-secondary btn-sm">明細</a>
|
||||
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>-->
|
||||
</template>
|
||||
</v-data-table>
|
||||
<v-container>
|
||||
<v-row class="align-baseline" wrap>
|
||||
<v-col cols="12" md="9">
|
||||
<v-pagination v-model="detail_table.page"
|
||||
:length="pageCount">
|
||||
</v-pagination>
|
||||
</v-col>
|
||||
<v-col class="text-truncate text-right" cols="12" md="2">
|
||||
共 {{ detail_table.count }} 筆, 頁數:
|
||||
</v-col>
|
||||
<v-col cols="6" md="1">
|
||||
<v-text-field v-model="detail_table.page"
|
||||
type="number"
|
||||
hide-details
|
||||
dense
|
||||
min="1"
|
||||
:max="pageCount"
|
||||
@input="detail_table.page = parseInt($event, 10)"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-card-text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
props: {
|
||||
num: {
|
||||
type: Number }
|
||||
},
|
||||
activated() {
|
||||
this.getDetail();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getDetail();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
detail_table: {
|
||||
loading: true,
|
||||
list: [],
|
||||
selected: [],
|
||||
singleSelect: false,
|
||||
count: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
header: [
|
||||
{ text: '單號', value: 'order_no' },
|
||||
{ text: '姓名', value: 'u_name' },
|
||||
{ text: '報名日期', value: 'up_time' },
|
||||
{ text: '單據狀態', value: 'keyin1_txt', align: 'start' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
|
||||
],
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
itemsPerPageOptions: [5, 10, 20, 30],
|
||||
},
|
||||
},
|
||||
search: {
|
||||
u_name: '',
|
||||
phone: '',
|
||||
cellphone: '',
|
||||
id_code:''
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler() {
|
||||
this.getDetail()
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
back01() {
|
||||
this.$emit('custom-event', { action: 'signup1', item: this.num });
|
||||
},
|
||||
fast_signup() {
|
||||
this.$emit('custom-event', { action: 'add', item: this.num });
|
||||
},
|
||||
clearSearch() {
|
||||
|
||||
},
|
||||
getDetail(clearpage=false) {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: sortBy[0], sortDesc: sortDesc[0],
|
||||
page: clearpage ? '1' : page, pageSize: itemsPerPage
|
||||
};
|
||||
let newsearch = {
|
||||
activity_num: this.num, f_user: {
|
||||
u_name: this.search.u_name, phone: this.search.phone,
|
||||
cellphone: this.search.cellphone, id_code: this.search.id_code
|
||||
}
|
||||
}
|
||||
this.detail_table.loading = true
|
||||
sessionStorage.setItem('orderpage', '1');// clearpage ? '1' : page
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/GetList', newsearch, { params: params })
|
||||
.then(response => {
|
||||
this.detail_table.list = response.data.list
|
||||
this.detail_table.count = response.data.count;
|
||||
this.detail_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
pageCount() {
|
||||
return Math.ceil(this.detail_table.count / this.detail_table.pageSize)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,495 @@
|
||||
<template>
|
||||
<div class="container-fluid">
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h5 class="mb-0">快速報名</h5>
|
||||
<div class="ms-auto">
|
||||
<v-btn @click.prevent="saveOrder()" v-if="follower.f_number!=undefined&&follower.f_number!=''">儲存</v-btn>
|
||||
<v-btn @click.prevent="back01()">返回</v-btn>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="name"
|
||||
:counter="20"
|
||||
label="姓名"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="idNo"
|
||||
:counter="20"
|
||||
label="身分證號"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="phoneNum"
|
||||
:counter="20"
|
||||
label="行動電話/市話"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-btn @click.prevent="getFollower">查詢</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider></v-divider>
|
||||
<v-row v-if="follower.f_number!=undefined&&follower.f_number!=''">
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="follower.f_number" readonly
|
||||
label="信眾編號"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="follower.u_name" readonly
|
||||
label="信眾姓名"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="follower.phoneDes" readonly
|
||||
label="電話"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="follower.cellphoneDes" readonly
|
||||
label="行動電話"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="follower.id_code" readonly
|
||||
label="身分證號"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="2">
|
||||
<v-text-field v-model="follower.passport" readonly
|
||||
label="護照號碼"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="follower.f_number!=undefined&&follower.f_number!=''">
|
||||
<v-col cols="12" md="12">
|
||||
<v-text-field v-model="follower.address" readonly
|
||||
label="地址"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<hr class="hr-text" data-content="前次法會功德" v-if="follower.f_number!=undefined&&follower.f_number!=''">
|
||||
<v-row v-show="tablet_show">
|
||||
<v-select :items="orders"
|
||||
label="選擇法會"
|
||||
item-text="subject" @change="changeOrderDetail()"
|
||||
item-value="order_no" v-model="order_no">
|
||||
</v-select>
|
||||
</v-row>
|
||||
<v-row v-show="tablet_show">
|
||||
<v-col cols="12" sm="12">
|
||||
<v-data-iterator :items="tablet_list" :items-per-page="-1"
|
||||
hide-default-footer>
|
||||
<template v-slot:default="{ items }">
|
||||
<v-row>
|
||||
<v-col cols="4" md="4" v-for="(item, i) in items" :key="i">
|
||||
<v-card-title>
|
||||
<v-row>
|
||||
<v-col col="12" md="12">
|
||||
<v-checkbox v-model="item.actitem_num_checked"
|
||||
:disabled="item.disabled" class="custom-checkbox">
|
||||
<template v-slot:label>
|
||||
<h5 :class="renderDisabled(item)">{{ item.actitem_num_selected.text }}</h5>
|
||||
</template>
|
||||
</v-checkbox>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="3" md="3">
|
||||
<v-btn class="ms-auto" @click.prevent="copytablet(item)">複製為</v-btn>
|
||||
</v-col>
|
||||
<v-col cols="9" md="9">
|
||||
|
||||
<v-select :items="act_items"
|
||||
label="選擇功德項目"
|
||||
item-text="act_item_selected.text"
|
||||
item-value="act_item_selected.val" v-model="item.changeActitem">
|
||||
</v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<div v-html="renderTabletContent(item)" style="font-size:20px;"></div>
|
||||
<v-divider></v-divider>
|
||||
</v-card-text>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
<template v-slot:no-data>
|
||||
<v-alert :value="value" color="error" icon="warning">
|
||||
無資料可顯示,可能此信眾未曾參加過任何法會。
|
||||
</v-alert>
|
||||
</template>
|
||||
</v-data-iterator>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-dialog v-model="message_dialog.show" class="dialog_width">
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ message_dialog.message }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="message_dialog.show=false" v-if="!message_dialog.show_confirm">關閉</v-btn>
|
||||
<v-btn @click.prevent="success_confirm()" v-if="message_dialog.show_confirm">確認</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog v-model="none_dialog.show" class="dialog_width">
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ none_dialog.message }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="none_dialog.show=false">關閉</v-btn>
|
||||
<v-btn @click.prevent="gotoOldSign()">前往傳統報名</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog v-model="transfer_dialog.show" class="dialog_width">
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ transfer_dialog.message }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="transfer_dialog.show=false">關閉</v-btn>
|
||||
<v-btn @click.prevent="gotoSignUp4()">報名並將資料回寫信眾資料</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
props: {
|
||||
num: {
|
||||
type: Number // num
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
transfer_dialog: { show: false, message: "" },
|
||||
message_dialog: { show: false, show_confirm: false, message: "" },
|
||||
none_dialog: { show: false, message: "" },
|
||||
idNo: "",
|
||||
phoneNum: "",
|
||||
name: "",
|
||||
follower: {},
|
||||
orders: [],
|
||||
tablet_list: [],
|
||||
act_items: [],
|
||||
search: {},
|
||||
value:false,
|
||||
query: {
|
||||
id_code: { type: String }, cellphone: { type: String }
|
||||
},
|
||||
search_options: { multiSort: false },
|
||||
tablet_show: false,
|
||||
activityes: [],
|
||||
order_no: "",
|
||||
copy_item: {}
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.tablet_show = false
|
||||
this.value=true
|
||||
//this.getFollower()
|
||||
//先清資料
|
||||
this.follower = {}
|
||||
this.orders = []
|
||||
this.tablet_list = []
|
||||
this.idNo = ""
|
||||
this.phoneNum = ""
|
||||
this.name=""
|
||||
this.getActItem()
|
||||
},
|
||||
methods: {
|
||||
gotoOldSign() {
|
||||
this.$emit('custom-event', { action: 'oldSign', item: this.num });
|
||||
},
|
||||
back01() {
|
||||
this.$emit('custom-event', { action: 'signup1', item: this.num });
|
||||
},
|
||||
gotoSignUp4() {
|
||||
this.$emit('custom-event', { action: 'signup4', item: this.num });
|
||||
},
|
||||
renderDisabled(item) {
|
||||
if (item.disabled) {
|
||||
return "disabled-checkbox"
|
||||
} else {
|
||||
return "enabled-checkbox"
|
||||
}
|
||||
},
|
||||
copytablet(item) {
|
||||
let t = this.act_items.find(x => x.act_item_selected.val == item.changeActitem)
|
||||
let newTablet = structuredClone(item)
|
||||
newTablet.id = this.tablet_list.length + 1
|
||||
//console.log("copytablet:",newTablet.nu, newTablet.actitem_num_selected, item.changeActitem);
|
||||
newTablet.actitem_num_selected.val = t.act_item_selected.val
|
||||
newTablet.actitem_num_selected.text = t.act_item_selected.text
|
||||
|
||||
newTablet.changeActitem = item.changeActitem
|
||||
newTablet.disabled=false
|
||||
this.tablet_list.push(newTablet)
|
||||
},
|
||||
getActItem() {
|
||||
this.act_items.length = 0
|
||||
this.search = { num: this.num }
|
||||
let params = { sortBy: 'num', sortDesc: false, page: 1, pageSize: -1 };
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/GetActRelaList', this.search, { params: params })
|
||||
.then(response => {
|
||||
|
||||
if (response.data.list) {
|
||||
this.act_items = response.data.list
|
||||
//if (this.act_items && this.act_items.length > 0) {
|
||||
// this.act_items = this.act_items.map(x => ({
|
||||
// ...x,selected:""
|
||||
// }))
|
||||
//}
|
||||
//console.log("QOO:",this.act_items)
|
||||
}
|
||||
else
|
||||
console.log("查無資料");
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
getFollower() {
|
||||
this.tablet_show = false
|
||||
this.tablet_list.length = 0
|
||||
this.follower = {}
|
||||
this.search = { id_code: this.idNo, u_name: this.name, phone_idcode: this.phoneNum }
|
||||
//應該要檢查他是否已經報完名
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/follower/GetFollowerNew', this.search)
|
||||
.then(response => {
|
||||
if (response.data.list) {
|
||||
//console.log(response.data.list)
|
||||
if (response.data.list.length > 1) {
|
||||
//alert("相同條件不只一人")
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message = "相同條件不只一人,請增加查詢條件"
|
||||
} else if (response.data.list.length==0) {
|
||||
this.transfer_dialog.show = true
|
||||
this.transfer_dialog.message = "查無信眾資料"
|
||||
} else {
|
||||
|
||||
this.tablet_show = true
|
||||
this.follower = response.data.list[0]
|
||||
this.getOrder()
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message = response.message
|
||||
}
|
||||
//alter(response.message);
|
||||
|
||||
// console.log("查無資料");
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
getOrder() {
|
||||
let params = { page: 1, pageSize: 10, sortBy: 'reg_time', sortDesc: true };
|
||||
this.search = { f_num: this.follower.num }
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/GetList', this.search, { params: params })
|
||||
.then(response => {
|
||||
if (response.data.list && response.data.list.length > 0) {
|
||||
this.orders = response.data.list
|
||||
|
||||
|
||||
//先確定是否有報名過
|
||||
let o = this.orders.find(x => x.activity_num === this.num)
|
||||
if (o != null && o != undefined) {
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message = "此人已有報名資料,請勿重複報名"
|
||||
return
|
||||
}
|
||||
this.orders = this.orders.filter(x => x.activity_num !== this.num)
|
||||
//console.log("orders",this.orders)
|
||||
if (this.orders && this.orders.length > 0) {
|
||||
|
||||
this.getOrderDetail()
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
this.none_dialog.show = true
|
||||
this.none_dialog.message = "尚未參加任何法會活動"
|
||||
console.log("getOrder 查無資料");
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
changeOrderDetail() {
|
||||
this.tablet_show = true
|
||||
this.tablet_list.length = 0
|
||||
let params = { sortBy: 'num', sortDesc: true, page: 1, pageSize: -1 };
|
||||
let search1 = { order_no: this.order_no }
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/GetItemList', search1, { params: params })
|
||||
.then(response => {
|
||||
if (response.data.list) {
|
||||
this.tablet_list = response.data.list
|
||||
this.tablet_list.forEach(x => {
|
||||
let act_item = this.act_items.filter(y => y.act_item_selected.val === x.actitem_num_selected.val)
|
||||
if (act_item && act_item.length > 0) {
|
||||
x.disabled = false
|
||||
} else {
|
||||
x.disabled = true
|
||||
}
|
||||
x["changeActitem"] = ""
|
||||
})
|
||||
}
|
||||
else
|
||||
console.log("changeOrderDetail 查無資料");
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
getOrderDetail() {
|
||||
this.tablet_show = true
|
||||
let params = { sortBy: 'num', sortDesc: true, page: 1, pageSize: -1 };
|
||||
let search1 = { order_no: this.orders[0].order_no }
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/GetItemList', search1, { params: params })
|
||||
.then(response => {
|
||||
if (response.data.list) {
|
||||
this.tablet_list = response.data.list
|
||||
this.tablet_list.forEach(x => {
|
||||
let act_item = this.act_items.filter(y => y.act_item_selected.val === x.actitem_num_selected.val)
|
||||
if (act_item && act_item.length > 0) {
|
||||
x.disabled = false
|
||||
} else {
|
||||
x.disabled = true
|
||||
}
|
||||
x["changeActitem"]=""
|
||||
})
|
||||
}
|
||||
else
|
||||
console.log("getOrderDetail 查無資料");
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
renderTabletContent(item) {
|
||||
let data = JSON.parse(item.f_num_tablet)
|
||||
let left = data.left_items
|
||||
let mid = data.mid_items
|
||||
let mid_right = data.mid_right
|
||||
let mid_left=data.mid_left
|
||||
let returnVal = ""
|
||||
if (left) {
|
||||
returnVal = "陽上:" + left.map(x => x.fam_name).join("、")
|
||||
}
|
||||
if (mid) {
|
||||
returnVal = returnVal + "<br>牌位正名:" + mid.map(x => x.fam_name).join("、")
|
||||
}
|
||||
if (mid_right) {
|
||||
returnVal = returnVal + "<br>右正名:" + mid_right.map(x => x.fam_name).join("、")
|
||||
}
|
||||
if (mid_left) {
|
||||
returnVal = returnVal + "<br>左正名:" + mid_left.map(x => x.fam_name).join("、")
|
||||
}
|
||||
return returnVal //item.actitem_num_selected.val+":" +
|
||||
},
|
||||
success_confirm() {
|
||||
this.message_dialog.show = false
|
||||
this.message_dialog.show_confirm=false
|
||||
this.follower = {}
|
||||
this.tablet_list.length = 0
|
||||
this.tablet_show=false
|
||||
},
|
||||
saveOrder() {
|
||||
let detail = []
|
||||
//整理資料存檔//只要抓那個活動的那幾筆功德項目代號
|
||||
this.tablet_list.forEach(x => {
|
||||
|
||||
if (x.actitem_num_checked && x.actitem_num_checked == true) {
|
||||
//console.log("OOQ:", x.num)
|
||||
let actItem = this.act_items.find(y => y.act_item_selected.val == x.actitem_num_selected.val)
|
||||
detail.push({
|
||||
num: x.num, order_no: x.order_no, change_item_num: x.changeActitem,
|
||||
price: actItem.price, qty: 1, style: actItem.act_item_selected.style, printed_files: actItem.files[0].num
|
||||
})
|
||||
// console.log("saveOrder:", x, x.num, x.order_no)
|
||||
}
|
||||
})
|
||||
|
||||
//放主檔資料,
|
||||
let main = {
|
||||
activity_num: this.num, f_num: this.follower.num,
|
||||
details: detail
|
||||
}
|
||||
//console.log("saveOrderDetail:",detail);
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/SaveWithDetails', main)
|
||||
.then(response => {
|
||||
//console.log("哪尼:",response)
|
||||
if (response.data.result && response.data.result === "Y") {
|
||||
//console.log("shit");
|
||||
}
|
||||
//console.log("蝦:", response)
|
||||
this.message_dialog.show_confirm = true
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message = response.data.message
|
||||
}).catch(error => {
|
||||
this.message_dialog.show_confirm = false
|
||||
this.message_dialog.show = true
|
||||
this.message_dialog.message =error
|
||||
console.log(error)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.hr-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.hr-text::before,
|
||||
.hr-text::after {
|
||||
content: "";
|
||||
flex: 1;
|
||||
border-top: 1px solid #ccc; /* 分隔線樣式 */
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.hr-text::before {
|
||||
content: attr(data-content);
|
||||
padding: 0 50px;
|
||||
color: black;
|
||||
font-size: 28px;
|
||||
}
|
||||
/* 当 checkbox 被禁用时,改变鼠标状态 */
|
||||
input[type="checkbox"]:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.4; /* 控制反灰程度 */
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.disabled-checkbox {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.8; /* 控制反灰程度 */
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.enabled-checkbox {
|
||||
}
|
||||
|
||||
.v-dialog{
|
||||
width:500px !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,432 @@
|
||||
<template>
|
||||
<div class="container-fluid">
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h4>快速報名</h4>
|
||||
<div class="ms-auto">
|
||||
<v-btn @click.prevent="addOrderWithDetail()">儲存</v-btn>
|
||||
<v-btn @click.prevent="back01()">返回</v-btn>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field v-model="follower.u_name" :rules="requiredrules"
|
||||
label="*姓名"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field v-model="follower.phone" :rules="phonerules"
|
||||
label="*電話"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field v-model="follower.cellphone" :rules="cellrules"
|
||||
label="*行動電話"></v-text-field>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="2" md="2">
|
||||
e <v-select :items="countrys" :rules="requiredrules"
|
||||
label="*國籍"
|
||||
item-text="name_zh"
|
||||
item-value="id" v-model="follower.country">
|
||||
</v-select>
|
||||
<!--<v-text-field v-model="follower.country" :rules="requiredrules"
|
||||
label="*國籍"></v-text-field>-->
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field v-model="follower.id_code"
|
||||
label="身分證號碼"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-text-field v-model="follower.passport"
|
||||
label="旅行證件號碼"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-select :items="sex_items" :rules="requiredrules"
|
||||
label="*性別"
|
||||
item-text="text"
|
||||
item-value="val" v-model="follower.sex">
|
||||
</v-select>
|
||||
<!--<v-text-field v-model="follower.sex" :rules="[rules.required]"
|
||||
label="*性別"></v-text-field>-->
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-select :items="identity_items" :rules="requiredrules"
|
||||
label="*身分別"
|
||||
item-text="text"
|
||||
item-value="val" v-model="follower.identity_type">
|
||||
</v-select>
|
||||
<!--<v-text-field v-model="follower.identity_type" :rules="[rules.required]"
|
||||
label="*身分別"></v-text-field>-->
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-menu v-model="menu"
|
||||
:close-on-content-click="false"
|
||||
:nudge-right="40"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="follower.birthday"
|
||||
label="生日"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="follower.birthday"
|
||||
@input="menu = false"></v-date-picker>
|
||||
</v-menu>
|
||||
<!--<v-date-picker v-model="follower.birthday"
|
||||
label="生日"></v-date-picker>-->
|
||||
<!--<v-text-field v-model="follower.birthday"
|
||||
label="生日"></v-text-field>-->
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-checkbox v-model="follower.send_receipt"
|
||||
label="寄送收據"></v-checkbox>
|
||||
</v-col>
|
||||
<v-col cols="4" md="4">
|
||||
<v-text-field v-model="follower.receipt_title"
|
||||
label="收據抬頭"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" md="12">
|
||||
<v-text-field v-model="follower.address"
|
||||
label="地址"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<hr class="hr-text" data-content="功德項目">
|
||||
<v-row>
|
||||
<v-col cols="3" md="3">
|
||||
<v-select :items="act_items"
|
||||
label="功德項目"
|
||||
item-text="act_item_selected.text"
|
||||
item-value="act_item_selected.val" v-model="select_act_item">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="2" md="2">
|
||||
<v-btn @click.prevent="newTablet()">新增</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="12">
|
||||
<v-expansion-panels>
|
||||
<v-expansion-panel v-for="(item,i) in tablets"
|
||||
:key="i">
|
||||
<v-expansion-panel-header>
|
||||
<h2>{{ item.actItem_subject }}</h2>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col col="12" md="1">
|
||||
標題
|
||||
</v-col>
|
||||
<v-col col="12" md="11">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field v-model="title_new.name"
|
||||
label="姓名"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="live_select"
|
||||
label="存/歿"
|
||||
item-text="text"
|
||||
item-value="val" v-model="title_new.islive">
|
||||
</v-select>
|
||||
<!--<v-text-field v-model="title_new.islive"
|
||||
label="存/歿"></v-text-field>-->
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn @click.prevent="addTitle(item)">加入</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12" md="12">
|
||||
{{ renderContent( item.tablet.title) }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="checkType(item)">
|
||||
<v-col col="12" md="1">
|
||||
陽上
|
||||
</v-col>
|
||||
<v-col col="12" md="11">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field v-model="alive_new.name"
|
||||
label="姓名"></v-text-field>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-select :items="live_select"
|
||||
label="存/歿"
|
||||
item-text="text"
|
||||
item-value="val" v-model="alive_new.islive">
|
||||
</v-select>
|
||||
<!--<v-text-field v-model="alive_new.islive"
|
||||
label="存/歿"></v-text-field>-->
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-btn @click.prevent="addLive(item)">加入</v-btn>
|
||||
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12" md="12">
|
||||
{{ renderContent( item.tablet.alive) }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
props: {
|
||||
num: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
follower: {
|
||||
u_name: "", sex: "", identity_type: "", phone: "",
|
||||
cellphone: "", country: "", address: "",
|
||||
birthday: "", send_recript: "", receipt_title: "",
|
||||
id_code:"",passport:""
|
||||
},
|
||||
act_items: [],
|
||||
search: {},
|
||||
date: new Date().toISOString().substr(0, 10),
|
||||
menu: false,
|
||||
tablets: [],
|
||||
select_act_item: {},
|
||||
title_new: { name: "", islive: true },
|
||||
alive_new: { name: "", islive: true },
|
||||
live_select: [
|
||||
{ val: true, text: '存' },
|
||||
{ val: false, text: '歿' },
|
||||
],
|
||||
requiredrules: [
|
||||
v=>!!v||'必須填寫',
|
||||
],
|
||||
cellrules: [
|
||||
v => (!!v||!!this.follower.phone) || '行動電話或電話為必須擇一填寫',
|
||||
v => /^09\d{2}-?\d{3}-?\d{3}$/.test(v) || '行動電話必須為09xx-xxx-xxx',
|
||||
],
|
||||
phonerules: [
|
||||
v => (!!v || !!this.follower.cellphone) || '行動電話或電話為必須擇一填寫',
|
||||
],
|
||||
sex_items: [
|
||||
{ text: "男眾", val: "男眾" },
|
||||
{ text: "女眾", val: "女眾" },
|
||||
],
|
||||
identity_items: [
|
||||
{ text: "出家眾", val: "1" },
|
||||
{ text: "個人", val: "2" },
|
||||
{ text: "法人", val: "3" },
|
||||
{ text: "往生菩薩", val: "4" },
|
||||
{ text: "蓮友", val: "10" },
|
||||
],
|
||||
countrys:[]
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.getActItem();
|
||||
this.getCountrys();
|
||||
},
|
||||
methods: {
|
||||
back01() {
|
||||
this.$emit('custom-event', { action: 'signup1', item: this.num });
|
||||
},
|
||||
addOrderWithDetail() {
|
||||
//組資料,信眾資料,報名資料,功德資料
|
||||
let details = []
|
||||
|
||||
|
||||
this.tablets.forEach(x => {
|
||||
let mid_items = []
|
||||
let left_items = []
|
||||
if (x.tablet.title) {
|
||||
x.tablet.title.forEach(y => {
|
||||
mid_items.push(
|
||||
{
|
||||
num: 0,
|
||||
follower_num: 0,
|
||||
fam_name: y.name,
|
||||
deceased: !y.islive,
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
if (x.tablet.alive) {
|
||||
x.tablet.alive.forEach(y => {
|
||||
left_items.push(
|
||||
{
|
||||
num: 0,
|
||||
follower_num: 0,
|
||||
fam_name: y.name,
|
||||
deceased: !y.islive,
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
//let f_num_tablet = {
|
||||
// mid_items: mid_items,
|
||||
// left_items:left_items
|
||||
//}//這應該只存名字跟存歿,因為還要先存親友資料取得num
|
||||
details.push({
|
||||
num: 0,
|
||||
actItem_num: x.actItem_num,
|
||||
price: x.price,
|
||||
qty: x.qty,
|
||||
printed_files: x.files.val,
|
||||
style: x.style,
|
||||
mid_items: mid_items,
|
||||
left_items: left_items,
|
||||
})
|
||||
})
|
||||
|
||||
let order = {
|
||||
order_no: "",
|
||||
f_num: 0,
|
||||
u_name: "",
|
||||
activity_num: this.num,
|
||||
phone: this.follower.phone,
|
||||
address: this.follower.address,
|
||||
send_recript: this.follower.send_recript,
|
||||
receipt_title: this.follower.receipt_title,
|
||||
f_user: this.follower,
|
||||
details:details
|
||||
}
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/AddOrderWithDetail', order)
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
})
|
||||
},
|
||||
renderContent(titles) {
|
||||
return titles.map(title => title.name).join('、');
|
||||
//return title.join("、")
|
||||
},
|
||||
checkType(item) {
|
||||
if (item.actItem_subject.startsWith("超")) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
addTitle(item) {
|
||||
item.tablet.title.push({
|
||||
name: this.title_new.name, islive: this.title_new.islive
|
||||
});
|
||||
this.title_new = { name: "", islive: this.title_new.islive }
|
||||
},
|
||||
addLive(item) {
|
||||
item.tablet.alive.push({
|
||||
name: this.alive_new.name, islive: this.alive_new.islive
|
||||
});
|
||||
this.alive_new = { name: "", islive: this.alive_new.islive }
|
||||
},
|
||||
newTablet() {
|
||||
console.log(this.act_items);
|
||||
console.log(this.select_act_item);
|
||||
let item = this.act_items.find(x => x.act_item_selected.val == this.select_act_item);
|
||||
this.tablets.push({
|
||||
actItem_num: item.act_item_selected.val,
|
||||
actItem_subject: item.act_item_selected.text,
|
||||
f_num_tablet: [],
|
||||
num: this.tablets.length,
|
||||
qty: 1,
|
||||
price: item.price,
|
||||
files: item.files,
|
||||
style: item.act_item_selected.style,
|
||||
tablet: {
|
||||
title: [],
|
||||
alive: []
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
getCountrys() {
|
||||
let search = {}
|
||||
let params = { sortBy: 'ID', sortDesc: false, page: 1, pageSize: -1 };
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/country/GetList', this.search, { params: params })
|
||||
.then(response => {
|
||||
|
||||
if (response.data.list) {
|
||||
this.countrys = response.data.list
|
||||
}
|
||||
else
|
||||
console.log("查無資料");
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
getActItem() {//抓法會可用功德項目
|
||||
this.act_items.length = 0
|
||||
this.search = { num: this.num }
|
||||
let params = { sortBy: 'num', sortDesc: false, page: 1, pageSize: -1 };
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/GetActRelaList', this.search, { params: params })
|
||||
.then(response => {
|
||||
|
||||
if (response.data.list) {
|
||||
this.act_items = response.data.list
|
||||
console.log(this.act_items);
|
||||
}
|
||||
else
|
||||
console.log("查無資料");
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.hr-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.hr-text::before,
|
||||
.hr-text::after {
|
||||
content: "";
|
||||
flex: 1;
|
||||
border-top: 1px solid #ccc; /* 分隔線樣式 */
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.hr-text::before {
|
||||
content: attr(data-content);
|
||||
padding: 0 50px;
|
||||
color: black;
|
||||
font-size: 28px;
|
||||
}
|
||||
/* 当 checkbox 被禁用时,改变鼠标状态 */
|
||||
input[type="checkbox"]:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.4; /* 控制反灰程度 */
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.disabled-checkbox {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.8; /* 控制反灰程度 */
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.enabled-checkbox {
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div class="container-fluid">
|
||||
<v-card>
|
||||
<v-card-title class="bg-primary white--text text-center">
|
||||
<h4>批次報名</h4>
|
||||
<div class="ms-auto">
|
||||
<v-btn @click.prevent="batchSave()">儲存</v-btn>
|
||||
<v-btn @click.prevent="back01()">返回</v-btn>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-select :items="data_table.list"
|
||||
label="選擇法會"
|
||||
item-text="subject"
|
||||
item-value="num" v-model="selected">
|
||||
</v-select>
|
||||
<v-data-table v-model="detail_table.selected"
|
||||
:items="detail_table.list"
|
||||
:headers="detail_table.header"
|
||||
:footer-props="detail_table.footer"
|
||||
:server-items-length="detail_table.count"
|
||||
:loading="detail_table.loading"
|
||||
show-select
|
||||
item-key="order_no"
|
||||
hide-default-footer
|
||||
:page.sync="detail_table.page"
|
||||
:items-per-page.sync="detail_table.pageSize"
|
||||
class="elevation-1">
|
||||
<template #item.slot_btn="{ item }">
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-dialog v-model="message_dialog.show" class="dialog_width">
|
||||
<template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ message_dialog.message }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn @click.prevent="message_dialog.show=false" v-if="!message_dialog.show_confirm">關閉</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
module.exports = {
|
||||
props: {
|
||||
num: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
message_dialog: { show: false, show_confirm: false, message: "" },
|
||||
data_table: {
|
||||
loading: true,
|
||||
list: [],
|
||||
selected: [],
|
||||
singleSelect: false,
|
||||
count: 0,
|
||||
page: 1,
|
||||
pageSize: -1,
|
||||
},
|
||||
selected: null,
|
||||
detail_table: {
|
||||
loading: false,
|
||||
list: [],
|
||||
selected: [],
|
||||
singleSelect: false,
|
||||
count: 0,
|
||||
page: 1,
|
||||
pageSize: -1,
|
||||
header: [
|
||||
{ text: '單號', value: 'order_no' },
|
||||
{ text: '信眾號碼', value: 'f_num' },
|
||||
{ text: '姓名', value: 'u_name' },
|
||||
{ text: '報名日期', value: 'up_time' },
|
||||
{ text: '單據狀態', value: 'keyin1_txt', align: 'start' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
|
||||
],
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
itemsPerPageOptions: [5, 10, 20, 30],
|
||||
},
|
||||
},
|
||||
search: {subject:""}
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.getActivity()
|
||||
},
|
||||
watch: {
|
||||
selected: {
|
||||
handler() {
|
||||
this.getProOrder()
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
batchSave() {//批次存檔
|
||||
const orders = []
|
||||
this.detail_table.selected.forEach(x => {
|
||||
orders.push(x.order_no)
|
||||
})
|
||||
const po = {
|
||||
old_activity_num: this.selected,
|
||||
activity_num: this.num,
|
||||
orders: orders
|
||||
}
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/BatchSave', po)
|
||||
.then(response => {
|
||||
this.message_dialog.show = true;
|
||||
|
||||
if (response.data.result == "Y") {
|
||||
let rp = response.data.data;
|
||||
let other = ""
|
||||
if (rp && rp.length>0) {
|
||||
other = rp.join(",")
|
||||
other = ",以下信眾號碼已經報過名:" + other;
|
||||
}
|
||||
this.message_dialog.message = response.data.message + other;
|
||||
if (rp.length > 0) {
|
||||
} else {
|
||||
this.$emit('custom-event', { action: 'signup1', item: this.num });
|
||||
}
|
||||
} else {
|
||||
this.message_dialog.message = response.data.message
|
||||
}
|
||||
}).catch(error => console.log(error))
|
||||
},
|
||||
back01() {//返回
|
||||
this.$emit('custom-event', { action: 'signup1', item: this.num });
|
||||
},
|
||||
getActivity() {//撈法會資料
|
||||
//const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: "startDate_solar", sortDesc: true,
|
||||
page: 1, pageSize: -1
|
||||
};
|
||||
this.data_table.loading = true
|
||||
const self = this
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/GetListNew', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.list=this.data_table.list.filter(x=>x.num!=self.num)
|
||||
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
getProOrder() {//撈報名資料,勾選要報名的人
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
sortBy: "order_no", sortDesc: true,
|
||||
page: 1, pageSize: -1
|
||||
};
|
||||
let newsearch = {
|
||||
activity_num: this.selected
|
||||
}
|
||||
this.detail_table.loading = true
|
||||
// sessionStorage.setItem('orderpage', '1');// clearpage ? '1' : page
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/GetList', newsearch, { params: params })
|
||||
.then(response => {
|
||||
this.detail_table.list = response.data.list
|
||||
this.detail_table.count = response.data.count;
|
||||
this.detail_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.v-dialog{
|
||||
width:80% !important;
|
||||
}
|
||||
</style>
|
||||
+233
-61
@@ -14,17 +14,18 @@
|
||||
<a @click="print_dialog.show=true" class="btn btn-outline-primary btn-print" target="_blank">
|
||||
<i class="mdi mdi-printer"></i>列印管理報表
|
||||
</a>
|
||||
|
||||
<div class="dropdown d-inline-block">
|
||||
<a class="btn btn-outline-primary btn-print dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><i class="mdi mdi-printer"></i>列印報名資料</a>
|
||||
<ul class="dropdown-menu ps-0 w-100" aria-labelledby="dropdownPrintLink">
|
||||
<li><a @click="search.hasPrice='Y';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>有金額</a></li>
|
||||
<li><a @click="search.hasPrice='N';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>無金額</a></li>
|
||||
</ul>
|
||||
<div :style="data_table.list.length === 0 ? 'pointer-events: none; opacity: 0.5;' : ''" style="display:inline-block;">
|
||||
<div class="dropdown d-inline-block">
|
||||
<a class="btn btn-outline-primary btn-print dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><i class="mdi mdi-printer"></i>列印查詢資料</a>
|
||||
<ul class="dropdown-menu ps-0 w-100" aria-labelledby="dropdownPrintLink">
|
||||
<li><a @click="search.hasPrice='Y';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>有金額</a></li>
|
||||
<li><a @click="search.hasPrice='N';goPrint()" class="dropdown-item"><i class="mdi mdi-printer me-1"></i>無金額</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div :style="data_table.list.length === 0 ? 'pointer-events: none; opacity: 0.5;' : ''" style="display:inline-block;">
|
||||
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出查詢資料(Excel)</asp:LinkButton>
|
||||
</div>
|
||||
|
||||
<asp:LinkButton ID="excel" runat="server" CssClass="btn btn-outline-success" OnClick="excel_Click"><span class="fa-solid fa-file-excel"></span> 匯出Excel</asp:LinkButton>
|
||||
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" runat="Server">
|
||||
@@ -39,6 +40,8 @@
|
||||
vuetify: new Vuetify(vuetify_options),
|
||||
data() {
|
||||
return {
|
||||
print_error_msg: "",
|
||||
isSearched: false,
|
||||
this_act : '<%= Request["act_id"]%>',
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
@@ -56,6 +59,7 @@
|
||||
{ text: '報名日期', value: 'up_time' },
|
||||
{ text: '報名活動', value: 'subject', align: 'start' },
|
||||
{ text: '單據狀態', value: 'keyin1_txt' },
|
||||
{ text: '報到狀態', value: 'status' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
|
||||
],
|
||||
footer:{
|
||||
@@ -203,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const printResult = document.getElementById('<%= hid_err_msg.ClientID %>').value;
|
||||
document.getElementById('<%= hid_err_msg.ClientID %>').value = '';
|
||||
window._printResult = printResult
|
||||
|
||||
this.detalKeyinArray();
|
||||
this.search_dialog.current = this.search_dialog.controls.search1 ///default
|
||||
if (this.this_act != '')
|
||||
@@ -211,20 +219,63 @@
|
||||
this.initActivity();
|
||||
const navEntries = performance.getEntriesByType("navigation");
|
||||
const isReload = navEntries.length > 0 && navEntries[0].type === "reload";
|
||||
|
||||
if (isReload) {
|
||||
sessionStorage.removeItem("orderpage");
|
||||
sessionStorage.removeItem("order_list_cache");
|
||||
sessionStorage.removeItem("order_query_params");
|
||||
}
|
||||
else if ("<%=lastAddedNo%>" !== "") {
|
||||
const newQuery = { order_no: '<%=lastAddedNo%>' };
|
||||
sessionStorage.setItem('order_query_params', JSON.stringify(newQuery));
|
||||
this.search = newQuery;
|
||||
this.isSearched = true;
|
||||
}
|
||||
else {
|
||||
const savedPage = parseInt(sessionStorage.getItem('orderpage'));
|
||||
const savedData = sessionStorage.getItem("order_list_cache");
|
||||
const savedQuery = JSON.parse(sessionStorage.getItem("order_query_params"));
|
||||
if (savedQuery) {
|
||||
this.search = savedQuery;
|
||||
this.isSearched = true;
|
||||
}
|
||||
if (savedPage) {
|
||||
this.options.page = savedPage;
|
||||
}
|
||||
}
|
||||
if (savedData && savedData !== "undefined") {
|
||||
this.data_table = JSON.parse(savedData);
|
||||
this.isSearched = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (printResult === 'nodata' || printResult === 'success') {
|
||||
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.print_dialog.show = true;
|
||||
if (printResult === 'nodata') {
|
||||
this.print_error_msg = "查無資料,請重新選擇區間";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
// 清空 URL
|
||||
const cleanUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||
window.history.replaceState({}, '', cleanUrl);
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler() {
|
||||
this.getDefault()
|
||||
if (this.isSearched) {
|
||||
this.getDefault()
|
||||
}
|
||||
else {
|
||||
this.data_table.loading = false;
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
@@ -236,6 +287,57 @@
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
triggerManagementExport(mode) {
|
||||
this.print_error_msg = "";
|
||||
if (this.print_search.year == '') {
|
||||
msgbox('請輸入年份');
|
||||
return;
|
||||
}
|
||||
if (!this.print_search.chk_noact && !this.print_search.chk_hasact) {
|
||||
msgbox('活動/非活動至少勾選一項');
|
||||
return;
|
||||
}
|
||||
|
||||
// 將 Vue 狀態同步至 ASP.NET HiddenField,供後端 PostBack 讀取參數
|
||||
document.getElementById('<%= hid_print_mode.ClientID %>').value = this.print_conditions;
|
||||
document.getElementById('<%= hid_print_year.ClientID %>').value = this.print_search.year;
|
||||
if (this.print_conditions == 'mm')
|
||||
document.getElementById('<%= hid_print_month.ClientID %>').value = this.print_search.month;
|
||||
else if (this.print_conditions == 'ss')
|
||||
document.getElementById('<%= hid_print_season.ClientID %>').value = this.print_search.season;
|
||||
document.getElementById('<%= hid_select_act.ClientID %>').value = this.print_search.select_act;
|
||||
document.getElementById('<%= hid_select_actitem.ClientID %>').value = this.print_search.select_actitem;
|
||||
document.getElementById('<%= hid_chk_hasact.ClientID %>').value = this.print_search.chk_hasact;
|
||||
document.getElementById('<%= hid_chk_noact.ClientID %>').value = this.print_search.chk_noact;
|
||||
|
||||
let qry = "";
|
||||
Object.keys(this.print_search).forEach(key => {
|
||||
if (this.print_search[key] != undefined && this.print_search[key] != null && this.print_search[key] != '') {
|
||||
if (key == 'month' ) {
|
||||
if (this.print_conditions == 'mm') {
|
||||
qry += "&month=" + this.print_search.month;
|
||||
}
|
||||
} else if ( key == 'season')
|
||||
{
|
||||
if (this.print_conditions == 'ss') {
|
||||
qry += "&season=" + this.print_search.season;
|
||||
}
|
||||
}
|
||||
else {
|
||||
qry += (qry != '' ? '&' : '?') + (key + '=' + this.print_search[key]);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
document.getElementById('<%= hid_qry.ClientID %>').value = qry;
|
||||
|
||||
if (mode === 'print') {
|
||||
document.getElementById('<%= print_management.ClientID %>').click();
|
||||
}
|
||||
else if (mode === "excel") {
|
||||
document.getElementById('<%= excel_management.ClientID %>').click();
|
||||
}
|
||||
},
|
||||
search_show(curr) {
|
||||
//console.log("btn_click:", curr, curr.api_url);
|
||||
this.search_dialog.current = curr;
|
||||
@@ -321,19 +423,24 @@
|
||||
this.data_table.list = response.data.list
|
||||
this.data_table.count = response.data.count;
|
||||
this.data_table.loading = false
|
||||
|
||||
const dataToStore = JSON.stringify(this.data_table);
|
||||
sessionStorage.setItem("order_list_cache", dataToStore);
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
detalKeyinArray() {
|
||||
var getArray = <%=Newtonsoft.Json.JsonConvert.SerializeObject(_keyin1Item, Newtonsoft.Json.Formatting.Indented) %>;
|
||||
var keys = Object.keys(getArray);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
//console.log(`${keys[i]}:${getArray[keys[i]]}`); //value : text
|
||||
var _tmp = {
|
||||
text: getArray[keys[i]],
|
||||
val: parseInt(keys[i]),
|
||||
if (getArray !== null) {
|
||||
var keys = Object.keys(getArray);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
//console.log(`${keys[i]}:${getArray[keys[i]]}`); //value : text
|
||||
var _tmp = {
|
||||
text: getArray[keys[i]],
|
||||
val: parseInt(keys[i]),
|
||||
}
|
||||
this.keyin1_items.push(_tmp);
|
||||
}
|
||||
this.keyin1_items.push(_tmp);
|
||||
}
|
||||
|
||||
},
|
||||
@@ -368,22 +475,28 @@
|
||||
//}
|
||||
//this.data_table.selected = [];
|
||||
//this.data_table.count = this.data_table.list.length
|
||||
location.reload();
|
||||
//location.reload();
|
||||
this.getDefault();
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
}
|
||||
},
|
||||
btn_search() {
|
||||
this.isSearched = true;
|
||||
sessionStorage.setItem("order_query_params", JSON.stringify(this.search));
|
||||
this.this_act = '';
|
||||
this.search.activity_num = '';
|
||||
|
||||
this.getDefault(true)
|
||||
bootstrap.Offcanvas.getInstance(document.getElementById("offcanvasRight")).hide()
|
||||
},
|
||||
btn_all() {
|
||||
this.isSearched = false;
|
||||
this.this_act = '';
|
||||
this.search.activity_num = '';
|
||||
clearObjProps(this.search);
|
||||
this.btn_search()
|
||||
sessionStorage.setItem("order_query_params", JSON.stringify(this.search));
|
||||
//this.btn_search()
|
||||
},
|
||||
checkInMsg(item) {
|
||||
this.check_data.f_num = item.f_num;
|
||||
@@ -392,39 +505,59 @@
|
||||
this.check_data.activity_name = item.subject;
|
||||
this.check_dialog.show = true;
|
||||
},
|
||||
checkIn() {
|
||||
if (this.check_data.qty > 0 && this.check_data.status.val > 0) {
|
||||
var chechdata =
|
||||
{
|
||||
f_num: this.check_data.f_num,
|
||||
activity_num: this.check_data.activity_num,
|
||||
status: this.check_data.status.val,
|
||||
qty: this.check_data.qty,
|
||||
}
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/OrderCheckIn', chechdata)
|
||||
.then(response => {
|
||||
//清空
|
||||
this.check_data.f_num = 0;
|
||||
this.check_data.u_name = '';
|
||||
this.check_data.activity_num = 0;
|
||||
this.check_data.activity_name = '';
|
||||
this.check_data.qty = 1;
|
||||
this.check_data.status.text = '';
|
||||
this.check_data.status.val = 1;
|
||||
|
||||
this.check_dialog.show = false;
|
||||
msgtop('簽到成功')
|
||||
})
|
||||
.catch(
|
||||
error => {
|
||||
console.log(error)
|
||||
msgtop('簽到失敗', 'error')
|
||||
}
|
||||
)
|
||||
} else {
|
||||
msgbox('報到資訊請填寫完整');
|
||||
checkIn(item) {
|
||||
var checkdata =
|
||||
{
|
||||
f_num: item.f_num,
|
||||
activity_num: item.activity_num,
|
||||
status: 1,
|
||||
qty: 1,
|
||||
}
|
||||
console.log(checkdata)
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/activity/OrderCheckIn', checkdata)
|
||||
.then(response => {
|
||||
msgtop('簽到成功');
|
||||
this.getDefault();
|
||||
})
|
||||
.catch(
|
||||
error => {
|
||||
console.log(error)
|
||||
msgtop('簽到失敗', 'error')
|
||||
}
|
||||
)
|
||||
//if (this.check_data.qty > 0 && this.check_data.status.val > 0) {
|
||||
// var chechdata =
|
||||
// {
|
||||
// f_num: this.check_data.f_num,
|
||||
// activity_num: this.check_data.activity_num,
|
||||
// status: this.check_data.status.val,
|
||||
// qty: this.check_data.qty,
|
||||
// }
|
||||
// axios
|
||||
// .post(HTTP_HOST + 'api/activity/OrderCheckIn', chechdata)
|
||||
// .then(response => {
|
||||
// //清空
|
||||
// this.check_data.f_num = 0;
|
||||
// this.check_data.u_name = '';
|
||||
// this.check_data.activity_num = 0;
|
||||
// this.check_data.activity_name = '';
|
||||
// this.check_data.qty = 1;
|
||||
// this.check_data.status.text = '';
|
||||
// this.check_data.status.val = 1;
|
||||
|
||||
// this.check_dialog.show = false;
|
||||
// msgtop('簽到成功')
|
||||
// })
|
||||
// .catch(
|
||||
// error => {
|
||||
// console.log(error)
|
||||
// msgtop('簽到失敗', 'error')
|
||||
// }
|
||||
// )
|
||||
//} else {
|
||||
// msgbox('報到資訊請填寫完整');
|
||||
//}
|
||||
}, goPrint() {
|
||||
let _qry = "";
|
||||
Object.keys(this.search).forEach(key => {
|
||||
@@ -442,6 +575,7 @@
|
||||
//列印管理報表
|
||||
print_close() {
|
||||
this.print_dialog.show = false;
|
||||
this.print_error_msg = "";
|
||||
}
|
||||
,
|
||||
initPrintSearch() {
|
||||
@@ -504,9 +638,9 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(_qry);
|
||||
this.print_dialog.show = false;
|
||||
window.open("print.aspx" + _qry, '_blank');
|
||||
//window.open("print.aspx" + _qry, '_blank');
|
||||
} else {
|
||||
msgbox('活動/非活動至少勾選一項');
|
||||
}
|
||||
@@ -537,7 +671,7 @@
|
||||
initActivity() {
|
||||
axios.get(HTTP_HOST + 'api/activity')
|
||||
.then(response => {
|
||||
this.select_act_list = response.data
|
||||
this.select_act_list = response.data
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
@@ -556,10 +690,35 @@
|
||||
$('#country2').val('');
|
||||
VueApp.search.country2 = '';
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
// 判斷是否彈出 search dialog
|
||||
let hasSearchResult = sessionStorage.getItem("order_list_cache") !== null;
|
||||
|
||||
if (!hasSearchResult && window._printResult === '') {
|
||||
let $btn = $("a[data-bs-target='#offcanvasRight'][href='#search_panel']");
|
||||
$btn.click();
|
||||
let el = document.getElementById('offcanvasRight');
|
||||
let offcanvas = bootstrap.Offcanvas.getOrCreateInstance(el);
|
||||
offcanvas.show();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
||||
<asp:HiddenField ID="hid_err_msg" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_year" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_month" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_season" runat="server" />
|
||||
<asp:HiddenField ID="hid_print_mode" runat="server" />
|
||||
<asp:HiddenField ID="hid_chk_hasact" runat="server" />
|
||||
<asp:HiddenField ID="hid_chk_noact" runat="server" />
|
||||
<asp:HiddenField ID="hid_select_act" runat="server" />
|
||||
<asp:HiddenField ID="hid_select_actitem" runat="server" />
|
||||
<asp:HiddenField ID="hid_qry" runat="server" />
|
||||
<asp:LinkButton ID="print_management" runat="server" OnClick="export_Click" style="display:none;" />
|
||||
<asp:LinkButton ID="excel_management" runat="server" OnClick="export_Click" style="display:none;" />
|
||||
<div id="content" class="container-fluid">
|
||||
<v-data-table
|
||||
v-model="data_table.selected"
|
||||
@@ -580,10 +739,13 @@
|
||||
<template #item.up_time="{ item }" >
|
||||
{{ item.up_time|timeString('YYYY/MM/DD') }}
|
||||
</template>
|
||||
<template #item.u_name="{ item }" >
|
||||
<a v-if="item.f_num != null && item.activity_num != null" @click="checkInMsg(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-account-check"></i>報到</a>
|
||||
<template #item.u_name="{ item }" >
|
||||
{{ item.u_name }}
|
||||
</template>
|
||||
<template #item.status="{ item }" >
|
||||
<a v-if="item.f_num != null && item.activity_num != null && item.status == 0" @click="checkIn(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-account"></i>報到</a>
|
||||
<a v-if="item.f_num != null && item.activity_num != null && item.status == 1" class="btn btn-outline-secondary btn-sm opacity-50" style="pointer-events: none" ><i class="mdi mdi-account-check"></i>已報到</a>
|
||||
</template>
|
||||
<template #item.slot_btn="{ item }">
|
||||
<a :href="'reg.aspx?order_no='+item.order_no" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-pencil-box-outline"></i>修改</a>
|
||||
<a @click="deleteItem(item)" class="btn btn-outline-secondary btn-sm"><i class="mdi mdi-trash-can"></i>刪除</a>
|
||||
@@ -692,7 +854,8 @@
|
||||
item-text="text"
|
||||
item-value="val"
|
||||
v-model="print_search.month"
|
||||
:items="select_items.month"
|
||||
:items="select_items.month"
|
||||
eager
|
||||
></v-select>
|
||||
</v-col>
|
||||
<v-col :cols="2" class="pt-5" v-if="print_conditions=='ss' ">
|
||||
@@ -703,7 +866,8 @@
|
||||
item-text="text"
|
||||
item-value="val"
|
||||
v-model="print_search.season"
|
||||
:items="select_items.season"
|
||||
:items="select_items.season"
|
||||
eager
|
||||
></v-select>
|
||||
</v-col>
|
||||
|
||||
@@ -764,9 +928,17 @@
|
||||
</v-row>
|
||||
</v-col>--%>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<div v-if="print_error_msg" class="red--text mt-2 text-center" style="font-weight: bold;">
|
||||
{{ print_error_msg }}
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row densee class="pt-3" >
|
||||
<v-col :cols="12" class="pt-3 text-center" >
|
||||
<v-btn class="ma-2" color="primary" dark @click="goPrint2" > 列印 </v-btn>
|
||||
<v-btn class="ma-2" color="primary" dark @click="triggerManagementExport('print')" > 列印 </v-btn>
|
||||
<v-btn class="ma-2" color="primary" dark @click="triggerManagementExport('excel')"> 匯出 Excel </v-btn>
|
||||
<v-btn class="ma-2" color="green" dark @click="print_close" > 取消 </v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
+565
-26
@@ -1,22 +1,28 @@
|
||||
using System;
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.OleDb;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using DocumentFormat.OpenXml.Packaging;
|
||||
using DocumentFormat.OpenXml;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using System.Linq;
|
||||
using static Model.admin_log;
|
||||
using static regionController;
|
||||
|
||||
public partial class admin_order_index : MyWeb.config
|
||||
{
|
||||
private Model.ezEntities _db = new Model.ezEntities();
|
||||
public Dictionary<int, string> _keyin1Item = null;
|
||||
protected string lastAddedNo;
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
@@ -33,6 +39,13 @@ public partial class admin_order_index : MyWeb.config
|
||||
}
|
||||
|
||||
_keyin1Item = publicFun.enum_desc<Model.activity_check.keyin1>(); //狀態
|
||||
|
||||
if (Session["LastAddedNo"] != null)
|
||||
{
|
||||
lastAddedNo = Session["LastAddedNo"].ToString();
|
||||
Session.Remove("LastAddedNo");
|
||||
}
|
||||
|
||||
BuildKind();
|
||||
|
||||
}
|
||||
@@ -58,6 +71,452 @@ public partial class admin_order_index : MyWeb.config
|
||||
#endregion
|
||||
#region 匯出Excel
|
||||
|
||||
protected void export_Click(object sender, EventArgs e)
|
||||
{
|
||||
LinkButton btn = sender as LinkButton;
|
||||
if (btn == null) return;
|
||||
bool isPrintMode = (btn.ID == "print_management");
|
||||
bool isExcelMode = (btn.ID == "excel_management" || btn.ID == "excel");
|
||||
|
||||
//查詢要匯出的資料
|
||||
string _query = ""; // 紀錄匯出條件
|
||||
//var list = searchData(ref _query, isManagementMode);
|
||||
|
||||
if (isExcelMode)
|
||||
{
|
||||
int selYear = !string.IsNullOrEmpty(hid_print_year.Value) ? int.Parse(hid_print_year.Value) : 0;
|
||||
int selMonth = !string.IsNullOrEmpty(hid_print_month.Value) ? int.Parse(hid_print_month.Value) : 0;
|
||||
int selSeason = !string.IsNullOrEmpty(hid_print_season.Value) ? int.Parse(hid_print_season.Value) : 0;
|
||||
string selMode = !string.IsNullOrEmpty(hid_print_mode.Value) ? hid_print_mode.Value : "";
|
||||
bool chkHasAct = !string.IsNullOrEmpty(hid_chk_hasact.Value) && Convert.ToBoolean(hid_chk_hasact.Value);
|
||||
bool chkNoAct = !string.IsNullOrEmpty(hid_chk_noact.Value) && Convert.ToBoolean(hid_chk_noact.Value);
|
||||
int selAct = !string.IsNullOrEmpty(hid_select_act.Value) ? int.Parse(hid_select_act.Value) : 0;
|
||||
int selActItem = !string.IsNullOrEmpty(hid_select_actitem.Value) ? int.Parse(hid_select_actitem.Value) : 0;
|
||||
|
||||
var qry = _db.pro_order.AsQueryable();
|
||||
|
||||
if (selYear > 0)
|
||||
{
|
||||
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Year == selYear);
|
||||
_query += "年份:" + selYear + "\n";
|
||||
}
|
||||
|
||||
if (selMode == "mm" && selMonth > 0)
|
||||
{
|
||||
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Month == selMonth);
|
||||
_query += "月份:" + selMonth + "\n";
|
||||
}
|
||||
|
||||
if (selMode == "ss" && selSeason > 0)
|
||||
{
|
||||
if (selSeason == 1)
|
||||
{
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 1 || o.up_time.Value.Month == 2 || o.up_time.Value.Month == 3);
|
||||
}
|
||||
else if (selSeason == 2)
|
||||
{
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 4 || o.up_time.Value.Month == 5 || o.up_time.Value.Month == 6);
|
||||
}
|
||||
else if (selSeason == 3)
|
||||
{
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 7 || o.up_time.Value.Month == 8 || o.up_time.Value.Month == 9);
|
||||
}
|
||||
else if (selSeason == 4)
|
||||
{
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 10 || o.up_time.Value.Month == 11 || o.up_time.Value.Month == 12);
|
||||
}
|
||||
|
||||
_query += "季度:" + selSeason + "\n";
|
||||
}
|
||||
|
||||
if (chkHasAct)
|
||||
{
|
||||
if(selAct > 0)
|
||||
{
|
||||
var actSubject = _db.activities.Where(a => a.num == selAct).Select(a => a.subject).FirstOrDefault();
|
||||
_query += $"活動報名: {actSubject}\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
_query += $"活動報名\n";
|
||||
}
|
||||
|
||||
if (chkNoAct)
|
||||
{
|
||||
_query += "非活動報名\n";
|
||||
if (selAct > 0)
|
||||
qry = qry.Where(o => o.activity_num.HasValue && o.activity_num.Value == selAct);
|
||||
}
|
||||
else
|
||||
{
|
||||
qry = qry.Where(o => o.activity_num.HasValue);
|
||||
if (selAct > 0)
|
||||
qry = qry.Where(o => o.activity_num.Value == selAct);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chkNoAct)
|
||||
{
|
||||
qry = qry.Where(o => o.activity_num == null);
|
||||
_query += "非活動報名\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (selActItem > 0)
|
||||
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem_num.Value == selActItem).Count() > 0);
|
||||
|
||||
if (selYear > 0)
|
||||
qry = qry.OrderByDescending(o => o.activity != null ? o.activity.startDate_solar : null).ThenByDescending(o => o.up_time).ThenByDescending(o => o.order_no);
|
||||
else
|
||||
qry = qry.OrderByDescending(o => o.order_no);
|
||||
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
var tdesc = publicFun.enum_desc<Model.pro_order.detailKeyin1>();
|
||||
var bedDt = _db.bed_order_detail.AsQueryable();//掛單明細
|
||||
|
||||
//紀錄匯出條件
|
||||
//var list = qry.ToList();
|
||||
var list = qry.GroupJoin(
|
||||
_db.pro_order_detail, o => o.order_no, p => p.order_no, (o, c) =>
|
||||
new
|
||||
{
|
||||
//訂單資料
|
||||
order_no = o.order_no,
|
||||
up_time = o.up_time,
|
||||
keyin1 = o.keyin1,
|
||||
f_num = o.follower != null ? o.follower.u_name : "", //姓名/名稱
|
||||
phone = o.phone,
|
||||
activity_num = o.activity_num.HasValue ? o.activity.subject : "",
|
||||
address = o.address,
|
||||
demo = o.demo,
|
||||
c
|
||||
}).SelectMany(o => o.c.DefaultIfEmpty(), (o, d) => //SelectMany 展開
|
||||
new
|
||||
{
|
||||
//訂單資料
|
||||
order_no = o.order_no,
|
||||
up_time = o.up_time,
|
||||
keyin1 = o.keyin1,
|
||||
f_num = o.f_num, //姓名/名稱
|
||||
phone = o.phone,
|
||||
activity_num = o.activity_num,
|
||||
address = o.address,
|
||||
demo = o.demo,
|
||||
|
||||
//訂單明細
|
||||
//使用DefaultIfEmpty 因匿名型別無法輸出NULL(無法轉換成強型別),需特別注意Null的處理
|
||||
d_actItem_num = d == null ? "" : (d.actItem_num.HasValue ? d.actItem.subject : ""), //項目名稱
|
||||
d_category = d == null ? "" : (d.actItem_num.HasValue ? d.actItem.category.ToString() : ""),
|
||||
d_f_num = d == null ? "" : (d.f_num.HasValue ? d.follower.u_name : ""), //姓名
|
||||
d_address = d == null ? "" : d.address,
|
||||
d_from_id = d == null ? "" : (d.from_id.HasValue ? d.follower1.u_name : ""), //陽上/報恩者
|
||||
d_f_num_tablet = d == null ? "" : d.f_num_tablet,
|
||||
d_start_date = d == null ? (DateTime?)null : d.start_date, //開始日期
|
||||
d_due_date = d == null ? (DateTime?)null : d.due_date, //期滿日期
|
||||
d_extend_date = d == null ? (DateTime?)null : d.extend_date, //應續約日
|
||||
d_price = d == null ? (float?)null : d.price, //預設金額
|
||||
d_qty = d == null ? "" : (d.qty.HasValue ? d.qty.Value.ToString() : "0"), //數量
|
||||
d_writeBedQty = d == null ? 0 : bedDt.Where(b => (b.bed_order.o_detail_id.Value == d.num) && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count(), //已劃數量
|
||||
d_notBedQty = d == null ? 0 : bedDt.Where(b => b.bed_order.o_detail_id.Value == d.num && (!b.checkIn_date.HasValue || !b.bed_kind_detail_id.HasValue)).Count(), //未劃數量
|
||||
d_pay = d == null ? "" : (d.pay.HasValue ? d.pay.Value.ToString() : "0"), //已收金額
|
||||
d_pay_date = d == null ? (DateTime?)null : d.start_date, //付款期限
|
||||
d_keyin1 = d == null ? (int?)null : d.keyin1,
|
||||
d_demo = d == null ? "" : d.demo, //狀態備註
|
||||
}).ToList();
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
using (var doc = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
|
||||
{
|
||||
var wb = doc.AddWorkbookPart();
|
||||
wb.Workbook = new Workbook();
|
||||
var sheets = wb.Workbook.AppendChild(new Sheets());
|
||||
|
||||
//建立第一個頁籤
|
||||
var ws = wb.AddNewPart<WorksheetPart>();
|
||||
ws.Worksheet = new Worksheet();
|
||||
sheets.Append(new Sheet()
|
||||
{
|
||||
Id = wb.GetIdOfPart(ws),
|
||||
SheetId = 1,
|
||||
Name = "報名"
|
||||
});
|
||||
|
||||
//設定欄寬
|
||||
var cu = new Columns();
|
||||
cu.Append(
|
||||
new Column { Min = 1, Max = 1, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 2, Max = 4, Width = 10, CustomWidth = true },
|
||||
new Column { Min = 5, Max = 5, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 6, Max = 8, Width = 25, CustomWidth = true },
|
||||
new Column { Min = 9, Max = 9, Width = 15, CustomWidth = true },
|
||||
new Column { Min = 10, Max = 10, Width = 10, CustomWidth = true },
|
||||
new Column { Min = 11, Max = 11, Width = 25, CustomWidth = true },
|
||||
new Column { Min = 12, Max = 16, Width = 10, CustomWidth = true },
|
||||
new Column { Min = 17, Max = 20, Width = 10, CustomWidth = true }
|
||||
);
|
||||
ws.Worksheet.Append(cu);
|
||||
|
||||
//建立資料頁
|
||||
var sd = new SheetData();
|
||||
ws.Worksheet.AppendChild(sd);
|
||||
|
||||
//第一列資料
|
||||
var tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue("單號"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("報名日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("單據狀態"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("姓名/名稱"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("聯絡電話"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("報名活動"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("收件地址"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("備註"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("項目名稱"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("姓名"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("代表地址"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("標題"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("陽上/報恩者"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("開始日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("期滿日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("應續約日"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("劃位狀態"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("預設金額"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("數量"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("小計"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("已收金額"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("未收金額"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("付款期限"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("報名狀態"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("狀態備註"), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
|
||||
|
||||
foreach (var item in list)
|
||||
{
|
||||
string midNamesResult = "";
|
||||
string leftNamesResult = "";
|
||||
string jsonString = item.d_f_num_tablet?.ToString() ?? "";
|
||||
try
|
||||
{
|
||||
var jo = JObject.Parse(jsonString);
|
||||
|
||||
// 標題
|
||||
var midList = jo["mid_items"]?
|
||||
.Select(i => (string)i["fam_name"])
|
||||
.Where(name => !string.IsNullOrEmpty(name))
|
||||
.ToList();
|
||||
if (midList != null && midList.Any())
|
||||
{
|
||||
midNamesResult = string.Join(", ", midList);
|
||||
}
|
||||
|
||||
// 陽上
|
||||
var leftList = jo["left_items"]?
|
||||
.Select(i => (string)i["fam_name"])
|
||||
.Where(name => !string.IsNullOrEmpty(name))
|
||||
.ToList();
|
||||
if (leftList != null && leftList.Any())
|
||||
{
|
||||
leftNamesResult = string.Join(", ", leftList);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"JSON 解析失敗 (訂單:{item.order_no}): {ex.Message}");
|
||||
}
|
||||
|
||||
//新增資料列
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(item.order_no), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.up_time?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(Model.pro_order.keyin1_value_to_text(item.keyin1)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.f_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.phone)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.activity_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.address), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.demo), DataType = CellValues.String },
|
||||
|
||||
new Cell() { CellValue = new CellValue(item.d_actItem_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_f_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_address), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(midNamesResult), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(leftNamesResult), DataType = CellValues.String },
|
||||
//new Cell() { CellValue = new CellValue(item.d_from_id), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_start_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_due_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_extend_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue((Val(item.d_category) == (int)Model.activity.category.Order) ? (item.d_notBedQty + "/" + item.d_writeBedQty) : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(item.d_price)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_qty), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(ValFloat(item.d_price) * Val(item.d_qty))), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(item.d_pay)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(ValFloat(item.d_price) * Val(item.d_qty) - ValFloat(item.d_pay))), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_pay_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_keyin1.HasValue ? tdesc[item.d_keyin1.Value] : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_demo), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
}
|
||||
|
||||
//空一列
|
||||
tr = new Row();
|
||||
sd.AppendChild(tr);
|
||||
|
||||
//匯出資訊
|
||||
string _data = "匯出時間 : " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
_data += " " + admin.info.u_id;
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
_data = "匯出條件 : " + (!isStrNull(_query) ? _query : "-");
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Order, (int)Model.admin_log.Status.Excel, admin_log.LogViewBtn(list.Select(x => x.order_no).ToList()));
|
||||
}
|
||||
|
||||
HttpContext.Current.Response.Clear();
|
||||
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=報名.xlsx");
|
||||
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray());
|
||||
HttpContext.Current.Response.End();
|
||||
|
||||
hid_err_msg.Value = "success";
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_err_msg.Value = "nodata";
|
||||
}
|
||||
}
|
||||
else if (isPrintMode)
|
||||
{
|
||||
int selYear = !string.IsNullOrEmpty(hid_print_year.Value) ? int.Parse(hid_print_year.Value) : 0;
|
||||
int selMonth = !string.IsNullOrEmpty(hid_print_month.Value) ? int.Parse(hid_print_month.Value) : 0;
|
||||
int selSeason = !string.IsNullOrEmpty(hid_print_season.Value) ? int.Parse(hid_print_season.Value) : 0;
|
||||
string selMode = !string.IsNullOrEmpty(hid_print_mode.Value) ? hid_print_mode.Value : "";
|
||||
bool chkHasAct = !string.IsNullOrEmpty(hid_chk_hasact.Value) && Convert.ToBoolean(hid_chk_hasact.Value);
|
||||
bool chkNoAct = !string.IsNullOrEmpty(hid_chk_noact.Value) && Convert.ToBoolean(hid_chk_noact.Value);
|
||||
int selAct = !string.IsNullOrEmpty(hid_select_act.Value) ? int.Parse(hid_select_act.Value) : -1;
|
||||
int selActItem = !string.IsNullOrEmpty(hid_select_actitem.Value) ? int.Parse(hid_select_actitem.Value) : -1;
|
||||
string urlParams = !string.IsNullOrEmpty(hid_qry.Value) ? hid_qry.Value : "";
|
||||
|
||||
var qry = _db.pro_order.AsQueryable();
|
||||
|
||||
if (selYear > 0)
|
||||
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Year == selYear);
|
||||
if (selMode == "mm" && selMonth > 0)
|
||||
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Month == selMonth);
|
||||
else if (selMode == "ss" && selSeason > 0)
|
||||
{
|
||||
if (selSeason == 1)
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 1 || o.up_time.Value.Month == 2 || o.up_time.Value.Month == 3);
|
||||
else if (selSeason == 2)
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 4 || o.up_time.Value.Month == 5 || o.up_time.Value.Month == 6);
|
||||
else if (selSeason == 3)
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 7 || o.up_time.Value.Month == 8 || o.up_time.Value.Month == 9);
|
||||
else if (selSeason == 4)
|
||||
qry = qry.Where(o => o.up_time.HasValue)
|
||||
.Where(o => o.up_time.Value.Month == 10 || o.up_time.Value.Month == 11 || o.up_time.Value.Month == 12);
|
||||
}
|
||||
|
||||
if (chkHasAct)
|
||||
{
|
||||
if (chkNoAct)
|
||||
{
|
||||
if (selAct >= 0)
|
||||
qry = qry.Where(o => o.activity_num.HasValue && o.activity_num.Value == selAct);
|
||||
}
|
||||
else
|
||||
{
|
||||
qry = qry.Where(o => o.activity_num.HasValue);
|
||||
if (selAct >= 0)
|
||||
qry = qry.Where(o => o.activity_num.Value == selAct);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chkNoAct)
|
||||
qry = qry.Where(o => o.activity_num == null);
|
||||
}
|
||||
|
||||
if (selActItem >= 0)
|
||||
{
|
||||
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem_num.Value == selActItem).Count() > 0);
|
||||
}
|
||||
|
||||
|
||||
var count = qry.Count();
|
||||
if (count > 0)
|
||||
{
|
||||
hid_err_msg.Value = "success";
|
||||
|
||||
string script = $@"var otherWin = window.open('print.aspx{urlParams}', '列印報名資料', 'noopener,noreferrer');";
|
||||
ScriptManager.RegisterStartupScript(this, GetType(), "ExecutePrint", script, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_err_msg.Value = "nodata";
|
||||
}
|
||||
//var qry = _db.followers.AsQueryable();
|
||||
//if (selYear > 0)
|
||||
//{
|
||||
// urlParams += "&year=" + selYear;
|
||||
//}
|
||||
//if (selMode == "mm" && selMonth > 0)
|
||||
//{
|
||||
// urlParams += "&month=" + selMonth;
|
||||
//}
|
||||
//else if (selMode == "ss" && selSeason > 0)
|
||||
//{
|
||||
// urlParams += "&season=" + selSeason;
|
||||
//}
|
||||
|
||||
//if (list.Count > 0)
|
||||
//{
|
||||
// hid_err_msg.Value = "success";
|
||||
// hid_print_year.Value = selYear.ToString();
|
||||
// hid_print_month.Value = selMonth.ToString();
|
||||
// hid_print_season.Value = selSeason.ToString();
|
||||
// hid_print_mode.Value = selMode;
|
||||
|
||||
// string script = $@"window.open('print.aspx?{urlParams}&mode={selMode}', '列印信眾資料');";
|
||||
// ScriptManager.RegisterStartupScript(this, GetType(), "ExecutePrint", script, true);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// hid_err_msg.Value = "nodata";
|
||||
// string script = $@"
|
||||
// var win = window.open('', '列印信眾資料');
|
||||
// if (win) win.close()";
|
||||
|
||||
// ScriptManager.RegisterStartupScript(this, GetType(), "CancelPrint", script, true);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void excel_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
@@ -111,6 +570,7 @@ public partial class admin_order_index : MyWeb.config
|
||||
new Cell() { CellValue = new CellValue("項目名稱"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("姓名"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("代表地址"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("標題"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("陽上/報恩者"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("開始日期"), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("期滿日期"), DataType = CellValues.String },
|
||||
@@ -132,32 +592,57 @@ public partial class admin_order_index : MyWeb.config
|
||||
// 改為整數陣列,避免後續查詢中使用 .ToString()
|
||||
var aIDt = _db.actItems.Where(f => f.subject.Contains(s_actItemTxt.Value.Trim())).Select(f => f.num).ToArray();//品項
|
||||
var qry = _db.pro_order.AsQueryable();
|
||||
string _query = ""; // 紀錄匯出條件
|
||||
|
||||
if (!isStrNull(s_order_no.Value))
|
||||
{
|
||||
_query += "單號:" + s_order_no.Value + "\n";
|
||||
qry = qry.Where(o => o.order_no.Contains(s_order_no.Value.Trim()));
|
||||
}
|
||||
if (!isStrNull(s_u_name.Value))
|
||||
{
|
||||
_query += "姓名/名稱:" + s_u_name.Value + "\n";
|
||||
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(s_u_name.Value.Trim()));
|
||||
}
|
||||
if (!isStrNull(s_introducerTxt.Value))
|
||||
{
|
||||
_query += "介紹人:" + s_introducerTxt.Value + "\n";
|
||||
qry = qry.Where(o => o.f_num.HasValue && o.follower1.u_name.Contains(s_introducerTxt.Value.Trim()));
|
||||
}
|
||||
if (!isStrNull(s_subject.Value))
|
||||
{
|
||||
_query += "報名活動:" + s_subject.Value + "\n";
|
||||
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(s_subject.Value.Trim()));
|
||||
}
|
||||
if (!isStrNull(s_actItemTxt.Value))
|
||||
{
|
||||
// ❌ 錯誤寫法: qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num.ToString())).Count() > 0);
|
||||
// ✅ 實際比較:僅在 actItem_num 有值時才與整數陣列比對
|
||||
_query += "品項:" + s_actItemTxt.Value + "\n";
|
||||
qry = qry.Where(o => o.pro_order_detail.Any(f2 =>
|
||||
f2.order_no == o.order_no &&
|
||||
f2.actItem_num.HasValue &&
|
||||
aIDt.Contains(f2.actItem_num.Value)));
|
||||
}
|
||||
if (!isStrNull(s_keyin1.SelectedValue))
|
||||
{
|
||||
_query += $"單據狀態:{Model.pro_order.keyin1_value_to_text(s_keyin1.SelectedValue)}\n";
|
||||
qry = qry.Where(o => o.keyin1 == s_keyin1.SelectedValue);
|
||||
}
|
||||
|
||||
if (!isStrNull(s_up_time1.Value) && isDate(s_up_time1.Value))
|
||||
qry = qry.Where(o => o.up_time >= ValDate(s_up_time1.Value));
|
||||
{
|
||||
_query += "報名日期(起):" + s_up_time1.Value.Trim() + "\n";
|
||||
var tmp_s_up_time1 = ValDate(s_up_time1.Value);
|
||||
qry = qry.Where(o => o.up_time >= tmp_s_up_time1);
|
||||
}
|
||||
if (!isStrNull(s_up_time2.Value) && isDate(s_up_time2.Value))
|
||||
qry = qry.Where(o => o.up_time < Convert.ToDateTime(s_up_time2.Value).AddDays(1));
|
||||
|
||||
{
|
||||
_query += "報名日期(訖):" + s_up_time2.Value.Trim() + "\n";
|
||||
var tmp_s_up_time2 = Convert.ToDateTime(s_up_time2.Value).AddDays(1);
|
||||
qry = qry.Where(o => o.up_time < tmp_s_up_time2);
|
||||
}
|
||||
|
||||
qry = qry.OrderByDescending(o => o.reg_time);
|
||||
|
||||
MyWeb.encrypt encrypt = new MyWeb.encrypt();
|
||||
@@ -198,20 +683,21 @@ public partial class admin_order_index : MyWeb.config
|
||||
//訂單明細
|
||||
//使用DefaultIfEmpty 因匿名型別無法輸出NULL(無法轉換成強型別),需特別注意Null的處理
|
||||
d_actItem_num = d == null ? "" : (d.actItem_num.HasValue ? d.actItem.subject : ""), //項目名稱
|
||||
d_category = d == null ? "" : (d.actItem_num.HasValue ? d.actItem.category.ToString() : ""),
|
||||
d_category = d == null ? "" : (d.actItem_num.HasValue ? d.actItem.category.ToString() : ""),
|
||||
d_f_num = d == null ? "" : (d.f_num.HasValue ? d.follower.u_name : ""), //姓名
|
||||
d_address = d == null ? "" : d.address,
|
||||
d_from_id = d == null ? "" : (d.from_id.HasValue ? d.follower1.u_name : ""), //陽上/報恩者
|
||||
d_start_date = d == null ? "" : (d.start_date.HasValue ? d.start_date.Value.ToString("yyyy/MM/dd") : ""), //開始日期
|
||||
d_due_date = d == null ? "" : (d.due_date.HasValue ? d.due_date.Value.ToString("yyyy/MM/dd") : ""), //期滿日期
|
||||
d_extend_date = d == null ? "" : (d.extend_date.HasValue ? d.extend_date.Value.ToString("yyyy/MM/dd") : ""), //應續約日
|
||||
d_price = d == null ? "" : (d.price.HasValue ? d.price.Value.ToString() : "0"), //預設金額
|
||||
d_f_num_tablet = d == null ? "" : d.f_num_tablet,
|
||||
d_start_date = d == null ? (DateTime?)null : d.start_date, //開始日期
|
||||
d_due_date = d == null ? (DateTime?)null : d.due_date, //期滿日期
|
||||
d_extend_date = d == null ? (DateTime?)null : d.extend_date, //應續約日
|
||||
d_price = d == null ? (float?)null : d.price, //預設金額
|
||||
d_qty = d == null ? "" : (d.qty.HasValue ? d.qty.Value.ToString() : "0"), //數量
|
||||
d_writeBedQty = d == null ? 0 : bedDt.Where(b =>( b.bed_order.o_detail_id.Value == d.num) && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count(), //已劃數量
|
||||
d_writeBedQty = d == null ? 0 : bedDt.Where(b => (b.bed_order.o_detail_id.Value == d.num) && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count(), //已劃數量
|
||||
d_notBedQty = d == null ? 0 : bedDt.Where(b => b.bed_order.o_detail_id.Value == d.num && (!b.checkIn_date.HasValue || !b.bed_kind_detail_id.HasValue)).Count(), //未劃數量
|
||||
d_pay = d == null ? "" : (d.pay.HasValue ? d.pay.Value.ToString() : "0"), //已收金額
|
||||
d_pay_date = d == null ? "" : (d.pay_date.HasValue ? d.pay_date.Value.ToString("yyyy/MM/dd") : ""), //付款期限
|
||||
d_keyin1 = d == null ? "" : (d.keyin1.HasValue&& d.keyin1.Value>0 ? tdesc[d.keyin1 ?? 1] : ""), //報名狀態
|
||||
d_pay_date = d == null ? (DateTime?)null : d.start_date, //付款期限
|
||||
d_keyin1 = d == null ? (int?)null : d.keyin1,
|
||||
d_demo = d == null ? "" : d.demo, //狀態備註
|
||||
}).ToList();
|
||||
|
||||
@@ -259,11 +745,43 @@ public partial class admin_order_index : MyWeb.config
|
||||
{
|
||||
foreach (var item in list)
|
||||
{
|
||||
string midNamesResult = "";
|
||||
string leftNamesResult = "";
|
||||
string jsonString = item.d_f_num_tablet?.ToString() ?? "";
|
||||
try
|
||||
{
|
||||
var jo = JObject.Parse(jsonString);
|
||||
|
||||
// 標題
|
||||
var midList = jo["mid_items"]?
|
||||
.Select(i => (string)i["fam_name"])
|
||||
.Where(name => !string.IsNullOrEmpty(name))
|
||||
.ToList();
|
||||
if (midList != null && midList.Any())
|
||||
{
|
||||
midNamesResult = string.Join(", ", midList);
|
||||
}
|
||||
|
||||
// 陽上
|
||||
var leftList = jo["left_items"]?
|
||||
.Select(i => (string)i["fam_name"])
|
||||
.Where(name => !string.IsNullOrEmpty(name))
|
||||
.ToList();
|
||||
if (leftList != null && leftList.Any())
|
||||
{
|
||||
leftNamesResult = string.Join(", ", leftList);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"JSON 解析失敗 (訂單:{item.order_no}): {ex.Message}");
|
||||
}
|
||||
|
||||
//新增資料列
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(item.order_no), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.up_time.Value.ToString("yyyy/MM/dd")), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.up_time?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(Model.pro_order.keyin1_value_to_text(item.keyin1)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.f_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(encrypt.DecryptAutoKey(item.phone)), DataType = CellValues.String },
|
||||
@@ -274,23 +792,44 @@ public partial class admin_order_index : MyWeb.config
|
||||
new Cell() { CellValue = new CellValue(item.d_actItem_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_f_num), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_address), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_from_id), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_start_date), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_due_date), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_extend_date), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue((Val(item.d_category) ==(int)Model.activity.category.Order) ?( item.d_notBedQty +"/" + item.d_writeBedQty):""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(midNamesResult), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(leftNamesResult), DataType = CellValues.String },
|
||||
//new Cell() { CellValue = new CellValue(item.d_from_id), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_start_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_due_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_extend_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue((Val(item.d_category) == (int)Model.activity.category.Order) ? (item.d_notBedQty + "/" + item.d_writeBedQty) : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(item.d_price)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_qty), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(ValFloat(item.d_price) * Val(item.d_qty))), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(item.d_pay)), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue("$" + ValMoney(ValFloat(item.d_price) * Val(item.d_qty) - ValFloat(item.d_pay))), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_pay_date), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_keyin1), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_pay_date?.ToString("yyyy/MM/dd") ?? ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_keyin1.HasValue ? tdesc[item.d_keyin1.Value] : ""), DataType = CellValues.String },
|
||||
new Cell() { CellValue = new CellValue(item.d_demo), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
}
|
||||
|
||||
//空一列
|
||||
tr = new Row();
|
||||
sd.AppendChild(tr);
|
||||
|
||||
//匯出資訊
|
||||
string _data = "匯出時間 : " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
_data += " " + admin.info.u_id;
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
_data = "匯出條件 : " + (!isStrNull(_query) ? _query : "-");
|
||||
tr = new Row();
|
||||
tr.Append(
|
||||
new Cell() { CellValue = new CellValue(_data), DataType = CellValues.String }
|
||||
);
|
||||
sd.AppendChild(tr);
|
||||
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Order, (int)Model.admin_log.Status.Excel, admin_log.LogViewBtn(list.Select(x => x.order_no).ToList()));
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
{ text: '活動名稱', value: 'subject', },
|
||||
{ text: '報到日期', value: 'reg_time_date', },
|
||||
{ text: '報到時間', value: 'reg_time_time' },
|
||||
{ text: '姓名(人數)', value: 'qty' },
|
||||
{ text: '姓名', value: 'qty' },
|
||||
{ text: '狀態', value: 'statusTxt' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
{{item.reg_time |timeString('HH:mm:ss') }}
|
||||
</template>
|
||||
<template #item.qty="{ item }" >
|
||||
{{item.u_name }}({{item.qty }})
|
||||
{{item.u_name }}
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
+42
-10
@@ -1,12 +1,21 @@
|
||||
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index3.aspx.cs" Inherits="admin_order_index3" %>
|
||||
<%@ Register Src="~/admin/_uc/alert.ascx" TagPrefix="uc1" TagName="alert" %>
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" runat="Server">
|
||||
<style>
|
||||
.modify_modal{
|
||||
width:calc(100vw-20%);
|
||||
background-color:white;
|
||||
opacity:1;
|
||||
z-index:1046 !important;
|
||||
}
|
||||
</style>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" runat="Server">
|
||||
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
<uc1:alert runat="server" ID="L_msg" Text="" />
|
||||
|
||||
|
||||
<keep-alive>
|
||||
<component
|
||||
@@ -16,8 +25,24 @@
|
||||
</keep-alive>
|
||||
|
||||
|
||||
<div id="print_data">
|
||||
</div>
|
||||
<div id="print_data">
|
||||
|
||||
</div>
|
||||
<%-- <v-container>
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<v-dialog v-model="modify_dialog.show" class="modify_modal">
|
||||
<template>
|
||||
|
||||
<keep-alive>
|
||||
<component :is="modifyView" @close-dialog="modify_dialog.show=false"></component>
|
||||
</keep-alive>
|
||||
|
||||
</template>
|
||||
</v-dialog>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-container>--%>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" runat="Server">
|
||||
|
||||
@@ -625,6 +650,9 @@
|
||||
Vue.component('step-two', {
|
||||
template: `
|
||||
<div class="container-fluid">
|
||||
<template>
|
||||
<button class='btn btn-plus' @click.prevent='fast_signup'>快速報名</button>
|
||||
</template>
|
||||
<v-data-table
|
||||
v-model="detail_table.selected"
|
||||
:items="detail_table.list"
|
||||
@@ -728,6 +756,10 @@
|
||||
|
||||
},
|
||||
methods: {
|
||||
fast_signup() {
|
||||
//this.$root.modify_dialog.show = true
|
||||
this.$root.currentView = "step-three"
|
||||
},
|
||||
getDetail() {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
@@ -765,13 +797,8 @@
|
||||
let VueApp = new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(),
|
||||
data() {
|
||||
return {
|
||||
currentView: 'step-one',
|
||||
selected_act: '',
|
||||
selected_order:'',
|
||||
};
|
||||
},activated() {
|
||||
|
||||
activated() {
|
||||
console.log("yes ,go go");
|
||||
this.getDetail();
|
||||
},
|
||||
@@ -779,6 +806,8 @@
|
||||
return {
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
selected_act: '',
|
||||
selected_order: '',
|
||||
sign_table: {
|
||||
loading: true,
|
||||
list: [],
|
||||
@@ -812,7 +841,10 @@
|
||||
country: '',
|
||||
country2: '',
|
||||
hasPrice: '',
|
||||
}
|
||||
},
|
||||
modifyView: '',
|
||||
modify_dialog: { show: false },
|
||||
currentView: 'step-one',
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index4.aspx.cs" Inherits="admin_order_index4" %>
|
||||
|
||||
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
|
||||
<link rel="stylesheet" href="../../js/_bootstrap-icons-1.8.1/bootstrap-icons.css">
|
||||
<style>
|
||||
.function-icon {
|
||||
font-size: 2em;
|
||||
line-height: 1;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.external-link-icon {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.modify_modal {
|
||||
width: calc(100vw-20%);
|
||||
background-color: white;
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
<script src="/js/httpVueLoader.js"></script>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
|
||||
<%-- <v-container class="container-fluid">--%>
|
||||
<div id="content" class="container-fluid py-4">
|
||||
<keep-alive>
|
||||
<component :is="currentView" :form-data="$data"
|
||||
:num="twoData"
|
||||
@custom-event="changeView">
|
||||
</component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
<%-- </v-container>--%>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
|
||||
<script>
|
||||
let VueApp = new Vue({
|
||||
el: '#app',
|
||||
vuetify: new Vuetify(),
|
||||
mounted() {
|
||||
this.getDetail();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: { multiSort: false },
|
||||
search_options: { multiSort: false },
|
||||
selected_act: '',
|
||||
selected_order: '',
|
||||
sign_table: {
|
||||
loading: true,
|
||||
list: [],
|
||||
selected: [],
|
||||
singleSelect: false,
|
||||
count: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
header: [
|
||||
{ text: '單號', value: 'order_no' },
|
||||
{ text: '姓名', value: 'u_name' },
|
||||
{ text: '報名日期', value: 'up_time' },
|
||||
{ text: '單據狀態', value: 'keyin1_txt', align: 'start' },
|
||||
{ text: '', value: 'slot_btn', sortable: false, align: 'end' }
|
||||
],
|
||||
footer: {
|
||||
showFirstLastPage: true,
|
||||
itemsPerPageOptions: [5, 10, 20, 30],
|
||||
},
|
||||
},
|
||||
search: {
|
||||
keyin1: '',
|
||||
order_no: '',
|
||||
subject: '',
|
||||
u_name: '',
|
||||
up_time1: '',
|
||||
up_time2: '',
|
||||
actItemTxt: '',
|
||||
introducerTxt: '',
|
||||
activity_num: '',
|
||||
country: '',
|
||||
country2: '',
|
||||
hasPrice: '',
|
||||
},
|
||||
currentView: 'fastSignUp-component',
|
||||
twoData: {},
|
||||
detail_table:[]
|
||||
};
|
||||
},
|
||||
components: {
|
||||
'fastSignUp-component': httpVueLoader('./fastSignUp.vue'),
|
||||
'fastSignUp2-component': httpVueLoader('./fastSignUp2.vue'),
|
||||
'fastSignUp3-component': httpVueLoader('./fastSignUp3.vue'),
|
||||
'fastSignUp4-component': httpVueLoader('./fastSignUp4.vue'),
|
||||
'fastSignUp5-component': httpVueLoader('./fastSignUp5.vue'),
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
handler() {
|
||||
this.getDetail()
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
changeView(item) {
|
||||
if (item.action === "detail") {
|
||||
this.twoData = item.item.num
|
||||
this.currentView = "fastSignUp2-component"
|
||||
} else if (item.action === "add") {
|
||||
this.twoData = item.item.num
|
||||
this.currentView = "fastSignUp3-component"
|
||||
} else if (item.action === "signup4") {
|
||||
this.twoData = item.item
|
||||
this.currentView = "fastSignUp4-component"
|
||||
} else if (item.action === "signup1") {
|
||||
this.twoData = item.item
|
||||
this.currentView = "fastSignUp-component"
|
||||
} else if (item.action === "oldSign") {
|
||||
location.href="/admin/order/index.aspx"
|
||||
} else if (item.action === "batchSign") {
|
||||
this.twoData = item.item.num
|
||||
this.currentView = "fastSignUp5-component"
|
||||
}
|
||||
//console.log("item.action:",this.twoData)
|
||||
},
|
||||
getDetail() {
|
||||
const { sortBy, sortDesc, page, itemsPerPage } = this.options
|
||||
const params = {
|
||||
page: '1', pageSize: 10,
|
||||
|
||||
};
|
||||
this.search = { activity_num: this.$root.selected_act }
|
||||
this.detail_table.loading = true
|
||||
sessionStorage.setItem('orderpage', '1');// clearpage ? '1' : page
|
||||
axios
|
||||
.post(HTTP_HOST + 'api/order/GetList', this.search, { params: params })
|
||||
.then(response => {
|
||||
this.detail_table.list = response.data.list
|
||||
this.detail_table.count = response.data.count;
|
||||
this.detail_table.loading = false
|
||||
})
|
||||
.catch(error => console.log(error))
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
pageCount() {
|
||||
return Math.ceil(this.detail_table.count / this.detail_table.pageSize)
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</asp:Content>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public partial class admin_order_index4 : MyWeb.config
|
||||
{
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -144,13 +144,10 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>項目名稱</th>
|
||||
<th class="nowarp">姓名</th>
|
||||
<th>代表地址</th>
|
||||
<th class="nowarp">陽上/報恩</th>
|
||||
<th class="nowarp">陽上</th>
|
||||
<th class="nowarp">標題</th>
|
||||
<th class="fit">開始日</th>
|
||||
<th class="fit">期滿日</th>
|
||||
<th class="fit">延續日</th>
|
||||
<th class="fit">劃位</th>
|
||||
<asp:PlaceHolder ID="PlaceHolder2" runat="server">
|
||||
<th class="fit">功德金</th>
|
||||
<th class="fit">數量</th>
|
||||
@@ -167,18 +164,14 @@
|
||||
<td>
|
||||
<asp:Literal ID="actitem_numTxt" runat="server"></asp:Literal></td>
|
||||
<td class="nowarp">
|
||||
<asp:Literal ID="f_numTxt" runat="server"></asp:Literal></td>
|
||||
<td><%# Eval("address") %></td>
|
||||
<asp:Literal ID="left_nameTxt" runat="server"></asp:Literal></td>
|
||||
<td class="nowarp">
|
||||
<asp:Literal ID="from_idTxt" runat="server"></asp:Literal></td>
|
||||
<asp:Literal ID="mid_nameTxt" runat="server"></asp:Literal></td>
|
||||
|
||||
|
||||
<td class="fit"><%# Eval("start_date") != null? Convert.ToDateTime( Eval("start_date")).ToString("yyyy/MM/dd") : "" %></td>
|
||||
<td class="fit">
|
||||
<asp:Literal ID="due_date" runat="server"></asp:Literal></td>
|
||||
<td class="fit">
|
||||
<asp:Literal ID="extend_date" runat="server"></asp:Literal></td>
|
||||
|
||||
<td class="fit">
|
||||
<asp:Literal ID="BedQty" runat="server"></asp:Literal></td>
|
||||
<asp:PlaceHolder ID="PlaceHolder2" runat="server">
|
||||
<td class="fit text-end">
|
||||
<asp:Literal ID="item_price" runat="server" Text='<%# Eval("price") %>'></asp:Literal></td>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using DocumentFormat.OpenXml.Vml.Office;
|
||||
using Microsoft.Ajax.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Helpers;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
@@ -182,8 +188,20 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
|
||||
if (!string.IsNullOrEmpty(_chkHasAct) && Convert.ToBoolean(_chkHasAct))
|
||||
{
|
||||
_query += "活動報名\n";
|
||||
|
||||
if (!string.IsNullOrEmpty(_selectAct))
|
||||
{
|
||||
int selectAct = Convert.ToInt32(_selectAct);
|
||||
if (selectAct > 0)
|
||||
{
|
||||
var actSubject = _db.activities.Where(a => a.num == selectAct).Select(a => a.subject).FirstOrDefault();
|
||||
_query += $"活動報名: {actSubject}\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_query += $"活動報名\n";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(_chkNoAct) && Convert.ToBoolean(_chkNoAct))
|
||||
{
|
||||
_query += "非活動報名\n";
|
||||
@@ -200,7 +218,7 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
else
|
||||
{
|
||||
qry = qry.Where(o => o.activity_num.HasValue);
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(_selectAct))
|
||||
{
|
||||
int selectAct = Convert.ToInt32(_selectAct);
|
||||
@@ -404,16 +422,56 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
actitem_numTxt.Text = row.actItem_num.HasValue && row.actItem != null ? row.actItem.subject : "";
|
||||
}
|
||||
|
||||
Literal fNumTxtLit = (Literal)e.Item.FindControl("f_numTxt");
|
||||
if (fNumTxtLit != null)
|
||||
{
|
||||
fNumTxtLit.Text = row.f_num.HasValue && row.follower != null ? row.follower.u_name : "";
|
||||
}
|
||||
//Literal fNumTxtLit = (Literal)e.Item.FindControl("f_numTxt");
|
||||
//if (fNumTxtLit != null)
|
||||
//{
|
||||
// fNumTxtLit.Text = row.f_num.HasValue && row.follower != null ? row.follower.u_name : "";
|
||||
//}
|
||||
|
||||
Literal fromIdTxtLit = (Literal)e.Item.FindControl("from_idTxt");
|
||||
if (fromIdTxtLit != null)
|
||||
string jsonString = row.f_num_tablet?.ToString() ?? "";
|
||||
if (!string.IsNullOrWhiteSpace(jsonString))
|
||||
{
|
||||
fromIdTxtLit.Text = row.from_id.HasValue && row.follower1 != null ? row.follower1.u_name : "";
|
||||
var jo = JObject.Parse(jsonString);
|
||||
List<string> allMidNames = new List<string>();
|
||||
List<string> allLeftNames = new List<string>();
|
||||
|
||||
// 標題
|
||||
var midNames = jo["mid_items"]?
|
||||
.Select(item => (string)item["fam_name"])
|
||||
.ToList();
|
||||
|
||||
if (midNames != null && midNames.Any())
|
||||
{
|
||||
allMidNames.AddRange(midNames);
|
||||
}
|
||||
|
||||
if (allMidNames.Any())
|
||||
{
|
||||
Literal midNameTextLit = (Literal)e.Item.FindControl("mid_nameTxt");
|
||||
if (midNameTextLit != null)
|
||||
{
|
||||
midNameTextLit.Text = string.Join(", ", allMidNames);
|
||||
}
|
||||
}
|
||||
|
||||
// 陽上
|
||||
var leftNames = jo["left_items"]?
|
||||
.Select(item => (string)item["fam_name"])
|
||||
.ToList();
|
||||
|
||||
if (leftNames != null && leftNames.Any())
|
||||
{
|
||||
allLeftNames.AddRange(leftNames);
|
||||
}
|
||||
|
||||
if (allLeftNames.Any())
|
||||
{
|
||||
Literal leftNameTextLit = (Literal)e.Item.FindControl("left_nameTxt");
|
||||
if (leftNameTextLit != null)
|
||||
{
|
||||
leftNameTextLit.Text = string.Join(", ", allLeftNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Literal dueDateLit = (Literal)e.Item.FindControl("due_date");
|
||||
@@ -422,21 +480,21 @@ public partial class admin_follower_print_ : System.Web.UI.Page
|
||||
dueDateLit.Text = row.due_date.HasValue ? row.due_date.Value.ToString("yyyy-MM-dd") : "";
|
||||
}
|
||||
|
||||
Literal extendDateLit = (Literal)e.Item.FindControl("extend_date");
|
||||
if (extendDateLit != null)
|
||||
{
|
||||
extendDateLit.Text = row.extend_date.HasValue ? row.extend_date.Value.ToString("yyyy-MM-dd") : "";
|
||||
}
|
||||
//Literal extendDateLit = (Literal)e.Item.FindControl("extend_date");
|
||||
//if (extendDateLit != null)
|
||||
//{
|
||||
// extendDateLit.Text = row.extend_date.HasValue ? row.extend_date.Value.ToString("yyyy-MM-dd") : "";
|
||||
//}
|
||||
|
||||
//劃位狀態
|
||||
int writeBedQty = _bedDt.Where(b => b.bed_order != null && b.bed_order.o_detail_id == row.num && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count();
|
||||
int notBedQty = _bedDt.Where(b => b.bed_order != null && b.bed_order.o_detail_id == row.num && (!b.checkIn_date.HasValue || !b.bed_kind_detail_id.HasValue)).Count();
|
||||
|
||||
Literal bedQtyLit = (Literal)e.Item.FindControl("BedQty");
|
||||
if (bedQtyLit != null)
|
||||
{
|
||||
bedQtyLit.Text = (row.actItem != null && row.actItem.category.HasValue && Convert.ToInt32(row.actItem.category.Value) == (int)Model.activity.category.Order) ? (notBedQty + "/" + writeBedQty) : "";
|
||||
}
|
||||
////劃位狀態
|
||||
//int writeBedQty = _bedDt.Where(b => b.bed_order != null && b.bed_order.o_detail_id == row.num && b.checkIn_date.HasValue && b.bed_kind_detail_id.HasValue).Count();
|
||||
//int notBedQty = _bedDt.Where(b => b.bed_order != null && b.bed_order.o_detail_id == row.num && (!b.checkIn_date.HasValue || !b.bed_kind_detail_id.HasValue)).Count();
|
||||
|
||||
//Literal bedQtyLit = (Literal)e.Item.FindControl("BedQty");
|
||||
//if (bedQtyLit != null)
|
||||
//{
|
||||
// bedQtyLit.Text = (row.actItem != null && row.actItem.category.HasValue && Convert.ToInt32(row.actItem.category.Value) == (int)Model.activity.category.Order) ? (notBedQty + "/" + writeBedQty) : "";
|
||||
//}
|
||||
|
||||
Literal keyin1Lit = (Literal)e.Item.FindControl("keyin1");
|
||||
if (keyin1Lit != null)
|
||||
|
||||
@@ -755,6 +755,7 @@
|
||||
curr.select(this.editedItem, row);
|
||||
}
|
||||
this.search_dialog.show = false;
|
||||
this.search_dialog.page = 1;
|
||||
//console.log(row, row["u_name"], row["f_number"], curr.id, target);
|
||||
},
|
||||
//報名詳細資料
|
||||
@@ -859,7 +860,7 @@
|
||||
isValidDate = Date.parse(item.pay_date);
|
||||
if (!isNaN(isValidDate))
|
||||
item.pay_date = new Date(item.pay_date).format("yyyy-MM-dd")
|
||||
|
||||
console.log(item);
|
||||
this.editedItem = $.extend(true, {}, item);
|
||||
this.data_dialog.show = true;
|
||||
this.data_dialog.isAddNew = false;
|
||||
@@ -1100,9 +1101,11 @@
|
||||
/* (this.editedItem.category=="1"? this.editedItem.from_id_selected.val != 0 : true) &&*/
|
||||
this.requireData(this.editedItem.qty, (this.editedItem.num == 0 ? false : true)) ) /* qty為0視為不需要此項目,不儲存此筆資料*/
|
||||
{
|
||||
console.log(this.editedItem);
|
||||
//check price
|
||||
if (this.editedItem.pay <= this.editedItem.price * this.editedItem.qty) {
|
||||
|
||||
console.log(this.editedItem.f_num_selected.val);
|
||||
console.log(this.editedItem.from_id_selected.val);
|
||||
//check qty
|
||||
//數量不可小於掛單明細的數量
|
||||
if (this.editedItem.qty >= this.editedItem.writeBedQty + this.editedItem.notBedQty) {
|
||||
@@ -1857,7 +1860,7 @@
|
||||
<div class="">
|
||||
<asp:Button ID="add" runat="server" Text="送出" OnClick="add_Click" CssClass="btn btn-primary" />
|
||||
<asp:Button ID="edit" runat="server" Text="修改" Visible="false" OnClick="edit_Click" CssClass="btn btn-primary" />
|
||||
<asp:Button ID="goback" runat="server" Text="回列表" Visible="false" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||
<asp:Button ID="goback" runat="server" Text="取消" CausesValidation="false" OnClick="goback_Click" CssClass="btn btn-outline-secondary" />
|
||||
</div>
|
||||
</asp:Content>
|
||||
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
|
||||
@@ -2486,7 +2489,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; search_dialog.page = 1;"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text >
|
||||
<v-row>
|
||||
|
||||
+26
-12
@@ -1,15 +1,16 @@
|
||||
using System;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.Entity.Infrastructure;
|
||||
using System.Data.OleDb;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Data.Entity.Infrastructure;
|
||||
|
||||
public partial class admin_order_reg : MyWeb.config
|
||||
{
|
||||
@@ -187,16 +188,29 @@ public partial class admin_order_reg : MyWeb.config
|
||||
{
|
||||
if (!isStrNull(pro_order.order_no))
|
||||
{
|
||||
_db.pro_order.Add(pro_order);
|
||||
_db.SaveChanges();
|
||||
bool isRegistered = _db.pro_order.Any(x => x.f_num == pro_order.f_num && x.activity_num == pro_order.activity_num);
|
||||
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Order, (int)Model.admin_log.Status.Insert, pro_order.order_no);
|
||||
if (isRegistered) // 重複報名
|
||||
{
|
||||
L_msg.Type = alert_type.warning;
|
||||
L_msg.Text = "此信眾已報名過本活動";
|
||||
}
|
||||
else
|
||||
{
|
||||
_db.pro_order.Add(pro_order);
|
||||
_db.SaveChanges();
|
||||
|
||||
Model.admin_log admin_log = new Model.admin_log();
|
||||
admin_log.writeLog(admin.info.u_id, (int)Model.admin_log.Systems.Order, (int)Model.admin_log.Status.Insert, pro_order.order_no);
|
||||
|
||||
|
||||
string url = "index.aspx";
|
||||
url = "reg.aspx?order_no=" + pro_order.order_no;
|
||||
Response.Redirect(url);
|
||||
string url = "index.aspx";
|
||||
url = "reg.aspx?order_no=" + pro_order.order_no;
|
||||
|
||||
Session["LastAddedNo"] = pro_order.order_no;
|
||||
|
||||
Response.Redirect(url);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
<div class="row mt-2">
|
||||
<div class="col-3">
|
||||
版型設定:
|
||||
<select id="styleSel" onchange="designer.changeStyle()">
|
||||
|
||||
<select id="styleSel" onchange="designer.changeStyle()" class="form-select">
|
||||
<option value="">請選擇版型</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -211,10 +212,10 @@
|
||||
toast: null,
|
||||
modal: null,
|
||||
bg: [
|
||||
{ name: "黃1", path: "../../../admin/print/html/tablet-1_new.svg" },
|
||||
{ name: "黃2", path: "../../../admin/print/html/tablet-1B_new.svg" },
|
||||
{ name: "紅1", path: "../../../admin/print/html/tablet-2.svg" },
|
||||
{ name: "紅2", path: "../../../admin/print/html/tablet-2B.svg" }
|
||||
{ name: "超薦1", path: "../../../admin/print/html/tablet-1_new.svg" },
|
||||
{ name: "超薦2", path: "../../../admin/print/html/tablet-1B_new.svg" },
|
||||
{ name: "消災1", path: "../../../admin/print/html/tablet-2.svg" },
|
||||
{ name: "消災2", path: "../../../admin/print/html/tablet-2B.svg" }
|
||||
],
|
||||
async init() {
|
||||
// 載入常用片語
|
||||
@@ -303,7 +304,7 @@
|
||||
let data = response.data;
|
||||
if (data.data) {
|
||||
data.data.forEach(x => {
|
||||
if (x.styleID !== "00001") {
|
||||
if (x.styleID !== "000001") {
|
||||
this.allStyle.push(x);
|
||||
$("#styleSel").append(`<option value="${x.styleID}">${x.name}</option`);
|
||||
}
|
||||
@@ -853,11 +854,28 @@
|
||||
self.bindEvent();
|
||||
},
|
||||
async addNewItem() {
|
||||
console.log("addNewItem:",$("#custom_txt").val())
|
||||
if ($("#custom_txt").val()=="") {
|
||||
|
||||
alert("名稱不可空白")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
let self = this;
|
||||
let target = $(self.selectedElement).children().first();
|
||||
|
||||
let error=""
|
||||
//let fam = self.familyMembers.find(x => x.fam_name == target.text());
|
||||
if (target.hasClass("liveList")) {
|
||||
self.alive.forEach(x => {
|
||||
if (x == $("#custom_txt").val()) {
|
||||
error = "名稱已存在"
|
||||
}
|
||||
})
|
||||
if (error != "") {
|
||||
alert(error)
|
||||
return false
|
||||
}
|
||||
self.alive.push($("#custom_txt").val());
|
||||
let obj = {
|
||||
IsShuWen: false,
|
||||
@@ -871,6 +889,15 @@
|
||||
}
|
||||
self.family_deceased_Y_selected.push(obj);
|
||||
} else if (target.hasClass("nameList") || target.hasClass("rosterList")) {
|
||||
self.properTitle.forEach(x => {
|
||||
if (x == $("#custom_txt").val()) {
|
||||
error = "名稱已存在"
|
||||
}
|
||||
})
|
||||
if (error != "") {
|
||||
alert(error)
|
||||
return false
|
||||
}
|
||||
self.properTitle.push($("#custom_txt").val());
|
||||
let obj = {
|
||||
IsShuWen: false,
|
||||
@@ -884,6 +911,16 @@
|
||||
}
|
||||
self.family_deceased_N_selected.push(obj);
|
||||
} else if (target.hasClass("ancestor-wrapper")) {
|
||||
//再來判斷是否已有這個名稱
|
||||
self.properTitle.forEach(x => {
|
||||
if (x == $("#custom_txt").val()) {
|
||||
error = "名稱已存在"
|
||||
}
|
||||
})
|
||||
if (error != "") {
|
||||
alert(error)
|
||||
return false
|
||||
}
|
||||
if (self.properTitle.length >= 2) {
|
||||
alert("多姓氏合併必須第一個名稱為姓,第二個名稱為氏歷代祖先之類,且最多兩個名稱");
|
||||
} else {
|
||||
@@ -901,9 +938,15 @@
|
||||
self.family_deceased_N_selected.push(obj);
|
||||
}
|
||||
} else if (target.hasClass("lefttitle")) {
|
||||
//if (self.leftProperTitle.length >= 1) {
|
||||
// alert("左正名");
|
||||
//} else {
|
||||
self.leftProperTitle.forEach(x => {
|
||||
if (x == $("#custom_txt").val()) {
|
||||
error = "名稱已存在"
|
||||
}
|
||||
})
|
||||
if (error != "") {
|
||||
alert(error)
|
||||
return false
|
||||
}
|
||||
self.leftProperTitle.length = 0;
|
||||
self.family_left_title.length = 0;
|
||||
self.leftProperTitle.push($("#custom_txt").val());
|
||||
@@ -921,9 +964,15 @@
|
||||
//self.family_deceased_N_selected.push(obj);
|
||||
//}
|
||||
} else if (target.hasClass("righttitle")) {
|
||||
//if (self.rightProperTitle.length >= 1) {
|
||||
// alert("右正名");
|
||||
//} else {
|
||||
self.rightProperTitle.forEach(x => {
|
||||
if (x == $("#custom_txt").val()) {
|
||||
error = "名稱已存在"
|
||||
}
|
||||
})
|
||||
if (error != "") {
|
||||
alert(error)
|
||||
return false
|
||||
}
|
||||
self.rightProperTitle.length = 0;
|
||||
self.family_right_title.length = 0;
|
||||
self.rightProperTitle.push($("#custom_txt").val());
|
||||
|
||||
@@ -105,6 +105,23 @@
|
||||
></v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.kind="{ item }">
|
||||
<div>
|
||||
<div class="mb-2">
|
||||
<span class="badge bg-primary me-1" title="支付方式">收支項目</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<v-select
|
||||
:items="accountingKinds"
|
||||
v-model="item.kind"
|
||||
dense
|
||||
outlined
|
||||
hide-details
|
||||
style="max-width: 200px"
|
||||
></v-select>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.check_memo="{ item }">
|
||||
<div class="d-flex align-center my-2" style="min-width: 300px">
|
||||
<v-text-field
|
||||
@@ -159,6 +176,7 @@ new Vue({
|
||||
{ text: '*入帳銀行/帳戶 | 支付資訊/帳號後5碼', value: 'acc_num' },
|
||||
{ text: '*入帳日期', value: 'check_date' },
|
||||
{ text: '*入帳金額', value: 'check_amount' },
|
||||
{ text: '*收支項目', value: 'kind' },
|
||||
{ text: '備註/狀態 | 核對記錄', value: 'check_memo' }
|
||||
],
|
||||
items: [],
|
||||
@@ -172,7 +190,8 @@ new Vue({
|
||||
{ text: '其他問題', value: '4' },
|
||||
{ text: '作廢', value: '5' }
|
||||
],
|
||||
bankOptions: [],
|
||||
bankOptions: [],
|
||||
accountingKinds:[],
|
||||
payTypeText: {
|
||||
1: '現金',
|
||||
2: '匯款',
|
||||
@@ -212,6 +231,13 @@ new Vue({
|
||||
text: x.kind + (x.bank_name ? ' - ' + x.bank_name : '') + (x.bank_id ? ' (' + x.bank_id + ')' : ''),
|
||||
value: x.num
|
||||
}));
|
||||
|
||||
const kindRes = await axios.post('../../api/accounting/GetTitleKindList', {}, { params: { page: 1, pageSize: 1000 } });
|
||||
this.accountingKinds = kindRes.data.list.map(x => ({
|
||||
text: x.kind ,
|
||||
value: x.num
|
||||
}));
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
async submitData() {
|
||||
@@ -246,7 +272,8 @@ new Vue({
|
||||
acc_num: item.acc_num,
|
||||
check_date: item.check_date,
|
||||
check_amount: item.check_amount,
|
||||
check_memo: item.check_memo
|
||||
check_memo: item.check_memo,
|
||||
kind: item.kind
|
||||
}));
|
||||
try {
|
||||
const res = await axios.post('../../api/transfer_register/batch_update', updateList);
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
</template>
|
||||
<template v-slot:item.transfer_info="{ item }">
|
||||
<div>
|
||||
<div class="font-weight-bold text-primary">應收總額:{{ item.price_totals | currency }}</div>
|
||||
<div class="font-weight-bold text-primary">入帳金額:{{ item.transfer_check_amount | currency }}</div>
|
||||
<div class="text-success">沖帳日期:{{ item.transfer_check_date | date }}</div>
|
||||
<div v-if="item.transfer_remain_amount > 0" class="text-warning">
|
||||
@@ -202,6 +203,7 @@
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳帳戶:</span>{{ dialog.selected.acc_name }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳日期:</span>{{ dialog.selected.transfer_check_date | date }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">入帳金額:</span>{{ dialog.selected.transfer_check_amount | currency }}</div>
|
||||
<div class="mb-2"><span class="font-weight-bold">應收總額:</span>{{ dialog.selected.price_totals | currency }}</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider class="my-4"></v-divider>
|
||||
|
||||
@@ -0,0 +1,478 @@
|
||||
(function umd(root,factory){
|
||||
if(typeof module==='object' && typeof exports === 'object' )
|
||||
module.exports=factory()
|
||||
else if(typeof define==='function' && define.amd)
|
||||
define([],factory)
|
||||
else
|
||||
root.httpVueLoader=factory()
|
||||
})(this,function factory() {
|
||||
'use strict';
|
||||
|
||||
var scopeIndex = 0;
|
||||
|
||||
StyleContext.prototype = {
|
||||
|
||||
withBase: function(callback) {
|
||||
|
||||
var tmpBaseElt;
|
||||
if ( this.component.baseURI ) {
|
||||
|
||||
// firefox and chrome need the <base> to be set while inserting or modifying <style> in a document.
|
||||
tmpBaseElt = document.createElement('base');
|
||||
tmpBaseElt.href = this.component.baseURI;
|
||||
|
||||
var headElt = this.component.getHead();
|
||||
headElt.insertBefore(tmpBaseElt, headElt.firstChild);
|
||||
}
|
||||
|
||||
callback.call(this);
|
||||
|
||||
if ( tmpBaseElt )
|
||||
this.component.getHead().removeChild(tmpBaseElt);
|
||||
},
|
||||
|
||||
scopeStyles: function(styleElt, scopeName) {
|
||||
|
||||
function process() {
|
||||
|
||||
var sheet = styleElt.sheet;
|
||||
var rules = sheet.cssRules;
|
||||
|
||||
for ( var i = 0; i < rules.length; ++i ) {
|
||||
|
||||
var rule = rules[i];
|
||||
if ( rule.type !== 1 )
|
||||
continue;
|
||||
|
||||
var scopedSelectors = [];
|
||||
|
||||
rule.selectorText.split(/\s*,\s*/).forEach(function(sel) {
|
||||
|
||||
scopedSelectors.push(scopeName+' '+sel);
|
||||
var segments = sel.match(/([^ :]+)(.+)?/);
|
||||
scopedSelectors.push(segments[1] + scopeName + (segments[2]||''));
|
||||
});
|
||||
|
||||
var scopedRule = scopedSelectors.join(',') + rule.cssText.substr(rule.selectorText.length);
|
||||
sheet.deleteRule(i);
|
||||
sheet.insertRule(scopedRule, i);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// firefox may fail sheet.cssRules with InvalidAccessError
|
||||
process();
|
||||
} catch (ex) {
|
||||
|
||||
if ( ex instanceof DOMException && ex.code === DOMException.INVALID_ACCESS_ERR ) {
|
||||
|
||||
styleElt.sheet.disabled = true;
|
||||
styleElt.addEventListener('load', function onStyleLoaded() {
|
||||
|
||||
styleElt.removeEventListener('load', onStyleLoaded);
|
||||
|
||||
// firefox need this timeout otherwise we have to use document.importNode(style, true)
|
||||
setTimeout(function() {
|
||||
|
||||
process();
|
||||
styleElt.sheet.disabled = false;
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
},
|
||||
|
||||
compile: function() {
|
||||
|
||||
var hasTemplate = this.template !== null;
|
||||
|
||||
var scoped = this.elt.hasAttribute('scoped');
|
||||
|
||||
if ( scoped ) {
|
||||
|
||||
// no template, no scopable style needed
|
||||
if ( !hasTemplate )
|
||||
return;
|
||||
|
||||
// firefox does not tolerate this attribute
|
||||
this.elt.removeAttribute('scoped');
|
||||
}
|
||||
|
||||
this.withBase(function() {
|
||||
|
||||
this.component.getHead().appendChild(this.elt);
|
||||
});
|
||||
|
||||
if ( scoped )
|
||||
this.scopeStyles(this.elt, '['+this.component.getScopeId()+']');
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
getContent: function() {
|
||||
|
||||
return this.elt.textContent;
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
|
||||
this.withBase(function() {
|
||||
|
||||
this.elt.textContent = content;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function StyleContext(component, elt) {
|
||||
|
||||
this.component = component;
|
||||
this.elt = elt;
|
||||
}
|
||||
|
||||
|
||||
ScriptContext.prototype = {
|
||||
|
||||
getContent: function() {
|
||||
|
||||
return this.elt.textContent;
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
|
||||
this.elt.textContent = content;
|
||||
},
|
||||
|
||||
compile: function(module) {
|
||||
|
||||
var childModuleRequire = function(childURL) {
|
||||
|
||||
return httpVueLoader.require(resolveURL(this.component.baseURI, childURL));
|
||||
}.bind(this);
|
||||
|
||||
var childLoader = function(childURL, childName) {
|
||||
|
||||
return httpVueLoader(resolveURL(this.component.baseURI, childURL), childName);
|
||||
}.bind(this);
|
||||
|
||||
try {
|
||||
Function('exports', 'require', 'httpVueLoader', 'module', this.getContent()).call(this.module.exports, this.module.exports, childModuleRequire, childLoader, this.module);
|
||||
} catch(ex) {
|
||||
|
||||
if ( !('lineNumber' in ex) ) {
|
||||
|
||||
return Promise.reject(ex);
|
||||
}
|
||||
var vueFileData = responseText.replace(/\r?\n/g, '\n');
|
||||
var lineNumber = vueFileData.substr(0, vueFileData.indexOf(script)).split('\n').length + ex.lineNumber - 1;
|
||||
throw new (ex.constructor)(ex.message, url, lineNumber);
|
||||
}
|
||||
|
||||
return Promise.resolve(this.module.exports)
|
||||
.then(httpVueLoader.scriptExportsHandler.bind(this))
|
||||
.then(function(exports) {
|
||||
|
||||
this.module.exports = exports;
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
function ScriptContext(component, elt) {
|
||||
|
||||
this.component = component;
|
||||
this.elt = elt;
|
||||
this.module = { exports:{} };
|
||||
}
|
||||
|
||||
|
||||
TemplateContext.prototype = {
|
||||
|
||||
getContent: function() {
|
||||
|
||||
return this.elt.innerHTML;
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
|
||||
this.elt.innerHTML = content;
|
||||
},
|
||||
|
||||
getRootElt: function() {
|
||||
|
||||
var tplElt = this.elt.content || this.elt;
|
||||
|
||||
if ( 'firstElementChild' in tplElt )
|
||||
return tplElt.firstElementChild;
|
||||
|
||||
for ( tplElt = tplElt.firstChild; tplElt !== null; tplElt = tplElt.nextSibling )
|
||||
if ( tplElt.nodeType === Node.ELEMENT_NODE )
|
||||
return tplElt;
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
compile: function() {
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
function TemplateContext(component, elt) {
|
||||
|
||||
this.component = component;
|
||||
this.elt = elt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Component.prototype = {
|
||||
|
||||
getHead: function() {
|
||||
|
||||
return document.head || document.getElementsByTagName('head')[0];
|
||||
},
|
||||
|
||||
getScopeId: function() {
|
||||
|
||||
if ( this._scopeId === '' ) {
|
||||
|
||||
this._scopeId = 'data-s-' + (scopeIndex++).toString(36);
|
||||
this.template.getRootElt().setAttribute(this._scopeId, '');
|
||||
}
|
||||
return this._scopeId;
|
||||
},
|
||||
|
||||
load: function(componentURL) {
|
||||
|
||||
return httpVueLoader.httpRequest(componentURL)
|
||||
.then(function(responseText) {
|
||||
|
||||
this.baseURI = componentURL.substr(0, componentURL.lastIndexOf('/')+1);
|
||||
var doc = document.implementation.createHTMLDocument('');
|
||||
|
||||
// IE requires the <base> to come with <style>
|
||||
doc.body.innerHTML = (this.baseURI ? '<base href="'+this.baseURI+'">' : '') + responseText;
|
||||
|
||||
for ( var it = doc.body.firstChild; it; it = it.nextSibling ) {
|
||||
|
||||
switch ( it.nodeName ) {
|
||||
case 'TEMPLATE':
|
||||
this.template = new TemplateContext(this, it);
|
||||
break;
|
||||
case 'SCRIPT':
|
||||
this.script = new ScriptContext(this, it);
|
||||
break;
|
||||
case 'STYLE':
|
||||
this.styles.push(new StyleContext(this, it));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_normalizeSection: function(eltCx) {
|
||||
|
||||
var p;
|
||||
|
||||
if ( eltCx === null || !eltCx.elt.hasAttribute('src') ) {
|
||||
|
||||
p = Promise.resolve(null);
|
||||
} else {
|
||||
|
||||
p = httpVueLoader.httpRequest(eltCx.elt.getAttribute('src'))
|
||||
.then(function(content) {
|
||||
|
||||
eltCx.elt.removeAttribute('src');
|
||||
return content;
|
||||
});
|
||||
}
|
||||
|
||||
return p
|
||||
.then(function(content) {
|
||||
|
||||
if ( eltCx !== null && eltCx.elt.hasAttribute('lang') ) {
|
||||
|
||||
var lang = eltCx.elt.getAttribute('lang');
|
||||
eltCx.elt.removeAttribute('lang');
|
||||
return httpVueLoader.langProcessor[lang.toLowerCase()].call(this, content === null ? eltCx.getContent() : content);
|
||||
}
|
||||
return content;
|
||||
}.bind(this))
|
||||
.then(function(content) {
|
||||
|
||||
if ( content !== null )
|
||||
eltCx.setContent(content);
|
||||
});
|
||||
},
|
||||
|
||||
normalize: function() {
|
||||
|
||||
return Promise.all(Array.prototype.concat(
|
||||
this._normalizeSection(this.template),
|
||||
this._normalizeSection(this.script),
|
||||
this.styles.map(this._normalizeSection)
|
||||
))
|
||||
.then(function() {
|
||||
|
||||
return this;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
compile: function() {
|
||||
|
||||
return Promise.all(Array.prototype.concat(
|
||||
this.template && this.template.compile(),
|
||||
this.script && this.script.compile(),
|
||||
this.styles.map(function(style) { return style.compile(); })
|
||||
))
|
||||
.then(function() {
|
||||
|
||||
return this;
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
function Component(name) {
|
||||
|
||||
this.name = name;
|
||||
this.template = null;
|
||||
this.script = null;
|
||||
this.styles = [];
|
||||
this._scopeId = '';
|
||||
}
|
||||
|
||||
function identity(value) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function parseComponentURL(url) {
|
||||
|
||||
var comp = url.match(/(.*?)([^/]+?)\/?(\.vue)?(\?.*|#.*|$)/);
|
||||
return {
|
||||
name: comp[2],
|
||||
url: comp[1] + comp[2] + (comp[3] === undefined ? '/index.vue' : comp[3]) + comp[4]
|
||||
};
|
||||
}
|
||||
|
||||
function resolveURL(baseURL, url) {
|
||||
|
||||
if (url.substr(0, 2) === './' || url.substr(0, 3) === '../') {
|
||||
return baseURL + url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
httpVueLoader.load = function(url, name) {
|
||||
|
||||
return function() {
|
||||
|
||||
return new Component(name).load(url)
|
||||
.then(function(component) {
|
||||
|
||||
return component.normalize();
|
||||
})
|
||||
.then(function(component) {
|
||||
|
||||
return component.compile();
|
||||
})
|
||||
.then(function(component) {
|
||||
|
||||
var exports = component.script !== null ? component.script.module.exports : {};
|
||||
|
||||
if ( component.template !== null )
|
||||
exports.template = component.template.getContent();
|
||||
|
||||
if ( exports.name === undefined )
|
||||
if ( component.name !== undefined )
|
||||
exports.name = component.name;
|
||||
|
||||
exports._baseURI = component.baseURI;
|
||||
|
||||
return exports;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
httpVueLoader.register = function(Vue, url) {
|
||||
|
||||
var comp = parseComponentURL(url);
|
||||
Vue.component(comp.name, httpVueLoader.load(comp.url));
|
||||
};
|
||||
|
||||
httpVueLoader.install = function(Vue) {
|
||||
|
||||
Vue.mixin({
|
||||
|
||||
beforeCreate: function () {
|
||||
|
||||
var components = this.$options.components;
|
||||
|
||||
for ( var componentName in components ) {
|
||||
|
||||
if ( typeof(components[componentName]) === 'string' && components[componentName].substr(0, 4) === 'url:' ) {
|
||||
|
||||
var comp = parseComponentURL(components[componentName].substr(4));
|
||||
|
||||
var componentURL = ('_baseURI' in this.$options) ? resolveURL(this.$options._baseURI, comp.url) : comp.url;
|
||||
|
||||
if ( isNaN(componentName) )
|
||||
components[componentName] = httpVueLoader.load(componentURL, componentName);
|
||||
else
|
||||
components[componentName] = Vue.component(comp.name, httpVueLoader.load(componentURL, comp.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
httpVueLoader.require = function(moduleName) {
|
||||
|
||||
return window[moduleName];
|
||||
};
|
||||
|
||||
httpVueLoader.httpRequest = function(url) {
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.responseType = 'text';
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
|
||||
if ( xhr.readyState === 4 ) {
|
||||
|
||||
if ( xhr.status >= 200 && xhr.status < 300 )
|
||||
resolve(xhr.responseText);
|
||||
else
|
||||
reject(xhr.status);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
});
|
||||
};
|
||||
|
||||
httpVueLoader.langProcessor = {
|
||||
html: identity,
|
||||
js: identity,
|
||||
css: identity
|
||||
};
|
||||
|
||||
httpVueLoader.scriptExportsHandler = identity;
|
||||
|
||||
function httpVueLoader(url, name) {
|
||||
|
||||
var comp = parseComponentURL(url);
|
||||
return httpVueLoader.load(comp.url, name);
|
||||
}
|
||||
|
||||
return httpVueLoader;
|
||||
});
|
||||
+7
-4
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
@@ -42,12 +42,14 @@
|
||||
<add key="UseSearchKeywords" value="true" />
|
||||
<!--網站的簡稱,用來區別session和cookie-->
|
||||
<add key="SC" value="erp17168" />
|
||||
<add key="LogPath" value="C:\\log\\" />
|
||||
<add key="LogPath" value="D:\\log\\" />
|
||||
<!--是否啟用信眾自動編號 (true=啟用, false=停用)-->
|
||||
<add key="IsAutoNumbering" value="true" />
|
||||
</appSettings>
|
||||
<connectionStrings>
|
||||
<!--SQL用-->
|
||||
<add name="shopConn" providerName="System.Data.SqlClient" connectionString="Data Source=192.168.5.20;Initial Catalog=17168erp_c;User ID=sa;Password=linux@mssql1234;Encrypt=False;TrustServerCertificate=True;Provider=SQLOLEDB;Connection Timeout=10;" />
|
||||
<add name="ezEntities" providerName="System.Data.EntityClient" connectionString="metadata=res://*/App_Code.Model.Model.csdl|res://*/App_Code.Model.Model.ssdl|res://*/App_Code.Model.Model.msl;provider=System.Data.SqlClient;provider connection string="Data Source=192.168.5.20;Initial Catalog=17168erp_c;User ID=sa;Password=linux@mssql1234;Encrypt=False;TrustServerCertificate=True;Connection Timeout=10;"" />
|
||||
<add name="shopConn" providerName="System.Data.SqlClient" connectionString="Data Source=192.168.5.225;Initial Catalog=17168erp_c;User ID=sa;Password=linux@mssql1234;Encrypt=False;TrustServerCertificate=True;Provider=SQLOLEDB;Connection Timeout=10;" />
|
||||
<add name="ezEntities" providerName="System.Data.EntityClient" connectionString="metadata=res://*/App_Code.Model.Model.csdl|res://*/App_Code.Model.Model.ssdl|res://*/App_Code.Model.Model.msl;provider=System.Data.SqlClient;provider connection string="Data Source=192.168.5.225;Initial Catalog=17168erp_c;User ID=sa;Password=linux@mssql1234;Encrypt=False;TrustServerCertificate=True;Connection Timeout=10;"" />
|
||||
<!--
|
||||
-->
|
||||
<!--SQL用-->
|
||||
@@ -223,6 +225,7 @@
|
||||
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
|
||||
<staticContent>
|
||||
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="777.00:00:00" />
|
||||
<mimeMap fileExtension=".vue" mimeType="application/javascript"/>
|
||||
</staticContent>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
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
|
||||
|
||||
actitem 加上 sort_order(int) 欄位
|
||||
Reference in New Issue
Block a user